Coverage Report

Created: 2023-06-07 07:13

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