Coverage Report

Created: 2022-08-24 06:31

/src/libressl/ssl/ssl_asn1.c
Line
Count
Source (jump to first uncovered line)
1
/* $OpenBSD: ssl_asn1.c,v 1.65 2022/06/07 17:53:42 tb Exp $ */
2
/*
3
 * Copyright (c) 2016 Joel Sing <jsing@openbsd.org>
4
 *
5
 * Permission to use, copy, modify, and distribute this software for any
6
 * purpose with or without fee is hereby granted, provided that the above
7
 * copyright notice and this permission notice appear in all copies.
8
 *
9
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
 */
17
18
#include <limits.h>
19
20
#include <openssl/ssl.h>
21
#include <openssl/x509.h>
22
23
#include "bytestring.h"
24
#include "ssl_locl.h"
25
26
6.36k
#define SSLASN1_TAG (CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC)
27
1.20k
#define SSLASN1_TIME_TAG    (SSLASN1_TAG | 1)
28
1.14k
#define SSLASN1_TIMEOUT_TAG   (SSLASN1_TAG | 2)
29
640
#define SSLASN1_PEER_CERT_TAG   (SSLASN1_TAG | 3)
30
1.05k
#define SSLASN1_SESSION_ID_CTX_TAG  (SSLASN1_TAG | 4)
31
740
#define SSLASN1_VERIFY_RESULT_TAG (SSLASN1_TAG | 5)
32
542
#define SSLASN1_HOSTNAME_TAG    (SSLASN1_TAG | 6)
33
556
#define SSLASN1_LIFETIME_TAG    (SSLASN1_TAG | 9)
34
476
#define SSLASN1_TICKET_TAG    (SSLASN1_TAG | 10)
35
36
static uint64_t
37
time_max(void)
38
779
{
39
779
  if (sizeof(time_t) == sizeof(int32_t))
40
0
    return INT32_MAX;
41
779
  if (sizeof(time_t) == sizeof(int64_t))
42
779
    return INT64_MAX;
43
0
  return 0;
44
779
}
45
46
static int
47
SSL_SESSION_encode(SSL_SESSION *s, unsigned char **out, size_t *out_len,
48
    int ticket_encoding)
49
422
{
50
422
  CBB cbb, session, cipher_suite, session_id, master_key, time, timeout;
51
422
  CBB peer_cert, sidctx, verify_result, hostname, lifetime, ticket, value;
52
422
  unsigned char *peer_cert_bytes = NULL;
53
422
  int len, rv = 0;
54
422
  uint16_t cid;
55
56
422
  if (!CBB_init(&cbb, 0))
57
0
    goto err;
58
59
422
  if (!CBB_add_asn1(&cbb, &session, CBS_ASN1_SEQUENCE))
60
0
    goto err;
61
62
  /* Session ASN1 version. */
63
422
  if (!CBB_add_asn1_uint64(&session, SSL_SESSION_ASN1_VERSION))
64
0
    goto err;
65
66
  /* TLS/SSL protocol version. */
67
422
  if (s->ssl_version < 0)
68
0
    goto err;
69
422
  if (!CBB_add_asn1_uint64(&session, s->ssl_version))
70
0
    goto err;
71
72
  /* Cipher suite ID. */
73
  /* XXX - require cipher to be non-NULL or always/only use cipher_id. */
74
422
  cid = (uint16_t)(s->cipher_id & SSL3_CK_VALUE_MASK);
75
422
  if (s->cipher != NULL)
76
0
    cid = ssl3_cipher_get_value(s->cipher);
77
422
  if (!CBB_add_asn1(&session, &cipher_suite, CBS_ASN1_OCTETSTRING))
78
0
    goto err;
79
422
  if (!CBB_add_u16(&cipher_suite, cid))
80
0
    goto err;
81
82
  /* Session ID - zero length for a ticket. */
83
422
  if (!CBB_add_asn1(&session, &session_id, CBS_ASN1_OCTETSTRING))
84
0
    goto err;
85
422
  if (!CBB_add_bytes(&session_id, s->session_id,
86
422
      ticket_encoding ? 0 : s->session_id_length))
87
0
    goto err;
88
89
  /* Master key. */
90
422
  if (!CBB_add_asn1(&session, &master_key, CBS_ASN1_OCTETSTRING))
91
0
    goto err;
92
422
  if (!CBB_add_bytes(&master_key, s->master_key, s->master_key_length))
93
0
    goto err;
94
95
  /* Time [1]. */
96
422
  if (s->time != 0) {
97
422
    if (s->time < 0)
98
0
      goto err;
99
422
    if (!CBB_add_asn1(&session, &time, SSLASN1_TIME_TAG))
100
0
      goto err;
101
422
    if (!CBB_add_asn1_uint64(&time, s->time))
102
0
      goto err;
103
422
  }
104
105
  /* Timeout [2]. */
106
422
  if (s->timeout != 0) {
107
422
    if (s->timeout < 0)
108
0
      goto err;
109
422
    if (!CBB_add_asn1(&session, &timeout, SSLASN1_TIMEOUT_TAG))
110
0
      goto err;
111
422
    if (!CBB_add_asn1_uint64(&timeout, s->timeout))
112
0
      goto err;
113
422
  }
114
115
  /* Peer certificate [3]. */
116
422
  if (s->peer_cert != NULL) {
117
2
    if ((len = i2d_X509(s->peer_cert, &peer_cert_bytes)) <= 0)
118
0
      goto err;
119
2
    if (!CBB_add_asn1(&session, &peer_cert, SSLASN1_PEER_CERT_TAG))
120
0
      goto err;
121
2
    if (!CBB_add_bytes(&peer_cert, peer_cert_bytes, len))
122
0
      goto err;
123
2
  }
124
125
  /* Session ID context [4]. */
126
  /* XXX - Actually handle this as optional? */
127
422
  if (!CBB_add_asn1(&session, &sidctx, SSLASN1_SESSION_ID_CTX_TAG))
128
0
    goto err;
129
422
  if (!CBB_add_asn1(&sidctx, &value, CBS_ASN1_OCTETSTRING))
130
0
    goto err;
131
422
  if (!CBB_add_bytes(&value, s->sid_ctx, s->sid_ctx_length))
132
0
    goto err;
133
134
  /* Verify result [5]. */
135
422
  if (s->verify_result != X509_V_OK) {
136
130
    if (s->verify_result < 0)
137
0
      goto err;
138
130
    if (!CBB_add_asn1(&session, &verify_result,
139
130
        SSLASN1_VERIFY_RESULT_TAG))
140
0
      goto err;
141
130
    if (!CBB_add_asn1_uint64(&verify_result, s->verify_result))
142
0
      goto err;
143
130
  }
144
145
  /* Hostname [6]. */
146
422
  if (s->tlsext_hostname != NULL) {
147
2
    if (!CBB_add_asn1(&session, &hostname, SSLASN1_HOSTNAME_TAG))
148
0
      goto err;
149
2
    if (!CBB_add_asn1(&hostname, &value, CBS_ASN1_OCTETSTRING))
150
0
      goto err;
151
2
    if (!CBB_add_bytes(&value, (const uint8_t *)s->tlsext_hostname,
152
2
        strlen(s->tlsext_hostname)))
153
0
      goto err;
154
2
  }
155
156
  /* PSK identity hint [7]. */
157
  /* PSK identity [8]. */
158
159
  /* Ticket lifetime hint [9]. */
160
422
  if (s->tlsext_tick_lifetime_hint > 0) {
161
26
    if (!CBB_add_asn1(&session, &lifetime, SSLASN1_LIFETIME_TAG))
162
0
      goto err;
163
26
    if (!CBB_add_asn1_uint64(&lifetime,
164
26
        s->tlsext_tick_lifetime_hint))
165
0
      goto err;
166
26
  }
167
168
  /* Ticket [10]. */
169
422
  if (s->tlsext_tick != NULL) {
170
8
    if (!CBB_add_asn1(&session, &ticket, SSLASN1_TICKET_TAG))
171
0
      goto err;
172
8
    if (!CBB_add_asn1(&ticket, &value, CBS_ASN1_OCTETSTRING))
173
0
      goto err;
174
8
    if (!CBB_add_bytes(&value, s->tlsext_tick, s->tlsext_ticklen))
175
0
      goto err;
176
8
  }
177
178
  /* Compression method [11]. */
179
  /* SRP username [12]. */
180
181
422
  if (!CBB_finish(&cbb, out, out_len))
182
0
    goto err;
183
184
422
  rv = 1;
185
186
422
 err:
187
422
  CBB_cleanup(&cbb);
188
422
  free(peer_cert_bytes);
189
190
422
  return rv;
191
422
}
192
193
int
194
SSL_SESSION_ticket(SSL_SESSION *ss, unsigned char **out, size_t *out_len)
195
0
{
196
0
  if (ss == NULL)
197
0
    return 0;
198
199
0
  if (ss->cipher == NULL && ss->cipher_id == 0)
200
0
    return 0;
201
202
0
  return SSL_SESSION_encode(ss, out, out_len, 1);
203
0
}
204
205
int
206
i2d_SSL_SESSION(SSL_SESSION *ss, unsigned char **pp)
207
422
{
208
422
  unsigned char *data = NULL;
209
422
  size_t data_len = 0;
210
422
  int rv = -1;
211
212
422
  if (ss == NULL)
213
0
    return 0;
214
215
422
  if (ss->cipher == NULL && ss->cipher_id == 0)
216
0
    return 0;
217
218
422
  if (!SSL_SESSION_encode(ss, &data, &data_len, 0))
219
0
    goto err;
220
221
422
  if (data_len > INT_MAX)
222
0
    goto err;
223
224
422
  if (pp != NULL) {
225
422
    if (*pp == NULL) {
226
422
      *pp = data;
227
422
      data = NULL;
228
422
    } else {
229
0
      memcpy(*pp, data, data_len);
230
0
      *pp += data_len;
231
0
    }
232
422
  }
233
234
422
  rv = (int)data_len;
235
236
422
 err:
237
422
  freezero(data, data_len);
238
239
422
  return rv;
240
422
}
241
242
SSL_SESSION *
243
d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, long length)
244
14.3k
{
245
14.3k
  CBS cbs, session, cipher_suite, session_id, master_key, peer_cert;
246
14.3k
  CBS hostname, ticket;
247
14.3k
  uint64_t version, tls_version, stime, timeout, verify_result, lifetime;
248
14.3k
  const unsigned char *peer_cert_bytes;
249
14.3k
  uint16_t cipher_value;
250
14.3k
  SSL_SESSION *s = NULL;
251
14.3k
  size_t data_len;
252
14.3k
  int present;
253
254
14.3k
  if (a != NULL)
255
0
    s = *a;
256
257
14.3k
  if (s == NULL) {
258
14.3k
    if ((s = SSL_SESSION_new()) == NULL) {
259
0
      SSLerrorx(ERR_R_MALLOC_FAILURE);
260
0
      return (NULL);
261
0
    }
262
14.3k
  }
263
264
14.3k
  CBS_init(&cbs, *pp, length);
265
266
14.3k
  if (!CBS_get_asn1(&cbs, &session, CBS_ASN1_SEQUENCE))
267
7.43k
    goto err;
268
269
  /* Session ASN1 version. */
270
6.93k
  if (!CBS_get_asn1_uint64(&session, &version))
271
2.95k
    goto err;
272
3.97k
  if (version != SSL_SESSION_ASN1_VERSION)
273
2.82k
    goto err;
274
275
  /* TLS/SSL Protocol Version. */
276
1.15k
  if (!CBS_get_asn1_uint64(&session, &tls_version))
277
275
    goto err;
278
878
  if (tls_version > INT_MAX)
279
47
    goto err;
280
831
  s->ssl_version = (int)tls_version;
281
282
  /* Cipher suite. */
283
831
  if (!CBS_get_asn1(&session, &cipher_suite, CBS_ASN1_OCTETSTRING))
284
42
    goto err;
285
789
  if (!CBS_get_u16(&cipher_suite, &cipher_value))
286
1
    goto err;
287
788
  if (CBS_len(&cipher_suite) != 0)
288
1
    goto err;
289
290
  /* XXX - populate cipher instead? */
291
787
  s->cipher = NULL;
292
787
  s->cipher_id = SSL3_CK_ID | cipher_value;
293
294
  /* Session ID. */
295
787
  if (!CBS_get_asn1(&session, &session_id, CBS_ASN1_OCTETSTRING))
296
2
    goto err;
297
785
  if (!CBS_write_bytes(&session_id, s->session_id, sizeof(s->session_id),
298
785
      &s->session_id_length))
299
1
    goto err;
300
301
  /* Master key. */
302
784
  if (!CBS_get_asn1(&session, &master_key, CBS_ASN1_OCTETSTRING))
303
1
    goto err;
304
783
  if (!CBS_write_bytes(&master_key, s->master_key, sizeof(s->master_key),
305
783
      &s->master_key_length))
306
1
    goto err;
307
308
  /* Time [1]. */
309
782
  s->time = time(NULL);
310
782
  if (!CBS_get_optional_asn1_uint64(&session, &stime, SSLASN1_TIME_TAG,
311
782
      0))
312
3
    goto err;
313
779
  if (stime > time_max())
314
55
    goto err;
315
724
  if (stime != 0)
316
69
    s->time = (time_t)stime;
317
318
  /* Timeout [2]. */
319
724
  s->timeout = 3;
320
724
  if (!CBS_get_optional_asn1_uint64(&session, &timeout,
321
724
      SSLASN1_TIMEOUT_TAG, 0))
322
31
    goto err;
323
693
  if (timeout > LONG_MAX)
324
55
    goto err;
325
638
  if (timeout != 0)
326
76
    s->timeout = (long)timeout;
327
328
  /* Peer certificate [3]. */
329
638
  X509_free(s->peer_cert);
330
638
  s->peer_cert = NULL;
331
638
  if (!CBS_get_optional_asn1(&session, &peer_cert, &present,
332
638
      SSLASN1_PEER_CERT_TAG))
333
1
    goto err;
334
637
  if (present) {
335
5
    data_len = CBS_len(&peer_cert);
336
5
    if (data_len > LONG_MAX)
337
0
      goto err;
338
5
    peer_cert_bytes = CBS_data(&peer_cert);
339
5
    if (d2i_X509(&s->peer_cert, &peer_cert_bytes,
340
5
        (long)data_len) == NULL)
341
2
      goto err;
342
5
  }
343
344
  /* Session ID context [4]. */
345
635
  s->sid_ctx_length = 0;
346
635
  if (!CBS_get_optional_asn1_octet_string(&session, &session_id, &present,
347
635
      SSLASN1_SESSION_ID_CTX_TAG))
348
24
    goto err;
349
611
  if (present) {
350
8
    if (!CBS_write_bytes(&session_id, (uint8_t *)&s->sid_ctx,
351
8
        sizeof(s->sid_ctx), &s->sid_ctx_length))
352
1
      goto err;
353
8
  }
354
355
  /* Verify result [5]. */
356
610
  s->verify_result = X509_V_OK;
357
610
  if (!CBS_get_optional_asn1_uint64(&session, &verify_result,
358
610
      SSLASN1_VERIFY_RESULT_TAG, X509_V_OK))
359
13
    goto err;
360
597
  if (verify_result > LONG_MAX)
361
57
    goto err;
362
540
  s->verify_result = (long)verify_result;
363
364
  /* Hostname [6]. */
365
540
  free(s->tlsext_hostname);
366
540
  s->tlsext_hostname = NULL;
367
540
  if (!CBS_get_optional_asn1_octet_string(&session, &hostname, &present,
368
540
      SSLASN1_HOSTNAME_TAG))
369
9
    goto err;
370
531
  if (present) {
371
3
    if (CBS_contains_zero_byte(&hostname))
372
1
      goto err;
373
2
    if (!CBS_strdup(&hostname, &s->tlsext_hostname))
374
0
      goto err;
375
2
  }
376
377
  /* PSK identity hint [7]. */
378
  /* PSK identity [8]. */
379
380
  /* Ticket lifetime [9]. */
381
530
  s->tlsext_tick_lifetime_hint = 0;
382
530
  if (!CBS_get_optional_asn1_uint64(&session, &lifetime,
383
530
      SSLASN1_LIFETIME_TAG, 0))
384
6
    goto err;
385
524
  if (lifetime > UINT32_MAX)
386
56
    goto err;
387
468
  if (lifetime > 0)
388
28
    s->tlsext_tick_lifetime_hint = (uint32_t)lifetime;
389
390
  /* Ticket [10]. */
391
468
  free(s->tlsext_tick);
392
468
  s->tlsext_tick = NULL;
393
468
  if (!CBS_get_optional_asn1_octet_string(&session, &ticket, &present,
394
468
      SSLASN1_TICKET_TAG))
395
46
    goto err;
396
422
  if (present) {
397
9
    if (!CBS_stow(&ticket, &s->tlsext_tick, &s->tlsext_ticklen))
398
0
      goto err;
399
9
  }
400
401
  /* Compression method [11]. */
402
  /* SRP username [12]. */
403
404
422
  *pp = CBS_data(&cbs);
405
406
422
  if (a != NULL)
407
0
    *a = s;
408
409
422
  return (s);
410
411
13.9k
 err:
412
13.9k
  ERR_asprintf_error_data("offset=%d", (int)(CBS_data(&cbs) - *pp));
413
414
13.9k
  if (s != NULL && (a == NULL || *a != s))
415
13.9k
    SSL_SESSION_free(s);
416
417
13.9k
  return (NULL);
418
422
}