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