Commit 230fd6b7 authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

Preliminary streaming ASN1 encode support.

parent 20b33a01
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -4,6 +4,17 @@

 Changes between 0.9.7 and 0.9.8  [xx XXX 2002]

  *) Extend ASN1 encoder to support indefinite length constructed
     encoding. This can output sequences tags and octet strings in
     this form. Modify pk7_asn1.c to support indefinite length
     encoding. This is experimental and needs additional code to
     be useful, such as an ASN1 bio and some enhanced streaming
     PKCS#7 code.

     Extend template encode functionality so that tagging is passed
     down to the template encoder.
     [Steve Henson]

  *) Let 'openssl req' fail if an argument to '-newkey' is not
     recognized instead of using RSA as a default.
     [Bodo Moeller]
+12 −0
Original line number Diff line number Diff line
@@ -192,6 +192,11 @@ typedef struct asn1_object_st
	} ASN1_OBJECT;

#define ASN1_STRING_FLAG_BITS_LEFT 0x08 /* Set if 0x07 has bits left value */
/* This indicates that the ASN1_STRING is not a real value but just a place
 * holder for the location where indefinite length constructed data should
 * be inserted in the memory buffer 
 */
#define ASN1_STRING_FLAG_NDEF 0x010 
/* This is the base type that holds just about everything :-) */
typedef struct asn1_string_st
	{
@@ -280,6 +285,9 @@ typedef struct ASN1_VALUE_st ASN1_VALUE;
	int i2d_##name(const type *a, unsigned char **out); \
	DECLARE_ASN1_ITEM(name)

#define	DECLARE_ASN1_NDEF_FUNCTION(name) \
	int i2d_##name##_NDEF(name *a, unsigned char **out);

#define DECLARE_ASN1_FUNCTIONS_const(name) \
	name *name##_new(void); \
	void name##_free(name *a);
@@ -793,6 +801,8 @@ DECLARE_ASN1_FUNCTIONS(ASN1_UTCTIME)
DECLARE_ASN1_FUNCTIONS(ASN1_GENERALIZEDTIME)
DECLARE_ASN1_FUNCTIONS(ASN1_TIME)

DECLARE_ASN1_ITEM(ASN1_OCTET_STRING_NDEF)

ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s,time_t t);
int ASN1_TIME_check(ASN1_TIME *t);
ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME **out);
@@ -849,6 +859,7 @@ int ASN1_get_object(unsigned char **pp, long *plength, int *ptag,
int ASN1_check_infinite_end(unsigned char **p,long len);
void ASN1_put_object(unsigned char **pp, int constructed, int length,
	int tag, int xclass);
int ASN1_put_eoc(unsigned char **pp);
int ASN1_object_size(int constructed, int length, int tag);

/* Used to implement other functions */
@@ -935,6 +946,7 @@ 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_ndef_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it);

void ASN1_add_oid_module(void);

+13 −4
Original line number Diff line number Diff line
@@ -203,13 +203,22 @@ void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag,
			}
		p += ttag;
		}
	if ((constructed == 2) && (length == 0))
		*(p++)=0x80; /* der_put_length would output 0 instead */
	if (constructed == 2)
		*(p++)=0x80;
	else
		asn1_put_length(&p,length);
	*pp=p;
	}

int ASN1_put_eoc(unsigned char **pp)
	{
	unsigned char *p = *pp;
	*p++ = 0;
	*p++ = 0;
	*pp = p;
	return 2;
	}

static void asn1_put_length(unsigned char **pp, int length)
	{
	unsigned char *p= *pp;
@@ -247,8 +256,8 @@ int ASN1_object_size(int constructed, int length, int tag)
			ret++;
			}
		}
	if ((length == 0) && (constructed == 2))
		ret+=2;
	if (constructed == 2)
		return ret + 3;
	ret++;
	if (length > 127)
		{
+44 −6
Original line number Diff line number Diff line
@@ -166,6 +166,9 @@ extern "C" {
		#stname \
	ASN1_ITEM_end(tname)

#define ASN1_NDEF_SEQUENCE(tname) \
	ASN1_SEQUENCE(tname)

#define ASN1_SEQUENCE_cb(tname, cb) \
	const static ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \
	ASN1_SEQUENCE(tname)
@@ -182,6 +185,18 @@ extern "C" {
	const static ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_ENCODING, 0, 0, cb, offsetof(tname, enc)}; \
	ASN1_SEQUENCE(tname)

#define ASN1_NDEF_SEQUENCE_END(tname) \
	;\
	ASN1_ITEM_start(tname) \
		ASN1_ITYPE_NDEF_SEQUENCE,\
		V_ASN1_SEQUENCE,\
		tname##_seq_tt,\
		sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
		NULL,\
		sizeof(tname),\
		#tname \
	ASN1_ITEM_end(tname)

#define ASN1_BROKEN_SEQUENCE_END(stname) ASN1_SEQUENCE_END_ref(stname, stname)

#define ASN1_SEQUENCE_END_enc(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname)
@@ -353,6 +368,10 @@ extern "C" {
#define ASN1_EXP_SEQUENCE_OF_OPT(stname, field, type, tag) \
			ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL)

/* EXPLICIT OPTIONAL using indefinite length constructed form */
#define ASN1_NDEF_EXP_OPT(stname, field, type, tag) \
			ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_NDEF)

/* Macros for the ASN1_ADB structure */

#define ASN1_ADB(name) \
@@ -518,6 +537,13 @@ struct ASN1_ADB_TABLE_st {

#define ASN1_TFLG_COMBINE	(0x1<<10)

/* This flag when present in a SEQUENCE OF, SET OF
 * or EXPLICIT causes indefinite length constructed
 * encoding to be used if required.
 */

#define ASN1_TFLG_NDEF		(0x1<<11)

/* This is the actual ASN1 item itself */

struct ASN1_ITEM_st {
@@ -570,6 +596,10 @@ const char *sname; /* Structure name */
 * has a special meaning, it is used as a mask
 * of acceptable types using the B_ASN1 constants.
 *
 * NDEF_SEQUENCE is the same as SEQUENCE except
 * that it will use indefinite length constructed
 * encoding if requested.
 *
 */

#define ASN1_ITYPE_PRIMITIVE		0x0
@@ -584,6 +614,8 @@ const char *sname; /* Structure name */

#define ASN1_ITYPE_MSTRING		0x5

#define ASN1_ITYPE_NDEF_SEQUENCE	0x6

/* Cache for ASN1 tag and length, so we
 * don't keep re-reading it for things
 * like CHOICE
@@ -767,6 +799,12 @@ typedef struct ASN1_AUX_st {
		return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\
	} 

#define IMPLEMENT_ASN1_NDEF_FUNCTION(stname) \
	int i2d_##stname##_NDEF(stname *a, unsigned char **out) \
	{ \
		return ASN1_item_ndef_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(stname));\
	} 

/* This includes evil casts to remove const: they will go away when full
 * ASN1 constification is done.
 */
+1 −0
Original line number Diff line number Diff line
@@ -289,6 +289,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1
				goto auxerr;
		return 1;

		case ASN1_ITYPE_NDEF_SEQUENCE:
		case ASN1_ITYPE_SEQUENCE:
		p = *in;
		tmplen = len;
Loading