diff options
Diffstat (limited to 'src/lib/libcrypto/ct/ct_sct.c')
-rw-r--r-- | src/lib/libcrypto/ct/ct_sct.c | 507 |
1 files changed, 0 insertions, 507 deletions
diff --git a/src/lib/libcrypto/ct/ct_sct.c b/src/lib/libcrypto/ct/ct_sct.c deleted file mode 100644 index 4b2716e734..0000000000 --- a/src/lib/libcrypto/ct/ct_sct.c +++ /dev/null | |||
@@ -1,507 +0,0 @@ | |||
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 | { | ||
79 | SCT *sct = calloc(1, sizeof(*sct)); | ||
80 | |||
81 | if (sct == NULL) { | ||
82 | CTerror(ERR_R_MALLOC_FAILURE); | ||
83 | return NULL; | ||
84 | } | ||
85 | |||
86 | sct->entry_type = CT_LOG_ENTRY_TYPE_NOT_SET; | ||
87 | sct->version = SCT_VERSION_NOT_SET; | ||
88 | return sct; | ||
89 | } | ||
90 | LCRYPTO_ALIAS(SCT_new); | ||
91 | |||
92 | void | ||
93 | SCT_free(SCT *sct) | ||
94 | { | ||
95 | if (sct == NULL) | ||
96 | return; | ||
97 | |||
98 | free(sct->log_id); | ||
99 | free(sct->ext); | ||
100 | free(sct->sig); | ||
101 | free(sct->sct); | ||
102 | free(sct); | ||
103 | } | ||
104 | LCRYPTO_ALIAS(SCT_free); | ||
105 | |||
106 | void | ||
107 | SCT_LIST_free(STACK_OF(SCT) *scts) | ||
108 | { | ||
109 | sk_SCT_pop_free(scts, SCT_free); | ||
110 | } | ||
111 | LCRYPTO_ALIAS(SCT_LIST_free); | ||
112 | |||
113 | int | ||
114 | SCT_set_version(SCT *sct, sct_version_t version) | ||
115 | { | ||
116 | if (version != SCT_VERSION_V1) { | ||
117 | CTerror(CT_R_UNSUPPORTED_VERSION); | ||
118 | return 0; | ||
119 | } | ||
120 | sct->version = version; | ||
121 | sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET; | ||
122 | return 1; | ||
123 | } | ||
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 | { | ||
129 | sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET; | ||
130 | |||
131 | switch (entry_type) { | ||
132 | case CT_LOG_ENTRY_TYPE_X509: | ||
133 | case CT_LOG_ENTRY_TYPE_PRECERT: | ||
134 | sct->entry_type = entry_type; | ||
135 | return 1; | ||
136 | case CT_LOG_ENTRY_TYPE_NOT_SET: | ||
137 | break; | ||
138 | } | ||
139 | CTerror(CT_R_UNSUPPORTED_ENTRY_TYPE); | ||
140 | return 0; | ||
141 | } | ||
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 | { | ||
147 | if (sct->version == SCT_VERSION_V1 && log_id_len != CT_V1_HASHLEN) { | ||
148 | CTerror(CT_R_INVALID_LOG_ID_LENGTH); | ||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | free(sct->log_id); | ||
153 | sct->log_id = log_id; | ||
154 | sct->log_id_len = log_id_len; | ||
155 | sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET; | ||
156 | return 1; | ||
157 | } | ||
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 | { | ||
163 | if (sct->version == SCT_VERSION_V1 && log_id_len != CT_V1_HASHLEN) { | ||
164 | CTerror(CT_R_INVALID_LOG_ID_LENGTH); | ||
165 | return 0; | ||
166 | } | ||
167 | |||
168 | free(sct->log_id); | ||
169 | sct->log_id = NULL; | ||
170 | sct->log_id_len = 0; | ||
171 | sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET; | ||
172 | |||
173 | if (log_id != NULL && log_id_len > 0) { | ||
174 | sct->log_id = malloc(log_id_len); | ||
175 | if (sct->log_id == NULL) { | ||
176 | CTerror(ERR_R_MALLOC_FAILURE); | ||
177 | return 0; | ||
178 | } | ||
179 | memcpy(sct->log_id, log_id, log_id_len); | ||
180 | sct->log_id_len = log_id_len; | ||
181 | } | ||
182 | return 1; | ||
183 | } | ||
184 | LCRYPTO_ALIAS(SCT_set1_log_id); | ||
185 | |||
186 | |||
187 | void | ||
188 | SCT_set_timestamp(SCT *sct, uint64_t timestamp) | ||
189 | { | ||
190 | sct->timestamp = timestamp; | ||
191 | sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET; | ||
192 | } | ||
193 | LCRYPTO_ALIAS(SCT_set_timestamp); | ||
194 | |||
195 | int | ||
196 | SCT_set_signature_nid(SCT *sct, int nid) | ||
197 | { | ||
198 | switch (nid) { | ||
199 | case NID_sha256WithRSAEncryption: | ||
200 | sct->hash_alg = 4; /* XXX */ | ||
201 | sct->sig_alg = 1; /* XXX */ | ||
202 | sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET; | ||
203 | return 1; | ||
204 | case NID_ecdsa_with_SHA256: | ||
205 | sct->hash_alg = 4; /* XXX */ | ||
206 | sct->sig_alg = 3; /* XXX */ | ||
207 | sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET; | ||
208 | return 1; | ||
209 | default: | ||
210 | CTerror(CT_R_UNRECOGNIZED_SIGNATURE_NID); | ||
211 | return 0; | ||
212 | } | ||
213 | } | ||
214 | LCRYPTO_ALIAS(SCT_set_signature_nid); | ||
215 | |||
216 | void | ||
217 | SCT_set0_extensions(SCT *sct, unsigned char *ext, size_t ext_len) | ||
218 | { | ||
219 | free(sct->ext); | ||
220 | sct->ext = ext; | ||
221 | sct->ext_len = ext_len; | ||
222 | sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET; | ||
223 | } | ||
224 | LCRYPTO_ALIAS(SCT_set0_extensions); | ||
225 | |||
226 | int | ||
227 | SCT_set1_extensions(SCT *sct, const unsigned char *ext, size_t ext_len) | ||
228 | { | ||
229 | free(sct->ext); | ||
230 | sct->ext = NULL; | ||
231 | sct->ext_len = 0; | ||
232 | sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET; | ||
233 | |||
234 | if (ext != NULL && ext_len > 0) { | ||
235 | sct->ext = malloc(ext_len); | ||
236 | if (sct->ext == NULL) { | ||
237 | CTerror(ERR_R_MALLOC_FAILURE); | ||
238 | return 0; | ||
239 | } | ||
240 | memcpy(sct->ext, ext, ext_len); | ||
241 | sct->ext_len = ext_len; | ||
242 | } | ||
243 | return 1; | ||
244 | } | ||
245 | LCRYPTO_ALIAS(SCT_set1_extensions); | ||
246 | |||
247 | void | ||
248 | SCT_set0_signature(SCT *sct, unsigned char *sig, size_t sig_len) | ||
249 | { | ||
250 | free(sct->sig); | ||
251 | sct->sig = sig; | ||
252 | sct->sig_len = sig_len; | ||
253 | sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET; | ||
254 | } | ||
255 | LCRYPTO_ALIAS(SCT_set0_signature); | ||
256 | |||
257 | int | ||
258 | SCT_set1_signature(SCT *sct, const unsigned char *sig, size_t sig_len) | ||
259 | { | ||
260 | free(sct->sig); | ||
261 | sct->sig = NULL; | ||
262 | sct->sig_len = 0; | ||
263 | sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET; | ||
264 | |||
265 | if (sig != NULL && sig_len > 0) { | ||
266 | sct->sig = malloc(sig_len); | ||
267 | if (sct->sig == NULL) { | ||
268 | CTerror(ERR_R_MALLOC_FAILURE); | ||
269 | return 0; | ||
270 | } | ||
271 | memcpy(sct->sig, sig, sig_len); | ||
272 | sct->sig_len = sig_len; | ||
273 | } | ||
274 | return 1; | ||
275 | } | ||
276 | LCRYPTO_ALIAS(SCT_set1_signature); | ||
277 | |||
278 | sct_version_t | ||
279 | SCT_get_version(const SCT *sct) | ||
280 | { | ||
281 | return sct->version; | ||
282 | } | ||
283 | LCRYPTO_ALIAS(SCT_get_version); | ||
284 | |||
285 | ct_log_entry_type_t | ||
286 | SCT_get_log_entry_type(const SCT *sct) | ||
287 | { | ||
288 | return sct->entry_type; | ||
289 | } | ||
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 | { | ||
295 | *log_id = sct->log_id; | ||
296 | return sct->log_id_len; | ||
297 | } | ||
298 | LCRYPTO_ALIAS(SCT_get0_log_id); | ||
299 | |||
300 | uint64_t | ||
301 | SCT_get_timestamp(const SCT *sct) | ||
302 | { | ||
303 | return sct->timestamp; | ||
304 | } | ||
305 | LCRYPTO_ALIAS(SCT_get_timestamp); | ||
306 | |||
307 | int | ||
308 | SCT_get_signature_nid(const SCT *sct) | ||
309 | { | ||
310 | if (sct->version == SCT_VERSION_V1) { | ||
311 | /* XXX sigalg numbers */ | ||
312 | if (sct->hash_alg == 4) { | ||
313 | switch (sct->sig_alg) { | ||
314 | case 3: | ||
315 | return NID_ecdsa_with_SHA256; | ||
316 | case 1: | ||
317 | return NID_sha256WithRSAEncryption; | ||
318 | default: | ||
319 | return NID_undef; | ||
320 | } | ||
321 | } | ||
322 | } | ||
323 | return NID_undef; | ||
324 | } | ||
325 | LCRYPTO_ALIAS(SCT_get_signature_nid); | ||
326 | |||
327 | size_t | ||
328 | SCT_get0_extensions(const SCT *sct, unsigned char **ext) | ||
329 | { | ||
330 | *ext = sct->ext; | ||
331 | return sct->ext_len; | ||
332 | } | ||
333 | LCRYPTO_ALIAS(SCT_get0_extensions); | ||
334 | |||
335 | size_t | ||
336 | SCT_get0_signature(const SCT *sct, unsigned char **sig) | ||
337 | { | ||
338 | *sig = sct->sig; | ||
339 | return sct->sig_len; | ||
340 | } | ||
341 | LCRYPTO_ALIAS(SCT_get0_signature); | ||
342 | |||
343 | int | ||
344 | SCT_is_complete(const SCT *sct) | ||
345 | { | ||
346 | switch (sct->version) { | ||
347 | case SCT_VERSION_NOT_SET: | ||
348 | return 0; | ||
349 | case SCT_VERSION_V1: | ||
350 | return sct->log_id != NULL && SCT_signature_is_complete(sct); | ||
351 | default: | ||
352 | return sct->sct != NULL; /* Just need cached encoding */ | ||
353 | } | ||
354 | } | ||
355 | |||
356 | int | ||
357 | SCT_signature_is_complete(const SCT *sct) | ||
358 | { | ||
359 | return SCT_get_signature_nid(sct) != NID_undef && | ||
360 | sct->sig != NULL && sct->sig_len > 0; | ||
361 | } | ||
362 | |||
363 | sct_source_t | ||
364 | SCT_get_source(const SCT *sct) | ||
365 | { | ||
366 | return sct->source; | ||
367 | } | ||
368 | LCRYPTO_ALIAS(SCT_get_source); | ||
369 | |||
370 | int | ||
371 | SCT_set_source(SCT *sct, sct_source_t source) | ||
372 | { | ||
373 | sct->source = source; | ||
374 | sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET; | ||
375 | switch (source) { | ||
376 | case SCT_SOURCE_TLS_EXTENSION: | ||
377 | case SCT_SOURCE_OCSP_STAPLED_RESPONSE: | ||
378 | return SCT_set_log_entry_type(sct, CT_LOG_ENTRY_TYPE_X509); | ||
379 | case SCT_SOURCE_X509V3_EXTENSION: | ||
380 | return SCT_set_log_entry_type(sct, CT_LOG_ENTRY_TYPE_PRECERT); | ||
381 | case SCT_SOURCE_UNKNOWN: | ||
382 | break; | ||
383 | } | ||
384 | /* if we aren't sure, leave the log entry type alone */ | ||
385 | return 1; | ||
386 | } | ||
387 | LCRYPTO_ALIAS(SCT_set_source); | ||
388 | |||
389 | sct_validation_status_t | ||
390 | SCT_get_validation_status(const SCT *sct) | ||
391 | { | ||
392 | return sct->validation_status; | ||
393 | } | ||
394 | LCRYPTO_ALIAS(SCT_get_validation_status); | ||
395 | |||
396 | int | ||
397 | SCT_validate(SCT *sct, const CT_POLICY_EVAL_CTX *ctx) | ||
398 | { | ||
399 | int is_sct_valid = -1; | ||
400 | SCT_CTX *sctx = NULL; | ||
401 | X509_PUBKEY *pub = NULL, *log_pkey = NULL; | ||
402 | 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 | if (sct->version != SCT_VERSION_V1) { | ||
409 | sct->validation_status = SCT_VALIDATION_STATUS_UNKNOWN_VERSION; | ||
410 | return 0; | ||
411 | } | ||
412 | |||
413 | log = CTLOG_STORE_get0_log_by_id(ctx->log_store, sct->log_id, | ||
414 | sct->log_id_len); | ||
415 | |||
416 | /* Similarly, an SCT from an unknown log also cannot be validated. */ | ||
417 | if (log == NULL) { | ||
418 | sct->validation_status = SCT_VALIDATION_STATUS_UNKNOWN_LOG; | ||
419 | return 0; | ||
420 | } | ||
421 | |||
422 | sctx = SCT_CTX_new(); | ||
423 | if (sctx == NULL) | ||
424 | goto err; | ||
425 | |||
426 | if (X509_PUBKEY_set(&log_pkey, CTLOG_get0_public_key(log)) != 1) | ||
427 | goto err; | ||
428 | if (SCT_CTX_set1_pubkey(sctx, log_pkey) != 1) | ||
429 | goto err; | ||
430 | |||
431 | if (SCT_get_log_entry_type(sct) == CT_LOG_ENTRY_TYPE_PRECERT) { | ||
432 | EVP_PKEY *issuer_pkey; | ||
433 | |||
434 | if (ctx->issuer == NULL) { | ||
435 | sct->validation_status = SCT_VALIDATION_STATUS_UNVERIFIED; | ||
436 | goto end; | ||
437 | } | ||
438 | |||
439 | if ((issuer_pkey = X509_get0_pubkey(ctx->issuer)) == NULL) | ||
440 | goto err; | ||
441 | |||
442 | if (X509_PUBKEY_set(&pub, issuer_pkey) != 1) | ||
443 | goto err; | ||
444 | if (SCT_CTX_set1_issuer_pubkey(sctx, pub) != 1) | ||
445 | goto err; | ||
446 | } | ||
447 | |||
448 | 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 | if (SCT_CTX_set1_cert(sctx, ctx->cert, NULL) != 1) | ||
469 | sct->validation_status = SCT_VALIDATION_STATUS_UNVERIFIED; | ||
470 | else | ||
471 | sct->validation_status = SCT_CTX_verify(sctx, sct) == 1 ? | ||
472 | SCT_VALIDATION_STATUS_VALID : SCT_VALIDATION_STATUS_INVALID; | ||
473 | |||
474 | end: | ||
475 | is_sct_valid = sct->validation_status == SCT_VALIDATION_STATUS_VALID; | ||
476 | err: | ||
477 | X509_PUBKEY_free(pub); | ||
478 | X509_PUBKEY_free(log_pkey); | ||
479 | SCT_CTX_free(sctx); | ||
480 | |||
481 | return is_sct_valid; | ||
482 | } | ||
483 | LCRYPTO_ALIAS(SCT_validate); | ||
484 | |||
485 | int | ||
486 | SCT_LIST_validate(const STACK_OF(SCT) *scts, CT_POLICY_EVAL_CTX *ctx) | ||
487 | { | ||
488 | int are_scts_valid = 1; | ||
489 | int sct_count = scts != NULL ? sk_SCT_num(scts) : 0; | ||
490 | int i; | ||
491 | |||
492 | for (i = 0; i < sct_count; ++i) { | ||
493 | int is_sct_valid = -1; | ||
494 | SCT *sct = sk_SCT_value(scts, i); | ||
495 | |||
496 | if (sct == NULL) | ||
497 | continue; | ||
498 | |||
499 | is_sct_valid = SCT_validate(sct, ctx); | ||
500 | if (is_sct_valid < 0) | ||
501 | return is_sct_valid; | ||
502 | are_scts_valid &= is_sct_valid; | ||
503 | } | ||
504 | |||
505 | return are_scts_valid; | ||
506 | } | ||
507 | LCRYPTO_ALIAS(SCT_LIST_validate); | ||