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