summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2001-03-16 02:04:17 +0000
committerDr. Stephen Henson <steve@openssl.org>2001-03-16 02:04:17 +0000
commit791bd0cd2b267d38fcbe7eb4dd3df2aa92877f11 (patch)
tree5fdf5eae1304f65185c74b4884bad7a33f8a2c32 /apps
parente890dcdb196aa2b971f3c85ccc94389bb01edb91 (diff)
Add copy_extensions option to 'ca' utility.
Diffstat (limited to 'apps')
-rw-r--r--apps/apps.c56
-rw-r--r--apps/apps.h6
-rw-r--r--apps/ca.c84
-rw-r--r--apps/openssl.cnf3
4 files changed, 102 insertions, 47 deletions
diff --git a/apps/apps.c b/apps/apps.c
index d8d9140075..4aeabdfa38 100644
--- a/apps/apps.c
+++ b/apps/apps.c
@@ -809,6 +809,62 @@ int set_name_ex(unsigned long *flags, const char *arg)
return set_multi_opts(flags, arg, ex_tbl);
}
+int set_ext_copy(int *copy_type, const char *arg)
+{
+ if (!strcasecmp(arg, "none"))
+ *copy_type = EXT_COPY_NONE;
+ else if (!strcasecmp(arg, "copy"))
+ *copy_type = EXT_COPY_ADD;
+ else if (!strcasecmp(arg, "copyall"))
+ *copy_type = EXT_COPY_ALL;
+ else
+ return 0;
+ return 1;
+}
+
+int copy_extensions(X509 *x, X509_REQ *req, int copy_type)
+{
+ STACK_OF(X509_EXTENSION) *exts = NULL;
+ X509_EXTENSION *ext, *tmpext;
+ ASN1_OBJECT *obj;
+ int i, idx, ret = 0;
+ if (!x || !req || (copy_type == EXT_COPY_NONE))
+ return 1;
+ exts = X509_REQ_get_extensions(req);
+
+ for(i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
+ ext = sk_X509_EXTENSION_value(exts, i);
+ obj = X509_EXTENSION_get_object(ext);
+ idx = X509_get_ext_by_OBJ(x, obj, -1);
+ /* Does extension exist? */
+ if (idx != -1) {
+ /* If normal copy don't override existing extension */
+ if (copy_type == EXT_COPY_ADD)
+ continue;
+ /* Delete all extensions of same type */
+ do {
+ tmpext = X509_get_ext(x, idx);
+ X509_delete_ext(x, idx);
+ X509_EXTENSION_free(tmpext);
+ idx = X509_get_ext_by_OBJ(x, obj, -1);
+ } while (idx != -1);
+ }
+ if (!X509_add_ext(x, ext, -1))
+ goto end;
+ }
+
+ ret = 1;
+
+ end:
+
+ sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
+
+ return ret;
+}
+
+
+
+
static int set_multi_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl)
{
STACK_OF(CONF_VALUE) *vals;
diff --git a/apps/apps.h b/apps/apps.h
index fb2e01b3a2..96dafd972d 100644
--- a/apps/apps.h
+++ b/apps/apps.h
@@ -153,6 +153,8 @@ void print_name(BIO *out, char *title, X509_NAME *nm, unsigned long lflags);
#endif
int set_cert_ex(unsigned long *flags, const char *arg);
int set_name_ex(unsigned long *flags, const char *arg);
+int set_ext_copy(int *copy_type, const char *arg);
+int copy_extensions(X509 *x, X509_REQ *req, int copy_type);
int app_passwd(BIO *err, char *arg1, char *arg2, char **pass1, char **pass2);
int add_oid_section(BIO *err, LHASH *conf);
X509 *load_cert(BIO *err, char *file, int format);
@@ -170,6 +172,10 @@ X509_STORE *setup_verify(BIO *bp, char *CAfile, char *CApath);
#define FORMAT_SMIME 6
#define FORMAT_ENGINE 7
+#define EXT_COPY_NONE 0
+#define EXT_COPY_ADD 1
+#define EXT_COPY_ALL 2
+
#define NETSCAPE_CERT_HDR "certificate"
#define APP_PASS_LEN 1024
diff --git a/apps/ca.c b/apps/ca.c
index 41850098b6..a37e33314e 100644
--- a/apps/ca.c
+++ b/apps/ca.c
@@ -134,6 +134,7 @@
#define ENV_MSIE_HACK "msie_hack"
#define ENV_NAMEOPT "name_opt"
#define ENV_CERTOPT "cert_opt"
+#define ENV_EXTCOPY "copy_extensions"
#define ENV_DATABASE "database"
@@ -303,7 +304,7 @@ int MAIN(int argc, char **argv)
int notext=0;
unsigned long nameopt = 0, certopt = 0;
int default_op = 1;
- int ext_copy = 0;
+ int ext_copy = EXT_COPY_NONE;
X509 *x509=NULL;
X509 *x=NULL;
BIO *in=NULL,*out=NULL,*Sout=NULL,*Cout=NULL;
@@ -798,6 +799,18 @@ bad:
else
ERR_clear_error();
+ f=CONF_get_string(conf,section,ENV_EXTCOPY);
+
+ if (f)
+ {
+ if (!set_ext_copy(&ext_copy, f))
+ {
+ BIO_printf(bio_err, "Invalid extension copy option: \"%s\"\n", f);
+ goto err;
+ }
+ }
+ else
+ ERR_clear_error();
/*****************************************************************/
/* lookup where to write new certificates */
@@ -1944,40 +1957,6 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
if (default_op)
old_entry_print(bio_err, obj, str);
-#if 0
- j=i2a_ASN1_OBJECT(bio_err,obj);
- pbuf=buf;
- for (j=22-j; j>0; j--)
- *(pbuf++)=' ';
- *(pbuf++)=':';
- *(pbuf++)='\0';
- BIO_puts(bio_err,buf);
-
- if (str->type == V_ASN1_PRINTABLESTRING)
- BIO_printf(bio_err,"PRINTABLE:'");
- else if (str->type == V_ASN1_T61STRING)
- BIO_printf(bio_err,"T61STRING:'");
- else if (str->type == V_ASN1_IA5STRING)
- BIO_printf(bio_err,"IA5STRING:'");
- else if (str->type == V_ASN1_UNIVERSALSTRING)
- BIO_printf(bio_err,"UNIVERSALSTRING:'");
- else
- BIO_printf(bio_err,"ASN.1 %2d:'",str->type);
-
- p=(char *)str->data;
- for (j=str->length; j>0; j--)
- {
- if ((*p >= ' ') && (*p <= '~'))
- BIO_printf(bio_err,"%c",*p);
- else if (*p & 0x80)
- BIO_printf(bio_err,"\\0x%02X",*p);
- else if ((unsigned char)*p == 0xf7)
- BIO_printf(bio_err,"^?");
- else BIO_printf(bio_err,"^%c",*p+'@');
- p++;
- }
- BIO_printf(bio_err,"'\n");
-#endif
}
/* Ok, now we check the 'policy' stuff. */
@@ -2171,7 +2150,6 @@ again2:
if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
goto err;
- BIO_printf(bio_err,"Certificate is to be certified until ");
if (strcmp(startdate,"today") == 0)
X509_gmtime_adj(X509_get_notBefore(ret),0);
else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate);
@@ -2180,10 +2158,6 @@ again2:
X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);
else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate);
- ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret));
- if (days) BIO_printf(bio_err," (%d days)",days);
- BIO_printf(bio_err, "\n");
-
if (!X509_set_subject_name(ret,subject)) goto err;
pktmp=X509_REQ_get_pubkey(req);
@@ -2251,16 +2225,32 @@ again2:
}
}
+ /* Copy extensions from request (if any) */
+
+ if (!copy_extensions(ret, req, ext_copy))
+ {
+ BIO_printf(bio_err, "ERROR: adding extensions from request\n");
+ ERR_print_errors(bio_err);
+ goto err;
+ }
+
+
+ if (!default_op)
+ {
+ BIO_printf(bio_err, "Certificate Details:\n");
+ /* Never print signature details because signature not present */
+ certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME;
+ X509_print_ex(bio_err, ret, nameopt, certopt);
+ }
+
+ BIO_printf(bio_err,"Certificate is to be certified until ");
+ ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret));
+ if (days) BIO_printf(bio_err," (%d days)",days);
+ BIO_printf(bio_err, "\n");
if (!batch)
{
- if (!default_op)
- {
- BIO_printf(bio_err, "Certificate Details:\n");
- /* Never print signature details because signature not present */
- certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME;
- X509_print_ex(bio_err, ret, nameopt, certopt);
- }
+
BIO_printf(bio_err,"Sign the certificate? [y/n]:");
(void)BIO_flush(bio_err);
buf[0]='\0';
diff --git a/apps/openssl.cnf b/apps/openssl.cnf
index f02b2bdf84..5071d858c5 100644
--- a/apps/openssl.cnf
+++ b/apps/openssl.cnf
@@ -53,6 +53,9 @@ x509_extensions = usr_cert # The extentions to add to the cert
name_opt = ca_default # Subject Name options
cert_opt = ca_default # Certificate field options
+# Extension copying option: use with caution.
+# copy_extensions = copy
+
# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
# so this is commented out by default to leave a V1 CRL.
# crl_extensions = crl_ext