Coverage Report

Created: 2023-03-26 06:22

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