]> git.saurik.com Git - apple/security.git/blob - libsecurity_ssl/lib/sslCrypto.c
Security-55179.1.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 <Security/SecKeyInternal.h>
42 #include <corecrypto/ccdh.h>
43 #include <corecrypto/ccec.h>
44 #include <corecrypto/ccrng.h>
45 #include <Security/SecCertificate.h>
46 #include <Security/SecPolicy.h>
47 #include <Security/SecRSAKey.h>
48 #include <Security/SecTrust.h>
49 #include <AssertMacros.h>
50 #include <Security/SecInternal.h>
51
52 #ifndef _SSL_KEYCHAIN_H_
53 #include "sslKeychain.h"
54 #endif
55
56 #if APPLE_DH
57 #include <libDER/libDER.h>
58 #include <libDER/DER_Keys.h>
59 #include <libDER/DER_Encode.h>
60 #include <libDER/asn1Types.h>
61 #include <Security/SecRandom.h>
62 #endif
63 #include <Security/SecECKey.h>
64
65 #include <string.h>
66 #include <stdlib.h>
67 #include <assert.h>
68
69 #if TARGET_OS_IOS
70 #define CCRNGSTATE ccrng_seckey
71 #else
72 /* extern struct ccrng_state *ccDRBGGetRngState(); */
73 #include <CommonCrypto/CommonRandomSPI.h>
74 #define CCRNGSTATE ccDRBGGetRngState()
75 #endif
76
77
78 /*
79 * Free a pubKey object.
80 */
81 extern OSStatus sslFreePubKey(SSLPubKey **pubKey)
82 {
83 if (pubKey && *pubKey) {
84 CFReleaseNull(SECKEYREF(*pubKey));
85 }
86 return noErr;
87 }
88
89 /*
90 * Free a privKey object.
91 */
92 extern OSStatus sslFreePrivKey(SSLPrivKey **privKey)
93 {
94 if (privKey && *privKey) {
95 CFReleaseNull(SECKEYREF(*privKey));
96 }
97 return noErr;
98 }
99
100 /*
101 * Get algorithm id for a SSLPubKey object.
102 */
103 CFIndex sslPubKeyGetAlgorithmID(SSLPubKey *pubKey)
104 {
105 #if TARGET_OS_IOS
106 return SecKeyGetAlgorithmID(SECKEYREF(pubKey));
107 #else
108 return SecKeyGetAlgorithmId(SECKEYREF(pubKey));
109 #endif
110 }
111
112 /*
113 * Get algorithm id for a SSLPrivKey object.
114 */
115 CFIndex sslPrivKeyGetAlgorithmID(SSLPrivKey *privKey)
116 {
117 #if TARGET_OS_IOS
118 return SecKeyGetAlgorithmID(SECKEYREF(privKey));
119 #else
120 return SecKeyGetAlgorithmId(SECKEYREF(privKey));
121 #endif
122 }
123
124 /*
125 * Raw RSA/DSA sign/verify.
126 */
127 OSStatus sslRawSign(
128 SSLContext *ctx,
129 SSLPrivKey *privKey,
130 const uint8_t *plainText,
131 size_t plainTextLen,
132 uint8_t *sig, // mallocd by caller; RETURNED
133 size_t sigLen, // available
134 size_t *actualBytes) // RETURNED
135 {
136 #if 0
137 RSAStatus rsaStatus;
138 #if RSA_SIG_SHARE_GIANT
139 RSASignBuffer *signBuffer = (RSASignBuffer *)sig;
140 assert(sigLen >= sizeof(RSASignBuffer));
141 #endif
142 assert(actualBytes != NULL);
143
144 /* @@@ Shouldn't need to init giSigLen according to libgRSA docs. */
145 gi_uint16 giSigLen = sigLen;
146
147 rsaStatus = RSA_Sign(&privKey->rsaKey,
148 RP_PKCS1,
149 plainText,
150 plainTextLen,
151 #if RSA_SIG_SHARE_GIANT
152 signBuffer,
153 #else
154 sig,
155 #endif
156 &giSigLen);
157 *actualBytes = giSigLen;
158
159 return rsaStatus ? rsaStatusToSSL(rsaStatus) : noErr;
160 #else
161
162 size_t inOutSigLen = sigLen;
163
164 assert(actualBytes != NULL);
165
166 OSStatus status = SecKeyRawSign(SECKEYREF(privKey), kSecPaddingPKCS1,
167 plainText, plainTextLen, sig, &inOutSigLen);
168
169 if (status) {
170 sslErrorLog("sslRawSign: SecKeyRawSign failed (error %d)\n", status);
171 }
172
173 /* Since the KeyExchange already allocated modulus size bytes we'll
174 use all of them. SecureTransport has always sent that many bytes,
175 so we're not going to deviate, to avoid interoperability issues. */
176 if (!status && (inOutSigLen < sigLen)) {
177 size_t offset = sigLen - inOutSigLen;
178 memmove(sig + offset, sig, inOutSigLen);
179 memset(sig, 0, offset);
180 inOutSigLen = sigLen;
181 }
182
183
184 *actualBytes = inOutSigLen;
185 return status;
186 #endif
187 }
188
189 /* TLS 1.2 RSA signature */
190 OSStatus sslRsaSign(
191 SSLContext *ctx,
192 SSLPrivKey *privKey,
193 const SecAsn1AlgId *algId,
194 const uint8_t *plainText,
195 size_t plainTextLen,
196 uint8_t *sig, // mallocd by caller; RETURNED
197 size_t sigLen, // available
198 size_t *actualBytes) // RETURNED
199 {
200 size_t inOutSigLen = sigLen;
201
202 assert(actualBytes != NULL);
203
204 OSStatus status = SecKeySignDigest(SECKEYREF(privKey), algId,
205 plainText, plainTextLen, sig, &inOutSigLen);
206
207 if (status) {
208 sslErrorLog("sslRsaSign: SecKeySignDigest failed (error %d)\n", status);
209 }
210
211 /* Since the KeyExchange already allocated modulus size bytes we'll
212 use all of them. SecureTransport has always sent that many bytes,
213 so we're not going to deviate, to avoid interoperability issues. */
214 if (!status && (inOutSigLen < sigLen)) {
215 size_t offset = sigLen - inOutSigLen;
216 memmove(sig + offset, sig, inOutSigLen);
217 memset(sig, 0, offset);
218 inOutSigLen = sigLen;
219 }
220
221 *actualBytes = inOutSigLen;
222 return status;
223 }
224
225 OSStatus sslRawVerify(
226 SSLContext *ctx,
227 SSLPubKey *pubKey,
228 const uint8_t *plainText,
229 size_t plainTextLen,
230 const uint8_t *sig,
231 size_t sigLen) // available
232 {
233 #if 0
234 RSAStatus rsaStatus;
235
236 rsaStatus = RSA_SigVerify(&pubKey->rsaKey,
237 RP_PKCS1,
238 plainText,
239 plainTextLen,
240 sig,
241 sigLen);
242
243 return rsaStatus ? rsaStatusToSSL(rsaStatus) : noErr;
244 #else
245 OSStatus status = SecKeyRawVerify(SECKEYREF(pubKey), kSecPaddingPKCS1,
246 plainText, plainTextLen, sig, sigLen);
247
248 if (status) {
249 sslErrorLog("sslRawVerify: SecKeyRawVerify failed (error %d)\n", status);
250 }
251
252 return status;
253 #endif
254 }
255
256 /* TLS 1.2 RSA verify */
257 OSStatus sslRsaVerify(
258 SSLContext *ctx,
259 SSLPubKey *pubKey,
260 const SecAsn1AlgId *algId,
261 const uint8_t *plainText,
262 size_t plainTextLen,
263 const uint8_t *sig,
264 size_t sigLen) // available
265 {
266 OSStatus status = SecKeyVerifyDigest(SECKEYREF(pubKey), algId,
267 plainText, plainTextLen, sig, sigLen);
268
269 if (status) {
270 sslErrorLog("sslRsaVerify: SecKeyVerifyDigest failed (error %d)\n", status);
271 }
272
273 return status;
274 }
275
276 /*
277 * Encrypt/Decrypt
278 */
279 OSStatus sslRsaEncrypt(
280 SSLContext *ctx,
281 SSLPubKey *pubKey,
282 const uint32_t padding,
283 const uint8_t *plainText,
284 size_t plainTextLen,
285 uint8_t *cipherText, // mallocd by caller; RETURNED
286 size_t cipherTextLen, // available
287 size_t *actualBytes) // RETURNED
288 {
289 #if 0
290 gi_uint16 giCipherTextLen = cipherTextLen;
291 RSAStatus rsaStatus;
292
293 assert(actualBytes != NULL);
294
295 rsaStatus = RSA_Encrypt(&pubKey->rsaKey,
296 RP_PKCS1,
297 getRandomByte,
298 plainText,
299 plainTextLen,
300 cipherText,
301 &giCipherTextLen);
302 *actualBytes = giCipherTextLen;
303
304 return rsaStatus ? rsaStatusToSSL(rsaStatus) : noErr;
305 #else
306 size_t ctlen = cipherTextLen;
307
308 assert(actualBytes != NULL);
309
310 #if RSA_PUB_KEY_USAGE_HACK
311 /* Force key usage to allow encryption with public key */
312 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
313 const CSSM_KEY_PTR cssmKey = NULL;
314 if (SecKeyGetCSSMKey(SECKEYREF(pubKey), &cssmKey)==noErr && cssmKey)
315 cssmKey->KeyHeader.KeyUsage |= CSSM_KEYUSE_ENCRYPT;
316 #endif
317 #endif
318
319 OSStatus status = SecKeyEncrypt(SECKEYREF(pubKey), padding,
320 plainText, plainTextLen, cipherText, &ctlen);
321
322 if (status) {
323 sslErrorLog("sslRsaEncrypt: SecKeyEncrypt failed (error %d)\n", status);
324 }
325
326 /* Since the KeyExchange already allocated modulus size bytes we'll
327 use all of them. SecureTransport has always sent that many bytes,
328 so we're not going to deviate, to avoid interoperability issues. */
329 if (!status && (ctlen < cipherTextLen)) {
330 size_t offset = cipherTextLen - ctlen;
331 memmove(cipherText + offset, cipherText, ctlen);
332 memset(cipherText, 0, offset);
333 ctlen = cipherTextLen;
334 }
335
336 if (actualBytes)
337 *actualBytes = ctlen;
338
339 if (status)
340 sslErrorLog("***sslRsaEncrypt: error %d\n", status);
341
342 return status;
343 #endif
344 }
345
346 OSStatus sslRsaDecrypt(
347 SSLContext *ctx,
348 SSLPrivKey *privKey,
349 const uint32_t padding,
350 const uint8_t *cipherText,
351 size_t cipherTextLen,
352 uint8_t *plainText, // mallocd by caller; RETURNED
353 size_t plainTextLen, // available
354 size_t *actualBytes) // RETURNED
355 {
356 #if 0
357 gi_uint16 giPlainTextLen = plainTextLen;
358 RSAStatus rsaStatus;
359
360 assert(actualBytes != NULL);
361
362 rsaStatus = RSA_Decrypt(&privKey->rsaKey,
363 RP_PKCS1,
364 cipherText,
365 cipherTextLen,
366 plainText,
367 &giPlainTextLen);
368 *actualBytes = giPlainTextLen;
369
370 return rsaStatus ? rsaStatusToSSL(rsaStatus) : noErr;
371 #else
372 size_t ptlen = plainTextLen;
373
374 assert(actualBytes != NULL);
375
376 OSStatus status = SecKeyDecrypt(SECKEYREF(privKey), padding,
377 cipherText, cipherTextLen, plainText, &ptlen);
378 *actualBytes = ptlen;
379
380 if (status) {
381 sslErrorLog("sslRsaDecrypt: SecKeyDecrypt failed (error %d)\n", status);
382 }
383
384 return status;
385 #endif
386 }
387
388 /*
389 * Obtain size of the modulus of privKey in bytes.
390 */
391 size_t sslPrivKeyLengthInBytes(SSLPrivKey *privKey)
392 {
393 #if 0
394 /* Get the length of p + q (which is the size of the modulus) in bits. */
395 gi_uint16 bitLen = bitlen(&privKey->rsaKey.p.g) +
396 bitlen(&privKey->rsaKey.q.g);
397 /* Convert it to bytes. */
398 return (bitLen + 7) / 8;
399 #else
400 return SecKeyGetBlockSize(SECKEYREF(privKey));
401 #endif
402 }
403
404 /*
405 * Obtain size of the modulus of pubKey in bytes.
406 */
407 size_t sslPubKeyLengthInBytes(SSLPubKey *pubKey)
408 {
409 #if 0
410 /* Get the length of the modulus in bytes. */
411 return giantNumBytes(&pubKey->rsaKey.n.g);
412 #else
413 return SecKeyGetBlockSize(SECKEYREF(pubKey));
414 #endif
415 }
416
417
418 /*
419 * Obtain maximum size of signature in bytes. A bit of a kludge; we could
420 * ask the CSP to do this but that would be kind of expensive.
421 */
422 OSStatus sslGetMaxSigSize(
423 SSLPrivKey *privKey,
424 size_t *maxSigSize)
425 {
426 assert(maxSigSize != NULL);
427
428 #if 0
429 #if RSA_SIG_SHARE_GIANT
430 *maxSigSize = sizeof(RSASignBuffer);
431 #else
432 *maxSigSize = MAX_PRIME_SIZE_BYTES;
433 #endif
434 #else
435 *maxSigSize = SecKeyGetBlockSize(SECKEYREF(privKey));
436 #endif
437
438 return noErr;
439 }
440
441 #if 0
442 static OSStatus sslGiantToBuffer(
443 SSLContext *ctx, // Currently unused.
444 giant g,
445 SSLBuffer *buffer)
446 {
447 gi_uint8 *chars;
448 gi_uint16 ioLen;
449 gi_uint16 zeroCount;
450 GIReturn giReturn;
451 OSStatus status;
452
453 ioLen = serializeGiantBytes(g);
454 status = SSLAllocBuffer(buffer, ioLen, ctx);
455 if (status)
456 return status;
457 chars = buffer->data;
458
459 /* Serialize the giant g into chars. */
460 giReturn = serializeGiant(g, chars, &ioLen);
461 if(giReturn) {
462 SSLFreeBuffer(buffer, ctx);
463 return giReturnToSSL(giReturn);
464 }
465
466 /* Trim off leading zeroes (but leave one zero if that's all there is). */
467 for (zeroCount = 0; zeroCount < (ioLen - 1); ++zeroCount)
468 if (chars[zeroCount])
469 break;
470
471 if (zeroCount > 0) {
472 buffer->length = ioLen - zeroCount;
473 memmove(chars, chars + zeroCount, buffer->length);
474 }
475
476 return status;
477 }
478
479 /*
480 * Get raw key bits from an RSA public key.
481 */
482 OSStatus sslGetPubKeyBits(
483 SSLContext *ctx, // Currently unused.
484 SSLPubKey *pubKey,
485 SSLBuffer *modulus, // data mallocd and RETURNED
486 SSLBuffer *exponent) // data mallocd and RETURNED
487 {
488 OSStatus status;
489
490 status = sslGiantToBuffer(ctx, &pubKey->rsaKey.n.g, modulus);
491 if(status)
492 return status;
493
494 status = sslGiantToBuffer(ctx, &pubKey->rsaKey.e.g, exponent);
495 if(status) {
496 SSLFreeBuffer(modulus, ctx);
497 return status;
498 }
499
500 return status;
501 }
502 #endif
503
504 /*
505 * Given raw RSA key bits, cook up a SSLPubKey. Used in
506 * Server-initiated key exchange.
507 */
508 OSStatus sslGetPubKeyFromBits(
509 SSLContext *ctx,
510 const SSLBuffer *modulus,
511 const SSLBuffer *exponent,
512 SSLPubKey **pubKey) // mallocd and RETURNED
513 {
514 if (!pubKey)
515 return paramErr;
516 #if 0
517 SSLPubKey *key;
518 RSAStatus rsaStatus;
519 RSAPubKey apiKey = {
520 modulus->data, modulus->length,
521 NULL, 0,
522 exponent->data, exponent->length
523 };
524
525 key = sslMalloc(sizeof(*key));
526 rsaStatus = rsaInitPubGKey(&apiKey, &key->rsaKey);
527 if (rsaStatus) {
528 sslFree(key);
529 return rsaStatusToSSL(rsaStatus);
530 }
531
532 *pubKey = key;
533 return noErr;
534 #else
535 check(pubKey);
536 SecRSAPublicKeyParams params = {
537 modulus->data, modulus->length,
538 exponent->data, exponent->length
539 };
540 #if SSL_DEBUG
541 sslDebugLog("Creating RSA pub key from modulus=%p len=%lu exponent=%p len=%lu\n",
542 (uintptr_t)modulus->data, modulus->length,
543 (uintptr_t)exponent->data, exponent->length);
544 #endif
545 SecKeyRef key = SecKeyCreateRSAPublicKey(NULL, (const uint8_t *)&params,
546 sizeof(params), kSecKeyEncodingRSAPublicParams);
547 if (!key) {
548 sslErrorLog("sslGetPubKeyFromBits: SecKeyCreateRSAPublicKey failed\n");
549 return errSSLCrypto;
550 }
551 #if SSL_DEBUG
552 size_t blocksize = SecKeyGetBlockSize(key);
553 sslDebugLog("sslGetPubKeyFromBits: RSA pub key block size=%lu\n", blocksize);
554 #endif
555 *pubKey = (SSLPubKey*)key;
556 return noErr;
557 #endif
558 }
559
560 #pragma mark -
561 #pragma mark Public Certificate Functions
562
563 #ifdef USE_SSLCERTIFICATE
564
565 /*
566 * Given a SSLCertificate cert, obtain its public key as a SSLPubKey.
567 * Caller must sslFreePubKey and free the SSLPubKey itself.
568 */
569 OSStatus sslPubKeyFromCert(
570 SSLContext *ctx,
571 const SSLCertificate *cert,
572 SSLPubKey **pubKey) // RETURNED
573 {
574 DERItem der;
575 DERSignedCertCrl signedCert;
576 DERTBSCert tbsCert;
577 DERSubjPubKeyInfo pubKeyInfo;
578 DERByte numUnused;
579 DERItem pubKeyPkcs1;
580 SSLPubKey *key;
581 DERReturn drtn;
582 RSAStatus rsaStatus;
583
584 assert(cert);
585 assert(pubKey != NULL);
586
587 der.data = cert->derCert.data;
588 der.length = cert->derCert.length;
589
590 /* top level decode */
591 drtn = DERParseSequence(&der, DERNumSignedCertCrlItemSpecs,
592 DERSignedCertCrlItemSpecs, &signedCert, sizeof(signedCert));
593 if(drtn)
594 return errSSLBadCert;
595
596 /* decode the TBSCert - it was saved in full DER form */
597 drtn = DERParseSequence(&signedCert.tbs,
598 DERNumTBSCertItemSpecs, DERTBSCertItemSpecs,
599 &tbsCert, sizeof(tbsCert));
600 if(drtn)
601 return errSSLBadCert;
602
603 /* sequence we're given: encoded DERSubjPubKeyInfo */
604 drtn = DERParseSequenceContent(&tbsCert.subjectPubKey,
605 DERNumSubjPubKeyInfoItemSpecs, DERSubjPubKeyInfoItemSpecs,
606 &pubKeyInfo, sizeof(pubKeyInfo));
607 if(drtn)
608 return errSSLBadCert;
609
610 /* @@@ verify that this is an RSA key by decoding the AlgId */
611
612 /*
613 * The contents of pubKeyInfo.pubKey is a bit string whose contents
614 * are a PKCS1 format RSA key.
615 */
616 drtn = DERParseBitString(&pubKeyInfo.pubKey, &pubKeyPkcs1, &numUnused);
617 if(drtn)
618 return errSSLBadCert;
619
620 #if TARGET_OS_IOS
621 /* Now we have the public key in pkcs1 format. Let's make a public key
622 object out of it. */
623 key = sslMalloc(sizeof(*key));
624 rsaStatus = RSA_DecodePubKey(pubKeyPkcs1.data, pubKeyPkcs1.length,
625 &key->rsaKey);
626 if (rsaStatus) {
627 sslFree(key);
628 }
629 #else
630 SecKeyRef rsaPubKeyRef = SecKeyCreateRSAPublicKey(NULL,
631 pubKeyPkcs1.data, pubKeyPkcs1.length,
632 kSecKeyEncodingRSAPublicParams);
633 rsaStatus = (rsaPubKeyRef) ? 0 : 1;
634 key = (SSLPubKey*)rsaPubKeyRef;
635 #endif
636 if (rsaStatus) {
637 return rsaStatusToSSL(rsaStatus);
638 }
639
640 *pubKey = key;
641 return noErr;
642 }
643
644 /*
645 * Verify a chain of DER-encoded certs.
646 * First cert in a chain is root; this must also be present
647 * in ctx->trustedCerts.
648 *
649 * If arePeerCerts is true, host name verification is enabled and we
650 * save the resulting SecTrustRef in ctx->peerSecTrust. Otherwise
651 * we're just validating our own certs; no host name checking and
652 * peerSecTrust is transient.
653 */
654 OSStatus sslVerifyCertChain(
655 SSLContext *ctx,
656 const SSLCertificate *certChain,
657 bool arePeerCerts)
658 {
659 OSStatus ortn = noErr;
660
661 assert(certChain);
662
663 /* No point checking our own certs, our clients can do that. */
664 if (!arePeerCerts)
665 return noErr;
666
667 CertVerifyReturn cvrtn;
668 /* @@@ Add real cert checking. */
669 if (certChain->next) {
670 DERItem subject, issuer;
671
672 issuer.data = certChain->derCert.data;
673 issuer.length = certChain->derCert.length;
674 subject.data = certChain->next->derCert.data;
675 subject.length = certChain->next->derCert.length;
676 cvrtn = certVerify(&subject, &issuer);
677 if (cvrtn != CVR_Success)
678 ortn = errSSLBadCert;
679 }
680 else
681 {
682 sslErrorLog("***sslVerifyCertChain: only one cert in chain\n");
683 }
684 return ortn;
685 }
686
687 #else /* !USE_SSLCERTIFICATE */
688
689 OSStatus
690 sslCreateSecTrust(
691 SSLContext *ctx,
692 CFArrayRef certChain,
693 bool arePeerCerts,
694 SecTrustRef *pTrust) /* RETURNED */
695 {
696 OSStatus status = memFullErr;
697 CFStringRef peerDomainName = NULL;
698 CFTypeRef policies = NULL;
699 SecTrustRef trust = NULL;
700
701 if (CFArrayGetCount(certChain) == 0) {
702 status = errSSLBadCert;
703 goto errOut;
704 }
705
706 if (arePeerCerts) {
707 if (ctx->peerDomainNameLen && ctx->peerDomainName) {
708 CFIndex len = ctx->peerDomainNameLen;
709 if (ctx->peerDomainName[len - 1] == 0) {
710 len--;
711 //secwarning("peerDomainName is zero terminated!");
712 }
713 /* @@@ Double check that this is the correct encoding. */
714 require(peerDomainName = CFStringCreateWithBytes(kCFAllocatorDefault,
715 (const UInt8 *)ctx->peerDomainName, len,
716 kCFStringEncodingUTF8, false), errOut);
717 }
718 }
719 /* If we are the client, our peer certificates must satisfy the
720 ssl server policy. */
721 bool server = ctx->protocolSide == kSSLClientSide;
722 require(policies = SecPolicyCreateSSL(server, peerDomainName), errOut);
723
724 require_noerr(status = SecTrustCreateWithCertificates(certChain, policies,
725 &trust), errOut);
726
727 /* If we have trustedAnchors we set them here. */
728 if (ctx->trustedCerts) {
729 require_noerr(status = SecTrustSetAnchorCertificates(trust,
730 ctx->trustedCerts), errOut);
731 require_noerr(status = SecTrustSetAnchorCertificatesOnly(trust,
732 ctx->trustedCertsOnly), errOut);
733 }
734
735 status = noErr;
736
737 errOut:
738 CFReleaseSafe(peerDomainName);
739 CFReleaseSafe(policies);
740
741 *pTrust = trust;
742
743 return status;
744 }
745
746 /* Return the first certificate reference from the supplied array
747 * whose data matches the given certificate, or NULL if none match.
748 */
749 SecCertificateRef
750 sslGetMatchingCertInArray(
751 SecCertificateRef certRef,
752 CFArrayRef certArray)
753 {
754 SecCertificateRef matchedCert = NULL;
755
756 if (certRef == NULL || certArray == NULL) {
757 return NULL;
758 }
759
760 CFDataRef certData = SecCertificateCopyData(certRef);
761 if (certData) {
762 CFIndex idx, count = CFArrayGetCount(certArray);
763 for(idx=0; idx<count; idx++) {
764 SecCertificateRef aCert = (SecCertificateRef)CFArrayGetValueAtIndex(certArray, idx);
765 CFDataRef aData = SecCertificateCopyData(aCert);
766 if (aData && CFEqual(aData, certData)) {
767 matchedCert = aCert;
768 }
769 CFReleaseSafe(aData);
770 if (matchedCert)
771 break;
772 }
773 CFReleaseSafe(certData);
774 }
775
776 return matchedCert;
777 }
778
779 /*
780 * Verify a chain of DER-encoded certs.
781 * Last cert in a chain is the leaf; this must also be present
782 * in ctx->trustedCerts.
783 *
784 * If arePeerCerts is true, host name verification is enabled and we
785 * save the resulting SecTrustRef in ctx->peerSecTrust. Otherwise
786 * we're just validating our own certs; no host name checking and
787 * peerSecTrust is transient.
788 */
789 extern OSStatus sslVerifyCertChain(
790 SSLContext *ctx,
791 CFArrayRef certChain,
792 bool arePeerCerts)
793 {
794 OSStatus status;
795 SecTrustRef trust = NULL;
796
797 assert(certChain);
798
799 if (arePeerCerts) {
800 /* renegotiate - start with a new SecTrustRef */
801 CFReleaseNull(ctx->peerSecTrust);
802 }
803
804 status = sslCreateSecTrust(ctx, certChain, arePeerCerts, &trust);
805
806 if (!ctx->enableCertVerify) {
807 /* trivial case, this is caller's responsibility */
808 status = noErr;
809 goto errOut;
810 }
811
812 SecTrustResultType secTrustResult;
813 require_noerr(status = SecTrustEvaluate(trust, &secTrustResult), errOut);
814 switch (secTrustResult) {
815 case kSecTrustResultUnspecified:
816 /* cert chain valid, no special UserTrust assignments */
817 case kSecTrustResultProceed:
818 /* cert chain valid AND user explicitly trusts this */
819 status = noErr;
820 break;
821 case kSecTrustResultDeny:
822 case kSecTrustResultConfirm:
823 case kSecTrustResultRecoverableTrustFailure:
824 default:
825 if(ctx->allowAnyRoot) {
826 sslErrorLog("***Warning: accepting unverified cert chain\n");
827 status = noErr;
828 }
829 else {
830 /*
831 * If the caller provided a list of trusted leaf certs, check them here
832 */
833 if(ctx->trustedLeafCerts) {
834 if (sslGetMatchingCertInArray((SecCertificateRef)CFArrayGetValueAtIndex(certChain, 0),
835 ctx->trustedLeafCerts)) {
836 status = noErr;
837 goto errOut;
838 }
839 }
840 status = errSSLXCertChainInvalid;
841 }
842 /* Do we really need to return things like:
843 errSSLNoRootCert
844 errSSLUnknownRootCert
845 errSSLCertExpired
846 errSSLCertNotYetValid
847 errSSLHostNameMismatch
848 for our client to see what went wrong, or should we just always
849 return
850 errSSLXCertChainInvalid
851 when something is wrong? */
852 break;
853 }
854
855 errOut:
856 if (arePeerCerts)
857 ctx->peerSecTrust = trust;
858 else
859 CFReleaseSafe(trust);
860
861 return status;
862 }
863
864 /*
865 * Given a SecCertificateRef cert, obtain its public key as a SSLPubKey.
866 * Caller must sslFreePubKey and free the SSLPubKey itself.
867 */
868 extern OSStatus sslCopyPeerPubKey(
869 SSLContext *ctx,
870 SSLPubKey **pubKey)
871 {
872 OSStatus status = noErr;
873
874 check(pubKey);
875 check(ctx->peerSecTrust);
876
877 if (!ctx->enableCertVerify) {
878 SecTrustResultType result;
879 require_noerr(status = SecTrustEvaluate(ctx->peerSecTrust, &result),
880 errOut);
881 }
882
883 SecKeyRef key = SecTrustCopyPublicKey(ctx->peerSecTrust);
884 if (!key) {
885 sslErrorLog("sslCopyPeerPubKey: %s, ctx->peerSecTrust=%p\n",
886 "SecTrustCopyPublicKey failed", (uintptr_t)ctx->peerSecTrust);
887 return errSSLBadCert;
888 }
889 *pubKey = (SSLPubKey*)key;
890
891 errOut:
892 if (status) {
893 sslErrorLog("sslCopyPeerPubKey: error %d\n", status);
894 }
895 return status;
896 }
897
898 #endif /* !USE_SSLCERTIFICATE */
899
900 #ifndef NDEBUG
901 void stPrintCdsaError(const char *op, OSStatus crtn)
902 {
903 assert(FALSE);
904 }
905 #endif
906
907 /*
908 * After ciphersuite negotiation is complete, verify that we have
909 * the capability of actually performing the selected cipher.
910 * Currently we just verify that we have a cert and private signing
911 * key, if needed, and that the signing key's algorithm matches the
912 * expected key exchange method.
913 *
914 * This is currently called from FindCipherSpec(), after it sets
915 * ctx->selectedCipherSpec to a (supposedly) valid value, and from
916 * sslBuildCipherSpecArray(), in server mode (pre-negotiation) only.
917 */
918 OSStatus sslVerifySelectedCipher(
919 SSLContext *ctx,
920 const SSLCipherSpec *selectedCipherSpec)
921 {
922 if(ctx->protocolSide == kSSLClientSide) {
923 return noErr;
924 }
925 #if SSL_PAC_SERVER_ENABLE
926 if((ctx->masterSecretCallback != NULL) &&
927 (ctx->sessionTicket.data != NULL)) {
928 /* EAP via PAC resumption; we can do it */
929 return noErr;
930 }
931 #endif /* SSL_PAC_SERVER_ENABLE */
932
933 CFIndex requireAlg;
934 if(selectedCipherSpec == NULL) {
935 sslErrorLog("sslVerifySelectedCipher: no selected cipher\n");
936 return errSSLInternal;
937 }
938 switch (selectedCipherSpec->keyExchangeMethod) {
939 case SSL_RSA:
940 case SSL_RSA_EXPORT:
941 case SSL_DH_RSA:
942 case SSL_DH_RSA_EXPORT:
943 case SSL_DHE_RSA:
944 case SSL_DHE_RSA_EXPORT:
945 requireAlg = kSecRSAAlgorithmID;
946 break;
947 case SSL_DHE_DSS:
948 case SSL_DHE_DSS_EXPORT:
949 case SSL_DH_DSS:
950 case SSL_DH_DSS_EXPORT:
951 requireAlg = kSecDSAAlgorithmID;
952 break;
953 case SSL_DH_anon:
954 case SSL_DH_anon_EXPORT:
955 requireAlg = kSecNullAlgorithmID; /* no signing key */
956 break;
957 /*
958 * When SSL_ECDSA_SERVER is true and we support ECDSA on the server side,
959 * we'll need to add some logic here...
960 */
961 #if SSL_ECDSA_SERVER
962 case SSL_ECDHE_ECDSA:
963 case SSL_ECDHE_RSA:
964 case SSL_ECDH_ECDSA:
965 case SSL_ECDH_RSA:
966 case SSL_ECDH_anon:
967 requireAlg = kSecECDSAAlgorithmID;
968 break;
969 #endif
970
971 default:
972 /* needs update per cipherSpecs.c */
973 assert(0);
974 sslErrorLog("sslVerifySelectedCipher: unknown key exchange method\n");
975 return errSSLInternal;
976 }
977
978 if(requireAlg == kSecNullAlgorithmID) {
979 return noErr;
980 }
981
982 /* private signing key required */
983 if(ctx->signingPrivKeyRef == NULL) {
984 sslErrorLog("sslVerifySelectedCipher: no signing key\n");
985 return errSSLBadConfiguration;
986 }
987
988 /* Check the alg of our signing key. */
989 CFIndex keyAlg = sslPrivKeyGetAlgorithmID(ctx->signingPrivKeyRef);
990 if (requireAlg != keyAlg) {
991 sslErrorLog("sslVerifySelectedCipher: signing key alg mismatch\n");
992 return errSSLBadConfiguration;
993 }
994
995 return noErr;
996 }
997
998 #if APPLE_DH
999
1000 /* FIXME: This is duplicated in SecDH */
1001 typedef struct {
1002 DERItem p;
1003 DERItem g;
1004 DERItem l;
1005 } DER_DHParams;
1006
1007 static const DERItemSpec DER_DHParamsItemSpecs[] =
1008 {
1009 { DER_OFFSET(DER_DHParams, p),
1010 ASN1_INTEGER,
1011 DER_DEC_NO_OPTS | DER_ENC_SIGNED_INT },
1012 { DER_OFFSET(DER_DHParams, g),
1013 ASN1_INTEGER,
1014 DER_DEC_NO_OPTS | DER_ENC_SIGNED_INT },
1015 { DER_OFFSET(DER_DHParams, l),
1016 ASN1_INTEGER,
1017 DER_DEC_OPTIONAL | DER_ENC_SIGNED_INT },
1018 };
1019 static const DERSize DER_NumDHParamsItemSpecs =
1020 sizeof(DER_DHParamsItemSpecs) / sizeof(DERItemSpec);
1021
1022 /* Max encoded size for standard (PKCS3) parameters */
1023 #define DH_ENCODED_PARAM_SIZE(primeSizeInBytes) \
1024 DER_MAX_ENCODED_SIZE( \
1025 DER_MAX_ENCODED_SIZE(primeSizeInBytes) + /* g */ \
1026 DER_MAX_ENCODED_SIZE(primeSizeInBytes) + /* p */ \
1027 DER_MAX_ENCODED_SIZE(4)) /* l */
1028
1029
1030 OSStatus sslDecodeDhParams(
1031 const SSLBuffer *blob, /* Input - PKCS-3 encoded */
1032 SSLBuffer *prime, /* Output - wire format */
1033 SSLBuffer *generator) /* Output - wire format */
1034 {
1035 OSStatus ortn = noErr;
1036 DERReturn drtn;
1037 DERItem paramItem = {(DERByte *)blob->data, blob->length};
1038 DER_DHParams decodedParams;
1039
1040 drtn = DERParseSequence(&paramItem,
1041 DER_NumDHParamsItemSpecs, DER_DHParamsItemSpecs,
1042 &decodedParams, sizeof(decodedParams));
1043 if(drtn)
1044 return drtn;
1045
1046 prime->data = decodedParams.p.data;
1047 prime->length = decodedParams.p.length;
1048
1049 generator->data = decodedParams.g.data;
1050 generator->length = decodedParams.g.length;
1051
1052 return ortn;
1053 }
1054
1055
1056 OSStatus sslEncodeDhParams(SSLBuffer *blob, /* data mallocd and RETURNED PKCS-3 encoded */
1057 const SSLBuffer *prime, /* Wire format */
1058 const SSLBuffer *generator) /* Wire format */
1059 {
1060 OSStatus ortn = noErr;
1061 DER_DHParams derParams =
1062 {
1063 .p = {
1064 .length = prime->length,
1065 .data = prime->data,
1066 },
1067 .g = {
1068 .length = generator->length,
1069 .data = generator->data,
1070 },
1071 .l = {
1072 .length = 0,
1073 .data = NULL,
1074 }
1075 };
1076
1077 DERSize ioLen = DH_ENCODED_PARAM_SIZE(derParams.p.length);
1078 DERByte *der = sslMalloc(ioLen);
1079 // FIXME: What if this fails - we should probably not have a malloc here ?
1080 assert(der);
1081 ortn = (OSStatus)DEREncodeSequence(ASN1_CONSTR_SEQUENCE,
1082 &derParams,
1083 DER_NumDHParamsItemSpecs, DER_DHParamsItemSpecs,
1084 der,
1085 &ioLen);
1086 // This should never fail
1087
1088 blob->length=ioLen;
1089 blob->data=der;
1090
1091 return ortn;
1092 }
1093
1094 OSStatus sslDhCreateKey(SSLContext *ctx)
1095 {
1096 if (ctx->secDHContext) {
1097 SecDHDestroy(ctx->secDHContext);
1098 ctx->secDHContext = NULL;
1099 }
1100
1101 /* Server params are set using encoded dh params */
1102 if (!(ctx->dhParamsEncoded.length && ctx->dhParamsEncoded.data))
1103 return errSSLInternal;
1104
1105 if (SecDHCreateFromParameters(ctx->dhParamsEncoded.data,
1106 ctx->dhParamsEncoded.length, &ctx->secDHContext))
1107 return errSSLCrypto;
1108
1109 return noErr;
1110 }
1111
1112 OSStatus sslDhGenerateKeyPair(SSLContext *ctx)
1113 {
1114 OSStatus ortn = noErr;
1115
1116 require_noerr(ortn = SSLAllocBuffer(&ctx->dhExchangePublic,
1117 SecDHGetMaxKeyLength(ctx->secDHContext), ctx), out);
1118 require_noerr(ortn = SecDHGenerateKeypair(ctx->secDHContext,
1119 ctx->dhExchangePublic.data, &ctx->dhExchangePublic.length), out);
1120
1121 out:
1122 return ortn;
1123 }
1124
1125
1126 OSStatus sslDhKeyExchange(SSLContext *ctx)
1127 {
1128 OSStatus ortn = noErr;
1129
1130 if (ctx == NULL ||
1131 ctx->secDHContext == NULL ||
1132 ctx->dhPeerPublic.length == 0) {
1133 /* comes from peer, don't panic */
1134 sslErrorLog("sslDhKeyExchange: null peer public key\n");
1135 return errSSLProtocol;
1136 }
1137
1138 require_noerr(ortn = SSLAllocBuffer(&ctx->preMasterSecret,
1139 SecDHGetMaxKeyLength(ctx->secDHContext), ctx), out);
1140 require_noerr(ortn = SecDHComputeKey(ctx->secDHContext,
1141 ctx->dhPeerPublic.data, ctx->dhPeerPublic.length,
1142 ctx->preMasterSecret.data, &ctx->preMasterSecret.length), out);
1143
1144 return ortn;
1145 out:
1146 sslErrorLog("sslDhKeyExchange: failed to compute key (error %d)\n", ortn);
1147 return ortn;
1148 }
1149
1150 #endif /* APPLE_DH */
1151
1152 /*
1153 * Given an ECDSA key in SecKey format, extract the SSL_ECDSA_NamedCurve
1154 * from its algorithm parameters.
1155 */
1156 OSStatus sslEcdsaPeerCurve(
1157 SSLPubKey *pubKey,
1158 SSL_ECDSA_NamedCurve *namedCurve)
1159 {
1160 /* Cast is safe because enums are kept in sync. */
1161 *namedCurve = (SSL_ECDSA_NamedCurve)SecECKeyGetNamedCurve(SECKEYREF(pubKey));
1162 if (*namedCurve == kSecECCurveNone) {
1163 sslErrorLog("sslEcdsaPeerCurve: no named curve for public key\n");
1164 return errSSLProtocol;
1165 }
1166 return noErr;
1167 }
1168
1169 /*
1170 * Generate ECDH key pair with the given SSL_ECDSA_NamedCurve.
1171 * Private key, in ref form, is placed in ctx->ecdhPrivate.
1172 * Public key, in ECPoint form - which can NOT be used as
1173 * a key in any CSP ops - is placed in ecdhExchangePublic.
1174 */
1175 OSStatus sslEcdhGenerateKeyPair(
1176 SSLContext *ctx,
1177 SSL_ECDSA_NamedCurve namedCurve)
1178 {
1179 OSStatus ortn = noErr;
1180
1181 ccec_const_cp_t cp;
1182 switch (namedCurve) {
1183 case SSL_Curve_secp256r1:
1184 cp = ccec_cp_256();
1185 break;
1186 case SSL_Curve_secp384r1:
1187 cp = ccec_cp_384();
1188 break;
1189 case SSL_Curve_secp521r1:
1190 cp = ccec_cp_521();
1191 break;
1192 default:
1193 /* should not have gotten this far */
1194 sslErrorLog("sslEcdhGenerateKeyPair: bad namedCurve (%u)\n",
1195 (unsigned)namedCurve);
1196 return errSSLInternal;
1197 }
1198
1199 ccec_generate_key(cp, CCRNGSTATE, ctx->ecdhContext);
1200 size_t pub_size = ccec_export_pub_size(ctx->ecdhContext);
1201 SSLFreeBuffer(&ctx->ecdhExchangePublic, ctx);
1202 require_noerr(ortn = SSLAllocBuffer(&ctx->ecdhExchangePublic,
1203 pub_size, ctx), errOut);
1204 ccec_export_pub(ctx->ecdhContext, ctx->ecdhExchangePublic.data);
1205
1206 sslDebugLog("sslEcdhGenerateKeyPair: pub key size=%ld, data=%p\n",
1207 pub_size, (uintptr_t)ctx->ecdhExchangePublic.data);
1208
1209 errOut:
1210 return ortn;
1211 }
1212
1213 /*
1214 * Perform ECDH key exchange. Obtained key material is the same
1215 * size as our private key.
1216 *
1217 * On entry, ecdhPrivate is our private key. The peer's public key
1218 * is either ctx->ecdhPeerPublic for ECDHE exchange, or
1219 * ctx->peerPubKey for ECDH exchange.
1220 */
1221 OSStatus sslEcdhKeyExchange(
1222 SSLContext *ctx,
1223 SSLBuffer *exchanged)
1224 {
1225 OSStatus ortn = noErr;
1226 CFDataRef pubKeyData = NULL;
1227 const unsigned char *pubKeyBits;
1228 unsigned long pubKeyLen;
1229
1230 switch(ctx->selectedCipherSpec.keyExchangeMethod) {
1231 case SSL_ECDHE_ECDSA:
1232 case SSL_ECDHE_RSA:
1233 /* public key passed in as CSSM_DATA *Param */
1234 if(ctx->ecdhPeerPublic.length == 0) {
1235 /* comes from peer, don't panic */
1236 sslErrorLog("sslEcdhKeyExchange: null peer public key\n");
1237 ortn = errSSLProtocol;
1238 goto errOut;
1239 }
1240 pubKeyBits = ctx->ecdhPeerPublic.data;
1241 pubKeyLen = ctx->ecdhPeerPublic.length;
1242 break;
1243 case SSL_ECDH_ECDSA:
1244 case SSL_ECDH_RSA:
1245 /* Use the public key provided by the peer. */
1246 if(ctx->peerPubKey == NULL) {
1247 sslErrorLog("sslEcdhKeyExchange: no peer key\n");
1248 ortn = errSSLInternal;
1249 goto errOut;
1250 }
1251
1252 pubKeyData = SecECKeyCopyPublicBits(SECKEYREF(ctx->peerPubKey));
1253 if (!pubKeyData) {
1254 sslErrorLog("sslEcdhKeyExchange: SecECKeyCopyPublicBits failed\n");
1255 ortn = errSSLProtocol;
1256 goto errOut;
1257 }
1258 pubKeyBits = CFDataGetBytePtr(pubKeyData);
1259 pubKeyLen = CFDataGetLength(pubKeyData);
1260 break;
1261 default:
1262 /* shouldn't be here */
1263 sslErrorLog("sslEcdhKeyExchange: unknown keyExchangeMethod (%d)\n",
1264 ctx->selectedCipherSpec.keyExchangeMethod);
1265 assert(0);
1266 ortn = errSSLInternal;
1267 goto errOut;
1268 }
1269
1270 ccec_const_cp_t cp = ccec_ctx_cp(ctx->ecdhContext);
1271 ccec_pub_ctx_decl(ccn_sizeof(521), pubKey);
1272 ccec_import_pub(cp, pubKeyLen, pubKeyBits, pubKey);
1273 size_t len = 1 + 2 * ccec_ccn_size(cp);
1274 require_noerr(ortn = SSLAllocBuffer(exchanged, len, NULL), errOut);
1275 require_noerr(ccec_compute_key(ctx->ecdhContext, pubKey, &exchanged->length, exchanged->data), errOut);
1276
1277 sslDebugLog("sslEcdhKeyExchange: exchanged key length=%ld, data=%p\n",
1278 exchanged->length, (uintptr_t)exchanged->data);
1279
1280 errOut:
1281 CFReleaseSafe(pubKeyData);
1282 return ortn;
1283 }