]> git.saurik.com Git - apple/security.git/blob - libsecurity_ssl/lib/sslCrypto.c
Security-55471.14.tar.gz
[apple/security.git] / libsecurity_ssl / lib / sslCrypto.c
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 */
84 extern 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 */
95 extern 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 */
106 CFIndex 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 */
118 CFIndex 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 */
130 OSStatus 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 */
193 OSStatus 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
228 OSStatus 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 */
260 OSStatus 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 */
282 OSStatus 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
349 OSStatus 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 */
394 size_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 */
410 size_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 */
425 OSStatus 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
445 static 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 */
485 OSStatus 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 */
511 OSStatus 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 *)&params,
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 */
571 OSStatus 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
691 OSStatus
692 sslCreateSecTrust(
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
739 errOut:
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 */
751 static
752 SecCertificateRef
753 sslGetMatchingCertInArray(
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 */
792 extern 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
858 errOut:
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 */
871 extern OSStatus sslCopyPeerPubKey(
872 SSLContext *ctx,
873 SSLPubKey **pubKey)
874 {
875 check(pubKey);
876 check(ctx->peerSecTrust);
877
878 #if !TARGET_OS_IPHONE
879 /* This is not required on iOS, but still required on osx */
880 if (!ctx->enableCertVerify) {
881 OSStatus status;
882 SecTrustResultType result;
883 verify_noerr_action(status = SecTrustEvaluate(ctx->peerSecTrust, &result),
884 return status);
885 }
886 #endif
887
888 SecKeyRef key = SecTrustCopyPublicKey(ctx->peerSecTrust);
889 if (!key) {
890 sslErrorLog("sslCopyPeerPubKey: %s, ctx->peerSecTrust=%p\n",
891 "SecTrustCopyPublicKey failed", ctx->peerSecTrust);
892 return errSSLBadCert;
893 }
894 *pubKey = (SSLPubKey*)key;
895
896 return errSecSuccess;
897 }
898
899 #endif /* !USE_SSLCERTIFICATE */
900
901 #ifndef NDEBUG
902 void stPrintCdsaError(const char *op, OSStatus crtn)
903 {
904 assert(FALSE);
905 }
906 #endif
907
908 /*
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.
914 *
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.
918 */
919 OSStatus sslVerifySelectedCipher(SSLContext *ctx)
920 {
921 if(ctx->protocolSide == kSSLClientSide) {
922 return errSecSuccess;
923 }
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;
929 }
930 #endif /* SSL_PAC_SERVER_ENABLE */
931
932 CFIndex requireAlg;
933 switch (ctx->selectedCipherSpecParams.keyExchangeMethod) {
934 case SSL_RSA:
935 case SSL_RSA_EXPORT:
936 case SSL_DH_RSA:
937 case SSL_DH_RSA_EXPORT:
938 case SSL_DHE_RSA:
939 case SSL_DHE_RSA_EXPORT:
940 requireAlg = kSecRSAAlgorithmID;
941 break;
942 case SSL_DHE_DSS:
943 case SSL_DHE_DSS_EXPORT:
944 case SSL_DH_DSS:
945 case SSL_DH_DSS_EXPORT:
946 requireAlg = kSecDSAAlgorithmID;
947 break;
948 case SSL_DH_anon:
949 case SSL_DH_anon_EXPORT:
950 case TLS_PSK:
951 requireAlg = kSecNullAlgorithmID; /* no signing key */
952 break;
953 /*
954 * When SSL_ECDSA_SERVER is true and we support ECDSA on the server side,
955 * we'll need to add some logic here...
956 */
957 #if SSL_ECDSA_SERVER
958 case SSL_ECDHE_ECDSA:
959 case SSL_ECDHE_RSA:
960 case SSL_ECDH_ECDSA:
961 case SSL_ECDH_RSA:
962 case SSL_ECDH_anon:
963 requireAlg = kSecECDSAAlgorithmID;
964 break;
965 #endif
966
967 default:
968 /* needs update per cipherSpecs.c */
969 assert(0);
970 sslErrorLog("sslVerifySelectedCipher: unknown key exchange method\n");
971 return errSSLInternal;
972 }
973
974 if(requireAlg == kSecNullAlgorithmID) {
975 return errSecSuccess;
976 }
977
978 /* private signing key required */
979 if(ctx->signingPrivKeyRef == NULL) {
980 sslErrorLog("sslVerifySelectedCipher: no signing key\n");
981 return errSSLBadConfiguration;
982 }
983
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;
989 }
990
991 return errSecSuccess;
992 }
993
994 #if APPLE_DH
995
996 /* FIXME: This is duplicated in SecDH */
997 typedef struct {
998 DERItem p;
999 DERItem g;
1000 DERItem l;
1001 } DER_DHParams;
1002
1003 static const DERItemSpec DER_DHParamsItemSpecs[] =
1004 {
1005 { DER_OFFSET(DER_DHParams, p),
1006 ASN1_INTEGER,
1007 DER_DEC_NO_OPTS | DER_ENC_SIGNED_INT },
1008 { DER_OFFSET(DER_DHParams, g),
1009 ASN1_INTEGER,
1010 DER_DEC_NO_OPTS | DER_ENC_SIGNED_INT },
1011 { DER_OFFSET(DER_DHParams, l),
1012 ASN1_INTEGER,
1013 DER_DEC_OPTIONAL | DER_ENC_SIGNED_INT },
1014 };
1015 static const DERSize DER_NumDHParamsItemSpecs =
1016 sizeof(DER_DHParamsItemSpecs) / sizeof(DERItemSpec);
1017
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 */
1024
1025
1026 OSStatus sslDecodeDhParams(
1027 const SSLBuffer *blob, /* Input - PKCS-3 encoded */
1028 SSLBuffer *prime, /* Output - wire format */
1029 SSLBuffer *generator) /* Output - wire format */
1030 {
1031 OSStatus ortn = errSecSuccess;
1032 DERReturn drtn;
1033 DERItem paramItem = {(DERByte *)blob->data, blob->length};
1034 DER_DHParams decodedParams;
1035
1036 drtn = DERParseSequence(&paramItem,
1037 DER_NumDHParamsItemSpecs, DER_DHParamsItemSpecs,
1038 &decodedParams, sizeof(decodedParams));
1039 if(drtn)
1040 return drtn;
1041
1042 prime->data = decodedParams.p.data;
1043 prime->length = decodedParams.p.length;
1044
1045 generator->data = decodedParams.g.data;
1046 generator->length = decodedParams.g.length;
1047
1048 return ortn;
1049 }
1050
1051
1052 OSStatus sslEncodeDhParams(SSLBuffer *blob, /* data mallocd and RETURNED PKCS-3 encoded */
1053 const SSLBuffer *prime, /* Wire format */
1054 const SSLBuffer *generator) /* Wire format */
1055 {
1056 OSStatus ortn = errSecSuccess;
1057 DER_DHParams derParams =
1058 {
1059 .p = {
1060 .length = prime->length,
1061 .data = prime->data,
1062 },
1063 .g = {
1064 .length = generator->length,
1065 .data = generator->data,
1066 },
1067 .l = {
1068 .length = 0,
1069 .data = NULL,
1070 }
1071 };
1072
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 ?
1076 assert(der);
1077 ortn = (OSStatus)DEREncodeSequence(ASN1_CONSTR_SEQUENCE,
1078 &derParams,
1079 DER_NumDHParamsItemSpecs, DER_DHParamsItemSpecs,
1080 der,
1081 &ioLen);
1082 // This should never fail
1083
1084 blob->length=ioLen;
1085 blob->data=der;
1086
1087 return ortn;
1088 }
1089
1090 OSStatus sslDhCreateKey(SSLContext *ctx)
1091 {
1092 if (ctx->secDHContext) {
1093 SecDHDestroy(ctx->secDHContext);
1094 ctx->secDHContext = NULL;
1095 }
1096
1097 /* Server params are set using encoded dh params */
1098 if (!(ctx->dhParamsEncoded.length && ctx->dhParamsEncoded.data))
1099 return errSSLInternal;
1100
1101 if (SecDHCreateFromParameters(ctx->dhParamsEncoded.data,
1102 ctx->dhParamsEncoded.length, &ctx->secDHContext))
1103 return errSSLCrypto;
1104
1105 return errSecSuccess;
1106 }
1107
1108 OSStatus sslDhGenerateKeyPair(SSLContext *ctx)
1109 {
1110 OSStatus ortn = errSecSuccess;
1111
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);
1116
1117 out:
1118 return ortn;
1119 }
1120
1121
1122 OSStatus sslDhKeyExchange(SSLContext *ctx)
1123 {
1124 OSStatus ortn = errSecSuccess;
1125
1126 if (ctx == NULL ||
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;
1132 }
1133
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);
1139
1140 return ortn;
1141 out:
1142 sslErrorLog("sslDhKeyExchange: failed to compute key (error %d)\n", (int)ortn);
1143 return ortn;
1144 }
1145
1146 #endif /* APPLE_DH */
1147
1148 /*
1149 * Given an ECDSA key in SecKey format, extract the SSL_ECDSA_NamedCurve
1150 * from its algorithm parameters.
1151 */
1152 OSStatus sslEcdsaPeerCurve(
1153 SSLPubKey *pubKey,
1154 SSL_ECDSA_NamedCurve *namedCurve)
1155 {
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;
1161 }
1162 return errSecSuccess;
1163 }
1164
1165 /*
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.
1170 */
1171 OSStatus sslEcdhGenerateKeyPair(
1172 SSLContext *ctx,
1173 SSL_ECDSA_NamedCurve namedCurve)
1174 {
1175 OSStatus ortn = errSecSuccess;
1176
1177 ccec_const_cp_t cp;
1178 switch (namedCurve) {
1179 case SSL_Curve_secp256r1:
1180 cp = ccec_cp_256();
1181 break;
1182 case SSL_Curve_secp384r1:
1183 cp = ccec_cp_384();
1184 break;
1185 case SSL_Curve_secp521r1:
1186 cp = ccec_cp_521();
1187 break;
1188 default:
1189 /* should not have gotten this far */
1190 sslErrorLog("sslEcdhGenerateKeyPair: bad namedCurve (%u)\n",
1191 (unsigned)namedCurve);
1192 return errSSLInternal;
1193 }
1194
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,
1199 pub_size), errOut);
1200 ccec_export_pub(ctx->ecdhContext, ctx->ecdhExchangePublic.data);
1201
1202 sslDebugLog("sslEcdhGenerateKeyPair: pub key size=%ld, data=%p\n",
1203 pub_size, ctx->ecdhExchangePublic.data);
1204
1205 errOut:
1206 return ortn;
1207 }
1208
1209 /*
1210 * Perform ECDH key exchange. Obtained key material is the same
1211 * size as our private key.
1212 *
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.
1216 */
1217 OSStatus sslEcdhKeyExchange(
1218 SSLContext *ctx,
1219 SSLBuffer *exchanged)
1220 {
1221 OSStatus ortn = errSecSuccess;
1222 CFDataRef pubKeyData = NULL;
1223 const unsigned char *pubKeyBits;
1224 unsigned long pubKeyLen;
1225
1226 switch(ctx->selectedCipherSpecParams.keyExchangeMethod) {
1227 case SSL_ECDHE_ECDSA:
1228 case SSL_ECDHE_RSA:
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;
1234 goto errOut;
1235 }
1236 pubKeyBits = ctx->ecdhPeerPublic.data;
1237 pubKeyLen = ctx->ecdhPeerPublic.length;
1238 break;
1239 case SSL_ECDH_ECDSA:
1240 case SSL_ECDH_RSA:
1241 /* Use the public key provided by the peer. */
1242 if(ctx->peerPubKey == NULL) {
1243 sslErrorLog("sslEcdhKeyExchange: no peer key\n");
1244 ortn = errSSLInternal;
1245 goto errOut;
1246 }
1247
1248 pubKeyData = SecECKeyCopyPublicBits(SECKEYREF(ctx->peerPubKey));
1249 if (!pubKeyData) {
1250 sslErrorLog("sslEcdhKeyExchange: SecECKeyCopyPublicBits failed\n");
1251 ortn = errSSLProtocol;
1252 goto errOut;
1253 }
1254 pubKeyBits = CFDataGetBytePtr(pubKeyData);
1255 pubKeyLen = CFDataGetLength(pubKeyData);
1256 break;
1257 default:
1258 /* shouldn't be here */
1259 sslErrorLog("sslEcdhKeyExchange: unknown keyExchangeMethod (%d)\n",
1260 ctx->selectedCipherSpecParams.keyExchangeMethod);
1261 assert(0);
1262 ortn = errSSLInternal;
1263 goto errOut;
1264 }
1265
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);
1272
1273 sslDebugLog("sslEcdhKeyExchange: exchanged key length=%ld, data=%p\n",
1274 exchanged->length, exchanged->data);
1275
1276 errOut:
1277 CFReleaseSafe(pubKeyData);
1278 return ortn;
1279 }