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