2 * Copyright (c) 1999-2001,2005-2012 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
25 * sslContext.c - SSLContext accessors
29 #include "sslContext.h"
30 #include "sslMemory.h"
31 #include "sslDigests.h"
33 #include "sslCrypto.h"
35 #include "SecureTransport.h"
37 #include <CoreFoundation/CFData.h>
38 #include <CoreFoundation/CFPreferences.h>
40 #include <Security/SecTrust.h>
41 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
42 #include <Security/oidsalg.h>
43 #include <Security/SecTrustSettingsPriv.h>
46 #include "sslKeychain.h"
48 #include "cipherSpecs.h"
49 #include "appleSession.h"
50 #include "SecureTransportPriv.h"
53 #include <Security/SecCertificate.h>
54 #include <Security/SecCertificatePriv.h>
55 #include <Security/SecCertificateInternal.h>
56 #include <Security/SecInternal.h>
57 #include <Security/SecTrust.h>
58 #include <Security/oidsalg.h>
59 #include <Security/SecTrustSettingsPriv.h>
60 #include <AssertMacros.h>
62 static void sslFreeDnList(
65 DNListElem
*dn
, *nextDN
;
67 dn
= ctx
->acceptableDNList
;
70 SSLFreeBuffer(&dn
->derDN
, ctx
);
75 ctx
->acceptableDNList
= NULL
;
78 #define min(a,b) ( ((a) < (b)) ? (a) : (b) )
79 #define max(a,b) ( ((a) > (b)) ? (a) : (b) )
82 * Minimum and maximum supported versions
84 //#define MINIMUM_STREAM_VERSION SSL_Version_2_0 /* Disabled */
85 #define MINIMUM_STREAM_VERSION SSL_Version_3_0
86 #define MAXIMUM_STREAM_VERSION TLS_Version_1_2
87 #define MINIMUM_DATAGRAM_VERSION DTLS_Version_1_0
89 /* This should be changed when we start supporting DTLS_Version_1_x */
90 #define MAXIMUM_DATAGRAM_VERSION DTLS_Version_1_0
92 #define SSL_ENABLE_ECDSA_SIGN_AUTH 0
93 #define SSL_ENABLE_RSA_FIXED_ECDH_AUTH 0
94 #define SSL_ENABLE_ECDSA_FIXED_ECDH_AUTH 0
96 #define DEFAULT_DTLS_TIMEOUT 1
97 #define DEFAULT_DTLS_MTU 1400
98 #define MIN_ALLOWED_DTLS_MTU 64 /* this ensure than there will be no integer
99 underflow when calculating max write size */
101 static CFTypeID kSSLContextTypeID
;
102 int kSplitDefaultValue
;
104 static void _sslContextDestroy(CFTypeRef arg
);
105 static Boolean
_sslContextEqual(CFTypeRef a
, CFTypeRef b
);
106 static CFHashCode
_sslContextHash(CFTypeRef arg
);
107 static CFStringRef
_sslContextDescribe(CFTypeRef arg
);
109 static void _SSLContextReadDefault()
111 CFTypeRef value
= (CFTypeRef
)CFPreferencesCopyValue(CFSTR("SSLWriteSplit"),
112 CFSTR("com.apple.security"),
113 kCFPreferencesAnyUser
,
114 kCFPreferencesAnyHost
);
116 if (CFGetTypeID(value
) == CFBooleanGetTypeID())
117 kSplitDefaultValue
= CFBooleanGetValue((CFBooleanRef
)value
) ? 1 : 0;
118 else if (CFGetTypeID(value
) == CFNumberGetTypeID()) {
119 if (!CFNumberGetValue((CFNumberRef
)value
, kCFNumberIntType
, &kSplitDefaultValue
))
120 kSplitDefaultValue
= 0;
122 if (kSplitDefaultValue
< 0 || kSplitDefaultValue
> 2) {
123 kSplitDefaultValue
= 0;
128 kSplitDefaultValue
= 0;
132 static void _SSLContextRegisterClass()
134 static const CFRuntimeClass kSSLContextRegisterClass
= {
136 "SSLContext", /* class name */
139 _sslContextDestroy
, /* dealloc */
140 _sslContextEqual
, /* equal */
141 _sslContextHash
, /* hash */
142 NULL
, /* copyFormattingDesc */
143 _sslContextDescribe
/* copyDebugDesc */
146 kSSLContextTypeID
= _CFRuntimeRegisterClass(&kSSLContextRegisterClass
);
150 SSLContextGetTypeID(void)
152 static pthread_once_t sOnce
= PTHREAD_ONCE_INIT
;
153 pthread_once(&sOnce
, _SSLContextRegisterClass
);
154 return kSSLContextTypeID
;
159 SSLNewContext (Boolean isServer
,
160 SSLContextRef
*contextPtr
) /* RETURNED */
162 if(contextPtr
== NULL
) {
166 *contextPtr
= SSLCreateContext(kCFAllocatorDefault
, isServer
?kSSLServerSide
:kSSLClientSide
, kSSLStreamType
);
168 if (*contextPtr
== NULL
)
174 SSLContextRef
SSLCreateContext(CFAllocatorRef alloc
, SSLProtocolSide protocolSide
, SSLConnectionType connectionType
)
176 OSStatus serr
= noErr
;
177 SSLContext
*ctx
= (SSLContext
*) _CFRuntimeCreateInstance(alloc
, SSLContextGetTypeID(), sizeof(SSLContext
) - sizeof(CFRuntimeBase
), NULL
);
183 /* subsequent errors to errOut: */
184 memset(((uint8_t*) ctx
) + sizeof(CFRuntimeBase
), 0, sizeof(SSLContext
) - sizeof(CFRuntimeBase
));
186 ctx
->state
= SSL_HdskStateUninit
;
187 ctx
->timeout_duration
= DEFAULT_DTLS_TIMEOUT
;
188 ctx
->clientCertState
= kSSLClientCertNone
;
190 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
191 ctx
->maxProtocolVersion
= MAXIMUM_STREAM_VERSION
;
194 ctx
->dtlsCookie
.data
= NULL
;
195 ctx
->dtlsCookie
.length
= 0;
196 ctx
->hdskMessageSeq
= 0;
197 ctx
->hdskMessageSeqNext
= 0;
198 ctx
->mtu
= DEFAULT_DTLS_MTU
;
200 ctx
->negProtocolVersion
= SSL_Version_Undetermined
;
203 ctx
->protocolSide
= protocolSide
;
204 /* Default value so we can send and receive hello msgs */
205 ctx
->sslTslCalls
= &Ssl3Callouts
;
207 /* Initialize the cipher state to NULL_WITH_NULL_NULL */
209 ctx
->selectedCipher
= TLS_NULL_WITH_NULL_NULL
;
211 ctx
->writeCipher
.macRef
= ctx
->selectedCipherSpec
.macAlgorithm
;
212 ctx
->readCipher
.macRef
= ctx
->selectedCipherSpec
.macAlgorithm
;
213 ctx
->readCipher
.symCipher
= ctx
->selectedCipherSpec
.cipher
;
214 ctx
->writeCipher
.symCipher
= ctx
->selectedCipherSpec
.cipher
;
216 /* these two are invariant */
217 ctx
->writeCipher
.encrypting
= 1;
218 ctx
->writePending
.encrypting
= 1;
220 /* this gets init'd on first call to SSLHandshake() */
221 ctx
->validCipherSuites
= NULL
;
222 ctx
->numValidCipherSuites
= 0;
224 ctx
->numValidNonSSLv2Suites
= 0;
227 ctx
->peerDomainName
= NULL
;
228 ctx
->peerDomainNameLen
= 0;
230 #ifdef USE_CDSA_CRYPTO
231 /* attach to CSP, CL, TP */
232 serr
= attachToAll(ctx
);
236 #endif /* USE_CDSA_CRYPTO */
238 /* Initial cert verify state: verify with default system roots */
239 ctx
->enableCertVerify
= true;
241 /* Default for RSA blinding is ENABLED */
242 ctx
->rsaBlindingEnable
= true;
244 /* Default for sending one-byte app data record is DISABLED */
245 ctx
->oneByteRecordEnable
= false;
247 /* Consult global system preference for default behavior:
248 * 0 = disabled, 1 = split every write, 2 = split second and subsequent writes
249 * (caller can override by setting kSSLSessionOptionSendOneByteRecord)
251 static pthread_once_t sReadDefault
= PTHREAD_ONCE_INIT
;
252 pthread_once(&sReadDefault
, _SSLContextReadDefault
);
253 if (kSplitDefaultValue
> 0)
254 ctx
->oneByteRecordEnable
= true;
256 /* default for anonymous ciphers is DISABLED */
257 ctx
->anonCipherEnable
= false;
259 ctx
->breakOnServerAuth
= false;
260 ctx
->breakOnCertRequest
= false;
261 ctx
->breakOnClientAuth
= false;
262 ctx
->signalServerAuth
= false;
263 ctx
->signalCertRequest
= false;
264 ctx
->signalClientAuth
= false;
267 * Initial/default set of ECDH curves
269 ctx
->ecdhNumCurves
= SSL_ECDSA_NUM_CURVES
;
270 ctx
->ecdhCurves
[0] = SSL_Curve_secp256r1
;
271 ctx
->ecdhCurves
[1] = SSL_Curve_secp384r1
;
272 ctx
->ecdhCurves
[2] = SSL_Curve_secp521r1
;
274 ctx
->ecdhPeerCurve
= SSL_Curve_None
; /* until we negotiate one */
275 ctx
->negAuthType
= SSLClientAuthNone
; /* ditto */
277 ctx
->recordWriteQueue
= NULL
;
278 ctx
->messageWriteQueue
= NULL
;
280 if(connectionType
==kSSLDatagramType
) {
281 ctx
->minProtocolVersion
= MINIMUM_DATAGRAM_VERSION
;
282 ctx
->maxProtocolVersion
= MAXIMUM_DATAGRAM_VERSION
;
286 ctx
->secure_renegotiation
= false;
288 #ifdef USE_CDSA_CRYPTO
290 #endif /* USE_CDSA_CRYPTO */
299 SSLNewDatagramContext (Boolean isServer
,
300 SSLContextRef
*contextPtr
) /* RETURNED */
302 if (contextPtr
== NULL
)
304 *contextPtr
= SSLCreateContext(kCFAllocatorDefault
, isServer
?kSSLServerSide
:kSSLClientSide
, kSSLDatagramType
);
305 if (*contextPtr
== NULL
)
311 * Dispose of an SSLContext. (private)
312 * This function is invoked after our dispatch queue is safely released,
313 * or directly from SSLDisposeContext if there is no dispatch queue.
316 SSLDisposeContext (SSLContextRef context
)
318 if(context
== NULL
) {
325 CFStringRef
_sslContextDescribe(CFTypeRef arg
)
327 SSLContext
* ctx
= (SSLContext
*) arg
;
332 CFStringRef result
= CFStringCreateWithFormat(kCFAllocatorDefault
, NULL
, CFSTR("<SSLContext(%p) { ... }>"), ctx
);
337 Boolean
_sslContextEqual(CFTypeRef a
, CFTypeRef b
)
342 CFHashCode
_sslContextHash(CFTypeRef arg
)
344 return (CFHashCode
) arg
;
347 void _sslContextDestroy(CFTypeRef arg
)
349 SSLContext
* ctx
= (SSLContext
*) arg
;
350 WaitingRecord
*waitRecord
, *next
;
352 #if USE_SSLCERTIFICATE
353 sslDeleteCertificateChain(ctx
->localCert
, ctx
);
354 sslDeleteCertificateChain(ctx
->encryptCert
, ctx
);
355 sslDeleteCertificateChain(ctx
->peerCert
, ctx
);
356 ctx
->localCert
= ctx
->encryptCert
= ctx
->peerCert
= NULL
;
358 CFReleaseNull(ctx
->localCert
);
359 CFReleaseNull(ctx
->encryptCert
);
360 CFReleaseNull(ctx
->peerCert
);
361 CFReleaseNull(ctx
->trustedCerts
);
364 /* Free the last handshake message flight */
367 SSLFreeBuffer(&ctx
->partialReadBuffer
, ctx
);
368 if(ctx
->peerSecTrust
) {
369 CFRelease(ctx
->peerSecTrust
);
370 ctx
->peerSecTrust
= NULL
;
372 waitRecord
= ctx
->recordWriteQueue
;
374 { next
= waitRecord
->next
;
378 SSLFreeBuffer(&ctx
->sessionTicket
, ctx
);
381 SSLFreeBuffer(&ctx
->dhParamsEncoded
, ctx
);
382 #ifdef USE_CDSA_CRYPTO
383 sslFreeKey(ctx
->cspHand
, &ctx
->dhPrivate
, NULL
);
385 if (ctx
->secDHContext
)
386 SecDHDestroy(ctx
->secDHContext
);
387 #endif /* !USE_CDSA_CRYPTO */
388 SSLFreeBuffer(&ctx
->dhPeerPublic
, ctx
);
389 SSLFreeBuffer(&ctx
->dhExchangePublic
, ctx
);
390 #endif /* APPLE_DH */
392 SSLFreeBuffer(&ctx
->ecdhPeerPublic
, ctx
);
393 SSLFreeBuffer(&ctx
->ecdhExchangePublic
, ctx
);
395 if(ctx
->ecdhPrivCspHand
== ctx
->cspHand
) {
396 sslFreeKey(ctx
->ecdhPrivCspHand
, &ctx
->ecdhPrivate
, NULL
);
398 /* else we got this key from a SecKeyRef, no free needed */
401 CloseHash(&SSLHashSHA1
, &ctx
->shaState
, ctx
);
402 CloseHash(&SSLHashMD5
, &ctx
->md5State
, ctx
);
403 CloseHash(&SSLHashSHA256
, &ctx
->sha256State
, ctx
);
404 CloseHash(&SSLHashSHA384
, &ctx
->sha512State
, ctx
);
406 SSLFreeBuffer(&ctx
->sessionID
, ctx
);
407 SSLFreeBuffer(&ctx
->peerID
, ctx
);
408 SSLFreeBuffer(&ctx
->resumableSession
, ctx
);
409 SSLFreeBuffer(&ctx
->preMasterSecret
, ctx
);
410 SSLFreeBuffer(&ctx
->partialReadBuffer
, ctx
);
411 SSLFreeBuffer(&ctx
->fragmentedMessageCache
, ctx
);
412 SSLFreeBuffer(&ctx
->receivedDataBuffer
, ctx
);
414 if(ctx
->peerDomainName
) {
415 sslFree(ctx
->peerDomainName
);
416 ctx
->peerDomainName
= NULL
;
417 ctx
->peerDomainNameLen
= 0;
419 SSLDisposeCipherSuite(&ctx
->readCipher
, ctx
);
420 SSLDisposeCipherSuite(&ctx
->writeCipher
, ctx
);
421 SSLDisposeCipherSuite(&ctx
->readPending
, ctx
);
422 SSLDisposeCipherSuite(&ctx
->writePending
, ctx
);
424 sslFree(ctx
->validCipherSuites
);
425 ctx
->validCipherSuites
= NULL
;
426 ctx
->numValidCipherSuites
= 0;
430 * NOTE: currently, all public keys come from the CL via CSSM_CL_CertGetKeyInfo.
431 * We really don't know what CSP the CL used to generate a public key (in fact,
432 * it uses the raw CSP only to get LogicalKeySizeInBits, but we can't know
433 * that). Thus using e.g. signingKeyCsp (or any other CSP) to free
434 * signingPubKey is not tecnically accurate. However, our public keys
435 * are all raw keys, and all Apple CSPs dispose of raw keys in the same
438 sslFreeKey(ctx
->cspHand
, &ctx
->signingPubKey
, NULL
);
439 sslFreeKey(ctx
->cspHand
, &ctx
->encryptPubKey
, NULL
);
440 sslFreeKey(ctx
->peerPubKeyCsp
, &ctx
->peerPubKey
, NULL
);
442 if(ctx
->signingPrivKeyRef
) {
443 CFRelease(ctx
->signingPrivKeyRef
);
445 if(ctx
->encryptPrivKeyRef
) {
446 CFRelease(ctx
->encryptPrivKeyRef
);
448 if(ctx
->trustedCerts
) {
449 CFRelease(ctx
->trustedCerts
);
453 sslFreePubKey(&ctx
->signingPubKey
);
454 sslFreePubKey(&ctx
->encryptPubKey
);
455 sslFreePubKey(&ctx
->peerPubKey
);
456 sslFreePrivKey(&ctx
->signingPrivKeyRef
);
457 sslFreePrivKey(&ctx
->encryptPrivKeyRef
);
458 #endif /* USE_CDSA_CRYPTO */
459 CFReleaseSafe(ctx
->acceptableCAs
);
460 CFReleaseSafe(ctx
->trustedLeafCerts
);
461 CFReleaseSafe(ctx
->localCertArray
);
462 CFReleaseSafe(ctx
->encryptCertArray
);
463 CFReleaseSafe(ctx
->encryptCertArray
);
464 if(ctx
->clientAuthTypes
) {
465 sslFree(ctx
->clientAuthTypes
);
467 if(ctx
->serverSigAlgs
!= NULL
) {
468 sslFree(ctx
->serverSigAlgs
);
470 if(ctx
->clientSigAlgs
!= NULL
) {
471 sslFree(ctx
->clientSigAlgs
);
475 SSLFreeBuffer(&ctx
->ownVerifyData
, ctx
);
476 SSLFreeBuffer(&ctx
->peerVerifyData
, ctx
);
478 memset(((uint8_t*) ctx
) + sizeof(CFRuntimeBase
), 0, sizeof(SSLContext
) - sizeof(CFRuntimeBase
));
484 * Determine the state of an SSL session.
487 SSLGetSessionState (SSLContextRef context
,
488 SSLSessionState
*state
) /* RETURNED */
490 SSLSessionState rtnState
= kSSLIdle
;
492 if(context
== NULL
) {
496 switch(context
->state
) {
497 case SSL_HdskStateUninit
:
498 case SSL_HdskStateServerUninit
:
499 case SSL_HdskStateClientUninit
:
502 case SSL_HdskStateGracefulClose
:
503 rtnState
= kSSLClosed
;
505 case SSL_HdskStateErrorClose
:
506 case SSL_HdskStateNoNotifyClose
:
507 rtnState
= kSSLAborted
;
509 case SSL_HdskStateServerReady
:
510 case SSL_HdskStateClientReady
:
511 rtnState
= kSSLConnected
;
514 assert((context
->state
>= SSL_HdskStateServerHello
) &&
515 (context
->state
<= SSL2_HdskStateServerFinished
));
516 rtnState
= kSSLHandshake
;
525 * Set options for an SSL session.
528 SSLSetSessionOption (SSLContextRef context
,
529 SSLSessionOption option
,
532 if(context
== NULL
) {
535 if(sslIsSessionActive(context
)) {
536 /* can't do this with an active session */
540 case kSSLSessionOptionBreakOnServerAuth
:
541 context
->breakOnServerAuth
= value
;
542 context
->enableCertVerify
= !value
;
544 case kSSLSessionOptionBreakOnCertRequested
:
545 context
->breakOnCertRequest
= value
;
547 case kSSLSessionOptionBreakOnClientAuth
:
548 context
->breakOnClientAuth
= value
;
549 context
->enableCertVerify
= !value
;
551 case kSSLSessionOptionSendOneByteRecord
:
552 context
->oneByteRecordEnable
= value
;
562 * Determine current value for the specified option in an SSL session.
565 SSLGetSessionOption (SSLContextRef context
,
566 SSLSessionOption option
,
569 if(context
== NULL
|| value
== NULL
) {
573 case kSSLSessionOptionBreakOnServerAuth
:
574 *value
= context
->breakOnServerAuth
;
576 case kSSLSessionOptionBreakOnCertRequested
:
577 *value
= context
->breakOnCertRequest
;
579 case kSSLSessionOptionBreakOnClientAuth
:
580 *value
= context
->breakOnClientAuth
;
582 case kSSLSessionOptionSendOneByteRecord
:
583 *value
= context
->oneByteRecordEnable
;
593 SSLSetIOFuncs (SSLContextRef ctx
,
594 SSLReadFunc readFunc
,
595 SSLWriteFunc writeFunc
)
600 if(sslIsSessionActive(ctx
)) {
601 /* can't do this with an active session */
605 ctx
->ioCtx
.read
= readFunc
;
606 ctx
->ioCtx
.write
= writeFunc
;
611 SSLSetConnection (SSLContextRef ctx
,
612 SSLConnectionRef connection
)
617 if(sslIsSessionActive(ctx
)) {
618 /* can't do this with an active session */
622 ctx
->ioCtx
.ioRef
= connection
;
627 SSLGetConnection (SSLContextRef ctx
,
628 SSLConnectionRef
*connection
)
630 if((ctx
== NULL
) || (connection
== NULL
)) {
633 *connection
= ctx
->ioCtx
.ioRef
;
638 SSLSetPeerDomainName (SSLContextRef ctx
,
639 const char *peerName
,
645 if(sslIsSessionActive(ctx
)) {
646 /* can't do this with an active session */
650 /* free possible existing name */
651 if(ctx
->peerDomainName
) {
652 sslFree(ctx
->peerDomainName
);
656 ctx
->peerDomainName
= (char *)sslMalloc(peerNameLen
);
657 if(ctx
->peerDomainName
== NULL
) {
660 memmove(ctx
->peerDomainName
, peerName
, peerNameLen
);
661 ctx
->peerDomainNameLen
= peerNameLen
;
666 * Determine the buffer size needed for SSLGetPeerDomainName().
669 SSLGetPeerDomainNameLength (SSLContextRef ctx
,
670 size_t *peerNameLen
) // RETURNED
675 *peerNameLen
= ctx
->peerDomainNameLen
;
680 SSLGetPeerDomainName (SSLContextRef ctx
,
681 char *peerName
, // returned here
682 size_t *peerNameLen
) // IN/OUT
687 if(*peerNameLen
< ctx
->peerDomainNameLen
) {
688 return errSSLBufferOverflow
;
690 memmove(peerName
, ctx
->peerDomainName
, ctx
->peerDomainNameLen
);
691 *peerNameLen
= ctx
->peerDomainNameLen
;
696 SSLSetDatagramHelloCookie (SSLContextRef ctx
,
706 if(!ctx
->isDTLS
) return paramErr
;
708 if((ctx
== NULL
) || (cookieLen
>32)) {
711 if(sslIsSessionActive(ctx
)) {
712 /* can't do this with an active session */
716 /* free possible existing cookie */
717 if(ctx
->dtlsCookie
.data
) {
718 SSLFreeBuffer(&ctx
->dtlsCookie
, ctx
);
722 if((err
=SSLAllocBuffer(&ctx
->dtlsCookie
, cookieLen
, ctx
))!=noErr
)
725 memmove(ctx
->dtlsCookie
.data
, cookie
, cookieLen
);
730 SSLSetMaxDatagramRecordSize (SSLContextRef ctx
,
734 if(ctx
== NULL
) return paramErr
;
735 if(!ctx
->isDTLS
) return paramErr
;
736 if(maxSize
< MIN_ALLOWED_DTLS_MTU
) return paramErr
;
744 SSLGetMaxDatagramRecordSize (SSLContextRef ctx
,
747 if(ctx
== NULL
) return paramErr
;
748 if(!ctx
->isDTLS
) return paramErr
;
757 Keys to to math below:
759 A DTLS record looks like this: | header (13 bytes) | fragment |
761 For Null cipher, fragment is clear text as follows:
764 For block cipher, fragment size must be a multiple of the cipher block size, and is the
765 encryption of the following plaintext :
766 | IV (1 block) | content | MAC | padding (0 to 255 bytes) | Padlen (1 byte) |
768 The maximum content length in that case is achieved for 0 padding bytes.
773 SSLGetDatagramWriteSize (SSLContextRef ctx
,
776 if(ctx
== NULL
) return paramErr
;
777 if(!ctx
->isDTLS
) return paramErr
;
778 if(bufSize
== NULL
) return paramErr
;
780 size_t max_fragment_size
= ctx
->mtu
-13; /* 13 = dtls record header */
782 UInt16 blockSize
= ctx
->writeCipher
.symCipher
->blockSize
;
785 /* max_fragment_size must be a multiple of blocksize */
786 max_fragment_size
= max_fragment_size
& ~(blockSize
-1);
787 max_fragment_size
-= blockSize
; /* 1 block for IV */
788 max_fragment_size
-= 1; /* 1 byte for pad length */
791 /* less the mac size */
792 max_fragment_size
-= ctx
->writeCipher
.macRef
->hash
->digestSize
;
794 /* Thats just a sanity check */
795 assert(max_fragment_size
<ctx
->mtu
);
797 *bufSize
= max_fragment_size
;
802 static SSLProtocolVersion
SSLProtocolToProtocolVersion(SSLProtocol protocol
) {
804 case kSSLProtocol2
: return SSL_Version_2_0
;
805 case kSSLProtocol3
: return SSL_Version_3_0
;
806 case kTLSProtocol1
: return TLS_Version_1_0
;
807 case kTLSProtocol11
: return TLS_Version_1_1
;
808 case kTLSProtocol12
: return TLS_Version_1_2
;
809 case kDTLSProtocol1
: return DTLS_Version_1_0
;
810 default: return SSL_Version_Undetermined
;
814 /* concert between private SSLProtocolVersion and public SSLProtocol */
815 static SSLProtocol
SSLProtocolVersionToProtocol(SSLProtocolVersion version
)
818 case SSL_Version_2_0
: return kSSLProtocol2
;
819 case SSL_Version_3_0
: return kSSLProtocol3
;
820 case TLS_Version_1_0
: return kTLSProtocol1
;
821 case TLS_Version_1_1
: return kTLSProtocol11
;
822 case TLS_Version_1_2
: return kTLSProtocol12
;
823 case DTLS_Version_1_0
: return kDTLSProtocol1
;
825 sslErrorLog("SSLProtocolVersionToProtocol: bad prot (%04x)\n",
828 case SSL_Version_Undetermined
: return kSSLProtocolUnknown
;
833 SSLSetProtocolVersionMin (SSLContextRef ctx
,
834 SSLProtocol minVersion
)
836 if(ctx
== NULL
) return paramErr
;
838 SSLProtocolVersion version
= SSLProtocolToProtocolVersion(minVersion
);
840 if (version
> MINIMUM_DATAGRAM_VERSION
||
841 version
< MAXIMUM_DATAGRAM_VERSION
)
842 return errSSLIllegalParam
;
843 if (version
< ctx
->maxProtocolVersion
)
844 ctx
->maxProtocolVersion
= version
;
846 if (version
< MINIMUM_STREAM_VERSION
|| version
> MAXIMUM_STREAM_VERSION
)
847 return errSSLIllegalParam
;
848 if (version
> ctx
->maxProtocolVersion
)
849 ctx
->maxProtocolVersion
= version
;
851 ctx
->minProtocolVersion
= version
;
857 SSLGetProtocolVersionMin (SSLContextRef ctx
,
858 SSLProtocol
*minVersion
)
860 if(ctx
== NULL
) return paramErr
;
862 *minVersion
= SSLProtocolVersionToProtocol(ctx
->minProtocolVersion
);
867 SSLSetProtocolVersionMax (SSLContextRef ctx
,
868 SSLProtocol maxVersion
)
870 if(ctx
== NULL
) return paramErr
;
872 SSLProtocolVersion version
= SSLProtocolToProtocolVersion(maxVersion
);
874 if (version
> MINIMUM_DATAGRAM_VERSION
||
875 version
< MAXIMUM_DATAGRAM_VERSION
)
876 return errSSLIllegalParam
;
877 if (version
> ctx
->minProtocolVersion
)
878 ctx
->minProtocolVersion
= version
;
880 if (version
< MINIMUM_STREAM_VERSION
|| version
> MAXIMUM_STREAM_VERSION
)
881 return errSSLIllegalParam
;
882 if (version
< ctx
->minProtocolVersion
)
883 ctx
->minProtocolVersion
= version
;
885 ctx
->maxProtocolVersion
= version
;
891 SSLGetProtocolVersionMax (SSLContextRef ctx
,
892 SSLProtocol
*maxVersion
)
894 if(ctx
== NULL
) return paramErr
;
896 *maxVersion
= SSLProtocolVersionToProtocol(ctx
->maxProtocolVersion
);
902 SSLSetProtocolVersionEnabled(SSLContextRef ctx
,
903 SSLProtocol protocol
,
909 if(sslIsSessionActive(ctx
) || ctx
->isDTLS
) {
910 /* Can't do this with an active session, nor with a DTLS session */
913 if (protocol
== kSSLProtocolAll
) {
915 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
916 ctx
->maxProtocolVersion
= MAXIMUM_STREAM_VERSION
;
918 ctx
->minProtocolVersion
= SSL_Version_Undetermined
;
919 ctx
->maxProtocolVersion
= SSL_Version_Undetermined
;
922 SSLProtocolVersion version
= SSLProtocolToProtocolVersion(protocol
);
924 if (version
< MINIMUM_STREAM_VERSION
|| version
> MAXIMUM_STREAM_VERSION
) {
927 if (version
> ctx
->maxProtocolVersion
) {
928 ctx
->maxProtocolVersion
= version
;
929 if (ctx
->minProtocolVersion
== SSL_Version_Undetermined
)
930 ctx
->minProtocolVersion
= version
;
932 if (version
< ctx
->minProtocolVersion
) {
933 ctx
->minProtocolVersion
= version
;
936 if (version
< SSL_Version_2_0
|| version
> MAXIMUM_STREAM_VERSION
) {
939 /* Disabling a protocol version now resets the minimum acceptable
940 * version to the next higher version. This means it's no longer
941 * possible to enable a discontiguous set of protocol versions.
943 SSLProtocolVersion nextVersion
;
945 case SSL_Version_2_0
:
946 nextVersion
= SSL_Version_3_0
;
948 case SSL_Version_3_0
:
949 nextVersion
= TLS_Version_1_0
;
951 case TLS_Version_1_0
:
952 nextVersion
= TLS_Version_1_1
;
954 case TLS_Version_1_1
:
955 nextVersion
= TLS_Version_1_2
;
957 case TLS_Version_1_2
:
959 nextVersion
= SSL_Version_Undetermined
;
962 ctx
->minProtocolVersion
= max(ctx
->minProtocolVersion
, nextVersion
);
963 if (ctx
->minProtocolVersion
> ctx
->maxProtocolVersion
) {
964 ctx
->minProtocolVersion
= SSL_Version_Undetermined
;
965 ctx
->maxProtocolVersion
= SSL_Version_Undetermined
;
974 SSLGetProtocolVersionEnabled(SSLContextRef ctx
,
975 SSLProtocol protocol
,
976 Boolean
*enable
) /* RETURNED */
982 /* Can't do this with a DTLS session */
992 SSLProtocolVersion version
= SSLProtocolToProtocolVersion(protocol
);
993 *enable
= (ctx
->minProtocolVersion
<= version
994 && ctx
->maxProtocolVersion
>= version
);
997 case kSSLProtocolAll
:
998 *enable
= (ctx
->minProtocolVersion
<= MINIMUM_STREAM_VERSION
999 && ctx
->maxProtocolVersion
>= MAXIMUM_STREAM_VERSION
);
1009 SSLSetProtocolVersion (SSLContextRef ctx
,
1010 SSLProtocol version
)
1015 if(sslIsSessionActive(ctx
) || ctx
->isDTLS
) {
1016 /* Can't do this with an active session, nor with a DTLS session */
1022 /* this tells us to do our best, up to 3.0 */
1023 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1024 ctx
->maxProtocolVersion
= SSL_Version_3_0
;
1026 case kSSLProtocol3Only
:
1027 ctx
->minProtocolVersion
= SSL_Version_3_0
;
1028 ctx
->maxProtocolVersion
= SSL_Version_3_0
;
1031 /* this tells us to do our best, up to TLS, but allows 3.0 */
1032 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1033 ctx
->maxProtocolVersion
= TLS_Version_1_0
;
1035 case kTLSProtocol1Only
:
1036 ctx
->minProtocolVersion
= TLS_Version_1_0
;
1037 ctx
->maxProtocolVersion
= TLS_Version_1_0
;
1039 case kTLSProtocol11
:
1040 /* This tells us to do our best, up to TLS 1.1, currently also
1041 allows 3.0 or TLS 1.0 */
1042 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1043 ctx
->maxProtocolVersion
= TLS_Version_1_1
;
1045 case kTLSProtocol12
:
1046 case kSSLProtocolAll
:
1047 case kSSLProtocolUnknown
:
1048 /* This tells us to do our best, up to TLS 1.2, currently also
1049 allows 3.0 or TLS 1.0 or TLS 1.1 */
1050 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1051 ctx
->maxProtocolVersion
= MAXIMUM_STREAM_VERSION
;
1062 SSLGetProtocolVersion (SSLContextRef ctx
,
1063 SSLProtocol
*protocol
) /* RETURNED */
1068 /* translate array of booleans to public value; not all combinations
1069 * are legal (i.e., meaningful) for this call */
1070 if (ctx
->maxProtocolVersion
== MAXIMUM_STREAM_VERSION
) {
1071 if(ctx
->minProtocolVersion
== MINIMUM_STREAM_VERSION
) {
1072 /* traditional 'all enabled' */
1073 *protocol
= kSSLProtocolAll
;
1076 } else if (ctx
->maxProtocolVersion
== TLS_Version_1_1
) {
1077 if(ctx
->minProtocolVersion
== MINIMUM_STREAM_VERSION
) {
1078 /* traditional 'all enabled' */
1079 *protocol
= kTLSProtocol11
;
1082 } else if (ctx
->maxProtocolVersion
== TLS_Version_1_0
) {
1083 if(ctx
->minProtocolVersion
== MINIMUM_STREAM_VERSION
) {
1084 /* TLS1.1 and below enabled */
1085 *protocol
= kTLSProtocol1
;
1087 } else if(ctx
->minProtocolVersion
== TLS_Version_1_0
) {
1088 *protocol
= kTLSProtocol1Only
;
1090 } else if(ctx
->maxProtocolVersion
== SSL_Version_3_0
) {
1091 if(ctx
->minProtocolVersion
== MINIMUM_STREAM_VERSION
) {
1092 /* Could also return kSSLProtocol3Only since
1093 MINIMUM_STREAM_VERSION == SSL_Version_3_0. */
1094 *protocol
= kSSLProtocol3
;
1103 SSLGetNegotiatedProtocolVersion (SSLContextRef ctx
,
1104 SSLProtocol
*protocol
) /* RETURNED */
1109 *protocol
= SSLProtocolVersionToProtocol(ctx
->negProtocolVersion
);
1114 SSLSetEnableCertVerify (SSLContextRef ctx
,
1115 Boolean enableVerify
)
1120 sslCertDebug("SSLSetEnableCertVerify %s",
1121 enableVerify
? "true" : "false");
1122 if(sslIsSessionActive(ctx
)) {
1123 /* can't do this with an active session */
1126 ctx
->enableCertVerify
= enableVerify
;
1131 SSLGetEnableCertVerify (SSLContextRef ctx
,
1132 Boolean
*enableVerify
)
1137 *enableVerify
= ctx
->enableCertVerify
;
1142 SSLSetAllowsExpiredCerts(SSLContextRef ctx
,
1143 Boolean allowExpired
)
1148 sslCertDebug("SSLSetAllowsExpiredCerts %s",
1149 allowExpired
? "true" : "false");
1150 if(sslIsSessionActive(ctx
)) {
1151 /* can't do this with an active session */
1154 ctx
->allowExpiredCerts
= allowExpired
;
1159 SSLGetAllowsExpiredCerts (SSLContextRef ctx
,
1160 Boolean
*allowExpired
)
1165 *allowExpired
= ctx
->allowExpiredCerts
;
1170 SSLSetAllowsExpiredRoots(SSLContextRef ctx
,
1171 Boolean allowExpired
)
1176 sslCertDebug("SSLSetAllowsExpiredRoots %s",
1177 allowExpired
? "true" : "false");
1178 if(sslIsSessionActive(ctx
)) {
1179 /* can't do this with an active session */
1182 ctx
->allowExpiredRoots
= allowExpired
;
1187 SSLGetAllowsExpiredRoots (SSLContextRef ctx
,
1188 Boolean
*allowExpired
)
1193 *allowExpired
= ctx
->allowExpiredRoots
;
1197 OSStatus
SSLSetAllowsAnyRoot(
1204 sslCertDebug("SSLSetAllowsAnyRoot %s", anyRoot
? "true" : "false");
1205 ctx
->allowAnyRoot
= anyRoot
;
1210 SSLGetAllowsAnyRoot(
1217 *anyRoot
= ctx
->allowAnyRoot
;
1221 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
1222 /* obtain the system roots sets for this app, policy SSL */
1223 static OSStatus
sslDefaultSystemRoots(
1225 CFArrayRef
*systemRoots
) // created and RETURNED
1228 return SecTrustSettingsCopyQualifiedCerts(&CSSMOID_APPLE_TP_SSL
,
1229 NULL
, true, // application - us
1230 ctx
->peerDomainName
,
1231 ctx
->peerDomainNameLen
,
1232 (ctx
->protocolSide
== kSSLServerSide
) ?
1233 /* server verifies, client encrypts */
1234 CSSM_KEYUSE_VERIFY
: CSSM_KEYUSE_ENCRYPT
,
1237 #endif /* OS X only */
1240 SSLSetTrustedRoots (SSLContextRef ctx
,
1241 CFArrayRef trustedRoots
,
1242 Boolean replaceExisting
)
1244 #ifdef USE_CDSA_CRYPTO
1248 if(sslIsSessionActive(ctx
)) {
1249 /* can't do this with an active session */
1253 if(replaceExisting
) {
1254 /* trivial case - retain the new, throw out the old. */
1256 CFRetain(trustedRoots
);
1257 CFReleaseSafe(ctx
->trustedCerts
);
1258 ctx
->trustedCerts
= trustedRoots
;
1262 /* adding new trusted roots - to either our existing set, or the system set */
1263 CFArrayRef existingRoots
= NULL
;
1265 if(ctx
->trustedCerts
!= NULL
) {
1266 /* we'll release these as we exit */
1267 existingRoots
= ctx
->trustedCerts
;
1270 /* get system set for this app, policy SSL */
1271 ortn
= sslDefaultSystemRoots(ctx
, &existingRoots
);
1273 CFReleaseSafe(existingRoots
);
1278 /* Create a new root array with caller's roots first */
1279 CFMutableArrayRef newRoots
= CFArrayCreateMutableCopy(NULL
, 0, trustedRoots
);
1280 CFRange existRange
= { 0, CFArrayGetCount(existingRoots
) };
1281 CFArrayAppendArray(newRoots
, existingRoots
, existRange
);
1282 CFRelease(existingRoots
);
1283 ctx
->trustedCerts
= newRoots
;
1287 if (sslIsSessionActive(ctx
)) {
1288 /* can't do this with an active session */
1291 sslCertDebug("SSLSetTrustedRoot numCerts %d replaceExist %s",
1292 (int)CFArrayGetCount(trustedRoots
), replaceExisting
? "true" : "false");
1294 if (replaceExisting
) {
1295 ctx
->trustedCertsOnly
= true;
1296 CFReleaseNull(ctx
->trustedCerts
);
1299 if (ctx
->trustedCerts
) {
1300 CFIndex count
= CFArrayGetCount(trustedRoots
);
1301 CFRange range
= { 0, count
};
1302 CFArrayAppendArray(ctx
->trustedCerts
, trustedRoots
, range
);
1304 require(ctx
->trustedCerts
=
1305 CFArrayCreateMutableCopy(kCFAllocatorDefault
, 0, trustedRoots
),
1313 #endif /* !USE_CDSA_CRYPTO */
1317 SSLCopyTrustedRoots (SSLContextRef ctx
,
1318 CFArrayRef
*trustedRoots
) /* RETURNED */
1320 if(ctx
== NULL
|| trustedRoots
== NULL
) {
1323 if(ctx
->trustedCerts
!= NULL
) {
1324 *trustedRoots
= ctx
->trustedCerts
;
1325 CFRetain(ctx
->trustedCerts
);
1328 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
1329 /* use default system roots */
1330 return sslDefaultSystemRoots(ctx
, trustedRoots
);
1332 *trustedRoots
= NULL
;
1337 /* legacy version, caller must CFRelease each cert */
1339 SSLGetTrustedRoots (SSLContextRef ctx
,
1340 CFArrayRef
*trustedRoots
) /* RETURNED */
1344 if((ctx
== NULL
) || (trustedRoots
== NULL
)) {
1348 ortn
= SSLCopyTrustedRoots(ctx
, trustedRoots
);
1352 /* apply the legacy bug */
1353 CFIndex numCerts
= CFArrayGetCount(*trustedRoots
);
1355 for(dex
=0; dex
<numCerts
; dex
++) {
1356 CFRetain(CFArrayGetValueAtIndex(*trustedRoots
, dex
));
1362 SSLSetTrustedLeafCertificates (SSLContextRef ctx
,
1363 CFArrayRef trustedCerts
)
1368 if(sslIsSessionActive(ctx
)) {
1369 /* can't do this with an active session */
1373 if(ctx
->trustedLeafCerts
) {
1374 CFRelease(ctx
->trustedLeafCerts
);
1376 ctx
->trustedLeafCerts
= trustedCerts
;
1377 CFRetain(trustedCerts
);
1382 SSLCopyTrustedLeafCertificates (SSLContextRef ctx
,
1383 CFArrayRef
*trustedCerts
) /* RETURNED */
1388 if(ctx
->trustedLeafCerts
!= NULL
) {
1389 *trustedCerts
= ctx
->trustedLeafCerts
;
1390 CFRetain(ctx
->trustedCerts
);
1393 *trustedCerts
= NULL
;
1398 SSLSetClientSideAuthenticate (SSLContext
*ctx
,
1399 SSLAuthenticate auth
)
1404 if(sslIsSessionActive(ctx
)) {
1405 /* can't do this with an active session */
1408 ctx
->clientAuth
= auth
;
1410 case kNeverAuthenticate
:
1411 ctx
->tryClientAuth
= false;
1413 case kAlwaysAuthenticate
:
1414 case kTryAuthenticate
:
1415 ctx
->tryClientAuth
= true;
1422 SSLGetClientSideAuthenticate (SSLContext
*ctx
,
1423 SSLAuthenticate
*auth
) /* RETURNED */
1425 if(ctx
== NULL
|| auth
== NULL
) {
1428 *auth
= ctx
->clientAuth
;
1433 SSLGetClientCertificateState (SSLContextRef ctx
,
1434 SSLClientCertificateState
*clientState
)
1439 *clientState
= ctx
->clientCertState
;
1444 SSLSetCertificate (SSLContextRef ctx
,
1445 CFArrayRef certRefs
)
1448 * -- free localCerts if we have any
1449 * -- Get raw cert data, convert to ctx->localCert
1450 * -- get pub, priv keys from certRef[0]
1451 * -- validate cert chain
1457 /* can't do this with an active session */
1458 if(sslIsSessionActive(ctx
) &&
1459 /* kSSLClientCertRequested implies client side */
1460 (ctx
->clientCertState
!= kSSLClientCertRequested
))
1464 CFReleaseNull(ctx
->localCertArray
);
1465 /* changing the client cert invalidates negotiated auth type */
1466 ctx
->negAuthType
= SSLClientAuthNone
;
1467 if(certRefs
== NULL
) {
1468 return noErr
; // we have cleared the cert, as requested
1470 OSStatus ortn
= parseIncomingCerts(ctx
,
1473 &ctx
->signingPubKey
,
1474 &ctx
->signingPrivKeyRef
,
1475 &ctx
->ourSignerAlg
);
1477 ctx
->localCertArray
= certRefs
;
1479 /* client cert was changed, must update auth type */
1480 ortn
= SSLUpdateNegotiatedClientAuthType(ctx
);
1486 SSLSetEncryptionCertificate (SSLContextRef ctx
,
1487 CFArrayRef certRefs
)
1490 * -- free encryptCert if we have any
1491 * -- Get raw cert data, convert to ctx->encryptCert
1492 * -- get pub, priv keys from certRef[0]
1493 * -- validate cert chain
1498 if(sslIsSessionActive(ctx
)) {
1499 /* can't do this with an active session */
1502 CFReleaseNull(ctx
->encryptCertArray
);
1503 OSStatus ortn
= parseIncomingCerts(ctx
,
1506 &ctx
->encryptPubKey
,
1507 &ctx
->encryptPrivKeyRef
,
1508 NULL
); /* Signer alg */
1510 ctx
->encryptCertArray
= certRefs
;
1516 OSStatus
SSLGetCertificate(SSLContextRef ctx
,
1517 CFArrayRef
*certRefs
)
1522 *certRefs
= ctx
->localCertArray
;
1526 OSStatus
SSLGetEncryptionCertificate(SSLContextRef ctx
,
1527 CFArrayRef
*certRefs
)
1532 *certRefs
= ctx
->encryptCertArray
;
1537 SSLSetPeerID (SSLContext
*ctx
,
1543 /* copy peerId to context->peerId */
1549 if(sslIsSessionActive(ctx
) &&
1550 /* kSSLClientCertRequested implies client side */
1551 (ctx
->clientCertState
!= kSSLClientCertRequested
))
1555 SSLFreeBuffer(&ctx
->peerID
, ctx
);
1556 serr
= SSLAllocBuffer(&ctx
->peerID
, peerIDLen
, ctx
);
1560 memmove(ctx
->peerID
.data
, peerID
, peerIDLen
);
1565 SSLGetPeerID (SSLContextRef ctx
,
1566 const void **peerID
,
1569 *peerID
= ctx
->peerID
.data
; // may be NULL
1570 *peerIDLen
= ctx
->peerID
.length
;
1575 SSLGetNegotiatedCipher (SSLContextRef ctx
,
1576 SSLCipherSuite
*cipherSuite
)
1581 if(!sslIsSessionActive(ctx
)) {
1584 *cipherSuite
= (SSLCipherSuite
)ctx
->selectedCipher
;
1589 * Add an acceptable distinguished name (client authentication only).
1592 SSLAddDistinguishedName(
1603 if(sslIsSessionActive(ctx
)) {
1607 dn
= (DNListElem
*)sslMalloc(sizeof(DNListElem
));
1611 if ((err
= SSLAllocBuffer(&dn
->derDN
, derDNLen
, ctx
)) != 0)
1613 memcpy(dn
->derDN
.data
, derDN
, derDNLen
);
1614 dn
->next
= ctx
->acceptableDNList
;
1615 ctx
->acceptableDNList
= dn
;
1619 /* single-cert version of SSLSetCertificateAuthorities() */
1621 sslAddCA(SSLContextRef ctx
,
1622 SecCertificateRef cert
)
1624 OSStatus ortn
= paramErr
;
1625 CFDataRef subjectName
;
1627 /* Get subject from certificate. */
1628 require(subjectName
= SecCertificateCopySubjectSequence(cert
), errOut
);
1629 /* add to acceptableCAs as cert, creating array if necessary */
1630 if(ctx
->acceptableCAs
== NULL
) {
1631 require(ctx
->acceptableCAs
= CFArrayCreateMutable(NULL
, 0,
1632 &kCFTypeArrayCallBacks
), errOut
);
1633 if(ctx
->acceptableCAs
== NULL
) {
1637 CFArrayAppendValue(ctx
->acceptableCAs
, cert
);
1639 /* then add this cert's subject name to acceptableDNList */
1640 ortn
= SSLAddDistinguishedName(ctx
, CFDataGetBytePtr(subjectName
),
1641 CFDataGetLength(subjectName
));
1643 CFReleaseSafe(subjectName
);
1648 * Add a SecCertificateRef, or a CFArray of them, to a server's list
1649 * of acceptable Certificate Authorities (CAs) to present to the client
1650 * when client authentication is performed.
1653 SSLSetCertificateAuthorities(SSLContextRef ctx
,
1654 CFTypeRef certificateOrArray
,
1655 Boolean replaceExisting
)
1658 OSStatus ortn
= noErr
;
1660 if((ctx
== NULL
) || sslIsSessionActive(ctx
) ||
1661 (ctx
->protocolSide
!= kSSLServerSide
)) {
1664 if(replaceExisting
) {
1666 if(ctx
->acceptableCAs
) {
1667 CFRelease(ctx
->acceptableCAs
);
1668 ctx
->acceptableCAs
= NULL
;
1671 /* else appending */
1673 itemType
= CFGetTypeID(certificateOrArray
);
1674 if(itemType
== SecCertificateGetTypeID()) {
1676 ortn
= sslAddCA(ctx
, (SecCertificateRef
)certificateOrArray
);
1678 else if(itemType
== CFArrayGetTypeID()) {
1679 CFArrayRef cfa
= (CFArrayRef
)certificateOrArray
;
1680 CFIndex numCerts
= CFArrayGetCount(cfa
);
1683 /* array of certs */
1684 for(dex
=0; dex
<numCerts
; dex
++) {
1685 SecCertificateRef cert
= (SecCertificateRef
)CFArrayGetValueAtIndex(cfa
, dex
);
1686 if(CFGetTypeID(cert
) != SecCertificateGetTypeID()) {
1689 ortn
= sslAddCA(ctx
, cert
);
1703 * Obtain the certificates specified in SSLSetCertificateAuthorities(),
1704 * if any. Returns a NULL array if SSLSetCertificateAuthorities() has not
1706 * Caller must CFRelease the returned array.
1709 SSLCopyCertificateAuthorities(SSLContextRef ctx
,
1710 CFArrayRef
*certificates
) /* RETURNED */
1712 if((ctx
== NULL
) || (certificates
== NULL
)) {
1715 if(ctx
->acceptableCAs
== NULL
) {
1716 *certificates
= NULL
;
1719 *certificates
= ctx
->acceptableCAs
;
1720 CFRetain(ctx
->acceptableCAs
);
1726 * Obtain the list of acceptable distinguished names as provided by
1727 * a server (if the SSLCotextRef is configured as a client), or as
1728 * specified by SSLSetCertificateAuthorities() (if the SSLContextRef
1729 * is configured as a server).
1732 SSLCopyDistinguishedNames (SSLContextRef ctx
,
1735 CFMutableArrayRef outArray
= NULL
;
1738 if((ctx
== NULL
) || (names
== NULL
)) {
1741 if(ctx
->acceptableDNList
== NULL
) {
1745 outArray
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1746 dn
= ctx
->acceptableDNList
;
1748 CFDataRef cfDn
= CFDataCreate(NULL
, dn
->derDN
.data
, dn
->derDN
.length
);
1749 CFArrayAppendValue(outArray
, cfDn
);
1759 * Request peer certificates. Valid anytime, subsequent to
1760 * a handshake attempt.
1761 * Common code for SSLGetPeerCertificates() and SSLCopyPeerCertificates().
1764 sslCopyPeerCertificates (SSLContextRef ctx
,
1772 #ifdef USE_SSLCERTIFICATE
1774 CFMutableArrayRef ca
;
1776 SecCertificateRef cfd
;
1779 SSLCertificate
*scert
;
1784 * Copy peerCert, a chain of SSLCertificates, to a CFArray of
1785 * CFDataRefs, each of which is one DER-encoded cert.
1787 numCerts
= SSLGetCertificateChainLength(ctx
->peerCert
);
1791 ca
= CFArrayCreateMutable(kCFAllocatorDefault
,
1792 (CFIndex
)numCerts
, &kCFTypeArrayCallBacks
);
1798 * Caller gets leaf cert first, the opposite of the way we store them.
1800 scert
= ctx
->peerCert
;
1801 for(i
=0; (unsigned)i
<numCerts
; i
++) {
1802 assert(scert
!= NULL
); /* else SSLGetCertificateChainLength
1804 SSLBUF_TO_CSSM(&scert
->derCert
, &certData
);
1805 ortn
= SecCertificateCreateFromData(&certData
,
1807 CSSM_CERT_ENCODING_DER
,
1813 /* insert at head of array */
1814 CFArrayInsertValueAtIndex(ca
, 0, cfd
);
1816 /* skip for legacy SSLGetPeerCertificates() */
1819 scert
= scert
->next
;
1824 if (!ctx
->peerCert
) {
1829 CFArrayRef ca
= CFArrayCreateCopy(kCFAllocatorDefault
, ctx
->peerCert
);
1836 CFIndex ix
, count
= CFArrayGetCount(ca
);
1837 for (ix
= 0; ix
< count
; ++ix
) {
1838 CFRetain(CFArrayGetValueAtIndex(ca
, ix
));
1847 SSLCopyPeerCertificates (SSLContextRef ctx
,
1850 return sslCopyPeerCertificates(ctx
, certs
, false);
1854 SSLGetPeerCertificates (SSLContextRef ctx
,
1857 return sslCopyPeerCertificates(ctx
, certs
, true);
1862 * Specify Diffie-Hellman parameters. Optional; if we are configured to allow
1863 * for D-H ciphers and a D-H cipher is negotiated, and this function has not
1864 * been called, a set of process-wide parameters will be calculated. However
1865 * that can take a long time (30 seconds).
1867 OSStatus
SSLSetDiffieHellmanParams(
1869 const void *dhParams
,
1876 if(sslIsSessionActive(ctx
)) {
1879 SSLFreeBuffer(&ctx
->dhParamsEncoded
, ctx
);
1880 #if !USE_CDSA_CRYPTO
1881 if (ctx
->secDHContext
)
1882 SecDHDestroy(ctx
->secDHContext
);
1886 ortn
= SSLCopyBufferFromData(dhParams
, dhParamsLen
,
1887 &ctx
->dhParamsEncoded
);
1891 #endif /* APPLE_DH */
1895 * Return parameter block specified in SSLSetDiffieHellmanParams.
1896 * Returned data is not copied and belongs to the SSLContextRef.
1898 OSStatus
SSLGetDiffieHellmanParams(
1900 const void **dhParams
,
1901 size_t *dhParamsLen
)
1907 *dhParams
= ctx
->dhParamsEncoded
.data
;
1908 *dhParamsLen
= ctx
->dhParamsEncoded
.length
;
1912 #endif /* APPLE_DH */
1915 OSStatus
SSLSetRsaBlinding(
1922 ctx
->rsaBlindingEnable
= blinding
;
1926 OSStatus
SSLGetRsaBlinding(
1933 *blinding
= ctx
->rsaBlindingEnable
;
1940 SecTrustRef
*trust
) /* RETURNED */
1942 OSStatus status
= noErr
;
1943 if (ctx
== NULL
|| trust
== NULL
)
1946 /* Create a SecTrustRef if this was a resumed session and we
1947 didn't have one yet. */
1948 if (!ctx
->peerSecTrust
&& ctx
->peerCert
) {
1949 status
= sslCreateSecTrust(ctx
, ctx
->peerCert
, true,
1950 &ctx
->peerSecTrust
);
1953 *trust
= ctx
->peerSecTrust
;
1954 if (ctx
->peerSecTrust
)
1955 CFRetain(ctx
->peerSecTrust
);
1960 OSStatus
SSLGetPeerSecTrust(
1962 SecTrustRef
*trust
) /* RETURNED */
1964 OSStatus status
= noErr
;
1965 if (ctx
== NULL
|| trust
== NULL
)
1968 /* Create a SecTrustRef if this was a resumed session and we
1969 didn't have one yet. */
1970 if (!ctx
->peerSecTrust
&& ctx
->peerCert
) {
1971 status
= sslCreateSecTrust(ctx
, ctx
->peerCert
, true,
1972 &ctx
->peerSecTrust
);
1975 *trust
= ctx
->peerSecTrust
;
1979 OSStatus
SSLInternalMasterSecret(
1981 void *secret
, // mallocd by caller, SSL_MASTER_SECRET_SIZE
1982 size_t *secretSize
) // in/out
1984 if((ctx
== NULL
) || (secret
== NULL
) || (secretSize
== NULL
)) {
1987 if(*secretSize
< SSL_MASTER_SECRET_SIZE
) {
1990 memmove(secret
, ctx
->masterSecret
, SSL_MASTER_SECRET_SIZE
);
1991 *secretSize
= SSL_MASTER_SECRET_SIZE
;
1995 OSStatus
SSLInternalServerRandom(
1997 void *randBuf
, // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
1998 size_t *randSize
) // in/out
2000 if((ctx
== NULL
) || (randBuf
== NULL
) || (randSize
== NULL
)) {
2003 if(*randSize
< SSL_CLIENT_SRVR_RAND_SIZE
) {
2006 memmove(randBuf
, ctx
->serverRandom
, SSL_CLIENT_SRVR_RAND_SIZE
);
2007 *randSize
= SSL_CLIENT_SRVR_RAND_SIZE
;
2011 OSStatus
SSLInternalClientRandom(
2013 void *randBuf
, // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
2014 size_t *randSize
) // in/out
2016 if((ctx
== NULL
) || (randBuf
== NULL
) || (randSize
== NULL
)) {
2019 if(*randSize
< SSL_CLIENT_SRVR_RAND_SIZE
) {
2022 memmove(randBuf
, ctx
->clientRandom
, SSL_CLIENT_SRVR_RAND_SIZE
);
2023 *randSize
= SSL_CLIENT_SRVR_RAND_SIZE
;
2027 OSStatus
SSLGetCipherSizes(
2030 size_t *symmetricKeySize
,
2033 const SSLCipherSpec
*currCipher
;
2035 if((ctx
== NULL
) || (digestSize
== NULL
) ||
2036 (symmetricKeySize
== NULL
) || (ivSize
== NULL
)) {
2039 currCipher
= &ctx
->selectedCipherSpec
;
2040 *digestSize
= currCipher
->macAlgorithm
->hash
->digestSize
;
2041 *symmetricKeySize
= currCipher
->cipher
->secretKeySize
;
2042 *ivSize
= currCipher
->cipher
->ivSize
;
2047 SSLGetResumableSessionInfo(
2049 Boolean
*sessionWasResumed
, // RETURNED
2050 void *sessionID
, // RETURNED, mallocd by caller
2051 size_t *sessionIDLength
) // IN/OUT
2053 if((ctx
== NULL
) || (sessionWasResumed
== NULL
) ||
2054 (sessionID
== NULL
) || (sessionIDLength
== NULL
) ||
2055 (*sessionIDLength
< MAX_SESSION_ID_LENGTH
)) {
2058 if(ctx
->sessionMatch
) {
2059 *sessionWasResumed
= true;
2060 if(ctx
->sessionID
.length
> *sessionIDLength
) {
2061 /* really should never happen - means ID > 32 */
2064 if(ctx
->sessionID
.length
) {
2066 * Note PAC-based session resumption can result in sessionMatch
2069 memmove(sessionID
, ctx
->sessionID
.data
, ctx
->sessionID
.length
);
2071 *sessionIDLength
= ctx
->sessionID
.length
;
2074 *sessionWasResumed
= false;
2075 *sessionIDLength
= 0;
2081 * Get/set enable of anonymous ciphers. Default is enabled.
2084 SSLSetAllowAnonymousCiphers(
2091 if(sslIsSessionActive(ctx
)) {
2094 if(ctx
->validCipherSuites
!= NULL
) {
2095 /* SSLSetEnabledCiphers() has already been called */
2098 ctx
->anonCipherEnable
= enable
;
2103 SSLGetAllowAnonymousCiphers(
2107 if((ctx
== NULL
) || (enable
== NULL
)) {
2110 if(sslIsSessionActive(ctx
)) {
2113 *enable
= ctx
->anonCipherEnable
;
2118 * Override the default session cache timeout for a cache entry created for
2119 * the current session.
2122 SSLSetSessionCacheTimeout(
2124 uint32_t timeoutInSeconds
)
2129 ctx
->sessionCacheTimeout
= timeoutInSeconds
;
2134 * Register a callback for obtaining the master_secret when performing
2135 * PAC-based session resumption.
2138 SSLInternalSetMasterSecretFunction(
2140 SSLInternalMasterSecretFunction mFunc
,
2141 const void *arg
) /* opaque to SecureTransport; app-specific */
2146 ctx
->masterSecretCallback
= mFunc
;
2147 ctx
->masterSecretArg
= arg
;
2152 * Provide an opaque SessionTicket for use in PAC-based session
2153 * resumption. Client side only. The provided ticket is sent in
2154 * the ClientHello message as a SessionTicket extension.
2156 * We won't reject this on the server side, but server-side support
2157 * for PAC-based session resumption is currently enabled for
2158 * Development builds only. To fully support this for server side,
2159 * besides the rudimentary support that's here for Development builds,
2160 * we'd need a getter for the session ticket, so the app code can
2161 * access the SessionTicket when its SSLInternalMasterSecretFunction
2162 * callback is called.
2164 OSStatus
SSLInternalSetSessionTicket(
2167 size_t ticketLength
)
2172 if(sslIsSessionActive(ctx
)) {
2173 /* can't do this with an active session */
2176 if(ticketLength
> 0xffff) {
2177 /* extension data encoded with a 2-byte length! */
2180 SSLFreeBuffer(&ctx
->sessionTicket
, NULL
);
2181 return SSLCopyBufferFromData(ticket
, ticketLength
, &ctx
->sessionTicket
);
2185 * ECDSA curve accessors.
2189 * Obtain the SSL_ECDSA_NamedCurve negotiated during a handshake.
2190 * Returns paramErr if no ECDH-related ciphersuite was negotiated.
2192 OSStatus
SSLGetNegotiatedCurve(
2194 SSL_ECDSA_NamedCurve
*namedCurve
) /* RETURNED */
2196 if((ctx
== NULL
) || (namedCurve
== NULL
)) {
2199 if(ctx
->ecdhPeerCurve
== SSL_Curve_None
) {
2202 *namedCurve
= ctx
->ecdhPeerCurve
;
2207 * Obtain the number of currently enabled SSL_ECDSA_NamedCurves.
2209 OSStatus
SSLGetNumberOfECDSACurves(
2211 unsigned *numCurves
) /* RETURNED */
2213 if((ctx
== NULL
) || (numCurves
== NULL
)) {
2216 *numCurves
= ctx
->ecdhNumCurves
;
2221 * Obtain the ordered list of currently enabled SSL_ECDSA_NamedCurves.
2223 OSStatus
SSLGetECDSACurves(
2225 SSL_ECDSA_NamedCurve
*namedCurves
, /* RETURNED */
2226 unsigned *numCurves
) /* IN/OUT */
2228 if((ctx
== NULL
) || (namedCurves
== NULL
) || (numCurves
== NULL
)) {
2231 if(*numCurves
< ctx
->ecdhNumCurves
) {
2234 memmove(namedCurves
, ctx
->ecdhCurves
,
2235 (ctx
->ecdhNumCurves
* sizeof(SSL_ECDSA_NamedCurve
)));
2236 *numCurves
= ctx
->ecdhNumCurves
;
2241 * Specify ordered list of allowable named curves.
2243 OSStatus
SSLSetECDSACurves(
2245 const SSL_ECDSA_NamedCurve
*namedCurves
,
2248 if((ctx
== NULL
) || (namedCurves
== NULL
) || (numCurves
== 0)) {
2251 if(numCurves
> SSL_ECDSA_NUM_CURVES
) {
2254 if(sslIsSessionActive(ctx
)) {
2255 /* can't do this with an active session */
2258 memmove(ctx
->ecdhCurves
, namedCurves
, (numCurves
* sizeof(SSL_ECDSA_NamedCurve
)));
2259 ctx
->ecdhNumCurves
= numCurves
;
2264 * Obtain the number of client authentication mechanisms specified by
2265 * the server in its Certificate Request message.
2266 * Returns paramErr if server hasn't sent a Certificate Request message
2267 * (i.e., client certificate state is kSSLClientCertNone).
2269 OSStatus
SSLGetNumberOfClientAuthTypes(
2273 if((ctx
== NULL
) || (ctx
->clientCertState
== kSSLClientCertNone
)) {
2276 *numTypes
= ctx
->numAuthTypes
;
2281 * Obtain the client authentication mechanisms specified by
2282 * the server in its Certificate Request message.
2283 * Caller allocates returned array and specifies its size (in
2284 * SSLClientAuthenticationTypes) in *numType on entry; *numTypes
2285 * is the actual size of the returned array on successful return.
2287 OSStatus
SSLGetClientAuthTypes(
2289 SSLClientAuthenticationType
*authTypes
, /* RETURNED */
2290 unsigned *numTypes
) /* IN/OUT */
2292 if((ctx
== NULL
) || (ctx
->clientCertState
== kSSLClientCertNone
)) {
2295 memmove(authTypes
, ctx
->clientAuthTypes
,
2296 ctx
->numAuthTypes
* sizeof(SSLClientAuthenticationType
));
2297 *numTypes
= ctx
->numAuthTypes
;
2302 * Obtain the SSLClientAuthenticationType actually performed.
2303 * Only valid if client certificate state is kSSLClientCertSent
2304 * or kSSLClientCertRejected; returns paramErr otherwise.
2306 OSStatus
SSLGetNegotiatedClientAuthType(
2308 SSLClientAuthenticationType
*authType
) /* RETURNED */
2313 *authType
= ctx
->negAuthType
;
2318 * Update the negotiated client authentication type.
2319 * This function may be called at any time; however, note that
2320 * the negotiated authentication type will be SSLClientAuthNone
2321 * until both of the following have taken place (in either order):
2322 * - a CertificateRequest message from the server has been processed
2323 * - a client certificate has been specified
2324 * As such, this function (only) needs to be called from (both)
2325 * SSLProcessCertificateRequest and SSLSetCertificate.
2327 OSStatus
SSLUpdateNegotiatedClientAuthType(
2334 * See if we have a signing cert that matches one of the
2335 * allowed auth types. The x509Requested flag indicates "we
2336 * have a cert that we think the server will accept".
2338 ctx
->x509Requested
= 0;
2339 ctx
->negAuthType
= SSLClientAuthNone
;
2340 if(ctx
->signingPrivKeyRef
!= NULL
) {
2341 CFIndex ourKeyAlg
= sslPubKeyGetAlgorithmID(ctx
->signingPubKey
);
2343 for(i
=0; i
<ctx
->numAuthTypes
; i
++) {
2344 switch(ctx
->clientAuthTypes
[i
]) {
2345 case SSLClientAuth_RSASign
:
2346 if(ourKeyAlg
== kSecRSAAlgorithmID
) {
2347 ctx
->x509Requested
= 1;
2348 ctx
->negAuthType
= SSLClientAuth_RSASign
;
2351 #if SSL_ENABLE_ECDSA_SIGN_AUTH
2352 case SSLClientAuth_ECDSASign
:
2354 #if SSL_ENABLE_ECDSA_FIXED_ECDH_AUTH
2355 case SSLClientAuth_ECDSAFixedECDH
:
2357 if((ourKeyAlg
== kSecECDSAAlgorithmID
) &&
2358 (ctx
->ourSignerAlg
== kSecECDSAAlgorithmID
)) {
2359 ctx
->x509Requested
= 1;
2360 ctx
->negAuthType
= ctx
->clientAuthTypes
[i
];
2363 #if SSL_ENABLE_RSA_FIXED_ECDH_AUTH
2364 case SSLClientAuth_RSAFixedECDH
:
2365 /* Odd case, we differ from our signer */
2366 if((ourKeyAlg
== kSecECDSAAlgorithmID
) &&
2367 (ctx
->ourSignerAlg
== kSecRSAAlgorithmID
)) {
2368 ctx
->x509Requested
= 1;
2369 ctx
->negAuthType
= SSLClientAuth_RSAFixedECDH
;
2374 /* None others supported */
2377 if(ctx
->x509Requested
) {
2378 sslLogNegotiateDebug("===CHOOSING authType %d", (int)ctx
->negAuthType
);
2381 } /* parsing authTypes */
2382 } /* we have a signing key */
2387 OSStatus
SSLGetNumberOfSignatureAlgorithms(
2389 unsigned *numSigAlgs
)
2391 if((ctx
== NULL
) || (ctx
->clientCertState
== kSSLClientCertNone
)) {
2394 *numSigAlgs
= ctx
->numServerSigAlgs
;
2398 OSStatus
SSLGetSignatureAlgorithms(
2400 SSLSignatureAndHashAlgorithm
*sigAlgs
, /* RETURNED */
2401 unsigned *numSigAlgs
) /* IN/OUT */
2403 if((ctx
== NULL
) || (ctx
->clientCertState
== kSSLClientCertNone
)) {
2406 memmove(sigAlgs
, ctx
->serverSigAlgs
,
2407 ctx
->numServerSigAlgs
* sizeof(SSLSignatureAndHashAlgorithm
));
2408 *numSigAlgs
= ctx
->numServerSigAlgs
;