1/* crypto/asn1/a_int.c */ 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 <stdio.h> 60#include "cryptlib.h" 61#include <openssl/asn1.h> 62 63ASN1_INTEGER *ASN1_INTEGER_dup(ASN1_INTEGER *x) 64{ return M_ASN1_INTEGER_dup(x);} 65 66int ASN1_INTEGER_cmp(ASN1_INTEGER *x, ASN1_INTEGER *y) 67 { 68 int neg, ret; 69 /* Compare signs */ 70 neg = x->type & V_ASN1_NEG; 71 if (neg != (y->type & V_ASN1_NEG)) 72 { 73 if (neg) 74 return -1; 75 else 76 return 1; 77 } 78 79 ret = ASN1_STRING_cmp(x, y); 80 81 if (neg) 82 return -ret; 83 else 84 return ret; 85 } 86 87 88/* 89 * This converts an ASN1 INTEGER into its content encoding. 90 * The internal representation is an ASN1_STRING whose data is a big endian 91 * representation of the value, ignoring the sign. The sign is determined by 92 * the type: V_ASN1_INTEGER for positive and V_ASN1_NEG_INTEGER for negative. 93 * 94 * Positive integers are no problem: they are almost the same as the DER 95 * encoding, except if the first byte is >= 0x80 we need to add a zero pad. 96 * 97 * Negative integers are a bit trickier... 98 * The DER representation of negative integers is in 2s complement form. 99 * The internal form is converted by complementing each octet and finally 100 * adding one to the result. This can be done less messily with a little trick. 101 * If the internal form has trailing zeroes then they will become FF by the 102 * complement and 0 by the add one (due to carry) so just copy as many trailing 103 * zeros to the destination as there are in the source. The carry will add one 104 * to the last none zero octet: so complement this octet and add one and finally 105 * complement any left over until you get to the start of the string. 106 * 107 * Padding is a little trickier too. If the first bytes is > 0x80 then we pad 108 * with 0xff. However if the first byte is 0x80 and one of the following bytes 109 * is non-zero we pad with 0xff. The reason for this distinction is that 0x80 110 * followed by optional zeros isn't padded. 111 */ 112 113int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp) 114 { 115 int pad=0,ret,i,neg; 116 unsigned char *p,*n,pb=0; 117 118 if ((a == NULL) || (a->data == NULL)) return(0); 119 neg=a->type & V_ASN1_NEG; 120 if (a->length == 0) 121 ret=1; 122 else 123 { 124 ret=a->length; 125 i=a->data[0]; 126 if (!neg && (i > 127)) { 127 pad=1; 128 pb=0; 129 } else if(neg) { 130 if(i>128) { 131 pad=1; 132 pb=0xFF; 133 } else if(i == 128) { 134 /* 135 * Special case: if any other bytes non zero we pad: 136 * otherwise we don't. 137 */ 138 for(i = 1; i < a->length; i++) if(a->data[i]) { 139 pad=1; 140 pb=0xFF; 141 break; 142 } 143 } 144 } 145 ret+=pad; 146 } 147 if (pp == NULL) return(ret); 148 p= *pp; 149 150 if (pad) *(p++)=pb; 151 if (a->length == 0) *(p++)=0; 152 else if (!neg) memcpy(p,a->data,(unsigned int)a->length); 153 else { 154 /* Begin at the end of the encoding */ 155 n=a->data + a->length - 1; 156 p += a->length - 1; 157 i = a->length; 158 /* Copy zeros to destination as long as source is zero */ 159 while(!*n) { 160 *(p--) = 0; 161 n--; 162 i--; 163 } 164 /* Complement and increment next octet */ 165 *(p--) = ((*(n--)) ^ 0xff) + 1; 166 i--; 167 /* Complement any octets left */ 168 for(;i > 0; i--) *(p--) = *(n--) ^ 0xff; 169 } 170 171 *pp+=ret; 172 return(ret); 173 } 174 175/* Convert just ASN1 INTEGER content octets to ASN1_INTEGER structure */ 176 177ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, unsigned char **pp, 178 long len) 179 { 180 ASN1_INTEGER *ret=NULL; 181 unsigned char *p,*to,*s, *pend; 182 int i; 183 184 if ((a == NULL) || ((*a) == NULL)) 185 { 186 if ((ret=M_ASN1_INTEGER_new()) == NULL) return(NULL); 187 ret->type=V_ASN1_INTEGER; 188 } 189 else 190 ret=(*a); 191 192 p= *pp; 193 pend = p + len; 194 195 /* We must OPENSSL_malloc stuff, even for 0 bytes otherwise it 196 * signifies a missing NULL parameter. */ 197 s=(unsigned char *)OPENSSL_malloc((int)len+1); 198 if (s == NULL) 199 { 200 i=ERR_R_MALLOC_FAILURE; 201 goto err; 202 } 203 to=s; 204 if(!len) { 205 /* Strictly speaking this is an illegal INTEGER but we 206 * tolerate it. 207 */ 208 ret->type=V_ASN1_INTEGER; 209 } else if (*p & 0x80) /* a negative number */ 210 { 211 ret->type=V_ASN1_NEG_INTEGER; 212 if ((*p == 0xff) && (len != 1)) { 213 p++; 214 len--; 215 } 216 i = len; 217 p += i - 1; 218 to += i - 1; 219 while((!*p) && i) { 220 *(to--) = 0; 221 i--; 222 p--; 223 } 224 /* Special case: if all zeros then the number will be of 225 * the form FF followed by n zero bytes: this corresponds to 226 * 1 followed by n zero bytes. We've already written n zeros 227 * so we just append an extra one and set the first byte to 228 * a 1. This is treated separately because it is the only case 229 * where the number of bytes is larger than len. 230 */ 231 if(!i) { 232 *s = 1; 233 s[len] = 0; 234 len++; 235 } else { 236 *(to--) = (*(p--) ^ 0xff) + 1; 237 i--; 238 for(;i > 0; i--) *(to--) = *(p--) ^ 0xff; 239 } 240 } else { 241 ret->type=V_ASN1_INTEGER; 242 if ((*p == 0) && (len != 1)) 243 { 244 p++; 245 len--; 246 } 247 memcpy(s,p,(int)len); 248 } 249 250 if (ret->data != NULL) OPENSSL_free(ret->data); 251 ret->data=s; 252 ret->length=(int)len; 253 if (a != NULL) (*a)=ret; 254 *pp=pend; 255 return(ret); 256err: 257 ASN1err(ASN1_F_D2I_ASN1_INTEGER,i); 258 if ((ret != NULL) && ((a == NULL) || (*a != ret))) 259 M_ASN1_INTEGER_free(ret); 260 return(NULL); 261 } 262 263 264/* This is a version of d2i_ASN1_INTEGER that ignores the sign bit of 265 * ASN1 integers: some broken software can encode a positive INTEGER 266 * with its MSB set as negative (it doesn't add a padding zero). 267 */ 268 269ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, unsigned char **pp, 270 long length) 271 { 272 ASN1_INTEGER *ret=NULL; 273 unsigned char *p,*to,*s; 274 long len; 275 int inf,tag,xclass; 276 int i; 277 278 if ((a == NULL) || ((*a) == NULL)) 279 { 280 if ((ret=M_ASN1_INTEGER_new()) == NULL) return(NULL); 281 ret->type=V_ASN1_INTEGER; 282 } 283 else 284 ret=(*a); 285 286 p= *pp; 287 inf=ASN1_get_object(&p,&len,&tag,&xclass,length); 288 if (inf & 0x80) 289 { 290 i=ASN1_R_BAD_OBJECT_HEADER; 291 goto err; 292 } 293 294 if (tag != V_ASN1_INTEGER) 295 { 296 i=ASN1_R_EXPECTING_AN_INTEGER; 297 goto err; 298 } 299 300 /* We must OPENSSL_malloc stuff, even for 0 bytes otherwise it 301 * signifies a missing NULL parameter. */ 302 s=(unsigned char *)OPENSSL_malloc((int)len+1); 303 if (s == NULL) 304 { 305 i=ERR_R_MALLOC_FAILURE; 306 goto err; 307 } 308 to=s; 309 ret->type=V_ASN1_INTEGER; 310 if(len) { 311 if ((*p == 0) && (len != 1)) 312 { 313 p++; 314 len--; 315 } 316 memcpy(s,p,(int)len); 317 p+=len; 318 } 319 320 if (ret->data != NULL) OPENSSL_free(ret->data); 321 ret->data=s; 322 ret->length=(int)len; 323 if (a != NULL) (*a)=ret; 324 *pp=p; 325 return(ret); 326err: 327 ASN1err(ASN1_F_D2I_ASN1_UINTEGER,i); 328 if ((ret != NULL) && ((a == NULL) || (*a != ret))) 329 M_ASN1_INTEGER_free(ret); 330 return(NULL); 331 } 332 333int ASN1_INTEGER_set(ASN1_INTEGER *a, long v) 334 { 335 int i,j,k; 336 unsigned char buf[sizeof(long)+1]; 337 long d; 338 339 a->type=V_ASN1_INTEGER; 340 if (a->length < (sizeof(long)+1)) 341 { 342 if (a->data != NULL) 343 OPENSSL_free(a->data); 344 if ((a->data=(unsigned char *)OPENSSL_malloc(sizeof(long)+1)) != NULL) 345 memset((char *)a->data,0,sizeof(long)+1); 346 } 347 if (a->data == NULL) 348 { 349 ASN1err(ASN1_F_ASN1_INTEGER_SET,ERR_R_MALLOC_FAILURE); 350 return(0); 351 } 352 d=v; 353 if (d < 0) 354 { 355 d= -d; 356 a->type=V_ASN1_NEG_INTEGER; 357 } 358 359 for (i=0; i<sizeof(long); i++) 360 { 361 if (d == 0) break; 362 buf[i]=(int)d&0xff; 363 d>>=8; 364 } 365 j=0; 366 for (k=i-1; k >=0; k--) 367 a->data[j++]=buf[k]; 368 a->length=j; 369 return(1); 370 } 371 372long ASN1_INTEGER_get(ASN1_INTEGER *a) 373 { 374 int neg=0,i; 375 long r=0; 376 377 if (a == NULL) return(0L); 378 i=a->type; 379 if (i == V_ASN1_NEG_INTEGER) 380 neg=1; 381 else if (i != V_ASN1_INTEGER) 382 return -1; 383 384 if (a->length > sizeof(long)) 385 { 386 /* hmm... a bit ugly */ 387 return(0xffffffffL); 388 } 389 if (a->data == NULL) 390 return 0; 391 392 for (i=0; i<a->length; i++) 393 { 394 r<<=8; 395 r|=(unsigned char)a->data[i]; 396 } 397 if (neg) r= -r; 398 return(r); 399 } 400 401ASN1_INTEGER *BN_to_ASN1_INTEGER(BIGNUM *bn, ASN1_INTEGER *ai) 402 { 403 ASN1_INTEGER *ret; 404 int len,j; 405 406 if (ai == NULL) 407 ret=M_ASN1_INTEGER_new(); 408 else 409 ret=ai; 410 if (ret == NULL) 411 { 412 ASN1err(ASN1_F_BN_TO_ASN1_INTEGER,ERR_R_NESTED_ASN1_ERROR); 413 goto err; 414 } 415 if(bn->neg) ret->type = V_ASN1_NEG_INTEGER; 416 else ret->type=V_ASN1_INTEGER; 417 j=BN_num_bits(bn); 418 len=((j == 0)?0:((j/8)+1)); 419 if (ret->length < len+4) 420 { 421 unsigned char *new_data=OPENSSL_realloc(ret->data, len+4); 422 if (!new_data) 423 { 424 ASN1err(ASN1_F_BN_TO_ASN1_INTEGER,ERR_R_MALLOC_FAILURE); 425 goto err; 426 } 427 ret->data=new_data; 428 } 429 ret->length=BN_bn2bin(bn,ret->data); 430 /* Correct zero case */ 431 if(!ret->length) 432 { 433 ret->data[0] = 0; 434 ret->length = 1; 435 } 436 return(ret); 437err: 438 if (ret != ai) M_ASN1_INTEGER_free(ret); 439 return(NULL); 440 } 441 442BIGNUM *ASN1_INTEGER_to_BN(ASN1_INTEGER *ai, BIGNUM *bn) 443 { 444 BIGNUM *ret; 445 446 if ((ret=BN_bin2bn(ai->data,ai->length,bn)) == NULL) 447 ASN1err(ASN1_F_ASN1_INTEGER_TO_BN,ASN1_R_BN_LIB); 448 else if(ai->type == V_ASN1_NEG_INTEGER) ret->neg = 1; 449 return(ret); 450 } 451 452IMPLEMENT_STACK_OF(ASN1_INTEGER) 453IMPLEMENT_ASN1_SET_OF(ASN1_INTEGER) 454