1 /*
2 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
3 * Copyright 2005 Nokia. All rights reserved.
4 *
5 * Licensed under the OpenSSL license (the "License"). You may not use
6 * this file except in compliance with the License. You can obtain a copy
7 * in the file LICENSE in the source distribution or at
8 * https://www.openssl.org/source/license.html
9 */
10
11 #include <openssl/ssl.h>
12
13 #include <limits.h>
14 #include <string.h>
15
16 #include <utility>
17
18 #include <openssl/bytestring.h>
19 #include <openssl/err.h>
20 #include <openssl/mem.h>
21 #include <openssl/x509.h>
22
23 #include "../crypto/internal.h"
24 #include "internal.h"
25
26
27 BSSL_NAMESPACE_BEGIN
28
29 // An SSL_SESSION is serialized as the following ASN.1 structure:
30 //
31 // SSLSession ::= SEQUENCE {
32 // version INTEGER (1), -- session structure version
33 // sslVersion INTEGER, -- protocol version number
34 // cipher OCTET STRING, -- two bytes long
35 // sessionID OCTET STRING,
36 // secret OCTET STRING,
37 // time [1] INTEGER, -- seconds since UNIX epoch
38 // timeout [2] INTEGER, -- in seconds
39 // peer [3] Certificate OPTIONAL,
40 // sessionIDContext [4] OCTET STRING OPTIONAL,
41 // verifyResult [5] INTEGER OPTIONAL, -- one of X509_V_* codes
42 // pskIdentity [8] OCTET STRING OPTIONAL,
43 // ticketLifetimeHint [9] INTEGER OPTIONAL, -- client-only
44 // ticket [10] OCTET STRING OPTIONAL, -- client-only
45 // peerSHA256 [13] OCTET STRING OPTIONAL,
46 // originalHandshakeHash [14] OCTET STRING OPTIONAL,
47 // signedCertTimestampList [15] OCTET STRING OPTIONAL,
48 // -- contents of SCT extension
49 // ocspResponse [16] OCTET STRING OPTIONAL,
50 // -- stapled OCSP response from the server
51 // extendedMasterSecret [17] BOOLEAN OPTIONAL,
52 // groupID [18] INTEGER OPTIONAL,
53 // certChain [19] SEQUENCE OF Certificate OPTIONAL,
54 // ticketAgeAdd [21] OCTET STRING OPTIONAL,
55 // isServer [22] BOOLEAN DEFAULT TRUE,
56 // peerSignatureAlgorithm [23] INTEGER OPTIONAL,
57 // ticketMaxEarlyData [24] INTEGER OPTIONAL,
58 // authTimeout [25] INTEGER OPTIONAL, -- defaults to timeout
59 // earlyALPN [26] OCTET STRING OPTIONAL,
60 // isQuic [27] BOOLEAN OPTIONAL,
61 // quicEarlyDataHash [28] OCTET STRING OPTIONAL,
62 // localALPS [29] OCTET STRING OPTIONAL,
63 // peerALPS [30] OCTET STRING OPTIONAL,
64 // -- Either both or none of localALPS and peerALPS must be present. If both
65 // -- are present, earlyALPN must be present and non-empty.
66 // }
67 //
68 // Note: historically this serialization has included other optional
69 // fields. Their presence is currently treated as a parse error, except for
70 // hostName, which is ignored.
71 //
72 // keyArg [0] IMPLICIT OCTET STRING OPTIONAL,
73 // hostName [6] OCTET STRING OPTIONAL,
74 // pskIdentityHint [7] OCTET STRING OPTIONAL,
75 // compressionMethod [11] OCTET STRING OPTIONAL,
76 // srpUsername [12] OCTET STRING OPTIONAL,
77 // ticketFlags [20] INTEGER OPTIONAL,
78
79 static const unsigned kVersion = 1;
80
81 static const CBS_ASN1_TAG kTimeTag =
82 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 1;
83 static const CBS_ASN1_TAG kTimeoutTag =
84 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 2;
85 static const CBS_ASN1_TAG kPeerTag =
86 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 3;
87 static const CBS_ASN1_TAG kSessionIDContextTag =
88 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 4;
89 static const CBS_ASN1_TAG kVerifyResultTag =
90 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 5;
91 static const CBS_ASN1_TAG kHostNameTag =
92 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 6;
93 static const CBS_ASN1_TAG kPSKIdentityTag =
94 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 8;
95 static const CBS_ASN1_TAG kTicketLifetimeHintTag =
96 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 9;
97 static const CBS_ASN1_TAG kTicketTag =
98 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 10;
99 static const CBS_ASN1_TAG kPeerSHA256Tag =
100 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 13;
101 static const CBS_ASN1_TAG kOriginalHandshakeHashTag =
102 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 14;
103 static const CBS_ASN1_TAG kSignedCertTimestampListTag =
104 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 15;
105 static const CBS_ASN1_TAG kOCSPResponseTag =
106 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 16;
107 static const CBS_ASN1_TAG kExtendedMasterSecretTag =
108 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 17;
109 static const CBS_ASN1_TAG kGroupIDTag =
110 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 18;
111 static const CBS_ASN1_TAG kCertChainTag =
112 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 19;
113 static const CBS_ASN1_TAG kTicketAgeAddTag =
114 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 21;
115 static const CBS_ASN1_TAG kIsServerTag =
116 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 22;
117 static const CBS_ASN1_TAG kPeerSignatureAlgorithmTag =
118 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 23;
119 static const CBS_ASN1_TAG kTicketMaxEarlyDataTag =
120 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 24;
121 static const CBS_ASN1_TAG kAuthTimeoutTag =
122 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 25;
123 static const CBS_ASN1_TAG kEarlyALPNTag =
124 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 26;
125 static const CBS_ASN1_TAG kIsQuicTag =
126 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 27;
127 static const CBS_ASN1_TAG kQuicEarlyDataContextTag =
128 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 28;
129 static const CBS_ASN1_TAG kLocalALPSTag =
130 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 29;
131 static const CBS_ASN1_TAG kPeerALPSTag =
132 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 30;
133
SSL_SESSION_to_bytes_full(const SSL_SESSION * in,CBB * cbb,int for_ticket)134 static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb,
135 int for_ticket) {
136 if (in == NULL || in->cipher == NULL) {
137 return 0;
138 }
139
140 CBB session, child, child2;
141 if (!CBB_add_asn1(cbb, &session, CBS_ASN1_SEQUENCE) ||
142 !CBB_add_asn1_uint64(&session, kVersion) ||
143 !CBB_add_asn1_uint64(&session, in->ssl_version) ||
144 !CBB_add_asn1(&session, &child, CBS_ASN1_OCTETSTRING) ||
145 !CBB_add_u16(&child, (uint16_t)(in->cipher->id & 0xffff)) ||
146 // The session ID is irrelevant for a session ticket.
147 !CBB_add_asn1_octet_string(&session, in->session_id.data(),
148 for_ticket ? 0 : in->session_id.size()) ||
149 !CBB_add_asn1_octet_string(&session, in->secret.data(),
150 in->secret.size()) ||
151 !CBB_add_asn1(&session, &child, kTimeTag) ||
152 !CBB_add_asn1_uint64(&child, in->time) ||
153 !CBB_add_asn1(&session, &child, kTimeoutTag) ||
154 !CBB_add_asn1_uint64(&child, in->timeout)) {
155 return 0;
156 }
157
158 // The peer certificate is only serialized if the SHA-256 isn't
159 // serialized instead.
160 if (sk_CRYPTO_BUFFER_num(in->certs.get()) > 0 && !in->peer_sha256_valid) {
161 const CRYPTO_BUFFER *buffer = sk_CRYPTO_BUFFER_value(in->certs.get(), 0);
162 if (!CBB_add_asn1(&session, &child, kPeerTag) ||
163 !CBB_add_bytes(&child, CRYPTO_BUFFER_data(buffer),
164 CRYPTO_BUFFER_len(buffer))) {
165 return 0;
166 }
167 }
168
169 // Although it is OPTIONAL and usually empty, OpenSSL has
170 // historically always encoded the sid_ctx.
171 if (!CBB_add_asn1(&session, &child, kSessionIDContextTag) ||
172 !CBB_add_asn1_octet_string(&child, in->sid_ctx.data(),
173 in->sid_ctx.size())) {
174 return 0;
175 }
176
177 if (in->verify_result != X509_V_OK) {
178 if (!CBB_add_asn1(&session, &child, kVerifyResultTag) ||
179 !CBB_add_asn1_uint64(&child, in->verify_result)) {
180 return 0;
181 }
182 }
183
184 if (in->psk_identity) {
185 if (!CBB_add_asn1(&session, &child, kPSKIdentityTag) ||
186 !CBB_add_asn1_octet_string(&child,
187 (const uint8_t *)in->psk_identity.get(),
188 strlen(in->psk_identity.get()))) {
189 return 0;
190 }
191 }
192
193 if (in->ticket_lifetime_hint > 0) {
194 if (!CBB_add_asn1(&session, &child, kTicketLifetimeHintTag) ||
195 !CBB_add_asn1_uint64(&child, in->ticket_lifetime_hint)) {
196 return 0;
197 }
198 }
199
200 if (!in->ticket.empty() && !for_ticket) {
201 if (!CBB_add_asn1(&session, &child, kTicketTag) ||
202 !CBB_add_asn1_octet_string(&child, in->ticket.data(),
203 in->ticket.size())) {
204 return 0;
205 }
206 }
207
208 if (in->peer_sha256_valid) {
209 if (!CBB_add_asn1(&session, &child, kPeerSHA256Tag) ||
210 !CBB_add_asn1_octet_string(&child, in->peer_sha256,
211 sizeof(in->peer_sha256))) {
212 return 0;
213 }
214 }
215
216 if (!in->original_handshake_hash.empty()) {
217 if (!CBB_add_asn1(&session, &child, kOriginalHandshakeHashTag) ||
218 !CBB_add_asn1_octet_string(&child, in->original_handshake_hash.data(),
219 in->original_handshake_hash.size())) {
220 return 0;
221 }
222 }
223
224 if (in->signed_cert_timestamp_list != nullptr) {
225 if (!CBB_add_asn1(&session, &child, kSignedCertTimestampListTag) ||
226 !CBB_add_asn1_octet_string(
227 &child, CRYPTO_BUFFER_data(in->signed_cert_timestamp_list.get()),
228 CRYPTO_BUFFER_len(in->signed_cert_timestamp_list.get()))) {
229 return 0;
230 }
231 }
232
233 if (in->ocsp_response != nullptr) {
234 if (!CBB_add_asn1(&session, &child, kOCSPResponseTag) ||
235 !CBB_add_asn1_octet_string(
236 &child, CRYPTO_BUFFER_data(in->ocsp_response.get()),
237 CRYPTO_BUFFER_len(in->ocsp_response.get()))) {
238 return 0;
239 }
240 }
241
242 if (in->extended_master_secret) {
243 if (!CBB_add_asn1(&session, &child, kExtendedMasterSecretTag) ||
244 !CBB_add_asn1_bool(&child, true)) {
245 return 0;
246 }
247 }
248
249 if (in->group_id > 0 && //
250 (!CBB_add_asn1(&session, &child, kGroupIDTag) || //
251 !CBB_add_asn1_uint64(&child, in->group_id))) {
252 return 0;
253 }
254
255 // The certificate chain is only serialized if the leaf's SHA-256 isn't
256 // serialized instead.
257 if (in->certs != NULL && //
258 !in->peer_sha256_valid && //
259 sk_CRYPTO_BUFFER_num(in->certs.get()) >= 2) {
260 if (!CBB_add_asn1(&session, &child, kCertChainTag)) {
261 return 0;
262 }
263 for (size_t i = 1; i < sk_CRYPTO_BUFFER_num(in->certs.get()); i++) {
264 const CRYPTO_BUFFER *buffer = sk_CRYPTO_BUFFER_value(in->certs.get(), i);
265 if (!CBB_add_bytes(&child, CRYPTO_BUFFER_data(buffer),
266 CRYPTO_BUFFER_len(buffer))) {
267 return 0;
268 }
269 }
270 }
271
272 if (in->ticket_age_add_valid) {
273 if (!CBB_add_asn1(&session, &child, kTicketAgeAddTag) ||
274 !CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) ||
275 !CBB_add_u32(&child2, in->ticket_age_add)) {
276 return 0;
277 }
278 }
279
280 if (!in->is_server) {
281 if (!CBB_add_asn1(&session, &child, kIsServerTag) ||
282 !CBB_add_asn1_bool(&child, false)) {
283 return 0;
284 }
285 }
286
287 if (in->peer_signature_algorithm != 0 &&
288 (!CBB_add_asn1(&session, &child, kPeerSignatureAlgorithmTag) ||
289 !CBB_add_asn1_uint64(&child, in->peer_signature_algorithm))) {
290 return 0;
291 }
292
293 if (in->ticket_max_early_data != 0 &&
294 (!CBB_add_asn1(&session, &child, kTicketMaxEarlyDataTag) ||
295 !CBB_add_asn1_uint64(&child, in->ticket_max_early_data))) {
296 return 0;
297 }
298
299 if (in->timeout != in->auth_timeout &&
300 (!CBB_add_asn1(&session, &child, kAuthTimeoutTag) ||
301 !CBB_add_asn1_uint64(&child, in->auth_timeout))) {
302 return 0;
303 }
304
305 if (!in->early_alpn.empty()) {
306 if (!CBB_add_asn1(&session, &child, kEarlyALPNTag) ||
307 !CBB_add_asn1_octet_string(&child, in->early_alpn.data(),
308 in->early_alpn.size())) {
309 return 0;
310 }
311 }
312
313 if (in->is_quic) {
314 if (!CBB_add_asn1(&session, &child, kIsQuicTag) ||
315 !CBB_add_asn1_bool(&child, true)) {
316 return 0;
317 }
318 }
319
320 if (!in->quic_early_data_context.empty()) {
321 if (!CBB_add_asn1(&session, &child, kQuicEarlyDataContextTag) ||
322 !CBB_add_asn1_octet_string(&child, in->quic_early_data_context.data(),
323 in->quic_early_data_context.size())) {
324 return 0;
325 }
326 }
327
328 if (in->has_application_settings) {
329 if (!CBB_add_asn1(&session, &child, kLocalALPSTag) ||
330 !CBB_add_asn1_octet_string(&child,
331 in->local_application_settings.data(),
332 in->local_application_settings.size()) ||
333 !CBB_add_asn1(&session, &child, kPeerALPSTag) ||
334 !CBB_add_asn1_octet_string(&child, in->peer_application_settings.data(),
335 in->peer_application_settings.size())) {
336 return 0;
337 }
338 }
339
340 return CBB_flush(cbb);
341 }
342
343 // SSL_SESSION_parse_string gets an optional ASN.1 OCTET STRING explicitly
344 // tagged with |tag| from |cbs| and saves it in |*out|. If the element was not
345 // found, it sets |*out| to NULL. It returns one on success, whether or not the
346 // element was found, and zero on decode error.
SSL_SESSION_parse_string(CBS * cbs,UniquePtr<char> * out,CBS_ASN1_TAG tag)347 static int SSL_SESSION_parse_string(CBS *cbs, UniquePtr<char> *out,
348 CBS_ASN1_TAG tag) {
349 CBS value;
350 int present;
351 if (!CBS_get_optional_asn1_octet_string(cbs, &value, &present, tag)) {
352 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
353 return 0;
354 }
355 if (present) {
356 if (CBS_contains_zero_byte(&value)) {
357 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
358 return 0;
359 }
360 char *raw = nullptr;
361 if (!CBS_strdup(&value, &raw)) {
362 return 0;
363 }
364 out->reset(raw);
365 } else {
366 out->reset();
367 }
368 return 1;
369 }
370
371 // SSL_SESSION_parse_octet_string gets an optional ASN.1 OCTET STRING explicitly
372 // tagged with |tag| from |cbs| and stows it in |*out|. It returns one on
373 // success, whether or not the element was found, and zero on decode error.
SSL_SESSION_parse_octet_string(CBS * cbs,Array<uint8_t> * out,CBS_ASN1_TAG tag)374 static bool SSL_SESSION_parse_octet_string(CBS *cbs, Array<uint8_t> *out,
375 CBS_ASN1_TAG tag) {
376 CBS value;
377 if (!CBS_get_optional_asn1_octet_string(cbs, &value, NULL, tag)) {
378 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
379 return false;
380 }
381 return out->CopyFrom(value);
382 }
383
SSL_SESSION_parse_crypto_buffer(CBS * cbs,UniquePtr<CRYPTO_BUFFER> * out,CBS_ASN1_TAG tag,CRYPTO_BUFFER_POOL * pool)384 static int SSL_SESSION_parse_crypto_buffer(CBS *cbs,
385 UniquePtr<CRYPTO_BUFFER> *out,
386 CBS_ASN1_TAG tag,
387 CRYPTO_BUFFER_POOL *pool) {
388 if (!CBS_peek_asn1_tag(cbs, tag)) {
389 return 1;
390 }
391
392 CBS child, value;
393 if (!CBS_get_asn1(cbs, &child, tag) ||
394 !CBS_get_asn1(&child, &value, CBS_ASN1_OCTETSTRING) ||
395 CBS_len(&child) != 0) {
396 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
397 return 0;
398 }
399 out->reset(CRYPTO_BUFFER_new_from_CBS(&value, pool));
400 if (*out == nullptr) {
401 return 0;
402 }
403 return 1;
404 }
405
SSL_SESSION_parse_long(CBS * cbs,long * out,CBS_ASN1_TAG tag,long default_value)406 static int SSL_SESSION_parse_long(CBS *cbs, long *out, CBS_ASN1_TAG tag,
407 long default_value) {
408 uint64_t value;
409 if (!CBS_get_optional_asn1_uint64(cbs, &value, tag,
410 (uint64_t)default_value) ||
411 value > LONG_MAX) {
412 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
413 return 0;
414 }
415 *out = (long)value;
416 return 1;
417 }
418
SSL_SESSION_parse_u32(CBS * cbs,uint32_t * out,CBS_ASN1_TAG tag,uint32_t default_value)419 static int SSL_SESSION_parse_u32(CBS *cbs, uint32_t *out, CBS_ASN1_TAG tag,
420 uint32_t default_value) {
421 uint64_t value;
422 if (!CBS_get_optional_asn1_uint64(cbs, &value, tag,
423 (uint64_t)default_value) ||
424 value > 0xffffffff) {
425 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
426 return 0;
427 }
428 *out = (uint32_t)value;
429 return 1;
430 }
431
SSL_SESSION_parse_u16(CBS * cbs,uint16_t * out,CBS_ASN1_TAG tag,uint16_t default_value)432 static int SSL_SESSION_parse_u16(CBS *cbs, uint16_t *out, CBS_ASN1_TAG tag,
433 uint16_t default_value) {
434 uint64_t value;
435 if (!CBS_get_optional_asn1_uint64(cbs, &value, tag,
436 (uint64_t)default_value) ||
437 value > 0xffff) {
438 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
439 return 0;
440 }
441 *out = (uint16_t)value;
442 return 1;
443 }
444
SSL_SESSION_parse(CBS * cbs,const SSL_X509_METHOD * x509_method,CRYPTO_BUFFER_POOL * pool)445 UniquePtr<SSL_SESSION> SSL_SESSION_parse(CBS *cbs,
446 const SSL_X509_METHOD *x509_method,
447 CRYPTO_BUFFER_POOL *pool) {
448 UniquePtr<SSL_SESSION> ret = ssl_session_new(x509_method);
449 if (!ret) {
450 return nullptr;
451 }
452
453 CBS session;
454 uint64_t version, ssl_version;
455 uint16_t unused;
456 if (!CBS_get_asn1(cbs, &session, CBS_ASN1_SEQUENCE) || //
457 !CBS_get_asn1_uint64(&session, &version) || //
458 version != kVersion || //
459 !CBS_get_asn1_uint64(&session, &ssl_version) || //
460 // Require sessions have versions valid in either TLS or DTLS. The session
461 // will not be used by the handshake if not applicable, but, for
462 // simplicity, never parse a session that does not pass
463 // |ssl_protocol_version_from_wire|.
464 ssl_version > UINT16_MAX || //
465 !ssl_protocol_version_from_wire(&unused, ssl_version)) {
466 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
467 return nullptr;
468 }
469 ret->ssl_version = ssl_version;
470
471 CBS cipher;
472 uint16_t cipher_value;
473 if (!CBS_get_asn1(&session, &cipher, CBS_ASN1_OCTETSTRING) || //
474 !CBS_get_u16(&cipher, &cipher_value) || //
475 CBS_len(&cipher) != 0) {
476 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
477 return nullptr;
478 }
479 ret->cipher = SSL_get_cipher_by_value(cipher_value);
480 if (ret->cipher == NULL) {
481 OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_CIPHER);
482 return nullptr;
483 }
484
485 CBS session_id, secret, child;
486 uint64_t timeout;
487 if (!CBS_get_asn1(&session, &session_id, CBS_ASN1_OCTETSTRING) ||
488 !ret->session_id.TryCopyFrom(session_id) ||
489 !CBS_get_asn1(&session, &secret, CBS_ASN1_OCTETSTRING) ||
490 !ret->secret.TryCopyFrom(secret) ||
491 !CBS_get_asn1(&session, &child, kTimeTag) ||
492 !CBS_get_asn1_uint64(&child, &ret->time) ||
493 !CBS_get_asn1(&session, &child, kTimeoutTag) ||
494 !CBS_get_asn1_uint64(&child, &timeout) || //
495 timeout > UINT32_MAX) {
496 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
497 return nullptr;
498 }
499
500 ret->timeout = (uint32_t)timeout;
501
502 CBS peer;
503 int has_peer;
504 if (!CBS_get_optional_asn1(&session, &peer, &has_peer, kPeerTag) ||
505 (has_peer && CBS_len(&peer) == 0)) {
506 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
507 return nullptr;
508 }
509 // |peer| is processed with the certificate chain.
510
511 CBS sid_ctx;
512 if (!CBS_get_optional_asn1_octet_string(
513 &session, &sid_ctx, /*out_present=*/nullptr, kSessionIDContextTag) ||
514 !ret->sid_ctx.TryCopyFrom(sid_ctx) ||
515 !SSL_SESSION_parse_long(&session, &ret->verify_result, kVerifyResultTag,
516 X509_V_OK)) {
517 return nullptr;
518 }
519
520 // Skip the historical hostName field.
521 CBS unused_hostname;
522 if (!CBS_get_optional_asn1(&session, &unused_hostname, nullptr,
523 kHostNameTag)) {
524 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
525 return nullptr;
526 }
527
528 if (!SSL_SESSION_parse_string(&session, &ret->psk_identity,
529 kPSKIdentityTag) ||
530 !SSL_SESSION_parse_u32(&session, &ret->ticket_lifetime_hint,
531 kTicketLifetimeHintTag, 0) ||
532 !SSL_SESSION_parse_octet_string(&session, &ret->ticket, kTicketTag)) {
533 return nullptr;
534 }
535
536 if (CBS_peek_asn1_tag(&session, kPeerSHA256Tag)) {
537 CBS peer_sha256;
538 if (!CBS_get_asn1(&session, &child, kPeerSHA256Tag) ||
539 !CBS_get_asn1(&child, &peer_sha256, CBS_ASN1_OCTETSTRING) ||
540 CBS_len(&peer_sha256) != sizeof(ret->peer_sha256) ||
541 CBS_len(&child) != 0) {
542 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
543 return nullptr;
544 }
545 OPENSSL_memcpy(ret->peer_sha256, CBS_data(&peer_sha256),
546 sizeof(ret->peer_sha256));
547 ret->peer_sha256_valid = true;
548 } else {
549 ret->peer_sha256_valid = false;
550 }
551
552 CBS original_handshake_hash;
553 if (!CBS_get_optional_asn1_octet_string(&session, &original_handshake_hash,
554 /*out_present=*/nullptr,
555 kOriginalHandshakeHashTag) ||
556 !ret->original_handshake_hash.TryCopyFrom(original_handshake_hash) ||
557 !SSL_SESSION_parse_crypto_buffer(&session,
558 &ret->signed_cert_timestamp_list,
559 kSignedCertTimestampListTag, pool) ||
560 !SSL_SESSION_parse_crypto_buffer(&session, &ret->ocsp_response,
561 kOCSPResponseTag, pool)) {
562 return nullptr;
563 }
564
565 int extended_master_secret;
566 if (!CBS_get_optional_asn1_bool(&session, &extended_master_secret,
567 kExtendedMasterSecretTag,
568 0 /* default to false */)) {
569 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
570 return nullptr;
571 }
572 ret->extended_master_secret = !!extended_master_secret;
573
574 if (!SSL_SESSION_parse_u16(&session, &ret->group_id, kGroupIDTag, 0)) {
575 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
576 return nullptr;
577 }
578
579 CBS cert_chain;
580 CBS_init(&cert_chain, NULL, 0);
581 int has_cert_chain;
582 if (!CBS_get_optional_asn1(&session, &cert_chain, &has_cert_chain,
583 kCertChainTag) ||
584 (has_cert_chain && CBS_len(&cert_chain) == 0)) {
585 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
586 return nullptr;
587 }
588 if (has_cert_chain && !has_peer) {
589 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
590 return nullptr;
591 }
592 if (has_peer || has_cert_chain) {
593 ret->certs.reset(sk_CRYPTO_BUFFER_new_null());
594 if (ret->certs == nullptr) {
595 return nullptr;
596 }
597
598 if (has_peer) {
599 UniquePtr<CRYPTO_BUFFER> buffer(CRYPTO_BUFFER_new_from_CBS(&peer, pool));
600 if (!buffer || //
601 !PushToStack(ret->certs.get(), std::move(buffer))) {
602 return nullptr;
603 }
604 }
605
606 while (CBS_len(&cert_chain) > 0) {
607 CBS cert;
608 if (!CBS_get_any_asn1_element(&cert_chain, &cert, NULL, NULL) ||
609 CBS_len(&cert) == 0) {
610 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
611 return nullptr;
612 }
613
614 UniquePtr<CRYPTO_BUFFER> buffer(CRYPTO_BUFFER_new_from_CBS(&cert, pool));
615 if (buffer == nullptr ||
616 !PushToStack(ret->certs.get(), std::move(buffer))) {
617 return nullptr;
618 }
619 }
620 }
621
622 CBS age_add;
623 int age_add_present;
624 if (!CBS_get_optional_asn1_octet_string(&session, &age_add, &age_add_present,
625 kTicketAgeAddTag) ||
626 (age_add_present && //
627 !CBS_get_u32(&age_add, &ret->ticket_age_add)) || //
628 CBS_len(&age_add) != 0) {
629 return nullptr;
630 }
631 ret->ticket_age_add_valid = age_add_present != 0;
632
633 int is_server;
634 if (!CBS_get_optional_asn1_bool(&session, &is_server, kIsServerTag,
635 1 /* default to true */)) {
636 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
637 return nullptr;
638 }
639 /* TODO: in time we can include |is_server| for servers too, then we can
640 enforce that client and server sessions are never mixed up. */
641
642 ret->is_server = is_server;
643
644 int is_quic;
645 if (!SSL_SESSION_parse_u16(&session, &ret->peer_signature_algorithm,
646 kPeerSignatureAlgorithmTag, 0) ||
647 !SSL_SESSION_parse_u32(&session, &ret->ticket_max_early_data,
648 kTicketMaxEarlyDataTag, 0) ||
649 !SSL_SESSION_parse_u32(&session, &ret->auth_timeout, kAuthTimeoutTag,
650 ret->timeout) ||
651 !SSL_SESSION_parse_octet_string(&session, &ret->early_alpn,
652 kEarlyALPNTag) ||
653 !CBS_get_optional_asn1_bool(&session, &is_quic, kIsQuicTag,
654 /*default_value=*/false) ||
655 !SSL_SESSION_parse_octet_string(&session, &ret->quic_early_data_context,
656 kQuicEarlyDataContextTag)) {
657 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
658 return nullptr;
659 }
660
661 CBS settings;
662 int has_local_alps, has_peer_alps;
663 if (!CBS_get_optional_asn1_octet_string(&session, &settings, &has_local_alps,
664 kLocalALPSTag) ||
665 !ret->local_application_settings.CopyFrom(settings) ||
666 !CBS_get_optional_asn1_octet_string(&session, &settings, &has_peer_alps,
667 kPeerALPSTag) ||
668 !ret->peer_application_settings.CopyFrom(settings) ||
669 CBS_len(&session) != 0) {
670 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
671 return nullptr;
672 }
673 ret->is_quic = is_quic;
674
675 // The two ALPS values and ALPN must be consistent.
676 if (has_local_alps != has_peer_alps ||
677 (has_local_alps && ret->early_alpn.empty())) {
678 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
679 return nullptr;
680 }
681 ret->has_application_settings = has_local_alps;
682
683 if (!x509_method->session_cache_objects(ret.get())) {
684 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
685 return nullptr;
686 }
687
688 return ret;
689 }
690
ssl_session_serialize(const SSL_SESSION * in,CBB * cbb)691 bool ssl_session_serialize(const SSL_SESSION *in, CBB *cbb) {
692 return SSL_SESSION_to_bytes_full(in, cbb, 0);
693 }
694
695 BSSL_NAMESPACE_END
696
697 using namespace bssl;
698
SSL_SESSION_to_bytes(const SSL_SESSION * in,uint8_t ** out_data,size_t * out_len)699 int SSL_SESSION_to_bytes(const SSL_SESSION *in, uint8_t **out_data,
700 size_t *out_len) {
701 if (in->not_resumable) {
702 // If the caller has an unresumable session, e.g. if |SSL_get_session| were
703 // called on a TLS 1.3 or False Started connection, serialize with a
704 // placeholder value so it is not accidentally deserialized into a resumable
705 // one.
706 static const char kNotResumableSession[] = "NOT RESUMABLE";
707
708 *out_len = strlen(kNotResumableSession);
709 *out_data = (uint8_t *)OPENSSL_memdup(kNotResumableSession, *out_len);
710 if (*out_data == NULL) {
711 return 0;
712 }
713
714 return 1;
715 }
716
717 ScopedCBB cbb;
718 if (!CBB_init(cbb.get(), 256) ||
719 !SSL_SESSION_to_bytes_full(in, cbb.get(), 0) ||
720 !CBB_finish(cbb.get(), out_data, out_len)) {
721 return 0;
722 }
723
724 return 1;
725 }
726
SSL_SESSION_to_bytes_for_ticket(const SSL_SESSION * in,uint8_t ** out_data,size_t * out_len)727 int SSL_SESSION_to_bytes_for_ticket(const SSL_SESSION *in, uint8_t **out_data,
728 size_t *out_len) {
729 ScopedCBB cbb;
730 if (!CBB_init(cbb.get(), 256) ||
731 !SSL_SESSION_to_bytes_full(in, cbb.get(), 1) ||
732 !CBB_finish(cbb.get(), out_data, out_len)) {
733 return 0;
734 }
735
736 return 1;
737 }
738
i2d_SSL_SESSION(SSL_SESSION * in,uint8_t ** pp)739 int i2d_SSL_SESSION(SSL_SESSION *in, uint8_t **pp) {
740 uint8_t *out;
741 size_t len;
742
743 if (!SSL_SESSION_to_bytes(in, &out, &len)) {
744 return -1;
745 }
746
747 if (len > INT_MAX) {
748 OPENSSL_free(out);
749 OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
750 return -1;
751 }
752
753 if (pp) {
754 OPENSSL_memcpy(*pp, out, len);
755 *pp += len;
756 }
757 OPENSSL_free(out);
758
759 return len;
760 }
761
SSL_SESSION_from_bytes(const uint8_t * in,size_t in_len,const SSL_CTX * ctx)762 SSL_SESSION *SSL_SESSION_from_bytes(const uint8_t *in, size_t in_len,
763 const SSL_CTX *ctx) {
764 CBS cbs;
765 CBS_init(&cbs, in, in_len);
766 UniquePtr<SSL_SESSION> ret =
767 SSL_SESSION_parse(&cbs, ctx->x509_method, ctx->pool);
768 if (!ret) {
769 return NULL;
770 }
771 if (CBS_len(&cbs) != 0) {
772 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
773 return NULL;
774 }
775 return ret.release();
776 }
777