summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsteve <steve>2000-11-25 23:42:43 +0000
committersteve <steve>2000-11-25 23:42:43 +0000
commitb3483567c625e7c8bd0029d5288765024972c066 (patch)
tree3e49e84a47bfccf39cc58d300ef78b4b08bd6dfb
parent5d6f4da3d45f7c15b87cc7147a2a0e85630741ae (diff)
downloadopenssl-b3483567c625e7c8bd0029d5288765024972c066.tar.gz
Add an ASN1_ENCODING type and support to automatically
cache the received encoding of a structure. This is useful partly for efficiency but mainly because the signatures may be wrong if calculated on a re-encoded structure. Replace old X509_REQ handling. This results in slightly different 'kludge' behaviour. X509_REQ_print() and the 'req' utility have been modified to accommodate this. Free up a STACK before reusing it in the decode routines for SET OF and STACK OF. Also free up and zero any OPTIONAL sequence components. Can probably be handled more cleanly in the free routines themselves by passing (ASN1_VALUE **).
-rw-r--r--README.ASN16
-rw-r--r--apps/req.c9
-rw-r--r--crypto/asn1/asn1.h12
-rw-r--r--crypto/asn1/asn1t.h18
-rw-r--r--crypto/asn1/t_req.c9
-rw-r--r--crypto/asn1/tasn_dec.c62
-rw-r--r--crypto/asn1/tasn_enc.c6
-rw-r--r--crypto/asn1/tasn_fre.c1
-rw-r--r--crypto/asn1/tasn_new.c1
-rw-r--r--crypto/asn1/tasn_utl.c61
-rw-r--r--crypto/asn1/x_req.c230
-rw-r--r--crypto/x509/x509.h18
12 files changed, 189 insertions, 244 deletions
diff --git a/README.ASN1 b/README.ASN1
index 836c69876..f232ba68b 100644
--- a/README.ASN1
+++ b/README.ASN1
@@ -133,6 +133,12 @@ called 'single' which is 0 for a SET OF and 1 for single. The old field has
been deleted to deliberately break source compatibility. Since this structure
is normally accessed via higher level functions this shouldn't break too much.
+The X509_REQ_INFO certificate request info structure no longer has a field
+called 'req_kludge'. This used to be set to 1 if the attributes field was
+(incorrectly) omitted. You can check to see if the field is omitted now by
+checking if the attributes field is NULL. Similarly if you need to omit
+the field then free attributes and set it to NULL.
+
The top level 'detached' field in the PKCS7 structure is no longer set when
a PKCS#7 structure is read in. PKCS7_is_detached() should be called instead.
The behaviour of PKCS7_get_detached() is unaffected.
diff --git a/apps/req.c b/apps/req.c
index 4c4b9e3ea..a27959868 100644
--- a/apps/req.c
+++ b/apps/req.c
@@ -102,7 +102,7 @@
* -nodes - no des encryption
* -config file - Load configuration file.
* -key file - make a request using key in file (or use it for verification).
- * -keyform arg - key file format.
+ * -keyform - key file format.
* -rand file(s) - load the file(s) into the PRNG.
* -newkey - make a key and a request.
* -modulus - print RSA modulus.
@@ -752,8 +752,11 @@ loop:
}
i=make_REQ(req,pkey,!x509);
- if (kludge >= 0)
- req->req_info->req_kludge=kludge;
+ if ((kludge > 0) && !sk_X509_ATTRIBUTE_num(req->req_info->attributes))
+ {
+ sk_X509_ATTRIBUTE_free(req->req_info->attributes);
+ req->req_info->attributes = NULL;
+ }
if (!i)
{
BIO_printf(bio_err,"problems making Certificate Request\n");
diff --git a/crypto/asn1/asn1.h b/crypto/asn1/asn1.h
index c46ba6996..650eb1639 100644
--- a/crypto/asn1/asn1.h
+++ b/crypto/asn1/asn1.h
@@ -196,6 +196,18 @@ typedef struct asn1_string_st
long flags;
} ASN1_STRING;
+/* ASN1_ENCODING structure: this is used to save the received
+ * encoding of an ASN1 type. This is useful to get round
+ * problems with invalid encodings which can break signatures.
+ */
+
+typedef struct ASN1_ENCODING_st
+ {
+ unsigned char *enc; /* DER encoding */
+ long len; /* Length of encoding */
+ int modified; /* set to 1 if 'enc' is invalid */
+ } ASN1_ENCODING;
+
#define STABLE_FLAGS_MALLOC 0x01
#define STABLE_NO_MASK 0x02
#define DIRSTRING_TYPE \
diff --git a/crypto/asn1/asn1t.h b/crypto/asn1/asn1t.h
index b3a1c468d..50e608406 100644
--- a/crypto/asn1/asn1t.h
+++ b/crypto/asn1/asn1t.h
@@ -125,13 +125,19 @@ extern "C" {
}
#define ASN1_SEQUENCE_cb(tname, cb) \
- const static ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb}; \
+ const static ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \
ASN1_SEQUENCE(tname)
#define ASN1_SEQUENCE_ref(tname, cb, lck) \
- const static ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), lck, cb}; \
+ const static ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), lck, cb, 0}; \
ASN1_SEQUENCE(tname)
+#define ASN1_SEQUENCE_enc(tname, enc, cb) \
+ const static ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_ENCODING, 0, 0, cb, offsetof(tname, enc)}; \
+ ASN1_SEQUENCE(tname)
+
+#define ASN1_SEQUENCE_END_enc(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname)
+
#define ASN1_SEQUENCE_END_cb(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname)
#define ASN1_SEQUENCE_END_ref(stname, tname) \
@@ -542,12 +548,15 @@ typedef struct ASN1_AUX_st {
int ref_offset; /* Offset of reference value */
int ref_lock; /* Lock type to use */
ASN1_aux_cb *asn1_cb;
+ int enc_offset; /* Offset of ASN1_ENCODING structure */
} ASN1_AUX;
/* Flags in ASN1_AUX */
/* Use a reference count */
#define ASN1_AFLG_REFCOUNT 1
+/* Save the encoding of structure (useful for signatures) */
+#define ASN1_AFLG_ENCODING 2
/* operation values for asn1_cb */
@@ -654,6 +663,11 @@ int asn1_template_is_bool(const ASN1_TEMPLATE *tt);
int asn1_item_is_bool(const ASN1_ITEM *it);
int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it);
+void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it);
+void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
+int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, const ASN1_ITEM *it);
+int asn1_enc_save(ASN1_VALUE **pval, unsigned char *in, int inlen, const ASN1_ITEM *it);
+
#ifdef __cplusplus
}
#endif
diff --git a/crypto/asn1/t_req.c b/crypto/asn1/t_req.c
index 9f38446a5..b80ea1857 100644
--- a/crypto/asn1/t_req.c
+++ b/crypto/asn1/t_req.c
@@ -145,13 +145,10 @@ int X509_REQ_print(BIO *bp, X509_REQ *x)
if (BIO_puts(bp,str) <= 0) goto err;
sk=x->req_info->attributes;
- if ((sk == NULL) || (sk_X509_ATTRIBUTE_num(sk) == 0))
+ if (sk_X509_ATTRIBUTE_num(sk) == 0)
{
- if (!x->req_info->req_kludge)
- {
- sprintf(str,"%12sa0:00\n","");
- if (BIO_puts(bp,str) <= 0) goto err;
- }
+ sprintf(str,"%12sa0:00\n","");
+ if (BIO_puts(bp,str) <= 0) goto err;
}
else
{
diff --git a/crypto/asn1/tasn_dec.c b/crypto/asn1/tasn_dec.c
index a18f0011e..5218427d6 100644
--- a/crypto/asn1/tasn_dec.c
+++ b/crypto/asn1/tasn_dec.c
@@ -353,13 +353,23 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1
const ASN1_TEMPLATE *seqtt;
seqtt = asn1_do_adb(pval, tt, 1);
if(!seqtt) goto err;
- if(!(seqtt->flags & ASN1_TFLG_OPTIONAL)) {
+ if(seqtt->flags & ASN1_TFLG_OPTIONAL) {
+ ASN1_VALUE **pseqval;
+ pseqval = asn1_get_field_ptr(pval, seqtt);
+ if(asn1_template_is_bool(seqtt))
+ *(ASN1_BOOLEAN *)pseqval = -1;
+ else if(*pseqval) {
+ ASN1_template_free(pseqval, seqtt);
+ *pseqval = NULL;
+ }
+ } else {
errtt = seqtt;
ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_FIELD_MISSING);
goto err;
}
}
-
+ /* Save encoding */
+ if(!asn1_enc_save(pval, *in, p - *in, it)) goto auxerr;
*in = p;
if(asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it))
goto auxerr;
@@ -476,6 +486,16 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val, unsigned char **in, long le
return 0;
} else if(ret == -1) return -1;
if(!*val) *val = (ASN1_VALUE *)sk_new_null();
+ else {
+ /* We've got a valid STACK: free up any items present */
+ STACK *sktmp = (STACK *)*val;
+ ASN1_VALUE *vtmp;
+ while(sk_num(sktmp) > 0) {
+ vtmp = (ASN1_VALUE *)sk_pop(sktmp);
+ ASN1_item_free(vtmp, tt->item);
+ }
+ }
+
if(!*val) {
ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_MALLOC_FAILURE);
goto err;
@@ -539,7 +559,7 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, unsigned char **in, long inl
{
int ret = 0;
long plen;
- char cst, inf;
+ char cst, inf, free_cont = 0;
unsigned char *p;
BUF_MEM buf;
unsigned char *cont = NULL;
@@ -630,6 +650,7 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, unsigned char **in, long inl
asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL);
cont = (unsigned char *)buf.data;
len = buf.length;
+ free_cont = 1;
} else {
cont = p;
len = plen;
@@ -683,6 +704,10 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, unsigned char **in, long inl
case V_ASN1_UNIVERSALSTRING:
case V_ASN1_BMPSTRING:
case V_ASN1_UTF8STRING:
+ case V_ASN1_OTHER:
+ case V_ASN1_SET:
+ case V_ASN1_SEQUENCE:
+ default:
/* All based on ASN1_STRING and handled the same */
if(!*pval) {
stmp = ASN1_STRING_type_new(utype);
@@ -696,11 +721,11 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, unsigned char **in, long inl
stmp->type = utype;
}
/* If we've already allocated a buffer use it */
- if(cst) {
+ if(free_cont) {
if(stmp->data) OPENSSL_free(stmp->data);
stmp->data = cont;
stmp->length = len;
- buf.data = NULL;
+ free_cont = 0;
} else {
if(!ASN1_STRING_set(stmp, cont, len)) {
ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_MALLOC_FAILURE);
@@ -710,37 +735,12 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, unsigned char **in, long inl
}
}
break;
-
- /* If SEQUENCE, or SET or we don't understand the type
- * then just collect its encoded form
- */
-
- default:
- case V_ASN1_OTHER:
- 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);
+ if(free_cont && buf.data) OPENSSL_free(buf.data);
return ret;
}
diff --git a/crypto/asn1/tasn_enc.c b/crypto/asn1/tasn_enc.c
index 6716d62a8..a71292302 100644
--- a/crypto/asn1/tasn_enc.c
+++ b/crypto/asn1/tasn_enc.c
@@ -144,6 +144,12 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it
return i;
case ASN1_ITYPE_SEQUENCE:
+ i = asn1_enc_restore(&seqcontlen, out, pval, it);
+ /* An error occurred */
+ if(i < 0) return 0;
+ /* We have a valid cached encoding... */
+ if(i > 0) return seqcontlen;
+ /* Otherwise carry on */
seqcontlen = 0;
/* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
if(tag == -1) {
diff --git a/crypto/asn1/tasn_fre.c b/crypto/asn1/tasn_fre.c
index 2661d338d..a6f27fd13 100644
--- a/crypto/asn1/tasn_fre.c
+++ b/crypto/asn1/tasn_fre.c
@@ -120,6 +120,7 @@ static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int c
case ASN1_ITYPE_SEQUENCE:
if(asn1_do_lock(pval, -1, it) > 0) return;
if(asn1_cb) asn1_cb(ASN1_OP_FREE_PRE, pval, it);
+ asn1_enc_free(pval, it);
/* If we free up as normal we will invalidate any
* ANY DEFINED BY field and we wont be able to
* determine the type of the field it defines. So
diff --git a/crypto/asn1/tasn_new.c b/crypto/asn1/tasn_new.c
index 6f652a16f..e926a01bd 100644
--- a/crypto/asn1/tasn_new.c
+++ b/crypto/asn1/tasn_new.c
@@ -143,6 +143,7 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int
if(!*pval) goto memerr;
memset(*pval, 0, it->size);
asn1_do_lock(pval, 0, it);
+ asn1_enc_init(pval, it);
}
if(asn1_cb && !asn1_cb(ASN1_OP_NEW_PRE, pval, it))
goto auxerr;
diff --git a/crypto/asn1/tasn_utl.c b/crypto/asn1/tasn_utl.c
index 78f522374..c3319f248 100644
--- a/crypto/asn1/tasn_utl.c
+++ b/crypto/asn1/tasn_utl.c
@@ -120,6 +120,67 @@ int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it)
return ret;
}
+static ASN1_ENCODING *asn1_get_enc_ptr(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+ const ASN1_AUX *aux;
+ if(!pval || !*pval) return NULL;
+ aux = it->funcs;
+ if(!aux || !(aux->flags & ASN1_AFLG_ENCODING)) return NULL;
+ return offset2ptr(*pval, aux->enc_offset);
+}
+
+void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+ ASN1_ENCODING *enc;
+ enc = asn1_get_enc_ptr(pval, it);
+ if(enc) {
+ enc->enc = NULL;
+ enc->len = 0;
+ enc->modified = 1;
+ }
+}
+
+void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+ ASN1_ENCODING *enc;
+ enc = asn1_get_enc_ptr(pval, it);
+ if(enc) {
+ if(enc->enc) OPENSSL_free(enc->enc);
+ enc->enc = NULL;
+ enc->len = 0;
+ enc->modified = 1;
+ }
+}
+
+int asn1_enc_save(ASN1_VALUE **pval, unsigned char *in, int inlen, const ASN1_ITEM *it)
+{
+ ASN1_ENCODING *enc;
+ enc = asn1_get_enc_ptr(pval, it);
+ if(!enc) return 1;
+
+ if(enc->enc) OPENSSL_free(enc->enc);
+ enc->enc = OPENSSL_malloc(inlen);
+ if(!enc->enc) return 0;
+ memcpy(enc->enc, in, inlen);
+ enc->len = inlen;
+ enc->modified = 0;
+
+ return 1;
+}
+
+int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+ ASN1_ENCODING *enc;
+ enc = asn1_get_enc_ptr(pval, it);
+ if(!enc || enc->modified) return 0;
+ if(out) {
+ memcpy(*out, enc->enc, enc->len);
+ *out += enc->len;
+ }
+ if(len) *len = enc->len;
+ return 1;
+}
+
/* Given an ASN1_TEMPLATE get a pointer to a field */
ASN1_VALUE ** asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
{
diff --git a/crypto/asn1/x_req.c b/crypto/asn1/x_req.c
index 6dddd4f65..84a5ca65d 100644
--- a/crypto/asn1/x_req.c
+++ b/crypto/asn1/x_req.c
@@ -58,200 +58,54 @@
#include <stdio.h>
#include "cryptlib.h"
-#include <openssl/asn1_mac.h>
+#include <openssl/asn1t.h>
#include <openssl/x509.h>
-int i2d_X509_REQ_INFO(X509_REQ_INFO *a, unsigned char **pp)
- {
- M_ASN1_I2D_vars(a);
-
- if(a->asn1) {
- if(pp) {
- memcpy(*pp, a->asn1, a->length);
- *pp += a->length;
- }
- return a->length;
- }
-
- M_ASN1_I2D_len(a->version, i2d_ASN1_INTEGER);
- M_ASN1_I2D_len(a->subject, i2d_X509_NAME);
- M_ASN1_I2D_len(a->pubkey, i2d_X509_PUBKEY);
-
- /* this is a *nasty* hack reported to be required to
- * allow some CA Software to accept the cert request.
- * It is not following the PKCS standards ...
- * PKCS#10 pg 5
- * attributes [0] IMPLICIT Attributes
- * NOTE: no OPTIONAL ... so it *must* be there
- */
- if (a->req_kludge)
- {
- M_ASN1_I2D_len_IMP_SET_opt_type(X509_ATTRIBUTE,a->attributes,i2d_X509_ATTRIBUTE,0);
- }
- else
- {
- M_ASN1_I2D_len_IMP_SET_type(X509_ATTRIBUTE,a->attributes,
- i2d_X509_ATTRIBUTE,0);
- }
-
- M_ASN1_I2D_seq_total();
- M_ASN1_I2D_put(a->version, i2d_ASN1_INTEGER);
- M_ASN1_I2D_put(a->subject, i2d_X509_NAME);
- M_ASN1_I2D_put(a->pubkey, i2d_X509_PUBKEY);
+/* X509_REQ_INFO is handled in an unusual way to get round
+ * invalid encodings. Some broken certificate requests don't
+ * encode the attributes field if it is empty. This is in
+ * violation of PKCS#10 but we need to tolerate it. We do
+ * this by making the attributes field OPTIONAL then using
+ * the callback to initialise it to an empty STACK.
+ *
+ * This means that the field will be correctly encoded unless
+ * we NULL out the field.
+ *
+ * As a result we no longer need the req_kludge field because
+ * the information is now contained in the attributes field:
+ * 1. If it is NULL then it's the invalid omission.
+ * 2. If it is empty it is the correct encoding.
+ * 3. If it is not empty then some attributes are present.
+ *
+ */
- /* this is a *nasty* hack reported to be required by some CA's.
- * It is not following the PKCS standards ...
- * PKCS#10 pg 5
- * attributes [0] IMPLICIT Attributes
- * NOTE: no OPTIONAL ... so it *must* be there
- */
- if (a->req_kludge)
- {
- M_ASN1_I2D_put_IMP_SET_opt_type(X509_ATTRIBUTE,a->attributes,
- i2d_X509_ATTRIBUTE,0);
- }
- else
- {
- M_ASN1_I2D_put_IMP_SET_type(X509_ATTRIBUTE,a->attributes,
- i2d_X509_ATTRIBUTE,0);
- }
+static int rinf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+ X509_REQ_INFO *rinf = (X509_REQ_INFO *)*pval;
- M_ASN1_I2D_finish();
+ if(operation == ASN1_OP_NEW_POST) {
+ rinf->attributes = sk_X509_ATTRIBUTE_new_null();
+ if(!rinf->attributes) return 0;
}
-
-X509_REQ_INFO *d2i_X509_REQ_INFO(X509_REQ_INFO **a, unsigned char **pp,
- long length)
- {
- M_ASN1_D2I_vars(a,X509_REQ_INFO *,X509_REQ_INFO_new);
-
- M_ASN1_D2I_Init();
- M_ASN1_D2I_start_sequence();
- M_ASN1_D2I_get(ret->version,d2i_ASN1_INTEGER);
- M_ASN1_D2I_get(ret->subject,d2i_X509_NAME);
- M_ASN1_D2I_get(ret->pubkey,d2i_X509_PUBKEY);
-
- /* this is a *nasty* hack to allow for some CA's that
- * have been reported as requiring it.
- * It is not following the PKCS standards ...
- * PKCS#10 pg 5
- * attributes [0] IMPLICIT Attributes
- * NOTE: no OPTIONAL ... so it *must* be there
+ return 1;
+}
+
+ASN1_SEQUENCE_enc(X509_REQ_INFO, enc, rinf_cb) = {
+ ASN1_SIMPLE(X509_REQ_INFO, version, ASN1_INTEGER),
+ ASN1_SIMPLE(X509_REQ_INFO, subject, X509_NAME),
+ ASN1_SIMPLE(X509_REQ_INFO, pubkey, X509_PUBKEY),
+ /* This isn't really OPTIONAL but it gets round invalid
+ * encodings
*/
- if (asn1_Finish(&c))
- ret->req_kludge=1;
- else
- {
- M_ASN1_D2I_get_IMP_set_type(X509_ATTRIBUTE,ret->attributes,
- d2i_X509_ATTRIBUTE,
- X509_ATTRIBUTE_free,0);
- }
-
- M_ASN1_D2I_Finish(a,X509_REQ_INFO_free,ASN1_F_D2I_X509_REQ_INFO);
- }
-
-X509_REQ_INFO *X509_REQ_INFO_new(void)
- {
- X509_REQ_INFO *ret=NULL;
- ASN1_CTX c;
-
- M_ASN1_New_Malloc(ret,X509_REQ_INFO);
- M_ASN1_New(ret->version,M_ASN1_INTEGER_new);
- M_ASN1_New(ret->subject,X509_NAME_new);
- M_ASN1_New(ret->pubkey,X509_PUBKEY_new);
- M_ASN1_New(ret->attributes,sk_X509_ATTRIBUTE_new_null);
- ret->req_kludge=0;
- ret->asn1 = NULL;
- return(ret);
- M_ASN1_New_Error(ASN1_F_X509_REQ_INFO_NEW);
- }
-
-void X509_REQ_INFO_free(X509_REQ_INFO *a)
- {
- if (a == NULL) return;
- if(a->asn1) OPENSSL_free(a->asn1);
- M_ASN1_INTEGER_free(a->version);
- X509_NAME_free(a->subject);
- X509_PUBKEY_free(a->pubkey);
- sk_X509_ATTRIBUTE_pop_free(a->attributes,X509_ATTRIBUTE_free);
- OPENSSL_free(a);
- }
+ ASN1_IMP_SET_OF_OPT(X509_REQ_INFO, attributes, X509_ATTRIBUTE, 0)
+} ASN1_SEQUENCE_END_enc(X509_REQ_INFO, X509_REQ_INFO);
-int i2d_X509_REQ(X509_REQ *a, unsigned char **pp)
- {
- M_ASN1_I2D_vars(a);
- M_ASN1_I2D_len(a->req_info, i2d_X509_REQ_INFO);
- M_ASN1_I2D_len(a->sig_alg, i2d_X509_ALGOR);
- M_ASN1_I2D_len(a->signature, i2d_ASN1_BIT_STRING);
-
- M_ASN1_I2D_seq_total();
-
- M_ASN1_I2D_put(a->req_info, i2d_X509_REQ_INFO);
- M_ASN1_I2D_put(a->sig_alg, i2d_X509_ALGOR);
- M_ASN1_I2D_put(a->signature, i2d_ASN1_BIT_STRING);
-
- M_ASN1_I2D_finish();
- }
-
-X509_REQ *d2i_X509_REQ(X509_REQ **a, unsigned char **pp, long length)
- {
- M_ASN1_D2I_vars(a,X509_REQ *,X509_REQ_new);
-
- M_ASN1_D2I_Init();
- M_ASN1_D2I_start_sequence();
- M_ASN1_D2I_get(ret->req_info,d2i_X509_REQ_INFO);
-
- /* Keep a copy of the original encoding for signature checking */
- ret->req_info->length = c.p - c.q;
- if(!(ret->req_info->asn1 = OPENSSL_malloc(ret->req_info->length))) {
- c.line=__LINE__;
- c.error = ERR_R_MALLOC_FAILURE;
- goto err;
- }
-
- memcpy(ret->req_info->asn1, c.q, ret->req_info->length);
-
- M_ASN1_D2I_get(ret->sig_alg,d2i_X509_ALGOR);
- M_ASN1_D2I_get(ret->signature,d2i_ASN1_BIT_STRING);
- M_ASN1_D2I_Finish(a,X509_REQ_free,ASN1_F_D2I_X509_REQ);
- }
-
-X509_REQ *X509_REQ_new(void)
- {
- X509_REQ *ret=NULL;
- ASN1_CTX c;
-
- M_ASN1_New_Malloc(ret,X509_REQ);
- ret->references=1;
- M_ASN1_New(ret->req_info,X509_REQ_INFO_new);
- M_ASN1_New(ret->sig_alg,X509_ALGOR_new);
- M_ASN1_New(ret->signature,M_ASN1_BIT_STRING_new);
- return(ret);
- M_ASN1_New_Error(ASN1_F_X509_REQ_NEW);
- }
-
-void X509_REQ_free(X509_REQ *a)
- {
- int i;
-
- if (a == NULL) return;
-
- i=CRYPTO_add(&a->references,-1,CRYPTO_LOCK_X509_REQ);
-#ifdef REF_PRINT
- REF_PRINT("X509_REQ",a);
-#endif
- if (i > 0) return;
-#ifdef REF_CHECK
- if (i < 0)
- {
- fprintf(stderr,"X509_REQ_free, bad reference count\n");
- abort();
- }
-#endif
-
- X509_REQ_INFO_free(a->req_info);
- X509_ALGOR_free(a->sig_alg);
- M_ASN1_BIT_STRING_free(a->signature);
- OPENSSL_free(a);
- }
+IMPLEMENT_ASN1_FUNCTIONS(X509_REQ_INFO)
+ASN1_SEQUENCE_ref(X509_REQ, 0, CRYPTO_LOCK_X509_INFO) = {
+ ASN1_SIMPLE(X509_REQ, req_info, X509_REQ_INFO),
+ ASN1_SIMPLE(X509_REQ, sig_alg, X509_ALGOR),
+ ASN1_SIMPLE(X509_REQ, signature, ASN1_BIT_STRING)
+} ASN1_SEQUENCE_END_ref(X509_REQ, X509_REQ);
+IMPLEMENT_ASN1_FUNCTIONS(X509_REQ)
diff --git a/crypto/x509/x509.h b/crypto/x509/x509.h
index ef87b62a1..fc38277ca 100644
--- a/crypto/x509/x509.h
+++ b/crypto/x509/x509.h
@@ -204,16 +204,15 @@ typedef struct x509_attributes_st
DECLARE_STACK_OF(X509_ATTRIBUTE)
DECLARE_ASN1_SET_OF(X509_ATTRIBUTE)
+
typedef struct X509_req_info_st
{
- unsigned char *asn1;
- int length;
+ ASN1_ENCODING enc;
ASN1_INTEGER *version;
X509_NAME *subject;
X509_PUBKEY *pubkey;
/* d=2 hl=2 l= 0 cons: cont: 00 */
STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */
- int req_kludge;
} X509_REQ_INFO;
typedef struct X509_req_st
@@ -848,17 +847,8 @@ DSA * d2i_DSA_PUBKEY(DSA **a,unsigned char **pp,
#endif
DECLARE_ASN1_FUNCTIONS(X509_SIG)
-
-X509_REQ_INFO *X509_REQ_INFO_new(void);
-void X509_REQ_INFO_free(X509_REQ_INFO *a);
-int i2d_X509_REQ_INFO(X509_REQ_INFO *a,unsigned char **pp);
-X509_REQ_INFO *d2i_X509_REQ_INFO(X509_REQ_INFO **a,unsigned char **pp,
- long length);
-
-X509_REQ * X509_REQ_new(void);
-void X509_REQ_free(X509_REQ *a);
-int i2d_X509_REQ(X509_REQ *a,unsigned char **pp);
-X509_REQ * d2i_X509_REQ(X509_REQ **a,unsigned char **pp,long length);
+DECLARE_ASN1_FUNCTIONS(X509_REQ_INFO)
+DECLARE_ASN1_FUNCTIONS(X509_REQ)
DECLARE_ASN1_FUNCTIONS(X509_ATTRIBUTE)
X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value);