1/*
2 * Copyright 2016 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 <limits.h>
15#include <string.h>
16
17#include <openssl/asn1.h>
18#include <openssl/buffer.h>
19#include <openssl/ct.h>
20#include <openssl/err.h>
21
22#include "ct_local.h"
23
24int o2i_SCT_signature(SCT *sct, const unsigned char **in, size_t len)
25{
26 size_t siglen;
27 size_t len_remaining = len;
28 const unsigned char *p;
29
30 if (sct->version != SCT_VERSION_V1) {
31 CTerr(CT_F_O2I_SCT_SIGNATURE, CT_R_UNSUPPORTED_VERSION);
32 return -1;
33 }
34 /*
35 * digitally-signed struct header: (1 byte) Hash algorithm (1 byte)
36 * Signature algorithm (2 bytes + ?) Signature
37 *
38 * This explicitly rejects empty signatures: they're invalid for
39 * all supported algorithms.
40 */
41 if (len <= 4) {
42 CTerr(CT_F_O2I_SCT_SIGNATURE, CT_R_SCT_INVALID_SIGNATURE);
43 return -1;
44 }
45
46 p = *in;
47 /* Get hash and signature algorithm */
48 sct->hash_alg = *p++;
49 sct->sig_alg = *p++;
50 if (SCT_get_signature_nid(sct) == NID_undef) {
51 CTerr(CT_F_O2I_SCT_SIGNATURE, CT_R_SCT_INVALID_SIGNATURE);
52 return -1;
53 }
54 /* Retrieve signature and check it is consistent with the buffer length */
55 n2s(p, siglen);
56 len_remaining -= (p - *in);
57 if (siglen > len_remaining) {
58 CTerr(CT_F_O2I_SCT_SIGNATURE, CT_R_SCT_INVALID_SIGNATURE);
59 return -1;
60 }
61
62 if (SCT_set1_signature(sct, p, siglen) != 1)
63 return -1;
64 len_remaining -= siglen;
65 *in = p + siglen;
66
67 return len - len_remaining;
68}
69
70SCT *o2i_SCT(SCT **psct, const unsigned char **in, size_t len)
71{
72 SCT *sct = NULL;
73 const unsigned char *p;
74
75 if (len == 0 || len > MAX_SCT_SIZE) {
76 CTerr(CT_F_O2I_SCT, CT_R_SCT_INVALID);
77 goto err;
78 }
79
80 if ((sct = SCT_new()) == NULL)
81 goto err;
82
83 p = *in;
84
85 sct->version = *p;
86 if (sct->version == SCT_VERSION_V1) {
87 int sig_len;
88 size_t len2;
89 /*-
90 * Fixed-length header:
91 * struct {
92 * Version sct_version; (1 byte)
93 * log_id id; (32 bytes)
94 * uint64 timestamp; (8 bytes)
95 * CtExtensions extensions; (2 bytes + ?)
96 * }
97 */
98 if (len < 43) {
99 CTerr(CT_F_O2I_SCT, CT_R_SCT_INVALID);
100 goto err;
101 }
102 len -= 43;
103 p++;
104 sct->log_id = OPENSSL_memdup(p, CT_V1_HASHLEN);
105 if (sct->log_id == NULL)
106 goto err;
107 sct->log_id_len = CT_V1_HASHLEN;
108 p += CT_V1_HASHLEN;
109
110 n2l8(p, sct->timestamp);
111
112 n2s(p, len2);
113 if (len < len2) {
114 CTerr(CT_F_O2I_SCT, CT_R_SCT_INVALID);
115 goto err;
116 }
117 if (len2 > 0) {
118 sct->ext = OPENSSL_memdup(p, len2);
119 if (sct->ext == NULL)
120 goto err;
121 }
122 sct->ext_len = len2;
123 p += len2;
124 len -= len2;
125
126 sig_len = o2i_SCT_signature(sct, &p, len);
127 if (sig_len <= 0) {
128 CTerr(CT_F_O2I_SCT, CT_R_SCT_INVALID);
129 goto err;
130 }
131 len -= sig_len;
132 *in = p + len;
133 } else {
134 /* If not V1 just cache encoding */
135 sct->sct = OPENSSL_memdup(p, len);
136 if (sct->sct == NULL)
137 goto err;
138 sct->sct_len = len;
139 *in = p + len;
140 }
141
142 if (psct != NULL) {
143 SCT_free(*psct);
144 *psct = sct;
145 }
146
147 return sct;
148err:
149 SCT_free(sct);
150 return NULL;
151}
152
153int i2o_SCT_signature(const SCT *sct, unsigned char **out)
154{
155 size_t len;
156 unsigned char *p = NULL, *pstart = NULL;
157
158 if (!SCT_signature_is_complete(sct)) {
159 CTerr(CT_F_I2O_SCT_SIGNATURE, CT_R_SCT_INVALID_SIGNATURE);
160 goto err;
161 }
162
163 if (sct->version != SCT_VERSION_V1) {
164 CTerr(CT_F_I2O_SCT_SIGNATURE, CT_R_UNSUPPORTED_VERSION);
165 goto err;
166 }
167
168 /*
169 * (1 byte) Hash algorithm
170 * (1 byte) Signature algorithm
171 * (2 bytes + ?) Signature
172 */
173 len = 4 + sct->sig_len;
174
175 if (out != NULL) {
176 if (*out != NULL) {
177 p = *out;
178 *out += len;
179 } else {
180 pstart = p = OPENSSL_malloc(len);
181 if (p == NULL) {
182 CTerr(CT_F_I2O_SCT_SIGNATURE, ERR_R_MALLOC_FAILURE);
183 goto err;
184 }
185 *out = p;
186 }
187
188 *p++ = sct->hash_alg;
189 *p++ = sct->sig_alg;
190 s2n(sct->sig_len, p);
191 memcpy(p, sct->sig, sct->sig_len);
192 }
193
194 return len;
195err:
196 OPENSSL_free(pstart);
197 return -1;
198}
199
200int i2o_SCT(const SCT *sct, unsigned char **out)
201{
202 size_t len;
203 unsigned char *p = NULL, *pstart = NULL;
204
205 if (!SCT_is_complete(sct)) {
206 CTerr(CT_F_I2O_SCT, CT_R_SCT_NOT_SET);
207 goto err;
208 }
209 /*
210 * Fixed-length header: struct { (1 byte) Version sct_version; (32 bytes)
211 * log_id id; (8 bytes) uint64 timestamp; (2 bytes + ?) CtExtensions
212 * extensions; (1 byte) Hash algorithm (1 byte) Signature algorithm (2
213 * bytes + ?) Signature
214 */
215 if (sct->version == SCT_VERSION_V1)
216 len = 43 + sct->ext_len + 4 + sct->sig_len;
217 else
218 len = sct->sct_len;
219
220 if (out == NULL)
221 return len;
222
223 if (*out != NULL) {
224 p = *out;
225 *out += len;
226 } else {
227 pstart = p = OPENSSL_malloc(len);
228 if (p == NULL) {
229 CTerr(CT_F_I2O_SCT, ERR_R_MALLOC_FAILURE);
230 goto err;
231 }
232 *out = p;
233 }
234
235 if (sct->version == SCT_VERSION_V1) {
236 *p++ = sct->version;
237 memcpy(p, sct->log_id, CT_V1_HASHLEN);
238 p += CT_V1_HASHLEN;
239 l2n8(sct->timestamp, p);
240 s2n(sct->ext_len, p);
241 if (sct->ext_len > 0) {
242 memcpy(p, sct->ext, sct->ext_len);
243 p += sct->ext_len;
244 }
245 if (i2o_SCT_signature(sct, &p) <= 0)
246 goto err;
247 } else {
248 memcpy(p, sct->sct, len);
249 }
250
251 return len;
252err:
253 OPENSSL_free(pstart);
254 return -1;
255}
256
257STACK_OF(SCT) *o2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp,
258 size_t len)
259{
260 STACK_OF(SCT) *sk = NULL;
261 size_t list_len, sct_len;
262
263 if (len < 2 || len > MAX_SCT_LIST_SIZE) {
264 CTerr(CT_F_O2I_SCT_LIST, CT_R_SCT_LIST_INVALID);
265 return NULL;
266 }
267
268 n2s(*pp, list_len);
269 if (list_len != len - 2) {
270 CTerr(CT_F_O2I_SCT_LIST, CT_R_SCT_LIST_INVALID);
271 return NULL;
272 }
273
274 if (a == NULL || *a == NULL) {
275 sk = sk_SCT_new_null();
276 if (sk == NULL)
277 return NULL;
278 } else {
279 SCT *sct;
280
281 /* Use the given stack, but empty it first. */
282 sk = *a;
283 while ((sct = sk_SCT_pop(sk)) != NULL)
284 SCT_free(sct);
285 }
286
287 while (list_len > 0) {
288 SCT *sct;
289
290 if (list_len < 2) {
291 CTerr(CT_F_O2I_SCT_LIST, CT_R_SCT_LIST_INVALID);
292 goto err;
293 }
294 n2s(*pp, sct_len);
295 list_len -= 2;
296
297 if (sct_len == 0 || sct_len > list_len) {
298 CTerr(CT_F_O2I_SCT_LIST, CT_R_SCT_LIST_INVALID);
299 goto err;
300 }
301 list_len -= sct_len;
302
303 if ((sct = o2i_SCT(NULL, pp, sct_len)) == NULL)
304 goto err;
305 if (!sk_SCT_push(sk, sct)) {
306 SCT_free(sct);
307 goto err;
308 }
309 }
310
311 if (a != NULL && *a == NULL)
312 *a = sk;
313 return sk;
314
315 err:
316 if (a == NULL || *a == NULL)
317 SCT_LIST_free(sk);
318 return NULL;
319}
320
321int i2o_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **pp)
322{
323 int len, sct_len, i, is_pp_new = 0;
324 size_t len2;
325 unsigned char *p = NULL, *p2;
326
327 if (pp != NULL) {
328 if (*pp == NULL) {
329 if ((len = i2o_SCT_LIST(a, NULL)) == -1) {
330 CTerr(CT_F_I2O_SCT_LIST, CT_R_SCT_LIST_INVALID);
331 return -1;
332 }
333 if ((*pp = OPENSSL_malloc(len)) == NULL) {
334 CTerr(CT_F_I2O_SCT_LIST, ERR_R_MALLOC_FAILURE);
335 return -1;
336 }
337 is_pp_new = 1;
338 }
339 p = *pp + 2;
340 }
341
342 len2 = 2;
343 for (i = 0; i < sk_SCT_num(a); i++) {
344 if (pp != NULL) {
345 p2 = p;
346 p += 2;
347 if ((sct_len = i2o_SCT(sk_SCT_value(a, i), &p)) == -1)
348 goto err;
349 s2n(sct_len, p2);
350 } else {
351 if ((sct_len = i2o_SCT(sk_SCT_value(a, i), NULL)) == -1)
352 goto err;
353 }
354 len2 += 2 + sct_len;
355 }
356
357 if (len2 > MAX_SCT_LIST_SIZE)
358 goto err;
359
360 if (pp != NULL) {
361 p = *pp;
362 s2n(len2 - 2, p);
363 if (!is_pp_new)
364 *pp += len2;
365 }
366 return len2;
367
368 err:
369 if (is_pp_new) {
370 OPENSSL_free(*pp);
371 *pp = NULL;
372 }
373 return -1;
374}
375
376STACK_OF(SCT) *d2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp,
377 long len)
378{
379 ASN1_OCTET_STRING *oct = NULL;
380 STACK_OF(SCT) *sk = NULL;
381 const unsigned char *p;
382
383 p = *pp;
384 if (d2i_ASN1_OCTET_STRING(&oct, &p, len) == NULL)
385 return NULL;
386
387 p = oct->data;
388 if ((sk = o2i_SCT_LIST(a, &p, oct->length)) != NULL)
389 *pp += len;
390
391 ASN1_OCTET_STRING_free(oct);
392 return sk;
393}
394
395int i2d_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **out)
396{
397 ASN1_OCTET_STRING oct;
398 int len;
399
400 oct.data = NULL;
401 if ((oct.length = i2o_SCT_LIST(a, &oct.data)) == -1)
402 return -1;
403
404 len = i2d_ASN1_OCTET_STRING(&oct, out);
405 OPENSSL_free(oct.data);
406 return len;
407}
408