diff options
author | Dr. Stephen Henson <steve@openssl.org> | 2001-03-16 02:04:17 +0000 |
---|---|---|
committer | Dr. Stephen Henson <steve@openssl.org> | 2001-03-16 02:04:17 +0000 |
commit | 791bd0cd2b267d38fcbe7eb4dd3df2aa92877f11 (patch) | |
tree | 5fdf5eae1304f65185c74b4884bad7a33f8a2c32 /apps | |
parent | e890dcdb196aa2b971f3c85ccc94389bb01edb91 (diff) |
Add copy_extensions option to 'ca' utility.
Diffstat (limited to 'apps')
-rw-r--r-- | apps/apps.c | 56 | ||||
-rw-r--r-- | apps/apps.h | 6 | ||||
-rw-r--r-- | apps/ca.c | 84 | ||||
-rw-r--r-- | apps/openssl.cnf | 3 |
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 @@ -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 |