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 { 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((const char *) 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((const char *) 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((const char *) 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 || !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 { 1009 cred->key = crypto_private_key_import(key, len, passwd); 1010 if (cred->key == NULL) 1011 cred->key = tlsv1_set_key_pem(key, len); 1012 if (cred->key == NULL) 1013 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 if (cred->key == NULL) { 1019 wpa_printf(MSG_INFO, "TLSv1: Failed to parse private key"); 1020 return -1; 1021 } 1022 return 0; 1023 } 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 { 1042 crypto_private_key_free(cred->key); 1043 cred->key = NULL; 1044 1045 if (private_key_blob) 1046 return tlsv1_set_key(cred, private_key_blob, 1047 private_key_blob_len, 1048 private_key_passwd); 1049 1050 if (private_key) { 1051 u8 *buf; 1052 size_t len; 1053 int ret; 1054 1055 buf = (u8 *) os_readfile(private_key, &len); 1056 if (buf == NULL) { 1057 wpa_printf(MSG_INFO, "TLSv1: Failed to read '%s'", 1058 private_key); 1059 return -1; 1060 } 1061 1062 ret = tlsv1_set_key(cred, buf, len, private_key_passwd); 1063 os_free(buf); 1064 return ret; 1065 } 1066 1067 return 0; 1068 } 1069 1070 1071 static int tlsv1_set_dhparams_der(struct tlsv1_credentials *cred, 1072 const u8 *dh, size_t len) 1073 { 1074 struct asn1_hdr hdr; 1075 const u8 *pos, *end; 1076 1077 pos = dh; 1078 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 if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) { 1089 asn1_unexpected(&hdr, 1090 "DH: DH parameters did not start with a valid SEQUENCE"); 1091 return -1; 1092 } 1093 pos = hdr.payload; 1094 1095 /* prime INTEGER */ 1096 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 1097 !asn1_is_integer(&hdr)) { 1098 asn1_unexpected(&hdr, "DH: No INTEGER tag found for p"); 1099 return -1; 1100 } 1101 1102 wpa_hexdump(MSG_MSGDUMP, "DH: prime (p)", hdr.payload, hdr.length); 1103 if (hdr.length == 0) 1104 return -1; 1105 os_free(cred->dh_p); 1106 cred->dh_p = os_memdup(hdr.payload, hdr.length); 1107 if (cred->dh_p == NULL) 1108 return -1; 1109 cred->dh_p_len = hdr.length; 1110 pos = hdr.payload + hdr.length; 1111 1112 /* base INTEGER */ 1113 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 1114 !asn1_is_integer(&hdr)) { 1115 asn1_unexpected(&hdr, "DH: No INTEGER tag found for g"); 1116 return -1; 1117 } 1118 1119 wpa_hexdump(MSG_MSGDUMP, "DH: base (g)", hdr.payload, hdr.length); 1120 if (hdr.length == 0) 1121 return -1; 1122 os_free(cred->dh_g); 1123 cred->dh_g = os_memdup(hdr.payload, hdr.length); 1124 if (cred->dh_g == NULL) 1125 return -1; 1126 cred->dh_g_len = hdr.length; 1127 1128 return 0; 1129 } 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 { 1139 const u8 *pos, *end; 1140 unsigned char *der; 1141 size_t der_len; 1142 1143 pos = search_tag(pem_dhparams_begin, buf, len); 1144 if (!pos) { 1145 wpa_printf(MSG_DEBUG, "TLSv1: No PEM dhparams tag found - " 1146 "assume DER format"); 1147 return tlsv1_set_dhparams_der(cred, buf, len); 1148 } 1149 1150 wpa_printf(MSG_DEBUG, "TLSv1: Converting PEM format dhparams into DER " 1151 "format"); 1152 1153 pos += os_strlen(pem_dhparams_begin); 1154 end = search_tag(pem_dhparams_end, pos, buf + len - pos); 1155 if (end == NULL) { 1156 wpa_printf(MSG_INFO, "TLSv1: Could not find PEM dhparams end " 1157 "tag (%s)", pem_dhparams_end); 1158 return -1; 1159 } 1160 1161 der = base64_decode((const char *) pos, end - pos, &der_len); 1162 if (der == NULL) { 1163 wpa_printf(MSG_INFO, "TLSv1: Could not decode PEM dhparams"); 1164 return -1; 1165 } 1166 1167 if (tlsv1_set_dhparams_der(cred, der, der_len) < 0) { 1168 wpa_printf(MSG_INFO, "TLSv1: Failed to parse PEM dhparams " 1169 "DER conversion"); 1170 os_free(der); 1171 return -1; 1172 } 1173 1174 os_free(der); 1175 1176 return 0; 1177 } 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 { 1191 if (dh_blob) 1192 return tlsv1_set_dhparams_blob(cred, dh_blob, dh_blob_len); 1193 1194 if (dh_file) { 1195 u8 *buf; 1196 size_t len; 1197 int ret; 1198 1199 buf = (u8 *) os_readfile(dh_file, &len); 1200 if (buf == NULL) { 1201 wpa_printf(MSG_INFO, "TLSv1: Failed to read '%s'", 1202 dh_file); 1203 return -1; 1204 } 1205 1206 ret = tlsv1_set_dhparams_blob(cred, buf, len); 1207 os_free(buf); 1208 return ret; 1209 } 1210 1211 return 0; 1212 } 1213