]> git.saurik.com Git - apple/security.git/blob - SecureTransport/sslsess.c
Security-29.tar.gz
[apple/security.git] / SecureTransport / sslsess.c
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
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
8 * using this file.
9 *
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.
16 */
17
18
19 /* *********************************************************************
20 File: sslsess.c
21
22 SSLRef 3.0 Final -- 11/19/96
23
24 Copyright (c)1996 by Netscape Communications Corp.
25
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.
29
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/>.
33
34 *********************************************************************
35
36 File: sslsess.c SSL Session DB interface
37
38 This file contains functions which interact with the session database
39 to store and restore sessions and retrieve information from packed
40 session records.
41
42 ****************************************************************** */
43
44 #ifndef _SSL_H_
45 #include "ssl.h"
46 #endif
47
48 #ifndef _SSLCTX_H_
49 #include "sslctx.h"
50 #endif
51
52 #ifndef _SSLSESS_H_
53 #include "sslsess.h"
54 #endif
55
56 #ifndef _SSLALLOC_H_
57 #include "sslalloc.h"
58 #endif
59
60 #ifndef _SSLUTIL_H_
61 #include "sslutil.h"
62 #endif
63
64 #ifndef _SSL_DEBUG_H_
65 #include "sslDebug.h"
66 #endif
67
68 #ifndef _CIPHER_SPECS_H_
69 #include "cipherSpecs.h"
70 #endif
71
72 #ifdef _APPLE_CDSA_
73 #ifndef _APPLE_SESSION_H_
74 #include "appleSession.h"
75 #endif
76 #endif
77
78 #include <string.h>
79 #include <stddef.h>
80
81 typedef struct
82 { int sessionIDLen;
83 UInt8 sessionID[32];
84 SSLProtocolVersion protocolVersion;
85 UInt16 cipherSuite;
86 UInt8 masterSecret[48];
87 int certCount;
88 UInt8 certs[1]; /* Actually, variable length */
89 } ResumableSession;
90
91 /*
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?
97 */
98 SSLErr
99 SSLAddSessionID(const SSLContext *ctx)
100 { SSLErr err;
101 uint32 sessionIDLen;
102 SSLBuffer sessionID;
103 ResumableSession *session;
104 int certCount;
105 SSLCertificate *cert;
106 uint8 *certDest;
107
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;
111
112 sessionIDLen = offsetof(ResumableSession, certs);
113 cert = ctx->peerCert;
114 certCount = 0;
115 while (cert)
116 { ++certCount;
117 sessionIDLen += 4 + cert->derCert.length;
118 cert = cert->next;
119 }
120
121 if ((err = SSLAllocBuffer(&sessionID, sessionIDLen, &ctx->sysCtx)) != 0)
122 return err;
123
124 session = (ResumableSession*)sessionID.data;
125
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;
132
133 certDest = session->certs;
134 cert = ctx->peerCert;
135 while (cert)
136 { certDest = SSLEncodeInt(certDest, cert->derCert.length, 4);
137 memcpy(certDest, cert->derCert.data, cert->derCert.length);
138 certDest += cert->derCert.length;
139 cert = cert->next;
140 }
141
142 #ifdef _APPLE_CDSA_
143 err = sslAddSession(ctx->peerID, sessionID, ctx->sessionCtx.sessionRef);
144 #else
145 err = ctx->sessionCtx.addSession(ctx->peerID, sessionID, ctx->sessionCtx.sessionRef);
146 #endif
147 SSLFreeBuffer(&sessionID, &ctx->sysCtx);
148
149 return err;
150 }
151
152 /*
153 * Retrieve resumable session data, from key ctx->peerID.
154 */
155 SSLErr
156 SSLGetSessionID(SSLBuffer *sessionData, const SSLContext *ctx)
157 { SSLErr err;
158
159 if (ctx->peerID.data == 0)
160 return ERR(SSLSessionNotFoundErr);
161
162 sessionData->data = 0;
163
164 #ifdef _APPLE_CDSA_
165 err = sslGetSession(ctx->peerID, sessionData, ctx->sessionCtx.sessionRef);
166 #else
167 ERR(err = ctx->sessionCtx.getSession(ctx->peerID, sessionData, ctx->sessionCtx.sessionRef));
168 #endif
169
170 if (sessionData->data == 0)
171 return ERR(SSLSessionNotFoundErr);
172
173 return err;
174 }
175
176 SSLErr
177 SSLDeleteSessionID(const SSLContext *ctx)
178 { SSLErr err;
179
180 if (ctx->peerID.data == 0)
181 return SSLSessionNotFoundErr;
182
183 #ifdef _APPLE_CDSA_
184 err = sslDeleteSession(ctx->peerID, ctx->sessionCtx.sessionRef);
185 #else
186 err = ctx->sessionCtx.deleteSession(ctx->peerID, ctx->sessionCtx.sessionRef);
187 #endif
188 return err;
189 }
190
191 /*
192 * Given a sessionData blob, obtain the associated sessionID (NOT the key...).
193 */
194 SSLErr
195 SSLRetrieveSessionIDIdentifier(
196 const SSLBuffer sessionData,
197 SSLBuffer *identifier,
198 const SSLContext *ctx)
199 { SSLErr err;
200 ResumableSession *session;
201
202 session = (ResumableSession*) sessionData.data;
203 if ((err = SSLAllocBuffer(identifier, session->sessionIDLen, &ctx->sysCtx)) != 0)
204 return err;
205 memcpy(identifier->data, session->sessionID, session->sessionIDLen);
206 return SSLNoErr;
207 }
208
209 /*
210 * Obtain the protocol version associated with a specified resumable session blob.
211 */
212 SSLErr
213 SSLRetrieveSessionIDProtocolVersion(
214 const SSLBuffer sessionID,
215 SSLProtocolVersion *version,
216 const SSLContext *ctx)
217 { ResumableSession *session;
218
219 session = (ResumableSession*) sessionID.data;
220 *version = session->protocolVersion;
221 return SSLNoErr;
222 }
223
224 /*
225 * Retrieve session state. Presumably, ctx->sessionID and
226 * ctx->negProtocolVersion are already init'd (from the above two functions).
227 */
228 SSLErr
229 SSLInstallSessionID(const SSLBuffer sessionData, SSLContext *ctx)
230 { SSLErr err;
231 ResumableSession *session;
232 uint8 *storedCertProgress;
233 SSLCertificate *cert, *lastCert;
234 #ifndef __APPLE__
235 SSLBuffer certAlloc;
236 #endif
237 int certCount;
238 uint32 certLen;
239
240 session = (ResumableSession*)sessionData.data;
241
242 CASSERT(ctx->negProtocolVersion == session->protocolVersion);
243
244 ctx->selectedCipher = session->cipherSuite;
245 if ((err = FindCipherSpec(ctx)) != 0) {
246 return err;
247 }
248 memcpy(ctx->masterSecret, session->masterSecret, 48);
249
250 lastCert = 0;
251 storedCertProgress = session->certs;
252 certCount = session->certCount;
253
254 while (certCount--)
255 {
256 #ifdef __APPLE__
257 cert = (SSLCertificate *)sslMalloc(sizeof(SSLCertificate));
258 if(cert == NULL) {
259 return SSLMemoryErr;
260 }
261 #else
262 if ((err = SSLAllocBuffer(&certAlloc, sizeof(SSLCertificate), &ctx->sysCtx)) != 0)
263 return err;
264 cert = (SSLCertificate*)certAlloc.data;
265 #endif
266 cert->next = 0;
267 certLen = SSLDecodeInt(storedCertProgress, 4);
268 storedCertProgress += 4;
269 if ((err = SSLAllocBuffer(&cert->derCert, certLen, &ctx->sysCtx)) != 0)
270 {
271 #ifdef __APPLE__
272 sslFree(cert);
273 #else
274 SSLFreeBuffer(&certAlloc,&ctx->sysCtx);
275 #endif
276 return err;
277 }
278 memcpy(cert->derCert.data, storedCertProgress, certLen);
279 storedCertProgress += certLen;
280 #ifndef _APPLE_CDSA_
281 /* we don't decode */
282 if ((err = ASNParseX509Certificate(cert->derCert, &cert->cert, ctx)) != 0)
283 {
284 SSLFreeBuffer(&cert->derCert,&ctx->sysCtx);
285 #ifdef __APPLE__
286 sslFree(cert);
287 #else
288 SSLFreeBuffer(&certAlloc,&ctx->sysCtx);
289 #endif
290 return err;
291 }
292 #endif
293 if (lastCert == 0)
294 ctx->peerCert = cert;
295 else
296 lastCert->next = cert;
297 lastCert = cert;
298 }
299
300 return SSLNoErr;
301 }