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