summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsteve <steve>2000-11-11 01:18:07 +0000
committersteve <steve>2000-11-11 01:18:07 +0000
commit8e8e1737354d506e1a1ebe2dc5b7dd3ce3f28060 (patch)
tree69a3f060f251c0b24faf8a10b4038d8156556244
parent2fad3fbce91fef85425fba110cfc5beda8fd8c0b (diff)
downloadopenssl-8e8e1737354d506e1a1ebe2dc5b7dd3ce3f28060.tar.gz
Initial new ASN1 template code. This is highly
experimental, doesn't work properly and does lots of evil things. Quite a few of the files aren't even compile in yet. It should however give a rough idea of how things will ultimately work. Don't even think about modifying any of this yet...
-rw-r--r--crypto/asn1/Makefile.ssl42
-rw-r--r--crypto/asn1/a_bytes.c6
-rw-r--r--crypto/asn1/asn1.h95
-rw-r--r--crypto/asn1/asn1_err.c51
-rw-r--r--crypto/asn1/asn1t.h512
-rw-r--r--crypto/asn1/tasn_dec.c810
-rw-r--r--crypto/asn1/tasn_enc.c415
-rw-r--r--crypto/asn1/tasn_fre.c152
-rw-r--r--crypto/asn1/tasn_new.c187
-rw-r--r--crypto/asn1/tasn_prn.c196
-rw-r--r--crypto/asn1/tasn_typ.c84
-rw-r--r--crypto/asn1/tasn_utl.c185
12 files changed, 2673 insertions, 62 deletions
diff --git a/crypto/asn1/Makefile.ssl b/crypto/asn1/Makefile.ssl
index cb73cda47..ae8f6470d 100644
--- a/crypto/asn1/Makefile.ssl
+++ b/crypto/asn1/Makefile.ssl
@@ -31,6 +31,7 @@ LIBSRC= a_object.c a_bitstr.c a_utctm.c a_gentm.c a_time.c a_int.c a_octet.c \
d2i_s_pr.c i2d_s_pr.c d2i_s_pu.c i2d_s_pu.c \
d2i_pu.c d2i_pr.c i2d_pu.c i2d_pr.c\
t_req.c t_x509.c t_x509a.c t_crl.c t_pkey.c t_spki.c t_bitst.c \
+ tasn_new.c tasn_fre.c tasn_enc.c tasn_dec.c tasn_utl.c tasn_typ.c \
p7_i_s.c p7_signi.c p7_signd.c p7_recip.c p7_enc_c.c p7_evp.c \
p7_dgst.c p7_s_e.c p7_enc.c p7_lib.c \
f_int.c f_string.c i2d_dhp.c i2d_dsap.c d2i_dhp.c d2i_dsap.c n_pkey.c \
@@ -46,6 +47,7 @@ LIBOBJ= a_object.o a_bitstr.o a_utctm.o a_gentm.o a_time.o a_int.o a_octet.o \
d2i_s_pr.o i2d_s_pr.o d2i_s_pu.o i2d_s_pu.o \
d2i_pu.o d2i_pr.o i2d_pu.o i2d_pr.o \
t_req.o t_x509.o t_x509a.o t_crl.o t_pkey.o t_spki.o t_bitst.o \
+ tasn_new.o tasn_fre.o tasn_enc.o tasn_dec.o tasn_utl.o tasn_typ.o \
p7_i_s.o p7_signi.o p7_signd.o p7_recip.o p7_enc_c.o p7_evp.o \
p7_dgst.o p7_s_e.o p7_enc.o p7_lib.o \
f_int.o f_string.o i2d_dhp.o i2d_dsap.o d2i_dhp.o d2i_dsap.o n_pkey.o \
@@ -55,7 +57,7 @@ LIBOBJ= a_object.o a_bitstr.o a_utctm.o a_gentm.o a_time.o a_int.o a_octet.o \
SRC= $(LIBSRC)
-EXHEADER= asn1.h asn1_mac.h
+EXHEADER= asn1.h asn1_mac.h asn1t.h
HEADER= $(EXHEADER)
ALL= $(GENERAL) $(SRC) $(HEADER)
@@ -1097,6 +1099,44 @@ t_x509a.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
t_x509a.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
t_x509a.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
t_x509a.o: ../../include/openssl/x509_vfy.h ../cryptlib.h
+tasn_dec.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+tasn_dec.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+tasn_dec.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+tasn_dec.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+tasn_dec.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+tasn_dec.o: ../../include/openssl/opensslconf.h
+tasn_dec.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h
+tasn_dec.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+tasn_enc.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+tasn_enc.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+tasn_enc.o: ../../include/openssl/crypto.h ../../include/openssl/obj_mac.h
+tasn_enc.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+tasn_enc.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h
+tasn_enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+tasn_fre.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+tasn_fre.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+tasn_fre.o: ../../include/openssl/crypto.h ../../include/openssl/obj_mac.h
+tasn_fre.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+tasn_fre.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h
+tasn_fre.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+tasn_new.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+tasn_new.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+tasn_new.o: ../../include/openssl/crypto.h ../../include/openssl/err.h
+tasn_new.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+tasn_new.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+tasn_new.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h
+tasn_new.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+tasn_typ.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+tasn_typ.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+tasn_typ.o: ../../include/openssl/crypto.h ../../include/openssl/opensslconf.h
+tasn_typ.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h
+tasn_typ.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+tasn_utl.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+tasn_utl.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+tasn_utl.o: ../../include/openssl/crypto.h ../../include/openssl/obj_mac.h
+tasn_utl.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+tasn_utl.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h
+tasn_utl.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
x_algor.o: ../../include/openssl/asn1.h ../../include/openssl/asn1_mac.h
x_algor.o: ../../include/openssl/bio.h ../../include/openssl/blowfish.h
x_algor.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
diff --git a/crypto/asn1/a_bytes.c b/crypto/asn1/a_bytes.c
index 3a0c0c783..b57aa27ef 100644
--- a/crypto/asn1/a_bytes.c
+++ b/crypto/asn1/a_bytes.c
@@ -71,6 +71,12 @@ B_ASN1_T61STRING,B_ASN1_VIDEOTEXSTRING,B_ASN1_IA5STRING,0,
B_ASN1_UNIVERSALSTRING,B_ASN1_UNKNOWN,B_ASN1_BMPSTRING,B_ASN1_UNKNOWN,
};
+unsigned long ASN1_tag2bit(int tag)
+{
+ if((tag < 0) || (tag > 30)) return 0;
+ return tag2bit[tag];
+}
+
static int asn1_collate_primitive(ASN1_STRING *a, ASN1_CTX *c);
/* type is a 'bitmap' of acceptable string types.
*/
diff --git a/crypto/asn1/asn1.h b/crypto/asn1/asn1.h
index 3daf4e483..41da44772 100644
--- a/crypto/asn1/asn1.h
+++ b/crypto/asn1/asn1.h
@@ -84,6 +84,7 @@ extern "C" {
#define V_ASN1_APP_CHOOSE -2 /* let the recipient choose */
#define V_ASN1_OTHER -3 /* used in ASN1_TYPE */
+#define V_ASN1_ANY -3 /* used in ASN1 template code */
#define V_ASN1_NEG 0x100 /* negative flag */
@@ -237,6 +238,7 @@ DECLARE_STACK_OF(ASN1_STRING_TABLE)
#define ASN1_VISIBLESTRING ASN1_STRING
#define ASN1_UTF8STRING ASN1_STRING
#define ASN1_BOOLEAN int
+#define ASN1_NULL int
#else
typedef struct asn1_string_st ASN1_INTEGER;
typedef struct asn1_string_st ASN1_ENUMERATED;
@@ -254,9 +256,17 @@ typedef struct asn1_string_st ASN1_GENERALIZEDTIME;
typedef struct asn1_string_st ASN1_VISIBLESTRING;
typedef struct asn1_string_st ASN1_UTF8STRING;
typedef int ASN1_BOOLEAN;
+typedef int ASN1_NULL;
#endif
-typedef int ASN1_NULL;
+/* Declarations for template structures: for full definitions
+ * see asn1t.h
+ */
+typedef struct ASN1_TEMPLATE_st ASN1_TEMPLATE;
+typedef struct ASN1_ITEM_st ASN1_ITEM;
+typedef struct ASN1_TLC_st ASN1_TLC;
+/* This is just an opaque pointer */
+typedef struct ASN1_VALUE_st ASN1_VALUE;
/* Parameters used by ASN1_STRING_print_ex() */
@@ -787,6 +797,7 @@ int ASN1_PRINTABLE_type(unsigned char *s, int max);
int i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass);
ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, unsigned char **pp,
long length, int Ptag, int Pclass);
+unsigned long ASN1_tag2bit(int tag);
/* type is one or more of the B_ASN1_ values. */
ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a,unsigned char **pp,
long length,int type);
@@ -873,6 +884,37 @@ ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid);
int ASN1_STRING_TABLE_add(int, long, long, unsigned long, unsigned long);
void ASN1_STRING_TABLE_cleanup(void);
+/* ASN1 template functions */
+
+/* Old API compatible functions */
+ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it);
+void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it);
+ASN1_VALUE * ASN1_item_d2i(ASN1_VALUE **val, unsigned char **in, long len, const ASN1_ITEM *it);
+int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it);
+
+int ASN1_item_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it);
+int ASN1_template_new(ASN1_VALUE **val, const ASN1_TEMPLATE *tt);
+int ASN1_primitive_new(ASN1_VALUE **val, long utype);
+
+void ASN1_template_free(ASN1_VALUE *arg, const ASN1_TEMPLATE *tt);
+int ASN1_template_d2i(ASN1_VALUE **val, unsigned char **in, long len, const ASN1_TEMPLATE *tt);
+int ASN1_item_ex_d2i(ASN1_VALUE **val, unsigned char **in, long len, const ASN1_ITEM *it,
+ int tag, int aclass, char opt, ASN1_TLC *ctx);
+
+int ASN1_item_ex_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass);
+int ASN1_template_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_TEMPLATE *tt);
+void ASN1_primitive_free(ASN1_VALUE *val, long utype);
+
+int asn1_get_choice_selector(ASN1_VALUE *data, const ASN1_ITEM *it);
+int asn1_set_choice_selector(ASN1_VALUE **data, int value, const ASN1_ITEM *it);
+ASN1_VALUE * asn1_get_field(ASN1_VALUE *data, const ASN1_TEMPLATE *tt);
+ASN1_VALUE ** asn1_get_field_ptr(ASN1_VALUE **data, const ASN1_TEMPLATE *tt);
+const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE *val, const ASN1_TEMPLATE *tt);
+int asn1_template_is_bool(const ASN1_TEMPLATE *tt);
+int asn1_item_is_bool(const ASN1_ITEM *it);
+
+
+
/* BEGIN ERROR CODES */
/* The following lines are auto generated by the script mkerr.pl. Any changes
* made after this point may be overwritten when the script is next run.
@@ -886,8 +928,11 @@ void ASN1_STRING_TABLE_cleanup(void);
#define ASN1_F_A2I_ASN1_INTEGER 101
#define ASN1_F_A2I_ASN1_STRING 102
#define ASN1_F_ACCESS_DESCRIPTION_NEW 291
+#define ASN1_F_ASN1_CHECK_TLEN 293
#define ASN1_F_ASN1_COLLATE_PRIMITIVE 103
+#define ASN1_F_ASN1_COLLECT 294
#define ASN1_F_ASN1_D2I_BIO 104
+#define ASN1_F_ASN1_D2I_EX_PRIMITIVE 295
#define ASN1_F_ASN1_D2I_FP 105
#define ASN1_F_ASN1_DUP 106
#define ASN1_F_ASN1_ENUMERATED_SET 232
@@ -899,6 +944,8 @@ void ASN1_STRING_TABLE_cleanup(void);
#define ASN1_F_ASN1_I2D_FP 110
#define ASN1_F_ASN1_INTEGER_SET 111
#define ASN1_F_ASN1_INTEGER_TO_BN 112
+#define ASN1_F_ASN1_ITEM_EX_D2I 296
+#define ASN1_F_ASN1_ITEM_NEW 297
#define ASN1_F_ASN1_MBSTRING_COPY 282
#define ASN1_F_ASN1_OBJECT_NEW 113
#define ASN1_F_ASN1_PACK_STRING 245
@@ -909,6 +956,9 @@ void ASN1_STRING_TABLE_cleanup(void);
#define ASN1_F_ASN1_STRING_NEW 115
#define ASN1_F_ASN1_STRING_TABLE_ADD 283
#define ASN1_F_ASN1_STRING_TYPE_NEW 116
+#define ASN1_F_ASN1_TEMPLATE_D2I 298
+#define ASN1_F_ASN1_TEMPLATE_EX_D2I 299
+#define ASN1_F_ASN1_TEMPLATE_NEW 300
#define ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING 117
#define ASN1_F_ASN1_TYPE_GET_OCTETSTRING 118
#define ASN1_F_ASN1_TYPE_NEW 119
@@ -919,6 +969,7 @@ void ASN1_STRING_TABLE_cleanup(void);
#define ASN1_F_BASIC_CONSTRAINTS_NEW 226
#define ASN1_F_BN_TO_ASN1_ENUMERATED 234
#define ASN1_F_BN_TO_ASN1_INTEGER 122
+#define ASN1_F_COLLECT_DATA 301
#define ASN1_F_D2I_ACCESS_DESCRIPTION 284
#define ASN1_F_D2I_ASN1_BIT_STRING 123
#define ASN1_F_D2I_ASN1_BMPSTRING 124
@@ -956,21 +1007,6 @@ void ASN1_STRING_TABLE_cleanup(void);
#define ASN1_F_D2I_NETSCAPE_SPKAC 143
#define ASN1_F_D2I_NETSCAPE_SPKI 144
#define ASN1_F_D2I_NOTICEREF 268
-#define ASN1_F_D2I_OCSP_BASICRESP 293
-#define ASN1_F_D2I_OCSP_CERTID 294
-#define ASN1_F_D2I_OCSP_CERTSTATUS 295
-#define ASN1_F_D2I_OCSP_CRLID 296
-#define ASN1_F_D2I_OCSP_ONEREQ 297
-#define ASN1_F_D2I_OCSP_REQINFO 298
-#define ASN1_F_D2I_OCSP_REQUEST 299
-#define ASN1_F_D2I_OCSP_RESPBYTES 300
-#define ASN1_F_D2I_OCSP_RESPDATA 301
-#define ASN1_F_D2I_OCSP_RESPID 302
-#define ASN1_F_D2I_OCSP_RESPONSE 303
-#define ASN1_F_D2I_OCSP_REVOKEDINFO 304
-#define ASN1_F_D2I_OCSP_SERVICELOC 305
-#define ASN1_F_D2I_OCSP_SIGNATURE 306
-#define ASN1_F_D2I_OCSP_SINGLERESP 307
#define ASN1_F_D2I_OTHERNAME 287
#define ASN1_F_D2I_PBE2PARAM 262
#define ASN1_F_D2I_PBEPARAM 249
@@ -1042,21 +1078,6 @@ void ASN1_STRING_TABLE_cleanup(void);
#define ASN1_F_NETSCAPE_SPKAC_NEW 190
#define ASN1_F_NETSCAPE_SPKI_NEW 191
#define ASN1_F_NOTICEREF_NEW 272
-#define ASN1_F_OCSP_BASICRESP_NEW 308
-#define ASN1_F_OCSP_CERTID_NEW 309
-#define ASN1_F_OCSP_CERTSTATUS_NEW 310
-#define ASN1_F_OCSP_CRLID_NEW 311
-#define ASN1_F_OCSP_ONEREQ_NEW 312
-#define ASN1_F_OCSP_REQINFO_NEW 313
-#define ASN1_F_OCSP_REQUEST_NEW 314
-#define ASN1_F_OCSP_RESPBYTES_NEW 315
-#define ASN1_F_OCSP_RESPDATA_NEW 316
-#define ASN1_F_OCSP_RESPID_NEW 317
-#define ASN1_F_OCSP_RESPONSE_NEW 318
-#define ASN1_F_OCSP_REVOKEDINFO_NEW 319
-#define ASN1_F_OCSP_SERVICELOC_NEW 320
-#define ASN1_F_OCSP_SIGNATURE_NEW 321
-#define ASN1_F_OCSP_SINGLERESP_NEW 322
#define ASN1_F_OTHERNAME_NEW 288
#define ASN1_F_PBE2PARAM_NEW 264
#define ASN1_F_PBEPARAM_NEW 251
@@ -1133,10 +1154,14 @@ void ASN1_STRING_TABLE_cleanup(void);
#define ASN1_R_EXPECTING_A_NULL 164
#define ASN1_R_EXPECTING_A_TIME 152
#define ASN1_R_EXPECTING_A_UTCTIME 118
+#define ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED 167
+#define ASN1_R_FIELD_MISSING 168
#define ASN1_R_FIRST_NUM_TOO_LARGE 119
#define ASN1_R_GENERALIZEDTIME_TOO_LONG 153
#define ASN1_R_HEADER_TOO_LONG 120
#define ASN1_R_ILLEGAL_CHARACTERS 158
+#define ASN1_R_ILLEGAL_NULL 169
+#define ASN1_R_ILLEGAL_TAGGED_ANY 170
#define ASN1_R_INVALID_BMPSTRING_LENGTH 159
#define ASN1_R_INVALID_DIGIT 121
#define ASN1_R_INVALID_SEPARATOR 122
@@ -1145,22 +1170,30 @@ void ASN1_STRING_TABLE_cleanup(void);
#define ASN1_R_INVALID_UTF8STRING 161
#define ASN1_R_IV_TOO_LARGE 124
#define ASN1_R_LENGTH_ERROR 125
+#define ASN1_R_MISSING_EOC 171
#define ASN1_R_MISSING_SECOND_NUMBER 126
+#define ASN1_R_MSTRING_NOT_UNIVERSAL 172
+#define ASN1_R_MSTRING_WRONG_TAG 173
#define ASN1_R_NON_HEX_CHARACTERS 127
#define ASN1_R_NOT_ENOUGH_DATA 128
+#define ASN1_R_NO_MATCHING_CHOICE_TYPE 174
#define ASN1_R_NULL_IS_WRONG_LENGTH 165
#define ASN1_R_ODD_NUMBER_OF_CHARS 129
#define ASN1_R_PARSING 130
#define ASN1_R_PRIVATE_KEY_HEADER_MISSING 131
#define ASN1_R_SECOND_NUMBER_TOO_LARGE 132
+#define ASN1_R_SEQUENCE_LENGTH_MISMATCH 175
+#define ASN1_R_SEQUENCE_NOT_CONSTRUCTED 176
#define ASN1_R_SHORT_LINE 133
#define ASN1_R_STRING_TOO_LONG 163
#define ASN1_R_STRING_TOO_SHORT 134
#define ASN1_R_TAG_VALUE_TOO_HIGH 135
#define ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 136
#define ASN1_R_TOO_LONG 137
+#define ASN1_R_TYPE_NOT_CONSTRUCTED 177
#define ASN1_R_UNABLE_TO_DECODE_RSA_KEY 138
#define ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY 139
+#define ASN1_R_UNEXPECTED_EOC 178
#define ASN1_R_UNKNOWN_ATTRIBUTE_TYPE 140
#define ASN1_R_UNKNOWN_FORMAT 162
#define ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM 141
diff --git a/crypto/asn1/asn1_err.c b/crypto/asn1/asn1_err.c
index 3a53cb33c..7d84bf61a 100644
--- a/crypto/asn1/asn1_err.c
+++ b/crypto/asn1/asn1_err.c
@@ -71,8 +71,11 @@ static ERR_STRING_DATA ASN1_str_functs[]=
{ERR_PACK(0,ASN1_F_A2I_ASN1_INTEGER,0), "a2i_ASN1_INTEGER"},
{ERR_PACK(0,ASN1_F_A2I_ASN1_STRING,0), "a2i_ASN1_STRING"},
{ERR_PACK(0,ASN1_F_ACCESS_DESCRIPTION_NEW,0), "ACCESS_DESCRIPTION_new"},
+{ERR_PACK(0,ASN1_F_ASN1_CHECK_TLEN,0), "ASN1_CHECK_TLEN"},
{ERR_PACK(0,ASN1_F_ASN1_COLLATE_PRIMITIVE,0), "ASN1_COLLATE_PRIMITIVE"},
+{ERR_PACK(0,ASN1_F_ASN1_COLLECT,0), "ASN1_COLLECT"},
{ERR_PACK(0,ASN1_F_ASN1_D2I_BIO,0), "ASN1_d2i_bio"},
+{ERR_PACK(0,ASN1_F_ASN1_D2I_EX_PRIMITIVE,0), "ASN1_D2I_EX_PRIMITIVE"},
{ERR_PACK(0,ASN1_F_ASN1_D2I_FP,0), "ASN1_d2i_fp"},
{ERR_PACK(0,ASN1_F_ASN1_DUP,0), "ASN1_dup"},
{ERR_PACK(0,ASN1_F_ASN1_ENUMERATED_SET,0), "ASN1_ENUMERATED_set"},
@@ -84,6 +87,8 @@ static ERR_STRING_DATA ASN1_str_functs[]=
{ERR_PACK(0,ASN1_F_ASN1_I2D_FP,0), "ASN1_i2d_fp"},
{ERR_PACK(0,ASN1_F_ASN1_INTEGER_SET,0), "ASN1_INTEGER_set"},
{ERR_PACK(0,ASN1_F_ASN1_INTEGER_TO_BN,0), "ASN1_INTEGER_to_BN"},
+{ERR_PACK(0,ASN1_F_ASN1_ITEM_EX_D2I,0), "ASN1_item_ex_d2i"},
+{ERR_PACK(0,ASN1_F_ASN1_ITEM_NEW,0), "ASN1_item_new"},
{ERR_PACK(0,ASN1_F_ASN1_MBSTRING_COPY,0), "ASN1_mbstring_copy"},
{ERR_PACK(0,ASN1_F_ASN1_OBJECT_NEW,0), "ASN1_OBJECT_new"},
{ERR_PACK(0,ASN1_F_ASN1_PACK_STRING,0), "ASN1_pack_string"},
@@ -94,6 +99,9 @@ static ERR_STRING_DATA ASN1_str_functs[]=
{ERR_PACK(0,ASN1_F_ASN1_STRING_NEW,0), "ASN1_STRING_new"},
{ERR_PACK(0,ASN1_F_ASN1_STRING_TABLE_ADD,0), "ASN1_STRING_TABLE_add"},
{ERR_PACK(0,ASN1_F_ASN1_STRING_TYPE_NEW,0), "ASN1_STRING_type_new"},
+{ERR_PACK(0,ASN1_F_ASN1_TEMPLATE_D2I,0), "ASN1_template_d2i"},
+{ERR_PACK(0,ASN1_F_ASN1_TEMPLATE_EX_D2I,0), "ASN1_TEMPLATE_EX_D2I"},
+{ERR_PACK(0,ASN1_F_ASN1_TEMPLATE_NEW,0), "ASN1_template_new"},
{ERR_PACK(0,ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING,0), "ASN1_TYPE_get_int_octetstring"},
{ERR_PACK(0,ASN1_F_ASN1_TYPE_GET_OCTETSTRING,0), "ASN1_TYPE_get_octetstring"},
{ERR_PACK(0,ASN1_F_ASN1_TYPE_NEW,0), "ASN1_TYPE_new"},
@@ -104,6 +112,7 @@ static ERR_STRING_DATA ASN1_str_functs[]=
{ERR_PACK(0,ASN1_F_BASIC_CONSTRAINTS_NEW,0), "BASIC_CONSTRAINTS_new"},
{ERR_PACK(0,ASN1_F_BN_TO_ASN1_ENUMERATED,0), "BN_to_ASN1_ENUMERATED"},
{ERR_PACK(0,ASN1_F_BN_TO_ASN1_INTEGER,0), "BN_to_ASN1_INTEGER"},
+{ERR_PACK(0,ASN1_F_COLLECT_DATA,0), "COLLECT_DATA"},
{ERR_PACK(0,ASN1_F_D2I_ACCESS_DESCRIPTION,0), "d2i_ACCESS_DESCRIPTION"},
{ERR_PACK(0,ASN1_F_D2I_ASN1_BIT_STRING,0), "d2i_ASN1_BIT_STRING"},
{ERR_PACK(0,ASN1_F_D2I_ASN1_BMPSTRING,0), "d2i_ASN1_BMPSTRING"},
@@ -141,21 +150,6 @@ static ERR_STRING_DATA ASN1_str_functs[]=
{ERR_PACK(0,ASN1_F_D2I_NETSCAPE_SPKAC,0), "d2i_NETSCAPE_SPKAC"},
{ERR_PACK(0,ASN1_F_D2I_NETSCAPE_SPKI,0), "d2i_NETSCAPE_SPKI"},
{ERR_PACK(0,ASN1_F_D2I_NOTICEREF,0), "d2i_NOTICEREF"},
-{ERR_PACK(0,ASN1_F_D2I_OCSP_BASICRESP,0), "d2i_OCSP_BASICRESP"},
-{ERR_PACK(0,ASN1_F_D2I_OCSP_CERTID,0), "d2i_OCSP_CERTID"},
-{ERR_PACK(0,ASN1_F_D2I_OCSP_CERTSTATUS,0), "d2i_OCSP_CERTSTATUS"},
-{ERR_PACK(0,ASN1_F_D2I_OCSP_CRLID,0), "d2i_OCSP_CRLID"},
-{ERR_PACK(0,ASN1_F_D2I_OCSP_ONEREQ,0), "d2i_OCSP_ONEREQ"},
-{ERR_PACK(0,ASN1_F_D2I_OCSP_REQINFO,0), "d2i_OCSP_REQINFO"},
-{ERR_PACK(0,ASN1_F_D2I_OCSP_REQUEST,0), "d2i_OCSP_REQUEST"},
-{ERR_PACK(0,ASN1_F_D2I_OCSP_RESPBYTES,0), "d2i_OCSP_RESPBYTES"},
-{ERR_PACK(0,ASN1_F_D2I_OCSP_RESPDATA,0), "d2i_OCSP_RESPDATA"},
-{ERR_PACK(0,ASN1_F_D2I_OCSP_RESPID,0), "d2i_OCSP_RESPID"},
-{ERR_PACK(0,ASN1_F_D2I_OCSP_RESPONSE,0), "d2i_OCSP_RESPONSE"},
-{ERR_PACK(0,ASN1_F_D2I_OCSP_REVOKEDINFO,0), "d2i_OCSP_REVOKEDINFO"},
-{ERR_PACK(0,ASN1_F_D2I_OCSP_SERVICELOC,0), "d2i_OCSP_SERVICELOC"},
-{ERR_PACK(0,ASN1_F_D2I_OCSP_SIGNATURE,0), "d2i_OCSP_SIGNATURE"},
-{ERR_PACK(0,ASN1_F_D2I_OCSP_SINGLERESP,0), "d2i_OCSP_SINGLERESP"},
{ERR_PACK(0,ASN1_F_D2I_OTHERNAME,0), "d2i_OTHERNAME"},
{ERR_PACK(0,ASN1_F_D2I_PBE2PARAM,0), "d2i_PBE2PARAM"},
{ERR_PACK(0,ASN1_F_D2I_PBEPARAM,0), "d2i_PBEPARAM"},
@@ -227,21 +221,6 @@ static ERR_STRING_DATA ASN1_str_functs[]=
{ERR_PACK(0,ASN1_F_NETSCAPE_SPKAC_NEW,0), "NETSCAPE_SPKAC_new"},
{ERR_PACK(0,ASN1_F_NETSCAPE_SPKI_NEW,0), "NETSCAPE_SPKI_new"},
{ERR_PACK(0,ASN1_F_NOTICEREF_NEW,0), "NOTICEREF_new"},
-{ERR_PACK(0,ASN1_F_OCSP_BASICRESP_NEW,0), "OCSP_BASICRESP_new"},
-{ERR_PACK(0,ASN1_F_OCSP_CERTID_NEW,0), "OCSP_CERTID_new"},
-{ERR_PACK(0,ASN1_F_OCSP_CERTSTATUS_NEW,0), "OCSP_CERTSTATUS_new"},
-{ERR_PACK(0,ASN1_F_OCSP_CRLID_NEW,0), "OCSP_CRLID_new"},
-{ERR_PACK(0,ASN1_F_OCSP_ONEREQ_NEW,0), "OCSP_ONEREQ_new"},
-{ERR_PACK(0,ASN1_F_OCSP_REQINFO_NEW,0), "OCSP_REQINFO_new"},
-{ERR_PACK(0,ASN1_F_OCSP_REQUEST_NEW,0), "OCSP_REQUEST_new"},
-{ERR_PACK(0,ASN1_F_OCSP_RESPBYTES_NEW,0), "OCSP_RESPBYTES_new"},
-{ERR_PACK(0,ASN1_F_OCSP_RESPDATA_NEW,0), "OCSP_RESPDATA_new"},
-{ERR_PACK(0,ASN1_F_OCSP_RESPID_NEW,0), "OCSP_RESPID_new"},
-{ERR_PACK(0,ASN1_F_OCSP_RESPONSE_NEW,0), "OCSP_RESPONSE_new"},
-{ERR_PACK(0,ASN1_F_OCSP_REVOKEDINFO_NEW,0), "OCSP_REVOKEDINFO_new"},
-{ERR_PACK(0,ASN1_F_OCSP_SERVICELOC_NEW,0), "OCSP_SERVICELOC_new"},
-{ERR_PACK(0,ASN1_F_OCSP_SIGNATURE_NEW,0), "OCSP_SIGNATURE_new"},
-{ERR_PACK(0,ASN1_F_OCSP_SINGLERESP_NEW,0), "OCSP_SINGLERESP_new"},
{ERR_PACK(0,ASN1_F_OTHERNAME_NEW,0), "OTHERNAME_new"},
{ERR_PACK(0,ASN1_F_PBE2PARAM_NEW,0), "PBE2PARAM_new"},
{ERR_PACK(0,ASN1_F_PBEPARAM_NEW,0), "PBEPARAM_new"},
@@ -321,10 +300,14 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
{ASN1_R_EXPECTING_A_NULL ,"expecting a null"},
{ASN1_R_EXPECTING_A_TIME ,"expecting a time"},
{ASN1_R_EXPECTING_A_UTCTIME ,"expecting a utctime"},
+{ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED ,"explicit tag not constructed"},
+{ASN1_R_FIELD_MISSING ,"field missing"},
{ASN1_R_FIRST_NUM_TOO_LARGE ,"first num too large"},
{ASN1_R_GENERALIZEDTIME_TOO_LONG ,"generalizedtime too long"},
{ASN1_R_HEADER_TOO_LONG ,"header too long"},
{ASN1_R_ILLEGAL_CHARACTERS ,"illegal characters"},
+{ASN1_R_ILLEGAL_NULL ,"illegal null"},
+{ASN1_R_ILLEGAL_TAGGED_ANY ,"illegal tagged any"},
{ASN1_R_INVALID_BMPSTRING_LENGTH ,"invalid bmpstring length"},
{ASN1_R_INVALID_DIGIT ,"invalid digit"},
{ASN1_R_INVALID_SEPARATOR ,"invalid separator"},
@@ -333,22 +316,30 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
{ASN1_R_INVALID_UTF8STRING ,"invalid utf8string"},
{ASN1_R_IV_TOO_LARGE ,"iv too large"},
{ASN1_R_LENGTH_ERROR ,"length error"},
+{ASN1_R_MISSING_EOC ,"missing eoc"},
{ASN1_R_MISSING_SECOND_NUMBER ,"missing second number"},
+{ASN1_R_MSTRING_NOT_UNIVERSAL ,"mstring not universal"},
+{ASN1_R_MSTRING_WRONG_TAG ,"mstring wrong tag"},
{ASN1_R_NON_HEX_CHARACTERS ,"non hex characters"},
{ASN1_R_NOT_ENOUGH_DATA ,"not enough data"},
+{ASN1_R_NO_MATCHING_CHOICE_TYPE ,"no matching choice type"},
{ASN1_R_NULL_IS_WRONG_LENGTH ,"null is wrong length"},
{ASN1_R_ODD_NUMBER_OF_CHARS ,"odd number of chars"},
{ASN1_R_PARSING ,"parsing"},
{ASN1_R_PRIVATE_KEY_HEADER_MISSING ,"private key header missing"},
{ASN1_R_SECOND_NUMBER_TOO_LARGE ,"second number too large"},
+{ASN1_R_SEQUENCE_LENGTH_MISMATCH ,"sequence length mismatch"},
+{ASN1_R_SEQUENCE_NOT_CONSTRUCTED ,"sequence not constructed"},
{ASN1_R_SHORT_LINE ,"short line"},
{ASN1_R_STRING_TOO_LONG ,"string too long"},
{ASN1_R_STRING_TOO_SHORT ,"string too short"},
{ASN1_R_TAG_VALUE_TOO_HIGH ,"tag value too high"},
{ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD,"the asn1 object identifier is not known for this md"},
{ASN1_R_TOO_LONG ,"too long"},
+{ASN1_R_TYPE_NOT_CONSTRUCTED ,"type not constructed"},
{ASN1_R_UNABLE_TO_DECODE_RSA_KEY ,"unable to decode rsa key"},
{ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY ,"unable to decode rsa private key"},
+{ASN1_R_UNEXPECTED_EOC ,"unexpected eoc"},
{ASN1_R_UNKNOWN_ATTRIBUTE_TYPE ,"unknown attribute type"},
{ASN1_R_UNKNOWN_FORMAT ,"unknown format"},
{ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM ,"unknown message digest algorithm"},
diff --git a/crypto/asn1/asn1t.h b/crypto/asn1/asn1t.h
new file mode 100644
index 000000000..186afeab6
--- /dev/null
+++ b/crypto/asn1/asn1t.h
@@ -0,0 +1,512 @@
+/* asnt.h */
+/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#ifndef HEADER_ASNT_H
+#define HEADER_ASNT_H
+
+/* ASN1 template defines, structures and functions */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Macros to aid ASN1 template writing */
+
+/* This pair helps declare a SEQUENCE. We can do:
+ *
+ * ASN1_SEQUENCE(stname) = {
+ * ... SEQUENCE components ...
+ * ASN1_SEQUENCE_END(stname);
+ *
+ * This will produce an ASN1_ITEM called stname_it
+ * for a structure called stname.
+ *
+ * If you want the same structure but a different
+ * name then use:
+ *
+ * ASN1_SEQUENCE(itname) = {
+ * ... SEQUENCE components ...
+ * ASN1_SEQUENCE_END_name(stname, itname);
+ *
+ * This will create an item called itname_it using
+ * a structure called stname.
+ */
+
+#define ASN1_SEQUENCE(tname) \
+ const static ASN1_TEMPLATE tname##_seq_tt[]
+
+#define ASN1_SEQUENCE_END(stname) ASN1_SEQUENCE_END_name(stname, stname)
+
+#define ASN1_SEQUENCE_END_name(stname, tname) \
+ ;\
+ const ASN1_ITEM tname##_it = { \
+ ASN1_ITYPE_SEQUENCE,\
+ V_ASN1_SEQUENCE,\
+ tname##_seq_tt,\
+ sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
+ NULL,\
+ sizeof(stname),\
+ #stname \
+ }
+
+
+/* This pair helps declare a CHOICE type. We can do:
+ *
+ * ASN1_CHOICE(chname) = {
+ * ... CHOICE options ...
+ * ASN1_CHOICE_END(chname);
+ *
+ * This will produce an ASN1_ITEM called chname_it
+ * for a structure called chname. The structure
+ * definition must look like this:
+ * typedef struct {
+ * int type;
+ * union {
+ * ASN1_SOMETHING *opt1;
+ * ASN1_SOMEOTHER *opt2;
+ * } value;
+ * } chname;
+ *
+ * the name of the selector must be 'type'
+ */
+
+#define ASN1_CHOICE(tname) \
+ const static ASN1_TEMPLATE tname##_ch_tt[]
+
+#define ASN1_CHOICE_END(stname) ASN1_CHOICE_END_name(stname, stname)
+
+#define ASN1_CHOICE_END_name(stname, tname) \
+ ;\
+ ASN1_ITEM tname##_it = { \
+ ASN1_ITYPE_CHOICE,\
+ offsetof(stname,type) ,\
+ tname##_ch_tt,\
+ sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\
+ NULL,\
+ sizeof(stname),\
+ #stname \
+ }
+
+
+
+
+/* These help with SEQUENCE or CHOICE components */
+
+/* used to declare other types */
+
+#define ASN1_EX_TYPE(flags, tag, stname, field, type) { \
+ (flags), (tag), offsetof(stname, field),\
+ #field, &(type##_it) }
+
+#define ASN1_IMP_EX(stname, field, type, tag, ex) \
+ ASN1_EX_TYPE(ASN1_TFLG_IMPLICIT | ex, tag, stname, field, type)
+
+#define ASN1_EXP_EX(stname, field, type, tag, ex) \
+ ASN1_EX_TYPE(ASN1_TFLG_EXPLICIT | ex, tag, stname, field, type)
+
+/* Plain simple type */
+#define ASN1_SIMPLE(stname, field, type) ASN1_EX_TYPE(0,0, stname, field, type)
+
+/* OPTIONAL simple type */
+#define ASN1_OPT(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_OPTIONAL, 0, stname, field, type)
+
+/* IMPLICIT tagged simple type */
+#define ASN1_IMP(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, 0)
+
+/* IMPLICIT tagged OPTIONAL simple type */
+#define ASN1_IMP_OPT(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL)
+
+/* Same as above but EXPLICIT */
+
+#define ASN1_EXP(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, 0)
+#define ASN1_EXP_OPT(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL)
+
+/* SEQUENCE OF type */
+#define ASN1_SEQUENCE_OF(stname, field, type) \
+ ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, stname, field, type)
+
+/* OPTIONAL SEQUENCE OF */
+#define ASN1_SEQUENCE_OF_OPT(stname, field, type) \
+ ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type)
+
+/* Same as above but for SET OF */
+
+#define ASN1_SET_OF(stname, field, type) \
+ ASN1_EX_TYPE(ASN1_TFLG_SET_OF, 0, stname, field, type)
+
+#define ASN1_SET_OF_OPT(stname, field, type) \
+ ASN1_EX_TYPE(ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type)
+
+/* Finally compound types of SEQUENCE, SET, IMPLICIT, EXPLICIT and OPTIONAL */
+
+#define ASN1_IMP_SET_OF(stname, field, type, tag) \
+ ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF)
+
+#define ASN1_EXP_SET_OF(stname, field, type, tag) \
+ ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF)
+
+#define ASN1_IMP_SET_OF_OPT(stname, field, type, tag) \
+ ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL)
+
+#define ASN1_EXP_SET_OF_OPT(stname, field, type, tag) \
+ ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL)
+
+#define ASN1_IMP_SEQUENCE_OF(stname, field, type, tag) \
+ ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF)
+
+#define ASN1_IMP_SEQUENCE_OF_OPT(stname, field, type, tag) \
+ ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL)
+
+#define ASN1_EXP_SEQUENCE_OF(stname, field, type, tag) \
+ ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF)
+
+#define ASN1_EXP_SEQUENCE_OF_OPT(stname, field, type, tag) \
+ ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL)
+
+/* This is the ASN1 template structure that defines
+ * a wrapper round the actual type. It determines the
+ * actual position of the field in the value structure,
+ * various flags such as OPTIONAL and the field name.
+ */
+
+struct ASN1_TEMPLATE_st {
+unsigned long flags; /* Various flags */
+long tag; /* tag, not used if no tagging */
+unsigned long offset; /* Offset of this field in structure */
+#ifndef NO_ASN1_FIELD_NAMES
+char *field_name; /* Field name */
+#endif
+const void *item; /* Relevant ASN1_ITEM or ASN1_ADB */
+};
+
+
+typedef struct ASN1_ADB_TABLE_st ASN1_ADB_TABLE;
+typedef struct ASN1_ADB_st ASN1_ADB;
+
+struct ASN1_ADB_st {
+ unsigned long flags; /* Various flags */
+ unsigned long offset; /* Offset of selector field */
+ STACK_OF(ASN1_ADB_TABLE) **app_items; /* Application defined items */
+ const ASN1_ADB_TABLE *tbl; /* Table of possible types */
+ long tblcount; /* Number of entries in tbl */
+ const ASN1_TEMPLATE *default_tt; /* Type to use if no match */
+ const ASN1_TEMPLATE *null_tt; /* Type to use if selector is NULL */
+};
+
+struct ASN1_ADB_TABLE_st {
+ long value; /* NID for an object or value for an int */
+ const ASN1_TEMPLATE *tt; /* item for this value */
+};
+
+/* template flags */
+
+/* Field is optional */
+#define ASN1_TFLG_OPTIONAL (0x1)
+
+/* Field is a SET OF */
+#define ASN1_TFLG_SET_OF (0x1 << 1)
+
+/* Field is a SEQUENCE OF */
+#define ASN1_TFLG_SEQUENCE_OF (0x2 << 1)
+
+#define ASN1_TFLG_SK_MASK (0x3 << 1)
+
+/* These flags mean the tag should be taken from the
+ * tag field. If EXPLICIT then the underlying type
+ * is used for the inner tag.
+ */
+
+/* IMPLICIT tagging */
+#define ASN1_TFLG_IMPTAG (0x1 << 3)
+
+
+/* EXPLICIT tagging, inner tag from underlying type */
+#define ASN1_TFLG_EXPTAG (0x2 << 3)
+
+#define ASN1_TFLG_TAG_MASK (0x3 << 3)
+
+/* context specific IMPLICIT */
+#define ASN1_TFLG_IMPLICIT ASN1_TFLG_IMPTAG|ASN1_TFLG_CONTEXT
+
+/* context specific EXPLICIT */
+#define ASN1_TFLG_EXPLICIT ASN1_TFLG_EXPTAG|ASN1_TFLG_CONTEXT
+
+/* If tagging is in force these determine the
+ * type of tag to use. Otherwise the tag is
+ * determined by the underlying type. These
+ * values reflect the actual octet format.
+ */
+
+/* Universal tag */
+#define ASN1_TFLG_UNIVERSAL (0x0<<6)
+/* Application tag */
+#define ASN1_TFLG_APPLICATION (0x1<<6)
+/* Context specific tag */
+#define ASN1_TFLG_CONTEXT (0x2<<6)
+/* Private tag */
+#define ASN1_TFLG_PRIVATE (0x3<<6)
+
+#define ASN1_TFLG_TAG_CLASS (0x3<<6)
+
+/* These are for ANY DEFINED BY type. In this case
+ * the 'item' field points to an ASN1_ADB structure
+ * which contains a table of values to decode the
+ * relevant type
+ */
+
+#define ASN1_TFLG_ADB_MASK (0x3<<8)
+
+#define ASN1_TFLG_ADB_OID (0x1<<8)
+
+#define ASN1_TFLG_ADB_INT (0x1<<9)
+
+
+/* This is the actual ASN1 item itself */
+
+struct ASN1_ITEM_st {
+char itype; /* The item type, primitive, SEQUENCE, CHOICE or extern */
+long utype; /* underlying type */
+const ASN1_TEMPLATE *templates; /* If SEQUENCE or CHOICE this contains the contents */
+long tcount; /* Number of templates if SEQUENCE or CHOICE */
+const void *funcs; /* functions that handle this type */
+long size; /* Structure size (usually)*/
+#ifndef NO_ASN1_FIELD_NAMES
+const char *sname; /* Structure name */
+#endif
+};
+
+/* These are values for the itype field and
+ * determine how the type is interpreted.
+ *
+ * For PRIMITIVE types the underlying type
+ * determines the behaviour if items is NULL.
+ *
+ * Otherwise templates must contain a single
+ * template and the type is treated in the
+ * same way as the type specified in the template.
+ *
+ * For SEQUENCE types the templates field points
+ * to the members, the size field is the
+ * structure size.
+ *
+ * For CHOICE types the templates field points
+ * to each possible member (typically a union)
+ * and the 'size' field is the offset of the
+ * selector.
+ *
+ * The 'funcs' field is used for application
+ * specific functions.
+ *
+ * For COMPAT types the funcs field gives a
+ * set of functions that handle this type, this
+ * supports the old d2i, i2d convention.
+ *
+ * The EXTERN type uses a new style d2i/i2d.
+ * The new style should be used where possible
+ * because it avoids things like the d2i IMPLICIT
+ * hack.
+ *
+ * MSTRING is a multiple string type, it is used
+ * for a CHOICE of character strings where the
+ * actual strings all occupy an ASN1_STRING
+ * structure. In this case the 'utype' field
+ * has a special meaning, it is used as a mask
+ * of acceptable types using the B_ASN1 constants.
+ *
+ */
+
+#define ASN1_ITYPE_PRIMITIVE 0x0
+
+#define ASN1_ITYPE_SEQUENCE 0x1
+
+#define ASN1_ITYPE_CHOICE 0x2
+
+#define ASN1_ITYPE_COMPAT 0x3
+
+#define ASN1_ITYPE_EXTERN 0x4
+
+#define ASN1_ITYPE_MSTRING 0x5
+
+/* Cache for ASN1 tag and length, so we
+ * don't keep re-reading it for things
+ * like CHOICE
+ */
+
+struct ASN1_TLC_st{
+ char valid; /* Values below are valid */
+ int ret; /* return value */
+ long plen; /* length */
+ int ptag; /* class value */
+ int pclass; /* class value */
+ int hdrlen; /* header length */
+};
+
+/* Typedefs for ASN1 functions */
+
+typedef ASN1_VALUE * ASN1_new_func(void);
+typedef void ASN1_free_func(ASN1_VALUE *a);
+typedef ASN1_VALUE * ASN1_d2i_func(ASN1_VALUE **a, unsigned char ** in, long length);
+typedef int ASN1_i2d_func(ASN1_VALUE * a, unsigned char **in);
+
+typedef int ASN1_ex_d2i(ASN1_VALUE **val, unsigned char **in, long len, const ASN1_ITEM *it,
+ int tag, int aclass, char opt, ASN1_TLC *ctx);
+
+typedef int ASN1_ex_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass);
+typedef int ASN1_ex_new_func(ASN1_VALUE **val, const ASN1_ITEM *it);
+typedef void ASN1_ex_free_func(ASN1_VALUE *val, const ASN1_ITEM *it);
+
+typedef struct ASN1_COMPAT_FUNCS_st {
+ ASN1_new_func *asn1_new;
+ ASN1_free_func *asn1_free;
+ ASN1_d2i_func *asn1_d2i;
+ ASN1_i2d_func *asn1_i2d;
+} ASN1_COMPAT_FUNCS;
+
+typedef struct ASN1_EXTERN_FUNCS_st {
+ void *app_data;
+ ASN1_ex_new_func *asn1_ex_new;
+ ASN1_ex_free_func *asn1_ex_free;
+ ASN1_ex_d2i *asn1_ex_d2i;
+ ASN1_ex_i2d *asn1_ex_i2d;
+} ASN1_EXTERN_FUNCS;
+
+/* Macro to implement an ASN1_ITEM in terms of old style funcs */
+
+#define IMPLEMENT_COMPAT_ASN1(sname) IMPLEMENT_COMPAT_ASN1_type(sname, V_ASN1_SEQUENCE)
+
+#define IMPLEMENT_COMPAT_ASN1_type(sname, type) \
+ static const ASN1_COMPAT_FUNCS sname##_ff = { \
+ (ASN1_new_func *)sname##_new, \
+ (ASN1_free_func *)sname##_free, \
+ (ASN1_d2i_func *)d2i_##sname, \
+ (ASN1_i2d_func *)i2d_##sname, \
+ }; \
+ ASN1_ITEM const sname##_it = { \
+ ASN1_ITYPE_COMPAT, \
+ type, \
+ NULL, \
+ 0, \
+ &sname##_ff, \
+ 0, \
+ #sname \
+ }
+
+/* Macro to implement standard functions in terms of ASN1_ITEM structures */
+
+#define IMPLEMENT_ASN1(type) \
+ (type *) type##_new(void) \
+ { \
+ return ASN1_item_new(&type##_it); \
+ } \
+ void type##_free(type *a) \
+ { \
+ return ASN1_item_free(a, &type##_it); \
+ }
+
+/* external definitions for primitive types */
+
+extern const ASN1_ITEM ASN1_BOOLEAN_it;
+extern const ASN1_ITEM ASN1_INTEGER_it;
+extern const ASN1_ITEM ASN1_BIT_STRING_it;
+extern const ASN1_ITEM ASN1_OCTET_STRING_it;
+extern const ASN1_ITEM ASN1_NULL_it;
+extern const ASN1_ITEM ASN1_OBJECT_it;
+extern const ASN1_ITEM ASN1_ENUMERATED_it;
+extern const ASN1_ITEM ASN1_UTF8STRING_it;
+extern const ASN1_ITEM ASN1_PRINTABLESTRING_it;
+extern const ASN1_ITEM ASN1_T61STRING_it;
+extern const ASN1_ITEM ASN1_IA5STRING_it;
+extern const ASN1_ITEM ASN1_UTCTIME_it;
+extern const ASN1_ITEM ASN1_GENERALIZEDTIME_it;
+extern const ASN1_ITEM ASN1_VISIBLESTRING_it;
+extern const ASN1_ITEM ASN1_UNIVERSALSTRING_it;
+extern const ASN1_ITEM ASN1_BMPSTRING_it;
+extern const ASN1_ITEM ASN1_ANY_it;
+
+#if 0
+
+int ASN1_item_new(void *arg, const ASN1_ITEM *it);
+int ASN1_template_new(void *arg, const ASN1_TEMPLATE *tt);
+void *ASN1_primitive_new(long utype);
+
+void ASN1_item_free(void *field, const ASN1_ITEM *it);
+void ASN1_template_free(void *arg, const ASN1_TEMPLATE *tt);
+
+int ASN1_item_d2i(void *dptr, unsigned char **in, long len, const ASN1_ITEM *it);
+int ASN1_template_d2i(void *dptr, unsigned char **in, long len, const ASN1_TEMPLATE *tt);
+int ASN1_item_ex_d2i(void *dptr, unsigned char **in, long len, const ASN1_ITEM *it,
+ int tag, int aclass, char opt, ASN1_TLC *ctx);
+
+int ASN1_item_i2d(void *data, unsigned char **out, const ASN1_ITEM *it);
+int ASN1_item_ex_i2d(void *data, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass);
+int ASN1_template_i2d(void *data, unsigned char **out, const ASN1_TEMPLATE *tt);
+void ASN1_primitive_free(void *type, long utype);
+
+int asn1_get_choice_selector(void *data, const ASN1_ITEM *it);
+int asn1_set_choice_selector(void **data, int value, const ASN1_ITEM *it);
+void *asn1_get_field(void *data, const ASN1_TEMPLATE *tt);
+void *asn1_get_field_ptr(void **data, const ASN1_TEMPLATE *tt);
+const ASN1_TEMPLATE *asn1_do_adb(void *data, const ASN1_TEMPLATE *tt);
+int asn1_template_is_bool(const ASN1_TEMPLATE *tt);
+int asn1_item_is_bool(const ASN1_ITEM *it);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/crypto/asn1/tasn_dec.c b/crypto/asn1/tasn_dec.c
new file mode 100644
index 000000000..260fc7b54
--- /dev/null
+++ b/crypto/asn1/tasn_dec.c
@@ -0,0 +1,810 @@
+/* tasn_dec.c */
+/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+#include <stddef.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/objects.h>
+#include <openssl/buffer.h>
+#include <openssl/err.h>
+
+static int asn1_check_eoc(unsigned char **in, long len);
+static int asn1_collect(BUF_MEM *buf, unsigned char **in, long len, char inf, int tag);
+static int collect_data(BUF_MEM *buf, unsigned char **p, long plen);
+static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, char *inf, char *cst,
+ unsigned char **in, long len, int exptag, int expclass, char opt, ASN1_TLC *ctx);
+static int asn1_template_ex_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx);
+static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, unsigned char **in, long len,
+ int utype, int tag, int aclass, char opt, ASN1_TLC *ctx);
+
+/* Macro to initialize and invalidate the cache */
+
+#define asn1_tlc_clear(c) if(c) (c)->valid = 0
+
+/* Decode an ASN1 item, this currently behaves just
+ * like a standard 'd2i' function. 'in' points to
+ * a buffer to read the data from, in future we will
+ * have more advanced versions that can input data
+ * a piece at a time and this will simply be a special
+ * case.
+ */
+
+ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1_ITEM *it)
+{
+ ASN1_TLC c;
+ ASN1_VALUE *ptmpval = NULL;
+ if(!pval) pval = &ptmpval;
+ asn1_tlc_clear(&c);
+ if(ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0)
+ return *pval;
+ return NULL;
+}
+
+int ASN1_template_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1_TEMPLATE *tt)
+{
+ ASN1_TLC c;
+ asn1_tlc_clear(&c);
+ return asn1_template_ex_d2i(pval, in, len, tt, 0, &c);
+}
+
+
+/* Decode an item, taking care of IMPLICIT tagging, if any.
+ * If 'opt' set and tag mismatch return -1 to handle OPTIONAL
+ */
+
+int ASN1_item_ex_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1_ITEM *it,
+ int tag, int aclass, char opt, ASN1_TLC *ctx)
+{
+ const ASN1_TEMPLATE *tt;
+ const ASN1_COMPAT_FUNCS *cf;
+ const ASN1_EXTERN_FUNCS *ef;
+ unsigned char *p, *q, imphack = 0, oclass;
+ char seq_eoc, cst, isopt;
+ int i;
+ int otag;
+ int ret = 0;
+ ASN1_VALUE *pchval, **pchptr, *ptmpval;
+ if(!pval) return 0;
+
+ tt = NULL;
+
+ switch(it->itype) {
+
+ case ASN1_ITYPE_PRIMITIVE:
+ if(it->templates)
+ return asn1_template_ex_d2i(pval, in, len, it->templates, opt, ctx);
+ return asn1_d2i_ex_primitive(pval, in, len, it->utype, tag, aclass, opt, ctx);
+ break;
+
+ case ASN1_ITYPE_MSTRING:
+ p = *in;
+ /* Just read in tag and class */
+ ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL, &p, len, -1, 0, 1, ctx);
+ if(!ret) {
+ ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
+ goto err;
+ }
+ /* Must be UNIVERSAL class */
+ if(oclass != V_ASN1_UNIVERSAL) {
+ /* If OPTIONAL, assume this is OK */
+ if(opt) return -1;
+ ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MSTRING_NOT_UNIVERSAL);
+ goto err;
+ }
+ /* Check tag matches bit map */
+ if(ASN1_tag2bit(otag) & it->utype) {
+ /* If OPTIONAL, assume this is OK */
+ if(opt) return -1;
+ ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MSTRING_WRONG_TAG);
+ goto err;
+ }
+ return asn1_d2i_ex_primitive(pval, in, len, otag, -1, 0, 1, ctx);
+
+ case ASN1_ITYPE_EXTERN:
+ /* Use new style d2i */
+ ef = it->funcs;
+ return ef->asn1_ex_d2i(pval, in, len, it, tag, aclass, opt, ctx);
+
+ case ASN1_ITYPE_COMPAT:
+ /* we must resort to old style evil hackery */
+ cf = it->funcs;
+
+ /* If OPTIONAL see if it is there */
+ if(opt) {
+ int exptag;
+ p = *in;
+ if(tag == -1) exptag = it->utype;
+ else exptag = tag;
+ /* Don't care about anything other than presence of expected tag */
+ ret = asn1_check_tlen(NULL, NULL, NULL, NULL, NULL, &p, len, exptag, aclass, 1, ctx);
+ if(!ret) {
+ ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
+ goto err;
+ }
+ if(ret == -1) return -1;
+ }
+ /* This is the old style evil hack IMPLICIT handling:
+ * since the underlying code is expecting a tag and
+ * class other than the one present we change the
+ * buffer temporarily then change it back afterwards.
+ * This doesn't and never did work for tags > 30.
+ *
+ * Yes this is *horrible* but it is only needed for
+ * old style d2i which will hopefully not be around
+ * for much longer.
+ * FIXME: should copy the buffer then modify it so
+ * the input buffer can be const: we should *always*
+ * copy because the old style d2i might modify the
+ * buffer.
+ */
+
+ if(tag != -1) {
+ p = *in;
+ imphack = *p;
+ *p = (*p & V_ASN1_CONSTRUCTED) | it->utype;
+ }
+
+ ptmpval = cf->asn1_d2i(pval, in, len);
+
+ if(tag != -1) *p = imphack;
+
+ if(ptmpval) return 1;
+ ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
+ goto err;
+
+
+ case ASN1_ITYPE_CHOICE:
+ /* CHOICE type, try each possibility in turn */
+ pchval = NULL;
+ p = *in;
+ for(i = 0, tt=it->templates; i < it->tcount; i++, tt++) {
+ /* We mark field as OPTIONAL so its absence
+ * can be recognised.
+ */
+ ret = asn1_template_ex_d2i(&pchval, &p, len, tt, 1, ctx);
+ /* If field not present, try the next one */
+ if(ret == -1) continue;
+ /* If positive return, read OK, break loop */
+ if(ret > 0) break;
+ /* Otherwise must be an ASN1 parsing error */
+ ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
+ /* FIXME: note choice type that did this */
+ return 0;
+ }
+ /* Did we fall off the end without reading anything? */
+ if(i == it->tcount) {
+ /* If OPTIONAL, this is OK */
+ if(opt) return -1;
+ ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_NO_MATCHING_CHOICE_TYPE);
+ return 0;
+ }
+ /* Otherwise we got a match, allocate structure and populate it */
+ if(!*pval) {
+ if(!ASN1_item_ex_new(pval, it)) {
+ ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
+ return 0;
+ }
+ }
+ pchptr = asn1_get_field_ptr(pval, tt);
+ *pchptr = pchval;
+ asn1_set_choice_selector(pval, i, it);
+ *in = p;
+ return 1;
+
+ case ASN1_ITYPE_SEQUENCE:
+ p = *in;
+ /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
+ if(tag == -1) {
+ tag = V_ASN1_SEQUENCE;
+ aclass = V_ASN1_UNIVERSAL;
+ }
+ /* Get SEQUENCE length and update len, p */
+ ret = asn1_check_tlen(&len, NULL, NULL, &seq_eoc, &cst, &p, len, tag, aclass, opt, ctx);
+ if(!ret) {
+ ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
+ goto err;
+ } else if(ret == -1) return -1;
+ if(!cst) {
+ ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_SEQUENCE_NOT_CONSTRUCTED);
+ goto err;
+ }
+
+ if(!*pval) {
+ if(!ASN1_item_ex_new(pval, it)) {
+ ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
+ goto err;
+ }
+ }
+
+ /* Get each field entry */
+ for(i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
+ const ASN1_TEMPLATE *seqtt;
+ ASN1_VALUE **pseqval;
+ seqtt = asn1_do_adb(*pval, tt);
+ pseqval = asn1_get_field_ptr(pval, seqtt);
+ /* Have we ran out of data? */
+ if(!len) break;
+ q = p;
+ if(asn1_check_eoc(&p, len)) {
+ if(!seq_eoc) {
+ ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_UNEXPECTED_EOC);
+ goto err;
+ }
+ len -= p - q;
+ seq_eoc = 0;
+ q = p;
+ break;
+ }
+ /* This determines the OPTIONAL flag value. The field cannot
+ * be omitted if it is the last of a SEQUENCE and there is
+ * still data to be read. This isn't strictly necessary but
+ * it increases efficiency in some cases.
+ */
+ isopt = (i == (it->tcount - 1)) ? 0 : seqtt->flags & ASN1_TFLG_OPTIONAL;
+ /* attempt to read in field, allowing each to be OPTIONAL */
+ ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, ctx);
+ if(!ret) {
+ /* Add error field info */
+ goto err;
+ } else if(ret == -1) {
+ /* OPTIONAL component absent.
+ * Since this is the only place we take any notice of
+ * OPTIONAL this is the only place we need to handle freeing
+ * and zeroing the field.
+ * BOOLEAN is a special case as always and must be set to -1.
+ */
+ if(asn1_template_is_bool(seqtt))
+ *(int *)pseqval = -1;
+ else if(*pseqval) {
+ ASN1_template_free(*pseqval, seqtt);
+ *pseqval = NULL;
+ }
+ continue;
+ }
+ /* Update length */
+ len -= p - q;
+ }
+ /* Check for EOC if expecting one */
+ if(seq_eoc) {
+ ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MISSING_EOC);
+ goto err;
+ }
+ /* Check all data read */
+ if(len) {
+ ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_SEQUENCE_LENGTH_MISMATCH);
+ goto err;
+ }
+
+ /* If we get here we've got no more data in the SEQUENCE,
+ * however we may not have read all fields so check all
+ * remaining are OPTIONAL.
+ */
+ for(; i < it->tcount; tt++, i++) {
+ const ASN1_TEMPLATE *seqtt;
+ seqtt = asn1_do_adb(*pval, tt);
+ if(!(tt->flags & ASN1_TFLG_OPTIONAL)) {
+ ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_FIELD_MISSING);
+ goto err;
+ }
+ }
+
+ *in = p;
+ return 1;
+
+ default:
+ return 0;
+ }
+ err:
+ ASN1_item_free(*pval, it);
+ *pval = NULL;
+ if(tt) ERR_add_error_data(4, "Field=", tt->field_name, ", Structure=", it->sname);
+ else ERR_add_error_data(2, "Structure=", it->sname);
+ return 0;
+}
+
+int asn1_template_ex_d2i(ASN1_VALUE **val, unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx)
+{
+ int flags, aclass;
+ int ret;
+ unsigned char *p, *q;
+ char exp_eoc;
+ if(!val) return 0;
+ flags = tt->flags;
+ aclass = flags & ASN1_TFLG_TAG_CLASS;
+
+ p = *in;
+ q = p;
+
+ /* If explicit tag expected then swallow it */
+ if(flags & ASN1_TFLG_EXPTAG) {
+ char cst;
+ /* This updates 'len' to the amount of data inside the EXPLICIT tag:
+ * this is what is available to the rest of the structure. If INDEF then this
+ * just subtracts the header length, leaving us enough room for the
+ * data and the expected EOC.
+ */
+ /* FIXME: this doesn't get things right if it and the enclosed stuff is NDEF.
+ * also we need to avoid trailing garbage before the end of the tag
+ */
+ ret = asn1_check_tlen(&len, NULL, NULL, &exp_eoc, &cst, &p, len, tt->tag, aclass, opt, ctx);
+ if(!ret) {
+ ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
+ return 0;
+ } else if(ret == -1) return -1;
+ if(!cst) {
+ ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED);
+ return 0;
+ }
+ /* We've found the field so it can't be OPTIONAL now */
+ opt = 0;
+ } else exp_eoc = 0;
+
+ if(flags & ASN1_TFLG_SK_MASK) {
+ /* SET OF, SEQUENCE OF */
+ int sktag, skaclass;
+ char sk_eoc;
+ /* First work out expected inner tag value */
+ if(flags & ASN1_TFLG_IMPTAG) {
+ sktag = tt->tag;
+ skaclass = aclass;
+ } else {
+ skaclass = V_ASN1_UNIVERSAL;
+ if(flags & ASN1_TFLG_SET_OF) sktag = V_ASN1_SET;
+ else sktag = V_ASN1_SEQUENCE;
+ }
+ /* Get the tag */
+ ret = asn1_check_tlen(&len, NULL, NULL, &sk_eoc, NULL, &p, len, sktag, skaclass, opt, ctx);
+ if(!ret) {
+ ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
+ return 0;
+ } else if(ret == -1) return -1;
+ if(!(*val = (ASN1_VALUE *)sk_new_null())) {
+ ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ /* Read as many items as we can */
+ while(len > 0) {
+ ASN1_VALUE *skfield;
+ /* See if EOC found */
+ q = p;
+ if(asn1_check_eoc(&p, len)) {
+ if(!sk_eoc) {
+ ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ASN1_R_UNEXPECTED_EOC);
+ goto err;
+ }
+ len -= p - q;
+ sk_eoc = 0;
+ break;
+ }
+ skfield = NULL;
+ if(!ASN1_item_ex_d2i(&skfield, &p, len, tt->item, -1, 0, 0, ctx)) {
+ ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ERR_R_NESTED_ASN1_ERROR);
+ goto err;
+ }
+ len -= p - q;
+ if(!sk_push((STACK *)*val, (char *)skfield)) {
+ ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+ if(sk_eoc) {
+ ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ASN1_R_MISSING_EOC);
+ goto err;
+ }
+ } else if(flags & ASN1_TFLG_IMPTAG) {
+ /* IMPLICIT tagging */
+ ret = ASN1_item_ex_d2i(val, &p, len, tt->item, tt->tag, aclass, opt, ctx);
+ if(!ret) {
+ ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ERR_R_NESTED_ASN1_ERROR);
+ goto err;
+ } else if(ret == -1) return -1;
+ } else {
+ /* Nothing special */
+ ret = ASN1_item_ex_d2i(val, &p, len, tt->item, -1, 0, opt, ctx);
+ if(!ret) {
+ ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ERR_R_NESTED_ASN1_ERROR);
+ goto err;
+ } else if(ret == -1) return -1;
+ }
+
+ if(exp_eoc && !asn1_check_eoc(&p, len)) {
+ ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ASN1_R_MISSING_EOC);
+ goto err;
+ }
+
+ *in = p;
+ return 1;
+
+ err:
+ ASN1_template_free(*val, tt);
+ *val = NULL;
+ return 0;
+}
+
+static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, unsigned char **in, long inlen, int utype,
+ int tag, int aclass, char opt, ASN1_TLC *ctx)
+{
+ int ret = 0;
+ long plen;
+ char cst, inf;
+ unsigned char *p;
+ BUF_MEM buf;
+ unsigned char *cont = NULL;
+ ASN1_STRING *stmp;
+ int *tbool;
+ long len;
+ if(!*pval) {
+ ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_NULL);
+ return 0; /* Should never happen */
+ }
+ if(utype == V_ASN1_ANY) {
+ int otag;
+ unsigned char oclass;
+ ASN1_TYPE *ttmp;
+ ASN1_VALUE *anytype;
+ if(tag >= 0) {
+ ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_TAGGED_ANY);
+ return 0;
+ }
+ p = *in;
+ ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL, &p, inlen, -1, 0, 0, ctx);
+ if(!ret) {
+ ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR);
+ return 0;
+ }
+ if(oclass != V_ASN1_UNIVERSAL) otag = V_ASN1_UNDEF;
+ anytype = NULL;
+ ret = asn1_d2i_ex_primitive(&anytype, in, inlen, otag, -1, 0, 0, ctx);
+ if(!ret) {
+ ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR);
+ return 0;
+ }
+ if(*pval) ASN1_TYPE_free((ASN1_TYPE *)*pval);
+ ttmp = ASN1_TYPE_new();
+ *pval = (ASN1_VALUE *)ttmp;
+ if(!ttmp) {
+ ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ if(otag != V_ASN1_NULL) ttmp->value.ptr = (char *)anytype;
+ ttmp->type = otag;
+ return 1;
+
+ }
+ if(tag == -1) {
+ tag = utype;
+ aclass = V_ASN1_UNIVERSAL;
+ }
+ p = *in;
+ /* Check header */
+ ret = asn1_check_tlen(&plen, NULL, NULL, &inf, &cst, &p, inlen, tag, aclass, opt, ctx);
+ if(!ret) {
+ ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR);
+ return 0;
+ } else if(ret == -1) return -1;
+ /* SEQUENCE and SET must be constructed */
+ if((utype == V_ASN1_SEQUENCE) || (utype == V_ASN1_SET)) {
+ if(!cst) {
+ ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_TYPE_NOT_CONSTRUCTED);
+ return 0;
+ }
+ /* FIXME: if it is indefinite length constructed need to work out
+ * actual length.
+ */
+ len = inlen;
+ } else if(cst) {
+ buf.length = 0;
+ buf.max = 0;
+ buf.data = NULL;
+ asn1_collect(&buf, &p, plen, inf, -1);
+ cont = (unsigned char *)buf.data;
+ len = buf.length;
+ } else {
+ cont = p;
+ len = plen;
+ p += plen;
+ }
+
+ switch(utype) {
+ case V_ASN1_OBJECT:
+ if(!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len)) goto err;
+ break;
+
+ case V_ASN1_NULL:
+ if(plen) {
+ ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_NULL_IS_WRONG_LENGTH);
+ goto err;
+ }
+ *pval = (ASN1_VALUE *)ASN1_NULL_new();
+ break;
+
+ case V_ASN1_BOOLEAN:
+ if(plen != 1) {
+ ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_BOOLEAN_IS_WRONG_LENGTH);
+ goto err;
+ }
+ tbool = (int *)pval;
+ *tbool = *cont;
+ break;
+
+ case V_ASN1_BIT_STRING:
+ if(!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len)) goto err;
+ break;
+
+ case V_ASN1_INTEGER:
+ case V_ASN1_NEG_INTEGER:
+ case V_ASN1_ENUMERATED:
+ case V_ASN1_NEG_ENUMERATED:
+ if(!c2i_ASN1_INTEGER((ASN1_INTEGER **)pval, &cont, len)) goto err;
+ break;
+
+ case V_ASN1_OCTET_STRING:
+ case V_ASN1_NUMERICSTRING:
+ case V_ASN1_PRINTABLESTRING:
+ case V_ASN1_T61STRING:
+ case V_ASN1_VIDEOTEXSTRING:
+ case V_ASN1_IA5STRING:
+ case V_ASN1_UTCTIME:
+ case V_ASN1_GENERALIZEDTIME:
+ case V_ASN1_GRAPHICSTRING:
+ case V_ASN1_VISIBLESTRING:
+ case V_ASN1_GENERALSTRING:
+ case V_ASN1_UNIVERSALSTRING:
+ case V_ASN1_BMPSTRING:
+ case V_ASN1_UTF8STRING:
+ /* All based on ASN1_STRING and handled the same */
+ if(!*pval) {
+ stmp = ASN1_STRING_type_new(utype);
+ if(!stmp) {
+ ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ *pval = (ASN1_VALUE *)stmp;
+ } else stmp = (ASN1_STRING *)*pval;
+ /* If we've already allocated a buffer use it */
+ if(cst) {
+ if(stmp->data) OPENSSL_free(stmp->data);
+ stmp->data = cont;
+ stmp->length = len;
+ buf.data = NULL;
+ } else {
+ if(!ASN1_STRING_set(stmp, cont, len)) {
+ ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_MALLOC_FAILURE);
+ ASN1_STRING_free(stmp);
+ *pval = NULL;
+ goto err;
+ }
+ }
+ break;
+
+ /* If SEQUENCE, or SET or we don't understand the type
+ * then just collect its encoded form
+ */
+
+ default:
+ case V_ASN1_SET:
+ case V_ASN1_SEQUENCE:
+ if(!*pval) {
+ stmp = ASN1_STRING_new();
+ if(!stmp) {
+ ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ *pval = (ASN1_VALUE *)stmp;
+ } else stmp = (ASN1_STRING *)*pval;
+ if(!ASN1_STRING_set(stmp, *in, inlen)) {
+ ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_MALLOC_FAILURE);
+ ASN1_STRING_free(stmp);
+ *pval = NULL;
+ goto err;
+ }
+ break;
+
+ }
+
+ *in = p;
+ ret = 1;
+ err:
+ if(cst && buf.data) OPENSSL_free(buf.data);
+ return ret;
+}
+
+/* This function collects the asn1 data from a constructred string
+ * type into a buffer. The values of 'in' and 'len' should refer
+ * to the contents of the constructed type and 'inf' should be set
+ * if it is indefinite length
+ */
+
+static int asn1_collect(BUF_MEM *buf, unsigned char **in, long len, char inf, int tag)
+{
+ unsigned char *p, *q;
+ long plen;
+ char cst;
+ p = *in;
+ inf &= 1;
+ while(len > 0) {
+ q = p;
+ /* Check for EOC */
+ if(asn1_check_eoc(&p, len)) {
+ /* EOC is illegal outside indefinite length constructed form */
+ if(!inf) {
+ ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_UNEXPECTED_EOC);
+ return 0;
+ }
+ inf = 0;
+ goto err;
+ }
+ if(!asn1_check_tlen(&plen, NULL, NULL, &inf, &cst, &p, len, tag, V_ASN1_UNIVERSAL, 0, NULL)) {
+ ASN1err(ASN1_F_ASN1_COLLECT, ERR_R_NESTED_ASN1_ERROR);
+ return 0;
+ }
+ /* If indefinite length constructed update max length */
+ if(cst) {
+ if(!asn1_collect(buf, &p, plen, inf, tag)) return 0;
+ } else {
+ if(!collect_data(buf, &p, plen)) return 0;
+ }
+ len -= p - q;
+ }
+ if(inf) {
+ ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_MISSING_EOC);
+ return 0;
+ }
+ *in = p;
+ return 1;
+ err:
+ return 0;
+}
+
+static int collect_data(BUF_MEM *buf, unsigned char **p, long plen)
+{
+ int len;
+ len = buf->length;
+ if(!BUF_MEM_grow(buf, len + plen)) {
+ ASN1err(ASN1_F_COLLECT_DATA, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ memcpy(buf->data + len, *p, plen);
+ *p += plen;
+ return 1;
+}
+
+/* Check for ASN1 EOC and swallow it if found */
+
+static int asn1_check_eoc(unsigned char **in, long len)
+{
+ unsigned char *p;
+ if(len < 2) return 0;
+ p = *in;
+ if(!p[0] && !p[1]) {
+ *in += 2;
+ return 1;
+ }
+ return 0;
+}
+
+/* Check an ASN1 tag and length: a bit like ASN1_get_object
+ * but it sets the length for indefinite length constructed
+ * form, we don't know the exact length but we can set an
+ * upper bound to the amount of data available minus the
+ * header length just read.
+ */
+
+static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, char *inf, char *cst,
+ unsigned char **in, long len, int exptag, int expclass, char opt, ASN1_TLC *ctx)
+{
+ int i;
+ int ptag, pclass;
+ long plen;
+ unsigned char *p, *q;
+ p = *in;
+ q = p;
+
+ if(ctx && ctx->valid) {
+ i = ctx->ret;
+ plen = ctx->plen;
+ pclass = ctx->pclass;
+ ptag = ctx->ptag;
+ p += ctx->hdrlen;
+ } else {
+ i = ASN1_get_object(&p, &plen, &ptag, &pclass, len);
+ if(ctx) {
+ ctx->ret = i;
+ ctx->plen = plen;
+ ctx->pclass = pclass;
+ ctx->ptag = ptag;
+ ctx->hdrlen = p - q;
+ ctx->valid = 1;
+ }
+ }
+
+ if(i & 0x80) {
+ ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_BAD_OBJECT_HEADER);
+ asn1_tlc_clear(ctx);
+ return 0;
+ }
+ if(exptag >= 0) {
+ if((exptag != ptag) || (expclass != pclass)) {
+ /* If type is OPTIONAL, not an error, but indicate missing
+ * type.
+ */
+ if(opt) return -1;
+ asn1_tlc_clear(ctx);
+ ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_WRONG_TAG);
+ return 0;
+ }
+ /* We have a tag and class match, so assume we are going to do something with it */
+ asn1_tlc_clear(ctx);
+ }
+ if(i & 1) plen = len - (p - q);
+
+ if(inf) *inf = i & 1;
+
+ if(cst) *cst = i & V_ASN1_CONSTRUCTED;
+
+ if(olen) *olen = plen;
+ if(oclass) *oclass = pclass;
+ if(otag) *otag = ptag;
+
+ *in = p;
+ return 1;
+}
+
+
+
diff --git a/crypto/asn1/tasn_enc.c b/crypto/asn1/tasn_enc.c
new file mode 100644
index 000000000..81f35db97
--- /dev/null
+++ b/crypto/asn1/tasn_enc.c
@@ -0,0 +1,415 @@
+/* tasn_enc.c */
+/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+#include <stddef.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/objects.h>
+
+static int asn1_i2d_ex_primitive(ASN1_VALUE *val, unsigned char **out, int utype, int tag, int aclass);
+static int asn1_set_seq_out(STACK *seq, unsigned char **out, int skcontlen, const ASN1_ITEM *item, int isset);
+
+/* Encode an ASN1 item, this currently behaves just
+ * like a standard 'i2d' function. 'out' points to
+ * a buffer to output the data to, in future we will
+ * have more advanced versions that can output data
+ * a piece at a time and this will simply be a special
+ * case.
+ */
+
+
+int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it)
+{
+ return ASN1_item_ex_i2d(val, out, it, -1, 0);
+}
+
+/* Encode an item, taking care of IMPLICIT tagging (if any).
+ * This function performs the normal item handling: it can be
+ * used in external types.
+ */
+
+int ASN1_item_ex_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass)
+{
+ const ASN1_TEMPLATE *tt = NULL;
+ unsigned char *p = NULL;
+ int i, seqcontlen, seqlen;
+ ASN1_STRING *strtmp;
+ const ASN1_COMPAT_FUNCS *cf;
+ const ASN1_EXTERN_FUNCS *ef;
+ if(!val) return 0;
+
+ switch(it->itype) {
+
+ case ASN1_ITYPE_PRIMITIVE:
+ if(it->templates)
+ return ASN1_template_i2d(val, out, it->templates);
+ return asn1_i2d_ex_primitive(val, out, it->utype, tag, aclass);
+ break;
+
+ case ASN1_ITYPE_MSTRING:
+ strtmp = (ASN1_STRING *)val;
+ return asn1_i2d_ex_primitive(val, out, strtmp->type, tag, aclass);
+
+ case ASN1_ITYPE_CHOICE:
+ i = asn1_get_choice_selector(val, it);
+ if((i >= 0) && (i < it->tcount)) {
+ ASN1_VALUE *chval;
+ const ASN1_TEMPLATE *chtt;
+ chtt = it->templates + i;
+ chval = asn1_get_field(val, chtt);
+ return ASN1_template_i2d(chval, out, chtt);
+ }
+ /* Fixme: error condition if selector out of range */
+ break;
+
+ case ASN1_ITYPE_EXTERN:
+ /* If new style i2d it does all the work */
+ ef = it->funcs;
+ return ef->asn1_ex_i2d(val, out, it, tag, aclass);
+
+ case ASN1_ITYPE_COMPAT:
+ /* old style hackery... */
+ cf = it->funcs;
+ if(out) p = *out;
+ i = cf->asn1_i2d(val, out);
+ /* Fixup for IMPLICIT tag: note this messes up for tags > 30,
+ * but so did the old code. Tags > 30 are very rare anyway.
+ */
+ if(out && (tag != -1))
+ *p = aclass | tag | (*p & V_ASN1_CONSTRUCTED);
+ return i;
+
+ case ASN1_ITYPE_SEQUENCE:
+ seqcontlen = 0;
+ /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
+ if(tag == -1) {
+ tag = V_ASN1_SEQUENCE;
+ aclass = V_ASN1_UNIVERSAL;
+ }
+ /* First work out sequence content length */
+ for(i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
+ const ASN1_TEMPLATE *seqtt;
+ ASN1_VALUE *seqval;
+ seqtt = asn1_do_adb(val, tt);
+ if(!seqtt) return 0;
+ seqval = asn1_get_field(val, seqtt);
+ /* FIXME: check for errors in enhanced version */
+ /* FIXME: special handling of indefinite length encoding */
+ seqcontlen += ASN1_template_i2d(seqval, NULL, seqtt);
+ }
+ seqlen = ASN1_object_size(1, seqcontlen, tag);
+ if(!out) return seqlen;
+ /* Output SEQUENCE header */
+ ASN1_put_object(out, 1, seqcontlen, tag, aclass);
+ for(i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
+ const ASN1_TEMPLATE *seqtt;
+ ASN1_VALUE *seqval;
+ seqtt = asn1_do_adb(val, tt);
+ if(!seqtt) return 0;
+ seqval = asn1_get_field(val, seqtt);
+ /* FIXME: check for errors in enhanced version */
+ ASN1_template_i2d(seqval, out, seqtt);
+ }
+ return seqlen;
+
+ default:
+ return 0;
+ }
+ return 0;
+}
+
+int ASN1_template_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_TEMPLATE *tt)
+{
+ int i, ret, flags, aclass;
+ if(!val) return 0;
+ flags = tt->flags;
+ aclass = flags & ASN1_TFLG_TAG_CLASS;
+ if(flags & ASN1_TFLG_SK_MASK) {
+ /* SET OF, SEQUENCE OF */
+ STACK *sk = (STACK *)val;
+ int isset, sktag, skaclass;
+ int skcontlen, sklen;
+ ASN1_VALUE *skitem;
+ isset = flags & ASN1_TFLG_SET_OF;
+ /* First work out inner tag value */
+ if(flags & ASN1_TFLG_IMPTAG) {
+ sktag = tt->tag;
+ skaclass = aclass;
+ } else {
+ skaclass = V_ASN1_UNIVERSAL;
+ if(isset) sktag = V_ASN1_SET;
+ else sktag = V_ASN1_SEQUENCE;
+ }
+ /* Now work out length of items */
+ skcontlen = 0;
+ for(i = 0; i < sk_num(sk); i++) {
+ skitem = (ASN1_VALUE *)sk_value(sk, i);
+ skcontlen += ASN1_item_ex_i2d(skitem, NULL, tt->item, -1, 0);
+ }
+ sklen = ASN1_object_size(1, skcontlen, sktag);
+ /* If EXPLICIT need length of surrounding tag */
+ if(flags & ASN1_TFLG_EXPTAG)
+ ret = ASN1_object_size(1, sklen, tt->tag);
+ else ret = sklen;
+
+ if(!out) return ret;
+
+ /* Now encode this lot... */
+ /* EXPLICIT tag */
+ if(flags & ASN1_TFLG_EXPTAG)
+ ASN1_put_object(out, 1, sklen, tt->tag, aclass);
+ /* SET or SEQUENCE and IMPLICIT tag */
+ ASN1_put_object(out, 1, skcontlen, sktag, skaclass);
+ /* And finally the stuff itself */
+ asn1_set_seq_out(sk, out, skcontlen, tt->item, isset);
+
+ return ret;
+ }
+
+ if(flags & ASN1_TFLG_EXPTAG) {
+ /* EXPLICIT tagging */
+ /* Find length of tagged item */
+ i = ASN1_item_ex_i2d(val, NULL, tt->item, -1, 0);
+ /* Find length of EXPLICIT tag */
+ ret = ASN1_object_size(1, i, tt->tag);
+ if(out) {
+ /* Output tag and item */
+ ASN1_put_object(out, 1, i, tt->tag, aclass);
+ ASN1_item_ex_i2d(val, out, tt->item, -1, 0);
+ }
+ return ret;
+ }
+ if(flags & ASN1_TFLG_IMPTAG) {
+ /* IMPLICIT tagging */
+ return ASN1_item_ex_i2d(val, out, tt->item, tt->tag, aclass);
+ }
+ /* Nothing special: treat as normal */
+ return ASN1_item_ex_i2d(val, out, tt->item, -1, 0);
+}
+
+/* Temporary structure used to hold DER encoding of items for SET OF */
+
+typedef struct {
+ unsigned char *data;
+ int length;
+} DER_ENC;
+
+static int der_cmp(const void *a, const void *b)
+{
+ const DER_ENC *d1 = a, *d2 = b;
+ int cmplen, i;
+ cmplen = (d1->length < d2->length) ? d1->length : d2->length;
+ i = memcmp(d1->data, d2->data, cmplen);
+ if(i) return i;
+ return d1->length - d2->length;
+}
+
+/* Output the content octets of SET OF or SEQUENCE OF */
+
+static int asn1_set_seq_out(STACK *sk, unsigned char **out, int skcontlen, const ASN1_ITEM *item, int do_sort)
+{
+ int i;
+ void *skitem;
+ unsigned char *tmpdat, *p;
+ DER_ENC *derlst, *tder;
+ if(do_sort) {
+ /* Don't need to sort less than 2 items */
+ if(sk_num(sk) < 2) do_sort = 0;
+ else {
+ derlst = OPENSSL_malloc(sk_num(sk) * sizeof(*derlst));
+ tmpdat = OPENSSL_malloc(skcontlen);
+ if(!derlst || !tmpdat) return 0;
+ }
+ }
+ /* If not sorting just output each item */
+ if(!do_sort) {
+ for(i = 0; i < sk_num(sk); i++) {
+ skitem = sk_value(sk, i);
+ ASN1_item_i2d(skitem, out, item);
+ }
+ return 1;
+ }
+ p = tmpdat;
+ /* Doing sort: build up a list of each member's DER encoding */
+ for(i = 0, tder = derlst; i < sk_num(sk); i++, tder++) {
+ skitem = sk_value(sk, i);
+ tder->data = p;
+ tder->length = ASN1_item_i2d(skitem, &p, item);
+ }
+ /* Now sort them */
+ qsort(derlst, sk_num(sk), sizeof(*derlst), der_cmp);
+ /* Output sorted DER encoding */
+ p = *out;
+ for(i = 0, tder = derlst; i < sk_num(sk); i++, tder++) {
+ memcpy(p, tder->data, tder->length);
+ p += tder->length;
+ }
+ *out = p;
+ OPENSSL_free(derlst);
+ OPENSSL_free(tmpdat);
+ return 1;
+}
+
+static int asn1_i2d_ex_primitive(ASN1_VALUE *val, unsigned char **out, int utype, int tag, int aclass)
+{
+ int len;
+ unsigned char *cont = NULL, c;
+ ASN1_OBJECT *otmp;
+ ASN1_STRING *stmp;
+ int btmp;
+ if(!val) return 0;
+ if(utype == V_ASN1_ANY) {
+ ASN1_TYPE *atype;
+ atype = (ASN1_TYPE *)val;
+ utype = atype->type;
+ /* NB: not a leak because ASN1_NULL_new()
+ * doesn't allocate anything
+ */
+ if(utype == V_ASN1_NULL) val = (ASN1_VALUE *)ASN1_NULL_new();
+ else val = (ASN1_VALUE *)atype->value.ptr;
+ }
+ if(tag == -1) {
+ tag = utype;
+ aclass = V_ASN1_UNIVERSAL;
+ }
+ /* Setup cont and len to point to content octets and
+ * their length.
+ */
+ switch(utype) {
+ case V_ASN1_OBJECT:
+ otmp = (ASN1_OBJECT *)val;
+ cont = otmp->data;
+ len = otmp->length;
+ break;
+
+ case V_ASN1_NULL:
+ cont = NULL;
+ len = 0;
+ break;
+
+ case V_ASN1_BOOLEAN:
+ btmp = *(int *)val;
+ /* -1 means undefined and thus omitted */
+ if(btmp == -1) return 0;
+ if(btmp) c = 0xff;
+ else c = 0;
+ cont = &c;
+ len = 1;
+ break;
+
+ case V_ASN1_BIT_STRING:
+ len = i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)val, NULL);
+ if(out) {
+ ASN1_put_object(out, 0, len, tag, aclass);
+ i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)val, out);
+ }
+ return ASN1_object_size(0, len, tag);
+ break;
+
+ case V_ASN1_INTEGER:
+ case V_ASN1_NEG_INTEGER:
+ case V_ASN1_ENUMERATED:
+ case V_ASN1_NEG_ENUMERATED:
+ /* These are all have the same content format
+ * as ASN1_INTEGER
+ */
+ len = i2c_ASN1_INTEGER((ASN1_INTEGER *)val, NULL);
+ if(out) {
+ ASN1_put_object(out, 0, len, tag, aclass);
+ i2c_ASN1_INTEGER((ASN1_INTEGER *)val, out);
+ }
+ return ASN1_object_size(0, len, tag);
+
+ case V_ASN1_OCTET_STRING:
+ case V_ASN1_NUMERICSTRING:
+ case V_ASN1_PRINTABLESTRING:
+ case V_ASN1_T61STRING:
+ case V_ASN1_VIDEOTEXSTRING:
+ case V_ASN1_IA5STRING:
+ case V_ASN1_UTCTIME:
+ case V_ASN1_GENERALIZEDTIME:
+ case V_ASN1_GRAPHICSTRING:
+ case V_ASN1_VISIBLESTRING:
+ case V_ASN1_GENERALSTRING:
+ case V_ASN1_UNIVERSALSTRING:
+ case V_ASN1_BMPSTRING:
+ case V_ASN1_UTF8STRING:
+ /* All based on ASN1_STRING and handled the same */
+ stmp = (ASN1_STRING *)val;
+ cont = stmp->data;
+ len = stmp->length;
+
+ break;
+
+
+ case V_ASN1_SEQUENCE:
+ case V_ASN1_SET:
+ default:
+ stmp = (ASN1_STRING *)val;
+ if(stmp->data && out) memcpy(*out, stmp->data, stmp->length);
+ return stmp->length;
+
+ }
+ if(out) {
+ ASN1_put_object(out, 0, len, tag, aclass);
+ if(cont) memcpy(*out, cont, len);
+ *out += len;
+ }
+ return ASN1_object_size(0, len, tag);
+}
diff --git a/crypto/asn1/tasn_fre.c b/crypto/asn1/tasn_fre.c
new file mode 100644
index 000000000..3f1a764d0
--- /dev/null
+++ b/crypto/asn1/tasn_fre.c
@@ -0,0 +1,152 @@
+/* tasn_fre.c */
+/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+#include <stddef.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/objects.h>
+
+/* Free up an ASN1 structure */
+
+void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it)
+{
+ const ASN1_TEMPLATE *tt = NULL, *seqtt;
+ const ASN1_EXTERN_FUNCS *ef;
+ const ASN1_COMPAT_FUNCS *cf;
+ int i;
+ if(!val) return;
+
+ switch(it->itype) {
+
+ case ASN1_ITYPE_PRIMITIVE:
+ ASN1_primitive_free(val, it->utype);
+ break;
+
+ case ASN1_ITYPE_MSTRING:
+ ASN1_primitive_free(val, -1);
+ break;
+
+ case ASN1_ITYPE_CHOICE:
+ i = asn1_get_choice_selector(val, it);
+ if((i >= 0) && (i < it->tcount)) {
+ ASN1_VALUE *chval;
+ tt = it->templates + i;
+ chval = asn1_get_field(val, tt);
+ ASN1_template_free(chval, tt);
+ }
+ OPENSSL_free(val);
+ break;
+
+ case ASN1_ITYPE_COMPAT:
+ cf = it->funcs;
+ if(cf && cf->asn1_free) cf->asn1_free(val);
+ break;
+
+ case ASN1_ITYPE_EXTERN:
+ ef = it->funcs;
+ if(ef && ef->asn1_ex_free) ef->asn1_ex_free(val, it);
+ break;
+
+ case ASN1_ITYPE_SEQUENCE:
+ for(i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
+ ASN1_VALUE *seqval;
+ seqtt = asn1_do_adb(val, tt);
+ seqval = asn1_get_field(val, seqtt);
+ ASN1_template_free(seqval, seqtt);
+ }
+ OPENSSL_free(val);
+ break;
+ }
+}
+
+void ASN1_template_free(ASN1_VALUE *val, const ASN1_TEMPLATE *tt)
+{
+ int i;
+ if(tt->flags & ASN1_TFLG_SK_MASK) {
+ STACK *sk = (STACK *)val;
+ for(i = 0; i < sk_num(sk); i++) {
+ ASN1_item_free((ASN1_VALUE *)sk_value(sk, i), tt->item);
+ }
+ sk_free(sk);
+ } else ASN1_item_free(val, tt->item);
+}
+
+void ASN1_primitive_free(ASN1_VALUE *type, long utype)
+{
+ switch(utype) {
+ case V_ASN1_OBJECT:
+ ASN1_OBJECT_free((ASN1_OBJECT *)type);
+ break;
+
+ case V_ASN1_NULL:
+ ASN1_NULL_free((ASN1_NULL *)type);
+ break;
+
+ case V_ASN1_ANY:
+ ASN1_TYPE_free((ASN1_TYPE *)type);
+ break;
+
+ case V_ASN1_BOOLEAN:
+ break;
+
+ default:
+ ASN1_STRING_free((ASN1_STRING*)type);
+ break;
+ }
+}
diff --git a/crypto/asn1/tasn_new.c b/crypto/asn1/tasn_new.c
new file mode 100644
index 000000000..a1aa9ba0d
--- /dev/null
+++ b/crypto/asn1/tasn_new.c
@@ -0,0 +1,187 @@
+/* tasn_new.c */
+/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+#include <stddef.h>
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+#include <openssl/err.h>
+#include <openssl/asn1t.h>
+
+ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it)
+{
+ ASN1_VALUE *ret = NULL;
+ if(ASN1_item_ex_new(&ret, it) > 0) return ret;
+ return NULL;
+}
+
+/* Allocate an ASN1 structure */
+
+int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+ const ASN1_TEMPLATE *tt = NULL;
+ const ASN1_COMPAT_FUNCS *cf;
+ const ASN1_EXTERN_FUNCS *ef;
+ ASN1_VALUE **pseqval;
+ int i;
+
+ switch(it->itype) {
+
+ case ASN1_ITYPE_EXTERN:
+ ef = it->funcs;
+ if(ef && ef->asn1_ex_new) {
+ if(!ef->asn1_ex_new(pval, it))
+ goto memerr;
+ }
+ break;
+
+ case ASN1_ITYPE_COMPAT:
+ cf = it->funcs;
+ if(cf && cf->asn1_new) {
+ *pval = cf->asn1_new();
+ if(!*pval) goto memerr;
+ }
+ break;
+
+ case ASN1_ITYPE_PRIMITIVE:
+
+ if(!ASN1_primitive_new(pval, it->utype))
+ goto memerr;
+ break;
+
+ case ASN1_ITYPE_MSTRING:
+ if(!ASN1_primitive_new(pval, -1))
+ goto memerr;
+ break;
+
+ case ASN1_ITYPE_CHOICE:
+ case ASN1_ITYPE_SEQUENCE:
+ *pval = OPENSSL_malloc(it->size);
+ if(!*pval) goto memerr;
+ memset(*pval, 0, it->size);
+ /* FIXME: set selector for CHOICE */
+ for(i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
+ pseqval = asn1_get_field_ptr(pval, tt);
+ if(!ASN1_template_new(pseqval, tt)) goto memerr;
+ }
+ break;
+ }
+ return 1;
+
+ memerr:
+ ASN1err(ASN1_F_ASN1_ITEM_NEW, ERR_R_MALLOC_FAILURE);
+ return 0;
+}
+
+
+int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
+{
+ const ASN1_ITEM *it = tt->item;
+ /* Special BOOLEAN handling */
+ if(asn1_template_is_bool(tt))
+ return ASN1_item_ex_new(pval, it);
+
+ /* If OPTIONAL or ANY DEFINED BY nothing to do */
+ if(tt->flags & (ASN1_TFLG_OPTIONAL|ASN1_TFLG_ADB_MASK)) {
+ /* Maybe free it first? */
+ *pval = NULL;
+ return 1;
+ }
+ /* If SET OF or SEQUENCE OF, its a STACK */
+ if(tt->flags & ASN1_TFLG_SK_MASK) {
+ *pval = (ASN1_VALUE *)sk_new_null();
+ if(!*pval) {
+ ASN1err(ASN1_F_ASN1_TEMPLATE_NEW, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ return 1;
+ }
+ /* Otherwise pass it back to the item routine */
+ return ASN1_item_ex_new(pval, it);
+}
+
+/* NB: could probably combine most of the real XXX_new() behaviour and junk all the old
+ * functions.
+ */
+
+int ASN1_primitive_new(ASN1_VALUE **pval, long utype)
+{
+ switch(utype) {
+ case V_ASN1_OBJECT:
+ *pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef);
+ return 1;
+
+ case V_ASN1_BOOLEAN:
+ *(int *)pval = -1;
+ return 1;
+
+ case V_ASN1_NULL:
+ *pval = (ASN1_VALUE *)ASN1_NULL_new();
+ return 1;
+
+ case V_ASN1_ANY:
+ *pval = (ASN1_VALUE *)ASN1_TYPE_new();
+ break;
+
+ default:
+ *pval = (ASN1_VALUE *)ASN1_STRING_type_new(utype);
+ break;
+ }
+ if(*pval) return 1;
+ return 0;
+}
diff --git a/crypto/asn1/tasn_prn.c b/crypto/asn1/tasn_prn.c
new file mode 100644
index 000000000..a0c71ea99
--- /dev/null
+++ b/crypto/asn1/tasn_prn.c
@@ -0,0 +1,196 @@
+/* tasn_prn.c */
+/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+#include <stddef.h>
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+#include <openssl/buffer.h>
+#include <openssl/err.h>
+#include <openssl/nasn.h>
+
+/* Print routines. Print out a whole structure from a template.
+ */
+
+static int asn1_item_print_nm(BIO *out, void *fld, int indent, const ASN1_ITEM *it, const char *name);
+
+int ASN1_item_print(BIO *out, void *fld, int indent, const ASN1_ITEM *it)
+{
+ return asn1_item_print_nm(out, fld, indent, it, it->sname);
+}
+
+static int asn1_item_print_nm(BIO *out, void *fld, int indent, const ASN1_ITEM *it, const char *name)
+{
+ ASN1_STRING *str;
+ const ASN1_TEMPLATE *tt;
+ void *tmpfld;
+ int i;
+ if(!fld) {
+ BIO_printf(out, "%*s%s ABSENT\n", indent, "", name);
+ return 1;
+ }
+ switch(it->itype) {
+
+ case ASN1_ITYPE_PRIMITIVE:
+ if(it->templates)
+ return ASN1_template_print(out, fld, indent, it->templates);
+ return asn1_primitive_print(out, fld, it->utype, indent, name);
+ break;
+
+ case ASN1_ITYPE_MSTRING:
+ str = fld;
+ return asn1_primitive_print(out, fld, str->type, indent, name);
+
+ case ASN1_ITYPE_EXTERN:
+ BIO_printf(out, "%*s%s:EXTERNAL TYPE %s %s\n", indent, "", name, it->sname, fld ? "" : "ABSENT");
+ return 1;
+ case ASN1_ITYPE_COMPAT:
+ BIO_printf(out, "%*s%s:COMPATIBLE TYPE %s %s\n", indent, "", name, it->sname, fld ? "" : "ABSENT");
+ return 1;
+
+
+ case ASN1_ITYPE_CHOICE:
+ /* CHOICE type, get selector */
+ i = asn1_get_choice_selector(fld, it);
+ /* This should never happen... */
+ if((i < 0) || (i >= it->tcount)) {
+ BIO_printf(out, "%s selector [%d] out of range\n", it->sname, i);
+ return 1;
+ }
+ tt = it->templates + i;
+ tmpfld = asn1_get_field(fld, tt);
+ return ASN1_template_print(out, tmpfld, indent, tt);
+
+ case ASN1_ITYPE_SEQUENCE:
+ BIO_printf(out, "%*s%s {\n", indent, "", name);
+ /* Get each field entry */
+ for(i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
+ tmpfld = asn1_get_field(fld, tt);
+ ASN1_template_print(out, tmpfld, indent + 2, tt);
+ }
+ BIO_printf(out, "%*s}\n", indent, "");
+ return 1;
+
+ default:
+ return 0;
+ }
+}
+
+int ASN1_template_print(BIO *out, void *fld, int indent, const ASN1_TEMPLATE *tt)
+{
+ int i, flags;
+ //if(!fld) return 0;
+ flags = tt->flags;
+ if(flags & ASN1_TFLG_SK_MASK) {
+ char *tname;
+ void *skitem;
+ /* SET OF, SEQUENCE OF */
+ if(flags & ASN1_TFLG_SET_OF) tname = "SET";
+ else tname = "SEQUENCE";
+ if(fld) {
+ BIO_printf(out, "%*s%s OF %s {\n", indent, "", tname, tt->field_name);
+ for(i = 0; i < sk_num(fld); i++) {
+ skitem = sk_value(fld, i);
+ asn1_item_print_nm(out, skitem, indent + 2, tt->item, "");
+ }
+ BIO_printf(out, "%*s}\n", indent, "");
+ } else
+ BIO_printf(out, "%*s%s OF %s ABSENT\n", indent, "", tname, tt->field_name);
+ return 1;
+ }
+ return asn1_item_print_nm(out, fld, indent, tt->item, tt->field_name);
+}
+
+static int asn1_primitive_print(BIO *out, void *fld, long utype, int indent, const char *name)
+{
+ ASN1_STRING *str = fld;
+ if(fld) {
+ if(utype == V_ASN1_BOOLEAN) {
+ int *bool = fld;
+if(*bool == -1) printf("BOOL MISSING\n");
+ BIO_printf(out, "%*s%s:%s", indent, "", "BOOLEAN", *bool ? "TRUE" : "FALSE");
+ } else if((utype == V_ASN1_INTEGER)
+ || (utype == V_ASN1_ENUMERATED)) {
+ char *s, *nm;
+ s = i2s_ASN1_INTEGER(NULL, fld);
+ if(utype == V_ASN1_INTEGER) nm = "INTEGER";
+ else nm = "ENUMERATED";
+ BIO_printf(out, "%*s%s:%s", indent, "", nm, s);
+ OPENSSL_free(s);
+ } else if(utype == V_ASN1_NULL) {
+ BIO_printf(out, "%*s%s", indent, "", "NULL");
+ } else if(utype == V_ASN1_UTCTIME) {
+ BIO_printf(out, "%*s%s:%s:", indent, "", name, "UTCTIME");
+ ASN1_UTCTIME_print(out, str);
+ } else if(utype == V_ASN1_GENERALIZEDTIME) {
+ BIO_printf(out, "%*s%s:%s:", indent, "", name, "GENERALIZEDTIME");
+ ASN1_GENERALIZEDTIME_print(out, str);
+ } else if(utype == V_ASN1_OBJECT) {
+ char objbuf[80], *ln;
+ ln = OBJ_nid2ln(OBJ_obj2nid(fld));
+ if(!ln) ln = "";
+ OBJ_obj2txt(objbuf, 80, fld, 1);
+ BIO_printf(out, "%*s%s:%s (%s)", indent, "", "OBJECT", ln, objbuf);
+ } else {
+ BIO_printf(out, "%*s%s:", indent, "", name);
+ ASN1_STRING_print_ex(out, str, ASN1_STRFLGS_DUMP_UNKNOWN|ASN1_STRFLGS_SHOW_TYPE);
+ }
+ BIO_printf(out, "\n");
+ } else BIO_printf(out, "%*s%s [ABSENT]\n", indent, "", name);
+ return 1;
+}
diff --git a/crypto/asn1/tasn_typ.c b/crypto/asn1/tasn_typ.c
new file mode 100644
index 000000000..c5ba39301
--- /dev/null
+++ b/crypto/asn1/tasn_typ.c
@@ -0,0 +1,84 @@
+/* tasn_typ.c */
+/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#include <stdio.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+
+
+
+#define IMPLEMENT_ASN1_TYPE(type) const ASN1_ITEM type##_it = { ASN1_ITYPE_PRIMITIVE, V_##type, NULL, 0, NULL, sizeof(type)}
+
+
+IMPLEMENT_ASN1_TYPE(ASN1_BOOLEAN);
+IMPLEMENT_ASN1_TYPE(ASN1_INTEGER);
+IMPLEMENT_ASN1_TYPE(ASN1_BIT_STRING);
+IMPLEMENT_ASN1_TYPE(ASN1_OCTET_STRING);
+IMPLEMENT_ASN1_TYPE(ASN1_NULL);
+IMPLEMENT_ASN1_TYPE(ASN1_OBJECT);
+IMPLEMENT_ASN1_TYPE(ASN1_ENUMERATED);
+IMPLEMENT_ASN1_TYPE(ASN1_UTF8STRING);
+IMPLEMENT_ASN1_TYPE(ASN1_PRINTABLESTRING);
+IMPLEMENT_ASN1_TYPE(ASN1_T61STRING);
+IMPLEMENT_ASN1_TYPE(ASN1_IA5STRING);
+IMPLEMENT_ASN1_TYPE(ASN1_UTCTIME);
+IMPLEMENT_ASN1_TYPE(ASN1_GENERALIZEDTIME);
+IMPLEMENT_ASN1_TYPE(ASN1_VISIBLESTRING);
+IMPLEMENT_ASN1_TYPE(ASN1_UNIVERSALSTRING);
+IMPLEMENT_ASN1_TYPE(ASN1_BMPSTRING);
+const ASN1_ITEM ASN1_ANY_it = { ASN1_ITYPE_PRIMITIVE, V_ASN1_ANY, NULL, 0, NULL, sizeof(ASN1_TYPE)};
+
diff --git a/crypto/asn1/tasn_utl.c b/crypto/asn1/tasn_utl.c
new file mode 100644
index 000000000..7068a0284
--- /dev/null
+++ b/crypto/asn1/tasn_utl.c
@@ -0,0 +1,185 @@
+/* tasn_utl.c */
+/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+#include <stddef.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/objects.h>
+
+/* Utility functions for manipulating fields and offsets */
+
+/* Add 'offset' to 'addr' */
+#define offset2ptr(addr, offset) (void *)(((char *) addr) + offset)
+
+/* Given an ASN1_ITEM CHOICE type return
+ * the selector value
+ */
+
+int asn1_get_choice_selector(ASN1_VALUE *val, const ASN1_ITEM *it)
+{
+ int *sel = offset2ptr(val, it->utype);
+ return *sel;
+}
+
+/* Given an ASN1_ITEM CHOICE type set
+ * the selector value, return old value.
+ */
+
+int asn1_set_choice_selector(ASN1_VALUE **pval, int value, const ASN1_ITEM *it)
+{
+ int *sel, ret;
+ sel = offset2ptr(*pval, it->utype);
+ ret = *sel;
+ *sel = value;
+ return ret;
+}
+
+/* Given an ASN1_TEMPLATE get a field */
+
+ASN1_VALUE *asn1_get_field(ASN1_VALUE *val, const ASN1_TEMPLATE *tt)
+{
+ ASN1_VALUE **ptr = offset2ptr(val, tt->offset);
+ /* NOTE for BOOLEAN types the field is just a plain
+ * int so we don't dereference it. This means that
+ * BOOLEAN is an (int *).
+ */
+ if(asn1_template_is_bool(tt)) {
+ int *bool = (int *)ptr;
+ /* If BOOLEAN is -1 it is absent so return
+ * NULL for compatibility with other types
+ */
+ if(*bool == -1)
+ return NULL;
+ return (ASN1_VALUE *)ptr;
+ }
+ return *ptr;
+}
+
+/* Given an ASN1_TEMPLATE get a pointer to a field */
+ASN1_VALUE ** asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
+{
+ ASN1_VALUE **pvaltmp = offset2ptr(*pval, tt->offset);
+ /* NOTE for BOOLEAN types the field is just a plain
+ * int so we can't return int **, so settle for
+ * (int *).
+ */
+ return pvaltmp;
+}
+
+/* Handle ANY DEFINED BY template, find the selector, look up
+ * the relevant ASN1_TEMPLATE in the table and return it.
+ */
+
+const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE *val, const ASN1_TEMPLATE *tt)
+{
+ const ASN1_ADB *adb;
+ const ASN1_ADB_TABLE *atbl;
+ long selector;
+ ASN1_VALUE *sfld;
+ int i;
+ if(!(tt->flags & ASN1_TFLG_ADB_MASK)) return tt;
+
+ /* Else ANY DEFINED BY ... get the table */
+ adb = tt->item;
+
+ /* Get the selector field */
+ sfld = offset2ptr(val, adb->offset);
+
+ /* Check if NULL */
+ if(!sfld) return adb->null_tt;
+
+ /* Convert type to a long:
+ * NB: don't check for NID_undef here because it
+ * might be a legitimate value in the table
+ */
+ if(tt->flags & ASN1_TFLG_ADB_OID)
+ selector = OBJ_obj2nid((ASN1_OBJECT *)sfld);
+ else
+ selector = ASN1_INTEGER_get((ASN1_INTEGER *)sfld);
+
+ /* Try to find matching entry in table
+ * Maybe should check application types first to
+ * allow application override? Might also be useful
+ * to have a flag which indicates table is sorted and
+ * we can do a binary search. For now stick to a
+ * linear search.
+ */
+
+ for(atbl = adb->tbl, i = 0; i < adb->tblcount; i++, atbl++)
+ if(atbl->value == selector) return atbl->tt;
+
+ /* FIXME: need to search application table too */
+
+ /* No match, return default type */
+ return adb->default_tt;
+}
+
+int asn1_template_is_bool(const ASN1_TEMPLATE *tt)
+{
+ if(tt->flags & ASN1_TFLG_SK_MASK) return 0;
+ else return asn1_item_is_bool(tt->item);
+}
+
+int asn1_item_is_bool(const ASN1_ITEM *it)
+{
+ /* Special BOOLEAN handling */
+ if((it->utype == V_ASN1_BOOLEAN) &&
+ (it->itype == ASN1_ITYPE_PRIMITIVE)) return 1;
+ return 0;
+}