mirror of
https://github.com/openssl/openssl.git
synced 2025-01-30 14:01:55 +08:00
Implement self-signing in 'openssl ca'. This makes it easier to have
the CA certificate part of the CA database, and combined with 'unique_subject=no', it should make operations like CA certificate roll-over easier.
This commit is contained in:
parent
e6526fbf4d
commit
16b1b03543
7
CHANGES
7
CHANGES
@ -4,6 +4,13 @@
|
||||
|
||||
Changes between 0.9.7a and 0.9.8 [xx XXX xxxx]
|
||||
|
||||
*) Make it possible to create self-signed certificates with 'openssl ca'
|
||||
in such a way that the self-signed certificate becomes part of the
|
||||
CA database and uses the same mechanisms for serial number generation
|
||||
as all other certificate signing. The new flag '-selfsign' enables
|
||||
this functionality. Adapt CA.sh and CA.pl.in.
|
||||
[Richard Levitte]
|
||||
|
||||
*) Add functionality to check the public key of a certificate request
|
||||
against a given private. This is useful to check that a certificate
|
||||
request can be signed by that key (self-signing).
|
||||
|
@ -37,7 +37,8 @@
|
||||
# demoCA ... where everything is stored
|
||||
|
||||
$SSLEAY_CONFIG=$ENV{"SSLEAY_CONFIG"};
|
||||
$DAYS="-days 365";
|
||||
$DAYS="-days 365"; # 1 year
|
||||
$CADAYS="-days 1095"; # 3 years
|
||||
$REQ="openssl req $SSLEAY_CONFIG";
|
||||
$CA="openssl ca $SSLEAY_CONFIG";
|
||||
$VERIFY="openssl verify";
|
||||
@ -46,6 +47,7 @@ $PKCS12="openssl pkcs12";
|
||||
|
||||
$CATOP="./demoCA";
|
||||
$CAKEY="cakey.pem";
|
||||
$CAREQ="careq.pem";
|
||||
$CACERT="cacert.pem";
|
||||
|
||||
$DIRMODE = 0777;
|
||||
@ -101,8 +103,11 @@ foreach (@ARGV) {
|
||||
$RET=$?;
|
||||
} else {
|
||||
print "Making CA certificate ...\n";
|
||||
system ("$REQ -new -x509 -keyout " .
|
||||
"${CATOP}/private/$CAKEY -out ${CATOP}/$CACERT $DAYS");
|
||||
system ("$REQ -new -keyout " .
|
||||
"${CATOP}/private/$CAKEY -out ${CATOP}/$CAREQ");
|
||||
system ("$CA -out ${CATOP}/$CACERT $CADAYS -batch " .
|
||||
"-keyfile ${CATOP}/private/$CAKEY -selfsign " .
|
||||
"-infiles ${CATOP}/$CAREQ ");
|
||||
$RET=$?;
|
||||
}
|
||||
}
|
||||
|
13
apps/CA.sh
13
apps/CA.sh
@ -30,7 +30,8 @@
|
||||
# default openssl.cnf file has setup as per the following
|
||||
# demoCA ... where everything is stored
|
||||
|
||||
DAYS="-days 365"
|
||||
DAYS="-days 365" # 1 year
|
||||
CADAYS="-days 1095" # 3 years
|
||||
REQ="openssl req $SSLEAY_CONFIG"
|
||||
CA="openssl ca $SSLEAY_CONFIG"
|
||||
VERIFY="openssl verify"
|
||||
@ -38,6 +39,7 @@ X509="openssl x509"
|
||||
|
||||
CATOP=./demoCA
|
||||
CAKEY=./cakey.pem
|
||||
CAREQ=./careq.pem
|
||||
CACERT=./cacert.pem
|
||||
|
||||
for i
|
||||
@ -70,7 +72,7 @@ case $i in
|
||||
mkdir ${CATOP}/crl
|
||||
mkdir ${CATOP}/newcerts
|
||||
mkdir ${CATOP}/private
|
||||
echo "01" > ${CATOP}/serial
|
||||
echo "00" > ${CATOP}/serial
|
||||
touch ${CATOP}/index.txt
|
||||
fi
|
||||
if [ ! -f ${CATOP}/private/$CAKEY ]; then
|
||||
@ -83,8 +85,11 @@ case $i in
|
||||
RET=$?
|
||||
else
|
||||
echo "Making CA certificate ..."
|
||||
$REQ -new -x509 -keyout ${CATOP}/private/$CAKEY \
|
||||
-out ${CATOP}/$CACERT $DAYS
|
||||
$REQ -new -keyout ${CATOP}/private/$CAKEY \
|
||||
-out ${CATOP}/$CAREQ
|
||||
$CA -out ${CATOP}/$CACERT $CADAYS -batch \
|
||||
-keyfile ${CATOP}/private/$CAKEY -selfsign \
|
||||
-infiles ${CATOP}/$CAREQ
|
||||
RET=$?
|
||||
fi
|
||||
fi
|
||||
|
90
apps/ca.c
90
apps/ca.c
@ -204,7 +204,7 @@ static int certify(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
|
||||
BIGNUM *serial, char *subj, int email_dn, char *startdate,
|
||||
char *enddate, long days, int batch, char *ext_sect, CONF *conf,
|
||||
int verbose, unsigned long certopt, unsigned long nameopt,
|
||||
int default_op, int ext_copy);
|
||||
int default_op, int ext_copy, int selfsign);
|
||||
static int certify_cert(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
|
||||
const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
|
||||
CA_DB *db, BIGNUM *serial, char *subj, int email_dn,
|
||||
@ -225,7 +225,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
|
||||
int email_dn, char *startdate, char *enddate, long days, int batch,
|
||||
int verbose, X509_REQ *req, char *ext_sect, CONF *conf,
|
||||
unsigned long certopt, unsigned long nameopt, int default_op,
|
||||
int ext_copy);
|
||||
int ext_copy, int selfsign);
|
||||
static int do_revoke(X509 *x509, CA_DB *db, int ext, char *extval);
|
||||
static int get_certificate_status(const char *ser_status, CA_DB *db);
|
||||
static int do_updatedb(CA_DB *db);
|
||||
@ -292,7 +292,8 @@ int MAIN(int argc, char **argv)
|
||||
unsigned long nameopt = 0, certopt = 0;
|
||||
int default_op = 1;
|
||||
int ext_copy = EXT_COPY_NONE;
|
||||
X509 *x509=NULL;
|
||||
int selfsign = 0;
|
||||
X509 *x509=NULL, *x509p = NULL;
|
||||
X509 *x=NULL;
|
||||
BIO *in=NULL,*out=NULL,*Sout=NULL,*Cout=NULL;
|
||||
char *dbfile=NULL;
|
||||
@ -406,6 +407,8 @@ EF_ALIGNMENT=0;
|
||||
if (--argc < 1) goto bad;
|
||||
certfile= *(++argv);
|
||||
}
|
||||
else if (strcmp(*argv,"-selfsign") == 0)
|
||||
selfsign=1;
|
||||
else if (strcmp(*argv,"-in") == 0)
|
||||
{
|
||||
if (--argc < 1) goto bad;
|
||||
@ -700,7 +703,7 @@ bad:
|
||||
}
|
||||
|
||||
/*****************************************************************/
|
||||
/* we definitely need a public key, so let's get it */
|
||||
/* we definitely need a private key, so let's get it */
|
||||
|
||||
if ((keyfile == NULL) && ((keyfile=NCONF_get_string(conf,
|
||||
section,ENV_PRIVATE_KEY)) == NULL))
|
||||
@ -728,22 +731,27 @@ bad:
|
||||
|
||||
/*****************************************************************/
|
||||
/* we need a certificate */
|
||||
if ((certfile == NULL) && ((certfile=NCONF_get_string(conf,
|
||||
section,ENV_CERTIFICATE)) == NULL))
|
||||
if (!selfsign || spkac_file || ss_cert_file || gencrl)
|
||||
{
|
||||
lookup_fail(section,ENV_CERTIFICATE);
|
||||
goto err;
|
||||
}
|
||||
x509=load_cert(bio_err, certfile, FORMAT_PEM, NULL, e,
|
||||
"CA certificate");
|
||||
if (x509 == NULL)
|
||||
goto err;
|
||||
if ((certfile == NULL)
|
||||
&& ((certfile=NCONF_get_string(conf,
|
||||
section,ENV_CERTIFICATE)) == NULL))
|
||||
{
|
||||
lookup_fail(section,ENV_CERTIFICATE);
|
||||
goto err;
|
||||
}
|
||||
x509=load_cert(bio_err, certfile, FORMAT_PEM, NULL, e,
|
||||
"CA certificate");
|
||||
if (x509 == NULL)
|
||||
goto err;
|
||||
|
||||
if (!X509_check_private_key(x509,pkey))
|
||||
{
|
||||
BIO_printf(bio_err,"CA certificate and CA private key do not match\n");
|
||||
goto err;
|
||||
if (!X509_check_private_key(x509,pkey))
|
||||
{
|
||||
BIO_printf(bio_err,"CA certificate and CA private key do not match\n");
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
if (!selfsign) x509p = x509;
|
||||
|
||||
f=NCONF_get_string(conf,BASE_SECTION,ENV_PRESERVE);
|
||||
if (f == NULL)
|
||||
@ -1175,10 +1183,10 @@ bad:
|
||||
if (infile != NULL)
|
||||
{
|
||||
total++;
|
||||
j=certify(&x,infile,pkey,x509,dgst,attribs,db,
|
||||
j=certify(&x,infile,pkey,x509p,dgst,attribs,db,
|
||||
serial,subj,email_dn,startdate,enddate,days,batch,
|
||||
extensions,conf,verbose, certopt, nameopt,
|
||||
default_op, ext_copy);
|
||||
default_op, ext_copy, selfsign);
|
||||
if (j < 0) goto err;
|
||||
if (j > 0)
|
||||
{
|
||||
@ -1195,10 +1203,10 @@ bad:
|
||||
for (i=0; i<argc; i++)
|
||||
{
|
||||
total++;
|
||||
j=certify(&x,argv[i],pkey,x509,dgst,attribs,db,
|
||||
j=certify(&x,argv[i],pkey,x509p,dgst,attribs,db,
|
||||
serial,subj,email_dn,startdate,enddate,days,batch,
|
||||
extensions,conf,verbose, certopt, nameopt,
|
||||
default_op, ext_copy);
|
||||
default_op, ext_copy, selfsign);
|
||||
if (j < 0) goto err;
|
||||
if (j > 0)
|
||||
{
|
||||
@ -1515,7 +1523,7 @@ err:
|
||||
BN_free(serial);
|
||||
free_index(db);
|
||||
EVP_PKEY_free(pkey);
|
||||
X509_free(x509);
|
||||
if (x509) X509_free(x509);
|
||||
X509_CRL_free(crl);
|
||||
NCONF_free(conf);
|
||||
OBJ_cleanup();
|
||||
@ -1533,7 +1541,7 @@ static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
|
||||
BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
|
||||
long days, int batch, char *ext_sect, CONF *lconf, int verbose,
|
||||
unsigned long certopt, unsigned long nameopt, int default_op,
|
||||
int ext_copy)
|
||||
int ext_copy, int selfsign)
|
||||
{
|
||||
X509_REQ *req=NULL;
|
||||
BIO *in=NULL;
|
||||
@ -1558,6 +1566,12 @@ static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
|
||||
|
||||
BIO_printf(bio_err,"Check that the request matches the signature\n");
|
||||
|
||||
if (selfsign && !X509_REQ_check_private_key(req,pkey))
|
||||
{
|
||||
BIO_printf(bio_err,"Certificate request and CA private key do not match\n");
|
||||
ok=0;
|
||||
goto err;
|
||||
}
|
||||
if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)
|
||||
{
|
||||
BIO_printf(bio_err,"error unpacking public key\n");
|
||||
@ -1582,7 +1596,7 @@ static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
|
||||
|
||||
ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj, email_dn,
|
||||
startdate,enddate,days,batch,verbose,req,ext_sect,lconf,
|
||||
certopt, nameopt, default_op, ext_copy);
|
||||
certopt, nameopt, default_op, ext_copy, selfsign);
|
||||
|
||||
err:
|
||||
if (req != NULL) X509_REQ_free(req);
|
||||
@ -1636,7 +1650,7 @@ static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
|
||||
|
||||
ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,email_dn,startdate,enddate,
|
||||
days,batch,verbose,rreq,ext_sect,lconf, certopt, nameopt, default_op,
|
||||
ext_copy);
|
||||
ext_copy, 0);
|
||||
|
||||
err:
|
||||
if (rreq != NULL) X509_REQ_free(rreq);
|
||||
@ -1649,7 +1663,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
|
||||
int email_dn, char *startdate, char *enddate, long days, int batch,
|
||||
int verbose, X509_REQ *req, char *ext_sect, CONF *lconf,
|
||||
unsigned long certopt, unsigned long nameopt, int default_op,
|
||||
int ext_copy)
|
||||
int ext_copy, int selfsign)
|
||||
{
|
||||
X509_NAME *name=NULL,*CAname=NULL,*subject=NULL, *dn_subject=NULL;
|
||||
ASN1_UTCTIME *tm,*tmptm;
|
||||
@ -1753,7 +1767,10 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
|
||||
}
|
||||
|
||||
/* take a copy of the issuer name before we mess with it. */
|
||||
CAname=X509_NAME_dup(x509->cert_info->subject);
|
||||
if (selfsign)
|
||||
CAname=X509_NAME_dup(name);
|
||||
else
|
||||
CAname=X509_NAME_dup(x509->cert_info->subject);
|
||||
if (CAname == NULL) goto err;
|
||||
str=str2=NULL;
|
||||
|
||||
@ -1965,8 +1982,16 @@ again2:
|
||||
|
||||
if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL)
|
||||
goto err;
|
||||
if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
|
||||
goto err;
|
||||
if (selfsign)
|
||||
{
|
||||
if (!X509_set_issuer_name(ret,subject))
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (strcmp(startdate,"today") == 0)
|
||||
X509_gmtime_adj(X509_get_notBefore(ret),0);
|
||||
@ -2001,7 +2026,10 @@ again2:
|
||||
ci->extensions = NULL;
|
||||
|
||||
/* Initialize the context structure */
|
||||
X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
|
||||
if (selfsign)
|
||||
X509V3_set_ctx(&ctx, ret, ret, req, NULL, 0);
|
||||
else
|
||||
X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
|
||||
|
||||
if (extconf)
|
||||
{
|
||||
@ -2344,7 +2372,7 @@ static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
|
||||
EVP_PKEY_free(pktmp);
|
||||
ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,email_dn,startdate,enddate,
|
||||
days,1,verbose,req,ext_sect,lconf, certopt, nameopt, default_op,
|
||||
ext_copy);
|
||||
ext_copy, 0);
|
||||
err:
|
||||
if (req != NULL) X509_REQ_free(req);
|
||||
if (parms != NULL) CONF_free(parms);
|
||||
|
@ -66,14 +66,13 @@ Section 5 will tell you more on how to handle the certificate you
|
||||
received.
|
||||
|
||||
|
||||
4. Creating a self-signed certificate
|
||||
4. Creating a self-signed test certificate
|
||||
|
||||
If you don't want to deal with another certificate authority, or just
|
||||
want to create a test certificate for yourself, or are setting up a
|
||||
certificate authority of your own, you may want to make the requested
|
||||
certificate a self-signed one. This is similar to creating a
|
||||
certificate request, but creates a certificate instead of a
|
||||
certificate request (1095 is 3 years):
|
||||
want to create a test certificate for yourself. This is similar to
|
||||
creating a certificate request, but creates a certificate instead of
|
||||
a certificate request. This is NOT the recommended way to create a
|
||||
CA certificate, see ca.txt.
|
||||
|
||||
openssl req -new -x509 -key privkey.pem -out cacert.pem -days 1095
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user