Coverage Report

Created: 2026-10-16 06:12

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/hostap/src/tls/x509v3.c
Line
Count
Source
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
8.40k
{
19
8.40k
  size_t i;
20
21
12.6k
  for (i = 0; i < name->num_attr; i++) {
22
4.22k
    os_free(name->attr[i].value);
23
4.22k
    name->attr[i].value = NULL;
24
4.22k
    name->attr[i].type = X509_NAME_ATTR_NOT_USED;
25
4.22k
  }
26
8.40k
  name->num_attr = 0;
27
8.40k
  os_free(name->email);
28
8.40k
  name->email = NULL;
29
30
8.40k
  os_free(name->alt_email);
31
8.40k
  os_free(name->dns);
32
8.40k
  os_free(name->uri);
33
8.40k
  os_free(name->ip);
34
8.40k
  name->alt_email = name->dns = name->uri = NULL;
35
8.40k
  name->ip = NULL;
36
8.40k
  name->ip_len = 0;
37
8.40k
  os_memset(&name->rid, 0, sizeof(name->rid));
38
8.40k
}
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
4.06k
{
47
4.06k
  if (cert == NULL)
48
0
    return;
49
4.06k
  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
4.06k
  x509_free_name(&cert->issuer);
55
4.06k
  x509_free_name(&cert->subject);
56
4.06k
  os_free(cert->public_key);
57
4.06k
  os_free(cert->sign_value);
58
4.06k
  os_free(cert->subject_dn);
59
4.06k
  os_free(cert);
60
4.06k
}
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
5.59k
{
69
5.59k
  struct x509_certificate *next;
70
71
7.27k
  while (cert) {
72
1.68k
    next = cert->next;
73
1.68k
    cert->next = NULL;
74
1.68k
    x509_certificate_free(cert);
75
1.68k
    cert = next;
76
1.68k
  }
77
5.59k
}
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.72k
{
185
9.72k
  struct asn1_hdr hdr;
186
9.72k
  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.72k
  if (asn1_get_next(buf, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
196
76
    asn1_unexpected(&hdr,
197
76
        "X509: Expected SEQUENCE (AlgorithmIdentifier)");
198
76
    return -1;
199
76
  }
200
9.65k
  if (hdr.length > buf + len - hdr.payload)
201
0
    return -1;
202
9.65k
  pos = hdr.payload;
203
9.65k
  end = pos + hdr.length;
204
205
9.65k
  *next = end;
206
207
9.65k
  if (asn1_get_oid(pos, end - pos, &id->oid, &pos))
208
57
    return -1;
209
210
  /* TODO: optional parameters */
211
212
9.59k
  return 0;
213
9.65k
}
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.20k
{
220
3.20k
  struct asn1_hdr hdr;
221
3.20k
  const u8 *pos, *end;
222
223
  /*
224
   * SubjectPublicKeyInfo ::= SEQUENCE {
225
   *     algorithm            AlgorithmIdentifier,
226
   *     subjectPublicKey     BIT STRING
227
   * }
228
   */
229
230
3.20k
  pos = buf;
231
3.20k
  end = buf + len;
232
233
3.20k
  if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
234
3.19k
      !asn1_is_sequence(&hdr)) {
235
13
    asn1_unexpected(&hdr,
236
13
        "X509: Expected SEQUENCE (SubjectPublicKeyInfo)");
237
13
    return -1;
238
13
  }
239
3.18k
  pos = hdr.payload;
240
241
3.18k
  if (hdr.length > end - pos)
242
0
    return -1;
243
3.18k
  end = pos + hdr.length;
244
3.18k
  *next = end;
245
246
3.18k
  if (x509_parse_algorithm_identifier(pos, end - pos,
247
3.18k
              &cert->public_key_alg, &pos))
248
12
    return -1;
249
250
3.17k
  if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
251
3.17k
      !asn1_is_bitstring(&hdr)) {
252
12
    asn1_unexpected(&hdr,
253
12
        "X509: Expected BITSTRING (subjectPublicKey)");
254
12
    return -1;
255
12
  }
256
3.16k
  if (hdr.length < 1)
257
1
    return -1;
258
3.16k
  pos = hdr.payload;
259
3.16k
  if (*pos) {
260
1.31k
    wpa_printf(MSG_DEBUG,
261
1.31k
         "X509: BITSTRING (subjectPublicKey) - %d unused bits",
262
1.31k
         *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
1.31k
  }
270
3.16k
  os_free(cert->public_key);
271
3.16k
  cert->public_key = os_memdup(pos + 1, hdr.length - 1);
272
3.16k
  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.16k
  cert->public_key_len = hdr.length - 1;
278
3.16k
  wpa_hexdump(MSG_MSGDUMP, "X509: subjectPublicKey",
279
3.16k
        cert->public_key, cert->public_key_len);
280
281
3.16k
  return 0;
282
3.16k
}
283
284
285
int x509_parse_name(const u8 *buf, size_t len, struct x509_name *name,
286
        const u8 **next)
287
6.94k
{
288
6.94k
  struct asn1_hdr hdr;
289
6.94k
  const u8 *pos, *end, *set_pos, *set_end, *seq_pos, *seq_end;
290
6.94k
  struct asn1_oid oid;
291
6.94k
  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
6.94k
  if (asn1_get_next(buf, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
306
58
    asn1_unexpected(&hdr,
307
58
        "X509: Expected SEQUENCE (Name / RDNSequencer)");
308
58
    return -1;
309
58
  }
310
6.88k
  pos = hdr.payload;
311
312
6.88k
  if (hdr.length > buf + len - pos)
313
0
    return -1;
314
315
6.88k
  end = *next = pos + hdr.length;
316
317
24.5k
  while (pos < end) {
318
17.9k
    enum x509_name_attr_type type;
319
320
17.9k
    if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
321
17.8k
        !asn1_is_set(&hdr)) {
322
205
      asn1_unexpected(&hdr,
323
205
          "X509: Expected SET (RelativeDistinguishedName)");
324
205
      x509_free_name(name);
325
205
      return -1;
326
205
    }
327
328
17.7k
    set_pos = hdr.payload;
329
17.7k
    pos = set_end = hdr.payload + hdr.length;
330
331
17.7k
    if (asn1_get_next(set_pos, set_end - set_pos, &hdr) < 0 ||
332
17.7k
        !asn1_is_sequence(&hdr)) {
333
37
      asn1_unexpected(&hdr,
334
37
          "X509: Expected SEQUENCE (AttributeTypeAndValue)");
335
37
      x509_free_name(name);
336
37
      return -1;
337
37
    }
338
339
17.7k
    seq_pos = hdr.payload;
340
17.7k
    seq_end = hdr.payload + hdr.length;
341
342
17.7k
    if (asn1_get_oid(seq_pos, seq_end - seq_pos, &oid, &seq_pos)) {
343
15
      x509_free_name(name);
344
15
      return -1;
345
15
    }
346
347
17.7k
    if (asn1_get_next(seq_pos, seq_end - seq_pos, &hdr) < 0 ||
348
17.6k
        hdr.class != ASN1_CLASS_UNIVERSAL) {
349
19
      wpa_printf(MSG_DEBUG, "X509: Failed to parse "
350
19
           "AttributeValue");
351
19
      x509_free_name(name);
352
19
      return -1;
353
19
    }
354
355
17.6k
    if (!asn1_is_string_type(&hdr)) {
356
3.98k
      wpa_printf(MSG_DEBUG,
357
3.98k
           "X509: Ignore non-string type attribute (tag 0x%x)",
358
3.98k
           hdr.tag);
359
3.98k
      continue;
360
3.98k
    }
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
13.7k
    type = X509_NAME_ATTR_NOT_USED;
371
13.7k
    if (oid.len == 4 &&
372
10.9k
        oid.oid[0] == 2 && oid.oid[1] == 5 && oid.oid[2] == 4) {
373
      /* id-at ::= 2.5.4 */
374
5.22k
      switch (oid.oid[3]) {
375
1.21k
      case 3:
376
        /* commonName */
377
1.21k
        type = X509_NAME_ATTR_CN;
378
1.21k
        break;
379
1.38k
      case 6:
380
        /*  countryName */
381
1.38k
        type = X509_NAME_ATTR_C;
382
1.38k
        break;
383
65
      case 7:
384
        /* localityName */
385
65
        type = X509_NAME_ATTR_L;
386
65
        break;
387
30
      case 8:
388
        /* stateOrProvinceName */
389
30
        type = X509_NAME_ATTR_ST;
390
30
        break;
391
1.34k
      case 10:
392
        /* organizationName */
393
1.34k
        type = X509_NAME_ATTR_O;
394
1.34k
        break;
395
199
      case 11:
396
        /* organizationalUnitName */
397
199
        type = X509_NAME_ATTR_OU;
398
199
        break;
399
5.22k
      }
400
8.48k
    } else if (oid.len == 7 &&
401
382
         oid.oid[0] == 1 && oid.oid[1] == 2 &&
402
184
         oid.oid[2] == 840 && oid.oid[3] == 113549 &&
403
102
         oid.oid[4] == 1 && oid.oid[5] == 9 &&
404
40
         oid.oid[6] == 1) {
405
      /* 1.2.840.113549.1.9.1 - e-mailAddress */
406
12
      os_free(name->email);
407
12
      name->email = os_malloc(hdr.length + 1);
408
12
      if (name->email == NULL) {
409
0
        x509_free_name(name);
410
0
        return -1;
411
0
      }
412
12
      os_memcpy(name->email, hdr.payload, hdr.length);
413
12
      name->email[hdr.length] = '\0';
414
12
      continue;
415
8.47k
    } else if (oid.len == 7 &&
416
370
         oid.oid[0] == 0 && oid.oid[1] == 9 &&
417
149
         oid.oid[2] == 2342 && oid.oid[3] == 19200300 &&
418
71
         oid.oid[4] == 100 && oid.oid[5] == 1 &&
419
24
         oid.oid[6] == 25) {
420
      /* 0.9.2342.19200300.100.1.25 - domainComponent */
421
3
      type = X509_NAME_ATTR_DC;
422
3
    }
423
424
13.6k
    if (type == X509_NAME_ATTR_NOT_USED) {
425
9.46k
      wpa_hexdump(MSG_DEBUG, "X509: Unrecognized OID",
426
9.46k
            (u8 *) oid.oid,
427
9.46k
            oid.len * sizeof(oid.oid[0]));
428
9.46k
      wpa_hexdump_ascii(MSG_MSGDUMP, "X509: Attribute Data",
429
9.46k
            hdr.payload, hdr.length);
430
9.46k
      continue;
431
9.46k
    }
432
433
4.23k
    if (name->num_attr == X509_MAX_NAME_ATTRIBUTES) {
434
0
      wpa_printf(MSG_INFO, "X509: Too many Name attributes");
435
0
      x509_free_name(name);
436
0
      return -1;
437
0
    }
438
439
4.23k
    val = dup_binstr(hdr.payload, hdr.length);
440
4.23k
    if (val == NULL) {
441
0
      x509_free_name(name);
442
0
      return -1;
443
0
    }
444
4.23k
    if (os_strlen(val) != hdr.length) {
445
5
      wpa_printf(MSG_INFO, "X509: Reject certificate with "
446
5
           "embedded NUL byte in a string (%s[NUL])",
447
5
           val);
448
5
      os_free(val);
449
5
      x509_free_name(name);
450
5
      return -1;
451
5
    }
452
453
4.22k
    name->attr[name->num_attr].type = type;
454
4.22k
    name->attr[name->num_attr].value = val;
455
4.22k
    name->num_attr++;
456
4.22k
  }
457
458
6.60k
  return 0;
459
6.88k
}
460
461
462
static const char * x509_name_attr_str(enum x509_name_attr_type type)
463
4.15k
{
464
4.15k
  switch (type) {
465
0
  case X509_NAME_ATTR_NOT_USED:
466
0
    return "[N/A]";
467
0
  case X509_NAME_ATTR_DC:
468
0
    return "DC";
469
1.19k
  case X509_NAME_ATTR_CN:
470
1.19k
    return "CN";
471
1.35k
  case X509_NAME_ATTR_C:
472
1.35k
    return "C";
473
55
  case X509_NAME_ATTR_L:
474
55
    return "L";
475
26
  case X509_NAME_ATTR_ST:
476
26
    return "ST";
477
1.33k
  case X509_NAME_ATTR_O:
478
1.33k
    return "O";
479
186
  case X509_NAME_ATTR_OU:
480
186
    return "OU";
481
4.15k
  }
482
0
  return "?";
483
4.15k
}
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
6.60k
{
494
6.60k
  char *pos, *end;
495
6.60k
  int ret;
496
6.60k
  size_t i;
497
498
6.60k
  if (len == 0)
499
0
    return;
500
501
6.60k
  pos = buf;
502
6.60k
  end = buf + len;
503
504
10.7k
  for (i = 0; i < name->num_attr; i++) {
505
4.15k
    ret = os_snprintf(pos, end - pos, "%s=%s, ",
506
4.15k
          x509_name_attr_str(name->attr[i].type),
507
4.15k
          name->attr[i].value);
508
4.15k
    if (os_snprintf_error(end - pos, ret))
509
0
      goto done;
510
4.15k
    pos += ret;
511
4.15k
  }
512
513
6.60k
  if (pos > buf + 1 && pos[-1] == ' ' && pos[-2] == ',') {
514
2.55k
    pos--;
515
2.55k
    *pos = '\0';
516
2.55k
    pos--;
517
2.55k
    *pos = '\0';
518
2.55k
  }
519
520
6.60k
  if (name->email) {
521
9
    ret = os_snprintf(pos, end - pos, "/emailAddress=%s",
522
9
          name->email);
523
9
    if (os_snprintf_error(end - pos, ret))
524
0
      goto done;
525
9
    pos += ret;
526
9
  }
527
528
6.60k
done:
529
6.60k
  if (pos < end)
530
6.60k
    *pos = '\0';
531
6.60k
  end[-1] = '\0';
532
6.60k
}
533
534
535
static int parse_uint2(const char *pos, size_t len)
536
38.9k
{
537
38.9k
  char buf[3];
538
38.9k
  int ret;
539
540
38.9k
  if (len < 2)
541
0
    return -1;
542
38.9k
  buf[0] = pos[0];
543
38.9k
  buf[1] = pos[1];
544
38.9k
  buf[2] = 0x00;
545
38.9k
  if (sscanf(buf, "%2d", &ret) != 1)
546
11
    return -1;
547
38.9k
  return ret;
548
38.9k
}
549
550
551
static int parse_uint4(const char *pos, size_t len)
552
43
{
553
43
  char buf[5];
554
43
  int ret;
555
556
43
  if (len < 4)
557
0
    return -1;
558
43
  buf[0] = pos[0];
559
43
  buf[1] = pos[1];
560
43
  buf[2] = pos[2];
561
43
  buf[3] = pos[3];
562
43
  buf[4] = 0x00;
563
43
  if (sscanf(buf, "%4d", &ret) != 1)
564
2
    return -1;
565
41
  return ret;
566
43
}
567
568
569
int x509_parse_time(const u8 *buf, size_t len, u8 asn1_tag, os_time_t *val)
570
6.54k
{
571
6.54k
  const char *pos, *end;
572
6.54k
  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
6.54k
  pos = (const char *) buf;
585
6.54k
  end = pos + len;
586
587
6.54k
  switch (asn1_tag) {
588
6.49k
  case ASN1_TAG_UTCTIME:
589
6.49k
    if (len != 13 || buf[12] != 'Z') {
590
12
      wpa_hexdump_ascii(MSG_DEBUG, "X509: Unrecognized "
591
12
            "UTCTime format", buf, len);
592
12
      return -1;
593
12
    }
594
6.48k
    year = parse_uint2(pos, end - pos);
595
6.48k
    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
6.47k
    if (year < 50)
601
5.37k
      year += 2000;
602
1.10k
    else
603
1.10k
      year += 1900;
604
6.47k
    pos += 2;
605
6.47k
    break;
606
48
  case ASN1_TAG_GENERALIZEDTIME:
607
48
    if (len != 15 || buf[14] != 'Z') {
608
5
      wpa_hexdump_ascii(MSG_DEBUG, "X509: Unrecognized "
609
5
            "GeneralizedTime format", buf, len);
610
5
      return -1;
611
5
    }
612
43
    year = parse_uint4(pos, end - pos);
613
43
    if (year < 0) {
614
11
      wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse "
615
11
            "GeneralizedTime year", buf, len);
616
11
      return -1;
617
11
    }
618
32
    pos += 4;
619
32
    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
6.54k
  }
625
626
6.51k
  month = parse_uint2(pos, end - pos);
627
6.51k
  if (month < 0) {
628
3
    wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time "
629
3
          "(month)", buf, len);
630
3
    return -1;
631
3
  }
632
6.50k
  pos += 2;
633
634
6.50k
  day = parse_uint2(pos, end - pos);
635
6.50k
  if (day < 0) {
636
5
    wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time "
637
5
          "(day)", buf, len);
638
5
    return -1;
639
5
  }
640
6.50k
  pos += 2;
641
642
6.50k
  hour = parse_uint2(pos, end - pos);
643
6.50k
  if (hour < 0) {
644
4
    wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time "
645
4
          "(hour)", buf, len);
646
4
    return -1;
647
4
  }
648
6.49k
  pos += 2;
649
650
6.49k
  min = parse_uint2(pos, end - pos);
651
6.49k
  if (min < 0) {
652
5
    wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time "
653
5
          "(min)", buf, len);
654
5
    return -1;
655
5
  }
656
6.49k
  pos += 2;
657
658
6.49k
  sec = parse_uint2(pos, end - pos);
659
6.49k
  if (sec < 0) {
660
5
    wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time "
661
5
          "(sec)", buf, len);
662
5
    return -1;
663
5
  }
664
665
6.48k
  if (os_mktime(year, month, day, hour, min, sec, val) < 0) {
666
815
    wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to convert Time",
667
815
          buf, len);
668
815
    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
799
      wpa_printf(MSG_DEBUG, "X509: Year=%d before epoch - "
675
799
           "assume epoch as the time", year);
676
799
      *val = 0;
677
799
      return 0;
678
799
    }
679
16
    return -1;
680
815
  }
681
682
5.67k
  return 0;
683
6.48k
}
684
685
686
static int x509_parse_validity(const u8 *buf, size_t len,
687
             struct x509_certificate *cert, const u8 **next)
688
3.40k
{
689
3.40k
  struct asn1_hdr hdr;
690
3.40k
  const u8 *pos;
691
3.40k
  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
3.40k
  if (asn1_get_next(buf, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
706
68
    asn1_unexpected(&hdr, "X509: Expected SEQUENCE (Validity)");
707
68
    return -1;
708
68
  }
709
3.33k
  pos = hdr.payload;
710
3.33k
  plen = hdr.length;
711
712
3.33k
  if (plen > (size_t) (buf + len - pos))
713
0
    return -1;
714
715
3.33k
  *next = pos + plen;
716
717
3.33k
  if (asn1_get_next(pos, plen, &hdr) < 0 ||
718
3.32k
      (!asn1_is_utctime(&hdr) && !asn1_is_generalizedtime(&hdr)) ||
719
3.30k
      x509_parse_time(hdr.payload, hdr.length, hdr.tag,
720
3.30k
          &cert->not_before) < 0) {
721
73
    wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse notBefore "
722
73
          "Time", hdr.payload, hdr.length);
723
73
    return -1;
724
73
  }
725
726
3.26k
  pos = hdr.payload + hdr.length;
727
3.26k
  plen = *next - pos;
728
729
3.26k
  if (asn1_get_next(pos, plen, &hdr) < 0 ||
730
3.25k
      (!asn1_is_utctime(&hdr) && !asn1_is_generalizedtime(&hdr)) ||
731
3.24k
      x509_parse_time(hdr.payload, hdr.length, hdr.tag,
732
3.24k
          &cert->not_after) < 0) {
733
47
    wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse notAfter "
734
47
          "Time", hdr.payload, hdr.length);
735
47
    return -1;
736
47
  }
737
738
3.21k
  wpa_printf(MSG_MSGDUMP, "X509: Validity: notBefore: %lu notAfter: %lu",
739
3.21k
       (unsigned long) cert->not_before,
740
3.21k
       (unsigned long) cert->not_after);
741
742
3.21k
  return 0;
743
3.26k
}
744
745
746
static int x509_id_ce_oid(struct asn1_oid *oid)
747
4.41k
{
748
  /* id-ce arc from X.509 for standard X.509v3 extensions */
749
4.41k
  return oid->len >= 4 &&
750
4.01k
    oid->oid[0] == 2 /* joint-iso-ccitt */ &&
751
3.40k
    oid->oid[1] == 5 /* ds */ &&
752
2.88k
    oid->oid[2] == 29 /* id-ce */;
753
4.41k
}
754
755
756
static int x509_any_ext_key_usage_oid(struct asn1_oid *oid)
757
827
{
758
827
  return oid->len == 6 &&
759
298
    x509_id_ce_oid(oid) &&
760
57
    oid->oid[3] == 37 /* extKeyUsage */ &&
761
28
    oid->oid[4] == 0 /* anyExtendedKeyUsage */;
762
827
}
763
764
765
static int x509_parse_ext_key_usage(struct x509_certificate *cert,
766
            const u8 *pos, size_t len)
767
73
{
768
73
  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
73
  if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_bitstring(&hdr) ||
784
62
      hdr.length < 1) {
785
12
    asn1_unexpected(&hdr, "X509: Expected BIT STRING in KeyUsage");
786
12
    return -1;
787
12
  }
788
789
61
  cert->extensions_present |= X509_EXT_KEY_USAGE;
790
61
  cert->key_usage = asn1_bit_string_to_long(hdr.payload, hdr.length);
791
792
61
  wpa_printf(MSG_DEBUG, "X509: KeyUsage 0x%lx", cert->key_usage);
793
794
61
  return 0;
795
73
}
796
797
798
static int x509_parse_ext_basic_constraints(struct x509_certificate *cert,
799
              const u8 *pos, size_t len)
800
420
{
801
420
  struct asn1_hdr hdr;
802
420
  unsigned long value;
803
420
  size_t left;
804
420
  const u8 *end_seq;
805
806
  /*
807
   * BasicConstraints ::= SEQUENCE {
808
   * cA                      BOOLEAN DEFAULT FALSE,
809
   * pathLenConstraint       INTEGER (0..MAX) OPTIONAL }
810
   */
811
812
420
  if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
813
15
    asn1_unexpected(&hdr,
814
15
        "X509: Expected SEQUENCE in BasicConstraints");
815
15
    return -1;
816
15
  }
817
818
405
  cert->extensions_present |= X509_EXT_BASIC_CONSTRAINTS;
819
820
405
  if (hdr.length == 0)
821
204
    return 0;
822
823
201
  end_seq = hdr.payload + hdr.length;
824
201
  if (asn1_get_next(hdr.payload, hdr.length, &hdr) < 0) {
825
2
    wpa_printf(MSG_DEBUG, "X509: Failed to parse "
826
2
         "BasicConstraints");
827
2
    return -1;
828
2
  }
829
830
199
  if (asn1_is_boolean(&hdr)) {
831
171
    cert->ca = hdr.payload[0];
832
833
171
    pos = hdr.payload + hdr.length;
834
171
    if (pos >= end_seq) {
835
      /* No optional pathLenConstraint */
836
157
      wpa_printf(MSG_DEBUG, "X509: BasicConstraints - cA=%d",
837
157
           cert->ca);
838
157
      return 0;
839
157
    }
840
14
    if (asn1_get_next(pos, end_seq - pos, &hdr) < 0) {
841
1
      wpa_printf(MSG_DEBUG, "X509: Failed to parse "
842
1
           "BasicConstraints");
843
1
      return -1;
844
1
    }
845
14
  }
846
847
41
  if (!asn1_is_integer(&hdr)) {
848
4
    asn1_unexpected(&hdr,
849
4
        "X509: Expected INTEGER in BasicConstraints");
850
4
    return -1;
851
4
  }
852
853
37
  pos = hdr.payload;
854
37
  left = hdr.length;
855
37
  value = 0;
856
94
  while (left) {
857
57
    value <<= 8;
858
57
    value |= *pos++;
859
57
    left--;
860
57
  }
861
862
37
  cert->path_len_constraint = value;
863
37
  cert->extensions_present |= X509_EXT_PATH_LEN_CONSTRAINT;
864
865
37
  wpa_printf(MSG_DEBUG, "X509: BasicConstraints - cA=%d "
866
37
       "pathLenConstraint=%lu",
867
37
       cert->ca, cert->path_len_constraint);
868
869
37
  return 0;
870
41
}
871
872
873
static int x509_parse_alt_name_rfc8222(struct x509_name *name,
874
               const u8 *pos, size_t len)
875
39
{
876
  /* rfc822Name IA5String */
877
39
  wpa_hexdump_ascii(MSG_MSGDUMP, "X509: altName - rfc822Name", pos, len);
878
39
  os_free(name->alt_email);
879
39
  name->alt_email = os_zalloc(len + 1);
880
39
  if (name->alt_email == NULL)
881
0
    return -1;
882
39
  os_memcpy(name->alt_email, pos, len);
883
39
  if (os_strlen(name->alt_email) != len) {
884
5
    wpa_printf(MSG_INFO, "X509: Reject certificate with "
885
5
         "embedded NUL byte in rfc822Name (%s[NUL])",
886
5
         name->alt_email);
887
5
    os_free(name->alt_email);
888
5
    name->alt_email = NULL;
889
5
    return -1;
890
5
  }
891
34
  return 0;
892
39
}
893
894
895
static int x509_parse_alt_name_dns(struct x509_name *name,
896
           const u8 *pos, size_t len)
897
191
{
898
  /* dNSName IA5String */
899
191
  wpa_hexdump_ascii(MSG_MSGDUMP, "X509: altName - dNSName", pos, len);
900
191
  os_free(name->dns);
901
191
  name->dns = os_zalloc(len + 1);
902
191
  if (name->dns == NULL)
903
0
    return -1;
904
191
  os_memcpy(name->dns, pos, len);
905
191
  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
189
  return 0;
914
191
}
915
916
917
static int x509_parse_alt_name_uri(struct x509_name *name,
918
           const u8 *pos, size_t len)
919
47
{
920
  /* uniformResourceIdentifier IA5String */
921
47
  wpa_hexdump_ascii(MSG_MSGDUMP,
922
47
        "X509: altName - uniformResourceIdentifier",
923
47
        pos, len);
924
47
  os_free(name->uri);
925
47
  name->uri = os_zalloc(len + 1);
926
47
  if (name->uri == NULL)
927
0
    return -1;
928
47
  os_memcpy(name->uri, pos, len);
929
47
  if (os_strlen(name->uri) != len) {
930
1
    wpa_printf(MSG_INFO, "X509: Reject certificate with "
931
1
         "embedded NUL byte in uniformResourceIdentifier "
932
1
         "(%s[NUL])", name->uri);
933
1
    os_free(name->uri);
934
1
    name->uri = NULL;
935
1
    return -1;
936
1
  }
937
46
  return 0;
938
47
}
939
940
941
static int x509_parse_alt_name_ip(struct x509_name *name,
942
               const u8 *pos, size_t len)
943
41
{
944
  /* iPAddress OCTET STRING */
945
41
  wpa_hexdump(MSG_MSGDUMP, "X509: altName - iPAddress", pos, len);
946
41
  os_free(name->ip);
947
41
  name->ip = os_memdup(pos, len);
948
41
  if (name->ip == NULL)
949
0
    return -1;
950
41
  name->ip_len = len;
951
41
  return 0;
952
41
}
953
954
955
static int x509_parse_alt_name_rid(struct x509_name *name,
956
           const u8 *pos, size_t len)
957
203
{
958
203
  char buf[80];
959
960
  /* registeredID OBJECT IDENTIFIER */
961
203
  if (asn1_parse_oid(pos, len, &name->rid) < 0)
962
29
    return -1;
963
964
174
  asn1_oid_to_str(&name->rid, buf, sizeof(buf));
965
174
  wpa_printf(MSG_MSGDUMP, "X509: altName - registeredID: %s", buf);
966
967
174
  return 0;
968
203
}
969
970
971
static int x509_parse_ext_alt_name(struct x509_name *name,
972
           const u8 *pos, size_t len)
973
326
{
974
326
  struct asn1_hdr hdr;
975
326
  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
1.14k
  for (p = pos, end = pos + len; p < end; p = hdr.payload + hdr.length) {
1001
875
    int res;
1002
1003
875
    if (asn1_get_next(p, end - p, &hdr) < 0) {
1004
16
      wpa_printf(MSG_DEBUG, "X509: Failed to parse "
1005
16
           "SubjectAltName item");
1006
16
      return -1;
1007
16
    }
1008
1009
859
    if (hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC)
1010
221
      continue;
1011
1012
638
    switch (hdr.tag) {
1013
39
    case 1:
1014
39
      res = x509_parse_alt_name_rfc8222(name, hdr.payload,
1015
39
                hdr.length);
1016
39
      break;
1017
191
    case 2:
1018
191
      res = x509_parse_alt_name_dns(name, hdr.payload,
1019
191
                  hdr.length);
1020
191
      break;
1021
47
    case 6:
1022
47
      res = x509_parse_alt_name_uri(name, hdr.payload,
1023
47
                  hdr.length);
1024
47
      break;
1025
41
    case 7:
1026
41
      res = x509_parse_alt_name_ip(name, hdr.payload,
1027
41
                 hdr.length);
1028
41
      break;
1029
203
    case 8:
1030
203
      res = x509_parse_alt_name_rid(name, hdr.payload,
1031
203
                  hdr.length);
1032
203
      break;
1033
56
    case 0: /* TODO: otherName */
1034
56
    case 3: /* TODO: x500Address */
1035
56
    case 4: /* TODO: directoryName */
1036
59
    case 5: /* TODO: ediPartyName */
1037
117
    default:
1038
117
      res = 0;
1039
117
      break;
1040
638
    }
1041
638
    if (res < 0)
1042
37
      return res;
1043
638
  }
1044
1045
273
  return 0;
1046
326
}
1047
1048
1049
static int x509_parse_ext_subject_alt_name(struct x509_certificate *cert,
1050
             const u8 *pos, size_t len)
1051
302
{
1052
302
  struct asn1_hdr hdr;
1053
1054
  /* SubjectAltName ::= GeneralNames */
1055
1056
302
  if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
1057
8
    asn1_unexpected(&hdr,
1058
8
        "X509: Expected SEQUENCE in SubjectAltName");
1059
8
    return -1;
1060
8
  }
1061
1062
294
  wpa_printf(MSG_DEBUG, "X509: SubjectAltName");
1063
294
  cert->extensions_present |= X509_EXT_SUBJECT_ALT_NAME;
1064
1065
294
  if (hdr.length == 0)
1066
23
    return 0;
1067
1068
271
  return x509_parse_ext_alt_name(&cert->subject, hdr.payload,
1069
271
               hdr.length);
1070
294
}
1071
1072
1073
static int x509_parse_ext_issuer_alt_name(struct x509_certificate *cert,
1074
            const u8 *pos, size_t len)
1075
120
{
1076
120
  struct asn1_hdr hdr;
1077
1078
  /* IssuerAltName ::= GeneralNames */
1079
1080
120
  if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
1081
11
    asn1_unexpected(&hdr,
1082
11
        "X509: Expected SEQUENCE in IssuerAltName");
1083
11
    return -1;
1084
11
  }
1085
1086
109
  wpa_printf(MSG_DEBUG, "X509: IssuerAltName");
1087
109
  cert->extensions_present |= X509_EXT_ISSUER_ALT_NAME;
1088
1089
109
  if (hdr.length == 0)
1090
54
    return 0;
1091
1092
55
  return x509_parse_ext_alt_name(&cert->issuer, hdr.payload,
1093
55
               hdr.length);
1094
109
}
1095
1096
1097
static int x509_id_cert_policy_any_oid(struct asn1_oid *oid)
1098
463
{
1099
463
  return oid->len == 5 &&
1100
168
    oid->oid[0] == 2 /* iso/itu-t */ &&
1101
128
    oid->oid[1] == 5 /* X.500 Directory Services */ &&
1102
87
    oid->oid[2] == 29 /* id-ce */ &&
1103
52
    oid->oid[3] == 32 /* id-ce-certificate-policies */ &&
1104
30
    oid->oid[4] == 0 /* anyPolicy */;
1105
463
}
1106
1107
1108
static int x509_id_wfa_oid(struct asn1_oid *oid)
1109
539
{
1110
539
  return oid->len >= 7 &&
1111
539
    oid->oid[0] == 1 /* iso */ &&
1112
467
    oid->oid[1] == 3 /* identified-organization */ &&
1113
403
    oid->oid[2] == 6 /* dod */ &&
1114
349
    oid->oid[3] == 1 /* internet */ &&
1115
297
    oid->oid[4] == 4 /* private */ &&
1116
245
    oid->oid[5] == 1 /* enterprise */ &&
1117
173
    oid->oid[6] == 40808 /* WFA */;
1118
539
}
1119
1120
1121
static int x509_id_wfa_tod_oid(struct asn1_oid *oid)
1122
539
{
1123
539
  return oid->len >= 9 &&
1124
539
    x509_id_wfa_oid(oid) &&
1125
125
    oid->oid[7] == 1 &&
1126
69
    oid->oid[8] == 3;
1127
539
}
1128
1129
1130
static int x509_id_wfa_tod_strict_oid(struct asn1_oid *oid)
1131
448
{
1132
448
  return oid->len == 10 &&
1133
274
    x509_id_wfa_tod_oid(oid) &&
1134
32
    oid->oid[9] == 1;
1135
448
}
1136
1137
1138
static int x509_id_wfa_tod_tofu_oid(struct asn1_oid *oid)
1139
439
{
1140
439
  return oid->len == 10 &&
1141
265
    x509_id_wfa_tod_oid(oid) &&
1142
23
    oid->oid[9] == 2;
1143
439
}
1144
1145
1146
static int x509_parse_ext_certificate_policies(struct x509_certificate *cert,
1147
                 const u8 *pos, size_t len)
1148
378
{
1149
378
  struct asn1_hdr hdr;
1150
378
  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
378
  if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
1164
15
    asn1_unexpected(&hdr,
1165
15
        "X509: Expected SEQUENCE (certificatePolicies)");
1166
15
    return -1;
1167
15
  }
1168
363
  if (hdr.length > pos + len - hdr.payload)
1169
0
    return -1;
1170
363
  pos = hdr.payload;
1171
363
  end = pos + hdr.length;
1172
1173
363
  wpa_hexdump(MSG_MSGDUMP, "X509: certificatePolicies", pos, end - pos);
1174
1175
826
  while (pos < end) {
1176
526
    const u8 *pol_end;
1177
526
    struct asn1_oid oid;
1178
526
    char buf[80];
1179
1180
526
    if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1181
491
        !asn1_is_sequence(&hdr)) {
1182
57
      asn1_unexpected(&hdr,
1183
57
          "X509: Expected SEQUENCE (PolicyInformation)");
1184
57
      return -1;
1185
57
    }
1186
469
    if (hdr.length > end - hdr.payload)
1187
0
      return -1;
1188
469
    pos = hdr.payload;
1189
469
    pol_end = pos + hdr.length;
1190
469
    wpa_hexdump(MSG_MSGDUMP, "X509: PolicyInformation",
1191
469
          pos, pol_end - pos);
1192
1193
469
    if (asn1_get_oid(pos, pol_end - pos, &oid, &pos))
1194
6
      return -1;
1195
463
    if (x509_id_cert_policy_any_oid(&oid)) {
1196
15
      os_strlcpy(buf, "anyPolicy-STRICT", sizeof(buf));
1197
15
      cert->certificate_policy |=
1198
15
        X509_EXT_CERT_POLICY_ANY;
1199
448
    } else if (x509_id_wfa_tod_strict_oid(&oid)) {
1200
9
      os_strlcpy(buf, "TOD-STRICT", sizeof(buf));
1201
9
      cert->certificate_policy |=
1202
9
        X509_EXT_CERT_POLICY_TOD_STRICT;
1203
439
    } else if (x509_id_wfa_tod_tofu_oid(&oid)) {
1204
14
      os_strlcpy(buf, "TOD-TOFU", sizeof(buf));
1205
14
      cert->certificate_policy |=
1206
14
        X509_EXT_CERT_POLICY_TOD_TOFU;
1207
425
    } else {
1208
425
      asn1_oid_to_str(&oid, buf, sizeof(buf));
1209
425
    }
1210
463
    wpa_printf(MSG_DEBUG, "policyIdentifier: %s", buf);
1211
1212
463
    pos = pol_end;
1213
463
  }
1214
1215
300
  cert->extensions_present |= X509_EXT_CERTIFICATE_POLICY;
1216
1217
300
  return 0;
1218
363
}
1219
1220
1221
static int x509_id_pkix_oid(struct asn1_oid *oid)
1222
899
{
1223
899
  return oid->len >= 7 &&
1224
899
    oid->oid[0] == 1 /* iso */ &&
1225
830
    oid->oid[1] == 3 /* identified-organization */ &&
1226
764
    oid->oid[2] == 6 /* dod */ &&
1227
626
    oid->oid[3] == 1 /* internet */ &&
1228
536
    oid->oid[4] == 5 /* security */ &&
1229
428
    oid->oid[5] == 5 /* mechanisms */ &&
1230
362
    oid->oid[6] == 7 /* id-pkix */;
1231
899
}
1232
1233
1234
static int x509_id_kp_oid(struct asn1_oid *oid)
1235
899
{
1236
  /* id-kp */
1237
899
  return oid->len >= 8 &&
1238
899
    x509_id_pkix_oid(oid) &&
1239
314
    oid->oid[7] == 3 /* id-kp */;
1240
899
}
1241
1242
1243
static int x509_id_kp_server_auth_oid(struct asn1_oid *oid)
1244
814
{
1245
  /* id-kp */
1246
814
  return oid->len == 9 &&
1247
395
    x509_id_kp_oid(oid) &&
1248
184
    oid->oid[8] == 1 /* id-kp-serverAuth */;
1249
814
}
1250
1251
1252
static int x509_id_kp_client_auth_oid(struct asn1_oid *oid)
1253
678
{
1254
  /* id-kp */
1255
678
  return oid->len == 9 &&
1256
259
    x509_id_kp_oid(oid) &&
1257
48
    oid->oid[8] == 2 /* id-kp-clientAuth */;
1258
678
}
1259
1260
1261
static int x509_id_kp_ocsp_oid(struct asn1_oid *oid)
1262
664
{
1263
  /* id-kp */
1264
664
  return oid->len == 9 &&
1265
245
    x509_id_kp_oid(oid) &&
1266
34
    oid->oid[8] == 9 /* id-kp-OCSPSigning */;
1267
664
}
1268
1269
1270
static int x509_parse_ext_ext_key_usage(struct x509_certificate *cert,
1271
          const u8 *pos, size_t len)
1272
382
{
1273
382
  struct asn1_hdr hdr;
1274
382
  const u8 *end;
1275
382
  struct asn1_oid oid;
1276
1277
  /*
1278
   * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
1279
   *
1280
   * KeyPurposeId ::= OBJECT IDENTIFIER
1281
   */
1282
1283
382
  if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
1284
18
    asn1_unexpected(&hdr,
1285
18
        "X509: Expected SEQUENCE (ExtKeyUsageSyntax)");
1286
18
    return -1;
1287
18
  }
1288
364
  if (hdr.length > pos + len - hdr.payload)
1289
0
    return -1;
1290
364
  pos = hdr.payload;
1291
364
  end = pos + hdr.length;
1292
1293
364
  wpa_hexdump(MSG_MSGDUMP, "X509: ExtKeyUsageSyntax", pos, end - pos);
1294
1295
1.19k
  while (pos < end) {
1296
927
    char buf[80];
1297
1298
927
    if (asn1_get_oid(pos, end - pos, &oid, &pos))
1299
100
      return -1;
1300
827
    if (x509_any_ext_key_usage_oid(&oid)) {
1301
13
      os_strlcpy(buf, "anyExtendedKeyUsage", sizeof(buf));
1302
13
      cert->ext_key_usage |= X509_EXT_KEY_USAGE_ANY;
1303
814
    } else if (x509_id_kp_server_auth_oid(&oid)) {
1304
136
      os_strlcpy(buf, "id-kp-serverAuth", sizeof(buf));
1305
136
      cert->ext_key_usage |= X509_EXT_KEY_USAGE_SERVER_AUTH;
1306
678
    } else if (x509_id_kp_client_auth_oid(&oid)) {
1307
14
      os_strlcpy(buf, "id-kp-clientAuth", sizeof(buf));
1308
14
      cert->ext_key_usage |= X509_EXT_KEY_USAGE_CLIENT_AUTH;
1309
664
    } else if (x509_id_kp_ocsp_oid(&oid)) {
1310
10
      os_strlcpy(buf, "id-kp-OCSPSigning", sizeof(buf));
1311
10
      cert->ext_key_usage |= X509_EXT_KEY_USAGE_OCSP;
1312
654
    } else {
1313
654
      asn1_oid_to_str(&oid, buf, sizeof(buf));
1314
654
    }
1315
827
    wpa_printf(MSG_DEBUG, "ExtKeyUsage KeyPurposeId: %s", buf);
1316
827
  }
1317
1318
264
  cert->extensions_present |= X509_EXT_EXT_KEY_USAGE;
1319
1320
264
  return 0;
1321
364
}
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
4.11k
{
1328
4.11k
  if (!x509_id_ce_oid(oid))
1329
1.58k
    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
2.53k
  switch (oid->oid[3]) {
1337
73
  case 15: /* id-ce-keyUsage */
1338
73
    return x509_parse_ext_key_usage(cert, pos, len);
1339
302
  case 17: /* id-ce-subjectAltName */
1340
302
    return x509_parse_ext_subject_alt_name(cert, pos, len);
1341
120
  case 18: /* id-ce-issuerAltName */
1342
120
    return x509_parse_ext_issuer_alt_name(cert, pos, len);
1343
420
  case 19: /* id-ce-basicConstraints */
1344
420
    return x509_parse_ext_basic_constraints(cert, pos, len);
1345
378
  case 32: /* id-ce-certificatePolicies */
1346
378
    return x509_parse_ext_certificate_policies(cert, pos, len);
1347
382
  case 37: /* id-ce-extKeyUsage */
1348
382
    return x509_parse_ext_ext_key_usage(cert, pos, len);
1349
858
  default:
1350
858
    return 1;
1351
2.53k
  }
1352
2.53k
}
1353
1354
1355
static int x509_parse_extension(struct x509_certificate *cert,
1356
        const u8 *pos, size_t len, const u8 **next)
1357
4.21k
{
1358
4.21k
  const u8 *end;
1359
4.21k
  struct asn1_hdr hdr;
1360
4.21k
  struct asn1_oid oid;
1361
4.21k
  int critical_ext = 0, res;
1362
4.21k
  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
4.21k
  if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
1373
62
    asn1_unexpected(&hdr, "X509: Expected SEQUENCE in Extensions");
1374
62
    return -1;
1375
62
  }
1376
4.14k
  pos = hdr.payload;
1377
4.14k
  *next = end = pos + hdr.length;
1378
1379
4.14k
  if (asn1_get_oid(pos, end - pos, &oid, &pos) < 0) {
1380
10
    wpa_printf(MSG_DEBUG, "X509: Unexpected ASN.1 data for "
1381
10
         "Extension (expected OID)");
1382
10
    return -1;
1383
10
  }
1384
1385
4.13k
  if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1386
4.13k
      (!asn1_is_boolean(&hdr) && !asn1_is_octetstring(&hdr))) {
1387
17
    asn1_unexpected(&hdr,
1388
17
        "X509: Expected BOOLEAN or OCTETSTRING in Extensions");
1389
17
    return -1;
1390
17
  }
1391
1392
4.12k
  if (hdr.tag == ASN1_TAG_BOOLEAN) {
1393
36
    critical_ext = hdr.payload[0];
1394
36
    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
36
    if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1402
35
        (!asn1_is_octetstring(&hdr) &&
1403
35
         !(hdr.class == ASN1_CLASS_PRIVATE &&
1404
33
           hdr.tag == ASN1_TAG_OCTETSTRING))) {
1405
8
      asn1_unexpected(&hdr,
1406
8
          "X509: Expected OCTETSTRING in Extensions");
1407
8
      return -1;
1408
8
    }
1409
36
  }
1410
1411
4.11k
  asn1_oid_to_str(&oid, buf, sizeof(buf));
1412
4.11k
  wpa_printf(MSG_DEBUG, "X509: Extension: extnID=%s critical=%d",
1413
4.11k
       buf, critical_ext);
1414
4.11k
  wpa_hexdump(MSG_MSGDUMP, "X509: extnValue", hdr.payload, hdr.length);
1415
1416
4.11k
  res = x509_parse_extension_data(cert, &oid, hdr.payload, hdr.length);
1417
4.11k
  if (res < 0)
1418
302
    return res;
1419
3.81k
  if (res == 1 && critical_ext) {
1420
2
    wpa_printf(MSG_INFO, "X509: Unknown critical extension %s",
1421
2
         buf);
1422
2
    return -1;
1423
2
  }
1424
1425
3.81k
  return 0;
1426
3.81k
}
1427
1428
1429
static int x509_parse_extensions(struct x509_certificate *cert,
1430
         const u8 *pos, size_t len)
1431
1.03k
{
1432
1.03k
  const u8 *end;
1433
1.03k
  struct asn1_hdr hdr;
1434
1435
  /* Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension */
1436
1437
1.03k
  if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
1438
13
    asn1_unexpected(&hdr, "X509: Expected SEQUENCE for Extensions");
1439
13
    return -1;
1440
13
  }
1441
1442
1.01k
  pos = hdr.payload;
1443
1.01k
  end = pos + hdr.length;
1444
1445
4.82k
  while (pos < end) {
1446
4.21k
    if (x509_parse_extension(cert, pos, end - pos, &pos)
1447
4.21k
        < 0)
1448
401
      return -1;
1449
4.21k
  }
1450
1451
617
  return 0;
1452
1.01k
}
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
3.93k
{
1459
3.93k
  struct asn1_hdr hdr;
1460
3.93k
  const u8 *pos, *end;
1461
3.93k
  size_t left;
1462
3.93k
  char sbuf[128];
1463
3.93k
  unsigned long value;
1464
3.93k
  const u8 *subject_dn;
1465
1466
  /* tbsCertificate TBSCertificate ::= SEQUENCE */
1467
3.93k
  if (asn1_get_next(buf, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
1468
44
    asn1_unexpected(&hdr,
1469
44
        "X509: tbsCertificate did not start with a valid SEQUENCE");
1470
44
    return -1;
1471
44
  }
1472
3.89k
  pos = hdr.payload;
1473
3.89k
  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
3.89k
  if (asn1_get_next(pos, end - pos, &hdr) < 0)
1480
13
    return -1;
1481
3.87k
  pos = hdr.payload;
1482
1483
3.87k
  if (asn1_is_cs_tag(&hdr, 0) && hdr.constructed) {
1484
2.98k
    if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1485
2.97k
        !asn1_is_integer(&hdr)) {
1486
21
      asn1_unexpected(&hdr,
1487
21
          "X509: No INTEGER tag found for version field");
1488
21
      return -1;
1489
21
    }
1490
2.96k
    if (hdr.length != 1) {
1491
2
      wpa_printf(MSG_DEBUG, "X509: Unexpected version field "
1492
2
           "length %u (expected 1)", hdr.length);
1493
2
      return -1;
1494
2
    }
1495
2.95k
    pos = hdr.payload;
1496
2.95k
    left = hdr.length;
1497
2.95k
    value = 0;
1498
5.91k
    while (left) {
1499
2.95k
      value <<= 8;
1500
2.95k
      value |= *pos++;
1501
2.95k
      left--;
1502
2.95k
    }
1503
1504
2.95k
    cert->version = value;
1505
2.95k
    if (cert->version != X509_CERT_V1 &&
1506
1.88k
        cert->version != X509_CERT_V2 &&
1507
1.84k
        cert->version != X509_CERT_V3) {
1508
9
      wpa_printf(MSG_DEBUG, "X509: Unsupported version %d",
1509
9
           cert->version + 1);
1510
9
      return -1;
1511
9
    }
1512
1513
2.94k
    if (asn1_get_next(pos, end - pos, &hdr) < 0)
1514
5
      return -1;
1515
2.94k
  } else
1516
897
    cert->version = X509_CERT_V1;
1517
3.84k
  wpa_printf(MSG_MSGDUMP, "X509: Version X.509v%d", cert->version + 1);
1518
1519
  /* serialNumber CertificateSerialNumber ::= INTEGER */
1520
3.84k
  if (!asn1_is_integer(&hdr) ||
1521
3.81k
      hdr.length < 1 || hdr.length > X509_MAX_SERIAL_NUM_LEN) {
1522
33
    asn1_unexpected(&hdr,
1523
33
        "X509: No INTEGER tag found for serialNumber");
1524
33
    return -1;
1525
33
  }
1526
1527
3.80k
  pos = hdr.payload + hdr.length;
1528
7.81k
  while (hdr.length > 0 && hdr.payload[0] == 0) {
1529
4.00k
    hdr.payload++;
1530
4.00k
    hdr.length--;
1531
4.00k
  }
1532
3.80k
  os_memcpy(cert->serial_number, hdr.payload, hdr.length);
1533
3.80k
  cert->serial_number_len = hdr.length;
1534
3.80k
  wpa_hexdump(MSG_MSGDUMP, "X509: serialNumber", cert->serial_number,
1535
3.80k
        cert->serial_number_len);
1536
1537
  /* signature AlgorithmIdentifier */
1538
3.80k
  if (x509_parse_algorithm_identifier(pos, end - pos, &cert->signature,
1539
3.80k
              &pos))
1540
80
    return -1;
1541
1542
  /* issuer Name */
1543
3.72k
  if (x509_parse_name(pos, end - pos, &cert->issuer, &pos))
1544
327
    return -1;
1545
3.40k
  x509_name_string(&cert->issuer, sbuf, sizeof(sbuf));
1546
3.40k
  wpa_printf(MSG_MSGDUMP, "X509: issuer %s", sbuf);
1547
1548
  /* validity Validity */
1549
3.40k
  if (x509_parse_validity(pos, end - pos, cert, &pos))
1550
188
    return -1;
1551
1552
  /* subject Name */
1553
3.21k
  subject_dn = pos;
1554
3.21k
  if (x509_parse_name(pos, end - pos, &cert->subject, &pos))
1555
12
    return -1;
1556
3.20k
  cert->subject_dn = os_malloc(pos - subject_dn);
1557
3.20k
  if (!cert->subject_dn)
1558
0
    return -1;
1559
3.20k
  cert->subject_dn_len = pos - subject_dn;
1560
3.20k
  os_memcpy(cert->subject_dn, subject_dn, cert->subject_dn_len);
1561
3.20k
  x509_name_string(&cert->subject, sbuf, sizeof(sbuf));
1562
3.20k
  wpa_printf(MSG_MSGDUMP, "X509: subject %s", sbuf);
1563
1564
  /* subjectPublicKeyInfo SubjectPublicKeyInfo */
1565
3.20k
  if (x509_parse_public_key(pos, end - pos, cert, &pos))
1566
38
    return -1;
1567
1568
3.16k
  if (pos == end)
1569
303
    return 0;
1570
1571
2.86k
  if (cert->version == X509_CERT_V1)
1572
1.05k
    return 0;
1573
1574
1.80k
  if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1575
1.79k
      hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC) {
1576
8
    asn1_unexpected(&hdr,
1577
8
        "X509: Expected Context-Specific tag to parse optional tbsCertificate field(s)");
1578
8
    return -1;
1579
8
  }
1580
1581
1.79k
  if (hdr.tag == 1) {
1582
    /* issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL */
1583
60
    wpa_printf(MSG_DEBUG, "X509: issuerUniqueID");
1584
    /* TODO: parse UniqueIdentifier ::= BIT STRING */
1585
1586
60
    pos = hdr.payload + hdr.length;
1587
60
    if (pos == end)
1588
44
      return 0;
1589
1590
16
    if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1591
15
        hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC) {
1592
3
      asn1_unexpected(&hdr,
1593
3
          "X509: Expected Context-Specific tag to parse optional tbsCertificate field(s)");
1594
3
      return -1;
1595
3
    }
1596
16
  }
1597
1598
1.74k
  if (hdr.tag == 2) {
1599
    /* subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL */
1600
226
    wpa_printf(MSG_DEBUG, "X509: subjectUniqueID");
1601
    /* TODO: parse UniqueIdentifier ::= BIT STRING */
1602
1603
226
    pos = hdr.payload + hdr.length;
1604
226
    if (pos == end)
1605
55
      return 0;
1606
1607
171
    if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1608
170
        hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC) {
1609
5
      asn1_unexpected(&hdr,
1610
5
          "X509: Expected Context-Specific tag to parse optional tbsCertificate field(s)");
1611
5
      return -1;
1612
5
    }
1613
171
  }
1614
1615
1.68k
  if (hdr.tag != 3) {
1616
654
    wpa_printf(MSG_DEBUG,
1617
654
         "X509: Ignored unexpected Context-Specific constructed %d tag %d in optional tbsCertificate fields",
1618
654
         hdr.constructed, hdr.tag);
1619
654
    return 0;
1620
654
  }
1621
1622
  /* extensions      [3]  EXPLICIT Extensions OPTIONAL */
1623
1624
1.03k
  if (cert->version != X509_CERT_V3) {
1625
2
    wpa_printf(MSG_DEBUG, "X509: X.509%d certificate and "
1626
2
         "Extensions data which are only allowed for "
1627
2
         "version 3", cert->version + 1);
1628
2
    return -1;
1629
2
  }
1630
1631
1.03k
  if (x509_parse_extensions(cert, hdr.payload, hdr.length) < 0)
1632
414
    return -1;
1633
1634
617
  pos = hdr.payload + hdr.length;
1635
617
  if (pos < end) {
1636
19
    wpa_hexdump(MSG_DEBUG,
1637
19
          "X509: Ignored extra tbsCertificate data",
1638
19
          pos, end - pos);
1639
19
  }
1640
1641
617
  return 0;
1642
1.03k
}
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
4.06k
{
1729
4.06k
  struct asn1_hdr hdr;
1730
4.06k
  const u8 *pos, *end, *hash_start;
1731
4.06k
  struct x509_certificate *cert;
1732
1733
4.06k
  cert = os_zalloc(sizeof(*cert) + len);
1734
4.06k
  if (cert == NULL)
1735
0
    return NULL;
1736
4.06k
  os_memcpy(cert + 1, buf, len);
1737
4.06k
  cert->cert_start = (u8 *) (cert + 1);
1738
4.06k
  cert->cert_len = len;
1739
1740
4.06k
  pos = buf;
1741
4.06k
  end = buf + len;
1742
1743
  /* RFC 3280 - X.509 v3 certificate / ASN.1 DER */
1744
1745
  /* Certificate ::= SEQUENCE */
1746
4.06k
  if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
1747
128
    asn1_unexpected(&hdr,
1748
128
        "X509: Certificate did not start with a valid SEQUENCE");
1749
128
    x509_certificate_free(cert);
1750
128
    return NULL;
1751
128
  }
1752
3.93k
  pos = hdr.payload;
1753
1754
3.93k
  if (hdr.length > end - pos) {
1755
0
    x509_certificate_free(cert);
1756
0
    return NULL;
1757
0
  }
1758
1759
3.93k
  if (hdr.length < end - pos) {
1760
1.69k
    wpa_hexdump(MSG_MSGDUMP, "X509: Ignoring extra data after DER "
1761
1.69k
          "encoded certificate",
1762
1.69k
          pos + hdr.length, end - (pos + hdr.length));
1763
1.69k
    end = pos + hdr.length;
1764
1.69k
  }
1765
1766
3.93k
  hash_start = pos;
1767
3.93k
  cert->tbs_cert_start = cert->cert_start + (hash_start - buf);
1768
3.93k
  if (x509_parse_tbs_certificate(pos, end - pos, cert, &pos)) {
1769
1.20k
    x509_certificate_free(cert);
1770
1.20k
    return NULL;
1771
1.20k
  }
1772
2.73k
  cert->tbs_cert_len = pos - hash_start;
1773
1774
  /* signatureAlgorithm AlgorithmIdentifier */
1775
2.73k
  if (x509_parse_algorithm_identifier(pos, end - pos,
1776
2.73k
              &cert->signature_alg, &pos)) {
1777
41
    x509_certificate_free(cert);
1778
41
    return NULL;
1779
41
  }
1780
1781
  /* signatureValue BIT STRING */
1782
2.69k
  if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1783
2.68k
      !asn1_is_bitstring(&hdr)) {
1784
14
    asn1_unexpected(&hdr,
1785
14
        "X509: Expected BITSTRING (signatureValue)");
1786
14
    x509_certificate_free(cert);
1787
14
    return NULL;
1788
14
  }
1789
2.67k
  if (hdr.length < 1) {
1790
2
    x509_certificate_free(cert);
1791
2
    return NULL;
1792
2
  }
1793
2.67k
  pos = hdr.payload;
1794
2.67k
  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.66k
  os_free(cert->sign_value);
1806
2.66k
  cert->sign_value = os_memdup(pos + 1, hdr.length - 1);
1807
2.66k
  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.66k
  cert->sign_value_len = hdr.length - 1;
1814
2.66k
  wpa_hexdump(MSG_MSGDUMP, "X509: signature",
1815
2.66k
        cert->sign_value, cert->sign_value_len);
1816
1817
2.66k
  return cert;
1818
2.66k
}
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
}