Coverage Report

Created: 2025-12-01 06:32

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/strongswan/src/libstrongswan/plugins/x509/x509_cert.c
Line
Count
Source
1
/*
2
 * Copyright (C) 2000 Andreas Hess, Patric Lichtsteiner, Roger Wegmann
3
 * Copyright (C) 2001 Marco Bertossa, Andreas Schleiss
4
 * Copyright (C) 2002 Mario Strasser
5
 * Copyright (C) 2000-2022 Andreas Steffen
6
 * Copyright (C) 2006-2009 Martin Willi
7
 * Copyright (C) 2008-2017 Tobias Brunner
8
 *
9
 * Copyright (C) secunet Security Networks AG
10
 *
11
 * This program is free software; you can redistribute it and/or modify it
12
 * under the terms of the GNU General Public License as published by the
13
 * Free Software Foundation; either version 2 of the License, or (at your
14
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
15
 *
16
 * This program is distributed in the hope that it will be useful, but
17
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
19
 * for more details.
20
 */
21
22
#define _GNU_SOURCE
23
24
#include <sys/stat.h>
25
#include <time.h>
26
#include <unistd.h>
27
#include <string.h>
28
#include <stdio.h>
29
30
#include "x509_cert.h"
31
32
#include <library.h>
33
#include <utils/debug.h>
34
#include <asn1/oid.h>
35
#include <asn1/asn1.h>
36
#include <asn1/asn1_parser.h>
37
#include <crypto/hashers/hasher.h>
38
#include <credentials/keys/private_key.h>
39
#include <collections/linked_list.h>
40
#include <utils/identification.h>
41
#include <selectors/traffic_selector.h>
42
43
/**
44
 * Different kinds of generalNames
45
 */
46
typedef enum {
47
  GN_OTHER_NAME =   0,
48
  GN_RFC822_NAME =  1,
49
  GN_DNS_NAME =   2,
50
  GN_X400_ADDRESS = 3,
51
  GN_DIRECTORY_NAME = 4,
52
  GN_EDI_PARTY_NAME = 5,
53
  GN_URI =      6,
54
  GN_IP_ADDRESS =   7,
55
  GN_REGISTERED_ID =  8,
56
} generalNames_t;
57
58
59
typedef struct private_x509_cert_t private_x509_cert_t;
60
61
/**
62
 * Private data of a x509_cert_t object.
63
 */
64
struct private_x509_cert_t {
65
  /**
66
   * Public interface for this certificate.
67
   */
68
  x509_cert_t public;
69
70
  /**
71
   * X.509 certificate encoding in ASN.1 DER format
72
   */
73
  chunk_t encoding;
74
75
  /**
76
   * SHA1 hash of the DER encoding of this X.509 certificate
77
   */
78
  chunk_t encoding_hash;
79
80
  /**
81
   * X.509 certificate body over which signature is computed
82
   */
83
  chunk_t tbsCertificate;
84
85
  /**
86
   * Version of the X.509 certificate
87
   */
88
  u_int version;
89
90
  /**
91
   * Serial number of the X.509 certificate
92
   */
93
  chunk_t serialNumber;
94
95
  /**
96
   * ID representing the certificate issuer
97
   */
98
  identification_t *issuer;
99
100
  /**
101
   * Start time of certificate validity
102
   */
103
  time_t notBefore;
104
105
  /**
106
   * End time of certificate validity
107
   */
108
  time_t notAfter;
109
110
  /**
111
   * ID representing the certificate subject
112
   */
113
  identification_t *subject;
114
115
  /**
116
   * List of subjectAltNames as identification_t
117
   */
118
  linked_list_t *subjectAltNames;
119
120
  /**
121
   * List of crlDistributionPoints as x509_cdp_t*
122
   */
123
  linked_list_t *crl_uris;
124
125
  /**
126
   * List of ocspAccessLocations as allocated char*
127
   */
128
  linked_list_t *ocsp_uris;
129
130
  /**
131
   * List of ipAddrBlocks as traffic_selector_t
132
   */
133
  linked_list_t *ipAddrBlocks;
134
135
  /**
136
   * List of permitted name constraints
137
   */
138
  linked_list_t *permitted_names;
139
140
  /**
141
   * List of excluded name constraints
142
   */
143
  linked_list_t *excluded_names;
144
145
  /**
146
   * List of certificatePolicies, as x509_cert_policy_t
147
   */
148
  linked_list_t *cert_policies;
149
150
  /**
151
   * List of policyMappings, as x509_policy_mapping_t
152
   */
153
  linked_list_t *policy_mappings;
154
155
  /**
156
   * certificate's embedded public key
157
   */
158
  public_key_t *public_key;
159
160
  /**
161
   * Subject Key Identifier
162
   */
163
  chunk_t subjectKeyIdentifier;
164
165
  /**
166
   * Authority Key Identifier
167
   */
168
  chunk_t authKeyIdentifier;
169
170
  /**
171
   * Authority Key Serial Number
172
   */
173
  chunk_t authKeySerialNumber;
174
175
  /**
176
   * Optional OID of an [unsupported] critical extension
177
   */
178
  chunk_t critical_extension_oid;
179
180
  /**
181
   * Path Length Constraint
182
   */
183
  u_char pathLenConstraint;
184
185
  /**
186
   * requireExplicitPolicy Constraint
187
   */
188
  u_char require_explicit;
189
190
  /**
191
   * inhibitPolicyMapping Constraint
192
   */
193
  u_char inhibit_mapping;
194
195
  /**
196
   * inhibitAnyPolicy Constraint
197
   */
198
  u_char inhibit_any;
199
200
  /**
201
   * x509 constraints and other flags
202
   */
203
  x509_flag_t flags;
204
205
  /**
206
   * Signature scheme
207
   */
208
  signature_params_t *scheme;
209
210
  /**
211
   * Signature
212
   */
213
  chunk_t signature;
214
215
  /**
216
   * Certificate parsed from blob/file?
217
   */
218
  bool parsed;
219
220
  /**
221
   * reference count
222
   */
223
  refcount_t ref;
224
};
225
226
/**
227
 * Convert a generalName to a string
228
 */
229
static bool gn_to_string(identification_t *id, char **uri)
230
403
{
231
403
  int len;
232
233
403
#ifdef USE_FUZZING
234
403
  chunk_t proper;
235
403
  chunk_printable(id->get_encoding(id), &proper, '?');
236
403
  len = asprintf(uri, "%.*s", (int)proper.len, proper.ptr);
237
403
  chunk_free(&proper);
238
#else
239
  len = asprintf(uri, "%Y", id);
240
#endif
241
403
  if (!len)
242
191
  {
243
191
    free(*uri);
244
191
    return FALSE;
245
191
  }
246
212
  return len > 0;
247
403
}
248
249
/**
250
 * Destroy a CertificatePolicy
251
 */
252
static void cert_policy_destroy(x509_cert_policy_t *this)
253
0
{
254
0
  free(this->oid.ptr);
255
0
  free(this->cps_uri);
256
0
  free(this->unotice_text);
257
0
  free(this);
258
0
}
259
260
/**
261
 * Free policy mapping
262
 */
263
static void policy_mapping_destroy(x509_policy_mapping_t *mapping)
264
0
{
265
0
  free(mapping->issuer.ptr);
266
0
  free(mapping->subject.ptr);
267
0
  free(mapping);
268
0
}
269
270
/**
271
 * Parse a length constraint from an unwrapped integer
272
 */
273
static u_int parse_constraint(chunk_t object)
274
0
{
275
0
  switch (object.len)
276
0
  {
277
0
    case 0:
278
0
      return 0;
279
0
    case 1:
280
0
      return (object.ptr[0] & 0x80) ? X509_NO_CONSTRAINT : object.ptr[0];
281
0
    default:
282
0
      return X509_NO_CONSTRAINT;
283
0
  }
284
0
}
285
286
/**
287
 * ASN.1 definition of a basicConstraints extension
288
 */
289
static const asn1Object_t basicConstraintsObjects[] = {
290
  { 0, "basicConstraints",  ASN1_SEQUENCE,  ASN1_NONE     }, /*  0 */
291
  { 1,   "CA",        ASN1_BOOLEAN, ASN1_DEF|ASN1_BODY  }, /*  1 */
292
  { 1,   "pathLenConstraint", ASN1_INTEGER, ASN1_OPT|ASN1_BODY  }, /*  2 */
293
  { 1,   "end opt",     ASN1_EOC,   ASN1_END      }, /*  3 */
294
  { 0, "exit",        ASN1_EOC,   ASN1_EXIT     }
295
};
296
0
#define BASIC_CONSTRAINTS_CA    1
297
0
#define BASIC_CONSTRAINTS_PATH_LEN  2
298
299
/**
300
 * Extracts the basicConstraints extension
301
 */
302
static bool parse_basicConstraints(chunk_t blob, int level0,
303
                   private_x509_cert_t *this)
304
0
{
305
0
  asn1_parser_t *parser;
306
0
  chunk_t object;
307
0
  int objectID;
308
0
  bool isCA = FALSE;
309
0
  bool success;
310
311
0
  parser = asn1_parser_create(basicConstraintsObjects, blob);
312
0
  parser->set_top_level(parser, level0);
313
314
0
  while (parser->iterate(parser, &objectID, &object))
315
0
  {
316
0
    switch (objectID)
317
0
    {
318
0
      case BASIC_CONSTRAINTS_CA:
319
0
        isCA = object.len && *object.ptr;
320
0
        DBG2(DBG_ASN, "  %s", isCA ? "TRUE" : "FALSE");
321
0
        if (isCA)
322
0
        {
323
0
          this->flags |= X509_CA;
324
0
        }
325
0
        break;
326
0
      case BASIC_CONSTRAINTS_PATH_LEN:
327
0
        if (isCA)
328
0
        {
329
0
          this->pathLenConstraint = parse_constraint(object);
330
0
        }
331
0
        break;
332
0
      default:
333
0
        break;
334
0
    }
335
0
  }
336
0
  success = parser->success(parser);
337
0
  parser->destroy(parser);
338
339
0
  return success;
340
0
}
341
342
/**
343
 * ASN.1 definition of otherName
344
 */
345
static const asn1Object_t otherNameObjects[] = {
346
  {0, "type-id",  ASN1_OID,     ASN1_BODY }, /* 0 */
347
  {0, "value",  ASN1_CONTEXT_C_0, ASN1_BODY }, /* 1 */
348
  {0, "exit",   ASN1_EOC,     ASN1_EXIT }
349
};
350
5
#define ON_OBJ_ID_TYPE    0
351
3
#define ON_OBJ_VALUE    1
352
353
/**
354
 * Extracts an otherName
355
 */
356
static bool parse_otherName(chunk_t *blob, int level0, id_type_t *type)
357
7
{
358
7
  asn1_parser_t *parser;
359
7
  chunk_t object;
360
7
  int objectID;
361
7
  int oid = OID_UNKNOWN;
362
7
  bool success = FALSE;
363
364
7
  parser = asn1_parser_create(otherNameObjects, *blob);
365
7
  parser->set_top_level(parser, level0);
366
367
15
  while (parser->iterate(parser, &objectID, &object))
368
8
  {
369
8
    switch (objectID)
370
8
    {
371
5
      case ON_OBJ_ID_TYPE:
372
5
        oid = asn1_known_oid(object);
373
5
        break;
374
3
      case ON_OBJ_VALUE:
375
3
        switch (oid)
376
3
        {
377
0
          case OID_XMPP_ADDR:
378
0
            if (asn1_parse_simple_object(&object, ASN1_UTF8STRING,
379
0
                  parser->get_level(parser)+1, "xmppAddr"))
380
0
            { /* we handle xmppAddr as RFC822 addr */
381
0
              *blob = object;
382
0
              *type = ID_RFC822_ADDR;
383
0
            }
384
0
            else
385
0
            {
386
0
              goto end;
387
0
            }
388
0
            break;
389
0
          case OID_USER_PRINCIPAL_NAME:
390
0
            if (asn1_parse_simple_object(&object, ASN1_UTF8STRING,
391
0
                  parser->get_level(parser)+1, "msUPN"))
392
0
            { /* we handle UPNs as RFC822 addr */
393
0
              *blob = object;
394
0
              *type = ID_RFC822_ADDR;
395
0
            }
396
0
            else
397
0
            {
398
0
              goto end;
399
0
            }
400
0
            break;
401
3
        }
402
3
        break;
403
3
      default:
404
0
        break;
405
8
    }
406
8
  }
407
7
  success = parser->success(parser);
408
409
7
end:
410
7
  parser->destroy(parser);
411
7
  return success;
412
7
}
413
414
/**
415
 * ASN.1 definition of generalName
416
 */
417
static const asn1Object_t generalNameObjects[] = {
418
  { 0, "otherName",   ASN1_CONTEXT_C_0,  ASN1_OPT|ASN1_BODY }, /*  0 */
419
  { 0, "end choice",    ASN1_EOC,          ASN1_END       }, /*  1 */
420
  { 0, "rfc822Name",    ASN1_CONTEXT_S_1,  ASN1_OPT|ASN1_BODY }, /*  2 */
421
  { 0, "end choice",    ASN1_EOC,          ASN1_END       }, /*  3 */
422
  { 0, "dnsName",     ASN1_CONTEXT_S_2,  ASN1_OPT|ASN1_BODY }, /*  4 */
423
  { 0, "end choice",    ASN1_EOC,          ASN1_END       }, /*  5 */
424
  { 0, "x400Address",   ASN1_CONTEXT_S_3,  ASN1_OPT|ASN1_BODY }, /*  6 */
425
  { 0, "end choice",    ASN1_EOC,          ASN1_END       }, /*  7 */
426
  { 0, "directoryName", ASN1_CONTEXT_C_4,  ASN1_OPT|ASN1_BODY }, /*  8 */
427
  { 0, "end choice",    ASN1_EOC,          ASN1_END       }, /*  9 */
428
  { 0, "ediPartyName",  ASN1_CONTEXT_C_5,  ASN1_OPT|ASN1_BODY }, /* 10 */
429
  { 0, "end choice",    ASN1_EOC,          ASN1_END       }, /* 11 */
430
  { 0, "URI",       ASN1_CONTEXT_S_6,  ASN1_OPT|ASN1_BODY }, /* 12 */
431
  { 0, "end choice",    ASN1_EOC,          ASN1_END       }, /* 13 */
432
  { 0, "ipAddress",   ASN1_CONTEXT_S_7,  ASN1_OPT|ASN1_BODY }, /* 14 */
433
  { 0, "end choice",    ASN1_EOC,          ASN1_END       }, /* 15 */
434
  { 0, "registeredID",  ASN1_CONTEXT_S_8,  ASN1_OPT|ASN1_BODY }, /* 16 */
435
  { 0, "end choice",    ASN1_EOC,          ASN1_END       }, /* 17 */
436
  { 0, "exit",      ASN1_EOC,          ASN1_EXIT      }
437
};
438
7
#define GN_OBJ_OTHER_NAME    0
439
62
#define GN_OBJ_RFC822_NAME     2
440
77
#define GN_OBJ_DNS_NAME      4
441
0
#define GN_OBJ_X400_ADDRESS    6
442
1.01k
#define GN_OBJ_DIRECTORY_NAME  8
443
0
#define GN_OBJ_EDI_PARTY_NAME 10
444
41
#define GN_OBJ_URI        12
445
56
#define GN_OBJ_IP_ADDRESS   14
446
0
#define GN_OBJ_REGISTERED_ID  16
447
448
/**
449
 * Extracts a generalName
450
 */
451
static identification_t *parse_generalName(chunk_t blob, int level0)
452
1.25k
{
453
1.25k
  asn1_parser_t *parser;
454
1.25k
  chunk_t object;
455
1.25k
  int objectID ;
456
457
1.25k
  identification_t *gn = NULL;
458
459
1.25k
  parser = asn1_parser_create(generalNameObjects, blob);
460
1.25k
  parser->set_top_level(parser, level0);
461
462
6.22k
  while (parser->iterate(parser, &objectID, &object))
463
6.21k
  {
464
6.21k
    id_type_t id_type = ID_ANY;
465
466
6.21k
    switch (objectID)
467
6.21k
    {
468
62
      case GN_OBJ_RFC822_NAME:
469
62
        id_type = ID_RFC822_ADDR;
470
62
        break;
471
77
      case GN_OBJ_DNS_NAME:
472
77
        id_type = ID_FQDN;
473
77
        break;
474
41
      case GN_OBJ_URI:
475
41
        id_type = ID_DER_ASN1_GN_URI;
476
41
        break;
477
1.01k
      case GN_OBJ_DIRECTORY_NAME:
478
1.01k
        id_type = ID_DER_ASN1_DN;
479
1.01k
        break;
480
56
      case GN_OBJ_IP_ADDRESS:
481
56
        switch (object.len)
482
56
        {
483
24
          case 4:
484
24
            id_type = ID_IPV4_ADDR;
485
24
            break;
486
10
          case 8:
487
10
            id_type = ID_IPV4_ADDR_SUBNET;
488
10
            break;
489
10
          case 16:
490
10
            id_type = ID_IPV6_ADDR;
491
10
            break;
492
6
          case 32:
493
6
            id_type = ID_IPV6_ADDR_SUBNET;
494
6
            break;
495
6
          default:
496
6
            break;
497
56
        }
498
56
        break;
499
56
      case GN_OBJ_OTHER_NAME:
500
7
        if (!parse_otherName(&object, parser->get_level(parser)+1,
501
7
                   &id_type))
502
4
        {
503
4
          goto end;
504
4
        }
505
3
        break;
506
3
      case GN_OBJ_X400_ADDRESS:
507
0
      case GN_OBJ_EDI_PARTY_NAME:
508
0
      case GN_OBJ_REGISTERED_ID:
509
4.96k
      default:
510
4.96k
        break;
511
6.21k
    }
512
6.20k
    if (id_type != ID_ANY)
513
1.24k
    {
514
1.24k
      gn = identification_create_from_encoding(id_type, object);
515
1.24k
      DBG2(DBG_ASN, "  '%Y'", gn);
516
1.24k
      goto end;
517
1.24k
    }
518
6.20k
  }
519
520
1.25k
end:
521
1.25k
  parser->destroy(parser);
522
1.25k
  return gn;
523
1.25k
}
524
525
/**
526
 * ASN.1 definition of generalNames
527
 */
528
static const asn1Object_t generalNamesObjects[] = {
529
  { 0, "generalNames",  ASN1_SEQUENCE,  ASN1_LOOP }, /* 0 */
530
  { 1,   "generalName", ASN1_EOC,   ASN1_RAW  }, /* 1 */
531
  { 0, "end loop",    ASN1_EOC,   ASN1_END  }, /* 2 */
532
  { 0, "exit",      ASN1_EOC,   ASN1_EXIT }
533
};
534
1.54k
#define GENERAL_NAMES_GN  1
535
536
/**
537
 * Extracts one or several GNs and puts them into a chained list
538
 */
539
bool x509_parse_generalNames(chunk_t blob, int level0, bool implicit,
540
               linked_list_t *list)
541
171
{
542
171
  asn1_parser_t *parser;
543
171
  chunk_t object;
544
171
  identification_t *gn;
545
171
  int objectID;
546
171
  bool success = FALSE;
547
548
171
  parser = asn1_parser_create(generalNamesObjects, blob);
549
171
  parser->set_top_level(parser, level0);
550
171
  parser->set_flags(parser, implicit, FALSE);
551
552
1.69k
  while (parser->iterate(parser, &objectID, &object))
553
1.54k
  {
554
1.54k
    if (objectID == GENERAL_NAMES_GN)
555
1.25k
    {
556
1.25k
      gn = parse_generalName(object, parser->get_level(parser)+1);
557
1.25k
      if (!gn)
558
16
      {
559
16
        goto end;
560
16
      }
561
1.24k
      list->insert_last(list, (void *)gn);
562
1.24k
    }
563
1.54k
  }
564
155
  success = parser->success(parser);
565
566
171
end:
567
171
  parser->destroy(parser);
568
569
171
  return success;
570
155
}
571
572
/**
573
 * ASN.1 definition of a authorityKeyIdentifier extension
574
 */
575
static const asn1Object_t authKeyIdentifierObjects[] = {
576
  { 0, "authorityKeyIdentifier",    ASN1_SEQUENCE,    ASN1_NONE     }, /* 0 */
577
  { 1,   "keyIdentifier",       ASN1_CONTEXT_S_0, ASN1_OPT|ASN1_BODY  }, /* 1 */
578
  { 1,   "end opt",         ASN1_EOC,     ASN1_END      }, /* 2 */
579
  { 1,   "authorityCertIssuer",   ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_OBJ }, /* 3 */
580
  { 1,   "end opt",         ASN1_EOC,     ASN1_END      }, /* 4 */
581
  { 1,   "authorityCertSerialNumber", ASN1_CONTEXT_S_2, ASN1_OPT|ASN1_BODY  }, /* 5 */
582
  { 1,   "end opt",         ASN1_EOC,     ASN1_END      }, /* 6 */
583
  { 0, "exit",            ASN1_EOC,     ASN1_EXIT     }
584
};
585
83
#define AUTH_KEY_ID_KEY_ID      1
586
5
#define AUTH_KEY_ID_CERT_ISSUER   3
587
44
#define AUTH_KEY_ID_CERT_SERIAL   5
588
589
/**
590
 * Extracts an authoritykeyIdentifier
591
 */
592
chunk_t x509_parse_authorityKeyIdentifier(chunk_t blob, int level0,
593
                        chunk_t *authKeySerialNumber)
594
486
{
595
486
  asn1_parser_t *parser;
596
486
  chunk_t object;
597
486
  int objectID;
598
486
  chunk_t authKeyIdentifier = chunk_empty;
599
600
486
  *authKeySerialNumber = chunk_empty;
601
602
486
  parser = asn1_parser_create(authKeyIdentifierObjects, blob);
603
486
  parser->set_top_level(parser, level0);
604
605
1.21k
  while (parser->iterate(parser, &objectID, &object))
606
730
  {
607
730
    switch (objectID)
608
730
    {
609
83
      case AUTH_KEY_ID_KEY_ID:
610
83
        authKeyIdentifier = chunk_clone(object);
611
83
        break;
612
5
      case AUTH_KEY_ID_CERT_ISSUER:
613
        /* TODO: x509_parse_generalNames(object, level+1, TRUE); */
614
5
        break;
615
44
      case AUTH_KEY_ID_CERT_SERIAL:
616
44
        *authKeySerialNumber = object;
617
44
        break;
618
598
      default:
619
598
        break;
620
730
    }
621
730
  }
622
486
  parser->destroy(parser);
623
624
486
  return authKeyIdentifier;
625
486
}
626
627
/**
628
 * ASN.1 definition of a authorityInfoAccess extension
629
 */
630
static const asn1Object_t authInfoAccessObjects[] = {
631
  { 0, "authorityInfoAccess", ASN1_SEQUENCE,  ASN1_LOOP }, /* 0 */
632
  { 1,   "accessDescription", ASN1_SEQUENCE,  ASN1_NONE }, /* 1 */
633
  { 2,     "accessMethod",  ASN1_OID,   ASN1_BODY }, /* 2 */
634
  { 2,     "accessLocation",  ASN1_EOC,   ASN1_RAW  }, /* 3 */
635
  { 0, "end loop",      ASN1_EOC,   ASN1_END  }, /* 4 */
636
  { 0, "exit",        ASN1_EOC,   ASN1_EXIT }
637
};
638
0
#define AUTH_INFO_ACCESS_METHOD   2
639
0
#define AUTH_INFO_ACCESS_LOCATION 3
640
641
/**
642
 * Extracts an authorityInfoAcess location
643
 */
644
static bool parse_authorityInfoAccess(chunk_t blob, int level0,
645
                    private_x509_cert_t *this)
646
0
{
647
0
  asn1_parser_t *parser;
648
0
  chunk_t object;
649
0
  int objectID;
650
0
  int accessMethod = OID_UNKNOWN;
651
0
  bool success = FALSE;
652
653
0
  parser = asn1_parser_create(authInfoAccessObjects, blob);
654
0
  parser->set_top_level(parser, level0);
655
656
0
  while (parser->iterate(parser, &objectID, &object))
657
0
  {
658
0
    switch (objectID)
659
0
    {
660
0
      case AUTH_INFO_ACCESS_METHOD:
661
0
        accessMethod = asn1_known_oid(object);
662
0
        break;
663
0
      case AUTH_INFO_ACCESS_LOCATION:
664
0
      {
665
0
        switch (accessMethod)
666
0
        {
667
0
          case OID_OCSP:
668
0
          case OID_CA_ISSUERS:
669
0
            {
670
0
              identification_t *id;
671
0
              char *uri;
672
673
0
              id = parse_generalName(object,
674
0
                      parser->get_level(parser)+1);
675
0
              if (id == NULL)
676
0
              {
677
                /* parsing went wrong - abort */
678
0
                goto end;
679
0
              }
680
0
              DBG2(DBG_ASN, "  '%Y'", id);
681
0
              if (accessMethod == OID_OCSP &&
682
0
                gn_to_string(id, &uri))
683
0
              {
684
0
                this->ocsp_uris->insert_last(this->ocsp_uris, uri);
685
0
              }
686
0
              id->destroy(id);
687
0
            }
688
0
            break;
689
0
          default:
690
            /* unknown accessMethod, ignoring */
691
0
            break;
692
0
        }
693
0
        break;
694
0
      }
695
0
      default:
696
0
        break;
697
0
    }
698
0
  }
699
0
  success = parser->success(parser);
700
701
0
end:
702
0
  parser->destroy(parser);
703
704
0
  return success;
705
0
}
706
707
/**
708
 * Extract KeyUsage flags
709
 */
710
static void parse_keyUsage(chunk_t blob, private_x509_cert_t *this)
711
0
{
712
0
  enum {
713
0
    KU_DIGITAL_SIGNATURE =  0,
714
0
    KU_NON_REPUDIATION =  1,
715
0
    KU_KEY_ENCIPHERMENT = 2,
716
0
    KU_DATA_ENCIPHERMENT =  3,
717
0
    KU_KEY_AGREEMENT =    4,
718
0
    KU_KEY_CERT_SIGN =    5,
719
0
    KU_CRL_SIGN =     6,
720
0
    KU_ENCIPHER_ONLY =    7,
721
0
    KU_DECIPHER_ONLY =    8,
722
0
  };
723
724
0
  if (asn1_unwrap(&blob, &blob) == ASN1_BIT_STRING && blob.len)
725
0
  {
726
0
    int bit, byte, unused = blob.ptr[0];
727
728
0
    blob = chunk_skip(blob, 1);
729
0
    for (byte = 0; byte < blob.len; byte++)
730
0
    {
731
0
      for (bit = 0; bit < 8; bit++)
732
0
      {
733
0
        if (byte == blob.len - 1 && bit > (7 - unused))
734
0
        {
735
0
          break;
736
0
        }
737
0
        if (blob.ptr[byte] & 1 << (7 - bit))
738
0
        {
739
0
          switch (byte * 8 + bit)
740
0
          {
741
0
            case KU_CRL_SIGN:
742
0
              this->flags |= X509_CRL_SIGN;
743
0
              break;
744
0
            case KU_DIGITAL_SIGNATURE:
745
0
            case KU_NON_REPUDIATION:
746
0
              this->flags |= X509_IKE_COMPLIANT;
747
0
              break;
748
0
            case KU_KEY_CERT_SIGN:
749
              /* we use the caBasicConstraint, MUST be set */
750
0
            case KU_KEY_ENCIPHERMENT:
751
0
            case KU_DATA_ENCIPHERMENT:
752
0
            case KU_KEY_AGREEMENT:
753
0
            case KU_ENCIPHER_ONLY:
754
0
            case KU_DECIPHER_ONLY:
755
0
              break;
756
0
          }
757
0
        }
758
0
      }
759
0
    }
760
0
  }
761
0
}
762
763
/**
764
 * ASN.1 definition of a extendedKeyUsage extension
765
 */
766
static const asn1Object_t extendedKeyUsageObjects[] = {
767
  { 0, "extendedKeyUsage",  ASN1_SEQUENCE,  ASN1_LOOP }, /* 0 */
768
  { 1,   "keyPurposeID",    ASN1_OID,   ASN1_BODY }, /* 1 */
769
  { 0, "end loop",      ASN1_EOC,   ASN1_END  }, /* 2 */
770
  { 0, "exit",        ASN1_EOC,   ASN1_EXIT }
771
};
772
0
#define EXT_KEY_USAGE_PURPOSE_ID  1
773
774
/**
775
 * Extracts extendedKeyUsage OIDs (shared with x509_pkcs10.c)
776
 */
777
bool x509_parse_eku_extension(chunk_t blob, int level0, x509_flag_t *flags)
778
0
{
779
0
  asn1_parser_t *parser;
780
0
  chunk_t object;
781
0
  int objectID;
782
0
  bool success;
783
784
0
  parser = asn1_parser_create(extendedKeyUsageObjects, blob);
785
0
  parser->set_top_level(parser, level0);
786
787
0
  while (parser->iterate(parser, &objectID, &object))
788
0
  {
789
0
    if (objectID == EXT_KEY_USAGE_PURPOSE_ID)
790
0
    {
791
0
      switch (asn1_known_oid(object))
792
0
      {
793
0
        case OID_SERVER_AUTH:
794
0
          *flags |= X509_SERVER_AUTH;
795
0
          break;
796
0
        case OID_CLIENT_AUTH:
797
0
          *flags |= X509_CLIENT_AUTH;
798
0
          break;
799
0
        case OID_IKE_INTERMEDIATE:
800
0
          *flags |= X509_IKE_INTERMEDIATE;
801
0
          break;
802
0
        case OID_OCSP_SIGNING:
803
0
          *flags |= X509_OCSP_SIGNER;
804
0
          break;
805
0
        case OID_MS_SMARTCARD_LOGON:
806
0
          *flags |= X509_MS_SMARTCARD_LOGON;
807
0
          break;
808
0
        default:
809
0
          break;
810
0
      }
811
0
    }
812
0
  }
813
0
  success = parser->success(parser);
814
0
  parser->destroy(parser);
815
816
0
  return success;
817
0
}
818
819
/**
820
 * ASN.1 definition of crlDistributionPoints
821
 */
822
static const asn1Object_t crlDistributionPointsObjects[] = {
823
  { 0, "crlDistributionPoints",   ASN1_SEQUENCE,    ASN1_LOOP            }, /*  0 */
824
  { 1,   "DistributionPoint",     ASN1_SEQUENCE,    ASN1_NONE            }, /*  1 */
825
  { 2,     "distributionPoint",   ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_CHOICE }, /*  2 */
826
  { 3,       "fullName",          ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_OBJ    }, /*  3 */
827
  { 3,       "end choice",        ASN1_EOC,         ASN1_END|ASN1_CH     }, /*  4 */
828
  { 3,       "nameRelToCRLIssuer",ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_BODY   }, /*  5 */
829
  { 3,       "end choice",        ASN1_EOC,         ASN1_END|ASN1_CH     }, /*  6 */
830
  { 2,     "end opt/choices",     ASN1_EOC,         ASN1_END|ASN1_CHOICE }, /*  7 */
831
  { 2,     "reasons",             ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_BODY   }, /*  8 */
832
  { 2,     "end opt",             ASN1_EOC,         ASN1_END             }, /*  9 */
833
  { 2,     "crlIssuer",           ASN1_CONTEXT_C_2, ASN1_OPT|ASN1_OBJ    }, /* 10 */
834
  { 2,     "end opt",             ASN1_EOC,         ASN1_END             }, /* 11 */
835
  { 0, "end loop",                ASN1_EOC,         ASN1_END             }, /* 12 */
836
  { 0, "exit",                    ASN1_EOC,         ASN1_EXIT            }
837
};
838
209
#define CRL_DIST_POINTS        1
839
78
#define CRL_DIST_POINTS_FULLNAME   3
840
93
#define CRL_DIST_POINTS_ISSUER    10
841
842
/**
843
 * Add entry to the list of each pairing of URI and Issuer
844
 */
845
static void add_cdps(linked_list_t *list, linked_list_t *uris,
846
           linked_list_t *issuers)
847
340
{
848
340
  identification_t *issuer, *id;
849
340
  enumerator_t *enumerator;
850
340
  x509_cdp_t *cdp;
851
340
  char *uri;
852
853
743
  while (uris->remove_last(uris, (void**)&id) == SUCCESS)
854
403
  {
855
403
    if (gn_to_string(id, &uri))
856
212
    {
857
212
      if (issuers->get_count(issuers))
858
154
      {
859
154
        enumerator = issuers->create_enumerator(issuers);
860
3.29k
        while (enumerator->enumerate(enumerator, &issuer))
861
3.13k
        {
862
3.13k
          INIT(cdp,
863
3.13k
            .uri = strdup(uri),
864
3.13k
            .issuer = issuer->clone(issuer),
865
3.13k
          );
866
3.13k
          list->insert_last(list, cdp);
867
3.13k
        }
868
154
        enumerator->destroy(enumerator);
869
154
        free(uri);
870
154
      }
871
58
      else
872
58
      {
873
58
        INIT(cdp,
874
58
          .uri = uri,
875
58
        );
876
58
        list->insert_last(list, cdp);
877
58
      }
878
212
    }
879
403
    id->destroy(id);
880
403
  }
881
1.00k
  while (issuers->remove_last(issuers, (void**)&id) == SUCCESS)
882
666
  {
883
666
    id->destroy(id);
884
666
  }
885
340
}
886
887
/**
888
 * Extracts one or several crlDistributionPoints into a list
889
 */
890
bool x509_parse_crlDistributionPoints(chunk_t blob, int level0,
891
                    linked_list_t *list)
892
158
{
893
158
  linked_list_t *uris, *issuers;
894
158
  asn1_parser_t *parser;
895
158
  chunk_t object;
896
158
  int objectID;
897
158
  bool success = FALSE;
898
899
158
  uris = linked_list_create();
900
158
  issuers = linked_list_create();
901
158
  parser = asn1_parser_create(crlDistributionPointsObjects, blob);
902
158
  parser->set_top_level(parser, level0);
903
904
1.46k
  while (parser->iterate(parser, &objectID, &object))
905
1.33k
  {
906
1.33k
    switch (objectID)
907
1.33k
    {
908
209
      case CRL_DIST_POINTS:
909
209
        add_cdps(list, uris, issuers);
910
209
        break;
911
78
      case CRL_DIST_POINTS_FULLNAME:
912
78
        if (!x509_parse_generalNames(object,
913
78
                parser->get_level(parser) + 1, TRUE, uris))
914
8
        {
915
8
          goto end;
916
8
        }
917
70
        break;
918
93
      case CRL_DIST_POINTS_ISSUER:
919
93
        if (!x509_parse_generalNames(object,
920
93
                parser->get_level(parser) + 1, TRUE, issuers))
921
19
        {
922
19
          goto end;
923
19
        }
924
74
        break;
925
950
      default:
926
950
        break;
927
1.33k
    }
928
1.33k
  }
929
131
  success = parser->success(parser);
930
131
  add_cdps(list, uris, issuers);
931
932
158
end:
933
158
  parser->destroy(parser);
934
158
  uris->destroy_offset(uris, offsetof(identification_t, destroy));
935
158
  issuers->destroy_offset(issuers, offsetof(identification_t, destroy));
936
937
158
  return success;
938
131
}
939
940
/**
941
 * ASN.1 definition of nameConstraints
942
 */
943
static const asn1Object_t nameConstraintsObjects[] = {
944
  { 0, "nameConstraints",     ASN1_SEQUENCE,    ASN1_NONE     }, /*  0 */
945
  { 1,   "permittedSubtrees",   ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_LOOP  }, /*  1 */
946
  { 2,     "generalSubtree",    ASN1_SEQUENCE,    ASN1_BODY     }, /*  2 */
947
  { 1,   "end loop",        ASN1_EOC,     ASN1_END      }, /*  3 */
948
  { 1,   "excludedSubtrees",    ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_LOOP  }, /*  4 */
949
  { 2,     "generalSubtree",    ASN1_SEQUENCE,    ASN1_BODY     }, /*  5 */
950
  { 1,   "end loop",        ASN1_EOC,     ASN1_END      }, /*  6 */
951
  { 0, "exit",          ASN1_EOC,     ASN1_EXIT     }
952
};
953
0
#define NAME_CONSTRAINT_PERMITTED 2
954
0
#define NAME_CONSTRAINT_EXCLUDED  5
955
956
/**
957
 * Parse permitted/excluded nameConstraints
958
 */
959
static bool parse_nameConstraints(chunk_t blob, int level0,
960
                  private_x509_cert_t *this)
961
0
{
962
0
  asn1_parser_t *parser;
963
0
  identification_t *id;
964
0
  chunk_t object;
965
0
  int objectID;
966
0
  bool success = FALSE;
967
968
0
  parser = asn1_parser_create(nameConstraintsObjects, blob);
969
0
  parser->set_top_level(parser, level0);
970
971
0
  while (parser->iterate(parser, &objectID, &object))
972
0
  {
973
0
    switch (objectID)
974
0
    {
975
0
      case NAME_CONSTRAINT_PERMITTED:
976
0
        id = parse_generalName(object, parser->get_level(parser) + 1);
977
0
        if (!id)
978
0
        {
979
0
          goto end;
980
0
        }
981
0
        this->permitted_names->insert_last(this->permitted_names, id);
982
0
        break;
983
0
      case NAME_CONSTRAINT_EXCLUDED:
984
0
        id = parse_generalName(object, parser->get_level(parser) + 1);
985
0
        if (!id)
986
0
        {
987
0
          goto end;
988
0
        }
989
0
        this->excluded_names->insert_last(this->excluded_names, id);
990
0
        break;
991
0
      default:
992
0
        break;
993
0
    }
994
0
  }
995
0
  success = parser->success(parser);
996
997
0
end:
998
0
  parser->destroy(parser);
999
1000
0
  return success;
1001
0
}
1002
1003
/**
1004
 * ASN.1 definition of a certificatePolicies extension
1005
 */
1006
static const asn1Object_t certificatePoliciesObject[] = {
1007
  { 0, "certificatePolicies",      ASN1_SEQUENCE,  ASN1_LOOP            }, /*  0 */
1008
  { 1,   "policyInformation",      ASN1_SEQUENCE,  ASN1_NONE            }, /*  1 */
1009
  { 2,     "policyId",             ASN1_OID,       ASN1_BODY            }, /*  2 */
1010
  { 2,     "qualifiers",           ASN1_SEQUENCE,  ASN1_OPT|ASN1_LOOP   }, /*  3 */
1011
  { 3,       "qualifierInfo",      ASN1_SEQUENCE,  ASN1_NONE            }, /*  4 */
1012
  { 4,         "qualifierId",      ASN1_OID,       ASN1_BODY            }, /*  5 */
1013
  { 4,         "qualifier",        ASN1_EOC,       ASN1_CHOICE          }, /*  6 */
1014
  { 5,           "cPSuri",         ASN1_IA5STRING, ASN1_OPT|ASN1_BODY   }, /*  7 */
1015
  { 5,           "end choice",     ASN1_EOC,       ASN1_END|ASN1_CH     }, /*  8 */
1016
  { 5,           "userNotice",     ASN1_SEQUENCE,  ASN1_OPT|ASN1_BODY   }, /*  9 */
1017
  { 6,             "explicitText", ASN1_EOC,       ASN1_RAW             }, /* 10 */
1018
  { 5,           "end choice",     ASN1_EOC,       ASN1_END|ASN1_CH     }, /* 11 */
1019
  { 4,         "end choices",      ASN1_EOC,       ASN1_END|ASN1_CHOICE }, /* 12 */
1020
  { 2,     "end opt/loop",         ASN1_EOC,       ASN1_END             }, /* 13 */
1021
  { 0, "end loop",                 ASN1_EOC,       ASN1_END             }, /* 14 */
1022
  { 0, "exit",                     ASN1_EOC,       ASN1_EXIT            }
1023
};
1024
0
#define CERT_POLICY_ID              2
1025
0
#define CERT_POLICY_QUALIFIER_ID    5
1026
0
#define CERT_POLICY_CPS_URI         7
1027
0
#define CERT_POLICY_EXPLICIT_TEXT  10
1028
1029
/**
1030
 * Parse certificatePolicies
1031
 */
1032
static bool parse_certificatePolicies(chunk_t blob, int level0,
1033
                    private_x509_cert_t *this)
1034
0
{
1035
0
  x509_cert_policy_t *policy = NULL;
1036
0
  asn1_parser_t *parser;
1037
0
  chunk_t object;
1038
0
  int objectID, qualifier = OID_UNKNOWN;
1039
0
  bool success;
1040
1041
0
  parser = asn1_parser_create(certificatePoliciesObject, blob);
1042
0
  parser->set_top_level(parser, level0);
1043
1044
0
  while (parser->iterate(parser, &objectID, &object))
1045
0
  {
1046
0
    switch (objectID)
1047
0
    {
1048
0
      case CERT_POLICY_ID:
1049
0
        INIT(policy,
1050
0
          .oid = chunk_clone(object),
1051
0
        );
1052
0
        this->cert_policies->insert_last(this->cert_policies, policy);
1053
0
        break;
1054
0
      case CERT_POLICY_QUALIFIER_ID:
1055
0
        qualifier = asn1_known_oid(object);
1056
0
        break;
1057
0
      case CERT_POLICY_CPS_URI:
1058
0
        if (policy && !policy->cps_uri && object.len &&
1059
0
          qualifier == OID_POLICY_QUALIFIER_CPS &&
1060
0
          chunk_printable(object, NULL, 0))
1061
0
        {
1062
0
          policy->cps_uri = strndup(object.ptr, object.len);
1063
0
        }
1064
0
        break;
1065
0
      case CERT_POLICY_EXPLICIT_TEXT:
1066
        /* TODO */
1067
0
        break;
1068
0
      default:
1069
0
        break;
1070
0
    }
1071
0
  }
1072
0
  success = parser->success(parser);
1073
0
  parser->destroy(parser);
1074
1075
0
  return success;
1076
0
}
1077
1078
/**
1079
 * ASN.1 definition of a policyMappings extension
1080
 */
1081
static const asn1Object_t policyMappingsObjects[] = {
1082
  { 0, "policyMappings",      ASN1_SEQUENCE,  ASN1_LOOP     }, /*  0 */
1083
  { 1,   "policyMapping",     ASN1_SEQUENCE,  ASN1_NONE     }, /*  1 */
1084
  { 2,     "issuerPolicy",    ASN1_OID,   ASN1_BODY     }, /*  2 */
1085
  { 2,     "subjectPolicy",   ASN1_OID,   ASN1_BODY     }, /*  3 */
1086
  { 0, "end loop",        ASN1_EOC,   ASN1_END      }, /*  4 */
1087
  { 0, "exit",          ASN1_EOC,   ASN1_EXIT     }
1088
};
1089
0
#define POLICY_MAPPING      1
1090
0
#define POLICY_MAPPING_ISSUER 2
1091
0
#define POLICY_MAPPING_SUBJECT  3
1092
1093
/**
1094
 * Parse policyMappings
1095
 */
1096
static bool parse_policyMappings(chunk_t blob, int level0,
1097
                 private_x509_cert_t *this)
1098
0
{
1099
0
  x509_policy_mapping_t *map = NULL;
1100
0
  asn1_parser_t *parser;
1101
0
  chunk_t object;
1102
0
  int objectID;
1103
0
  bool success;
1104
1105
0
  parser = asn1_parser_create(policyMappingsObjects, blob);
1106
0
  parser->set_top_level(parser, level0);
1107
1108
0
  while (parser->iterate(parser, &objectID, &object))
1109
0
  {
1110
0
    switch (objectID)
1111
0
    {
1112
0
      case POLICY_MAPPING:
1113
0
        INIT(map);
1114
0
        this->policy_mappings->insert_last(this->policy_mappings, map);
1115
0
        break;
1116
0
      case POLICY_MAPPING_ISSUER:
1117
0
        if (map && !map->issuer.len)
1118
0
        {
1119
0
          map->issuer = chunk_clone(object);
1120
0
        }
1121
0
        break;
1122
0
      case POLICY_MAPPING_SUBJECT:
1123
0
        if (map && !map->subject.len)
1124
0
        {
1125
0
          map->subject = chunk_clone(object);
1126
0
        }
1127
0
        break;
1128
0
      default:
1129
0
        break;
1130
0
    }
1131
0
  }
1132
0
  success = parser->success(parser);
1133
0
  parser->destroy(parser);
1134
1135
0
  return success;
1136
0
}
1137
1138
/**
1139
 * ASN.1 definition of a policyConstraints extension
1140
 */
1141
static const asn1Object_t policyConstraintsObjects[] = {
1142
  { 0, "policyConstraints",   ASN1_SEQUENCE,    ASN1_NONE     }, /*  0 */
1143
  { 1,   "requireExplicitPolicy", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_NONE  }, /*  1 */
1144
  { 2,     "SkipCerts",     ASN1_INTEGER,   ASN1_BODY     }, /*  2 */
1145
  { 1,   "end opt",       ASN1_EOC,     ASN1_END      }, /*  3 */
1146
  { 1,   "inhibitPolicyMapping",  ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_NONE  }, /*  4 */
1147
  { 2,     "SkipCerts",     ASN1_INTEGER,   ASN1_BODY     }, /*  5 */
1148
  { 1,   "end opt",       ASN1_EOC,     ASN1_END      }, /*  6 */
1149
  { 0, "exit",          ASN1_EOC,     ASN1_EXIT     }
1150
};
1151
0
#define POLICY_CONSTRAINT_EXPLICIT 2
1152
0
#define POLICY_CONSTRAINT_INHIBIT  5
1153
1154
/**
1155
 * Parse policyConstraints
1156
 */
1157
static bool parse_policyConstraints(chunk_t blob, int level0,
1158
                  private_x509_cert_t *this)
1159
0
{
1160
0
  asn1_parser_t *parser;
1161
0
  chunk_t object;
1162
0
  int objectID;
1163
0
  bool success;
1164
1165
0
  parser = asn1_parser_create(policyConstraintsObjects, blob);
1166
0
  parser->set_top_level(parser, level0);
1167
1168
0
  while (parser->iterate(parser, &objectID, &object))
1169
0
  {
1170
0
    switch (objectID)
1171
0
    {
1172
0
      case POLICY_CONSTRAINT_EXPLICIT:
1173
0
        this->require_explicit = parse_constraint(object);
1174
0
        break;
1175
0
      case POLICY_CONSTRAINT_INHIBIT:
1176
0
        this->inhibit_mapping = parse_constraint(object);
1177
0
        break;
1178
0
      default:
1179
0
        break;
1180
0
    }
1181
0
  }
1182
0
  success = parser->success(parser);
1183
0
  parser->destroy(parser);
1184
1185
0
  return success;
1186
0
}
1187
1188
/**
1189
 * ASN.1 definition of ipAddrBlocks according to RFC 3779
1190
 */
1191
static const asn1Object_t ipAddrBlocksObjects[] = {
1192
  { 0, "ipAddrBlocks",            ASN1_SEQUENCE,     ASN1_LOOP            }, /*  0 */
1193
  { 1,   "ipAddressFamily",       ASN1_SEQUENCE,     ASN1_NONE            }, /*  1 */
1194
  { 2,     "addressFamily",       ASN1_OCTET_STRING, ASN1_BODY            }, /*  2 */
1195
  { 2,     "ipAddressChoice",     ASN1_EOC,          ASN1_CHOICE          }, /*  3 */
1196
  { 3,       "inherit",           ASN1_NULL,         ASN1_OPT             }, /*  4 */
1197
  { 3,       "end choice",        ASN1_EOC,          ASN1_END|ASN1_CH     }, /*  5 */
1198
  { 3,       "addressesOrRanges", ASN1_SEQUENCE,     ASN1_OPT|ASN1_LOOP   }, /*  6 */
1199
  { 4,         "addressOrRange",  ASN1_EOC,          ASN1_CHOICE          }, /*  7 */
1200
  { 5,           "addressPrefix", ASN1_BIT_STRING,   ASN1_OPT|ASN1_BODY   }, /*  8 */
1201
  { 5,           "end choice",    ASN1_EOC,          ASN1_END|ASN1_CH     }, /*  9 */
1202
  { 5,           "addressRange",  ASN1_SEQUENCE,     ASN1_OPT             }, /* 10 */
1203
  { 6,             "min",         ASN1_BIT_STRING,   ASN1_BODY            }, /* 11 */
1204
  { 6,             "max",         ASN1_BIT_STRING,   ASN1_BODY            }, /* 12 */
1205
  { 5,           "end choice",    ASN1_EOC,          ASN1_END|ASN1_CH     }, /* 13 */
1206
  { 4,         "end choices",     ASN1_EOC,          ASN1_END|ASN1_CHOICE }, /* 14 */
1207
  { 3,       "end loop/choice",   ASN1_EOC,          ASN1_END|ASN1_CH     }, /* 15 */
1208
  { 2,     "end choices",         ASN1_EOC,          ASN1_END|ASN1_CHOICE }, /* 16 */
1209
  { 0, "end loop",                ASN1_EOC,          ASN1_END             }, /* 17 */
1210
  { 0, "exit",                    ASN1_EOC,          ASN1_EXIT            }
1211
};
1212
0
#define IP_ADDR_BLOCKS_FAMILY       2
1213
0
#define IP_ADDR_BLOCKS_INHERIT      4
1214
0
#define IP_ADDR_BLOCKS_PREFIX       8
1215
0
#define IP_ADDR_BLOCKS_MIN         11
1216
0
#define IP_ADDR_BLOCKS_MAX         12
1217
1218
static bool check_address_object(ts_type_t ts_type, chunk_t object)
1219
0
{
1220
0
  switch (ts_type)
1221
0
  {
1222
0
    case TS_IPV4_ADDR_RANGE:
1223
0
      if (object.len > 5)
1224
0
      {
1225
0
        DBG1(DBG_ASN, "IPv4 address object is larger than 5 octets");
1226
0
        return FALSE;
1227
0
      }
1228
0
      break;
1229
0
    case TS_IPV6_ADDR_RANGE:
1230
0
      if (object.len > 17)
1231
0
      {
1232
0
        DBG1(DBG_ASN, "IPv6 address object is larger than 17 octets");
1233
0
        return FALSE;
1234
0
      }
1235
0
      break;
1236
0
    default:
1237
0
      DBG1(DBG_ASN, "unknown address family");
1238
0
      return FALSE;
1239
0
  }
1240
0
  if (object.len == 0)
1241
0
  {
1242
0
    DBG1(DBG_ASN, "An ASN.1 bit string must contain at least the "
1243
0
       "initial octet");
1244
0
    return FALSE;
1245
0
  }
1246
0
  if (object.len == 1 && object.ptr[0] != 0)
1247
0
  {
1248
0
    DBG1(DBG_ASN, "An empty ASN.1 bit string must contain a zero "
1249
0
       "initial octet");
1250
0
    return FALSE;
1251
0
  }
1252
0
  if (object.ptr[0] > 7)
1253
0
  {
1254
0
    DBG1(DBG_ASN, "number of unused bits is too large");
1255
0
    return FALSE;
1256
0
  }
1257
0
  return TRUE;
1258
0
}
1259
1260
static bool parse_ipAddrBlocks(chunk_t blob, int level0,
1261
                 private_x509_cert_t *this)
1262
0
{
1263
0
  asn1_parser_t *parser;
1264
0
  chunk_t object, min_object;
1265
0
  ts_type_t ts_type = 0;
1266
0
  traffic_selector_t *ts;
1267
0
  int objectID;
1268
0
  bool success = FALSE;
1269
1270
0
  parser = asn1_parser_create(ipAddrBlocksObjects, blob);
1271
0
  parser->set_top_level(parser, level0);
1272
1273
0
  while (parser->iterate(parser, &objectID, &object))
1274
0
  {
1275
0
    switch (objectID)
1276
0
    {
1277
0
      case IP_ADDR_BLOCKS_FAMILY:
1278
0
        ts_type = 0;
1279
0
        if (object.len == 2 && object.ptr[0] == 0)
1280
0
        {
1281
0
          if (object.ptr[1] == 1)
1282
0
          {
1283
0
            ts_type = TS_IPV4_ADDR_RANGE;
1284
0
          }
1285
0
          else if (object.ptr[1] == 2)
1286
0
          {
1287
0
            ts_type = TS_IPV6_ADDR_RANGE;
1288
0
          }
1289
0
          else
1290
0
          {
1291
0
            break;
1292
0
          }
1293
0
          DBG2(DBG_ASN, "  %N", ts_type_name, ts_type);
1294
0
        }
1295
0
        break;
1296
0
      case IP_ADDR_BLOCKS_INHERIT:
1297
0
        DBG1(DBG_ASN, "inherit choice is not supported");
1298
0
        break;
1299
0
      case IP_ADDR_BLOCKS_PREFIX:
1300
0
        if (!check_address_object(ts_type, object))
1301
0
        {
1302
0
          goto end;
1303
0
        }
1304
0
        ts = traffic_selector_create_from_rfc3779_format(ts_type,
1305
0
                          object, object);
1306
0
        DBG2(DBG_ASN, "  %R", ts);
1307
0
        this->ipAddrBlocks->insert_last(this->ipAddrBlocks, ts);
1308
0
        break;
1309
0
      case IP_ADDR_BLOCKS_MIN:
1310
0
        if (!check_address_object(ts_type, object))
1311
0
        {
1312
0
          goto end;
1313
0
        }
1314
0
        min_object = object;
1315
0
        break;
1316
0
      case IP_ADDR_BLOCKS_MAX:
1317
0
        if (!check_address_object(ts_type, object))
1318
0
        {
1319
0
          goto end;
1320
0
        }
1321
0
        ts = traffic_selector_create_from_rfc3779_format(ts_type,
1322
0
                          min_object, object);
1323
0
        DBG2(DBG_ASN, "  %R", ts);
1324
0
        this->ipAddrBlocks->insert_last(this->ipAddrBlocks, ts);
1325
0
        break;
1326
0
      default:
1327
0
        break;
1328
0
    }
1329
0
  }
1330
0
  success = parser->success(parser);
1331
0
  this->flags |= X509_IP_ADDR_BLOCKS;
1332
1333
0
end:
1334
0
  parser->destroy(parser);
1335
1336
0
  return success;
1337
0
}
1338
1339
/**
1340
 * ASN.1 definition of an X.509v3 x509_cert
1341
 */
1342
static const asn1Object_t certObjects[] = {
1343
  { 0, "x509",          ASN1_SEQUENCE,    ASN1_OBJ      }, /*  0 */
1344
  { 1,   "tbsCertificate",    ASN1_SEQUENCE,    ASN1_OBJ      }, /*  1 */
1345
  { 2,     "DEFAULT v1",      ASN1_CONTEXT_C_0, ASN1_DEF      }, /*  2 */
1346
  { 3,       "version",     ASN1_INTEGER,   ASN1_BODY     }, /*  3 */
1347
  { 2,     "serialNumber",    ASN1_INTEGER,   ASN1_BODY     }, /*  4 */
1348
  { 2,     "signature",     ASN1_EOC,     ASN1_RAW      }, /*  5 */
1349
  { 2,     "issuer",        ASN1_SEQUENCE,    ASN1_OBJ      }, /*  6 */
1350
  { 2,     "validity",      ASN1_SEQUENCE,    ASN1_NONE     }, /*  7 */
1351
  { 3,       "notBefore",     ASN1_EOC,     ASN1_RAW      }, /*  8 */
1352
  { 3,       "notAfter",      ASN1_EOC,     ASN1_RAW      }, /*  9 */
1353
  { 2,     "subject",       ASN1_SEQUENCE,    ASN1_OBJ      }, /* 10 */
1354
  { 2,     "subjectPublicKeyInfo",ASN1_SEQUENCE,    ASN1_RAW      }, /* 11 */
1355
  { 2,     "issuerUniqueID",    ASN1_CONTEXT_C_1, ASN1_OPT      }, /* 12 */
1356
  { 2,     "end opt",       ASN1_EOC,     ASN1_END      }, /* 13 */
1357
  { 2,     "subjectUniqueID",   ASN1_CONTEXT_C_2, ASN1_OPT      }, /* 14 */
1358
  { 2,     "end opt",       ASN1_EOC,     ASN1_END      }, /* 15 */
1359
  { 2,     "optional extensions", ASN1_CONTEXT_C_3, ASN1_OPT      }, /* 16 */
1360
  { 3,       "extensions",    ASN1_SEQUENCE,    ASN1_LOOP     }, /* 17 */
1361
  { 4,         "extension",   ASN1_SEQUENCE,    ASN1_NONE     }, /* 18 */
1362
  { 5,           "extnID",    ASN1_OID,     ASN1_BODY     }, /* 19 */
1363
  { 5,           "critical",    ASN1_BOOLEAN,   ASN1_DEF|ASN1_BODY  }, /* 20 */
1364
  { 5,           "extnValue",   ASN1_OCTET_STRING,  ASN1_BODY     }, /* 21 */
1365
  { 3,       "end loop",      ASN1_EOC,     ASN1_END      }, /* 22 */
1366
  { 2,     "end opt",       ASN1_EOC,     ASN1_END      }, /* 23 */
1367
  { 1,   "signatureAlgorithm",  ASN1_EOC,     ASN1_RAW      }, /* 24 */
1368
  { 1,   "signatureValue",    ASN1_BIT_STRING,  ASN1_BODY     }, /* 25 */
1369
  { 0, "exit",          ASN1_EOC,     ASN1_EXIT     }
1370
};
1371
0
#define X509_OBJ_TBS_CERTIFICATE         1
1372
0
#define X509_OBJ_VERSION             3
1373
0
#define X509_OBJ_SERIAL_NUMBER           4
1374
0
#define X509_OBJ_SIG_ALG             5
1375
0
#define X509_OBJ_ISSUER              6
1376
0
#define X509_OBJ_NOT_BEFORE            8
1377
0
#define X509_OBJ_NOT_AFTER             9
1378
0
#define X509_OBJ_SUBJECT            10
1379
0
#define X509_OBJ_SUBJECT_PUBLIC_KEY_INFO    11
1380
0
#define X509_OBJ_OPTIONAL_EXTENSIONS      16
1381
0
#define X509_OBJ_EXTN_ID            19
1382
0
#define X509_OBJ_CRITICAL           20
1383
0
#define X509_OBJ_EXTN_VALUE           21
1384
0
#define X509_OBJ_ALGORITHM            24
1385
0
#define X509_OBJ_SIGNATURE            25
1386
1387
/**
1388
 * Parses an X.509v3 certificate
1389
 */
1390
static bool parse_certificate(private_x509_cert_t *this)
1391
0
{
1392
0
  asn1_parser_t *parser;
1393
0
  chunk_t object;
1394
0
  int objectID;
1395
0
  int extn_oid = OID_UNKNOWN;
1396
0
  signature_params_t sig_alg = {};
1397
0
  bool critical = FALSE, key_usage_parsed = FALSE;
1398
0
  bool success = FALSE;
1399
1400
0
  parser = asn1_parser_create(certObjects, this->encoding);
1401
1402
0
  while (parser->iterate(parser, &objectID, &object))
1403
0
  {
1404
0
    u_int level = parser->get_level(parser)+1;
1405
1406
0
    switch (objectID)
1407
0
    {
1408
0
      case X509_OBJ_TBS_CERTIFICATE:
1409
0
        this->tbsCertificate = object;
1410
0
        break;
1411
0
      case X509_OBJ_VERSION:
1412
0
        this->version = (object.len) ? (1+(u_int)*object.ptr) : 1;
1413
0
        if (this->version < 1 || this->version > 3)
1414
0
        {
1415
0
          DBG1(DBG_ASN, "X.509v%d not supported", this->version);
1416
0
          goto end;
1417
0
        }
1418
0
        else
1419
0
        {
1420
0
          DBG2(DBG_ASN, "  X.509v%d", this->version);
1421
0
        }
1422
0
        break;
1423
0
      case X509_OBJ_SERIAL_NUMBER:
1424
0
        this->serialNumber = object;
1425
0
        break;
1426
0
      case X509_OBJ_SIG_ALG:
1427
0
        if (!signature_params_parse(object, level, &sig_alg))
1428
0
        {
1429
0
          DBG1(DBG_ASN, "  unable to parse signature algorithm");
1430
0
          goto end;
1431
0
        }
1432
0
        break;
1433
0
      case X509_OBJ_ISSUER:
1434
0
        this->issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object);
1435
0
        DBG2(DBG_ASN, "  '%Y'", this->issuer);
1436
0
        break;
1437
0
      case X509_OBJ_NOT_BEFORE:
1438
0
        this->notBefore = asn1_parse_time(object, level);
1439
0
        break;
1440
0
      case X509_OBJ_NOT_AFTER:
1441
0
        this->notAfter = asn1_parse_time(object, level);
1442
0
        break;
1443
0
      case X509_OBJ_SUBJECT:
1444
0
        this->subject = identification_create_from_encoding(ID_DER_ASN1_DN, object);
1445
0
        DBG2(DBG_ASN, "  '%Y'", this->subject);
1446
0
        break;
1447
0
      case X509_OBJ_SUBJECT_PUBLIC_KEY_INFO:
1448
0
        DBG2(DBG_ASN, "-- > --");
1449
0
        this->public_key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY,
1450
0
            KEY_ANY, BUILD_BLOB_ASN1_DER, object, BUILD_END);
1451
0
        DBG2(DBG_ASN, "-- < --");
1452
0
        if (this->public_key == NULL)
1453
0
        {
1454
0
          goto end;
1455
0
        }
1456
0
        break;
1457
0
      case X509_OBJ_OPTIONAL_EXTENSIONS:
1458
0
        if (this->version != 3)
1459
0
        {
1460
0
          DBG1(DBG_ASN, "Only X.509v3 certificates have extensions");
1461
0
          goto end;
1462
0
        }
1463
0
        break;
1464
0
      case X509_OBJ_EXTN_ID:
1465
0
        extn_oid = asn1_known_oid(object);
1466
0
        break;
1467
0
      case X509_OBJ_CRITICAL:
1468
0
        critical = object.len && *object.ptr;
1469
0
        DBG2(DBG_ASN, "  %s", critical ? "TRUE" : "FALSE");
1470
0
        break;
1471
0
      case X509_OBJ_EXTN_VALUE:
1472
0
      {
1473
0
        switch (extn_oid)
1474
0
        {
1475
0
          case OID_SUBJECT_KEY_ID:
1476
0
            if (!asn1_parse_simple_object(&object, ASN1_OCTET_STRING,
1477
0
                            level, "keyIdentifier"))
1478
0
            {
1479
0
              goto end;
1480
0
            }
1481
0
            this->subjectKeyIdentifier = object;
1482
0
            break;
1483
0
          case OID_SUBJECT_ALT_NAME:
1484
0
            if (!x509_parse_generalNames(object, level, FALSE,
1485
0
                           this->subjectAltNames))
1486
0
            {
1487
0
              goto end;
1488
0
            }
1489
0
            break;
1490
0
          case OID_BASIC_CONSTRAINTS:
1491
0
            if (!parse_basicConstraints(object, level, this))
1492
0
            {
1493
0
              goto end;
1494
0
            }
1495
0
            break;
1496
0
          case OID_CRL_DISTRIBUTION_POINTS:
1497
0
            if (!x509_parse_crlDistributionPoints(object, level,
1498
0
                                this->crl_uris))
1499
0
            {
1500
0
              goto end;
1501
0
            }
1502
0
            break;
1503
0
          case OID_AUTHORITY_KEY_ID:
1504
0
            chunk_free(&this->authKeyIdentifier);
1505
0
            this->authKeyIdentifier = x509_parse_authorityKeyIdentifier(
1506
0
                  object, level, &this->authKeySerialNumber);
1507
0
            break;
1508
0
          case OID_AUTHORITY_INFO_ACCESS:
1509
0
            if (!parse_authorityInfoAccess(object, level, this))
1510
0
            {
1511
0
              goto end;
1512
0
            }
1513
0
            break;
1514
0
          case OID_KEY_USAGE:
1515
0
            parse_keyUsage(object, this);
1516
0
            key_usage_parsed = TRUE;
1517
0
            break;
1518
0
          case OID_EXTENDED_KEY_USAGE:
1519
0
            if (!x509_parse_eku_extension(object, level, &this->flags))
1520
0
            {
1521
0
              goto end;
1522
0
            }
1523
0
            break;
1524
0
          case OID_IP_ADDR_BLOCKS:
1525
0
            if (!parse_ipAddrBlocks(object, level, this))
1526
0
            {
1527
0
              goto end;
1528
0
            }
1529
0
            break;
1530
0
          case OID_NAME_CONSTRAINTS:
1531
0
            if (!parse_nameConstraints(object, level, this))
1532
0
            {
1533
0
              goto end;
1534
0
            }
1535
0
            break;
1536
0
          case OID_CERTIFICATE_POLICIES:
1537
0
            if (!parse_certificatePolicies(object, level, this))
1538
0
            {
1539
0
              goto end;
1540
0
            }
1541
0
            break;
1542
0
          case OID_POLICY_MAPPINGS:
1543
0
            if (!parse_policyMappings(object, level, this))
1544
0
            {
1545
0
              goto end;
1546
0
            }
1547
0
            break;
1548
0
          case OID_POLICY_CONSTRAINTS:
1549
0
            if (!parse_policyConstraints(object, level, this))
1550
0
            {
1551
0
              goto end;
1552
0
            }
1553
0
            break;
1554
0
          case OID_INHIBIT_ANY_POLICY:
1555
0
            if (!asn1_parse_simple_object(&object, ASN1_INTEGER,
1556
0
                            level, "inhibitAnyPolicy"))
1557
0
            {
1558
0
              goto end;
1559
0
            }
1560
0
            this->inhibit_any = parse_constraint(object);
1561
0
            break;
1562
0
          case OID_NS_REVOCATION_URL:
1563
0
          case OID_NS_CA_REVOCATION_URL:
1564
0
          case OID_NS_CA_POLICY_URL:
1565
0
          case OID_NS_COMMENT:
1566
0
            if (!asn1_parse_simple_object(&object, ASN1_IA5STRING,
1567
0
                      level, oid_names[extn_oid].name))
1568
0
            {
1569
0
              goto end;
1570
0
            }
1571
0
            break;
1572
0
          default:
1573
0
            if (critical && lib->settings->get_bool(lib->settings,
1574
0
              "%s.x509.enforce_critical", TRUE, lib->ns))
1575
0
            {
1576
0
              DBG1(DBG_ASN, "critical '%s' extension not supported",
1577
0
                 (extn_oid == OID_UNKNOWN) ? "unknown" :
1578
0
                 (char*)oid_names[extn_oid].name);
1579
0
              goto end;
1580
0
            }
1581
0
            break;
1582
0
        }
1583
0
        break;
1584
0
      }
1585
0
      case X509_OBJ_ALGORITHM:
1586
0
        INIT(this->scheme);
1587
0
        if (!signature_params_parse(object, level, this->scheme))
1588
0
        {
1589
0
          DBG1(DBG_ASN, "  unable to parse signature algorithm");
1590
0
          goto end;
1591
0
        }
1592
0
        if (!signature_params_equal(this->scheme, &sig_alg))
1593
0
        {
1594
0
          DBG1(DBG_ASN, "  signature algorithms do not agree");
1595
0
          goto end;
1596
0
        }
1597
0
        break;
1598
0
      case X509_OBJ_SIGNATURE:
1599
0
        this->signature = chunk_skip(object, 1);
1600
0
        break;
1601
0
      default:
1602
0
        break;
1603
0
    }
1604
0
  }
1605
0
  success = parser->success(parser);
1606
1607
0
end:
1608
0
  parser->destroy(parser);
1609
0
  signature_params_clear(&sig_alg);
1610
0
  if (success)
1611
0
  {
1612
0
    hasher_t *hasher;
1613
1614
0
    if (!key_usage_parsed)
1615
0
    {
1616
      /* we are compliant with RFC 4945 without keyUsage extension */
1617
0
      this->flags |= X509_IKE_COMPLIANT;
1618
      /* allow CA certificates without keyUsage extension to sign CRLs */
1619
0
      if (this->flags & X509_CA)
1620
0
      {
1621
0
        this->flags |= X509_CRL_SIGN;
1622
0
      }
1623
0
    }
1624
1625
    /* check if the certificate is self-signed */
1626
0
    if (this->public.interface.interface.issued_by(
1627
0
                      &this->public.interface.interface,
1628
0
                      &this->public.interface.interface,
1629
0
                      NULL))
1630
0
    {
1631
0
      this->flags |= X509_SELF_SIGNED;
1632
0
    }
1633
    /* create certificate hash */
1634
0
    hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
1635
0
    if (!hasher ||
1636
0
      !hasher->allocate_hash(hasher, this->encoding, &this->encoding_hash))
1637
0
    {
1638
0
      DESTROY_IF(hasher);
1639
0
      DBG1(DBG_ASN, "  unable to create hash of certificate, SHA1 not supported");
1640
0
      return FALSE;
1641
0
    }
1642
0
    hasher->destroy(hasher);
1643
0
  }
1644
0
  return success;
1645
0
}
1646
1647
METHOD(certificate_t, get_type, certificate_type_t,
1648
  private_x509_cert_t *this)
1649
0
{
1650
0
  return CERT_X509;
1651
0
}
1652
1653
METHOD(certificate_t, get_subject, identification_t*,
1654
  private_x509_cert_t *this)
1655
0
{
1656
0
  return this->subject;
1657
0
}
1658
1659
METHOD(certificate_t, get_issuer, identification_t*,
1660
  private_x509_cert_t *this)
1661
0
{
1662
0
  return this->issuer;
1663
0
}
1664
1665
METHOD(certificate_t, has_subject, id_match_t,
1666
  private_x509_cert_t *this, identification_t *subject)
1667
0
{
1668
0
  identification_t *current;
1669
0
  enumerator_t *enumerator;
1670
0
  id_match_t match, best;
1671
0
  chunk_t encoding;
1672
1673
0
  if (subject->get_type(subject) == ID_KEY_ID)
1674
0
  {
1675
0
    encoding = subject->get_encoding(subject);
1676
1677
0
    if (this->encoding_hash.len &&
1678
0
      chunk_equals(this->encoding_hash, encoding))
1679
0
    {
1680
0
      return ID_MATCH_PERFECT;
1681
0
    }
1682
0
    if (this->subjectKeyIdentifier.len &&
1683
0
      chunk_equals(this->subjectKeyIdentifier, encoding))
1684
0
    {
1685
0
      return ID_MATCH_PERFECT;
1686
0
    }
1687
0
    if (this->public_key &&
1688
0
      this->public_key->has_fingerprint(this->public_key, encoding))
1689
0
    {
1690
0
      return ID_MATCH_PERFECT;
1691
0
    }
1692
0
    if (chunk_equals(this->serialNumber, encoding))
1693
0
    {
1694
0
      return ID_MATCH_PERFECT;
1695
0
    }
1696
0
  }
1697
0
  best = this->subject->matches(this->subject, subject);
1698
0
  enumerator = this->subjectAltNames->create_enumerator(this->subjectAltNames);
1699
0
  while (enumerator->enumerate(enumerator, &current))
1700
0
  {
1701
0
    match = current->matches(current, subject);
1702
0
    if (match > best)
1703
0
    {
1704
0
      best = match;
1705
0
    }
1706
0
  }
1707
0
  enumerator->destroy(enumerator);
1708
0
  return best;
1709
0
}
1710
1711
METHOD(certificate_t, has_issuer, id_match_t,
1712
  private_x509_cert_t *this, identification_t *issuer)
1713
0
{
1714
  /* issuerAltNames currently not supported */
1715
0
  return this->issuer->matches(this->issuer, issuer);
1716
0
}
1717
1718
METHOD(certificate_t, issued_by, bool,
1719
  private_x509_cert_t *this, certificate_t *issuer,
1720
  signature_params_t **scheme)
1721
0
{
1722
0
  public_key_t *key;
1723
0
  bool valid;
1724
0
  x509_t *x509 = (x509_t*)issuer;
1725
0
  chunk_t keyid = chunk_empty;
1726
1727
0
  if (&this->public.interface.interface == issuer)
1728
0
  {
1729
0
    if (this->flags & X509_SELF_SIGNED)
1730
0
    {
1731
0
      if (scheme)
1732
0
      {
1733
0
        *scheme = signature_params_clone(this->scheme);
1734
0
      }
1735
0
      return TRUE;
1736
0
    }
1737
0
  }
1738
0
  else
1739
0
  {
1740
0
    if (issuer->get_type(issuer) != CERT_X509)
1741
0
    {
1742
0
      return FALSE;
1743
0
    }
1744
0
    if (!(x509->get_flags(x509) & X509_CA))
1745
0
    {
1746
0
      return FALSE;
1747
0
    }
1748
0
  }
1749
1750
  /* compare keyIdentifiers if available, otherwise use DNs */
1751
0
  if (this->authKeyIdentifier.ptr)
1752
0
  {
1753
0
    keyid = x509->get_subjectKeyIdentifier(x509);
1754
0
    if (keyid.len && !chunk_equals(keyid, this->authKeyIdentifier))
1755
0
    {
1756
0
      return FALSE;
1757
0
    }
1758
0
  }
1759
0
  if (!keyid.len)
1760
0
  {
1761
0
    if (!this->issuer->equals(this->issuer, issuer->get_subject(issuer)))
1762
0
    {
1763
0
      return FALSE;
1764
0
    }
1765
0
  }
1766
1767
  /* get the public key of the issuer */
1768
0
  key = issuer->get_public_key(issuer);
1769
0
  if (!key)
1770
0
  {
1771
0
    return FALSE;
1772
0
  }
1773
0
  valid = key->verify(key, this->scheme->scheme, this->scheme->params,
1774
0
            this->tbsCertificate, this->signature);
1775
0
  key->destroy(key);
1776
0
  if (valid && scheme)
1777
0
  {
1778
0
    *scheme = signature_params_clone(this->scheme);
1779
0
  }
1780
0
  return valid;
1781
0
}
1782
1783
METHOD(certificate_t, get_public_key, public_key_t*,
1784
  private_x509_cert_t *this)
1785
0
{
1786
0
  this->public_key->get_ref(this->public_key);
1787
0
  return this->public_key;
1788
0
}
1789
1790
METHOD(certificate_t, get_ref, certificate_t*,
1791
  private_x509_cert_t *this)
1792
0
{
1793
0
  ref_get(&this->ref);
1794
0
  return &this->public.interface.interface;
1795
0
}
1796
1797
METHOD(certificate_t, get_validity, bool,
1798
  private_x509_cert_t *this, time_t *when, time_t *not_before,
1799
  time_t *not_after)
1800
0
{
1801
0
  time_t t = when ? *when : time(NULL);
1802
1803
0
  if (not_before)
1804
0
  {
1805
0
    *not_before = this->notBefore;
1806
0
  }
1807
0
  if (not_after)
1808
0
  {
1809
0
    *not_after = this->notAfter;
1810
0
  }
1811
0
  return (t >= this->notBefore && t <= this->notAfter);
1812
0
}
1813
1814
METHOD(certificate_t, get_encoding, bool,
1815
  private_x509_cert_t *this, cred_encoding_type_t type, chunk_t *encoding)
1816
0
{
1817
0
  if (type == CERT_ASN1_DER)
1818
0
  {
1819
0
    *encoding = chunk_clone(this->encoding);
1820
0
    return TRUE;
1821
0
  }
1822
0
  return lib->encoding->encode(lib->encoding, type, NULL, encoding,
1823
0
            CRED_PART_X509_ASN1_DER, this->encoding, CRED_PART_END);
1824
0
}
1825
1826
METHOD(certificate_t, equals, bool,
1827
  private_x509_cert_t *this, certificate_t *other)
1828
0
{
1829
0
  chunk_t encoding;
1830
0
  bool equal;
1831
1832
0
  if (this == (private_x509_cert_t*)other)
1833
0
  {
1834
0
    return TRUE;
1835
0
  }
1836
0
  if (other->get_type(other) != CERT_X509)
1837
0
  {
1838
0
    return FALSE;
1839
0
  }
1840
0
  if (other->equals == (void*)equals)
1841
0
  { /* skip allocation if we have the same implementation */
1842
0
    return chunk_equals(this->encoding, ((private_x509_cert_t*)other)->encoding);
1843
0
  }
1844
0
  if (!other->get_encoding(other, CERT_ASN1_DER, &encoding))
1845
0
  {
1846
0
    return FALSE;
1847
0
  }
1848
0
  equal = chunk_equals(this->encoding, encoding);
1849
0
  free(encoding.ptr);
1850
0
  return equal;
1851
0
}
1852
1853
METHOD(x509_t, get_flags, x509_flag_t,
1854
  private_x509_cert_t *this)
1855
0
{
1856
0
  return this->flags;
1857
0
}
1858
1859
METHOD(x509_t, get_serial, chunk_t,
1860
  private_x509_cert_t *this)
1861
0
{
1862
0
  return chunk_skip_zero(this->serialNumber);
1863
0
}
1864
1865
METHOD(x509_t, get_subjectKeyIdentifier, chunk_t,
1866
  private_x509_cert_t *this)
1867
0
{
1868
0
  if (this->subjectKeyIdentifier.ptr)
1869
0
  {
1870
0
    return this->subjectKeyIdentifier;
1871
0
  }
1872
0
  else
1873
0
  {
1874
0
    chunk_t fingerprint;
1875
1876
0
    if (this->public_key->get_fingerprint(this->public_key,
1877
0
                  KEYID_PUBKEY_SHA1, &fingerprint))
1878
0
    {
1879
0
      return fingerprint;
1880
0
    }
1881
0
    else
1882
0
    {
1883
0
      return chunk_empty;
1884
0
    }
1885
0
  }
1886
0
}
1887
1888
METHOD(x509_t, get_authKeyIdentifier, chunk_t,
1889
  private_x509_cert_t *this)
1890
0
{
1891
0
  return this->authKeyIdentifier;
1892
0
}
1893
1894
METHOD(x509_t, get_constraint, u_int,
1895
  private_x509_cert_t *this, x509_constraint_t type)
1896
0
{
1897
0
  switch (type)
1898
0
  {
1899
0
    case X509_PATH_LEN:
1900
0
      return this->pathLenConstraint;
1901
0
    case X509_REQUIRE_EXPLICIT_POLICY:
1902
0
      return this->require_explicit;
1903
0
    case X509_INHIBIT_POLICY_MAPPING:
1904
0
      return this->inhibit_mapping;
1905
0
    case X509_INHIBIT_ANY_POLICY:
1906
0
      return this->inhibit_any;
1907
0
    default:
1908
0
      return X509_NO_CONSTRAINT;
1909
0
  }
1910
0
}
1911
1912
METHOD(x509_t, create_subjectAltName_enumerator, enumerator_t*,
1913
  private_x509_cert_t *this)
1914
0
{
1915
0
  return this->subjectAltNames->create_enumerator(this->subjectAltNames);
1916
0
}
1917
1918
METHOD(x509_t, create_ocsp_uri_enumerator, enumerator_t*,
1919
  private_x509_cert_t *this)
1920
0
{
1921
0
  return this->ocsp_uris->create_enumerator(this->ocsp_uris);
1922
0
}
1923
1924
METHOD(x509_t, create_crl_uri_enumerator, enumerator_t*,
1925
  private_x509_cert_t *this)
1926
0
{
1927
0
  return this->crl_uris->create_enumerator(this->crl_uris);
1928
0
}
1929
1930
METHOD(x509_t, create_ipAddrBlock_enumerator, enumerator_t*,
1931
  private_x509_cert_t *this)
1932
0
{
1933
0
  return this->ipAddrBlocks->create_enumerator(this->ipAddrBlocks);
1934
0
}
1935
1936
METHOD(x509_t, create_name_constraint_enumerator, enumerator_t*,
1937
  private_x509_cert_t *this, bool perm)
1938
0
{
1939
0
  if (perm)
1940
0
  {
1941
0
    return this->permitted_names->create_enumerator(this->permitted_names);
1942
0
  }
1943
0
  return this->excluded_names->create_enumerator(this->excluded_names);
1944
0
}
1945
1946
METHOD(x509_t, create_cert_policy_enumerator, enumerator_t*,
1947
  private_x509_cert_t *this)
1948
0
{
1949
0
  return this->cert_policies->create_enumerator(this->cert_policies);
1950
0
}
1951
1952
METHOD(x509_t, create_policy_mapping_enumerator, enumerator_t*,
1953
  private_x509_cert_t *this)
1954
0
{
1955
0
  return this->policy_mappings->create_enumerator(this->policy_mappings);
1956
0
}
1957
1958
METHOD(certificate_t, destroy, void,
1959
  private_x509_cert_t *this)
1960
0
{
1961
0
  if (ref_put(&this->ref))
1962
0
  {
1963
0
    this->subjectAltNames->destroy_offset(this->subjectAltNames,
1964
0
                  offsetof(identification_t, destroy));
1965
0
    this->crl_uris->destroy_function(this->crl_uris,
1966
0
                     (void*)x509_cdp_destroy);
1967
0
    this->ocsp_uris->destroy_function(this->ocsp_uris, free);
1968
0
    this->ipAddrBlocks->destroy_offset(this->ipAddrBlocks,
1969
0
                    offsetof(traffic_selector_t, destroy));
1970
0
    this->permitted_names->destroy_offset(this->permitted_names,
1971
0
                    offsetof(identification_t, destroy));
1972
0
    this->excluded_names->destroy_offset(this->excluded_names,
1973
0
                    offsetof(identification_t, destroy));
1974
0
    this->cert_policies->destroy_function(this->cert_policies,
1975
0
                        (void*)cert_policy_destroy);
1976
0
    this->policy_mappings->destroy_function(this->policy_mappings,
1977
0
                        (void*)policy_mapping_destroy);
1978
0
    signature_params_destroy(this->scheme);
1979
0
    DESTROY_IF(this->issuer);
1980
0
    DESTROY_IF(this->subject);
1981
0
    DESTROY_IF(this->public_key);
1982
0
    chunk_free(&this->authKeyIdentifier);
1983
0
    chunk_free(&this->encoding);
1984
0
    chunk_free(&this->encoding_hash);
1985
0
    chunk_free(&this->critical_extension_oid);
1986
0
    if (!this->parsed)
1987
0
    { /* only parsed certificates point these fields to "encoded" */
1988
0
      chunk_free(&this->signature);
1989
0
      chunk_free(&this->serialNumber);
1990
0
      chunk_free(&this->tbsCertificate);
1991
0
    }
1992
0
    free(this);
1993
0
  }
1994
0
}
1995
1996
/**
1997
 * create an empty but initialized X.509 certificate
1998
 */
1999
static private_x509_cert_t* create_empty(void)
2000
0
{
2001
0
  private_x509_cert_t *this;
2002
2003
0
  INIT(this,
2004
0
    .public = {
2005
0
      .interface = {
2006
0
        .interface = {
2007
0
          .get_type = _get_type,
2008
0
          .get_subject = _get_subject,
2009
0
          .get_issuer = _get_issuer,
2010
0
          .has_subject = _has_subject,
2011
0
          .has_issuer = _has_issuer,
2012
0
          .issued_by = _issued_by,
2013
0
          .get_public_key = _get_public_key,
2014
0
          .get_validity = _get_validity,
2015
0
          .get_encoding = _get_encoding,
2016
0
          .equals = _equals,
2017
0
          .get_ref = _get_ref,
2018
0
          .destroy = _destroy,
2019
0
        },
2020
0
        .get_flags = _get_flags,
2021
0
        .get_serial = _get_serial,
2022
0
        .get_subjectKeyIdentifier = _get_subjectKeyIdentifier,
2023
0
        .get_authKeyIdentifier = _get_authKeyIdentifier,
2024
0
        .get_constraint = _get_constraint,
2025
0
        .create_subjectAltName_enumerator = _create_subjectAltName_enumerator,
2026
0
        .create_crl_uri_enumerator = _create_crl_uri_enumerator,
2027
0
        .create_ocsp_uri_enumerator = _create_ocsp_uri_enumerator,
2028
0
        .create_ipAddrBlock_enumerator = _create_ipAddrBlock_enumerator,
2029
0
        .create_name_constraint_enumerator = _create_name_constraint_enumerator,
2030
0
        .create_cert_policy_enumerator = _create_cert_policy_enumerator,
2031
0
        .create_policy_mapping_enumerator = _create_policy_mapping_enumerator,
2032
0
      },
2033
0
    },
2034
0
    .version = 1,
2035
0
    .subjectAltNames = linked_list_create(),
2036
0
    .crl_uris = linked_list_create(),
2037
0
    .ocsp_uris = linked_list_create(),
2038
0
    .ipAddrBlocks = linked_list_create(),
2039
0
    .permitted_names = linked_list_create(),
2040
0
    .excluded_names = linked_list_create(),
2041
0
    .cert_policies = linked_list_create(),
2042
0
    .policy_mappings = linked_list_create(),
2043
0
    .pathLenConstraint = X509_NO_CONSTRAINT,
2044
0
    .require_explicit = X509_NO_CONSTRAINT,
2045
0
    .inhibit_mapping = X509_NO_CONSTRAINT,
2046
0
    .inhibit_any = X509_NO_CONSTRAINT,
2047
0
    .ref = 1,
2048
0
  );
2049
0
  return this;
2050
0
}
2051
2052
/**
2053
 * Build a generalName from an id
2054
 */
2055
static chunk_t build_generalName(identification_t *id)
2056
0
{
2057
0
  int context;
2058
2059
0
  switch (id->get_type(id))
2060
0
  {
2061
0
    case ID_DER_ASN1_GN:
2062
0
      return chunk_clone(id->get_encoding(id));
2063
0
    case ID_RFC822_ADDR:
2064
0
      context = ASN1_CONTEXT_S_1;
2065
0
      break;
2066
0
    case ID_FQDN:
2067
0
      context = ASN1_CONTEXT_S_2;
2068
0
      break;
2069
0
    case ID_DER_ASN1_DN:
2070
0
      context = ASN1_CONTEXT_C_4;
2071
0
      break;
2072
0
    case ID_DER_ASN1_GN_URI:
2073
0
      context = ASN1_CONTEXT_S_6;
2074
0
      break;
2075
0
    case ID_IPV4_ADDR:
2076
0
    case ID_IPV6_ADDR:
2077
0
    case ID_IPV4_ADDR_SUBNET:
2078
0
    case ID_IPV6_ADDR_SUBNET:
2079
0
      context = ASN1_CONTEXT_S_7;
2080
0
      break;
2081
0
    default:
2082
0
      DBG1(DBG_ASN, "encoding %N as generalName not supported",
2083
0
         id_type_names, id->get_type(id));
2084
0
      return chunk_empty;
2085
0
  }
2086
0
  return asn1_wrap(context, "c", id->get_encoding(id));
2087
0
}
2088
2089
/**
2090
 * Encode a linked list of subjectAltNames
2091
 */
2092
chunk_t x509_build_subjectAltNames(linked_list_t *list)
2093
0
{
2094
0
  chunk_t subjectAltNames = chunk_empty, name;
2095
0
  enumerator_t *enumerator;
2096
0
  identification_t *id;
2097
2098
0
  if (list->get_count(list) == 0)
2099
0
  {
2100
0
    return chunk_empty;
2101
0
  }
2102
2103
0
  enumerator = list->create_enumerator(list);
2104
0
  while (enumerator->enumerate(enumerator, &id))
2105
0
  {
2106
0
    name = build_generalName(id);
2107
0
    subjectAltNames = chunk_cat("mm", subjectAltNames, name);
2108
0
  }
2109
0
  enumerator->destroy(enumerator);
2110
2111
0
  return asn1_wrap(ASN1_SEQUENCE, "mm",
2112
0
            asn1_build_known_oid(OID_SUBJECT_ALT_NAME),
2113
0
            asn1_wrap(ASN1_OCTET_STRING, "m",
2114
0
              asn1_wrap(ASN1_SEQUENCE, "m", subjectAltNames)
2115
0
            )
2116
0
           );
2117
0
}
2118
2119
/**
2120
 * Encode CRL distribution points extension from a x509_cdp_t list
2121
 */
2122
chunk_t x509_build_crlDistributionPoints(linked_list_t *list, int extn)
2123
0
{
2124
0
  chunk_t crlDistributionPoints = chunk_empty;
2125
0
  enumerator_t *enumerator;
2126
0
  x509_cdp_t *cdp;
2127
2128
0
  if (list->get_count(list) == 0)
2129
0
  {
2130
0
    return chunk_empty;
2131
0
  }
2132
2133
0
  enumerator = list->create_enumerator(list);
2134
0
  while (enumerator->enumerate(enumerator, &cdp))
2135
0
  {
2136
0
    chunk_t distributionPoint, crlIssuer = chunk_empty;
2137
2138
0
    if (cdp->issuer)
2139
0
    {
2140
0
      crlIssuer = asn1_wrap(ASN1_CONTEXT_C_2, "m",
2141
0
              build_generalName(cdp->issuer));
2142
0
    }
2143
0
    distributionPoint = asn1_wrap(ASN1_SEQUENCE, "mm",
2144
0
          asn1_wrap(ASN1_CONTEXT_C_0, "m",
2145
0
            asn1_wrap(ASN1_CONTEXT_C_0, "m",
2146
0
              asn1_wrap(ASN1_CONTEXT_S_6, "c",
2147
0
                chunk_create(cdp->uri, strlen(cdp->uri))))),
2148
0
          crlIssuer);
2149
0
    crlDistributionPoints = chunk_cat("mm", crlDistributionPoints,
2150
0
                      distributionPoint);
2151
0
  }
2152
0
  enumerator->destroy(enumerator);
2153
2154
0
  return asn1_wrap(ASN1_SEQUENCE, "mm",
2155
0
        asn1_build_known_oid(extn),
2156
0
        asn1_wrap(ASN1_OCTET_STRING, "m",
2157
0
          asn1_wrap(ASN1_SEQUENCE, "m", crlDistributionPoints)));
2158
0
}
2159
2160
static chunk_t generate_ts(traffic_selector_t *ts)
2161
0
{
2162
0
  chunk_t from, to;
2163
0
  uint8_t minbits = 0, maxbits = 0, unused;
2164
0
  host_t *net;
2165
0
  int bit, byte;
2166
2167
0
  if (ts->to_subnet(ts, &net, &minbits))
2168
0
  {
2169
0
    unused = round_up(minbits, BITS_PER_BYTE) - minbits;
2170
0
    from = asn1_wrap(ASN1_BIT_STRING, "m",
2171
0
      chunk_cat("cc", chunk_from_thing(unused),
2172
0
              chunk_create(net->get_address(net).ptr,
2173
0
                     (minbits + unused) / BITS_PER_BYTE)));
2174
0
    net->destroy(net);
2175
0
    return from;
2176
0
  }
2177
0
  net->destroy(net);
2178
2179
0
  from = ts->get_from_address(ts);
2180
0
  for (byte = from.len - 1; byte >= 0; byte--)
2181
0
  {
2182
0
    if (from.ptr[byte] != 0)
2183
0
    {
2184
0
      minbits = byte * BITS_PER_BYTE + BITS_PER_BYTE;
2185
0
      for (bit = 0; bit < BITS_PER_BYTE; bit++)
2186
0
      {
2187
0
        if (from.ptr[byte] & 1 << bit)
2188
0
        {
2189
0
          break;
2190
0
        }
2191
0
        minbits--;
2192
0
      }
2193
0
      break;
2194
0
    }
2195
0
  }
2196
0
  to = ts->get_to_address(ts);
2197
0
  for (byte = to.len - 1; byte >= 0; byte--)
2198
0
  {
2199
0
    if (to.ptr[byte] != 0xFF)
2200
0
    {
2201
0
      maxbits = byte * BITS_PER_BYTE + BITS_PER_BYTE;
2202
0
      for (bit = 0; bit < BITS_PER_BYTE; bit++)
2203
0
      {
2204
0
        if ((to.ptr[byte] & 1 << bit) == 0)
2205
0
        {
2206
0
          break;
2207
0
        }
2208
0
        maxbits--;
2209
0
      }
2210
0
      break;
2211
0
    }
2212
0
  }
2213
0
  unused = round_up(minbits, BITS_PER_BYTE) - minbits;
2214
0
  from = asn1_wrap(ASN1_BIT_STRING, "m",
2215
0
      chunk_cat("cc", chunk_from_thing(unused),
2216
0
              chunk_create(from.ptr,
2217
0
                     (minbits + unused) / BITS_PER_BYTE)));
2218
0
  unused = round_up(maxbits, BITS_PER_BYTE) - maxbits;
2219
0
  to = asn1_wrap(ASN1_BIT_STRING, "m",
2220
0
      chunk_cat("cc", chunk_from_thing(unused),
2221
0
              chunk_create(to.ptr,
2222
0
                     (maxbits + unused) / BITS_PER_BYTE)));
2223
0
  return asn1_wrap(ASN1_SEQUENCE, "mm", from, to);
2224
0
}
2225
2226
/**
2227
 * Generate an extendedKeyUsage X.509v3 extension (shared with x509_pkcs10.c)
2228
 */
2229
chunk_t x509_generate_eku_extension(x509_flag_t flags)
2230
0
{
2231
0
  chunk_t extendedKeyUsage = chunk_empty, ocspSigning = chunk_empty;
2232
0
  chunk_t serverAuth = chunk_empty, clientAuth = chunk_empty;
2233
0
  chunk_t ikeIntermediate = chunk_empty, msSmartcardLogon = chunk_empty;
2234
2235
0
  if (flags & X509_SERVER_AUTH)
2236
0
  {
2237
0
    serverAuth = asn1_build_known_oid(OID_SERVER_AUTH);
2238
0
  }
2239
0
  if (flags & X509_CLIENT_AUTH)
2240
0
  {
2241
0
    clientAuth = asn1_build_known_oid(OID_CLIENT_AUTH);
2242
0
  }
2243
0
  if (flags & X509_IKE_INTERMEDIATE)
2244
0
  {
2245
0
    ikeIntermediate = asn1_build_known_oid(OID_IKE_INTERMEDIATE);
2246
0
  }
2247
0
  if (flags & X509_OCSP_SIGNER)
2248
0
  {
2249
0
    ocspSigning = asn1_build_known_oid(OID_OCSP_SIGNING);
2250
0
  }
2251
0
  if (flags & X509_MS_SMARTCARD_LOGON)
2252
0
  {
2253
0
    msSmartcardLogon = asn1_build_known_oid(OID_MS_SMARTCARD_LOGON);
2254
0
  }
2255
2256
0
  if (serverAuth.ptr  || clientAuth.ptr || ikeIntermediate.ptr ||
2257
0
    ocspSigning.ptr || msSmartcardLogon.ptr)
2258
0
  {
2259
0
    extendedKeyUsage = asn1_wrap(ASN1_SEQUENCE, "mm",
2260
0
                asn1_build_known_oid(OID_EXTENDED_KEY_USAGE),
2261
0
                asn1_wrap(ASN1_OCTET_STRING, "m",
2262
0
                  asn1_wrap(ASN1_SEQUENCE, "mmmmm",
2263
0
                    serverAuth, clientAuth, ikeIntermediate,
2264
0
                    ocspSigning, msSmartcardLogon)));
2265
0
  }
2266
2267
0
  return extendedKeyUsage;
2268
0
}
2269
2270
/**
2271
 * Generate and sign a new certificate
2272
 */
2273
static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert,
2274
           private_key_t *sign_key, int digest_alg)
2275
0
{
2276
0
  const chunk_t keyUsageCrlSign = chunk_from_chars(0x01, 0x02);
2277
0
  const chunk_t keyUsageCertSignCrlSign = chunk_from_chars(0x01, 0x06);
2278
0
  chunk_t extensions = chunk_empty, certPolicies = chunk_empty;
2279
0
  chunk_t basicConstraints = chunk_empty, nameConstraints = chunk_empty;
2280
0
  chunk_t keyUsage = chunk_empty, keyUsageBits = chunk_empty;
2281
0
  chunk_t subjectAltNames = chunk_empty, policyMappings = chunk_empty;
2282
0
  chunk_t subjectKeyIdentifier = chunk_empty, authKeyIdentifier = chunk_empty;
2283
0
  chunk_t crlDistributionPoints = chunk_empty, authorityInfoAccess = chunk_empty;
2284
0
  chunk_t policyConstraints = chunk_empty, inhibitAnyPolicy = chunk_empty;
2285
0
  chunk_t ipAddrBlocks = chunk_empty, sig_scheme = chunk_empty;
2286
0
  chunk_t criticalExtension = chunk_empty, extendedKeyUsage = chunk_empty;
2287
0
  identification_t *issuer, *subject;
2288
0
  chunk_t key_info;
2289
0
  hasher_t *hasher;
2290
0
  enumerator_t *enumerator;
2291
0
  char *uri;
2292
2293
0
  subject = cert->subject;
2294
0
  if (sign_cert)
2295
0
  {
2296
0
    issuer = sign_cert->get_subject(sign_cert);
2297
0
    if (!cert->public_key)
2298
0
    {
2299
0
      return FALSE;
2300
0
    }
2301
0
  }
2302
0
  else
2303
0
  { /* self signed */
2304
0
    issuer = subject;
2305
0
    if (!cert->public_key)
2306
0
    {
2307
0
      cert->public_key = sign_key->get_public_key(sign_key);
2308
0
    }
2309
0
    cert->flags |= X509_SELF_SIGNED;
2310
0
  }
2311
0
  cert->issuer = issuer->clone(issuer);
2312
0
  if (!cert->notBefore)
2313
0
  {
2314
0
    cert->notBefore = time(NULL);
2315
0
  }
2316
0
  if (!cert->notAfter)
2317
0
  { /* defaults to 1 year from now */
2318
0
    cert->notAfter = cert->notBefore + 60 * 60 * 24 * 365;
2319
0
  }
2320
2321
  /* select signature scheme, if not already specified */
2322
0
  if (!cert->scheme)
2323
0
  {
2324
0
    INIT(cert->scheme,
2325
0
      .scheme = signature_scheme_from_oid(
2326
0
                hasher_signature_algorithm_to_oid(digest_alg,
2327
0
                        sign_key->get_type(sign_key))),
2328
0
    );
2329
0
  }
2330
0
  if (cert->scheme->scheme == SIGN_UNKNOWN)
2331
0
  {
2332
0
    return FALSE;
2333
0
  }
2334
0
  if (!signature_params_build(cert->scheme, &sig_scheme))
2335
0
  {
2336
0
    return FALSE;
2337
0
  }
2338
2339
0
  if (!cert->public_key->get_encoding(cert->public_key,
2340
0
                    PUBKEY_SPKI_ASN1_DER, &key_info))
2341
0
  {
2342
0
    chunk_free(&sig_scheme);
2343
0
    return FALSE;
2344
0
  }
2345
2346
  /* encode subjectAltNames */
2347
0
  subjectAltNames = x509_build_subjectAltNames(cert->subjectAltNames);
2348
2349
0
  crlDistributionPoints = x509_build_crlDistributionPoints(cert->crl_uris,
2350
0
                        OID_CRL_DISTRIBUTION_POINTS);
2351
2352
  /* encode OCSP URIs in authorityInfoAccess extension */
2353
0
  enumerator = cert->ocsp_uris->create_enumerator(cert->ocsp_uris);
2354
0
  while (enumerator->enumerate(enumerator, &uri))
2355
0
  {
2356
0
    chunk_t accessDescription;
2357
2358
0
    accessDescription = asn1_wrap(ASN1_SEQUENCE, "mm",
2359
0
                asn1_build_known_oid(OID_OCSP),
2360
0
                asn1_wrap(ASN1_CONTEXT_S_6, "c",
2361
0
                      chunk_create(uri, strlen(uri))));
2362
0
    authorityInfoAccess = chunk_cat("mm", authorityInfoAccess,
2363
0
                    accessDescription);
2364
0
  }
2365
0
  enumerator->destroy(enumerator);
2366
0
  if (authorityInfoAccess.ptr)
2367
0
  {
2368
0
    authorityInfoAccess = asn1_wrap(ASN1_SEQUENCE, "mm",
2369
0
          asn1_build_known_oid(OID_AUTHORITY_INFO_ACCESS),
2370
0
          asn1_wrap(ASN1_OCTET_STRING, "m",
2371
0
            asn1_wrap(ASN1_SEQUENCE, "m", authorityInfoAccess)));
2372
0
  }
2373
2374
  /* build CA basicConstraint and keyUsage flags for CA certificates */
2375
0
  if (cert->flags & X509_CA)
2376
0
  {
2377
0
    chunk_t pathLenConstraint = chunk_empty;
2378
2379
0
    if (cert->pathLenConstraint != X509_NO_CONSTRAINT)
2380
0
    {
2381
0
      pathLenConstraint = asn1_integer("c",
2382
0
                  chunk_from_thing(cert->pathLenConstraint));
2383
0
    }
2384
0
    basicConstraints = asn1_wrap(ASN1_SEQUENCE, "mmm",
2385
0
                asn1_build_known_oid(OID_BASIC_CONSTRAINTS),
2386
0
                asn1_wrap(ASN1_BOOLEAN, "c",
2387
0
                  chunk_from_chars(0xFF)),
2388
0
                asn1_wrap(ASN1_OCTET_STRING, "m",
2389
0
                    asn1_wrap(ASN1_SEQUENCE, "mm",
2390
0
                      asn1_wrap(ASN1_BOOLEAN, "c",
2391
0
                        chunk_from_chars(0xFF)),
2392
0
                      pathLenConstraint)));
2393
    /* set CertificateSign and implicitly CRLsign */
2394
0
    keyUsageBits = keyUsageCertSignCrlSign;
2395
0
  }
2396
0
  else if (cert->flags & X509_CRL_SIGN)
2397
0
  {
2398
0
    keyUsageBits = keyUsageCrlSign;
2399
0
  }
2400
0
  if (keyUsageBits.len)
2401
0
  {
2402
0
    keyUsage = asn1_wrap(ASN1_SEQUENCE, "mmm",
2403
0
            asn1_build_known_oid(OID_KEY_USAGE),
2404
0
            asn1_wrap(ASN1_BOOLEAN, "c", chunk_from_chars(0xFF)),
2405
0
            asn1_wrap(ASN1_OCTET_STRING, "m",
2406
0
              asn1_wrap(ASN1_BIT_STRING, "c", keyUsageBits)));
2407
0
  }
2408
2409
  /* add extendedKeyUsage flags */
2410
0
  extendedKeyUsage = x509_generate_eku_extension(cert->flags);
2411
2412
  /* add subjectKeyIdentifier to CA and OCSP signer certificates */
2413
0
  if (cert->flags & (X509_CA | X509_OCSP_SIGNER | X509_CRL_SIGN))
2414
0
  {
2415
0
    chunk_t keyid;
2416
2417
0
    if (cert->public_key->get_fingerprint(cert->public_key,
2418
0
                        KEYID_PUBKEY_SHA1, &keyid))
2419
0
    {
2420
0
      subjectKeyIdentifier = asn1_wrap(ASN1_SEQUENCE, "mm",
2421
0
                  asn1_build_known_oid(OID_SUBJECT_KEY_ID),
2422
0
                  asn1_wrap(ASN1_OCTET_STRING, "m",
2423
0
                    asn1_wrap(ASN1_OCTET_STRING, "c", keyid)));
2424
0
    }
2425
0
  }
2426
2427
  /* add the keyid authKeyIdentifier for non self-signed certificates */
2428
0
  if (sign_cert)
2429
0
  {
2430
0
    x509_t *sign_x509 = (x509_t*)sign_cert;
2431
0
    chunk_t keyid = chunk_empty;
2432
2433
0
    if (sign_cert->get_type(sign_cert) == CERT_X509)
2434
0
    {
2435
0
      keyid = sign_x509->get_subjectKeyIdentifier(sign_x509);
2436
0
    }
2437
0
    if (keyid.len ||
2438
0
      sign_key->get_fingerprint(sign_key, KEYID_PUBKEY_SHA1, &keyid))
2439
0
    {
2440
0
      authKeyIdentifier = asn1_wrap(ASN1_SEQUENCE, "mm",
2441
0
              asn1_build_known_oid(OID_AUTHORITY_KEY_ID),
2442
0
              asn1_wrap(ASN1_OCTET_STRING, "m",
2443
0
                asn1_wrap(ASN1_SEQUENCE, "m",
2444
0
                  asn1_wrap(ASN1_CONTEXT_S_0, "c", keyid))));
2445
0
    }
2446
0
  }
2447
2448
0
  if (cert->ipAddrBlocks->get_count(cert->ipAddrBlocks))
2449
0
  {
2450
0
    chunk_t v4blocks = chunk_empty, v6blocks = chunk_empty, block;
2451
0
    traffic_selector_t *ts;
2452
2453
0
    enumerator = cert->ipAddrBlocks->create_enumerator(cert->ipAddrBlocks);
2454
0
    while (enumerator->enumerate(enumerator, &ts))
2455
0
    {
2456
0
      switch (ts->get_type(ts))
2457
0
      {
2458
0
        case TS_IPV4_ADDR_RANGE:
2459
0
          block = generate_ts(ts);
2460
0
          v4blocks = chunk_cat("mm", v4blocks, block);
2461
0
          break;
2462
0
        case TS_IPV6_ADDR_RANGE:
2463
0
          block = generate_ts(ts);
2464
0
          v6blocks = chunk_cat("mm", v6blocks, block);
2465
0
          break;
2466
0
        default:
2467
0
          break;
2468
0
      }
2469
0
    }
2470
0
    enumerator->destroy(enumerator);
2471
2472
0
    if (v4blocks.ptr)
2473
0
    {
2474
0
      v4blocks = asn1_wrap(ASN1_SEQUENCE, "mm",
2475
0
            asn1_wrap(ASN1_OCTET_STRING, "c",
2476
0
              chunk_from_chars(0x00,0x01)),
2477
0
            asn1_wrap(ASN1_SEQUENCE, "m", v4blocks));
2478
0
    }
2479
0
    if (v6blocks.ptr)
2480
0
    {
2481
0
      v6blocks = asn1_wrap(ASN1_SEQUENCE, "mm",
2482
0
            asn1_wrap(ASN1_OCTET_STRING, "c",
2483
0
              chunk_from_chars(0x00,0x02)),
2484
0
            asn1_wrap(ASN1_SEQUENCE, "m", v6blocks));
2485
0
    }
2486
0
    ipAddrBlocks = asn1_wrap(ASN1_SEQUENCE, "mm",
2487
0
            asn1_build_known_oid(OID_IP_ADDR_BLOCKS),
2488
0
            asn1_wrap(ASN1_OCTET_STRING, "m",
2489
0
              asn1_wrap(ASN1_SEQUENCE, "mm",
2490
0
                v4blocks, v6blocks)));
2491
0
    cert->flags |= X509_IP_ADDR_BLOCKS;
2492
0
  }
2493
2494
0
  if (cert->permitted_names->get_count(cert->permitted_names) ||
2495
0
    cert->excluded_names->get_count(cert->excluded_names))
2496
0
  {
2497
0
    chunk_t permitted = chunk_empty, excluded = chunk_empty, subtree;
2498
0
    identification_t *id;
2499
2500
0
    enumerator = create_name_constraint_enumerator(cert, TRUE);
2501
0
    while (enumerator->enumerate(enumerator, &id))
2502
0
    {
2503
0
      subtree = asn1_wrap(ASN1_SEQUENCE, "m", build_generalName(id));
2504
0
      permitted = chunk_cat("mm", permitted, subtree);
2505
0
    }
2506
0
    enumerator->destroy(enumerator);
2507
0
    if (permitted.ptr)
2508
0
    {
2509
0
      permitted = asn1_wrap(ASN1_CONTEXT_C_0, "m", permitted);
2510
0
    }
2511
2512
0
    enumerator = create_name_constraint_enumerator(cert, FALSE);
2513
0
    while (enumerator->enumerate(enumerator, &id))
2514
0
    {
2515
0
      subtree = asn1_wrap(ASN1_SEQUENCE, "m", build_generalName(id));
2516
0
      excluded = chunk_cat("mm", excluded, subtree);
2517
0
    }
2518
0
    enumerator->destroy(enumerator);
2519
0
    if (excluded.ptr)
2520
0
    {
2521
0
      excluded = asn1_wrap(ASN1_CONTEXT_C_1, "m", excluded);
2522
0
    }
2523
2524
0
    nameConstraints = asn1_wrap(ASN1_SEQUENCE, "mm",
2525
0
              asn1_build_known_oid(OID_NAME_CONSTRAINTS),
2526
0
              asn1_wrap(ASN1_OCTET_STRING, "m",
2527
0
                asn1_wrap(ASN1_SEQUENCE, "mm",
2528
0
                  permitted, excluded)));
2529
0
  }
2530
2531
0
  if (cert->cert_policies->get_count(cert->cert_policies))
2532
0
  {
2533
0
    x509_cert_policy_t *policy;
2534
2535
0
    enumerator = create_cert_policy_enumerator(cert);
2536
0
    while (enumerator->enumerate(enumerator, &policy))
2537
0
    {
2538
0
      chunk_t chunk = chunk_empty, cps = chunk_empty, notice = chunk_empty;
2539
2540
0
      if (policy->cps_uri)
2541
0
      {
2542
0
        cps = asn1_wrap(ASN1_SEQUENCE, "mm",
2543
0
            asn1_build_known_oid(OID_POLICY_QUALIFIER_CPS),
2544
0
            asn1_wrap(ASN1_IA5STRING, "c",
2545
0
              chunk_create(policy->cps_uri,
2546
0
                     strlen(policy->cps_uri))));
2547
0
      }
2548
0
      if (policy->unotice_text)
2549
0
      {
2550
0
        notice = asn1_wrap(ASN1_SEQUENCE, "mm",
2551
0
              asn1_build_known_oid(OID_POLICY_QUALIFIER_UNOTICE),
2552
0
              asn1_wrap(ASN1_SEQUENCE, "m",
2553
0
                asn1_wrap(ASN1_VISIBLESTRING, "c",
2554
0
                  chunk_create(policy->unotice_text,
2555
0
                    strlen(policy->unotice_text)))));
2556
0
      }
2557
0
      if (cps.len || notice.len)
2558
0
      {
2559
0
        chunk = asn1_wrap(ASN1_SEQUENCE, "mm", cps, notice);
2560
0
      }
2561
0
      chunk = asn1_wrap(ASN1_SEQUENCE, "mm",
2562
0
            asn1_wrap(ASN1_OID, "c", policy->oid), chunk);
2563
0
      certPolicies = chunk_cat("mm", certPolicies, chunk);
2564
0
    }
2565
0
    enumerator->destroy(enumerator);
2566
2567
0
    certPolicies = asn1_wrap(ASN1_SEQUENCE, "mm",
2568
0
              asn1_build_known_oid(OID_CERTIFICATE_POLICIES),
2569
0
              asn1_wrap(ASN1_OCTET_STRING, "m",
2570
0
                asn1_wrap(ASN1_SEQUENCE, "m", certPolicies)));
2571
0
  }
2572
2573
0
  if (cert->policy_mappings->get_count(cert->policy_mappings))
2574
0
  {
2575
0
    x509_policy_mapping_t *mapping;
2576
2577
0
    enumerator = create_policy_mapping_enumerator(cert);
2578
0
    while (enumerator->enumerate(enumerator, &mapping))
2579
0
    {
2580
0
      chunk_t chunk;
2581
2582
0
      chunk = asn1_wrap(ASN1_SEQUENCE, "mm",
2583
0
            asn1_wrap(ASN1_OID, "c", mapping->issuer),
2584
0
            asn1_wrap(ASN1_OID, "c", mapping->subject));
2585
0
      policyMappings = chunk_cat("mm", policyMappings, chunk);
2586
0
    }
2587
0
    enumerator->destroy(enumerator);
2588
2589
0
    policyMappings = asn1_wrap(ASN1_SEQUENCE, "mm",
2590
0
              asn1_build_known_oid(OID_POLICY_MAPPINGS),
2591
0
              asn1_wrap(ASN1_OCTET_STRING, "m",
2592
0
                asn1_wrap(ASN1_SEQUENCE, "m", policyMappings)));
2593
0
  }
2594
2595
0
  if (cert->inhibit_mapping != X509_NO_CONSTRAINT ||
2596
0
    cert->require_explicit != X509_NO_CONSTRAINT)
2597
0
  {
2598
0
    chunk_t inhibit = chunk_empty, explicit = chunk_empty;
2599
2600
0
    if (cert->require_explicit != X509_NO_CONSTRAINT)
2601
0
    {
2602
0
      explicit = asn1_wrap(ASN1_CONTEXT_C_0, "m",
2603
0
            asn1_integer("c",
2604
0
              chunk_from_thing(cert->require_explicit)));
2605
0
    }
2606
0
    if (cert->inhibit_mapping != X509_NO_CONSTRAINT)
2607
0
    {
2608
0
      inhibit = asn1_wrap(ASN1_CONTEXT_C_1, "m",
2609
0
            asn1_integer("c",
2610
0
              chunk_from_thing(cert->inhibit_mapping)));
2611
0
    }
2612
0
    policyConstraints = asn1_wrap(ASN1_SEQUENCE, "mmm",
2613
0
            asn1_build_known_oid(OID_POLICY_CONSTRAINTS),
2614
0
            asn1_wrap(ASN1_BOOLEAN, "c", chunk_from_chars(0xFF)),
2615
0
            asn1_wrap(ASN1_OCTET_STRING, "m",
2616
0
              asn1_wrap(ASN1_SEQUENCE, "mm",
2617
0
                explicit, inhibit)));
2618
0
  }
2619
2620
0
  if (cert->inhibit_any != X509_NO_CONSTRAINT)
2621
0
  {
2622
0
    inhibitAnyPolicy = asn1_wrap(ASN1_SEQUENCE, "mmm",
2623
0
        asn1_build_known_oid(OID_INHIBIT_ANY_POLICY),
2624
0
        asn1_wrap(ASN1_BOOLEAN, "c", chunk_from_chars(0xFF)),
2625
0
        asn1_wrap(ASN1_OCTET_STRING, "m",
2626
0
          asn1_integer("c",
2627
0
            chunk_from_thing(cert->inhibit_any))));
2628
0
  }
2629
2630
0
  if (cert->critical_extension_oid.len > 0)
2631
0
  {
2632
0
    criticalExtension = asn1_wrap(ASN1_SEQUENCE, "mmm",
2633
0
          asn1_simple_object(ASN1_OID, cert->critical_extension_oid),
2634
0
          asn1_simple_object(ASN1_BOOLEAN, chunk_from_chars(0xFF)),
2635
0
          asn1_simple_object(ASN1_OCTET_STRING, chunk_empty));
2636
0
  }
2637
2638
0
  if (basicConstraints.ptr || keyUsage.ptr || subjectKeyIdentifier.ptr ||
2639
0
    authKeyIdentifier.ptr || subjectAltNames.ptr || extendedKeyUsage.ptr ||
2640
0
    crlDistributionPoints.ptr || authorityInfoAccess.ptr ||
2641
0
    nameConstraints.ptr || certPolicies.ptr || policyMappings.ptr ||
2642
0
    policyConstraints.ptr || inhibitAnyPolicy.ptr || ipAddrBlocks.ptr ||
2643
0
    criticalExtension.ptr)
2644
0
  {
2645
0
    extensions = asn1_wrap(ASN1_CONTEXT_C_3, "m",
2646
0
            asn1_wrap(ASN1_SEQUENCE, "mmmmmmmmmmmmmmm",
2647
0
              basicConstraints, keyUsage, subjectKeyIdentifier,
2648
0
              authKeyIdentifier, subjectAltNames,
2649
0
              extendedKeyUsage, crlDistributionPoints,
2650
0
              authorityInfoAccess, nameConstraints, certPolicies,
2651
0
              policyMappings, policyConstraints, inhibitAnyPolicy,
2652
0
              ipAddrBlocks, criticalExtension));
2653
0
  }
2654
2655
0
  cert->tbsCertificate = asn1_wrap(ASN1_SEQUENCE, "mmccmcmm",
2656
0
    asn1_simple_object(ASN1_CONTEXT_C_0, ASN1_INTEGER_2),
2657
0
    asn1_integer("c", cert->serialNumber),
2658
0
    sig_scheme,
2659
0
    issuer->get_encoding(issuer),
2660
0
    asn1_wrap(ASN1_SEQUENCE, "mm",
2661
0
      asn1_from_time(&cert->notBefore, ASN1_UTCTIME),
2662
0
      asn1_from_time(&cert->notAfter, ASN1_UTCTIME)),
2663
0
    subject->get_encoding(subject),
2664
0
    key_info, extensions);
2665
2666
0
  if (!sign_key->sign(sign_key, cert->scheme->scheme, cert->scheme->params,
2667
0
            cert->tbsCertificate, &cert->signature))
2668
0
  {
2669
0
    chunk_free(&sig_scheme);
2670
0
    return FALSE;
2671
0
  }
2672
0
  cert->encoding = asn1_wrap(ASN1_SEQUENCE, "cmm", cert->tbsCertificate,
2673
0
                 sig_scheme,
2674
0
                 asn1_bitstring("c", cert->signature));
2675
2676
0
  hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
2677
0
  if (!hasher ||
2678
0
    !hasher->allocate_hash(hasher, cert->encoding, &cert->encoding_hash))
2679
0
  {
2680
0
    DESTROY_IF(hasher);
2681
0
    return FALSE;
2682
0
  }
2683
0
  hasher->destroy(hasher);
2684
0
  return TRUE;
2685
0
}
2686
2687
/**
2688
 * See header.
2689
 */
2690
x509_cert_t *x509_cert_load(certificate_type_t type, va_list args)
2691
0
{
2692
0
  x509_flag_t flags = 0;
2693
0
  chunk_t blob = chunk_empty;
2694
2695
0
  while (TRUE)
2696
0
  {
2697
0
    switch (va_arg(args, builder_part_t))
2698
0
    {
2699
0
      case BUILD_BLOB_ASN1_DER:
2700
0
        blob = va_arg(args, chunk_t);
2701
0
        continue;
2702
0
      case BUILD_X509_FLAG:
2703
0
        flags |= va_arg(args, x509_flag_t);
2704
0
        continue;
2705
0
      case BUILD_END:
2706
0
        break;
2707
0
      default:
2708
0
        return NULL;
2709
0
    }
2710
0
    break;
2711
0
  }
2712
2713
0
  if (blob.ptr)
2714
0
  {
2715
0
    private_x509_cert_t *cert = create_empty();
2716
2717
0
    cert->encoding = chunk_clone(blob);
2718
0
    cert->parsed = TRUE;
2719
0
    if (parse_certificate(cert))
2720
0
    {
2721
0
      cert->flags |= flags;
2722
0
      return &cert->public;
2723
0
    }
2724
0
    destroy(cert);
2725
0
  }
2726
0
  return NULL;
2727
0
}
2728
2729
/**
2730
 * See header.
2731
 */
2732
x509_cert_t *x509_cert_gen(certificate_type_t type, va_list args)
2733
0
{
2734
0
  private_x509_cert_t *cert;
2735
0
  certificate_t *sign_cert = NULL;
2736
0
  private_key_t *sign_key = NULL;
2737
0
  hash_algorithm_t digest_alg = HASH_SHA256;
2738
0
  u_int constraint;
2739
2740
0
  cert = create_empty();
2741
0
  while (TRUE)
2742
0
  {
2743
0
    switch (va_arg(args, builder_part_t))
2744
0
    {
2745
0
      case BUILD_X509_FLAG:
2746
0
        cert->flags |= va_arg(args, x509_flag_t);
2747
0
        continue;
2748
0
      case BUILD_SIGNING_KEY:
2749
0
        sign_key = va_arg(args, private_key_t*);
2750
0
        continue;
2751
0
      case BUILD_SIGNING_CERT:
2752
0
        sign_cert = va_arg(args, certificate_t*);
2753
0
        continue;
2754
0
      case BUILD_PUBLIC_KEY:
2755
0
        cert->public_key = va_arg(args, public_key_t*);
2756
0
        cert->public_key->get_ref(cert->public_key);
2757
0
        continue;
2758
0
      case BUILD_SUBJECT:
2759
0
        cert->subject = va_arg(args, identification_t*);
2760
0
        cert->subject = cert->subject->clone(cert->subject);
2761
0
        continue;
2762
0
      case BUILD_SUBJECT_ALTNAMES:
2763
0
      {
2764
0
        enumerator_t *enumerator;
2765
0
        identification_t *id;
2766
0
        linked_list_t *list;
2767
2768
0
        list = va_arg(args, linked_list_t*);
2769
0
        enumerator = list->create_enumerator(list);
2770
0
        while (enumerator->enumerate(enumerator, &id))
2771
0
        {
2772
0
          cert->subjectAltNames->insert_last(cert->subjectAltNames,
2773
0
                          id->clone(id));
2774
0
        }
2775
0
        enumerator->destroy(enumerator);
2776
0
        continue;
2777
0
      }
2778
0
      case BUILD_CRL_DISTRIBUTION_POINTS:
2779
0
      {
2780
0
        enumerator_t *enumerator;
2781
0
        linked_list_t *list;
2782
0
        x509_cdp_t *in, *cdp;
2783
2784
0
        list = va_arg(args, linked_list_t*);
2785
0
        enumerator = list->create_enumerator(list);
2786
0
        while (enumerator->enumerate(enumerator, &in))
2787
0
        {
2788
0
          INIT(cdp,
2789
0
            .uri = strdup(in->uri),
2790
0
            .issuer = in->issuer ? in->issuer->clone(in->issuer) : NULL,
2791
0
          );
2792
0
          cert->crl_uris->insert_last(cert->crl_uris, cdp);
2793
0
        }
2794
0
        enumerator->destroy(enumerator);
2795
0
        continue;
2796
0
      }
2797
0
      case BUILD_OCSP_ACCESS_LOCATIONS:
2798
0
      {
2799
0
        enumerator_t *enumerator;
2800
0
        linked_list_t *list;
2801
0
        char *uri;
2802
2803
0
        list = va_arg(args, linked_list_t*);
2804
0
        enumerator = list->create_enumerator(list);
2805
0
        while (enumerator->enumerate(enumerator, &uri))
2806
0
        {
2807
0
          cert->ocsp_uris->insert_last(cert->ocsp_uris, strdup(uri));
2808
0
        }
2809
0
        enumerator->destroy(enumerator);
2810
0
        continue;
2811
0
      }
2812
0
      case BUILD_PATHLEN:
2813
0
        constraint = va_arg(args, u_int);
2814
0
        cert->pathLenConstraint = (constraint < 128) ?
2815
0
                       constraint : X509_NO_CONSTRAINT;
2816
0
        continue;
2817
0
      case BUILD_ADDRBLOCKS:
2818
0
      {
2819
0
        enumerator_t *enumerator;
2820
0
        traffic_selector_t *ts;
2821
0
        linked_list_t *list;
2822
2823
0
        list = va_arg(args, linked_list_t*);
2824
0
        enumerator = list->create_enumerator(list);
2825
0
        while (enumerator->enumerate(enumerator, &ts))
2826
0
        {
2827
0
          cert->ipAddrBlocks->insert_last(cert->ipAddrBlocks,
2828
0
                          ts->clone(ts));
2829
0
        }
2830
0
        enumerator->destroy(enumerator);
2831
0
        continue;
2832
0
      }
2833
0
      case BUILD_PERMITTED_NAME_CONSTRAINTS:
2834
0
      {
2835
0
        enumerator_t *enumerator;
2836
0
        linked_list_t *list;
2837
0
        identification_t *constraint;
2838
2839
0
        list = va_arg(args, linked_list_t*);
2840
0
        enumerator = list->create_enumerator(list);
2841
0
        while (enumerator->enumerate(enumerator, &constraint))
2842
0
        {
2843
0
          cert->permitted_names->insert_last(cert->permitted_names,
2844
0
                        constraint->clone(constraint));
2845
0
        }
2846
0
        enumerator->destroy(enumerator);
2847
0
        continue;
2848
0
      }
2849
0
      case BUILD_EXCLUDED_NAME_CONSTRAINTS:
2850
0
      {
2851
0
        enumerator_t *enumerator;
2852
0
        linked_list_t *list;
2853
0
        identification_t *constraint;
2854
2855
0
        list = va_arg(args, linked_list_t*);
2856
0
        enumerator = list->create_enumerator(list);
2857
0
        while (enumerator->enumerate(enumerator, &constraint))
2858
0
        {
2859
0
          cert->excluded_names->insert_last(cert->excluded_names,
2860
0
                        constraint->clone(constraint));
2861
0
        }
2862
0
        enumerator->destroy(enumerator);
2863
0
        continue;
2864
0
      }
2865
0
      case BUILD_CERTIFICATE_POLICIES:
2866
0
      {
2867
0
        enumerator_t *enumerator;
2868
0
        linked_list_t *list;
2869
0
        x509_cert_policy_t *policy, *in;
2870
2871
0
        list = va_arg(args, linked_list_t*);
2872
0
        enumerator = list->create_enumerator(list);
2873
0
        while (enumerator->enumerate(enumerator, &in))
2874
0
        {
2875
0
          INIT(policy,
2876
0
            .oid = chunk_clone(in->oid),
2877
0
            .cps_uri = strdupnull(in->cps_uri),
2878
0
            .unotice_text = strdupnull(in->unotice_text),
2879
0
          );
2880
0
          cert->cert_policies->insert_last(cert->cert_policies, policy);
2881
0
        }
2882
0
        enumerator->destroy(enumerator);
2883
0
        continue;
2884
0
      }
2885
0
      case BUILD_POLICY_MAPPINGS:
2886
0
      {
2887
0
        enumerator_t *enumerator;
2888
0
        linked_list_t *list;
2889
0
        x509_policy_mapping_t* mapping, *in;
2890
2891
0
        list = va_arg(args, linked_list_t*);
2892
0
        enumerator = list->create_enumerator(list);
2893
0
        while (enumerator->enumerate(enumerator, &in))
2894
0
        {
2895
0
          INIT(mapping,
2896
0
            .issuer = chunk_clone(in->issuer),
2897
0
            .subject = chunk_clone(in->subject),
2898
0
          );
2899
0
          cert->policy_mappings->insert_last(cert->policy_mappings,
2900
0
                             mapping);
2901
0
        }
2902
0
        enumerator->destroy(enumerator);
2903
0
        continue;
2904
0
      }
2905
0
      case BUILD_POLICY_REQUIRE_EXPLICIT:
2906
0
        constraint = va_arg(args, u_int);
2907
0
        cert->require_explicit = (constraint < 128) ?
2908
0
                      constraint : X509_NO_CONSTRAINT;
2909
0
        continue;
2910
0
      case BUILD_POLICY_INHIBIT_MAPPING:
2911
0
        constraint = va_arg(args, u_int);
2912
0
        cert->inhibit_mapping = (constraint < 128) ?
2913
0
                     constraint : X509_NO_CONSTRAINT;
2914
0
        continue;
2915
0
      case BUILD_POLICY_INHIBIT_ANY:
2916
0
        constraint = va_arg(args, u_int);
2917
0
        cert->inhibit_any = (constraint < 128) ?
2918
0
                   constraint : X509_NO_CONSTRAINT;
2919
0
        continue;
2920
0
      case BUILD_NOT_BEFORE_TIME:
2921
0
        cert->notBefore = va_arg(args, time_t);
2922
0
        continue;
2923
0
      case BUILD_NOT_AFTER_TIME:
2924
0
        cert->notAfter = va_arg(args, time_t);
2925
0
        continue;
2926
0
      case BUILD_SERIAL:
2927
0
        cert->serialNumber = chunk_clone(va_arg(args, chunk_t));
2928
0
        continue;
2929
0
      case BUILD_SIGNATURE_SCHEME:
2930
0
        cert->scheme = va_arg(args, signature_params_t*);
2931
0
        cert->scheme = signature_params_clone(cert->scheme);
2932
0
        continue;
2933
0
      case BUILD_DIGEST_ALG:
2934
0
        digest_alg = va_arg(args, int);
2935
0
        continue;
2936
0
      case BUILD_CRITICAL_EXTENSION:
2937
0
        cert->critical_extension_oid = chunk_clone(va_arg(args, chunk_t));
2938
0
        continue;
2939
0
      case BUILD_END:
2940
0
        break;
2941
0
      default:
2942
0
        destroy(cert);
2943
0
        return NULL;
2944
0
    }
2945
0
    break;
2946
0
  }
2947
2948
0
  if (sign_key && generate(cert, sign_cert, sign_key, digest_alg))
2949
0
  {
2950
0
    return &cert->public;
2951
0
  }
2952
0
  destroy(cert);
2953
  return NULL;
2954
0
}