/* crypto/asn1/asn1_mac.h */
-/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
#include "x509.h"
#include "pkcs7.h"
+#ifndef ASN1_MAC_ERR_LIB
+#define ASN1_MAC_ERR_LIB ERR_LIB_ASN1
+#endif
+
+#define ASN1_MAC_H_err(f,r,line) \
+ ERR_PUT_error(ASN1_MAC_ERR_LIB,(f),(r),ERR_file_name,(line))
+
#define M_ASN1_D2I_vars(a,type,func) \
ASN1_CTX c; \
type ret=NULL; \
\
c.pp=pp; \
- c.error=ASN1_R_ERROR_STACK; \
+ c.q= *pp; \
+ c.error=ERR_R_NESTED_ASN1_ERROR; \
if ((a == NULL) || ((*a) == NULL)) \
- { if ((ret=(type)func()) == NULL) goto err; } \
+ { if ((ret=(type)func()) == NULL) \
+ { c.line=__LINE__; goto err; } } \
else ret=(*a);
#define M_ASN1_D2I_Init() \
c.max=(length == 0)?0:(c.p+length);
#define M_ASN1_D2I_Finish_2(a) \
- if (!asn1_Finish(&c)) goto err; \
+ if (!asn1_Finish(&c)) \
+ { c.line=__LINE__; goto err; } \
*pp=c.p; \
if (a != NULL) (*a)=ret; \
return(ret);
#define M_ASN1_D2I_Finish(a,func,e) \
M_ASN1_D2I_Finish_2(a); \
err:\
- ASN1err((e),c.error); \
+ ASN1_MAC_H_err((e),c.error,c.line); \
+ asn1_add_error(*pp,(int)(c.q- *pp)); \
if ((ret != NULL) && ((a == NULL) || (*a != ret))) func(ret); \
return(NULL)
#define M_ASN1_D2I_start_sequence() \
- if (!asn1_GetSequence(&c,&length)) goto err;
+ if (!asn1_GetSequence(&c,&length)) \
+ { c.line=__LINE__; goto err; }
#define M_ASN1_D2I_end_sequence() \
(((c.inf&1) == 0)?(c.slen <= 0): \
(c.eos=ASN1_check_infinite_end(&c.p,c.slen)))
+/* Don't use this with d2i_ASN1_BOOLEAN() */
#define M_ASN1_D2I_get(b,func) \
c.q=c.p; \
- if (func(&(b),&c.p,c.slen) == NULL) goto err; \
+ if (func(&(b),&c.p,c.slen) == NULL) \
+ {c.line=__LINE__; goto err; } \
+ c.slen-=(c.p-c.q);
+
+/* use this instead () */
+#define M_ASN1_D2I_get_int(b,func) \
+ c.q=c.p; \
+ if (func(&(b),&c.p,c.slen) < 0) \
+ {c.line=__LINE__; goto err; } \
c.slen-=(c.p-c.q);
#define M_ASN1_D2I_get_opt(b,func,type) \
M_ASN1_D2I_get(b,func); \
}
+#define M_ASN1_D2I_get_imp(b,func, type) \
+ M_ASN1_next=(_tmp& V_ASN1_CONSTRUCTED)|type; \
+ c.q=c.p; \
+ if (func(&(b),&c.p,c.slen) == NULL) \
+ {c.line=__LINE__; M_ASN1_next_prev = _tmp; goto err; } \
+ c.slen-=(c.p-c.q);\
+ M_ASN1_next_prev=_tmp;
+
#define M_ASN1_D2I_get_IMP_opt(b,func,tag,type) \
if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) == \
(V_ASN1_CONTEXT_SPECIFIC|(tag)))) \
{ \
- unsigned char tmp; \
- tmp=M_ASN1_next; \
- M_ASN1_next=(tmp& ~V_ASN1_PRIMATIVE_TAG)|type; \
- M_ASN1_D2I_get(b,func); \
- M_ASN1_next_prev=tmp; \
+ unsigned char _tmp = M_ASN1_next; \
+ M_ASN1_D2I_get_imp(b,func, type);\
}
-#define M_ASN1_D2I_get_set(r,func) \
- M_ASN1_D2I_get_imp_set(r,func,V_ASN1_SET,V_ASN1_UNIVERSAL);
+#define M_ASN1_D2I_get_set(r,func,free_func) \
+ M_ASN1_D2I_get_imp_set(r,func,free_func, \
+ V_ASN1_SET,V_ASN1_UNIVERSAL);
+
+#define M_ASN1_D2I_get_set_opt(r,func,free_func) \
+ if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \
+ V_ASN1_CONSTRUCTED|V_ASN1_SET)))\
+ { M_ASN1_D2I_get_set(r,func,free_func); }
+
+#define M_ASN1_I2D_len_SET_opt(a,f) \
+ if ((a != NULL) && (sk_num(a) != 0)) \
+ M_ASN1_I2D_len_SET(a,f);
-#define M_ASN1_D2I_get_IMP_set_opt(b,func,tag) \
+#define M_ASN1_I2D_put_SET_opt(a,f) \
+ if ((a != NULL) && (sk_num(a) != 0)) \
+ M_ASN1_I2D_put_SET(a,f);
+
+#define M_ASN1_I2D_put_SEQUENCE_opt(a,f) \
+ if ((a != NULL) && (sk_num(a) != 0)) \
+ M_ASN1_I2D_put_SEQUENCE(a,f);
+
+#define M_ASN1_D2I_get_IMP_set_opt(b,func,free_func,tag) \
+ if ((c.slen != 0) && \
+ (M_ASN1_next == \
+ (V_ASN1_CONTEXT_SPECIFIC|V_ASN1_CONSTRUCTED|(tag))))\
+ { \
+ M_ASN1_D2I_get_imp_set(b,func,free_func,\
+ tag,V_ASN1_CONTEXT_SPECIFIC); \
+ }
+
+#define M_ASN1_D2I_get_IMP_set_opt_type(type,b,func,free_func,tag) \
if ((c.slen != 0) && \
(M_ASN1_next == \
(V_ASN1_CONTEXT_SPECIFIC|V_ASN1_CONSTRUCTED|(tag))))\
{ \
- M_ASN1_D2I_get_imp_set(b,func,tag,V_ASN1_CONTEXT_SPECIFIC); \
+ M_ASN1_D2I_get_imp_set_type(type,b,func,free_func,\
+ tag,V_ASN1_CONTEXT_SPECIFIC); \
}
-#define M_ASN1_D2I_get_seq(r,func) \
- M_ASN1_D2I_get_imp_set(r,func,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL);
+#define M_ASN1_D2I_get_seq(r,func,free_func) \
+ M_ASN1_D2I_get_imp_set(r,func,free_func,\
+ V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL);
-#define M_ASN1_D2I_get_seq_opt(r,func) \
+#define M_ASN1_D2I_get_seq_type(type,r,func,free_func) \
+ M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,\
+ V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL)
+
+#define M_ASN1_D2I_get_seq_opt(r,func,free_func) \
if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \
V_ASN1_CONSTRUCTED|V_ASN1_SEQUENCE)))\
- { M_ASN1_D2I_get_seq(r,func); }
+ { M_ASN1_D2I_get_seq(r,func,free_func); }
+
+#define M_ASN1_D2I_get_IMP_set(r,func,free_func,x) \
+ M_ASN1_D2I_get_imp_set(r,func,free_func,\
+ x,V_ASN1_CONTEXT_SPECIFIC);
-#define M_ASN1_D2I_get_IMP_set(r,func,x) \
- M_ASN1_D2I_get_imp_set(r,func,x,V_ASN1_CONTEXT_SPECIFIC);
+#define M_ASN1_D2I_get_imp_set(r,func,free_func,a,b) \
+ c.q=c.p; \
+ if (d2i_ASN1_SET(&(r),&c.p,c.slen,(char *(*)())func,\
+ (void (*)())free_func,a,b) == NULL) \
+ { c.line=__LINE__; goto err; } \
+ c.slen-=(c.p-c.q);
-#define M_ASN1_D2I_get_imp_set(r,func,a,b) \
+#define M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,a,b) \
c.q=c.p; \
- if (d2i_ASN1_SET(&(r),&c.p,c.slen,(char *(*)())func,a,b) == NULL) \
- goto err; \
+ if (d2i_ASN1_SET_OF_##type(&(r),&c.p,c.slen,func,\
+ free_func,a,b) == NULL) \
+ { c.line=__LINE__; goto err; } \
c.slen-=(c.p-c.q);
#define M_ASN1_D2I_get_set_strings(r,func,a,b) \
c.q=c.p; \
if (d2i_ASN1_STRING_SET(&(r),&c.p,c.slen,a,b) == NULL) \
- goto err; \
+ { c.line=__LINE__; goto err; } \
c.slen-=(c.p-c.q);
#define M_ASN1_D2I_get_EXP_opt(r,func,tag) \
c.q=c.p; \
Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \
if (Tinf & 0x80) \
- { c.error=ASN1_R_BAD_OBJECT_HEADER; goto err; } \
+ { c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \
+ c.line=__LINE__; goto err; } \
+ if (Tinf == (V_ASN1_CONSTRUCTED+1)) \
+ Tlen = c.slen - (c.p - c.q) - 2; \
if (func(&(r),&c.p,Tlen) == NULL) \
- goto err; \
+ { c.line=__LINE__; goto err; } \
+ if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \
+ Tlen = c.slen - (c.p - c.q); \
+ if(!ASN1_check_infinite_end(&c.p, Tlen)) \
+ { c.error=ERR_R_MISSING_ASN1_EOS; \
+ c.line=__LINE__; goto err; } \
+ }\
c.slen-=(c.p-c.q); \
}
-#define M_ASN1_D2I_get_EXP_set_opt(r,func,tag,b) \
+#define M_ASN1_D2I_get_EXP_set_opt(r,func,free_func,tag,b) \
if ((c.slen != 0) && (M_ASN1_next == \
(V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \
{ \
c.q=c.p; \
Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \
if (Tinf & 0x80) \
- { c.error=ASN1_R_BAD_OBJECT_HEADER; goto err; } \
+ { c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \
+ c.line=__LINE__; goto err; } \
+ if (Tinf == (V_ASN1_CONSTRUCTED+1)) \
+ Tlen = c.slen - (c.p - c.q) - 2; \
if (d2i_ASN1_SET(&(r),&c.p,Tlen,(char *(*)())func, \
+ (void (*)())free_func, \
b,V_ASN1_UNIVERSAL) == NULL) \
- goto err; \
+ { c.line=__LINE__; goto err; } \
+ if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \
+ Tlen = c.slen - (c.p - c.q); \
+ if(!ASN1_check_infinite_end(&c.p, Tlen)) \
+ { c.error=ERR_R_MISSING_ASN1_EOS; \
+ c.line=__LINE__; goto err; } \
+ }\
c.slen-=(c.p-c.q); \
}
/* New macros */
#define M_ASN1_New_Malloc(ret,type) \
- if ((ret=(type *)Malloc(sizeof(type))) == NULL) goto err2;
+ if ((ret=(type *)Malloc(sizeof(type))) == NULL) \
+ { c.line=__LINE__; goto err2; }
#define M_ASN1_New(arg,func) \
if (((arg)=func()) == NULL) return(NULL)
#define M_ASN1_New_Error(a) \
-/* err: ASN1err((a),ASN1_R_ERROR_STACK); \
+/* err: ASN1_MAC_H_err((a),ERR_R_NESTED_ASN1_ERROR,c.line); \
return(NULL);*/ \
- err2: ASN1err((a),ERR_R_MALLOC_FAILURE); \
+ err2: ASN1_MAC_H_err((a),ERR_R_MALLOC_FAILURE,c.line); \
return(NULL)
#define M_ASN1_I2D_len_IMP_opt(a,f) if (a != NULL) M_ASN1_I2D_len(a,f)
#define M_ASN1_I2D_len_SET(a,f) \
- ret+=i2d_ASN1_SET(a,NULL,f,V_ASN1_SET,V_ASN1_UNIVERSAL);
+ ret+=i2d_ASN1_SET(a,NULL,f,V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET);
+
+#define M_ASN1_I2D_len_SEQUENCE(a,f) \
+ ret+=i2d_ASN1_SET(a,NULL,f,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL, \
+ IS_SEQUENCE);
+
+#define M_ASN1_I2D_len_SEQUENCE_type(type,a,f) \
+ ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,V_ASN1_SEQUENCE, \
+ V_ASN1_UNIVERSAL,IS_SEQUENCE)
+
+#define M_ASN1_I2D_len_SEQUENCE_opt(a,f) \
+ if ((a != NULL) && (sk_num(a) != 0)) \
+ M_ASN1_I2D_len_SEQUENCE(a,f);
-#define M_ASN1_I2D_len_SEQ(a,f) \
- ret+=i2d_ASN1_SET(a,NULL,f,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL);
+#define M_ASN1_I2D_len_IMP_SET(a,f,x) \
+ ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC,IS_SET);
-#define M_ASN1_I2D_len_SEQ_opt(a,f) \
+#define M_ASN1_I2D_len_IMP_SET_opt(a,f,x) \
if ((a != NULL) && (sk_num(a) != 0)) \
- M_ASN1_I2D_len_SEQ(a,f);
+ ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \
+ IS_SET);
-#define M_ASN1_I2D_len_IMP_set(a,f,x) \
- ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC);
+#define M_ASN1_I2D_len_IMP_SEQUENCE(a,f,x) \
+ ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \
+ IS_SEQUENCE);
-#define M_ASN1_I2D_len_IMP_set_opt(a,f,x) \
+#define M_ASN1_I2D_len_IMP_SEQUENCE_opt(a,f,x) \
if ((a != NULL) && (sk_num(a) != 0)) \
- ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC);
+ ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \
+ IS_SEQUENCE);
+
+#define M_ASN1_I2D_len_IMP_SEQUENCE_opt_type(type,a,f,x) \
+ if ((a != NULL) && (sk_##type##_num(a) != 0)) \
+ ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \
+ V_ASN1_CONTEXT_SPECIFIC, \
+ IS_SEQUENCE);
#define M_ASN1_I2D_len_EXP_opt(a,f,mtag,v) \
if (a != NULL)\
ret+=ASN1_object_size(1,v,mtag); \
}
-#define M_ASN1_I2D_len_EXP_set_opt(a,f,mtag,tag,v) \
+#define M_ASN1_I2D_len_EXP_SET_opt(a,f,mtag,tag,v) \
if ((a != NULL) && (sk_num(a) != 0))\
{ \
- v=i2d_ASN1_SET(a,NULL,f,tag,V_ASN1_UNIVERSAL); \
+ v=i2d_ASN1_SET(a,NULL,f,tag,V_ASN1_UNIVERSAL,IS_SET); \
+ ret+=ASN1_object_size(1,v,mtag); \
+ }
+
+#define M_ASN1_I2D_len_EXP_SEQUENCE_opt(a,f,mtag,tag,v) \
+ if ((a != NULL) && (sk_num(a) != 0))\
+ { \
+ v=i2d_ASN1_SET(a,NULL,f,tag,V_ASN1_UNIVERSAL, \
+ IS_SEQUENCE); \
ret+=ASN1_object_size(1,v,mtag); \
}
{ \
unsigned char *q=p; \
f(a,&p); \
- *q=(V_ASN1_CONTEXT_SPECIFIC|t); \
+ *q=(V_ASN1_CONTEXT_SPECIFIC|t|(*q&V_ASN1_CONSTRUCTED));\
}
#define M_ASN1_I2D_put_SET(a,f) i2d_ASN1_SET(a,&p,f,V_ASN1_SET,\
- V_ASN1_UNIVERSAL)
-#define M_ASN1_I2D_put_IMP_set(a,f,x) i2d_ASN1_SET(a,&p,f,x,\
- V_ASN1_CONTEXT_SPECIFIC)
+ V_ASN1_UNIVERSAL,IS_SET)
+#define M_ASN1_I2D_put_IMP_SET(a,f,x) i2d_ASN1_SET(a,&p,f,x,\
+ V_ASN1_CONTEXT_SPECIFIC,IS_SET)
+#define M_ASN1_I2D_put_IMP_SEQUENCE(a,f,x) i2d_ASN1_SET(a,&p,f,x,\
+ V_ASN1_CONTEXT_SPECIFIC,IS_SEQUENCE)
+
+#define M_ASN1_I2D_put_SEQUENCE(a,f) i2d_ASN1_SET(a,&p,f,V_ASN1_SEQUENCE,\
+ V_ASN1_UNIVERSAL,IS_SEQUENCE)
-#define M_ASN1_I2D_put_SEQ(a,f) i2d_ASN1_SET(a,&p,f,V_ASN1_SEQUENCE,\
- V_ASN1_UNIVERSAL)
+#define M_ASN1_I2D_put_SEQUENCE_type(type,a,f) \
+ i2d_ASN1_SET_OF_##type(a,&p,f,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL, \
+ IS_SEQUENCE)
-#define M_ASN1_I2D_put_SEQ_opt(a,f) \
+#define M_ASN1_I2D_put_SEQUENCE_opt(a,f) \
if ((a != NULL) && (sk_num(a) != 0)) \
- M_ASN1_I2D_put_SEQ(a,f);
+ M_ASN1_I2D_put_SEQUENCE(a,f);
-#define M_ASN1_I2D_put_IMP_set_opt(a,f,x) \
+#define M_ASN1_I2D_put_IMP_SET_opt(a,f,x) \
if ((a != NULL) && (sk_num(a) != 0)) \
- { i2d_ASN1_SET(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC); }
+ { i2d_ASN1_SET(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC, \
+ IS_SET); }
+
+#define M_ASN1_I2D_put_IMP_SEQUENCE_opt(a,f,x) \
+ if ((a != NULL) && (sk_num(a) != 0)) \
+ { i2d_ASN1_SET(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC, \
+ IS_SEQUENCE); }
+
+#define M_ASN1_I2D_put_IMP_SEQUENCE_opt_type(type,a,f,x) \
+ if ((a != NULL) && (sk_##type##_num(a) != 0)) \
+ { i2d_ASN1_SET_OF_##type(a,&p,f,x, \
+ V_ASN1_CONTEXT_SPECIFIC, \
+ IS_SEQUENCE); }
#define M_ASN1_I2D_put_EXP_opt(a,f,tag,v) \
if (a != NULL) \
f(a,&p); \
}
-#define M_ASN1_I2D_put_EXP_set_opt(a,f,mtag,tag,v) \
+#define M_ASN1_I2D_put_EXP_SET_opt(a,f,mtag,tag,v) \
+ if ((a != NULL) && (sk_num(a) != 0)) \
+ { \
+ ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \
+ i2d_ASN1_SET(a,&p,f,tag,V_ASN1_UNIVERSAL,IS_SET); \
+ }
+
+#define M_ASN1_I2D_put_EXP_SEQUENCE_opt(a,f,mtag,tag,v) \
if ((a != NULL) && (sk_num(a) != 0)) \
{ \
ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \
- i2d_ASN1_SET(a,&p,f,tag,V_ASN1_UNIVERSAL); \
+ i2d_ASN1_SET(a,&p,f,tag,V_ASN1_UNIVERSAL,IS_SEQUENCE); \
}
#define M_ASN1_I2D_seq_total() \
#ifndef NOPROTO
int asn1_GetSequence(ASN1_CTX *c, long *length);
+void asn1_add_error(unsigned char *address,int offset);
#else
int asn1_GetSequence();
+void asn1_add_error();
#endif
#ifdef __cplusplus