Branch data Line data Source code
1 : : /* v3_scts.c */
2 : : /* Written by Rob Stradling (rob@comodo.com) for the OpenSSL project 2014.
3 : : */
4 : : /* ====================================================================
5 : : * Copyright (c) 2014 The OpenSSL Project. All rights reserved.
6 : : *
7 : : * Redistribution and use in source and binary forms, with or without
8 : : * modification, are permitted provided that the following conditions
9 : : * are met:
10 : : *
11 : : * 1. Redistributions of source code must retain the above copyright
12 : : * notice, this list of conditions and the following disclaimer.
13 : : *
14 : : * 2. Redistributions in binary form must reproduce the above copyright
15 : : * notice, this list of conditions and the following disclaimer in
16 : : * the documentation and/or other materials provided with the
17 : : * distribution.
18 : : *
19 : : * 3. All advertising materials mentioning features or use of this
20 : : * software must display the following acknowledgment:
21 : : * "This product includes software developed by the OpenSSL Project
22 : : * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
23 : : *
24 : : * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
25 : : * endorse or promote products derived from this software without
26 : : * prior written permission. For written permission, please contact
27 : : * licensing@OpenSSL.org.
28 : : *
29 : : * 5. Products derived from this software may not be called "OpenSSL"
30 : : * nor may "OpenSSL" appear in their names without prior written
31 : : * permission of the OpenSSL Project.
32 : : *
33 : : * 6. Redistributions of any form whatsoever must retain the following
34 : : * acknowledgment:
35 : : * "This product includes software developed by the OpenSSL Project
36 : : * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
37 : : *
38 : : * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
39 : : * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40 : : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41 : : * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
42 : : * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43 : : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44 : : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45 : : * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46 : : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47 : : * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48 : : * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49 : : * OF THE POSSIBILITY OF SUCH DAMAGE.
50 : : * ====================================================================
51 : : *
52 : : * This product includes cryptographic software written by Eric Young
53 : : * (eay@cryptsoft.com). This product includes software written by Tim
54 : : * Hudson (tjh@cryptsoft.com).
55 : : *
56 : : */
57 : :
58 : :
59 : : #include <stdio.h>
60 : : #include "cryptlib.h"
61 : : #include <openssl/asn1.h>
62 : : #include <openssl/x509v3.h>
63 : : #include "../ssl/ssl_locl.h"
64 : :
65 : : #if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
66 : : #define SCT_TIMESTAMP unsigned __int64
67 : : #elif defined(__arch64__)
68 : : #define SCT_TIMESTAMP unsigned long
69 : : #else
70 : : #define SCT_TIMESTAMP unsigned long long
71 : : #endif
72 : :
73 : : #define n2l8(c,l) (l =((SCT_TIMESTAMP)(*((c)++)))<<56, \
74 : : l|=((SCT_TIMESTAMP)(*((c)++)))<<48, \
75 : : l|=((SCT_TIMESTAMP)(*((c)++)))<<40, \
76 : : l|=((SCT_TIMESTAMP)(*((c)++)))<<32, \
77 : : l|=((SCT_TIMESTAMP)(*((c)++)))<<24, \
78 : : l|=((SCT_TIMESTAMP)(*((c)++)))<<16, \
79 : : l|=((SCT_TIMESTAMP)(*((c)++)))<< 8, \
80 : : l|=((SCT_TIMESTAMP)(*((c)++))))
81 : :
82 : : typedef struct SCT_st {
83 : : /* The encoded SCT */
84 : : unsigned char *sct;
85 : : unsigned short sctlen;
86 : :
87 : : /* Components of the SCT. "logid", "ext" and "sig" point to addresses
88 : : * inside "sct".
89 : : */
90 : : unsigned char version;
91 : : unsigned char* logid;
92 : : unsigned short logidlen;
93 : : SCT_TIMESTAMP timestamp;
94 : : unsigned char *ext;
95 : : unsigned short extlen;
96 : : unsigned char hash_alg;
97 : : unsigned char sig_alg;
98 : : unsigned char *sig;
99 : : unsigned short siglen;
100 : : } SCT;
101 : :
102 : : DECLARE_STACK_OF(SCT)
103 : :
104 : : static void SCT_LIST_free(STACK_OF(SCT) *a);
105 : : static STACK_OF(SCT) *d2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp,
106 : : long length);
107 : : static int i2r_SCT_LIST(X509V3_EXT_METHOD *method, STACK_OF(SCT) *sct_list,
108 : : BIO *out, int indent);
109 : :
110 : : const X509V3_EXT_METHOD v3_ct_scts[] = {
111 : : { NID_ct_precert_scts, 0, NULL,
112 : : 0,(X509V3_EXT_FREE)SCT_LIST_free,
113 : : (X509V3_EXT_D2I)d2i_SCT_LIST, 0,
114 : : 0,0,0,0,
115 : : (X509V3_EXT_I2R)i2r_SCT_LIST, 0,
116 : : NULL},
117 : :
118 : : { NID_ct_cert_scts, 0, NULL,
119 : : 0,(X509V3_EXT_FREE)SCT_LIST_free,
120 : : (X509V3_EXT_D2I)d2i_SCT_LIST, 0,
121 : : 0,0,0,0,
122 : : (X509V3_EXT_I2R)i2r_SCT_LIST, 0,
123 : : NULL},
124 : : };
125 : :
126 : 0 : static void tls12_signature_print(BIO *out, const unsigned char hash_alg,
127 : : const unsigned char sig_alg)
128 : : {
129 : 0 : int nid = NID_undef;
130 : : /* RFC6962 only permits two signature algorithms */
131 [ # # ]: 0 : if (hash_alg == TLSEXT_hash_sha256)
132 : : {
133 [ # # ]: 0 : if (sig_alg == TLSEXT_signature_rsa)
134 : : nid = NID_sha256WithRSAEncryption;
135 [ # # ]: 0 : else if (sig_alg == TLSEXT_signature_ecdsa)
136 : 0 : nid = NID_ecdsa_with_SHA256;
137 : : }
138 [ # # ]: 0 : if (nid == NID_undef)
139 : 0 : BIO_printf(out, "%02X%02X", hash_alg, sig_alg);
140 : : else
141 : 0 : BIO_printf(out, "%s", OBJ_nid2ln(nid));
142 : 0 : }
143 : :
144 : 0 : static void timestamp_print(BIO *out, SCT_TIMESTAMP timestamp)
145 : : {
146 : : ASN1_GENERALIZEDTIME *gen;
147 : : char genstr[20];
148 : 0 : gen = ASN1_GENERALIZEDTIME_new();
149 : 0 : ASN1_GENERALIZEDTIME_adj(gen, (time_t)0,
150 : 0 : (int)(timestamp / 86400000),
151 : 0 : (timestamp % 86400000) / 1000);
152 : : /* Note GeneralizedTime from ASN1_GENERALIZETIME_adj is always 15
153 : : * characters long with a final Z. Update it with fractional seconds.
154 : : */
155 : 0 : BIO_snprintf(genstr, sizeof(genstr), "%.14s.%03dZ",
156 : : ASN1_STRING_data(gen),
157 : 0 : (unsigned int)(timestamp % 1000));
158 : 0 : ASN1_GENERALIZEDTIME_set_string(gen, genstr);
159 : 0 : ASN1_GENERALIZEDTIME_print(out, gen);
160 : 0 : ASN1_GENERALIZEDTIME_free(gen);
161 : 0 : }
162 : :
163 : 0 : static void SCT_free(SCT *sct)
164 : : {
165 [ # # ]: 0 : if (sct)
166 : : {
167 [ # # ]: 0 : if (sct->sct) OPENSSL_free(sct->sct);
168 : 0 : OPENSSL_free(sct);
169 : : }
170 : 0 : }
171 : :
172 : 0 : static void SCT_LIST_free(STACK_OF(SCT) *a)
173 : : {
174 : 0 : sk_SCT_pop_free(a, SCT_free);
175 : 0 : }
176 : :
177 : 0 : static STACK_OF(SCT) *d2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp,
178 : : long length)
179 : : {
180 : 0 : ASN1_OCTET_STRING *oct = NULL;
181 : 0 : STACK_OF(SCT) *sk = NULL;
182 : : SCT *sct;
183 : : unsigned char *p, *p2;
184 : 0 : unsigned short listlen, sctlen = 0, fieldlen;
185 : :
186 [ # # ]: 0 : if (d2i_ASN1_OCTET_STRING(&oct, pp, length) == NULL)
187 : : return NULL;
188 [ # # ]: 0 : if (oct->length < 2)
189 : : goto done;
190 : 0 : p = oct->data;
191 : 0 : n2s(p, listlen);
192 [ # # ]: 0 : if (listlen != oct->length - 2)
193 : : goto done;
194 : :
195 [ # # ]: 0 : if ((sk=sk_SCT_new_null()) == NULL)
196 : : goto done;
197 : :
198 [ # # ]: 0 : while (listlen > 0)
199 : : {
200 [ # # ]: 0 : if (listlen < 2)
201 : : goto err;
202 : 0 : n2s(p, sctlen);
203 : 0 : listlen -= 2;
204 : :
205 [ # # ]: 0 : if ((sctlen < 1) || (sctlen > listlen))
206 : : goto err;
207 : 0 : listlen -= sctlen;
208 : :
209 : 0 : sct = OPENSSL_malloc(sizeof(SCT));
210 [ # # ]: 0 : if (!sct)
211 : : goto err;
212 [ # # ]: 0 : if (!sk_SCT_push(sk, sct))
213 : : {
214 : 0 : OPENSSL_free(sct);
215 : 0 : goto err;
216 : : }
217 : :
218 : 0 : sct->sct = OPENSSL_malloc(sctlen);
219 [ # # ]: 0 : if (!sct->sct)
220 : : goto err;
221 : 0 : memcpy(sct->sct, p, sctlen);
222 : 0 : sct->sctlen = sctlen;
223 : 0 : p += sctlen;
224 : 0 : p2 = sct->sct;
225 : :
226 : 0 : sct->version = *p2++;
227 [ # # ]: 0 : if (sct->version == 0) /* SCT v1 */
228 : : {
229 : : /* Fixed-length header:
230 : : * struct {
231 : : * (1 byte) Version sct_version;
232 : : * (32 bytes) LogID id;
233 : : * (8 bytes) uint64 timestamp;
234 : : * (2 bytes + ?) CtExtensions extensions;
235 : : */
236 [ # # ]: 0 : if (sctlen < 43)
237 : : goto err;
238 : 0 : sctlen -= 43;
239 : :
240 : 0 : sct->logid = p2;
241 : 0 : sct->logidlen = 32;
242 : 0 : p2 += 32;
243 : :
244 : 0 : n2l8(p2, sct->timestamp);
245 : :
246 : 0 : n2s(p2, fieldlen);
247 [ # # ]: 0 : if (sctlen < fieldlen)
248 : : goto err;
249 : 0 : sct->ext = p2;
250 : 0 : sct->extlen = fieldlen;
251 : 0 : p2 += fieldlen;
252 : 0 : sctlen -= fieldlen;
253 : :
254 : : /* digitally-signed struct header:
255 : : * (1 byte) Hash algorithm
256 : : * (1 byte) Signature algorithm
257 : : * (2 bytes + ?) Signature
258 : : */
259 [ # # ]: 0 : if (sctlen < 4)
260 : : goto err;
261 : 0 : sctlen -= 4;
262 : :
263 : 0 : sct->hash_alg = *p2++;
264 : 0 : sct->sig_alg = *p2++;
265 : 0 : n2s(p2, fieldlen);
266 [ # # ]: 0 : if (sctlen != fieldlen)
267 : : goto err;
268 : 0 : sct->sig = p2;
269 : 0 : sct->siglen = fieldlen;
270 : : }
271 : : }
272 : :
273 : : done:
274 : 0 : ASN1_OCTET_STRING_free(oct);
275 : 0 : return sk;
276 : :
277 : : err:
278 : 0 : SCT_LIST_free(sk);
279 : 0 : sk = NULL;
280 : 0 : goto done;
281 : : }
282 : :
283 : 0 : static int i2r_SCT_LIST(X509V3_EXT_METHOD *method, STACK_OF(SCT) *sct_list,
284 : : BIO *out, int indent)
285 : : {
286 : : SCT *sct;
287 : : int i;
288 : :
289 [ # # ]: 0 : for (i = 0; i < sk_SCT_num(sct_list);) {
290 : 0 : sct = sk_SCT_value(sct_list, i);
291 : :
292 : 0 : BIO_printf(out, "%*sSigned Certificate Timestamp:", indent, "");
293 : 0 : BIO_printf(out, "\n%*sVersion : ", indent + 4, "");
294 : :
295 [ # # ]: 0 : if (sct->version == 0) /* SCT v1 */
296 : : {
297 : 0 : BIO_printf(out, "v1(0)");
298 : :
299 : 0 : BIO_printf(out, "\n%*sLog ID : ", indent + 4, "");
300 : 0 : BIO_hex_string(out, indent + 16, 16, sct->logid,
301 : 0 : sct->logidlen);
302 : :
303 : 0 : BIO_printf(out, "\n%*sTimestamp : ", indent + 4, "");
304 : 0 : timestamp_print(out, sct->timestamp);
305 : :
306 : 0 : BIO_printf(out, "\n%*sExtensions: ", indent + 4, "");
307 [ # # ]: 0 : if (sct->extlen == 0)
308 : 0 : BIO_printf(out, "none");
309 : : else
310 : 0 : BIO_hex_string(out, indent + 16, 16, sct->ext,
311 : : sct->extlen);
312 : :
313 : 0 : BIO_printf(out, "\n%*sSignature : ", indent + 4, "");
314 : 0 : tls12_signature_print(out, sct->hash_alg, sct->sig_alg);
315 : 0 : BIO_printf(out, "\n%*s ", indent + 4, "");
316 : 0 : BIO_hex_string(out, indent + 16, 16, sct->sig,
317 : 0 : sct->siglen);
318 : : }
319 : : else /* Unknown version */
320 : : {
321 : 0 : BIO_printf(out, "unknown\n%*s", indent + 16, "");
322 : 0 : BIO_hex_string(out, indent + 16, 16, sct->sct,
323 : 0 : sct->sctlen);
324 : : }
325 : :
326 [ # # ]: 0 : if (++i < sk_SCT_num(sct_list)) BIO_printf(out, "\n");
327 : : }
328 : :
329 : 0 : return 1;
330 : : }
|