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