a_object.c revision 160814
1/* crypto/asn1/a_object.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 <limits.h> 61#include "cryptlib.h" 62#include <openssl/buffer.h> 63#include <openssl/asn1.h> 64#include <openssl/objects.h> 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 ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_FIRST_NUM_TOO_LARGE); 109 goto err; 110 } 111 112 if (num <= 0) 113 { 114 ASN1err(ASN1_F_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 ASN1err(ASN1_F_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 ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_INVALID_DIGIT); 139 goto err; 140 } 141 if (!use_bn && l > (ULONG_MAX / 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 ASN1err(ASN1_F_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 ASN1err(ASN1_F_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 ASN1err(ASN1_F_D2I_ASN1_OBJECT,i); 283 if ((ret != NULL) && ((a == NULL) || (*a != ret))) 284 ASN1_OBJECT_free(ret); 285 return(NULL); 286} 287ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, 288 long len) 289 { 290 ASN1_OBJECT *ret=NULL; 291 const unsigned char *p; 292 int i; 293 294 /* only the ASN1_OBJECTs from the 'table' will have values 295 * for ->sn or ->ln */ 296 if ((a == NULL) || ((*a) == NULL) || 297 !((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC)) 298 { 299 if ((ret=ASN1_OBJECT_new()) == NULL) return(NULL); 300 } 301 else ret=(*a); 302 303 p= *pp; 304 if ((ret->data == NULL) || (ret->length < len)) 305 { 306 if (ret->data != NULL) OPENSSL_free(ret->data); 307 ret->data=(unsigned char *)OPENSSL_malloc(len ? (int)len : 1); 308 ret->flags|=ASN1_OBJECT_FLAG_DYNAMIC_DATA; 309 if (ret->data == NULL) 310 { i=ERR_R_MALLOC_FAILURE; goto err; } 311 } 312 memcpy(ret->data,p,(int)len); 313 ret->length=(int)len; 314 ret->sn=NULL; 315 ret->ln=NULL; 316 /* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */ 317 p+=len; 318 319 if (a != NULL) (*a)=ret; 320 *pp=p; 321 return(ret); 322err: 323 ASN1err(ASN1_F_C2I_ASN1_OBJECT,i); 324 if ((ret != NULL) && ((a == NULL) || (*a != ret))) 325 ASN1_OBJECT_free(ret); 326 return(NULL); 327 } 328 329ASN1_OBJECT *ASN1_OBJECT_new(void) 330 { 331 ASN1_OBJECT *ret; 332 333 ret=(ASN1_OBJECT *)OPENSSL_malloc(sizeof(ASN1_OBJECT)); 334 if (ret == NULL) 335 { 336 ASN1err(ASN1_F_ASN1_OBJECT_NEW,ERR_R_MALLOC_FAILURE); 337 return(NULL); 338 } 339 ret->length=0; 340 ret->data=NULL; 341 ret->nid=0; 342 ret->sn=NULL; 343 ret->ln=NULL; 344 ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; 345 return(ret); 346 } 347 348void ASN1_OBJECT_free(ASN1_OBJECT *a) 349 { 350 if (a == NULL) return; 351 if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS) 352 { 353#ifndef CONST_STRICT /* disable purely for compile-time strict const checking. Doing this on a "real" compile will cause memory leaks */ 354 if (a->sn != NULL) OPENSSL_free((void *)a->sn); 355 if (a->ln != NULL) OPENSSL_free((void *)a->ln); 356#endif 357 a->sn=a->ln=NULL; 358 } 359 if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA) 360 { 361 if (a->data != NULL) OPENSSL_free(a->data); 362 a->data=NULL; 363 a->length=0; 364 } 365 if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC) 366 OPENSSL_free(a); 367 } 368 369ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len, 370 const char *sn, const char *ln) 371 { 372 ASN1_OBJECT o; 373 374 o.sn=sn; 375 o.ln=ln; 376 o.data=data; 377 o.nid=nid; 378 o.length=len; 379 o.flags=ASN1_OBJECT_FLAG_DYNAMIC|ASN1_OBJECT_FLAG_DYNAMIC_STRINGS| 380 ASN1_OBJECT_FLAG_DYNAMIC_DATA; 381 return(OBJ_dup(&o)); 382 } 383 384IMPLEMENT_STACK_OF(ASN1_OBJECT) 385IMPLEMENT_ASN1_SET_OF(ASN1_OBJECT) 386