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, ×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 * 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