From b2347661cef9447600a77b33575639a1bce6725c Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Tue, 26 Jan 1999 01:19:27 +0000 Subject: [PATCH] Still more X509 V3 stuff. Modify ca.c to work with the new code and modify openssl.cnf for the new syntax. --- CHANGES | 4 ++ apps/ca.c | 178 +++++++++++------------------------------------ apps/openssl.cnf | 47 ++++++++++--- apps/x509.c | 2 +- 4 files changed, 81 insertions(+), 150 deletions(-) diff --git a/CHANGES b/CHANGES index 1efdfb17e2..b09a2c5ba7 100644 --- a/CHANGES +++ b/CHANGES @@ -5,6 +5,10 @@ Changes between 0.9.1c and 0.9.2 + *) Modify the 'ca' program to handle the new extension code. Modify + openssl.cnf for new extension format, add comments. + [Steve Henson] + *) More X509 V3 changes. Fix typo in v3_bitstr.c. Add support to 'req' and add a sample to openssl.cnf so req -x509 now adds appropriate CA extensions. diff --git a/apps/ca.c b/apps/ca.c index 1ea90aa96a..ec8869ea0e 100644 --- a/apps/ca.c +++ b/apps/ca.c @@ -70,6 +70,7 @@ #include "txt_db.h" #include "evp.h" #include "x509.h" +#include "x509v3.h" #include "objects.h" #include "pem.h" #include "conf.h" @@ -154,7 +155,6 @@ extern int EF_ALIGNMENT; #endif #ifndef NOPROTO -static STACK *load_extensions(char *section); static void lookup_fail(char *name,char *tag); static int MS_CALLBACK key_callback(char *buf,int len,int verify); static unsigned long index_serial_hash(char **a); @@ -166,21 +166,21 @@ static BIGNUM *load_serial(char *serialfile); static int save_serial(char *serialfile, BIGNUM *serial); static int certify(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509, EVP_MD *dgst,STACK *policy,TXT_DB *db,BIGNUM *serial,char *startdate, - int days, int batch, STACK *extensions,int verbose); + int days, int batch, char *ext_sect, LHASH *conf,int verbose); static int certify_cert(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509, EVP_MD *dgst,STACK *policy,TXT_DB *db,BIGNUM *serial,char *startdate, - int days,int batch,STACK *extensions,int verbose); + int days,int batch,char *ext_sect, LHASH *conf,int verbose); static int certify_spkac(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509, EVP_MD *dgst,STACK *policy,TXT_DB *db,BIGNUM *serial,char *startdate, - int days,STACK *extensions,int verbose); + int days,char *ext_sect,LHASH *conf,int verbose); static int fix_data(int nid, int *type); static void write_new_certificate(BIO *bp, X509 *x, int output_der); static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, EVP_MD *dgst, STACK *policy, TXT_DB *db, BIGNUM *serial, char *startdate, - int days, int batch, int verbose, X509_REQ *req, STACK *extensions); + int days, int batch, int verbose, X509_REQ *req, char *ext_sect, + LHASH *conf); static int check_time_format(char *str); #else -static STACK *load_extensions(); static void lookup_fail(); static int MS_CALLBACK key_callback(); static unsigned long index_serial_hash(); @@ -251,7 +251,6 @@ char **argv; long l; EVP_MD *dgst=NULL; STACK *attribs=NULL; - STACK *extensions_sk=NULL; STACK *cert_sk=NULL; BIO *hex=NULL; #undef BSIZE @@ -266,7 +265,7 @@ EF_ALIGNMENT=0; apps_startup(); - X509v3_add_netscape_extensions(); + X509V3_add_standard_extensions(); preserve=0; if (bio_err == NULL) @@ -688,12 +687,17 @@ bad: goto err; } - if ((extensions=CONF_get_string(conf,section,ENV_EXTENSIONS)) - != NULL) - { - if ((extensions_sk=load_extensions(extensions)) == NULL) + extensions=CONF_get_string(conf,section,ENV_EXTENSIONS); + if(!extensions) { + + /* Check syntax of file */ + if(!X509V3_EXT_add_conf(conf, NULL, extensions, NULL)) { + BIO_printf(bio_err, + "Error Loading extension section %s\n", + extensions); goto err; } + } if (startdate == NULL) { @@ -749,7 +753,7 @@ bad: { total++; j=certify_spkac(&x,spkac_file,pkey,x509,dgst,attribs,db, - serial,startdate,days,extensions_sk,verbose); + serial,startdate,days,extensions,conf,verbose); if (j < 0) goto err; if (j > 0) { @@ -773,7 +777,7 @@ bad: total++; j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,attribs, db,serial,startdate,days,batch, - extensions_sk,verbose); + extensions,conf,verbose); if (j < 0) goto err; if (j > 0) { @@ -792,7 +796,7 @@ bad: total++; j=certify(&x,infile,pkey,x509,dgst,attribs,db, serial,startdate,days,batch, - extensions_sk,verbose); + extensions,conf,verbose); if (j < 0) goto err; if (j > 0) { @@ -811,7 +815,7 @@ bad: total++; j=certify(&x,argv[i],pkey,x509,dgst,attribs,db, serial,startdate,days,batch, - extensions_sk,verbose); + extensions,conf,verbose); if (j < 0) goto err; if (j > 0) { @@ -1046,8 +1050,6 @@ err: if (in != NULL) BIO_free(in); if (cert_sk != NULL) sk_pop_free(cert_sk,X509_free); - if (extensions_sk != NULL) - sk_pop_free(extensions_sk,X509_EXTENSION_free); if (ret) ERR_print_errors(bio_err); if (serial != NULL) BN_free(serial); @@ -1056,7 +1058,7 @@ err: if (x509 != NULL) X509_free(x509); if (crl != NULL) X509_CRL_free(crl); if (conf != NULL) CONF_free(conf); - X509v3_cleanup_extensions(); + X509V3_EXT_cleanup(); EXIT(ret); } @@ -1188,7 +1190,7 @@ err: } static int certify(xret,infile,pkey,x509,dgst,policy,db,serial,startdate,days, - batch,extensions,verbose) + batch,ext_sect,conf,verbose) X509 **xret; char *infile; EVP_PKEY *pkey; @@ -1200,7 +1202,8 @@ BIGNUM *serial; char *startdate; int days; int batch; -STACK *extensions; +char *ext_sect; +LHASH *conf; int verbose; { X509_REQ *req=NULL; @@ -1249,7 +1252,7 @@ int verbose; BIO_printf(bio_err,"Signature ok\n"); ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate, - days,batch,verbose,req,extensions); + days,batch,verbose,req,ext_sect,conf); err: if (req != NULL) X509_REQ_free(req); @@ -1258,7 +1261,7 @@ err: } static int certify_cert(xret,infile,pkey,x509,dgst,policy,db,serial,startdate, - days, batch,extensions,verbose) + days, batch,ext_sect,conf,verbose) X509 **xret; char *infile; EVP_PKEY *pkey; @@ -1270,7 +1273,8 @@ BIGNUM *serial; char *startdate; int days; int batch; -STACK *extensions; +char *ext_sect; +LHASH *conf; int verbose; { X509 *req=NULL; @@ -1322,7 +1326,7 @@ int verbose; goto err; ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,days, - batch,verbose,rreq,extensions); + batch,verbose,rreq,ext_sect,conf); err: if (rreq != NULL) X509_REQ_free(rreq); @@ -1332,7 +1336,7 @@ err: } static int do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,days, - batch,verbose,req, extensions) + batch,verbose,req, ext_sect,conf) X509 **xret; EVP_PKEY *pkey; X509 *x509; @@ -1345,7 +1349,8 @@ int days; int batch; int verbose; X509_REQ *req; -STACK *extensions; +char *ext_sect; +LHASH *conf; { X509_NAME *name=NULL,*CAname=NULL,*subject=NULL; ASN1_UTCTIME *tm,*tmptm; @@ -1355,7 +1360,6 @@ STACK *extensions; X509_CINF *ci; X509_NAME_ENTRY *ne; X509_NAME_ENTRY *tne,*push; - X509_EXTENSION *ex=NULL; EVP_PKEY *pktmp; int ok= -1,i,j,last,nid; char *p; @@ -1662,7 +1666,7 @@ again2: if (!i) goto err; /* Lets add the extensions, if there are any */ - if ((extensions != NULL) && (sk_num(extensions) > 0)) + if (ext_sect) { if (ci->version == NULL) if ((ci->version=ASN1_INTEGER_new()) == NULL) @@ -1674,17 +1678,10 @@ again2: if (ci->extensions != NULL) sk_pop_free(ci->extensions,X509_EXTENSION_free); - if ((ci->extensions=sk_new_null()) == NULL) - goto err; + ci->extensions = NULL; + + if(!X509V3_EXT_add_conf(conf, NULL, ext_sect, ret)) goto err; - /* Lets 'copy' in the new ones */ - for (i=0; iextensions,(char *)ex)) goto err; - } } @@ -1807,7 +1804,7 @@ int output_der; } static int certify_spkac(xret,infile,pkey,x509,dgst,policy,db,serial, - startdate,days,extensions,verbose) + startdate,days,ext_sect,conf,verbose) X509 **xret; char *infile; EVP_PKEY *pkey; @@ -1818,7 +1815,8 @@ TXT_DB *db; BIGNUM *serial; char *startdate; int days; -STACK *extensions; +char *ext_sect; +LHASH *conf; int verbose; { STACK *sk=NULL; @@ -1964,7 +1962,7 @@ int verbose; X509_REQ_set_pubkey(req,pktmp); EVP_PKEY_free(pktmp); ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate, - days,1,verbose,req,extensions); + days,1,verbose,req,ext_sect,conf); err: if (req != NULL) X509_REQ_free(req); if (parms != NULL) CONF_free(parms); @@ -1992,102 +1990,6 @@ int *type; return(1); } - -static STACK *load_extensions(sec) -char *sec; - { - STACK *ext; - STACK *ret=NULL; - CONF_VALUE *cv; - ASN1_OCTET_STRING *str=NULL; - ASN1_STRING *tmp=NULL; - X509_EXTENSION *x; - BIO *mem=NULL; - BUF_MEM *buf=NULL; - int i,nid,len; - unsigned char *ptr; - int pack_type; - int data_type; - - if ((ext=CONF_get_section(conf,sec)) == NULL) - { - BIO_printf(bio_err,"unable to find extension section called '%s'\n",sec); - return(NULL); - } - - if ((ret=sk_new_null()) == NULL) return(NULL); - - for (i=0; iname)) == NID_undef) - { - BIO_printf(bio_err,"%s:unknown object type in section, '%s'\n",sec,cv->name); - goto err; - } - - pack_type=X509v3_pack_type_by_NID(nid); - data_type=X509v3_data_type_by_NID(nid); - - /* pack up the input bytes */ - ptr=(unsigned char *)cv->value; - len=strlen((char *)ptr); - if ((len > 2) && (cv->value[0] == '0') && - (cv->value[1] == 'x')) - { - if (data_type == V_ASN1_UNDEF) - { - BIO_printf(bio_err,"data type for extension %s is unknown\n",cv->name); - goto err; - } - if (mem == NULL) - if ((mem=BIO_new(BIO_s_mem())) == NULL) - goto err; - if (((buf=BUF_MEM_new()) == NULL) || - !BUF_MEM_grow(buf,128)) - goto err; - if ((tmp=ASN1_STRING_new()) == NULL) goto err; - - BIO_reset(mem); - BIO_write(mem,(char *)&(ptr[2]),len-2); - if (!a2i_ASN1_STRING(mem,tmp,buf->data,buf->max)) - goto err; - len=tmp->length; - ptr=tmp->data; - } - - switch (pack_type) - { - case X509_EXT_PACK_STRING: - if ((str=X509v3_pack_string(&str, - data_type,ptr,len)) == NULL) - goto err; - break; - case X509_EXT_PACK_UNKNOWN: - default: - BIO_printf(bio_err,"Don't know how to pack extension %s\n",cv->name); - goto err; - /* break; */ - } - - if ((x=X509_EXTENSION_create_by_NID(NULL,nid,0,str)) == NULL) - goto err; - sk_push(ret,(char *)x); - } - - if (0) - { -err: - if (ret != NULL) sk_pop_free(ret,X509_EXTENSION_free); - ret=NULL; - } - if (str != NULL) ASN1_OCTET_STRING_free(str); - if (tmp != NULL) ASN1_STRING_free(tmp); - if (buf != NULL) BUF_MEM_free(buf); - if (mem != NULL) BIO_free(mem); - return(ret); - } - static int check_time_format(str) char *str; { diff --git a/apps/openssl.cnf b/apps/openssl.cnf index fbc328fad4..27abc08bad 100644 --- a/apps/openssl.cnf +++ b/apps/openssl.cnf @@ -25,7 +25,7 @@ crl = $dir/crl.pem # The current CRL private_key = $dir/private/cakey.pem# The private key RANDFILE = $dir/private/.rand # private random number file -x509_extensions = x509v3_extensions # The extentions to add to the cert +x509_extensions = usr_cert # The extentions to add to the cert default_days = 365 # how long to certify for default_crl_days= 30 # how long before next CRL default_md = md5 # which md to use. @@ -63,7 +63,7 @@ default_bits = 1024 default_keyfile = privkey.pem distinguished_name = req_distinguished_name attributes = req_attributes -x509_extensions = v3_ca # The extentions to add to the cert +x509_extensions = v3_ca # The extentions to add to the self signed cert [ req_distinguished_name ] countryName = Country Name (2 letter code) @@ -101,28 +101,53 @@ challengePassword_max = 20 unstructuredName = An optional company name -[ x509v3_extensions ] +[ usr_cert ] -nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem -nsComment = "This is a comment" +# These extensions are added when 'ca' signs a request. -# under ASN.1, the 0 bit would be encoded as 80 -nsCertType = 0x40 +# This goes against PKIX guidelines but some CAs do it and some software +# requires this to avoid interpreting an end user certificate as a CA. +basicConstraints=CA:FALSE + +# Here are some examples of the usage of nsCertType. If it is omitted +# the certificate can be used for anything *except* object signing. + +# This is OK for an SSL server. +#nsCertType = server + +# For an object signing certificate this would be used. +#nsCertType = objsign + +# For normal client use this is typical +#nsCertType = client, email + +# This is typical also + +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +nsComment = "OpenSSL Generated Certificate" + +#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem #nsBaseUrl #nsRevocationUrl #nsRenewalUrl #nsCaPolicyUrl #nsSslServerName -#nsCertSequence -#nsCertExt -#nsDataType [ v3_ca] # Extensions for a typical CA +# It's a CA certificate basicConstraints = CA:true -keyUsage = cRLSign, keyCertSign +# This is what PKIX recommends but some broken software chokes on critical +# extensions. +#basicConstraints = critical,CA:true + +# Key usage: again this should really be critical. +keyUsage = cRLSign, keyCertSign +# Some might want this also +#nsCertType = sslCA, emailCA diff --git a/apps/x509.c b/apps/x509.c index b375ffe32f..c4e4890999 100644 --- a/apps/x509.c +++ b/apps/x509.c @@ -694,7 +694,7 @@ end: if (Upkey != NULL) EVP_PKEY_free(Upkey); if (CApkey != NULL) EVP_PKEY_free(CApkey); if (rq != NULL) X509_REQ_free(rq); - X509v3_cleanup_extensions(); + X509V3_EXT_cleanup(); EXIT(ret); } -- 2.34.1