Coverage Report

Created: 2025-04-24 06:18

/src/hostap/src/tls/tlsv1_cred.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * TLSv1 credentials
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 "base64.h"
13
#include "crypto/crypto.h"
14
#include "crypto/sha1.h"
15
#include "pkcs5.h"
16
#include "pkcs8.h"
17
#include "x509v3.h"
18
#include "tlsv1_cred.h"
19
20
21
struct tlsv1_credentials * tlsv1_cred_alloc(void)
22
0
{
23
0
  struct tlsv1_credentials *cred;
24
0
  cred = os_zalloc(sizeof(*cred));
25
0
  return cred;
26
0
}
27
28
29
void tlsv1_cred_free(struct tlsv1_credentials *cred)
30
6.29k
{
31
6.29k
  if (cred == NULL)
32
6.29k
    return;
33
34
0
  x509_certificate_chain_free(cred->trusted_certs);
35
0
  x509_certificate_chain_free(cred->cert);
36
0
  crypto_private_key_free(cred->key);
37
0
  os_free(cred->dh_p);
38
0
  os_free(cred->dh_g);
39
0
  os_free(cred->ocsp_stapling_response);
40
0
  os_free(cred->ocsp_stapling_response_multi);
41
0
  os_free(cred);
42
0
}
43
44
45
static int tlsv1_add_cert_der(struct x509_certificate **chain,
46
            const u8 *buf, size_t len)
47
0
{
48
0
  struct x509_certificate *cert, *p;
49
0
  char name[128];
50
51
0
  cert = x509_certificate_parse(buf, len);
52
0
  if (cert == NULL) {
53
0
    wpa_printf(MSG_INFO, "TLSv1: %s - failed to parse certificate",
54
0
         __func__);
55
0
    return -1;
56
0
  }
57
58
0
  p = *chain;
59
0
  while (p && p->next)
60
0
    p = p->next;
61
0
  if (p && x509_name_compare(&cert->subject, &p->issuer) == 0) {
62
    /*
63
     * The new certificate is the issuer of the last certificate in
64
     * the chain - add the new certificate to the end.
65
     */
66
0
    p->next = cert;
67
0
  } else {
68
    /* Add to the beginning of the chain */
69
0
    cert->next = *chain;
70
0
    *chain = cert;
71
0
  }
72
73
0
  x509_name_string(&cert->subject, name, sizeof(name));
74
0
  wpa_printf(MSG_DEBUG, "TLSv1: Added certificate: %s", name);
75
76
0
  return 0;
77
0
}
78
79
80
static const char *pem_cert_begin = "-----BEGIN CERTIFICATE-----";
81
static const char *pem_cert_end = "-----END CERTIFICATE-----";
82
static const char *pem_key_begin = "-----BEGIN RSA PRIVATE KEY-----";
83
static const char *pem_key_end = "-----END RSA PRIVATE KEY-----";
84
static const char *pem_key2_begin = "-----BEGIN PRIVATE KEY-----";
85
static const char *pem_key2_end = "-----END PRIVATE KEY-----";
86
static const char *pem_key_enc_begin = "-----BEGIN ENCRYPTED PRIVATE KEY-----";
87
static const char *pem_key_enc_end = "-----END ENCRYPTED PRIVATE KEY-----";
88
89
90
static const u8 * search_tag(const char *tag, const u8 *buf, size_t len)
91
0
{
92
0
  size_t i, plen;
93
94
0
  plen = os_strlen(tag);
95
0
  if (len < plen)
96
0
    return NULL;
97
98
0
  for (i = 0; i < len - plen; i++) {
99
0
    if (os_memcmp(buf + i, tag, plen) == 0)
100
0
      return buf + i;
101
0
  }
102
103
0
  return NULL;
104
0
}
105
106
107
static int tlsv1_add_cert(struct x509_certificate **chain,
108
        const u8 *buf, size_t len)
109
0
{
110
0
  const u8 *pos, *end;
111
0
  unsigned char *der;
112
0
  size_t der_len;
113
114
0
  pos = search_tag(pem_cert_begin, buf, len);
115
0
  if (!pos) {
116
0
    wpa_printf(MSG_DEBUG, "TLSv1: No PEM certificate tag found - "
117
0
         "assume DER format");
118
0
    return tlsv1_add_cert_der(chain, buf, len);
119
0
  }
120
121
0
  wpa_printf(MSG_DEBUG, "TLSv1: Converting PEM format certificate into "
122
0
       "DER format");
123
124
0
  while (pos) {
125
0
    pos += os_strlen(pem_cert_begin);
126
0
    end = search_tag(pem_cert_end, pos, buf + len - pos);
127
0
    if (end == NULL) {
128
0
      wpa_printf(MSG_INFO, "TLSv1: Could not find PEM "
129
0
           "certificate end tag (%s)", pem_cert_end);
130
0
      return -1;
131
0
    }
132
133
0
    der = base64_decode((const char *) pos, end - pos, &der_len);
134
0
    if (der == NULL) {
135
0
      wpa_printf(MSG_INFO, "TLSv1: Could not decode PEM "
136
0
           "certificate");
137
0
      return -1;
138
0
    }
139
140
0
    if (tlsv1_add_cert_der(chain, der, der_len) < 0) {
141
0
      wpa_printf(MSG_INFO, "TLSv1: Failed to parse PEM "
142
0
           "certificate after DER conversion");
143
0
      os_free(der);
144
0
      return -1;
145
0
    }
146
147
0
    os_free(der);
148
149
0
    end += os_strlen(pem_cert_end);
150
0
    pos = search_tag(pem_cert_begin, end, buf + len - end);
151
0
  }
152
153
0
  return 0;
154
0
}
155
156
157
static int tlsv1_set_cert_chain(struct x509_certificate **chain,
158
        const char *cert, const u8 *cert_blob,
159
        size_t cert_blob_len)
160
0
{
161
0
  if (cert_blob)
162
0
    return tlsv1_add_cert(chain, cert_blob, cert_blob_len);
163
164
0
  if (cert) {
165
0
    u8 *buf;
166
0
    size_t len;
167
0
    int ret;
168
169
0
    buf = (u8 *) os_readfile(cert, &len);
170
0
    if (buf == NULL) {
171
0
      wpa_printf(MSG_INFO, "TLSv1: Failed to read '%s'",
172
0
           cert);
173
0
      return -1;
174
0
    }
175
176
0
    ret = tlsv1_add_cert(chain, buf, len);
177
0
    os_free(buf);
178
0
    return ret;
179
0
  }
180
181
0
  return 0;
182
0
}
183
184
185
/**
186
 * tlsv1_set_ca_cert - Set trusted CA certificate(s)
187
 * @cred: TLSv1 credentials from tlsv1_cred_alloc()
188
 * @cert: File or reference name for X.509 certificate in PEM or DER format
189
 * @cert_blob: cert as inlined data or %NULL if not used
190
 * @cert_blob_len: ca_cert_blob length
191
 * @path: Path to CA certificates (not yet supported)
192
 * Returns: 0 on success, -1 on failure
193
 */
194
int tlsv1_set_ca_cert(struct tlsv1_credentials *cred, const char *cert,
195
          const u8 *cert_blob, size_t cert_blob_len,
196
          const char *path)
197
0
{
198
0
  if (cert && os_strncmp(cert, "hash://", 7) == 0) {
199
0
    const char *pos = cert + 7;
200
0
    if (os_strncmp(pos, "server/sha256/", 14) != 0) {
201
0
      wpa_printf(MSG_DEBUG,
202
0
           "TLSv1: Unsupported ca_cert hash value '%s'",
203
0
           cert);
204
0
      return -1;
205
0
    }
206
0
    pos += 14;
207
0
    if (os_strlen(pos) != 32 * 2) {
208
0
      wpa_printf(MSG_DEBUG,
209
0
           "TLSv1: Unexpected SHA256 hash length in ca_cert '%s'",
210
0
           cert);
211
0
      return -1;
212
0
    }
213
0
    if (hexstr2bin(pos, cred->srv_cert_hash, 32) < 0) {
214
0
      wpa_printf(MSG_DEBUG,
215
0
           "TLSv1: Invalid SHA256 hash value in ca_cert '%s'",
216
0
           cert);
217
0
      return -1;
218
0
    }
219
0
    cred->server_cert_only = 1;
220
0
    cred->ca_cert_verify = 0;
221
0
    wpa_printf(MSG_DEBUG,
222
0
         "TLSv1: Checking only server certificate match");
223
0
    return 0;
224
0
  }
225
226
0
  if (cert && os_strncmp(cert, "probe://", 8) == 0) {
227
0
    cred->cert_probe = 1;
228
0
    cred->ca_cert_verify = 0;
229
0
    wpa_printf(MSG_DEBUG, "TLSv1: Only probe server certificate");
230
0
    return 0;
231
0
  }
232
233
0
  cred->ca_cert_verify = cert || cert_blob || path;
234
235
0
  if (tlsv1_set_cert_chain(&cred->trusted_certs, cert,
236
0
         cert_blob, cert_blob_len) < 0)
237
0
    return -1;
238
239
0
  if (path) {
240
    /* TODO: add support for reading number of certificate files */
241
0
    wpa_printf(MSG_INFO, "TLSv1: Use of CA certificate directory "
242
0
         "not yet supported");
243
0
    return -1;
244
0
  }
245
246
0
  return 0;
247
0
}
248
249
250
/**
251
 * tlsv1_set_cert - Set certificate
252
 * @cred: TLSv1 credentials from tlsv1_cred_alloc()
253
 * @cert: File or reference name for X.509 certificate in PEM or DER format
254
 * @cert_blob: cert as inlined data or %NULL if not used
255
 * @cert_blob_len: cert_blob length
256
 * Returns: 0 on success, -1 on failure
257
 */
258
int tlsv1_set_cert(struct tlsv1_credentials *cred, const char *cert,
259
       const u8 *cert_blob, size_t cert_blob_len)
260
0
{
261
0
  return tlsv1_set_cert_chain(&cred->cert, cert,
262
0
            cert_blob, cert_blob_len);
263
0
}
264
265
266
static struct crypto_private_key * tlsv1_set_key_pem(const u8 *key, size_t len)
267
0
{
268
0
  const u8 *pos, *end;
269
0
  unsigned char *der;
270
0
  size_t der_len;
271
0
  struct crypto_private_key *pkey;
272
273
0
  pos = search_tag(pem_key_begin, key, len);
274
0
  if (!pos) {
275
0
    pos = search_tag(pem_key2_begin, key, len);
276
0
    if (!pos)
277
0
      return NULL;
278
0
    pos += os_strlen(pem_key2_begin);
279
0
    end = search_tag(pem_key2_end, pos, key + len - pos);
280
0
    if (!end)
281
0
      return NULL;
282
0
  } else {
283
0
    const u8 *pos2;
284
0
    pos += os_strlen(pem_key_begin);
285
0
    end = search_tag(pem_key_end, pos, key + len - pos);
286
0
    if (!end)
287
0
      return NULL;
288
0
    pos2 = search_tag("Proc-Type: 4,ENCRYPTED", pos, end - pos);
289
0
    if (pos2) {
290
0
      wpa_printf(MSG_DEBUG, "TLSv1: Unsupported private key "
291
0
           "format (Proc-Type/DEK-Info)");
292
0
      return NULL;
293
0
    }
294
0
  }
295
296
0
  der = base64_decode((const char *) pos, end - pos, &der_len);
297
0
  if (!der)
298
0
    return NULL;
299
0
  pkey = crypto_private_key_import(der, der_len, NULL);
300
0
  os_free(der);
301
0
  return pkey;
302
0
}
303
304
305
static struct crypto_private_key * tlsv1_set_key_enc_pem(const u8 *key,
306
               size_t len,
307
               const char *passwd)
308
0
{
309
0
  const u8 *pos, *end;
310
0
  unsigned char *der;
311
0
  size_t der_len;
312
0
  struct crypto_private_key *pkey;
313
314
0
  if (passwd == NULL)
315
0
    return NULL;
316
0
  pos = search_tag(pem_key_enc_begin, key, len);
317
0
  if (!pos)
318
0
    return NULL;
319
0
  pos += os_strlen(pem_key_enc_begin);
320
0
  end = search_tag(pem_key_enc_end, pos, key + len - pos);
321
0
  if (!end)
322
0
    return NULL;
323
324
0
  der = base64_decode((const char *) pos, end - pos, &der_len);
325
0
  if (!der)
326
0
    return NULL;
327
0
  pkey = crypto_private_key_import(der, der_len, passwd);
328
0
  os_free(der);
329
0
  return pkey;
330
0
}
331
332
333
#ifdef PKCS12_FUNCS
334
335
static int oid_is_rsadsi(struct asn1_oid *oid)
336
{
337
  return oid->len >= 4 &&
338
    oid->oid[0] == 1 /* iso */ &&
339
    oid->oid[1] == 2 /* member-body */ &&
340
    oid->oid[2] == 840 /* us */ &&
341
    oid->oid[3] == 113549 /* rsadsi */;
342
}
343
344
345
static int pkcs12_is_bagtype_oid(struct asn1_oid *oid, unsigned long type)
346
{
347
  return oid->len == 9 &&
348
    oid_is_rsadsi(oid) &&
349
    oid->oid[4] == 1 /* pkcs */ &&
350
    oid->oid[5] == 12 /* pkcs-12 */ &&
351
    oid->oid[6] == 10 &&
352
    oid->oid[7] == 1 /* bagtypes */ &&
353
    oid->oid[8] == type;
354
}
355
356
357
static int is_oid_pkcs7(struct asn1_oid *oid)
358
{
359
  return oid->len == 7 &&
360
    oid->oid[0] == 1 /* iso */ &&
361
    oid->oid[1] == 2 /* member-body */ &&
362
    oid->oid[2] == 840 /* us */ &&
363
    oid->oid[3] == 113549 /* rsadsi */ &&
364
    oid->oid[4] == 1 /* pkcs */ &&
365
    oid->oid[5] == 7 /* pkcs-7 */;
366
}
367
368
369
static int is_oid_pkcs7_data(struct asn1_oid *oid)
370
{
371
  return is_oid_pkcs7(oid) && oid->oid[6] == 1 /* data */;
372
}
373
374
375
static int is_oid_pkcs7_enc_data(struct asn1_oid *oid)
376
{
377
  return is_oid_pkcs7(oid) && oid->oid[6] == 6 /* encryptedData */;
378
}
379
380
381
static int is_oid_pkcs9(struct asn1_oid *oid)
382
{
383
  return oid->len >= 6 &&
384
    oid->oid[0] == 1 /* iso */ &&
385
    oid->oid[1] == 2 /* member-body */ &&
386
    oid->oid[2] == 840 /* us */ &&
387
    oid->oid[3] == 113549 /* rsadsi */ &&
388
    oid->oid[4] == 1 /* pkcs */ &&
389
    oid->oid[5] == 9 /* pkcs-9 */;
390
}
391
392
393
static int is_oid_pkcs9_friendly_name(struct asn1_oid *oid)
394
{
395
  return oid->len == 7 && is_oid_pkcs9(oid) &&
396
    oid->oid[6] == 20;
397
}
398
399
400
static int is_oid_pkcs9_local_key_id(struct asn1_oid *oid)
401
{
402
  return oid->len == 7 && is_oid_pkcs9(oid) &&
403
    oid->oid[6] == 21;
404
}
405
406
407
static int is_oid_pkcs9_x509_cert(struct asn1_oid *oid)
408
{
409
  return oid->len == 8 && is_oid_pkcs9(oid) &&
410
    oid->oid[6] == 22 /* certTypes */ &&
411
    oid->oid[7] == 1 /* x509Certificate */;
412
}
413
414
415
static int pkcs12_keybag(struct tlsv1_credentials *cred,
416
       const u8 *buf, size_t len)
417
{
418
  /* TODO */
419
  return 0;
420
}
421
422
423
static int pkcs12_pkcs8_keybag(struct tlsv1_credentials *cred,
424
             const u8 *buf, size_t len,
425
             const char *passwd)
426
{
427
  struct crypto_private_key *key;
428
429
  /* PKCS8ShroudedKeyBag ::= EncryptedPrivateKeyInfo */
430
  key = pkcs8_enc_key_import(buf, len, passwd);
431
  if (!key)
432
    return -1;
433
434
  wpa_printf(MSG_DEBUG,
435
       "PKCS #12: Successfully decrypted PKCS8ShroudedKeyBag");
436
  crypto_private_key_free(cred->key);
437
  cred->key = key;
438
439
  return 0;
440
}
441
442
443
static int pkcs12_certbag(struct tlsv1_credentials *cred,
444
        const u8 *buf, size_t len)
445
{
446
  struct asn1_hdr hdr;
447
  struct asn1_oid oid;
448
  char obuf[80];
449
  const u8 *pos, *end;
450
451
  /*
452
   * CertBag ::= SEQUENCE {
453
   *     certId      BAG-TYPE.&id   ({CertTypes}),
454
   *     certValue   [0] EXPLICIT BAG-TYPE.&Type ({CertTypes}{@certId})
455
   * }
456
   */
457
458
  if (asn1_get_next(buf, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
459
    asn1_unexpected(&hdr, "PKCS #12: Expected SEQUENCE (CertBag)");
460
    return -1;
461
  }
462
463
  pos = hdr.payload;
464
  end = hdr.payload + hdr.length;
465
466
  if (asn1_get_oid(pos, end - pos, &oid, &pos)) {
467
    wpa_printf(MSG_DEBUG,
468
         "PKCS #12: Failed to parse OID (certId)");
469
    return -1;
470
  }
471
472
  asn1_oid_to_str(&oid, obuf, sizeof(obuf));
473
  wpa_printf(MSG_DEBUG, "PKCS #12: certId %s", obuf);
474
475
  if (!is_oid_pkcs9_x509_cert(&oid)) {
476
    wpa_printf(MSG_DEBUG,
477
         "PKCS #12: Ignored unsupported certificate type (certId %s)",
478
         obuf);
479
  }
480
481
  if (asn1_get_next(pos, end - pos, &hdr) < 0 || !hdr.constructed ||
482
      !asn1_is_cs_tag(&hdr, 0)) {
483
    asn1_unexpected(&hdr,
484
        "PKCS #12: Expected [0] EXPLICIT (certValue)");
485
    return -1;
486
  }
487
488
  if (asn1_get_next(hdr.payload, hdr.length, &hdr) < 0 ||
489
      !asn1_is_octetstring(&hdr)) {
490
    asn1_unexpected(&hdr,
491
        "PKCS #12: Expected OCTET STRING (x509Certificate)");
492
    return -1;
493
  }
494
495
  wpa_hexdump(MSG_DEBUG, "PKCS #12: x509Certificate",
496
        hdr.payload, hdr.length);
497
  if (cred->cert) {
498
    struct x509_certificate *cert;
499
500
    wpa_printf(MSG_DEBUG, "PKCS #12: Ignore extra certificate");
501
    cert = x509_certificate_parse(hdr.payload, hdr.length);
502
    if (!cert) {
503
      wpa_printf(MSG_DEBUG,
504
           "PKCS #12: Failed to parse x509Certificate");
505
      return 0;
506
    }
507
    x509_certificate_chain_free(cert);
508
509
    return 0;
510
  }
511
  return tlsv1_set_cert(cred, NULL, hdr.payload, hdr.length);
512
}
513
514
515
static int pkcs12_parse_attr_friendly_name(const u8 *pos, const u8 *end)
516
{
517
  struct asn1_hdr hdr;
518
519
  /*
520
   * RFC 2985, 5.5.1:
521
   * friendlyName ATTRIBUTE ::= {
522
   *         WITH SYNTAX BMPString (SIZE(1..pkcs-9-ub-friendlyName))
523
   *         EQUALITY MATCHING RULE caseIgnoreMatch
524
   *         SINGLE VALUE TRUE
525
   *          ID pkcs-9-at-friendlyName
526
   * }
527
   */
528
  if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
529
      !asn1_is_bmpstring(&hdr)) {
530
    asn1_unexpected(&hdr,
531
        "PKCS #12: Expected BMPSTRING (friendlyName)");
532
    return 0;
533
  }
534
  wpa_hexdump_ascii(MSG_DEBUG, "PKCS #12: friendlyName",
535
        hdr.payload, hdr.length);
536
  return 0;
537
}
538
539
540
static int pkcs12_parse_attr_local_key_id(const u8 *pos, const u8 *end)
541
{
542
  struct asn1_hdr hdr;
543
544
  /*
545
   * RFC 2985, 5.5.2:
546
   * localKeyId ATTRIBUTE ::= {
547
   *         WITH SYNTAX OCTET STRING
548
   *         EQUALITY MATCHING RULE octetStringMatch
549
   *         SINGLE VALUE TRUE
550
   *         ID pkcs-9-at-localKeyId
551
   * }
552
   */
553
  if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
554
      !asn1_is_octetstring(&hdr)) {
555
    asn1_unexpected(&hdr,
556
        "PKCS #12: Expected OCTET STRING (localKeyID)");
557
    return -1;
558
  }
559
  wpa_hexdump_key(MSG_DEBUG, "PKCS #12: localKeyID",
560
      hdr.payload, hdr.length);
561
  return 0;
562
}
563
564
565
static int pkcs12_parse_attr(const u8 *pos, size_t len)
566
{
567
  const u8 *end = pos + len;
568
  struct asn1_hdr hdr;
569
  struct asn1_oid a_oid;
570
  char obuf[80];
571
572
  /*
573
   * PKCS12Attribute ::= SEQUENCE {
574
   * attrId      ATTRIBUTE.&id ({PKCS12AttrSet}),
575
   * attrValues  SET OF ATTRIBUTE.&Type ({PKCS12AttrSet}{@attrId})
576
   * }
577
   */
578
579
  if (asn1_get_oid(pos, end - pos, &a_oid, &pos)) {
580
    wpa_printf(MSG_DEBUG, "PKCS #12: Failed to parse OID (attrId)");
581
    return -1;
582
  }
583
584
  asn1_oid_to_str(&a_oid, obuf, sizeof(obuf));
585
  wpa_printf(MSG_DEBUG, "PKCS #12: attrId %s", obuf);
586
587
  if (asn1_get_next(pos, end - pos, &hdr) < 0 || !asn1_is_set(&hdr)) {
588
    asn1_unexpected(&hdr, "PKCS #12: Expected SET (attrValues)");
589
    return -1;
590
  }
591
  wpa_hexdump_key(MSG_MSGDUMP, "PKCS #12: attrValues",
592
      hdr.payload, hdr.length);
593
  pos = hdr.payload;
594
  end = hdr.payload + hdr.length;
595
596
  if (is_oid_pkcs9_friendly_name(&a_oid))
597
    return pkcs12_parse_attr_friendly_name(pos, end);
598
  if (is_oid_pkcs9_local_key_id(&a_oid))
599
    return pkcs12_parse_attr_local_key_id(pos, end);
600
601
  wpa_printf(MSG_DEBUG, "PKCS #12: Ignore unknown attribute");
602
  return 0;
603
}
604
605
606
static int pkcs12_safebag(struct tlsv1_credentials *cred,
607
        const u8 *buf, size_t len, const char *passwd)
608
{
609
  struct asn1_hdr hdr;
610
  struct asn1_oid oid;
611
  char obuf[80];
612
  const u8 *pos = buf, *end = buf + len;
613
  const u8 *value;
614
  size_t value_len;
615
616
  wpa_hexdump_key(MSG_MSGDUMP, "PKCS #12: SafeBag", buf, len);
617
618
  /* BAG-TYPE ::= TYPE-IDENTIFIER */
619
  if (asn1_get_oid(pos, end - pos, &oid, &pos)) {
620
    wpa_printf(MSG_DEBUG,
621
         "PKCS #12: Failed to parse OID (BAG-TYPE)");
622
    return -1;
623
  }
624
625
  asn1_oid_to_str(&oid, obuf, sizeof(obuf));
626
  wpa_printf(MSG_DEBUG, "PKCS #12: BAG-TYPE %s", obuf);
627
628
  if (asn1_get_next(pos, end - pos, &hdr) < 0 || !hdr.constructed ||
629
      !asn1_is_cs_tag(&hdr, 0)) {
630
    asn1_unexpected(&hdr,
631
        "PKCS #12: Expected [0] EXPLICIT (bagValue)");
632
    return 0;
633
  }
634
  value = hdr.payload;
635
  value_len = hdr.length;
636
  wpa_hexdump_key(MSG_MSGDUMP, "PKCS #12: bagValue", value, value_len);
637
  pos = hdr.payload + hdr.length;
638
639
  if (pos < end) {
640
    /* bagAttributes  SET OF PKCS12Attribute OPTIONAL */
641
    if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
642
        !asn1_is_set(&hdr)) {
643
      asn1_unexpected(&hdr,
644
          "PKCS #12: Expected SET (bagAttributes)");
645
      return -1;
646
    }
647
    wpa_hexdump_key(MSG_MSGDUMP, "PKCS #12: bagAttributes",
648
        hdr.payload, hdr.length);
649
650
    pos = hdr.payload;
651
    end = hdr.payload + hdr.length;
652
    while (pos < end) {
653
      /* PKCS12Attribute ::= SEQUENCE */
654
      if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
655
          !asn1_is_sequence(&hdr)) {
656
        asn1_unexpected(&hdr,
657
            "PKCS #12: Expected SEQUENCE (PKCS12Attribute)");
658
        return -1;
659
      }
660
      if (pkcs12_parse_attr(hdr.payload, hdr.length) < 0)
661
        return -1;
662
      pos = hdr.payload + hdr.length;
663
    }
664
  }
665
666
  if (pkcs12_is_bagtype_oid(&oid, 1))
667
    return pkcs12_keybag(cred, value, value_len);
668
  if (pkcs12_is_bagtype_oid(&oid, 2))
669
    return pkcs12_pkcs8_keybag(cred, value, value_len, passwd);
670
  if (pkcs12_is_bagtype_oid(&oid, 3))
671
    return pkcs12_certbag(cred, value, value_len);
672
673
  wpa_printf(MSG_DEBUG, "PKCS #12: Ignore unsupported BAG-TYPE");
674
  return 0;
675
}
676
677
678
static int pkcs12_safecontents(struct tlsv1_credentials *cred,
679
             const u8 *buf, size_t len,
680
             const char *passwd)
681
{
682
  struct asn1_hdr hdr;
683
  const u8 *pos, *end;
684
685
  /* SafeContents ::= SEQUENCE OF SafeBag */
686
  if (asn1_get_next(buf, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
687
    asn1_unexpected(&hdr,
688
        "PKCS #12: Expected SEQUENCE (SafeContents)");
689
    return -1;
690
  }
691
  pos = hdr.payload;
692
  end = hdr.payload + hdr.length;
693
694
  /*
695
   * SafeBag ::= SEQUENCE {
696
   *   bagId          BAG-TYPE.&id ({PKCS12BagSet})
697
   *   bagValue       [0] EXPLICIT BAG-TYPE.&Type({PKCS12BagSet}{@bagId}),
698
   *   bagAttributes  SET OF PKCS12Attribute OPTIONAL
699
   * }
700
   */
701
702
  while (pos < end) {
703
    if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
704
        !asn1_is_sequence(&hdr)) {
705
      asn1_unexpected(&hdr,
706
          "PKCS #12: Expected SEQUENCE (SafeBag)");
707
      return -1;
708
    }
709
    if (pkcs12_safebag(cred, hdr.payload, hdr.length, passwd) < 0)
710
      return -1;
711
    pos = hdr.payload + hdr.length;
712
  }
713
714
  return 0;
715
}
716
717
718
static int pkcs12_parse_content_data(struct tlsv1_credentials *cred,
719
             const u8 *pos, const u8 *end,
720
             const char *passwd)
721
{
722
  struct asn1_hdr hdr;
723
724
  /* Data ::= OCTET STRING */
725
  if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
726
      !asn1_is_octetstring(&hdr)) {
727
    asn1_unexpected(&hdr, "PKCS #12: Expected OCTET STRING (Data)");
728
    return -1;
729
  }
730
731
  wpa_hexdump(MSG_MSGDUMP, "PKCS #12: Data", hdr.payload, hdr.length);
732
733
  return pkcs12_safecontents(cred, hdr.payload, hdr.length, passwd);
734
}
735
736
737
static int pkcs12_parse_content_enc_data(struct tlsv1_credentials *cred,
738
           const u8 *pos, const u8 *end,
739
           const char *passwd)
740
{
741
  struct asn1_hdr hdr;
742
  struct asn1_oid oid;
743
  char buf[80];
744
  const u8 *enc_alg;
745
  u8 *data;
746
  size_t enc_alg_len, data_len;
747
  int res = -1;
748
749
  /*
750
   * EncryptedData ::= SEQUENCE {
751
   *   version Version,
752
   *   encryptedContentInfo EncryptedContentInfo }
753
   */
754
  if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
755
      !asn1_is_sequence(&hdr)) {
756
    asn1_unexpected(&hdr,
757
        "PKCS #12: Expected SEQUENCE (EncryptedData)");
758
    return 0;
759
  }
760
  pos = hdr.payload;
761
762
  /* Version ::= INTEGER */
763
  if (asn1_get_next(pos, end - pos, &hdr) < 0 || !asn1_is_integer(&hdr)) {
764
    asn1_unexpected(&hdr,
765
        "PKCS #12: No INTEGER tag found for version");
766
    return -1;
767
  }
768
  if (hdr.length != 1 || hdr.payload[0] != 0) {
769
    wpa_printf(MSG_DEBUG, "PKCS #12: Unrecognized PKCS #7 version");
770
    return -1;
771
  }
772
  pos = hdr.payload + hdr.length;
773
774
  wpa_hexdump(MSG_MSGDUMP, "PKCS #12: EncryptedContentInfo",
775
        pos, end - pos);
776
777
  /*
778
   * EncryptedContentInfo ::= SEQUENCE {
779
   *   contentType ContentType,
780
   *   contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
781
   *   encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL }
782
   */
783
  if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
784
      !asn1_is_sequence(&hdr)) {
785
    asn1_unexpected(&hdr,
786
        "PKCS #12: Expected SEQUENCE (EncryptedContentInfo)");
787
    return -1;
788
  }
789
790
  pos = hdr.payload;
791
  end = pos + hdr.length;
792
793
  /* ContentType ::= OBJECT IDENTIFIER */
794
  if (asn1_get_oid(pos, end - pos, &oid, &pos)) {
795
    wpa_printf(MSG_DEBUG,
796
         "PKCS #12: Could not find OBJECT IDENTIFIER (contentType)");
797
    return -1;
798
  }
799
  asn1_oid_to_str(&oid, buf, sizeof(buf));
800
  wpa_printf(MSG_DEBUG, "PKCS #12: EncryptedContentInfo::contentType %s",
801
       buf);
802
803
  if (!is_oid_pkcs7_data(&oid)) {
804
    wpa_printf(MSG_DEBUG,
805
         "PKCS #12: Unsupported EncryptedContentInfo::contentType %s",
806
         buf);
807
    return 0;
808
  }
809
810
  /* ContentEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier */
811
  if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
812
      !asn1_is_sequence(&hdr)) {
813
    asn1_unexpected(&hdr,
814
        "PKCS #12: Expected SEQUENCE (ContentEncryptionAlgorithmIdentifier)");
815
    return -1;
816
  }
817
  enc_alg = hdr.payload;
818
  enc_alg_len = hdr.length;
819
  pos = hdr.payload + hdr.length;
820
821
  if (asn1_get_next(pos, end - pos, &hdr) < 0 || hdr.constructed ||
822
      !asn1_is_cs_tag(&hdr, 0)) {
823
    asn1_unexpected(&hdr,
824
        "PKCS #12: Expected [0] IMPLICIT (encryptedContent)");
825
    return -1;
826
  }
827
828
  /* EncryptedContent ::= OCTET STRING */
829
  data = pkcs5_decrypt(enc_alg, enc_alg_len, hdr.payload, hdr.length,
830
           passwd, &data_len);
831
  if (data) {
832
    wpa_hexdump_key(MSG_MSGDUMP,
833
        "PKCS #12: Decrypted encryptedContent",
834
        data, data_len);
835
    res = pkcs12_safecontents(cred, data, data_len, passwd);
836
    os_free(data);
837
  }
838
839
  return res;
840
}
841
842
843
static int pkcs12_parse_content(struct tlsv1_credentials *cred,
844
        const u8 *buf, size_t len,
845
        const char *passwd)
846
{
847
  const u8 *pos = buf;
848
  const u8 *end = buf + len;
849
  struct asn1_oid oid;
850
  char txt[80];
851
  struct asn1_hdr hdr;
852
853
  wpa_hexdump(MSG_MSGDUMP, "PKCS #12: ContentInfo", buf, len);
854
855
  if (asn1_get_oid(pos, end - pos, &oid, &pos)) {
856
    wpa_printf(MSG_DEBUG,
857
         "PKCS #12: Could not find OBJECT IDENTIFIER (contentType)");
858
    return 0;
859
  }
860
861
  asn1_oid_to_str(&oid, txt, sizeof(txt));
862
  wpa_printf(MSG_DEBUG, "PKCS #12: contentType %s", txt);
863
864
  if (asn1_get_next(pos, end - pos, &hdr) < 0 || !hdr.constructed ||
865
      !asn1_is_cs_tag(&hdr, 0)) {
866
    asn1_unexpected(&hdr,
867
        "PKCS #12: Expected [0] EXPLICIT (content)");
868
    return 0;
869
  }
870
  pos = hdr.payload;
871
872
  if (is_oid_pkcs7_data(&oid))
873
    return pkcs12_parse_content_data(cred, pos, end, passwd);
874
  if (is_oid_pkcs7_enc_data(&oid))
875
    return pkcs12_parse_content_enc_data(cred, pos, end, passwd);
876
877
  wpa_printf(MSG_DEBUG, "PKCS #12: Ignored unsupported contentType %s",
878
       txt);
879
880
  return 0;
881
}
882
883
884
static int pkcs12_parse(struct tlsv1_credentials *cred,
885
      const u8 *key, size_t len, const char *passwd)
886
{
887
  struct asn1_hdr hdr;
888
  const u8 *pos, *end;
889
  struct asn1_oid oid;
890
  char buf[80];
891
892
  /*
893
   * PFX ::= SEQUENCE {
894
   *     version     INTEGER {v3(3)}(v3,...),
895
   *     authSafe    ContentInfo,
896
   *     macData     MacData OPTIONAL
897
   * }
898
   */
899
900
  if (asn1_get_next(key, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
901
    asn1_unexpected(&hdr,
902
        "PKCS #12: Expected SEQUENCE (PFX); assume PKCS #12 not used");
903
    return -1;
904
  }
905
906
  pos = hdr.payload;
907
  end = pos + hdr.length;
908
909
  if (asn1_get_next(pos, end - pos, &hdr) < 0 || !asn1_is_integer(&hdr)) {
910
    asn1_unexpected(&hdr,
911
        "PKCS #12: No INTEGER tag found for version");
912
    return -1;
913
  }
914
  if (hdr.length != 1 || hdr.payload[0] != 3) {
915
    wpa_printf(MSG_DEBUG, "PKCS #12: Unrecognized version");
916
    return -1;
917
  }
918
  pos = hdr.payload + hdr.length;
919
920
  /*
921
   * ContentInfo ::= SEQUENCE {
922
   *   contentType ContentType,
923
   *   content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
924
   */
925
926
  if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
927
      !asn1_is_sequence(&hdr)) {
928
    asn1_unexpected(&hdr,
929
        "PKCS #12: Expected SEQUENCE (authSafe); assume PKCS #12 not used");
930
    return -1;
931
  }
932
933
  pos = hdr.payload;
934
  end = pos + hdr.length;
935
936
  /* ContentType ::= OBJECT IDENTIFIER */
937
  if (asn1_get_oid(pos, end - pos, &oid, &pos)) {
938
    wpa_printf(MSG_DEBUG,
939
         "PKCS #12: Could not find OBJECT IDENTIFIER (contentType); assume PKCS #12 not used");
940
    return -1;
941
  }
942
  asn1_oid_to_str(&oid, buf, sizeof(buf));
943
  wpa_printf(MSG_DEBUG, "PKCS #12: contentType %s", buf);
944
  if (!is_oid_pkcs7_data(&oid)) {
945
    wpa_printf(MSG_DEBUG, "PKCS #12: Unsupported contentType %s",
946
         buf);
947
    return -1;
948
  }
949
950
  if (asn1_get_next(pos, end - pos, &hdr) < 0 || !hdr.constructed ||
951
      !asn1_is_cs_tag(&hdr, 0)) {
952
    asn1_unexpected(&hdr,
953
        "PKCS #12: Expected [0] EXPLICIT (content); assume PKCS #12 not used");
954
    return -1;
955
  }
956
957
  pos = hdr.payload;
958
959
  /* Data ::= OCTET STRING */
960
  if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
961
      !asn1_is_octetstring(&hdr)) {
962
    asn1_unexpected(&hdr,
963
        "PKCS #12: Expected OCTET STRING (Data); assume PKCS #12 not used");
964
    return -1;
965
  }
966
967
  /*
968
   * AuthenticatedSafe ::= SEQUENCE OF ContentInfo
969
   *     -- Data if unencrypted
970
   *     -- EncryptedData if password-encrypted
971
   *     -- EnvelopedData if public key-encrypted
972
   */
973
  wpa_hexdump(MSG_MSGDUMP, "PKCS #12: Data content",
974
        hdr.payload, hdr.length);
975
976
  if (asn1_get_next(hdr.payload, hdr.length, &hdr) < 0 ||
977
      !asn1_is_sequence(&hdr)) {
978
    asn1_unexpected(&hdr,
979
        "PKCS #12: Expected SEQUENCE within Data content; assume PKCS #12 not used");
980
    return -1;
981
  }
982
983
  pos = hdr.payload;
984
  end = pos + hdr.length;
985
986
  while (end > pos) {
987
    if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
988
        !asn1_is_sequence(&hdr)) {
989
      asn1_unexpected(&hdr,
990
          "PKCS #12: Expected SEQUENCE (ContentInfo); assume PKCS #12 not used");
991
      return -1;
992
    }
993
    if (pkcs12_parse_content(cred, hdr.payload, hdr.length,
994
           passwd) < 0)
995
      return -1;
996
997
    pos = hdr.payload + hdr.length;
998
  }
999
1000
  return 0;
1001
}
1002
1003
#endif /* PKCS12_FUNCS */
1004
1005
1006
static int tlsv1_set_key(struct tlsv1_credentials *cred,
1007
       const u8 *key, size_t len, const char *passwd)
1008
0
{
1009
0
  cred->key = crypto_private_key_import(key, len, passwd);
1010
0
  if (cred->key == NULL)
1011
0
    cred->key = tlsv1_set_key_pem(key, len);
1012
0
  if (cred->key == NULL)
1013
0
    cred->key = tlsv1_set_key_enc_pem(key, len, passwd);
1014
#ifdef PKCS12_FUNCS
1015
  if (!cred->key)
1016
    pkcs12_parse(cred, key, len, passwd);
1017
#endif /* PKCS12_FUNCS */
1018
0
  if (cred->key == NULL) {
1019
0
    wpa_printf(MSG_INFO, "TLSv1: Failed to parse private key");
1020
0
    return -1;
1021
0
  }
1022
0
  return 0;
1023
0
}
1024
1025
1026
/**
1027
 * tlsv1_set_private_key - Set private key
1028
 * @cred: TLSv1 credentials from tlsv1_cred_alloc()
1029
 * @private_key: File or reference name for the key in PEM or DER format
1030
 * @private_key_passwd: Passphrase for decrypted private key, %NULL if no
1031
 * passphrase is used.
1032
 * @private_key_blob: private_key as inlined data or %NULL if not used
1033
 * @private_key_blob_len: private_key_blob length
1034
 * Returns: 0 on success, -1 on failure
1035
 */
1036
int tlsv1_set_private_key(struct tlsv1_credentials *cred,
1037
        const char *private_key,
1038
        const char *private_key_passwd,
1039
        const u8 *private_key_blob,
1040
        size_t private_key_blob_len)
1041
0
{
1042
0
  crypto_private_key_free(cred->key);
1043
0
  cred->key = NULL;
1044
1045
0
  if (private_key_blob)
1046
0
    return tlsv1_set_key(cred, private_key_blob,
1047
0
             private_key_blob_len,
1048
0
             private_key_passwd);
1049
1050
0
  if (private_key) {
1051
0
    u8 *buf;
1052
0
    size_t len;
1053
0
    int ret;
1054
1055
0
    buf = (u8 *) os_readfile(private_key, &len);
1056
0
    if (buf == NULL) {
1057
0
      wpa_printf(MSG_INFO, "TLSv1: Failed to read '%s'",
1058
0
           private_key);
1059
0
      return -1;
1060
0
    }
1061
1062
0
    ret = tlsv1_set_key(cred, buf, len, private_key_passwd);
1063
0
    os_free(buf);
1064
0
    return ret;
1065
0
  }
1066
1067
0
  return 0;
1068
0
}
1069
1070
1071
static int tlsv1_set_dhparams_der(struct tlsv1_credentials *cred,
1072
          const u8 *dh, size_t len)
1073
0
{
1074
0
  struct asn1_hdr hdr;
1075
0
  const u8 *pos, *end;
1076
1077
0
  pos = dh;
1078
0
  end = dh + len;
1079
1080
  /*
1081
   * DHParameter ::= SEQUENCE {
1082
   *   prime INTEGER, -- p
1083
   *   base INTEGER, -- g
1084
   *   privateValueLength INTEGER OPTIONAL }
1085
   */
1086
1087
  /* DHParamer ::= SEQUENCE */
1088
0
  if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
1089
0
    asn1_unexpected(&hdr,
1090
0
        "DH: DH parameters did not start with a valid SEQUENCE");
1091
0
    return -1;
1092
0
  }
1093
0
  pos = hdr.payload;
1094
1095
  /* prime INTEGER */
1096
0
  if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1097
0
      !asn1_is_integer(&hdr)) {
1098
0
    asn1_unexpected(&hdr, "DH: No INTEGER tag found for p");
1099
0
    return -1;
1100
0
  }
1101
1102
0
  wpa_hexdump(MSG_MSGDUMP, "DH: prime (p)", hdr.payload, hdr.length);
1103
0
  if (hdr.length == 0)
1104
0
    return -1;
1105
0
  os_free(cred->dh_p);
1106
0
  cred->dh_p = os_memdup(hdr.payload, hdr.length);
1107
0
  if (cred->dh_p == NULL)
1108
0
    return -1;
1109
0
  cred->dh_p_len = hdr.length;
1110
0
  pos = hdr.payload + hdr.length;
1111
1112
  /* base INTEGER */
1113
0
  if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1114
0
      !asn1_is_integer(&hdr)) {
1115
0
    asn1_unexpected(&hdr, "DH: No INTEGER tag found for g");
1116
0
    return -1;
1117
0
  }
1118
1119
0
  wpa_hexdump(MSG_MSGDUMP, "DH: base (g)", hdr.payload, hdr.length);
1120
0
  if (hdr.length == 0)
1121
0
    return -1;
1122
0
  os_free(cred->dh_g);
1123
0
  cred->dh_g = os_memdup(hdr.payload, hdr.length);
1124
0
  if (cred->dh_g == NULL)
1125
0
    return -1;
1126
0
  cred->dh_g_len = hdr.length;
1127
1128
0
  return 0;
1129
0
}
1130
1131
1132
static const char *pem_dhparams_begin = "-----BEGIN DH PARAMETERS-----";
1133
static const char *pem_dhparams_end = "-----END DH PARAMETERS-----";
1134
1135
1136
static int tlsv1_set_dhparams_blob(struct tlsv1_credentials *cred,
1137
           const u8 *buf, size_t len)
1138
0
{
1139
0
  const u8 *pos, *end;
1140
0
  unsigned char *der;
1141
0
  size_t der_len;
1142
1143
0
  pos = search_tag(pem_dhparams_begin, buf, len);
1144
0
  if (!pos) {
1145
0
    wpa_printf(MSG_DEBUG, "TLSv1: No PEM dhparams tag found - "
1146
0
         "assume DER format");
1147
0
    return tlsv1_set_dhparams_der(cred, buf, len);
1148
0
  }
1149
1150
0
  wpa_printf(MSG_DEBUG, "TLSv1: Converting PEM format dhparams into DER "
1151
0
       "format");
1152
1153
0
  pos += os_strlen(pem_dhparams_begin);
1154
0
  end = search_tag(pem_dhparams_end, pos, buf + len - pos);
1155
0
  if (end == NULL) {
1156
0
    wpa_printf(MSG_INFO, "TLSv1: Could not find PEM dhparams end "
1157
0
         "tag (%s)", pem_dhparams_end);
1158
0
    return -1;
1159
0
  }
1160
1161
0
  der = base64_decode((const char *) pos, end - pos, &der_len);
1162
0
  if (der == NULL) {
1163
0
    wpa_printf(MSG_INFO, "TLSv1: Could not decode PEM dhparams");
1164
0
    return -1;
1165
0
  }
1166
1167
0
  if (tlsv1_set_dhparams_der(cred, der, der_len) < 0) {
1168
0
    wpa_printf(MSG_INFO, "TLSv1: Failed to parse PEM dhparams "
1169
0
         "DER conversion");
1170
0
    os_free(der);
1171
0
    return -1;
1172
0
  }
1173
1174
0
  os_free(der);
1175
1176
0
  return 0;
1177
0
}
1178
1179
1180
/**
1181
 * tlsv1_set_dhparams - Set Diffie-Hellman parameters
1182
 * @cred: TLSv1 credentials from tlsv1_cred_alloc()
1183
 * @dh_file: File or reference name for the DH params in PEM or DER format
1184
 * @dh_blob: DH params as inlined data or %NULL if not used
1185
 * @dh_blob_len: dh_blob length
1186
 * Returns: 0 on success, -1 on failure
1187
 */
1188
int tlsv1_set_dhparams(struct tlsv1_credentials *cred, const char *dh_file,
1189
           const u8 *dh_blob, size_t dh_blob_len)
1190
0
{
1191
0
  if (dh_blob)
1192
0
    return tlsv1_set_dhparams_blob(cred, dh_blob, dh_blob_len);
1193
1194
0
  if (dh_file) {
1195
0
    u8 *buf;
1196
0
    size_t len;
1197
0
    int ret;
1198
1199
0
    buf = (u8 *) os_readfile(dh_file, &len);
1200
0
    if (buf == NULL) {
1201
0
      wpa_printf(MSG_INFO, "TLSv1: Failed to read '%s'",
1202
0
           dh_file);
1203
0
      return -1;
1204
0
    }
1205
1206
0
    ret = tlsv1_set_dhparams_blob(cred, buf, len);
1207
0
    os_free(buf);
1208
0
    return ret;
1209
0
  }
1210
1211
0
  return 0;
1212
0
}