1 /* 2 * TLSv1 credentials 3 * Copyright (c) 2006-2015, Jouni Malinen <j (at) 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 { 23 struct tlsv1_credentials *cred; 24 cred = os_zalloc(sizeof(*cred)); 25 return cred; 26 } 27 28 29 void tlsv1_cred_free(struct tlsv1_credentials *cred) 30 { 31 if (cred == NULL) 32 return; 33 34 x509_certificate_chain_free(cred->trusted_certs); 35 x509_certificate_chain_free(cred->cert); 36 crypto_private_key_free(cred->key); 37 os_free(cred->dh_p); 38 os_free(cred->dh_g); 39 os_free(cred->ocsp_stapling_response); 40 os_free(cred->ocsp_stapling_response_multi); 41 os_free(cred); 42 } 43 44 45 static int tlsv1_add_cert_der(struct x509_certificate **chain, 46 const u8 *buf, size_t len) 47 { 48 struct x509_certificate *cert, *p; 49 char name[128]; 50 51 cert = x509_certificate_parse(buf, len); 52 if (cert == NULL) { 53 wpa_printf(MSG_INFO, "TLSv1: %s - failed to parse certificate", 54 __func__); 55 return -1; 56 } 57 58 p = *chain; 59 while (p && p->next) 60 p = p->next; 61 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 p->next = cert; 67 } else { 68 /* Add to the beginning of the chain */ 69 cert->next = *chain; 70 *chain = cert; 71 } 72 73 x509_name_string(&cert->subject, name, sizeof(name)); 74 wpa_printf(MSG_DEBUG, "TLSv1: Added certificate: %s", name); 75 76 return 0; 77 } 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 { 92 size_t i, plen; 93 94 plen = os_strlen(tag); 95 if (len < plen) 96 return NULL; 97 98 for (i = 0; i < len - plen; i++) { 99 if (os_memcmp(buf + i, tag, plen) == 0) 100 return buf + i; 101 } 102 103 return NULL; 104 } 105 106 107 static int tlsv1_add_cert(struct x509_certificate **chain, 108 const u8 *buf, size_t len) 109 { 110 const u8 *pos, *end; 111 unsigned char *der; 112 size_t der_len; 113 114 pos = search_tag(pem_cert_begin, buf, len); 115 if (!pos) { 116 wpa_printf(MSG_DEBUG, "TLSv1: No PEM certificate tag found - " 117 "assume DER format"); 118 return tlsv1_add_cert_der(chain, buf, len); 119 } 120 121 wpa_printf(MSG_DEBUG, "TLSv1: Converting PEM format certificate into " 122 "DER format"); 123 124 while (pos) { 125 pos += os_strlen(pem_cert_begin); 126 end = search_tag(pem_cert_end, pos, buf + len - pos); 127 if (end == NULL) { 128 wpa_printf(MSG_INFO, "TLSv1: Could not find PEM " 129 "certificate end tag (%s)", pem_cert_end); 130 return -1; 131 } 132 133 der = base64_decode(pos, end - pos, &der_len); 134 if (der == NULL) { 135 wpa_printf(MSG_INFO, "TLSv1: Could not decode PEM " 136 "certificate"); 137 return -1; 138 } 139 140 if (tlsv1_add_cert_der(chain, der, der_len) < 0) { 141 wpa_printf(MSG_INFO, "TLSv1: Failed to parse PEM " 142 "certificate after DER conversion"); 143 os_free(der); 144 return -1; 145 } 146 147 os_free(der); 148 149 end += os_strlen(pem_cert_end); 150 pos = search_tag(pem_cert_begin, end, buf + len - end); 151 } 152 153 return 0; 154 } 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 { 161 if (cert_blob) 162 return tlsv1_add_cert(chain, cert_blob, cert_blob_len); 163 164 if (cert) { 165 u8 *buf; 166 size_t len; 167 int ret; 168 169 buf = (u8 *) os_readfile(cert, &len); 170 if (buf == NULL) { 171 wpa_printf(MSG_INFO, "TLSv1: Failed to read '%s'", 172 cert); 173 return -1; 174 } 175 176 ret = tlsv1_add_cert(chain, buf, len); 177 os_free(buf); 178 return ret; 179 } 180 181 return 0; 182 } 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 { 198 if (cert && os_strncmp(cert, "hash://", 7) == 0) { 199 const char *pos = cert + 7; 200 if (os_strncmp(pos, "server/sha256/", 14) != 0) { 201 wpa_printf(MSG_DEBUG, 202 "TLSv1: Unsupported ca_cert hash value '%s'", 203 cert); 204 return -1; 205 } 206 pos += 14; 207 if (os_strlen(pos) != 32 * 2) { 208 wpa_printf(MSG_DEBUG, 209 "TLSv1: Unexpected SHA256 hash length in ca_cert '%s'", 210 cert); 211 return -1; 212 } 213 if (hexstr2bin(pos, cred->srv_cert_hash, 32) < 0) { 214 wpa_printf(MSG_DEBUG, 215 "TLSv1: Invalid SHA256 hash value in ca_cert '%s'", 216 cert); 217 return -1; 218 } 219 cred->server_cert_only = 1; 220 cred->ca_cert_verify = 0; 221 wpa_printf(MSG_DEBUG, 222 "TLSv1: Checking only server certificate match"); 223 return 0; 224 } 225 226 if (cert && os_strncmp(cert, "probe://", 8) == 0) { 227 cred->cert_probe = 1; 228 cred->ca_cert_verify = 0; 229 wpa_printf(MSG_DEBUG, "TLSv1: Only probe server certificate"); 230 return 0; 231 } 232 233 cred->ca_cert_verify = cert || cert_blob || path; 234 235 if (tlsv1_set_cert_chain(&cred->trusted_certs, cert, 236 cert_blob, cert_blob_len) < 0) 237 return -1; 238 239 if (path) { 240 /* TODO: add support for reading number of certificate files */ 241 wpa_printf(MSG_INFO, "TLSv1: Use of CA certificate directory " 242 "not yet supported"); 243 return -1; 244 } 245 246 return 0; 247 } 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 { 261 return tlsv1_set_cert_chain(&cred->cert, cert, 262 cert_blob, cert_blob_len); 263 } 264 265 266 static struct crypto_private_key * tlsv1_set_key_pem(const u8 *key, size_t len) 267 { 268 const u8 *pos, *end; 269 unsigned char *der; 270 size_t der_len; 271 struct crypto_private_key *pkey; 272 273 pos = search_tag(pem_key_begin, key, len); 274 if (!pos) { 275 pos = search_tag(pem_key2_begin, key, len); 276 if (!pos) 277 return NULL; 278 pos += os_strlen(pem_key2_begin); 279 end = search_tag(pem_key2_end, pos, key + len - pos); 280 if (!end) 281 return NULL; 282 } else { 283 const u8 *pos2; 284 pos += os_strlen(pem_key_begin); 285 end = search_tag(pem_key_end, pos, key + len - pos); 286 if (!end) 287 return NULL; 288 pos2 = search_tag("Proc-Type: 4,ENCRYPTED", pos, end - pos); 289 if (pos2) { 290 wpa_printf(MSG_DEBUG, "TLSv1: Unsupported private key " 291 "format (Proc-Type/DEK-Info)"); 292 return NULL; 293 } 294 } 295 296 der = base64_decode(pos, end - pos, &der_len); 297 if (!der) 298 return NULL; 299 pkey = crypto_private_key_import(der, der_len, NULL); 300 os_free(der); 301 return pkey; 302 } 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 { 309 const u8 *pos, *end; 310 unsigned char *der; 311 size_t der_len; 312 struct crypto_private_key *pkey; 313 314 if (passwd == NULL) 315 return NULL; 316 pos = search_tag(pem_key_enc_begin, key, len); 317 if (!pos) 318 return NULL; 319 pos += os_strlen(pem_key_enc_begin); 320 end = search_tag(pem_key_enc_end, pos, key + len - pos); 321 if (!end) 322 return NULL; 323 324 der = base64_decode(pos, end - pos, &der_len); 325 if (!der) 326 return NULL; 327 pkey = crypto_private_key_import(der, der_len, passwd); 328 os_free(der); 329 return pkey; 330 } 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 || 459 hdr.class != ASN1_CLASS_UNIVERSAL || 460 hdr.tag != ASN1_TAG_SEQUENCE) { 461 wpa_printf(MSG_DEBUG, 462 "PKCS #12: Expected SEQUENCE (CertBag) - found class %d tag 0x%x", 463 hdr.class, hdr.tag); 464 return -1; 465 } 466 467 pos = hdr.payload; 468 end = hdr.payload + hdr.length; 469 470 if (asn1_get_oid(pos, end - pos, &oid, &pos)) { 471 wpa_printf(MSG_DEBUG, 472 "PKCS #12: Failed to parse OID (certId)"); 473 return -1; 474 } 475 476 asn1_oid_to_str(&oid, obuf, sizeof(obuf)); 477 wpa_printf(MSG_DEBUG, "PKCS #12: certId %s", obuf); 478 479 if (!is_oid_pkcs9_x509_cert(&oid)) { 480 wpa_printf(MSG_DEBUG, 481 "PKCS #12: Ignored unsupported certificate type (certId %s)", 482 obuf); 483 } 484 485 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 486 hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC || 487 hdr.tag != 0) { 488 wpa_printf(MSG_DEBUG, 489 "PKCS #12: Expected [0] EXPLICIT (certValue) - found class %d tag 0x%x", 490 hdr.class, hdr.tag); 491 return -1; 492 } 493 494 if (asn1_get_next(hdr.payload, hdr.length, &hdr) < 0 || 495 hdr.class != ASN1_CLASS_UNIVERSAL || 496 hdr.tag != ASN1_TAG_OCTETSTRING) { 497 wpa_printf(MSG_DEBUG, 498 "PKCS #12: Expected OCTET STRING (x509Certificate) - found class %d tag 0x%x", 499 hdr.class, hdr.tag); 500 return -1; 501 } 502 503 wpa_hexdump(MSG_DEBUG, "PKCS #12: x509Certificate", 504 hdr.payload, hdr.length); 505 if (cred->cert) { 506 struct x509_certificate *cert; 507 508 wpa_printf(MSG_DEBUG, "PKCS #12: Ignore extra certificate"); 509 cert = x509_certificate_parse(hdr.payload, hdr.length); 510 if (!cert) { 511 wpa_printf(MSG_DEBUG, 512 "PKCS #12: Failed to parse x509Certificate"); 513 return 0; 514 } 515 x509_certificate_chain_free(cert); 516 517 return 0; 518 } 519 return tlsv1_set_cert(cred, NULL, hdr.payload, hdr.length); 520 } 521 522 523 static int pkcs12_parse_attr_friendly_name(const u8 *pos, const u8 *end) 524 { 525 struct asn1_hdr hdr; 526 527 /* 528 * RFC 2985, 5.5.1: 529 * friendlyName ATTRIBUTE ::= { 530 * WITH SYNTAX BMPString (SIZE(1..pkcs-9-ub-friendlyName)) 531 * EQUALITY MATCHING RULE caseIgnoreMatch 532 * SINGLE VALUE TRUE 533 * ID pkcs-9-at-friendlyName 534 * } 535 */ 536 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 537 hdr.class != ASN1_CLASS_UNIVERSAL || 538 hdr.tag != ASN1_TAG_BMPSTRING) { 539 wpa_printf(MSG_DEBUG, 540 "PKCS #12: Expected BMPSTRING (friendlyName) - found class %d tag 0x%x", 541 hdr.class, hdr.tag); 542 return 0; 543 } 544 wpa_hexdump_ascii(MSG_DEBUG, "PKCS #12: friendlyName", 545 hdr.payload, hdr.length); 546 return 0; 547 } 548 549 550 static int pkcs12_parse_attr_local_key_id(const u8 *pos, const u8 *end) 551 { 552 struct asn1_hdr hdr; 553 554 /* 555 * RFC 2985, 5.5.2: 556 * localKeyId ATTRIBUTE ::= { 557 * WITH SYNTAX OCTET STRING 558 * EQUALITY MATCHING RULE octetStringMatch 559 * SINGLE VALUE TRUE 560 * ID pkcs-9-at-localKeyId 561 * } 562 */ 563 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 564 hdr.class != ASN1_CLASS_UNIVERSAL || 565 hdr.tag != ASN1_TAG_OCTETSTRING) { 566 wpa_printf(MSG_DEBUG, 567 "PKCS #12: Expected OCTET STRING (localKeyID) - found class %d tag 0x%x", 568 hdr.class, hdr.tag); 569 return -1; 570 } 571 wpa_hexdump_key(MSG_DEBUG, "PKCS #12: localKeyID", 572 hdr.payload, hdr.length); 573 return 0; 574 } 575 576 577 static int pkcs12_parse_attr(const u8 *pos, size_t len) 578 { 579 const u8 *end = pos + len; 580 struct asn1_hdr hdr; 581 struct asn1_oid a_oid; 582 char obuf[80]; 583 584 /* 585 * PKCS12Attribute ::= SEQUENCE { 586 * attrId ATTRIBUTE.&id ({PKCS12AttrSet}), 587 * attrValues SET OF ATTRIBUTE.&Type ({PKCS12AttrSet}{@attrId}) 588 * } 589 */ 590 591 if (asn1_get_oid(pos, end - pos, &a_oid, &pos)) { 592 wpa_printf(MSG_DEBUG, "PKCS #12: Failed to parse OID (attrId)"); 593 return -1; 594 } 595 596 asn1_oid_to_str(&a_oid, obuf, sizeof(obuf)); 597 wpa_printf(MSG_DEBUG, "PKCS #12: attrId %s", obuf); 598 599 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 600 hdr.class != ASN1_CLASS_UNIVERSAL || 601 hdr.tag != ASN1_TAG_SET) { 602 wpa_printf(MSG_DEBUG, 603 "PKCS #12: Expected SET (attrValues) - found class %d tag 0x%x", 604 hdr.class, hdr.tag); 605 return -1; 606 } 607 wpa_hexdump_key(MSG_MSGDUMP, "PKCS #12: attrValues", 608 hdr.payload, hdr.length); 609 pos = hdr.payload; 610 end = hdr.payload + hdr.length; 611 612 if (is_oid_pkcs9_friendly_name(&a_oid)) 613 return pkcs12_parse_attr_friendly_name(pos, end); 614 if (is_oid_pkcs9_local_key_id(&a_oid)) 615 return pkcs12_parse_attr_local_key_id(pos, end); 616 617 wpa_printf(MSG_DEBUG, "PKCS #12: Ignore unknown attribute"); 618 return 0; 619 } 620 621 622 static int pkcs12_safebag(struct tlsv1_credentials *cred, 623 const u8 *buf, size_t len, const char *passwd) 624 { 625 struct asn1_hdr hdr; 626 struct asn1_oid oid; 627 char obuf[80]; 628 const u8 *pos = buf, *end = buf + len; 629 const u8 *value; 630 size_t value_len; 631 632 wpa_hexdump_key(MSG_MSGDUMP, "PKCS #12: SafeBag", buf, len); 633 634 /* BAG-TYPE ::= TYPE-IDENTIFIER */ 635 if (asn1_get_oid(pos, end - pos, &oid, &pos)) { 636 wpa_printf(MSG_DEBUG, 637 "PKCS #12: Failed to parse OID (BAG-TYPE)"); 638 return -1; 639 } 640 641 asn1_oid_to_str(&oid, obuf, sizeof(obuf)); 642 wpa_printf(MSG_DEBUG, "PKCS #12: BAG-TYPE %s", obuf); 643 644 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 645 hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC || 646 hdr.tag != 0) { 647 wpa_printf(MSG_DEBUG, 648 "PKCS #12: Expected [0] EXPLICIT (bagValue) - found class %d tag 0x%x", 649 hdr.class, hdr.tag); 650 return 0; 651 } 652 value = hdr.payload; 653 value_len = hdr.length; 654 wpa_hexdump_key(MSG_MSGDUMP, "PKCS #12: bagValue", value, value_len); 655 pos = hdr.payload + hdr.length; 656 657 if (pos < end) { 658 /* bagAttributes SET OF PKCS12Attribute OPTIONAL */ 659 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 660 hdr.class != ASN1_CLASS_UNIVERSAL || 661 hdr.tag != ASN1_TAG_SET) { 662 wpa_printf(MSG_DEBUG, 663 "PKCS #12: Expected SET (bagAttributes) - found class %d tag 0x%x", 664 hdr.class, hdr.tag); 665 return -1; 666 } 667 wpa_hexdump_key(MSG_MSGDUMP, "PKCS #12: bagAttributes", 668 hdr.payload, hdr.length); 669 670 pos = hdr.payload; 671 end = hdr.payload + hdr.length; 672 while (pos < end) { 673 /* PKCS12Attribute ::= SEQUENCE */ 674 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 675 hdr.class != ASN1_CLASS_UNIVERSAL || 676 hdr.tag != ASN1_TAG_SEQUENCE) { 677 wpa_printf(MSG_DEBUG, 678 "PKCS #12: Expected SEQUENCE (PKCS12Attribute) - found class %d tag 0x%x", 679 hdr.class, hdr.tag); 680 return -1; 681 } 682 if (pkcs12_parse_attr(hdr.payload, hdr.length) < 0) 683 return -1; 684 pos = hdr.payload + hdr.length; 685 } 686 } 687 688 if (pkcs12_is_bagtype_oid(&oid, 1)) 689 return pkcs12_keybag(cred, value, value_len); 690 if (pkcs12_is_bagtype_oid(&oid, 2)) 691 return pkcs12_pkcs8_keybag(cred, value, value_len, passwd); 692 if (pkcs12_is_bagtype_oid(&oid, 3)) 693 return pkcs12_certbag(cred, value, value_len); 694 695 wpa_printf(MSG_DEBUG, "PKCS #12: Ignore unsupported BAG-TYPE"); 696 return 0; 697 } 698 699 700 static int pkcs12_safecontents(struct tlsv1_credentials *cred, 701 const u8 *buf, size_t len, 702 const char *passwd) 703 { 704 struct asn1_hdr hdr; 705 const u8 *pos, *end; 706 707 /* SafeContents ::= SEQUENCE OF SafeBag */ 708 if (asn1_get_next(buf, len, &hdr) < 0 || 709 hdr.class != ASN1_CLASS_UNIVERSAL || 710 hdr.tag != ASN1_TAG_SEQUENCE) { 711 wpa_printf(MSG_DEBUG, 712 "PKCS #12: Expected SEQUENCE (SafeContents) - found class %d tag 0x%x", 713 hdr.class, hdr.tag); 714 return -1; 715 } 716 pos = hdr.payload; 717 end = hdr.payload + hdr.length; 718 719 /* 720 * SafeBag ::= SEQUENCE { 721 * bagId BAG-TYPE.&id ({PKCS12BagSet}) 722 * bagValue [0] EXPLICIT BAG-TYPE.&Type({PKCS12BagSet}{@bagId}), 723 * bagAttributes SET OF PKCS12Attribute OPTIONAL 724 * } 725 */ 726 727 while (pos < end) { 728 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 729 hdr.class != ASN1_CLASS_UNIVERSAL || 730 hdr.tag != ASN1_TAG_SEQUENCE) { 731 wpa_printf(MSG_DEBUG, 732 "PKCS #12: Expected SEQUENCE (SafeBag) - found class %d tag 0x%x", 733 hdr.class, hdr.tag); 734 return -1; 735 } 736 if (pkcs12_safebag(cred, hdr.payload, hdr.length, passwd) < 0) 737 return -1; 738 pos = hdr.payload + hdr.length; 739 } 740 741 return 0; 742 } 743 744 745 static int pkcs12_parse_content_data(struct tlsv1_credentials *cred, 746 const u8 *pos, const u8 *end, 747 const char *passwd) 748 { 749 struct asn1_hdr hdr; 750 751 /* Data ::= OCTET STRING */ 752 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 753 hdr.class != ASN1_CLASS_UNIVERSAL || 754 hdr.tag != ASN1_TAG_OCTETSTRING) { 755 wpa_printf(MSG_DEBUG, 756 "PKCS #12: Expected OCTET STRING (Data) - found class %d tag 0x%x", 757 hdr.class, hdr.tag); 758 return -1; 759 } 760 761 wpa_hexdump(MSG_MSGDUMP, "PKCS #12: Data", hdr.payload, hdr.length); 762 763 return pkcs12_safecontents(cred, hdr.payload, hdr.length, passwd); 764 } 765 766 767 static int pkcs12_parse_content_enc_data(struct tlsv1_credentials *cred, 768 const u8 *pos, const u8 *end, 769 const char *passwd) 770 { 771 struct asn1_hdr hdr; 772 struct asn1_oid oid; 773 char buf[80]; 774 const u8 *enc_alg; 775 u8 *data; 776 size_t enc_alg_len, data_len; 777 int res = -1; 778 779 /* 780 * EncryptedData ::= SEQUENCE { 781 * version Version, 782 * encryptedContentInfo EncryptedContentInfo } 783 */ 784 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 785 hdr.class != ASN1_CLASS_UNIVERSAL || 786 hdr.tag != ASN1_TAG_SEQUENCE) { 787 wpa_printf(MSG_DEBUG, 788 "PKCS #12: Expected SEQUENCE (EncryptedData) - found class %d tag 0x%x", 789 hdr.class, hdr.tag); 790 return 0; 791 } 792 pos = hdr.payload; 793 794 /* Version ::= INTEGER */ 795 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 796 hdr.class != ASN1_CLASS_UNIVERSAL || hdr.tag != ASN1_TAG_INTEGER) { 797 wpa_printf(MSG_DEBUG, 798 "PKCS #12: No INTEGER tag found for version; class=%d tag=0x%x", 799 hdr.class, hdr.tag); 800 return -1; 801 } 802 if (hdr.length != 1 || hdr.payload[0] != 0) { 803 wpa_printf(MSG_DEBUG, "PKCS #12: Unrecognized PKCS #7 version"); 804 return -1; 805 } 806 pos = hdr.payload + hdr.length; 807 808 wpa_hexdump(MSG_MSGDUMP, "PKCS #12: EncryptedContentInfo", 809 pos, end - pos); 810 811 /* 812 * EncryptedContentInfo ::= SEQUENCE { 813 * contentType ContentType, 814 * contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier, 815 * encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL } 816 */ 817 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 818 hdr.class != ASN1_CLASS_UNIVERSAL || 819 hdr.tag != ASN1_TAG_SEQUENCE) { 820 wpa_printf(MSG_DEBUG, 821 "PKCS #12: Expected SEQUENCE (EncryptedContentInfo) - found class %d tag 0x%x", 822 hdr.class, hdr.tag); 823 return -1; 824 } 825 826 pos = hdr.payload; 827 end = pos + hdr.length; 828 829 /* ContentType ::= OBJECT IDENTIFIER */ 830 if (asn1_get_oid(pos, end - pos, &oid, &pos)) { 831 wpa_printf(MSG_DEBUG, 832 "PKCS #12: Could not find OBJECT IDENTIFIER (contentType)"); 833 return -1; 834 } 835 asn1_oid_to_str(&oid, buf, sizeof(buf)); 836 wpa_printf(MSG_DEBUG, "PKCS #12: EncryptedContentInfo::contentType %s", 837 buf); 838 839 if (!is_oid_pkcs7_data(&oid)) { 840 wpa_printf(MSG_DEBUG, 841 "PKCS #12: Unsupported EncryptedContentInfo::contentType %s", 842 buf); 843 return 0; 844 } 845 846 /* ContentEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier */ 847 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 848 hdr.class != ASN1_CLASS_UNIVERSAL || 849 hdr.tag != ASN1_TAG_SEQUENCE) { 850 wpa_printf(MSG_DEBUG, "PKCS #12: Expected SEQUENCE (ContentEncryptionAlgorithmIdentifier) - found class %d tag 0x%x", 851 hdr.class, hdr.tag); 852 return -1; 853 } 854 enc_alg = hdr.payload; 855 enc_alg_len = hdr.length; 856 pos = hdr.payload + hdr.length; 857 858 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 859 hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC || 860 hdr.tag != 0) { 861 wpa_printf(MSG_DEBUG, 862 "PKCS #12: Expected [0] IMPLICIT (encryptedContent) - found class %d tag 0x%x", 863 hdr.class, hdr.tag); 864 return -1; 865 } 866 867 /* EncryptedContent ::= OCTET STRING */ 868 data = pkcs5_decrypt(enc_alg, enc_alg_len, hdr.payload, hdr.length, 869 passwd, &data_len); 870 if (data) { 871 wpa_hexdump_key(MSG_MSGDUMP, 872 "PKCS #12: Decrypted encryptedContent", 873 data, data_len); 874 res = pkcs12_safecontents(cred, data, data_len, passwd); 875 os_free(data); 876 } 877 878 return res; 879 } 880 881 882 static int pkcs12_parse_content(struct tlsv1_credentials *cred, 883 const u8 *buf, size_t len, 884 const char *passwd) 885 { 886 const u8 *pos = buf; 887 const u8 *end = buf + len; 888 struct asn1_oid oid; 889 char txt[80]; 890 struct asn1_hdr hdr; 891 892 wpa_hexdump(MSG_MSGDUMP, "PKCS #12: ContentInfo", buf, len); 893 894 if (asn1_get_oid(pos, end - pos, &oid, &pos)) { 895 wpa_printf(MSG_DEBUG, 896 "PKCS #12: Could not find OBJECT IDENTIFIER (contentType)"); 897 return 0; 898 } 899 900 asn1_oid_to_str(&oid, txt, sizeof(txt)); 901 wpa_printf(MSG_DEBUG, "PKCS #12: contentType %s", txt); 902 903 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 904 hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC || 905 hdr.tag != 0) { 906 wpa_printf(MSG_DEBUG, 907 "PKCS #12: Expected [0] EXPLICIT (content) - found class %d tag 0x%x", 908 hdr.class, hdr.tag); 909 return 0; 910 } 911 pos = hdr.payload; 912 913 if (is_oid_pkcs7_data(&oid)) 914 return pkcs12_parse_content_data(cred, pos, end, passwd); 915 if (is_oid_pkcs7_enc_data(&oid)) 916 return pkcs12_parse_content_enc_data(cred, pos, end, passwd); 917 918 wpa_printf(MSG_DEBUG, "PKCS #12: Ignored unsupported contentType %s", 919 txt); 920 921 return 0; 922 } 923 924 925 static int pkcs12_parse(struct tlsv1_credentials *cred, 926 const u8 *key, size_t len, const char *passwd) 927 { 928 struct asn1_hdr hdr; 929 const u8 *pos, *end; 930 struct asn1_oid oid; 931 char buf[80]; 932 933 /* 934 * PFX ::= SEQUENCE { 935 * version INTEGER {v3(3)}(v3,...), 936 * authSafe ContentInfo, 937 * macData MacData OPTIONAL 938 * } 939 */ 940 941 if (asn1_get_next(key, len, &hdr) < 0 || 942 hdr.class != ASN1_CLASS_UNIVERSAL || 943 hdr.tag != ASN1_TAG_SEQUENCE) { 944 wpa_printf(MSG_DEBUG, 945 "PKCS #12: Expected SEQUENCE (PFX) - found class %d tag 0x%x; assume PKCS #12 not used", 946 hdr.class, hdr.tag); 947 return -1; 948 } 949 950 pos = hdr.payload; 951 end = pos + hdr.length; 952 953 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 954 hdr.class != ASN1_CLASS_UNIVERSAL || hdr.tag != ASN1_TAG_INTEGER) { 955 wpa_printf(MSG_DEBUG, 956 "PKCS #12: No INTEGER tag found for version; class=%d tag=0x%x", 957 hdr.class, hdr.tag); 958 return -1; 959 } 960 if (hdr.length != 1 || hdr.payload[0] != 3) { 961 wpa_printf(MSG_DEBUG, "PKCS #12: Unrecognized version"); 962 return -1; 963 } 964 pos = hdr.payload + hdr.length; 965 966 /* 967 * ContentInfo ::= SEQUENCE { 968 * contentType ContentType, 969 * content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL } 970 */ 971 972 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 973 hdr.class != ASN1_CLASS_UNIVERSAL || 974 hdr.tag != ASN1_TAG_SEQUENCE) { 975 wpa_printf(MSG_DEBUG, 976 "PKCS #12: Expected SEQUENCE (authSafe) - found class %d tag 0x%x; assume PKCS #12 not used", 977 hdr.class, hdr.tag); 978 return -1; 979 } 980 981 pos = hdr.payload; 982 end = pos + hdr.length; 983 984 /* ContentType ::= OBJECT IDENTIFIER */ 985 if (asn1_get_oid(pos, end - pos, &oid, &pos)) { 986 wpa_printf(MSG_DEBUG, 987 "PKCS #12: Could not find OBJECT IDENTIFIER (contentType); assume PKCS #12 not used"); 988 return -1; 989 } 990 asn1_oid_to_str(&oid, buf, sizeof(buf)); 991 wpa_printf(MSG_DEBUG, "PKCS #12: contentType %s", buf); 992 if (!is_oid_pkcs7_data(&oid)) { 993 wpa_printf(MSG_DEBUG, "PKCS #12: Unsupported contentType %s", 994 buf); 995 return -1; 996 } 997 998 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 999 hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC || 1000 hdr.tag != 0) { 1001 wpa_printf(MSG_DEBUG, 1002 "PKCS #12: Expected [0] EXPLICIT (content) - found class %d tag 0x%x; assume PKCS #12 not used", 1003 hdr.class, hdr.tag); 1004 return -1; 1005 } 1006 1007 pos = hdr.payload; 1008 1009 /* Data ::= OCTET STRING */ 1010 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 1011 hdr.class != ASN1_CLASS_UNIVERSAL || 1012 hdr.tag != ASN1_TAG_OCTETSTRING) { 1013 wpa_printf(MSG_DEBUG, 1014 "PKCS #12: Expected OCTET STRING (Data) - found class %d tag 0x%x; assume PKCS #12 not used", 1015 hdr.class, hdr.tag); 1016 return -1; 1017 } 1018 1019 /* 1020 * AuthenticatedSafe ::= SEQUENCE OF ContentInfo 1021 * -- Data if unencrypted 1022 * -- EncryptedData if password-encrypted 1023 * -- EnvelopedData if public key-encrypted 1024 */ 1025 wpa_hexdump(MSG_MSGDUMP, "PKCS #12: Data content", 1026 hdr.payload, hdr.length); 1027 1028 if (asn1_get_next(hdr.payload, hdr.length, &hdr) < 0 || 1029 hdr.class != ASN1_CLASS_UNIVERSAL || 1030 hdr.tag != ASN1_TAG_SEQUENCE) { 1031 wpa_printf(MSG_DEBUG, 1032 "PKCS #12: Expected SEQUENCE within Data content - found class %d tag 0x%x; assume PKCS #12 not used", 1033 hdr.class, hdr.tag); 1034 return -1; 1035 } 1036 1037 pos = hdr.payload; 1038 end = pos + hdr.length; 1039 1040 while (end > pos) { 1041 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 1042 hdr.class != ASN1_CLASS_UNIVERSAL || 1043 hdr.tag != ASN1_TAG_SEQUENCE) { 1044 wpa_printf(MSG_DEBUG, 1045 "PKCS #12: Expected SEQUENCE (ContentInfo) - found class %d tag 0x%x; assume PKCS #12 not used", 1046 hdr.class, hdr.tag); 1047 return -1; 1048 } 1049 if (pkcs12_parse_content(cred, hdr.payload, hdr.length, 1050 passwd) < 0) 1051 return -1; 1052 1053 pos = hdr.payload + hdr.length; 1054 } 1055 1056 return 0; 1057 } 1058 1059 #endif /* PKCS12_FUNCS */ 1060 1061 1062 static int tlsv1_set_key(struct tlsv1_credentials *cred, 1063 const u8 *key, size_t len, const char *passwd) 1064 { 1065 cred->key = crypto_private_key_import(key, len, passwd); 1066 if (cred->key == NULL) 1067 cred->key = tlsv1_set_key_pem(key, len); 1068 if (cred->key == NULL) 1069 cred->key = tlsv1_set_key_enc_pem(key, len, passwd); 1070 #ifdef PKCS12_FUNCS 1071 if (!cred->key) 1072 pkcs12_parse(cred, key, len, passwd); 1073 #endif /* PKCS12_FUNCS */ 1074 if (cred->key == NULL) { 1075 wpa_printf(MSG_INFO, "TLSv1: Failed to parse private key"); 1076 return -1; 1077 } 1078 return 0; 1079 } 1080 1081 1082 /** 1083 * tlsv1_set_private_key - Set private key 1084 * @cred: TLSv1 credentials from tlsv1_cred_alloc() 1085 * @private_key: File or reference name for the key in PEM or DER format 1086 * @private_key_passwd: Passphrase for decrypted private key, %NULL if no 1087 * passphrase is used. 1088 * @private_key_blob: private_key as inlined data or %NULL if not used 1089 * @private_key_blob_len: private_key_blob length 1090 * Returns: 0 on success, -1 on failure 1091 */ 1092 int tlsv1_set_private_key(struct tlsv1_credentials *cred, 1093 const char *private_key, 1094 const char *private_key_passwd, 1095 const u8 *private_key_blob, 1096 size_t private_key_blob_len) 1097 { 1098 crypto_private_key_free(cred->key); 1099 cred->key = NULL; 1100 1101 if (private_key_blob) 1102 return tlsv1_set_key(cred, private_key_blob, 1103 private_key_blob_len, 1104 private_key_passwd); 1105 1106 if (private_key) { 1107 u8 *buf; 1108 size_t len; 1109 int ret; 1110 1111 buf = (u8 *) os_readfile(private_key, &len); 1112 if (buf == NULL) { 1113 wpa_printf(MSG_INFO, "TLSv1: Failed to read '%s'", 1114 private_key); 1115 return -1; 1116 } 1117 1118 ret = tlsv1_set_key(cred, buf, len, private_key_passwd); 1119 os_free(buf); 1120 return ret; 1121 } 1122 1123 return 0; 1124 } 1125 1126 1127 static int tlsv1_set_dhparams_der(struct tlsv1_credentials *cred, 1128 const u8 *dh, size_t len) 1129 { 1130 struct asn1_hdr hdr; 1131 const u8 *pos, *end; 1132 1133 pos = dh; 1134 end = dh + len; 1135 1136 /* 1137 * DHParameter ::= SEQUENCE { 1138 * prime INTEGER, -- p 1139 * base INTEGER, -- g 1140 * privateValueLength INTEGER OPTIONAL } 1141 */ 1142 1143 /* DHParamer ::= SEQUENCE */ 1144 if (asn1_get_next(pos, len, &hdr) < 0 || 1145 hdr.class != ASN1_CLASS_UNIVERSAL || 1146 hdr.tag != ASN1_TAG_SEQUENCE) { 1147 wpa_printf(MSG_DEBUG, "DH: DH parameters did not start with a " 1148 "valid SEQUENCE - found class %d tag 0x%x", 1149 hdr.class, hdr.tag); 1150 return -1; 1151 } 1152 pos = hdr.payload; 1153 1154 /* prime INTEGER */ 1155 if (asn1_get_next(pos, end - pos, &hdr) < 0) 1156 return -1; 1157 1158 if (hdr.class != ASN1_CLASS_UNIVERSAL || 1159 hdr.tag != ASN1_TAG_INTEGER) { 1160 wpa_printf(MSG_DEBUG, "DH: No INTEGER tag found for p; " 1161 "class=%d tag=0x%x", hdr.class, hdr.tag); 1162 return -1; 1163 } 1164 1165 wpa_hexdump(MSG_MSGDUMP, "DH: prime (p)", hdr.payload, hdr.length); 1166 if (hdr.length == 0) 1167 return -1; 1168 os_free(cred->dh_p); 1169 cred->dh_p = os_malloc(hdr.length); 1170 if (cred->dh_p == NULL) 1171 return -1; 1172 os_memcpy(cred->dh_p, hdr.payload, hdr.length); 1173 cred->dh_p_len = hdr.length; 1174 pos = hdr.payload + hdr.length; 1175 1176 /* base INTEGER */ 1177 if (asn1_get_next(pos, end - pos, &hdr) < 0) 1178 return -1; 1179 1180 if (hdr.class != ASN1_CLASS_UNIVERSAL || 1181 hdr.tag != ASN1_TAG_INTEGER) { 1182 wpa_printf(MSG_DEBUG, "DH: No INTEGER tag found for g; " 1183 "class=%d tag=0x%x", hdr.class, hdr.tag); 1184 return -1; 1185 } 1186 1187 wpa_hexdump(MSG_MSGDUMP, "DH: base (g)", hdr.payload, hdr.length); 1188 if (hdr.length == 0) 1189 return -1; 1190 os_free(cred->dh_g); 1191 cred->dh_g = os_malloc(hdr.length); 1192 if (cred->dh_g == NULL) 1193 return -1; 1194 os_memcpy(cred->dh_g, hdr.payload, hdr.length); 1195 cred->dh_g_len = hdr.length; 1196 1197 return 0; 1198 } 1199 1200 1201 static const char *pem_dhparams_begin = "-----BEGIN DH PARAMETERS-----"; 1202 static const char *pem_dhparams_end = "-----END DH PARAMETERS-----"; 1203 1204 1205 static int tlsv1_set_dhparams_blob(struct tlsv1_credentials *cred, 1206 const u8 *buf, size_t len) 1207 { 1208 const u8 *pos, *end; 1209 unsigned char *der; 1210 size_t der_len; 1211 1212 pos = search_tag(pem_dhparams_begin, buf, len); 1213 if (!pos) { 1214 wpa_printf(MSG_DEBUG, "TLSv1: No PEM dhparams tag found - " 1215 "assume DER format"); 1216 return tlsv1_set_dhparams_der(cred, buf, len); 1217 } 1218 1219 wpa_printf(MSG_DEBUG, "TLSv1: Converting PEM format dhparams into DER " 1220 "format"); 1221 1222 pos += os_strlen(pem_dhparams_begin); 1223 end = search_tag(pem_dhparams_end, pos, buf + len - pos); 1224 if (end == NULL) { 1225 wpa_printf(MSG_INFO, "TLSv1: Could not find PEM dhparams end " 1226 "tag (%s)", pem_dhparams_end); 1227 return -1; 1228 } 1229 1230 der = base64_decode(pos, end - pos, &der_len); 1231 if (der == NULL) { 1232 wpa_printf(MSG_INFO, "TLSv1: Could not decode PEM dhparams"); 1233 return -1; 1234 } 1235 1236 if (tlsv1_set_dhparams_der(cred, der, der_len) < 0) { 1237 wpa_printf(MSG_INFO, "TLSv1: Failed to parse PEM dhparams " 1238 "DER conversion"); 1239 os_free(der); 1240 return -1; 1241 } 1242 1243 os_free(der); 1244 1245 return 0; 1246 } 1247 1248 1249 /** 1250 * tlsv1_set_dhparams - Set Diffie-Hellman parameters 1251 * @cred: TLSv1 credentials from tlsv1_cred_alloc() 1252 * @dh_file: File or reference name for the DH params in PEM or DER format 1253 * @dh_blob: DH params as inlined data or %NULL if not used 1254 * @dh_blob_len: dh_blob length 1255 * Returns: 0 on success, -1 on failure 1256 */ 1257 int tlsv1_set_dhparams(struct tlsv1_credentials *cred, const char *dh_file, 1258 const u8 *dh_blob, size_t dh_blob_len) 1259 { 1260 if (dh_blob) 1261 return tlsv1_set_dhparams_blob(cred, dh_blob, dh_blob_len); 1262 1263 if (dh_file) { 1264 u8 *buf; 1265 size_t len; 1266 int ret; 1267 1268 buf = (u8 *) os_readfile(dh_file, &len); 1269 if (buf == NULL) { 1270 wpa_printf(MSG_INFO, "TLSv1: Failed to read '%s'", 1271 dh_file); 1272 return -1; 1273 } 1274 1275 ret = tlsv1_set_dhparams_blob(cred, buf, len); 1276 os_free(buf); 1277 return ret; 1278 } 1279 1280 return 0; 1281 } 1282