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" 
  48 #include <Security/Security.h> 
  49 #include <Security/SecKeyPriv.h> 
  50 #include <AssertMacros.h> 
  51 #include <tls_handshake.h> 
  54 #include <Security/oidsalg.h> 
  57 /* Private Key operations */ 
  59 SecAsn1Oid 
oidForSSLHash(SSL_HashAlgorithm hash
) 
  62         case tls_hash_algorithm_SHA1
: 
  63             return CSSMOID_SHA1WithRSA
; 
  64         case tls_hash_algorithm_SHA256
: 
  65             return CSSMOID_SHA256WithRSA
; 
  66         case tls_hash_algorithm_SHA384
: 
  67             return CSSMOID_SHA384WithRSA
; 
  73     // This guarantee failure down the line 
  74     return CSSMOID_MD5WithRSA
; 
  78 int mySSLPrivKeyRSA_sign(void *key
, tls_hash_algorithm hash
, const uint8_t *plaintext
, size_t plaintextLen
, uint8_t *sig
, size_t *sigLen
) 
  80     SecKeyRef keyRef 
= key
; 
  82     if(hash 
== tls_hash_algorithm_None
) { 
  83         return SecKeyRawSign(keyRef
, kSecPaddingPKCS1
, plaintext
, plaintextLen
, sig
, sigLen
); 
  86         algId
.algorithm 
= oidForSSLHash(hash
); 
  87         return SecKeySignDigest(keyRef
, &algId
, plaintext
, plaintextLen
, sig
, sigLen
); 
  92 int mySSLPrivKeyRSA_decrypt(void *key
, const uint8_t *ciphertext
, size_t ciphertextLen
, uint8_t *plaintext
, size_t *plaintextLen
) 
  94     SecKeyRef keyRef 
= key
; 
  96     return SecKeyDecrypt(keyRef
, kSecPaddingPKCS1
, ciphertext
, ciphertextLen
, plaintext
, plaintextLen
); 
  99 void sslFreePrivKey(tls_private_key_t 
*sslPrivKey
) 
 104         CFReleaseSafe(tls_private_key_get_context(*sslPrivKey
)); 
 105         tls_private_key_destroy(*sslPrivKey
); 
 114         SSLCertificate          
**destCertChain
, /* &ctx->{localCertChain,encryptCertChain} */ 
 115         tls_private_key_t   
*sslPrivKey
)         /* &ctx->signingPrivKeyRef, etc. */ 
 118         CFIndex                         ix
, numCerts
; 
 119         SecIdentityRef          identity
; 
 120         SSLCertificate      
*certChain 
= NULL
;  /* Retained */ 
 121         SecCertificateRef       leafCert 
= NULL
;        /* Retained */ 
 122         SecKeyRef           privKey 
= NULL
;     /* Retained */ 
 125         assert(destCertChain 
!= NULL
);          /* though its referent may be NULL */ 
 126         assert(sslPrivKey 
!= NULL
); 
 129                 sslErrorLog("parseIncomingCerts: NULL incoming cert array\n"); 
 130                 ortn 
= errSSLBadCert
; 
 133         numCerts 
= CFArrayGetCount(certs
); 
 135                 sslErrorLog("parseIncomingCerts: empty incoming cert array\n"); 
 136                 ortn 
= errSSLBadCert
; 
 140     certChain
=sslMalloc(numCerts
*sizeof(SSLCertificate
)); 
 142         ortn 
= errSecAllocate
; 
 147          * Certs[0] is an SecIdentityRef from which we extract subject cert, 
 150          * 1. ensure the first element is a SecIdentityRef. 
 152         identity 
= (SecIdentityRef
)CFArrayGetValueAtIndex(certs
, 0); 
 153         if (identity 
== NULL
) { 
 154                 sslErrorLog("parseIncomingCerts: bad cert array (1)\n"); 
 158         if (CFGetTypeID(identity
) != SecIdentityGetTypeID()) { 
 159                 sslErrorLog("parseIncomingCerts: bad cert array (2)\n"); 
 165          * 2. Extract cert, keys and convert to local format. 
 167         ortn 
= SecIdentityCopyCertificate(identity
, &leafCert
); 
 169                 sslErrorLog("parseIncomingCerts: bad cert array (3)\n"); 
 173         /* Fetch private key from identity */ 
 174         ortn 
= SecIdentityCopyPrivateKey(identity
, &privKey
); 
 176                 sslErrorLog("parseIncomingCerts: SecIdentityCopyPrivateKey err %d\n", 
 181     /* Convert the input array of SecIdentityRef at the start to an array of 
 184     certChain
[0].derCert
.data 
= (uint8_t *)SecCertificateGetBytePtr(leafCert
); 
 185     certChain
[0].derCert
.length 
= SecCertificateGetLength(leafCert
); 
 186     certChain
[0].next 
= NULL
; 
 188         for (ix 
= 1; ix 
< numCerts
; ++ix
) { 
 189                 SecCertificateRef intermediate 
= 
 190                         (SecCertificateRef
)CFArrayGetValueAtIndex(certs
, ix
); 
 191                 if (intermediate 
== NULL
) { 
 192                         sslErrorLog("parseIncomingCerts: bad cert array (5)\n"); 
 196                 if (CFGetTypeID(intermediate
) != SecCertificateGetTypeID()) { 
 197                         sslErrorLog("parseIncomingCerts: bad cert array (6)\n"); 
 202         certChain
[ix
].derCert
.data 
= (uint8_t *)SecCertificateGetBytePtr(intermediate
); 
 203         certChain
[ix
].derCert
.length 
= SecCertificateGetLength(intermediate
); 
 204         certChain
[ix
].next 
= NULL
; 
 205         certChain
[ix
-1].next 
= &certChain
[ix
]; 
 209     if(sslPrivKeyGetAlgorithmID(privKey
)!=kSecRSAAlgorithmID
) { 
 214     sslFreePrivKey(sslPrivKey
); 
 215     *sslPrivKey 
= tls_private_key_rsa_create(privKey
, SecKeyGetBlockSize(privKey
), mySSLPrivKeyRSA_sign
, mySSLPrivKeyRSA_decrypt
); 
 217         ortn 
= errSecSuccess
; 
 219         ortn 
= errSecAllocate
; 
 223         CFReleaseSafe(leafCert
); 
 225     sslFree(*destCertChain
); 
 229                 CFReleaseSafe(privKey
); 
 230                 *destCertChain 
= NULL
; 
 232                 *destCertChain 
= certChain
;