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