a_type.c revision 59191
1/* crypto/asn1/a_type.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_mac.h> 62 63static void ASN1_TYPE_component_free(ASN1_TYPE *a); 64int i2d_ASN1_TYPE(ASN1_TYPE *a, unsigned char **pp) 65 { 66 int r=0; 67 68 if (a == NULL) return(0); 69 70 switch (a->type) 71 { 72 case V_ASN1_NULL: 73 if (pp != NULL) 74 ASN1_put_object(pp,0,0,V_ASN1_NULL,V_ASN1_UNIVERSAL); 75 r=2; 76 break; 77 case V_ASN1_INTEGER: 78 case V_ASN1_NEG_INTEGER: 79 r=i2d_ASN1_INTEGER(a->value.integer,pp); 80 break; 81 case V_ASN1_ENUMERATED: 82 case V_ASN1_NEG_ENUMERATED: 83 r=i2d_ASN1_ENUMERATED(a->value.enumerated,pp); 84 break; 85 case V_ASN1_BIT_STRING: 86 r=i2d_ASN1_BIT_STRING(a->value.bit_string,pp); 87 break; 88 case V_ASN1_OCTET_STRING: 89 r=i2d_ASN1_OCTET_STRING(a->value.octet_string,pp); 90 break; 91 case V_ASN1_OBJECT: 92 r=i2d_ASN1_OBJECT(a->value.object,pp); 93 break; 94 case V_ASN1_PRINTABLESTRING: 95 r=M_i2d_ASN1_PRINTABLESTRING(a->value.printablestring,pp); 96 break; 97 case V_ASN1_T61STRING: 98 r=M_i2d_ASN1_T61STRING(a->value.t61string,pp); 99 break; 100 case V_ASN1_IA5STRING: 101 r=M_i2d_ASN1_IA5STRING(a->value.ia5string,pp); 102 break; 103 case V_ASN1_GENERALSTRING: 104 r=M_i2d_ASN1_GENERALSTRING(a->value.generalstring,pp); 105 break; 106 case V_ASN1_UNIVERSALSTRING: 107 r=M_i2d_ASN1_UNIVERSALSTRING(a->value.universalstring,pp); 108 break; 109 case V_ASN1_UTF8STRING: 110 r=M_i2d_ASN1_UTF8STRING(a->value.utf8string,pp); 111 break; 112 case V_ASN1_VISIBLESTRING: 113 r=M_i2d_ASN1_VISIBLESTRING(a->value.visiblestring,pp); 114 break; 115 case V_ASN1_BMPSTRING: 116 r=M_i2d_ASN1_BMPSTRING(a->value.bmpstring,pp); 117 break; 118 case V_ASN1_UTCTIME: 119 r=i2d_ASN1_UTCTIME(a->value.utctime,pp); 120 break; 121 case V_ASN1_GENERALIZEDTIME: 122 r=i2d_ASN1_GENERALIZEDTIME(a->value.generalizedtime,pp); 123 break; 124 case V_ASN1_SET: 125 case V_ASN1_SEQUENCE: 126 if (a->value.set == NULL) 127 r=0; 128 else 129 { 130 r=a->value.set->length; 131 if (pp != NULL) 132 { 133 memcpy(*pp,a->value.set->data,r); 134 *pp+=r; 135 } 136 } 137 break; 138 } 139 return(r); 140 } 141 142ASN1_TYPE *d2i_ASN1_TYPE(ASN1_TYPE **a, unsigned char **pp, long length) 143 { 144 ASN1_TYPE *ret=NULL; 145 unsigned char *q,*p,*max; 146 int inf,tag,xclass; 147 long len; 148 149 if ((a == NULL) || ((*a) == NULL)) 150 { 151 if ((ret=ASN1_TYPE_new()) == NULL) goto err; 152 } 153 else 154 ret=(*a); 155 156 p= *pp; 157 q=p; 158 max=(p+length); 159 160 inf=ASN1_get_object(&q,&len,&tag,&xclass,length); 161 if (inf & 0x80) goto err; 162 163 ASN1_TYPE_component_free(ret); 164 165 switch (tag) 166 { 167 case V_ASN1_NULL: 168 p=q; 169 ret->value.ptr=NULL; 170 break; 171 case V_ASN1_INTEGER: 172 if ((ret->value.integer= 173 d2i_ASN1_INTEGER(NULL,&p,max-p)) == NULL) 174 goto err; 175 break; 176 case V_ASN1_ENUMERATED: 177 if ((ret->value.enumerated= 178 d2i_ASN1_ENUMERATED(NULL,&p,max-p)) == NULL) 179 goto err; 180 break; 181 case V_ASN1_BIT_STRING: 182 if ((ret->value.bit_string= 183 d2i_ASN1_BIT_STRING(NULL,&p,max-p)) == NULL) 184 goto err; 185 break; 186 case V_ASN1_OCTET_STRING: 187 if ((ret->value.octet_string= 188 d2i_ASN1_OCTET_STRING(NULL,&p,max-p)) == NULL) 189 goto err; 190 break; 191 case V_ASN1_VISIBLESTRING: 192 if ((ret->value.visiblestring= 193 d2i_ASN1_VISIBLESTRING(NULL,&p,max-p)) == NULL) 194 goto err; 195 break; 196 case V_ASN1_UTF8STRING: 197 if ((ret->value.utf8string= 198 d2i_ASN1_UTF8STRING(NULL,&p,max-p)) == NULL) 199 goto err; 200 break; 201 case V_ASN1_OBJECT: 202 if ((ret->value.object= 203 d2i_ASN1_OBJECT(NULL,&p,max-p)) == NULL) 204 goto err; 205 break; 206 case V_ASN1_PRINTABLESTRING: 207 if ((ret->value.printablestring= 208 d2i_ASN1_PRINTABLESTRING(NULL,&p,max-p)) == NULL) 209 goto err; 210 break; 211 case V_ASN1_T61STRING: 212 if ((ret->value.t61string= 213 M_d2i_ASN1_T61STRING(NULL,&p,max-p)) == NULL) 214 goto err; 215 break; 216 case V_ASN1_IA5STRING: 217 if ((ret->value.ia5string= 218 M_d2i_ASN1_IA5STRING(NULL,&p,max-p)) == NULL) 219 goto err; 220 break; 221 case V_ASN1_GENERALSTRING: 222 if ((ret->value.generalstring= 223 M_d2i_ASN1_GENERALSTRING(NULL,&p,max-p)) == NULL) 224 goto err; 225 break; 226 case V_ASN1_UNIVERSALSTRING: 227 if ((ret->value.universalstring= 228 M_d2i_ASN1_UNIVERSALSTRING(NULL,&p,max-p)) == NULL) 229 goto err; 230 break; 231 case V_ASN1_BMPSTRING: 232 if ((ret->value.bmpstring= 233 M_d2i_ASN1_BMPSTRING(NULL,&p,max-p)) == NULL) 234 goto err; 235 break; 236 case V_ASN1_UTCTIME: 237 if ((ret->value.utctime= 238 d2i_ASN1_UTCTIME(NULL,&p,max-p)) == NULL) 239 goto err; 240 break; 241 case V_ASN1_GENERALIZEDTIME: 242 if ((ret->value.generalizedtime= 243 d2i_ASN1_GENERALIZEDTIME(NULL,&p,max-p)) == NULL) 244 goto err; 245 break; 246 case V_ASN1_SET: 247 case V_ASN1_SEQUENCE: 248 /* Sets and sequences are left complete */ 249 if ((ret->value.set=ASN1_STRING_new()) == NULL) goto err; 250 ret->value.set->type=tag; 251 len+=(q-p); 252 if (!ASN1_STRING_set(ret->value.set,p,(int)len)) goto err; 253 p+=len; 254 break; 255 default: 256 ASN1err(ASN1_F_D2I_ASN1_TYPE,ASN1_R_BAD_TYPE); 257 goto err; 258 } 259 260 ret->type=tag; 261 if (a != NULL) (*a)=ret; 262 *pp=p; 263 return(ret); 264err: 265 if ((ret != NULL) && ((a == NULL) || (*a != ret))) ASN1_TYPE_free(ret); 266 return(NULL); 267 } 268 269ASN1_TYPE *ASN1_TYPE_new(void) 270 { 271 ASN1_TYPE *ret=NULL; 272 ASN1_CTX c; 273 274 M_ASN1_New_Malloc(ret,ASN1_TYPE); 275 ret->type= -1; 276 ret->value.ptr=NULL; 277 return(ret); 278 M_ASN1_New_Error(ASN1_F_ASN1_TYPE_NEW); 279 } 280 281void ASN1_TYPE_free(ASN1_TYPE *a) 282 { 283 if (a == NULL) return; 284 ASN1_TYPE_component_free(a); 285 Free(a); 286 } 287 288int ASN1_TYPE_get(ASN1_TYPE *a) 289 { 290 if (a->value.ptr != NULL) 291 return(a->type); 292 else 293 return(0); 294 } 295 296void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value) 297 { 298 if (a->value.ptr != NULL) 299 ASN1_TYPE_component_free(a); 300 a->type=type; 301 a->value.ptr=value; 302 } 303 304static void ASN1_TYPE_component_free(ASN1_TYPE *a) 305 { 306 if (a == NULL) return; 307 308 if (a->value.ptr != NULL) 309 { 310 switch (a->type) 311 { 312 case V_ASN1_OBJECT: 313 ASN1_OBJECT_free(a->value.object); 314 break; 315 case V_ASN1_INTEGER: 316 case V_ASN1_NEG_INTEGER: 317 case V_ASN1_ENUMERATED: 318 case V_ASN1_NEG_ENUMERATED: 319 case V_ASN1_BIT_STRING: 320 case V_ASN1_OCTET_STRING: 321 case V_ASN1_SEQUENCE: 322 case V_ASN1_SET: 323 case V_ASN1_NUMERICSTRING: 324 case V_ASN1_PRINTABLESTRING: 325 case V_ASN1_T61STRING: 326 case V_ASN1_VIDEOTEXSTRING: 327 case V_ASN1_IA5STRING: 328 case V_ASN1_UTCTIME: 329 case V_ASN1_GENERALIZEDTIME: 330 case V_ASN1_GRAPHICSTRING: 331 case V_ASN1_VISIBLESTRING: 332 case V_ASN1_GENERALSTRING: 333 case V_ASN1_UNIVERSALSTRING: 334 case V_ASN1_BMPSTRING: 335 case V_ASN1_UTF8STRING: 336 ASN1_STRING_free((ASN1_STRING *)a->value.ptr); 337 break; 338 default: 339 /* MEMORY LEAK */ 340 break; 341 } 342 a->type=0; 343 a->value.ptr=NULL; 344 } 345 } 346 347IMPLEMENT_STACK_OF(ASN1_TYPE) 348IMPLEMENT_ASN1_SET_OF(ASN1_TYPE) 349