2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
22 Contains: SSLContext accessors
24 Written by: Doug Mitchell
26 Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
31 #include "sslContext.h"
32 #include "sslMemory.h"
33 #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
34 #include "sslDigests.h"
36 #include "appleCdsa.h"
37 #include "sslKeychain.h"
39 #include "cipherSpecs.h"
40 #include "appleSession.h"
43 #include <Security/SecCertificate.h>
44 #include <Security/SecTrust.h>
46 static void sslFreeDnList(
49 DNListElem
*dn
, *nextDN
;
51 dn
= ctx
->acceptableDNList
;
54 SSLFreeBuffer(dn
->derDN
, ctx
);
59 ctx
->acceptableDNList
= NULL
;
62 static OSStatus
sslFreeTrustedRoots(
68 if((ctx
->numTrustedCerts
== 0) || (ctx
->trustedCerts
== NULL
)) {
69 /* they really should both be zero, right? */
70 assert((ctx
->numTrustedCerts
== 0) && (ctx
->trustedCerts
== NULL
));
73 for(i
=0; i
<ctx
->numTrustedCerts
; i
++) {
74 stFreeCssmData(&ctx
->trustedCerts
[i
], CSSM_FALSE
);
76 sslFree(ctx
->trustedCerts
);
78 ctx
->numTrustedCerts
= 0;
79 ctx
->trustedCerts
= NULL
;
85 * Default version enables.
87 #define DEFAULT_SSL2_ENABLE true
88 #define DEFAULT_SSL3_ENABLE true
89 #define DEFAULT_TLS1_ENABLE true
92 SSLNewContext (Boolean isServer
,
93 SSLContextRef
*contextPtr
) /* RETURNED */
98 if(contextPtr
== NULL
) {
102 ctx
= (SSLContext
*)sslMalloc(sizeof(SSLContext
));
106 /* subsequent errors to errOut: */
108 memset(ctx
, 0, sizeof(SSLContext
));
109 ctx
->state
= SSL_HdskStateUninit
;
110 ctx
->clientCertState
= kSSLClientCertNone
;
112 ctx
->versionSsl2Enable
= DEFAULT_SSL2_ENABLE
;
113 ctx
->versionSsl3Enable
= DEFAULT_SSL3_ENABLE
;
114 ctx
->versionTls1Enable
= DEFAULT_TLS1_ENABLE
;
115 ctx
->negProtocolVersion
= SSL_Version_Undetermined
;
118 ctx
->protocolSide
= SSL_ServerSide
;
121 ctx
->protocolSide
= SSL_ClientSide
;
124 /* Default value so we can send and receive hello msgs */
125 ctx
->sslTslCalls
= &Ssl3Callouts
;
127 /* Initialize the cipher state to NULL_WITH_NULL_NULL */
128 ctx
->selectedCipherSpec
= &SSL_NULL_WITH_NULL_NULL_CipherSpec
;
129 ctx
->selectedCipher
= ctx
->selectedCipherSpec
->cipherSpec
;
130 ctx
->writeCipher
.macRef
= ctx
->selectedCipherSpec
->macAlgorithm
;
131 ctx
->readCipher
.macRef
= ctx
->selectedCipherSpec
->macAlgorithm
;
132 ctx
->readCipher
.symCipher
= ctx
->selectedCipherSpec
->cipher
;
133 ctx
->writeCipher
.symCipher
= ctx
->selectedCipherSpec
->cipher
;
135 /* these two are invariant */
136 ctx
->writeCipher
.encrypting
= 1;
137 ctx
->writePending
.encrypting
= 1;
139 /* this gets init'd on first call to SSLHandshake() */
140 ctx
->validCipherSpecs
= NULL
;
141 ctx
->numValidCipherSpecs
= 0;
143 ctx
->peerDomainName
= NULL
;
144 ctx
->peerDomainNameLen
= 0;
146 /* attach to CSP, CL, TP */
147 serr
= attachToAll(ctx
);
152 /* Initial cert verify state: verify with default system roots */
153 ctx
->enableCertVerify
= true;
155 /* Default for RSA blinding is ENABLED */
156 ctx
->rsaBlindingEnable
= true;
168 * Dispose of an SSLContext.
171 SSLDisposeContext (SSLContext
*ctx
)
173 WaitingRecord
*wait
, *next
;
179 sslDeleteCertificateChain(ctx
->localCert
, ctx
);
180 sslDeleteCertificateChain(ctx
->encryptCert
, ctx
);
181 sslDeleteCertificateChain(ctx
->peerCert
, ctx
);
182 ctx
->localCert
= ctx
->encryptCert
= ctx
->peerCert
= NULL
;
183 SSLFreeBuffer(ctx
->partialReadBuffer
, ctx
);
184 if(ctx
->peerSecTrust
) {
185 CFRelease(ctx
->peerSecTrust
);
186 ctx
->peerSecTrust
= NULL
;
188 wait
= ctx
->recordWriteQueue
;
190 { SSLFreeBuffer(wait
->data
, ctx
);
192 buf
.data
= (uint8
*)wait
;
193 buf
.length
= sizeof(WaitingRecord
);
194 SSLFreeBuffer(buf
, ctx
);
199 SSLFreeBuffer(ctx
->dhParamsPrime
, ctx
);
200 SSLFreeBuffer(ctx
->dhParamsGenerator
, ctx
);
201 SSLFreeBuffer(ctx
->dhParamsEncoded
, ctx
);
202 SSLFreeBuffer(ctx
->dhPeerPublic
, ctx
);
203 SSLFreeBuffer(ctx
->dhExchangePublic
, ctx
);
204 sslFreeKey(ctx
->cspHand
, &ctx
->dhPrivate
, NULL
);
205 #endif /* APPLE_DH */
207 CloseHash(SSLHashSHA1
, ctx
->shaState
, ctx
);
208 CloseHash(SSLHashMD5
, ctx
->md5State
, ctx
);
210 SSLFreeBuffer(ctx
->sessionID
, ctx
);
211 SSLFreeBuffer(ctx
->peerID
, ctx
);
212 SSLFreeBuffer(ctx
->resumableSession
, ctx
);
213 SSLFreeBuffer(ctx
->preMasterSecret
, ctx
);
214 SSLFreeBuffer(ctx
->partialReadBuffer
, ctx
);
215 SSLFreeBuffer(ctx
->fragmentedMessageCache
, ctx
);
216 SSLFreeBuffer(ctx
->receivedDataBuffer
, ctx
);
218 if(ctx
->peerDomainName
) {
219 sslFree(ctx
->peerDomainName
);
220 ctx
->peerDomainName
= NULL
;
221 ctx
->peerDomainNameLen
= 0;
223 SSLDisposeCipherSuite(&ctx
->readCipher
, ctx
);
224 SSLDisposeCipherSuite(&ctx
->writeCipher
, ctx
);
225 SSLDisposeCipherSuite(&ctx
->readPending
, ctx
);
226 SSLDisposeCipherSuite(&ctx
->writePending
, ctx
);
228 sslFree(ctx
->validCipherSpecs
);
229 ctx
->validCipherSpecs
= NULL
;
230 ctx
->numValidCipherSpecs
= 0;
233 * NOTE: currently, all public keys come from the CL via CSSM_CL_CertGetKeyInfo.
234 * We really don't know what CSP the CL used to generate a public key (in fact,
235 * it uses the raw CSP only to get LogicalKeySizeInBits, but we can't know
236 * that). Thus using e.g. signingKeyCsp (or any other CSP) to free
237 * signingPubKey is not tecnically accurate. However, our public keys
238 * are all raw keys, and all Apple CSPs dispose of raw keys in the same
241 sslFreeKey(ctx
->signingKeyCsp
, &ctx
->signingPubKey
, NULL
);
242 sslFreeKey(ctx
->encryptKeyCsp
, &ctx
->encryptPubKey
, NULL
);
243 sslFreeKey(ctx
->peerPubKeyCsp
, &ctx
->peerPubKey
, NULL
);
245 sslFreeTrustedRoots(ctx
);
249 memset(ctx
, 0, sizeof(SSLContext
));
256 * Determine the state of an SSL session.
259 SSLGetSessionState (SSLContextRef context
,
260 SSLSessionState
*state
) /* RETURNED */
262 SSLSessionState rtnState
= kSSLIdle
;
264 if(context
== NULL
) {
268 switch(context
->state
) {
269 case SSL_HdskStateUninit
:
270 case SSL_HdskStateServerUninit
:
271 case SSL_HdskStateClientUninit
:
274 case SSL_HdskStateGracefulClose
:
275 rtnState
= kSSLClosed
;
277 case SSL_HdskStateErrorClose
:
278 case SSL_HdskStateNoNotifyClose
:
279 rtnState
= kSSLAborted
;
281 case SSL_HdskStateServerReady
:
282 case SSL_HdskStateClientReady
:
283 rtnState
= kSSLConnected
;
286 assert((context
->state
>= SSL_HdskStateServerHello
) &&
287 (context
->state
<= SSL2_HdskStateServerFinished
));
288 rtnState
= kSSLHandshake
;
297 SSLSetIOFuncs (SSLContextRef ctx
,
304 if(sslIsSessionActive(ctx
)) {
305 /* can't do this with an active session */
308 ctx
->ioCtx
.read
= read
;
309 ctx
->ioCtx
.write
= write
;
314 SSLSetConnection (SSLContextRef ctx
,
315 SSLConnectionRef connection
)
320 if(sslIsSessionActive(ctx
)) {
321 /* can't do this with an active session */
324 ctx
->ioCtx
.ioRef
= connection
;
329 SSLGetConnection (SSLContextRef ctx
,
330 SSLConnectionRef
*connection
)
332 if((ctx
== NULL
) || (connection
== NULL
)) {
335 *connection
= ctx
->ioCtx
.ioRef
;
340 SSLSetPeerDomainName (SSLContextRef ctx
,
341 const char *peerName
,
347 if(sslIsSessionActive(ctx
)) {
348 /* can't do this with an active session */
352 /* free possible existing name */
353 if(ctx
->peerDomainName
) {
354 sslFree(ctx
->peerDomainName
);
358 ctx
->peerDomainName
= (char *)sslMalloc(peerNameLen
);
359 if(ctx
->peerDomainName
== NULL
) {
362 memmove(ctx
->peerDomainName
, peerName
, peerNameLen
);
363 ctx
->peerDomainNameLen
= peerNameLen
;
368 * Determine the buffer size needed for SSLGetPeerDomainName().
371 SSLGetPeerDomainNameLength (SSLContextRef ctx
,
372 size_t *peerNameLen
) // RETURNED
377 *peerNameLen
= ctx
->peerDomainNameLen
;
382 SSLGetPeerDomainName (SSLContextRef ctx
,
383 char *peerName
, // returned here
384 size_t *peerNameLen
) // IN/OUT
389 if(*peerNameLen
< ctx
->peerDomainNameLen
) {
390 return errSSLBufferOverflow
;
392 memmove(peerName
, ctx
->peerDomainName
, ctx
->peerDomainNameLen
);
393 *peerNameLen
= ctx
->peerDomainNameLen
;
397 /* concert between private SSLProtocolVersion and public SSLProtocol */
398 static SSLProtocol
convertProtToExtern(SSLProtocolVersion prot
)
401 case SSL_Version_Undetermined
:
402 return kSSLProtocolUnknown
;
403 case SSL_Version_2_0
:
404 return kSSLProtocol2
;
405 case SSL_Version_3_0
:
406 return kSSLProtocol3
;
407 case TLS_Version_1_0
:
408 return kTLSProtocol1
;
410 sslErrorLog("convertProtToExtern: bad prot\n");
411 return kSSLProtocolUnknown
;
413 /* not reached but make compiler happy */
414 return kSSLProtocolUnknown
;
418 SSLSetProtocolVersionEnabled(SSLContextRef ctx
,
419 SSLProtocol protocol
,
420 Boolean enable
) /* RETURNED */
425 if(sslIsSessionActive(ctx
)) {
426 /* can't do this with an active session */
431 ctx
->versionSsl2Enable
= enable
;
434 ctx
->versionSsl3Enable
= enable
;
437 ctx
->versionTls1Enable
= enable
;
439 case kSSLProtocolAll
:
440 ctx
->versionTls1Enable
= ctx
->versionSsl3Enable
=
441 ctx
->versionSsl2Enable
= enable
;
450 SSLGetProtocolVersionEnabled(SSLContextRef ctx
,
451 SSLProtocol protocol
,
452 Boolean
*enable
) /* RETURNED */
459 *enable
= ctx
->versionSsl2Enable
;
462 *enable
= ctx
->versionSsl3Enable
;
465 *enable
= ctx
->versionTls1Enable
;
467 case kSSLProtocolAll
:
468 if(ctx
->versionTls1Enable
&& ctx
->versionSsl3Enable
&&
469 ctx
->versionSsl2Enable
) {
484 SSLSetProtocolVersion (SSLContextRef ctx
,
490 if(sslIsSessionActive(ctx
)) {
491 /* can't do this with an active session */
495 /* convert external representation to three booleans */
497 case kSSLProtocolUnknown
:
498 ctx
->versionSsl2Enable
= DEFAULT_SSL2_ENABLE
;
499 ctx
->versionSsl3Enable
= DEFAULT_SSL3_ENABLE
;
500 ctx
->versionTls1Enable
= DEFAULT_TLS1_ENABLE
;
503 ctx
->versionSsl2Enable
= true;
504 ctx
->versionSsl3Enable
= false;
505 ctx
->versionTls1Enable
= false;
508 /* this tells us to do our best, up to 3.0, but allows 2.0 */
509 ctx
->versionSsl2Enable
= true;
510 ctx
->versionSsl3Enable
= true;
511 ctx
->versionTls1Enable
= false;
513 case kSSLProtocol3Only
:
514 ctx
->versionSsl2Enable
= false;
515 ctx
->versionSsl3Enable
= true;
516 ctx
->versionTls1Enable
= false;
519 case kSSLProtocolAll
:
520 /* this tells us to do our best, up to TLS, but allows 2.0 or 3.0 */
521 ctx
->versionSsl2Enable
= true;
522 ctx
->versionSsl3Enable
= true;
523 ctx
->versionTls1Enable
= true;
525 case kTLSProtocol1Only
:
526 ctx
->versionSsl2Enable
= false;
527 ctx
->versionSsl3Enable
= false;
528 ctx
->versionTls1Enable
= true;
538 SSLGetProtocolVersion (SSLContextRef ctx
,
539 SSLProtocol
*protocol
) /* RETURNED */
545 /* translate array of booleans to public value; not all combinations
546 * are legal (i.e., meaningful) for this call */
547 if(ctx
->versionTls1Enable
) {
548 if(ctx
->versionSsl2Enable
) {
549 if(ctx
->versionSsl3Enable
) {
550 /* traditional 'all enabled' */
551 *protocol
= kTLSProtocol1
;
555 /* SSL2 true, SSL3 false, TLS1 true - invalid here */
559 else if(ctx
->versionSsl3Enable
) {
560 /* SSL2 false, SSL3 true, TLS1 true - invalid here */
564 *protocol
= kTLSProtocol1Only
;
570 if(ctx
->versionSsl3Enable
) {
571 *protocol
= ctx
->versionSsl2Enable
?
572 kSSLProtocol3
: kSSLProtocol3Only
;
575 else if(ctx
->versionSsl2Enable
) {
576 *protocol
= kSSLProtocol2
;
581 * Bogus state - no enables - the API does provide a way
582 * to get into this state. Other than this path, the app
583 * will discover this bogon when attempting to do the
584 * handshake; sslGetMaxProtVersion will detect this.
593 SSLGetNegotiatedProtocolVersion (SSLContextRef ctx
,
594 SSLProtocol
*protocol
) /* RETURNED */
599 *protocol
= convertProtToExtern(ctx
->negProtocolVersion
);
604 SSLSetEnableCertVerify (SSLContextRef ctx
,
605 Boolean enableVerify
)
610 sslCertDebug("SSLSetEnableCertVerify %s",
611 enableVerify
? "true" : "false");
612 if(sslIsSessionActive(ctx
)) {
613 /* can't do this with an active session */
616 ctx
->enableCertVerify
= enableVerify
;
621 SSLGetEnableCertVerify (SSLContextRef ctx
,
622 Boolean
*enableVerify
)
627 *enableVerify
= ctx
->enableCertVerify
;
632 SSLSetAllowsExpiredCerts(SSLContextRef ctx
,
633 Boolean allowExpired
)
638 sslCertDebug("SSLSetAllowsExpiredCerts %s",
639 allowExpired
? "true" : "false");
640 if(sslIsSessionActive(ctx
)) {
641 /* can't do this with an active session */
644 ctx
->allowExpiredCerts
= allowExpired
;
649 SSLGetAllowsExpiredCerts (SSLContextRef ctx
,
650 Boolean
*allowExpired
)
655 *allowExpired
= ctx
->allowExpiredCerts
;
660 SSLSetAllowsExpiredRoots(SSLContextRef ctx
,
661 Boolean allowExpired
)
666 sslCertDebug("SSLSetAllowsExpiredRoots %s",
667 allowExpired
? "true" : "false");
668 if(sslIsSessionActive(ctx
)) {
669 /* can't do this with an active session */
672 ctx
->allowExpiredRoots
= allowExpired
;
677 SSLGetAllowsExpiredRoots (SSLContextRef ctx
,
678 Boolean
*allowExpired
)
683 *allowExpired
= ctx
->allowExpiredRoots
;
687 OSStatus
SSLSetAllowsAnyRoot(
694 sslCertDebug("SSLSetAllowsAnyRoot %s", anyRoot
? "true" : "false");
695 ctx
->allowAnyRoot
= anyRoot
;
707 *anyRoot
= ctx
->allowAnyRoot
;
712 SSLSetTrustedRoots (SSLContextRef ctx
,
713 CFArrayRef trustedRoots
,
714 Boolean replaceExisting
)
718 unsigned numIncoming
;
720 CSSM_DATA_PTR newRoots
= NULL
;
721 const CSSM_DATA
*existAnchors
= NULL
;
722 uint32 numExistAnchors
= 0;
723 OSStatus ortn
= noErr
;
728 if(sslIsSessionActive(ctx
)) {
729 /* can't do this with an active session */
732 numCerts
= numIncoming
= CFArrayGetCount(trustedRoots
);
733 sslCertDebug("SSLSetTrustedRoot numCerts %d replaceExist %s",
734 (int)numCerts
, replaceExisting
? "true" : "false");
735 if(!replaceExisting
) {
736 if(ctx
->trustedCerts
!= NULL
) {
737 /* adding to existing store */
738 existAnchors
= ctx
->trustedCerts
;
739 numExistAnchors
= ctx
->numTrustedCerts
;
742 /* adding to system roots */
743 ortn
= SecTrustGetCSSMAnchorCertificates(&existAnchors
,
746 /* should never happen */
750 numCerts
+= numExistAnchors
;
752 newRoots
= (CSSM_DATA_PTR
)sslMalloc(numCerts
* sizeof(CSSM_DATA
));
753 memset(newRoots
, 0, numCerts
* sizeof(CSSM_DATA
));
755 /* Caller's certs first */
756 for(dex
=0, outDex
=0; dex
<numIncoming
; dex
++, outDex
++) {
758 SecCertificateRef secCert
= (SecCertificateRef
)
759 CFArrayGetValueAtIndex(trustedRoots
, dex
);
761 if(CFGetTypeID(secCert
) != SecCertificateGetTypeID()) {
762 /* elements of trustedRoots must be SecCertificateRefs */
766 ortn
= SecCertificateGetData(secCert
, &certData
);
770 stSetUpCssmData(&newRoots
[outDex
], certData
.Length
);
771 memmove(newRoots
[outDex
].Data
, certData
.Data
, certData
.Length
);
774 /* now existing roots - either ours, or the system's */
775 for(dex
=0; dex
<numExistAnchors
; dex
++, outDex
++) {
776 stSetUpCssmData(&newRoots
[outDex
], existAnchors
[dex
].Length
);
777 memmove(newRoots
[outDex
].Data
, existAnchors
[dex
].Data
,
778 existAnchors
[dex
].Length
);
781 /* success - replace context values */
782 sslFreeTrustedRoots(ctx
);
783 ctx
->numTrustedCerts
= numCerts
;
784 ctx
->trustedCerts
= newRoots
;
793 SSLGetTrustedRoots (SSLContextRef ctx
,
794 CFArrayRef
*trustedRoots
) /* RETURNED */
797 const CSSM_DATA
*certs
;
798 CFMutableArrayRef certArray
;
800 SecCertificateRef secCert
;
806 if(ctx
->trustedCerts
!= NULL
) {
808 certs
= ctx
->trustedCerts
;
809 numCerts
= ctx
->numTrustedCerts
;
812 /* use default system roots */
813 OSStatus ortn
= SecTrustGetCSSMAnchorCertificates(&certs
,
816 /* should never happen */
821 certArray
= CFArrayCreateMutable(kCFAllocatorDefault
,
822 (CFIndex
)numCerts
, &kCFTypeArrayCallBacks
);
823 if(certArray
== NULL
) {
826 for(dex
=0; dex
<numCerts
; dex
++) {
827 ortn
= SecCertificateCreateFromData(&certs
[dex
],
829 CSSM_CERT_ENCODING_DER
,
832 CFRelease(certArray
);
835 CFArrayAppendValue(certArray
, secCert
);
837 *trustedRoots
= certArray
;
842 SSLSetClientSideAuthenticate (SSLContext
*ctx
,
843 SSLAuthenticate auth
)
848 if(sslIsSessionActive(ctx
)) {
849 /* can't do this with an active session */
852 ctx
->clientAuth
= auth
;
854 case kNeverAuthenticate
:
855 ctx
->tryClientAuth
= false;
857 case kAlwaysAuthenticate
:
858 case kTryAuthenticate
:
859 ctx
->tryClientAuth
= true;
866 SSLGetClientCertificateState (SSLContextRef ctx
,
867 SSLClientCertificateState
*clientState
)
872 *clientState
= ctx
->clientCertState
;
877 SSLSetCertificate (SSLContextRef ctx
,
881 * -- free localCerts if we have any
882 * -- Get raw cert data, convert to ctx->localCert
883 * -- get pub, priv keys from certRef[0]
884 * -- validate cert chain
889 if(sslIsSessionActive(ctx
)) {
890 /* can't do this with an active session */
893 return parseIncomingCerts(ctx
,
897 &ctx
->signingPrivKey
,
899 #if ST_KC_KEYS_NEED_REF
908 SSLSetEncryptionCertificate (SSLContextRef ctx
,
912 * -- free encryptCert if we have any
913 * -- Get raw cert data, convert to ctx->encryptCert
914 * -- get pub, priv keys from certRef[0]
915 * -- validate cert chain
920 if(sslIsSessionActive(ctx
)) {
921 /* can't do this with an active session */
924 return parseIncomingCerts(ctx
,
928 &ctx
->encryptPrivKey
,
929 &ctx
->encryptKeyCsp
);
933 SSLSetPeerID (SSLContext
*ctx
,
939 /* copy peerId to context->peerId */
945 if(sslIsSessionActive(ctx
)) {
946 /* can't do this with an active session */
949 SSLFreeBuffer(ctx
->peerID
, ctx
);
950 serr
= SSLAllocBuffer(ctx
->peerID
, peerIDLen
, ctx
);
954 memmove(ctx
->peerID
.data
, peerID
, peerIDLen
);
959 SSLGetPeerID (SSLContextRef ctx
,
963 *peerID
= ctx
->peerID
.data
; // may be NULL
964 *peerIDLen
= ctx
->peerID
.length
;
969 SSLGetNegotiatedCipher (SSLContextRef ctx
,
970 SSLCipherSuite
*cipherSuite
)
975 if(!sslIsSessionActive(ctx
)) {
978 *cipherSuite
= (SSLCipherSuite
)ctx
->selectedCipher
;
983 * Add an acceptable distinguished name (client authentication only).
986 SSLAddDistinguishedName(
994 dn
= (DNListElem
*)sslMalloc(sizeof(DNListElem
));
998 if ((err
= SSLAllocBuffer(dn
->derDN
, derDNLen
, ctx
)) != 0)
1000 memcpy(dn
->derDN
.data
, derDN
, derDNLen
);
1001 dn
->next
= ctx
->acceptableDNList
;
1002 ctx
->acceptableDNList
= dn
;
1007 * Request peer certificates. Valid anytime, subsequent to
1008 * a handshake attempt.
1011 SSLGetPeerCertificates (SSLContextRef ctx
,
1015 CFMutableArrayRef ca
;
1017 SecCertificateRef cfd
;
1020 SSLCertificate
*scert
;
1028 * Copy peerCert, a chain of SSLCertificates, to a CFArray of
1029 * CFDataRefs, each of which is one DER-encoded cert.
1031 numCerts
= SSLGetCertificateChainLength(ctx
->peerCert
);
1035 ca
= CFArrayCreateMutable(kCFAllocatorDefault
,
1036 (CFIndex
)numCerts
, &kCFTypeArrayCallBacks
);
1042 * Caller gets leaf cert first, the opposite of the way we store them.
1044 scert
= ctx
->peerCert
;
1045 for(i
=0; (unsigned)i
<numCerts
; i
++) {
1046 assert(scert
!= NULL
); /* else SSLGetCertificateChainLength
1048 SSLBUF_TO_CSSM(&scert
->derCert
, &certData
);
1049 ortn
= SecCertificateCreateFromData(&certData
,
1051 CSSM_CERT_ENCODING_DER
,
1057 /* insert at head of array */
1058 CFArrayInsertValueAtIndex(ca
, 0, cfd
);
1059 scert
= scert
->next
;
1066 * Specify Diffie-Hellman parameters. Optional; if we are configured to allow
1067 * for D-H ciphers and a D-H cipher is negotiated, and this function has not
1068 * been called, a set of process-wide parameters will be calculated. However
1069 * that can take a long time (30 seconds).
1071 OSStatus
SSLSetDiffieHellmanParams(
1073 const void *dhParams
,
1079 if(sslIsSessionActive(ctx
)) {
1082 SSLFreeBuffer(ctx
->dhParamsPrime
, ctx
);
1083 SSLFreeBuffer(ctx
->dhParamsGenerator
, ctx
);
1084 SSLFreeBuffer(ctx
->dhParamsEncoded
, ctx
);
1087 ortn
= SSLCopyBufferFromData(dhParams
, dhParamsLen
,
1088 ctx
->dhParamsEncoded
);
1093 /* decode for use by server over the wire */
1095 sParams
.data
= (UInt8
*)dhParams
;
1096 sParams
.length
= dhParamsLen
;
1097 return sslDecodeDhParams(&sParams
, &ctx
->dhParamsPrime
,
1098 &ctx
->dhParamsGenerator
);
1102 * Return parameter block specified in SSLSetDiffieHellmanParams.
1103 * Returned data is not copied and belongs to the SSLContextRef.
1105 OSStatus
SSLGetDiffieHellmanParams(
1107 const void **dhParams
,
1108 size_t *dhParamsLen
)
1113 *dhParams
= ctx
->dhParamsEncoded
.data
;
1114 *dhParamsLen
= ctx
->dhParamsEncoded
.length
;
1118 OSStatus
SSLSetRsaBlinding(
1125 ctx
->rsaBlindingEnable
= blinding
;
1129 OSStatus
SSLGetRsaBlinding(
1136 *blinding
= ctx
->rsaBlindingEnable
;
1140 OSStatus
SSLGetPeerSecTrust(
1142 SecTrustRef
*secTrust
) /* RETURNED */
1147 *secTrust
= ctx
->peerSecTrust
;
1151 OSStatus
SSLInternalMasterSecret(
1153 void *secret
, // mallocd by caller, SSL_MASTER_SECRET_SIZE
1154 size_t *secretSize
) // in/out
1156 if((ctx
== NULL
) || (secret
== NULL
) || (secretSize
== NULL
)) {
1159 if(*secretSize
< SSL_MASTER_SECRET_SIZE
) {
1162 memmove(secret
, ctx
->masterSecret
, SSL_MASTER_SECRET_SIZE
);
1163 *secretSize
= SSL_MASTER_SECRET_SIZE
;
1167 OSStatus
SSLInternalServerRandom(
1169 void *rand
, // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
1170 size_t *randSize
) // in/out
1172 if((ctx
== NULL
) || (rand
== NULL
) || (randSize
== NULL
)) {
1175 if(*randSize
< SSL_CLIENT_SRVR_RAND_SIZE
) {
1178 memmove(rand
, ctx
->serverRandom
, SSL_CLIENT_SRVR_RAND_SIZE
);
1179 *randSize
= SSL_CLIENT_SRVR_RAND_SIZE
;
1183 OSStatus
SSLInternalClientRandom(
1185 void *rand
, // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
1186 size_t *randSize
) // in/out
1188 if((ctx
== NULL
) || (rand
== NULL
) || (randSize
== NULL
)) {
1191 if(*randSize
< SSL_CLIENT_SRVR_RAND_SIZE
) {
1194 memmove(rand
, ctx
->clientRandom
, SSL_CLIENT_SRVR_RAND_SIZE
);
1195 *randSize
= SSL_CLIENT_SRVR_RAND_SIZE
;
1200 SSLGetResumableSessionInfo(
1202 Boolean
*sessionWasResumed
, // RETURNED
1203 void *sessionID
, // RETURNED, mallocd by caller
1204 size_t *sessionIDLength
) // IN/OUT
1206 if((ctx
== NULL
) || (sessionWasResumed
== NULL
) ||
1207 (sessionID
== NULL
) || (sessionIDLength
== NULL
) ||
1208 (*sessionIDLength
< MAX_SESSION_ID_LENGTH
)) {
1211 if(ctx
->sessionMatch
) {
1212 assert(ctx
->sessionID
.data
!= NULL
);
1213 *sessionWasResumed
= true;
1214 if(ctx
->sessionID
.length
> *sessionIDLength
) {
1215 /* really should never happen - means ID > 32 */
1218 memmove(sessionID
, ctx
->sessionID
.data
, ctx
->sessionID
.length
);
1219 *sessionIDLength
= ctx
->sessionID
.length
;
1222 *sessionWasResumed
= false;
1223 *sessionIDLength
= 0;