asn1_mac.h revision 59191
1/* crypto/asn1/asn1_mac.h */ 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#ifndef HEADER_ASN1_MAC_H 60#define HEADER_ASN1_MAC_H 61 62#ifdef __cplusplus 63extern "C" { 64#endif 65 66#include <openssl/asn1.h> 67 68#ifndef ASN1_MAC_ERR_LIB 69#define ASN1_MAC_ERR_LIB ERR_LIB_ASN1 70#endif 71 72#define ASN1_MAC_H_err(f,r,line) \ 73 ERR_PUT_error(ASN1_MAC_ERR_LIB,(f),(r),ERR_file_name,(line)) 74 75#define M_ASN1_D2I_vars(a,type,func) \ 76 ASN1_CTX c; \ 77 type ret=NULL; \ 78 \ 79 c.pp=pp; \ 80 c.q= *pp; \ 81 c.error=ERR_R_NESTED_ASN1_ERROR; \ 82 if ((a == NULL) || ((*a) == NULL)) \ 83 { if ((ret=(type)func()) == NULL) \ 84 { c.line=__LINE__; goto err; } } \ 85 else ret=(*a); 86 87#define M_ASN1_D2I_Init() \ 88 c.p= *pp; \ 89 c.max=(length == 0)?0:(c.p+length); 90 91#define M_ASN1_D2I_Finish_2(a) \ 92 if (!asn1_Finish(&c)) \ 93 { c.line=__LINE__; goto err; } \ 94 *pp=c.p; \ 95 if (a != NULL) (*a)=ret; \ 96 return(ret); 97 98#define M_ASN1_D2I_Finish(a,func,e) \ 99 M_ASN1_D2I_Finish_2(a); \ 100err:\ 101 ASN1_MAC_H_err((e),c.error,c.line); \ 102 asn1_add_error(*pp,(int)(c.q- *pp)); \ 103 if ((ret != NULL) && ((a == NULL) || (*a != ret))) func(ret); \ 104 return(NULL) 105 106#define M_ASN1_D2I_start_sequence() \ 107 if (!asn1_GetSequence(&c,&length)) \ 108 { c.line=__LINE__; goto err; } 109/* Begin reading ASN1 without a surrounding sequence */ 110#define M_ASN1_D2I_begin() \ 111 c.slen = length; 112 113/* End reading ASN1 with no check on length */ 114#define M_ASN1_D2I_Finish_nolen(a, func, e) \ 115 *pp=c.p; \ 116 if (a != NULL) (*a)=ret; \ 117 return(ret); \ 118err:\ 119 ASN1_MAC_H_err((e),c.error,c.line); \ 120 asn1_add_error(*pp,(int)(c.q- *pp)); \ 121 if ((ret != NULL) && ((a == NULL) || (*a != ret))) func(ret); \ 122 return(NULL) 123 124#define M_ASN1_D2I_end_sequence() \ 125 (((c.inf&1) == 0)?(c.slen <= 0): \ 126 (c.eos=ASN1_check_infinite_end(&c.p,c.slen))) 127 128/* Don't use this with d2i_ASN1_BOOLEAN() */ 129#define M_ASN1_D2I_get(b,func) \ 130 c.q=c.p; \ 131 if (func(&(b),&c.p,c.slen) == NULL) \ 132 {c.line=__LINE__; goto err; } \ 133 c.slen-=(c.p-c.q); 134 135/* use this instead () */ 136#define M_ASN1_D2I_get_int(b,func) \ 137 c.q=c.p; \ 138 if (func(&(b),&c.p,c.slen) < 0) \ 139 {c.line=__LINE__; goto err; } \ 140 c.slen-=(c.p-c.q); 141 142#define M_ASN1_D2I_get_opt(b,func,type) \ 143 if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) \ 144 == (V_ASN1_UNIVERSAL|(type)))) \ 145 { \ 146 M_ASN1_D2I_get(b,func); \ 147 } 148 149#define M_ASN1_D2I_get_imp(b,func, type) \ 150 M_ASN1_next=(_tmp& V_ASN1_CONSTRUCTED)|type; \ 151 c.q=c.p; \ 152 if (func(&(b),&c.p,c.slen) == NULL) \ 153 {c.line=__LINE__; M_ASN1_next_prev = _tmp; goto err; } \ 154 c.slen-=(c.p-c.q);\ 155 M_ASN1_next_prev=_tmp; 156 157#define M_ASN1_D2I_get_IMP_opt(b,func,tag,type) \ 158 if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) == \ 159 (V_ASN1_CONTEXT_SPECIFIC|(tag)))) \ 160 { \ 161 unsigned char _tmp = M_ASN1_next; \ 162 M_ASN1_D2I_get_imp(b,func, type);\ 163 } 164 165#define M_ASN1_D2I_get_set(r,func,free_func) \ 166 M_ASN1_D2I_get_imp_set(r,func,free_func, \ 167 V_ASN1_SET,V_ASN1_UNIVERSAL); 168 169#define M_ASN1_D2I_get_set_type(type,r,func,free_func) \ 170 M_ASN1_D2I_get_imp_set_type(type,r,func,free_func, \ 171 V_ASN1_SET,V_ASN1_UNIVERSAL); 172 173#define M_ASN1_D2I_get_set_opt(r,func,free_func) \ 174 if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \ 175 V_ASN1_CONSTRUCTED|V_ASN1_SET)))\ 176 { M_ASN1_D2I_get_set(r,func,free_func); } 177 178#define M_ASN1_D2I_get_set_opt_type(type,r,func,free_func) \ 179 if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \ 180 V_ASN1_CONSTRUCTED|V_ASN1_SET)))\ 181 { M_ASN1_D2I_get_set_type(type,r,func,free_func); } 182 183#define M_ASN1_I2D_len_SET_opt(a,f) \ 184 if ((a != NULL) && (sk_num(a) != 0)) \ 185 M_ASN1_I2D_len_SET(a,f); 186 187#define M_ASN1_I2D_put_SET_opt(a,f) \ 188 if ((a != NULL) && (sk_num(a) != 0)) \ 189 M_ASN1_I2D_put_SET(a,f); 190 191#define M_ASN1_I2D_put_SEQUENCE_opt(a,f) \ 192 if ((a != NULL) && (sk_num(a) != 0)) \ 193 M_ASN1_I2D_put_SEQUENCE(a,f); 194 195#define M_ASN1_I2D_put_SEQUENCE_opt_type(type,a,f) \ 196 if ((a != NULL) && (sk_##type##_num(a) != 0)) \ 197 M_ASN1_I2D_put_SEQUENCE_type(type,a,f); 198 199#define M_ASN1_D2I_get_IMP_set_opt(b,func,free_func,tag) \ 200 if ((c.slen != 0) && \ 201 (M_ASN1_next == \ 202 (V_ASN1_CONTEXT_SPECIFIC|V_ASN1_CONSTRUCTED|(tag))))\ 203 { \ 204 M_ASN1_D2I_get_imp_set(b,func,free_func,\ 205 tag,V_ASN1_CONTEXT_SPECIFIC); \ 206 } 207 208#define M_ASN1_D2I_get_IMP_set_opt_type(type,b,func,free_func,tag) \ 209 if ((c.slen != 0) && \ 210 (M_ASN1_next == \ 211 (V_ASN1_CONTEXT_SPECIFIC|V_ASN1_CONSTRUCTED|(tag))))\ 212 { \ 213 M_ASN1_D2I_get_imp_set_type(type,b,func,free_func,\ 214 tag,V_ASN1_CONTEXT_SPECIFIC); \ 215 } 216 217#define M_ASN1_D2I_get_seq(r,func,free_func) \ 218 M_ASN1_D2I_get_imp_set(r,func,free_func,\ 219 V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL); 220 221#define M_ASN1_D2I_get_seq_type(type,r,func,free_func) \ 222 M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,\ 223 V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL) 224 225#define M_ASN1_D2I_get_seq_opt(r,func,free_func) \ 226 if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \ 227 V_ASN1_CONSTRUCTED|V_ASN1_SEQUENCE)))\ 228 { M_ASN1_D2I_get_seq(r,func,free_func); } 229 230#define M_ASN1_D2I_get_seq_opt_type(type,r,func,free_func) \ 231 if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \ 232 V_ASN1_CONSTRUCTED|V_ASN1_SEQUENCE)))\ 233 { M_ASN1_D2I_get_seq_type(type,r,func,free_func); } 234 235#define M_ASN1_D2I_get_IMP_set(r,func,free_func,x) \ 236 M_ASN1_D2I_get_imp_set(r,func,free_func,\ 237 x,V_ASN1_CONTEXT_SPECIFIC); 238 239#define M_ASN1_D2I_get_IMP_set_type(type,r,func,free_func,x) \ 240 M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,\ 241 x,V_ASN1_CONTEXT_SPECIFIC); 242 243#define M_ASN1_D2I_get_imp_set(r,func,free_func,a,b) \ 244 c.q=c.p; \ 245 if (d2i_ASN1_SET(&(r),&c.p,c.slen,(char *(*)())func,\ 246 (void (*)())free_func,a,b) == NULL) \ 247 { c.line=__LINE__; goto err; } \ 248 c.slen-=(c.p-c.q); 249 250#define M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,a,b) \ 251 c.q=c.p; \ 252 if (d2i_ASN1_SET_OF_##type(&(r),&c.p,c.slen,func,\ 253 free_func,a,b) == NULL) \ 254 { c.line=__LINE__; goto err; } \ 255 c.slen-=(c.p-c.q); 256 257#define M_ASN1_D2I_get_set_strings(r,func,a,b) \ 258 c.q=c.p; \ 259 if (d2i_ASN1_STRING_SET(&(r),&c.p,c.slen,a,b) == NULL) \ 260 { c.line=__LINE__; goto err; } \ 261 c.slen-=(c.p-c.q); 262 263#define M_ASN1_D2I_get_EXP_opt(r,func,tag) \ 264 if ((c.slen != 0L) && (M_ASN1_next == \ 265 (V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \ 266 { \ 267 int Tinf,Ttag,Tclass; \ 268 long Tlen; \ 269 \ 270 c.q=c.p; \ 271 Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \ 272 if (Tinf & 0x80) \ 273 { c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \ 274 c.line=__LINE__; goto err; } \ 275 if (Tinf == (V_ASN1_CONSTRUCTED+1)) \ 276 Tlen = c.slen - (c.p - c.q) - 2; \ 277 if (func(&(r),&c.p,Tlen) == NULL) \ 278 { c.line=__LINE__; goto err; } \ 279 if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \ 280 Tlen = c.slen - (c.p - c.q); \ 281 if(!ASN1_check_infinite_end(&c.p, Tlen)) \ 282 { c.error=ERR_R_MISSING_ASN1_EOS; \ 283 c.line=__LINE__; goto err; } \ 284 }\ 285 c.slen-=(c.p-c.q); \ 286 } 287 288#define M_ASN1_D2I_get_EXP_set_opt(r,func,free_func,tag,b) \ 289 if ((c.slen != 0) && (M_ASN1_next == \ 290 (V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \ 291 { \ 292 int Tinf,Ttag,Tclass; \ 293 long Tlen; \ 294 \ 295 c.q=c.p; \ 296 Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \ 297 if (Tinf & 0x80) \ 298 { c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \ 299 c.line=__LINE__; goto err; } \ 300 if (Tinf == (V_ASN1_CONSTRUCTED+1)) \ 301 Tlen = c.slen - (c.p - c.q) - 2; \ 302 if (d2i_ASN1_SET(&(r),&c.p,Tlen,(char *(*)())func, \ 303 (void (*)())free_func, \ 304 b,V_ASN1_UNIVERSAL) == NULL) \ 305 { c.line=__LINE__; goto err; } \ 306 if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \ 307 Tlen = c.slen - (c.p - c.q); \ 308 if(!ASN1_check_infinite_end(&c.p, Tlen)) \ 309 { c.error=ERR_R_MISSING_ASN1_EOS; \ 310 c.line=__LINE__; goto err; } \ 311 }\ 312 c.slen-=(c.p-c.q); \ 313 } 314 315#define M_ASN1_D2I_get_EXP_set_opt_type(type,r,func,free_func,tag,b) \ 316 if ((c.slen != 0) && (M_ASN1_next == \ 317 (V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \ 318 { \ 319 int Tinf,Ttag,Tclass; \ 320 long Tlen; \ 321 \ 322 c.q=c.p; \ 323 Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \ 324 if (Tinf & 0x80) \ 325 { c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \ 326 c.line=__LINE__; goto err; } \ 327 if (Tinf == (V_ASN1_CONSTRUCTED+1)) \ 328 Tlen = c.slen - (c.p - c.q) - 2; \ 329 if (d2i_ASN1_SET_OF_##type(&(r),&c.p,Tlen,func, \ 330 free_func,b,V_ASN1_UNIVERSAL) == NULL) \ 331 { c.line=__LINE__; goto err; } \ 332 if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \ 333 Tlen = c.slen - (c.p - c.q); \ 334 if(!ASN1_check_infinite_end(&c.p, Tlen)) \ 335 { c.error=ERR_R_MISSING_ASN1_EOS; \ 336 c.line=__LINE__; goto err; } \ 337 }\ 338 c.slen-=(c.p-c.q); \ 339 } 340 341/* New macros */ 342#define M_ASN1_New_Malloc(ret,type) \ 343 if ((ret=(type *)Malloc(sizeof(type))) == NULL) \ 344 { c.line=__LINE__; goto err2; } 345 346#define M_ASN1_New(arg,func) \ 347 if (((arg)=func()) == NULL) return(NULL) 348 349#define M_ASN1_New_Error(a) \ 350/* err: ASN1_MAC_H_err((a),ERR_R_NESTED_ASN1_ERROR,c.line); \ 351 return(NULL);*/ \ 352 err2: ASN1_MAC_H_err((a),ERR_R_MALLOC_FAILURE,c.line); \ 353 return(NULL) 354 355 356#define M_ASN1_next (*c.p) 357#define M_ASN1_next_prev (*c.q) 358 359/*************************************************/ 360 361#define M_ASN1_I2D_vars(a) int r=0,ret=0; \ 362 unsigned char *p; \ 363 if (a == NULL) return(0) 364 365/* Length Macros */ 366#define M_ASN1_I2D_len(a,f) ret+=f(a,NULL) 367#define M_ASN1_I2D_len_IMP_opt(a,f) if (a != NULL) M_ASN1_I2D_len(a,f) 368 369#define M_ASN1_I2D_len_SET(a,f) \ 370 ret+=i2d_ASN1_SET(a,NULL,f,V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET); 371 372#define M_ASN1_I2D_len_SET_type(type,a,f) \ 373 ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,V_ASN1_SET, \ 374 V_ASN1_UNIVERSAL,IS_SET); 375 376#define M_ASN1_I2D_len_SEQUENCE(a,f) \ 377 ret+=i2d_ASN1_SET(a,NULL,f,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL, \ 378 IS_SEQUENCE); 379 380#define M_ASN1_I2D_len_SEQUENCE_type(type,a,f) \ 381 ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,V_ASN1_SEQUENCE, \ 382 V_ASN1_UNIVERSAL,IS_SEQUENCE) 383 384#define M_ASN1_I2D_len_SEQUENCE_opt(a,f) \ 385 if ((a != NULL) && (sk_num(a) != 0)) \ 386 M_ASN1_I2D_len_SEQUENCE(a,f); 387 388#define M_ASN1_I2D_len_SEQUENCE_opt_type(type,a,f) \ 389 if ((a != NULL) && (sk_##type##_num(a) != 0)) \ 390 M_ASN1_I2D_len_SEQUENCE_type(type,a,f); 391 392#define M_ASN1_I2D_len_IMP_SET(a,f,x) \ 393 ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC,IS_SET); 394 395#define M_ASN1_I2D_len_IMP_SET_type(type,a,f,x) \ 396 ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \ 397 V_ASN1_CONTEXT_SPECIFIC,IS_SET); 398 399#define M_ASN1_I2D_len_IMP_SET_opt(a,f,x) \ 400 if ((a != NULL) && (sk_num(a) != 0)) \ 401 ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \ 402 IS_SET); 403 404#define M_ASN1_I2D_len_IMP_SET_opt_type(type,a,f,x) \ 405 if ((a != NULL) && (sk_##type##_num(a) != 0)) \ 406 ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \ 407 V_ASN1_CONTEXT_SPECIFIC,IS_SET); 408 409#define M_ASN1_I2D_len_IMP_SEQUENCE(a,f,x) \ 410 ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \ 411 IS_SEQUENCE); 412 413#define M_ASN1_I2D_len_IMP_SEQUENCE_opt(a,f,x) \ 414 if ((a != NULL) && (sk_num(a) != 0)) \ 415 ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \ 416 IS_SEQUENCE); 417 418#define M_ASN1_I2D_len_IMP_SEQUENCE_opt_type(type,a,f,x) \ 419 if ((a != NULL) && (sk_##type##_num(a) != 0)) \ 420 ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \ 421 V_ASN1_CONTEXT_SPECIFIC, \ 422 IS_SEQUENCE); 423 424#define M_ASN1_I2D_len_EXP_opt(a,f,mtag,v) \ 425 if (a != NULL)\ 426 { \ 427 v=f(a,NULL); \ 428 ret+=ASN1_object_size(1,v,mtag); \ 429 } 430 431#define M_ASN1_I2D_len_EXP_SET_opt(a,f,mtag,tag,v) \ 432 if ((a != NULL) && (sk_num(a) != 0))\ 433 { \ 434 v=i2d_ASN1_SET(a,NULL,f,tag,V_ASN1_UNIVERSAL,IS_SET); \ 435 ret+=ASN1_object_size(1,v,mtag); \ 436 } 437 438#define M_ASN1_I2D_len_EXP_SEQUENCE_opt(a,f,mtag,tag,v) \ 439 if ((a != NULL) && (sk_num(a) != 0))\ 440 { \ 441 v=i2d_ASN1_SET(a,NULL,f,tag,V_ASN1_UNIVERSAL, \ 442 IS_SEQUENCE); \ 443 ret+=ASN1_object_size(1,v,mtag); \ 444 } 445 446#define M_ASN1_I2D_len_EXP_SEQUENCE_opt_type(type,a,f,mtag,tag,v) \ 447 if ((a != NULL) && (sk_##type##_num(a) != 0))\ 448 { \ 449 v=i2d_ASN1_SET_OF_##type(a,NULL,f,tag, \ 450 V_ASN1_UNIVERSAL, \ 451 IS_SEQUENCE); \ 452 ret+=ASN1_object_size(1,v,mtag); \ 453 } 454 455/* Put Macros */ 456#define M_ASN1_I2D_put(a,f) f(a,&p) 457 458#define M_ASN1_I2D_put_IMP_opt(a,f,t) \ 459 if (a != NULL) \ 460 { \ 461 unsigned char *q=p; \ 462 f(a,&p); \ 463 *q=(V_ASN1_CONTEXT_SPECIFIC|t|(*q&V_ASN1_CONSTRUCTED));\ 464 } 465 466#define M_ASN1_I2D_put_SET(a,f) i2d_ASN1_SET(a,&p,f,V_ASN1_SET,\ 467 V_ASN1_UNIVERSAL,IS_SET) 468#define M_ASN1_I2D_put_SET_type(type,a,f) \ 469 i2d_ASN1_SET_OF_##type(a,&p,f,V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET) 470#define M_ASN1_I2D_put_IMP_SET(a,f,x) i2d_ASN1_SET(a,&p,f,x,\ 471 V_ASN1_CONTEXT_SPECIFIC,IS_SET) 472#define M_ASN1_I2D_put_IMP_SET_type(type,a,f,x) \ 473 i2d_ASN1_SET_OF_##type(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC,IS_SET) 474#define M_ASN1_I2D_put_IMP_SEQUENCE(a,f,x) i2d_ASN1_SET(a,&p,f,x,\ 475 V_ASN1_CONTEXT_SPECIFIC,IS_SEQUENCE) 476 477#define M_ASN1_I2D_put_SEQUENCE(a,f) i2d_ASN1_SET(a,&p,f,V_ASN1_SEQUENCE,\ 478 V_ASN1_UNIVERSAL,IS_SEQUENCE) 479 480#define M_ASN1_I2D_put_SEQUENCE_type(type,a,f) \ 481 i2d_ASN1_SET_OF_##type(a,&p,f,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL, \ 482 IS_SEQUENCE) 483 484#define M_ASN1_I2D_put_SEQUENCE_opt(a,f) \ 485 if ((a != NULL) && (sk_num(a) != 0)) \ 486 M_ASN1_I2D_put_SEQUENCE(a,f); 487 488#define M_ASN1_I2D_put_IMP_SET_opt(a,f,x) \ 489 if ((a != NULL) && (sk_num(a) != 0)) \ 490 { i2d_ASN1_SET(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC, \ 491 IS_SET); } 492 493#define M_ASN1_I2D_put_IMP_SET_opt_type(type,a,f,x) \ 494 if ((a != NULL) && (sk_##type##_num(a) != 0)) \ 495 { i2d_ASN1_SET_OF_##type(a,&p,f,x, \ 496 V_ASN1_CONTEXT_SPECIFIC, \ 497 IS_SET); } 498 499#define M_ASN1_I2D_put_IMP_SEQUENCE_opt(a,f,x) \ 500 if ((a != NULL) && (sk_num(a) != 0)) \ 501 { i2d_ASN1_SET(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC, \ 502 IS_SEQUENCE); } 503 504#define M_ASN1_I2D_put_IMP_SEQUENCE_opt_type(type,a,f,x) \ 505 if ((a != NULL) && (sk_##type##_num(a) != 0)) \ 506 { i2d_ASN1_SET_OF_##type(a,&p,f,x, \ 507 V_ASN1_CONTEXT_SPECIFIC, \ 508 IS_SEQUENCE); } 509 510#define M_ASN1_I2D_put_EXP_opt(a,f,tag,v) \ 511 if (a != NULL) \ 512 { \ 513 ASN1_put_object(&p,1,v,tag,V_ASN1_CONTEXT_SPECIFIC); \ 514 f(a,&p); \ 515 } 516 517#define M_ASN1_I2D_put_EXP_SET_opt(a,f,mtag,tag,v) \ 518 if ((a != NULL) && (sk_num(a) != 0)) \ 519 { \ 520 ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \ 521 i2d_ASN1_SET(a,&p,f,tag,V_ASN1_UNIVERSAL,IS_SET); \ 522 } 523 524#define M_ASN1_I2D_put_EXP_SEQUENCE_opt(a,f,mtag,tag,v) \ 525 if ((a != NULL) && (sk_num(a) != 0)) \ 526 { \ 527 ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \ 528 i2d_ASN1_SET(a,&p,f,tag,V_ASN1_UNIVERSAL,IS_SEQUENCE); \ 529 } 530 531#define M_ASN1_I2D_put_EXP_SEQUENCE_opt_type(type,a,f,mtag,tag,v) \ 532 if ((a != NULL) && (sk_##type##_num(a) != 0)) \ 533 { \ 534 ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \ 535 i2d_ASN1_SET_OF_##type(a,&p,f,tag,V_ASN1_UNIVERSAL, \ 536 IS_SEQUENCE); \ 537 } 538 539#define M_ASN1_I2D_seq_total() \ 540 r=ASN1_object_size(1,ret,V_ASN1_SEQUENCE); \ 541 if (pp == NULL) return(r); \ 542 p= *pp; \ 543 ASN1_put_object(&p,1,ret,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL) 544 545#define M_ASN1_I2D_INF_seq_start(tag,ctx) \ 546 *(p++)=(V_ASN1_CONSTRUCTED|(tag)|(ctx)); \ 547 *(p++)=0x80 548 549#define M_ASN1_I2D_INF_seq_end() *(p++)=0x00; *(p++)=0x00 550 551#define M_ASN1_I2D_finish() *pp=p; \ 552 return(r); 553 554int asn1_GetSequence(ASN1_CTX *c, long *length); 555void asn1_add_error(unsigned char *address,int offset); 556#ifdef __cplusplus 557} 558#endif 559 560#endif 561