Preliminary streaming ASN1 encode support.
This commit is contained in:
parent
20b33a015f
commit
230fd6b7b6
11
CHANGES
11
CHANGES
@ -4,6 +4,17 @@
|
|||||||
|
|
||||||
Changes between 0.9.7 and 0.9.8 [xx XXX 2002]
|
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
|
*) Let 'openssl req' fail if an argument to '-newkey' is not
|
||||||
recognized instead of using RSA as a default.
|
recognized instead of using RSA as a default.
|
||||||
[Bodo Moeller]
|
[Bodo Moeller]
|
||||||
|
@ -192,6 +192,11 @@ typedef struct asn1_object_st
|
|||||||
} ASN1_OBJECT;
|
} ASN1_OBJECT;
|
||||||
|
|
||||||
#define ASN1_STRING_FLAG_BITS_LEFT 0x08 /* Set if 0x07 has bits left value */
|
#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 :-) */
|
/* This is the base type that holds just about everything :-) */
|
||||||
typedef struct asn1_string_st
|
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); \
|
int i2d_##name(const type *a, unsigned char **out); \
|
||||||
DECLARE_ASN1_ITEM(name)
|
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) \
|
#define DECLARE_ASN1_FUNCTIONS_const(name) \
|
||||||
name *name##_new(void); \
|
name *name##_new(void); \
|
||||||
void name##_free(name *a);
|
void name##_free(name *a);
|
||||||
@ -793,6 +801,8 @@ DECLARE_ASN1_FUNCTIONS(ASN1_UTCTIME)
|
|||||||
DECLARE_ASN1_FUNCTIONS(ASN1_GENERALIZEDTIME)
|
DECLARE_ASN1_FUNCTIONS(ASN1_GENERALIZEDTIME)
|
||||||
DECLARE_ASN1_FUNCTIONS(ASN1_TIME)
|
DECLARE_ASN1_FUNCTIONS(ASN1_TIME)
|
||||||
|
|
||||||
|
DECLARE_ASN1_ITEM(ASN1_OCTET_STRING_NDEF)
|
||||||
|
|
||||||
ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s,time_t t);
|
ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s,time_t t);
|
||||||
int ASN1_TIME_check(ASN1_TIME *t);
|
int ASN1_TIME_check(ASN1_TIME *t);
|
||||||
ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME **out);
|
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);
|
int ASN1_check_infinite_end(unsigned char **p,long len);
|
||||||
void ASN1_put_object(unsigned char **pp, int constructed, int length,
|
void ASN1_put_object(unsigned char **pp, int constructed, int length,
|
||||||
int tag, int xclass);
|
int tag, int xclass);
|
||||||
|
int ASN1_put_eoc(unsigned char **pp);
|
||||||
int ASN1_object_size(int constructed, int length, int tag);
|
int ASN1_object_size(int constructed, int length, int tag);
|
||||||
|
|
||||||
/* Used to implement other functions */
|
/* 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);
|
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);
|
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_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);
|
void ASN1_add_oid_module(void);
|
||||||
|
|
||||||
|
@ -203,13 +203,22 @@ void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag,
|
|||||||
}
|
}
|
||||||
p += ttag;
|
p += ttag;
|
||||||
}
|
}
|
||||||
if ((constructed == 2) && (length == 0))
|
if (constructed == 2)
|
||||||
*(p++)=0x80; /* der_put_length would output 0 instead */
|
*(p++)=0x80;
|
||||||
else
|
else
|
||||||
asn1_put_length(&p,length);
|
asn1_put_length(&p,length);
|
||||||
*pp=p;
|
*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)
|
static void asn1_put_length(unsigned char **pp, int length)
|
||||||
{
|
{
|
||||||
unsigned char *p= *pp;
|
unsigned char *p= *pp;
|
||||||
@ -247,8 +256,8 @@ int ASN1_object_size(int constructed, int length, int tag)
|
|||||||
ret++;
|
ret++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((length == 0) && (constructed == 2))
|
if (constructed == 2)
|
||||||
ret+=2;
|
return ret + 3;
|
||||||
ret++;
|
ret++;
|
||||||
if (length > 127)
|
if (length > 127)
|
||||||
{
|
{
|
||||||
|
@ -166,6 +166,9 @@ extern "C" {
|
|||||||
#stname \
|
#stname \
|
||||||
ASN1_ITEM_end(tname)
|
ASN1_ITEM_end(tname)
|
||||||
|
|
||||||
|
#define ASN1_NDEF_SEQUENCE(tname) \
|
||||||
|
ASN1_SEQUENCE(tname)
|
||||||
|
|
||||||
#define ASN1_SEQUENCE_cb(tname, cb) \
|
#define ASN1_SEQUENCE_cb(tname, cb) \
|
||||||
const static ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \
|
const static ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \
|
||||||
ASN1_SEQUENCE(tname)
|
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)}; \
|
const static ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_ENCODING, 0, 0, cb, offsetof(tname, enc)}; \
|
||||||
ASN1_SEQUENCE(tname)
|
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_BROKEN_SEQUENCE_END(stname) ASN1_SEQUENCE_END_ref(stname, stname)
|
||||||
|
|
||||||
#define ASN1_SEQUENCE_END_enc(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname)
|
#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) \
|
#define ASN1_EXP_SEQUENCE_OF_OPT(stname, field, type, tag) \
|
||||||
ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL)
|
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 */
|
/* Macros for the ASN1_ADB structure */
|
||||||
|
|
||||||
#define ASN1_ADB(name) \
|
#define ASN1_ADB(name) \
|
||||||
@ -518,6 +537,13 @@ struct ASN1_ADB_TABLE_st {
|
|||||||
|
|
||||||
#define ASN1_TFLG_COMBINE (0x1<<10)
|
#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 */
|
/* This is the actual ASN1 item itself */
|
||||||
|
|
||||||
struct ASN1_ITEM_st {
|
struct ASN1_ITEM_st {
|
||||||
@ -570,19 +596,25 @@ const char *sname; /* Structure name */
|
|||||||
* has a special meaning, it is used as a mask
|
* has a special meaning, it is used as a mask
|
||||||
* of acceptable types using the B_ASN1 constants.
|
* 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
|
#define ASN1_ITYPE_PRIMITIVE 0x0
|
||||||
|
|
||||||
#define ASN1_ITYPE_SEQUENCE 0x1
|
#define ASN1_ITYPE_SEQUENCE 0x1
|
||||||
|
|
||||||
#define ASN1_ITYPE_CHOICE 0x2
|
#define ASN1_ITYPE_CHOICE 0x2
|
||||||
|
|
||||||
#define ASN1_ITYPE_COMPAT 0x3
|
#define ASN1_ITYPE_COMPAT 0x3
|
||||||
|
|
||||||
#define ASN1_ITYPE_EXTERN 0x4
|
#define ASN1_ITYPE_EXTERN 0x4
|
||||||
|
|
||||||
#define ASN1_ITYPE_MSTRING 0x5
|
#define ASN1_ITYPE_MSTRING 0x5
|
||||||
|
|
||||||
|
#define ASN1_ITYPE_NDEF_SEQUENCE 0x6
|
||||||
|
|
||||||
/* Cache for ASN1 tag and length, so we
|
/* Cache for ASN1 tag and length, so we
|
||||||
* don't keep re-reading it for things
|
* don't keep re-reading it for things
|
||||||
@ -767,6 +799,12 @@ typedef struct ASN1_AUX_st {
|
|||||||
return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\
|
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
|
/* This includes evil casts to remove const: they will go away when full
|
||||||
* ASN1 constification is done.
|
* ASN1 constification is done.
|
||||||
*/
|
*/
|
||||||
|
@ -289,6 +289,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1
|
|||||||
goto auxerr;
|
goto auxerr;
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
case ASN1_ITYPE_NDEF_SEQUENCE:
|
||||||
case ASN1_ITYPE_SEQUENCE:
|
case ASN1_ITYPE_SEQUENCE:
|
||||||
p = *in;
|
p = *in;
|
||||||
tmplen = len;
|
tmplen = len;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* project 2000.
|
* project 2000.
|
||||||
*/
|
*/
|
||||||
/* ====================================================================
|
/* ====================================================================
|
||||||
* Copyright (c) 2000 The OpenSSL Project. All rights reserved.
|
* Copyright (c) 2000-2002 The OpenSSL Project. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
@ -63,38 +63,57 @@
|
|||||||
#include <openssl/asn1t.h>
|
#include <openssl/asn1t.h>
|
||||||
#include <openssl/objects.h>
|
#include <openssl/objects.h>
|
||||||
|
|
||||||
static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass);
|
static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
|
||||||
static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *seq, unsigned char **out, int skcontlen, const ASN1_ITEM *item, int isset);
|
const ASN1_ITEM *it,
|
||||||
|
int tag, int aclass);
|
||||||
|
static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
|
||||||
|
int skcontlen, const ASN1_ITEM *item,
|
||||||
|
int do_sort, int iclass);
|
||||||
|
static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
|
||||||
|
const ASN1_TEMPLATE *tt,
|
||||||
|
int tag, int aclass);
|
||||||
|
static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out,
|
||||||
|
const ASN1_ITEM *it, int flags);
|
||||||
|
|
||||||
/* Encode an ASN1 item, this is compatible with the
|
/* Top level i2d equivalents: the 'ndef' variant instructs the encoder
|
||||||
|
* to use indefinite length constructed encoding, where appropriate
|
||||||
|
*/
|
||||||
|
|
||||||
|
int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it)
|
||||||
|
{
|
||||||
|
return asn1_item_flags_i2d(val, out, it, ASN1_TFLG_NDEF);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it)
|
||||||
|
{
|
||||||
|
return asn1_item_flags_i2d(val, out, it, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Encode an ASN1 item, this is use by the
|
||||||
* standard 'i2d' function. 'out' points to
|
* standard 'i2d' function. 'out' points to
|
||||||
* a buffer to output the data to, in future we will
|
* a buffer to output the data to.
|
||||||
* have more advanced versions that can output data
|
|
||||||
* a piece at a time and this will simply be a special
|
|
||||||
* case.
|
|
||||||
*
|
*
|
||||||
* The new i2d has one additional feature. If the output
|
* The new i2d has one additional feature. If the output
|
||||||
* buffer is NULL (i.e. *out == NULL) then a buffer is
|
* buffer is NULL (i.e. *out == NULL) then a buffer is
|
||||||
* allocated and populated with the encoding.
|
* allocated and populated with the encoding.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it, int flags)
|
||||||
int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it)
|
|
||||||
{
|
{
|
||||||
if(out && !*out) {
|
if(out && !*out) {
|
||||||
unsigned char *p, *buf;
|
unsigned char *p, *buf;
|
||||||
int len;
|
int len;
|
||||||
len = ASN1_item_ex_i2d(&val, NULL, it, -1, 0);
|
len = ASN1_item_ex_i2d(&val, NULL, it, -1, flags);
|
||||||
if(len <= 0) return len;
|
if(len <= 0) return len;
|
||||||
buf = OPENSSL_malloc(len);
|
buf = OPENSSL_malloc(len);
|
||||||
if(!buf) return -1;
|
if(!buf) return -1;
|
||||||
p = buf;
|
p = buf;
|
||||||
ASN1_item_ex_i2d(&val, &p, it, -1, 0);
|
ASN1_item_ex_i2d(&val, &p, it, -1, flags);
|
||||||
*out = buf;
|
*out = buf;
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ASN1_item_ex_i2d(&val, out, it, -1, 0);
|
return ASN1_item_ex_i2d(&val, out, it, -1, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Encode an item, taking care of IMPLICIT tagging (if any).
|
/* Encode an item, taking care of IMPLICIT tagging (if any).
|
||||||
@ -102,31 +121,34 @@ int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it)
|
|||||||
* used in external types.
|
* used in external types.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass)
|
int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
|
||||||
|
const ASN1_ITEM *it, int tag, int aclass)
|
||||||
{
|
{
|
||||||
const ASN1_TEMPLATE *tt = NULL;
|
const ASN1_TEMPLATE *tt = NULL;
|
||||||
unsigned char *p = NULL;
|
unsigned char *p = NULL;
|
||||||
int i, seqcontlen, seqlen;
|
int i, seqcontlen, seqlen, ndef = 1;
|
||||||
ASN1_STRING *strtmp;
|
|
||||||
const ASN1_COMPAT_FUNCS *cf;
|
const ASN1_COMPAT_FUNCS *cf;
|
||||||
const ASN1_EXTERN_FUNCS *ef;
|
const ASN1_EXTERN_FUNCS *ef;
|
||||||
const ASN1_AUX *aux = it->funcs;
|
const ASN1_AUX *aux = it->funcs;
|
||||||
ASN1_aux_cb *asn1_cb;
|
ASN1_aux_cb *asn1_cb = 0;
|
||||||
if((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval) return 0;
|
|
||||||
if(aux && aux->asn1_cb) asn1_cb = aux->asn1_cb;
|
if((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)
|
||||||
else asn1_cb = 0;
|
return 0;
|
||||||
|
|
||||||
|
if(aux && aux->asn1_cb)
|
||||||
|
asn1_cb = aux->asn1_cb;
|
||||||
|
|
||||||
switch(it->itype) {
|
switch(it->itype) {
|
||||||
|
|
||||||
case ASN1_ITYPE_PRIMITIVE:
|
case ASN1_ITYPE_PRIMITIVE:
|
||||||
if(it->templates)
|
if(it->templates)
|
||||||
return ASN1_template_i2d(pval, out, it->templates);
|
return asn1_template_ex_i2d(pval, out, it->templates,
|
||||||
|
tag, aclass);
|
||||||
return asn1_i2d_ex_primitive(pval, out, it, tag, aclass);
|
return asn1_i2d_ex_primitive(pval, out, it, tag, aclass);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ASN1_ITYPE_MSTRING:
|
case ASN1_ITYPE_MSTRING:
|
||||||
strtmp = (ASN1_STRING *)*pval;
|
return asn1_i2d_ex_primitive(pval, out, it, -1, aclass);
|
||||||
return asn1_i2d_ex_primitive(pval, out, it, -1, 0);
|
|
||||||
|
|
||||||
case ASN1_ITYPE_CHOICE:
|
case ASN1_ITYPE_CHOICE:
|
||||||
if(asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it))
|
if(asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it))
|
||||||
@ -137,7 +159,8 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it
|
|||||||
const ASN1_TEMPLATE *chtt;
|
const ASN1_TEMPLATE *chtt;
|
||||||
chtt = it->templates + i;
|
chtt = it->templates + i;
|
||||||
pchval = asn1_get_field_ptr(pval, chtt);
|
pchval = asn1_get_field_ptr(pval, chtt);
|
||||||
return ASN1_template_i2d(pchval, out, chtt);
|
return asn1_template_ex_i2d(pchval, out, chtt,
|
||||||
|
-1, aclass);
|
||||||
}
|
}
|
||||||
/* Fixme: error condition if selector out of range */
|
/* Fixme: error condition if selector out of range */
|
||||||
if(asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it))
|
if(asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it))
|
||||||
@ -161,6 +184,12 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it
|
|||||||
*p = aclass | tag | (*p & V_ASN1_CONSTRUCTED);
|
*p = aclass | tag | (*p & V_ASN1_CONSTRUCTED);
|
||||||
return i;
|
return i;
|
||||||
|
|
||||||
|
case ASN1_ITYPE_NDEF_SEQUENCE:
|
||||||
|
//fprintf(stderr, "NDEF sequence from %s flags %d\n", it->sname, aclass & ASN1_TFLG_NDEF);
|
||||||
|
/* Use indefinite length constructed if requested */
|
||||||
|
if (aclass & ASN1_TFLG_NDEF) ndef = 2;
|
||||||
|
/* fall through */
|
||||||
|
|
||||||
case ASN1_ITYPE_SEQUENCE:
|
case ASN1_ITYPE_SEQUENCE:
|
||||||
i = asn1_enc_restore(&seqcontlen, out, pval, it);
|
i = asn1_enc_restore(&seqcontlen, out, pval, it);
|
||||||
/* An error occurred */
|
/* An error occurred */
|
||||||
@ -172,7 +201,9 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it
|
|||||||
/* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
|
/* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
|
||||||
if(tag == -1) {
|
if(tag == -1) {
|
||||||
tag = V_ASN1_SEQUENCE;
|
tag = V_ASN1_SEQUENCE;
|
||||||
aclass = V_ASN1_UNIVERSAL;
|
/* Retain any other flags in aclass */
|
||||||
|
aclass = (aclass & ~ASN1_TFLG_TAG_CLASS)
|
||||||
|
| V_ASN1_UNIVERSAL;
|
||||||
}
|
}
|
||||||
if(asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it))
|
if(asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it))
|
||||||
return 0;
|
return 0;
|
||||||
@ -184,13 +215,13 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it
|
|||||||
if(!seqtt) return 0;
|
if(!seqtt) return 0;
|
||||||
pseqval = asn1_get_field_ptr(pval, seqtt);
|
pseqval = asn1_get_field_ptr(pval, seqtt);
|
||||||
/* FIXME: check for errors in enhanced version */
|
/* FIXME: check for errors in enhanced version */
|
||||||
/* FIXME: special handling of indefinite length encoding */
|
seqcontlen += asn1_template_ex_i2d(pseqval, NULL, seqtt,
|
||||||
seqcontlen += ASN1_template_i2d(pseqval, NULL, seqtt);
|
-1, aclass);
|
||||||
}
|
}
|
||||||
seqlen = ASN1_object_size(1, seqcontlen, tag);
|
seqlen = ASN1_object_size(ndef, seqcontlen, tag);
|
||||||
if(!out) return seqlen;
|
if(!out) return seqlen;
|
||||||
/* Output SEQUENCE header */
|
/* Output SEQUENCE header */
|
||||||
ASN1_put_object(out, 1, seqcontlen, tag, aclass);
|
ASN1_put_object(out, ndef, seqcontlen, tag, aclass);
|
||||||
for(i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
|
for(i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
|
||||||
const ASN1_TEMPLATE *seqtt;
|
const ASN1_TEMPLATE *seqtt;
|
||||||
ASN1_VALUE **pseqval;
|
ASN1_VALUE **pseqval;
|
||||||
@ -198,8 +229,9 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it
|
|||||||
if(!seqtt) return 0;
|
if(!seqtt) return 0;
|
||||||
pseqval = asn1_get_field_ptr(pval, seqtt);
|
pseqval = asn1_get_field_ptr(pval, seqtt);
|
||||||
/* FIXME: check for errors in enhanced version */
|
/* FIXME: check for errors in enhanced version */
|
||||||
ASN1_template_i2d(pseqval, out, seqtt);
|
asn1_template_ex_i2d(pseqval, out, seqtt, -1, aclass);
|
||||||
}
|
}
|
||||||
|
if (ndef == 2) ASN1_put_eoc(out);
|
||||||
if(asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it))
|
if(asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it))
|
||||||
return 0;
|
return 0;
|
||||||
return seqlen;
|
return seqlen;
|
||||||
@ -210,42 +242,91 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_TEMPLATE *tt)
|
static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_TEMPLATE *tt, int tag, int iclass)
|
||||||
{
|
{
|
||||||
int i, ret, flags, aclass;
|
int i, ret, flags, ttag, tclass, ndef;
|
||||||
flags = tt->flags;
|
flags = tt->flags;
|
||||||
aclass = flags & ASN1_TFLG_TAG_CLASS;
|
/* Work out tag and class to use: tagging may come
|
||||||
|
* either from the template or the arguments, not both
|
||||||
|
* because this would create ambiguity. Additionally
|
||||||
|
* the iclass argument may contain some additional flags
|
||||||
|
* which should be noted and passed down to other levels.
|
||||||
|
*/
|
||||||
|
if (flags & ASN1_TFLG_TAG_MASK)
|
||||||
|
{
|
||||||
|
/* Error if argument and template tagging */
|
||||||
|
if (tag != -1)
|
||||||
|
/* FIXME: error code here */
|
||||||
|
return -1;
|
||||||
|
/* Get tagging from template */
|
||||||
|
ttag = tt->tag;
|
||||||
|
tclass = flags & ASN1_TFLG_TAG_CLASS;
|
||||||
|
}
|
||||||
|
else if (tag != -1)
|
||||||
|
{
|
||||||
|
/* No template tagging, get from arguments */
|
||||||
|
ttag = tag;
|
||||||
|
tclass = iclass & ASN1_TFLG_TAG_CLASS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ttag = -1;
|
||||||
|
tclass = 0;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Remove any class mask from iflag.
|
||||||
|
*/
|
||||||
|
iclass &= ~ASN1_TFLG_TAG_CLASS;
|
||||||
|
|
||||||
|
/* At this point 'ttag' contains the outer tag to use,
|
||||||
|
* 'tclass' is the class and iclass is any flags passed
|
||||||
|
* to this function.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* if template and arguments require ndef, use it */
|
||||||
|
if ((flags & ASN1_TFLG_NDEF) && (iclass & ASN1_TFLG_NDEF))
|
||||||
|
ndef = 2;
|
||||||
|
else ndef = 1;
|
||||||
|
|
||||||
if(flags & ASN1_TFLG_SK_MASK) {
|
if(flags & ASN1_TFLG_SK_MASK) {
|
||||||
/* SET OF, SEQUENCE OF */
|
/* SET OF, SEQUENCE OF */
|
||||||
STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
|
STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
|
||||||
int isset, sktag, skaclass;
|
int isset, sktag, skaclass;
|
||||||
int skcontlen, sklen;
|
int skcontlen, sklen;
|
||||||
ASN1_VALUE *skitem;
|
ASN1_VALUE *skitem;
|
||||||
|
|
||||||
if(!*pval) return 0;
|
if(!*pval) return 0;
|
||||||
|
|
||||||
if(flags & ASN1_TFLG_SET_OF) {
|
if(flags & ASN1_TFLG_SET_OF) {
|
||||||
isset = 1;
|
isset = 1;
|
||||||
/* 2 means we reorder */
|
/* 2 means we reorder */
|
||||||
if(flags & ASN1_TFLG_SEQUENCE_OF) isset = 2;
|
if(flags & ASN1_TFLG_SEQUENCE_OF) isset = 2;
|
||||||
} else isset = 0;
|
} else isset = 0;
|
||||||
/* First work out inner tag value */
|
|
||||||
if(flags & ASN1_TFLG_IMPTAG) {
|
/* Work out inner tag value: if EXPLICIT
|
||||||
sktag = tt->tag;
|
* or no tagging use underlying type.
|
||||||
skaclass = aclass;
|
*/
|
||||||
|
if((ttag != -1) && !(flags & ASN1_TFLG_EXPTAG)) {
|
||||||
|
sktag = ttag;
|
||||||
|
skaclass = tclass;
|
||||||
} else {
|
} else {
|
||||||
skaclass = V_ASN1_UNIVERSAL;
|
skaclass = V_ASN1_UNIVERSAL;
|
||||||
if(isset) sktag = V_ASN1_SET;
|
if(isset) sktag = V_ASN1_SET;
|
||||||
else sktag = V_ASN1_SEQUENCE;
|
else sktag = V_ASN1_SEQUENCE;
|
||||||
}
|
}
|
||||||
/* Now work out length of items */
|
|
||||||
|
/* Determine total length of items */
|
||||||
skcontlen = 0;
|
skcontlen = 0;
|
||||||
for(i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
|
for(i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
|
||||||
skitem = sk_ASN1_VALUE_value(sk, i);
|
skitem = sk_ASN1_VALUE_value(sk, i);
|
||||||
skcontlen += ASN1_item_ex_i2d(&skitem, NULL, ASN1_ITEM_ptr(tt->item), -1, 0);
|
skcontlen += ASN1_item_ex_i2d(&skitem, NULL,
|
||||||
|
ASN1_ITEM_ptr(tt->item),
|
||||||
|
-1, iclass);
|
||||||
}
|
}
|
||||||
sklen = ASN1_object_size(1, skcontlen, sktag);
|
sklen = ASN1_object_size(ndef, skcontlen, sktag);
|
||||||
/* If EXPLICIT need length of surrounding tag */
|
/* If EXPLICIT need length of surrounding tag */
|
||||||
if(flags & ASN1_TFLG_EXPTAG)
|
if(flags & ASN1_TFLG_EXPTAG)
|
||||||
ret = ASN1_object_size(1, sklen, tt->tag);
|
ret = ASN1_object_size(ndef, sklen, ttag);
|
||||||
else ret = sklen;
|
else ret = sklen;
|
||||||
|
|
||||||
if(!out) return ret;
|
if(!out) return ret;
|
||||||
@ -253,35 +334,43 @@ int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_TEMPLAT
|
|||||||
/* Now encode this lot... */
|
/* Now encode this lot... */
|
||||||
/* EXPLICIT tag */
|
/* EXPLICIT tag */
|
||||||
if(flags & ASN1_TFLG_EXPTAG)
|
if(flags & ASN1_TFLG_EXPTAG)
|
||||||
ASN1_put_object(out, 1, sklen, tt->tag, aclass);
|
ASN1_put_object(out, ndef, sklen, ttag, tclass);
|
||||||
/* SET or SEQUENCE and IMPLICIT tag */
|
/* SET or SEQUENCE and IMPLICIT tag */
|
||||||
ASN1_put_object(out, 1, skcontlen, sktag, skaclass);
|
ASN1_put_object(out, ndef, skcontlen, sktag, skaclass);
|
||||||
/* And finally the stuff itself */
|
/* And the stuff itself */
|
||||||
asn1_set_seq_out(sk, out, skcontlen, ASN1_ITEM_ptr(tt->item), isset);
|
asn1_set_seq_out(sk, out, skcontlen, ASN1_ITEM_ptr(tt->item),
|
||||||
|
isset, iclass);
|
||||||
|
if (ndef == 2) {
|
||||||
|
ASN1_put_eoc(out);
|
||||||
|
if(flags & ASN1_TFLG_EXPTAG)
|
||||||
|
ASN1_put_eoc(out);
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(flags & ASN1_TFLG_EXPTAG) {
|
if(flags & ASN1_TFLG_EXPTAG) {
|
||||||
/* EXPLICIT tagging */
|
/* EXPLICIT tagging */
|
||||||
/* Find length of tagged item */
|
/* Find length of tagged item */
|
||||||
i = ASN1_item_ex_i2d(pval, NULL, ASN1_ITEM_ptr(tt->item), -1, 0);
|
i = ASN1_item_ex_i2d(pval, NULL, ASN1_ITEM_ptr(tt->item),
|
||||||
|
-1, iclass);
|
||||||
if(!i) return 0;
|
if(!i) return 0;
|
||||||
/* Find length of EXPLICIT tag */
|
/* Find length of EXPLICIT tag */
|
||||||
ret = ASN1_object_size(1, i, tt->tag);
|
ret = ASN1_object_size(ndef, i, ttag);
|
||||||
if(out) {
|
if(out) {
|
||||||
/* Output tag and item */
|
/* Output tag and item */
|
||||||
ASN1_put_object(out, 1, i, tt->tag, aclass);
|
ASN1_put_object(out, ndef, i, ttag, tclass);
|
||||||
ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), -1, 0);
|
ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item),
|
||||||
|
-1, iclass);
|
||||||
|
if (ndef == 2) ASN1_put_eoc(out);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if(flags & ASN1_TFLG_IMPTAG) {
|
|
||||||
/* IMPLICIT tagging */
|
/* Either normal or IMPLICIT tagging: combine class and flags */
|
||||||
return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), tt->tag, aclass);
|
return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item),
|
||||||
}
|
ttag, tclass | iclass);
|
||||||
/* Nothing special: treat as normal */
|
|
||||||
return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), -1, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Temporary structure used to hold DER encoding of items for SET OF */
|
/* Temporary structure used to hold DER encoding of items for SET OF */
|
||||||
@ -304,7 +393,9 @@ static int der_cmp(const void *a, const void *b)
|
|||||||
|
|
||||||
/* Output the content octets of SET OF or SEQUENCE OF */
|
/* Output the content octets of SET OF or SEQUENCE OF */
|
||||||
|
|
||||||
static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out, int skcontlen, const ASN1_ITEM *item, int do_sort)
|
static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
|
||||||
|
int skcontlen, const ASN1_ITEM *item,
|
||||||
|
int do_sort, int iclass)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
ASN1_VALUE *skitem;
|
ASN1_VALUE *skitem;
|
||||||
@ -323,7 +414,7 @@ static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out, int s
|
|||||||
if(!do_sort) {
|
if(!do_sort) {
|
||||||
for(i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
|
for(i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
|
||||||
skitem = sk_ASN1_VALUE_value(sk, i);
|
skitem = sk_ASN1_VALUE_value(sk, i);
|
||||||
ASN1_item_i2d(skitem, out, item);
|
ASN1_item_ex_i2d(&skitem, out, item, -1, iclass);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -332,7 +423,7 @@ static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out, int s
|
|||||||
for(i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) {
|
for(i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) {
|
||||||
skitem = sk_ASN1_VALUE_value(sk, i);
|
skitem = sk_ASN1_VALUE_value(sk, i);
|
||||||
tder->data = p;
|
tder->data = p;
|
||||||
tder->length = ASN1_item_i2d(skitem, &p, item);
|
tder->length = ASN1_item_ex_i2d(&skitem, &p, item, -1, iclass);
|
||||||
tder->field = skitem;
|
tder->field = skitem;
|
||||||
}
|
}
|
||||||
/* Now sort them */
|
/* Now sort them */
|
||||||
@ -359,6 +450,7 @@ static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out, const A
|
|||||||
int len;
|
int len;
|
||||||
int utype;
|
int utype;
|
||||||
int usetag;
|
int usetag;
|
||||||
|
int ndef = 0;
|
||||||
|
|
||||||
utype = it->utype;
|
utype = it->utype;
|
||||||
|
|
||||||
@ -381,19 +473,27 @@ static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out, const A
|
|||||||
|
|
||||||
/* -1 means omit type */
|
/* -1 means omit type */
|
||||||
|
|
||||||
if(len == -1) return 0;
|
if(len == -1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* -2 return is special meaning use ndef */
|
||||||
|
if (len == -2)
|
||||||
|
{
|
||||||
|
ndef = 2;
|
||||||
|
len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* If not implicitly tagged get tag from underlying type */
|
/* If not implicitly tagged get tag from underlying type */
|
||||||
if(tag == -1) tag = utype;
|
if(tag == -1) tag = utype;
|
||||||
|
|
||||||
/* Output tag+length followed by content octets */
|
/* Output tag+length followed by content octets */
|
||||||
if(out) {
|
if(out) {
|
||||||
if(usetag) ASN1_put_object(out, 0, len, tag, aclass);
|
if(usetag) ASN1_put_object(out, ndef, len, tag, aclass);
|
||||||
asn1_ex_i2c(pval, *out, &utype, it);
|
asn1_ex_i2c(pval, *out, &utype, it);
|
||||||
*out += len;
|
*out += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(usetag) return ASN1_object_size(0, len, tag);
|
if(usetag) return ASN1_object_size(ndef, len, tag);
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -486,6 +586,19 @@ int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype, const ASN1_
|
|||||||
default:
|
default:
|
||||||
/* All based on ASN1_STRING and handled the same */
|
/* All based on ASN1_STRING and handled the same */
|
||||||
strtmp = (ASN1_STRING *)*pval;
|
strtmp = (ASN1_STRING *)*pval;
|
||||||
|
/* Special handling for NDEF */
|
||||||
|
if ((it->size == ASN1_TFLG_NDEF)
|
||||||
|
&& (strtmp->flags & ASN1_STRING_FLAG_NDEF))
|
||||||
|
{
|
||||||
|
if (cout)
|
||||||
|
{
|
||||||
|
strtmp->data = cout;
|
||||||
|
strtmp->length = 0;
|
||||||
|
ASN1_put_eoc(&cout);
|
||||||
|
}
|
||||||
|
/* Special return code */
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
cont = strtmp->data;
|
cont = strtmp->data;
|
||||||
len = strtmp->length;
|
len = strtmp->length;
|
||||||
|
|
||||||
|
@ -130,6 +130,7 @@ static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int c
|
|||||||
if(ef && ef->asn1_ex_free) ef->asn1_ex_free(pval, it);
|
if(ef && ef->asn1_ex_free) ef->asn1_ex_free(pval, it);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ASN1_ITYPE_NDEF_SEQUENCE:
|
||||||
case ASN1_ITYPE_SEQUENCE:
|
case ASN1_ITYPE_SEQUENCE:
|
||||||
if(asn1_do_lock(pval, -1, it) > 0) return;
|
if(asn1_do_lock(pval, -1, it) > 0) return;
|
||||||
if(asn1_cb) {
|
if(asn1_cb) {
|
||||||
|
@ -155,6 +155,7 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int
|
|||||||
goto auxerr;
|
goto auxerr;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ASN1_ITYPE_NDEF_SEQUENCE:
|
||||||
case ASN1_ITYPE_SEQUENCE:
|
case ASN1_ITYPE_SEQUENCE:
|
||||||
if(asn1_cb) {
|
if(asn1_cb) {
|
||||||
i = asn1_cb(ASN1_OP_NEW_PRE, pval, it);
|
i = asn1_cb(ASN1_OP_NEW_PRE, pval, it);
|
||||||
@ -231,6 +232,7 @@ static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
|
|||||||
case ASN1_ITYPE_COMPAT:
|
case ASN1_ITYPE_COMPAT:
|
||||||
case ASN1_ITYPE_CHOICE:
|
case ASN1_ITYPE_CHOICE:
|
||||||
case ASN1_ITYPE_SEQUENCE:
|
case ASN1_ITYPE_SEQUENCE:
|
||||||
|
case ASN1_ITYPE_NDEF_SEQUENCE:
|
||||||
*pval = NULL;
|
*pval = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -131,3 +131,7 @@ IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, DIRECTORYSTRING)
|
|||||||
IMPLEMENT_ASN1_TYPE_ex(ASN1_BOOLEAN, ASN1_BOOLEAN, -1)
|
IMPLEMENT_ASN1_TYPE_ex(ASN1_BOOLEAN, ASN1_BOOLEAN, -1)
|
||||||
IMPLEMENT_ASN1_TYPE_ex(ASN1_TBOOLEAN, ASN1_BOOLEAN, 1)
|
IMPLEMENT_ASN1_TYPE_ex(ASN1_TBOOLEAN, ASN1_BOOLEAN, 1)
|
||||||
IMPLEMENT_ASN1_TYPE_ex(ASN1_FBOOLEAN, ASN1_BOOLEAN, 0)
|
IMPLEMENT_ASN1_TYPE_ex(ASN1_FBOOLEAN, ASN1_BOOLEAN, 0)
|
||||||
|
|
||||||
|
/* Special, OCTET STRING with indefinite length constructed support */
|
||||||
|
|
||||||
|
IMPLEMENT_ASN1_TYPE_ex(ASN1_OCTET_STRING_NDEF, ASN1_OCTET_STRING, ASN1_TFLG_NDEF)
|
||||||
|
@ -102,7 +102,8 @@ int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it)
|
|||||||
{
|
{
|
||||||
const ASN1_AUX *aux;
|
const ASN1_AUX *aux;
|
||||||
int *lck, ret;
|
int *lck, ret;
|
||||||
if(it->itype != ASN1_ITYPE_SEQUENCE) return 0;
|
if((it->itype != ASN1_ITYPE_SEQUENCE)
|
||||||
|
&& (it->itype != ASN1_ITYPE_NDEF_SEQUENCE)) return 0;
|
||||||
aux = it->funcs;
|
aux = it->funcs;
|
||||||
if(!aux || !(aux->flags & ASN1_AFLG_REFCOUNT)) return 0;
|
if(!aux || !(aux->flags & ASN1_AFLG_REFCOUNT)) return 0;
|
||||||
lck = offset2ptr(*pval, aux->ref_offset);
|
lck = offset2ptr(*pval, aux->ref_offset);
|
||||||
|
@ -69,30 +69,31 @@
|
|||||||
ASN1_ADB_TEMPLATE(p7default) = ASN1_EXP_OPT(PKCS7, d.other, ASN1_ANY, 0);
|
ASN1_ADB_TEMPLATE(p7default) = ASN1_EXP_OPT(PKCS7, d.other, ASN1_ANY, 0);
|
||||||
|
|
||||||
ASN1_ADB(PKCS7) = {
|
ASN1_ADB(PKCS7) = {
|
||||||
ADB_ENTRY(NID_pkcs7_data, ASN1_EXP_OPT(PKCS7, d.data, ASN1_OCTET_STRING, 0)),
|
ADB_ENTRY(NID_pkcs7_data, ASN1_NDEF_EXP_OPT(PKCS7, d.data, ASN1_OCTET_STRING_NDEF, 0)),
|
||||||
ADB_ENTRY(NID_pkcs7_signed, ASN1_EXP_OPT(PKCS7, d.sign, PKCS7_SIGNED, 0)),
|
ADB_ENTRY(NID_pkcs7_signed, ASN1_NDEF_EXP_OPT(PKCS7, d.sign, PKCS7_SIGNED, 0)),
|
||||||
ADB_ENTRY(NID_pkcs7_enveloped, ASN1_EXP_OPT(PKCS7, d.enveloped, PKCS7_ENVELOPE, 0)),
|
ADB_ENTRY(NID_pkcs7_enveloped, ASN1_NDEF_EXP_OPT(PKCS7, d.enveloped, PKCS7_ENVELOPE, 0)),
|
||||||
ADB_ENTRY(NID_pkcs7_signedAndEnveloped, ASN1_EXP_OPT(PKCS7, d.signed_and_enveloped, PKCS7_SIGN_ENVELOPE, 0)),
|
ADB_ENTRY(NID_pkcs7_signedAndEnveloped, ASN1_NDEF_EXP_OPT(PKCS7, d.signed_and_enveloped, PKCS7_SIGN_ENVELOPE, 0)),
|
||||||
ADB_ENTRY(NID_pkcs7_digest, ASN1_EXP_OPT(PKCS7, d.digest, PKCS7_DIGEST, 0)),
|
ADB_ENTRY(NID_pkcs7_digest, ASN1_NDEF_EXP_OPT(PKCS7, d.digest, PKCS7_DIGEST, 0)),
|
||||||
ADB_ENTRY(NID_pkcs7_encrypted, ASN1_EXP_OPT(PKCS7, d.encrypted, PKCS7_ENCRYPT, 0))
|
ADB_ENTRY(NID_pkcs7_encrypted, ASN1_NDEF_EXP_OPT(PKCS7, d.encrypted, PKCS7_ENCRYPT, 0))
|
||||||
} ASN1_ADB_END(PKCS7, 0, type, 0, &p7default_tt, NULL);
|
} ASN1_ADB_END(PKCS7, 0, type, 0, &p7default_tt, NULL);
|
||||||
|
|
||||||
ASN1_SEQUENCE(PKCS7) = {
|
ASN1_NDEF_SEQUENCE(PKCS7) = {
|
||||||
ASN1_SIMPLE(PKCS7, type, ASN1_OBJECT),
|
ASN1_SIMPLE(PKCS7, type, ASN1_OBJECT),
|
||||||
ASN1_ADB_OBJECT(PKCS7)
|
ASN1_ADB_OBJECT(PKCS7)
|
||||||
}ASN1_SEQUENCE_END(PKCS7)
|
}ASN1_NDEF_SEQUENCE_END(PKCS7)
|
||||||
|
|
||||||
IMPLEMENT_ASN1_FUNCTIONS(PKCS7)
|
IMPLEMENT_ASN1_FUNCTIONS(PKCS7)
|
||||||
|
IMPLEMENT_ASN1_NDEF_FUNCTION(PKCS7)
|
||||||
IMPLEMENT_ASN1_DUP_FUNCTION(PKCS7)
|
IMPLEMENT_ASN1_DUP_FUNCTION(PKCS7)
|
||||||
|
|
||||||
ASN1_SEQUENCE(PKCS7_SIGNED) = {
|
ASN1_NDEF_SEQUENCE(PKCS7_SIGNED) = {
|
||||||
ASN1_SIMPLE(PKCS7_SIGNED, version, ASN1_INTEGER),
|
ASN1_SIMPLE(PKCS7_SIGNED, version, ASN1_INTEGER),
|
||||||
ASN1_SET_OF(PKCS7_SIGNED, md_algs, X509_ALGOR),
|
ASN1_SET_OF(PKCS7_SIGNED, md_algs, X509_ALGOR),
|
||||||
ASN1_SIMPLE(PKCS7_SIGNED, contents, PKCS7),
|
ASN1_SIMPLE(PKCS7_SIGNED, contents, PKCS7),
|
||||||
ASN1_IMP_SEQUENCE_OF_OPT(PKCS7_SIGNED, cert, X509, 0),
|
ASN1_IMP_SEQUENCE_OF_OPT(PKCS7_SIGNED, cert, X509, 0),
|
||||||
ASN1_IMP_SET_OF_OPT(PKCS7_SIGNED, crl, X509_CRL, 1),
|
ASN1_IMP_SET_OF_OPT(PKCS7_SIGNED, crl, X509_CRL, 1),
|
||||||
ASN1_SET_OF(PKCS7_SIGNED, signer_info, PKCS7_SIGNER_INFO)
|
ASN1_SET_OF(PKCS7_SIGNED, signer_info, PKCS7_SIGNER_INFO)
|
||||||
} ASN1_SEQUENCE_END(PKCS7_SIGNED)
|
} ASN1_NDEF_SEQUENCE_END(PKCS7_SIGNED)
|
||||||
|
|
||||||
IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGNED)
|
IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGNED)
|
||||||
|
|
||||||
@ -130,11 +131,11 @@ ASN1_SEQUENCE(PKCS7_ISSUER_AND_SERIAL) = {
|
|||||||
|
|
||||||
IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL)
|
IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL)
|
||||||
|
|
||||||
ASN1_SEQUENCE(PKCS7_ENVELOPE) = {
|
ASN1_NDEF_SEQUENCE(PKCS7_ENVELOPE) = {
|
||||||
ASN1_SIMPLE(PKCS7_ENVELOPE, version, ASN1_INTEGER),
|
ASN1_SIMPLE(PKCS7_ENVELOPE, version, ASN1_INTEGER),
|
||||||
ASN1_SET_OF(PKCS7_ENVELOPE, recipientinfo, PKCS7_RECIP_INFO),
|
ASN1_SET_OF(PKCS7_ENVELOPE, recipientinfo, PKCS7_RECIP_INFO),
|
||||||
ASN1_SIMPLE(PKCS7_ENVELOPE, enc_data, PKCS7_ENC_CONTENT)
|
ASN1_SIMPLE(PKCS7_ENVELOPE, enc_data, PKCS7_ENC_CONTENT)
|
||||||
} ASN1_SEQUENCE_END(PKCS7_ENVELOPE)
|
} ASN1_NDEF_SEQUENCE_END(PKCS7_ENVELOPE)
|
||||||
|
|
||||||
IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENVELOPE)
|
IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENVELOPE)
|
||||||
|
|
||||||
@ -157,15 +158,15 @@ ASN1_SEQUENCE_cb(PKCS7_RECIP_INFO, ri_cb) = {
|
|||||||
|
|
||||||
IMPLEMENT_ASN1_FUNCTIONS(PKCS7_RECIP_INFO)
|
IMPLEMENT_ASN1_FUNCTIONS(PKCS7_RECIP_INFO)
|
||||||
|
|
||||||
ASN1_SEQUENCE(PKCS7_ENC_CONTENT) = {
|
ASN1_NDEF_SEQUENCE(PKCS7_ENC_CONTENT) = {
|
||||||
ASN1_SIMPLE(PKCS7_ENC_CONTENT, content_type, ASN1_OBJECT),
|
ASN1_SIMPLE(PKCS7_ENC_CONTENT, content_type, ASN1_OBJECT),
|
||||||
ASN1_SIMPLE(PKCS7_ENC_CONTENT, algorithm, X509_ALGOR),
|
ASN1_SIMPLE(PKCS7_ENC_CONTENT, algorithm, X509_ALGOR),
|
||||||
ASN1_IMP_OPT(PKCS7_ENC_CONTENT, enc_data, ASN1_OCTET_STRING, 0)
|
ASN1_IMP_OPT(PKCS7_ENC_CONTENT, enc_data, ASN1_OCTET_STRING, 0)
|
||||||
} ASN1_SEQUENCE_END(PKCS7_ENC_CONTENT)
|
} ASN1_NDEF_SEQUENCE_END(PKCS7_ENC_CONTENT)
|
||||||
|
|
||||||
IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENC_CONTENT)
|
IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENC_CONTENT)
|
||||||
|
|
||||||
ASN1_SEQUENCE(PKCS7_SIGN_ENVELOPE) = {
|
ASN1_NDEF_SEQUENCE(PKCS7_SIGN_ENVELOPE) = {
|
||||||
ASN1_SIMPLE(PKCS7_SIGN_ENVELOPE, version, ASN1_INTEGER),
|
ASN1_SIMPLE(PKCS7_SIGN_ENVELOPE, version, ASN1_INTEGER),
|
||||||
ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, recipientinfo, PKCS7_RECIP_INFO),
|
ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, recipientinfo, PKCS7_RECIP_INFO),
|
||||||
ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, md_algs, X509_ALGOR),
|
ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, md_algs, X509_ALGOR),
|
||||||
@ -173,23 +174,23 @@ ASN1_SEQUENCE(PKCS7_SIGN_ENVELOPE) = {
|
|||||||
ASN1_IMP_SET_OF_OPT(PKCS7_SIGN_ENVELOPE, cert, X509, 0),
|
ASN1_IMP_SET_OF_OPT(PKCS7_SIGN_ENVELOPE, cert, X509, 0),
|
||||||
ASN1_IMP_SET_OF_OPT(PKCS7_SIGN_ENVELOPE, crl, X509_CRL, 1),
|
ASN1_IMP_SET_OF_OPT(PKCS7_SIGN_ENVELOPE, crl, X509_CRL, 1),
|
||||||
ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, signer_info, PKCS7_SIGNER_INFO)
|
ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, signer_info, PKCS7_SIGNER_INFO)
|
||||||
} ASN1_SEQUENCE_END(PKCS7_SIGN_ENVELOPE)
|
} ASN1_NDEF_SEQUENCE_END(PKCS7_SIGN_ENVELOPE)
|
||||||
|
|
||||||
IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGN_ENVELOPE)
|
IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGN_ENVELOPE)
|
||||||
|
|
||||||
ASN1_SEQUENCE(PKCS7_ENCRYPT) = {
|
ASN1_NDEF_SEQUENCE(PKCS7_ENCRYPT) = {
|
||||||
ASN1_SIMPLE(PKCS7_ENCRYPT, version, ASN1_INTEGER),
|
ASN1_SIMPLE(PKCS7_ENCRYPT, version, ASN1_INTEGER),
|
||||||
ASN1_SIMPLE(PKCS7_ENCRYPT, enc_data, PKCS7_ENC_CONTENT)
|
ASN1_SIMPLE(PKCS7_ENCRYPT, enc_data, PKCS7_ENC_CONTENT)
|
||||||
} ASN1_SEQUENCE_END(PKCS7_ENCRYPT)
|
} ASN1_NDEF_SEQUENCE_END(PKCS7_ENCRYPT)
|
||||||
|
|
||||||
IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENCRYPT)
|
IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENCRYPT)
|
||||||
|
|
||||||
ASN1_SEQUENCE(PKCS7_DIGEST) = {
|
ASN1_NDEF_SEQUENCE(PKCS7_DIGEST) = {
|
||||||
ASN1_SIMPLE(PKCS7_DIGEST, version, ASN1_INTEGER),
|
ASN1_SIMPLE(PKCS7_DIGEST, version, ASN1_INTEGER),
|
||||||
ASN1_SIMPLE(PKCS7_DIGEST, md, X509_ALGOR),
|
ASN1_SIMPLE(PKCS7_DIGEST, md, X509_ALGOR),
|
||||||
ASN1_SIMPLE(PKCS7_DIGEST, contents, PKCS7),
|
ASN1_SIMPLE(PKCS7_DIGEST, contents, PKCS7),
|
||||||
ASN1_SIMPLE(PKCS7_DIGEST, digest, ASN1_OCTET_STRING)
|
ASN1_SIMPLE(PKCS7_DIGEST, digest, ASN1_OCTET_STRING)
|
||||||
} ASN1_SEQUENCE_END(PKCS7_DIGEST)
|
} ASN1_NDEF_SEQUENCE_END(PKCS7_DIGEST)
|
||||||
|
|
||||||
IMPLEMENT_ASN1_FUNCTIONS(PKCS7_DIGEST)
|
IMPLEMENT_ASN1_FUNCTIONS(PKCS7_DIGEST)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user