1 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2 * All rights reserved.
3 *
4 * This package is an SSL implementation written
5 * by Eric Young (eay@cryptsoft.com).
6 * The implementation was written so as to conform with Netscapes SSL.
7 *
8 * This library is free for commercial and non-commercial use as long as
9 * the following conditions are aheared to. The following conditions
10 * apply to all code found in this distribution, be it the RC4, RSA,
11 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
12 * included with this distribution is covered by the same copyright terms
13 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14 *
15 * Copyright remains Eric Young's, and as such any Copyright notices in
16 * the code are not to be removed.
17 * If this package is used in a product, Eric Young should be given attribution
18 * as the author of the parts of the library used.
19 * This can be in the form of a textual message at program startup or
20 * in documentation (online or textual) provided with the package.
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
25 * 1. Redistributions of source code must retain the copyright
26 * notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in the
29 * documentation and/or other materials provided with the distribution.
30 * 3. All advertising materials mentioning features or use of this software
31 * must display the following acknowledgement:
32 * "This product includes cryptographic software written by
33 * Eric Young (eay@cryptsoft.com)"
34 * The word 'cryptographic' can be left out if the rouines from the library
35 * being used are not cryptographic related :-).
36 * 4. If you include any Windows specific code (or a derivative thereof) from
37 * the apps directory (application code) you must include an acknowledgement:
38 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50 * SUCH DAMAGE.
51 *
52 * The licence and distribution terms for any publically available version or
53 * derivative of this code cannot be changed. i.e. this code cannot simply be
54 * copied and put under another distribution licence
55 * [including the GNU Public Licence.]
56 */
57 /* ====================================================================
58 * Copyright 2005 Nokia. All rights reserved.
59 *
60 * The portions of the attached software ("Contribution") is developed by
61 * Nokia Corporation and is licensed pursuant to the OpenSSL open source
62 * license.
63 *
64 * The Contribution, originally written by Mika Kousa and Pasi Eronen of
65 * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
66 * support (see RFC 4279) to OpenSSL.
67 *
68 * No patent licenses or other rights except those expressly stated in
69 * the OpenSSL open source license shall be deemed granted or received
70 * expressly, by implication, estoppel, or otherwise.
71 *
72 * No assurances are provided by Nokia that the Contribution does not
73 * infringe the patent or other intellectual property rights of any third
74 * party or that the license provides you with all the necessary rights
75 * to make use of the Contribution.
76 *
77 * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
78 * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
79 * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
80 * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
81 * OTHERWISE. */
82
83 #include <openssl/ssl.h>
84
85 #include <limits.h>
86 #include <string.h>
87
88 #include <openssl/buf.h>
89 #include <openssl/bytestring.h>
90 #include <openssl/err.h>
91 #include <openssl/mem.h>
92 #include <openssl/x509.h>
93
94 #include "../crypto/internal.h"
95 #include "internal.h"
96
97
98 /* An SSL_SESSION is serialized as the following ASN.1 structure:
99 *
100 * SSLSession ::= SEQUENCE {
101 * version INTEGER (1), -- session structure version
102 * sslVersion INTEGER, -- protocol version number
103 * cipher OCTET STRING, -- two bytes long
104 * sessionID OCTET STRING,
105 * masterKey OCTET STRING,
106 * time [1] INTEGER, -- seconds since UNIX epoch
107 * timeout [2] INTEGER, -- in seconds
108 * peer [3] Certificate OPTIONAL,
109 * sessionIDContext [4] OCTET STRING OPTIONAL,
110 * verifyResult [5] INTEGER OPTIONAL, -- one of X509_V_* codes
111 * hostName [6] OCTET STRING OPTIONAL,
112 * -- from server_name extension
113 * pskIdentity [8] OCTET STRING OPTIONAL,
114 * ticketLifetimeHint [9] INTEGER OPTIONAL, -- client-only
115 * ticket [10] OCTET STRING OPTIONAL, -- client-only
116 * peerSHA256 [13] OCTET STRING OPTIONAL,
117 * originalHandshakeHash [14] OCTET STRING OPTIONAL,
118 * signedCertTimestampList [15] OCTET STRING OPTIONAL,
119 * -- contents of SCT extension
120 * ocspResponse [16] OCTET STRING OPTIONAL,
121 * -- stapled OCSP response from the server
122 * extendedMasterSecret [17] BOOLEAN OPTIONAL,
123 * groupID [18] INTEGER OPTIONAL,
124 * -- For historical reasons, for legacy DHE or
125 * -- static RSA ciphers, this field contains
126 * -- another value to be discarded.
127 * certChain [19] SEQUENCE OF Certificate OPTIONAL,
128 * ticketAgeAdd [21] OCTET STRING OPTIONAL,
129 * isServer [22] BOOLEAN DEFAULT TRUE,
130 * peerSignatureAlgorithm [23] INTEGER OPTIONAL,
131 * ticketMaxEarlyData [24] INTEGER OPTIONAL,
132 * authTimeout [25] INTEGER OPTIONAL, -- defaults to timeout
133 * earlyALPN [26] OCTET STRING OPTIONAL,
134 * }
135 *
136 * Note: historically this serialization has included other optional
137 * fields. Their presence is currently treated as a parse error:
138 *
139 * keyArg [0] IMPLICIT OCTET STRING OPTIONAL,
140 * pskIdentityHint [7] OCTET STRING OPTIONAL,
141 * compressionMethod [11] OCTET STRING OPTIONAL,
142 * srpUsername [12] OCTET STRING OPTIONAL,
143 * ticketFlags [20] INTEGER OPTIONAL,
144 */
145
146 static const unsigned kVersion = 1;
147
148 static const int kTimeTag =
149 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 1;
150 static const int kTimeoutTag =
151 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 2;
152 static const int kPeerTag =
153 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 3;
154 static const int kSessionIDContextTag =
155 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 4;
156 static const int kVerifyResultTag =
157 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 5;
158 static const int kHostNameTag =
159 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 6;
160 static const int kPSKIdentityTag =
161 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 8;
162 static const int kTicketLifetimeHintTag =
163 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 9;
164 static const int kTicketTag =
165 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 10;
166 static const int kPeerSHA256Tag =
167 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 13;
168 static const int kOriginalHandshakeHashTag =
169 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 14;
170 static const int kSignedCertTimestampListTag =
171 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 15;
172 static const int kOCSPResponseTag =
173 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 16;
174 static const int kExtendedMasterSecretTag =
175 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 17;
176 static const int kGroupIDTag =
177 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 18;
178 static const int kCertChainTag =
179 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 19;
180 static const int kTicketAgeAddTag =
181 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 21;
182 static const int kIsServerTag =
183 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 22;
184 static const int kPeerSignatureAlgorithmTag =
185 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 23;
186 static const int kTicketMaxEarlyDataTag =
187 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 24;
188 static const int kAuthTimeoutTag =
189 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 25;
190 static const int kEarlyALPNTag =
191 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 26;
192
SSL_SESSION_to_bytes_full(const SSL_SESSION * in,uint8_t ** out_data,size_t * out_len,int for_ticket)193 static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, uint8_t **out_data,
194 size_t *out_len, int for_ticket) {
195 CBB cbb, session, child, child2;
196
197 if (in == NULL || in->cipher == NULL) {
198 return 0;
199 }
200
201 CBB_zero(&cbb);
202 if (!CBB_init(&cbb, 0) ||
203 !CBB_add_asn1(&cbb, &session, CBS_ASN1_SEQUENCE) ||
204 !CBB_add_asn1_uint64(&session, kVersion) ||
205 !CBB_add_asn1_uint64(&session, in->ssl_version) ||
206 !CBB_add_asn1(&session, &child, CBS_ASN1_OCTETSTRING) ||
207 !CBB_add_u16(&child, (uint16_t)(in->cipher->id & 0xffff)) ||
208 !CBB_add_asn1(&session, &child, CBS_ASN1_OCTETSTRING) ||
209 /* The session ID is irrelevant for a session ticket. */
210 !CBB_add_bytes(&child, in->session_id,
211 for_ticket ? 0 : in->session_id_length) ||
212 !CBB_add_asn1(&session, &child, CBS_ASN1_OCTETSTRING) ||
213 !CBB_add_bytes(&child, in->master_key, in->master_key_length) ||
214 !CBB_add_asn1(&session, &child, kTimeTag) ||
215 !CBB_add_asn1_uint64(&child, in->time) ||
216 !CBB_add_asn1(&session, &child, kTimeoutTag) ||
217 !CBB_add_asn1_uint64(&child, in->timeout)) {
218 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
219 goto err;
220 }
221
222 /* The peer certificate is only serialized if the SHA-256 isn't
223 * serialized instead. */
224 if (sk_CRYPTO_BUFFER_num(in->certs) > 0 && !in->peer_sha256_valid) {
225 const CRYPTO_BUFFER *buffer = sk_CRYPTO_BUFFER_value(in->certs, 0);
226 if (!CBB_add_asn1(&session, &child, kPeerTag) ||
227 !CBB_add_bytes(&child, CRYPTO_BUFFER_data(buffer),
228 CRYPTO_BUFFER_len(buffer))) {
229 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
230 goto err;
231 }
232 }
233
234 /* Although it is OPTIONAL and usually empty, OpenSSL has
235 * historically always encoded the sid_ctx. */
236 if (!CBB_add_asn1(&session, &child, kSessionIDContextTag) ||
237 !CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) ||
238 !CBB_add_bytes(&child2, in->sid_ctx, in->sid_ctx_length)) {
239 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
240 goto err;
241 }
242
243 if (in->verify_result != X509_V_OK) {
244 if (!CBB_add_asn1(&session, &child, kVerifyResultTag) ||
245 !CBB_add_asn1_uint64(&child, in->verify_result)) {
246 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
247 goto err;
248 }
249 }
250
251 if (in->tlsext_hostname) {
252 if (!CBB_add_asn1(&session, &child, kHostNameTag) ||
253 !CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) ||
254 !CBB_add_bytes(&child2, (const uint8_t *)in->tlsext_hostname,
255 strlen(in->tlsext_hostname))) {
256 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
257 goto err;
258 }
259 }
260
261 if (in->psk_identity) {
262 if (!CBB_add_asn1(&session, &child, kPSKIdentityTag) ||
263 !CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) ||
264 !CBB_add_bytes(&child2, (const uint8_t *)in->psk_identity,
265 strlen(in->psk_identity))) {
266 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
267 goto err;
268 }
269 }
270
271 if (in->tlsext_tick_lifetime_hint > 0) {
272 if (!CBB_add_asn1(&session, &child, kTicketLifetimeHintTag) ||
273 !CBB_add_asn1_uint64(&child, in->tlsext_tick_lifetime_hint)) {
274 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
275 goto err;
276 }
277 }
278
279 if (in->tlsext_tick && !for_ticket) {
280 if (!CBB_add_asn1(&session, &child, kTicketTag) ||
281 !CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) ||
282 !CBB_add_bytes(&child2, in->tlsext_tick, in->tlsext_ticklen)) {
283 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
284 goto err;
285 }
286 }
287
288 if (in->peer_sha256_valid) {
289 if (!CBB_add_asn1(&session, &child, kPeerSHA256Tag) ||
290 !CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) ||
291 !CBB_add_bytes(&child2, in->peer_sha256, sizeof(in->peer_sha256))) {
292 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
293 goto err;
294 }
295 }
296
297 if (in->original_handshake_hash_len > 0) {
298 if (!CBB_add_asn1(&session, &child, kOriginalHandshakeHashTag) ||
299 !CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) ||
300 !CBB_add_bytes(&child2, in->original_handshake_hash,
301 in->original_handshake_hash_len)) {
302 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
303 goto err;
304 }
305 }
306
307 if (in->tlsext_signed_cert_timestamp_list_length > 0) {
308 if (!CBB_add_asn1(&session, &child, kSignedCertTimestampListTag) ||
309 !CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) ||
310 !CBB_add_bytes(&child2, in->tlsext_signed_cert_timestamp_list,
311 in->tlsext_signed_cert_timestamp_list_length)) {
312 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
313 goto err;
314 }
315 }
316
317 if (in->ocsp_response_length > 0) {
318 if (!CBB_add_asn1(&session, &child, kOCSPResponseTag) ||
319 !CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) ||
320 !CBB_add_bytes(&child2, in->ocsp_response, in->ocsp_response_length)) {
321 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
322 goto err;
323 }
324 }
325
326 if (in->extended_master_secret) {
327 if (!CBB_add_asn1(&session, &child, kExtendedMasterSecretTag) ||
328 !CBB_add_asn1(&child, &child2, CBS_ASN1_BOOLEAN) ||
329 !CBB_add_u8(&child2, 0xff)) {
330 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
331 goto err;
332 }
333 }
334
335 if (in->group_id > 0 &&
336 (!CBB_add_asn1(&session, &child, kGroupIDTag) ||
337 !CBB_add_asn1_uint64(&child, in->group_id))) {
338 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
339 goto err;
340 }
341
342 /* The certificate chain is only serialized if the leaf's SHA-256 isn't
343 * serialized instead. */
344 if (in->certs != NULL &&
345 !in->peer_sha256_valid &&
346 sk_CRYPTO_BUFFER_num(in->certs) >= 2) {
347 if (!CBB_add_asn1(&session, &child, kCertChainTag)) {
348 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
349 goto err;
350 }
351 for (size_t i = 1; i < sk_CRYPTO_BUFFER_num(in->certs); i++) {
352 const CRYPTO_BUFFER *buffer = sk_CRYPTO_BUFFER_value(in->certs, i);
353 if (!CBB_add_bytes(&child, CRYPTO_BUFFER_data(buffer),
354 CRYPTO_BUFFER_len(buffer))) {
355 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
356 goto err;
357 }
358 }
359 }
360
361 if (in->ticket_age_add_valid) {
362 if (!CBB_add_asn1(&session, &child, kTicketAgeAddTag) ||
363 !CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) ||
364 !CBB_add_u32(&child2, in->ticket_age_add)) {
365 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
366 goto err;
367 }
368 }
369
370 if (!in->is_server) {
371 if (!CBB_add_asn1(&session, &child, kIsServerTag) ||
372 !CBB_add_asn1(&child, &child2, CBS_ASN1_BOOLEAN) ||
373 !CBB_add_u8(&child2, 0x00)) {
374 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
375 goto err;
376 }
377 }
378
379 if (in->peer_signature_algorithm != 0 &&
380 (!CBB_add_asn1(&session, &child, kPeerSignatureAlgorithmTag) ||
381 !CBB_add_asn1_uint64(&child, in->peer_signature_algorithm))) {
382 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
383 goto err;
384 }
385
386 if (in->ticket_max_early_data != 0 &&
387 (!CBB_add_asn1(&session, &child, kTicketMaxEarlyDataTag) ||
388 !CBB_add_asn1_uint64(&child, in->ticket_max_early_data))) {
389 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
390 goto err;
391 }
392
393 if (in->timeout != in->auth_timeout &&
394 (!CBB_add_asn1(&session, &child, kAuthTimeoutTag) ||
395 !CBB_add_asn1_uint64(&child, in->auth_timeout))) {
396 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
397 goto err;
398 }
399
400 if (in->early_alpn) {
401 if (!CBB_add_asn1(&session, &child, kEarlyALPNTag) ||
402 !CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) ||
403 !CBB_add_bytes(&child2, (const uint8_t *)in->early_alpn,
404 in->early_alpn_len)) {
405 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
406 goto err;
407 }
408 }
409
410 if (!CBB_finish(&cbb, out_data, out_len)) {
411 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
412 goto err;
413 }
414 return 1;
415
416 err:
417 CBB_cleanup(&cbb);
418 return 0;
419 }
420
SSL_SESSION_to_bytes(const SSL_SESSION * in,uint8_t ** out_data,size_t * out_len)421 int SSL_SESSION_to_bytes(const SSL_SESSION *in, uint8_t **out_data,
422 size_t *out_len) {
423 if (in->not_resumable) {
424 /* If the caller has an unresumable session, e.g. if |SSL_get_session| were
425 * called on a TLS 1.3 or False Started connection, serialize with a
426 * placeholder value so it is not accidentally deserialized into a resumable
427 * one. */
428 static const char kNotResumableSession[] = "NOT RESUMABLE";
429
430 *out_len = strlen(kNotResumableSession);
431 *out_data = BUF_memdup(kNotResumableSession, *out_len);
432 if (*out_data == NULL) {
433 return 0;
434 }
435
436 return 1;
437 }
438
439 return SSL_SESSION_to_bytes_full(in, out_data, out_len, 0);
440 }
441
SSL_SESSION_to_bytes_for_ticket(const SSL_SESSION * in,uint8_t ** out_data,size_t * out_len)442 int SSL_SESSION_to_bytes_for_ticket(const SSL_SESSION *in, uint8_t **out_data,
443 size_t *out_len) {
444 return SSL_SESSION_to_bytes_full(in, out_data, out_len, 1);
445 }
446
i2d_SSL_SESSION(SSL_SESSION * in,uint8_t ** pp)447 int i2d_SSL_SESSION(SSL_SESSION *in, uint8_t **pp) {
448 uint8_t *out;
449 size_t len;
450
451 if (!SSL_SESSION_to_bytes(in, &out, &len)) {
452 return -1;
453 }
454
455 if (len > INT_MAX) {
456 OPENSSL_free(out);
457 OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
458 return -1;
459 }
460
461 if (pp) {
462 OPENSSL_memcpy(*pp, out, len);
463 *pp += len;
464 }
465 OPENSSL_free(out);
466
467 return len;
468 }
469
470 /* SSL_SESSION_parse_string gets an optional ASN.1 OCTET STRING
471 * explicitly tagged with |tag| from |cbs| and saves it in |*out|. On
472 * entry, if |*out| is not NULL, it frees the existing contents. If
473 * the element was not found, it sets |*out| to NULL. It returns one
474 * on success, whether or not the element was found, and zero on
475 * decode error. */
SSL_SESSION_parse_string(CBS * cbs,char ** out,unsigned tag)476 static int SSL_SESSION_parse_string(CBS *cbs, char **out, unsigned tag) {
477 CBS value;
478 int present;
479 if (!CBS_get_optional_asn1_octet_string(cbs, &value, &present, tag)) {
480 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
481 return 0;
482 }
483 if (present) {
484 if (CBS_contains_zero_byte(&value)) {
485 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
486 return 0;
487 }
488 if (!CBS_strdup(&value, out)) {
489 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
490 return 0;
491 }
492 } else {
493 OPENSSL_free(*out);
494 *out = NULL;
495 }
496 return 1;
497 }
498
499 /* SSL_SESSION_parse_string gets an optional ASN.1 OCTET STRING
500 * explicitly tagged with |tag| from |cbs| and stows it in |*out_ptr|
501 * and |*out_len|. If |*out_ptr| is not NULL, it frees the existing
502 * contents. On entry, if the element was not found, it sets
503 * |*out_ptr| to NULL. It returns one on success, whether or not the
504 * element was found, and zero on decode error. */
SSL_SESSION_parse_octet_string(CBS * cbs,uint8_t ** out_ptr,size_t * out_len,unsigned tag)505 static int SSL_SESSION_parse_octet_string(CBS *cbs, uint8_t **out_ptr,
506 size_t *out_len, unsigned tag) {
507 CBS value;
508 if (!CBS_get_optional_asn1_octet_string(cbs, &value, NULL, tag)) {
509 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
510 return 0;
511 }
512 if (!CBS_stow(&value, out_ptr, out_len)) {
513 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
514 return 0;
515 }
516 return 1;
517 }
518
519 /* SSL_SESSION_parse_bounded_octet_string parses an optional ASN.1 OCTET STRING
520 * explicitly tagged with |tag| of size at most |max_out|. */
SSL_SESSION_parse_bounded_octet_string(CBS * cbs,uint8_t * out,uint8_t * out_len,uint8_t max_out,unsigned tag)521 static int SSL_SESSION_parse_bounded_octet_string(
522 CBS *cbs, uint8_t *out, uint8_t *out_len, uint8_t max_out, unsigned tag) {
523 CBS value;
524 if (!CBS_get_optional_asn1_octet_string(cbs, &value, NULL, tag) ||
525 CBS_len(&value) > max_out) {
526 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
527 return 0;
528 }
529 OPENSSL_memcpy(out, CBS_data(&value), CBS_len(&value));
530 *out_len = (uint8_t)CBS_len(&value);
531 return 1;
532 }
533
SSL_SESSION_parse_long(CBS * cbs,long * out,unsigned tag,long default_value)534 static int SSL_SESSION_parse_long(CBS *cbs, long *out, unsigned tag,
535 long default_value) {
536 uint64_t value;
537 if (!CBS_get_optional_asn1_uint64(cbs, &value, tag,
538 (uint64_t)default_value) ||
539 value > LONG_MAX) {
540 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
541 return 0;
542 }
543 *out = (long)value;
544 return 1;
545 }
546
SSL_SESSION_parse_u32(CBS * cbs,uint32_t * out,unsigned tag,uint32_t default_value)547 static int SSL_SESSION_parse_u32(CBS *cbs, uint32_t *out, unsigned tag,
548 uint32_t default_value) {
549 uint64_t value;
550 if (!CBS_get_optional_asn1_uint64(cbs, &value, tag,
551 (uint64_t)default_value) ||
552 value > 0xffffffff) {
553 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
554 return 0;
555 }
556 *out = (uint32_t)value;
557 return 1;
558 }
559
SSL_SESSION_parse_u16(CBS * cbs,uint16_t * out,unsigned tag,uint16_t default_value)560 static int SSL_SESSION_parse_u16(CBS *cbs, uint16_t *out, unsigned tag,
561 uint16_t default_value) {
562 uint64_t value;
563 if (!CBS_get_optional_asn1_uint64(cbs, &value, tag,
564 (uint64_t)default_value) ||
565 value > 0xffff) {
566 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
567 return 0;
568 }
569 *out = (uint16_t)value;
570 return 1;
571 }
572
SSL_SESSION_parse(CBS * cbs,const SSL_X509_METHOD * x509_method,CRYPTO_BUFFER_POOL * pool)573 SSL_SESSION *SSL_SESSION_parse(CBS *cbs, const SSL_X509_METHOD *x509_method,
574 CRYPTO_BUFFER_POOL *pool) {
575 SSL_SESSION *ret = ssl_session_new(x509_method);
576 if (ret == NULL) {
577 goto err;
578 }
579
580 CBS session;
581 uint64_t version, ssl_version;
582 if (!CBS_get_asn1(cbs, &session, CBS_ASN1_SEQUENCE) ||
583 !CBS_get_asn1_uint64(&session, &version) ||
584 version != kVersion ||
585 !CBS_get_asn1_uint64(&session, &ssl_version)) {
586 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
587 goto err;
588 }
589 ret->ssl_version = ssl_version;
590
591 CBS cipher;
592 uint16_t cipher_value;
593 if (!CBS_get_asn1(&session, &cipher, CBS_ASN1_OCTETSTRING) ||
594 !CBS_get_u16(&cipher, &cipher_value) ||
595 CBS_len(&cipher) != 0) {
596 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
597 goto err;
598 }
599 ret->cipher = SSL_get_cipher_by_value(cipher_value);
600 if (ret->cipher == NULL) {
601 OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_CIPHER);
602 goto err;
603 }
604
605 CBS session_id, master_key;
606 if (!CBS_get_asn1(&session, &session_id, CBS_ASN1_OCTETSTRING) ||
607 CBS_len(&session_id) > SSL3_MAX_SSL_SESSION_ID_LENGTH ||
608 !CBS_get_asn1(&session, &master_key, CBS_ASN1_OCTETSTRING) ||
609 CBS_len(&master_key) > SSL_MAX_MASTER_KEY_LENGTH) {
610 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
611 goto err;
612 }
613 OPENSSL_memcpy(ret->session_id, CBS_data(&session_id), CBS_len(&session_id));
614 ret->session_id_length = CBS_len(&session_id);
615 OPENSSL_memcpy(ret->master_key, CBS_data(&master_key), CBS_len(&master_key));
616 ret->master_key_length = CBS_len(&master_key);
617
618 CBS child;
619 uint64_t timeout;
620 if (!CBS_get_asn1(&session, &child, kTimeTag) ||
621 !CBS_get_asn1_uint64(&child, &ret->time) ||
622 !CBS_get_asn1(&session, &child, kTimeoutTag) ||
623 !CBS_get_asn1_uint64(&child, &timeout) ||
624 timeout > UINT32_MAX) {
625 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
626 goto err;
627 }
628
629 ret->timeout = (uint32_t)timeout;
630
631 CBS peer;
632 int has_peer;
633 if (!CBS_get_optional_asn1(&session, &peer, &has_peer, kPeerTag) ||
634 (has_peer && CBS_len(&peer) == 0)) {
635 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
636 goto err;
637 }
638 /* |peer| is processed with the certificate chain. */
639
640 if (!SSL_SESSION_parse_bounded_octet_string(
641 &session, ret->sid_ctx, &ret->sid_ctx_length, sizeof(ret->sid_ctx),
642 kSessionIDContextTag) ||
643 !SSL_SESSION_parse_long(&session, &ret->verify_result, kVerifyResultTag,
644 X509_V_OK) ||
645 !SSL_SESSION_parse_string(&session, &ret->tlsext_hostname,
646 kHostNameTag) ||
647 !SSL_SESSION_parse_string(&session, &ret->psk_identity,
648 kPSKIdentityTag) ||
649 !SSL_SESSION_parse_u32(&session, &ret->tlsext_tick_lifetime_hint,
650 kTicketLifetimeHintTag, 0) ||
651 !SSL_SESSION_parse_octet_string(&session, &ret->tlsext_tick,
652 &ret->tlsext_ticklen, kTicketTag)) {
653 goto err;
654 }
655
656 if (CBS_peek_asn1_tag(&session, kPeerSHA256Tag)) {
657 CBS peer_sha256;
658 if (!CBS_get_asn1(&session, &child, kPeerSHA256Tag) ||
659 !CBS_get_asn1(&child, &peer_sha256, CBS_ASN1_OCTETSTRING) ||
660 CBS_len(&peer_sha256) != sizeof(ret->peer_sha256) ||
661 CBS_len(&child) != 0) {
662 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
663 goto err;
664 }
665 OPENSSL_memcpy(ret->peer_sha256, CBS_data(&peer_sha256),
666 sizeof(ret->peer_sha256));
667 ret->peer_sha256_valid = 1;
668 } else {
669 ret->peer_sha256_valid = 0;
670 }
671
672 if (!SSL_SESSION_parse_bounded_octet_string(
673 &session, ret->original_handshake_hash,
674 &ret->original_handshake_hash_len,
675 sizeof(ret->original_handshake_hash), kOriginalHandshakeHashTag) ||
676 !SSL_SESSION_parse_octet_string(
677 &session, &ret->tlsext_signed_cert_timestamp_list,
678 &ret->tlsext_signed_cert_timestamp_list_length,
679 kSignedCertTimestampListTag) ||
680 !SSL_SESSION_parse_octet_string(
681 &session, &ret->ocsp_response, &ret->ocsp_response_length,
682 kOCSPResponseTag)) {
683 goto err;
684 }
685
686 int extended_master_secret;
687 if (!CBS_get_optional_asn1_bool(&session, &extended_master_secret,
688 kExtendedMasterSecretTag,
689 0 /* default to false */)) {
690 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
691 goto err;
692 }
693 ret->extended_master_secret = !!extended_master_secret;
694
695 uint32_t value;
696 if (!SSL_SESSION_parse_u32(&session, &value, kGroupIDTag, 0)) {
697 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
698 goto err;
699 }
700
701 /* Historically, the group_id field was used for key-exchange-specific
702 * information. Discard all but the group ID. */
703 if (ret->cipher->algorithm_mkey & (SSL_kRSA | SSL_kDHE)) {
704 value = 0;
705 }
706
707 if (value > 0xffff) {
708 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
709 goto err;
710 }
711 ret->group_id = (uint16_t)value;
712
713 CBS cert_chain;
714 CBS_init(&cert_chain, NULL, 0);
715 int has_cert_chain;
716 if (!CBS_get_optional_asn1(&session, &cert_chain, &has_cert_chain,
717 kCertChainTag) ||
718 (has_cert_chain && CBS_len(&cert_chain) == 0)) {
719 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
720 goto err;
721 }
722 if (has_cert_chain && !has_peer) {
723 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
724 goto err;
725 }
726 if (has_peer || has_cert_chain) {
727 ret->certs = sk_CRYPTO_BUFFER_new_null();
728 if (ret->certs == NULL) {
729 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
730 goto err;
731 }
732
733 if (has_peer) {
734 /* TODO(agl): this should use the |SSL_CTX|'s pool. */
735 CRYPTO_BUFFER *buffer = CRYPTO_BUFFER_new_from_CBS(&peer, pool);
736 if (buffer == NULL ||
737 !sk_CRYPTO_BUFFER_push(ret->certs, buffer)) {
738 CRYPTO_BUFFER_free(buffer);
739 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
740 goto err;
741 }
742 }
743
744 while (CBS_len(&cert_chain) > 0) {
745 CBS cert;
746 if (!CBS_get_any_asn1_element(&cert_chain, &cert, NULL, NULL) ||
747 CBS_len(&cert) == 0) {
748 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
749 goto err;
750 }
751
752 /* TODO(agl): this should use the |SSL_CTX|'s pool. */
753 CRYPTO_BUFFER *buffer = CRYPTO_BUFFER_new_from_CBS(&cert, pool);
754 if (buffer == NULL ||
755 !sk_CRYPTO_BUFFER_push(ret->certs, buffer)) {
756 CRYPTO_BUFFER_free(buffer);
757 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
758 goto err;
759 }
760 }
761 }
762
763 if (!x509_method->session_cache_objects(ret)) {
764 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
765 goto err;
766 }
767
768 CBS age_add;
769 int age_add_present;
770 if (!CBS_get_optional_asn1_octet_string(&session, &age_add, &age_add_present,
771 kTicketAgeAddTag) ||
772 (age_add_present &&
773 !CBS_get_u32(&age_add, &ret->ticket_age_add)) ||
774 CBS_len(&age_add) != 0) {
775 goto err;
776 }
777 ret->ticket_age_add_valid = age_add_present;
778
779 int is_server;
780 if (!CBS_get_optional_asn1_bool(&session, &is_server, kIsServerTag,
781 1 /* default to true */)) {
782 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
783 goto err;
784 }
785 /* TODO: in time we can include |is_server| for servers too, then we can
786 enforce that client and server sessions are never mixed up. */
787
788 ret->is_server = is_server;
789
790 if (!SSL_SESSION_parse_u16(&session, &ret->peer_signature_algorithm,
791 kPeerSignatureAlgorithmTag, 0) ||
792 !SSL_SESSION_parse_u32(&session, &ret->ticket_max_early_data,
793 kTicketMaxEarlyDataTag, 0) ||
794 !SSL_SESSION_parse_u32(&session, &ret->auth_timeout, kAuthTimeoutTag,
795 ret->timeout) ||
796 !SSL_SESSION_parse_octet_string(&session, &ret->early_alpn,
797 &ret->early_alpn_len, kEarlyALPNTag) ||
798 CBS_len(&session) != 0) {
799 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
800 goto err;
801 }
802
803 return ret;
804
805 err:
806 SSL_SESSION_free(ret);
807 return NULL;
808 }
809
SSL_SESSION_from_bytes(const uint8_t * in,size_t in_len,const SSL_CTX * ctx)810 SSL_SESSION *SSL_SESSION_from_bytes(const uint8_t *in, size_t in_len,
811 const SSL_CTX *ctx) {
812 CBS cbs;
813 CBS_init(&cbs, in, in_len);
814 SSL_SESSION *ret = SSL_SESSION_parse(&cbs, ctx->x509_method, ctx->pool);
815 if (ret == NULL) {
816 return NULL;
817 }
818 if (CBS_len(&cbs) != 0) {
819 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
820 SSL_SESSION_free(ret);
821 return NULL;
822 }
823 return ret;
824 }
825