2  * Copyright (c) 2006-2012 Apple Inc. All Rights Reserved. 
   4  * @APPLE_LICENSE_HEADER_START@ 
   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 
  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. 
  21  * @APPLE_LICENSE_HEADER_END@ 
  25  * sslCrypto.c - interface between SSL and crypto libraries 
  28 #include "sslCrypto.h" 
  30 #include "CipherSuite.h" 
  32 #include "sslContext.h" 
  33 #include "sslMemory.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" 
  51 #include <Security/SecKeyInternal.h> 
  52 #include <Security/SecRSAKey.h> 
  53 #include <Security/SecECKey.h> 
  56 #ifndef _SSL_KEYCHAIN_H_ 
  57 #include "sslKeychain.h" 
  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> 
  73 #define CCRNGSTATE ccrng_seckey 
  75 /* extern struct ccrng_state *ccDRBGGetRngState(); */ 
  76 #include <CommonCrypto/CommonRandomSPI.h> 
  77 #define CCRNGSTATE ccDRBGGetRngState() 
  82  * Free a pubKey object. 
  84 extern OSStatus 
sslFreePubKey(SSLPubKey 
**pubKey
) 
  86         if (pubKey 
&& *pubKey
) { 
  87                 CFReleaseNull(SECKEYREF(*pubKey
)); 
  93  * Free a privKey object. 
  95 extern OSStatus 
sslFreePrivKey(SSLPrivKey 
**privKey
) 
  97         if (privKey 
&& *privKey
) { 
  98                 CFReleaseNull(SECKEYREF(*privKey
)); 
 100         return errSecSuccess
; 
 104  * Get algorithm id for a SSLPubKey object. 
 106 CFIndex 
sslPubKeyGetAlgorithmID(SSLPubKey 
*pubKey
) 
 109         return SecKeyGetAlgorithmID(SECKEYREF(pubKey
)); 
 111         return SecKeyGetAlgorithmId(SECKEYREF(pubKey
)); 
 116  * Get algorithm id for a SSLPrivKey object. 
 118 CFIndex 
sslPrivKeyGetAlgorithmID(SSLPrivKey 
*privKey
) 
 121         return SecKeyGetAlgorithmID(SECKEYREF(privKey
)); 
 123         return SecKeyGetAlgorithmId(SECKEYREF(privKey
)); 
 128  * Raw RSA/DSA sign/verify. 
 133         const uint8_t       *plainText
, 
 135         uint8_t                         *sig
,                   // mallocd by caller; RETURNED 
 136         size_t              sigLen
,         // available 
 137         size_t              *actualBytes
)   // RETURNED 
 141 #if RSA_SIG_SHARE_GIANT 
 142         RSASignBuffer 
*signBuffer 
= (RSASignBuffer 
*)sig
; 
 143         assert(sigLen 
>= sizeof(RSASignBuffer
)); 
 145         assert(actualBytes 
!= NULL
); 
 147         /* @@@ Shouldn't need to init giSigLen according to libgRSA docs. */ 
 148         gi_uint16 giSigLen 
= sigLen
; 
 150         rsaStatus 
= RSA_Sign(&privKey
->rsaKey
, 
 154 #if RSA_SIG_SHARE_GIANT 
 160         *actualBytes 
= giSigLen
; 
 162         return rsaStatus 
? rsaStatusToSSL(rsaStatus
) : errSecSuccess
; 
 165         size_t inOutSigLen 
= sigLen
; 
 167         assert(actualBytes 
!= NULL
); 
 169     OSStatus status 
= SecKeyRawSign(SECKEYREF(privKey
), kSecPaddingPKCS1
, 
 170         plainText
, plainTextLen
, sig
, &inOutSigLen
); 
 173                 sslErrorLog("sslRawSign: SecKeyRawSign failed (error %d)\n", (int)status
); 
 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
; 
 187         *actualBytes 
= inOutSigLen
; 
 192 /* TLS 1.2 RSA signature */ 
 196                     const SecAsn1AlgId  
*algId
, 
 197                     const uint8_t       *plainText
, 
 199                     uint8_t                             *sig
,                   // mallocd by caller; RETURNED 
 200                     size_t              sigLen
,         // available 
 201                     size_t              *actualBytes
)   // RETURNED 
 203         size_t inOutSigLen 
= sigLen
; 
 205         assert(actualBytes 
!= NULL
); 
 207     OSStatus status 
= SecKeySignDigest(SECKEYREF(privKey
), algId
, 
 208                                     plainText
, plainTextLen
, sig
, &inOutSigLen
); 
 211                 sslErrorLog("sslRsaSign: SecKeySignDigest failed (error %d)\n", (int) status
); 
 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
; 
 224         *actualBytes 
= inOutSigLen
; 
 228 OSStatus 
sslRawVerify( 
 231         const uint8_t       *plainText
, 
 234         size_t              sigLen
)         // available 
 239         rsaStatus 
= RSA_SigVerify(&pubKey
->rsaKey
, 
 246         return rsaStatus 
? rsaStatusToSSL(rsaStatus
) : errSecSuccess
; 
 248         OSStatus status 
= SecKeyRawVerify(SECKEYREF(pubKey
), kSecPaddingPKCS1
, 
 249         plainText
, plainTextLen
, sig
, sigLen
); 
 252                 sslErrorLog("sslRawVerify: SecKeyRawVerify failed (error %d)\n", (int) status
); 
 259 /* TLS 1.2 RSA verify */ 
 260 OSStatus 
sslRsaVerify( 
 263                       const SecAsn1AlgId  
*algId
, 
 264                       const uint8_t       *plainText
, 
 267                       size_t              sigLen
)         // available 
 269         OSStatus status 
= SecKeyVerifyDigest(SECKEYREF(pubKey
), algId
, 
 270                            plainText
, plainTextLen
, sig
, sigLen
); 
 273                 sslErrorLog("sslRsaVerify: SecKeyVerifyDigest failed (error %d)\n", (int) status
); 
 282 OSStatus 
sslRsaEncrypt( 
 285         const uint32_t          padding
, 
 286         const uint8_t       *plainText
, 
 288         uint8_t                         *cipherText
,            // mallocd by caller; RETURNED 
 289         size_t              cipherTextLen
,      // available 
 290         size_t              *actualBytes
)       // RETURNED 
 293         gi_uint16 giCipherTextLen 
= cipherTextLen
; 
 296         assert(actualBytes 
!= NULL
); 
 298         rsaStatus 
= RSA_Encrypt(&pubKey
->rsaKey
, 
 305         *actualBytes 
= giCipherTextLen
; 
 307         return rsaStatus 
? rsaStatusToSSL(rsaStatus
) : errSecSuccess
; 
 309     size_t ctlen 
= cipherTextLen
; 
 311         assert(actualBytes 
!= NULL
); 
 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
; 
 322     OSStatus status 
= SecKeyEncrypt(SECKEYREF(pubKey
), padding
, 
 323         plainText
, plainTextLen
, cipherText
, &ctlen
); 
 326                 sslErrorLog("sslRsaEncrypt: SecKeyEncrypt failed (error %d)\n", (int)status
); 
 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
; 
 340         *actualBytes 
= ctlen
; 
 343         sslErrorLog("***sslRsaEncrypt: error %d\n", (int)status
); 
 349 OSStatus 
sslRsaDecrypt( 
 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 
 360         gi_uint16 giPlainTextLen 
= plainTextLen
; 
 363         assert(actualBytes 
!= NULL
); 
 365         rsaStatus 
= RSA_Decrypt(&privKey
->rsaKey
, 
 371         *actualBytes 
= giPlainTextLen
; 
 373         return rsaStatus 
? rsaStatusToSSL(rsaStatus
) : errSecSuccess
; 
 375         size_t ptlen 
= plainTextLen
; 
 377         assert(actualBytes 
!= NULL
); 
 379     OSStatus status 
= SecKeyDecrypt(SECKEYREF(privKey
), padding
, 
 380         cipherText
, cipherTextLen
, plainText
, &ptlen
); 
 381         *actualBytes 
= ptlen
; 
 384         sslErrorLog("sslRsaDecrypt: SecKeyDecrypt failed (error %d)\n", (int)status
); 
 392  * Obtain size of the modulus of privKey in bytes. 
 394 size_t sslPrivKeyLengthInBytes(SSLPrivKey 
*privKey
) 
 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; 
 403     return SecKeyGetBlockSize(SECKEYREF(privKey
)); 
 408  * Obtain size of the modulus of pubKey in bytes. 
 410 size_t sslPubKeyLengthInBytes(SSLPubKey 
*pubKey
) 
 413         /* Get the length of the modulus in bytes. */ 
 414         return giantNumBytes(&pubKey
->rsaKey
.n
.g
); 
 416     return SecKeyGetBlockSize(SECKEYREF(pubKey
)); 
 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. 
 425 OSStatus 
sslGetMaxSigSize( 
 429         assert(maxSigSize 
!= NULL
); 
 432 #if RSA_SIG_SHARE_GIANT 
 433         *maxSigSize 
= sizeof(RSASignBuffer
); 
 435         *maxSigSize 
= MAX_PRIME_SIZE_BYTES
; 
 438     *maxSigSize 
= SecKeyGetBlockSize(SECKEYREF(privKey
)); 
 441         return errSecSuccess
; 
 445 static OSStatus 
sslGiantToBuffer( 
 446         SSLContext                      
*ctx
,                   // Currently unused. 
 456         ioLen 
= serializeGiantBytes(g
); 
 457         status 
= SSLAllocBuffer(buffer
, ioLen
); 
 460         chars 
= buffer
->data
; 
 462         /* Serialize the giant g into chars. */ 
 463         giReturn 
= serializeGiant(g
, chars
, &ioLen
); 
 465                 SSLFreeBuffer(buffer
); 
 466                 return giReturnToSSL(giReturn
); 
 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
]) 
 475                 buffer
->length 
= ioLen 
- zeroCount
; 
 476                 memmove(chars
, chars 
+ zeroCount
, buffer
->length
); 
 483  * Get raw key bits from an RSA public key. 
 485 OSStatus 
sslGetPubKeyBits( 
 486         SSLContext                      
*ctx
,                   // Currently unused. 
 488         SSLBuffer                       
*modulus
,               // data mallocd and RETURNED 
 489         SSLBuffer                       
*exponent
)              // data mallocd and RETURNED 
 493         status 
= sslGiantToBuffer(ctx
, &pubKey
->rsaKey
.n
.g
, modulus
); 
 497         status 
= sslGiantToBuffer(ctx
, &pubKey
->rsaKey
.e
.g
, exponent
); 
 499                 SSLFreeBuffer(modulus
); 
 508  * Given raw RSA key bits, cook up a SSLPubKey. Used in 
 509  * Server-initiated key exchange. 
 511 OSStatus 
sslGetPubKeyFromBits( 
 513         const SSLBuffer         
*modulus
, 
 514         const SSLBuffer         
*exponent
, 
 515         SSLPubKey           
**pubKey
)        // mallocd and RETURNED 
 523                 modulus
->data
, modulus
->length
, 
 525                 exponent
->data
, exponent
->length
 
 528         key 
= sslMalloc(sizeof(*key
)); 
 529         rsaStatus 
= rsaInitPubGKey(&apiKey
, &key
->rsaKey
); 
 532                 return rsaStatusToSSL(rsaStatus
); 
 536         return errSecSuccess
; 
 539         SecRSAPublicKeyParams params 
= { 
 540                 modulus
->data
, modulus
->length
, 
 541                 exponent
->data
, exponent
->length
 
 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
); 
 548         SecKeyRef key 
= SecKeyCreateRSAPublicKey(NULL
, (const uint8_t *)¶ms
, 
 549                         sizeof(params
), kSecKeyEncodingRSAPublicParams
); 
 551                 sslErrorLog("sslGetPubKeyFromBits: SecKeyCreateRSAPublicKey failed\n"); 
 555         sslDebugLog("sslGetPubKeyFromBits: RSA pub key block size=%lu\n", SecKeyGetBlockSize(key
)); 
 557         *pubKey 
= (SSLPubKey
*)key
; 
 558         return errSecSuccess
; 
 563 // MARK: Public Certificate Functions 
 565 #ifdef USE_SSLCERTIFICATE 
 568  * Given a SSLCertificate cert, obtain its public key as a SSLPubKey. 
 569  * Caller must sslFreePubKey and free the SSLPubKey itself. 
 571 OSStatus 
sslPubKeyFromCert( 
 573         const SSLCertificate    
*cert
, 
 574         SSLPubKey               
**pubKey
)               // RETURNED 
 577     DERSignedCertCrl signedCert
; 
 579         DERSubjPubKeyInfo pubKeyInfo
; 
 587         assert(pubKey 
!= NULL
); 
 589     der
.data 
= cert
->derCert
.data
; 
 590     der
.length 
= cert
->derCert
.length
; 
 592         /* top level decode */ 
 593         drtn 
= DERParseSequence(&der
, DERNumSignedCertCrlItemSpecs
, 
 594                 DERSignedCertCrlItemSpecs
, &signedCert
, sizeof(signedCert
)); 
 596                 return errSSLBadCert
; 
 598         /* decode the TBSCert - it was saved in full DER form */ 
 599         drtn 
= DERParseSequence(&signedCert
.tbs
, 
 600                 DERNumTBSCertItemSpecs
, DERTBSCertItemSpecs
, 
 601                 &tbsCert
, sizeof(tbsCert
)); 
 603                 return errSSLBadCert
; 
 605         /* sequence we're given: encoded DERSubjPubKeyInfo */ 
 606         drtn 
= DERParseSequenceContent(&tbsCert
.subjectPubKey
, 
 607                 DERNumSubjPubKeyInfoItemSpecs
, DERSubjPubKeyInfoItemSpecs
, 
 608                 &pubKeyInfo
, sizeof(pubKeyInfo
)); 
 610                 return errSSLBadCert
; 
 612         /* @@@ verify that this is an RSA key by decoding the AlgId */ 
 615          * The contents of pubKeyInfo.pubKey is a bit string whose contents 
 616          * are a PKCS1 format RSA key. 
 618         drtn 
= DERParseBitString(&pubKeyInfo
.pubKey
, &pubKeyPkcs1
, &numUnused
); 
 620                 return errSSLBadCert
; 
 623     /* Now we have the public key in pkcs1 format.  Let's make a public key 
 625     key 
= sslMalloc(sizeof(*key
)); 
 626     rsaStatus 
= RSA_DecodePubKey(pubKeyPkcs1
.data
, pubKeyPkcs1
.length
, 
 632         SecKeyRef rsaPubKeyRef 
= SecKeyCreateRSAPublicKey(NULL
, 
 633                 pubKeyPkcs1
.data
, pubKeyPkcs1
.length
, 
 634                 kSecKeyEncodingRSAPublicParams
); 
 635         rsaStatus 
= (rsaPubKeyRef
) ? 0 : 1; 
 636         key 
= (SSLPubKey
*)rsaPubKeyRef
; 
 639                 return rsaStatusToSSL(rsaStatus
); 
 643         return errSecSuccess
; 
 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. 
 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. 
 656  OSStatus 
sslVerifyCertChain( 
 658         const SSLCertificate    
*certChain
, 
 661         OSStatus ortn 
= errSecSuccess
; 
 665     /* No point checking our own certs, our clients can do that. */ 
 667         return errSecSuccess
; 
 669     CertVerifyReturn cvrtn
; 
 670     /* @@@ Add real cert checking. */ 
 671     if (certChain
->next
) { 
 672         DERItem subject
, issuer
; 
 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
; 
 684                 sslErrorLog("***sslVerifyCertChain: only one cert in chain\n"); 
 689 #else /* !USE_SSLCERTIFICATE */ 
 694         CFArrayRef                              certChain
, 
 696     SecTrustRef             
*pTrust
)    /* RETURNED */ 
 698         OSStatus status 
= errSecAllocate
; 
 699         CFStringRef peerDomainName 
= NULL
; 
 700         CFTypeRef policies 
= NULL
; 
 701         SecTrustRef trust 
= NULL
; 
 703     if (CFArrayGetCount(certChain
) == 0) { 
 704                 status 
= errSSLBadCert
; 
 709                 if (ctx
->peerDomainNameLen 
&& ctx
->peerDomainName
) { 
 710                         CFIndex len 
= ctx
->peerDomainNameLen
; 
 711                         if (ctx
->peerDomainName
[len 
- 1] == 0) { 
 713                                 //secwarning("peerDomainName is zero terminated!"); 
 715                         /* @@@ Double check that this is the correct encoding. */ 
 716                         require(peerDomainName 
= CFStringCreateWithBytes(kCFAllocatorDefault
, 
 717                                 (const UInt8 
*)ctx
->peerDomainName
, len
, 
 718                                 kCFStringEncodingUTF8
, false), errOut
); 
 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
); 
 726         require_noerr(status 
= SecTrustCreateWithCertificates(certChain
, policies
, 
 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
); 
 737     status 
= errSecSuccess
; 
 740         CFReleaseSafe(peerDomainName
); 
 741         CFReleaseSafe(policies
); 
 748 /* Return the first certificate reference from the supplied array 
 749  * whose data matches the given certificate, or NULL if none match. 
 753 sslGetMatchingCertInArray( 
 754         SecCertificateRef       certRef
, 
 755         CFArrayRef                      certArray
) 
 757         SecCertificateRef matchedCert 
= NULL
; 
 759         if (certRef 
== NULL 
|| certArray 
== NULL
) { 
 763         CFDataRef certData 
= SecCertificateCopyData(certRef
); 
 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
)) { 
 772                         CFReleaseSafe(aData
); 
 776                 CFReleaseSafe(certData
); 
 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. 
 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. 
 792 extern OSStatus 
sslVerifyCertChain( 
 794         CFArrayRef                              certChain
, 
 798         SecTrustRef trust 
= NULL
; 
 803                 /* renegotiate - start with a new SecTrustRef */ 
 804         CFReleaseNull(ctx
->peerSecTrust
); 
 807         status 
= sslCreateSecTrust(ctx
, certChain
, arePeerCerts
, &trust
); 
 809         if (!ctx
->enableCertVerify
) { 
 810                 /* trivial case, this is caller's responsibility */ 
 811                 status 
= errSecSuccess
; 
 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
; 
 824         case kSecTrustResultDeny
: 
 825         case kSecTrustResultConfirm
: 
 826         case kSecTrustResultRecoverableTrustFailure
: 
 828             if(ctx
->allowAnyRoot
) { 
 829                 sslErrorLog("***Warning: accepting unverified cert chain\n"); 
 830                 status 
= errSecSuccess
; 
 834                                  * If the caller provided a list of trusted leaf certs, check them here 
 836                                 if(ctx
->trustedLeafCerts
) { 
 837                                         if (sslGetMatchingCertInArray((SecCertificateRef
)CFArrayGetValueAtIndex(certChain
, 0), 
 838                                                                 ctx
->trustedLeafCerts
)) { 
 839                                                 status 
= errSecSuccess
; 
 843                                 status 
= errSSLXCertChainInvalid
; 
 845             /* Do we really need to return things like: 
 847                    errSSLUnknownRootCert 
 849                    errSSLCertNotYetValid 
 850                    errSSLHostNameMismatch 
 851                for our client to see what went wrong, or should we just always 
 853                    errSSLXCertChainInvalid 
 854                when something is wrong? */ 
 860                 ctx
->peerSecTrust 
= trust
; 
 862         CFReleaseSafe(trust
); 
 868  * Given a SecCertificateRef cert, obtain its public key as a SSLPubKey. 
 869  * Caller must sslFreePubKey and free the SSLPubKey itself. 
 871 extern OSStatus 
sslCopyPeerPubKey( 
 876     check(ctx
->peerSecTrust
); 
 878 #if !TARGET_OS_IPHONE 
 879     /* This is not required on iOS, but still required on osx */ 
 880     if (!ctx
->enableCertVerify
) { 
 882         SecTrustResultType result
; 
 883         verify_noerr_action(status 
= SecTrustEvaluate(ctx
->peerSecTrust
, &result
), 
 888     SecKeyRef key 
= SecTrustCopyPublicKey(ctx
->peerSecTrust
); 
 890                 sslErrorLog("sslCopyPeerPubKey: %s, ctx->peerSecTrust=%p\n", 
 891                         "SecTrustCopyPublicKey failed", ctx
->peerSecTrust
); 
 892                 return errSSLBadCert
; 
 894     *pubKey 
= (SSLPubKey
*)key
; 
 896     return errSecSuccess
; 
 899 #endif /* !USE_SSLCERTIFICATE */ 
 902 void stPrintCdsaError(const char *op
, OSStatus crtn
) 
 909  * After ciphersuite negotiation is complete, verify that we have 
 910  * the capability of actually performing the selected cipher. 
 911  * Currently we just verify that we have a cert and private signing 
 912  * key, if needed, and that the signing key's algorithm matches the 
 913  * expected key exchange method. 
 915  * This is currently called from FindCipherSpec(), after it sets 
 916  * ctx->selectedCipherSpec to a (supposedly) valid value, and from 
 917  * sslBuildCipherSpecArray(), in server mode (pre-negotiation) only. 
 919 OSStatus 
sslVerifySelectedCipher(SSLContext 
*ctx
) 
 921     if(ctx
->protocolSide 
== kSSLClientSide
) { 
 922         return errSecSuccess
; 
 924 #if SSL_PAC_SERVER_ENABLE 
 925     if((ctx
->masterSecretCallback 
!= NULL
) && 
 926        (ctx
->sessionTicket
.data 
!= NULL
)) { 
 927             /* EAP via PAC resumption; we can do it */ 
 928         return errSecSuccess
; 
 930 #endif  /* SSL_PAC_SERVER_ENABLE */ 
 933     switch (ctx
->selectedCipherSpecParams
.keyExchangeMethod
) { 
 937         case SSL_DH_RSA_EXPORT
: 
 939         case SSL_DHE_RSA_EXPORT
: 
 940             requireAlg 
= kSecRSAAlgorithmID
; 
 943         case SSL_DHE_DSS_EXPORT
: 
 945         case SSL_DH_DSS_EXPORT
: 
 946             requireAlg 
= kSecDSAAlgorithmID
; 
 949         case SSL_DH_anon_EXPORT
: 
 951             requireAlg 
= kSecNullAlgorithmID
; /* no signing key */ 
 954          * When SSL_ECDSA_SERVER is true and we support ECDSA on the server side, 
 955          * we'll need to add some logic here... 
 958         case SSL_ECDHE_ECDSA
: 
 963             requireAlg 
= kSecECDSAAlgorithmID
; 
 968             /* needs update per cipherSpecs.c */ 
 970             sslErrorLog("sslVerifySelectedCipher: unknown key exchange method\n"); 
 971             return errSSLInternal
; 
 974     if(requireAlg 
== kSecNullAlgorithmID
) { 
 975         return errSecSuccess
; 
 978     /* private signing key required */ 
 979     if(ctx
->signingPrivKeyRef 
== NULL
) { 
 980         sslErrorLog("sslVerifySelectedCipher: no signing key\n"); 
 981         return errSSLBadConfiguration
; 
 984     /* Check the alg of our signing key. */ 
 985     CFIndex keyAlg 
= sslPrivKeyGetAlgorithmID(ctx
->signingPrivKeyRef
); 
 986     if (requireAlg 
!= keyAlg
) { 
 987         sslErrorLog("sslVerifySelectedCipher: signing key alg mismatch\n"); 
 988         return errSSLBadConfiguration
; 
 991     return errSecSuccess
; 
 996 /* FIXME: This is duplicated in SecDH */ 
1003 static const DERItemSpec DER_DHParamsItemSpecs
[] = 
1005         { DER_OFFSET(DER_DHParams
, p
), 
1007         DER_DEC_NO_OPTS 
| DER_ENC_SIGNED_INT 
}, 
1008         { DER_OFFSET(DER_DHParams
, g
), 
1010         DER_DEC_NO_OPTS 
| DER_ENC_SIGNED_INT 
}, 
1011         { DER_OFFSET(DER_DHParams
, l
), 
1013         DER_DEC_OPTIONAL 
| DER_ENC_SIGNED_INT 
}, 
1015 static const DERSize DER_NumDHParamsItemSpecs 
= 
1016 sizeof(DER_DHParamsItemSpecs
) / sizeof(DERItemSpec
); 
1018 /* Max encoded size for standard (PKCS3) parameters */ 
1019 #define DH_ENCODED_PARAM_SIZE(primeSizeInBytes)                                 \ 
1020 DER_MAX_ENCODED_SIZE(                                                                           \ 
1021 DER_MAX_ENCODED_SIZE(primeSizeInBytes) +                /* g */         \ 
1022 DER_MAX_ENCODED_SIZE(primeSizeInBytes) +                /* p */     \ 
1023 DER_MAX_ENCODED_SIZE(4))                        /* l */ 
1026 OSStatus 
sslDecodeDhParams( 
1027         const SSLBuffer 
*blob
,                  /* Input - PKCS-3 encoded */ 
1028         SSLBuffer               
*prime
,                 /* Output - wire format */ 
1029         SSLBuffer               
*generator
)     /* Output - wire format */ 
1031     OSStatus ortn 
= errSecSuccess
; 
1033         DERItem paramItem 
= {(DERByte 
*)blob
->data
, blob
->length
}; 
1034         DER_DHParams decodedParams
; 
1036     drtn 
= DERParseSequence(¶mItem
, 
1037                             DER_NumDHParamsItemSpecs
, DER_DHParamsItemSpecs
, 
1038                             &decodedParams
, sizeof(decodedParams
)); 
1042     prime
->data 
= decodedParams
.p
.data
; 
1043     prime
->length 
= decodedParams
.p
.length
; 
1045     generator
->data 
= decodedParams
.g
.data
; 
1046     generator
->length 
= decodedParams
.g
.length
; 
1052 OSStatus 
sslEncodeDhParams(SSLBuffer        
*blob
,                      /* data mallocd and RETURNED PKCS-3 encoded */ 
1053                            const SSLBuffer      
*prime
,                 /* Wire format */ 
1054                            const SSLBuffer      
*generator
)     /* Wire format */ 
1056     OSStatus ortn 
= errSecSuccess
; 
1057     DER_DHParams derParams 
= 
1060             .length 
= prime
->length
, 
1061             .data 
= prime
->data
, 
1064             .length 
= generator
->length
, 
1065             .data 
= generator
->data
, 
1073     DERSize ioLen 
= DH_ENCODED_PARAM_SIZE(derParams
.p
.length
); 
1074     DERByte 
*der 
= sslMalloc(ioLen
); 
1075     // FIXME: What if this fails - we should probably not have a malloc here ? 
1077     ortn 
= (OSStatus
)DEREncodeSequence(ASN1_CONSTR_SEQUENCE
, 
1079                                        DER_NumDHParamsItemSpecs
, DER_DHParamsItemSpecs
, 
1082     // This should never fail 
1090 OSStatus 
sslDhCreateKey(SSLContext 
*ctx
) 
1092     if (ctx
->secDHContext
) { 
1093         SecDHDestroy(ctx
->secDHContext
); 
1094         ctx
->secDHContext 
= NULL
; 
1097     /* Server params are set using encoded dh params */ 
1098     if (!(ctx
->dhParamsEncoded
.length 
&& ctx
->dhParamsEncoded
.data
)) 
1099         return errSSLInternal
; 
1101     if (SecDHCreateFromParameters(ctx
->dhParamsEncoded
.data
, 
1102         ctx
->dhParamsEncoded
.length
, &ctx
->secDHContext
)) 
1103             return errSSLCrypto
; 
1105     return errSecSuccess
; 
1108 OSStatus 
sslDhGenerateKeyPair(SSLContext 
*ctx
) 
1110     OSStatus ortn 
= errSecSuccess
; 
1112     require_noerr(ortn 
= SSLAllocBuffer(&ctx
->dhExchangePublic
,  
1113         SecDHGetMaxKeyLength(ctx
->secDHContext
)), out
); 
1114     require_noerr(ortn 
= SecDHGenerateKeypair(ctx
->secDHContext
,  
1115         ctx
->dhExchangePublic
.data
, &ctx
->dhExchangePublic
.length
), out
); 
1122 OSStatus 
sslDhKeyExchange(SSLContext 
*ctx
) 
1124     OSStatus ortn 
= errSecSuccess
; 
1127         ctx
->secDHContext 
== NULL 
|| 
1128         ctx
->dhPeerPublic
.length 
== 0) { 
1129                 /* comes from peer, don't panic */ 
1130                 sslErrorLog("sslDhKeyExchange: null peer public key\n"); 
1131                 return errSSLProtocol
; 
1134     require_noerr(ortn 
= SSLAllocBuffer(&ctx
->preMasterSecret
,  
1135         SecDHGetMaxKeyLength(ctx
->secDHContext
)), out
); 
1136     require_noerr(ortn 
= SecDHComputeKey(ctx
->secDHContext
,  
1137         ctx
->dhPeerPublic
.data
, ctx
->dhPeerPublic
.length
,  
1138         ctx
->preMasterSecret
.data
, &ctx
->preMasterSecret
.length
), out
); 
1142         sslErrorLog("sslDhKeyExchange: failed to compute key (error %d)\n", (int)ortn
); 
1146 #endif /* APPLE_DH */ 
1149  * Given an ECDSA key in SecKey format, extract the SSL_ECDSA_NamedCurve 
1150  * from its algorithm parameters. 
1152 OSStatus 
sslEcdsaPeerCurve( 
1154         SSL_ECDSA_NamedCurve 
*namedCurve
) 
1156     /* Cast is safe because enums are kept in sync. */ 
1157     *namedCurve 
= (SSL_ECDSA_NamedCurve
)SecECKeyGetNamedCurve(SECKEYREF(pubKey
)); 
1158     if (*namedCurve 
== kSecECCurveNone
) { 
1159         sslErrorLog("sslEcdsaPeerCurve: no named curve for public key\n"); 
1160         return errSSLProtocol
; 
1162     return errSecSuccess
; 
1166  * Generate ECDH key pair with the given SSL_ECDSA_NamedCurve. 
1167  * Private key, in ref form, is placed in ctx->ecdhPrivate. 
1168  * Public key, in ECPoint form - which can NOT be used as 
1169  * a key in any CSP ops - is placed in ecdhExchangePublic. 
1171 OSStatus 
sslEcdhGenerateKeyPair( 
1173         SSL_ECDSA_NamedCurve namedCurve
) 
1175         OSStatus ortn 
= errSecSuccess
; 
1178         switch (namedCurve
) { 
1179     case SSL_Curve_secp256r1
: 
1182     case SSL_Curve_secp384r1
: 
1185     case SSL_Curve_secp521r1
: 
1189         /* should not have gotten this far */ 
1190         sslErrorLog("sslEcdhGenerateKeyPair: bad namedCurve (%u)\n", 
1191             (unsigned)namedCurve
); 
1192         return errSSLInternal
; 
1195     ccec_generate_key(cp
, CCRNGSTATE
, ctx
->ecdhContext
); 
1196     size_t pub_size 
= ccec_export_pub_size(ctx
->ecdhContext
); 
1197     SSLFreeBuffer(&ctx
->ecdhExchangePublic
); 
1198     require_noerr(ortn 
= SSLAllocBuffer(&ctx
->ecdhExchangePublic
, 
1200     ccec_export_pub(ctx
->ecdhContext
, ctx
->ecdhExchangePublic
.data
); 
1202         sslDebugLog("sslEcdhGenerateKeyPair: pub key size=%ld, data=%p\n", 
1203                 pub_size
, ctx
->ecdhExchangePublic
.data
); 
1210  * Perform ECDH key exchange. Obtained key material is the same 
1211  * size as our private key. 
1213  * On entry, ecdhPrivate is our private key. The peer's public key 
1214  * is either ctx->ecdhPeerPublic for ECDHE exchange, or 
1215  * ctx->peerPubKey for ECDH exchange. 
1217 OSStatus 
sslEcdhKeyExchange( 
1219         SSLBuffer               
*exchanged
) 
1221         OSStatus ortn 
= errSecSuccess
; 
1222     CFDataRef pubKeyData 
= NULL
; 
1223     const unsigned char *pubKeyBits
; 
1224     unsigned long pubKeyLen
; 
1226         switch(ctx
->selectedCipherSpecParams
.keyExchangeMethod
) { 
1227                 case SSL_ECDHE_ECDSA
: 
1229                         /* public key passed in as CSSM_DATA *Param */ 
1230                         if(ctx
->ecdhPeerPublic
.length 
== 0) { 
1231                                 /* comes from peer, don't panic */ 
1232                                 sslErrorLog("sslEcdhKeyExchange: null peer public key\n"); 
1233                                 ortn 
= errSSLProtocol
; 
1236             pubKeyBits 
= ctx
->ecdhPeerPublic
.data
; 
1237             pubKeyLen 
= ctx
->ecdhPeerPublic
.length
; 
1239                 case SSL_ECDH_ECDSA
: 
1241                         /* Use the public key provided by the peer. */ 
1242                         if(ctx
->peerPubKey 
== NULL
) { 
1243                            sslErrorLog("sslEcdhKeyExchange: no peer key\n"); 
1244                            ortn 
= errSSLInternal
; 
1248             pubKeyData 
= SecECKeyCopyPublicBits(SECKEYREF(ctx
->peerPubKey
)); 
1250                                 sslErrorLog("sslEcdhKeyExchange: SecECKeyCopyPublicBits failed\n"); 
1251                                 ortn 
= errSSLProtocol
; 
1254             pubKeyBits 
= CFDataGetBytePtr(pubKeyData
); 
1255             pubKeyLen 
= CFDataGetLength(pubKeyData
); 
1258                         /* shouldn't be here */ 
1259                         sslErrorLog("sslEcdhKeyExchange: unknown keyExchangeMethod (%d)\n", 
1260                                 ctx
->selectedCipherSpecParams
.keyExchangeMethod
); 
1262                         ortn 
= errSSLInternal
; 
1266     ccec_const_cp_t cp 
= ccec_ctx_cp(ctx
->ecdhContext
); 
1267     ccec_pub_ctx_decl(ccn_sizeof(521), pubKey
); 
1268     ccec_import_pub(cp
, pubKeyLen
, pubKeyBits
, pubKey
); 
1269     size_t len 
= 1 + 2 * ccec_ccn_size(cp
); 
1270     require_noerr(ortn 
= SSLAllocBuffer(exchanged
, len
), errOut
); 
1271     require_noerr(ccec_compute_key(ctx
->ecdhContext
, pubKey
,  &exchanged
->length
, exchanged
->data
), errOut
); 
1273         sslDebugLog("sslEcdhKeyExchange: exchanged key length=%ld, data=%p\n", 
1274                 exchanged
->length
, exchanged
->data
); 
1277     CFReleaseSafe(pubKeyData
);