summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorjsing <>2016-11-04 15:09:29 +0000
committerjsing <>2016-11-04 15:09:29 +0000
commitf34ab28d6356aae4d0458dd2076438a042314790 (patch)
tree17f0bc996d515c1b0d2abc8381266a2e8f88b952 /src/lib
parentf8f8b38885d68124ff34c69bf38a1c2b4499cc40 (diff)
downloadopenbsd-f34ab28d6356aae4d0458dd2076438a042314790.tar.gz
openbsd-f34ab28d6356aae4d0458dd2076438a042314790.tar.bz2
openbsd-f34ab28d6356aae4d0458dd2076438a042314790.zip
Completely rewrite the session handling ASN.1 code using CBB and CBS. This
addresses two 2038 related issues and also adds support for allocation in the i2d function, which will allow for simplification in the callers. ok beck@ miod@
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libssl/ssl_asn1.c945
1 files changed, 329 insertions, 616 deletions
diff --git a/src/lib/libssl/ssl_asn1.c b/src/lib/libssl/ssl_asn1.c
index ee00cb286d..59e7cdf7b2 100644
--- a/src/lib/libssl/ssl_asn1.c
+++ b/src/lib/libssl/ssl_asn1.c
@@ -1,691 +1,404 @@
1/* $OpenBSD: ssl_asn1.c,v 1.41 2016/03/11 07:08:45 mmcc Exp $ */ 1/* $OpenBSD: ssl_asn1.c,v 1.42 2016/11/04 15:09:29 jsing Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2
3 * All rights reserved. 3/*
4 * 4 * Copyright (c) 2016 Joel Sing <jsing@openbsd.org>
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 * 5 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 6 * Permission to use, copy, modify, and distribute this software for any
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 7 * purpose with or without fee is hereby granted, provided that the above
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 8 * copyright notice and this permission notice appear in all copies.
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 * 9 *
53 * The licence and distribution terms for any publically available version or 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
54 * derivative of this code cannot be changed. i.e. this code cannot simply be 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
55 * copied and put under another distribution licence 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
56 * [including the GNU Public Licence.] 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
57 */ 17 */
58 18
59#include <stdio.h> 19#include <limits.h>
60#include <stdlib.h> 20
21#include <openssl/ssl.h>
22#include <openssl/x509.h>
61 23
62#include "ssl_locl.h" 24#include "ssl_locl.h"
63 25
64#include <openssl/objects.h> 26#include "bytestring.h"
65#include <openssl/x509.h>
66 27
67/* XXX - these are here to avoid including asn1_mac.h */ 28#define SSLASN1_TAG (CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC)
68int asn1_GetSequence(ASN1_const_CTX *c, long *length); 29#define SSLASN1_TIME_TAG (SSLASN1_TAG | 1)
69void asn1_add_error(const unsigned char *address, int offset); 30#define SSLASN1_TIMEOUT_TAG (SSLASN1_TAG | 2)
70 31#define SSLASN1_PEER_CERT_TAG (SSLASN1_TAG | 3)
71typedef struct ssl_session_asn1_st { 32#define SSLASN1_SESSION_ID_CTX_TAG (SSLASN1_TAG | 4)
72 ASN1_INTEGER version; 33#define SSLASN1_VERIFY_RESULT_TAG (SSLASN1_TAG | 5)
73 ASN1_INTEGER ssl_version; 34#define SSLASN1_HOSTNAME_TAG (SSLASN1_TAG | 6)
74 ASN1_OCTET_STRING cipher; 35#define SSLASN1_LIFETIME_TAG (SSLASN1_TAG | 9)
75 ASN1_OCTET_STRING master_key; 36#define SSLASN1_TICKET_TAG (SSLASN1_TAG | 10)
76 ASN1_OCTET_STRING session_id; 37
77 ASN1_OCTET_STRING session_id_context; 38static uint64_t
78 ASN1_INTEGER time; 39time_max(void)
79 ASN1_INTEGER timeout; 40{
80 ASN1_INTEGER verify_result; 41 if (sizeof(time_t) == sizeof(int32_t))
81 ASN1_OCTET_STRING tlsext_hostname; 42 return INT32_MAX;
82 ASN1_INTEGER tlsext_tick_lifetime; 43 if (sizeof(time_t) == sizeof(int64_t))
83 ASN1_OCTET_STRING tlsext_tick; 44 return INT64_MAX;
84} SSL_SESSION_ASN1; 45 return 0;
46}
85 47
86int 48int
87i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp) 49i2d_SSL_SESSION(SSL_SESSION *s, unsigned char **pp)
88{ 50{
89#define LSIZE2 (sizeof(long)*2) 51 CBB cbb, session, cipher_suite, session_id, master_key, time, timeout;
90 int v1 = 0, v2 = 0, v3 = 0, v4 = 0, v5 = 0, v6 = 0, v9 = 0, v10 = 0; 52 CBB peer_cert, sidctx, verify_result, hostname, lifetime, ticket;
91 unsigned char buf[4], ibuf1[LSIZE2], ibuf2[LSIZE2]; 53 CBB value;
92 unsigned char ibuf3[LSIZE2], ibuf4[LSIZE2], ibuf5[LSIZE2]; 54 unsigned char *data = NULL, *peer_cert_bytes = NULL;
93 unsigned char ibuf6[LSIZE2]; 55 int len, rv = -1;
94 SSL_SESSION_ASN1 a; 56 size_t data_len;
95 unsigned char *p; 57 uint16_t cid;
96 int len = 0, ret; 58
97 long l; 59 if (s == NULL)
98
99 if ((in == NULL) || ((in->cipher == NULL) && (in->cipher_id == 0)))
100 return (0); 60 return (0);
101 61
102 /* 62 if (s->cipher == NULL && s->cipher_id == 0)
103 * Note that I cheat in the following 2 assignments. 63 return (0);
104 * I know that if the ASN1_INTEGER passed to ASN1_INTEGER_set
105 * is > sizeof(long)+1, the buffer will not be re-malloc()ed.
106 * This is a bit evil but makes things simple, no dynamic allocation
107 * to clean up :-)
108 */
109 a.version.length = LSIZE2;
110 a.version.type = V_ASN1_INTEGER;
111 a.version.data = ibuf1;
112 ASN1_INTEGER_set(&(a.version), SSL_SESSION_ASN1_VERSION);
113 len += i2d_ASN1_INTEGER(&(a.version), NULL);
114
115 a.ssl_version.length = LSIZE2;
116 a.ssl_version.type = V_ASN1_INTEGER;
117 a.ssl_version.data = ibuf2;
118 ASN1_INTEGER_set(&(a.ssl_version), in->ssl_version);
119 len += i2d_ASN1_INTEGER(&(a.ssl_version), NULL);
120
121 a.cipher.length = 2;
122 a.cipher.type = V_ASN1_OCTET_STRING;
123 l = (in->cipher == NULL) ? in->cipher_id : in->cipher->id;
124 buf[0] = ((unsigned char)(l >> 8L)) & 0xff;
125 buf[1] = ((unsigned char)(l)) & 0xff;
126 a.cipher.data = buf;
127 len += i2d_ASN1_OCTET_STRING(&(a.cipher), NULL);
128
129 a.master_key.length = in->master_key_length;
130 a.master_key.type = V_ASN1_OCTET_STRING;
131 a.master_key.data = in->master_key;
132 len += i2d_ASN1_OCTET_STRING(&(a.master_key), NULL);
133
134 a.session_id.length = in->session_id_length;
135 a.session_id.type = V_ASN1_OCTET_STRING;
136 a.session_id.data = in->session_id;
137 len += i2d_ASN1_OCTET_STRING(&(a.session_id), NULL);
138
139 if (in->time != 0L) {
140 a.time.length = LSIZE2;
141 a.time.type = V_ASN1_INTEGER;
142 a.time.data = ibuf3;
143 ASN1_INTEGER_set(&(a.time), in->time); /* XXX 2038 */
144 v1 = i2d_ASN1_INTEGER(&(a.time), NULL);
145 len += ASN1_object_size(1, v1, 1);
146 }
147 64
148 if (in->timeout != 0L) { 65 if (!CBB_init(&cbb, 0))
149 a.timeout.length = LSIZE2; 66 goto err;
150 a.timeout.type = V_ASN1_INTEGER;
151 a.timeout.data = ibuf4;
152 ASN1_INTEGER_set(&(a.timeout), in->timeout);
153 v2 = i2d_ASN1_INTEGER(&(a.timeout), NULL);
154 len += ASN1_object_size(1, v2, 2);
155 }
156 67
157 if (in->peer != NULL) { 68 if (!CBB_add_asn1(&cbb, &session, CBS_ASN1_SEQUENCE))
158 v3 = i2d_X509(in->peer, NULL); 69 goto err;
159 len += ASN1_object_size(1, v3, 3);
160 }
161 70
162 a.session_id_context.length = in->sid_ctx_length; 71 /* Session ASN1 version. */
163 a.session_id_context.type = V_ASN1_OCTET_STRING; 72 if (!CBB_add_asn1_uint64(&session, SSL_SESSION_ASN1_VERSION))
164 a.session_id_context.data = in->sid_ctx; 73 goto err;
165 v4 = i2d_ASN1_OCTET_STRING(&(a.session_id_context), NULL);
166 len += ASN1_object_size(1, v4, 4);
167
168 if (in->verify_result != X509_V_OK) {
169 a.verify_result.length = LSIZE2;
170 a.verify_result.type = V_ASN1_INTEGER;
171 a.verify_result.data = ibuf5;
172 ASN1_INTEGER_set(&a.verify_result, in->verify_result);
173 v5 = i2d_ASN1_INTEGER(&(a.verify_result), NULL);
174 len += ASN1_object_size(1, v5, 5);
175 }
176 74
177 if (in->tlsext_hostname) { 75 /* TLS/SSL protocol version. */
178 a.tlsext_hostname.length = strlen(in->tlsext_hostname); 76 if (s->ssl_version < 0)
179 a.tlsext_hostname.type = V_ASN1_OCTET_STRING; 77 goto err;
180 a.tlsext_hostname.data = (unsigned char *)in->tlsext_hostname; 78 if (!CBB_add_asn1_uint64(&session, s->ssl_version))
181 v6 = i2d_ASN1_OCTET_STRING(&(a.tlsext_hostname), NULL); 79 goto err;
182 len += ASN1_object_size(1, v6, 6);
183 }
184 80
185 /* 7 - PSK identity hint. */ 81 /* Cipher suite ID. */
186 /* 8 - PSK identity. */ 82 /* XXX - require cipher to be non-NULL or always/only use cipher_id. */
187 83 cid = (uint16_t)(s->cipher_id & 0xffff);
188 if (in->tlsext_tick_lifetime_hint > 0) { 84 if (s->cipher != NULL)
189 a.tlsext_tick_lifetime.length = LSIZE2; 85 cid = ssl3_cipher_get_value(s->cipher);
190 a.tlsext_tick_lifetime.type = V_ASN1_INTEGER; 86 if (!CBB_add_asn1(&session, &cipher_suite, CBS_ASN1_OCTETSTRING))
191 a.tlsext_tick_lifetime.data = ibuf6; 87 goto err;
192 ASN1_INTEGER_set(&a.tlsext_tick_lifetime, 88 if (!CBB_add_u16(&cipher_suite, cid))
193 in->tlsext_tick_lifetime_hint); 89 goto err;
194 v9 = i2d_ASN1_INTEGER(&(a.tlsext_tick_lifetime), NULL);
195 len += ASN1_object_size(1, v9, 9);
196 }
197 90
198 if (in->tlsext_tick) { 91 /* Session ID. */
199 a.tlsext_tick.length = in->tlsext_ticklen; 92 if (!CBB_add_asn1(&session, &session_id, CBS_ASN1_OCTETSTRING))
200 a.tlsext_tick.type = V_ASN1_OCTET_STRING; 93 goto err;
201 a.tlsext_tick.data = (unsigned char *)in->tlsext_tick; 94 if (!CBB_add_bytes(&session_id, s->session_id, s->session_id_length))
202 v10 = i2d_ASN1_OCTET_STRING(&(a.tlsext_tick), NULL); 95 goto err;
203 len += ASN1_object_size(1, v10, 10); 96
97 /* Master key. */
98 if (!CBB_add_asn1(&session, &master_key, CBS_ASN1_OCTETSTRING))
99 goto err;
100 if (!CBB_add_bytes(&master_key, s->master_key, s->master_key_length))
101 goto err;
102
103 /* Time [1]. */
104 if (s->time != 0) {
105 if (s->time < 0)
106 goto err;
107 if (!CBB_add_asn1(&session, &time, SSLASN1_TIME_TAG))
108 goto err;
109 if (!CBB_add_asn1_uint64(&time, s->time))
110 goto err;
204 } 111 }
205 112
206 /* 11 - Compression method. */ 113 /* Timeout [2]. */
207 /* 12 - SRP username. */ 114 if (s->timeout != 0) {
208 115 if (s->timeout < 0)
209 /* If given a NULL pointer, return the length only. */ 116 goto err;
210 ret = (ASN1_object_size(1, len, V_ASN1_SEQUENCE)); 117 if (!CBB_add_asn1(&session, &timeout, SSLASN1_TIMEOUT_TAG))
211 if (pp == NULL) 118 goto err;
212 return (ret); 119 if (!CBB_add_asn1_uint64(&timeout, s->timeout))
213 120 goto err;
214 /* Burp out the ASN1. */
215 p = *pp;
216 ASN1_put_object(&p, 1, len, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
217 i2d_ASN1_INTEGER(&(a.version), &p);
218 i2d_ASN1_INTEGER(&(a.ssl_version), &p);
219 i2d_ASN1_OCTET_STRING(&(a.cipher), &p);
220 i2d_ASN1_OCTET_STRING(&(a.session_id), &p);
221 i2d_ASN1_OCTET_STRING(&(a.master_key), &p);
222 if (in->time != 0L) {
223 ASN1_put_object(&p, 1, v1, 1, V_ASN1_CONTEXT_SPECIFIC);
224 i2d_ASN1_INTEGER(&(a.time), &p);
225 } 121 }
226 if (in->timeout != 0L) { 122
227 ASN1_put_object(&p, 1, v2, 2, V_ASN1_CONTEXT_SPECIFIC); 123 /* Peer certificate [3]. */
228 i2d_ASN1_INTEGER(&(a.timeout), &p); 124 if (s->peer != NULL) {
125 if (!CBB_add_asn1(&session, &peer_cert, SSLASN1_PEER_CERT_TAG))
126 goto err;
127 if (!CBB_add_asn1(&peer_cert, &value, CBS_ASN1_OCTETSTRING))
128 goto err;
129 if ((len = i2d_X509(s->peer, &peer_cert_bytes)) <= 0)
130 goto err;
131 if (!CBB_add_bytes(&value, peer_cert_bytes, len))
132 goto err;
229 } 133 }
230 if (in->peer != NULL) { 134
231 ASN1_put_object(&p, 1, v3, 3, V_ASN1_CONTEXT_SPECIFIC); 135 /* Session ID context [4]. */
232 i2d_X509(in->peer, &p); 136 /* XXX - Actually handle this as optional? */
137 if (!CBB_add_asn1(&session, &sidctx, SSLASN1_SESSION_ID_CTX_TAG))
138 goto err;
139 if (!CBB_add_asn1(&sidctx, &value, CBS_ASN1_OCTETSTRING))
140 goto err;
141 if (!CBB_add_bytes(&value, s->sid_ctx, s->sid_ctx_length))
142 goto err;
143
144 /* Verify result [5]. */
145 if (s->verify_result != X509_V_OK) {
146 if (s->verify_result < 0)
147 goto err;
148 if (!CBB_add_asn1(&session, &verify_result,
149 SSLASN1_VERIFY_RESULT_TAG))
150 goto err;
151 if (!CBB_add_asn1_uint64(&verify_result, s->verify_result))
152 goto err;
233 } 153 }
234 ASN1_put_object(&p, 1, v4, 4, V_ASN1_CONTEXT_SPECIFIC); 154
235 i2d_ASN1_OCTET_STRING(&(a.session_id_context), &p); 155 /* Hostname [6]. */
236 if (in->verify_result != X509_V_OK) { 156 if (s->tlsext_hostname != NULL) {
237 ASN1_put_object(&p, 1, v5, 5, V_ASN1_CONTEXT_SPECIFIC); 157 if (!CBB_add_asn1(&session, &hostname, SSLASN1_HOSTNAME_TAG))
238 i2d_ASN1_INTEGER(&(a.verify_result), &p); 158 goto err;
159 if (!CBB_add_asn1(&hostname, &value, CBS_ASN1_OCTETSTRING))
160 goto err;
161 if (!CBB_add_bytes(&value, s->tlsext_hostname,
162 strlen(s->tlsext_hostname)))
163 goto err;
239 } 164 }
240 if (in->tlsext_hostname) { 165
241 ASN1_put_object(&p, 1, v6, 6, V_ASN1_CONTEXT_SPECIFIC); 166 /* PSK identity hint [7]. */
242 i2d_ASN1_OCTET_STRING(&(a.tlsext_hostname), &p); 167 /* PSK identity [8]. */
168
169 /* Ticket lifetime hint [9]. */
170 if (s->tlsext_tick_lifetime_hint > 0) {
171 if (!CBB_add_asn1(&session, &lifetime, SSLASN1_LIFETIME_TAG))
172 goto err;
173 if (!CBB_add_asn1_uint64(&lifetime,
174 s->tlsext_tick_lifetime_hint))
175 goto err;
243 } 176 }
244 /* 7 - PSK identity hint. */ 177
245 /* 8 - PSK identity. */ 178 /* Ticket [10]. */
246 if (in->tlsext_tick_lifetime_hint > 0) { 179 if (s->tlsext_tick) {
247 ASN1_put_object(&p, 1, v9, 9, V_ASN1_CONTEXT_SPECIFIC); 180 if (!CBB_add_asn1(&session, &ticket, SSLASN1_TICKET_TAG))
248 i2d_ASN1_INTEGER(&(a.tlsext_tick_lifetime), &p); 181 goto err;
182 if (!CBB_add_asn1(&ticket, &value, CBS_ASN1_OCTETSTRING))
183 goto err;
184 if (!CBB_add_bytes(&value, s->tlsext_tick, s->tlsext_ticklen))
185 goto err;
249 } 186 }
250 if (in->tlsext_tick) { 187
251 ASN1_put_object(&p, 1, v10, 10, V_ASN1_CONTEXT_SPECIFIC); 188 /* Compression method [11]. */
252 i2d_ASN1_OCTET_STRING(&(a.tlsext_tick), &p); 189 /* SRP username [12]. */
190
191 if (!CBB_finish(&cbb, &data, &data_len))
192 goto err;
193
194 if (data_len > INT_MAX)
195 goto err;
196
197 if (pp != NULL) {
198 if (*pp == NULL) {
199 *pp = data;
200 data = NULL;
201 } else {
202 memcpy(*pp, data, data_len);
203 }
253 } 204 }
254 /* 11 - Compression method. */
255 /* 12 - SRP username. */
256 205
257 *pp = p; 206 rv = (int)data_len;
258 return (ret); 207
208 err:
209 CBB_cleanup(&session);
210 free(peer_cert_bytes);
211 free(data);
212
213 return rv;
259} 214}
260 215
261SSL_SESSION * 216SSL_SESSION *
262d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, long length) 217d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, long length)
263{ 218{
264 SSL_SESSION *ret = NULL; 219 CBS cbs, session, cipher_suite, session_id, master_key, peer_cert;
265 ASN1_const_CTX c; 220 CBS hostname, ticket;
266 ASN1_INTEGER ai, *aip; 221 uint64_t version, tls_version, stime, timeout, verify_result, lifetime;
267 ASN1_OCTET_STRING os, *osp; 222 const unsigned char *peer_cert_bytes;
268 int ssl_version = 0, i; 223 uint16_t cipher_value;
269 int Tinf, Ttag, Tclass; 224 SSL_SESSION *s = NULL;
270 long Tlen; 225 size_t data_len;
271 long id; 226 int present;
272 227
273 c.pp = pp; 228 if (a != NULL)
274 c.p = *pp; 229 s = *a;
275 c.q = *pp; 230
276 c.max = (length == 0) ? 0 : (c.p + length); 231 if (s == NULL) {
277 c.slen = length; 232 if ((s = SSL_SESSION_new()) == NULL) {
278 233 SSLerr(SSL_F_D2I_SSL_SESSION, ERR_R_MALLOC_FAILURE);
279 if (a == NULL || *a == NULL) {
280 if ((ret = SSL_SESSION_new()) == NULL) {
281 SSLerr(SSL_F_D2I_SSL_SESSION, ERR_R_NESTED_ASN1_ERROR);
282 goto err; 234 goto err;
283 } 235 }
284 } else 236 }
285 ret = *a;
286 237
287 aip = &ai; 238 CBS_init(&cbs, *pp, length);
288 osp = &os;
289 239
290 if (!asn1_GetSequence(&c, &length)) { 240 if (!CBS_get_asn1(&cbs, &session, CBS_ASN1_SEQUENCE))
291 SSLerr(SSL_F_D2I_SSL_SESSION, ERR_R_NESTED_ASN1_ERROR);
292 goto err; 241 goto err;
293 }
294 242
295 ai.data = NULL; 243 /* Session ASN1 version. */
296 ai.length = 0; 244 if (!CBS_get_asn1_uint64(&session, &version))
297 c.q = c.p; 245 goto err;
298 if (d2i_ASN1_INTEGER(&aip, &c.p, c.slen) == NULL) { 246 if (version != SSL_SESSION_ASN1_VERSION)
299 SSLerr(SSL_F_D2I_SSL_SESSION, ERR_R_NESTED_ASN1_ERROR);
300 goto err; 247 goto err;
301 }
302 c.slen -= (c.p - c.q);
303
304 if (ai.data != NULL) {
305 free(ai.data);
306 ai.data = NULL;
307 ai.length = 0;
308 }
309 248
310 /* we don't care about the version right now :-) */ 249 /* TLS/SSL Protocol Version. */
311 c.q = c.p; 250 if (!CBS_get_asn1_uint64(&session, &tls_version))
312 if (d2i_ASN1_INTEGER(&aip, &c.p, c.slen) == NULL) {
313 SSLerr(SSL_F_D2I_SSL_SESSION, ERR_R_NESTED_ASN1_ERROR);
314 goto err; 251 goto err;
315 } 252 if (tls_version > INT_MAX)
316 c.slen -= (c.p - c.q); 253 goto err;
317 ssl_version = (int)ASN1_INTEGER_get(aip); 254 s->ssl_version = (int)tls_version;
318 ret->ssl_version = ssl_version;
319 if (ai.data != NULL) {
320 free(ai.data);
321 ai.data = NULL;
322 ai.length = 0;
323 }
324 255
325 os.data = NULL; 256 /* Cipher suite. */
326 os.length = 0; 257 if (!CBS_get_asn1(&session, &cipher_suite, CBS_ASN1_OCTETSTRING))
327 c.q = c.p;
328 if (d2i_ASN1_OCTET_STRING(&osp, &c.p, c.slen) == NULL) {
329 SSLerr(SSL_F_D2I_SSL_SESSION, ERR_R_NESTED_ASN1_ERROR);
330 goto err; 258 goto err;
331 } 259 if (!CBS_get_u16(&cipher_suite, &cipher_value))
332 c.slen -= (c.p - c.q); 260 goto err;
333 if ((ssl_version >> 8) >= SSL3_VERSION_MAJOR) { 261 if (CBS_len(&cipher_suite) != 0)
334 if (os.length != 2) {
335 SSLerr(SSL_F_D2I_SSL_SESSION,
336 SSL_R_CIPHER_CODE_WRONG_LENGTH);
337 goto err;
338 }
339 id = 0x03000000L | ((unsigned long)os.data[0]<<8L) |
340 (unsigned long)os.data[1];
341 } else {
342 SSLerr(SSL_F_D2I_SSL_SESSION, SSL_R_UNKNOWN_SSL_VERSION);
343 goto err; 262 goto err;
344 }
345 263
346 ret->cipher = NULL; 264 /* XXX - populate cipher instead? */
347 ret->cipher_id = id; 265 s->cipher = NULL;
266 s->cipher_id = SSL3_CK_ID | cipher_value;
348 267
349 c.q = c.p; 268 /* Session ID. */
350 if (d2i_ASN1_OCTET_STRING(&osp, &c.p, c.slen) == NULL) { 269 if (!CBS_get_asn1(&session, &session_id, CBS_ASN1_OCTETSTRING))
351 SSLerr(SSL_F_D2I_SSL_SESSION, ERR_R_NESTED_ASN1_ERROR);
352 goto err; 270 goto err;
353 } 271 if (!CBS_write_bytes(&session_id, s->session_id, sizeof(s->session_id),
354 c.slen -= (c.p - c.q); 272 &data_len))
273 goto err;
274 if (data_len > UINT_MAX)
275 goto err;
276 s->session_id_length = (unsigned int)data_len;
355 277
356 i = SSL3_MAX_SSL_SESSION_ID_LENGTH; 278 /* Master key. */
357 if (os.length > i) 279 if (!CBS_get_asn1(&session, &master_key, CBS_ASN1_OCTETSTRING))
358 os.length = i; 280 goto err;
359 if (os.length > (int)sizeof(ret->session_id)) /* can't happen */ 281 if (!CBS_write_bytes(&master_key, s->master_key, sizeof(s->master_key),
360 os.length = sizeof(ret->session_id); 282 &data_len))
283 goto err;
284 if (data_len > INT_MAX)
285 goto err;
286 s->master_key_length = (int)data_len;
361 287
362 ret->session_id_length = os.length; 288 /* Time [1]. */
363 OPENSSL_assert(os.length <= (int)sizeof(ret->session_id)); 289 s->time = time(NULL);
364 memcpy(ret->session_id, os.data, os.length); 290 if (!CBS_get_optional_asn1_uint64(&session, &stime, SSLASN1_TIME_TAG,
291 0))
292 goto err;
293 if (stime > time_max())
294 goto err;
295 if (stime != 0)
296 s->time = (time_t)stime;
365 297
366 c.q = c.p; 298 /* Timeout [2]. */
367 if (d2i_ASN1_OCTET_STRING(&osp, &c.p, c.slen) == NULL) { 299 s->timeout = 3;
368 SSLerr(SSL_F_D2I_SSL_SESSION, ERR_R_NESTED_ASN1_ERROR); 300 if (!CBS_get_optional_asn1_uint64(&session, &timeout,
301 SSLASN1_TIMEOUT_TAG, 0))
369 goto err; 302 goto err;
370 } 303 if (timeout > LONG_MAX)
371 c.slen -= (c.p - c.q); 304 goto err;
372 if (os.length > SSL_MAX_MASTER_KEY_LENGTH) 305 if (timeout != 0)
373 ret->master_key_length = SSL_MAX_MASTER_KEY_LENGTH; 306 s->timeout = (long)timeout;
374 else 307
375 ret->master_key_length = os.length; 308 /* Peer certificate [3]. */
376 memcpy(ret->master_key, os.data, ret->master_key_length); 309 X509_free(s->peer);
377 310 s->peer = NULL;
378 os.length = 0; 311 if (!CBS_get_optional_asn1_octet_string(&session, &peer_cert, &present,
379 312 SSLASN1_PEER_CERT_TAG))
380 /* 1 - Time (INTEGER). */ 313 goto err;
381 /* XXX 2038 */ 314 if (present) {
382 ai.length = 0; 315 data_len = CBS_len(&peer_cert);
383 if (c.slen != 0L && 316 if (data_len > LONG_MAX)
384 *c.p == (V_ASN1_CONSTRUCTED | V_ASN1_CONTEXT_SPECIFIC | 1)) {
385 c.q = c.p;
386 Tinf = ASN1_get_object(&c.p, &Tlen, &Ttag, &Tclass, c.slen);
387 if (Tinf & 0x80) {
388 SSLerr(SSL_F_D2I_SSL_SESSION,
389 ERR_R_BAD_ASN1_OBJECT_HEADER);
390 goto err;
391 }
392 if (Tinf == (V_ASN1_CONSTRUCTED + 1))
393 Tlen = c.slen - (c.p - c.q) - 2;
394 if (d2i_ASN1_INTEGER(&aip, &c.p, Tlen) == NULL) {
395 SSLerr(SSL_F_D2I_SSL_SESSION, ERR_R_NESTED_ASN1_ERROR);
396 goto err;
397 }
398 if (Tinf == (V_ASN1_CONSTRUCTED + 1)) {
399 Tlen = c.slen - (c.p - c.q);
400 if(!ASN1_const_check_infinite_end(&c.p, Tlen)) {
401 SSLerr(SSL_F_D2I_SSL_SESSION,
402 ERR_R_MISSING_ASN1_EOS);
403 goto err;
404 }
405 }
406 c.slen -= (c.p - c.q);
407 }
408 if (ai.data != NULL) {
409 ret->time = ASN1_INTEGER_get(aip);
410 free(ai.data);
411 ai.data = NULL;
412 ai.length = 0;
413 } else
414 ret->time = time(NULL);
415
416 /* 2 - Timeout (INTEGER). */
417 ai.length = 0;
418 if (c.slen != 0L &&
419 *c.p == (V_ASN1_CONSTRUCTED | V_ASN1_CONTEXT_SPECIFIC | 2)) {
420 c.q = c.p;
421 Tinf = ASN1_get_object(&c.p, &Tlen, &Ttag, &Tclass, c.slen);
422 if (Tinf & 0x80) {
423 SSLerr(SSL_F_D2I_SSL_SESSION,
424 ERR_R_BAD_ASN1_OBJECT_HEADER);
425 goto err;
426 }
427 if (Tinf == (V_ASN1_CONSTRUCTED + 1))
428 Tlen = c.slen - (c.p - c.q) - 2;
429 if (d2i_ASN1_INTEGER(&aip, &c.p, Tlen) == NULL) {
430 SSLerr(SSL_F_D2I_SSL_SESSION, ERR_R_NESTED_ASN1_ERROR);
431 goto err;
432 }
433 if (Tinf == (V_ASN1_CONSTRUCTED + 1)) {
434 Tlen = c.slen - (c.p - c.q);
435 if(!ASN1_const_check_infinite_end(&c.p, Tlen)) {
436 SSLerr(SSL_F_D2I_SSL_SESSION,
437 ERR_R_MISSING_ASN1_EOS);
438 goto err;
439 }
440 }
441 c.slen -= (c.p - c.q);
442 }
443 if (ai.data != NULL) {
444 ret->timeout = ASN1_INTEGER_get(aip);
445 free(ai.data);
446 ai.data = NULL;
447 ai.length = 0;
448 } else
449 ret->timeout = 3;
450
451 /* 3 - Peer (X509). */
452 X509_free(ret->peer);
453 ret->peer = NULL;
454
455 if (c.slen != 0L &&
456 *c.p == (V_ASN1_CONSTRUCTED | V_ASN1_CONTEXT_SPECIFIC | 3)) {
457 c.q = c.p;
458 Tinf = ASN1_get_object(&c.p, &Tlen, &Ttag, &Tclass, c.slen);
459 if (Tinf & 0x80) {
460 SSLerr(SSL_F_D2I_SSL_SESSION,
461 ERR_R_BAD_ASN1_OBJECT_HEADER);
462 goto err; 317 goto err;
463 } 318 peer_cert_bytes = CBS_data(&peer_cert);
464 if (Tinf == (V_ASN1_CONSTRUCTED + 1)) 319 if (d2i_X509(&s->peer, &peer_cert_bytes,
465 Tlen = c.slen - (c.p - c.q) - 2; 320 (long)data_len) == NULL)
466 if (d2i_X509(&ret->peer, &c.p, Tlen) == NULL) {
467 SSLerr(SSL_F_D2I_SSL_SESSION, ERR_R_NESTED_ASN1_ERROR);
468 goto err; 321 goto err;
469 }
470 if (Tinf == (V_ASN1_CONSTRUCTED + 1)) {
471 Tlen = c.slen - (c.p - c.q);
472 if(!ASN1_const_check_infinite_end(&c.p, Tlen)) {
473 SSLerr(SSL_F_D2I_SSL_SESSION,
474 ERR_R_MISSING_ASN1_EOS);
475 goto err;
476 }
477 }
478 c.slen -= (c.p - c.q);
479 } 322 }
480 323
481 /* 4 - Session ID (OCTET STRING). */ 324 /* Session ID context [4]. */
482 os.length = 0; 325 s->sid_ctx_length = 0;
483 free(os.data); 326 if (!CBS_get_optional_asn1_octet_string(&session, &session_id, &present,
484 os.data = NULL; 327 SSLASN1_SESSION_ID_CTX_TAG))
485 if (c.slen != 0L && 328 goto err;
486 *c.p == (V_ASN1_CONSTRUCTED | V_ASN1_CONTEXT_SPECIFIC | 4)) { 329 if (present) {
487 c.q = c.p; 330 if (!CBS_write_bytes(&session_id, (uint8_t *)&s->sid_ctx,
488 Tinf = ASN1_get_object(&c.p, &Tlen, &Ttag, &Tclass, c.slen); 331 sizeof(s->sid_ctx), &data_len))
489 if (Tinf & 0x80) {
490 SSLerr(SSL_F_D2I_SSL_SESSION,
491 ERR_R_BAD_ASN1_OBJECT_HEADER);
492 goto err;
493 }
494 if (Tinf == (V_ASN1_CONSTRUCTED + 1))
495 Tlen = c.slen - (c.p - c.q) - 2;
496 if (d2i_ASN1_OCTET_STRING(&osp, &c.p, Tlen) == NULL) {
497 SSLerr(SSL_F_D2I_SSL_SESSION, ERR_R_NESTED_ASN1_ERROR);
498 goto err;
499 }
500 if (Tinf == (V_ASN1_CONSTRUCTED + 1)) {
501 Tlen = c.slen - (c.p - c.q);
502 if(!ASN1_const_check_infinite_end(&c.p, Tlen)) {
503 SSLerr(SSL_F_D2I_SSL_SESSION,
504 ERR_R_MISSING_ASN1_EOS);
505 goto err;
506 }
507 }
508 c.slen -= (c.p - c.q);
509 }
510 if (os.data != NULL) {
511 if (os.length > SSL_MAX_SID_CTX_LENGTH) {
512 SSLerr(SSL_F_D2I_SSL_SESSION, SSL_R_BAD_LENGTH);
513 goto err;
514 } else {
515 ret->sid_ctx_length = os.length;
516 memcpy(ret->sid_ctx, os.data, os.length);
517 }
518 free(os.data);
519 os.data = NULL;
520 os.length = 0;
521 } else
522 ret->sid_ctx_length = 0;
523
524 /* 5 - Verify_result. */
525 ai.length = 0;
526 if (c.slen != 0L &&
527 *c.p == (V_ASN1_CONSTRUCTED | V_ASN1_CONTEXT_SPECIFIC | 5)) {
528 c.q = c.p;
529 Tinf = ASN1_get_object(&c.p, &Tlen, &Ttag, &Tclass, c.slen);
530 if (Tinf & 0x80) {
531 SSLerr(SSL_F_D2I_SSL_SESSION,
532 ERR_R_BAD_ASN1_OBJECT_HEADER);
533 goto err;
534 }
535 if (Tinf == (V_ASN1_CONSTRUCTED + 1))
536 Tlen = c.slen - (c.p - c.q) - 2;
537 if (d2i_ASN1_INTEGER(&aip, &c.p, Tlen) == NULL) {
538 SSLerr(SSL_F_D2I_SSL_SESSION, ERR_R_NESTED_ASN1_ERROR);
539 goto err;
540 }
541 if (Tinf == (V_ASN1_CONSTRUCTED + 1)) {
542 Tlen = c.slen - (c.p - c.q);
543 if(!ASN1_const_check_infinite_end(&c.p, Tlen)) {
544 SSLerr(SSL_F_D2I_SSL_SESSION,
545 ERR_R_MISSING_ASN1_EOS);
546 goto err;
547 }
548 }
549 c.slen -= (c.p - c.q);
550 }
551 if (ai.data != NULL) {
552 ret->verify_result = ASN1_INTEGER_get(aip);
553 free(ai.data);
554 ai.data = NULL;
555 ai.length = 0;
556 } else
557 ret->verify_result = X509_V_OK;
558
559 /* 6 - HostName (OCTET STRING). */
560 os.length = 0;
561 os.data = NULL;
562 if (c.slen != 0L &&
563 *c.p == (V_ASN1_CONSTRUCTED | V_ASN1_CONTEXT_SPECIFIC | 6)) {
564 c.q = c.p;
565 Tinf = ASN1_get_object(&c.p, &Tlen, &Ttag, &Tclass, c.slen);
566 if (Tinf & 0x80) {
567 SSLerr(SSL_F_D2I_SSL_SESSION,
568 ERR_R_BAD_ASN1_OBJECT_HEADER);
569 goto err; 332 goto err;
570 } 333 if (data_len > UINT_MAX)
571 if (Tinf == (V_ASN1_CONSTRUCTED + 1))
572 Tlen = c.slen - (c.p - c.q) - 2;
573 if (d2i_ASN1_OCTET_STRING(&osp, &c.p, Tlen) == NULL) {
574 SSLerr(SSL_F_D2I_SSL_SESSION, ERR_R_NESTED_ASN1_ERROR);
575 goto err; 334 goto err;
576 } 335 s->sid_ctx_length = (unsigned int)data_len;
577 if (Tinf == (V_ASN1_CONSTRUCTED + 1)) {
578 Tlen = c.slen - (c.p - c.q);
579 if(!ASN1_const_check_infinite_end(&c.p, Tlen)) {
580 SSLerr(SSL_F_D2I_SSL_SESSION,
581 ERR_R_MISSING_ASN1_EOS);
582 goto err;
583 }
584 }
585 c.slen -= (c.p - c.q);
586 } 336 }
587 if (os.data) { 337
588 ret->tlsext_hostname = strndup((char *)os.data, os.length); 338 /* Verify result [5]. */
589 free(os.data); 339 s->verify_result = X509_V_OK;
590 os.data = NULL; 340 if (!CBS_get_optional_asn1_uint64(&session, &verify_result,
591 os.length = 0; 341 SSLASN1_VERIFY_RESULT_TAG, X509_V_OK))
592 } else 342 goto err;
593 ret->tlsext_hostname = NULL; 343 if (verify_result > LONG_MAX)
594 344 goto err;
595 /* 7 - PSK identity hint (OCTET STRING). */ 345 s->verify_result = (long)verify_result;
596 /* 8 - PSK identity (OCTET STRING). */ 346
597 347 /* Hostname [6]. */
598 /* 9 - Ticket lifetime. */ 348 free(s->tlsext_hostname);
599 ai.length = 0; 349 s->tlsext_hostname = NULL;
600 if (c.slen != 0L && 350 if (!CBS_get_optional_asn1_octet_string(&session, &hostname, &present,
601 *c.p == (V_ASN1_CONSTRUCTED | V_ASN1_CONTEXT_SPECIFIC | 9)) { 351 SSLASN1_HOSTNAME_TAG))
602 c.q = c.p; 352 goto err;
603 Tinf = ASN1_get_object(&c.p, &Tlen, &Ttag, &Tclass, c.slen); 353 if (present) {
604 if (Tinf & 0x80) { 354 if (CBS_contains_zero_byte(&hostname))
605 SSLerr(SSL_F_D2I_SSL_SESSION,
606 ERR_R_BAD_ASN1_OBJECT_HEADER);
607 goto err; 355 goto err;
608 } 356 if (!CBS_strdup(&hostname, &s->tlsext_hostname))
609 if (Tinf == (V_ASN1_CONSTRUCTED + 1))
610 Tlen = c.slen - (c.p - c.q) - 2;
611 if (d2i_ASN1_INTEGER(&aip, &c.p, Tlen) == NULL) {
612 SSLerr(SSL_F_D2I_SSL_SESSION, ERR_R_NESTED_ASN1_ERROR);
613 goto err; 357 goto err;
614 }
615 if (Tinf == (V_ASN1_CONSTRUCTED + 1)) {
616 Tlen = c.slen - (c.p - c.q);
617 if(!ASN1_const_check_infinite_end(&c.p, Tlen)) {
618 SSLerr(SSL_F_D2I_SSL_SESSION,
619 ERR_R_MISSING_ASN1_EOS);
620 goto err;
621 }
622 }
623 c.slen -= (c.p - c.q);
624 } 358 }
625 if (ai.data != NULL) { 359
626 ret->tlsext_tick_lifetime_hint = ASN1_INTEGER_get(aip); 360 /* PSK identity hint [7]. */
627 free(ai.data); 361 /* PSK identity [8]. */
628 ai.data = NULL; 362
629 ai.length = 0; 363 /* Ticket lifetime [9]. */
630 } else if (ret->tlsext_ticklen && ret->session_id_length) 364 s->tlsext_tick_lifetime_hint = 0;
631 ret->tlsext_tick_lifetime_hint = -1; 365 /* XXX - tlsext_ticklen is not yet set... */
632 else 366 if (s->tlsext_ticklen > 0 && s->session_id_length > 0)
633 ret->tlsext_tick_lifetime_hint = 0; 367 s->tlsext_tick_lifetime_hint = -1;
634 os.length = 0; 368 if (!CBS_get_optional_asn1_uint64(&session, &lifetime,
635 os.data = NULL; 369 SSLASN1_LIFETIME_TAG, 0))
636 370 goto err;
637 /* 10 - Ticket (OCTET STRING). */ 371 if (lifetime > LONG_MAX)
638 if (c.slen != 0L && 372 goto err;
639 *c.p == (V_ASN1_CONSTRUCTED | V_ASN1_CONTEXT_SPECIFIC | 10)) { 373 if (lifetime > 0)
640 c.q = c.p; 374 s->tlsext_tick_lifetime_hint = (long)lifetime;
641 Tinf = ASN1_get_object(&c.p, &Tlen, &Ttag, &Tclass, c.slen); 375
642 if (Tinf & 0x80) { 376 /* Ticket [10]. */
643 SSLerr(SSL_F_D2I_SSL_SESSION, 377 free(s->tlsext_tick);
644 ERR_R_BAD_ASN1_OBJECT_HEADER); 378 s->tlsext_tick = NULL;
645 goto err; 379 if (!CBS_get_optional_asn1_octet_string(&session, &ticket, &present,
646 } 380 SSLASN1_TICKET_TAG))
647 if (Tinf == (V_ASN1_CONSTRUCTED + 1)) 381 goto err;
648 Tlen = c.slen - (c.p - c.q) - 2; 382 if (present) {
649 if (d2i_ASN1_OCTET_STRING(&osp, &c.p, Tlen) == NULL) { 383 if (!CBS_stow(&ticket, &s->tlsext_tick, &s->tlsext_ticklen))
650 SSLerr(SSL_F_D2I_SSL_SESSION, ERR_R_NESTED_ASN1_ERROR);
651 goto err; 384 goto err;
652 }
653 if (Tinf == (V_ASN1_CONSTRUCTED + 1)) {
654 Tlen = c.slen - (c.p - c.q);
655 if(!ASN1_const_check_infinite_end(&c.p, Tlen)) {
656 SSLerr(SSL_F_D2I_SSL_SESSION,
657 ERR_R_MISSING_ASN1_EOS);
658 goto err;
659 }
660 }
661 c.slen -= (c.p - c.q);
662 } 385 }
663 if (os.data) {
664 ret->tlsext_tick = os.data;
665 ret->tlsext_ticklen = os.length;
666 os.data = NULL;
667 os.length = 0;
668 } else
669 ret->tlsext_tick = NULL;
670 386
671 /* 11 - Compression method (OCTET STRING). */ 387 /* Compression method [11]. */
672 /* 12 - SRP username (OCTET STRING). */ 388 /* SRP username [12]. */
673 389
674 if (!asn1_const_Finish(&c)) { 390 *pp = CBS_data(&cbs);
675 SSLerr(SSL_F_D2I_SSL_SESSION, ERR_R_NESTED_ASN1_ERROR);
676 goto err;
677 }
678 391
679 *pp = c.p;
680 if (a != NULL) 392 if (a != NULL)
681 *a = ret; 393 *a = s;
682 394
683 return (ret); 395 return (s);
684 396
685err: 397err:
686 ERR_asprintf_error_data("offset=%d", (int)(c.q - *pp)); 398 ERR_asprintf_error_data("offset=%d", (int)(CBS_data(&cbs) - *pp));
687 if (ret != NULL && (a == NULL || *a != ret)) 399
688 SSL_SESSION_free(ret); 400 if (s != NULL && (a == NULL || *a != s))
401 SSL_SESSION_free(s);
689 402
690 return (NULL); 403 return (NULL);
691} 404}