Coverage Report

Created: 2025-03-09 06:52

/src/libressl/crypto/ct/ct_sct.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: ct_sct.c,v 1.10 2023/07/22 17:02:49 tb Exp $ */
2
/*
3
 * Written by Rob Stradling (rob@comodo.com), Stephen Henson (steve@openssl.org)
4
 * and Adam Eijdenberg (adam.eijdenberg@gmail.com) for the OpenSSL project 2016.
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 disabled"
62
#endif
63
64
#include <stdint.h>
65
#include <stdlib.h>
66
#include <string.h>
67
68
#include <openssl/asn1.h>
69
#include <openssl/ct.h>
70
#include <openssl/err.h>
71
#include <openssl/objects.h>
72
#include <openssl/x509.h>
73
74
#include "ct_local.h"
75
76
SCT *
77
SCT_new(void)
78
15.7k
{
79
15.7k
  SCT *sct = calloc(1, sizeof(*sct));
80
81
15.7k
  if (sct == NULL) {
82
0
    CTerror(ERR_R_MALLOC_FAILURE);
83
0
    return NULL;
84
0
  }
85
86
15.7k
  sct->entry_type = CT_LOG_ENTRY_TYPE_NOT_SET;
87
15.7k
  sct->version = SCT_VERSION_NOT_SET;
88
15.7k
  return sct;
89
15.7k
}
90
LCRYPTO_ALIAS(SCT_new);
91
92
void
93
SCT_free(SCT *sct)
94
15.7k
{
95
15.7k
  if (sct == NULL)
96
0
    return;
97
98
15.7k
  free(sct->log_id);
99
15.7k
  free(sct->ext);
100
15.7k
  free(sct->sig);
101
15.7k
  free(sct->sct);
102
15.7k
  free(sct);
103
15.7k
}
104
LCRYPTO_ALIAS(SCT_free);
105
106
void
107
SCT_LIST_free(STACK_OF(SCT) *scts)
108
12.3k
{
109
12.3k
  sk_SCT_pop_free(scts, SCT_free);
110
12.3k
}
111
LCRYPTO_ALIAS(SCT_LIST_free);
112
113
int
114
SCT_set_version(SCT *sct, sct_version_t version)
115
0
{
116
0
  if (version != SCT_VERSION_V1) {
117
0
    CTerror(CT_R_UNSUPPORTED_VERSION);
118
0
    return 0;
119
0
  }
120
0
  sct->version = version;
121
0
  sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
122
0
  return 1;
123
0
}
124
LCRYPTO_ALIAS(SCT_set_version);
125
126
int
127
SCT_set_log_entry_type(SCT *sct, ct_log_entry_type_t entry_type)
128
11.5k
{
129
11.5k
  sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
130
131
11.5k
  switch (entry_type) {
132
8.06k
  case CT_LOG_ENTRY_TYPE_X509:
133
11.5k
  case CT_LOG_ENTRY_TYPE_PRECERT:
134
11.5k
    sct->entry_type = entry_type;
135
11.5k
    return 1;
136
0
  case CT_LOG_ENTRY_TYPE_NOT_SET:
137
0
    break;
138
11.5k
  }
139
0
  CTerror(CT_R_UNSUPPORTED_ENTRY_TYPE);
140
0
  return 0;
141
11.5k
}
142
LCRYPTO_ALIAS(SCT_set_log_entry_type);
143
144
int
145
SCT_set0_log_id(SCT *sct, unsigned char *log_id, size_t log_id_len)
146
0
{
147
0
  if (sct->version == SCT_VERSION_V1 && log_id_len != CT_V1_HASHLEN) {
148
0
    CTerror(CT_R_INVALID_LOG_ID_LENGTH);
149
0
    return 0;
150
0
  }
151
152
0
  free(sct->log_id);
153
0
  sct->log_id = log_id;
154
0
  sct->log_id_len = log_id_len;
155
0
  sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
156
0
  return 1;
157
0
}
158
LCRYPTO_ALIAS(SCT_set0_log_id);
159
160
int
161
SCT_set1_log_id(SCT *sct, const unsigned char *log_id, size_t log_id_len)
162
0
{
163
0
  if (sct->version == SCT_VERSION_V1 && log_id_len != CT_V1_HASHLEN) {
164
0
    CTerror(CT_R_INVALID_LOG_ID_LENGTH);
165
0
    return 0;
166
0
  }
167
168
0
  free(sct->log_id);
169
0
  sct->log_id = NULL;
170
0
  sct->log_id_len = 0;
171
0
  sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
172
173
0
  if (log_id != NULL && log_id_len > 0) {
174
0
    sct->log_id = malloc(log_id_len);
175
0
    if (sct->log_id == NULL) {
176
0
      CTerror(ERR_R_MALLOC_FAILURE);
177
0
      return 0;
178
0
    }
179
0
    memcpy(sct->log_id, log_id, log_id_len);
180
0
    sct->log_id_len = log_id_len;
181
0
  }
182
0
  return 1;
183
0
}
184
LCRYPTO_ALIAS(SCT_set1_log_id);
185
186
187
void
188
SCT_set_timestamp(SCT *sct, uint64_t timestamp)
189
0
{
190
0
  sct->timestamp = timestamp;
191
0
  sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
192
0
}
193
LCRYPTO_ALIAS(SCT_set_timestamp);
194
195
int
196
SCT_set_signature_nid(SCT *sct, int nid)
197
0
{
198
0
  switch (nid) {
199
0
  case NID_sha256WithRSAEncryption:
200
0
    sct->hash_alg = 4; /* XXX */
201
0
    sct->sig_alg = 1; /* XXX */
202
0
    sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
203
0
    return 1;
204
0
  case NID_ecdsa_with_SHA256:
205
0
    sct->hash_alg = 4; /* XXX */
206
0
    sct->sig_alg = 3; /* XXX */
207
0
    sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
208
0
    return 1;
209
0
  default:
210
0
    CTerror(CT_R_UNRECOGNIZED_SIGNATURE_NID);
211
0
    return 0;
212
0
  }
213
0
}
214
LCRYPTO_ALIAS(SCT_set_signature_nid);
215
216
void
217
SCT_set0_extensions(SCT *sct, unsigned char *ext, size_t ext_len)
218
0
{
219
0
  free(sct->ext);
220
0
  sct->ext = ext;
221
0
  sct->ext_len = ext_len;
222
0
  sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
223
0
}
224
LCRYPTO_ALIAS(SCT_set0_extensions);
225
226
int
227
SCT_set1_extensions(SCT *sct, const unsigned char *ext, size_t ext_len)
228
0
{
229
0
  free(sct->ext);
230
0
  sct->ext = NULL;
231
0
  sct->ext_len = 0;
232
0
  sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
233
234
0
  if (ext != NULL && ext_len > 0) {
235
0
    sct->ext = malloc(ext_len);
236
0
    if (sct->ext == NULL) {
237
0
      CTerror(ERR_R_MALLOC_FAILURE);
238
0
      return 0;
239
0
    }
240
0
    memcpy(sct->ext, ext, ext_len);
241
0
    sct->ext_len = ext_len;
242
0
  }
243
0
  return 1;
244
0
}
245
LCRYPTO_ALIAS(SCT_set1_extensions);
246
247
void
248
SCT_set0_signature(SCT *sct, unsigned char *sig, size_t sig_len)
249
0
{
250
0
  free(sct->sig);
251
0
  sct->sig = sig;
252
0
  sct->sig_len = sig_len;
253
0
  sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
254
0
}
255
LCRYPTO_ALIAS(SCT_set0_signature);
256
257
int
258
SCT_set1_signature(SCT *sct, const unsigned char *sig, size_t sig_len)
259
4.94k
{
260
4.94k
  free(sct->sig);
261
4.94k
  sct->sig = NULL;
262
4.94k
  sct->sig_len = 0;
263
4.94k
  sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
264
265
4.94k
  if (sig != NULL && sig_len > 0) {
266
4.94k
    sct->sig = malloc(sig_len);
267
4.94k
    if (sct->sig == NULL) {
268
0
      CTerror(ERR_R_MALLOC_FAILURE);
269
0
      return 0;
270
0
    }
271
4.94k
    memcpy(sct->sig, sig, sig_len);
272
4.94k
    sct->sig_len = sig_len;
273
4.94k
  }
274
4.94k
  return 1;
275
4.94k
}
276
LCRYPTO_ALIAS(SCT_set1_signature);
277
278
sct_version_t
279
SCT_get_version(const SCT *sct)
280
0
{
281
0
  return sct->version;
282
0
}
283
LCRYPTO_ALIAS(SCT_get_version);
284
285
ct_log_entry_type_t
286
SCT_get_log_entry_type(const SCT *sct)
287
0
{
288
0
  return sct->entry_type;
289
0
}
290
LCRYPTO_ALIAS(SCT_get_log_entry_type);
291
292
size_t
293
SCT_get0_log_id(const SCT *sct, unsigned char **log_id)
294
0
{
295
0
  *log_id = sct->log_id;
296
0
  return sct->log_id_len;
297
0
}
298
LCRYPTO_ALIAS(SCT_get0_log_id);
299
300
uint64_t
301
SCT_get_timestamp(const SCT *sct)
302
0
{
303
0
  return sct->timestamp;
304
0
}
305
LCRYPTO_ALIAS(SCT_get_timestamp);
306
307
int
308
SCT_get_signature_nid(const SCT *sct)
309
10.0k
{
310
10.0k
  if (sct->version == SCT_VERSION_V1) {
311
    /* XXX sigalg numbers */
312
10.0k
    if (sct->hash_alg == 4) {
313
9.95k
      switch (sct->sig_alg) {
314
4.05k
      case 3:
315
4.05k
        return NID_ecdsa_with_SHA256;
316
5.82k
      case 1:
317
5.82k
        return NID_sha256WithRSAEncryption;
318
79
      default:
319
79
        return NID_undef;
320
9.95k
      }
321
9.95k
    }
322
10.0k
  }
323
103
  return NID_undef;
324
10.0k
}
325
LCRYPTO_ALIAS(SCT_get_signature_nid);
326
327
size_t
328
SCT_get0_extensions(const SCT *sct, unsigned char **ext)
329
0
{
330
0
  *ext = sct->ext;
331
0
  return sct->ext_len;
332
0
}
333
LCRYPTO_ALIAS(SCT_get0_extensions);
334
335
size_t
336
SCT_get0_signature(const SCT *sct, unsigned char **sig)
337
0
{
338
0
  *sig = sct->sig;
339
0
  return sct->sig_len;
340
0
}
341
LCRYPTO_ALIAS(SCT_get0_signature);
342
343
int
344
SCT_is_complete(const SCT *sct)
345
0
{
346
0
  switch (sct->version) {
347
0
  case SCT_VERSION_NOT_SET:
348
0
    return 0;
349
0
  case SCT_VERSION_V1:
350
0
    return sct->log_id != NULL && SCT_signature_is_complete(sct);
351
0
  default:
352
0
    return sct->sct != NULL; /* Just need cached encoding */
353
0
  }
354
0
}
355
356
int
357
SCT_signature_is_complete(const SCT *sct)
358
0
{
359
0
  return SCT_get_signature_nid(sct) != NID_undef &&
360
0
      sct->sig != NULL && sct->sig_len > 0;
361
0
}
362
363
sct_source_t
364
SCT_get_source(const SCT *sct)
365
0
{
366
0
  return sct->source;
367
0
}
368
LCRYPTO_ALIAS(SCT_get_source);
369
370
int
371
SCT_set_source(SCT *sct, sct_source_t source)
372
11.5k
{
373
11.5k
  sct->source = source;
374
11.5k
  sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
375
11.5k
  switch (source) {
376
0
  case SCT_SOURCE_TLS_EXTENSION:
377
8.06k
  case SCT_SOURCE_OCSP_STAPLED_RESPONSE:
378
8.06k
    return SCT_set_log_entry_type(sct, CT_LOG_ENTRY_TYPE_X509);
379
3.47k
  case SCT_SOURCE_X509V3_EXTENSION:
380
3.47k
    return SCT_set_log_entry_type(sct, CT_LOG_ENTRY_TYPE_PRECERT);
381
0
  case SCT_SOURCE_UNKNOWN:
382
0
    break;
383
11.5k
  }
384
  /* if we aren't sure, leave the log entry type alone */
385
0
  return 1;
386
11.5k
}
387
LCRYPTO_ALIAS(SCT_set_source);
388
389
sct_validation_status_t
390
SCT_get_validation_status(const SCT *sct)
391
0
{
392
0
  return sct->validation_status;
393
0
}
394
LCRYPTO_ALIAS(SCT_get_validation_status);
395
396
int
397
SCT_validate(SCT *sct, const CT_POLICY_EVAL_CTX *ctx)
398
0
{
399
0
  int is_sct_valid = -1;
400
0
  SCT_CTX *sctx = NULL;
401
0
  X509_PUBKEY *pub = NULL, *log_pkey = NULL;
402
0
  const CTLOG *log;
403
404
  /*
405
   * With an unrecognized SCT version we don't know what such an SCT means,
406
   * let alone validate one.  So we return validation failure (0).
407
   */
408
0
  if (sct->version != SCT_VERSION_V1) {
409
0
    sct->validation_status = SCT_VALIDATION_STATUS_UNKNOWN_VERSION;
410
0
    return 0;
411
0
  }
412
413
0
  log = CTLOG_STORE_get0_log_by_id(ctx->log_store, sct->log_id,
414
0
      sct->log_id_len);
415
416
  /* Similarly, an SCT from an unknown log also cannot be validated. */
417
0
  if (log == NULL) {
418
0
    sct->validation_status = SCT_VALIDATION_STATUS_UNKNOWN_LOG;
419
0
    return 0;
420
0
  }
421
422
0
  sctx = SCT_CTX_new();
423
0
  if (sctx == NULL)
424
0
    goto err;
425
426
0
  if (X509_PUBKEY_set(&log_pkey, CTLOG_get0_public_key(log)) != 1)
427
0
    goto err;
428
0
  if (SCT_CTX_set1_pubkey(sctx, log_pkey) != 1)
429
0
    goto err;
430
431
0
  if (SCT_get_log_entry_type(sct) == CT_LOG_ENTRY_TYPE_PRECERT) {
432
0
    EVP_PKEY *issuer_pkey;
433
434
0
    if (ctx->issuer == NULL) {
435
0
      sct->validation_status = SCT_VALIDATION_STATUS_UNVERIFIED;
436
0
      goto end;
437
0
    }
438
439
0
    if ((issuer_pkey = X509_get0_pubkey(ctx->issuer)) == NULL)
440
0
      goto err;
441
442
0
    if (X509_PUBKEY_set(&pub, issuer_pkey) != 1)
443
0
      goto err;
444
0
    if (SCT_CTX_set1_issuer_pubkey(sctx, pub) != 1)
445
0
      goto err;
446
0
  }
447
448
0
  SCT_CTX_set_time(sctx, ctx->epoch_time_in_ms);
449
450
  /*
451
   * XXX: Potential for optimization.  This repeats some idempotent heavy
452
   * lifting on the certificate for each candidate SCT, and appears to not
453
   * use any information in the SCT itself, only the certificate is
454
   * processed.  So it may make more sense to to do this just once, perhaps
455
   * associated with the shared (by all SCTs) policy eval ctx.
456
   *
457
   * XXX: Failure here is global (SCT independent) and represents either an
458
   * issue with the certificate (e.g. duplicate extensions) or an out of
459
   * memory condition.  When the certificate is incompatible with CT, we just
460
   * mark the SCTs invalid, rather than report a failure to determine the
461
   * validation status.  That way, callbacks that want to do "soft" SCT
462
   * processing will not abort handshakes with false positive internal
463
   * errors.  Since the function does not distinguish between certificate
464
   * issues (peer's fault) and internal problems (out fault) the safe thing
465
   * to do is to report a validation failure and let the callback or
466
   * application decide what to do.
467
   */
468
0
  if (SCT_CTX_set1_cert(sctx, ctx->cert, NULL) != 1)
469
0
    sct->validation_status = SCT_VALIDATION_STATUS_UNVERIFIED;
470
0
  else
471
0
    sct->validation_status = SCT_CTX_verify(sctx, sct) == 1 ?
472
0
        SCT_VALIDATION_STATUS_VALID : SCT_VALIDATION_STATUS_INVALID;
473
474
0
 end:
475
0
  is_sct_valid = sct->validation_status == SCT_VALIDATION_STATUS_VALID;
476
0
 err:
477
0
  X509_PUBKEY_free(pub);
478
0
  X509_PUBKEY_free(log_pkey);
479
0
  SCT_CTX_free(sctx);
480
481
0
  return is_sct_valid;
482
0
}
483
LCRYPTO_ALIAS(SCT_validate);
484
485
int
486
SCT_LIST_validate(const STACK_OF(SCT) *scts, CT_POLICY_EVAL_CTX *ctx)
487
0
{
488
0
  int are_scts_valid = 1;
489
0
  int sct_count = scts != NULL ? sk_SCT_num(scts) : 0;
490
0
  int i;
491
492
0
  for (i = 0; i < sct_count; ++i) {
493
0
    int is_sct_valid = -1;
494
0
    SCT *sct = sk_SCT_value(scts, i);
495
496
0
    if (sct == NULL)
497
0
      continue;
498
499
0
    is_sct_valid = SCT_validate(sct, ctx);
500
0
    if (is_sct_valid < 0)
501
0
      return is_sct_valid;
502
0
    are_scts_valid &= is_sct_valid;
503
0
  }
504
505
0
  return are_scts_valid;
506
0
}
507
LCRYPTO_ALIAS(SCT_LIST_validate);