]> git.saurik.com Git - apple/security.git/blob - Security/libsecurity_ssl/lib/sslKeychain.c
Security-57031.40.6.tar.gz
[apple/security.git] / Security / libsecurity_ssl / lib / sslKeychain.c
1 /*
2 * Copyright (c) 1999-2001,2005-2008,2010-2014 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 * sslKeychain.c - Apple Keychain routines
26 */
27
28 #include "ssl.h"
29 #include "sslContext.h"
30 #include "sslMemory.h"
31
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"
40
41 #include "sslDebug.h"
42 #include "sslKeychain.h"
43 #include "sslUtils.h"
44 #include <string.h>
45 #include <assert.h>
46
47
48 #include <Security/Security.h>
49 #include <Security/SecKeyPriv.h>
50 #include <AssertMacros.h>
51 #include <tls_handshake.h>
52
53 #if TARGET_OS_IPHONE
54 #include <Security/oidsalg.h>
55 #endif
56
57 /* Private Key operations */
58 static
59 SecAsn1Oid oidForSSLHash(SSL_HashAlgorithm hash)
60 {
61 switch (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;
68 default:
69 break;
70 }
71 // Internal error
72 assert(0);
73 // This guarantee failure down the line
74 return CSSMOID_MD5WithRSA;
75 }
76
77 static
78 int mySSLPrivKeyRSA_sign(void *key, tls_hash_algorithm hash, const uint8_t *plaintext, size_t plaintextLen, uint8_t *sig, size_t *sigLen)
79 {
80 SecKeyRef keyRef = key;
81
82 if(hash == tls_hash_algorithm_None) {
83 return SecKeyRawSign(keyRef, kSecPaddingPKCS1, plaintext, plaintextLen, sig, sigLen);
84 } else {
85 SecAsn1AlgId algId;
86 algId.algorithm = oidForSSLHash(hash);
87 return SecKeySignDigest(keyRef, &algId, plaintext, plaintextLen, sig, sigLen);
88 }
89 }
90
91 static
92 int mySSLPrivKeyRSA_decrypt(void *key, const uint8_t *ciphertext, size_t ciphertextLen, uint8_t *plaintext, size_t *plaintextLen)
93 {
94 SecKeyRef keyRef = key;
95
96 return SecKeyDecrypt(keyRef, kSecPaddingPKCS1, ciphertext, ciphertextLen, plaintext, plaintextLen);
97 }
98
99 void sslFreePrivKey(tls_private_key_t *sslPrivKey)
100 {
101 assert(sslPrivKey);
102
103 if(*sslPrivKey) {
104 CFReleaseSafe(tls_private_key_get_context(*sslPrivKey));
105 tls_private_key_destroy(*sslPrivKey);
106 *sslPrivKey = NULL;
107 }
108 }
109
110 OSStatus
111 parseIncomingCerts(
112 SSLContext *ctx,
113 CFArrayRef certs,
114 SSLCertificate **destCertChain, /* &ctx->{localCertChain,encryptCertChain} */
115 tls_private_key_t *sslPrivKey) /* &ctx->signingPrivKeyRef, etc. */
116 {
117 OSStatus ortn;
118 CFIndex ix, numCerts;
119 SecIdentityRef identity;
120 SSLCertificate *certChain = NULL; /* Retained */
121 SecCertificateRef leafCert = NULL; /* Retained */
122 SecKeyRef privKey = NULL; /* Retained */
123
124 assert(ctx != NULL);
125 assert(destCertChain != NULL); /* though its referent may be NULL */
126 assert(sslPrivKey != NULL);
127
128 if (certs == NULL) {
129 sslErrorLog("parseIncomingCerts: NULL incoming cert array\n");
130 ortn = errSSLBadCert;
131 goto errOut;
132 }
133 numCerts = CFArrayGetCount(certs);
134 if (numCerts == 0) {
135 sslErrorLog("parseIncomingCerts: empty incoming cert array\n");
136 ortn = errSSLBadCert;
137 goto errOut;
138 }
139
140 certChain=sslMalloc(numCerts*sizeof(SSLCertificate));
141 if (!certChain) {
142 ortn = errSecAllocate;
143 goto errOut;
144 }
145
146 /*
147 * Certs[0] is an SecIdentityRef from which we extract subject cert,
148 * privKey, pubKey.
149 *
150 * 1. ensure the first element is a SecIdentityRef.
151 */
152 identity = (SecIdentityRef)CFArrayGetValueAtIndex(certs, 0);
153 if (identity == NULL) {
154 sslErrorLog("parseIncomingCerts: bad cert array (1)\n");
155 ortn = errSecParam;
156 goto errOut;
157 }
158 if (CFGetTypeID(identity) != SecIdentityGetTypeID()) {
159 sslErrorLog("parseIncomingCerts: bad cert array (2)\n");
160 ortn = errSecParam;
161 goto errOut;
162 }
163
164 /*
165 * 2. Extract cert, keys and convert to local format.
166 */
167 ortn = SecIdentityCopyCertificate(identity, &leafCert);
168 if (ortn) {
169 sslErrorLog("parseIncomingCerts: bad cert array (3)\n");
170 goto errOut;
171 }
172
173 /* Fetch private key from identity */
174 ortn = SecIdentityCopyPrivateKey(identity, &privKey);
175 if (ortn) {
176 sslErrorLog("parseIncomingCerts: SecIdentityCopyPrivateKey err %d\n",
177 (int)ortn);
178 goto errOut;
179 }
180
181 /* Convert the input array of SecIdentityRef at the start to an array of
182 all certificates. */
183
184 certChain[0].derCert.data = (uint8_t *)SecCertificateGetBytePtr(leafCert);
185 certChain[0].derCert.length = SecCertificateGetLength(leafCert);
186 certChain[0].next = NULL;
187
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");
193 ortn = errSecParam;
194 goto errOut;
195 }
196 if (CFGetTypeID(intermediate) != SecCertificateGetTypeID()) {
197 sslErrorLog("parseIncomingCerts: bad cert array (6)\n");
198 ortn = errSecParam;
199 goto errOut;
200 }
201
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];
206
207 }
208
209 if(sslPrivKeyGetAlgorithmID(privKey)!=kSecRSAAlgorithmID) {
210 ortn = errSecParam;
211 goto errOut;
212 }
213
214 sslFreePrivKey(sslPrivKey);
215 *sslPrivKey = tls_private_key_rsa_create(privKey, SecKeyGetBlockSize(privKey), mySSLPrivKeyRSA_sign, mySSLPrivKeyRSA_decrypt);
216 if(*sslPrivKey)
217 ortn = errSecSuccess;
218 else
219 ortn = errSecAllocate;
220
221 /* SUCCESS */
222 errOut:
223 CFReleaseSafe(leafCert);
224
225 sslFree(*destCertChain);
226
227 if (ortn) {
228 free(certChain);
229 CFReleaseSafe(privKey);
230 *destCertChain = NULL;
231 } else {
232 *destCertChain = certChain;
233 }
234
235 return ortn;
236 }