2 * Copyright (c) 1999-2001,2005-2008,2010-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 * sslUtils.c - Misc. SSL utility functions
28 #include "sslContext.h"
30 #include "sslMemory.h"
35 #include <fcntl.h> // for open
36 #include <unistd.h> // for read
37 #include <errno.h> // for errno
38 #include <Security/SecFramework.h>
39 #include <Security/SecRandom.h>
42 void SSLDump(const unsigned char *data
, unsigned long len
)
47 if((i
&0xf)==0) printf("%04lx :",i
);
48 printf(" %02x", data
[i
]);
49 if((i
&0xf)==0xf) printf("\n");
56 SSLDecodeInt(const uint8_t *p
, size_t length
)
59 assert(length
> 0 && length
<= 4); //anything else would be an internal error.
61 val
= (val
<< 8) | *p
++;
66 SSLEncodeInt(uint8_t *p
, unsigned int value
, size_t length
)
68 unsigned char *retVal
= p
+ length
; /* Return pointer to char after int */
69 assert(length
> 0 && length
<= 4); //anything else would be an internal error.
70 while (length
--) /* Assemble backwards */
71 { p
[length
] = (uint8_t)value
; /* Implicit masking to low byte */
78 SSLDecodeSize(const uint8_t *p
, size_t length
)
81 assert(length
> 0 && length
<= 4); //anything else would be an internal error.
83 val
= (val
<< 8) | *p
++;
88 SSLEncodeSize(uint8_t *p
, size_t value
, size_t length
)
90 unsigned char *retVal
= p
+ length
; /* Return pointer to char after int */
91 assert(length
> 0 && length
<= 4); //anything else would be an internal error.
92 while (length
--) /* Assemble backwards */
93 { p
[length
] = (uint8_t)value
; /* Implicit masking to low byte */
101 SSLEncodeUInt64(uint8_t *p
, sslUint64 value
)
103 p
= SSLEncodeInt(p
, value
.high
, 4);
104 return SSLEncodeInt(p
, value
.low
, 4);
109 SSLEncodeHandshakeHeader(SSLContext
*ctx
, SSLRecord
*rec
, SSLHandshakeType type
, size_t msglen
)
113 charPtr
= rec
->contents
.data
;
115 charPtr
= SSLEncodeSize(charPtr
, msglen
, 3);
117 if(rec
->protocolVersion
== DTLS_Version_1_0
) {
118 charPtr
= SSLEncodeInt(charPtr
, ctx
->hdskMessageSeq
, 2);
119 /* fragmentation -- we encode header as if unfragmented,
120 actual fragmentation happens at lower layer. */
121 charPtr
= SSLEncodeInt(charPtr
, 0, 3);
122 charPtr
= SSLEncodeSize(charPtr
, msglen
, 3);
130 IncrementUInt64(sslUint64
*v
)
131 { if (++v
->low
== 0) /* Must have just rolled over */
137 SSLDecodeUInt64(const uint8_t *p
, size_t length
, sslUint64
*v
)
139 assert(length
> 0 && length
<= 8);
141 v
->low
=SSLDecodeInt(p
, length
);
144 v
->high
=SSLDecodeInt(p
, length
-4);
145 v
->low
=SSLDecodeInt(p
+length
-4, 4);
150 #ifdef USE_SSLCERTIFICATE
152 SSLGetCertificateChainLength(const SSLCertificate
*c
)
164 OSStatus
sslDeleteCertificateChain(
165 SSLCertificate
*certs
,
168 SSLCertificate
*cert
;
169 SSLCertificate
*nextCert
;
173 while(cert
!= NULL
) {
174 nextCert
= cert
->next
;
175 SSLFreeBuffer(&cert
->derCert
, ctx
);
181 #endif /* USE_SSLCERTIFICATE */
183 Boolean
sslIsSessionActive(const SSLContext
*ctx
)
187 case SSL_HdskStateUninit
:
188 case SSL_HdskStateServerUninit
:
189 case SSL_HdskStateClientUninit
:
190 case SSL_HdskStateGracefulClose
:
191 case SSL_HdskStateErrorClose
:
200 const char *protocolVersStr(SSLProtocolVersion prot
)
203 case SSL_Version_Undetermined
: return "SSL_Version_Undetermined";
204 case SSL_Version_2_0
: return "SSL_Version_2_0";
205 case SSL_Version_3_0
: return "SSL_Version_3_0";
206 case TLS_Version_1_0
: return "TLS_Version_1_0";
207 case TLS_Version_1_1
: return "TLS_Version_1_1";
208 case TLS_Version_1_2
: return "TLS_Version_1_2";
209 default: sslErrorLog("protocolVersStr: bad prot\n"); return "BAD PROTOCOL";
211 return NULL
; /* NOT REACHED */
214 #endif /* SSL_DEBUG */
217 * Redirect SSLBuffer-based I/O call to user-supplied I/O.
221 size_t *actualLength
,
224 size_t dataLength
= buf
.length
;
228 ortn
= (ctx
->ioCtx
.read
)(ctx
->ioCtx
.ioRef
,
231 *actualLength
= dataLength
;
237 size_t *actualLength
,
240 size_t dataLength
= buf
.length
;
244 ortn
= (ctx
->ioCtx
.write
)(ctx
->ioCtx
.ioRef
,
247 *actualLength
= dataLength
;
251 OSStatus
sslTime(uint32_t *tim
)
260 * Common RNG function.
262 OSStatus
sslRand(SSLContext
*ctx
, SSLBuffer
*buf
)
265 assert(buf
->data
!= NULL
);
267 if(buf
->length
== 0) {
268 sslErrorLog("sslRand: zero buf->length\n");
272 return SecRandomCopyBytes(kSecRandomDefault
, buf
->length
, buf
->data
) ? errSSLCrypto
: noErr
;
276 * Given a protocol version sent by peer, determine if we accept that version
277 * and downgrade if appropriate (which can not be done for the client side).
279 OSStatus
sslVerifyProtVersion(
281 SSLProtocolVersion peerVersion
, // sent by peer
282 SSLProtocolVersion
*negVersion
) // final negotiated version if return success
285 ? peerVersion
> ctx
->minProtocolVersion
286 : peerVersion
< ctx
->minProtocolVersion
) {
287 return errSSLNegotiation
;
290 ? peerVersion
< ctx
->maxProtocolVersion
291 : peerVersion
> ctx
->maxProtocolVersion
) {
292 if (ctx
->protocolSide
== kSSLClientSide
) {
293 return errSSLNegotiation
;
295 *negVersion
= ctx
->maxProtocolVersion
;
297 *negVersion
= peerVersion
;
304 * Determine max enabled protocol, i.e., the one we try to negotiate for.
305 * Only returns an error (paramErr) if NO protocols are enabled, which can
306 * in fact happen by malicious or ignorant use of SSLSetProtocolVersionEnabled().
308 OSStatus
sslGetMaxProtVersion(
310 SSLProtocolVersion
*version
) // RETURNED
312 /* This check is here until SSLSetProtocolVersionEnabled() is gone .*/
313 if (ctx
->maxProtocolVersion
== SSL_Version_Undetermined
)
316 *version
= ctx
->maxProtocolVersion
;