xref: /dragonfly/crypto/libressl/crypto/ct/ct_oct.c (revision 6f5ec8b5)
1 /*	$OpenBSD: ct_oct.c,v 1.8 2021/12/20 17:23:07 jsing 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
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
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, &timestamp))
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 *
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 
212 int
213 i2o_SCT_signature(const SCT *sct, unsigned char **out)
214 {
215 	size_t len;
216 	unsigned char *p = NULL, *pstart = NULL;
217 
218 	if (!SCT_signature_is_complete(sct)) {
219 		CTerror(CT_R_SCT_INVALID_SIGNATURE);
220 		goto err;
221 	}
222 
223 	if (sct->version != SCT_VERSION_V1) {
224 		CTerror(CT_R_UNSUPPORTED_VERSION);
225 		goto err;
226 	}
227 
228 	/*
229 	 * (1 byte) Hash algorithm
230 	 * (1 byte) Signature algorithm
231 	 * (2 bytes + ?) Signature
232 	 */
233 	len = 4 + sct->sig_len;
234 
235 	if (out != NULL) {
236 		if (*out != NULL) {
237 			p = *out;
238 			*out += len;
239 		} else {
240 			pstart = p = malloc(len);
241 			if (p == NULL) {
242 				CTerror(ERR_R_MALLOC_FAILURE);
243 				goto err;
244 			}
245 			*out = p;
246 		}
247 
248 		*p++ = sct->hash_alg;
249 		*p++ = sct->sig_alg;
250 		s2n(sct->sig_len, p);
251 		memcpy(p, sct->sig, sct->sig_len);
252 	}
253 
254 	return len;
255  err:
256 	free(pstart);
257 	return -1;
258 }
259 
260 int
261 i2o_SCT(const SCT *sct, unsigned char **out)
262 {
263 	size_t len;
264 	unsigned char *p = NULL, *pstart = NULL;
265 
266 	if (!SCT_is_complete(sct)) {
267 		CTerror(CT_R_SCT_NOT_SET);
268 		goto err;
269 	}
270 	/*
271 	 * Fixed-length header: struct { (1 byte) Version sct_version; (32 bytes)
272 	 * log_id id; (8 bytes) uint64 timestamp; (2 bytes + ?) CtExtensions
273 	 * extensions; (1 byte) Hash algorithm (1 byte) Signature algorithm (2
274 	 * bytes + ?) Signature
275 	 */
276 	if (sct->version == SCT_VERSION_V1)
277 		len = 43 + sct->ext_len + 4 + sct->sig_len;
278 	else
279 		len = sct->sct_len;
280 
281 	if (out == NULL)
282 		return len;
283 
284 	if (*out != NULL) {
285 		p = *out;
286 		*out += len;
287 	} else {
288 		pstart = p = malloc(len);
289 		if (p == NULL) {
290 			CTerror(ERR_R_MALLOC_FAILURE);
291 			goto err;
292 		}
293 		*out = p;
294 	}
295 
296 	if (sct->version == SCT_VERSION_V1) {
297 		*p++ = sct->version;
298 		memcpy(p, sct->log_id, CT_V1_HASHLEN);
299 		p += CT_V1_HASHLEN;
300 		l2n8(sct->timestamp, p);
301 		s2n(sct->ext_len, p);
302 		if (sct->ext_len > 0) {
303 			memcpy(p, sct->ext, sct->ext_len);
304 			p += sct->ext_len;
305 		}
306 		if (i2o_SCT_signature(sct, &p) <= 0)
307 			goto err;
308 	} else {
309 		memcpy(p, sct->sct, len);
310 	}
311 
312 	return len;
313  err:
314 	free(pstart);
315 	return -1;
316 }
317 
318 STACK_OF(SCT) *
319 o2i_SCT_LIST(STACK_OF(SCT) **out_scts, const unsigned char **pp, size_t len)
320 {
321 	CBS cbs, cbs_scts, cbs_sct;
322 	STACK_OF(SCT) *scts = NULL;
323 
324 	CBS_init(&cbs, *pp, len);
325 
326 	if (CBS_len(&cbs) > MAX_SCT_LIST_SIZE)
327 		goto err_invalid;
328 	if (!CBS_get_u16_length_prefixed(&cbs, &cbs_scts))
329 		goto err_invalid;
330 	if (CBS_len(&cbs) != 0)
331 		goto err_invalid;
332 
333 	if (out_scts != NULL) {
334 		SCT_LIST_free(*out_scts);
335 		*out_scts = NULL;
336 	}
337 
338 	if ((scts = sk_SCT_new_null()) == NULL)
339 		return NULL;
340 
341 	while (CBS_len(&cbs_scts) > 0) {
342 		SCT *sct;
343 
344 		if (!CBS_get_u16_length_prefixed(&cbs_scts, &cbs_sct))
345 			goto err_invalid;
346 
347 		if (!o2i_SCT_internal(&sct, &cbs_sct))
348 			goto err;
349 		if (!sk_SCT_push(scts, sct)) {
350 			SCT_free(sct);
351 			goto err;
352 		}
353 	}
354 
355 	if (out_scts != NULL)
356 		*out_scts = scts;
357 
358 	*pp = CBS_data(&cbs);
359 
360 	return scts;
361 
362  err_invalid:
363 	CTerror(CT_R_SCT_LIST_INVALID);
364  err:
365 	SCT_LIST_free(scts);
366 
367 	return NULL;
368 }
369 
370 int
371 i2o_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **pp)
372 {
373 	int len, sct_len, i, is_pp_new = 0;
374 	size_t len2;
375 	unsigned char *p = NULL, *p2;
376 
377 	if (pp != NULL) {
378 		if (*pp == NULL) {
379 			if ((len = i2o_SCT_LIST(a, NULL)) == -1) {
380 				CTerror(CT_R_SCT_LIST_INVALID);
381 				return -1;
382 			}
383 			if ((*pp = malloc(len)) == NULL) {
384 				CTerror(ERR_R_MALLOC_FAILURE);
385 				return -1;
386 			}
387 			is_pp_new = 1;
388 		}
389 		p = *pp + 2;
390 	}
391 
392 	len2 = 2;
393 	for (i = 0; i < sk_SCT_num(a); i++) {
394 		if (pp != NULL) {
395 			p2 = p;
396 			p += 2;
397 			if ((sct_len = i2o_SCT(sk_SCT_value(a, i), &p)) == -1)
398 				goto err;
399 			s2n(sct_len, p2);
400 		} else {
401 			if ((sct_len = i2o_SCT(sk_SCT_value(a, i), NULL)) == -1)
402 				goto err;
403 		}
404 		len2 += 2 + sct_len;
405 	}
406 
407 	if (len2 > MAX_SCT_LIST_SIZE)
408 		goto err;
409 
410 	if (pp != NULL) {
411 		p = *pp;
412 		s2n(len2 - 2, p);
413 		if (!is_pp_new)
414 			*pp += len2;
415 	}
416 	return len2;
417 
418  err:
419 	if (is_pp_new) {
420 		free(*pp);
421 		*pp = NULL;
422 	}
423 	return -1;
424 }
425 
426 STACK_OF(SCT) *
427 d2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp, long len)
428 {
429 	ASN1_OCTET_STRING *oct = NULL;
430 	STACK_OF(SCT) *sk = NULL;
431 	const unsigned char *p;
432 
433 	p = *pp;
434 	if (d2i_ASN1_OCTET_STRING(&oct, &p, len) == NULL)
435 		return NULL;
436 
437 	p = oct->data;
438 	if ((sk = o2i_SCT_LIST(a, &p, oct->length)) != NULL)
439 		*pp += len;
440 
441 	ASN1_OCTET_STRING_free(oct);
442 	return sk;
443 }
444 
445 int
446 i2d_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **out)
447 {
448 	ASN1_OCTET_STRING oct;
449 	int len;
450 
451 	oct.data = NULL;
452 	if ((oct.length = i2o_SCT_LIST(a, &oct.data)) == -1)
453 		return -1;
454 
455 	len = i2d_ASN1_OCTET_STRING(&oct, out);
456 	free(oct.data);
457 	return len;
458 }
459