diff options
Diffstat (limited to 'src/lib/libcrypto/asn1/a_int.c')
-rw-r--r-- | src/lib/libcrypto/asn1/a_int.c | 108 |
1 files changed, 73 insertions, 35 deletions
diff --git a/src/lib/libcrypto/asn1/a_int.c b/src/lib/libcrypto/asn1/a_int.c index 8b6794e8c1..6f0413f885 100644 --- a/src/lib/libcrypto/asn1/a_int.c +++ b/src/lib/libcrypto/asn1/a_int.c | |||
@@ -72,8 +72,23 @@ ASN1_INTEGER *ASN1_INTEGER_dup(ASN1_INTEGER *x) | |||
72 | int ASN1_INTEGER_cmp(ASN1_INTEGER *x, ASN1_INTEGER *y) | 72 | int ASN1_INTEGER_cmp(ASN1_INTEGER *x, ASN1_INTEGER *y) |
73 | { return M_ASN1_INTEGER_cmp(x,y);} | 73 | { return M_ASN1_INTEGER_cmp(x,y);} |
74 | 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 | |||
75 | /* | 90 | /* |
76 | * This converts an ASN1 INTEGER into its DER encoding. | 91 | * This converts an ASN1 INTEGER into its content encoding. |
77 | * The internal representation is an ASN1_STRING whose data is a big endian | 92 | * The internal representation is an ASN1_STRING whose data is a big endian |
78 | * representation of the value, ignoring the sign. The sign is determined by | 93 | * representation of the value, ignoring the sign. The sign is determined by |
79 | * the type: V_ASN1_INTEGER for positive and V_ASN1_NEG_INTEGER for negative. | 94 | * the type: V_ASN1_INTEGER for positive and V_ASN1_NEG_INTEGER for negative. |
@@ -97,23 +112,23 @@ int ASN1_INTEGER_cmp(ASN1_INTEGER *x, ASN1_INTEGER *y) | |||
97 | * followed by optional zeros isn't padded. | 112 | * followed by optional zeros isn't padded. |
98 | */ | 113 | */ |
99 | 114 | ||
100 | int i2d_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp) | 115 | int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp) |
101 | { | 116 | { |
102 | int pad=0,ret,r,i,t; | 117 | int pad=0,ret,i,neg; |
103 | unsigned char *p,*n,pb=0; | 118 | unsigned char *p,*n,pb=0; |
104 | 119 | ||
105 | if ((a == NULL) || (a->data == NULL)) return(0); | 120 | if ((a == NULL) || (a->data == NULL)) return(0); |
106 | t=a->type; | 121 | neg=a->type & V_ASN1_NEG; |
107 | if (a->length == 0) | 122 | if (a->length == 0) |
108 | ret=1; | 123 | ret=1; |
109 | else | 124 | else |
110 | { | 125 | { |
111 | ret=a->length; | 126 | ret=a->length; |
112 | i=a->data[0]; | 127 | i=a->data[0]; |
113 | if ((t == V_ASN1_INTEGER) && (i > 127)) { | 128 | if (!neg && (i > 127)) { |
114 | pad=1; | 129 | pad=1; |
115 | pb=0; | 130 | pb=0; |
116 | } else if(t == V_ASN1_NEG_INTEGER) { | 131 | } else if(neg) { |
117 | if(i>128) { | 132 | if(i>128) { |
118 | pad=1; | 133 | pad=1; |
119 | pb=0xFF; | 134 | pb=0xFF; |
@@ -131,14 +146,12 @@ int i2d_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp) | |||
131 | } | 146 | } |
132 | ret+=pad; | 147 | ret+=pad; |
133 | } | 148 | } |
134 | r=ASN1_object_size(0,ret,V_ASN1_INTEGER); | 149 | if (pp == NULL) return(ret); |
135 | if (pp == NULL) return(r); | ||
136 | p= *pp; | 150 | p= *pp; |
137 | 151 | ||
138 | ASN1_put_object(&p,0,ret,V_ASN1_INTEGER,V_ASN1_UNIVERSAL); | ||
139 | if (pad) *(p++)=pb; | 152 | if (pad) *(p++)=pb; |
140 | if (a->length == 0) *(p++)=0; | 153 | if (a->length == 0) *(p++)=0; |
141 | else if (t == V_ASN1_INTEGER) memcpy(p,a->data,(unsigned int)a->length); | 154 | else if (!neg) memcpy(p,a->data,(unsigned int)a->length); |
142 | else { | 155 | else { |
143 | /* Begin at the end of the encoding */ | 156 | /* Begin at the end of the encoding */ |
144 | n=a->data + a->length - 1; | 157 | n=a->data + a->length - 1; |
@@ -157,30 +170,22 @@ int i2d_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp) | |||
157 | for(;i > 0; i--) *(p--) = *(n--) ^ 0xff; | 170 | for(;i > 0; i--) *(p--) = *(n--) ^ 0xff; |
158 | } | 171 | } |
159 | 172 | ||
160 | *pp+=r; | 173 | *pp+=ret; |
161 | return(r); | 174 | return(ret); |
162 | } | 175 | } |
163 | 176 | ||
177 | /* Convert DER encoded ASN1 INTEGER to ASN1_INTEGER structure */ | ||
164 | ASN1_INTEGER *d2i_ASN1_INTEGER(ASN1_INTEGER **a, unsigned char **pp, | 178 | ASN1_INTEGER *d2i_ASN1_INTEGER(ASN1_INTEGER **a, unsigned char **pp, |
165 | long length) | 179 | long length) |
166 | { | 180 | { |
167 | ASN1_INTEGER *ret=NULL; | 181 | unsigned char *p; |
168 | unsigned char *p,*to,*s, *pend; | ||
169 | long len; | 182 | long len; |
170 | int inf,tag,xclass; | ||
171 | int i; | 183 | int i; |
172 | 184 | int inf,tag,xclass; | |
173 | if ((a == NULL) || ((*a) == NULL)) | 185 | ASN1_INTEGER *ret; |
174 | { | ||
175 | if ((ret=M_ASN1_INTEGER_new()) == NULL) return(NULL); | ||
176 | ret->type=V_ASN1_INTEGER; | ||
177 | } | ||
178 | else | ||
179 | ret=(*a); | ||
180 | 186 | ||
181 | p= *pp; | 187 | p= *pp; |
182 | inf=ASN1_get_object(&p,&len,&tag,&xclass,length); | 188 | inf=ASN1_get_object(&p,&len,&tag,&xclass,length); |
183 | pend = p + len; | ||
184 | if (inf & 0x80) | 189 | if (inf & 0x80) |
185 | { | 190 | { |
186 | i=ASN1_R_BAD_OBJECT_HEADER; | 191 | i=ASN1_R_BAD_OBJECT_HEADER; |
@@ -192,10 +197,39 @@ ASN1_INTEGER *d2i_ASN1_INTEGER(ASN1_INTEGER **a, unsigned char **pp, | |||
192 | i=ASN1_R_EXPECTING_AN_INTEGER; | 197 | i=ASN1_R_EXPECTING_AN_INTEGER; |
193 | goto err; | 198 | goto err; |
194 | } | 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); | ||
195 | 226 | ||
196 | /* We must Malloc stuff, even for 0 bytes otherwise it | 227 | p= *pp; |
228 | pend = p + len; | ||
229 | |||
230 | /* We must OPENSSL_malloc stuff, even for 0 bytes otherwise it | ||
197 | * signifies a missing NULL parameter. */ | 231 | * signifies a missing NULL parameter. */ |
198 | s=(unsigned char *)Malloc((int)len+1); | 232 | s=(unsigned char *)OPENSSL_malloc((int)len+1); |
199 | if (s == NULL) | 233 | if (s == NULL) |
200 | { | 234 | { |
201 | i=ERR_R_MALLOC_FAILURE; | 235 | i=ERR_R_MALLOC_FAILURE; |
@@ -248,7 +282,7 @@ ASN1_INTEGER *d2i_ASN1_INTEGER(ASN1_INTEGER **a, unsigned char **pp, | |||
248 | memcpy(s,p,(int)len); | 282 | memcpy(s,p,(int)len); |
249 | } | 283 | } |
250 | 284 | ||
251 | if (ret->data != NULL) Free(ret->data); | 285 | if (ret->data != NULL) OPENSSL_free(ret->data); |
252 | ret->data=s; | 286 | ret->data=s; |
253 | ret->length=(int)len; | 287 | ret->length=(int)len; |
254 | if (a != NULL) (*a)=ret; | 288 | if (a != NULL) (*a)=ret; |
@@ -261,6 +295,7 @@ err: | |||
261 | return(NULL); | 295 | return(NULL); |
262 | } | 296 | } |
263 | 297 | ||
298 | |||
264 | /* This is a version of d2i_ASN1_INTEGER that ignores the sign bit of | 299 | /* 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 | 300 | * ASN1 integers: some broken software can encode a positive INTEGER |
266 | * with its MSB set as negative (it doesn't add a padding zero). | 301 | * with its MSB set as negative (it doesn't add a padding zero). |
@@ -297,9 +332,9 @@ ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, unsigned char **pp, | |||
297 | goto err; | 332 | goto err; |
298 | } | 333 | } |
299 | 334 | ||
300 | /* We must Malloc stuff, even for 0 bytes otherwise it | 335 | /* We must OPENSSL_malloc stuff, even for 0 bytes otherwise it |
301 | * signifies a missing NULL parameter. */ | 336 | * signifies a missing NULL parameter. */ |
302 | s=(unsigned char *)Malloc((int)len+1); | 337 | s=(unsigned char *)OPENSSL_malloc((int)len+1); |
303 | if (s == NULL) | 338 | if (s == NULL) |
304 | { | 339 | { |
305 | i=ERR_R_MALLOC_FAILURE; | 340 | i=ERR_R_MALLOC_FAILURE; |
@@ -317,7 +352,7 @@ ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, unsigned char **pp, | |||
317 | p+=len; | 352 | p+=len; |
318 | } | 353 | } |
319 | 354 | ||
320 | if (ret->data != NULL) Free(ret->data); | 355 | if (ret->data != NULL) OPENSSL_free(ret->data); |
321 | ret->data=s; | 356 | ret->data=s; |
322 | ret->length=(int)len; | 357 | ret->length=(int)len; |
323 | if (a != NULL) (*a)=ret; | 358 | if (a != NULL) (*a)=ret; |
@@ -340,8 +375,8 @@ int ASN1_INTEGER_set(ASN1_INTEGER *a, long v) | |||
340 | if (a->length < (sizeof(long)+1)) | 375 | if (a->length < (sizeof(long)+1)) |
341 | { | 376 | { |
342 | if (a->data != NULL) | 377 | if (a->data != NULL) |
343 | Free(a->data); | 378 | OPENSSL_free(a->data); |
344 | if ((a->data=(unsigned char *)Malloc(sizeof(long)+1)) != NULL) | 379 | if ((a->data=(unsigned char *)OPENSSL_malloc(sizeof(long)+1)) != NULL) |
345 | memset((char *)a->data,0,sizeof(long)+1); | 380 | memset((char *)a->data,0,sizeof(long)+1); |
346 | } | 381 | } |
347 | if (a->data == NULL) | 382 | if (a->data == NULL) |
@@ -416,7 +451,7 @@ ASN1_INTEGER *BN_to_ASN1_INTEGER(BIGNUM *bn, ASN1_INTEGER *ai) | |||
416 | else ret->type=V_ASN1_INTEGER; | 451 | else ret->type=V_ASN1_INTEGER; |
417 | j=BN_num_bits(bn); | 452 | j=BN_num_bits(bn); |
418 | len=((j == 0)?0:((j/8)+1)); | 453 | len=((j == 0)?0:((j/8)+1)); |
419 | ret->data=(unsigned char *)Malloc(len+4); | 454 | ret->data=(unsigned char *)OPENSSL_malloc(len+4); |
420 | ret->length=BN_bn2bin(bn,ret->data); | 455 | ret->length=BN_bn2bin(bn,ret->data); |
421 | return(ret); | 456 | return(ret); |
422 | err: | 457 | err: |
@@ -430,6 +465,9 @@ BIGNUM *ASN1_INTEGER_to_BN(ASN1_INTEGER *ai, BIGNUM *bn) | |||
430 | 465 | ||
431 | if ((ret=BN_bin2bn(ai->data,ai->length,bn)) == NULL) | 466 | if ((ret=BN_bin2bn(ai->data,ai->length,bn)) == NULL) |
432 | ASN1err(ASN1_F_ASN1_INTEGER_TO_BN,ASN1_R_BN_LIB); | 467 | ASN1err(ASN1_F_ASN1_INTEGER_TO_BN,ASN1_R_BN_LIB); |
433 | if(ai->type == V_ASN1_NEG_INTEGER) bn->neg = 1; | 468 | else if(ai->type == V_ASN1_NEG_INTEGER) ret->neg = 1; |
434 | return(ret); | 469 | return(ret); |
435 | } | 470 | } |
471 | |||
472 | IMPLEMENT_STACK_OF(ASN1_INTEGER) | ||
473 | IMPLEMENT_ASN1_SET_OF(ASN1_INTEGER) | ||