Coverage Report

Created: 2022-08-24 06:30

/src/libressl/crypto/ct/ct_oct.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: ct_oct.c,v 1.8 2021/12/20 17:23:07 jsing Exp $ */
2
/*
3
 * Written by Rob Stradling (rob@comodo.com) and Stephen Henson
4
 * (steve@openssl.org) for the OpenSSL project 2014.
5
 */
6
/* ====================================================================
7
 * Copyright (c) 2014 The OpenSSL Project.  All rights reserved.
8
 *
9
 * Redistribution and use in source and binary forms, with or without
10
 * modification, are permitted provided that the following conditions
11
 * are met:
12
 *
13
 * 1. Redistributions of source code must retain the above copyright
14
 *    notice, this list of conditions and the following disclaimer.
15
 *
16
 * 2. Redistributions in binary form must reproduce the above copyright
17
 *    notice, this list of conditions and the following disclaimer in
18
 *    the documentation and/or other materials provided with the
19
 *    distribution.
20
 *
21
 * 3. All advertising materials mentioning features or use of this
22
 *    software must display the following acknowledgment:
23
 *    "This product includes software developed by the OpenSSL Project
24
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25
 *
26
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27
 *    endorse or promote products derived from this software without
28
 *    prior written permission. For written permission, please contact
29
 *    licensing@OpenSSL.org.
30
 *
31
 * 5. Products derived from this software may not be called "OpenSSL"
32
 *    nor may "OpenSSL" appear in their names without prior written
33
 *    permission of the OpenSSL Project.
34
 *
35
 * 6. Redistributions of any form whatsoever must retain the following
36
 *    acknowledgment:
37
 *    "This product includes software developed by the OpenSSL Project
38
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39
 *
40
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
44
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51
 * OF THE POSSIBILITY OF SUCH DAMAGE.
52
 * ====================================================================
53
 *
54
 * This product includes cryptographic software written by Eric Young
55
 * (eay@cryptsoft.com).  This product includes software written by Tim
56
 * Hudson (tjh@cryptsoft.com).
57
 *
58
 */
59
60
#ifdef OPENSSL_NO_CT
61
# error "CT is disabled"
62
#endif
63
64
#include <limits.h>
65
#include <string.h>
66
67
#include <openssl/asn1.h>
68
#include <openssl/buffer.h>
69
#include <openssl/ct.h>
70
#include <openssl/err.h>
71
72
#include "bytestring.h"
73
#include "ct_local.h"
74
75
int
76
o2i_SCT_signature(SCT *sct, CBS *cbs)
77
0
{
78
0
  uint8_t hash_alg, sig_alg;
79
0
  CBS signature;
80
81
0
  if (sct->version != SCT_VERSION_V1) {
82
0
    CTerror(CT_R_UNSUPPORTED_VERSION);
83
0
    return 0;
84
0
  }
85
86
  /*
87
   * Parse a digitally-signed element - see RFC 6962 section 3.2 and
88
   * RFC 5246 sections 4.7 and 7.4.1.4.1.
89
   */
90
0
  if (!CBS_get_u8(cbs, &hash_alg))
91
0
    goto err_invalid;
92
0
  if (!CBS_get_u8(cbs, &sig_alg))
93
0
    goto err_invalid;
94
0
  if (!CBS_get_u16_length_prefixed(cbs, &signature))
95
0
    goto err_invalid;
96
0
  if (CBS_len(cbs) != 0)
97
0
    goto err_invalid;
98
99
  /*
100
   * Reject empty signatures since they are invalid for all supported
101
   * algorithms (this really should be done by SCT_set1_signature()).
102
   */
103
0
  if (CBS_len(&signature) == 0)
104
0
    goto err_invalid;
105
106
0
  sct->hash_alg = hash_alg;
107
0
  sct->sig_alg = sig_alg;
108
109
0
  if (SCT_get_signature_nid(sct) == NID_undef)
110
0
    goto err_invalid;
111
112
0
  if (!SCT_set1_signature(sct, CBS_data(&signature), CBS_len(&signature)))
113
0
    return 0;
114
115
0
  return 1;
116
117
0
 err_invalid:
118
0
  CTerror(CT_R_SCT_INVALID_SIGNATURE);
119
0
  return 0;
120
0
}
121
122
static int
123
o2i_SCT_internal(SCT **out_sct, CBS *cbs)
124
0
{
125
0
  SCT *sct = NULL;
126
0
  uint8_t version;
127
128
0
  *out_sct = NULL;
129
130
0
  if ((sct = SCT_new()) == NULL)
131
0
    goto err;
132
133
0
  if (CBS_len(cbs) > MAX_SCT_SIZE)
134
0
    goto err_invalid;
135
0
  if (!CBS_peek_u8(cbs, &version))
136
0
    goto err_invalid;
137
138
0
  sct->version = version;
139
140
0
  if (version == SCT_VERSION_V1) {
141
0
    CBS extensions, log_id;
142
0
    uint64_t timestamp;
143
144
    /*
145
     * Parse a v1 SignedCertificateTimestamp - see RFC 6962
146
     * section 3.2.
147
     */
148
0
    if (!CBS_get_u8(cbs, &version))
149
0
      goto err_invalid;
150
0
    if (!CBS_get_bytes(cbs, &log_id, CT_V1_LOG_ID_LEN))
151
0
      goto err_invalid;
152
0
    if (!CBS_get_u64(cbs, &timestamp))
153
0
      goto err_invalid;
154
0
    if (!CBS_get_u16_length_prefixed(cbs, &extensions))
155
0
      goto err_invalid;
156
157
0
    if (!CBS_stow(&log_id, &sct->log_id, &sct->log_id_len))
158
0
      goto err;
159
160
0
    sct->timestamp = timestamp;
161
162
0
    if (!CBS_stow(&extensions, &sct->ext, &sct->ext_len))
163
0
      goto err;
164
165
0
    if (!o2i_SCT_signature(sct, cbs))
166
0
      goto err;
167
168
0
    if (CBS_len(cbs) != 0)
169
0
      goto err_invalid;
170
0
  } else {
171
    /* If not V1 just cache encoding. */
172
0
    if (!CBS_stow(cbs, &sct->sct, &sct->sct_len))
173
0
      goto err;
174
0
  }
175
176
0
  *out_sct = sct;
177
178
0
  return 1;
179
180
0
 err_invalid:
181
0
  CTerror(CT_R_SCT_INVALID);
182
0
 err:
183
0
  SCT_free(sct);
184
185
0
  return 0;
186
0
}
187
188
SCT *
189
o2i_SCT(SCT **psct, const unsigned char **in, size_t len)
190
0
{
191
0
  SCT *sct;
192
0
  CBS cbs;
193
194
0
  CBS_init(&cbs, *in, len);
195
196
0
  if (psct != NULL) {
197
0
    SCT_free(*psct);
198
0
    *psct = NULL;
199
0
  }
200
201
0
  if (!o2i_SCT_internal(&sct, &cbs))
202
0
    return NULL;
203
204
0
  if (psct != NULL)
205
0
    *psct = sct;
206
207
0
  *in = CBS_data(&cbs);
208
209
0
  return sct;
210
0
}
211
212
int
213
i2o_SCT_signature(const SCT *sct, unsigned char **out)
214
0
{
215
0
  size_t len;
216
0
  unsigned char *p = NULL, *pstart = NULL;
217
218
0
  if (!SCT_signature_is_complete(sct)) {
219
0
    CTerror(CT_R_SCT_INVALID_SIGNATURE);
220
0
    goto err;
221
0
  }
222
223
0
  if (sct->version != SCT_VERSION_V1) {
224
0
    CTerror(CT_R_UNSUPPORTED_VERSION);
225
0
    goto err;
226
0
  }
227
228
  /*
229
   * (1 byte) Hash algorithm
230
   * (1 byte) Signature algorithm
231
   * (2 bytes + ?) Signature
232
   */
233
0
  len = 4 + sct->sig_len;
234
235
0
  if (out != NULL) {
236
0
    if (*out != NULL) {
237
0
      p = *out;
238
0
      *out += len;
239
0
    } else {
240
0
      pstart = p = malloc(len);
241
0
      if (p == NULL) {
242
0
        CTerror(ERR_R_MALLOC_FAILURE);
243
0
        goto err;
244
0
      }
245
0
      *out = p;
246
0
    }
247
248
0
    *p++ = sct->hash_alg;
249
0
    *p++ = sct->sig_alg;
250
0
    s2n(sct->sig_len, p);
251
0
    memcpy(p, sct->sig, sct->sig_len);
252
0
  }
253
254
0
  return len;
255
0
 err:
256
0
  free(pstart);
257
0
  return -1;
258
0
}
259
260
int
261
i2o_SCT(const SCT *sct, unsigned char **out)
262
0
{
263
0
  size_t len;
264
0
  unsigned char *p = NULL, *pstart = NULL;
265
266
0
  if (!SCT_is_complete(sct)) {
267
0
    CTerror(CT_R_SCT_NOT_SET);
268
0
    goto err;
269
0
  }
270
  /*
271
   * Fixed-length header: struct { (1 byte) Version sct_version; (32 bytes)
272
   * log_id id; (8 bytes) uint64 timestamp; (2 bytes + ?) CtExtensions
273
   * extensions; (1 byte) Hash algorithm (1 byte) Signature algorithm (2
274
   * bytes + ?) Signature
275
   */
276
0
  if (sct->version == SCT_VERSION_V1)
277
0
    len = 43 + sct->ext_len + 4 + sct->sig_len;
278
0
  else
279
0
    len = sct->sct_len;
280
281
0
  if (out == NULL)
282
0
    return len;
283
284
0
  if (*out != NULL) {
285
0
    p = *out;
286
0
    *out += len;
287
0
  } else {
288
0
    pstart = p = malloc(len);
289
0
    if (p == NULL) {
290
0
      CTerror(ERR_R_MALLOC_FAILURE);
291
0
      goto err;
292
0
    }
293
0
    *out = p;
294
0
  }
295
296
0
  if (sct->version == SCT_VERSION_V1) {
297
0
    *p++ = sct->version;
298
0
    memcpy(p, sct->log_id, CT_V1_HASHLEN);
299
0
    p += CT_V1_HASHLEN;
300
0
    l2n8(sct->timestamp, p);
301
0
    s2n(sct->ext_len, p);
302
0
    if (sct->ext_len > 0) {
303
0
      memcpy(p, sct->ext, sct->ext_len);
304
0
      p += sct->ext_len;
305
0
    }
306
0
    if (i2o_SCT_signature(sct, &p) <= 0)
307
0
      goto err;
308
0
  } else {
309
0
    memcpy(p, sct->sct, len);
310
0
  }
311
312
0
  return len;
313
0
 err:
314
0
  free(pstart);
315
0
  return -1;
316
0
}
317
318
STACK_OF(SCT) *
319
o2i_SCT_LIST(STACK_OF(SCT) **out_scts, const unsigned char **pp, size_t len)
320
0
{
321
0
  CBS cbs, cbs_scts, cbs_sct;
322
0
  STACK_OF(SCT) *scts = NULL;
323
324
0
  CBS_init(&cbs, *pp, len);
325
326
0
  if (CBS_len(&cbs) > MAX_SCT_LIST_SIZE)
327
0
    goto err_invalid;
328
0
  if (!CBS_get_u16_length_prefixed(&cbs, &cbs_scts))
329
0
    goto err_invalid;
330
0
  if (CBS_len(&cbs) != 0)
331
0
    goto err_invalid;
332
333
0
  if (out_scts != NULL) {
334
0
    SCT_LIST_free(*out_scts);
335
0
    *out_scts = NULL;
336
0
  }
337
338
0
  if ((scts = sk_SCT_new_null()) == NULL)
339
0
    return NULL;
340
341
0
  while (CBS_len(&cbs_scts) > 0) {
342
0
    SCT *sct;
343
344
0
    if (!CBS_get_u16_length_prefixed(&cbs_scts, &cbs_sct))
345
0
      goto err_invalid;
346
347
0
    if (!o2i_SCT_internal(&sct, &cbs_sct))
348
0
      goto err;
349
0
    if (!sk_SCT_push(scts, sct)) {
350
0
      SCT_free(sct);
351
0
      goto err;
352
0
    }
353
0
  }
354
355
0
  if (out_scts != NULL)
356
0
    *out_scts = scts;
357
358
0
  *pp = CBS_data(&cbs);
359
360
0
  return scts;
361
362
0
 err_invalid:
363
0
  CTerror(CT_R_SCT_LIST_INVALID);
364
0
 err:
365
0
  SCT_LIST_free(scts);
366
367
0
  return NULL;
368
0
}
369
370
int
371
i2o_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **pp)
372
0
{
373
0
  int len, sct_len, i, is_pp_new = 0;
374
0
  size_t len2;
375
0
  unsigned char *p = NULL, *p2;
376
377
0
  if (pp != NULL) {
378
0
    if (*pp == NULL) {
379
0
      if ((len = i2o_SCT_LIST(a, NULL)) == -1) {
380
0
        CTerror(CT_R_SCT_LIST_INVALID);
381
0
        return -1;
382
0
      }
383
0
      if ((*pp = malloc(len)) == NULL) {
384
0
        CTerror(ERR_R_MALLOC_FAILURE);
385
0
        return -1;
386
0
      }
387
0
      is_pp_new = 1;
388
0
    }
389
0
    p = *pp + 2;
390
0
  }
391
392
0
  len2 = 2;
393
0
  for (i = 0; i < sk_SCT_num(a); i++) {
394
0
    if (pp != NULL) {
395
0
      p2 = p;
396
0
      p += 2;
397
0
      if ((sct_len = i2o_SCT(sk_SCT_value(a, i), &p)) == -1)
398
0
        goto err;
399
0
      s2n(sct_len, p2);
400
0
    } else {
401
0
      if ((sct_len = i2o_SCT(sk_SCT_value(a, i), NULL)) == -1)
402
0
        goto err;
403
0
    }
404
0
    len2 += 2 + sct_len;
405
0
  }
406
407
0
  if (len2 > MAX_SCT_LIST_SIZE)
408
0
    goto err;
409
410
0
  if (pp != NULL) {
411
0
    p = *pp;
412
0
    s2n(len2 - 2, p);
413
0
    if (!is_pp_new)
414
0
      *pp += len2;
415
0
  }
416
0
  return len2;
417
418
0
 err:
419
0
  if (is_pp_new) {
420
0
    free(*pp);
421
0
    *pp = NULL;
422
0
  }
423
0
  return -1;
424
0
}
425
426
STACK_OF(SCT) *
427
d2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp, long len)
428
0
{
429
0
  ASN1_OCTET_STRING *oct = NULL;
430
0
  STACK_OF(SCT) *sk = NULL;
431
0
  const unsigned char *p;
432
433
0
  p = *pp;
434
0
  if (d2i_ASN1_OCTET_STRING(&oct, &p, len) == NULL)
435
0
    return NULL;
436
437
0
  p = oct->data;
438
0
  if ((sk = o2i_SCT_LIST(a, &p, oct->length)) != NULL)
439
0
    *pp += len;
440
441
0
  ASN1_OCTET_STRING_free(oct);
442
0
  return sk;
443
0
}
444
445
int
446
i2d_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **out)
447
0
{
448
0
  ASN1_OCTET_STRING oct;
449
0
  int len;
450
451
0
  oct.data = NULL;
452
0
  if ((oct.length = i2o_SCT_LIST(a, &oct.data)) == -1)
453
0
    return -1;
454
455
0
  len = i2d_ASN1_OCTET_STRING(&oct, out);
456
0
  free(oct.data);
457
0
  return len;
458
0
}