1 /* $OpenBSD: ct_oct.c,v 1.9 2023/07/08 07:22:58 beck 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
o2i_SCT_signature(SCT * sct,CBS * cbs)76 o2i_SCT_signature(SCT *sct, CBS *cbs)
77 {
78 uint8_t hash_alg, sig_alg;
79 CBS signature;
80
81 if (sct->version != SCT_VERSION_V1) {
82 CTerror(CT_R_UNSUPPORTED_VERSION);
83 return 0;
84 }
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 if (!CBS_get_u8(cbs, &hash_alg))
91 goto err_invalid;
92 if (!CBS_get_u8(cbs, &sig_alg))
93 goto err_invalid;
94 if (!CBS_get_u16_length_prefixed(cbs, &signature))
95 goto err_invalid;
96 if (CBS_len(cbs) != 0)
97 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 if (CBS_len(&signature) == 0)
104 goto err_invalid;
105
106 sct->hash_alg = hash_alg;
107 sct->sig_alg = sig_alg;
108
109 if (SCT_get_signature_nid(sct) == NID_undef)
110 goto err_invalid;
111
112 if (!SCT_set1_signature(sct, CBS_data(&signature), CBS_len(&signature)))
113 return 0;
114
115 return 1;
116
117 err_invalid:
118 CTerror(CT_R_SCT_INVALID_SIGNATURE);
119 return 0;
120 }
121
122 static int
o2i_SCT_internal(SCT ** out_sct,CBS * cbs)123 o2i_SCT_internal(SCT **out_sct, CBS *cbs)
124 {
125 SCT *sct = NULL;
126 uint8_t version;
127
128 *out_sct = NULL;
129
130 if ((sct = SCT_new()) == NULL)
131 goto err;
132
133 if (CBS_len(cbs) > MAX_SCT_SIZE)
134 goto err_invalid;
135 if (!CBS_peek_u8(cbs, &version))
136 goto err_invalid;
137
138 sct->version = version;
139
140 if (version == SCT_VERSION_V1) {
141 CBS extensions, log_id;
142 uint64_t timestamp;
143
144 /*
145 * Parse a v1 SignedCertificateTimestamp - see RFC 6962
146 * section 3.2.
147 */
148 if (!CBS_get_u8(cbs, &version))
149 goto err_invalid;
150 if (!CBS_get_bytes(cbs, &log_id, CT_V1_LOG_ID_LEN))
151 goto err_invalid;
152 if (!CBS_get_u64(cbs, ×tamp))
153 goto err_invalid;
154 if (!CBS_get_u16_length_prefixed(cbs, &extensions))
155 goto err_invalid;
156
157 if (!CBS_stow(&log_id, &sct->log_id, &sct->log_id_len))
158 goto err;
159
160 sct->timestamp = timestamp;
161
162 if (!CBS_stow(&extensions, &sct->ext, &sct->ext_len))
163 goto err;
164
165 if (!o2i_SCT_signature(sct, cbs))
166 goto err;
167
168 if (CBS_len(cbs) != 0)
169 goto err_invalid;
170 } else {
171 /* If not V1 just cache encoding. */
172 if (!CBS_stow(cbs, &sct->sct, &sct->sct_len))
173 goto err;
174 }
175
176 *out_sct = sct;
177
178 return 1;
179
180 err_invalid:
181 CTerror(CT_R_SCT_INVALID);
182 err:
183 SCT_free(sct);
184
185 return 0;
186 }
187
188 SCT *
o2i_SCT(SCT ** psct,const unsigned char ** in,size_t len)189 o2i_SCT(SCT **psct, const unsigned char **in, size_t len)
190 {
191 SCT *sct;
192 CBS cbs;
193
194 CBS_init(&cbs, *in, len);
195
196 if (psct != NULL) {
197 SCT_free(*psct);
198 *psct = NULL;
199 }
200
201 if (!o2i_SCT_internal(&sct, &cbs))
202 return NULL;
203
204 if (psct != NULL)
205 *psct = sct;
206
207 *in = CBS_data(&cbs);
208
209 return sct;
210 }
211 LCRYPTO_ALIAS(o2i_SCT);
212
213 int
i2o_SCT_signature(const SCT * sct,unsigned char ** out)214 i2o_SCT_signature(const SCT *sct, unsigned char **out)
215 {
216 size_t len;
217 unsigned char *p = NULL, *pstart = NULL;
218
219 if (!SCT_signature_is_complete(sct)) {
220 CTerror(CT_R_SCT_INVALID_SIGNATURE);
221 goto err;
222 }
223
224 if (sct->version != SCT_VERSION_V1) {
225 CTerror(CT_R_UNSUPPORTED_VERSION);
226 goto err;
227 }
228
229 /*
230 * (1 byte) Hash algorithm
231 * (1 byte) Signature algorithm
232 * (2 bytes + ?) Signature
233 */
234 len = 4 + sct->sig_len;
235
236 if (out != NULL) {
237 if (*out != NULL) {
238 p = *out;
239 *out += len;
240 } else {
241 pstart = p = malloc(len);
242 if (p == NULL) {
243 CTerror(ERR_R_MALLOC_FAILURE);
244 goto err;
245 }
246 *out = p;
247 }
248
249 *p++ = sct->hash_alg;
250 *p++ = sct->sig_alg;
251 s2n(sct->sig_len, p);
252 memcpy(p, sct->sig, sct->sig_len);
253 }
254
255 return len;
256 err:
257 free(pstart);
258 return -1;
259 }
260
261 int
i2o_SCT(const SCT * sct,unsigned char ** out)262 i2o_SCT(const SCT *sct, unsigned char **out)
263 {
264 size_t len;
265 unsigned char *p = NULL, *pstart = NULL;
266
267 if (!SCT_is_complete(sct)) {
268 CTerror(CT_R_SCT_NOT_SET);
269 goto err;
270 }
271 /*
272 * Fixed-length header: struct { (1 byte) Version sct_version; (32 bytes)
273 * log_id id; (8 bytes) uint64 timestamp; (2 bytes + ?) CtExtensions
274 * extensions; (1 byte) Hash algorithm (1 byte) Signature algorithm (2
275 * bytes + ?) Signature
276 */
277 if (sct->version == SCT_VERSION_V1)
278 len = 43 + sct->ext_len + 4 + sct->sig_len;
279 else
280 len = sct->sct_len;
281
282 if (out == NULL)
283 return len;
284
285 if (*out != NULL) {
286 p = *out;
287 *out += len;
288 } else {
289 pstart = p = malloc(len);
290 if (p == NULL) {
291 CTerror(ERR_R_MALLOC_FAILURE);
292 goto err;
293 }
294 *out = p;
295 }
296
297 if (sct->version == SCT_VERSION_V1) {
298 *p++ = sct->version;
299 memcpy(p, sct->log_id, CT_V1_HASHLEN);
300 p += CT_V1_HASHLEN;
301 l2n8(sct->timestamp, p);
302 s2n(sct->ext_len, p);
303 if (sct->ext_len > 0) {
304 memcpy(p, sct->ext, sct->ext_len);
305 p += sct->ext_len;
306 }
307 if (i2o_SCT_signature(sct, &p) <= 0)
308 goto err;
309 } else {
310 memcpy(p, sct->sct, len);
311 }
312
313 return len;
314 err:
315 free(pstart);
316 return -1;
317 }
318 LCRYPTO_ALIAS(i2o_SCT);
319
STACK_OF(SCT)320 STACK_OF(SCT) *
321 o2i_SCT_LIST(STACK_OF(SCT) **out_scts, const unsigned char **pp, size_t len)
322 {
323 CBS cbs, cbs_scts, cbs_sct;
324 STACK_OF(SCT) *scts = NULL;
325
326 CBS_init(&cbs, *pp, len);
327
328 if (CBS_len(&cbs) > MAX_SCT_LIST_SIZE)
329 goto err_invalid;
330 if (!CBS_get_u16_length_prefixed(&cbs, &cbs_scts))
331 goto err_invalid;
332 if (CBS_len(&cbs) != 0)
333 goto err_invalid;
334
335 if (out_scts != NULL) {
336 SCT_LIST_free(*out_scts);
337 *out_scts = NULL;
338 }
339
340 if ((scts = sk_SCT_new_null()) == NULL)
341 return NULL;
342
343 while (CBS_len(&cbs_scts) > 0) {
344 SCT *sct;
345
346 if (!CBS_get_u16_length_prefixed(&cbs_scts, &cbs_sct))
347 goto err_invalid;
348
349 if (!o2i_SCT_internal(&sct, &cbs_sct))
350 goto err;
351 if (!sk_SCT_push(scts, sct)) {
352 SCT_free(sct);
353 goto err;
354 }
355 }
356
357 if (out_scts != NULL)
358 *out_scts = scts;
359
360 *pp = CBS_data(&cbs);
361
362 return scts;
363
364 err_invalid:
365 CTerror(CT_R_SCT_LIST_INVALID);
366 err:
367 SCT_LIST_free(scts);
368
369 return NULL;
370 }
371 LCRYPTO_ALIAS(o2i_SCT_LIST);
372
373 int
i2o_SCT_LIST(const STACK_OF (SCT)* a,unsigned char ** pp)374 i2o_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **pp)
375 {
376 int len, sct_len, i, is_pp_new = 0;
377 size_t len2;
378 unsigned char *p = NULL, *p2;
379
380 if (pp != NULL) {
381 if (*pp == NULL) {
382 if ((len = i2o_SCT_LIST(a, NULL)) == -1) {
383 CTerror(CT_R_SCT_LIST_INVALID);
384 return -1;
385 }
386 if ((*pp = malloc(len)) == NULL) {
387 CTerror(ERR_R_MALLOC_FAILURE);
388 return -1;
389 }
390 is_pp_new = 1;
391 }
392 p = *pp + 2;
393 }
394
395 len2 = 2;
396 for (i = 0; i < sk_SCT_num(a); i++) {
397 if (pp != NULL) {
398 p2 = p;
399 p += 2;
400 if ((sct_len = i2o_SCT(sk_SCT_value(a, i), &p)) == -1)
401 goto err;
402 s2n(sct_len, p2);
403 } else {
404 if ((sct_len = i2o_SCT(sk_SCT_value(a, i), NULL)) == -1)
405 goto err;
406 }
407 len2 += 2 + sct_len;
408 }
409
410 if (len2 > MAX_SCT_LIST_SIZE)
411 goto err;
412
413 if (pp != NULL) {
414 p = *pp;
415 s2n(len2 - 2, p);
416 if (!is_pp_new)
417 *pp += len2;
418 }
419 return len2;
420
421 err:
422 if (is_pp_new) {
423 free(*pp);
424 *pp = NULL;
425 }
426 return -1;
427 }
428 LCRYPTO_ALIAS(i2o_SCT_LIST);
429
STACK_OF(SCT)430 STACK_OF(SCT) *
431 d2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp, long len)
432 {
433 ASN1_OCTET_STRING *oct = NULL;
434 STACK_OF(SCT) *sk = NULL;
435 const unsigned char *p;
436
437 p = *pp;
438 if (d2i_ASN1_OCTET_STRING(&oct, &p, len) == NULL)
439 return NULL;
440
441 p = oct->data;
442 if ((sk = o2i_SCT_LIST(a, &p, oct->length)) != NULL)
443 *pp += len;
444
445 ASN1_OCTET_STRING_free(oct);
446 return sk;
447 }
448 LCRYPTO_ALIAS(d2i_SCT_LIST);
449
450 int
i2d_SCT_LIST(const STACK_OF (SCT)* a,unsigned char ** out)451 i2d_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **out)
452 {
453 ASN1_OCTET_STRING oct;
454 int len;
455
456 oct.data = NULL;
457 if ((oct.length = i2o_SCT_LIST(a, &oct.data)) == -1)
458 return -1;
459
460 len = i2d_ASN1_OCTET_STRING(&oct, out);
461 free(oct.data);
462 return len;
463 }
464 LCRYPTO_ALIAS(i2d_SCT_LIST);
465