summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/ct/ct_sct_ctx.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/ct/ct_sct_ctx.c')
-rw-r--r--src/lib/libcrypto/ct/ct_sct_ctx.c323
1 files changed, 0 insertions, 323 deletions
diff --git a/src/lib/libcrypto/ct/ct_sct_ctx.c b/src/lib/libcrypto/ct/ct_sct_ctx.c
deleted file mode 100644
index b2b6d4e269..0000000000
--- a/src/lib/libcrypto/ct/ct_sct_ctx.c
+++ /dev/null
@@ -1,323 +0,0 @@
1/* $OpenBSD: ct_sct_ctx.c,v 1.6 2022/06/30 11:14:47 tb 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 <stddef.h>
65#include <string.h>
66
67#include <openssl/err.h>
68#include <openssl/objects.h>
69#include <openssl/x509.h>
70
71#include "ct_local.h"
72
73SCT_CTX *
74SCT_CTX_new(void)
75{
76 SCT_CTX *sctx = calloc(1, sizeof(*sctx));
77
78 if (sctx == NULL)
79 CTerror(ERR_R_MALLOC_FAILURE);
80
81 return sctx;
82}
83
84void
85SCT_CTX_free(SCT_CTX *sctx)
86{
87 if (sctx == NULL)
88 return;
89 EVP_PKEY_free(sctx->pkey);
90 free(sctx->pkeyhash);
91 free(sctx->ihash);
92 free(sctx->certder);
93 free(sctx->preder);
94 free(sctx);
95}
96
97/*
98 * Finds the index of the first extension with the given NID in cert.
99 * If there is more than one extension with that NID, *is_duplicated is set to
100 * 1, otherwise 0 (unless it is NULL).
101 */
102static int
103ct_x509_get_ext(X509 *cert, int nid, int *is_duplicated)
104{
105 int ret = X509_get_ext_by_NID(cert, nid, -1);
106
107 if (is_duplicated != NULL)
108 *is_duplicated = ret >= 0 &&
109 X509_get_ext_by_NID(cert, nid, ret) >= 0;
110
111 return ret;
112}
113
114/*
115 * Modifies a certificate by deleting extensions and copying the issuer and
116 * AKID from the presigner certificate, if necessary.
117 * Returns 1 on success, 0 otherwise.
118 */
119static int
120ct_x509_cert_fixup(X509 *cert, X509 *presigner)
121{
122 int preidx, certidx;
123 int pre_akid_ext_is_dup, cert_akid_ext_is_dup;
124
125 if (presigner == NULL)
126 return 1;
127
128 preidx = ct_x509_get_ext(presigner, NID_authority_key_identifier,
129 &pre_akid_ext_is_dup);
130 certidx = ct_x509_get_ext(cert, NID_authority_key_identifier,
131 &cert_akid_ext_is_dup);
132
133 /* An error occurred whilst searching for the extension */
134 if (preidx < -1 || certidx < -1)
135 return 0;
136 /* Invalid certificate if they contain duplicate extensions */
137 if (pre_akid_ext_is_dup || cert_akid_ext_is_dup)
138 return 0;
139 /* AKID must be present in both certificate or absent in both */
140 if (preidx >= 0 && certidx == -1)
141 return 0;
142 if (preidx == -1 && certidx >= 0)
143 return 0;
144 /* Copy issuer name */
145 if (!X509_set_issuer_name(cert, X509_get_issuer_name(presigner)))
146 return 0;
147 if (preidx != -1) {
148 /* Retrieve and copy AKID encoding */
149 X509_EXTENSION *preext = X509_get_ext(presigner, preidx);
150 X509_EXTENSION *certext = X509_get_ext(cert, certidx);
151 ASN1_OCTET_STRING *preextdata;
152
153 /* Should never happen */
154 if (preext == NULL || certext == NULL)
155 return 0;
156 preextdata = X509_EXTENSION_get_data(preext);
157 if (preextdata == NULL ||
158 !X509_EXTENSION_set_data(certext, preextdata))
159 return 0;
160 }
161 return 1;
162}
163
164int
165SCT_CTX_set1_cert(SCT_CTX *sctx, X509 *cert, X509 *presigner)
166{
167 unsigned char *certder = NULL, *preder = NULL;
168 X509 *pretmp = NULL;
169 int certderlen = 0, prederlen = 0;
170 int idx = -1;
171 int poison_ext_is_dup, sct_ext_is_dup;
172 int poison_idx = ct_x509_get_ext(cert, NID_ct_precert_poison, &poison_ext_is_dup);
173
174 /* Duplicate poison extensions are present - error */
175 if (poison_ext_is_dup)
176 goto err;
177
178 /* If *cert doesn't have a poison extension, it isn't a precert */
179 if (poison_idx == -1) {
180 /* cert isn't a precert, so we shouldn't have a presigner */
181 if (presigner != NULL)
182 goto err;
183
184 certderlen = i2d_X509(cert, &certder);
185 if (certderlen < 0)
186 goto err;
187 }
188
189 /* See if cert has a precert SCTs extension */
190 idx = ct_x509_get_ext(cert, NID_ct_precert_scts, &sct_ext_is_dup);
191 /* Duplicate SCT extensions are present - error */
192 if (sct_ext_is_dup)
193 goto err;
194
195 if (idx >= 0 && poison_idx >= 0) {
196 /*
197 * cert can't both contain SCTs (i.e. have an SCT extension) and be a
198 * precert (i.e. have a poison extension).
199 */
200 goto err;
201 }
202
203 if (idx == -1) {
204 idx = poison_idx;
205 }
206
207 /*
208 * If either a poison or SCT extension is present, remove it before encoding
209 * cert. This, along with ct_x509_cert_fixup(), gets a TBSCertificate (see
210 * RFC5280) from cert, which is what the CT log signed when it produced the
211 * SCT.
212 */
213 if (idx >= 0) {
214 X509_EXTENSION *ext;
215
216 /* Take a copy of certificate so we don't modify passed version */
217 pretmp = X509_dup(cert);
218 if (pretmp == NULL)
219 goto err;
220
221 ext = X509_delete_ext(pretmp, idx);
222 X509_EXTENSION_free(ext);
223
224 if (!ct_x509_cert_fixup(pretmp, presigner))
225 goto err;
226
227 prederlen = i2d_re_X509_tbs(pretmp, &preder);
228 if (prederlen <= 0)
229 goto err;
230 }
231
232 X509_free(pretmp);
233
234 free(sctx->certder);
235 sctx->certder = certder;
236 sctx->certderlen = certderlen;
237
238 free(sctx->preder);
239 sctx->preder = preder;
240 sctx->prederlen = prederlen;
241
242 return 1;
243 err:
244 free(certder);
245 free(preder);
246 X509_free(pretmp);
247 return 0;
248}
249
250static int
251ct_public_key_hash(X509_PUBKEY *pkey, unsigned char **hash, size_t *hash_len)
252{
253 int ret = 0;
254 unsigned char *md = NULL, *der = NULL;
255 int der_len;
256 unsigned int md_len;
257
258 /* Reuse buffer if possible */
259 if (*hash != NULL && *hash_len >= SHA256_DIGEST_LENGTH) {
260 md = *hash;
261 } else {
262 md = malloc(SHA256_DIGEST_LENGTH);
263 if (md == NULL)
264 goto err;
265 }
266
267 /* Calculate key hash */
268 der_len = i2d_X509_PUBKEY(pkey, &der);
269 if (der_len <= 0)
270 goto err;
271
272 if (!EVP_Digest(der, der_len, md, &md_len, EVP_sha256(), NULL))
273 goto err;
274
275 if (md != *hash) {
276 free(*hash);
277 *hash = md;
278 *hash_len = SHA256_DIGEST_LENGTH;
279 }
280
281 md = NULL;
282 ret = 1;
283 err:
284 free(md);
285 free(der);
286 return ret;
287}
288
289int
290SCT_CTX_set1_issuer(SCT_CTX *sctx, const X509 *issuer)
291{
292 return SCT_CTX_set1_issuer_pubkey(sctx, X509_get_X509_PUBKEY(issuer));
293}
294
295int
296SCT_CTX_set1_issuer_pubkey(SCT_CTX *sctx, X509_PUBKEY *pubkey)
297{
298 return ct_public_key_hash(pubkey, &sctx->ihash, &sctx->ihashlen);
299}
300
301int
302SCT_CTX_set1_pubkey(SCT_CTX *sctx, X509_PUBKEY *pubkey)
303{
304 EVP_PKEY *pkey = X509_PUBKEY_get(pubkey);
305
306 if (pkey == NULL)
307 return 0;
308
309 if (!ct_public_key_hash(pubkey, &sctx->pkeyhash, &sctx->pkeyhashlen)) {
310 EVP_PKEY_free(pkey);
311 return 0;
312 }
313
314 EVP_PKEY_free(sctx->pkey);
315 sctx->pkey = pkey;
316 return 1;
317}
318
319void
320SCT_CTX_set_time(SCT_CTX *sctx, uint64_t time_in_ms)
321{
322 sctx->epoch_time_in_ms = time_in_ms;
323}