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
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
212 int
i2o_SCT_signature(const SCT * sct,unsigned char ** out)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
i2o_SCT(const SCT * sct,unsigned char ** out)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
STACK_OF(SCT)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
i2o_SCT_LIST(const STACK_OF (SCT)* a,unsigned char ** pp)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
STACK_OF(SCT)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
i2d_SCT_LIST(const STACK_OF (SCT)* a,unsigned char ** out)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