2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
19 /* *********************************************************************
22 SSLRef 3.0 Final -- 11/19/96
24 Copyright (c)1996 by Netscape Communications Corp.
26 By retrieving this software you are bound by the licensing terms
27 disclosed in the file "LICENSE.txt". Please read it, and if you don't
28 accept the terms, delete this software.
30 SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
31 View, California <http://home.netscape.com/> and Consensus Development
32 Corporation of Berkeley, California <http://www.consensus.com/>.
34 *********************************************************************
36 File: sslsess.c SSL Session DB interface
38 This file contains functions which interact with the session database
39 to store and restore sessions and retrieve information from packed
42 ****************************************************************** */
68 #ifndef _CIPHER_SPECS_H_
69 #include "cipherSpecs.h"
73 #ifndef _APPLE_SESSION_H_
74 #include "appleSession.h"
84 SSLProtocolVersion protocolVersion
;
86 UInt8 masterSecret
[48];
88 UInt8 certs
[1]; /* Actually, variable length */
92 * Cook up a (private) resumable session blob, based on the
93 * specified ctx, store it with ctx->peerID as the key.
94 * NOTE: This is contrary to the SSLRef3 spec, which claims that
95 * servers store resumable sessions using ctx->sessionID as the key.
96 * I don' think this is an issue...is it?
99 SSLAddSessionID(const SSLContext
*ctx
)
103 ResumableSession
*session
;
105 SSLCertificate
*cert
;
108 /* If we don't know who the peer is, we can't store a session */
109 if (ctx
->peerID
.data
== 0)
110 return SSLSessionNotFoundErr
;
112 sessionIDLen
= offsetof(ResumableSession
, certs
);
113 cert
= ctx
->peerCert
;
117 sessionIDLen
+= 4 + cert
->derCert
.length
;
121 if ((err
= SSLAllocBuffer(&sessionID
, sessionIDLen
, &ctx
->sysCtx
)) != 0)
124 session
= (ResumableSession
*)sessionID
.data
;
126 session
->sessionIDLen
= ctx
->sessionID
.length
;
127 memcpy(session
->sessionID
, ctx
->sessionID
.data
, session
->sessionIDLen
);
128 session
->protocolVersion
= ctx
->negProtocolVersion
;
129 session
->cipherSuite
= ctx
->selectedCipher
;
130 memcpy(session
->masterSecret
, ctx
->masterSecret
, 48);
131 session
->certCount
= certCount
;
133 certDest
= session
->certs
;
134 cert
= ctx
->peerCert
;
136 { certDest
= SSLEncodeInt(certDest
, cert
->derCert
.length
, 4);
137 memcpy(certDest
, cert
->derCert
.data
, cert
->derCert
.length
);
138 certDest
+= cert
->derCert
.length
;
143 err
= sslAddSession(ctx
->peerID
, sessionID
, ctx
->sessionCtx
.sessionRef
);
145 err
= ctx
->sessionCtx
.addSession(ctx
->peerID
, sessionID
, ctx
->sessionCtx
.sessionRef
);
147 SSLFreeBuffer(&sessionID
, &ctx
->sysCtx
);
153 * Retrieve resumable session data, from key ctx->peerID.
156 SSLGetSessionID(SSLBuffer
*sessionData
, const SSLContext
*ctx
)
159 if (ctx
->peerID
.data
== 0)
160 return ERR(SSLSessionNotFoundErr
);
162 sessionData
->data
= 0;
165 err
= sslGetSession(ctx
->peerID
, sessionData
, ctx
->sessionCtx
.sessionRef
);
167 ERR(err
= ctx
->sessionCtx
.getSession(ctx
->peerID
, sessionData
, ctx
->sessionCtx
.sessionRef
));
170 if (sessionData
->data
== 0)
171 return ERR(SSLSessionNotFoundErr
);
177 SSLDeleteSessionID(const SSLContext
*ctx
)
180 if (ctx
->peerID
.data
== 0)
181 return SSLSessionNotFoundErr
;
184 err
= sslDeleteSession(ctx
->peerID
, ctx
->sessionCtx
.sessionRef
);
186 err
= ctx
->sessionCtx
.deleteSession(ctx
->peerID
, ctx
->sessionCtx
.sessionRef
);
192 * Given a sessionData blob, obtain the associated sessionID (NOT the key...).
195 SSLRetrieveSessionIDIdentifier(
196 const SSLBuffer sessionData
,
197 SSLBuffer
*identifier
,
198 const SSLContext
*ctx
)
200 ResumableSession
*session
;
202 session
= (ResumableSession
*) sessionData
.data
;
203 if ((err
= SSLAllocBuffer(identifier
, session
->sessionIDLen
, &ctx
->sysCtx
)) != 0)
205 memcpy(identifier
->data
, session
->sessionID
, session
->sessionIDLen
);
210 * Obtain the protocol version associated with a specified resumable session blob.
213 SSLRetrieveSessionIDProtocolVersion(
214 const SSLBuffer sessionID
,
215 SSLProtocolVersion
*version
,
216 const SSLContext
*ctx
)
217 { ResumableSession
*session
;
219 session
= (ResumableSession
*) sessionID
.data
;
220 *version
= session
->protocolVersion
;
225 * Retrieve session state. Presumably, ctx->sessionID and
226 * ctx->negProtocolVersion are already init'd (from the above two functions).
229 SSLInstallSessionID(const SSLBuffer sessionData
, SSLContext
*ctx
)
231 ResumableSession
*session
;
232 uint8
*storedCertProgress
;
233 SSLCertificate
*cert
, *lastCert
;
240 session
= (ResumableSession
*)sessionData
.data
;
242 CASSERT(ctx
->negProtocolVersion
== session
->protocolVersion
);
244 ctx
->selectedCipher
= session
->cipherSuite
;
245 if ((err
= FindCipherSpec(ctx
)) != 0) {
248 memcpy(ctx
->masterSecret
, session
->masterSecret
, 48);
251 storedCertProgress
= session
->certs
;
252 certCount
= session
->certCount
;
257 cert
= (SSLCertificate
*)sslMalloc(sizeof(SSLCertificate
));
262 if ((err
= SSLAllocBuffer(&certAlloc
, sizeof(SSLCertificate
), &ctx
->sysCtx
)) != 0)
264 cert
= (SSLCertificate
*)certAlloc
.data
;
267 certLen
= SSLDecodeInt(storedCertProgress
, 4);
268 storedCertProgress
+= 4;
269 if ((err
= SSLAllocBuffer(&cert
->derCert
, certLen
, &ctx
->sysCtx
)) != 0)
274 SSLFreeBuffer(&certAlloc
,&ctx
->sysCtx
);
278 memcpy(cert
->derCert
.data
, storedCertProgress
, certLen
);
279 storedCertProgress
+= certLen
;
281 /* we don't decode */
282 if ((err
= ASNParseX509Certificate(cert
->derCert
, &cert
->cert
, ctx
)) != 0)
284 SSLFreeBuffer(&cert
->derCert
,&ctx
->sysCtx
);
288 SSLFreeBuffer(&certAlloc
,&ctx
->sysCtx
);
294 ctx
->peerCert
= cert
;
296 lastCert
->next
= cert
;