1 /*
2 * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10 #ifdef OPENSSL_NO_CT
11 #error "CT is disabled"
12 #endif
13
14 #include <stddef.h>
15 #include <string.h>
16
17 #include <openssl/err.h>
18 #include <openssl/obj_mac.h>
19 #include <openssl/x509.h>
20
21 #include "ct_local.h"
22
SCT_CTX_new(OSSL_LIB_CTX * libctx,const char * propq)23 SCT_CTX *SCT_CTX_new(OSSL_LIB_CTX *libctx, const char *propq)
24 {
25 SCT_CTX *sctx = OPENSSL_zalloc(sizeof(*sctx));
26
27 if (sctx == NULL)
28 return NULL;
29
30 sctx->libctx = libctx;
31 if (propq != NULL) {
32 sctx->propq = OPENSSL_strdup(propq);
33 if (sctx->propq == NULL) {
34 OPENSSL_free(sctx);
35 return NULL;
36 }
37 }
38
39 return sctx;
40 }
41
SCT_CTX_free(SCT_CTX * sctx)42 void SCT_CTX_free(SCT_CTX *sctx)
43 {
44 if (sctx == NULL)
45 return;
46 EVP_PKEY_free(sctx->pkey);
47 OPENSSL_free(sctx->pkeyhash);
48 OPENSSL_free(sctx->ihash);
49 OPENSSL_free(sctx->certder);
50 OPENSSL_free(sctx->preder);
51 OPENSSL_free(sctx->propq);
52 OPENSSL_free(sctx);
53 }
54
55 /*
56 * Finds the index of the first extension with the given NID in cert.
57 * If there is more than one extension with that NID, *is_duplicated is set to
58 * 1, otherwise 0 (unless it is NULL).
59 */
ct_x509_get_ext(X509 * cert,int nid,int * is_duplicated)60 static int ct_x509_get_ext(X509 *cert, int nid, int *is_duplicated)
61 {
62 int ret = X509_get_ext_by_NID(cert, nid, -1);
63
64 if (is_duplicated != NULL)
65 *is_duplicated = ret >= 0 && X509_get_ext_by_NID(cert, nid, ret) >= 0;
66
67 return ret;
68 }
69
70 /*
71 * Modifies a certificate by deleting extensions and copying the issuer and
72 * AKID from the presigner certificate, if necessary.
73 * Returns 1 on success, 0 otherwise.
74 */
ct_x509_cert_fixup(X509 * cert,X509 * presigner)75 __owur static int ct_x509_cert_fixup(X509 *cert, X509 *presigner)
76 {
77 int preidx, certidx;
78 int pre_akid_ext_is_dup, cert_akid_ext_is_dup;
79
80 if (presigner == NULL)
81 return 1;
82
83 preidx = ct_x509_get_ext(presigner, NID_authority_key_identifier,
84 &pre_akid_ext_is_dup);
85 certidx = ct_x509_get_ext(cert, NID_authority_key_identifier,
86 &cert_akid_ext_is_dup);
87
88 /* An error occurred whilst searching for the extension */
89 if (preidx < -1 || certidx < -1)
90 return 0;
91 /* Invalid certificate if they contain duplicate extensions */
92 if (pre_akid_ext_is_dup || cert_akid_ext_is_dup)
93 return 0;
94 /* AKID must be present in both certificate or absent in both */
95 if (preidx >= 0 && certidx == -1)
96 return 0;
97 if (preidx == -1 && certidx >= 0)
98 return 0;
99 /* Copy issuer name */
100 if (!X509_set_issuer_name(cert, X509_get_issuer_name(presigner)))
101 return 0;
102 if (preidx != -1) {
103 /* Retrieve and copy AKID encoding */
104 X509_EXTENSION *preext = X509_get_ext(presigner, preidx);
105 X509_EXTENSION *certext = X509_get_ext(cert, certidx);
106 ASN1_OCTET_STRING *preextdata;
107
108 /* Should never happen */
109 if (preext == NULL || certext == NULL)
110 return 0;
111 preextdata = X509_EXTENSION_get_data(preext);
112 if (preextdata == NULL || !X509_EXTENSION_set_data(certext, preextdata))
113 return 0;
114 }
115 return 1;
116 }
117
SCT_CTX_set1_cert(SCT_CTX * sctx,X509 * cert,X509 * presigner)118 int SCT_CTX_set1_cert(SCT_CTX *sctx, X509 *cert, X509 *presigner)
119 {
120 unsigned char *certder = NULL, *preder = NULL;
121 X509 *pretmp = NULL;
122 int certderlen = 0, prederlen = 0;
123 int idx = -1;
124 int poison_ext_is_dup, sct_ext_is_dup;
125 int poison_idx = ct_x509_get_ext(cert, NID_ct_precert_poison, &poison_ext_is_dup);
126
127 /* Duplicate poison extensions are present - error */
128 if (poison_ext_is_dup)
129 goto err;
130
131 /* If *cert doesn't have a poison extension, it isn't a precert */
132 if (poison_idx == -1) {
133 /* cert isn't a precert, so we shouldn't have a presigner */
134 if (presigner != NULL)
135 goto err;
136
137 certderlen = i2d_X509(cert, &certder);
138 if (certderlen < 0)
139 goto err;
140 }
141
142 /* See if cert has a precert SCTs extension */
143 idx = ct_x509_get_ext(cert, NID_ct_precert_scts, &sct_ext_is_dup);
144 /* Duplicate SCT extensions are present - error */
145 if (sct_ext_is_dup)
146 goto err;
147
148 if (idx >= 0 && poison_idx >= 0) {
149 /*
150 * cert can't both contain SCTs (i.e. have an SCT extension) and be a
151 * precert (i.e. have a poison extension).
152 */
153 goto err;
154 }
155
156 if (idx == -1) {
157 idx = poison_idx;
158 }
159
160 /*
161 * If either a poison or SCT extension is present, remove it before encoding
162 * cert. This, along with ct_x509_cert_fixup(), gets a TBSCertificate (see
163 * RFC5280) from cert, which is what the CT log signed when it produced the
164 * SCT.
165 */
166 if (idx >= 0) {
167 /* Take a copy of certificate so we don't modify passed version */
168 pretmp = X509_dup(cert);
169 if (pretmp == NULL)
170 goto err;
171
172 X509_EXTENSION_free(X509_delete_ext(pretmp, idx));
173
174 if (!ct_x509_cert_fixup(pretmp, presigner))
175 goto err;
176
177 prederlen = i2d_re_X509_tbs(pretmp, &preder);
178 if (prederlen <= 0)
179 goto err;
180 }
181
182 X509_free(pretmp);
183
184 OPENSSL_free(sctx->certder);
185 sctx->certder = certder;
186 sctx->certderlen = certderlen;
187
188 OPENSSL_free(sctx->preder);
189 sctx->preder = preder;
190 sctx->prederlen = prederlen;
191
192 return 1;
193 err:
194 OPENSSL_free(certder);
195 OPENSSL_free(preder);
196 X509_free(pretmp);
197 return 0;
198 }
199
ct_public_key_hash(SCT_CTX * sctx,X509_PUBKEY * pkey,unsigned char ** hash,size_t * hash_len)200 __owur static int ct_public_key_hash(SCT_CTX *sctx, X509_PUBKEY *pkey,
201 unsigned char **hash, size_t *hash_len)
202 {
203 int ret = 0;
204 unsigned char *md = NULL, *der = NULL;
205 int der_len;
206 unsigned int md_len;
207 EVP_MD *sha256 = EVP_MD_fetch(sctx->libctx, "SHA2-256", sctx->propq);
208
209 if (sha256 == NULL)
210 goto err;
211
212 /* Reuse buffer if possible */
213 if (*hash != NULL && *hash_len >= SHA256_DIGEST_LENGTH) {
214 md = *hash;
215 } else {
216 md = OPENSSL_malloc(SHA256_DIGEST_LENGTH);
217 if (md == NULL)
218 goto err;
219 }
220
221 /* Calculate key hash */
222 der_len = i2d_X509_PUBKEY(pkey, &der);
223 if (der_len <= 0)
224 goto err;
225
226 if (!EVP_Digest(der, der_len, md, &md_len, sha256, NULL))
227 goto err;
228
229 if (md != *hash) {
230 OPENSSL_free(*hash);
231 *hash = md;
232 *hash_len = SHA256_DIGEST_LENGTH;
233 }
234
235 md = NULL;
236 ret = 1;
237 err:
238 EVP_MD_free(sha256);
239 OPENSSL_free(md);
240 OPENSSL_free(der);
241 return ret;
242 }
243
SCT_CTX_set1_issuer(SCT_CTX * sctx,const X509 * issuer)244 int SCT_CTX_set1_issuer(SCT_CTX *sctx, const X509 *issuer)
245 {
246 return SCT_CTX_set1_issuer_pubkey(sctx, X509_get_X509_PUBKEY(issuer));
247 }
248
SCT_CTX_set1_issuer_pubkey(SCT_CTX * sctx,X509_PUBKEY * pubkey)249 int SCT_CTX_set1_issuer_pubkey(SCT_CTX *sctx, X509_PUBKEY *pubkey)
250 {
251 return ct_public_key_hash(sctx, pubkey, &sctx->ihash, &sctx->ihashlen);
252 }
253
SCT_CTX_set1_pubkey(SCT_CTX * sctx,X509_PUBKEY * pubkey)254 int SCT_CTX_set1_pubkey(SCT_CTX *sctx, X509_PUBKEY *pubkey)
255 {
256 EVP_PKEY *pkey = X509_PUBKEY_get(pubkey);
257
258 if (pkey == NULL)
259 return 0;
260
261 if (!ct_public_key_hash(sctx, pubkey, &sctx->pkeyhash, &sctx->pkeyhashlen)) {
262 EVP_PKEY_free(pkey);
263 return 0;
264 }
265
266 EVP_PKEY_free(sctx->pkey);
267 sctx->pkey = pkey;
268 return 1;
269 }
270
SCT_CTX_set_time(SCT_CTX * sctx,uint64_t time_in_ms)271 void SCT_CTX_set_time(SCT_CTX *sctx, uint64_t time_in_ms)
272 {
273 sctx->epoch_time_in_ms = time_in_ms;
274 }
275