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