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
28 #include "SecureTransport.h"
30 #include "SSLRecordInternal.h"
31 #include "SecureTransportPriv.h"
32 #include "appleSession.h"
34 #include "sslCipherSpecs.h"
35 #include "sslContext.h"
36 #include "sslCrypto.h"
38 #include "sslDigests.h"
39 #include "sslKeychain.h"
40 #include "sslMemory.h"
43 #include <AssertMacros.h>
44 #include <CoreFoundation/CFData.h>
45 #include <CoreFoundation/CFPreferences.h>
46 #include <Security/SecCertificate.h>
47 #include <Security/SecCertificatePriv.h>
48 #include <Security/SecTrust.h>
49 #include <Security/SecTrustSettingsPriv.h>
50 #include <Security/oidsalg.h>
51 #include "utilities/SecCFRelease.h"
56 #include <Security/SecCertificateInternal.h>
58 #include <Security/oidsalg.h>
59 #include <Security/oidscert.h>
60 #include <Security/SecTrustSettingsPriv.h>
64 static void sslFreeDnList(
67 DNListElem
*dn
, *nextDN
;
69 dn
= ctx
->acceptableDNList
;
72 SSLFreeBuffer(&dn
->derDN
);
77 ctx
->acceptableDNList
= NULL
;
81 Boolean
sslIsSessionActive(const SSLContext
*ctx
)
85 case SSL_HdskStateUninit
:
86 case SSL_HdskStateServerUninit
:
87 case SSL_HdskStateClientUninit
:
88 case SSL_HdskStateGracefulClose
:
89 case SSL_HdskStateErrorClose
:
97 * Minimum and maximum supported versions
99 //#define MINIMUM_STREAM_VERSION SSL_Version_2_0 /* Disabled */
100 #define MINIMUM_STREAM_VERSION SSL_Version_3_0
101 #define MAXIMUM_STREAM_VERSION TLS_Version_1_2
102 #define MINIMUM_DATAGRAM_VERSION DTLS_Version_1_0
104 /* This should be changed when we start supporting DTLS_Version_1_x */
105 #define MAXIMUM_DATAGRAM_VERSION DTLS_Version_1_0
107 #define SSL_ENABLE_ECDSA_SIGN_AUTH 0
108 #define SSL_ENABLE_RSA_FIXED_ECDH_AUTH 0
109 #define SSL_ENABLE_ECDSA_FIXED_ECDH_AUTH 0
111 #define DEFAULT_DTLS_TIMEOUT 1
112 #define DEFAULT_DTLS_MTU 1400
113 #define MIN_ALLOWED_DTLS_MTU 64 /* this ensure than there will be no integer
114 underflow when calculating max write size */
116 static CFTypeID kSSLContextTypeID
;
117 int kSplitDefaultValue
;
119 static void _sslContextDestroy(CFTypeRef arg
);
120 static Boolean
_sslContextEqual(CFTypeRef a
, CFTypeRef b
);
121 static CFHashCode
_sslContextHash(CFTypeRef arg
);
122 static CFStringRef
_sslContextDescribe(CFTypeRef arg
);
124 static void _SSLContextReadDefault()
126 /* 0 = disabled, 1 = split every write, 2 = split second and subsequent writes */
127 /* Enabled by default, this make cause some interop issues, see <rdar://problem/12307662> and <rdar://problem/12323307> */
128 const int defaultSplitDefaultValue
= 2;
130 CFTypeRef value
= (CFTypeRef
)CFPreferencesCopyValue(CFSTR("SSLWriteSplit"),
131 CFSTR("com.apple.security"),
132 kCFPreferencesAnyUser
,
133 kCFPreferencesAnyHost
);
135 if (CFGetTypeID(value
) == CFBooleanGetTypeID())
136 kSplitDefaultValue
= CFBooleanGetValue((CFBooleanRef
)value
) ? 1 : 0;
137 else if (CFGetTypeID(value
) == CFNumberGetTypeID()) {
138 if (!CFNumberGetValue((CFNumberRef
)value
, kCFNumberIntType
, &kSplitDefaultValue
))
139 kSplitDefaultValue
= defaultSplitDefaultValue
;
141 if (kSplitDefaultValue
< 0 || kSplitDefaultValue
> 2) {
142 kSplitDefaultValue
= defaultSplitDefaultValue
;
147 kSplitDefaultValue
= defaultSplitDefaultValue
;
151 static void _SSLContextRegisterClass()
153 static const CFRuntimeClass kSSLContextRegisterClass
= {
155 "SSLContext", /* class name */
158 _sslContextDestroy
, /* dealloc */
159 _sslContextEqual
, /* equal */
160 _sslContextHash
, /* hash */
161 NULL
, /* copyFormattingDesc */
162 _sslContextDescribe
/* copyDebugDesc */
165 kSSLContextTypeID
= _CFRuntimeRegisterClass(&kSSLContextRegisterClass
);
169 SSLContextGetTypeID(void)
171 static pthread_once_t sOnce
= PTHREAD_ONCE_INIT
;
172 pthread_once(&sOnce
, _SSLContextRegisterClass
);
173 return kSSLContextTypeID
;
178 SSLNewContext (Boolean isServer
,
179 SSLContextRef
*contextPtr
) /* RETURNED */
181 if(contextPtr
== NULL
) {
185 *contextPtr
= SSLCreateContext(kCFAllocatorDefault
, isServer
?kSSLServerSide
:kSSLClientSide
, kSSLStreamType
);
187 if (*contextPtr
== NULL
)
188 return errSecAllocate
;
190 return errSecSuccess
;
193 SSLContextRef
SSLCreateContext(CFAllocatorRef alloc
, SSLProtocolSide protocolSide
, SSLConnectionType connectionType
)
197 ctx
= SSLCreateContextWithRecordFuncs(alloc
, protocolSide
, connectionType
, &SSLRecordLayerInternal
);
202 ctx
->recCtx
= SSLCreateInternalRecordLayer(connectionType
);
203 if(ctx
->recCtx
==NULL
) {
211 SSLContextRef
SSLCreateContextWithRecordFuncs(CFAllocatorRef alloc
, SSLProtocolSide protocolSide
, SSLConnectionType connectionType
, const struct SSLRecordFuncs
*recFuncs
)
213 OSStatus serr
= errSecSuccess
;
214 SSLContext
*ctx
= (SSLContext
*) _CFRuntimeCreateInstance(alloc
, SSLContextGetTypeID(), sizeof(SSLContext
) - sizeof(CFRuntimeBase
), NULL
);
220 /* subsequent errors to errOut: */
221 memset(((uint8_t*) ctx
) + sizeof(CFRuntimeBase
), 0, sizeof(SSLContext
) - sizeof(CFRuntimeBase
));
223 ctx
->state
= SSL_HdskStateUninit
;
224 ctx
->timeout_duration
= DEFAULT_DTLS_TIMEOUT
;
225 ctx
->clientCertState
= kSSLClientCertNone
;
227 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
228 ctx
->maxProtocolVersion
= MAXIMUM_STREAM_VERSION
;
231 ctx
->dtlsCookie
.data
= NULL
;
232 ctx
->dtlsCookie
.length
= 0;
233 ctx
->hdskMessageSeq
= 0;
234 ctx
->hdskMessageSeqNext
= 0;
235 ctx
->mtu
= DEFAULT_DTLS_MTU
;
237 ctx
->negProtocolVersion
= SSL_Version_Undetermined
;
240 ctx
->protocolSide
= protocolSide
;
241 /* Default value so we can send and receive hello msgs */
242 ctx
->sslTslCalls
= &Ssl3Callouts
;
244 ctx
->recFuncs
= recFuncs
;
246 /* Initialize the cipher state to NULL_WITH_NULL_NULL */
247 ctx
->selectedCipher
= TLS_NULL_WITH_NULL_NULL
;
248 InitCipherSpecParams(ctx
);
250 /* this gets init'd on first call to SSLHandshake() */
251 ctx
->validCipherSuites
= NULL
;
252 ctx
->numValidCipherSuites
= 0;
254 ctx
->numValidNonSSLv2Suites
= 0;
257 ctx
->peerDomainName
= NULL
;
258 ctx
->peerDomainNameLen
= 0;
260 #ifdef USE_CDSA_CRYPTO
261 /* attach to CSP, CL, TP */
262 serr
= attachToAll(ctx
);
266 #endif /* USE_CDSA_CRYPTO */
268 /* Initial cert verify state: verify with default system roots */
269 ctx
->enableCertVerify
= true;
271 /* Default for RSA blinding is ENABLED */
272 ctx
->rsaBlindingEnable
= true;
274 /* Default for sending one-byte app data record is DISABLED */
275 ctx
->oneByteRecordEnable
= false;
277 /* Consult global system preference for default behavior:
278 * 0 = disabled, 1 = split every write, 2 = split second and subsequent writes
279 * (caller can override by setting kSSLSessionOptionSendOneByteRecord)
281 static pthread_once_t sReadDefault
= PTHREAD_ONCE_INIT
;
282 pthread_once(&sReadDefault
, _SSLContextReadDefault
);
283 if (kSplitDefaultValue
> 0)
284 ctx
->oneByteRecordEnable
= true;
286 /* default for anonymous ciphers is DISABLED */
287 ctx
->anonCipherEnable
= false;
289 ctx
->breakOnServerAuth
= false;
290 ctx
->breakOnCertRequest
= false;
291 ctx
->breakOnClientAuth
= false;
292 ctx
->signalServerAuth
= false;
293 ctx
->signalCertRequest
= false;
294 ctx
->signalClientAuth
= false;
297 * Initial/default set of ECDH curves
299 ctx
->ecdhNumCurves
= SSL_ECDSA_NUM_CURVES
;
300 ctx
->ecdhCurves
[0] = SSL_Curve_secp256r1
;
301 ctx
->ecdhCurves
[1] = SSL_Curve_secp384r1
;
302 ctx
->ecdhCurves
[2] = SSL_Curve_secp521r1
;
304 ctx
->ecdhPeerCurve
= SSL_Curve_None
; /* until we negotiate one */
305 ctx
->negAuthType
= SSLClientAuthNone
; /* ditto */
307 ctx
->messageWriteQueue
= NULL
;
309 if(connectionType
==kSSLDatagramType
) {
310 ctx
->minProtocolVersion
= MINIMUM_DATAGRAM_VERSION
;
311 ctx
->maxProtocolVersion
= MAXIMUM_DATAGRAM_VERSION
;
315 ctx
->secure_renegotiation
= false;
317 if (serr
!= errSecSuccess
) {
325 SSLNewDatagramContext (Boolean isServer
,
326 SSLContextRef
*contextPtr
) /* RETURNED */
328 if (contextPtr
== NULL
)
330 *contextPtr
= SSLCreateContext(kCFAllocatorDefault
, isServer
?kSSLServerSide
:kSSLClientSide
, kSSLDatagramType
);
331 if (*contextPtr
== NULL
)
332 return errSecAllocate
;
333 return errSecSuccess
;
337 * Dispose of an SSLContext. (private)
338 * This function is invoked after our dispatch queue is safely released,
339 * or directly from SSLDisposeContext if there is no dispatch queue.
342 SSLDisposeContext (SSLContextRef context
)
344 if(context
== NULL
) {
348 return errSecSuccess
;
351 CF_RETURNS_RETAINED CFStringRef
_sslContextDescribe(CFTypeRef arg
)
353 SSLContext
* ctx
= (SSLContext
*) arg
;
358 CFStringRef result
= CFStringCreateWithFormat(kCFAllocatorDefault
, NULL
, CFSTR("<SSLContext(%p) { ... }>"), ctx
);
363 Boolean
_sslContextEqual(CFTypeRef a
, CFTypeRef b
)
368 CFHashCode
_sslContextHash(CFTypeRef arg
)
370 return (CFHashCode
) arg
;
373 void _sslContextDestroy(CFTypeRef arg
)
375 SSLContext
* ctx
= (SSLContext
*) arg
;
377 #if USE_SSLCERTIFICATE
378 sslDeleteCertificateChain(ctx
->localCert
, ctx
);
379 sslDeleteCertificateChain(ctx
->encryptCert
, ctx
);
380 sslDeleteCertificateChain(ctx
->peerCert
, ctx
);
381 ctx
->localCert
= ctx
->encryptCert
= ctx
->peerCert
= NULL
;
383 CFReleaseNull(ctx
->localCert
);
384 CFReleaseNull(ctx
->encryptCert
);
385 CFReleaseNull(ctx
->peerCert
);
386 CFReleaseNull(ctx
->trustedCerts
);
389 /* Free the last handshake message flight */
392 if(ctx
->peerSecTrust
) {
393 CFRelease(ctx
->peerSecTrust
);
394 ctx
->peerSecTrust
= NULL
;
396 SSLFreeBuffer(&ctx
->sessionTicket
);
399 SSLFreeBuffer(&ctx
->dhParamsEncoded
);
400 #ifdef USE_CDSA_CRYPTO
401 sslFreeKey(ctx
->cspHand
, &ctx
->dhPrivate
, NULL
);
403 if (ctx
->secDHContext
)
404 SecDHDestroy(ctx
->secDHContext
);
405 #endif /* !USE_CDSA_CRYPTO */
406 SSLFreeBuffer(&ctx
->dhPeerPublic
);
407 SSLFreeBuffer(&ctx
->dhExchangePublic
);
408 #endif /* APPLE_DH */
410 SSLFreeBuffer(&ctx
->ecdhPeerPublic
);
411 SSLFreeBuffer(&ctx
->ecdhExchangePublic
);
413 if(ctx
->ecdhPrivCspHand
== ctx
->cspHand
) {
414 sslFreeKey(ctx
->ecdhPrivCspHand
, &ctx
->ecdhPrivate
, NULL
);
416 /* else we got this key from a SecKeyRef, no free needed */
419 /* Only destroy if we were using the internal record layer */
420 if(ctx
->recFuncs
==&SSLRecordLayerInternal
)
421 SSLDestroyInternalRecordLayer(ctx
->recCtx
);
423 CloseHash(&SSLHashSHA1
, &ctx
->shaState
);
424 CloseHash(&SSLHashMD5
, &ctx
->md5State
);
425 CloseHash(&SSLHashSHA256
, &ctx
->sha256State
);
426 CloseHash(&SSLHashSHA384
, &ctx
->sha512State
);
428 SSLFreeBuffer(&ctx
->sessionID
);
429 SSLFreeBuffer(&ctx
->peerID
);
430 SSLFreeBuffer(&ctx
->resumableSession
);
431 SSLFreeBuffer(&ctx
->preMasterSecret
);
432 SSLFreeBuffer(&ctx
->fragmentedMessageCache
);
433 SSLFreeBuffer(&ctx
->receivedDataBuffer
);
435 if(ctx
->peerDomainName
) {
436 sslFree(ctx
->peerDomainName
);
437 ctx
->peerDomainName
= NULL
;
438 ctx
->peerDomainNameLen
= 0;
441 sslFree(ctx
->validCipherSuites
);
442 ctx
->validCipherSuites
= NULL
;
443 ctx
->numValidCipherSuites
= 0;
447 * NOTE: currently, all public keys come from the CL via CSSM_CL_CertGetKeyInfo.
448 * We really don't know what CSP the CL used to generate a public key (in fact,
449 * it uses the raw CSP only to get LogicalKeySizeInBits, but we can't know
450 * that). Thus using e.g. signingKeyCsp (or any other CSP) to free
451 * signingPubKey is not tecnically accurate. However, our public keys
452 * are all raw keys, and all Apple CSPs dispose of raw keys in the same
455 sslFreeKey(ctx
->cspHand
, &ctx
->signingPubKey
, NULL
);
456 sslFreeKey(ctx
->cspHand
, &ctx
->encryptPubKey
, NULL
);
457 sslFreeKey(ctx
->peerPubKeyCsp
, &ctx
->peerPubKey
, NULL
);
459 if(ctx
->signingPrivKeyRef
) {
460 CFRelease(ctx
->signingPrivKeyRef
);
462 if(ctx
->encryptPrivKeyRef
) {
463 CFRelease(ctx
->encryptPrivKeyRef
);
465 if(ctx
->trustedCerts
) {
466 CFRelease(ctx
->trustedCerts
);
470 sslFreePubKey(&ctx
->signingPubKey
);
471 sslFreePubKey(&ctx
->encryptPubKey
);
472 sslFreePubKey(&ctx
->peerPubKey
);
473 sslFreePrivKey(&ctx
->signingPrivKeyRef
);
474 sslFreePrivKey(&ctx
->encryptPrivKeyRef
);
475 #endif /* USE_CDSA_CRYPTO */
476 CFReleaseSafe(ctx
->acceptableCAs
);
477 CFReleaseSafe(ctx
->trustedLeafCerts
);
478 CFReleaseSafe(ctx
->localCertArray
);
479 CFReleaseSafe(ctx
->encryptCertArray
);
480 CFReleaseSafe(ctx
->encryptCertArray
);
481 if(ctx
->clientAuthTypes
) {
482 sslFree(ctx
->clientAuthTypes
);
484 if(ctx
->serverSigAlgs
!= NULL
) {
485 sslFree(ctx
->serverSigAlgs
);
487 if(ctx
->clientSigAlgs
!= NULL
) {
488 sslFree(ctx
->clientSigAlgs
);
492 SSLFreeBuffer(&ctx
->ownVerifyData
);
493 SSLFreeBuffer(&ctx
->peerVerifyData
);
495 SSLFreeBuffer(&ctx
->pskIdentity
);
496 SSLFreeBuffer(&ctx
->pskSharedSecret
);
498 memset(((uint8_t*) ctx
) + sizeof(CFRuntimeBase
), 0, sizeof(SSLContext
) - sizeof(CFRuntimeBase
));
504 * Determine the state of an SSL session.
507 SSLGetSessionState (SSLContextRef context
,
508 SSLSessionState
*state
) /* RETURNED */
510 SSLSessionState rtnState
= kSSLIdle
;
512 if(context
== NULL
) {
516 switch(context
->state
) {
517 case SSL_HdskStateUninit
:
518 case SSL_HdskStateServerUninit
:
519 case SSL_HdskStateClientUninit
:
522 case SSL_HdskStateGracefulClose
:
523 rtnState
= kSSLClosed
;
525 case SSL_HdskStateErrorClose
:
526 case SSL_HdskStateNoNotifyClose
:
527 rtnState
= kSSLAborted
;
529 case SSL_HdskStateServerReady
:
530 case SSL_HdskStateClientReady
:
531 rtnState
= kSSLConnected
;
534 assert((context
->state
>= SSL_HdskStateServerHello
) &&
535 (context
->state
<= SSL_HdskStateFinished
));
536 rtnState
= kSSLHandshake
;
541 return errSecSuccess
;
545 * Set options for an SSL session.
548 SSLSetSessionOption (SSLContextRef context
,
549 SSLSessionOption option
,
552 if(context
== NULL
) {
555 if(sslIsSessionActive(context
)) {
556 /* can't do this with an active session */
560 case kSSLSessionOptionBreakOnServerAuth
:
561 context
->breakOnServerAuth
= value
;
562 context
->enableCertVerify
= !value
;
564 case kSSLSessionOptionBreakOnCertRequested
:
565 context
->breakOnCertRequest
= value
;
567 case kSSLSessionOptionBreakOnClientAuth
:
568 context
->breakOnClientAuth
= value
;
569 context
->enableCertVerify
= !value
;
571 case kSSLSessionOptionSendOneByteRecord
:
572 context
->oneByteRecordEnable
= value
;
574 case kSSLSessionOptionFalseStart
:
575 context
->falseStartEnabled
= value
;
581 return errSecSuccess
;
585 * Determine current value for the specified option in an SSL session.
588 SSLGetSessionOption (SSLContextRef context
,
589 SSLSessionOption option
,
592 if(context
== NULL
|| value
== NULL
) {
596 case kSSLSessionOptionBreakOnServerAuth
:
597 *value
= context
->breakOnServerAuth
;
599 case kSSLSessionOptionBreakOnCertRequested
:
600 *value
= context
->breakOnCertRequest
;
602 case kSSLSessionOptionBreakOnClientAuth
:
603 *value
= context
->breakOnClientAuth
;
605 case kSSLSessionOptionSendOneByteRecord
:
606 *value
= context
->oneByteRecordEnable
;
608 case kSSLSessionOptionFalseStart
:
609 *value
= context
->falseStartEnabled
;
615 return errSecSuccess
;
619 SSLSetRecordContext (SSLContextRef ctx
,
620 SSLRecordContextRef recCtx
)
625 if(sslIsSessionActive(ctx
)) {
626 /* can't do this with an active session */
629 ctx
->recCtx
= recCtx
;
630 return errSecSuccess
;
633 /* Those two trampolines are used to make the connetion between
634 the record layer IO callbacks and the user provided IO callbacks.
635 Those are currently necessary because the record layer read/write callbacks
636 have different prototypes that the user callbacks advertised in the API.
637 They have different prototypes because the record layer callback have to build in kernelland.
639 This situation is not desirable. So we should figure out a way to get rid of them.
641 static int IORead(SSLIOConnectionRef connection
,
646 SSLContextRef ctx
= connection
;
649 rc
= ctx
->ioCtx
.read(ctx
->ioCtx
.ioRef
, data
, dataLength
);
651 /* We may need to translate error codes at this layer */
652 if(rc
==errSSLWouldBlock
) {
653 rc
=errSSLRecordWouldBlock
;
659 static int IOWrite(SSLIOConnectionRef connection
,
664 SSLContextRef ctx
= connection
;
666 rc
= ctx
->ioCtx
.write(ctx
->ioCtx
.ioRef
, data
, dataLength
);
668 /* We may need to translate error codes at this layer */
669 if(rc
==errSSLWouldBlock
) {
670 rc
=errSSLRecordWouldBlock
;
677 SSLSetIOFuncs (SSLContextRef ctx
,
678 SSLReadFunc readFunc
,
679 SSLWriteFunc writeFunc
)
684 if(ctx
->recFuncs
!=&SSLRecordLayerInternal
) {
685 /* Can Only do this with the internal record layer */
689 if(sslIsSessionActive(ctx
)) {
690 /* can't do this with an active session */
694 ctx
->ioCtx
.read
=readFunc
;
695 ctx
->ioCtx
.write
=writeFunc
;
697 return SSLSetInternalRecordLayerIOFuncs(ctx
->recCtx
, IORead
, IOWrite
);
701 SSLSetConnection (SSLContextRef ctx
,
702 SSLConnectionRef connection
)
707 if(ctx
->recFuncs
!=&SSLRecordLayerInternal
) {
708 /* Can Only do this with the internal record layer */
712 if(sslIsSessionActive(ctx
)) {
713 /* can't do this with an active session */
717 /* Need to keep a copy of it this layer for the Get function */
718 ctx
->ioCtx
.ioRef
= connection
;
720 return SSLSetInternalRecordLayerConnection(ctx
->recCtx
, ctx
);
724 SSLGetConnection (SSLContextRef ctx
,
725 SSLConnectionRef
*connection
)
727 if((ctx
== NULL
) || (connection
== NULL
)) {
730 *connection
= ctx
->ioCtx
.ioRef
;
731 return errSecSuccess
;
735 SSLSetPeerDomainName (SSLContextRef ctx
,
736 const char *peerName
,
742 if(sslIsSessionActive(ctx
)) {
743 /* can't do this with an active session */
747 /* free possible existing name */
748 if(ctx
->peerDomainName
) {
749 sslFree(ctx
->peerDomainName
);
753 ctx
->peerDomainName
= (char *)sslMalloc(peerNameLen
);
754 if(ctx
->peerDomainName
== NULL
) {
755 return errSecAllocate
;
757 memmove(ctx
->peerDomainName
, peerName
, peerNameLen
);
758 ctx
->peerDomainNameLen
= peerNameLen
;
759 return errSecSuccess
;
763 * Determine the buffer size needed for SSLGetPeerDomainName().
766 SSLGetPeerDomainNameLength (SSLContextRef ctx
,
767 size_t *peerNameLen
) // RETURNED
772 *peerNameLen
= ctx
->peerDomainNameLen
;
773 return errSecSuccess
;
777 SSLGetPeerDomainName (SSLContextRef ctx
,
778 char *peerName
, // returned here
779 size_t *peerNameLen
) // IN/OUT
784 if(*peerNameLen
< ctx
->peerDomainNameLen
) {
785 return errSSLBufferOverflow
;
787 memmove(peerName
, ctx
->peerDomainName
, ctx
->peerDomainNameLen
);
788 *peerNameLen
= ctx
->peerDomainNameLen
;
789 return errSecSuccess
;
793 SSLSetDatagramHelloCookie (SSLContextRef ctx
,
803 if(!ctx
->isDTLS
) return errSecParam
;
805 if((ctx
== NULL
) || (cookieLen
>32)) {
808 if(sslIsSessionActive(ctx
)) {
809 /* can't do this with an active session */
813 /* free possible existing cookie */
814 if(ctx
->dtlsCookie
.data
) {
815 SSLFreeBuffer(&ctx
->dtlsCookie
);
819 if((err
=SSLAllocBuffer(&ctx
->dtlsCookie
, cookieLen
)))
822 memmove(ctx
->dtlsCookie
.data
, cookie
, cookieLen
);
823 return errSecSuccess
;
827 SSLSetMaxDatagramRecordSize (SSLContextRef ctx
,
831 if(ctx
== NULL
) return errSecParam
;
832 if(!ctx
->isDTLS
) return errSecParam
;
833 if(maxSize
< MIN_ALLOWED_DTLS_MTU
) return errSecParam
;
837 return errSecSuccess
;
841 SSLGetMaxDatagramRecordSize (SSLContextRef ctx
,
844 if(ctx
== NULL
) return errSecParam
;
845 if(!ctx
->isDTLS
) return errSecParam
;
849 return errSecSuccess
;
854 Keys to to math below:
856 A DTLS record looks like this: | header (13 bytes) | fragment |
858 For Null cipher, fragment is clear text as follows:
861 For block cipher, fragment size must be a multiple of the cipher block size, and is the
862 encryption of the following plaintext :
863 | IV (1 block) | content | MAC | padding (0 to 255 bytes) | Padlen (1 byte) |
865 The maximum content length in that case is achieved for 0 padding bytes.
870 SSLGetDatagramWriteSize (SSLContextRef ctx
,
873 if(ctx
== NULL
) return errSecParam
;
874 if(!ctx
->isDTLS
) return errSecParam
;
875 if(bufSize
== NULL
) return errSecParam
;
877 size_t max_fragment_size
= ctx
->mtu
-13; /* 13 = dtls record header */
879 SSLCipherSpecParams
*currCipher
= &ctx
->selectedCipherSpecParams
;
881 size_t blockSize
= currCipher
->blockSize
;
882 size_t macSize
= currCipher
->macSize
;
885 /* max_fragment_size must be a multiple of blocksize */
886 max_fragment_size
= max_fragment_size
& ~(blockSize
-1);
887 max_fragment_size
-= blockSize
; /* 1 block for IV */
888 max_fragment_size
-= 1; /* 1 byte for pad length */
891 /* less the mac size */
892 max_fragment_size
-= macSize
;
894 /* Thats just a sanity check */
895 assert(max_fragment_size
<ctx
->mtu
);
897 *bufSize
= max_fragment_size
;
899 return errSecSuccess
;
902 static SSLProtocolVersion
SSLProtocolToProtocolVersion(SSLProtocol protocol
) {
904 case kSSLProtocol2
: return SSL_Version_2_0
;
905 case kSSLProtocol3
: return SSL_Version_3_0
;
906 case kTLSProtocol1
: return TLS_Version_1_0
;
907 case kTLSProtocol11
: return TLS_Version_1_1
;
908 case kTLSProtocol12
: return TLS_Version_1_2
;
909 case kDTLSProtocol1
: return DTLS_Version_1_0
;
910 default: return SSL_Version_Undetermined
;
914 /* concert between private SSLProtocolVersion and public SSLProtocol */
915 static SSLProtocol
SSLProtocolVersionToProtocol(SSLProtocolVersion version
)
918 case SSL_Version_2_0
: return kSSLProtocol2
;
919 case SSL_Version_3_0
: return kSSLProtocol3
;
920 case TLS_Version_1_0
: return kTLSProtocol1
;
921 case TLS_Version_1_1
: return kTLSProtocol11
;
922 case TLS_Version_1_2
: return kTLSProtocol12
;
923 case DTLS_Version_1_0
: return kDTLSProtocol1
;
925 sslErrorLog("SSLProtocolVersionToProtocol: bad prot (%04x)\n",
928 case SSL_Version_Undetermined
: return kSSLProtocolUnknown
;
933 SSLSetProtocolVersionMin (SSLContextRef ctx
,
934 SSLProtocol minVersion
)
936 if(ctx
== NULL
) return errSecParam
;
938 SSLProtocolVersion version
= SSLProtocolToProtocolVersion(minVersion
);
940 if (version
> MINIMUM_DATAGRAM_VERSION
||
941 version
< MAXIMUM_DATAGRAM_VERSION
)
942 return errSSLIllegalParam
;
943 if (version
< ctx
->maxProtocolVersion
)
944 ctx
->maxProtocolVersion
= version
;
946 if (version
< MINIMUM_STREAM_VERSION
|| version
> MAXIMUM_STREAM_VERSION
)
947 return errSSLIllegalParam
;
948 if (version
> ctx
->maxProtocolVersion
)
949 ctx
->maxProtocolVersion
= version
;
951 ctx
->minProtocolVersion
= version
;
953 return errSecSuccess
;
957 SSLGetProtocolVersionMin (SSLContextRef ctx
,
958 SSLProtocol
*minVersion
)
960 if(ctx
== NULL
) return errSecParam
;
962 *minVersion
= SSLProtocolVersionToProtocol(ctx
->minProtocolVersion
);
963 return errSecSuccess
;
967 SSLSetProtocolVersionMax (SSLContextRef ctx
,
968 SSLProtocol maxVersion
)
970 if(ctx
== NULL
) return errSecParam
;
972 SSLProtocolVersion version
= SSLProtocolToProtocolVersion(maxVersion
);
974 if (version
> MINIMUM_DATAGRAM_VERSION
||
975 version
< MAXIMUM_DATAGRAM_VERSION
)
976 return errSSLIllegalParam
;
977 if (version
> ctx
->minProtocolVersion
)
978 ctx
->minProtocolVersion
= version
;
980 if (version
< MINIMUM_STREAM_VERSION
|| version
> MAXIMUM_STREAM_VERSION
)
981 return errSSLIllegalParam
;
982 if (version
< ctx
->minProtocolVersion
)
983 ctx
->minProtocolVersion
= version
;
985 ctx
->maxProtocolVersion
= version
;
987 return errSecSuccess
;
991 SSLGetProtocolVersionMax (SSLContextRef ctx
,
992 SSLProtocol
*maxVersion
)
994 if(ctx
== NULL
) return errSecParam
;
996 *maxVersion
= SSLProtocolVersionToProtocol(ctx
->maxProtocolVersion
);
997 return errSecSuccess
;
1000 #define max(x,y) ((x)<(y)?(y):(x))
1003 SSLSetProtocolVersionEnabled(SSLContextRef ctx
,
1004 SSLProtocol protocol
,
1010 if(sslIsSessionActive(ctx
) || ctx
->isDTLS
) {
1011 /* Can't do this with an active session, nor with a DTLS session */
1012 return errSecBadReq
;
1014 if (protocol
== kSSLProtocolAll
) {
1016 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1017 ctx
->maxProtocolVersion
= MAXIMUM_STREAM_VERSION
;
1019 ctx
->minProtocolVersion
= SSL_Version_Undetermined
;
1020 ctx
->maxProtocolVersion
= SSL_Version_Undetermined
;
1023 SSLProtocolVersion version
= SSLProtocolToProtocolVersion(protocol
);
1025 if (version
< MINIMUM_STREAM_VERSION
|| version
> MAXIMUM_STREAM_VERSION
) {
1028 if (version
> ctx
->maxProtocolVersion
) {
1029 ctx
->maxProtocolVersion
= version
;
1030 if (ctx
->minProtocolVersion
== SSL_Version_Undetermined
)
1031 ctx
->minProtocolVersion
= version
;
1033 if (version
< ctx
->minProtocolVersion
) {
1034 ctx
->minProtocolVersion
= version
;
1037 if (version
< SSL_Version_2_0
|| version
> MAXIMUM_STREAM_VERSION
) {
1040 /* Disabling a protocol version now resets the minimum acceptable
1041 * version to the next higher version. This means it's no longer
1042 * possible to enable a discontiguous set of protocol versions.
1044 SSLProtocolVersion nextVersion
;
1046 case SSL_Version_2_0
:
1047 nextVersion
= SSL_Version_3_0
;
1049 case SSL_Version_3_0
:
1050 nextVersion
= TLS_Version_1_0
;
1052 case TLS_Version_1_0
:
1053 nextVersion
= TLS_Version_1_1
;
1055 case TLS_Version_1_1
:
1056 nextVersion
= TLS_Version_1_2
;
1058 case TLS_Version_1_2
:
1060 nextVersion
= SSL_Version_Undetermined
;
1063 ctx
->minProtocolVersion
= max(ctx
->minProtocolVersion
, nextVersion
);
1064 if (ctx
->minProtocolVersion
> ctx
->maxProtocolVersion
) {
1065 ctx
->minProtocolVersion
= SSL_Version_Undetermined
;
1066 ctx
->maxProtocolVersion
= SSL_Version_Undetermined
;
1071 return errSecSuccess
;
1075 SSLGetProtocolVersionEnabled(SSLContextRef ctx
,
1076 SSLProtocol protocol
,
1077 Boolean
*enable
) /* RETURNED */
1083 /* Can't do this with a DTLS session */
1084 return errSecBadReq
;
1090 case kTLSProtocol11
:
1091 case kTLSProtocol12
:
1093 SSLProtocolVersion version
= SSLProtocolToProtocolVersion(protocol
);
1094 *enable
= (ctx
->minProtocolVersion
<= version
1095 && ctx
->maxProtocolVersion
>= version
);
1098 case kSSLProtocolAll
:
1099 *enable
= (ctx
->minProtocolVersion
<= MINIMUM_STREAM_VERSION
1100 && ctx
->maxProtocolVersion
>= MAXIMUM_STREAM_VERSION
);
1105 return errSecSuccess
;
1110 SSLSetProtocolVersion (SSLContextRef ctx
,
1111 SSLProtocol version
)
1116 if(sslIsSessionActive(ctx
) || ctx
->isDTLS
) {
1117 /* Can't do this with an active session, nor with a DTLS session */
1118 return errSecBadReq
;
1123 /* this tells us to do our best, up to 3.0 */
1124 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1125 ctx
->maxProtocolVersion
= SSL_Version_3_0
;
1127 case kSSLProtocol3Only
:
1128 ctx
->minProtocolVersion
= SSL_Version_3_0
;
1129 ctx
->maxProtocolVersion
= SSL_Version_3_0
;
1132 /* this tells us to do our best, up to TLS, but allows 3.0 */
1133 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1134 ctx
->maxProtocolVersion
= TLS_Version_1_0
;
1136 case kTLSProtocol1Only
:
1137 ctx
->minProtocolVersion
= TLS_Version_1_0
;
1138 ctx
->maxProtocolVersion
= TLS_Version_1_0
;
1140 case kTLSProtocol11
:
1141 /* This tells us to do our best, up to TLS 1.1, currently also
1142 allows 3.0 or TLS 1.0 */
1143 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1144 ctx
->maxProtocolVersion
= TLS_Version_1_1
;
1146 case kTLSProtocol12
:
1147 case kSSLProtocolAll
:
1148 case kSSLProtocolUnknown
:
1149 /* This tells us to do our best, up to TLS 1.2, currently also
1150 allows 3.0 or TLS 1.0 or TLS 1.1 */
1151 ctx
->minProtocolVersion
= MINIMUM_STREAM_VERSION
;
1152 ctx
->maxProtocolVersion
= MAXIMUM_STREAM_VERSION
;
1158 return errSecSuccess
;
1163 SSLGetProtocolVersion (SSLContextRef ctx
,
1164 SSLProtocol
*protocol
) /* RETURNED */
1169 /* translate array of booleans to public value; not all combinations
1170 * are legal (i.e., meaningful) for this call */
1171 if (ctx
->maxProtocolVersion
== MAXIMUM_STREAM_VERSION
) {
1172 if(ctx
->minProtocolVersion
== MINIMUM_STREAM_VERSION
) {
1173 /* traditional 'all enabled' */
1174 *protocol
= kSSLProtocolAll
;
1175 return errSecSuccess
;
1177 } else if (ctx
->maxProtocolVersion
== TLS_Version_1_1
) {
1178 if(ctx
->minProtocolVersion
== MINIMUM_STREAM_VERSION
) {
1179 /* traditional 'all enabled' */
1180 *protocol
= kTLSProtocol11
;
1181 return errSecSuccess
;
1183 } else if (ctx
->maxProtocolVersion
== TLS_Version_1_0
) {
1184 if(ctx
->minProtocolVersion
== MINIMUM_STREAM_VERSION
) {
1185 /* TLS1.1 and below enabled */
1186 *protocol
= kTLSProtocol1
;
1187 return errSecSuccess
;
1188 } else if(ctx
->minProtocolVersion
== TLS_Version_1_0
) {
1189 *protocol
= kTLSProtocol1Only
;
1191 } else if(ctx
->maxProtocolVersion
== SSL_Version_3_0
) {
1192 if(ctx
->minProtocolVersion
== MINIMUM_STREAM_VERSION
) {
1193 /* Could also return kSSLProtocol3Only since
1194 MINIMUM_STREAM_VERSION == SSL_Version_3_0. */
1195 *protocol
= kSSLProtocol3
;
1196 return errSecSuccess
;
1204 SSLGetNegotiatedProtocolVersion (SSLContextRef ctx
,
1205 SSLProtocol
*protocol
) /* RETURNED */
1210 *protocol
= SSLProtocolVersionToProtocol(ctx
->negProtocolVersion
);
1211 return errSecSuccess
;
1215 SSLSetEnableCertVerify (SSLContextRef ctx
,
1216 Boolean enableVerify
)
1221 sslCertDebug("SSLSetEnableCertVerify %s",
1222 enableVerify
? "true" : "false");
1223 if(sslIsSessionActive(ctx
)) {
1224 /* can't do this with an active session */
1225 return errSecBadReq
;
1227 ctx
->enableCertVerify
= enableVerify
;
1228 return errSecSuccess
;
1232 SSLGetEnableCertVerify (SSLContextRef ctx
,
1233 Boolean
*enableVerify
)
1238 *enableVerify
= ctx
->enableCertVerify
;
1239 return errSecSuccess
;
1243 SSLSetAllowsExpiredCerts(SSLContextRef ctx
,
1244 Boolean allowExpired
)
1249 sslCertDebug("SSLSetAllowsExpiredCerts %s",
1250 allowExpired
? "true" : "false");
1251 if(sslIsSessionActive(ctx
)) {
1252 /* can't do this with an active session */
1253 return errSecBadReq
;
1255 ctx
->allowExpiredCerts
= allowExpired
;
1256 return errSecSuccess
;
1260 SSLGetAllowsExpiredCerts (SSLContextRef ctx
,
1261 Boolean
*allowExpired
)
1266 *allowExpired
= ctx
->allowExpiredCerts
;
1267 return errSecSuccess
;
1271 SSLSetAllowsExpiredRoots(SSLContextRef ctx
,
1272 Boolean allowExpired
)
1277 sslCertDebug("SSLSetAllowsExpiredRoots %s",
1278 allowExpired
? "true" : "false");
1279 if(sslIsSessionActive(ctx
)) {
1280 /* can't do this with an active session */
1281 return errSecBadReq
;
1283 ctx
->allowExpiredRoots
= allowExpired
;
1284 return errSecSuccess
;
1288 SSLGetAllowsExpiredRoots (SSLContextRef ctx
,
1289 Boolean
*allowExpired
)
1294 *allowExpired
= ctx
->allowExpiredRoots
;
1295 return errSecSuccess
;
1298 OSStatus
SSLSetAllowsAnyRoot(
1305 sslCertDebug("SSLSetAllowsAnyRoot %s", anyRoot
? "true" : "false");
1306 ctx
->allowAnyRoot
= anyRoot
;
1307 return errSecSuccess
;
1311 SSLGetAllowsAnyRoot(
1318 *anyRoot
= ctx
->allowAnyRoot
;
1319 return errSecSuccess
;
1322 #if !TARGET_OS_IPHONE
1323 /* obtain the system roots sets for this app, policy SSL */
1324 static OSStatus
sslDefaultSystemRoots(
1326 CFArrayRef
*systemRoots
) // created and RETURNED
1329 return SecTrustSettingsCopyQualifiedCerts(&CSSMOID_APPLE_TP_SSL
,
1330 ctx
->peerDomainName
,
1331 (uint32_t)ctx
->peerDomainNameLen
,
1332 (ctx
->protocolSide
== kSSLServerSide
) ?
1333 /* server verifies, client encrypts */
1334 CSSM_KEYUSE_VERIFY
: CSSM_KEYUSE_ENCRYPT
,
1337 #endif /* OS X only */
1340 SSLSetTrustedRoots (SSLContextRef ctx
,
1341 CFArrayRef trustedRoots
,
1342 Boolean replaceExisting
)
1344 #ifdef USE_CDSA_CRYPTO
1348 if(sslIsSessionActive(ctx
)) {
1349 /* can't do this with an active session */
1350 return errSecBadReq
;
1353 if(replaceExisting
) {
1354 /* trivial case - retain the new, throw out the old. */
1356 CFRetain(trustedRoots
);
1357 CFReleaseSafe(ctx
->trustedCerts
);
1358 ctx
->trustedCerts
= trustedRoots
;
1359 return errSecSuccess
;
1362 /* adding new trusted roots - to either our existing set, or the system set */
1363 CFArrayRef existingRoots
= NULL
;
1365 if(ctx
->trustedCerts
!= NULL
) {
1366 /* we'll release these as we exit */
1367 existingRoots
= ctx
->trustedCerts
;
1370 /* get system set for this app, policy SSL */
1371 ortn
= sslDefaultSystemRoots(ctx
, &existingRoots
);
1373 CFReleaseSafe(existingRoots
);
1378 /* Create a new root array with caller's roots first */
1379 CFMutableArrayRef newRoots
= CFArrayCreateMutableCopy(NULL
, 0, trustedRoots
);
1380 CFRange existRange
= { 0, CFArrayGetCount(existingRoots
) };
1381 CFArrayAppendArray(newRoots
, existingRoots
, existRange
);
1382 CFRelease(existingRoots
);
1383 ctx
->trustedCerts
= newRoots
;
1384 return errSecSuccess
;
1387 if (sslIsSessionActive(ctx
)) {
1388 /* can't do this with an active session */
1389 return errSecBadReq
;
1391 sslCertDebug("SSLSetTrustedRoot numCerts %d replaceExist %s",
1392 (int)CFArrayGetCount(trustedRoots
), replaceExisting
? "true" : "false");
1394 if (replaceExisting
) {
1395 ctx
->trustedCertsOnly
= true;
1396 CFReleaseNull(ctx
->trustedCerts
);
1399 if (ctx
->trustedCerts
) {
1400 CFIndex count
= CFArrayGetCount(trustedRoots
);
1401 CFRange range
= { 0, count
};
1402 CFArrayAppendArray(ctx
->trustedCerts
, trustedRoots
, range
);
1404 require(ctx
->trustedCerts
=
1405 CFArrayCreateMutableCopy(kCFAllocatorDefault
, 0, trustedRoots
),
1409 return errSecSuccess
;
1412 return errSecAllocate
;
1413 #endif /* !USE_CDSA_CRYPTO */
1417 SSLCopyTrustedRoots (SSLContextRef ctx
,
1418 CFArrayRef
*trustedRoots
) /* RETURNED */
1420 if(ctx
== NULL
|| trustedRoots
== NULL
) {
1423 if(ctx
->trustedCerts
!= NULL
) {
1424 *trustedRoots
= ctx
->trustedCerts
;
1425 CFRetain(ctx
->trustedCerts
);
1426 return errSecSuccess
;
1428 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
1429 /* use default system roots */
1430 return sslDefaultSystemRoots(ctx
, trustedRoots
);
1432 *trustedRoots
= NULL
;
1433 return errSecSuccess
;
1438 SSLSetTrustedLeafCertificates (SSLContextRef ctx
,
1439 CFArrayRef trustedCerts
)
1444 if(sslIsSessionActive(ctx
)) {
1445 /* can't do this with an active session */
1446 return errSecBadReq
;
1449 if(ctx
->trustedLeafCerts
) {
1450 CFRelease(ctx
->trustedLeafCerts
);
1452 ctx
->trustedLeafCerts
= trustedCerts
;
1453 CFRetain(trustedCerts
);
1454 return errSecSuccess
;
1458 SSLCopyTrustedLeafCertificates (SSLContextRef ctx
,
1459 CFArrayRef
*trustedCerts
) /* RETURNED */
1464 if(ctx
->trustedLeafCerts
!= NULL
) {
1465 *trustedCerts
= ctx
->trustedLeafCerts
;
1466 CFRetain(ctx
->trustedCerts
);
1467 return errSecSuccess
;
1469 *trustedCerts
= NULL
;
1470 return errSecSuccess
;
1474 SSLSetClientSideAuthenticate (SSLContext
*ctx
,
1475 SSLAuthenticate auth
)
1480 if(sslIsSessionActive(ctx
)) {
1481 /* can't do this with an active session */
1482 return errSecBadReq
;
1484 ctx
->clientAuth
= auth
;
1486 case kNeverAuthenticate
:
1487 ctx
->tryClientAuth
= false;
1489 case kAlwaysAuthenticate
:
1490 case kTryAuthenticate
:
1491 ctx
->tryClientAuth
= true;
1494 return errSecSuccess
;
1498 SSLGetClientSideAuthenticate (SSLContext
*ctx
,
1499 SSLAuthenticate
*auth
) /* RETURNED */
1501 if(ctx
== NULL
|| auth
== NULL
) {
1504 *auth
= ctx
->clientAuth
;
1505 return errSecSuccess
;
1509 SSLGetClientCertificateState (SSLContextRef ctx
,
1510 SSLClientCertificateState
*clientState
)
1515 *clientState
= ctx
->clientCertState
;
1516 return errSecSuccess
;
1520 SSLSetCertificate (SSLContextRef ctx
,
1521 CFArrayRef certRefs
)
1524 * -- free localCerts if we have any
1525 * -- Get raw cert data, convert to ctx->localCert
1526 * -- get pub, priv keys from certRef[0]
1527 * -- validate cert chain
1533 /* can't do this with an active session */
1534 if(sslIsSessionActive(ctx
) &&
1535 /* kSSLClientCertRequested implies client side */
1536 (ctx
->clientCertState
!= kSSLClientCertRequested
))
1538 return errSecBadReq
;
1540 CFReleaseNull(ctx
->localCertArray
);
1541 /* changing the client cert invalidates negotiated auth type */
1542 ctx
->negAuthType
= SSLClientAuthNone
;
1543 if(certRefs
== NULL
) {
1544 return errSecSuccess
; // we have cleared the cert, as requested
1546 OSStatus ortn
= parseIncomingCerts(ctx
,
1549 &ctx
->signingPubKey
,
1550 &ctx
->signingPrivKeyRef
,
1551 &ctx
->ourSignerAlg
);
1552 if(ortn
== errSecSuccess
) {
1553 ctx
->localCertArray
= certRefs
;
1555 /* client cert was changed, must update auth type */
1556 ortn
= SSLUpdateNegotiatedClientAuthType(ctx
);
1562 SSLSetEncryptionCertificate (SSLContextRef ctx
,
1563 CFArrayRef certRefs
)
1566 * -- free encryptCert if we have any
1567 * -- Get raw cert data, convert to ctx->encryptCert
1568 * -- get pub, priv keys from certRef[0]
1569 * -- validate cert chain
1574 if(sslIsSessionActive(ctx
)) {
1575 /* can't do this with an active session */
1576 return errSecBadReq
;
1578 CFReleaseNull(ctx
->encryptCertArray
);
1579 OSStatus ortn
= parseIncomingCerts(ctx
,
1582 &ctx
->encryptPubKey
,
1583 &ctx
->encryptPrivKeyRef
,
1584 NULL
); /* Signer alg */
1585 if(ortn
== errSecSuccess
) {
1586 ctx
->encryptCertArray
= certRefs
;
1592 OSStatus
SSLGetCertificate(SSLContextRef ctx
,
1593 CFArrayRef
*certRefs
)
1598 *certRefs
= ctx
->localCertArray
;
1599 return errSecSuccess
;
1602 OSStatus
SSLGetEncryptionCertificate(SSLContextRef ctx
,
1603 CFArrayRef
*certRefs
)
1608 *certRefs
= ctx
->encryptCertArray
;
1609 return errSecSuccess
;
1613 SSLSetPeerID (SSLContext
*ctx
,
1619 /* copy peerId to context->peerId */
1625 if(sslIsSessionActive(ctx
) &&
1626 /* kSSLClientCertRequested implies client side */
1627 (ctx
->clientCertState
!= kSSLClientCertRequested
))
1629 return errSecBadReq
;
1631 SSLFreeBuffer(&ctx
->peerID
);
1632 serr
= SSLAllocBuffer(&ctx
->peerID
, peerIDLen
);
1636 memmove(ctx
->peerID
.data
, peerID
, peerIDLen
);
1637 return errSecSuccess
;
1641 SSLGetPeerID (SSLContextRef ctx
,
1642 const void **peerID
,
1645 *peerID
= ctx
->peerID
.data
; // may be NULL
1646 *peerIDLen
= ctx
->peerID
.length
;
1647 return errSecSuccess
;
1651 SSLGetNegotiatedCipher (SSLContextRef ctx
,
1652 SSLCipherSuite
*cipherSuite
)
1657 if(!sslIsSessionActive(ctx
)) {
1658 return errSecBadReq
;
1660 *cipherSuite
= (SSLCipherSuite
)ctx
->selectedCipher
;
1661 return errSecSuccess
;
1665 * Add an acceptable distinguished name (client authentication only).
1668 SSLAddDistinguishedName(
1679 if(sslIsSessionActive(ctx
)) {
1680 return errSecBadReq
;
1683 dn
= (DNListElem
*)sslMalloc(sizeof(DNListElem
));
1685 return errSecAllocate
;
1687 if ((err
= SSLAllocBuffer(&dn
->derDN
, derDNLen
)))
1689 memcpy(dn
->derDN
.data
, derDN
, derDNLen
);
1690 dn
->next
= ctx
->acceptableDNList
;
1691 ctx
->acceptableDNList
= dn
;
1692 return errSecSuccess
;
1695 /* single-cert version of SSLSetCertificateAuthorities() */
1697 sslAddCA(SSLContextRef ctx
,
1698 SecCertificateRef cert
)
1700 OSStatus ortn
= errSecParam
;
1702 /* Get subject from certificate. */
1703 #if TARGET_OS_IPHONE
1704 CFDataRef subjectName
= NULL
;
1705 subjectName
= SecCertificateCopySubjectSequence(cert
);
1706 require(subjectName
, errOut
);
1708 CSSM_DATA_PTR subjectName
= NULL
;
1709 ortn
= SecCertificateCopyFirstFieldValue(cert
, &CSSMOID_X509V1SubjectNameStd
, &subjectName
);
1710 require_noerr(ortn
, errOut
);
1713 /* add to acceptableCAs as cert, creating array if necessary */
1714 if(ctx
->acceptableCAs
== NULL
) {
1715 require(ctx
->acceptableCAs
= CFArrayCreateMutable(NULL
, 0,
1716 &kCFTypeArrayCallBacks
), errOut
);
1717 if(ctx
->acceptableCAs
== NULL
) {
1718 return errSecAllocate
;
1721 CFArrayAppendValue(ctx
->acceptableCAs
, cert
);
1723 /* then add this cert's subject name to acceptableDNList */
1724 #if TARGET_OS_IPHONE
1725 ortn
= SSLAddDistinguishedName(ctx
,
1726 CFDataGetBytePtr(subjectName
),
1727 CFDataGetLength(subjectName
));
1729 ortn
= SSLAddDistinguishedName(ctx
, subjectName
->Data
, subjectName
->Length
);
1733 #if TARGET_OS_IPHONE
1734 CFReleaseSafe(subjectName
);
1740 * Add a SecCertificateRef, or a CFArray of them, to a server's list
1741 * of acceptable Certificate Authorities (CAs) to present to the client
1742 * when client authentication is performed.
1745 SSLSetCertificateAuthorities(SSLContextRef ctx
,
1746 CFTypeRef certificateOrArray
,
1747 Boolean replaceExisting
)
1750 OSStatus ortn
= errSecSuccess
;
1752 if((ctx
== NULL
) || sslIsSessionActive(ctx
) ||
1753 (ctx
->protocolSide
!= kSSLServerSide
)) {
1756 if(replaceExisting
) {
1758 if(ctx
->acceptableCAs
) {
1759 CFRelease(ctx
->acceptableCAs
);
1760 ctx
->acceptableCAs
= NULL
;
1763 /* else appending */
1765 itemType
= CFGetTypeID(certificateOrArray
);
1766 if(itemType
== SecCertificateGetTypeID()) {
1768 ortn
= sslAddCA(ctx
, (SecCertificateRef
)certificateOrArray
);
1770 else if(itemType
== CFArrayGetTypeID()) {
1771 CFArrayRef cfa
= (CFArrayRef
)certificateOrArray
;
1772 CFIndex numCerts
= CFArrayGetCount(cfa
);
1775 /* array of certs */
1776 for(dex
=0; dex
<numCerts
; dex
++) {
1777 SecCertificateRef cert
= (SecCertificateRef
)CFArrayGetValueAtIndex(cfa
, dex
);
1778 if(CFGetTypeID(cert
) != SecCertificateGetTypeID()) {
1781 ortn
= sslAddCA(ctx
, cert
);
1795 * Obtain the certificates specified in SSLSetCertificateAuthorities(),
1796 * if any. Returns a NULL array if SSLSetCertificateAuthorities() has not
1798 * Caller must CFRelease the returned array.
1801 SSLCopyCertificateAuthorities(SSLContextRef ctx
,
1802 CFArrayRef
*certificates
) /* RETURNED */
1804 if((ctx
== NULL
) || (certificates
== NULL
)) {
1807 if(ctx
->acceptableCAs
== NULL
) {
1808 *certificates
= NULL
;
1809 return errSecSuccess
;
1811 *certificates
= ctx
->acceptableCAs
;
1812 CFRetain(ctx
->acceptableCAs
);
1813 return errSecSuccess
;
1818 * Obtain the list of acceptable distinguished names as provided by
1819 * a server (if the SSLCotextRef is configured as a client), or as
1820 * specified by SSLSetCertificateAuthorities() (if the SSLContextRef
1821 * is configured as a server).
1824 SSLCopyDistinguishedNames (SSLContextRef ctx
,
1827 CFMutableArrayRef outArray
= NULL
;
1830 if((ctx
== NULL
) || (names
== NULL
)) {
1833 if(ctx
->acceptableDNList
== NULL
) {
1835 return errSecSuccess
;
1837 outArray
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1838 dn
= ctx
->acceptableDNList
;
1840 CFDataRef cfDn
= CFDataCreate(NULL
, dn
->derDN
.data
, dn
->derDN
.length
);
1841 CFArrayAppendValue(outArray
, cfDn
);
1846 return errSecSuccess
;
1851 * Request peer certificates. Valid anytime, subsequent to
1852 * a handshake attempt.
1853 * Common code for SSLGetPeerCertificates() and SSLCopyPeerCertificates().
1854 * TODO: the 'legacy' argument is not used anymore.
1857 sslCopyPeerCertificates (SSLContextRef ctx
,
1865 #ifdef USE_SSLCERTIFICATE
1867 CFMutableArrayRef ca
;
1869 SecCertificateRef cfd
;
1872 SSLCertificate
*scert
;
1877 * Copy peerCert, a chain of SSLCertificates, to a CFArray of
1878 * CFDataRefs, each of which is one DER-encoded cert.
1880 numCerts
= SSLGetCertificateChainLength(ctx
->peerCert
);
1882 return errSecSuccess
;
1884 ca
= CFArrayCreateMutable(kCFAllocatorDefault
,
1885 (CFIndex
)numCerts
, &kCFTypeArrayCallBacks
);
1887 return errSecAllocate
;
1891 * Caller gets leaf cert first, the opposite of the way we store them.
1893 scert
= ctx
->peerCert
;
1894 for(i
=0; (unsigned)i
<numCerts
; i
++) {
1895 assert(scert
!= NULL
); /* else SSLGetCertificateChainLength
1897 SSLBUF_TO_CSSM(&scert
->derCert
, &certData
);
1898 ortn
= SecCertificateCreateFromData(&certData
,
1900 CSSM_CERT_ENCODING_DER
,
1906 /* insert at head of array */
1907 CFArrayInsertValueAtIndex(ca
, 0, cfd
);
1909 /* skip for legacy SSLGetPeerCertificates() */
1912 scert
= scert
->next
;
1917 if (!ctx
->peerCert
) {
1919 return errSecBadReq
;
1922 CFArrayRef ca
= CFArrayCreateCopy(kCFAllocatorDefault
, ctx
->peerCert
);
1925 return errSecAllocate
;
1929 CFIndex ix
, count
= CFArrayGetCount(ca
);
1930 for (ix
= 0; ix
< count
; ++ix
) {
1931 CFRetain(CFArrayGetValueAtIndex(ca
, ix
));
1936 return errSecSuccess
;
1940 SSLCopyPeerCertificates (SSLContextRef ctx
,
1943 return sslCopyPeerCertificates(ctx
, certs
, false);
1946 #if !TARGET_OS_IPHONE
1947 // Permanently removing from iOS, keep for OSX (deprecated), removed from headers.
1948 // <rdar://problem/14215831> Mailsmith Crashes While Getting New Mail Under Mavericks Developer Preview
1950 SSLGetPeerCertificates (SSLContextRef ctx
,
1953 SSLGetPeerCertificates (SSLContextRef ctx
,
1956 return sslCopyPeerCertificates(ctx
, certs
, true);
1961 * Specify Diffie-Hellman parameters. Optional; if we are configured to allow
1962 * for D-H ciphers and a D-H cipher is negotiated, and this function has not
1963 * been called, a set of process-wide parameters will be calculated. However
1964 * that can take a long time (30 seconds).
1966 OSStatus
SSLSetDiffieHellmanParams(
1968 const void *dhParams
,
1975 if(sslIsSessionActive(ctx
)) {
1976 return errSecBadReq
;
1978 SSLFreeBuffer(&ctx
->dhParamsEncoded
);
1979 #if !USE_CDSA_CRYPTO
1980 if (ctx
->secDHContext
)
1981 SecDHDestroy(ctx
->secDHContext
);
1985 ortn
= SSLCopyBufferFromData(dhParams
, dhParamsLen
,
1986 &ctx
->dhParamsEncoded
);
1990 #endif /* APPLE_DH */
1994 * Return parameter block specified in SSLSetDiffieHellmanParams.
1995 * Returned data is not copied and belongs to the SSLContextRef.
1997 OSStatus
SSLGetDiffieHellmanParams(
1999 const void **dhParams
,
2000 size_t *dhParamsLen
)
2006 *dhParams
= ctx
->dhParamsEncoded
.data
;
2007 *dhParamsLen
= ctx
->dhParamsEncoded
.length
;
2008 return errSecSuccess
;
2010 return errSecUnimplemented
;
2011 #endif /* APPLE_DH */
2014 OSStatus
SSLSetRsaBlinding(
2021 ctx
->rsaBlindingEnable
= blinding
;
2022 return errSecSuccess
;
2025 OSStatus
SSLGetRsaBlinding(
2032 *blinding
= ctx
->rsaBlindingEnable
;
2033 return errSecSuccess
;
2039 SecTrustRef
*trust
) /* RETURNED */
2041 OSStatus status
= errSecSuccess
;
2042 if (ctx
== NULL
|| trust
== NULL
)
2045 /* Create a SecTrustRef if this was a resumed session and we
2046 didn't have one yet. */
2047 if (!ctx
->peerSecTrust
&& ctx
->peerCert
) {
2048 status
= sslCreateSecTrust(ctx
, ctx
->peerCert
, true,
2049 &ctx
->peerSecTrust
);
2052 *trust
= ctx
->peerSecTrust
;
2053 if (ctx
->peerSecTrust
)
2054 CFRetain(ctx
->peerSecTrust
);
2059 OSStatus
SSLGetPeerSecTrust(
2061 SecTrustRef
*trust
) /* RETURNED */
2063 OSStatus status
= errSecSuccess
;
2064 if (ctx
== NULL
|| trust
== NULL
)
2067 /* Create a SecTrustRef if this was a resumed session and we
2068 didn't have one yet. */
2069 if (!ctx
->peerSecTrust
&& ctx
->peerCert
) {
2070 status
= sslCreateSecTrust(ctx
, ctx
->peerCert
, true,
2071 &ctx
->peerSecTrust
);
2074 *trust
= ctx
->peerSecTrust
;
2078 OSStatus
SSLInternalMasterSecret(
2080 void *secret
, // mallocd by caller, SSL_MASTER_SECRET_SIZE
2081 size_t *secretSize
) // in/out
2083 if((ctx
== NULL
) || (secret
== NULL
) || (secretSize
== NULL
)) {
2086 if(*secretSize
< SSL_MASTER_SECRET_SIZE
) {
2089 memmove(secret
, ctx
->masterSecret
, SSL_MASTER_SECRET_SIZE
);
2090 *secretSize
= SSL_MASTER_SECRET_SIZE
;
2091 return errSecSuccess
;
2094 OSStatus
SSLInternalServerRandom(
2096 void *randBuf
, // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
2097 size_t *randSize
) // in/out
2099 if((ctx
== NULL
) || (randBuf
== NULL
) || (randSize
== NULL
)) {
2102 if(*randSize
< SSL_CLIENT_SRVR_RAND_SIZE
) {
2105 memmove(randBuf
, ctx
->serverRandom
, SSL_CLIENT_SRVR_RAND_SIZE
);
2106 *randSize
= SSL_CLIENT_SRVR_RAND_SIZE
;
2107 return errSecSuccess
;
2110 OSStatus
SSLInternalClientRandom(
2112 void *randBuf
, // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
2113 size_t *randSize
) // in/out
2115 if((ctx
== NULL
) || (randBuf
== NULL
) || (randSize
== NULL
)) {
2118 if(*randSize
< SSL_CLIENT_SRVR_RAND_SIZE
) {
2121 memmove(randBuf
, ctx
->clientRandom
, SSL_CLIENT_SRVR_RAND_SIZE
);
2122 *randSize
= SSL_CLIENT_SRVR_RAND_SIZE
;
2123 return errSecSuccess
;
2126 /* This is used by EAP 802.1x */
2127 OSStatus
SSLGetCipherSizes(
2130 size_t *symmetricKeySize
,
2133 const SSLCipherSpecParams
*currCipher
;
2135 if((ctx
== NULL
) || (digestSize
== NULL
) ||
2136 (symmetricKeySize
== NULL
) || (ivSize
== NULL
)) {
2139 currCipher
= &ctx
->selectedCipherSpecParams
;
2140 *digestSize
= currCipher
->macSize
;
2141 *symmetricKeySize
= currCipher
->keySize
;
2142 *ivSize
= currCipher
->ivSize
;
2143 return errSecSuccess
;
2147 SSLGetResumableSessionInfo(
2149 Boolean
*sessionWasResumed
, // RETURNED
2150 void *sessionID
, // RETURNED, mallocd by caller
2151 size_t *sessionIDLength
) // IN/OUT
2153 if((ctx
== NULL
) || (sessionWasResumed
== NULL
) ||
2154 (sessionID
== NULL
) || (sessionIDLength
== NULL
) ||
2155 (*sessionIDLength
< MAX_SESSION_ID_LENGTH
)) {
2158 if(ctx
->sessionMatch
) {
2159 *sessionWasResumed
= true;
2160 if(ctx
->sessionID
.length
> *sessionIDLength
) {
2161 /* really should never happen - means ID > 32 */
2164 if(ctx
->sessionID
.length
) {
2166 * Note PAC-based session resumption can result in sessionMatch
2169 memmove(sessionID
, ctx
->sessionID
.data
, ctx
->sessionID
.length
);
2171 *sessionIDLength
= ctx
->sessionID
.length
;
2174 *sessionWasResumed
= false;
2175 *sessionIDLength
= 0;
2177 return errSecSuccess
;
2181 * Get/set enable of anonymous ciphers. Default is enabled.
2184 SSLSetAllowAnonymousCiphers(
2191 if(sslIsSessionActive(ctx
)) {
2192 return errSecBadReq
;
2194 if(ctx
->validCipherSuites
!= NULL
) {
2195 /* SSLSetEnabledCiphers() has already been called */
2196 return errSecBadReq
;
2198 ctx
->anonCipherEnable
= enable
;
2199 return errSecSuccess
;
2203 SSLGetAllowAnonymousCiphers(
2207 if((ctx
== NULL
) || (enable
== NULL
)) {
2210 if(sslIsSessionActive(ctx
)) {
2211 return errSecBadReq
;
2213 *enable
= ctx
->anonCipherEnable
;
2214 return errSecSuccess
;
2218 * Override the default session cache timeout for a cache entry created for
2219 * the current session.
2222 SSLSetSessionCacheTimeout(
2224 uint32_t timeoutInSeconds
)
2229 ctx
->sessionCacheTimeout
= timeoutInSeconds
;
2230 return errSecSuccess
;
2234 * Register a callback for obtaining the master_secret when performing
2235 * PAC-based session resumption.
2238 SSLInternalSetMasterSecretFunction(
2240 SSLInternalMasterSecretFunction mFunc
,
2241 const void *arg
) /* opaque to SecureTransport; app-specific */
2246 ctx
->masterSecretCallback
= mFunc
;
2247 ctx
->masterSecretArg
= arg
;
2248 return errSecSuccess
;
2252 * Provide an opaque SessionTicket for use in PAC-based session
2253 * resumption. Client side only. The provided ticket is sent in
2254 * the ClientHello message as a SessionTicket extension.
2256 * We won't reject this on the server side, but server-side support
2257 * for PAC-based session resumption is currently enabled for
2258 * Development builds only. To fully support this for server side,
2259 * besides the rudimentary support that's here for Development builds,
2260 * we'd need a getter for the session ticket, so the app code can
2261 * access the SessionTicket when its SSLInternalMasterSecretFunction
2262 * callback is called.
2264 OSStatus
SSLInternalSetSessionTicket(
2267 size_t ticketLength
)
2272 if(sslIsSessionActive(ctx
)) {
2273 /* can't do this with an active session */
2274 return errSecBadReq
;
2276 if(ticketLength
> 0xffff) {
2277 /* extension data encoded with a 2-byte length! */
2280 SSLFreeBuffer(&ctx
->sessionTicket
);
2281 return SSLCopyBufferFromData(ticket
, ticketLength
, &ctx
->sessionTicket
);
2285 * ECDSA curve accessors.
2289 * Obtain the SSL_ECDSA_NamedCurve negotiated during a handshake.
2290 * Returns errSecParam if no ECDH-related ciphersuite was negotiated.
2292 OSStatus
SSLGetNegotiatedCurve(
2294 SSL_ECDSA_NamedCurve
*namedCurve
) /* RETURNED */
2296 if((ctx
== NULL
) || (namedCurve
== NULL
)) {
2299 if(ctx
->ecdhPeerCurve
== SSL_Curve_None
) {
2302 *namedCurve
= ctx
->ecdhPeerCurve
;
2303 return errSecSuccess
;
2307 * Obtain the number of currently enabled SSL_ECDSA_NamedCurves.
2309 OSStatus
SSLGetNumberOfECDSACurves(
2311 unsigned *numCurves
) /* RETURNED */
2313 if((ctx
== NULL
) || (numCurves
== NULL
)) {
2316 *numCurves
= ctx
->ecdhNumCurves
;
2317 return errSecSuccess
;
2321 * Obtain the ordered list of currently enabled SSL_ECDSA_NamedCurves.
2323 OSStatus
SSLGetECDSACurves(
2325 SSL_ECDSA_NamedCurve
*namedCurves
, /* RETURNED */
2326 unsigned *numCurves
) /* IN/OUT */
2328 if((ctx
== NULL
) || (namedCurves
== NULL
) || (numCurves
== NULL
)) {
2331 if(*numCurves
< ctx
->ecdhNumCurves
) {
2334 memmove(namedCurves
, ctx
->ecdhCurves
,
2335 (ctx
->ecdhNumCurves
* sizeof(SSL_ECDSA_NamedCurve
)));
2336 *numCurves
= ctx
->ecdhNumCurves
;
2337 return errSecSuccess
;
2341 * Specify ordered list of allowable named curves.
2343 OSStatus
SSLSetECDSACurves(
2345 const SSL_ECDSA_NamedCurve
*namedCurves
,
2348 if((ctx
== NULL
) || (namedCurves
== NULL
) || (numCurves
== 0)) {
2351 if(numCurves
> SSL_ECDSA_NUM_CURVES
) {
2354 if(sslIsSessionActive(ctx
)) {
2355 /* can't do this with an active session */
2356 return errSecBadReq
;
2358 memmove(ctx
->ecdhCurves
, namedCurves
, (numCurves
* sizeof(SSL_ECDSA_NamedCurve
)));
2359 ctx
->ecdhNumCurves
= numCurves
;
2360 return errSecSuccess
;
2364 * Obtain the number of client authentication mechanisms specified by
2365 * the server in its Certificate Request message.
2366 * Returns errSecParam if server hasn't sent a Certificate Request message
2367 * (i.e., client certificate state is kSSLClientCertNone).
2369 OSStatus
SSLGetNumberOfClientAuthTypes(
2373 if((ctx
== NULL
) || (ctx
->clientCertState
== kSSLClientCertNone
)) {
2376 *numTypes
= ctx
->numAuthTypes
;
2377 return errSecSuccess
;
2381 * Obtain the client authentication mechanisms specified by
2382 * the server in its Certificate Request message.
2383 * Caller allocates returned array and specifies its size (in
2384 * SSLClientAuthenticationTypes) in *numType on entry; *numTypes
2385 * is the actual size of the returned array on successful return.
2387 OSStatus
SSLGetClientAuthTypes(
2389 SSLClientAuthenticationType
*authTypes
, /* RETURNED */
2390 unsigned *numTypes
) /* IN/OUT */
2392 if((ctx
== NULL
) || (ctx
->clientCertState
== kSSLClientCertNone
)) {
2395 memmove(authTypes
, ctx
->clientAuthTypes
,
2396 ctx
->numAuthTypes
* sizeof(SSLClientAuthenticationType
));
2397 *numTypes
= ctx
->numAuthTypes
;
2398 return errSecSuccess
;
2402 * Obtain the SSLClientAuthenticationType actually performed.
2403 * Only valid if client certificate state is kSSLClientCertSent
2404 * or kSSLClientCertRejected; returns errSecParam otherwise.
2406 OSStatus
SSLGetNegotiatedClientAuthType(
2408 SSLClientAuthenticationType
*authType
) /* RETURNED */
2413 *authType
= ctx
->negAuthType
;
2414 return errSecSuccess
;
2418 * Update the negotiated client authentication type.
2419 * This function may be called at any time; however, note that
2420 * the negotiated authentication type will be SSLClientAuthNone
2421 * until both of the following have taken place (in either order):
2422 * - a CertificateRequest message from the server has been processed
2423 * - a client certificate has been specified
2424 * As such, this function (only) needs to be called from (both)
2425 * SSLProcessCertificateRequest and SSLSetCertificate.
2427 OSStatus
SSLUpdateNegotiatedClientAuthType(
2434 * See if we have a signing cert that matches one of the
2435 * allowed auth types. The x509Requested flag indicates "we
2436 * have a cert that we think the server will accept".
2438 ctx
->x509Requested
= 0;
2439 ctx
->negAuthType
= SSLClientAuthNone
;
2440 if(ctx
->signingPrivKeyRef
!= NULL
) {
2441 CFIndex ourKeyAlg
= sslPubKeyGetAlgorithmID(ctx
->signingPubKey
);
2443 for(i
=0; i
<ctx
->numAuthTypes
; i
++) {
2444 switch(ctx
->clientAuthTypes
[i
]) {
2445 case SSLClientAuth_RSASign
:
2446 if(ourKeyAlg
== kSecRSAAlgorithmID
) {
2447 ctx
->x509Requested
= 1;
2448 ctx
->negAuthType
= SSLClientAuth_RSASign
;
2451 #if SSL_ENABLE_ECDSA_SIGN_AUTH
2452 case SSLClientAuth_ECDSASign
:
2454 #if SSL_ENABLE_ECDSA_FIXED_ECDH_AUTH
2455 case SSLClientAuth_ECDSAFixedECDH
:
2457 if((ourKeyAlg
== kSecECDSAAlgorithmID
) &&
2458 (ctx
->ourSignerAlg
== kSecECDSAAlgorithmID
)) {
2459 ctx
->x509Requested
= 1;
2460 ctx
->negAuthType
= ctx
->clientAuthTypes
[i
];
2463 #if SSL_ENABLE_RSA_FIXED_ECDH_AUTH
2464 case SSLClientAuth_RSAFixedECDH
:
2465 /* Odd case, we differ from our signer */
2466 if((ourKeyAlg
== kSecECDSAAlgorithmID
) &&
2467 (ctx
->ourSignerAlg
== kSecRSAAlgorithmID
)) {
2468 ctx
->x509Requested
= 1;
2469 ctx
->negAuthType
= SSLClientAuth_RSAFixedECDH
;
2474 /* None others supported */
2477 if(ctx
->x509Requested
) {
2478 sslLogNegotiateDebug("===CHOOSING authType %d", (int)ctx
->negAuthType
);
2481 } /* parsing authTypes */
2482 } /* we have a signing key */
2484 return errSecSuccess
;
2487 OSStatus
SSLGetNumberOfSignatureAlgorithms(
2489 unsigned *numSigAlgs
)
2491 if((ctx
== NULL
) || (ctx
->clientCertState
== kSSLClientCertNone
)) {
2494 *numSigAlgs
= ctx
->numServerSigAlgs
;
2495 return errSecSuccess
;
2498 OSStatus
SSLGetSignatureAlgorithms(
2500 SSLSignatureAndHashAlgorithm
*sigAlgs
, /* RETURNED */
2501 unsigned *numSigAlgs
) /* IN/OUT */
2503 if((ctx
== NULL
) || (ctx
->clientCertState
== kSSLClientCertNone
)) {
2506 memmove(sigAlgs
, ctx
->serverSigAlgs
,
2507 ctx
->numServerSigAlgs
* sizeof(SSLSignatureAndHashAlgorithm
));
2508 *numSigAlgs
= ctx
->numServerSigAlgs
;
2509 return errSecSuccess
;
2513 OSStatus
SSLSetPSKSharedSecret(SSLContextRef ctx
,
2517 if(ctx
== NULL
) return errSecParam
;
2519 if(ctx
->pskSharedSecret
.data
)
2520 SSLFreeBuffer(&ctx
->pskSharedSecret
);
2522 if(SSLCopyBufferFromData(secret
, secretLen
, &ctx
->pskSharedSecret
))
2523 return errSecAllocate
;
2525 return errSecSuccess
;
2528 OSStatus
SSLSetPSKIdentity(SSLContextRef ctx
,
2529 const void *pskIdentity
,
2530 size_t pskIdentityLen
)
2532 if((ctx
== NULL
) || (pskIdentity
== NULL
) || (pskIdentityLen
== 0)) return errSecParam
;
2534 if(ctx
->pskIdentity
.data
)
2535 SSLFreeBuffer(&ctx
->pskIdentity
);
2537 if(SSLCopyBufferFromData(pskIdentity
, pskIdentityLen
, &ctx
->pskIdentity
))
2538 return errSecAllocate
;
2540 return errSecSuccess
;
2544 OSStatus
SSLGetPSKIdentity(SSLContextRef ctx
,
2545 const void **pskIdentity
,
2546 size_t *pskIdentityLen
)
2548 if((ctx
== NULL
) || (pskIdentity
== NULL
) || (pskIdentityLen
== NULL
)) return errSecParam
;
2550 *pskIdentity
=ctx
->pskIdentity
.data
;
2551 *pskIdentityLen
=ctx
->pskIdentity
.length
;
2552 return errSecSuccess
;
2556 #ifdef USE_SSLCERTIFICATE
2559 SSLGetCertificateChainLength(const SSLCertificate
*c
)
2571 OSStatus
sslDeleteCertificateChain(
2572 SSLCertificate
*certs
,
2575 SSLCertificate
*cert
;
2576 SSLCertificate
*nextCert
;
2578 assert(ctx
!= NULL
);
2580 while(cert
!= NULL
) {
2581 nextCert
= cert
->next
;
2582 SSLFreeBuffer(&cert
->derCert
);
2586 return errSecSuccess
;
2588 #endif /* USE_SSLCERTIFICATE */