1 /* $OpenBSD: a_int.c,v 1.34 2019/04/28 05:03:56 tb Exp $ */ 2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3 * All rights reserved. 4 * 5 * This package is an SSL implementation written 6 * by Eric Young (eay@cryptsoft.com). 7 * The implementation was written so as to conform with Netscapes SSL. 8 * 9 * This library is free for commercial and non-commercial use as long as 10 * the following conditions are aheared to. The following conditions 11 * apply to all code found in this distribution, be it the RC4, RSA, 12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13 * included with this distribution is covered by the same copyright terms 14 * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15 * 16 * Copyright remains Eric Young's, and as such any Copyright notices in 17 * the code are not to be removed. 18 * If this package is used in a product, Eric Young should be given attribution 19 * as the author of the parts of the library used. 20 * This can be in the form of a textual message at program startup or 21 * in documentation (online or textual) provided with the package. 22 * 23 * Redistribution and use in source and binary forms, with or without 24 * modification, are permitted provided that the following conditions 25 * are met: 26 * 1. Redistributions of source code must retain the copyright 27 * notice, this list of conditions and the following disclaimer. 28 * 2. Redistributions in binary form must reproduce the above copyright 29 * notice, this list of conditions and the following disclaimer in the 30 * documentation and/or other materials provided with the distribution. 31 * 3. All advertising materials mentioning features or use of this software 32 * must display the following acknowledgement: 33 * "This product includes cryptographic software written by 34 * Eric Young (eay@cryptsoft.com)" 35 * The word 'cryptographic' can be left out if the rouines from the library 36 * being used are not cryptographic related :-). 37 * 4. If you include any Windows specific code (or a derivative thereof) from 38 * the apps directory (application code) you must include an acknowledgement: 39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40 * 41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51 * SUCH DAMAGE. 52 * 53 * The licence and distribution terms for any publically available version or 54 * derivative of this code cannot be changed. i.e. this code cannot simply be 55 * copied and put under another distribution licence 56 * [including the GNU Public Licence.] 57 */ 58 59 #include <limits.h> 60 #include <stdio.h> 61 #include <string.h> 62 63 #include <openssl/asn1.h> 64 #include <openssl/bn.h> 65 #include <openssl/err.h> 66 67 static int 68 ASN1_INTEGER_valid(const ASN1_INTEGER *a) 69 { 70 return (a != NULL && a->length >= 0); 71 } 72 73 ASN1_INTEGER * 74 ASN1_INTEGER_dup(const ASN1_INTEGER *x) 75 { 76 if (!ASN1_INTEGER_valid(x)) 77 return NULL; 78 79 return ASN1_STRING_dup(x); 80 } 81 82 int 83 ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y) 84 { 85 int neg, ret; 86 87 /* Compare signs */ 88 neg = x->type & V_ASN1_NEG; 89 if (neg != (y->type & V_ASN1_NEG)) { 90 if (neg) 91 return -1; 92 else 93 return 1; 94 } 95 96 ret = ASN1_STRING_cmp(x, y); 97 98 if (neg) 99 return -ret; 100 else 101 return ret; 102 } 103 104 105 /* 106 * This converts an ASN1 INTEGER into its content encoding. 107 * The internal representation is an ASN1_STRING whose data is a big endian 108 * representation of the value, ignoring the sign. The sign is determined by 109 * the type: V_ASN1_INTEGER for positive and V_ASN1_NEG_INTEGER for negative. 110 * 111 * Positive integers are no problem: they are almost the same as the DER 112 * encoding, except if the first byte is >= 0x80 we need to add a zero pad. 113 * 114 * Negative integers are a bit trickier... 115 * The DER representation of negative integers is in 2s complement form. 116 * The internal form is converted by complementing each octet and finally 117 * adding one to the result. This can be done less messily with a little trick. 118 * If the internal form has trailing zeroes then they will become FF by the 119 * complement and 0 by the add one (due to carry) so just copy as many trailing 120 * zeros to the destination as there are in the source. The carry will add one 121 * to the last none zero octet: so complement this octet and add one and finally 122 * complement any left over until you get to the start of the string. 123 * 124 * Padding is a little trickier too. If the first bytes is > 0x80 then we pad 125 * with 0xff. However if the first byte is 0x80 and one of the following bytes 126 * is non-zero we pad with 0xff. The reason for this distinction is that 0x80 127 * followed by optional zeros isn't padded. 128 */ 129 130 int 131 i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp) 132 { 133 int pad = 0, ret, i, neg; 134 unsigned char *p, *n, pb = 0; 135 136 if (!ASN1_INTEGER_valid(a)) 137 return 0; 138 139 neg = a->type & V_ASN1_NEG; 140 if (a->length == 0) 141 ret = 1; 142 else { 143 ret = a->length; 144 i = a->data[0]; 145 if (!neg && (i > 127)) { 146 pad = 1; 147 pb = 0; 148 } else if (neg) { 149 if (i > 128) { 150 pad = 1; 151 pb = 0xFF; 152 } else if (i == 128) { 153 /* 154 * Special case: if any other bytes non zero we pad: 155 * otherwise we don't. 156 */ 157 for (i = 1; i < a->length; i++) if (a->data[i]) { 158 pad = 1; 159 pb = 0xFF; 160 break; 161 } 162 } 163 } 164 ret += pad; 165 } 166 if (pp == NULL) 167 return (ret); 168 p= *pp; 169 170 if (pad) 171 *(p++) = pb; 172 if (a->length == 0) 173 *(p++) = 0; 174 else if (!neg) 175 memcpy(p, a->data, a->length); 176 else { 177 /* Begin at the end of the encoding */ 178 n = a->data + a->length - 1; 179 p += a->length - 1; 180 i = a->length; 181 /* Copy zeros to destination as long as source is zero */ 182 while (!*n) { 183 *(p--) = 0; 184 n--; 185 i--; 186 } 187 /* Complement and increment next octet */ 188 *(p--) = ((*(n--)) ^ 0xff) + 1; 189 i--; 190 /* Complement any octets left */ 191 for (; i > 0; i--) 192 *(p--) = *(n--) ^ 0xff; 193 } 194 195 *pp += ret; 196 return (ret); 197 } 198 199 /* Convert just ASN1 INTEGER content octets to ASN1_INTEGER structure */ 200 201 ASN1_INTEGER * 202 c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp, long len) 203 { 204 ASN1_INTEGER *ret = NULL; 205 const unsigned char *p, *pend; 206 unsigned char *to, *s; 207 int i; 208 209 if ((a == NULL) || ((*a) == NULL)) { 210 if ((ret = ASN1_INTEGER_new()) == NULL) 211 return (NULL); 212 } else 213 ret = (*a); 214 215 if (!ASN1_INTEGER_valid(ret)) { 216 /* 217 * XXX using i for an alert is confusing, 218 * we should call this al 219 */ 220 i = ERR_R_ASN1_LENGTH_MISMATCH; 221 goto err; 222 } 223 224 p = *pp; 225 pend = p + len; 226 227 /* We must malloc stuff, even for 0 bytes otherwise it 228 * signifies a missing NULL parameter. */ 229 if (len < 0 || len > INT_MAX) { 230 i = ERR_R_ASN1_LENGTH_MISMATCH; 231 goto err; 232 } 233 s = malloc(len + 1); 234 if (s == NULL) { 235 i = ERR_R_MALLOC_FAILURE; 236 goto err; 237 } 238 to = s; 239 if (!len) { 240 /* Strictly speaking this is an illegal INTEGER but we 241 * tolerate it. 242 */ 243 ret->type = V_ASN1_INTEGER; 244 } else if (*p & 0x80) /* a negative number */ { 245 ret->type = V_ASN1_NEG_INTEGER; 246 if ((*p == 0xff) && (len != 1)) { 247 p++; 248 len--; 249 } 250 i = len; 251 p += i - 1; 252 to += i - 1; 253 while((!*p) && i) { 254 *(to--) = 0; 255 i--; 256 p--; 257 } 258 /* Special case: if all zeros then the number will be of 259 * the form FF followed by n zero bytes: this corresponds to 260 * 1 followed by n zero bytes. We've already written n zeros 261 * so we just append an extra one and set the first byte to 262 * a 1. This is treated separately because it is the only case 263 * where the number of bytes is larger than len. 264 */ 265 if (!i) { 266 *s = 1; 267 s[len] = 0; 268 len++; 269 } else { 270 *(to--) = (*(p--) ^ 0xff) + 1; 271 i--; 272 for (; i > 0; i--) 273 *(to--) = *(p--) ^ 0xff; 274 } 275 } else { 276 ret->type = V_ASN1_INTEGER; 277 if ((*p == 0) && (len != 1)) { 278 p++; 279 len--; 280 } 281 memcpy(s, p, len); 282 } 283 284 free(ret->data); 285 ret->data = s; 286 ret->length = (int)len; 287 if (a != NULL) 288 (*a) = ret; 289 *pp = pend; 290 return (ret); 291 292 err: 293 ASN1error(i); 294 if (a == NULL || *a != ret) 295 ASN1_INTEGER_free(ret); 296 return (NULL); 297 } 298 299 300 /* This is a version of d2i_ASN1_INTEGER that ignores the sign bit of 301 * ASN1 integers: some broken software can encode a positive INTEGER 302 * with its MSB set as negative (it doesn't add a padding zero). 303 */ 304 305 ASN1_INTEGER * 306 d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp, long length) 307 { 308 ASN1_INTEGER *ret = NULL; 309 const unsigned char *p; 310 unsigned char *s; 311 long len; 312 int inf, tag, xclass; 313 int i; 314 315 if ((a == NULL) || ((*a) == NULL)) { 316 if ((ret = ASN1_INTEGER_new()) == NULL) 317 return (NULL); 318 } else 319 ret = (*a); 320 321 if (!ASN1_INTEGER_valid(ret)) { 322 i = ERR_R_ASN1_LENGTH_MISMATCH; 323 goto err; 324 } 325 326 p = *pp; 327 inf = ASN1_get_object(&p, &len, &tag, &xclass, length); 328 if (inf & 0x80) { 329 i = ASN1_R_BAD_OBJECT_HEADER; 330 goto err; 331 } 332 333 if (tag != V_ASN1_INTEGER) { 334 i = ASN1_R_EXPECTING_AN_INTEGER; 335 goto err; 336 } 337 338 /* We must malloc stuff, even for 0 bytes otherwise it 339 * signifies a missing NULL parameter. */ 340 if (len < 0 || len > INT_MAX) { 341 i = ERR_R_ASN1_LENGTH_MISMATCH; 342 goto err; 343 } 344 s = malloc(len + 1); 345 if (s == NULL) { 346 i = ERR_R_MALLOC_FAILURE; 347 goto err; 348 } 349 ret->type = V_ASN1_INTEGER; 350 if (len) { 351 if ((*p == 0) && (len != 1)) { 352 p++; 353 len--; 354 } 355 memcpy(s, p, len); 356 p += len; 357 } 358 359 free(ret->data); 360 ret->data = s; 361 ret->length = (int)len; 362 if (a != NULL) 363 (*a) = ret; 364 *pp = p; 365 return (ret); 366 367 err: 368 ASN1error(i); 369 if (a == NULL || *a != ret) 370 ASN1_INTEGER_free(ret); 371 return (NULL); 372 } 373 374 int 375 ASN1_INTEGER_set(ASN1_INTEGER *a, long v) 376 { 377 int j, k; 378 unsigned int i; 379 unsigned char buf[sizeof(long) + 1]; 380 long d; 381 382 a->type = V_ASN1_INTEGER; 383 /* XXX ssl/ssl_asn1.c:i2d_SSL_SESSION() depends upon this bound vae */ 384 if (a->length < (int)(sizeof(long) + 1)) { 385 free(a->data); 386 a->data = calloc(1, sizeof(long) + 1); 387 } 388 if (a->data == NULL) { 389 ASN1error(ERR_R_MALLOC_FAILURE); 390 return (0); 391 } 392 d = v; 393 if (d < 0) { 394 d = -d; 395 a->type = V_ASN1_NEG_INTEGER; 396 } 397 398 for (i = 0; i < sizeof(long); i++) { 399 if (d == 0) 400 break; 401 buf[i] = (int)d & 0xff; 402 d >>= 8; 403 } 404 j = 0; 405 for (k = i - 1; k >= 0; k--) 406 a->data[j++] = buf[k]; 407 a->length = j; 408 return (1); 409 } 410 411 /* 412 * XXX this particular API is a gibbering eidrich horror that makes it 413 * impossible to determine valid return cases from errors.. "a bit 414 * ugly" is preserved for posterity, unfortunately this is probably 415 * unfixable without changing public API 416 */ 417 long 418 ASN1_INTEGER_get(const ASN1_INTEGER *a) 419 { 420 int neg = 0, i; 421 unsigned long r = 0; 422 423 if (a == NULL) 424 return (0L); 425 i = a->type; 426 if (i == V_ASN1_NEG_INTEGER) 427 neg = 1; 428 else if (i != V_ASN1_INTEGER) 429 return -1; 430 431 if (!ASN1_INTEGER_valid(a)) 432 return -1; /* XXX best effort */ 433 434 if (a->length > (int)sizeof(long)) { 435 /* hmm... a bit ugly, return all ones */ 436 return -1; 437 } 438 if (a->data == NULL) 439 return 0; 440 441 for (i = 0; i < a->length; i++) { 442 r <<= 8; 443 r |= (unsigned char)a->data[i]; 444 } 445 446 if (r > LONG_MAX) 447 return -1; 448 449 if (neg) 450 return -(long)r; 451 return (long)r; 452 } 453 454 ASN1_INTEGER * 455 BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai) 456 { 457 ASN1_INTEGER *ret; 458 int len, j; 459 460 if (ai == NULL) 461 ret = ASN1_INTEGER_new(); 462 else 463 ret = ai; 464 if (ret == NULL) { 465 ASN1error(ERR_R_NESTED_ASN1_ERROR); 466 goto err; 467 } 468 469 if (!ASN1_INTEGER_valid(ret)) 470 goto err; 471 472 if (BN_is_negative(bn)) 473 ret->type = V_ASN1_NEG_INTEGER; 474 else 475 ret->type = V_ASN1_INTEGER; 476 j = BN_num_bits(bn); 477 len = ((j == 0) ? 0 : ((j / 8) + 1)); 478 if (ret->length < len + 4) { 479 unsigned char *new_data = realloc(ret->data, len + 4); 480 if (!new_data) { 481 ASN1error(ERR_R_MALLOC_FAILURE); 482 goto err; 483 } 484 ret->data = new_data; 485 } 486 ret->length = BN_bn2bin(bn, ret->data); 487 488 /* Correct zero case */ 489 if (!ret->length) { 490 ret->data[0] = 0; 491 ret->length = 1; 492 } 493 return (ret); 494 495 err: 496 if (ret != ai) 497 ASN1_INTEGER_free(ret); 498 return (NULL); 499 } 500 501 BIGNUM * 502 ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn) 503 { 504 BIGNUM *ret; 505 506 if (!ASN1_INTEGER_valid(ai)) 507 return (NULL); 508 509 if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL) 510 ASN1error(ASN1_R_BN_LIB); 511 else if (ai->type == V_ASN1_NEG_INTEGER) 512 BN_set_negative(ret, 1); 513 return (ret); 514 } 515