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