1/* 2 * Copyright (c) 2006-2012 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24/* 25 * sslCrypto.c - interface between SSL and crypto libraries 26 */ 27 28#include "sslCrypto.h" 29 30#include "CipherSuite.h" 31#include "ssl.h" 32#include "sslContext.h" 33#include "sslMemory.h" 34#include "sslUtils.h" 35#include "sslDebug.h" 36#include <libDER/DER_CertCrl.h> 37#include <libDER/DER_Keys.h> 38#include <CoreFoundation/CFString.h> 39#include <Security/SecKey.h> 40#include <Security/SecKeyPriv.h> 41#include <corecrypto/ccdh.h> 42#include <corecrypto/ccec.h> 43#include <corecrypto/ccrng.h> 44#include <Security/SecCertificate.h> 45#include <Security/SecPolicy.h> 46#include <Security/SecTrust.h> 47#include <AssertMacros.h> 48#include "utilities/SecCFRelease.h" 49 50#if TARGET_OS_IPHONE 51#include <Security/SecKeyInternal.h> 52#include <Security/SecRSAKey.h> 53#include <Security/SecECKey.h> 54#endif 55 56#ifndef _SSL_KEYCHAIN_H_ 57#include "sslKeychain.h" 58#endif 59 60#if APPLE_DH 61#include <libDER/libDER.h> 62#include <libDER/DER_Keys.h> 63#include <libDER/DER_Encode.h> 64#include <libDER/asn1Types.h> 65#include <Security/SecRandom.h> 66#endif 67 68#include <string.h> 69#include <stdlib.h> 70#include <assert.h> 71 72#if TARGET_OS_IPHONE 73#define CCRNGSTATE ccrng_seckey 74#else 75/* extern struct ccrng_state *ccDRBGGetRngState(); */ 76#include <CommonCrypto/CommonRandomSPI.h> 77#define CCRNGSTATE ccDRBGGetRngState() 78#endif 79 80 81/* 82 * Free a pubKey object. 83 */ 84extern OSStatus sslFreePubKey(SSLPubKey **pubKey) 85{ 86 if (pubKey && *pubKey) { 87 CFReleaseNull(SECKEYREF(*pubKey)); 88 } 89 return errSecSuccess; 90} 91 92/* 93 * Free a privKey object. 94 */ 95extern OSStatus sslFreePrivKey(SSLPrivKey **privKey) 96{ 97 if (privKey && *privKey) { 98 CFReleaseNull(SECKEYREF(*privKey)); 99 } 100 return errSecSuccess; 101} 102 103/* 104 * Get algorithm id for a SSLPubKey object. 105 */ 106CFIndex sslPubKeyGetAlgorithmID(SSLPubKey *pubKey) 107{ 108#if TARGET_OS_IPHONE 109 return SecKeyGetAlgorithmID(SECKEYREF(pubKey)); 110#else 111 return SecKeyGetAlgorithmId(SECKEYREF(pubKey)); 112#endif 113} 114 115/* 116 * Get algorithm id for a SSLPrivKey object. 117 */ 118CFIndex sslPrivKeyGetAlgorithmID(SSLPrivKey *privKey) 119{ 120#if TARGET_OS_IPHONE 121 return SecKeyGetAlgorithmID(SECKEYREF(privKey)); 122#else 123 return SecKeyGetAlgorithmId(SECKEYREF(privKey)); 124#endif 125} 126 127/* 128 * Raw RSA/DSA sign/verify. 129 */ 130OSStatus sslRawSign( 131 SSLContext *ctx, 132 SSLPrivKey *privKey, 133 const uint8_t *plainText, 134 size_t plainTextLen, 135 uint8_t *sig, // mallocd by caller; RETURNED 136 size_t sigLen, // available 137 size_t *actualBytes) // RETURNED 138{ 139#if 0 140 RSAStatus rsaStatus; 141#if RSA_SIG_SHARE_GIANT 142 RSASignBuffer *signBuffer = (RSASignBuffer *)sig; 143 assert(sigLen >= sizeof(RSASignBuffer)); 144#endif 145 assert(actualBytes != NULL); 146 147 /* @@@ Shouldn't need to init giSigLen according to libgRSA docs. */ 148 gi_uint16 giSigLen = sigLen; 149 150 rsaStatus = RSA_Sign(&privKey->rsaKey, 151 RP_PKCS1, 152 plainText, 153 plainTextLen, 154#if RSA_SIG_SHARE_GIANT 155 signBuffer, 156#else 157 sig, 158#endif 159 &giSigLen); 160 *actualBytes = giSigLen; 161 162 return rsaStatus ? rsaStatusToSSL(rsaStatus) : errSecSuccess; 163#else 164 165 size_t inOutSigLen = sigLen; 166 167 assert(actualBytes != NULL); 168 169 OSStatus status = SecKeyRawSign(SECKEYREF(privKey), kSecPaddingPKCS1, 170 plainText, plainTextLen, sig, &inOutSigLen); 171 172 if (status) { 173 sslErrorLog("sslRawSign: SecKeyRawSign failed (error %d)\n", (int)status); 174 } 175 176 /* Since the KeyExchange already allocated modulus size bytes we'll 177 use all of them. SecureTransport has always sent that many bytes, 178 so we're not going to deviate, to avoid interoperability issues. */ 179 if (!status && (inOutSigLen < sigLen)) { 180 size_t offset = sigLen - inOutSigLen; 181 memmove(sig + offset, sig, inOutSigLen); 182 memset(sig, 0, offset); 183 inOutSigLen = sigLen; 184 } 185 186 187 *actualBytes = inOutSigLen; 188 return status; 189#endif 190} 191 192/* TLS 1.2 RSA signature */ 193OSStatus sslRsaSign( 194 SSLContext *ctx, 195 SSLPrivKey *privKey, 196 const SecAsn1AlgId *algId, 197 const uint8_t *plainText, 198 size_t plainTextLen, 199 uint8_t *sig, // mallocd by caller; RETURNED 200 size_t sigLen, // available 201 size_t *actualBytes) // RETURNED 202{ 203 size_t inOutSigLen = sigLen; 204 205 assert(actualBytes != NULL); 206 207 OSStatus status = SecKeySignDigest(SECKEYREF(privKey), algId, 208 plainText, plainTextLen, sig, &inOutSigLen); 209 210 if (status) { 211 sslErrorLog("sslRsaSign: SecKeySignDigest failed (error %d)\n", (int) status); 212 } 213 214 /* Since the KeyExchange already allocated modulus size bytes we'll 215 use all of them. SecureTransport has always sent that many bytes, 216 so we're not going to deviate, to avoid interoperability issues. */ 217 if (!status && (inOutSigLen < sigLen)) { 218 size_t offset = sigLen - inOutSigLen; 219 memmove(sig + offset, sig, inOutSigLen); 220 memset(sig, 0, offset); 221 inOutSigLen = sigLen; 222 } 223 224 *actualBytes = inOutSigLen; 225 return status; 226} 227 228OSStatus sslRawVerify( 229 SSLContext *ctx, 230 SSLPubKey *pubKey, 231 const uint8_t *plainText, 232 size_t plainTextLen, 233 const uint8_t *sig, 234 size_t sigLen) // available 235{ 236#if 0 237 RSAStatus rsaStatus; 238 239 rsaStatus = RSA_SigVerify(&pubKey->rsaKey, 240 RP_PKCS1, 241 plainText, 242 plainTextLen, 243 sig, 244 sigLen); 245 246 return rsaStatus ? rsaStatusToSSL(rsaStatus) : errSecSuccess; 247#else 248 OSStatus status = SecKeyRawVerify(SECKEYREF(pubKey), kSecPaddingPKCS1, 249 plainText, plainTextLen, sig, sigLen); 250 251 if (status) { 252 sslErrorLog("sslRawVerify: SecKeyRawVerify failed (error %d)\n", (int) status); 253 } 254 255 return status; 256#endif 257} 258 259/* TLS 1.2 RSA verify */ 260OSStatus sslRsaVerify( 261 SSLContext *ctx, 262 SSLPubKey *pubKey, 263 const SecAsn1AlgId *algId, 264 const uint8_t *plainText, 265 size_t plainTextLen, 266 const uint8_t *sig, 267 size_t sigLen) // available 268{ 269 OSStatus status = SecKeyVerifyDigest(SECKEYREF(pubKey), algId, 270 plainText, plainTextLen, sig, sigLen); 271 272 if (status) { 273 sslErrorLog("sslRsaVerify: SecKeyVerifyDigest failed (error %d)\n", (int) status); 274 } 275 276 return status; 277} 278 279/* 280 * Encrypt/Decrypt 281 */ 282OSStatus sslRsaEncrypt( 283 SSLContext *ctx, 284 SSLPubKey *pubKey, 285 const uint32_t padding, 286 const uint8_t *plainText, 287 size_t plainTextLen, 288 uint8_t *cipherText, // mallocd by caller; RETURNED 289 size_t cipherTextLen, // available 290 size_t *actualBytes) // RETURNED 291{ 292#if 0 293 gi_uint16 giCipherTextLen = cipherTextLen; 294 RSAStatus rsaStatus; 295 296 assert(actualBytes != NULL); 297 298 rsaStatus = RSA_Encrypt(&pubKey->rsaKey, 299 RP_PKCS1, 300 getRandomByte, 301 plainText, 302 plainTextLen, 303 cipherText, 304 &giCipherTextLen); 305 *actualBytes = giCipherTextLen; 306 307 return rsaStatus ? rsaStatusToSSL(rsaStatus) : errSecSuccess; 308#else 309 size_t ctlen = cipherTextLen; 310 311 assert(actualBytes != NULL); 312 313#if RSA_PUB_KEY_USAGE_HACK 314 /* Force key usage to allow encryption with public key */ 315 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) 316 CSSM_KEY *cssmKey = NULL; 317 if (SecKeyGetCSSMKey(SECKEYREF(pubKey), (const CSSM_KEY **)&cssmKey)==errSecSuccess && cssmKey) 318 cssmKey->KeyHeader.KeyUsage |= CSSM_KEYUSE_ENCRYPT; 319 #endif 320#endif 321 322 OSStatus status = SecKeyEncrypt(SECKEYREF(pubKey), padding, 323 plainText, plainTextLen, cipherText, &ctlen); 324 325 if (status) { 326 sslErrorLog("sslRsaEncrypt: SecKeyEncrypt failed (error %d)\n", (int)status); 327 } 328 329 /* Since the KeyExchange already allocated modulus size bytes we'll 330 use all of them. SecureTransport has always sent that many bytes, 331 so we're not going to deviate, to avoid interoperability issues. */ 332 if (!status && (ctlen < cipherTextLen)) { 333 size_t offset = cipherTextLen - ctlen; 334 memmove(cipherText + offset, cipherText, ctlen); 335 memset(cipherText, 0, offset); 336 ctlen = cipherTextLen; 337 } 338 339 if (actualBytes) 340 *actualBytes = ctlen; 341 342 if (status) { 343 sslErrorLog("***sslRsaEncrypt: error %d\n", (int)status); 344 } 345 return status; 346#endif 347} 348 349OSStatus sslRsaDecrypt( 350 SSLContext *ctx, 351 SSLPrivKey *privKey, 352 const uint32_t padding, 353 const uint8_t *cipherText, 354 size_t cipherTextLen, 355 uint8_t *plainText, // mallocd by caller; RETURNED 356 size_t plainTextLen, // available 357 size_t *actualBytes) // RETURNED 358{ 359#if 0 360 gi_uint16 giPlainTextLen = plainTextLen; 361 RSAStatus rsaStatus; 362 363 assert(actualBytes != NULL); 364 365 rsaStatus = RSA_Decrypt(&privKey->rsaKey, 366 RP_PKCS1, 367 cipherText, 368 cipherTextLen, 369 plainText, 370 &giPlainTextLen); 371 *actualBytes = giPlainTextLen; 372 373 return rsaStatus ? rsaStatusToSSL(rsaStatus) : errSecSuccess; 374#else 375 size_t ptlen = plainTextLen; 376 377 assert(actualBytes != NULL); 378 379 OSStatus status = SecKeyDecrypt(SECKEYREF(privKey), padding, 380 cipherText, cipherTextLen, plainText, &ptlen); 381 *actualBytes = ptlen; 382 383 if (status) { 384 sslErrorLog("sslRsaDecrypt: SecKeyDecrypt failed (error %d)\n", (int)status); 385 } 386 387 return status; 388#endif 389} 390 391/* 392 * Obtain size of the modulus of privKey in bytes. 393 */ 394size_t sslPrivKeyLengthInBytes(SSLPrivKey *privKey) 395{ 396#if 0 397 /* Get the length of p + q (which is the size of the modulus) in bits. */ 398 gi_uint16 bitLen = bitlen(&privKey->rsaKey.p.g) + 399 bitlen(&privKey->rsaKey.q.g); 400 /* Convert it to bytes. */ 401 return (bitLen + 7) / 8; 402#else 403 return SecKeyGetBlockSize(SECKEYREF(privKey)); 404#endif 405} 406 407/* 408 * Obtain size of the modulus of pubKey in bytes. 409 */ 410size_t sslPubKeyLengthInBytes(SSLPubKey *pubKey) 411{ 412#if 0 413 /* Get the length of the modulus in bytes. */ 414 return giantNumBytes(&pubKey->rsaKey.n.g); 415#else 416 return SecKeyGetBlockSize(SECKEYREF(pubKey)); 417#endif 418} 419 420 421/* 422 * Obtain maximum size of signature in bytes. A bit of a kludge; we could 423 * ask the CSP to do this but that would be kind of expensive. 424 */ 425OSStatus sslGetMaxSigSize( 426 SSLPrivKey *privKey, 427 size_t *maxSigSize) 428{ 429 assert(maxSigSize != NULL); 430 431#if 0 432#if RSA_SIG_SHARE_GIANT 433 *maxSigSize = sizeof(RSASignBuffer); 434#else 435 *maxSigSize = MAX_PRIME_SIZE_BYTES; 436#endif 437#else 438 *maxSigSize = SecKeyGetBlockSize(SECKEYREF(privKey)); 439#endif 440 441 return errSecSuccess; 442} 443 444#if 0 445static OSStatus sslGiantToBuffer( 446 SSLContext *ctx, // Currently unused. 447 giant g, 448 SSLBuffer *buffer) 449{ 450 gi_uint8 *chars; 451 gi_uint16 ioLen; 452 gi_uint16 zeroCount; 453 GIReturn giReturn; 454 OSStatus status; 455 456 ioLen = serializeGiantBytes(g); 457 status = SSLAllocBuffer(buffer, ioLen); 458 if (status) 459 return status; 460 chars = buffer->data; 461 462 /* Serialize the giant g into chars. */ 463 giReturn = serializeGiant(g, chars, &ioLen); 464 if(giReturn) { 465 SSLFreeBuffer(buffer); 466 return giReturnToSSL(giReturn); 467 } 468 469 /* Trim off leading zeroes (but leave one zero if that's all there is). */ 470 for (zeroCount = 0; zeroCount < (ioLen - 1); ++zeroCount) 471 if (chars[zeroCount]) 472 break; 473 474 if (zeroCount > 0) { 475 buffer->length = ioLen - zeroCount; 476 memmove(chars, chars + zeroCount, buffer->length); 477 } 478 479 return status; 480} 481 482/* 483 * Get raw key bits from an RSA public key. 484 */ 485OSStatus sslGetPubKeyBits( 486 SSLContext *ctx, // Currently unused. 487 SSLPubKey *pubKey, 488 SSLBuffer *modulus, // data mallocd and RETURNED 489 SSLBuffer *exponent) // data mallocd and RETURNED 490{ 491 OSStatus status; 492 493 status = sslGiantToBuffer(ctx, &pubKey->rsaKey.n.g, modulus); 494 if(status) 495 return status; 496 497 status = sslGiantToBuffer(ctx, &pubKey->rsaKey.e.g, exponent); 498 if(status) { 499 SSLFreeBuffer(modulus); 500 return status; 501 } 502 503 return status; 504} 505#endif 506 507/* 508 * Given raw RSA key bits, cook up a SSLPubKey. Used in 509 * Server-initiated key exchange. 510 */ 511OSStatus sslGetPubKeyFromBits( 512 SSLContext *ctx, 513 const SSLBuffer *modulus, 514 const SSLBuffer *exponent, 515 SSLPubKey **pubKey) // mallocd and RETURNED 516{ 517 if (!pubKey) 518 return errSecParam; 519#if 0 520 SSLPubKey *key; 521 RSAStatus rsaStatus; 522 RSAPubKey apiKey = { 523 modulus->data, modulus->length, 524 NULL, 0, 525 exponent->data, exponent->length 526 }; 527 528 key = sslMalloc(sizeof(*key)); 529 rsaStatus = rsaInitPubGKey(&apiKey, &key->rsaKey); 530 if (rsaStatus) { 531 sslFree(key); 532 return rsaStatusToSSL(rsaStatus); 533 } 534 535 *pubKey = key; 536 return errSecSuccess; 537#else 538 check(pubKey); 539 SecRSAPublicKeyParams params = { 540 modulus->data, modulus->length, 541 exponent->data, exponent->length 542 }; 543#if SSL_DEBUG 544 sslDebugLog("Creating RSA pub key from modulus=%p len=%lu exponent=%p len=%lu\n", 545 modulus->data, modulus->length, 546 exponent->data, exponent->length); 547#endif 548 SecKeyRef key = SecKeyCreateRSAPublicKey(NULL, (const uint8_t *)¶ms, 549 sizeof(params), kSecKeyEncodingRSAPublicParams); 550 if (!key) { 551 sslErrorLog("sslGetPubKeyFromBits: SecKeyCreateRSAPublicKey failed\n"); 552 return errSSLCrypto; 553 } 554#if SSL_DEBUG 555 sslDebugLog("sslGetPubKeyFromBits: RSA pub key block size=%lu\n", SecKeyGetBlockSize(key)); 556#endif 557 *pubKey = (SSLPubKey*)key; 558 return errSecSuccess; 559#endif 560} 561 562// MARK: - 563// MARK: Public Certificate Functions 564 565#ifdef USE_SSLCERTIFICATE 566 567/* 568 * Given a SSLCertificate cert, obtain its public key as a SSLPubKey. 569 * Caller must sslFreePubKey and free the SSLPubKey itself. 570 */ 571OSStatus sslPubKeyFromCert( 572 SSLContext *ctx, 573 const SSLCertificate *cert, 574 SSLPubKey **pubKey) // RETURNED 575{ 576 DERItem der; 577 DERSignedCertCrl signedCert; 578 DERTBSCert tbsCert; 579 DERSubjPubKeyInfo pubKeyInfo; 580 DERByte numUnused; 581 DERItem pubKeyPkcs1; 582 SSLPubKey *key; 583 DERReturn drtn; 584 RSAStatus rsaStatus; 585 586 assert(cert); 587 assert(pubKey != NULL); 588 589 der.data = cert->derCert.data; 590 der.length = cert->derCert.length; 591 592 /* top level decode */ 593 drtn = DERParseSequence(&der, DERNumSignedCertCrlItemSpecs, 594 DERSignedCertCrlItemSpecs, &signedCert, sizeof(signedCert)); 595 if(drtn) 596 return errSSLBadCert; 597 598 /* decode the TBSCert - it was saved in full DER form */ 599 drtn = DERParseSequence(&signedCert.tbs, 600 DERNumTBSCertItemSpecs, DERTBSCertItemSpecs, 601 &tbsCert, sizeof(tbsCert)); 602 if(drtn) 603 return errSSLBadCert; 604 605 /* sequence we're given: encoded DERSubjPubKeyInfo */ 606 drtn = DERParseSequenceContent(&tbsCert.subjectPubKey, 607 DERNumSubjPubKeyInfoItemSpecs, DERSubjPubKeyInfoItemSpecs, 608 &pubKeyInfo, sizeof(pubKeyInfo)); 609 if(drtn) 610 return errSSLBadCert; 611 612 /* @@@ verify that this is an RSA key by decoding the AlgId */ 613 614 /* 615 * The contents of pubKeyInfo.pubKey is a bit string whose contents 616 * are a PKCS1 format RSA key. 617 */ 618 drtn = DERParseBitString(&pubKeyInfo.pubKey, &pubKeyPkcs1, &numUnused); 619 if(drtn) 620 return errSSLBadCert; 621 622#if TARGET_OS_IPHONE 623 /* Now we have the public key in pkcs1 format. Let's make a public key 624 object out of it. */ 625 key = sslMalloc(sizeof(*key)); 626 rsaStatus = RSA_DecodePubKey(pubKeyPkcs1.data, pubKeyPkcs1.length, 627 &key->rsaKey); 628 if (rsaStatus) { 629 sslFree(key); 630 } 631#else 632 SecKeyRef rsaPubKeyRef = SecKeyCreateRSAPublicKey(NULL, 633 pubKeyPkcs1.data, pubKeyPkcs1.length, 634 kSecKeyEncodingRSAPublicParams); 635 rsaStatus = (rsaPubKeyRef) ? 0 : 1; 636 key = (SSLPubKey*)rsaPubKeyRef; 637#endif 638 if (rsaStatus) { 639 return rsaStatusToSSL(rsaStatus); 640 } 641 642 *pubKey = key; 643 return errSecSuccess; 644} 645 646/* 647 * Verify a chain of DER-encoded certs. 648 * First cert in a chain is root; this must also be present 649 * in ctx->trustedCerts. 650 * 651 * If arePeerCerts is true, host name verification is enabled and we 652 * save the resulting SecTrustRef in ctx->peerSecTrust. Otherwise 653 * we're just validating our own certs; no host name checking and 654 * peerSecTrust is transient. 655 */ 656 OSStatus sslVerifyCertChain( 657 SSLContext *ctx, 658 const SSLCertificate *certChain, 659 bool arePeerCerts) 660{ 661 OSStatus ortn = errSecSuccess; 662 663 assert(certChain); 664 665 /* No point checking our own certs, our clients can do that. */ 666 if (!arePeerCerts) 667 return errSecSuccess; 668 669 CertVerifyReturn cvrtn; 670 /* @@@ Add real cert checking. */ 671 if (certChain->next) { 672 DERItem subject, issuer; 673 674 issuer.data = certChain->derCert.data; 675 issuer.length = certChain->derCert.length; 676 subject.data = certChain->next->derCert.data; 677 subject.length = certChain->next->derCert.length; 678 cvrtn = certVerify(&subject, &issuer); 679 if (cvrtn != CVR_Success) 680 ortn = errSSLBadCert; 681 } 682 else 683 { 684 sslErrorLog("***sslVerifyCertChain: only one cert in chain\n"); 685 } 686 return ortn; 687} 688 689#else /* !USE_SSLCERTIFICATE */ 690 691OSStatus 692sslCreateSecTrust( 693 SSLContext *ctx, 694 CFArrayRef certChain, 695 bool arePeerCerts, 696 SecTrustRef *pTrust) /* RETURNED */ 697{ 698 OSStatus status = errSecAllocate; 699 CFStringRef peerDomainName = NULL; 700 CFTypeRef policies = NULL; 701 SecTrustRef trust = NULL; 702 703 if (CFArrayGetCount(certChain) == 0) { 704 status = errSSLBadCert; 705 goto errOut; 706 } 707 708 if (arePeerCerts) { 709 if (ctx->peerDomainNameLen && ctx->peerDomainName) { 710 CFIndex len = ctx->peerDomainNameLen; 711 if (ctx->peerDomainName[len - 1] == 0) { 712 len--; 713 //secwarning("peerDomainName is zero terminated!"); 714 } 715 /* @@@ Double check that this is the correct encoding. */ 716 require(peerDomainName = CFStringCreateWithBytes(kCFAllocatorDefault, 717 (const UInt8 *)ctx->peerDomainName, len, 718 kCFStringEncodingUTF8, false), errOut); 719 } 720 } 721 /* If we are the client, our peer certificates must satisfy the 722 ssl server policy. */ 723 bool server = ctx->protocolSide == kSSLClientSide; 724 require(policies = SecPolicyCreateSSL(server, peerDomainName), errOut); 725 726 require_noerr(status = SecTrustCreateWithCertificates(certChain, policies, 727 &trust), errOut); 728 729 /* If we have trustedAnchors we set them here. */ 730 if (ctx->trustedCerts) { 731 require_noerr(status = SecTrustSetAnchorCertificates(trust, 732 ctx->trustedCerts), errOut); 733 require_noerr(status = SecTrustSetAnchorCertificatesOnly(trust, 734 ctx->trustedCertsOnly), errOut); 735 } 736 737 status = errSecSuccess; 738 739errOut: 740 CFReleaseSafe(peerDomainName); 741 CFReleaseSafe(policies); 742 743 *pTrust = trust; 744 745 return status; 746} 747 748/* Return the first certificate reference from the supplied array 749 * whose data matches the given certificate, or NULL if none match. 750 */ 751static 752SecCertificateRef 753sslGetMatchingCertInArray( 754 SecCertificateRef certRef, 755 CFArrayRef certArray) 756{ 757 SecCertificateRef matchedCert = NULL; 758 759 if (certRef == NULL || certArray == NULL) { 760 return NULL; 761 } 762 763 CFDataRef certData = SecCertificateCopyData(certRef); 764 if (certData) { 765 CFIndex idx, count = CFArrayGetCount(certArray); 766 for(idx=0; idx<count; idx++) { 767 SecCertificateRef aCert = (SecCertificateRef)CFArrayGetValueAtIndex(certArray, idx); 768 CFDataRef aData = SecCertificateCopyData(aCert); 769 if (aData && CFEqual(aData, certData)) { 770 matchedCert = aCert; 771 } 772 CFReleaseSafe(aData); 773 if (matchedCert) 774 break; 775 } 776 CFReleaseSafe(certData); 777 } 778 779 return matchedCert; 780} 781 782/* 783 * Verify a chain of DER-encoded certs. 784 * Last cert in a chain is the leaf; this must also be present 785 * in ctx->trustedCerts. 786 * 787 * If arePeerCerts is true, host name verification is enabled and we 788 * save the resulting SecTrustRef in ctx->peerSecTrust. Otherwise 789 * we're just validating our own certs; no host name checking and 790 * peerSecTrust is transient. 791 */ 792extern OSStatus sslVerifyCertChain( 793 SSLContext *ctx, 794 CFArrayRef certChain, 795 bool arePeerCerts) 796{ 797 OSStatus status; 798 SecTrustRef trust = NULL; 799 800 assert(certChain); 801 802 if (arePeerCerts) { 803 /* renegotiate - start with a new SecTrustRef */ 804 CFReleaseNull(ctx->peerSecTrust); 805 } 806 807 status = sslCreateSecTrust(ctx, certChain, arePeerCerts, &trust); 808 809 if (!ctx->enableCertVerify) { 810 /* trivial case, this is caller's responsibility */ 811 status = errSecSuccess; 812 goto errOut; 813 } 814 815 SecTrustResultType secTrustResult; 816 require_noerr(status = SecTrustEvaluate(trust, &secTrustResult), errOut); 817 switch (secTrustResult) { 818 case kSecTrustResultUnspecified: 819 /* cert chain valid, no special UserTrust assignments */ 820 case kSecTrustResultProceed: 821 /* cert chain valid AND user explicitly trusts this */ 822 status = errSecSuccess; 823 break; 824 case kSecTrustResultDeny: 825 case kSecTrustResultConfirm: 826 case kSecTrustResultRecoverableTrustFailure: 827 default: 828 if(ctx->allowAnyRoot) { 829 sslErrorLog("***Warning: accepting unverified cert chain\n"); 830 status = errSecSuccess; 831 } 832 else { 833 /* 834 * If the caller provided a list of trusted leaf certs, check them here 835 */ 836 if(ctx->trustedLeafCerts) { 837 if (sslGetMatchingCertInArray((SecCertificateRef)CFArrayGetValueAtIndex(certChain, 0), 838 ctx->trustedLeafCerts)) { 839 status = errSecSuccess; 840 goto errOut; 841 } 842 } 843 status = errSSLXCertChainInvalid; 844 } 845 /* Do we really need to return things like: 846 errSSLNoRootCert 847 errSSLUnknownRootCert 848 errSSLCertExpired 849 errSSLCertNotYetValid 850 errSSLHostNameMismatch 851 for our client to see what went wrong, or should we just always 852 return 853 errSSLXCertChainInvalid 854 when something is wrong? */ 855 break; 856 } 857 858errOut: 859 if (arePeerCerts) 860 ctx->peerSecTrust = trust; 861 else 862 CFReleaseSafe(trust); 863 864 return status; 865} 866 867/* 868 * Given a SecCertificateRef cert, obtain its public key as a SSLPubKey. 869 * Caller must sslFreePubKey and free the SSLPubKey itself. 870 */ 871extern OSStatus sslCopyPeerPubKey( 872 SSLContext *ctx, 873 SSLPubKey **pubKey) 874{ 875 check(pubKey); 876 check(ctx->peerSecTrust); 877 878 SecKeyRef key = SecTrustCopyPublicKey(ctx->peerSecTrust); 879 if (!key) { 880 sslErrorLog("sslCopyPeerPubKey: %s, ctx->peerSecTrust=%p\n", 881 "SecTrustCopyPublicKey failed", ctx->peerSecTrust); 882 return errSSLBadCert; 883 } 884 *pubKey = (SSLPubKey*)key; 885 886 return errSecSuccess; 887} 888 889#endif /* !USE_SSLCERTIFICATE */ 890 891#ifndef NDEBUG 892void stPrintCdsaError(const char *op, OSStatus crtn) 893{ 894 assert(FALSE); 895} 896#endif 897 898/* 899 * After ciphersuite negotiation is complete, verify that we have 900 * the capability of actually performing the selected cipher. 901 * Currently we just verify that we have a cert and private signing 902 * key, if needed, and that the signing key's algorithm matches the 903 * expected key exchange method. 904 * 905 * This is currently called from FindCipherSpec(), after it sets 906 * ctx->selectedCipherSpec to a (supposedly) valid value, and from 907 * sslBuildCipherSpecArray(), in server mode (pre-negotiation) only. 908 */ 909OSStatus sslVerifySelectedCipher(SSLContext *ctx) 910{ 911 if(ctx->protocolSide == kSSLClientSide) { 912 return errSecSuccess; 913 } 914#if SSL_PAC_SERVER_ENABLE 915 if((ctx->masterSecretCallback != NULL) && 916 (ctx->sessionTicket.data != NULL)) { 917 /* EAP via PAC resumption; we can do it */ 918 return errSecSuccess; 919 } 920#endif /* SSL_PAC_SERVER_ENABLE */ 921 922 CFIndex requireAlg; 923 switch (ctx->selectedCipherSpecParams.keyExchangeMethod) { 924 case SSL_RSA: 925 case SSL_RSA_EXPORT: 926 case SSL_DH_RSA: 927 case SSL_DH_RSA_EXPORT: 928 case SSL_DHE_RSA: 929 case SSL_DHE_RSA_EXPORT: 930 requireAlg = kSecRSAAlgorithmID; 931 break; 932 case SSL_DHE_DSS: 933 case SSL_DHE_DSS_EXPORT: 934 case SSL_DH_DSS: 935 case SSL_DH_DSS_EXPORT: 936 requireAlg = kSecDSAAlgorithmID; 937 break; 938 case SSL_DH_anon: 939 case SSL_DH_anon_EXPORT: 940 case TLS_PSK: 941 requireAlg = kSecNullAlgorithmID; /* no signing key */ 942 break; 943 /* 944 * When SSL_ECDSA_SERVER is true and we support ECDSA on the server side, 945 * we'll need to add some logic here... 946 */ 947#if SSL_ECDSA_SERVER 948 case SSL_ECDHE_ECDSA: 949 case SSL_ECDHE_RSA: 950 case SSL_ECDH_ECDSA: 951 case SSL_ECDH_RSA: 952 case SSL_ECDH_anon: 953 requireAlg = kSecECDSAAlgorithmID; 954 break; 955#endif 956 957 default: 958 /* needs update per cipherSpecs.c */ 959 assert(0); 960 sslErrorLog("sslVerifySelectedCipher: unknown key exchange method\n"); 961 return errSSLInternal; 962 } 963 964 if(requireAlg == kSecNullAlgorithmID) { 965 return errSecSuccess; 966 } 967 968 /* private signing key required */ 969 if(ctx->signingPrivKeyRef == NULL) { 970 sslErrorLog("sslVerifySelectedCipher: no signing key\n"); 971 return errSSLBadConfiguration; 972 } 973 974 /* Check the alg of our signing key. */ 975 CFIndex keyAlg = sslPrivKeyGetAlgorithmID(ctx->signingPrivKeyRef); 976 if (requireAlg != keyAlg) { 977 sslErrorLog("sslVerifySelectedCipher: signing key alg mismatch\n"); 978 return errSSLBadConfiguration; 979 } 980 981 return errSecSuccess; 982} 983 984#if APPLE_DH 985 986/* FIXME: This is duplicated in SecDH */ 987typedef struct { 988 DERItem p; 989 DERItem g; 990 DERItem l; 991} DER_DHParams; 992 993static const DERItemSpec DER_DHParamsItemSpecs[] = 994{ 995 { DER_OFFSET(DER_DHParams, p), 996 ASN1_INTEGER, 997 DER_DEC_NO_OPTS | DER_ENC_SIGNED_INT }, 998 { DER_OFFSET(DER_DHParams, g), 999 ASN1_INTEGER, 1000 DER_DEC_NO_OPTS | DER_ENC_SIGNED_INT }, 1001 { DER_OFFSET(DER_DHParams, l), 1002 ASN1_INTEGER, 1003 DER_DEC_OPTIONAL | DER_ENC_SIGNED_INT }, 1004}; 1005static const DERSize DER_NumDHParamsItemSpecs = 1006sizeof(DER_DHParamsItemSpecs) / sizeof(DERItemSpec); 1007 1008/* Max encoded size for standard (PKCS3) parameters */ 1009#define DH_ENCODED_PARAM_SIZE(primeSizeInBytes) \ 1010DER_MAX_ENCODED_SIZE( \ 1011DER_MAX_ENCODED_SIZE(primeSizeInBytes) + /* g */ \ 1012DER_MAX_ENCODED_SIZE(primeSizeInBytes) + /* p */ \ 1013DER_MAX_ENCODED_SIZE(4)) /* l */ 1014 1015 1016OSStatus sslDecodeDhParams( 1017 const SSLBuffer *blob, /* Input - PKCS-3 encoded */ 1018 SSLBuffer *prime, /* Output - wire format */ 1019 SSLBuffer *generator) /* Output - wire format */ 1020{ 1021 OSStatus ortn = errSecSuccess; 1022 DERReturn drtn; 1023 DERItem paramItem = {(DERByte *)blob->data, blob->length}; 1024 DER_DHParams decodedParams; 1025 1026 drtn = DERParseSequence(¶mItem, 1027 DER_NumDHParamsItemSpecs, DER_DHParamsItemSpecs, 1028 &decodedParams, sizeof(decodedParams)); 1029 if(drtn) 1030 return drtn; 1031 1032 prime->data = decodedParams.p.data; 1033 prime->length = decodedParams.p.length; 1034 1035 generator->data = decodedParams.g.data; 1036 generator->length = decodedParams.g.length; 1037 1038 return ortn; 1039} 1040 1041 1042OSStatus sslEncodeDhParams(SSLBuffer *blob, /* data mallocd and RETURNED PKCS-3 encoded */ 1043 const SSLBuffer *prime, /* Wire format */ 1044 const SSLBuffer *generator) /* Wire format */ 1045{ 1046 OSStatus ortn = errSecSuccess; 1047 DER_DHParams derParams = 1048 { 1049 .p = { 1050 .length = prime->length, 1051 .data = prime->data, 1052 }, 1053 .g = { 1054 .length = generator->length, 1055 .data = generator->data, 1056 }, 1057 .l = { 1058 .length = 0, 1059 .data = NULL, 1060 } 1061 }; 1062 1063 DERSize ioLen = DH_ENCODED_PARAM_SIZE(derParams.p.length); 1064 DERByte *der = sslMalloc(ioLen); 1065 // FIXME: What if this fails - we should probably not have a malloc here ? 1066 assert(der); 1067 ortn = (OSStatus)DEREncodeSequence(ASN1_CONSTR_SEQUENCE, 1068 &derParams, 1069 DER_NumDHParamsItemSpecs, DER_DHParamsItemSpecs, 1070 der, 1071 &ioLen); 1072 // This should never fail 1073 1074 blob->length=ioLen; 1075 blob->data=der; 1076 1077 return ortn; 1078} 1079 1080OSStatus sslDhCreateKey(SSLContext *ctx) 1081{ 1082 if (ctx->secDHContext) { 1083 SecDHDestroy(ctx->secDHContext); 1084 ctx->secDHContext = NULL; 1085 } 1086 1087 /* Server params are set using encoded dh params */ 1088 if (!(ctx->dhParamsEncoded.length && ctx->dhParamsEncoded.data)) 1089 return errSSLInternal; 1090 1091 if (SecDHCreateFromParameters(ctx->dhParamsEncoded.data, 1092 ctx->dhParamsEncoded.length, &ctx->secDHContext)) 1093 return errSSLCrypto; 1094 1095 return errSecSuccess; 1096} 1097 1098OSStatus sslDhGenerateKeyPair(SSLContext *ctx) 1099{ 1100 OSStatus ortn = errSecSuccess; 1101 1102 require_noerr(ortn = SSLAllocBuffer(&ctx->dhExchangePublic, 1103 SecDHGetMaxKeyLength(ctx->secDHContext)), out); 1104 require_noerr(ortn = SecDHGenerateKeypair(ctx->secDHContext, 1105 ctx->dhExchangePublic.data, &ctx->dhExchangePublic.length), out); 1106 1107out: 1108 return ortn; 1109} 1110 1111 1112OSStatus sslDhKeyExchange(SSLContext *ctx) 1113{ 1114 OSStatus ortn = errSecSuccess; 1115 1116 if (ctx == NULL || 1117 ctx->secDHContext == NULL || 1118 ctx->dhPeerPublic.length == 0) { 1119 /* comes from peer, don't panic */ 1120 sslErrorLog("sslDhKeyExchange: null peer public key\n"); 1121 return errSSLProtocol; 1122 } 1123 1124 require_noerr(ortn = SSLAllocBuffer(&ctx->preMasterSecret, 1125 SecDHGetMaxKeyLength(ctx->secDHContext)), out); 1126 require_noerr(ortn = SecDHComputeKey(ctx->secDHContext, 1127 ctx->dhPeerPublic.data, ctx->dhPeerPublic.length, 1128 ctx->preMasterSecret.data, &ctx->preMasterSecret.length), out); 1129 1130 return ortn; 1131out: 1132 sslErrorLog("sslDhKeyExchange: failed to compute key (error %d)\n", (int)ortn); 1133 return ortn; 1134} 1135 1136#endif /* APPLE_DH */ 1137 1138/* 1139 * Given an ECDSA key in SecKey format, extract the SSL_ECDSA_NamedCurve 1140 * from its algorithm parameters. 1141 */ 1142OSStatus sslEcdsaPeerCurve( 1143 SSLPubKey *pubKey, 1144 SSL_ECDSA_NamedCurve *namedCurve) 1145{ 1146 /* Cast is safe because enums are kept in sync. */ 1147 *namedCurve = (SSL_ECDSA_NamedCurve)SecECKeyGetNamedCurve(SECKEYREF(pubKey)); 1148 if (*namedCurve == kSecECCurveNone) { 1149 sslErrorLog("sslEcdsaPeerCurve: no named curve for public key\n"); 1150 return errSSLProtocol; 1151 } 1152 return errSecSuccess; 1153} 1154 1155/* 1156 * Generate ECDH key pair with the given SSL_ECDSA_NamedCurve. 1157 * Private key, in ref form, is placed in ctx->ecdhPrivate. 1158 * Public key, in ECPoint form - which can NOT be used as 1159 * a key in any CSP ops - is placed in ecdhExchangePublic. 1160 */ 1161OSStatus sslEcdhGenerateKeyPair( 1162 SSLContext *ctx, 1163 SSL_ECDSA_NamedCurve namedCurve) 1164{ 1165 OSStatus ortn = errSecSuccess; 1166 1167 ccec_const_cp_t cp; 1168 switch (namedCurve) { 1169 case SSL_Curve_secp256r1: 1170 cp = ccec_cp_256(); 1171 break; 1172 case SSL_Curve_secp384r1: 1173 cp = ccec_cp_384(); 1174 break; 1175 case SSL_Curve_secp521r1: 1176 cp = ccec_cp_521(); 1177 break; 1178 default: 1179 /* should not have gotten this far */ 1180 sslErrorLog("sslEcdhGenerateKeyPair: bad namedCurve (%u)\n", 1181 (unsigned)namedCurve); 1182 return errSSLInternal; 1183 } 1184 1185 ccec_generate_key(cp, CCRNGSTATE, ctx->ecdhContext); 1186 size_t pub_size = ccec_export_pub_size(ctx->ecdhContext); 1187 SSLFreeBuffer(&ctx->ecdhExchangePublic); 1188 require_noerr(ortn = SSLAllocBuffer(&ctx->ecdhExchangePublic, 1189 pub_size), errOut); 1190 ccec_export_pub(ctx->ecdhContext, ctx->ecdhExchangePublic.data); 1191 1192 sslDebugLog("sslEcdhGenerateKeyPair: pub key size=%ld, data=%p\n", 1193 pub_size, ctx->ecdhExchangePublic.data); 1194 1195errOut: 1196 return ortn; 1197} 1198 1199/* 1200 * Perform ECDH key exchange. Obtained key material is the same 1201 * size as our private key. 1202 * 1203 * On entry, ecdhPrivate is our private key. The peer's public key 1204 * is either ctx->ecdhPeerPublic for ECDHE exchange, or 1205 * ctx->peerPubKey for ECDH exchange. 1206 */ 1207OSStatus sslEcdhKeyExchange( 1208 SSLContext *ctx, 1209 SSLBuffer *exchanged) 1210{ 1211 OSStatus ortn = errSecSuccess; 1212 CFDataRef pubKeyData = NULL; 1213 const unsigned char *pubKeyBits; 1214 unsigned long pubKeyLen; 1215 1216 switch(ctx->selectedCipherSpecParams.keyExchangeMethod) { 1217 case SSL_ECDHE_ECDSA: 1218 case SSL_ECDHE_RSA: 1219 /* public key passed in as CSSM_DATA *Param */ 1220 if(ctx->ecdhPeerPublic.length == 0) { 1221 /* comes from peer, don't panic */ 1222 sslErrorLog("sslEcdhKeyExchange: null peer public key\n"); 1223 ortn = errSSLProtocol; 1224 goto errOut; 1225 } 1226 pubKeyBits = ctx->ecdhPeerPublic.data; 1227 pubKeyLen = ctx->ecdhPeerPublic.length; 1228 break; 1229 case SSL_ECDH_ECDSA: 1230 case SSL_ECDH_RSA: 1231 /* Use the public key provided by the peer. */ 1232 if(ctx->peerPubKey == NULL) { 1233 sslErrorLog("sslEcdhKeyExchange: no peer key\n"); 1234 ortn = errSSLInternal; 1235 goto errOut; 1236 } 1237 1238 pubKeyData = SecECKeyCopyPublicBits(SECKEYREF(ctx->peerPubKey)); 1239 if (!pubKeyData) { 1240 sslErrorLog("sslEcdhKeyExchange: SecECKeyCopyPublicBits failed\n"); 1241 ortn = errSSLProtocol; 1242 goto errOut; 1243 } 1244 pubKeyBits = CFDataGetBytePtr(pubKeyData); 1245 pubKeyLen = CFDataGetLength(pubKeyData); 1246 break; 1247 default: 1248 /* shouldn't be here */ 1249 sslErrorLog("sslEcdhKeyExchange: unknown keyExchangeMethod (%d)\n", 1250 ctx->selectedCipherSpecParams.keyExchangeMethod); 1251 assert(0); 1252 ortn = errSSLInternal; 1253 goto errOut; 1254 } 1255 1256 ccec_const_cp_t cp = ccec_ctx_cp(ctx->ecdhContext); 1257 ccec_pub_ctx_decl(ccn_sizeof(521), pubKey); 1258 ccec_import_pub(cp, pubKeyLen, pubKeyBits, pubKey); 1259 size_t len = 1 + 2 * ccec_ccn_size(cp); 1260 require_noerr(ortn = SSLAllocBuffer(exchanged, len), errOut); 1261 require_noerr(ccec_compute_key(ctx->ecdhContext, pubKey, &exchanged->length, exchanged->data), errOut); 1262 1263 sslDebugLog("sslEcdhKeyExchange: exchanged key length=%ld, data=%p\n", 1264 exchanged->length, exchanged->data); 1265 1266errOut: 1267 CFReleaseSafe(pubKeyData); 1268 return ortn; 1269} 1270