1 /* $OpenBSD: ct_oct.c,v 1.9 2023/07/08 07:22:58 beck 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 LCRYPTO_ALIAS(o2i_SCT); 212 213 int 214 i2o_SCT_signature(const SCT *sct, unsigned char **out) 215 { 216 size_t len; 217 unsigned char *p = NULL, *pstart = NULL; 218 219 if (!SCT_signature_is_complete(sct)) { 220 CTerror(CT_R_SCT_INVALID_SIGNATURE); 221 goto err; 222 } 223 224 if (sct->version != SCT_VERSION_V1) { 225 CTerror(CT_R_UNSUPPORTED_VERSION); 226 goto err; 227 } 228 229 /* 230 * (1 byte) Hash algorithm 231 * (1 byte) Signature algorithm 232 * (2 bytes + ?) Signature 233 */ 234 len = 4 + sct->sig_len; 235 236 if (out != NULL) { 237 if (*out != NULL) { 238 p = *out; 239 *out += len; 240 } else { 241 pstart = p = malloc(len); 242 if (p == NULL) { 243 CTerror(ERR_R_MALLOC_FAILURE); 244 goto err; 245 } 246 *out = p; 247 } 248 249 *p++ = sct->hash_alg; 250 *p++ = sct->sig_alg; 251 s2n(sct->sig_len, p); 252 memcpy(p, sct->sig, sct->sig_len); 253 } 254 255 return len; 256 err: 257 free(pstart); 258 return -1; 259 } 260 261 int 262 i2o_SCT(const SCT *sct, unsigned char **out) 263 { 264 size_t len; 265 unsigned char *p = NULL, *pstart = NULL; 266 267 if (!SCT_is_complete(sct)) { 268 CTerror(CT_R_SCT_NOT_SET); 269 goto err; 270 } 271 /* 272 * Fixed-length header: struct { (1 byte) Version sct_version; (32 bytes) 273 * log_id id; (8 bytes) uint64 timestamp; (2 bytes + ?) CtExtensions 274 * extensions; (1 byte) Hash algorithm (1 byte) Signature algorithm (2 275 * bytes + ?) Signature 276 */ 277 if (sct->version == SCT_VERSION_V1) 278 len = 43 + sct->ext_len + 4 + sct->sig_len; 279 else 280 len = sct->sct_len; 281 282 if (out == NULL) 283 return len; 284 285 if (*out != NULL) { 286 p = *out; 287 *out += len; 288 } else { 289 pstart = p = malloc(len); 290 if (p == NULL) { 291 CTerror(ERR_R_MALLOC_FAILURE); 292 goto err; 293 } 294 *out = p; 295 } 296 297 if (sct->version == SCT_VERSION_V1) { 298 *p++ = sct->version; 299 memcpy(p, sct->log_id, CT_V1_HASHLEN); 300 p += CT_V1_HASHLEN; 301 l2n8(sct->timestamp, p); 302 s2n(sct->ext_len, p); 303 if (sct->ext_len > 0) { 304 memcpy(p, sct->ext, sct->ext_len); 305 p += sct->ext_len; 306 } 307 if (i2o_SCT_signature(sct, &p) <= 0) 308 goto err; 309 } else { 310 memcpy(p, sct->sct, len); 311 } 312 313 return len; 314 err: 315 free(pstart); 316 return -1; 317 } 318 LCRYPTO_ALIAS(i2o_SCT); 319 320 STACK_OF(SCT) * 321 o2i_SCT_LIST(STACK_OF(SCT) **out_scts, const unsigned char **pp, size_t len) 322 { 323 CBS cbs, cbs_scts, cbs_sct; 324 STACK_OF(SCT) *scts = NULL; 325 326 CBS_init(&cbs, *pp, len); 327 328 if (CBS_len(&cbs) > MAX_SCT_LIST_SIZE) 329 goto err_invalid; 330 if (!CBS_get_u16_length_prefixed(&cbs, &cbs_scts)) 331 goto err_invalid; 332 if (CBS_len(&cbs) != 0) 333 goto err_invalid; 334 335 if (out_scts != NULL) { 336 SCT_LIST_free(*out_scts); 337 *out_scts = NULL; 338 } 339 340 if ((scts = sk_SCT_new_null()) == NULL) 341 return NULL; 342 343 while (CBS_len(&cbs_scts) > 0) { 344 SCT *sct; 345 346 if (!CBS_get_u16_length_prefixed(&cbs_scts, &cbs_sct)) 347 goto err_invalid; 348 349 if (!o2i_SCT_internal(&sct, &cbs_sct)) 350 goto err; 351 if (!sk_SCT_push(scts, sct)) { 352 SCT_free(sct); 353 goto err; 354 } 355 } 356 357 if (out_scts != NULL) 358 *out_scts = scts; 359 360 *pp = CBS_data(&cbs); 361 362 return scts; 363 364 err_invalid: 365 CTerror(CT_R_SCT_LIST_INVALID); 366 err: 367 SCT_LIST_free(scts); 368 369 return NULL; 370 } 371 LCRYPTO_ALIAS(o2i_SCT_LIST); 372 373 int 374 i2o_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **pp) 375 { 376 int len, sct_len, i, is_pp_new = 0; 377 size_t len2; 378 unsigned char *p = NULL, *p2; 379 380 if (pp != NULL) { 381 if (*pp == NULL) { 382 if ((len = i2o_SCT_LIST(a, NULL)) == -1) { 383 CTerror(CT_R_SCT_LIST_INVALID); 384 return -1; 385 } 386 if ((*pp = malloc(len)) == NULL) { 387 CTerror(ERR_R_MALLOC_FAILURE); 388 return -1; 389 } 390 is_pp_new = 1; 391 } 392 p = *pp + 2; 393 } 394 395 len2 = 2; 396 for (i = 0; i < sk_SCT_num(a); i++) { 397 if (pp != NULL) { 398 p2 = p; 399 p += 2; 400 if ((sct_len = i2o_SCT(sk_SCT_value(a, i), &p)) == -1) 401 goto err; 402 s2n(sct_len, p2); 403 } else { 404 if ((sct_len = i2o_SCT(sk_SCT_value(a, i), NULL)) == -1) 405 goto err; 406 } 407 len2 += 2 + sct_len; 408 } 409 410 if (len2 > MAX_SCT_LIST_SIZE) 411 goto err; 412 413 if (pp != NULL) { 414 p = *pp; 415 s2n(len2 - 2, p); 416 if (!is_pp_new) 417 *pp += len2; 418 } 419 return len2; 420 421 err: 422 if (is_pp_new) { 423 free(*pp); 424 *pp = NULL; 425 } 426 return -1; 427 } 428 LCRYPTO_ALIAS(i2o_SCT_LIST); 429 430 STACK_OF(SCT) * 431 d2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp, long len) 432 { 433 ASN1_OCTET_STRING *oct = NULL; 434 STACK_OF(SCT) *sk = NULL; 435 const unsigned char *p; 436 437 p = *pp; 438 if (d2i_ASN1_OCTET_STRING(&oct, &p, len) == NULL) 439 return NULL; 440 441 p = oct->data; 442 if ((sk = o2i_SCT_LIST(a, &p, oct->length)) != NULL) 443 *pp += len; 444 445 ASN1_OCTET_STRING_free(oct); 446 return sk; 447 } 448 LCRYPTO_ALIAS(d2i_SCT_LIST); 449 450 int 451 i2d_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **out) 452 { 453 ASN1_OCTET_STRING oct; 454 int len; 455 456 oct.data = NULL; 457 if ((oct.length = i2o_SCT_LIST(a, &oct.data)) == -1) 458 return -1; 459 460 len = i2d_ASN1_OCTET_STRING(&oct, out); 461 free(oct.data); 462 return len; 463 } 464 LCRYPTO_ALIAS(i2d_SCT_LIST); 465