~ubuntu-branches/ubuntu/maverick/strongswan/maverick

« back to all changes in this revision

Viewing changes to src/libstrongswan/plugins/x509/x509_cert.c

  • Committer: Bazaar Package Importer
  • Author(s): Rene Mayrhofer
  • Date: 2009-04-01 22:17:52 UTC
  • mfrom: (1.1.8 upstream)
  • Revision ID: james.westby@ubuntu.com-20090401221752-eozrk0ctabblo94z
* New upstream release, which incorporates the fix. Removed dpatch for it.
  Closes: #521950: CVE-2009-0790: DoS
* New support for EAP RADIUS authentication, enabled for this package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18
18
 * for more details.
19
19
 *
20
 
 * $Id: x509_cert.c 4576 2008-11-05 08:32:38Z martin $
 
20
 * $Id: x509_cert.c 4936 2009-03-12 18:07:32Z tobias $
21
21
 */
22
22
 
23
23
#define _GNU_SOURCE
66
66
         * Public interface for this certificate.
67
67
         */
68
68
        x509_cert_t public;
69
 
 
 
69
        
70
70
        /**
71
71
         * X.509 certificate encoding in ASN.1 DER format
72
72
         */
76
76
         * SHA1 hash of the DER encoding of this X.509 certificate
77
77
         */
78
78
        chunk_t encoding_hash;
79
 
 
 
79
        
80
80
        /**
81
81
         * X.509 certificate body over which signature is computed
82
82
         */
96
96
         * ID representing the certificate issuer
97
97
         */
98
98
        identification_t *issuer;
99
 
 
 
99
        
100
100
        /**
101
101
         * Start time of certificate validity
102
102
         */
103
103
        time_t notBefore;
104
 
 
 
104
        
105
105
        /**
106
106
         * End time of certificate validity
107
107
         */
108
108
        time_t notAfter;
109
 
 
 
109
        
110
110
        /**
111
111
         * ID representing the certificate subject
112
112
         */
121
121
         * List of crlDistributionPoints as allocated char*
122
122
         */
123
123
        linked_list_t *crl_uris;
124
 
 
 
124
        
125
125
        /**
126
126
         * List ocspAccessLocations as identification_t
127
127
         */
128
128
        linked_list_t *ocsp_uris;
129
 
 
 
129
        
130
130
        /**
131
131
         * certificates embedded public key
132
132
         */
136
136
         * Subject Key Identifier
137
137
         */
138
138
        chunk_t subjectKeyID;
139
 
 
 
139
        
140
140
        /**
141
141
         * Authority Key Identifier
142
142
         */
143
143
        identification_t *authKeyIdentifier;
144
 
 
 
144
        
145
145
        /**
146
146
         * Authority Key Serial Number
147
147
         */
151
151
         * x509 constraints and other flags
152
152
         */
153
153
        x509_flag_t flags;
154
 
 
 
154
        
155
155
        /**
156
156
         * Signature algorithm
157
157
         */
158
158
        int algorithm;
159
 
 
 
159
        
160
160
        /**
161
161
         * Signature
162
162
         */
163
163
        chunk_t signature;
164
164
        
165
165
        /**
 
166
         * Certificate parsed from blob/file?
 
167
         */
 
168
        bool parsed;
 
169
        
 
170
        /**
166
171
         * reference count
167
172
         */
168
173
        refcount_t ref;
258
263
                }
259
264
        }
260
265
        success = parser->success(parser);
261
 
 
 
266
        
262
267
end:
263
268
        parser->destroy(parser);
264
269
        return success;
306
311
        asn1_parser_t *parser;
307
312
        chunk_t object;
308
313
        int objectID ;
309
 
 
 
314
        
310
315
        identification_t *gn = NULL;
311
 
 
 
316
        
312
317
        parser = asn1_parser_create(generalNameObjects, blob);
313
318
        parser->set_top_level(parser, level0);
314
 
 
 
319
        
315
320
        while (parser->iterate(parser, &objectID, &object))
316
321
        {
317
322
                id_type_t id_type = ID_ANY;
318
 
        
 
323
                
319
324
                switch (objectID)
320
325
                {
321
326
                        case GN_OBJ_RFC822_NAME:
329
334
                                break;
330
335
                        case GN_OBJ_DIRECTORY_NAME:
331
336
                                id_type = ID_DER_ASN1_DN;
332
 
                        break;
 
337
                                break;
333
338
                        case GN_OBJ_IP_ADDRESS:
334
339
                                id_type = ID_IPV4_ADDR;
335
340
                                break;
350
355
                        gn = identification_create_from_encoding(id_type, object);
351
356
                        DBG2("  '%D'", gn);
352
357
                        goto end;
353
 
        }
354
 
   }
355
 
 
 
358
                }
 
359
        }
 
360
        
356
361
end:
357
362
        parser->destroy(parser);
358
 
    return gn;
 
363
        return gn;
359
364
}
360
365
 
361
366
/**
377
382
        asn1_parser_t *parser;
378
383
        chunk_t object;
379
384
        int objectID;
380
 
 
 
385
        
381
386
        parser = asn1_parser_create(generalNamesObjects, blob);
382
387
        parser->set_top_level(parser, level0);
383
388
        parser->set_flags(parser, implicit, FALSE);
384
 
 
 
389
        
385
390
        while (parser->iterate(parser, &objectID, &object))
386
391
        {
387
392
                if (objectID == GENERAL_NAMES_GN)
388
393
                {
389
394
                        identification_t *gn = parse_generalName(object,
390
395
                                                                                        parser->get_level(parser)+1);
391
 
 
 
396
                        
392
397
                        if (gn)
393
398
                        {
394
399
                                list->insert_last(list, (void *)gn);
425
430
        chunk_t object;
426
431
        int objectID;
427
432
        identification_t *authKeyIdentifier = NULL;
428
 
 
 
433
        
429
434
        *authKeySerialNumber = chunk_empty;
430
 
 
 
435
        
431
436
        parser = asn1_parser_create(authKeyIdentifierObjects, blob);
432
437
        parser->set_top_level(parser, level0);
433
 
 
 
438
        
434
439
        while (parser->iterate(parser, &objectID, &object))
435
440
        {
436
441
                switch (objectID) 
480
485
        
481
486
        parser = asn1_parser_create(authInfoAccessObjects, blob);
482
487
        parser->set_top_level(parser, level0);
483
 
 
 
488
        
484
489
        while (parser->iterate(parser, &objectID, &object))
485
490
        {
486
491
                switch (objectID) 
497
502
                                                {
498
503
                                                        identification_t *id;
499
504
                                                        char *uri;
500
 
 
 
505
                                                        
501
506
                                                        id = parse_generalName(object,
502
507
                                                                                        parser->get_level(parser)+1);
503
508
                                                        if (id == NULL)
524
529
                                break;
525
530
                }
526
531
        }
527
 
 
 
532
        
528
533
end:
529
534
        parser->destroy(parser);
530
535
}
552
557
        
553
558
        parser = asn1_parser_create(extendedKeyUsageObjects, blob);
554
559
        parser->set_top_level(parser, level0);
555
 
 
 
560
        
556
561
        while (parser->iterate(parser, &objectID, &object))
557
562
        {
558
563
                if (objectID == EXT_KEY_USAGE_PURPOSE_ID && 
599
604
        
600
605
        parser = asn1_parser_create(crlDistributionPointsObjects, blob);
601
606
        parser->set_top_level(parser, level0);
602
 
 
 
607
        
603
608
        while (parser->iterate(parser, &objectID, &object))
604
609
        {
605
610
                if (objectID == CRL_DIST_POINTS_FULLNAME)
606
611
                {
607
612
                        identification_t *id;
608
 
 
 
613
                        
609
614
                        /* append extracted generalNames to existing chained list */
610
615
                        x509_parse_generalNames(object, parser->get_level(parser)+1,
611
616
                                                                        TRUE, list);
613
618
                        while (list->remove_last(list, (void**)&id) == SUCCESS)
614
619
                        {
615
620
                                char *uri;
616
 
 
 
621
                                
617
622
                                if (asprintf(&uri, "%D", id) > 0)
618
623
                                {
619
624
                                        this->crl_uris->insert_last(this->crl_uris, uri);
687
692
        bool critical;
688
693
        
689
694
        parser = asn1_parser_create(certObjects, this->encoding);
690
 
 
 
695
        
691
696
        while (parser->iterate(parser, &objectID, &object))
692
697
        {
693
698
                u_int level = parser->get_level(parser)+1;
694
 
 
 
699
                
695
700
                switch (objectID)
696
701
                {
697
702
                        case X509_OBJ_TBS_CERTIFICATE:
806
811
                }
807
812
        }
808
813
        success = parser->success(parser);
809
 
 
 
814
        
810
815
end:
811
816
        parser->destroy(parser);
812
817
        return success;
850
855
        {
851
856
                return ID_MATCH_PERFECT;
852
857
        }
853
 
 
 
858
        
854
859
        best = this->subject->matches(this->subject, subject);
855
860
        enumerator = this->subjectAltNames->create_enumerator(this->subjectAltNames);
856
861
        while (enumerator->enumerate(enumerator, &current))
1001
1006
{
1002
1007
        time_t this_update, that_update, now = time(NULL);
1003
1008
        bool new;
1004
 
 
 
1009
        
1005
1010
        this->get_validity(this, &now, &this_update, NULL);
1006
1011
        that->get_validity(that, &now, &that_update, NULL);
1007
1012
        new = this_update > that_update;
1008
 
        DBG1("  certificate from %#T is %s - existing certificate from %#T %s",
 
1013
        DBG1("  certificate from %T is %s - existing certificate from %T %s",
1009
1014
                                &this_update, FALSE, new ? "newer":"not newer",
1010
1015
                                &that_update, FALSE, new ? "replaced":"retained");
1011
1016
        return new;
1026
1031
{
1027
1032
        chunk_t encoding;
1028
1033
        bool equal;
1029
 
 
 
1034
        
1030
1035
        if (this == (private_x509_cert_t*)other)
1031
1036
        {
1032
1037
                return TRUE;
1102
1107
                DESTROY_IF(this->authKeyIdentifier);
1103
1108
                chunk_free(&this->encoding);
1104
1109
                chunk_free(&this->encoding_hash);
 
1110
                if (!this->parsed)
 
1111
                {       /* only parsed certificates point these fields to "encoded" */
 
1112
                        chunk_free(&this->signature);
 
1113
                        chunk_free(&this->serialNumber);
 
1114
                        chunk_free(&this->tbsCertificate);
 
1115
                }
1105
1116
                free(this);
1106
1117
        }
1107
1118
}
1132
1143
        this->public.interface.create_subjectAltName_enumerator = (enumerator_t* (*)(x509_t*))create_subjectAltName_enumerator;
1133
1144
        this->public.interface.create_crl_uri_enumerator = (enumerator_t* (*)(x509_t*))create_crl_uri_enumerator;
1134
1145
        this->public.interface.create_ocsp_uri_enumerator = (enumerator_t* (*)(x509_t*))create_ocsp_uri_enumerator;
1135
 
 
 
1146
        
1136
1147
        this->encoding = chunk_empty;
1137
1148
        this->encoding_hash = chunk_empty;
 
1149
        this->tbsCertificate = chunk_empty;
 
1150
        this->version = 3;
 
1151
        this->serialNumber = chunk_empty;       
 
1152
        this->notBefore = 0;
 
1153
        this->notAfter = 0;
1138
1154
        this->public_key = NULL;
1139
1155
        this->subject = NULL;
1140
1156
        this->issuer = NULL;
1144
1160
        this->subjectKeyID = chunk_empty;
1145
1161
        this->authKeyIdentifier = NULL;
1146
1162
        this->authKeySerialNumber = chunk_empty;
 
1163
        this->algorithm = 0;
 
1164
        this->signature = chunk_empty;
1147
1165
        this->flags = 0;
1148
1166
        this->ref = 1;
1149
 
 
 
1167
        this->parsed = FALSE;
 
1168
        
1150
1169
        return this;
1151
1170
}
1152
1171
 
1155
1174
 */
1156
1175
static private_x509_cert_t *create_from_chunk(chunk_t chunk)
1157
1176
{
 
1177
        hasher_t *hasher;
1158
1178
        private_x509_cert_t *this = create_empty();
1159
 
 
 
1179
        
1160
1180
        this->encoding = chunk;
1161
1181
        if (!parse_certificate(this))
1162
1182
        {
1163
1183
                destroy(this);
1164
1184
                return NULL;
1165
1185
        }
1166
 
 
 
1186
        
1167
1187
        /* check if the certificate is self-signed */
1168
1188
        if (issued_by(this, &this->public.interface.interface))
1169
1189
        {
1170
1190
                this->flags |= X509_SELF_SIGNED;
1171
1191
        }
1172
1192
        
1173
 
        hasher_t *hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
 
1193
        hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
1174
1194
        if (hasher != NULL)
1175
1195
        {
1176
1196
                hasher->allocate_hash(hasher, this->encoding, &this->encoding_hash);
1181
1201
                DBG1("  unable to create hash of certificate, SHA1 not supported");             
1182
1202
        }
1183
1203
        
 
1204
        this->parsed = TRUE;
1184
1205
        return this;
1185
1206
}
1186
1207
 
1207
1228
        }
1208
1229
        DBG1("  loaded certificate file '%s'",  path);
1209
1230
        return this;
1210
 
 
1211
1231
}
1212
1232
 
1213
1233
typedef struct private_builder_t private_builder_t;
1221
1241
        private_x509_cert_t *cert;
1222
1242
        /** additional flags to enforce */
1223
1243
        x509_flag_t flags;
 
1244
        /** certificate to sign, if we generate a new cert */
 
1245
        certificate_t *sign_cert;
 
1246
        /** private key to sign, if we generate a new cert */
 
1247
        private_key_t *sign_key;
1224
1248
};
1225
1249
 
1226
1250
/**
 
1251
 * Generate and sign a new certificate
 
1252
 */
 
1253
static bool generate(private_builder_t *this)
 
1254
{
 
1255
        chunk_t extensions = chunk_empty;
 
1256
        identification_t *issuer, *subject;
 
1257
        chunk_t key_info, key;
 
1258
        signature_scheme_t scheme;
 
1259
        hasher_t *hasher;
 
1260
        
 
1261
        subject = this->cert->subject;
 
1262
        if (this->sign_cert)
 
1263
        {
 
1264
                issuer = this->sign_cert->get_subject(this->sign_cert);
 
1265
                if (!this->cert->public_key)
 
1266
                {
 
1267
                        return FALSE;
 
1268
                }
 
1269
        }
 
1270
        else
 
1271
        {       /* self signed */
 
1272
                issuer = subject;
 
1273
                if (!this->cert->public_key)
 
1274
                {
 
1275
                        this->cert->public_key = this->sign_key->get_public_key(this->sign_key);
 
1276
                }
 
1277
                this->flags |= X509_SELF_SIGNED;
 
1278
        }
 
1279
        this->cert->issuer = issuer->clone(issuer);
 
1280
        if (!this->cert->notBefore)
 
1281
        {
 
1282
                this->cert->notBefore = time(NULL);
 
1283
        }
 
1284
        if (!this->cert->notAfter)
 
1285
        {       /* defaults to 1 years from now on */
 
1286
                this->cert->notAfter = this->cert->notBefore + 60 * 60 * 24 * 365;
 
1287
        }
 
1288
        this->cert->flags = this->flags;
 
1289
        
 
1290
        switch (this->sign_key->get_type(this->sign_key))
 
1291
        {
 
1292
                case KEY_RSA:
 
1293
                        this->cert->algorithm = OID_SHA1_WITH_RSA;
 
1294
                        scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
 
1295
                        break;
 
1296
                default:
 
1297
                        return FALSE;
 
1298
        }
 
1299
        
 
1300
        switch (this->cert->public_key->get_type(this->cert->public_key))
 
1301
        {
 
1302
                case KEY_RSA:
 
1303
                        key = this->cert->public_key->get_encoding(this->cert->public_key);
 
1304
                        key_info = asn1_wrap(ASN1_SEQUENCE, "cm",
 
1305
                                                        asn1_algorithmIdentifier(OID_RSA_ENCRYPTION), 
 
1306
                                                        asn1_bitstring("m", key));      
 
1307
                        break;
 
1308
                default:
 
1309
                        return FALSE;
 
1310
        }
 
1311
        
 
1312
        if (this->cert->subjectAltNames->get_count(this->cert->subjectAltNames))
 
1313
        {
 
1314
                /* TODO: encode subjectAltNames */
 
1315
        }
 
1316
        
 
1317
        this->cert->tbsCertificate = asn1_wrap(ASN1_SEQUENCE, "mmccmcmm", 
 
1318
                asn1_simple_object(ASN1_CONTEXT_C_0, ASN1_INTEGER_2),
 
1319
                asn1_simple_object(ASN1_INTEGER, this->cert->serialNumber),
 
1320
                asn1_algorithmIdentifier(this->cert->algorithm),
 
1321
                issuer->get_encoding(issuer),
 
1322
                asn1_wrap(ASN1_SEQUENCE, "mm",
 
1323
                        asn1_from_time(&this->cert->notBefore, ASN1_UTCTIME),
 
1324
                        asn1_from_time(&this->cert->notAfter, ASN1_UTCTIME)),
 
1325
                subject->get_encoding(subject),
 
1326
                key_info, extensions);
 
1327
        
 
1328
        if (!this->sign_key->sign(this->sign_key, scheme, 
 
1329
                                                        this->cert->tbsCertificate, &this->cert->signature))
 
1330
        {
 
1331
                return FALSE;
 
1332
        }
 
1333
        this->cert->encoding = asn1_wrap(ASN1_SEQUENCE, "ccm",
 
1334
                                                                this->cert->tbsCertificate,
 
1335
                                                                asn1_algorithmIdentifier(this->cert->algorithm),
 
1336
                                                                asn1_bitstring("c", this->cert->signature));
 
1337
        
 
1338
        hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
 
1339
        if (!hasher)
 
1340
        {
 
1341
                return FALSE;
 
1342
        }
 
1343
        hasher->allocate_hash(hasher, this->cert->encoding,
 
1344
                                                  &this->cert->encoding_hash);
 
1345
        hasher->destroy(hasher);
 
1346
        return TRUE;
 
1347
}
 
1348
 
 
1349
/**
1227
1350
 * Implementation of builder_t.build
1228
1351
 */
1229
1352
static private_x509_cert_t *build(private_builder_t *this)
1230
1353
{
1231
 
        private_x509_cert_t *cert = this->cert;
1232
 
        x509_flag_t flags = this->flags;
1233
 
 
 
1354
        private_x509_cert_t *cert;
 
1355
        x509_flag_t flags;
 
1356
        
 
1357
        if (this->cert && !this->cert->encoding.ptr)
 
1358
        {
 
1359
                if (!this->sign_key || !this->cert ||
 
1360
                        !generate(this))
 
1361
                {
 
1362
                        destroy(this->cert);
 
1363
                        free(this);
 
1364
                        return NULL;
 
1365
                }
 
1366
        }
 
1367
        cert = this->cert;
 
1368
        flags =  this->flags;
1234
1369
        free(this);
1235
1370
        if (cert == NULL)
1236
1371
        {
1237
1372
                return NULL;
1238
1373
        }
 
1374
        
1239
1375
        if ((flags & X509_CA) && !(cert->flags & X509_CA))
1240
1376
        {
1241
1377
                DBG1("  ca certificate must have ca basic constraint set, discarded");
1253
1389
{
1254
1390
        va_list args;
1255
1391
        chunk_t chunk;
 
1392
        bool handled = TRUE;
1256
1393
        
1257
1394
        va_start(args, part);
1258
1395
        switch (part)
1267
1404
                case BUILD_X509_FLAG:
1268
1405
                        this->flags = va_arg(args, x509_flag_t);
1269
1406
                        break;
 
1407
                case BUILD_SIGNING_KEY:
 
1408
                        this->sign_key = va_arg(args, private_key_t*);
 
1409
                        break;
 
1410
                case BUILD_SIGNING_CERT:
 
1411
                        this->sign_cert = va_arg(args, certificate_t*);
 
1412
                        break;
 
1413
                default:
 
1414
                        /* all other parts need an empty cert */
 
1415
                        if (!this->cert)
 
1416
                        {
 
1417
                                this->cert = create_empty();
 
1418
                        }
 
1419
                        handled = FALSE;
 
1420
                        break;
 
1421
        }
 
1422
        if (handled)
 
1423
        {
 
1424
                va_end(args);
 
1425
                return;
 
1426
        }
 
1427
        
 
1428
        switch (part)
 
1429
        {
 
1430
                case BUILD_PUBLIC_KEY:
 
1431
                {
 
1432
                        public_key_t *key = va_arg(args, public_key_t*);
 
1433
                        this->cert->public_key = key->get_ref(key);
 
1434
                        break;
 
1435
                }
 
1436
                case BUILD_SUBJECT:
 
1437
                {
 
1438
                        identification_t *id = va_arg(args, identification_t*);
 
1439
                        this->cert->subject = id->clone(id);
 
1440
                        break;
 
1441
                }
 
1442
                case BUILD_SUBJECT_ALTNAME:
 
1443
                {
 
1444
                        identification_t *id = va_arg(args, identification_t*);
 
1445
                        this->cert->subjectAltNames->insert_last(
 
1446
                                                                        this->cert->subjectAltNames, id->clone(id));
 
1447
                        break;
 
1448
                }
 
1449
                case BUILD_NOT_BEFORE_TIME:
 
1450
                        this->cert->notBefore = va_arg(args, time_t);
 
1451
                        break;
 
1452
                case BUILD_NOT_AFTER_TIME:
 
1453
                        this->cert->notAfter = va_arg(args, time_t);
 
1454
                        break;
 
1455
                case BUILD_SERIAL:
 
1456
                {
 
1457
                        chunk_t serial = va_arg(args, chunk_t);
 
1458
                        this->cert->serialNumber = chunk_clone(serial);
 
1459
                        break;
 
1460
                }
1270
1461
                default:
1271
1462
                        /* abort if unsupported option */
1272
1463
                        if (this->cert)
1295
1486
        
1296
1487
        this->cert = NULL;
1297
1488
        this->flags = 0;
 
1489
        this->sign_cert = NULL;
 
1490
        this->sign_key = NULL;
1298
1491
        this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
1299
1492
        this->public.build = (void*(*)(builder_t *this))build;
1300
1493