1/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2 * All rights reserved. 3 * 4 * This package is an SSL implementation written 5 * by Eric Young (eay@cryptsoft.com). 6 * The implementation was written so as to conform with Netscapes SSL. 7 * 8 * This library is free for commercial and non-commercial use as long as 9 * the following conditions are aheared to. The following conditions 10 * apply to all code found in this distribution, be it the RC4, RSA, 11 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 12 * included with this distribution is covered by the same copyright terms 13 * except that the holder is Tim Hudson (tjh@cryptsoft.com). 14 * 15 * Copyright remains Eric Young's, and as such any Copyright notices in 16 * the code are not to be removed. 17 * If this package is used in a product, Eric Young should be given attribution 18 * as the author of the parts of the library used. 19 * This can be in the form of a textual message at program startup or 20 * in documentation (online or textual) provided with the package. 21 * 22 * Redistribution and use in source and binary forms, with or without 23 * modification, are permitted provided that the following conditions 24 * are met: 25 * 1. Redistributions of source code must retain the copyright 26 * notice, this list of conditions and the following disclaimer. 27 * 2. Redistributions in binary form must reproduce the above copyright 28 * notice, this list of conditions and the following disclaimer in the 29 * documentation and/or other materials provided with the distribution. 30 * 3. All advertising materials mentioning features or use of this software 31 * must display the following acknowledgement: 32 * "This product includes cryptographic software written by 33 * Eric Young (eay@cryptsoft.com)" 34 * The word 'cryptographic' can be left out if the rouines from the library 35 * being used are not cryptographic related :-). 36 * 4. If you include any Windows specific code (or a derivative thereof) from 37 * the apps directory (application code) you must include an acknowledgement: 38 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 39 * 40 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 43 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 50 * SUCH DAMAGE. 51 * 52 * The licence and distribution terms for any publically available version or 53 * derivative of this code cannot be changed. i.e. this code cannot simply be 54 * copied and put under another distribution licence 55 * [including the GNU Public Licence.] */ 56 57#include <openssl/asn1.h> 58 59#include <limits.h> 60 61#include <openssl/err.h> 62#include <openssl/mem.h> 63#include <openssl/obj.h> 64 65 66int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp) 67 { 68 unsigned char *p; 69 int objsize; 70 71 if ((a == NULL) || (a->data == NULL)) return(0); 72 73 objsize = ASN1_object_size(0,a->length,V_ASN1_OBJECT); 74 if (pp == NULL) return objsize; 75 76 p= *pp; 77 ASN1_put_object(&p,0,a->length,V_ASN1_OBJECT,V_ASN1_UNIVERSAL); 78 memcpy(p,a->data,a->length); 79 p+=a->length; 80 81 *pp=p; 82 return(objsize); 83 } 84 85int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num) 86 { 87 int i,first,len=0,c, use_bn; 88 char ftmp[24], *tmp = ftmp; 89 int tmpsize = sizeof ftmp; 90 const char *p; 91 unsigned long l; 92 BIGNUM *bl = NULL; 93 94 if (num == 0) 95 return(0); 96 else if (num == -1) 97 num=strlen(buf); 98 99 p=buf; 100 c= *(p++); 101 num--; 102 if ((c >= '0') && (c <= '2')) 103 { 104 first= c-'0'; 105 } 106 else 107 { 108 OPENSSL_PUT_ERROR(ASN1, a2d_ASN1_OBJECT, ASN1_R_FIRST_NUM_TOO_LARGE); 109 goto err; 110 } 111 112 if (num <= 0) 113 { 114 OPENSSL_PUT_ERROR(ASN1, a2d_ASN1_OBJECT, ASN1_R_MISSING_SECOND_NUMBER); 115 goto err; 116 } 117 c= *(p++); 118 num--; 119 for (;;) 120 { 121 if (num <= 0) break; 122 if ((c != '.') && (c != ' ')) 123 { 124 OPENSSL_PUT_ERROR(ASN1, a2d_ASN1_OBJECT, ASN1_R_INVALID_SEPARATOR); 125 goto err; 126 } 127 l=0; 128 use_bn = 0; 129 for (;;) 130 { 131 if (num <= 0) break; 132 num--; 133 c= *(p++); 134 if ((c == ' ') || (c == '.')) 135 break; 136 if ((c < '0') || (c > '9')) 137 { 138 OPENSSL_PUT_ERROR(ASN1, a2d_ASN1_OBJECT, ASN1_R_INVALID_DIGIT); 139 goto err; 140 } 141 if (!use_bn && l >= ((ULONG_MAX - 80) / 10L)) 142 { 143 use_bn = 1; 144 if (!bl) 145 bl = BN_new(); 146 if (!bl || !BN_set_word(bl, l)) 147 goto err; 148 } 149 if (use_bn) 150 { 151 if (!BN_mul_word(bl, 10L) 152 || !BN_add_word(bl, c-'0')) 153 goto err; 154 } 155 else 156 l=l*10L+(long)(c-'0'); 157 } 158 if (len == 0) 159 { 160 if ((first < 2) && (l >= 40)) 161 { 162 OPENSSL_PUT_ERROR(ASN1, a2d_ASN1_OBJECT, ASN1_R_SECOND_NUMBER_TOO_LARGE); 163 goto err; 164 } 165 if (use_bn) 166 { 167 if (!BN_add_word(bl, first * 40)) 168 goto err; 169 } 170 else 171 l+=(long)first*40; 172 } 173 i=0; 174 if (use_bn) 175 { 176 int blsize; 177 blsize = BN_num_bits(bl); 178 blsize = (blsize + 6)/7; 179 if (blsize > tmpsize) 180 { 181 if (tmp != ftmp) 182 OPENSSL_free(tmp); 183 tmpsize = blsize + 32; 184 tmp = OPENSSL_malloc(tmpsize); 185 if (!tmp) 186 goto err; 187 } 188 while(blsize--) 189 tmp[i++] = (unsigned char)BN_div_word(bl, 0x80L); 190 } 191 else 192 { 193 194 for (;;) 195 { 196 tmp[i++]=(unsigned char)l&0x7f; 197 l>>=7L; 198 if (l == 0L) break; 199 } 200 201 } 202 if (out != NULL) 203 { 204 if (len+i > olen) 205 { 206 OPENSSL_PUT_ERROR(ASN1, a2d_ASN1_OBJECT, ASN1_R_BUFFER_TOO_SMALL); 207 goto err; 208 } 209 while (--i > 0) 210 out[len++]=tmp[i]|0x80; 211 out[len++]=tmp[0]; 212 } 213 else 214 len+=i; 215 } 216 if (tmp != ftmp) 217 OPENSSL_free(tmp); 218 if (bl) 219 BN_free(bl); 220 return(len); 221err: 222 if (tmp != ftmp) 223 OPENSSL_free(tmp); 224 if (bl) 225 BN_free(bl); 226 return(0); 227 } 228 229int i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a) 230{ 231 return OBJ_obj2txt(buf, buf_len, a, 0); 232} 233 234int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a) 235 { 236 char buf[80], *p = buf; 237 int i; 238 239 if ((a == NULL) || (a->data == NULL)) 240 return(BIO_write(bp,"NULL",4)); 241 i=i2t_ASN1_OBJECT(buf,sizeof buf,a); 242 if (i > (int)(sizeof(buf) - 1)) 243 { 244 p = OPENSSL_malloc(i + 1); 245 if (!p) 246 return -1; 247 i2t_ASN1_OBJECT(p,i + 1,a); 248 } 249 if (i <= 0) 250 return BIO_write(bp, "<INVALID>", 9); 251 BIO_write(bp,p,i); 252 if (p != buf) 253 OPENSSL_free(p); 254 return(i); 255 } 256 257ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, 258 long length) 259{ 260 const unsigned char *p; 261 long len; 262 int tag,xclass; 263 int inf,i; 264 ASN1_OBJECT *ret = NULL; 265 p= *pp; 266 inf=ASN1_get_object(&p,&len,&tag,&xclass,length); 267 if (inf & 0x80) 268 { 269 i=ASN1_R_BAD_OBJECT_HEADER; 270 goto err; 271 } 272 273 if (tag != V_ASN1_OBJECT) 274 { 275 i=ASN1_R_EXPECTING_AN_OBJECT; 276 goto err; 277 } 278 ret = c2i_ASN1_OBJECT(a, &p, len); 279 if(ret) *pp = p; 280 return ret; 281err: 282 OPENSSL_PUT_ERROR(ASN1, d2i_ASN1_OBJECT, i); 283 return(NULL); 284} 285 286ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, 287 long len) 288 { 289 ASN1_OBJECT *ret=NULL; 290 const unsigned char *p; 291 unsigned char *data; 292 int i, length; 293 294 /* Sanity check OID encoding. 295 * Need at least one content octet. 296 * MSB must be clear in the last octet. 297 * can't have leading 0x80 in subidentifiers, see: X.690 8.19.2 298 */ 299 if (len <= 0 || len > INT_MAX || pp == NULL || (p = *pp) == NULL || 300 p[len - 1] & 0x80) 301 { 302 OPENSSL_PUT_ERROR(ASN1, c2i_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING); 303 return NULL; 304 } 305 /* Now 0 < len <= INT_MAX, so the cast is safe. */ 306 length = (int)len; 307 for (i = 0; i < length; i++, p++) 308 { 309 if (*p == 0x80 && (!i || !(p[-1] & 0x80))) 310 { 311 OPENSSL_PUT_ERROR(ASN1, c2i_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING); 312 return NULL; 313 } 314 } 315 316 /* only the ASN1_OBJECTs from the 'table' will have values 317 * for ->sn or ->ln */ 318 if ((a == NULL) || ((*a) == NULL) || 319 !((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC)) 320 { 321 if ((ret=ASN1_OBJECT_new()) == NULL) return(NULL); 322 } 323 else ret=(*a); 324 325 p= *pp; 326 /* detach data from object */ 327 data = (unsigned char *)ret->data; 328 ret->data = NULL; 329 /* once detached we can change it */ 330 if ((data == NULL) || (ret->length < length)) 331 { 332 ret->length=0; 333 if (data != NULL) OPENSSL_free(data); 334 data=(unsigned char *)OPENSSL_malloc(length); 335 if (data == NULL) 336 { i=ERR_R_MALLOC_FAILURE; goto err; } 337 ret->flags|=ASN1_OBJECT_FLAG_DYNAMIC_DATA; 338 } 339 memcpy(data,p,length); 340 /* reattach data to object, after which it remains const */ 341 ret->data =data; 342 ret->length=length; 343 ret->sn=NULL; 344 ret->ln=NULL; 345 /* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */ 346 p+=length; 347 348 if (a != NULL) (*a)=ret; 349 *pp=p; 350 return(ret); 351err: 352 OPENSSL_PUT_ERROR(ASN1, c2i_ASN1_OBJECT, i); 353 if ((ret != NULL) && ((a == NULL) || (*a != ret))) 354 ASN1_OBJECT_free(ret); 355 return(NULL); 356 } 357 358ASN1_OBJECT *ASN1_OBJECT_new(void) 359 { 360 ASN1_OBJECT *ret; 361 362 ret=(ASN1_OBJECT *)OPENSSL_malloc(sizeof(ASN1_OBJECT)); 363 if (ret == NULL) 364 { 365 OPENSSL_PUT_ERROR(ASN1, ASN1_OBJECT_new, ERR_R_MALLOC_FAILURE); 366 return(NULL); 367 } 368 ret->length=0; 369 ret->data=NULL; 370 ret->nid=0; 371 ret->sn=NULL; 372 ret->ln=NULL; 373 ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; 374 return(ret); 375 } 376 377void ASN1_OBJECT_free(ASN1_OBJECT *a) 378 { 379 if (a == NULL) return; 380 if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS) 381 { 382#ifndef CONST_STRICT /* disable purely for compile-time strict const checking. Doing this on a "real" compile will cause memory leaks */ 383 if (a->sn != NULL) OPENSSL_free((void *)a->sn); 384 if (a->ln != NULL) OPENSSL_free((void *)a->ln); 385#endif 386 a->sn=a->ln=NULL; 387 } 388 if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA) 389 { 390 if (a->data != NULL) OPENSSL_free((void *)a->data); 391 a->data=NULL; 392 a->length=0; 393 } 394 if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC) 395 OPENSSL_free(a); 396 } 397 398ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len, 399 const char *sn, const char *ln) 400 { 401 ASN1_OBJECT o; 402 403 o.sn=sn; 404 o.ln=ln; 405 o.data=data; 406 o.nid=nid; 407 o.length=len; 408 o.flags=ASN1_OBJECT_FLAG_DYNAMIC|ASN1_OBJECT_FLAG_DYNAMIC_STRINGS| 409 ASN1_OBJECT_FLAG_DYNAMIC_DATA; 410 return(OBJ_dup(&o)); 411 } 412