Still more X509 V3 stuff. Modify ca.c to work with the new code and modify
openssl.cnf for the new syntax.
This commit is contained in:
parent
fd9d35f56e
commit
b2347661ce
4
CHANGES
4
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.
|
||||
|
178
apps/ca.c
178
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; i<sk_num(extensions); i++)
|
||||
{
|
||||
ex=X509_EXTENSION_dup((X509_EXTENSION *)
|
||||
sk_value(extensions,i));
|
||||
if (ex == NULL) goto err;
|
||||
if (!sk_push(ci->extensions,(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; i<sk_num(ext); i++)
|
||||
{
|
||||
cv=(CONF_VALUE *)sk_value(ext,i); /* get the object id */
|
||||
if ((nid=OBJ_txt2nid(cv->name)) == 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;
|
||||
{
|
||||
|
@ -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
|
||||
|
||||
# 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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user