summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/ca.c1
-rw-r--r--apps/openssl.cnf12
-rw-r--r--crypto/asn1/asn1.h2
-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
-rwxr-xr-xutil/libeay.num3
9 files changed, 230 insertions, 6 deletions
diff --git a/apps/ca.c b/apps/ca.c
index 08f4146dca..76bbcbc2c5 100644
--- a/apps/ca.c
+++ b/apps/ca.c
@@ -695,6 +695,7 @@ bad:
BIO_printf(bio_err,
"Error Loading extension section %s\n",
extensions);
+ ret = 1;
goto err;
}
}
diff --git a/apps/openssl.cnf b/apps/openssl.cnf
index fbf0a1ba7f..7dee6432a8 100644
--- a/apps/openssl.cnf
+++ b/apps/openssl.cnf
@@ -132,6 +132,13 @@ nsComment = "OpenSSL Generated Certificate"
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer:always
+# Import the email address.
+
+subjectAltName=email:copy
+
+# Copy subject details
+
+issuerAltName=issuer:copy
#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
#nsBaseUrl
@@ -163,6 +170,11 @@ keyUsage = cRLSign, keyCertSign
# Some might want this also
#nsCertType = sslCA, emailCA
+# Include email address in subject alt name: another PKIX recommendation
+subjectAltName=email:copy
+# Copy issuer details
+issuerAltName=issuer:copy
+
# RAW DER hex encoding of an extension: beware experts only!
# 1.2.3.5=RAW:02:03
# You can even override a supported extension:
diff --git a/crypto/asn1/asn1.h b/crypto/asn1/asn1.h
index 0f74f40e65..9901d6bd89 100644
--- a/crypto/asn1/asn1.h
+++ b/crypto/asn1/asn1.h
@@ -328,6 +328,8 @@ typedef struct asn1_header_st
#define ASN1_IA5STRING_new() (ASN1_IA5STRING *)\
ASN1_STRING_type_new(V_ASN1_IA5STRING)
#define ASN1_IA5STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+#define ASN1_IA5STRING_dup(a) \
+ (ASN1_IA5STRING *)ASN1_STRING_dup((ASN1_STRING *)a)
#define M_i2d_ASN1_IA5STRING(a,pp) \
i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_IA5STRING,\
V_ASN1_UNIVERSAL)
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
diff --git a/util/libeay.num b/util/libeay.num
index ee5da522ae..54778768bb 100755
--- a/util/libeay.num
+++ b/util/libeay.num
@@ -1211,3 +1211,6 @@ v2i_GENERAL_NAMES 1236
i2s_ASN1_INTEGER 1237
X509V3_EXT_get_d2i 1238
name_cmp 1239
+str_dup 1240
+i2s_ASN1_ENUMERATED 1241
+i2s_ASN1_ENUMERATED_TABLE 1242