aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/x509v3
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>1999-02-21 01:46:45 +0000
committerDr. Stephen Henson <steve@openssl.org>1999-02-21 01:46:45 +0000
commitaa066b9e6e44297a00e641e200bf48b5728ae5c3 (patch)
treefceb166c14070cc27c1da8156f3bf78c042bfc24 /crypto/x509v3
parenta67a9694f7fb5cf96cf0c370f3494111a05770be (diff)
downloadopenssl-aa066b9e6e44297a00e641e200bf48b5728ae5c3.tar.gz
Add more functionality to issuer alt name and subject alt name. New options
to include email addresses from DN and copy details from issuer certificate. Include examples in openssl.cnf, update Win32 ordinals.
Diffstat (limited to 'crypto/x509v3')
-rw-r--r--crypto/x509v3/v3_alt.c172
-rw-r--r--crypto/x509v3/v3_conf.c15
-rw-r--r--crypto/x509v3/v3err.c10
-rw-r--r--crypto/x509v3/x509v3.err10
-rw-r--r--crypto/x509v3/x509v3.h11
5 files changed, 212 insertions, 6 deletions
diff --git a/crypto/x509v3/v3_alt.c b/crypto/x509v3/v3_alt.c
index 0e8211b007..76f1b633c5 100644
--- a/crypto/x509v3/v3_alt.c
+++ b/crypto/x509v3/v3_alt.c
@@ -65,6 +65,18 @@
#include <conf.h>
#include "x509v3.h"
+#ifndef NOPROTO
+STACK *v2i_subject_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK *nval);
+STACK *v2i_issuer_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK *nval);
+static int copy_email(X509V3_CTX *ctx, STACK *gens);
+static int copy_issuer(X509V3_CTX *ctx, STACK *gens);
+#else
+STACK *v2i_issuer_alt();
+STACK *v2i_subject_alt();
+static int copy_email();
+static int copy_issuer();
+#endif
+
X509V3_EXT_METHOD v3_alt[] = {
{ NID_subject_alt_name, 0,
(X509V3_EXT_NEW)GENERAL_NAMES_new,
@@ -73,7 +85,7 @@ GENERAL_NAMES_free,
i2d_GENERAL_NAMES,
NULL, NULL,
(X509V3_EXT_I2V)i2v_GENERAL_NAMES,
-(X509V3_EXT_V2I)v2i_GENERAL_NAMES,
+(X509V3_EXT_V2I)v2i_subject_alt,
NULL, NULL},
{ NID_issuer_alt_name, 0,
(X509V3_EXT_NEW)GENERAL_NAMES_new,
@@ -82,7 +94,7 @@ GENERAL_NAMES_free,
i2d_GENERAL_NAMES,
NULL, NULL,
(X509V3_EXT_I2V)i2v_GENERAL_NAMES,
-(X509V3_EXT_V2I)v2i_GENERAL_NAMES,
+(X509V3_EXT_V2I)v2i_issuer_alt,
NULL, NULL},
EXT_END
};
@@ -158,6 +170,157 @@ STACK *ret;
return ret;
}
+STACK *v2i_issuer_alt(method, ctx, nval)
+X509V3_EXT_METHOD *method;
+X509V3_CTX *ctx;
+STACK *nval;
+{
+ STACK *gens = NULL;
+ CONF_VALUE *cnf;
+ int i;
+ if(!(gens = sk_new(NULL))) {
+ X509V3err(X509V3_F_V2I_GENERAL_NAMES,ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ for(i = 0; i < sk_num(nval); i++) {
+ cnf = (CONF_VALUE *)sk_value(nval, i);
+ if(!name_cmp(cnf->name, "issuer") && cnf->value &&
+ !strcmp(cnf->value, "copy")) {
+ if(!copy_issuer(ctx, gens)) goto err;
+ } else {
+ GENERAL_NAME *gen;
+ if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
+ goto err;
+ sk_push(gens, (char *)gen);
+ }
+ }
+ return gens;
+ err:
+ sk_pop_free(gens, GENERAL_NAME_free);
+ return NULL;
+}
+
+/* Append subject altname of issuer to issuer alt name of subject */
+
+static int copy_issuer(ctx, gens)
+X509V3_CTX *ctx;
+STACK *gens;
+{
+ STACK *ialt;
+ char *gen;
+ X509_EXTENSION *ext;
+ int i;
+ if(ctx && (ctx->flags == CTX_TEST)) return 1;
+ if(!ctx || !ctx->issuer_cert) {
+ X509V3err(X509V3_F_COPY_ISSUER,X509V3_R_NO_ISSUER_DETAILS);
+ goto err;
+ }
+ i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1);
+ if(i < 0) return 1;
+ if(!(ext = X509_get_ext(ctx->issuer_cert, i)) ||
+ !(ialt = (STACK *) X509V3_EXT_d2i(ext)) ) {
+ X509V3err(X509V3_F_COPY_ISSUER,X509V3_R_ISSUER_DECODE_ERROR);
+ goto err;
+ }
+
+ for(i = 0; i < sk_num(ialt); i++) {
+ gen = sk_value(ialt, i);
+ if(!sk_push(gens, gen)) {
+ X509V3err(X509V3_F_COPY_ISSUER,ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+ sk_free(ialt);
+
+ return 1;
+
+ err:
+ return 0;
+
+}
+
+STACK *v2i_subject_alt(method, ctx, nval)
+X509V3_EXT_METHOD *method;
+X509V3_CTX *ctx;
+STACK *nval;
+{
+ STACK *gens = NULL;
+ CONF_VALUE *cnf;
+ int i;
+ if(!(gens = sk_new(NULL))) {
+ X509V3err(X509V3_F_V2I_GENERAL_NAMES,ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ for(i = 0; i < sk_num(nval); i++) {
+ cnf = (CONF_VALUE *)sk_value(nval, i);
+ if(!name_cmp(cnf->name, "email") && cnf->value &&
+ !strcmp(cnf->value, "copy")) {
+ if(!copy_email(ctx, gens)) goto err;
+ } else {
+ GENERAL_NAME *gen;
+ if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
+ goto err;
+ sk_push(gens, (char *)gen);
+ }
+ }
+ return gens;
+ err:
+ sk_pop_free(gens, GENERAL_NAME_free);
+ return NULL;
+}
+
+/* Copy any email addresses in a certificate or request to
+ * GENERAL_NAMES
+ */
+
+static int copy_email(ctx, gens)
+X509V3_CTX *ctx;
+STACK *gens;
+{
+ X509_NAME *nm;
+ ASN1_IA5STRING *email = NULL;
+ X509_NAME_ENTRY *ne;
+ GENERAL_NAME *gen = NULL;
+ int i;
+ if(ctx->flags == CTX_TEST) return 1;
+ if(!ctx || (!ctx->subject_cert && !ctx->subject_req)) {
+ X509V3err(X509V3_F_COPY_EMAIL,X509V3_R_NO_SUBJECT_DETAILS);
+ goto err;
+ }
+ /* Find the subject name */
+ if(ctx->subject_cert) nm = X509_get_subject_name(ctx->subject_cert);
+ else nm = X509_REQ_get_subject_name(ctx->subject_req);
+
+ /* Now add any email address(es) to STACK */
+ i = -1;
+ while((i = X509_NAME_get_index_by_NID(nm,
+ NID_pkcs9_emailAddress, i)) > 0) {
+ ne = X509_NAME_get_entry(nm, i);
+ email = ASN1_IA5STRING_dup(X509_NAME_ENTRY_get_data(ne));
+ if(!email || !(gen = GENERAL_NAME_new())) {
+ X509V3err(X509V3_F_COPY_EMAIL,ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ gen->d.ia5 = email;
+ email = NULL;
+ gen->type = GEN_EMAIL;
+ if(!sk_push(gens, (char *)gen)) {
+ X509V3err(X509V3_F_COPY_EMAIL,ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ gen = NULL;
+ }
+
+
+ return 1;
+
+ err:
+ GENERAL_NAME_free(gen);
+ ASN1_IA5STRING_free(email);
+ return 0;
+
+}
+
STACK *v2i_GENERAL_NAMES(method, ctx, nval)
X509V3_EXT_METHOD *method;
X509V3_CTX *ctx;
@@ -196,6 +359,11 @@ char *name, *value;
name = cnf->name;
value = cnf->value;
+if(!value) {
+ X509V3err(X509V3_F_V2I_GENERAL_NAME,X509V3_R_MISSING_VALUE);
+ return NULL;
+}
+
if(!(gen = GENERAL_NAME_new())) {
X509V3err(X509V3_F_V2I_GENERAL_NAME,ERR_R_MALLOC_FAILURE);
return NULL;
diff --git a/crypto/x509v3/v3_conf.c b/crypto/x509v3/v3_conf.c
index a87af95f26..22ad348dee 100644
--- a/crypto/x509v3/v3_conf.c
+++ b/crypto/x509v3/v3_conf.c
@@ -85,10 +85,16 @@ char *value; /* Value */
{
int crit;
int ext_type;
+ X509_EXTENSION *ret;
crit = v3_check_critical(&value);
if((ext_type = v3_check_generic(&value)))
return v3_generic_extension(name, value, crit, ext_type);
- return do_ext_conf(conf, ctx, OBJ_sn2nid(name), crit, value);
+ ret = do_ext_conf(conf, ctx, OBJ_sn2nid(name), crit, value);
+ if(!ret) {
+ X509V3err(X509V3_F_X509V3_EXT_CONF,X509V3_R_ERROR_IN_EXTENSION);
+ ERR_add_error_data(4,"name=", name, ", value=", value);
+ }
+ return ret;
}
X509_EXTENSION *X509V3_EXT_conf_nid(conf, ctx, ext_nid, value)
@@ -120,9 +126,12 @@ char *value; /* Value */
char *ext_der, *p;
int ext_len;
ASN1_OCTET_STRING *ext_oct;
- if(ext_nid == NID_undef) return NULL;
+ if(ext_nid == NID_undef) {
+ X509V3err(X509V3_F_DO_EXT_CONF,X509V3_R_UNKNOWN_EXTENSION_NAME);
+ return NULL;
+ }
if(!(method = X509V3_EXT_get_nid(ext_nid))) {
- /* Add generic extension support here */
+ X509V3err(X509V3_F_DO_EXT_CONF,X509V3_R_UNKNOWN_EXTENSION);
return NULL;
}
/* Now get internal extension representation based on type */
diff --git a/crypto/x509v3/v3err.c b/crypto/x509v3/v3err.c
index cee230ec4f..ecf50c75ae 100644
--- a/crypto/x509v3/v3err.c
+++ b/crypto/x509v3/v3err.c
@@ -63,6 +63,9 @@
#ifndef NO_ERR
static ERR_STRING_DATA X509V3_str_functs[]=
{
+{ERR_PACK(0,X509V3_F_COPY_EMAIL,0), "COPY_EMAIL"},
+{ERR_PACK(0,X509V3_F_COPY_ISSUER,0), "COPY_ISSUER"},
+{ERR_PACK(0,X509V3_F_DO_EXT_CONF,0), "DO_EXT_CONF"},
{ERR_PACK(0,X509V3_F_HEX_TO_STRING,0), "hex_to_string"},
{ERR_PACK(0,X509V3_F_I2S_ASN1_ENUMERATED,0), "i2s_ASN1_ENUMERATED"},
{ERR_PACK(0,X509V3_F_I2S_ASN1_INTEGER,0), "i2s_ASN1_INTEGER"},
@@ -94,6 +97,7 @@ static ERR_STRING_DATA X509V3_str_reasons[]=
{X509V3_R_BAD_OBJECT ,"bad object"},
{X509V3_R_BN_DEC2BN_ERROR ,"bn dec2bn error"},
{X509V3_R_BN_TO_ASN1_INTEGER_ERROR ,"bn to asn1 integer error"},
+{X509V3_R_ERROR_IN_EXTENSION ,"error in extension"},
{X509V3_R_EXTENSION_NAME_ERROR ,"extension name error"},
{X509V3_R_EXTENSION_NOT_FOUND ,"extension not found"},
{X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED,"extension setting not supported"},
@@ -106,12 +110,18 @@ static ERR_STRING_DATA X509V3_str_reasons[]=
{X509V3_R_INVALID_NULL_NAME ,"invalid null name"},
{X509V3_R_INVALID_NULL_VALUE ,"invalid null value"},
{X509V3_R_INVALID_OBJECT_IDENTIFIER ,"invalid object identifier"},
+{X509V3_R_ISSUER_DECODE_ERROR ,"issuer decode error"},
+{X509V3_R_MISSING_VALUE ,"missing value"},
{X509V3_R_NO_ISSUER_CERTIFICATE ,"no issuer certificate"},
+{X509V3_R_NO_ISSUER_DETAILS ,"no issuer details"},
{X509V3_R_NO_PUBLIC_KEY ,"no public key"},
+{X509V3_R_NO_SUBJECT_DETAILS ,"no subject details"},
{X509V3_R_ODD_NUMBER_OF_DIGITS ,"odd number of digits"},
{X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS ,"unable to get issuer details"},
{X509V3_R_UNABLE_TO_GET_ISSUER_KEYID ,"unable to get issuer keyid"},
{X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT ,"unknown bit string argument"},
+{X509V3_R_UNKNOWN_EXTENSION ,"unknown extension"},
+{X509V3_R_UNKNOWN_EXTENSION_NAME ,"unknown extension name"},
{X509V3_R_UNKNOWN_OPTION ,"unknown option"},
{X509V3_R_UNSUPPORTED_OPTION ,"unsupported option"},
{0,NULL},
diff --git a/crypto/x509v3/x509v3.err b/crypto/x509v3/x509v3.err
index f389768680..0f1d948829 100644
--- a/crypto/x509v3/x509v3.err
+++ b/crypto/x509v3/x509v3.err
@@ -1,6 +1,9 @@
/* Error codes for the X509V3 functions. */
/* Function codes. */
+#define X509V3_F_COPY_EMAIL 122
+#define X509V3_F_COPY_ISSUER 123
+#define X509V3_F_DO_EXT_CONF 124
#define X509V3_F_HEX_TO_STRING 111
#define X509V3_F_I2S_ASN1_ENUMERATED 121
#define X509V3_F_I2S_ASN1_INTEGER 120
@@ -29,6 +32,7 @@
#define X509V3_R_BAD_OBJECT 119
#define X509V3_R_BN_DEC2BN_ERROR 100
#define X509V3_R_BN_TO_ASN1_INTEGER_ERROR 101
+#define X509V3_R_ERROR_IN_EXTENSION 128
#define X509V3_R_EXTENSION_NAME_ERROR 115
#define X509V3_R_EXTENSION_NOT_FOUND 102
#define X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED 103
@@ -41,11 +45,17 @@
#define X509V3_R_INVALID_NULL_NAME 108
#define X509V3_R_INVALID_NULL_VALUE 109
#define X509V3_R_INVALID_OBJECT_IDENTIFIER 110
+#define X509V3_R_ISSUER_DECODE_ERROR 126
+#define X509V3_R_MISSING_VALUE 124
#define X509V3_R_NO_ISSUER_CERTIFICATE 121
+#define X509V3_R_NO_ISSUER_DETAILS 127
#define X509V3_R_NO_PUBLIC_KEY 114
+#define X509V3_R_NO_SUBJECT_DETAILS 125
#define X509V3_R_ODD_NUMBER_OF_DIGITS 112
#define X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS 122
#define X509V3_R_UNABLE_TO_GET_ISSUER_KEYID 123
#define X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT 111
+#define X509V3_R_UNKNOWN_EXTENSION 129
+#define X509V3_R_UNKNOWN_EXTENSION_NAME 130
#define X509V3_R_UNKNOWN_OPTION 120
#define X509V3_R_UNSUPPORTED_OPTION 117
diff --git a/crypto/x509v3/x509v3.h b/crypto/x509v3/x509v3.h
index 73ac250b2c..b4aeaf68cf 100644
--- a/crypto/x509v3/x509v3.h
+++ b/crypto/x509v3/x509v3.h
@@ -237,7 +237,6 @@ int i2d_ext_ku(STACK *a, unsigned char **pp);
STACK *d2i_ext_ku(STACK **a, unsigned char **pp, long length);
void ext_ku_free(STACK *a);
STACK *ext_ku_new(void);
-
char *str_dup(char *val);
#ifdef HEADER_CONF_H
@@ -349,6 +348,9 @@ int X509V3_EXT_print_fp();
/* Error codes for the X509V3 functions. */
/* Function codes. */
+#define X509V3_F_COPY_EMAIL 122
+#define X509V3_F_COPY_ISSUER 123
+#define X509V3_F_DO_EXT_CONF 124
#define X509V3_F_HEX_TO_STRING 111
#define X509V3_F_I2S_ASN1_ENUMERATED 121
#define X509V3_F_I2S_ASN1_INTEGER 120
@@ -377,6 +379,7 @@ int X509V3_EXT_print_fp();
#define X509V3_R_BAD_OBJECT 119
#define X509V3_R_BN_DEC2BN_ERROR 100
#define X509V3_R_BN_TO_ASN1_INTEGER_ERROR 101
+#define X509V3_R_ERROR_IN_EXTENSION 128
#define X509V3_R_EXTENSION_NAME_ERROR 115
#define X509V3_R_EXTENSION_NOT_FOUND 102
#define X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED 103
@@ -389,12 +392,18 @@ int X509V3_EXT_print_fp();
#define X509V3_R_INVALID_NULL_NAME 108
#define X509V3_R_INVALID_NULL_VALUE 109
#define X509V3_R_INVALID_OBJECT_IDENTIFIER 110
+#define X509V3_R_ISSUER_DECODE_ERROR 126
+#define X509V3_R_MISSING_VALUE 124
#define X509V3_R_NO_ISSUER_CERTIFICATE 121
+#define X509V3_R_NO_ISSUER_DETAILS 127
#define X509V3_R_NO_PUBLIC_KEY 114
+#define X509V3_R_NO_SUBJECT_DETAILS 125
#define X509V3_R_ODD_NUMBER_OF_DIGITS 112
#define X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS 122
#define X509V3_R_UNABLE_TO_GET_ISSUER_KEYID 123
#define X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT 111
+#define X509V3_R_UNKNOWN_EXTENSION 129
+#define X509V3_R_UNKNOWN_EXTENSION_NAME 130
#define X509V3_R_UNKNOWN_OPTION 120
#define X509V3_R_UNSUPPORTED_OPTION 117