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"
42 #include <Security/SecCertificate.h>
43 #include <Security/SecTrust.h>
45 static void sslFreeDnList(
48 DNListElem
*dn
, *nextDN
;
50 dn
= ctx
->acceptableDNList
;
53 SSLFreeBuffer(dn
->derDN
, ctx
);
58 ctx
->acceptableDNList
= NULL
;
61 static OSStatus
sslFreeTrustedRoots(
67 if((ctx
->numTrustedCerts
== 0) || (ctx
->trustedCerts
== NULL
)) {
68 /* they really should both be zero, right? */
69 assert((ctx
->numTrustedCerts
== 0) && (ctx
->trustedCerts
== NULL
));
72 for(i
=0; i
<ctx
->numTrustedCerts
; i
++) {
73 stFreeCssmData(&ctx
->trustedCerts
[i
], CSSM_FALSE
);
75 sslFree(ctx
->trustedCerts
);
77 ctx
->numTrustedCerts
= 0;
78 ctx
->trustedCerts
= NULL
;
84 * Default attempted version.
86 #define DEFAULT_MAX_VERSION TLS_Version_1_0
89 SSLNewContext (Boolean isServer
,
90 SSLContextRef
*contextPtr
) /* RETURNED */
95 if(contextPtr
== NULL
) {
99 ctx
= (SSLContext
*)sslMalloc(sizeof(SSLContext
));
103 /* subsequent errors to errOut: */
105 memset(ctx
, 0, sizeof(SSLContext
));
106 ctx
->state
= SSL_HdskStateUninit
;
107 ctx
->clientCertState
= kSSLClientCertNone
;
109 /* different defaults for client and server ... */
111 ctx
->protocolSide
= SSL_ServerSide
;
112 ctx
->reqProtocolVersion
= DEFAULT_MAX_VERSION
;
115 ctx
->protocolSide
= SSL_ClientSide
;
116 ctx
->reqProtocolVersion
= SSL_Version_Undetermined
;
118 ctx
->negProtocolVersion
= SSL_Version_Undetermined
;
119 ctx
->maxProtocolVersion
= DEFAULT_MAX_VERSION
;
120 /* Default value so we can send and receive hello msgs */
121 ctx
->sslTslCalls
= &Ssl3Callouts
;
123 /* Initialize the cipher state to NULL_WITH_NULL_NULL */
124 ctx
->selectedCipherSpec
= &SSL_NULL_WITH_NULL_NULL_CipherSpec
;
125 ctx
->selectedCipher
= ctx
->selectedCipherSpec
->cipherSpec
;
126 ctx
->writeCipher
.macRef
= ctx
->selectedCipherSpec
->macAlgorithm
;
127 ctx
->readCipher
.macRef
= ctx
->selectedCipherSpec
->macAlgorithm
;
128 ctx
->readCipher
.symCipher
= ctx
->selectedCipherSpec
->cipher
;
129 ctx
->writeCipher
.symCipher
= ctx
->selectedCipherSpec
->cipher
;
131 /* these two are invariant */
132 ctx
->writeCipher
.encrypting
= 1;
133 ctx
->writePending
.encrypting
= 1;
135 /* this gets init'd on first call to SSLHandshake() */
136 ctx
->validCipherSpecs
= NULL
;
137 ctx
->numValidCipherSpecs
= 0;
139 ctx
->peerDomainName
= NULL
;
140 ctx
->peerDomainNameLen
= 0;
142 /* attach to CSP, CL, TP */
143 serr
= attachToAll(ctx
);
148 /* Initial cert verify state: verify with default system roots */
149 ctx
->enableCertVerify
= true;
151 /* snag root certs from Keychain, tolerate error */
152 addBuiltInCerts(ctx
);
164 * Dispose of an SSLContext.
167 SSLDisposeContext (SSLContext
*ctx
)
169 WaitingRecord
*wait
, *next
;
175 sslDeleteCertificateChain(ctx
->localCert
, ctx
);
176 sslDeleteCertificateChain(ctx
->encryptCert
, ctx
);
177 sslDeleteCertificateChain(ctx
->peerCert
, ctx
);
178 ctx
->localCert
= ctx
->encryptCert
= ctx
->peerCert
= NULL
;
179 SSLFreeBuffer(ctx
->partialReadBuffer
, ctx
);
181 wait
= ctx
->recordWriteQueue
;
183 { SSLFreeBuffer(wait
->data
, ctx
);
185 buf
.data
= (uint8
*)wait
;
186 buf
.length
= sizeof(WaitingRecord
);
187 SSLFreeBuffer(buf
, ctx
);
191 SSLFreeBuffer(ctx
->dhPeerPublic
, ctx
);
192 SSLFreeBuffer(ctx
->dhExchangePublic
, ctx
);
193 SSLFreeBuffer(ctx
->dhPrivate
, ctx
);
195 CloseHash(SSLHashSHA1
, ctx
->shaState
, ctx
);
196 CloseHash(SSLHashMD5
, ctx
->md5State
, ctx
);
198 SSLFreeBuffer(ctx
->sessionID
, ctx
);
199 SSLFreeBuffer(ctx
->peerID
, ctx
);
200 SSLFreeBuffer(ctx
->resumableSession
, ctx
);
201 SSLFreeBuffer(ctx
->preMasterSecret
, ctx
);
202 SSLFreeBuffer(ctx
->partialReadBuffer
, ctx
);
203 SSLFreeBuffer(ctx
->fragmentedMessageCache
, ctx
);
204 SSLFreeBuffer(ctx
->receivedDataBuffer
, ctx
);
206 if(ctx
->peerDomainName
) {
207 sslFree(ctx
->peerDomainName
);
208 ctx
->peerDomainName
= NULL
;
209 ctx
->peerDomainNameLen
= 0;
211 SSLDisposeCipherSuite(&ctx
->readCipher
, ctx
);
212 SSLDisposeCipherSuite(&ctx
->writeCipher
, ctx
);
213 SSLDisposeCipherSuite(&ctx
->readPending
, ctx
);
214 SSLDisposeCipherSuite(&ctx
->writePending
, ctx
);
216 sslFree(ctx
->validCipherSpecs
);
217 ctx
->validCipherSpecs
= NULL
;
218 ctx
->numValidCipherSpecs
= 0;
221 * NOTE: currently, all public keys come from the CL via CSSM_CL_CertGetKeyInfo.
222 * We really don't know what CSP the CL used to generate a public key (in fact,
223 * it uses the raw CSP only to get LogicalKeySizeInBits, but we can't know
224 * that). Thus using e.g. signingKeyCsp (or any other CSP) to free
225 * signingPubKey is not tecnically accurate. However, our public keys
226 * are all raw keys, and all Apple CSPs dispose of raw keys in the same
229 sslFreeKey(ctx
->signingKeyCsp
, &ctx
->signingPubKey
, NULL
);
230 sslFreeKey(ctx
->encryptKeyCsp
, &ctx
->encryptPubKey
, NULL
);
231 sslFreeKey(ctx
->peerPubKeyCsp
, &ctx
->peerPubKey
, NULL
);
233 sslFreeTrustedRoots(ctx
);
237 memset(ctx
, 0, sizeof(SSLContext
));
244 * Determine the state of an SSL session.
247 SSLGetSessionState (SSLContextRef context
,
248 SSLSessionState
*state
) /* RETURNED */
250 SSLSessionState rtnState
= kSSLIdle
;
252 if(context
== NULL
) {
256 switch(context
->state
) {
257 case SSL_HdskStateUninit
:
258 case SSL_HdskStateServerUninit
:
259 case SSL_HdskStateClientUninit
:
262 case SSL_HdskStateGracefulClose
:
263 rtnState
= kSSLClosed
;
265 case SSL_HdskStateErrorClose
:
266 case SSL_HdskStateNoNotifyClose
:
267 rtnState
= kSSLAborted
;
269 case SSL2_HdskStateServerReady
:
270 case SSL2_HdskStateClientReady
:
271 rtnState
= kSSLConnected
;
274 assert((context
->state
>= SSL_HdskStateServerHello
) &&
275 (context
->state
<= SSL2_HdskStateServerFinished
));
276 rtnState
= kSSLHandshake
;
285 SSLSetIOFuncs (SSLContextRef ctx
,
292 if(sslIsSessionActive(ctx
)) {
293 /* can't do this with an active session */
296 ctx
->ioCtx
.read
= read
;
297 ctx
->ioCtx
.write
= write
;
302 SSLSetConnection (SSLContextRef ctx
,
303 SSLConnectionRef connection
)
308 if(sslIsSessionActive(ctx
)) {
309 /* can't do this with an active session */
312 ctx
->ioCtx
.ioRef
= connection
;
317 SSLSetPeerDomainName (SSLContextRef ctx
,
318 const char *peerName
,
324 if(sslIsSessionActive(ctx
)) {
325 /* can't do this with an active session */
329 /* free possible existing name */
330 if(ctx
->peerDomainName
) {
331 sslFree(ctx
->peerDomainName
);
335 ctx
->peerDomainName
= (char *)sslMalloc(peerNameLen
);
336 if(ctx
->peerDomainName
== NULL
) {
339 memmove(ctx
->peerDomainName
, peerName
, peerNameLen
);
340 ctx
->peerDomainNameLen
= peerNameLen
;
345 * Determine the buffer size needed for SSLGetPeerDomainName().
348 SSLGetPeerDomainNameLength (SSLContextRef ctx
,
349 size_t *peerNameLen
) // RETURNED
354 *peerNameLen
= ctx
->peerDomainNameLen
;
359 SSLGetPeerDomainName (SSLContextRef ctx
,
360 char *peerName
, // returned here
361 size_t *peerNameLen
) // IN/OUT
366 if(*peerNameLen
< ctx
->peerDomainNameLen
) {
367 return errSSLBufferOverflow
;
369 memmove(peerName
, ctx
->peerDomainName
, ctx
->peerDomainNameLen
);
370 *peerNameLen
= ctx
->peerDomainNameLen
;
375 SSLSetProtocolVersion (SSLContextRef ctx
,
378 SSLProtocolVersion versInt
;
379 SSLProtocolVersion versMax
;
384 if(sslIsSessionActive(ctx
)) {
385 /* can't do this with an active session */
389 /* convert external representation to private */
391 case kSSLProtocolUnknown
:
392 versInt
= SSL_Version_Undetermined
;
393 versMax
= DEFAULT_MAX_VERSION
;
396 versInt
= versMax
= SSL_Version_2_0
;
399 /* this tells us to do our best but allows 2.0 */
400 versInt
= SSL_Version_Undetermined
;
401 versMax
= SSL_Version_3_0
;
403 case kSSLProtocol3Only
:
404 versInt
= SSL_Version_3_0_Only
;
405 versMax
= SSL_Version_3_0
;
408 /* this tells us to do our best but allows 2.0 */
409 versInt
= SSL_Version_Undetermined
;
410 versMax
= TLS_Version_1_0
;
412 case kTLSProtocol1Only
:
413 versInt
= TLS_Version_1_0_Only
;
414 versMax
= TLS_Version_1_0
;
419 ctx
->reqProtocolVersion
= ctx
->negProtocolVersion
= versInt
;
420 ctx
->maxProtocolVersion
= versMax
;
424 static SSLProtocol
convertProtToExtern(SSLProtocolVersion prot
)
427 case SSL_Version_Undetermined
:
428 return kSSLProtocolUnknown
;
429 case SSL_Version_3_0_Only
:
430 return kSSLProtocol3Only
;
431 case SSL_Version_2_0
:
432 return kSSLProtocol2
;
433 case SSL_Version_3_0
:
434 return kSSLProtocol3
;
435 case TLS_Version_1_0_Only
:
436 return kTLSProtocol1Only
;
437 case TLS_Version_1_0
:
438 return kTLSProtocol1
;
439 /* this can happen in an intermediate state while negotiation
440 * is active...right? */
441 case SSL_Version_3_0_With_2_0_Hello
:
442 return kSSLProtocolUnknown
;
444 sslErrorLog("convertProtToExtern: bad prot\n");
445 return kSSLProtocolUnknown
;
447 /* not reached but make compiler happy */
448 return kSSLProtocolUnknown
;
452 SSLGetProtocolVersion (SSLContextRef ctx
,
453 SSLProtocol
*protocol
) /* RETURNED */
458 *protocol
= convertProtToExtern(ctx
->reqProtocolVersion
);
463 SSLGetNegotiatedProtocolVersion (SSLContextRef ctx
,
464 SSLProtocol
*protocol
) /* RETURNED */
469 *protocol
= convertProtToExtern(ctx
->negProtocolVersion
);
474 SSLSetEnableCertVerify (SSLContextRef ctx
,
475 Boolean enableVerify
)
480 if(sslIsSessionActive(ctx
)) {
481 /* can't do this with an active session */
484 ctx
->enableCertVerify
= enableVerify
;
489 SSLGetEnableCertVerify (SSLContextRef ctx
,
490 Boolean
*enableVerify
)
495 *enableVerify
= ctx
->enableCertVerify
;
500 SSLSetAllowsExpiredCerts(SSLContextRef ctx
,
501 Boolean allowExpired
)
506 if(sslIsSessionActive(ctx
)) {
507 /* can't do this with an active session */
510 ctx
->allowExpiredCerts
= allowExpired
;
515 SSLGetAllowsExpiredCerts (SSLContextRef ctx
,
516 Boolean
*allowExpired
)
521 *allowExpired
= ctx
->allowExpiredCerts
;
526 SSLSetAllowsExpiredRoots(SSLContextRef ctx
,
527 Boolean allowExpired
)
532 if(sslIsSessionActive(ctx
)) {
533 /* can't do this with an active session */
536 ctx
->allowExpiredRoots
= allowExpired
;
541 SSLGetAllowsExpiredRoots (SSLContextRef ctx
,
542 Boolean
*allowExpired
)
547 *allowExpired
= ctx
->allowExpiredRoots
;
551 OSStatus
SSLSetAllowsAnyRoot(
558 ctx
->allowAnyRoot
= anyRoot
;
570 *anyRoot
= ctx
->allowAnyRoot
;
575 SSLSetTrustedRoots (SSLContextRef ctx
,
576 CFArrayRef trustedRoots
,
577 Boolean replaceExisting
)
581 unsigned numIncoming
;
583 CSSM_DATA_PTR newRoots
= NULL
;
584 const CSSM_DATA
*existAnchors
= NULL
;
585 uint32 numExistAnchors
= 0;
586 OSStatus ortn
= noErr
;
591 if(sslIsSessionActive(ctx
)) {
592 /* can't do this with an active session */
595 numCerts
= numIncoming
= CFArrayGetCount(trustedRoots
);
596 if(!replaceExisting
) {
597 if(ctx
->trustedCerts
!= NULL
) {
598 /* adding to existing store */
599 existAnchors
= ctx
->trustedCerts
;
600 numExistAnchors
= ctx
->numTrustedCerts
;
603 /* adding to system roots */
604 ortn
= SecTrustGetCSSMAnchorCertificates(&existAnchors
,
607 /* should never happen */
611 numCerts
+= numExistAnchors
;
613 newRoots
= (CSSM_DATA_PTR
)sslMalloc(numCerts
* sizeof(CSSM_DATA
));
614 memset(newRoots
, 0, numCerts
* sizeof(CSSM_DATA
));
616 /* Caller's certs first */
617 for(dex
=0, outDex
=0; dex
<numIncoming
; dex
++, outDex
++) {
619 SecCertificateRef secCert
= (SecCertificateRef
)
620 CFArrayGetValueAtIndex(trustedRoots
, dex
);
622 if(CFGetTypeID(secCert
) != SecCertificateGetTypeID()) {
623 /* elements of trustedRoots must be SecCertificateRefs */
627 ortn
= SecCertificateGetData(secCert
, &certData
);
631 stSetUpCssmData(&newRoots
[outDex
], certData
.Length
);
632 memmove(newRoots
[outDex
].Data
, certData
.Data
, certData
.Length
);
635 /* now existing roots - either ours, or the system's */
636 for(dex
=0; dex
<numExistAnchors
; dex
++, outDex
++) {
637 stSetUpCssmData(&newRoots
[outDex
], existAnchors
[dex
].Length
);
638 memmove(newRoots
[outDex
].Data
, existAnchors
[dex
].Data
,
639 existAnchors
[dex
].Length
);
642 /* success - replace context values */
643 sslFreeTrustedRoots(ctx
);
644 ctx
->numTrustedCerts
= numCerts
;
645 ctx
->trustedCerts
= newRoots
;
654 SSLGetTrustedRoots (SSLContextRef ctx
,
655 CFArrayRef
*trustedRoots
) /* RETURNED */
658 const CSSM_DATA
*certs
;
659 CFMutableArrayRef certArray
;
661 SecCertificateRef secCert
;
667 if(ctx
->trustedCerts
!= NULL
) {
669 certs
= ctx
->trustedCerts
;
670 numCerts
= ctx
->numTrustedCerts
;
673 /* use default system roots */
674 OSStatus ortn
= SecTrustGetCSSMAnchorCertificates(&certs
,
677 /* should never happen */
682 certArray
= CFArrayCreateMutable(kCFAllocatorDefault
,
683 (CFIndex
)numCerts
, &kCFTypeArrayCallBacks
);
684 if(certArray
== NULL
) {
687 for(dex
=0; dex
<numCerts
; dex
++) {
688 ortn
= SecCertificateCreateFromData(&certs
[dex
],
690 CSSM_CERT_ENCODING_DER
,
693 CFRelease(certArray
);
696 CFArrayAppendValue(certArray
, secCert
);
698 *trustedRoots
= certArray
;
703 SSLSetClientSideAuthenticate (SSLContext
*ctx
,
704 SSLAuthenticate auth
)
709 if(sslIsSessionActive(ctx
)) {
710 /* can't do this with an active session */
713 ctx
->clientAuth
= auth
;
715 case kNeverAuthenticate
:
716 ctx
->tryClientAuth
= false;
718 case kAlwaysAuthenticate
:
719 case kTryAuthenticate
:
720 ctx
->tryClientAuth
= true;
727 SSLGetClientCertificateState (SSLContextRef ctx
,
728 SSLClientCertificateState
*clientState
)
733 *clientState
= ctx
->clientCertState
;
738 SSLSetCertificate (SSLContextRef ctx
,
742 * -- free localCerts if we have any
743 * -- Get raw cert data, convert to ctx->localCert
744 * -- get pub, priv keys from certRef[0]
745 * -- validate cert chain
750 if(sslIsSessionActive(ctx
)) {
751 /* can't do this with an active session */
754 return parseIncomingCerts(ctx
,
758 &ctx
->signingPrivKey
,
760 #if ST_KC_KEYS_NEED_REF
769 SSLSetEncryptionCertificate (SSLContextRef ctx
,
773 * -- free encryptCert if we have any
774 * -- Get raw cert data, convert to ctx->encryptCert
775 * -- get pub, priv keys from certRef[0]
776 * -- validate cert chain
781 if(sslIsSessionActive(ctx
)) {
782 /* can't do this with an active session */
785 return parseIncomingCerts(ctx
,
789 &ctx
->encryptPrivKey
,
791 #if ST_KC_KEYS_NEED_REF
793 &ctx
->encryptKeyRef
);
799 #if ST_MANAGES_TRUSTED_ROOTS
802 * Add (optional, additional) trusted root certs.
805 SSLSetTrustedRootCertKC (SSLContextRef ctx
,
807 Boolean deleteExisting
)
810 * -- free trustedCerts if deleteExisting
811 * -- Get raw cert data, add to ctx->trustedCerts
812 * -- verify that each of these is a valid (self-verifying)
814 * -- add each subject name to acceptableDNList
816 if((ctx
== NULL
) || (keyChainRef
== nil
)) {
819 if(sslIsSessionActive(ctx
)) {
820 /* can't do this with an active session */
824 sslFreeTrustedRoots(ctx
);
826 return parseTrustedKeychain(ctx
, keyChainRef
);
830 SSLSetNewRootKC (SSLContextRef ctx
,
834 if((ctx
== NULL
) || (keyChainRef
== nil
)) {
837 if(sslIsSessionActive(ctx
)) {
838 /* can't do this with an active session */
841 if(ctx
->newRootCertKc
!= NULL
) {
842 /* can't do this multiple times */
845 ctx
->newRootCertKc
= keyChainRef
;
846 ctx
->accessCreds
= accessCreds
;
849 #endif /* ST_MANAGES_TRUSTED_ROOTS */
852 SSLSetPeerID (SSLContext
*ctx
,
858 /* copy peerId to context->peerId */
864 if(sslIsSessionActive(ctx
)) {
865 /* can't do this with an active session */
868 SSLFreeBuffer(ctx
->peerID
, ctx
);
869 serr
= SSLAllocBuffer(ctx
->peerID
, peerIDLen
, ctx
);
873 memmove(ctx
->peerID
.data
, peerID
, peerIDLen
);
878 SSLGetPeerID (SSLContextRef ctx
,
882 *peerID
= ctx
->peerID
.data
; // may be NULL
883 *peerIDLen
= ctx
->peerID
.length
;
888 SSLGetNegotiatedCipher (SSLContextRef ctx
,
889 SSLCipherSuite
*cipherSuite
)
894 if(!sslIsSessionActive(ctx
)) {
897 *cipherSuite
= (SSLCipherSuite
)ctx
->selectedCipher
;
902 * Add an acceptable distinguished name (client authentication only).
905 SSLAddDistinguishedName(
913 dn
= (DNListElem
*)sslMalloc(sizeof(DNListElem
));
917 if ((err
= SSLAllocBuffer(dn
->derDN
, derDNLen
, ctx
)) != 0)
919 memcpy(dn
->derDN
.data
, derDN
, derDNLen
);
920 dn
->next
= ctx
->acceptableDNList
;
921 ctx
->acceptableDNList
= dn
;
926 * Request peer certificates. Valid anytime, subsequent to
927 * a handshake attempt.
930 SSLGetPeerCertificates (SSLContextRef ctx
,
934 CFMutableArrayRef ca
;
936 SecCertificateRef cfd
;
939 SSLCertificate
*scert
;
947 * Copy peerCert, a chain of SSLCertificates, to a CFArray of
948 * CFDataRefs, each of which is one DER-encoded cert.
950 numCerts
= SSLGetCertificateChainLength(ctx
->peerCert
);
954 ca
= CFArrayCreateMutable(kCFAllocatorDefault
,
955 (CFIndex
)numCerts
, &kCFTypeArrayCallBacks
);
961 * Caller gets leaf cert first, the opposite of the way we store them.
963 scert
= ctx
->peerCert
;
964 for(i
=0; (unsigned)i
<numCerts
; i
++) {
965 assert(scert
!= NULL
); /* else SSLGetCertificateChainLength
967 SSLBUF_TO_CSSM(&scert
->derCert
, &certData
);
968 ortn
= SecCertificateCreateFromData(&certData
,
970 CSSM_CERT_ENCODING_DER
,
976 /* insert at head of array */
977 CFArrayInsertValueAtIndex(ca
, 0, cfd
);
984 OSStatus
SSLInternalMasterSecret(
986 void *secret
, // mallocd by caller, SSL_MASTER_SECRET_SIZE
987 size_t *secretSize
) // in/out
989 if((ctx
== NULL
) || (secret
== NULL
) || (secretSize
== NULL
)) {
992 if(*secretSize
< SSL_MASTER_SECRET_SIZE
) {
995 memmove(secret
, ctx
->masterSecret
, SSL_MASTER_SECRET_SIZE
);
996 *secretSize
= SSL_MASTER_SECRET_SIZE
;
1000 OSStatus
SSLInternalServerRandom(
1002 void *rand
, // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
1003 size_t *randSize
) // in/out
1005 if((ctx
== NULL
) || (rand
== NULL
) || (randSize
== NULL
)) {
1008 if(*randSize
< SSL_CLIENT_SRVR_RAND_SIZE
) {
1011 memmove(rand
, ctx
->serverRandom
, SSL_CLIENT_SRVR_RAND_SIZE
);
1012 *randSize
= SSL_CLIENT_SRVR_RAND_SIZE
;
1016 OSStatus
SSLInternalClientRandom(
1018 void *rand
, // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
1019 size_t *randSize
) // in/out
1021 if((ctx
== NULL
) || (rand
== NULL
) || (randSize
== NULL
)) {
1024 if(*randSize
< SSL_CLIENT_SRVR_RAND_SIZE
) {
1027 memmove(rand
, ctx
->clientRandom
, SSL_CLIENT_SRVR_RAND_SIZE
);
1028 *randSize
= SSL_CLIENT_SRVR_RAND_SIZE
;