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 */
84extern 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 */
95extern 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 */
106CFIndex 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 */
118CFIndex 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 */
130OSStatus 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 */
193OSStatus 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
228OSStatus 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 */
260OSStatus 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 */
282OSStatus 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
349OSStatus 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 */
394size_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 */
410size_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 */
425OSStatus 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
445static 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 */
485OSStatus 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 */
511OSStatus 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 */
571OSStatus 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
691OSStatus
692sslCreateSecTrust(
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
739errOut:
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 */
751static
752SecCertificateRef
753sslGetMatchingCertInArray(
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 */
792extern 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
858errOut:
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 */
871extern OSStatus sslCopyPeerPubKey(
872	SSLContext 				*ctx,
873	SSLPubKey               **pubKey)
874{
875    check(pubKey);
876    check(ctx->peerSecTrust);
877
878    SecKeyRef key = SecTrustCopyPublicKey(ctx->peerSecTrust);
879    if (!key) {
880		sslErrorLog("sslCopyPeerPubKey: %s, ctx->peerSecTrust=%p\n",
881			"SecTrustCopyPublicKey failed", ctx->peerSecTrust);
882		return errSSLBadCert;
883	}
884    *pubKey = (SSLPubKey*)key;
885
886    return errSecSuccess;
887}
888
889#endif /* !USE_SSLCERTIFICATE */
890
891#ifndef	NDEBUG
892void stPrintCdsaError(const char *op, OSStatus crtn)
893{
894	assert(FALSE);
895}
896#endif
897
898/*
899 * After ciphersuite negotiation is complete, verify that we have
900 * the capability of actually performing the selected cipher.
901 * Currently we just verify that we have a cert and private signing
902 * key, if needed, and that the signing key's algorithm matches the
903 * expected key exchange method.
904 *
905 * This is currently called from FindCipherSpec(), after it sets
906 * ctx->selectedCipherSpec to a (supposedly) valid value, and from
907 * sslBuildCipherSpecArray(), in server mode (pre-negotiation) only.
908 */
909OSStatus sslVerifySelectedCipher(SSLContext *ctx)
910{
911    if(ctx->protocolSide == kSSLClientSide) {
912        return errSecSuccess;
913    }
914#if SSL_PAC_SERVER_ENABLE
915    if((ctx->masterSecretCallback != NULL) &&
916       (ctx->sessionTicket.data != NULL)) {
917            /* EAP via PAC resumption; we can do it */
918	return errSecSuccess;
919    }
920#endif	/* SSL_PAC_SERVER_ENABLE */
921
922    CFIndex requireAlg;
923    switch (ctx->selectedCipherSpecParams.keyExchangeMethod) {
924        case SSL_RSA:
925        case SSL_RSA_EXPORT:
926	case SSL_DH_RSA:
927	case SSL_DH_RSA_EXPORT:
928	case SSL_DHE_RSA:
929	case SSL_DHE_RSA_EXPORT:
930            requireAlg = kSecRSAAlgorithmID;
931            break;
932 	case SSL_DHE_DSS:
933	case SSL_DHE_DSS_EXPORT:
934 	case SSL_DH_DSS:
935	case SSL_DH_DSS_EXPORT:
936            requireAlg = kSecDSAAlgorithmID;
937            break;
938	case SSL_DH_anon:
939	case SSL_DH_anon_EXPORT:
940        case TLS_PSK:
941            requireAlg = kSecNullAlgorithmID; /* no signing key */
942            break;
943        /*
944         * When SSL_ECDSA_SERVER is true and we support ECDSA on the server side,
945         * we'll need to add some logic here...
946         */
947#if SSL_ECDSA_SERVER
948        case SSL_ECDHE_ECDSA:
949        case SSL_ECDHE_RSA:
950        case SSL_ECDH_ECDSA:
951        case SSL_ECDH_RSA:
952        case SSL_ECDH_anon:
953            requireAlg = kSecECDSAAlgorithmID;
954            break;
955#endif
956
957	default:
958            /* needs update per cipherSpecs.c */
959            assert(0);
960            sslErrorLog("sslVerifySelectedCipher: unknown key exchange method\n");
961            return errSSLInternal;
962    }
963
964    if(requireAlg == kSecNullAlgorithmID) {
965	return errSecSuccess;
966    }
967
968    /* private signing key required */
969    if(ctx->signingPrivKeyRef == NULL) {
970	sslErrorLog("sslVerifySelectedCipher: no signing key\n");
971	return errSSLBadConfiguration;
972    }
973
974    /* Check the alg of our signing key. */
975    CFIndex keyAlg = sslPrivKeyGetAlgorithmID(ctx->signingPrivKeyRef);
976    if (requireAlg != keyAlg) {
977	sslErrorLog("sslVerifySelectedCipher: signing key alg mismatch\n");
978	return errSSLBadConfiguration;
979    }
980
981    return errSecSuccess;
982}
983
984#if APPLE_DH
985
986/* FIXME: This is duplicated in SecDH */
987typedef struct {
988	DERItem				p;
989	DERItem				g;
990	DERItem				l;
991} DER_DHParams;
992
993static const DERItemSpec DER_DHParamsItemSpecs[] =
994{
995	{ DER_OFFSET(DER_DHParams, p),
996        ASN1_INTEGER,
997        DER_DEC_NO_OPTS | DER_ENC_SIGNED_INT },
998	{ DER_OFFSET(DER_DHParams, g),
999        ASN1_INTEGER,
1000        DER_DEC_NO_OPTS | DER_ENC_SIGNED_INT },
1001	{ DER_OFFSET(DER_DHParams, l),
1002        ASN1_INTEGER,
1003        DER_DEC_OPTIONAL | DER_ENC_SIGNED_INT },
1004};
1005static const DERSize DER_NumDHParamsItemSpecs =
1006sizeof(DER_DHParamsItemSpecs) / sizeof(DERItemSpec);
1007
1008/* Max encoded size for standard (PKCS3) parameters */
1009#define DH_ENCODED_PARAM_SIZE(primeSizeInBytes)					\
1010DER_MAX_ENCODED_SIZE(										\
1011DER_MAX_ENCODED_SIZE(primeSizeInBytes) +		/* g */		\
1012DER_MAX_ENCODED_SIZE(primeSizeInBytes) +		/* p */     \
1013DER_MAX_ENCODED_SIZE(4))                        /* l */
1014
1015
1016OSStatus sslDecodeDhParams(
1017	const SSLBuffer	*blob,			/* Input - PKCS-3 encoded */
1018	SSLBuffer		*prime,			/* Output - wire format */
1019	SSLBuffer		*generator)     /* Output - wire format */
1020{
1021    OSStatus ortn = errSecSuccess;
1022    DERReturn drtn;
1023	DERItem paramItem = {(DERByte *)blob->data, blob->length};
1024	DER_DHParams decodedParams;
1025
1026    drtn = DERParseSequence(&paramItem,
1027                            DER_NumDHParamsItemSpecs, DER_DHParamsItemSpecs,
1028                            &decodedParams, sizeof(decodedParams));
1029    if(drtn)
1030        return drtn;
1031
1032    prime->data = decodedParams.p.data;
1033    prime->length = decodedParams.p.length;
1034
1035    generator->data = decodedParams.g.data;
1036    generator->length = decodedParams.g.length;
1037
1038    return ortn;
1039}
1040
1041
1042OSStatus sslEncodeDhParams(SSLBuffer        *blob,			/* data mallocd and RETURNED PKCS-3 encoded */
1043                           const SSLBuffer	*prime,			/* Wire format */
1044                           const SSLBuffer	*generator)     /* Wire format */
1045{
1046    OSStatus ortn = errSecSuccess;
1047    DER_DHParams derParams =
1048    {
1049        .p = {
1050            .length = prime->length,
1051            .data = prime->data,
1052        },
1053        .g = {
1054            .length = generator->length,
1055            .data = generator->data,
1056        },
1057        .l = {
1058            .length = 0,
1059            .data = NULL,
1060        }
1061    };
1062
1063    DERSize ioLen = DH_ENCODED_PARAM_SIZE(derParams.p.length);
1064    DERByte *der = sslMalloc(ioLen);
1065    // FIXME: What if this fails - we should probably not have a malloc here ?
1066    assert(der);
1067    ortn = (OSStatus)DEREncodeSequence(ASN1_CONSTR_SEQUENCE,
1068                                       &derParams,
1069                                       DER_NumDHParamsItemSpecs, DER_DHParamsItemSpecs,
1070                                       der,
1071                                       &ioLen);
1072    // This should never fail
1073
1074    blob->length=ioLen;
1075    blob->data=der;
1076
1077    return ortn;
1078}
1079
1080OSStatus sslDhCreateKey(SSLContext *ctx)
1081{
1082    if (ctx->secDHContext) {
1083        SecDHDestroy(ctx->secDHContext);
1084        ctx->secDHContext = NULL;
1085    }
1086
1087    /* Server params are set using encoded dh params */
1088    if (!(ctx->dhParamsEncoded.length && ctx->dhParamsEncoded.data))
1089        return errSSLInternal;
1090
1091    if (SecDHCreateFromParameters(ctx->dhParamsEncoded.data,
1092        ctx->dhParamsEncoded.length, &ctx->secDHContext))
1093            return errSSLCrypto;
1094
1095    return errSecSuccess;
1096}
1097
1098OSStatus sslDhGenerateKeyPair(SSLContext *ctx)
1099{
1100    OSStatus ortn = errSecSuccess;
1101
1102    require_noerr(ortn = SSLAllocBuffer(&ctx->dhExchangePublic,
1103        SecDHGetMaxKeyLength(ctx->secDHContext)), out);
1104    require_noerr(ortn = SecDHGenerateKeypair(ctx->secDHContext,
1105        ctx->dhExchangePublic.data, &ctx->dhExchangePublic.length), out);
1106
1107out:
1108    return ortn;
1109}
1110
1111
1112OSStatus sslDhKeyExchange(SSLContext *ctx)
1113{
1114    OSStatus ortn = errSecSuccess;
1115
1116	if (ctx == NULL ||
1117        ctx->secDHContext == NULL ||
1118        ctx->dhPeerPublic.length == 0) {
1119		/* comes from peer, don't panic */
1120		sslErrorLog("sslDhKeyExchange: null peer public key\n");
1121		return errSSLProtocol;
1122	}
1123
1124    require_noerr(ortn = SSLAllocBuffer(&ctx->preMasterSecret,
1125        SecDHGetMaxKeyLength(ctx->secDHContext)), out);
1126    require_noerr(ortn = SecDHComputeKey(ctx->secDHContext,
1127        ctx->dhPeerPublic.data, ctx->dhPeerPublic.length,
1128        ctx->preMasterSecret.data, &ctx->preMasterSecret.length), out);
1129
1130	return ortn;
1131out:
1132	sslErrorLog("sslDhKeyExchange: failed to compute key (error %d)\n", (int)ortn);
1133	return ortn;
1134}
1135
1136#endif /* APPLE_DH */
1137
1138/*
1139 * Given an ECDSA key in SecKey format, extract the SSL_ECDSA_NamedCurve
1140 * from its algorithm parameters.
1141 */
1142OSStatus sslEcdsaPeerCurve(
1143	SSLPubKey *pubKey,
1144	SSL_ECDSA_NamedCurve *namedCurve)
1145{
1146    /* Cast is safe because enums are kept in sync. */
1147    *namedCurve = (SSL_ECDSA_NamedCurve)SecECKeyGetNamedCurve(SECKEYREF(pubKey));
1148    if (*namedCurve == kSecECCurveNone) {
1149        sslErrorLog("sslEcdsaPeerCurve: no named curve for public key\n");
1150        return errSSLProtocol;
1151    }
1152    return errSecSuccess;
1153}
1154
1155/*
1156 * Generate ECDH key pair with the given SSL_ECDSA_NamedCurve.
1157 * Private key, in ref form, is placed in ctx->ecdhPrivate.
1158 * Public key, in ECPoint form - which can NOT be used as
1159 * a key in any CSP ops - is placed in ecdhExchangePublic.
1160 */
1161OSStatus sslEcdhGenerateKeyPair(
1162	SSLContext *ctx,
1163	SSL_ECDSA_NamedCurve namedCurve)
1164{
1165	OSStatus ortn = errSecSuccess;
1166
1167    ccec_const_cp_t cp;
1168	switch (namedCurve) {
1169    case SSL_Curve_secp256r1:
1170        cp = ccec_cp_256();
1171        break;
1172    case SSL_Curve_secp384r1:
1173        cp = ccec_cp_384();
1174        break;
1175    case SSL_Curve_secp521r1:
1176        cp = ccec_cp_521();
1177        break;
1178    default:
1179        /* should not have gotten this far */
1180        sslErrorLog("sslEcdhGenerateKeyPair: bad namedCurve (%u)\n",
1181            (unsigned)namedCurve);
1182        return errSSLInternal;
1183	}
1184
1185    ccec_generate_key(cp, CCRNGSTATE, ctx->ecdhContext);
1186    size_t pub_size = ccec_export_pub_size(ctx->ecdhContext);
1187    SSLFreeBuffer(&ctx->ecdhExchangePublic);
1188    require_noerr(ortn = SSLAllocBuffer(&ctx->ecdhExchangePublic,
1189                                        pub_size), errOut);
1190    ccec_export_pub(ctx->ecdhContext, ctx->ecdhExchangePublic.data);
1191
1192	sslDebugLog("sslEcdhGenerateKeyPair: pub key size=%ld, data=%p\n",
1193		pub_size, ctx->ecdhExchangePublic.data);
1194
1195errOut:
1196	return ortn;
1197}
1198
1199/*
1200 * Perform ECDH key exchange. Obtained key material is the same
1201 * size as our private key.
1202 *
1203 * On entry, ecdhPrivate is our private key. The peer's public key
1204 * is either ctx->ecdhPeerPublic for ECDHE exchange, or
1205 * ctx->peerPubKey for ECDH exchange.
1206 */
1207OSStatus sslEcdhKeyExchange(
1208	SSLContext		*ctx,
1209	SSLBuffer		*exchanged)
1210{
1211	OSStatus ortn = errSecSuccess;
1212    CFDataRef pubKeyData = NULL;
1213    const unsigned char *pubKeyBits;
1214    unsigned long pubKeyLen;
1215
1216	switch(ctx->selectedCipherSpecParams.keyExchangeMethod) {
1217		case SSL_ECDHE_ECDSA:
1218		case SSL_ECDHE_RSA:
1219			/* public key passed in as CSSM_DATA *Param */
1220			if(ctx->ecdhPeerPublic.length == 0) {
1221				/* comes from peer, don't panic */
1222				sslErrorLog("sslEcdhKeyExchange: null peer public key\n");
1223				ortn = errSSLProtocol;
1224				goto errOut;
1225			}
1226            pubKeyBits = ctx->ecdhPeerPublic.data;
1227            pubKeyLen = ctx->ecdhPeerPublic.length;
1228			break;
1229		case SSL_ECDH_ECDSA:
1230		case SSL_ECDH_RSA:
1231			/* Use the public key provided by the peer. */
1232			if(ctx->peerPubKey == NULL) {
1233			   sslErrorLog("sslEcdhKeyExchange: no peer key\n");
1234			   ortn = errSSLInternal;
1235			   goto errOut;
1236			}
1237
1238            pubKeyData = SecECKeyCopyPublicBits(SECKEYREF(ctx->peerPubKey));
1239            if (!pubKeyData) {
1240				sslErrorLog("sslEcdhKeyExchange: SecECKeyCopyPublicBits failed\n");
1241				ortn = errSSLProtocol;
1242				goto errOut;
1243            }
1244            pubKeyBits = CFDataGetBytePtr(pubKeyData);
1245            pubKeyLen = CFDataGetLength(pubKeyData);
1246			break;
1247		default:
1248			/* shouldn't be here */
1249			sslErrorLog("sslEcdhKeyExchange: unknown keyExchangeMethod (%d)\n",
1250				ctx->selectedCipherSpecParams.keyExchangeMethod);
1251			assert(0);
1252			ortn = errSSLInternal;
1253			goto errOut;
1254	}
1255
1256    ccec_const_cp_t cp = ccec_ctx_cp(ctx->ecdhContext);
1257    ccec_pub_ctx_decl(ccn_sizeof(521), pubKey);
1258    ccec_import_pub(cp, pubKeyLen, pubKeyBits, pubKey);
1259    size_t len = 1 + 2 * ccec_ccn_size(cp);
1260    require_noerr(ortn = SSLAllocBuffer(exchanged, len), errOut);
1261    require_noerr(ccec_compute_key(ctx->ecdhContext, pubKey,  &exchanged->length, exchanged->data), errOut);
1262
1263	sslDebugLog("sslEcdhKeyExchange: exchanged key length=%ld, data=%p\n",
1264		exchanged->length, exchanged->data);
1265
1266errOut:
1267    CFReleaseSafe(pubKeyData);
1268	return ortn;
1269}
1270