Commit 791bd0cd authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

Add copy_extensions option to 'ca' utility.

parent e890dcdb
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -3,6 +3,10 @@

 Changes between 0.9.6 and 0.9.7  [xx XXX 2000]

  *) Add a 'copy_extensions' option to the 'ca' utility. This copies
     extensions from a certificate request to the certificate.
     [Steve Henson]

  *) Allow multiple 'certopt' and 'nameopt' options to be separated
     by commas. Add 'namopt' and 'certopt' options to the 'ca' config
     file: this allows the display of the certificate about to be
+56 −0
Original line number Diff line number Diff line
@@ -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;
+6 −0
Original line number Diff line number Diff line
@@ -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
+37 −47
Original line number Diff line number Diff line
@@ -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,9 +2225,16 @@ again2:
			}
		}

	/* Copy extensions from request (if any) */

	if (!batch)
	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");
@@ -2261,6 +2242,15 @@ again2:
		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)
		{

		BIO_printf(bio_err,"Sign the certificate? [y/n]:");
		(void)BIO_flush(bio_err);
		buf[0]='\0';
+3 −0
Original line number Diff line number Diff line
@@ -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
Loading