1*de0e0e4dSAntonio Huete Jimenez /* $OpenBSD: ct_oct.c,v 1.8 2021/12/20 17:23:07 jsing Exp $ */
2*de0e0e4dSAntonio Huete Jimenez /*
3*de0e0e4dSAntonio Huete Jimenez * Written by Rob Stradling (rob@comodo.com) and Stephen Henson
4*de0e0e4dSAntonio Huete Jimenez * (steve@openssl.org) for the OpenSSL project 2014.
5*de0e0e4dSAntonio Huete Jimenez */
6*de0e0e4dSAntonio Huete Jimenez /* ====================================================================
7*de0e0e4dSAntonio Huete Jimenez * Copyright (c) 2014 The OpenSSL Project. All rights reserved.
8*de0e0e4dSAntonio Huete Jimenez *
9*de0e0e4dSAntonio Huete Jimenez * Redistribution and use in source and binary forms, with or without
10*de0e0e4dSAntonio Huete Jimenez * modification, are permitted provided that the following conditions
11*de0e0e4dSAntonio Huete Jimenez * are met:
12*de0e0e4dSAntonio Huete Jimenez *
13*de0e0e4dSAntonio Huete Jimenez * 1. Redistributions of source code must retain the above copyright
14*de0e0e4dSAntonio Huete Jimenez * notice, this list of conditions and the following disclaimer.
15*de0e0e4dSAntonio Huete Jimenez *
16*de0e0e4dSAntonio Huete Jimenez * 2. Redistributions in binary form must reproduce the above copyright
17*de0e0e4dSAntonio Huete Jimenez * notice, this list of conditions and the following disclaimer in
18*de0e0e4dSAntonio Huete Jimenez * the documentation and/or other materials provided with the
19*de0e0e4dSAntonio Huete Jimenez * distribution.
20*de0e0e4dSAntonio Huete Jimenez *
21*de0e0e4dSAntonio Huete Jimenez * 3. All advertising materials mentioning features or use of this
22*de0e0e4dSAntonio Huete Jimenez * software must display the following acknowledgment:
23*de0e0e4dSAntonio Huete Jimenez * "This product includes software developed by the OpenSSL Project
24*de0e0e4dSAntonio Huete Jimenez * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25*de0e0e4dSAntonio Huete Jimenez *
26*de0e0e4dSAntonio Huete Jimenez * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27*de0e0e4dSAntonio Huete Jimenez * endorse or promote products derived from this software without
28*de0e0e4dSAntonio Huete Jimenez * prior written permission. For written permission, please contact
29*de0e0e4dSAntonio Huete Jimenez * licensing@OpenSSL.org.
30*de0e0e4dSAntonio Huete Jimenez *
31*de0e0e4dSAntonio Huete Jimenez * 5. Products derived from this software may not be called "OpenSSL"
32*de0e0e4dSAntonio Huete Jimenez * nor may "OpenSSL" appear in their names without prior written
33*de0e0e4dSAntonio Huete Jimenez * permission of the OpenSSL Project.
34*de0e0e4dSAntonio Huete Jimenez *
35*de0e0e4dSAntonio Huete Jimenez * 6. Redistributions of any form whatsoever must retain the following
36*de0e0e4dSAntonio Huete Jimenez * acknowledgment:
37*de0e0e4dSAntonio Huete Jimenez * "This product includes software developed by the OpenSSL Project
38*de0e0e4dSAntonio Huete Jimenez * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39*de0e0e4dSAntonio Huete Jimenez *
40*de0e0e4dSAntonio Huete Jimenez * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41*de0e0e4dSAntonio Huete Jimenez * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42*de0e0e4dSAntonio Huete Jimenez * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43*de0e0e4dSAntonio Huete Jimenez * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
44*de0e0e4dSAntonio Huete Jimenez * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45*de0e0e4dSAntonio Huete Jimenez * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46*de0e0e4dSAntonio Huete Jimenez * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47*de0e0e4dSAntonio Huete Jimenez * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48*de0e0e4dSAntonio Huete Jimenez * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49*de0e0e4dSAntonio Huete Jimenez * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50*de0e0e4dSAntonio Huete Jimenez * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51*de0e0e4dSAntonio Huete Jimenez * OF THE POSSIBILITY OF SUCH DAMAGE.
52*de0e0e4dSAntonio Huete Jimenez * ====================================================================
53*de0e0e4dSAntonio Huete Jimenez *
54*de0e0e4dSAntonio Huete Jimenez * This product includes cryptographic software written by Eric Young
55*de0e0e4dSAntonio Huete Jimenez * (eay@cryptsoft.com). This product includes software written by Tim
56*de0e0e4dSAntonio Huete Jimenez * Hudson (tjh@cryptsoft.com).
57*de0e0e4dSAntonio Huete Jimenez *
58*de0e0e4dSAntonio Huete Jimenez */
59*de0e0e4dSAntonio Huete Jimenez
60*de0e0e4dSAntonio Huete Jimenez #ifdef OPENSSL_NO_CT
61*de0e0e4dSAntonio Huete Jimenez # error "CT is disabled"
62*de0e0e4dSAntonio Huete Jimenez #endif
63*de0e0e4dSAntonio Huete Jimenez
64*de0e0e4dSAntonio Huete Jimenez #include <limits.h>
65*de0e0e4dSAntonio Huete Jimenez #include <string.h>
66*de0e0e4dSAntonio Huete Jimenez
67*de0e0e4dSAntonio Huete Jimenez #include <openssl/asn1.h>
68*de0e0e4dSAntonio Huete Jimenez #include <openssl/buffer.h>
69*de0e0e4dSAntonio Huete Jimenez #include <openssl/ct.h>
70*de0e0e4dSAntonio Huete Jimenez #include <openssl/err.h>
71*de0e0e4dSAntonio Huete Jimenez
72*de0e0e4dSAntonio Huete Jimenez #include "bytestring.h"
73*de0e0e4dSAntonio Huete Jimenez #include "ct_local.h"
74*de0e0e4dSAntonio Huete Jimenez
75*de0e0e4dSAntonio Huete Jimenez int
o2i_SCT_signature(SCT * sct,CBS * cbs)76*de0e0e4dSAntonio Huete Jimenez o2i_SCT_signature(SCT *sct, CBS *cbs)
77*de0e0e4dSAntonio Huete Jimenez {
78*de0e0e4dSAntonio Huete Jimenez uint8_t hash_alg, sig_alg;
79*de0e0e4dSAntonio Huete Jimenez CBS signature;
80*de0e0e4dSAntonio Huete Jimenez
81*de0e0e4dSAntonio Huete Jimenez if (sct->version != SCT_VERSION_V1) {
82*de0e0e4dSAntonio Huete Jimenez CTerror(CT_R_UNSUPPORTED_VERSION);
83*de0e0e4dSAntonio Huete Jimenez return 0;
84*de0e0e4dSAntonio Huete Jimenez }
85*de0e0e4dSAntonio Huete Jimenez
86*de0e0e4dSAntonio Huete Jimenez /*
87*de0e0e4dSAntonio Huete Jimenez * Parse a digitally-signed element - see RFC 6962 section 3.2 and
88*de0e0e4dSAntonio Huete Jimenez * RFC 5246 sections 4.7 and 7.4.1.4.1.
89*de0e0e4dSAntonio Huete Jimenez */
90*de0e0e4dSAntonio Huete Jimenez if (!CBS_get_u8(cbs, &hash_alg))
91*de0e0e4dSAntonio Huete Jimenez goto err_invalid;
92*de0e0e4dSAntonio Huete Jimenez if (!CBS_get_u8(cbs, &sig_alg))
93*de0e0e4dSAntonio Huete Jimenez goto err_invalid;
94*de0e0e4dSAntonio Huete Jimenez if (!CBS_get_u16_length_prefixed(cbs, &signature))
95*de0e0e4dSAntonio Huete Jimenez goto err_invalid;
96*de0e0e4dSAntonio Huete Jimenez if (CBS_len(cbs) != 0)
97*de0e0e4dSAntonio Huete Jimenez goto err_invalid;
98*de0e0e4dSAntonio Huete Jimenez
99*de0e0e4dSAntonio Huete Jimenez /*
100*de0e0e4dSAntonio Huete Jimenez * Reject empty signatures since they are invalid for all supported
101*de0e0e4dSAntonio Huete Jimenez * algorithms (this really should be done by SCT_set1_signature()).
102*de0e0e4dSAntonio Huete Jimenez */
103*de0e0e4dSAntonio Huete Jimenez if (CBS_len(&signature) == 0)
104*de0e0e4dSAntonio Huete Jimenez goto err_invalid;
105*de0e0e4dSAntonio Huete Jimenez
106*de0e0e4dSAntonio Huete Jimenez sct->hash_alg = hash_alg;
107*de0e0e4dSAntonio Huete Jimenez sct->sig_alg = sig_alg;
108*de0e0e4dSAntonio Huete Jimenez
109*de0e0e4dSAntonio Huete Jimenez if (SCT_get_signature_nid(sct) == NID_undef)
110*de0e0e4dSAntonio Huete Jimenez goto err_invalid;
111*de0e0e4dSAntonio Huete Jimenez
112*de0e0e4dSAntonio Huete Jimenez if (!SCT_set1_signature(sct, CBS_data(&signature), CBS_len(&signature)))
113*de0e0e4dSAntonio Huete Jimenez return 0;
114*de0e0e4dSAntonio Huete Jimenez
115*de0e0e4dSAntonio Huete Jimenez return 1;
116*de0e0e4dSAntonio Huete Jimenez
117*de0e0e4dSAntonio Huete Jimenez err_invalid:
118*de0e0e4dSAntonio Huete Jimenez CTerror(CT_R_SCT_INVALID_SIGNATURE);
119*de0e0e4dSAntonio Huete Jimenez return 0;
120*de0e0e4dSAntonio Huete Jimenez }
121*de0e0e4dSAntonio Huete Jimenez
122*de0e0e4dSAntonio Huete Jimenez static int
o2i_SCT_internal(SCT ** out_sct,CBS * cbs)123*de0e0e4dSAntonio Huete Jimenez o2i_SCT_internal(SCT **out_sct, CBS *cbs)
124*de0e0e4dSAntonio Huete Jimenez {
125*de0e0e4dSAntonio Huete Jimenez SCT *sct = NULL;
126*de0e0e4dSAntonio Huete Jimenez uint8_t version;
127*de0e0e4dSAntonio Huete Jimenez
128*de0e0e4dSAntonio Huete Jimenez *out_sct = NULL;
129*de0e0e4dSAntonio Huete Jimenez
130*de0e0e4dSAntonio Huete Jimenez if ((sct = SCT_new()) == NULL)
131*de0e0e4dSAntonio Huete Jimenez goto err;
132*de0e0e4dSAntonio Huete Jimenez
133*de0e0e4dSAntonio Huete Jimenez if (CBS_len(cbs) > MAX_SCT_SIZE)
134*de0e0e4dSAntonio Huete Jimenez goto err_invalid;
135*de0e0e4dSAntonio Huete Jimenez if (!CBS_peek_u8(cbs, &version))
136*de0e0e4dSAntonio Huete Jimenez goto err_invalid;
137*de0e0e4dSAntonio Huete Jimenez
138*de0e0e4dSAntonio Huete Jimenez sct->version = version;
139*de0e0e4dSAntonio Huete Jimenez
140*de0e0e4dSAntonio Huete Jimenez if (version == SCT_VERSION_V1) {
141*de0e0e4dSAntonio Huete Jimenez CBS extensions, log_id;
142*de0e0e4dSAntonio Huete Jimenez uint64_t timestamp;
143*de0e0e4dSAntonio Huete Jimenez
144*de0e0e4dSAntonio Huete Jimenez /*
145*de0e0e4dSAntonio Huete Jimenez * Parse a v1 SignedCertificateTimestamp - see RFC 6962
146*de0e0e4dSAntonio Huete Jimenez * section 3.2.
147*de0e0e4dSAntonio Huete Jimenez */
148*de0e0e4dSAntonio Huete Jimenez if (!CBS_get_u8(cbs, &version))
149*de0e0e4dSAntonio Huete Jimenez goto err_invalid;
150*de0e0e4dSAntonio Huete Jimenez if (!CBS_get_bytes(cbs, &log_id, CT_V1_LOG_ID_LEN))
151*de0e0e4dSAntonio Huete Jimenez goto err_invalid;
152*de0e0e4dSAntonio Huete Jimenez if (!CBS_get_u64(cbs, ×tamp))
153*de0e0e4dSAntonio Huete Jimenez goto err_invalid;
154*de0e0e4dSAntonio Huete Jimenez if (!CBS_get_u16_length_prefixed(cbs, &extensions))
155*de0e0e4dSAntonio Huete Jimenez goto err_invalid;
156*de0e0e4dSAntonio Huete Jimenez
157*de0e0e4dSAntonio Huete Jimenez if (!CBS_stow(&log_id, &sct->log_id, &sct->log_id_len))
158*de0e0e4dSAntonio Huete Jimenez goto err;
159*de0e0e4dSAntonio Huete Jimenez
160*de0e0e4dSAntonio Huete Jimenez sct->timestamp = timestamp;
161*de0e0e4dSAntonio Huete Jimenez
162*de0e0e4dSAntonio Huete Jimenez if (!CBS_stow(&extensions, &sct->ext, &sct->ext_len))
163*de0e0e4dSAntonio Huete Jimenez goto err;
164*de0e0e4dSAntonio Huete Jimenez
165*de0e0e4dSAntonio Huete Jimenez if (!o2i_SCT_signature(sct, cbs))
166*de0e0e4dSAntonio Huete Jimenez goto err;
167*de0e0e4dSAntonio Huete Jimenez
168*de0e0e4dSAntonio Huete Jimenez if (CBS_len(cbs) != 0)
169*de0e0e4dSAntonio Huete Jimenez goto err_invalid;
170*de0e0e4dSAntonio Huete Jimenez } else {
171*de0e0e4dSAntonio Huete Jimenez /* If not V1 just cache encoding. */
172*de0e0e4dSAntonio Huete Jimenez if (!CBS_stow(cbs, &sct->sct, &sct->sct_len))
173*de0e0e4dSAntonio Huete Jimenez goto err;
174*de0e0e4dSAntonio Huete Jimenez }
175*de0e0e4dSAntonio Huete Jimenez
176*de0e0e4dSAntonio Huete Jimenez *out_sct = sct;
177*de0e0e4dSAntonio Huete Jimenez
178*de0e0e4dSAntonio Huete Jimenez return 1;
179*de0e0e4dSAntonio Huete Jimenez
180*de0e0e4dSAntonio Huete Jimenez err_invalid:
181*de0e0e4dSAntonio Huete Jimenez CTerror(CT_R_SCT_INVALID);
182*de0e0e4dSAntonio Huete Jimenez err:
183*de0e0e4dSAntonio Huete Jimenez SCT_free(sct);
184*de0e0e4dSAntonio Huete Jimenez
185*de0e0e4dSAntonio Huete Jimenez return 0;
186*de0e0e4dSAntonio Huete Jimenez }
187*de0e0e4dSAntonio Huete Jimenez
188*de0e0e4dSAntonio Huete Jimenez SCT *
o2i_SCT(SCT ** psct,const unsigned char ** in,size_t len)189*de0e0e4dSAntonio Huete Jimenez o2i_SCT(SCT **psct, const unsigned char **in, size_t len)
190*de0e0e4dSAntonio Huete Jimenez {
191*de0e0e4dSAntonio Huete Jimenez SCT *sct;
192*de0e0e4dSAntonio Huete Jimenez CBS cbs;
193*de0e0e4dSAntonio Huete Jimenez
194*de0e0e4dSAntonio Huete Jimenez CBS_init(&cbs, *in, len);
195*de0e0e4dSAntonio Huete Jimenez
196*de0e0e4dSAntonio Huete Jimenez if (psct != NULL) {
197*de0e0e4dSAntonio Huete Jimenez SCT_free(*psct);
198*de0e0e4dSAntonio Huete Jimenez *psct = NULL;
199*de0e0e4dSAntonio Huete Jimenez }
200*de0e0e4dSAntonio Huete Jimenez
201*de0e0e4dSAntonio Huete Jimenez if (!o2i_SCT_internal(&sct, &cbs))
202*de0e0e4dSAntonio Huete Jimenez return NULL;
203*de0e0e4dSAntonio Huete Jimenez
204*de0e0e4dSAntonio Huete Jimenez if (psct != NULL)
205*de0e0e4dSAntonio Huete Jimenez *psct = sct;
206*de0e0e4dSAntonio Huete Jimenez
207*de0e0e4dSAntonio Huete Jimenez *in = CBS_data(&cbs);
208*de0e0e4dSAntonio Huete Jimenez
209*de0e0e4dSAntonio Huete Jimenez return sct;
210*de0e0e4dSAntonio Huete Jimenez }
211*de0e0e4dSAntonio Huete Jimenez
212*de0e0e4dSAntonio Huete Jimenez int
i2o_SCT_signature(const SCT * sct,unsigned char ** out)213*de0e0e4dSAntonio Huete Jimenez i2o_SCT_signature(const SCT *sct, unsigned char **out)
214*de0e0e4dSAntonio Huete Jimenez {
215*de0e0e4dSAntonio Huete Jimenez size_t len;
216*de0e0e4dSAntonio Huete Jimenez unsigned char *p = NULL, *pstart = NULL;
217*de0e0e4dSAntonio Huete Jimenez
218*de0e0e4dSAntonio Huete Jimenez if (!SCT_signature_is_complete(sct)) {
219*de0e0e4dSAntonio Huete Jimenez CTerror(CT_R_SCT_INVALID_SIGNATURE);
220*de0e0e4dSAntonio Huete Jimenez goto err;
221*de0e0e4dSAntonio Huete Jimenez }
222*de0e0e4dSAntonio Huete Jimenez
223*de0e0e4dSAntonio Huete Jimenez if (sct->version != SCT_VERSION_V1) {
224*de0e0e4dSAntonio Huete Jimenez CTerror(CT_R_UNSUPPORTED_VERSION);
225*de0e0e4dSAntonio Huete Jimenez goto err;
226*de0e0e4dSAntonio Huete Jimenez }
227*de0e0e4dSAntonio Huete Jimenez
228*de0e0e4dSAntonio Huete Jimenez /*
229*de0e0e4dSAntonio Huete Jimenez * (1 byte) Hash algorithm
230*de0e0e4dSAntonio Huete Jimenez * (1 byte) Signature algorithm
231*de0e0e4dSAntonio Huete Jimenez * (2 bytes + ?) Signature
232*de0e0e4dSAntonio Huete Jimenez */
233*de0e0e4dSAntonio Huete Jimenez len = 4 + sct->sig_len;
234*de0e0e4dSAntonio Huete Jimenez
235*de0e0e4dSAntonio Huete Jimenez if (out != NULL) {
236*de0e0e4dSAntonio Huete Jimenez if (*out != NULL) {
237*de0e0e4dSAntonio Huete Jimenez p = *out;
238*de0e0e4dSAntonio Huete Jimenez *out += len;
239*de0e0e4dSAntonio Huete Jimenez } else {
240*de0e0e4dSAntonio Huete Jimenez pstart = p = malloc(len);
241*de0e0e4dSAntonio Huete Jimenez if (p == NULL) {
242*de0e0e4dSAntonio Huete Jimenez CTerror(ERR_R_MALLOC_FAILURE);
243*de0e0e4dSAntonio Huete Jimenez goto err;
244*de0e0e4dSAntonio Huete Jimenez }
245*de0e0e4dSAntonio Huete Jimenez *out = p;
246*de0e0e4dSAntonio Huete Jimenez }
247*de0e0e4dSAntonio Huete Jimenez
248*de0e0e4dSAntonio Huete Jimenez *p++ = sct->hash_alg;
249*de0e0e4dSAntonio Huete Jimenez *p++ = sct->sig_alg;
250*de0e0e4dSAntonio Huete Jimenez s2n(sct->sig_len, p);
251*de0e0e4dSAntonio Huete Jimenez memcpy(p, sct->sig, sct->sig_len);
252*de0e0e4dSAntonio Huete Jimenez }
253*de0e0e4dSAntonio Huete Jimenez
254*de0e0e4dSAntonio Huete Jimenez return len;
255*de0e0e4dSAntonio Huete Jimenez err:
256*de0e0e4dSAntonio Huete Jimenez free(pstart);
257*de0e0e4dSAntonio Huete Jimenez return -1;
258*de0e0e4dSAntonio Huete Jimenez }
259*de0e0e4dSAntonio Huete Jimenez
260*de0e0e4dSAntonio Huete Jimenez int
i2o_SCT(const SCT * sct,unsigned char ** out)261*de0e0e4dSAntonio Huete Jimenez i2o_SCT(const SCT *sct, unsigned char **out)
262*de0e0e4dSAntonio Huete Jimenez {
263*de0e0e4dSAntonio Huete Jimenez size_t len;
264*de0e0e4dSAntonio Huete Jimenez unsigned char *p = NULL, *pstart = NULL;
265*de0e0e4dSAntonio Huete Jimenez
266*de0e0e4dSAntonio Huete Jimenez if (!SCT_is_complete(sct)) {
267*de0e0e4dSAntonio Huete Jimenez CTerror(CT_R_SCT_NOT_SET);
268*de0e0e4dSAntonio Huete Jimenez goto err;
269*de0e0e4dSAntonio Huete Jimenez }
270*de0e0e4dSAntonio Huete Jimenez /*
271*de0e0e4dSAntonio Huete Jimenez * Fixed-length header: struct { (1 byte) Version sct_version; (32 bytes)
272*de0e0e4dSAntonio Huete Jimenez * log_id id; (8 bytes) uint64 timestamp; (2 bytes + ?) CtExtensions
273*de0e0e4dSAntonio Huete Jimenez * extensions; (1 byte) Hash algorithm (1 byte) Signature algorithm (2
274*de0e0e4dSAntonio Huete Jimenez * bytes + ?) Signature
275*de0e0e4dSAntonio Huete Jimenez */
276*de0e0e4dSAntonio Huete Jimenez if (sct->version == SCT_VERSION_V1)
277*de0e0e4dSAntonio Huete Jimenez len = 43 + sct->ext_len + 4 + sct->sig_len;
278*de0e0e4dSAntonio Huete Jimenez else
279*de0e0e4dSAntonio Huete Jimenez len = sct->sct_len;
280*de0e0e4dSAntonio Huete Jimenez
281*de0e0e4dSAntonio Huete Jimenez if (out == NULL)
282*de0e0e4dSAntonio Huete Jimenez return len;
283*de0e0e4dSAntonio Huete Jimenez
284*de0e0e4dSAntonio Huete Jimenez if (*out != NULL) {
285*de0e0e4dSAntonio Huete Jimenez p = *out;
286*de0e0e4dSAntonio Huete Jimenez *out += len;
287*de0e0e4dSAntonio Huete Jimenez } else {
288*de0e0e4dSAntonio Huete Jimenez pstart = p = malloc(len);
289*de0e0e4dSAntonio Huete Jimenez if (p == NULL) {
290*de0e0e4dSAntonio Huete Jimenez CTerror(ERR_R_MALLOC_FAILURE);
291*de0e0e4dSAntonio Huete Jimenez goto err;
292*de0e0e4dSAntonio Huete Jimenez }
293*de0e0e4dSAntonio Huete Jimenez *out = p;
294*de0e0e4dSAntonio Huete Jimenez }
295*de0e0e4dSAntonio Huete Jimenez
296*de0e0e4dSAntonio Huete Jimenez if (sct->version == SCT_VERSION_V1) {
297*de0e0e4dSAntonio Huete Jimenez *p++ = sct->version;
298*de0e0e4dSAntonio Huete Jimenez memcpy(p, sct->log_id, CT_V1_HASHLEN);
299*de0e0e4dSAntonio Huete Jimenez p += CT_V1_HASHLEN;
300*de0e0e4dSAntonio Huete Jimenez l2n8(sct->timestamp, p);
301*de0e0e4dSAntonio Huete Jimenez s2n(sct->ext_len, p);
302*de0e0e4dSAntonio Huete Jimenez if (sct->ext_len > 0) {
303*de0e0e4dSAntonio Huete Jimenez memcpy(p, sct->ext, sct->ext_len);
304*de0e0e4dSAntonio Huete Jimenez p += sct->ext_len;
305*de0e0e4dSAntonio Huete Jimenez }
306*de0e0e4dSAntonio Huete Jimenez if (i2o_SCT_signature(sct, &p) <= 0)
307*de0e0e4dSAntonio Huete Jimenez goto err;
308*de0e0e4dSAntonio Huete Jimenez } else {
309*de0e0e4dSAntonio Huete Jimenez memcpy(p, sct->sct, len);
310*de0e0e4dSAntonio Huete Jimenez }
311*de0e0e4dSAntonio Huete Jimenez
312*de0e0e4dSAntonio Huete Jimenez return len;
313*de0e0e4dSAntonio Huete Jimenez err:
314*de0e0e4dSAntonio Huete Jimenez free(pstart);
315*de0e0e4dSAntonio Huete Jimenez return -1;
316*de0e0e4dSAntonio Huete Jimenez }
317*de0e0e4dSAntonio Huete Jimenez
STACK_OF(SCT)318*de0e0e4dSAntonio Huete Jimenez STACK_OF(SCT) *
319*de0e0e4dSAntonio Huete Jimenez o2i_SCT_LIST(STACK_OF(SCT) **out_scts, const unsigned char **pp, size_t len)
320*de0e0e4dSAntonio Huete Jimenez {
321*de0e0e4dSAntonio Huete Jimenez CBS cbs, cbs_scts, cbs_sct;
322*de0e0e4dSAntonio Huete Jimenez STACK_OF(SCT) *scts = NULL;
323*de0e0e4dSAntonio Huete Jimenez
324*de0e0e4dSAntonio Huete Jimenez CBS_init(&cbs, *pp, len);
325*de0e0e4dSAntonio Huete Jimenez
326*de0e0e4dSAntonio Huete Jimenez if (CBS_len(&cbs) > MAX_SCT_LIST_SIZE)
327*de0e0e4dSAntonio Huete Jimenez goto err_invalid;
328*de0e0e4dSAntonio Huete Jimenez if (!CBS_get_u16_length_prefixed(&cbs, &cbs_scts))
329*de0e0e4dSAntonio Huete Jimenez goto err_invalid;
330*de0e0e4dSAntonio Huete Jimenez if (CBS_len(&cbs) != 0)
331*de0e0e4dSAntonio Huete Jimenez goto err_invalid;
332*de0e0e4dSAntonio Huete Jimenez
333*de0e0e4dSAntonio Huete Jimenez if (out_scts != NULL) {
334*de0e0e4dSAntonio Huete Jimenez SCT_LIST_free(*out_scts);
335*de0e0e4dSAntonio Huete Jimenez *out_scts = NULL;
336*de0e0e4dSAntonio Huete Jimenez }
337*de0e0e4dSAntonio Huete Jimenez
338*de0e0e4dSAntonio Huete Jimenez if ((scts = sk_SCT_new_null()) == NULL)
339*de0e0e4dSAntonio Huete Jimenez return NULL;
340*de0e0e4dSAntonio Huete Jimenez
341*de0e0e4dSAntonio Huete Jimenez while (CBS_len(&cbs_scts) > 0) {
342*de0e0e4dSAntonio Huete Jimenez SCT *sct;
343*de0e0e4dSAntonio Huete Jimenez
344*de0e0e4dSAntonio Huete Jimenez if (!CBS_get_u16_length_prefixed(&cbs_scts, &cbs_sct))
345*de0e0e4dSAntonio Huete Jimenez goto err_invalid;
346*de0e0e4dSAntonio Huete Jimenez
347*de0e0e4dSAntonio Huete Jimenez if (!o2i_SCT_internal(&sct, &cbs_sct))
348*de0e0e4dSAntonio Huete Jimenez goto err;
349*de0e0e4dSAntonio Huete Jimenez if (!sk_SCT_push(scts, sct)) {
350*de0e0e4dSAntonio Huete Jimenez SCT_free(sct);
351*de0e0e4dSAntonio Huete Jimenez goto err;
352*de0e0e4dSAntonio Huete Jimenez }
353*de0e0e4dSAntonio Huete Jimenez }
354*de0e0e4dSAntonio Huete Jimenez
355*de0e0e4dSAntonio Huete Jimenez if (out_scts != NULL)
356*de0e0e4dSAntonio Huete Jimenez *out_scts = scts;
357*de0e0e4dSAntonio Huete Jimenez
358*de0e0e4dSAntonio Huete Jimenez *pp = CBS_data(&cbs);
359*de0e0e4dSAntonio Huete Jimenez
360*de0e0e4dSAntonio Huete Jimenez return scts;
361*de0e0e4dSAntonio Huete Jimenez
362*de0e0e4dSAntonio Huete Jimenez err_invalid:
363*de0e0e4dSAntonio Huete Jimenez CTerror(CT_R_SCT_LIST_INVALID);
364*de0e0e4dSAntonio Huete Jimenez err:
365*de0e0e4dSAntonio Huete Jimenez SCT_LIST_free(scts);
366*de0e0e4dSAntonio Huete Jimenez
367*de0e0e4dSAntonio Huete Jimenez return NULL;
368*de0e0e4dSAntonio Huete Jimenez }
369*de0e0e4dSAntonio Huete Jimenez
370*de0e0e4dSAntonio Huete Jimenez int
i2o_SCT_LIST(const STACK_OF (SCT)* a,unsigned char ** pp)371*de0e0e4dSAntonio Huete Jimenez i2o_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **pp)
372*de0e0e4dSAntonio Huete Jimenez {
373*de0e0e4dSAntonio Huete Jimenez int len, sct_len, i, is_pp_new = 0;
374*de0e0e4dSAntonio Huete Jimenez size_t len2;
375*de0e0e4dSAntonio Huete Jimenez unsigned char *p = NULL, *p2;
376*de0e0e4dSAntonio Huete Jimenez
377*de0e0e4dSAntonio Huete Jimenez if (pp != NULL) {
378*de0e0e4dSAntonio Huete Jimenez if (*pp == NULL) {
379*de0e0e4dSAntonio Huete Jimenez if ((len = i2o_SCT_LIST(a, NULL)) == -1) {
380*de0e0e4dSAntonio Huete Jimenez CTerror(CT_R_SCT_LIST_INVALID);
381*de0e0e4dSAntonio Huete Jimenez return -1;
382*de0e0e4dSAntonio Huete Jimenez }
383*de0e0e4dSAntonio Huete Jimenez if ((*pp = malloc(len)) == NULL) {
384*de0e0e4dSAntonio Huete Jimenez CTerror(ERR_R_MALLOC_FAILURE);
385*de0e0e4dSAntonio Huete Jimenez return -1;
386*de0e0e4dSAntonio Huete Jimenez }
387*de0e0e4dSAntonio Huete Jimenez is_pp_new = 1;
388*de0e0e4dSAntonio Huete Jimenez }
389*de0e0e4dSAntonio Huete Jimenez p = *pp + 2;
390*de0e0e4dSAntonio Huete Jimenez }
391*de0e0e4dSAntonio Huete Jimenez
392*de0e0e4dSAntonio Huete Jimenez len2 = 2;
393*de0e0e4dSAntonio Huete Jimenez for (i = 0; i < sk_SCT_num(a); i++) {
394*de0e0e4dSAntonio Huete Jimenez if (pp != NULL) {
395*de0e0e4dSAntonio Huete Jimenez p2 = p;
396*de0e0e4dSAntonio Huete Jimenez p += 2;
397*de0e0e4dSAntonio Huete Jimenez if ((sct_len = i2o_SCT(sk_SCT_value(a, i), &p)) == -1)
398*de0e0e4dSAntonio Huete Jimenez goto err;
399*de0e0e4dSAntonio Huete Jimenez s2n(sct_len, p2);
400*de0e0e4dSAntonio Huete Jimenez } else {
401*de0e0e4dSAntonio Huete Jimenez if ((sct_len = i2o_SCT(sk_SCT_value(a, i), NULL)) == -1)
402*de0e0e4dSAntonio Huete Jimenez goto err;
403*de0e0e4dSAntonio Huete Jimenez }
404*de0e0e4dSAntonio Huete Jimenez len2 += 2 + sct_len;
405*de0e0e4dSAntonio Huete Jimenez }
406*de0e0e4dSAntonio Huete Jimenez
407*de0e0e4dSAntonio Huete Jimenez if (len2 > MAX_SCT_LIST_SIZE)
408*de0e0e4dSAntonio Huete Jimenez goto err;
409*de0e0e4dSAntonio Huete Jimenez
410*de0e0e4dSAntonio Huete Jimenez if (pp != NULL) {
411*de0e0e4dSAntonio Huete Jimenez p = *pp;
412*de0e0e4dSAntonio Huete Jimenez s2n(len2 - 2, p);
413*de0e0e4dSAntonio Huete Jimenez if (!is_pp_new)
414*de0e0e4dSAntonio Huete Jimenez *pp += len2;
415*de0e0e4dSAntonio Huete Jimenez }
416*de0e0e4dSAntonio Huete Jimenez return len2;
417*de0e0e4dSAntonio Huete Jimenez
418*de0e0e4dSAntonio Huete Jimenez err:
419*de0e0e4dSAntonio Huete Jimenez if (is_pp_new) {
420*de0e0e4dSAntonio Huete Jimenez free(*pp);
421*de0e0e4dSAntonio Huete Jimenez *pp = NULL;
422*de0e0e4dSAntonio Huete Jimenez }
423*de0e0e4dSAntonio Huete Jimenez return -1;
424*de0e0e4dSAntonio Huete Jimenez }
425*de0e0e4dSAntonio Huete Jimenez
STACK_OF(SCT)426*de0e0e4dSAntonio Huete Jimenez STACK_OF(SCT) *
427*de0e0e4dSAntonio Huete Jimenez d2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp, long len)
428*de0e0e4dSAntonio Huete Jimenez {
429*de0e0e4dSAntonio Huete Jimenez ASN1_OCTET_STRING *oct = NULL;
430*de0e0e4dSAntonio Huete Jimenez STACK_OF(SCT) *sk = NULL;
431*de0e0e4dSAntonio Huete Jimenez const unsigned char *p;
432*de0e0e4dSAntonio Huete Jimenez
433*de0e0e4dSAntonio Huete Jimenez p = *pp;
434*de0e0e4dSAntonio Huete Jimenez if (d2i_ASN1_OCTET_STRING(&oct, &p, len) == NULL)
435*de0e0e4dSAntonio Huete Jimenez return NULL;
436*de0e0e4dSAntonio Huete Jimenez
437*de0e0e4dSAntonio Huete Jimenez p = oct->data;
438*de0e0e4dSAntonio Huete Jimenez if ((sk = o2i_SCT_LIST(a, &p, oct->length)) != NULL)
439*de0e0e4dSAntonio Huete Jimenez *pp += len;
440*de0e0e4dSAntonio Huete Jimenez
441*de0e0e4dSAntonio Huete Jimenez ASN1_OCTET_STRING_free(oct);
442*de0e0e4dSAntonio Huete Jimenez return sk;
443*de0e0e4dSAntonio Huete Jimenez }
444*de0e0e4dSAntonio Huete Jimenez
445*de0e0e4dSAntonio Huete Jimenez int
i2d_SCT_LIST(const STACK_OF (SCT)* a,unsigned char ** out)446*de0e0e4dSAntonio Huete Jimenez i2d_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **out)
447*de0e0e4dSAntonio Huete Jimenez {
448*de0e0e4dSAntonio Huete Jimenez ASN1_OCTET_STRING oct;
449*de0e0e4dSAntonio Huete Jimenez int len;
450*de0e0e4dSAntonio Huete Jimenez
451*de0e0e4dSAntonio Huete Jimenez oct.data = NULL;
452*de0e0e4dSAntonio Huete Jimenez if ((oct.length = i2o_SCT_LIST(a, &oct.data)) == -1)
453*de0e0e4dSAntonio Huete Jimenez return -1;
454*de0e0e4dSAntonio Huete Jimenez
455*de0e0e4dSAntonio Huete Jimenez len = i2d_ASN1_OCTET_STRING(&oct, out);
456*de0e0e4dSAntonio Huete Jimenez free(oct.data);
457*de0e0e4dSAntonio Huete Jimenez return len;
458*de0e0e4dSAntonio Huete Jimenez }
459