Coverage Report

Created: 2025-04-24 06:18

/src/hostap/src/tls/x509v3.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * X.509v3 certificate parsing and processing (RFC 3280 profile)
3
 * Copyright (c) 2006-2015, Jouni Malinen <j@w1.fi>
4
 *
5
 * This software may be distributed under the terms of the BSD license.
6
 * See README for more details.
7
 */
8
9
#include "includes.h"
10
11
#include "common.h"
12
#include "crypto/crypto.h"
13
#include "asn1.h"
14
#include "x509v3.h"
15
16
17
void x509_free_name(struct x509_name *name)
18
13.6k
{
19
13.6k
  size_t i;
20
21
14.3k
  for (i = 0; i < name->num_attr; i++) {
22
717
    os_free(name->attr[i].value);
23
717
    name->attr[i].value = NULL;
24
717
    name->attr[i].type = X509_NAME_ATTR_NOT_USED;
25
717
  }
26
13.6k
  name->num_attr = 0;
27
13.6k
  os_free(name->email);
28
13.6k
  name->email = NULL;
29
30
13.6k
  os_free(name->alt_email);
31
13.6k
  os_free(name->dns);
32
13.6k
  os_free(name->uri);
33
13.6k
  os_free(name->ip);
34
13.6k
  name->alt_email = name->dns = name->uri = NULL;
35
13.6k
  name->ip = NULL;
36
13.6k
  name->ip_len = 0;
37
13.6k
  os_memset(&name->rid, 0, sizeof(name->rid));
38
13.6k
}
39
40
41
/**
42
 * x509_certificate_free - Free an X.509 certificate
43
 * @cert: Certificate to be freed
44
 */
45
void x509_certificate_free(struct x509_certificate *cert)
46
13.1k
{
47
13.1k
  if (cert == NULL)
48
6.59k
    return;
49
6.59k
  if (cert->next) {
50
0
    wpa_printf(MSG_DEBUG, "X509: x509_certificate_free: cer=%p "
51
0
         "was still on a list (next=%p)\n",
52
0
         cert, cert->next);
53
0
  }
54
6.59k
  x509_free_name(&cert->issuer);
55
6.59k
  x509_free_name(&cert->subject);
56
6.59k
  os_free(cert->public_key);
57
6.59k
  os_free(cert->sign_value);
58
6.59k
  os_free(cert->subject_dn);
59
6.59k
  os_free(cert);
60
6.59k
}
61
62
63
/**
64
 * x509_certificate_free - Free an X.509 certificate chain
65
 * @cert: Pointer to the first certificate in the chain
66
 */
67
void x509_certificate_chain_free(struct x509_certificate *cert)
68
0
{
69
0
  struct x509_certificate *next;
70
71
0
  while (cert) {
72
0
    next = cert->next;
73
0
    cert->next = NULL;
74
0
    x509_certificate_free(cert);
75
0
    cert = next;
76
0
  }
77
0
}
78
79
80
static int x509_whitespace(char c)
81
0
{
82
0
  return c == ' ' || c == '\t';
83
0
}
84
85
86
static void x509_str_strip_whitespace(char *a)
87
0
{
88
0
  char *ipos, *opos;
89
0
  int remove_whitespace = 1;
90
91
0
  ipos = opos = a;
92
93
0
  while (*ipos) {
94
0
    if (remove_whitespace && x509_whitespace(*ipos))
95
0
      ipos++;
96
0
    else {
97
0
      remove_whitespace = x509_whitespace(*ipos);
98
0
      *opos++ = *ipos++;
99
0
    }
100
0
  }
101
102
0
  *opos-- = '\0';
103
0
  if (opos > a && x509_whitespace(*opos))
104
0
    *opos = '\0';
105
0
}
106
107
108
static int x509_str_compare(const char *a, const char *b)
109
0
{
110
0
  char *aa, *bb;
111
0
  int ret;
112
113
0
  if (!a && b)
114
0
    return -1;
115
0
  if (a && !b)
116
0
    return 1;
117
0
  if (!a && !b)
118
0
    return 0;
119
120
0
  aa = os_strdup(a);
121
0
  bb = os_strdup(b);
122
123
0
  if (aa == NULL || bb == NULL) {
124
0
    os_free(aa);
125
0
    os_free(bb);
126
0
    return os_strcasecmp(a, b);
127
0
  }
128
129
0
  x509_str_strip_whitespace(aa);
130
0
  x509_str_strip_whitespace(bb);
131
132
0
  ret = os_strcasecmp(aa, bb);
133
134
0
  os_free(aa);
135
0
  os_free(bb);
136
137
0
  return ret;
138
0
}
139
140
141
/**
142
 * x509_name_compare - Compare X.509 certificate names
143
 * @a: Certificate name
144
 * @b: Certificate name
145
 * Returns: <0, 0, or >0 based on whether a is less than, equal to, or
146
 * greater than b
147
 */
148
int x509_name_compare(struct x509_name *a, struct x509_name *b)
149
0
{
150
0
  int res;
151
0
  size_t i;
152
153
0
  if (!a && b)
154
0
    return -1;
155
0
  if (a && !b)
156
0
    return 1;
157
0
  if (!a && !b)
158
0
    return 0;
159
0
  if (a->num_attr < b->num_attr)
160
0
    return -1;
161
0
  if (a->num_attr > b->num_attr)
162
0
    return 1;
163
164
0
  for (i = 0; i < a->num_attr; i++) {
165
0
    if (a->attr[i].type < b->attr[i].type)
166
0
      return -1;
167
0
    if (a->attr[i].type > b->attr[i].type)
168
0
      return -1;
169
0
    res = x509_str_compare(a->attr[i].value, b->attr[i].value);
170
0
    if (res)
171
0
      return res;
172
0
  }
173
0
  res = x509_str_compare(a->email, b->email);
174
0
  if (res)
175
0
    return res;
176
177
0
  return 0;
178
0
}
179
180
181
int x509_parse_algorithm_identifier(const u8 *buf, size_t len,
182
            struct x509_algorithm_identifier *id,
183
            const u8 **next)
184
9.80k
{
185
9.80k
  struct asn1_hdr hdr;
186
9.80k
  const u8 *pos, *end;
187
188
  /*
189
   * AlgorithmIdentifier ::= SEQUENCE {
190
   *     algorithm            OBJECT IDENTIFIER,
191
   *     parameters           ANY DEFINED BY algorithm OPTIONAL
192
   * }
193
   */
194
195
9.80k
  if (asn1_get_next(buf, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
196
362
    asn1_unexpected(&hdr,
197
362
        "X509: Expected SEQUENCE (AlgorithmIdentifier)");
198
362
    return -1;
199
362
  }
200
9.44k
  if (hdr.length > buf + len - hdr.payload)
201
0
    return -1;
202
9.44k
  pos = hdr.payload;
203
9.44k
  end = pos + hdr.length;
204
205
9.44k
  *next = end;
206
207
9.44k
  if (asn1_get_oid(pos, end - pos, &id->oid, &pos))
208
135
    return -1;
209
210
  /* TODO: optional parameters */
211
212
9.30k
  return 0;
213
9.44k
}
214
215
216
static int x509_parse_public_key(const u8 *buf, size_t len,
217
         struct x509_certificate *cert,
218
         const u8 **next)
219
3.59k
{
220
3.59k
  struct asn1_hdr hdr;
221
3.59k
  const u8 *pos, *end;
222
223
  /*
224
   * SubjectPublicKeyInfo ::= SEQUENCE {
225
   *     algorithm            AlgorithmIdentifier,
226
   *     subjectPublicKey     BIT STRING
227
   * }
228
   */
229
230
3.59k
  pos = buf;
231
3.59k
  end = buf + len;
232
233
3.59k
  if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
234
3.59k
      !asn1_is_sequence(&hdr)) {
235
40
    asn1_unexpected(&hdr,
236
40
        "X509: Expected SEQUENCE (SubjectPublicKeyInfo)");
237
40
    return -1;
238
40
  }
239
3.55k
  pos = hdr.payload;
240
241
3.55k
  if (hdr.length > end - pos)
242
0
    return -1;
243
3.55k
  end = pos + hdr.length;
244
3.55k
  *next = end;
245
246
3.55k
  if (x509_parse_algorithm_identifier(pos, end - pos,
247
3.55k
              &cert->public_key_alg, &pos))
248
71
    return -1;
249
250
3.48k
  if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
251
3.48k
      !asn1_is_bitstring(&hdr)) {
252
40
    asn1_unexpected(&hdr,
253
40
        "X509: Expected BITSTRING (subjectPublicKey)");
254
40
    return -1;
255
40
  }
256
3.44k
  if (hdr.length < 1)
257
2
    return -1;
258
3.44k
  pos = hdr.payload;
259
3.44k
  if (*pos) {
260
3.05k
    wpa_printf(MSG_DEBUG,
261
3.05k
         "X509: BITSTRING (subjectPublicKey) - %d unused bits",
262
3.05k
         *pos);
263
    /*
264
     * TODO: should this be rejected? X.509 certificates are
265
     * unlikely to use such a construction. Now we would end up
266
     * including the extra bits in the buffer which may also be
267
     * ok.
268
     */
269
3.05k
  }
270
3.44k
  os_free(cert->public_key);
271
3.44k
  cert->public_key = os_memdup(pos + 1, hdr.length - 1);
272
3.44k
  if (cert->public_key == NULL) {
273
0
    wpa_printf(MSG_DEBUG, "X509: Failed to allocate memory for "
274
0
         "public key");
275
0
    return -1;
276
0
  }
277
3.44k
  cert->public_key_len = hdr.length - 1;
278
3.44k
  wpa_hexdump(MSG_MSGDUMP, "X509: subjectPublicKey",
279
3.44k
        cert->public_key, cert->public_key_len);
280
281
3.44k
  return 0;
282
3.44k
}
283
284
285
int x509_parse_name(const u8 *buf, size_t len, struct x509_name *name,
286
        const u8 **next)
287
9.39k
{
288
9.39k
  struct asn1_hdr hdr;
289
9.39k
  const u8 *pos, *end, *set_pos, *set_end, *seq_pos, *seq_end;
290
9.39k
  struct asn1_oid oid;
291
9.39k
  char *val;
292
293
  /*
294
   * Name ::= CHOICE { RDNSequence }
295
   * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
296
   * RelativeDistinguishedName ::= SET OF AttributeTypeAndValue
297
   * AttributeTypeAndValue ::= SEQUENCE {
298
   *     type     AttributeType,
299
   *     value    AttributeValue
300
   * }
301
   * AttributeType ::= OBJECT IDENTIFIER
302
   * AttributeValue ::= ANY DEFINED BY AttributeType
303
   */
304
305
9.39k
  if (asn1_get_next(buf, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
306
133
    asn1_unexpected(&hdr,
307
133
        "X509: Expected SEQUENCE (Name / RDNSequencer)");
308
133
    return -1;
309
133
  }
310
9.26k
  pos = hdr.payload;
311
312
9.26k
  if (hdr.length > buf + len - pos)
313
0
    return -1;
314
315
9.26k
  end = *next = pos + hdr.length;
316
317
27.9k
  while (pos < end) {
318
19.1k
    enum x509_name_attr_type type;
319
320
19.1k
    if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
321
19.1k
        !asn1_is_set(&hdr)) {
322
387
      asn1_unexpected(&hdr,
323
387
          "X509: Expected SET (RelativeDistinguishedName)");
324
387
      x509_free_name(name);
325
387
      return -1;
326
387
    }
327
328
18.7k
    set_pos = hdr.payload;
329
18.7k
    pos = set_end = hdr.payload + hdr.length;
330
331
18.7k
    if (asn1_get_next(set_pos, set_end - set_pos, &hdr) < 0 ||
332
18.7k
        !asn1_is_sequence(&hdr)) {
333
47
      asn1_unexpected(&hdr,
334
47
          "X509: Expected SEQUENCE (AttributeTypeAndValue)");
335
47
      x509_free_name(name);
336
47
      return -1;
337
47
    }
338
339
18.6k
    seq_pos = hdr.payload;
340
18.6k
    seq_end = hdr.payload + hdr.length;
341
342
18.6k
    if (asn1_get_oid(seq_pos, seq_end - seq_pos, &oid, &seq_pos)) {
343
11
      x509_free_name(name);
344
11
      return -1;
345
11
    }
346
347
18.6k
    if (asn1_get_next(seq_pos, seq_end - seq_pos, &hdr) < 0 ||
348
18.6k
        hdr.class != ASN1_CLASS_UNIVERSAL) {
349
16
      wpa_printf(MSG_DEBUG, "X509: Failed to parse "
350
16
           "AttributeValue");
351
16
      x509_free_name(name);
352
16
      return -1;
353
16
    }
354
355
18.6k
    if (!asn1_is_string_type(&hdr)) {
356
8.57k
      wpa_printf(MSG_DEBUG,
357
8.57k
           "X509: Ignore non-string type attribute (tag 0x%x)",
358
8.57k
           hdr.tag);
359
8.57k
      continue;
360
8.57k
    }
361
362
    /* RFC 3280:
363
     * MUST: country, organization, organizational-unit,
364
     * distinguished name qualifier, state or province name,
365
     * common name, serial number.
366
     * SHOULD: locality, title, surname, given name, initials,
367
     * pseudonym, generation qualifier.
368
     * MUST: domainComponent (RFC 2247).
369
     */
370
10.0k
    type = X509_NAME_ATTR_NOT_USED;
371
10.0k
    if (oid.len == 4 &&
372
10.0k
        oid.oid[0] == 2 && oid.oid[1] == 5 && oid.oid[2] == 4) {
373
      /* id-at ::= 2.5.4 */
374
987
      switch (oid.oid[3]) {
375
102
      case 3:
376
        /* commonName */
377
102
        type = X509_NAME_ATTR_CN;
378
102
        break;
379
119
      case 6:
380
        /*  countryName */
381
119
        type = X509_NAME_ATTR_C;
382
119
        break;
383
131
      case 7:
384
        /* localityName */
385
131
        type = X509_NAME_ATTR_L;
386
131
        break;
387
103
      case 8:
388
        /* stateOrProvinceName */
389
103
        type = X509_NAME_ATTR_ST;
390
103
        break;
391
78
      case 10:
392
        /* organizationName */
393
78
        type = X509_NAME_ATTR_O;
394
78
        break;
395
135
      case 11:
396
        /* organizationalUnitName */
397
135
        type = X509_NAME_ATTR_OU;
398
135
        break;
399
987
      }
400
9.10k
    } else if (oid.len == 7 &&
401
9.10k
         oid.oid[0] == 1 && oid.oid[1] == 2 &&
402
9.10k
         oid.oid[2] == 840 && oid.oid[3] == 113549 &&
403
9.10k
         oid.oid[4] == 1 && oid.oid[5] == 9 &&
404
9.10k
         oid.oid[6] == 1) {
405
      /* 1.2.840.113549.1.9.1 - e-mailAddress */
406
240
      os_free(name->email);
407
240
      name->email = os_malloc(hdr.length + 1);
408
240
      if (name->email == NULL) {
409
0
        x509_free_name(name);
410
0
        return -1;
411
0
      }
412
240
      os_memcpy(name->email, hdr.payload, hdr.length);
413
240
      name->email[hdr.length] = '\0';
414
240
      continue;
415
8.86k
    } else if (oid.len == 7 &&
416
8.86k
         oid.oid[0] == 0 && oid.oid[1] == 9 &&
417
8.86k
         oid.oid[2] == 2342 && oid.oid[3] == 19200300 &&
418
8.86k
         oid.oid[4] == 100 && oid.oid[5] == 1 &&
419
8.86k
         oid.oid[6] == 25) {
420
      /* 0.9.2342.19200300.100.1.25 - domainComponent */
421
60
      type = X509_NAME_ATTR_DC;
422
60
    }
423
424
9.85k
    if (type == X509_NAME_ATTR_NOT_USED) {
425
9.12k
      wpa_hexdump(MSG_DEBUG, "X509: Unrecognized OID",
426
9.12k
            (u8 *) oid.oid,
427
9.12k
            oid.len * sizeof(oid.oid[0]));
428
9.12k
      wpa_hexdump_ascii(MSG_MSGDUMP, "X509: Attribute Data",
429
9.12k
            hdr.payload, hdr.length);
430
9.12k
      continue;
431
9.12k
    }
432
433
728
    if (name->num_attr == X509_MAX_NAME_ATTRIBUTES) {
434
1
      wpa_printf(MSG_INFO, "X509: Too many Name attributes");
435
1
      x509_free_name(name);
436
1
      return -1;
437
1
    }
438
439
727
    val = dup_binstr(hdr.payload, hdr.length);
440
727
    if (val == NULL) {
441
0
      x509_free_name(name);
442
0
      return -1;
443
0
    }
444
727
    if (os_strlen(val) != hdr.length) {
445
10
      wpa_printf(MSG_INFO, "X509: Reject certificate with "
446
10
           "embedded NUL byte in a string (%s[NUL])",
447
10
           val);
448
10
      os_free(val);
449
10
      x509_free_name(name);
450
10
      return -1;
451
10
    }
452
453
717
    name->attr[name->num_attr].type = type;
454
717
    name->attr[name->num_attr].value = val;
455
717
    name->num_attr++;
456
717
  }
457
458
8.78k
  return 0;
459
9.26k
}
460
461
462
static char * x509_name_attr_str(enum x509_name_attr_type type)
463
462
{
464
462
  switch (type) {
465
0
  case X509_NAME_ATTR_NOT_USED:
466
0
    return "[N/A]";
467
32
  case X509_NAME_ATTR_DC:
468
32
    return "DC";
469
41
  case X509_NAME_ATTR_CN:
470
41
    return "CN";
471
74
  case X509_NAME_ATTR_C:
472
74
    return "C";
473
81
  case X509_NAME_ATTR_L:
474
81
    return "L";
475
91
  case X509_NAME_ATTR_ST:
476
91
    return "ST";
477
46
  case X509_NAME_ATTR_O:
478
46
    return "O";
479
97
  case X509_NAME_ATTR_OU:
480
97
    return "OU";
481
462
  }
482
0
  return "?";
483
462
}
484
485
486
/**
487
 * x509_name_string - Convert an X.509 certificate name into a string
488
 * @name: Name to convert
489
 * @buf: Buffer for the string
490
 * @len: Maximum buffer length
491
 */
492
void x509_name_string(struct x509_name *name, char *buf, size_t len)
493
8.78k
{
494
8.78k
  char *pos, *end;
495
8.78k
  int ret;
496
8.78k
  size_t i;
497
498
8.78k
  if (len == 0)
499
0
    return;
500
501
8.78k
  pos = buf;
502
8.78k
  end = buf + len;
503
504
9.24k
  for (i = 0; i < name->num_attr; i++) {
505
462
    ret = os_snprintf(pos, end - pos, "%s=%s, ",
506
462
          x509_name_attr_str(name->attr[i].type),
507
462
          name->attr[i].value);
508
462
    if (os_snprintf_error(end - pos, ret))
509
6
      goto done;
510
456
    pos += ret;
511
456
  }
512
513
8.78k
  if (pos > buf + 1 && pos[-1] == ' ' && pos[-2] == ',') {
514
122
    pos--;
515
122
    *pos = '\0';
516
122
    pos--;
517
122
    *pos = '\0';
518
122
  }
519
520
8.78k
  if (name->email) {
521
16
    ret = os_snprintf(pos, end - pos, "/emailAddress=%s",
522
16
          name->email);
523
16
    if (os_snprintf_error(end - pos, ret))
524
3
      goto done;
525
13
    pos += ret;
526
13
  }
527
528
8.78k
done:
529
8.78k
  if (pos < end)
530
8.78k
    *pos = '\0';
531
8.78k
  end[-1] = '\0';
532
8.78k
}
533
534
535
static int parse_uint2(const char *pos, size_t len)
536
44.1k
{
537
44.1k
  char buf[3];
538
44.1k
  int ret;
539
540
44.1k
  if (len < 2)
541
0
    return -1;
542
44.1k
  buf[0] = pos[0];
543
44.1k
  buf[1] = pos[1];
544
44.1k
  buf[2] = 0x00;
545
44.1k
  if (sscanf(buf, "%2d", &ret) != 1)
546
21
    return -1;
547
44.1k
  return ret;
548
44.1k
}
549
550
551
static int parse_uint4(const char *pos, size_t len)
552
71
{
553
71
  char buf[5];
554
71
  int ret;
555
556
71
  if (len < 4)
557
0
    return -1;
558
71
  buf[0] = pos[0];
559
71
  buf[1] = pos[1];
560
71
  buf[2] = pos[2];
561
71
  buf[3] = pos[3];
562
71
  buf[4] = 0x00;
563
71
  if (sscanf(buf, "%4d", &ret) != 1)
564
2
    return -1;
565
69
  return ret;
566
71
}
567
568
569
int x509_parse_time(const u8 *buf, size_t len, u8 asn1_tag, os_time_t *val)
570
7.43k
{
571
7.43k
  const char *pos, *end;
572
7.43k
  int year, month, day, hour, min, sec;
573
574
  /*
575
   * Time ::= CHOICE {
576
   *     utcTime        UTCTime,
577
   *     generalTime    GeneralizedTime
578
   * }
579
   *
580
   * UTCTime: YYMMDDHHMMSSZ
581
   * GeneralizedTime: YYYYMMDDHHMMSSZ
582
   */
583
584
7.43k
  pos = (const char *) buf;
585
7.43k
  end = pos + len;
586
587
7.43k
  switch (asn1_tag) {
588
7.34k
  case ASN1_TAG_UTCTIME:
589
7.34k
    if (len != 13 || buf[12] != 'Z') {
590
16
      wpa_hexdump_ascii(MSG_DEBUG, "X509: Unrecognized "
591
16
            "UTCTime format", buf, len);
592
16
      return -1;
593
16
    }
594
7.32k
    year = parse_uint2(pos, end - pos);
595
7.32k
    if (year < 0) {
596
5
      wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse "
597
5
            "UTCTime year", buf, len);
598
5
      return -1;
599
5
    }
600
7.32k
    if (year < 50)
601
6.13k
      year += 2000;
602
1.18k
    else
603
1.18k
      year += 1900;
604
7.32k
    pos += 2;
605
7.32k
    break;
606
95
  case ASN1_TAG_GENERALIZEDTIME:
607
95
    if (len != 15 || buf[14] != 'Z') {
608
24
      wpa_hexdump_ascii(MSG_DEBUG, "X509: Unrecognized "
609
24
            "GeneralizedTime format", buf, len);
610
24
      return -1;
611
24
    }
612
71
    year = parse_uint4(pos, end - pos);
613
71
    if (year < 0) {
614
13
      wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse "
615
13
            "GeneralizedTime year", buf, len);
616
13
      return -1;
617
13
    }
618
58
    pos += 4;
619
58
    break;
620
0
  default:
621
0
    wpa_printf(MSG_DEBUG, "X509: Expected UTCTime or "
622
0
         "GeneralizedTime - found tag 0x%x", asn1_tag);
623
0
    return -1;
624
7.43k
  }
625
626
7.37k
  month = parse_uint2(pos, end - pos);
627
7.37k
  if (month < 0) {
628
11
    wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time "
629
11
          "(month)", buf, len);
630
11
    return -1;
631
11
  }
632
7.36k
  pos += 2;
633
634
7.36k
  day = parse_uint2(pos, end - pos);
635
7.36k
  if (day < 0) {
636
8
    wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time "
637
8
          "(day)", buf, len);
638
8
    return -1;
639
8
  }
640
7.36k
  pos += 2;
641
642
7.36k
  hour = parse_uint2(pos, end - pos);
643
7.36k
  if (hour < 0) {
644
5
    wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time "
645
5
          "(hour)", buf, len);
646
5
    return -1;
647
5
  }
648
7.35k
  pos += 2;
649
650
7.35k
  min = parse_uint2(pos, end - pos);
651
7.35k
  if (min < 0) {
652
9
    wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time "
653
9
          "(min)", buf, len);
654
9
    return -1;
655
9
  }
656
7.34k
  pos += 2;
657
658
7.34k
  sec = parse_uint2(pos, end - pos);
659
7.34k
  if (sec < 0) {
660
6
    wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time "
661
6
          "(sec)", buf, len);
662
6
    return -1;
663
6
  }
664
665
7.34k
  if (os_mktime(year, month, day, hour, min, sec, val) < 0) {
666
1.00k
    wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to convert Time",
667
1.00k
          buf, len);
668
1.00k
    if (year < 1970) {
669
      /*
670
       * At least some test certificates have been configured
671
       * to use dates prior to 1970. Set the date to
672
       * beginning of 1970 to handle these case.
673
       */
674
975
      wpa_printf(MSG_DEBUG, "X509: Year=%d before epoch - "
675
975
           "assume epoch as the time", year);
676
975
      *val = 0;
677
975
      return 0;
678
975
    }
679
31
    return -1;
680
1.00k
  }
681
682
6.33k
  return 0;
683
7.34k
}
684
685
686
static int x509_parse_validity(const u8 *buf, size_t len,
687
             struct x509_certificate *cert, const u8 **next)
688
5.19k
{
689
5.19k
  struct asn1_hdr hdr;
690
5.19k
  const u8 *pos;
691
5.19k
  size_t plen;
692
693
  /*
694
   * Validity ::= SEQUENCE {
695
   *     notBefore      Time,
696
   *     notAfter       Time
697
   * }
698
   *
699
   * RFC 3280, 4.1.2.5:
700
   * CAs conforming to this profile MUST always encode certificate
701
   * validity dates through the year 2049 as UTCTime; certificate
702
   * validity dates in 2050 or later MUST be encoded as GeneralizedTime.
703
   */
704
705
5.19k
  if (asn1_get_next(buf, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
706
1.32k
    asn1_unexpected(&hdr, "X509: Expected SEQUENCE (Validity)");
707
1.32k
    return -1;
708
1.32k
  }
709
3.86k
  pos = hdr.payload;
710
3.86k
  plen = hdr.length;
711
712
3.86k
  if (plen > (size_t) (buf + len - pos))
713
0
    return -1;
714
715
3.86k
  *next = pos + plen;
716
717
3.86k
  if (asn1_get_next(pos, plen, &hdr) < 0 ||
718
3.86k
      (!asn1_is_utctime(&hdr) && !asn1_is_generalizedtime(&hdr)) ||
719
3.86k
      x509_parse_time(hdr.payload, hdr.length, hdr.tag,
720
3.81k
          &cert->not_before) < 0) {
721
177
    wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse notBefore "
722
177
          "Time", hdr.payload, hdr.length);
723
177
    return -1;
724
177
  }
725
726
3.68k
  pos = hdr.payload + hdr.length;
727
3.68k
  plen = *next - pos;
728
729
3.68k
  if (asn1_get_next(pos, plen, &hdr) < 0 ||
730
3.68k
      (!asn1_is_utctime(&hdr) && !asn1_is_generalizedtime(&hdr)) ||
731
3.68k
      x509_parse_time(hdr.payload, hdr.length, hdr.tag,
732
3.62k
          &cert->not_after) < 0) {
733
65
    wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse notAfter "
734
65
          "Time", hdr.payload, hdr.length);
735
65
    return -1;
736
65
  }
737
738
3.62k
  wpa_printf(MSG_MSGDUMP, "X509: Validity: notBefore: %lu notAfter: %lu",
739
3.62k
       (unsigned long) cert->not_before,
740
3.62k
       (unsigned long) cert->not_after);
741
742
3.62k
  return 0;
743
3.68k
}
744
745
746
static int x509_id_ce_oid(struct asn1_oid *oid)
747
13.9k
{
748
  /* id-ce arc from X.509 for standard X.509v3 extensions */
749
13.9k
  return oid->len >= 4 &&
750
13.9k
    oid->oid[0] == 2 /* joint-iso-ccitt */ &&
751
13.9k
    oid->oid[1] == 5 /* ds */ &&
752
13.9k
    oid->oid[2] == 29 /* id-ce */;
753
13.9k
}
754
755
756
static int x509_any_ext_key_usage_oid(struct asn1_oid *oid)
757
8.42k
{
758
8.42k
  return oid->len == 6 &&
759
8.42k
    x509_id_ce_oid(oid) &&
760
8.42k
    oid->oid[3] == 37 /* extKeyUsage */ &&
761
8.42k
    oid->oid[4] == 0 /* anyExtendedKeyUsage */;
762
8.42k
}
763
764
765
static int x509_parse_ext_key_usage(struct x509_certificate *cert,
766
            const u8 *pos, size_t len)
767
1.60k
{
768
1.60k
  struct asn1_hdr hdr;
769
770
  /*
771
   * KeyUsage ::= BIT STRING {
772
   *     digitalSignature        (0),
773
   *     nonRepudiation          (1),
774
   *     keyEncipherment         (2),
775
   *     dataEncipherment        (3),
776
   *     keyAgreement            (4),
777
   *     keyCertSign             (5),
778
   *     cRLSign                 (6),
779
   *     encipherOnly            (7),
780
   *     decipherOnly            (8) }
781
   */
782
783
1.60k
  if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_bitstring(&hdr) ||
784
1.60k
      hdr.length < 1) {
785
37
    asn1_unexpected(&hdr, "X509: Expected BIT STRING in KeyUsage");
786
37
    return -1;
787
37
  }
788
789
1.56k
  cert->extensions_present |= X509_EXT_KEY_USAGE;
790
1.56k
  cert->key_usage = asn1_bit_string_to_long(hdr.payload, hdr.length);
791
792
1.56k
  wpa_printf(MSG_DEBUG, "X509: KeyUsage 0x%lx", cert->key_usage);
793
794
1.56k
  return 0;
795
1.60k
}
796
797
798
static int x509_parse_ext_basic_constraints(struct x509_certificate *cert,
799
              const u8 *pos, size_t len)
800
1.02k
{
801
1.02k
  struct asn1_hdr hdr;
802
1.02k
  unsigned long value;
803
1.02k
  size_t left;
804
1.02k
  const u8 *end_seq;
805
806
  /*
807
   * BasicConstraints ::= SEQUENCE {
808
   * cA                      BOOLEAN DEFAULT FALSE,
809
   * pathLenConstraint       INTEGER (0..MAX) OPTIONAL }
810
   */
811
812
1.02k
  if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
813
35
    asn1_unexpected(&hdr,
814
35
        "X509: Expected SEQUENCE in BasicConstraints");
815
35
    return -1;
816
35
  }
817
818
991
  cert->extensions_present |= X509_EXT_BASIC_CONSTRAINTS;
819
820
991
  if (hdr.length == 0)
821
312
    return 0;
822
823
679
  end_seq = hdr.payload + hdr.length;
824
679
  if (asn1_get_next(hdr.payload, hdr.length, &hdr) < 0) {
825
6
    wpa_printf(MSG_DEBUG, "X509: Failed to parse "
826
6
         "BasicConstraints");
827
6
    return -1;
828
6
  }
829
830
673
  if (asn1_is_boolean(&hdr)) {
831
185
    cert->ca = hdr.payload[0];
832
833
185
    pos = hdr.payload + hdr.length;
834
185
    if (pos >= end_seq) {
835
      /* No optional pathLenConstraint */
836
106
      wpa_printf(MSG_DEBUG, "X509: BasicConstraints - cA=%d",
837
106
           cert->ca);
838
106
      return 0;
839
106
    }
840
79
    if (asn1_get_next(pos, end_seq - pos, &hdr) < 0) {
841
2
      wpa_printf(MSG_DEBUG, "X509: Failed to parse "
842
2
           "BasicConstraints");
843
2
      return -1;
844
2
    }
845
79
  }
846
847
565
  if (!asn1_is_integer(&hdr)) {
848
30
    asn1_unexpected(&hdr,
849
30
        "X509: Expected INTEGER in BasicConstraints");
850
30
    return -1;
851
30
  }
852
853
535
  pos = hdr.payload;
854
535
  left = hdr.length;
855
535
  value = 0;
856
4.41k
  while (left) {
857
3.88k
    value <<= 8;
858
3.88k
    value |= *pos++;
859
3.88k
    left--;
860
3.88k
  }
861
862
535
  cert->path_len_constraint = value;
863
535
  cert->extensions_present |= X509_EXT_PATH_LEN_CONSTRAINT;
864
865
535
  wpa_printf(MSG_DEBUG, "X509: BasicConstraints - cA=%d "
866
535
       "pathLenConstraint=%lu",
867
535
       cert->ca, cert->path_len_constraint);
868
869
535
  return 0;
870
565
}
871
872
873
static int x509_parse_alt_name_rfc8222(struct x509_name *name,
874
               const u8 *pos, size_t len)
875
1.07k
{
876
  /* rfc822Name IA5String */
877
1.07k
  wpa_hexdump_ascii(MSG_MSGDUMP, "X509: altName - rfc822Name", pos, len);
878
1.07k
  os_free(name->alt_email);
879
1.07k
  name->alt_email = os_zalloc(len + 1);
880
1.07k
  if (name->alt_email == NULL)
881
0
    return -1;
882
1.07k
  os_memcpy(name->alt_email, pos, len);
883
1.07k
  if (os_strlen(name->alt_email) != len) {
884
11
    wpa_printf(MSG_INFO, "X509: Reject certificate with "
885
11
         "embedded NUL byte in rfc822Name (%s[NUL])",
886
11
         name->alt_email);
887
11
    os_free(name->alt_email);
888
11
    name->alt_email = NULL;
889
11
    return -1;
890
11
  }
891
1.06k
  return 0;
892
1.07k
}
893
894
895
static int x509_parse_alt_name_dns(struct x509_name *name,
896
           const u8 *pos, size_t len)
897
1.15k
{
898
  /* dNSName IA5String */
899
1.15k
  wpa_hexdump_ascii(MSG_MSGDUMP, "X509: altName - dNSName", pos, len);
900
1.15k
  os_free(name->dns);
901
1.15k
  name->dns = os_zalloc(len + 1);
902
1.15k
  if (name->dns == NULL)
903
0
    return -1;
904
1.15k
  os_memcpy(name->dns, pos, len);
905
1.15k
  if (os_strlen(name->dns) != len) {
906
2
    wpa_printf(MSG_INFO, "X509: Reject certificate with "
907
2
         "embedded NUL byte in dNSName (%s[NUL])",
908
2
         name->dns);
909
2
    os_free(name->dns);
910
2
    name->dns = NULL;
911
2
    return -1;
912
2
  }
913
1.15k
  return 0;
914
1.15k
}
915
916
917
static int x509_parse_alt_name_uri(struct x509_name *name,
918
           const u8 *pos, size_t len)
919
826
{
920
  /* uniformResourceIdentifier IA5String */
921
826
  wpa_hexdump_ascii(MSG_MSGDUMP,
922
826
        "X509: altName - uniformResourceIdentifier",
923
826
        pos, len);
924
826
  os_free(name->uri);
925
826
  name->uri = os_zalloc(len + 1);
926
826
  if (name->uri == NULL)
927
0
    return -1;
928
826
  os_memcpy(name->uri, pos, len);
929
826
  if (os_strlen(name->uri) != len) {
930
13
    wpa_printf(MSG_INFO, "X509: Reject certificate with "
931
13
         "embedded NUL byte in uniformResourceIdentifier "
932
13
         "(%s[NUL])", name->uri);
933
13
    os_free(name->uri);
934
13
    name->uri = NULL;
935
13
    return -1;
936
13
  }
937
813
  return 0;
938
826
}
939
940
941
static int x509_parse_alt_name_ip(struct x509_name *name,
942
               const u8 *pos, size_t len)
943
660
{
944
  /* iPAddress OCTET STRING */
945
660
  wpa_hexdump(MSG_MSGDUMP, "X509: altName - iPAddress", pos, len);
946
660
  os_free(name->ip);
947
660
  name->ip = os_memdup(pos, len);
948
660
  if (name->ip == NULL)
949
0
    return -1;
950
660
  name->ip_len = len;
951
660
  return 0;
952
660
}
953
954
955
static int x509_parse_alt_name_rid(struct x509_name *name,
956
           const u8 *pos, size_t len)
957
3.31k
{
958
3.31k
  char buf[80];
959
960
  /* registeredID OBJECT IDENTIFIER */
961
3.31k
  if (asn1_parse_oid(pos, len, &name->rid) < 0)
962
51
    return -1;
963
964
3.26k
  asn1_oid_to_str(&name->rid, buf, sizeof(buf));
965
3.26k
  wpa_printf(MSG_MSGDUMP, "X509: altName - registeredID: %s", buf);
966
967
3.26k
  return 0;
968
3.31k
}
969
970
971
static int x509_parse_ext_alt_name(struct x509_name *name,
972
           const u8 *pos, size_t len)
973
774
{
974
774
  struct asn1_hdr hdr;
975
774
  const u8 *p, *end;
976
977
  /*
978
   * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
979
   *
980
   * GeneralName ::= CHOICE {
981
   *     otherName                       [0]     OtherName,
982
   *     rfc822Name                      [1]     IA5String,
983
   *     dNSName                         [2]     IA5String,
984
   *     x400Address                     [3]     ORAddress,
985
   *     directoryName                   [4]     Name,
986
   *     ediPartyName                    [5]     EDIPartyName,
987
   *     uniformResourceIdentifier       [6]     IA5String,
988
   *     iPAddress                       [7]     OCTET STRING,
989
   *     registeredID                    [8]     OBJECT IDENTIFIER }
990
   *
991
   * OtherName ::= SEQUENCE {
992
   *     type-id    OBJECT IDENTIFIER,
993
   *     value      [0] EXPLICIT ANY DEFINED BY type-id }
994
   *
995
   * EDIPartyName ::= SEQUENCE {
996
   *     nameAssigner            [0]     DirectoryString OPTIONAL,
997
   *     partyName               [1]     DirectoryString }
998
   */
999
1000
13.1k
  for (p = pos, end = pos + len; p < end; p = hdr.payload + hdr.length) {
1001
12.5k
    int res;
1002
1003
12.5k
    if (asn1_get_next(p, end - p, &hdr) < 0) {
1004
98
      wpa_printf(MSG_DEBUG, "X509: Failed to parse "
1005
98
           "SubjectAltName item");
1006
98
      return -1;
1007
98
    }
1008
1009
12.4k
    if (hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC)
1010
4.36k
      continue;
1011
1012
8.08k
    switch (hdr.tag) {
1013
1.07k
    case 1:
1014
1.07k
      res = x509_parse_alt_name_rfc8222(name, hdr.payload,
1015
1.07k
                hdr.length);
1016
1.07k
      break;
1017
1.15k
    case 2:
1018
1.15k
      res = x509_parse_alt_name_dns(name, hdr.payload,
1019
1.15k
                  hdr.length);
1020
1.15k
      break;
1021
826
    case 6:
1022
826
      res = x509_parse_alt_name_uri(name, hdr.payload,
1023
826
                  hdr.length);
1024
826
      break;
1025
660
    case 7:
1026
660
      res = x509_parse_alt_name_ip(name, hdr.payload,
1027
660
                 hdr.length);
1028
660
      break;
1029
3.31k
    case 8:
1030
3.31k
      res = x509_parse_alt_name_rid(name, hdr.payload,
1031
3.31k
                  hdr.length);
1032
3.31k
      break;
1033
206
    case 0: /* TODO: otherName */
1034
208
    case 3: /* TODO: x500Address */
1035
215
    case 4: /* TODO: directoryName */
1036
661
    case 5: /* TODO: ediPartyName */
1037
1.04k
    default:
1038
1.04k
      res = 0;
1039
1.04k
      break;
1040
8.08k
    }
1041
8.08k
    if (res < 0)
1042
77
      return res;
1043
8.08k
  }
1044
1045
599
  return 0;
1046
774
}
1047
1048
1049
static int x509_parse_ext_subject_alt_name(struct x509_certificate *cert,
1050
             const u8 *pos, size_t len)
1051
436
{
1052
436
  struct asn1_hdr hdr;
1053
1054
  /* SubjectAltName ::= GeneralNames */
1055
1056
436
  if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
1057
20
    asn1_unexpected(&hdr,
1058
20
        "X509: Expected SEQUENCE in SubjectAltName");
1059
20
    return -1;
1060
20
  }
1061
1062
416
  wpa_printf(MSG_DEBUG, "X509: SubjectAltName");
1063
416
  cert->extensions_present |= X509_EXT_SUBJECT_ALT_NAME;
1064
1065
416
  if (hdr.length == 0)
1066
110
    return 0;
1067
1068
306
  return x509_parse_ext_alt_name(&cert->subject, hdr.payload,
1069
306
               hdr.length);
1070
416
}
1071
1072
1073
static int x509_parse_ext_issuer_alt_name(struct x509_certificate *cert,
1074
            const u8 *pos, size_t len)
1075
744
{
1076
744
  struct asn1_hdr hdr;
1077
1078
  /* IssuerAltName ::= GeneralNames */
1079
1080
744
  if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
1081
7
    asn1_unexpected(&hdr,
1082
7
        "X509: Expected SEQUENCE in IssuerAltName");
1083
7
    return -1;
1084
7
  }
1085
1086
737
  wpa_printf(MSG_DEBUG, "X509: IssuerAltName");
1087
737
  cert->extensions_present |= X509_EXT_ISSUER_ALT_NAME;
1088
1089
737
  if (hdr.length == 0)
1090
269
    return 0;
1091
1092
468
  return x509_parse_ext_alt_name(&cert->issuer, hdr.payload,
1093
468
               hdr.length);
1094
737
}
1095
1096
1097
static int x509_id_cert_policy_any_oid(struct asn1_oid *oid)
1098
6.33k
{
1099
6.33k
  return oid->len == 5 &&
1100
6.33k
    oid->oid[0] == 2 /* iso/itu-t */ &&
1101
6.33k
    oid->oid[1] == 5 /* X.500 Directory Services */ &&
1102
6.33k
    oid->oid[2] == 29 /* id-ce */ &&
1103
6.33k
    oid->oid[3] == 32 /* id-ce-certificate-policies */ &&
1104
6.33k
    oid->oid[4] == 0 /* anyPolicy */;
1105
6.33k
}
1106
1107
1108
static int x509_id_wfa_oid(struct asn1_oid *oid)
1109
5.37k
{
1110
5.37k
  return oid->len >= 7 &&
1111
5.37k
    oid->oid[0] == 1 /* iso */ &&
1112
5.37k
    oid->oid[1] == 3 /* identified-organization */ &&
1113
5.37k
    oid->oid[2] == 6 /* dod */ &&
1114
5.37k
    oid->oid[3] == 1 /* internet */ &&
1115
5.37k
    oid->oid[4] == 4 /* private */ &&
1116
5.37k
    oid->oid[5] == 1 /* enterprise */ &&
1117
5.37k
    oid->oid[6] == 40808 /* WFA */;
1118
5.37k
}
1119
1120
1121
static int x509_id_wfa_tod_oid(struct asn1_oid *oid)
1122
5.37k
{
1123
5.37k
  return oid->len >= 9 &&
1124
5.37k
    x509_id_wfa_oid(oid) &&
1125
5.37k
    oid->oid[7] == 1 &&
1126
5.37k
    oid->oid[8] == 3;
1127
5.37k
}
1128
1129
1130
static int x509_id_wfa_tod_strict_oid(struct asn1_oid *oid)
1131
5.97k
{
1132
5.97k
  return oid->len == 10 &&
1133
5.97k
    x509_id_wfa_tod_oid(oid) &&
1134
5.97k
    oid->oid[9] == 1;
1135
5.97k
}
1136
1137
1138
static int x509_id_wfa_tod_tofu_oid(struct asn1_oid *oid)
1139
5.86k
{
1140
5.86k
  return oid->len == 10 &&
1141
5.86k
    x509_id_wfa_tod_oid(oid) &&
1142
5.86k
    oid->oid[9] == 2;
1143
5.86k
}
1144
1145
1146
static int x509_parse_ext_certificate_policies(struct x509_certificate *cert,
1147
                 const u8 *pos, size_t len)
1148
1.63k
{
1149
1.63k
  struct asn1_hdr hdr;
1150
1.63k
  const u8 *end;
1151
1152
  /*
1153
   * certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
1154
   *
1155
   * PolicyInformation ::= SEQUENCE {
1156
   *      policyIdentifier   CertPolicyId,
1157
   *      policyQualifiers   SEQUENCE SIZE (1..MAX) OF
1158
   *                              PolicyQualifierInfo OPTIONAL }
1159
   *
1160
   * CertPolicyId ::= OBJECT IDENTIFIER
1161
   */
1162
1163
1.63k
  if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
1164
35
    asn1_unexpected(&hdr,
1165
35
        "X509: Expected SEQUENCE (certificatePolicies)");
1166
35
    return -1;
1167
35
  }
1168
1.59k
  if (hdr.length > pos + len - hdr.payload)
1169
0
    return -1;
1170
1.59k
  pos = hdr.payload;
1171
1.59k
  end = pos + hdr.length;
1172
1173
1.59k
  wpa_hexdump(MSG_MSGDUMP, "X509: certificatePolicies", pos, end - pos);
1174
1175
7.93k
  while (pos < end) {
1176
7.43k
    const u8 *pol_end;
1177
7.43k
    struct asn1_oid oid;
1178
7.43k
    char buf[80];
1179
1180
7.43k
    if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1181
7.43k
        !asn1_is_sequence(&hdr)) {
1182
1.05k
      asn1_unexpected(&hdr,
1183
1.05k
          "X509: Expected SEQUENCE (PolicyInformation)");
1184
1.05k
      return -1;
1185
1.05k
    }
1186
6.38k
    if (hdr.length > end - hdr.payload)
1187
0
      return -1;
1188
6.38k
    pos = hdr.payload;
1189
6.38k
    pol_end = pos + hdr.length;
1190
6.38k
    wpa_hexdump(MSG_MSGDUMP, "X509: PolicyInformation",
1191
6.38k
          pos, pol_end - pos);
1192
1193
6.38k
    if (asn1_get_oid(pos, pol_end - pos, &oid, &pos))
1194
43
      return -1;
1195
6.33k
    if (x509_id_cert_policy_any_oid(&oid)) {
1196
363
      os_strlcpy(buf, "anyPolicy-STRICT", sizeof(buf));
1197
363
      cert->certificate_policy |=
1198
363
        X509_EXT_CERT_POLICY_ANY;
1199
5.97k
    } else if (x509_id_wfa_tod_strict_oid(&oid)) {
1200
106
      os_strlcpy(buf, "TOD-STRICT", sizeof(buf));
1201
106
      cert->certificate_policy |=
1202
106
        X509_EXT_CERT_POLICY_TOD_STRICT;
1203
5.86k
    } else if (x509_id_wfa_tod_tofu_oid(&oid)) {
1204
372
      os_strlcpy(buf, "TOD-TOFU", sizeof(buf));
1205
372
      cert->certificate_policy |=
1206
372
        X509_EXT_CERT_POLICY_TOD_TOFU;
1207
5.49k
    } else {
1208
5.49k
      asn1_oid_to_str(&oid, buf, sizeof(buf));
1209
5.49k
    }
1210
6.33k
    wpa_printf(MSG_DEBUG, "policyIdentifier: %s", buf);
1211
1212
6.33k
    pos = pol_end;
1213
6.33k
  }
1214
1215
499
  cert->extensions_present |= X509_EXT_CERTIFICATE_POLICY;
1216
1217
499
  return 0;
1218
1.59k
}
1219
1220
1221
static int x509_id_pkix_oid(struct asn1_oid *oid)
1222
12.1k
{
1223
12.1k
  return oid->len >= 7 &&
1224
12.1k
    oid->oid[0] == 1 /* iso */ &&
1225
12.1k
    oid->oid[1] == 3 /* identified-organization */ &&
1226
12.1k
    oid->oid[2] == 6 /* dod */ &&
1227
12.1k
    oid->oid[3] == 1 /* internet */ &&
1228
12.1k
    oid->oid[4] == 5 /* security */ &&
1229
12.1k
    oid->oid[5] == 5 /* mechanisms */ &&
1230
12.1k
    oid->oid[6] == 7 /* id-pkix */;
1231
12.1k
}
1232
1233
1234
static int x509_id_kp_oid(struct asn1_oid *oid)
1235
12.1k
{
1236
  /* id-kp */
1237
12.1k
  return oid->len >= 8 &&
1238
12.1k
    x509_id_pkix_oid(oid) &&
1239
12.1k
    oid->oid[7] == 3 /* id-kp */;
1240
12.1k
}
1241
1242
1243
static int x509_id_kp_server_auth_oid(struct asn1_oid *oid)
1244
7.92k
{
1245
  /* id-kp */
1246
7.92k
  return oid->len == 9 &&
1247
7.92k
    x509_id_kp_oid(oid) &&
1248
7.92k
    oid->oid[8] == 1 /* id-kp-serverAuth */;
1249
7.92k
}
1250
1251
1252
static int x509_id_kp_client_auth_oid(struct asn1_oid *oid)
1253
7.80k
{
1254
  /* id-kp */
1255
7.80k
  return oid->len == 9 &&
1256
7.80k
    x509_id_kp_oid(oid) &&
1257
7.80k
    oid->oid[8] == 2 /* id-kp-clientAuth */;
1258
7.80k
}
1259
1260
1261
static int x509_id_kp_ocsp_oid(struct asn1_oid *oid)
1262
7.64k
{
1263
  /* id-kp */
1264
7.64k
  return oid->len == 9 &&
1265
7.64k
    x509_id_kp_oid(oid) &&
1266
7.64k
    oid->oid[8] == 9 /* id-kp-OCSPSigning */;
1267
7.64k
}
1268
1269
1270
static int x509_parse_ext_ext_key_usage(struct x509_certificate *cert,
1271
          const u8 *pos, size_t len)
1272
2.67k
{
1273
2.67k
  struct asn1_hdr hdr;
1274
2.67k
  const u8 *end;
1275
2.67k
  struct asn1_oid oid;
1276
1277
  /*
1278
   * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
1279
   *
1280
   * KeyPurposeId ::= OBJECT IDENTIFIER
1281
   */
1282
1283
2.67k
  if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
1284
42
    asn1_unexpected(&hdr,
1285
42
        "X509: Expected SEQUENCE (ExtKeyUsageSyntax)");
1286
42
    return -1;
1287
42
  }
1288
2.63k
  if (hdr.length > pos + len - hdr.payload)
1289
0
    return -1;
1290
2.63k
  pos = hdr.payload;
1291
2.63k
  end = pos + hdr.length;
1292
1293
2.63k
  wpa_hexdump(MSG_MSGDUMP, "X509: ExtKeyUsageSyntax", pos, end - pos);
1294
1295
11.0k
  while (pos < end) {
1296
8.79k
    char buf[80];
1297
1298
8.79k
    if (asn1_get_oid(pos, end - pos, &oid, &pos))
1299
370
      return -1;
1300
8.42k
    if (x509_any_ext_key_usage_oid(&oid)) {
1301
508
      os_strlcpy(buf, "anyExtendedKeyUsage", sizeof(buf));
1302
508
      cert->ext_key_usage |= X509_EXT_KEY_USAGE_ANY;
1303
7.92k
    } else if (x509_id_kp_server_auth_oid(&oid)) {
1304
116
      os_strlcpy(buf, "id-kp-serverAuth", sizeof(buf));
1305
116
      cert->ext_key_usage |= X509_EXT_KEY_USAGE_SERVER_AUTH;
1306
7.80k
    } else if (x509_id_kp_client_auth_oid(&oid)) {
1307
161
      os_strlcpy(buf, "id-kp-clientAuth", sizeof(buf));
1308
161
      cert->ext_key_usage |= X509_EXT_KEY_USAGE_CLIENT_AUTH;
1309
7.64k
    } else if (x509_id_kp_ocsp_oid(&oid)) {
1310
662
      os_strlcpy(buf, "id-kp-OCSPSigning", sizeof(buf));
1311
662
      cert->ext_key_usage |= X509_EXT_KEY_USAGE_OCSP;
1312
6.98k
    } else {
1313
6.98k
      asn1_oid_to_str(&oid, buf, sizeof(buf));
1314
6.98k
    }
1315
8.42k
    wpa_printf(MSG_DEBUG, "ExtKeyUsage KeyPurposeId: %s", buf);
1316
8.42k
  }
1317
1318
2.26k
  cert->extensions_present |= X509_EXT_EXT_KEY_USAGE;
1319
1320
2.26k
  return 0;
1321
2.63k
}
1322
1323
1324
static int x509_parse_extension_data(struct x509_certificate *cert,
1325
             struct asn1_oid *oid,
1326
             const u8 *pos, size_t len)
1327
10.7k
{
1328
10.7k
  if (!x509_id_ce_oid(oid))
1329
2.16k
    return 1;
1330
1331
  /* TODO: add other extensions required by RFC 3280, Ch 4.2:
1332
   * name constraints (section 4.2.1.11)
1333
   * policy constraints (section 4.2.1.12)
1334
   * inhibit any-policy (section 4.2.1.15)
1335
   */
1336
8.57k
  switch (oid->oid[3]) {
1337
1.60k
  case 15: /* id-ce-keyUsage */
1338
1.60k
    return x509_parse_ext_key_usage(cert, pos, len);
1339
436
  case 17: /* id-ce-subjectAltName */
1340
436
    return x509_parse_ext_subject_alt_name(cert, pos, len);
1341
744
  case 18: /* id-ce-issuerAltName */
1342
744
    return x509_parse_ext_issuer_alt_name(cert, pos, len);
1343
1.02k
  case 19: /* id-ce-basicConstraints */
1344
1.02k
    return x509_parse_ext_basic_constraints(cert, pos, len);
1345
1.63k
  case 32: /* id-ce-certificatePolicies */
1346
1.63k
    return x509_parse_ext_certificate_policies(cert, pos, len);
1347
2.67k
  case 37: /* id-ce-extKeyUsage */
1348
2.67k
    return x509_parse_ext_ext_key_usage(cert, pos, len);
1349
461
  default:
1350
461
    return 1;
1351
8.57k
  }
1352
8.57k
}
1353
1354
1355
static int x509_parse_extension(struct x509_certificate *cert,
1356
        const u8 *pos, size_t len, const u8 **next)
1357
11.9k
{
1358
11.9k
  const u8 *end;
1359
11.9k
  struct asn1_hdr hdr;
1360
11.9k
  struct asn1_oid oid;
1361
11.9k
  int critical_ext = 0, res;
1362
11.9k
  char buf[80];
1363
1364
  /*
1365
   * Extension  ::=  SEQUENCE  {
1366
   *     extnID      OBJECT IDENTIFIER,
1367
   *     critical    BOOLEAN DEFAULT FALSE,
1368
   *     extnValue   OCTET STRING
1369
   * }
1370
   */
1371
1372
11.9k
  if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
1373
1.06k
    asn1_unexpected(&hdr, "X509: Expected SEQUENCE in Extensions");
1374
1.06k
    return -1;
1375
1.06k
  }
1376
10.8k
  pos = hdr.payload;
1377
10.8k
  *next = end = pos + hdr.length;
1378
1379
10.8k
  if (asn1_get_oid(pos, end - pos, &oid, &pos) < 0) {
1380
30
    wpa_printf(MSG_DEBUG, "X509: Unexpected ASN.1 data for "
1381
30
         "Extension (expected OID)");
1382
30
    return -1;
1383
30
  }
1384
1385
10.8k
  if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1386
10.8k
      (!asn1_is_boolean(&hdr) && !asn1_is_octetstring(&hdr))) {
1387
78
    asn1_unexpected(&hdr,
1388
78
        "X509: Expected BOOLEAN or OCTETSTRING in Extensions");
1389
78
    return -1;
1390
78
  }
1391
1392
10.7k
  if (hdr.tag == ASN1_TAG_BOOLEAN) {
1393
1.43k
    critical_ext = hdr.payload[0];
1394
1.43k
    pos = hdr.payload;
1395
    /*
1396
     * Number of CA certificates seem to be using Private class in
1397
     * one of the X.509v3 extensions, so let's accept that instead
1398
     * of rejecting the certificate. asn1_is_octetstring() covers
1399
     * the more common case.
1400
     */
1401
1.43k
    if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1402
1.43k
        (!asn1_is_octetstring(&hdr) &&
1403
1.43k
         !(hdr.class == ASN1_CLASS_PRIVATE &&
1404
1.43k
           hdr.tag == ASN1_TAG_OCTETSTRING))) {
1405
32
      asn1_unexpected(&hdr,
1406
32
          "X509: Expected OCTETSTRING in Extensions");
1407
32
      return -1;
1408
32
    }
1409
1.43k
  }
1410
1411
10.7k
  asn1_oid_to_str(&oid, buf, sizeof(buf));
1412
10.7k
  wpa_printf(MSG_DEBUG, "X509: Extension: extnID=%s critical=%d",
1413
10.7k
       buf, critical_ext);
1414
10.7k
  wpa_hexdump(MSG_MSGDUMP, "X509: extnValue", hdr.payload, hdr.length);
1415
1416
10.7k
  res = x509_parse_extension_data(cert, &oid, hdr.payload, hdr.length);
1417
10.7k
  if (res < 0)
1418
1.85k
    return res;
1419
8.88k
  if (res == 1 && critical_ext) {
1420
5
    wpa_printf(MSG_INFO, "X509: Unknown critical extension %s",
1421
5
         buf);
1422
5
    return -1;
1423
5
  }
1424
1425
8.88k
  return 0;
1426
8.88k
}
1427
1428
1429
static int x509_parse_extensions(struct x509_certificate *cert,
1430
         const u8 *pos, size_t len)
1431
3.25k
{
1432
3.25k
  const u8 *end;
1433
3.25k
  struct asn1_hdr hdr;
1434
1435
  /* Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension */
1436
1437
3.25k
  if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
1438
33
    asn1_unexpected(&hdr, "X509: Expected SEQUENCE for Extensions");
1439
33
    return -1;
1440
33
  }
1441
1442
3.22k
  pos = hdr.payload;
1443
3.22k
  end = pos + hdr.length;
1444
1445
12.1k
  while (pos < end) {
1446
11.9k
    if (x509_parse_extension(cert, pos, end - pos, &pos)
1447
11.9k
        < 0)
1448
3.06k
      return -1;
1449
11.9k
  }
1450
1451
161
  return 0;
1452
3.22k
}
1453
1454
1455
static int x509_parse_tbs_certificate(const u8 *buf, size_t len,
1456
              struct x509_certificate *cert,
1457
              const u8 **next)
1458
6.12k
{
1459
6.12k
  struct asn1_hdr hdr;
1460
6.12k
  const u8 *pos, *end;
1461
6.12k
  size_t left;
1462
6.12k
  char sbuf[128];
1463
6.12k
  unsigned long value;
1464
6.12k
  const u8 *subject_dn;
1465
1466
  /* tbsCertificate TBSCertificate ::= SEQUENCE */
1467
6.12k
  if (asn1_get_next(buf, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
1468
62
    asn1_unexpected(&hdr,
1469
62
        "X509: tbsCertificate did not start with a valid SEQUENCE");
1470
62
    return -1;
1471
62
  }
1472
6.06k
  pos = hdr.payload;
1473
6.06k
  end = *next = pos + hdr.length;
1474
1475
  /*
1476
   * version [0]  EXPLICIT Version DEFAULT v1
1477
   * Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
1478
   */
1479
6.06k
  if (asn1_get_next(pos, end - pos, &hdr) < 0)
1480
5
    return -1;
1481
6.05k
  pos = hdr.payload;
1482
1483
6.05k
  if (asn1_is_cs_tag(&hdr, 0) && hdr.constructed) {
1484
3.47k
    if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1485
3.47k
        !asn1_is_integer(&hdr)) {
1486
34
      asn1_unexpected(&hdr,
1487
34
          "X509: No INTEGER tag found for version field");
1488
34
      return -1;
1489
34
    }
1490
3.43k
    if (hdr.length != 1) {
1491
14
      wpa_printf(MSG_DEBUG, "X509: Unexpected version field "
1492
14
           "length %u (expected 1)", hdr.length);
1493
14
      return -1;
1494
14
    }
1495
3.42k
    pos = hdr.payload;
1496
3.42k
    left = hdr.length;
1497
3.42k
    value = 0;
1498
6.85k
    while (left) {
1499
3.42k
      value <<= 8;
1500
3.42k
      value |= *pos++;
1501
3.42k
      left--;
1502
3.42k
    }
1503
1504
3.42k
    cert->version = value;
1505
3.42k
    if (cert->version != X509_CERT_V1 &&
1506
3.42k
        cert->version != X509_CERT_V2 &&
1507
3.42k
        cert->version != X509_CERT_V3) {
1508
12
      wpa_printf(MSG_DEBUG, "X509: Unsupported version %d",
1509
12
           cert->version + 1);
1510
12
      return -1;
1511
12
    }
1512
1513
3.41k
    if (asn1_get_next(pos, end - pos, &hdr) < 0)
1514
3
      return -1;
1515
3.41k
  } else
1516
2.58k
    cert->version = X509_CERT_V1;
1517
5.99k
  wpa_printf(MSG_MSGDUMP, "X509: Version X.509v%d", cert->version + 1);
1518
1519
  /* serialNumber CertificateSerialNumber ::= INTEGER */
1520
5.99k
  if (!asn1_is_integer(&hdr) ||
1521
5.99k
      hdr.length < 1 || hdr.length > X509_MAX_SERIAL_NUM_LEN) {
1522
78
    asn1_unexpected(&hdr,
1523
78
        "X509: No INTEGER tag found for serialNumber");
1524
78
    return -1;
1525
78
  }
1526
1527
5.91k
  pos = hdr.payload + hdr.length;
1528
6.82k
  while (hdr.length > 0 && hdr.payload[0] == 0) {
1529
908
    hdr.payload++;
1530
908
    hdr.length--;
1531
908
  }
1532
5.91k
  os_memcpy(cert->serial_number, hdr.payload, hdr.length);
1533
5.91k
  cert->serial_number_len = hdr.length;
1534
5.91k
  wpa_hexdump(MSG_MSGDUMP, "X509: serialNumber", cert->serial_number,
1535
5.91k
        cert->serial_number_len);
1536
1537
  /* signature AlgorithmIdentifier */
1538
5.91k
  if (x509_parse_algorithm_identifier(pos, end - pos, &cert->signature,
1539
5.91k
              &pos))
1540
142
    return -1;
1541
1542
  /* issuer Name */
1543
5.77k
  if (x509_parse_name(pos, end - pos, &cert->issuer, &pos))
1544
582
    return -1;
1545
5.19k
  x509_name_string(&cert->issuer, sbuf, sizeof(sbuf));
1546
5.19k
  wpa_printf(MSG_MSGDUMP, "X509: issuer %s", sbuf);
1547
1548
  /* validity Validity */
1549
5.19k
  if (x509_parse_validity(pos, end - pos, cert, &pos))
1550
1.56k
    return -1;
1551
1552
  /* subject Name */
1553
3.62k
  subject_dn = pos;
1554
3.62k
  if (x509_parse_name(pos, end - pos, &cert->subject, &pos))
1555
23
    return -1;
1556
3.59k
  cert->subject_dn = os_malloc(pos - subject_dn);
1557
3.59k
  if (!cert->subject_dn)
1558
0
    return -1;
1559
3.59k
  cert->subject_dn_len = pos - subject_dn;
1560
3.59k
  os_memcpy(cert->subject_dn, subject_dn, cert->subject_dn_len);
1561
3.59k
  x509_name_string(&cert->subject, sbuf, sizeof(sbuf));
1562
3.59k
  wpa_printf(MSG_MSGDUMP, "X509: subject %s", sbuf);
1563
1564
  /* subjectPublicKeyInfo SubjectPublicKeyInfo */
1565
3.59k
  if (x509_parse_public_key(pos, end - pos, cert, &pos))
1566
153
    return -1;
1567
1568
3.44k
  if (pos == end)
1569
92
    return 0;
1570
1571
3.35k
  if (cert->version == X509_CERT_V1)
1572
19
    return 0;
1573
1574
3.33k
  if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1575
3.33k
      hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC) {
1576
12
    asn1_unexpected(&hdr,
1577
12
        "X509: Expected Context-Specific tag to parse optional tbsCertificate field(s)");
1578
12
    return -1;
1579
12
  }
1580
1581
3.32k
  if (hdr.tag == 1) {
1582
    /* issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL */
1583
10
    wpa_printf(MSG_DEBUG, "X509: issuerUniqueID");
1584
    /* TODO: parse UniqueIdentifier ::= BIT STRING */
1585
1586
10
    pos = hdr.payload + hdr.length;
1587
10
    if (pos == end)
1588
1
      return 0;
1589
1590
9
    if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1591
9
        hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC) {
1592
4
      asn1_unexpected(&hdr,
1593
4
          "X509: Expected Context-Specific tag to parse optional tbsCertificate field(s)");
1594
4
      return -1;
1595
4
    }
1596
9
  }
1597
1598
3.31k
  if (hdr.tag == 2) {
1599
    /* subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL */
1600
8
    wpa_printf(MSG_DEBUG, "X509: subjectUniqueID");
1601
    /* TODO: parse UniqueIdentifier ::= BIT STRING */
1602
1603
8
    pos = hdr.payload + hdr.length;
1604
8
    if (pos == end)
1605
2
      return 0;
1606
1607
6
    if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1608
6
        hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC) {
1609
4
      asn1_unexpected(&hdr,
1610
4
          "X509: Expected Context-Specific tag to parse optional tbsCertificate field(s)");
1611
4
      return -1;
1612
4
    }
1613
6
  }
1614
1615
3.31k
  if (hdr.tag != 3) {
1616
54
    wpa_printf(MSG_DEBUG,
1617
54
         "X509: Ignored unexpected Context-Specific constructed %d tag %d in optional tbsCertificate fields",
1618
54
         hdr.constructed, hdr.tag);
1619
54
    return 0;
1620
54
  }
1621
1622
  /* extensions      [3]  EXPLICIT Extensions OPTIONAL */
1623
1624
3.25k
  if (cert->version != X509_CERT_V3) {
1625
1
    wpa_printf(MSG_DEBUG, "X509: X.509%d certificate and "
1626
1
         "Extensions data which are only allowed for "
1627
1
         "version 3", cert->version + 1);
1628
1
    return -1;
1629
1
  }
1630
1631
3.25k
  if (x509_parse_extensions(cert, hdr.payload, hdr.length) < 0)
1632
3.09k
    return -1;
1633
1634
161
  pos = hdr.payload + hdr.length;
1635
161
  if (pos < end) {
1636
42
    wpa_hexdump(MSG_DEBUG,
1637
42
          "X509: Ignored extra tbsCertificate data",
1638
42
          pos, end - pos);
1639
42
  }
1640
1641
161
  return 0;
1642
3.25k
}
1643
1644
1645
static int x509_rsadsi_oid(struct asn1_oid *oid)
1646
0
{
1647
0
  return oid->len >= 4 &&
1648
0
    oid->oid[0] == 1 /* iso */ &&
1649
0
    oid->oid[1] == 2 /* member-body */ &&
1650
0
    oid->oid[2] == 840 /* us */ &&
1651
0
    oid->oid[3] == 113549 /* rsadsi */;
1652
0
}
1653
1654
1655
static int x509_pkcs_oid(struct asn1_oid *oid)
1656
0
{
1657
0
  return oid->len >= 5 &&
1658
0
    x509_rsadsi_oid(oid) &&
1659
0
    oid->oid[4] == 1 /* pkcs */;
1660
0
}
1661
1662
1663
static int x509_digest_oid(struct asn1_oid *oid)
1664
0
{
1665
0
  return oid->len >= 5 &&
1666
0
    x509_rsadsi_oid(oid) &&
1667
0
    oid->oid[4] == 2 /* digestAlgorithm */;
1668
0
}
1669
1670
1671
int x509_sha1_oid(struct asn1_oid *oid)
1672
0
{
1673
0
  return oid->len == 6 &&
1674
0
    oid->oid[0] == 1 /* iso */ &&
1675
0
    oid->oid[1] == 3 /* identified-organization */ &&
1676
0
    oid->oid[2] == 14 /* oiw */ &&
1677
0
    oid->oid[3] == 3 /* secsig */ &&
1678
0
    oid->oid[4] == 2 /* algorithms */ &&
1679
0
    oid->oid[5] == 26 /* id-sha1 */;
1680
0
}
1681
1682
1683
static int x509_sha2_oid(struct asn1_oid *oid)
1684
0
{
1685
0
  return oid->len == 9 &&
1686
0
    oid->oid[0] == 2 /* joint-iso-itu-t */ &&
1687
0
    oid->oid[1] == 16 /* country */ &&
1688
0
    oid->oid[2] == 840 /* us */ &&
1689
0
    oid->oid[3] == 1 /* organization */ &&
1690
0
    oid->oid[4] == 101 /* gov */ &&
1691
0
    oid->oid[5] == 3 /* csor */ &&
1692
0
    oid->oid[6] == 4 /* nistAlgorithm */ &&
1693
0
    oid->oid[7] == 2 /* hashAlgs */;
1694
0
}
1695
1696
1697
int x509_sha256_oid(struct asn1_oid *oid)
1698
0
{
1699
0
  return x509_sha2_oid(oid) &&
1700
0
    oid->oid[8] == 1 /* sha256 */;
1701
0
}
1702
1703
1704
int x509_sha384_oid(struct asn1_oid *oid)
1705
0
{
1706
0
  return x509_sha2_oid(oid) &&
1707
0
    oid->oid[8] == 2 /* sha384 */;
1708
0
}
1709
1710
1711
int x509_sha512_oid(struct asn1_oid *oid)
1712
0
{
1713
0
  return x509_sha2_oid(oid) &&
1714
0
    oid->oid[8] == 3 /* sha512 */;
1715
0
}
1716
1717
1718
/**
1719
 * x509_certificate_parse - Parse a X.509 certificate in DER format
1720
 * @buf: Pointer to the X.509 certificate in DER format
1721
 * @len: Buffer length
1722
 * Returns: Pointer to the parsed certificate or %NULL on failure
1723
 *
1724
 * Caller is responsible for freeing the returned certificate by calling
1725
 * x509_certificate_free().
1726
 */
1727
struct x509_certificate * x509_certificate_parse(const u8 *buf, size_t len)
1728
6.59k
{
1729
6.59k
  struct asn1_hdr hdr;
1730
6.59k
  const u8 *pos, *end, *hash_start;
1731
6.59k
  struct x509_certificate *cert;
1732
1733
6.59k
  cert = os_zalloc(sizeof(*cert) + len);
1734
6.59k
  if (cert == NULL)
1735
0
    return NULL;
1736
6.59k
  os_memcpy(cert + 1, buf, len);
1737
6.59k
  cert->cert_start = (u8 *) (cert + 1);
1738
6.59k
  cert->cert_len = len;
1739
1740
6.59k
  pos = buf;
1741
6.59k
  end = buf + len;
1742
1743
  /* RFC 3280 - X.509 v3 certificate / ASN.1 DER */
1744
1745
  /* Certificate ::= SEQUENCE */
1746
6.59k
  if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
1747
476
    asn1_unexpected(&hdr,
1748
476
        "X509: Certificate did not start with a valid SEQUENCE");
1749
476
    x509_certificate_free(cert);
1750
476
    return NULL;
1751
476
  }
1752
6.12k
  pos = hdr.payload;
1753
1754
6.12k
  if (hdr.length > end - pos) {
1755
0
    x509_certificate_free(cert);
1756
0
    return NULL;
1757
0
  }
1758
1759
6.12k
  if (hdr.length < end - pos) {
1760
38
    wpa_hexdump(MSG_MSGDUMP, "X509: Ignoring extra data after DER "
1761
38
          "encoded certificate",
1762
38
          pos + hdr.length, end - (pos + hdr.length));
1763
38
    end = pos + hdr.length;
1764
38
  }
1765
1766
6.12k
  hash_start = pos;
1767
6.12k
  cert->tbs_cert_start = cert->cert_start + (hash_start - buf);
1768
6.12k
  if (x509_parse_tbs_certificate(pos, end - pos, cert, &pos)) {
1769
5.79k
    x509_certificate_free(cert);
1770
5.79k
    return NULL;
1771
5.79k
  }
1772
329
  cert->tbs_cert_len = pos - hash_start;
1773
1774
  /* signatureAlgorithm AlgorithmIdentifier */
1775
329
  if (x509_parse_algorithm_identifier(pos, end - pos,
1776
329
              &cert->signature_alg, &pos)) {
1777
284
    x509_certificate_free(cert);
1778
284
    return NULL;
1779
284
  }
1780
1781
  /* signatureValue BIT STRING */
1782
45
  if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1783
45
      !asn1_is_bitstring(&hdr)) {
1784
33
    asn1_unexpected(&hdr,
1785
33
        "X509: Expected BITSTRING (signatureValue)");
1786
33
    x509_certificate_free(cert);
1787
33
    return NULL;
1788
33
  }
1789
12
  if (hdr.length < 1) {
1790
1
    x509_certificate_free(cert);
1791
1
    return NULL;
1792
1
  }
1793
11
  pos = hdr.payload;
1794
11
  if (*pos) {
1795
9
    wpa_printf(MSG_DEBUG,
1796
9
         "X509: BITSTRING (signatureValue) - %d unused bits",
1797
9
         *pos);
1798
    /* PKCS #1 v1.5 10.2.1:
1799
     * It is an error if the length in bits of the signature S is
1800
     * not a multiple of eight.
1801
     */
1802
9
    x509_certificate_free(cert);
1803
9
    return NULL;
1804
9
  }
1805
2
  os_free(cert->sign_value);
1806
2
  cert->sign_value = os_memdup(pos + 1, hdr.length - 1);
1807
2
  if (cert->sign_value == NULL) {
1808
0
    wpa_printf(MSG_DEBUG, "X509: Failed to allocate memory for "
1809
0
         "signatureValue");
1810
0
    x509_certificate_free(cert);
1811
0
    return NULL;
1812
0
  }
1813
2
  cert->sign_value_len = hdr.length - 1;
1814
2
  wpa_hexdump(MSG_MSGDUMP, "X509: signature",
1815
2
        cert->sign_value, cert->sign_value_len);
1816
1817
2
  return cert;
1818
2
}
1819
1820
1821
/**
1822
 * x509_certificate_check_signature - Verify certificate signature
1823
 * @issuer: Issuer certificate
1824
 * @cert: Certificate to be verified
1825
 * Returns: 0 if cert has a valid signature that was signed by the issuer,
1826
 * -1 if not
1827
 */
1828
int x509_certificate_check_signature(struct x509_certificate *issuer,
1829
             struct x509_certificate *cert)
1830
0
{
1831
0
  return x509_check_signature(issuer, &cert->signature,
1832
0
            cert->sign_value, cert->sign_value_len,
1833
0
            cert->tbs_cert_start, cert->tbs_cert_len);
1834
0
}
1835
1836
1837
int x509_check_signature(struct x509_certificate *issuer,
1838
       struct x509_algorithm_identifier *signature,
1839
       const u8 *sign_value, size_t sign_value_len,
1840
       const u8 *signed_data, size_t signed_data_len)
1841
0
{
1842
0
  struct crypto_public_key *pk;
1843
0
  u8 *data;
1844
0
  const u8 *pos, *end, *next, *da_end;
1845
0
  size_t data_len;
1846
0
  struct asn1_hdr hdr;
1847
0
  struct asn1_oid oid;
1848
0
  u8 hash[64];
1849
0
  size_t hash_len;
1850
0
  const u8 *addr[1] = { signed_data };
1851
0
  size_t len[1] = { signed_data_len };
1852
1853
0
  if (!x509_pkcs_oid(&signature->oid) ||
1854
0
      signature->oid.len != 7 ||
1855
0
      signature->oid.oid[5] != 1 /* pkcs-1 */) {
1856
0
    wpa_printf(MSG_DEBUG, "X509: Unrecognized signature "
1857
0
         "algorithm");
1858
0
    return -1;
1859
0
  }
1860
1861
0
  pk = crypto_public_key_import(issuer->public_key,
1862
0
              issuer->public_key_len);
1863
0
  if (pk == NULL)
1864
0
    return -1;
1865
1866
0
  data_len = sign_value_len;
1867
0
  data = os_malloc(data_len);
1868
0
  if (data == NULL) {
1869
0
    crypto_public_key_free(pk);
1870
0
    return -1;
1871
0
  }
1872
1873
0
  if (crypto_public_key_decrypt_pkcs1(pk, sign_value,
1874
0
              sign_value_len, data,
1875
0
              &data_len) < 0) {
1876
0
    wpa_printf(MSG_DEBUG, "X509: Failed to decrypt signature");
1877
0
    crypto_public_key_free(pk);
1878
0
    os_free(data);
1879
0
    return -1;
1880
0
  }
1881
0
  crypto_public_key_free(pk);
1882
1883
0
  wpa_hexdump(MSG_MSGDUMP, "X509: Signature data D", data, data_len);
1884
1885
  /*
1886
   * PKCS #1 v1.5, 10.1.2:
1887
   *
1888
   * DigestInfo ::= SEQUENCE {
1889
   *     digestAlgorithm DigestAlgorithmIdentifier,
1890
   *     digest Digest
1891
   * }
1892
   *
1893
   * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
1894
   *
1895
   * Digest ::= OCTET STRING
1896
   *
1897
   */
1898
0
  if (asn1_get_next(data, data_len, &hdr) < 0 ||
1899
0
      !asn1_is_sequence(&hdr)) {
1900
0
    asn1_unexpected(&hdr, "X509: Expected SEQUENCE (DigestInfo)");
1901
0
    os_free(data);
1902
0
    return -1;
1903
0
  }
1904
0
  wpa_hexdump(MSG_MSGDUMP, "X509: DigestInfo", hdr.payload, hdr.length);
1905
1906
0
  pos = hdr.payload;
1907
0
  end = pos + hdr.length;
1908
1909
  /*
1910
   * X.509:
1911
   * AlgorithmIdentifier ::= SEQUENCE {
1912
   *     algorithm            OBJECT IDENTIFIER,
1913
   *     parameters           ANY DEFINED BY algorithm OPTIONAL
1914
   * }
1915
   */
1916
1917
0
  if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1918
0
      !asn1_is_sequence(&hdr)) {
1919
0
    asn1_unexpected(&hdr,
1920
0
        "X509: Expected SEQUENCE (AlgorithmIdentifier)");
1921
0
    os_free(data);
1922
0
    return -1;
1923
0
  }
1924
0
  wpa_hexdump(MSG_MSGDUMP, "X509: DigestAlgorithmIdentifier",
1925
0
        hdr.payload, hdr.length);
1926
0
  da_end = hdr.payload + hdr.length;
1927
1928
0
  if (asn1_get_oid(hdr.payload, hdr.length, &oid, &next)) {
1929
0
    wpa_printf(MSG_DEBUG, "X509: Failed to parse digestAlgorithm");
1930
0
    os_free(data);
1931
0
    return -1;
1932
0
  }
1933
0
  wpa_hexdump(MSG_MSGDUMP, "X509: Digest algorithm parameters",
1934
0
        next, da_end - next);
1935
1936
  /*
1937
   * RFC 5754: The correct encoding for the SHA2 algorithms would be to
1938
   * omit the parameters, but there are implementation that encode these
1939
   * as a NULL element. Allow these two cases and reject anything else.
1940
   */
1941
0
  if (da_end > next &&
1942
0
      (asn1_get_next(next, da_end - next, &hdr) < 0 ||
1943
0
       !asn1_is_null(&hdr) ||
1944
0
       hdr.payload + hdr.length != da_end)) {
1945
0
    wpa_printf(MSG_DEBUG,
1946
0
         "X509: Unexpected digest algorithm parameters");
1947
0
    os_free(data);
1948
0
    return -1;
1949
0
  }
1950
1951
0
  if (x509_sha1_oid(&oid)) {
1952
0
    if (signature->oid.oid[6] != 5 /* sha-1WithRSAEncryption */) {
1953
0
      wpa_printf(MSG_DEBUG, "X509: digestAlgorithm SHA1 "
1954
0
           "does not match with certificate "
1955
0
           "signatureAlgorithm (%lu)",
1956
0
           signature->oid.oid[6]);
1957
0
      os_free(data);
1958
0
      return -1;
1959
0
    }
1960
0
    goto skip_digest_oid;
1961
0
  }
1962
1963
0
  if (x509_sha256_oid(&oid)) {
1964
0
    if (signature->oid.oid[6] !=
1965
0
        11 /* sha2561WithRSAEncryption */) {
1966
0
      wpa_printf(MSG_DEBUG, "X509: digestAlgorithm SHA256 "
1967
0
           "does not match with certificate "
1968
0
           "signatureAlgorithm (%lu)",
1969
0
           signature->oid.oid[6]);
1970
0
      os_free(data);
1971
0
      return -1;
1972
0
    }
1973
0
    goto skip_digest_oid;
1974
0
  }
1975
1976
0
  if (x509_sha384_oid(&oid)) {
1977
0
    if (signature->oid.oid[6] != 12 /* sha384WithRSAEncryption */) {
1978
0
      wpa_printf(MSG_DEBUG, "X509: digestAlgorithm SHA384 "
1979
0
           "does not match with certificate "
1980
0
           "signatureAlgorithm (%lu)",
1981
0
           signature->oid.oid[6]);
1982
0
      os_free(data);
1983
0
      return -1;
1984
0
    }
1985
0
    goto skip_digest_oid;
1986
0
  }
1987
1988
0
  if (x509_sha512_oid(&oid)) {
1989
0
    if (signature->oid.oid[6] != 13 /* sha512WithRSAEncryption */) {
1990
0
      wpa_printf(MSG_DEBUG, "X509: digestAlgorithm SHA512 "
1991
0
           "does not match with certificate "
1992
0
           "signatureAlgorithm (%lu)",
1993
0
           signature->oid.oid[6]);
1994
0
      os_free(data);
1995
0
      return -1;
1996
0
    }
1997
0
    goto skip_digest_oid;
1998
0
  }
1999
2000
0
  if (!x509_digest_oid(&oid)) {
2001
0
    wpa_printf(MSG_DEBUG, "X509: Unrecognized digestAlgorithm");
2002
0
    os_free(data);
2003
0
    return -1;
2004
0
  }
2005
0
  switch (oid.oid[5]) {
2006
0
  case 5: /* md5 */
2007
0
    if (signature->oid.oid[6] != 4 /* md5WithRSAEncryption */) {
2008
0
      wpa_printf(MSG_DEBUG, "X509: digestAlgorithm MD5 does "
2009
0
           "not match with certificate "
2010
0
           "signatureAlgorithm (%lu)",
2011
0
           signature->oid.oid[6]);
2012
0
      os_free(data);
2013
0
      return -1;
2014
0
    }
2015
0
    break;
2016
0
  case 2: /* md2 */
2017
0
  case 4: /* md4 */
2018
0
  default:
2019
0
    wpa_printf(MSG_DEBUG, "X509: Unsupported digestAlgorithm "
2020
0
         "(%lu)", oid.oid[5]);
2021
0
    os_free(data);
2022
0
    return -1;
2023
0
  }
2024
2025
0
skip_digest_oid:
2026
  /* Digest ::= OCTET STRING */
2027
0
  pos = da_end;
2028
2029
0
  if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
2030
0
      !asn1_is_octetstring(&hdr)) {
2031
0
    asn1_unexpected(&hdr, "X509: Expected OCTETSTRING (Digest)");
2032
0
    os_free(data);
2033
0
    return -1;
2034
0
  }
2035
0
  wpa_hexdump(MSG_MSGDUMP, "X509: Decrypted Digest",
2036
0
        hdr.payload, hdr.length);
2037
2038
0
  switch (signature->oid.oid[6]) {
2039
0
  case 4: /* md5WithRSAEncryption */
2040
0
    md5_vector(1, addr, len, hash);
2041
0
    hash_len = 16;
2042
0
    wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (MD5)",
2043
0
          hash, hash_len);
2044
0
    break;
2045
0
  case 5: /* sha-1WithRSAEncryption */
2046
0
    sha1_vector(1, addr, len, hash);
2047
0
    hash_len = 20;
2048
0
    wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (SHA1)",
2049
0
          hash, hash_len);
2050
0
    break;
2051
0
  case 11: /* sha256WithRSAEncryption */
2052
0
    sha256_vector(1, addr, len, hash);
2053
0
    hash_len = 32;
2054
0
    wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (SHA256)",
2055
0
          hash, hash_len);
2056
0
    break;
2057
0
  case 12: /* sha384WithRSAEncryption */
2058
0
    sha384_vector(1, addr, len, hash);
2059
0
    hash_len = 48;
2060
0
    wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (SHA384)",
2061
0
          hash, hash_len);
2062
0
    break;
2063
0
  case 13: /* sha512WithRSAEncryption */
2064
0
    sha512_vector(1, addr, len, hash);
2065
0
    hash_len = 64;
2066
0
    wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (SHA512)",
2067
0
          hash, hash_len);
2068
0
    break;
2069
0
  case 2: /* md2WithRSAEncryption */
2070
0
  default:
2071
0
    wpa_printf(MSG_INFO, "X509: Unsupported certificate signature "
2072
0
         "algorithm (%lu)", signature->oid.oid[6]);
2073
0
    os_free(data);
2074
0
    return -1;
2075
0
  }
2076
2077
0
  if (hdr.length != hash_len ||
2078
0
      os_memcmp_const(hdr.payload, hash, hdr.length) != 0) {
2079
0
    wpa_printf(MSG_INFO, "X509: Certificate Digest does not match "
2080
0
         "with calculated tbsCertificate hash");
2081
0
    os_free(data);
2082
0
    return -1;
2083
0
  }
2084
2085
0
  if (hdr.payload + hdr.length < data + data_len) {
2086
0
    wpa_hexdump(MSG_INFO,
2087
0
          "X509: Extra data after certificate signature hash",
2088
0
          hdr.payload + hdr.length,
2089
0
          data + data_len - hdr.payload - hdr.length);
2090
0
    os_free(data);
2091
0
    return -1;
2092
0
  }
2093
2094
0
  os_free(data);
2095
2096
0
  wpa_printf(MSG_DEBUG, "X509: Certificate Digest matches with "
2097
0
       "calculated tbsCertificate hash");
2098
2099
0
  return 0;
2100
0
}
2101
2102
2103
static int x509_valid_issuer(const struct x509_certificate *cert)
2104
0
{
2105
0
  if ((cert->extensions_present & X509_EXT_BASIC_CONSTRAINTS) &&
2106
0
      !cert->ca) {
2107
0
    wpa_printf(MSG_DEBUG, "X509: Non-CA certificate used as an "
2108
0
         "issuer");
2109
0
    return -1;
2110
0
  }
2111
2112
0
  if (cert->version == X509_CERT_V3 &&
2113
0
      !(cert->extensions_present & X509_EXT_BASIC_CONSTRAINTS)) {
2114
0
    wpa_printf(MSG_DEBUG, "X509: v3 CA certificate did not "
2115
0
         "include BasicConstraints extension");
2116
0
    return -1;
2117
0
  }
2118
2119
0
  if ((cert->extensions_present & X509_EXT_KEY_USAGE) &&
2120
0
      !(cert->key_usage & X509_KEY_USAGE_KEY_CERT_SIGN)) {
2121
0
    wpa_printf(MSG_DEBUG, "X509: Issuer certificate did not have "
2122
0
         "keyCertSign bit in Key Usage");
2123
0
    return -1;
2124
0
  }
2125
2126
0
  return 0;
2127
0
}
2128
2129
2130
/**
2131
 * x509_certificate_chain_validate - Validate X.509 certificate chain
2132
 * @trusted: List of trusted certificates
2133
 * @chain: Certificate chain to be validated (first chain must be issued by
2134
 * signed by the second certificate in the chain and so on)
2135
 * @reason: Buffer for returning failure reason (X509_VALIDATE_*)
2136
 * Returns: 0 if chain is valid, -1 if not
2137
 */
2138
int x509_certificate_chain_validate(struct x509_certificate *trusted,
2139
            struct x509_certificate *chain,
2140
            int *reason, int disable_time_checks)
2141
0
{
2142
0
  long unsigned idx;
2143
0
  int chain_trusted = 0;
2144
0
  struct x509_certificate *cert, *trust;
2145
0
  char buf[128];
2146
0
  struct os_time now;
2147
2148
0
  *reason = X509_VALIDATE_OK;
2149
2150
0
  wpa_printf(MSG_DEBUG, "X509: Validate certificate chain");
2151
0
  os_get_time(&now);
2152
2153
0
  for (cert = chain, idx = 0; cert; cert = cert->next, idx++) {
2154
0
    cert->issuer_trusted = 0;
2155
0
    x509_name_string(&cert->subject, buf, sizeof(buf));
2156
0
    wpa_printf(MSG_DEBUG, "X509: %lu: %s", idx, buf);
2157
2158
0
    if (chain_trusted)
2159
0
      continue;
2160
2161
0
    if (!disable_time_checks &&
2162
0
        ((unsigned long) now.sec <
2163
0
         (unsigned long) cert->not_before ||
2164
0
         (unsigned long) now.sec >
2165
0
         (unsigned long) cert->not_after)) {
2166
0
      wpa_printf(MSG_INFO, "X509: Certificate not valid "
2167
0
           "(now=%lu not_before=%lu not_after=%lu)",
2168
0
           now.sec, cert->not_before, cert->not_after);
2169
0
      *reason = X509_VALIDATE_CERTIFICATE_EXPIRED;
2170
0
      return -1;
2171
0
    }
2172
2173
0
    if (cert->next) {
2174
0
      if (x509_name_compare(&cert->issuer,
2175
0
                &cert->next->subject) != 0) {
2176
0
        wpa_printf(MSG_DEBUG, "X509: Certificate "
2177
0
             "chain issuer name mismatch");
2178
0
        x509_name_string(&cert->issuer, buf,
2179
0
             sizeof(buf));
2180
0
        wpa_printf(MSG_DEBUG, "X509: cert issuer: %s",
2181
0
             buf);
2182
0
        x509_name_string(&cert->next->subject, buf,
2183
0
             sizeof(buf));
2184
0
        wpa_printf(MSG_DEBUG, "X509: next cert "
2185
0
             "subject: %s", buf);
2186
0
        *reason = X509_VALIDATE_CERTIFICATE_UNKNOWN;
2187
0
        return -1;
2188
0
      }
2189
2190
0
      if (x509_valid_issuer(cert->next) < 0) {
2191
0
        *reason = X509_VALIDATE_BAD_CERTIFICATE;
2192
0
        return -1;
2193
0
      }
2194
2195
0
      if ((cert->next->extensions_present &
2196
0
           X509_EXT_PATH_LEN_CONSTRAINT) &&
2197
0
          idx > cert->next->path_len_constraint) {
2198
0
        wpa_printf(MSG_DEBUG, "X509: pathLenConstraint"
2199
0
             " not met (idx=%lu issuer "
2200
0
             "pathLenConstraint=%lu)", idx,
2201
0
             cert->next->path_len_constraint);
2202
0
        *reason = X509_VALIDATE_BAD_CERTIFICATE;
2203
0
        return -1;
2204
0
      }
2205
2206
0
      if (x509_certificate_check_signature(cert->next, cert)
2207
0
          < 0) {
2208
0
        wpa_printf(MSG_DEBUG, "X509: Invalid "
2209
0
             "certificate signature within "
2210
0
             "chain");
2211
0
        *reason = X509_VALIDATE_BAD_CERTIFICATE;
2212
0
        return -1;
2213
0
      }
2214
0
    }
2215
2216
0
    for (trust = trusted; trust; trust = trust->next) {
2217
0
      if (x509_name_compare(&cert->issuer, &trust->subject)
2218
0
          == 0)
2219
0
        break;
2220
0
    }
2221
2222
0
    if (trust) {
2223
0
      wpa_printf(MSG_DEBUG, "X509: Found issuer from the "
2224
0
           "list of trusted certificates");
2225
0
      if (x509_valid_issuer(trust) < 0) {
2226
0
        *reason = X509_VALIDATE_BAD_CERTIFICATE;
2227
0
        return -1;
2228
0
      }
2229
2230
0
      if (x509_certificate_check_signature(trust, cert) < 0)
2231
0
      {
2232
0
        wpa_printf(MSG_DEBUG, "X509: Invalid "
2233
0
             "certificate signature");
2234
0
        *reason = X509_VALIDATE_BAD_CERTIFICATE;
2235
0
        return -1;
2236
0
      }
2237
2238
0
      wpa_printf(MSG_DEBUG, "X509: Trusted certificate "
2239
0
           "found to complete the chain");
2240
0
      cert->issuer_trusted = 1;
2241
0
      chain_trusted = 1;
2242
0
    }
2243
0
  }
2244
2245
0
  if (!chain_trusted) {
2246
0
    wpa_printf(MSG_DEBUG, "X509: Did not find any of the issuers "
2247
0
         "from the list of trusted certificates");
2248
0
    if (trusted) {
2249
0
      *reason = X509_VALIDATE_UNKNOWN_CA;
2250
0
      return -1;
2251
0
    }
2252
0
    wpa_printf(MSG_DEBUG, "X509: Certificate chain validation "
2253
0
         "disabled - ignore unknown CA issue");
2254
0
  }
2255
2256
0
  wpa_printf(MSG_DEBUG, "X509: Certificate chain valid");
2257
2258
0
  return 0;
2259
0
}
2260
2261
2262
/**
2263
 * x509_certificate_get_subject - Get a certificate based on Subject name
2264
 * @chain: Certificate chain to search through
2265
 * @name: Subject name to search for
2266
 * Returns: Pointer to the certificate with the given Subject name or
2267
 * %NULL on failure
2268
 */
2269
struct x509_certificate *
2270
x509_certificate_get_subject(struct x509_certificate *chain,
2271
           struct x509_name *name)
2272
0
{
2273
0
  struct x509_certificate *cert;
2274
2275
0
  for (cert = chain; cert; cert = cert->next) {
2276
0
    if (x509_name_compare(&cert->subject, name) == 0)
2277
0
      return cert;
2278
0
  }
2279
0
  return NULL;
2280
0
}
2281
2282
2283
/**
2284
 * x509_certificate_self_signed - Is the certificate self-signed?
2285
 * @cert: Certificate
2286
 * Returns: 1 if certificate is self-signed, 0 if not
2287
 */
2288
int x509_certificate_self_signed(struct x509_certificate *cert)
2289
0
{
2290
0
  return x509_name_compare(&cert->issuer, &cert->subject) == 0;
2291
0
}