2  * Copyright (c) 1999-2001,2005-2008,2010-2014 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  * sslKeychain.c - Apple Keychain routines 
  29 #include "sslContext.h" 
  30 #include "sslMemory.h" 
  32 #include "sslCrypto.h" 
  33 #include <Security/SecBase.h> 
  34 #include <Security/SecCertificate.h> 
  35 #include <Security/SecCertificatePriv.h> 
  36 #include <Security/SecIdentity.h> 
  37 #include <Security/SecPolicy.h> 
  38 #include <Security/SecTrust.h> 
  39 #include "utilities/SecCFRelease.h" 
  42 #include "sslKeychain.h" 
  47 #include <Security/Security.h> 
  48 #include <Security/SecKeyPriv.h> 
  50 #include <Security/SecECKey.h> 
  52 #include <AssertMacros.h> 
  53 #include <tls_handshake.h> 
  56 #include <Security/oidsalg.h> 
  57 #include <Security/SecECKey.h> 
  60 /* Private Key operations */ 
  62 SecAsn1Oid 
oidForSSLHash(SSL_HashAlgorithm hash
) 
  65         case tls_hash_algorithm_SHA1
: 
  66             return CSSMOID_SHA1WithRSA
; 
  67         case tls_hash_algorithm_SHA256
: 
  68             return CSSMOID_SHA256WithRSA
; 
  69         case tls_hash_algorithm_SHA384
: 
  70             return CSSMOID_SHA384WithRSA
; 
  76     // This guarantee failure down the line 
  77     return CSSMOID_MD5WithRSA
; 
  81 int mySSLPrivKeyRSA_sign(void *key
, tls_hash_algorithm hash
, const uint8_t *plaintext
, size_t plaintextLen
, uint8_t *sig
, size_t *sigLen
) 
  83     SecKeyRef keyRef 
= key
; 
  85     if(hash 
== tls_hash_algorithm_None
) { 
  86         return SecKeyRawSign(keyRef
, kSecPaddingPKCS1
, plaintext
, plaintextLen
, sig
, sigLen
); 
  89         algId
.algorithm 
= oidForSSLHash(hash
); 
  90         return SecKeySignDigest(keyRef
, &algId
, plaintext
, plaintextLen
, sig
, sigLen
); 
  95 int mySSLPrivKeyRSA_decrypt(void *key
, const uint8_t *ciphertext
, size_t ciphertextLen
, uint8_t *plaintext
, size_t *plaintextLen
) 
  97     SecKeyRef keyRef 
= key
; 
  99     return SecKeyDecrypt(keyRef
, kSecPaddingPKCS1
, ciphertext
, ciphertextLen
, plaintext
, plaintextLen
); 
 103 int mySSLPrivKeyECDSA_sign(void *key
, const uint8_t *plaintext
, size_t plaintextLen
, uint8_t *sig
, size_t *sigLen
) 
 105     SecKeyRef keyRef 
= key
; 
 107     return SecKeyRawSign(keyRef
, kSecPaddingPKCS1
, plaintext
, plaintextLen
, sig
, sigLen
); 
 110 void sslFreePrivKey(tls_private_key_t 
*sslPrivKey
) 
 115         CFReleaseSafe(tls_private_key_get_context(*sslPrivKey
)); 
 116         tls_private_key_destroy(*sslPrivKey
); 
 125         SSLCertificate          
**destCertChain
, /* &ctx->{localCertChain,encryptCertChain} */ 
 126         tls_private_key_t   
*sslPrivKey
)         /* &ctx->signingPrivKeyRef, etc. */ 
 129         CFIndex                         ix
, numCerts
; 
 130         SecIdentityRef          identity
; 
 131         SSLCertificate      
*certChain 
= NULL
;  /* Retained */ 
 132         SecCertificateRef       leafCert 
= NULL
;        /* Retained */ 
 133         SecKeyRef           privKey 
= NULL
;     /* Retained */ 
 136         assert(destCertChain 
!= NULL
);          /* though its referent may be NULL */ 
 137         assert(sslPrivKey 
!= NULL
); 
 140                 sslErrorLog("parseIncomingCerts: NULL incoming cert array\n"); 
 141                 ortn 
= errSSLBadCert
; 
 144         numCerts 
= CFArrayGetCount(certs
); 
 146                 sslErrorLog("parseIncomingCerts: empty incoming cert array\n"); 
 147                 ortn 
= errSSLBadCert
; 
 151     certChain
=sslMalloc(numCerts
*sizeof(SSLCertificate
)); 
 153         ortn 
= errSecAllocate
; 
 158          * Certs[0] is an SecIdentityRef from which we extract subject cert, 
 161          * 1. ensure the first element is a SecIdentityRef. 
 163         identity 
= (SecIdentityRef
)CFArrayGetValueAtIndex(certs
, 0); 
 164         if (identity 
== NULL
) { 
 165                 sslErrorLog("parseIncomingCerts: bad cert array (1)\n"); 
 169         if (CFGetTypeID(identity
) != SecIdentityGetTypeID()) { 
 170                 sslErrorLog("parseIncomingCerts: bad cert array (2)\n"); 
 176          * 2. Extract cert, keys and convert to local format. 
 178         ortn 
= SecIdentityCopyCertificate(identity
, &leafCert
); 
 180                 sslErrorLog("parseIncomingCerts: bad cert array (3)\n"); 
 184         /* Fetch private key from identity */ 
 185         ortn 
= SecIdentityCopyPrivateKey(identity
, &privKey
); 
 187                 sslErrorLog("parseIncomingCerts: SecIdentityCopyPrivateKey err %d\n", 
 192     /* Convert the input array of SecIdentityRef at the start to an array of 
 194     SSLCopyBufferFromData(SecCertificateGetBytePtr(leafCert
), SecCertificateGetLength(leafCert
), &certChain
[0].derCert
); 
 195     certChain
[0].next 
= NULL
; 
 197         for (ix 
= 1; ix 
< numCerts
; ++ix
) { 
 198                 SecCertificateRef intermediate 
= 
 199                         (SecCertificateRef
)CFArrayGetValueAtIndex(certs
, ix
); 
 200                 if (intermediate 
== NULL
) { 
 201                         sslErrorLog("parseIncomingCerts: bad cert array (5)\n"); 
 205                 if (CFGetTypeID(intermediate
) != SecCertificateGetTypeID()) { 
 206                         sslErrorLog("parseIncomingCerts: bad cert array (6)\n"); 
 211         SSLCopyBufferFromData(SecCertificateGetBytePtr(intermediate
), SecCertificateGetLength(intermediate
), &certChain
[ix
].derCert
); 
 212         certChain
[ix
].next 
= NULL
; 
 213         certChain
[ix
-1].next 
= &certChain
[ix
]; 
 217     sslFreePrivKey(sslPrivKey
); 
 218     size_t size 
= SecKeyGetBlockSize(privKey
); 
 219     if(SecKeyGetAlgorithmId(privKey
) == kSecRSAAlgorithmID
) { 
 220         *sslPrivKey 
= tls_private_key_rsa_create(privKey
, SecKeyGetBlockSize(privKey
), mySSLPrivKeyRSA_sign
, mySSLPrivKeyRSA_decrypt
); 
 221     } else if (SecKeyGetAlgorithmId(privKey
) == kSecECDSAAlgorithmID
) { 
 223         /* Compute signature size from key size */ 
 224         size_t sigSize 
= 8+2*size
; 
 226         size_t sigSize 
= size
; 
 228         *sslPrivKey 
= tls_private_key_ecdsa_create(privKey
, sigSize
, SecECKeyGetNamedCurve(privKey
), mySSLPrivKeyECDSA_sign
); 
 234         ortn 
= errSecSuccess
; 
 236         ortn 
= errSecAllocate
; 
 240         CFReleaseSafe(leafCert
); 
 242     sslFree(*destCertChain
); 
 246                 CFReleaseSafe(privKey
); 
 247                 *destCertChain 
= NULL
; 
 249                 *destCertChain 
= certChain
;