apps/x509 etc.: allow private key input when public key is expected

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: David von Oheimb <david.von.oheimb@siemens.com>
(Merged from https://github.com/openssl/openssl/pull/19076)
This commit is contained in:
Dr. David von Oheimb 2022-08-26 20:40:48 +02:00 committed by Dr. David von Oheimb
parent b7cc2d2f29
commit 0e89b39619
14 changed files with 123 additions and 111 deletions

View File

@ -66,8 +66,8 @@ BIO *bio_open_owner(const char *filename, int format, int private);
BIO *bio_open_default(const char *filename, char mode, int format);
BIO *bio_open_default_quiet(const char *filename, char mode, int format);
CONF *app_load_config_bio(BIO *in, const char *filename);
#define app_load_config(filename) app_load_config_internal(filename, 0)
#define app_load_config_quiet(filename) app_load_config_internal(filename, 1)
# define app_load_config(filename) app_load_config_internal(filename, 0)
# define app_load_config_quiet(filename) app_load_config_internal(filename, 1)
CONF *app_load_config_internal(const char *filename, int quiet);
CONF *app_load_config_verbose(const char *filename, int verbose);
int app_load_modules(const CONF *config);
@ -100,7 +100,7 @@ int progress_cb(EVP_PKEY_CTX *ctx);
int chopup_args(ARGS *arg, char *buf);
void dump_cert_text(BIO *out, X509 *x);
void print_name(BIO *out, const char *title, const X509_NAME *nm);
void print_bignum_var(BIO *, const BIGNUM *, const char*,
void print_bignum_var(BIO *, const BIGNUM *, const char *,
int, unsigned char *);
void print_array(BIO *, const char *, int, const unsigned char *);
int set_nameopt(const char *arg);
@ -117,13 +117,14 @@ X509_REQ *load_csr(const char *file, int format, const char *desc);
X509_REQ *load_csr_autofmt(const char *infile, int format, const char *desc);
X509 *load_cert_pass(const char *uri, int format, int maybe_stdin,
const char *pass, const char *desc);
#define load_cert(uri, format, desc) load_cert_pass(uri, format, 1, NULL, desc)
# define load_cert(uri, format, desc) load_cert_pass(uri, format, 1, NULL, desc)
X509_CRL *load_crl(const char *uri, int format, int maybe_stdin,
const char *desc);
void cleanse(char *str);
void clear_free(char *str);
EVP_PKEY *load_key(const char *uri, int format, int maybe_stdin,
const char *pass, ENGINE *e, const char *desc);
/* first try reading public key, on failure resort to loading private key */
EVP_PKEY *load_pubkey(const char *uri, int format, int maybe_stdin,
const char *pass, ENGINE *e, const char *desc);
EVP_PKEY *load_keyparams(const char *uri, int format, int maybe_stdin,
@ -145,15 +146,11 @@ int load_certs(const char *uri, int maybe_stdin, STACK_OF(X509) **certs,
int load_crls(const char *uri, STACK_OF(X509_CRL) **crls,
const char *pass, const char *desc);
int load_key_certs_crls(const char *uri, int format, int maybe_stdin,
const char *pass, const char *desc,
const char *pass, const char *desc, int quiet,
EVP_PKEY **ppkey, EVP_PKEY **ppubkey,
EVP_PKEY **pparams,
X509 **pcert, STACK_OF(X509) **pcerts,
X509_CRL **pcrl, STACK_OF(X509_CRL) **pcrls);
int load_key_cert_crl(const char *uri, int format, int maybe_stdin,
const char *pass, const char *desc,
EVP_PKEY **ppkey, EVP_PKEY **ppubkey,
X509 **pcert, X509_CRL **pcrl);
X509_STORE *setup_verify(const char *CAfile, int noCAfile,
const char *CApath, int noCApath,
const char *CAstore, int noCAstore);
@ -199,10 +196,9 @@ int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold,
# define DB_type 0
# define DB_exp_date 1
# define DB_rev_date 2
# define DB_serial 3 /* index - unique */
# define DB_serial 3 /* index - unique */
# define DB_file 4
# define DB_name 5 /* index - unique when active and not
* disabled */
# define DB_name 5 /* index - unique when active and not disabled */
# define DB_NUMBER 6
# define DB_TYPE_REV 'R' /* Revoked */
@ -243,8 +239,8 @@ int rotate_index(const char *dbfile, const char *new_suffix,
const char *old_suffix);
void free_index(CA_DB *db);
# define index_name_cmp_noconst(a, b) \
index_name_cmp((const OPENSSL_CSTRING *)CHECKED_PTR_OF(OPENSSL_STRING, a), \
(const OPENSSL_CSTRING *)CHECKED_PTR_OF(OPENSSL_STRING, b))
index_name_cmp((const OPENSSL_CSTRING *)CHECKED_PTR_OF(OPENSSL_STRING, a), \
(const OPENSSL_CSTRING *)CHECKED_PTR_OF(OPENSSL_STRING, b))
int index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b);
int parse_yesno(const char *str, int def);
@ -271,12 +267,11 @@ int do_X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const char *md,
extern char *psk_key;
unsigned char *next_protos_parse(size_t *outlen, const char *in);
int check_cert_attributes(BIO *bio, X509 *x,
const char *checkhost,
const char *checkemail, const char *checkip, int print);
const char *checkhost, const char *checkemail,
const char *checkip, int print);
void store_setup_crl_download(X509_STORE *st);
@ -310,16 +305,16 @@ ASN1_VALUE *app_http_post_asn1(const char *host, const char *port,
# define EXT_COPY_ADD 1
# define EXT_COPY_ALL 2
# define NETSCAPE_CERT_HDR "certificate"
# define NETSCAPE_CERT_HDR "certificate"
# define APP_PASS_LEN 1024
# define APP_PASS_LEN 1024
/*
* IETF RFC 5280 says serial number must be <= 20 bytes. Use 159 bits
* so that the first bit will never be one, so that the DER encoding
* rules won't force a leading octet.
*/
# define SERIAL_RAND_BITS 159
# define SERIAL_RAND_BITS 159
int app_isdir(const char *);
int app_access(const char *, int flag);

View File

@ -469,7 +469,7 @@ X509 *load_cert_pass(const char *uri, int format, int maybe_stdin,
BIO_printf(bio_err, "Unable to load %s from %s\n", desc, uri);
}
} else {
(void)load_key_certs_crls(uri, format, maybe_stdin, pass, desc,
(void)load_key_certs_crls(uri, format, maybe_stdin, pass, desc, 0,
NULL, NULL, NULL, &cert, NULL, NULL, NULL);
}
return cert;
@ -491,7 +491,7 @@ X509_CRL *load_crl(const char *uri, int format, int maybe_stdin,
BIO_printf(bio_err, "Unable to load %s from %s\n", desc, uri);
}
} else {
(void)load_key_certs_crls(uri, format, maybe_stdin, NULL, desc,
(void)load_key_certs_crls(uri, format, maybe_stdin, NULL, desc, 0,
NULL, NULL, NULL, NULL, NULL, &crl, NULL);
}
return crl;
@ -582,16 +582,16 @@ EVP_PKEY *load_key(const char *uri, int format, int may_stdin,
if (desc == NULL)
desc = "private key";
if (format == FORMAT_ENGINE) {
if (format == FORMAT_ENGINE)
uri = allocated_uri = make_engine_uri(e, uri, desc);
}
(void)load_key_certs_crls(uri, format, may_stdin, pass, desc,
(void)load_key_certs_crls(uri, format, may_stdin, pass, desc, 0,
&pkey, NULL, NULL, NULL, NULL, NULL, NULL);
OPENSSL_free(allocated_uri);
return pkey;
}
/* first try reading public key, on failure resort to loading private key */
EVP_PKEY *load_pubkey(const char *uri, int format, int maybe_stdin,
const char *pass, ENGINE *e, const char *desc)
{
@ -601,12 +601,13 @@ EVP_PKEY *load_pubkey(const char *uri, int format, int maybe_stdin,
if (desc == NULL)
desc = "public key";
if (format == FORMAT_ENGINE) {
if (format == FORMAT_ENGINE)
uri = allocated_uri = make_engine_uri(e, uri, desc);
}
(void)load_key_certs_crls(uri, format, maybe_stdin, pass, desc,
(void)load_key_certs_crls(uri, format, maybe_stdin, pass, desc, 1,
NULL, &pkey, NULL, NULL, NULL, NULL, NULL);
if (pkey == NULL)
(void)load_key_certs_crls(uri, format, maybe_stdin, pass, desc, 0,
&pkey, NULL, NULL, NULL, NULL, NULL, NULL);
OPENSSL_free(allocated_uri);
return pkey;
}
@ -616,13 +617,11 @@ EVP_PKEY *load_keyparams_suppress(const char *uri, int format, int maybe_stdin,
int suppress_decode_errors)
{
EVP_PKEY *params = NULL;
BIO *bio_bak = bio_err;
if (desc == NULL)
desc = "key parameters";
if (suppress_decode_errors)
bio_err = NULL;
(void)load_key_certs_crls(uri, format, maybe_stdin, NULL, desc,
suppress_decode_errors,
NULL, NULL, &params, NULL, NULL, NULL, NULL);
if (params != NULL && keytype != NULL && !EVP_PKEY_is_a(params, keytype)) {
ERR_print_errors(bio_err);
@ -632,7 +631,6 @@ EVP_PKEY *load_keyparams_suppress(const char *uri, int format, int maybe_stdin,
EVP_PKEY_free(params);
params = NULL;
}
bio_err = bio_bak;
return params;
}
@ -725,7 +723,7 @@ int load_cert_certs(const char *uri,
return ret;
}
pass_string = get_passwd(pass, desc);
ret = load_key_certs_crls(uri, FORMAT_UNDEF, 0, pass_string, desc,
ret = load_key_certs_crls(uri, FORMAT_UNDEF, 0, pass_string, desc, 0,
NULL, NULL, NULL, pcert, pcerts, NULL, NULL);
clear_free(pass_string);
@ -833,7 +831,7 @@ int load_certs(const char *uri, int maybe_stdin, STACK_OF(X509) **certs,
if (desc == NULL)
desc = "certificates";
ret = load_key_certs_crls(uri, FORMAT_UNDEF, maybe_stdin, pass, desc,
ret = load_key_certs_crls(uri, FORMAT_UNDEF, maybe_stdin, pass, desc, 0,
NULL, NULL, NULL, NULL, certs, NULL, NULL);
if (!ret && was_NULL) {
@ -854,7 +852,7 @@ int load_crls(const char *uri, STACK_OF(X509_CRL) **crls,
if (desc == NULL)
desc = "CRLs";
ret = load_key_certs_crls(uri, FORMAT_UNDEF, 0, pass, desc,
ret = load_key_certs_crls(uri, FORMAT_UNDEF, 0, pass, desc, 0,
NULL, NULL, NULL, NULL, NULL, NULL, crls);
if (!ret && was_NULL) {
@ -902,8 +900,9 @@ static const char *format2string(int format)
* of *pcerts and *pcrls (as far as they are not NULL).
*/
int load_key_certs_crls(const char *uri, int format, int maybe_stdin,
const char *pass, const char *desc, EVP_PKEY **ppkey,
EVP_PKEY **ppubkey, EVP_PKEY **pparams,
const char *pass, const char *desc, int quiet,
EVP_PKEY **ppkey, EVP_PKEY **ppubkey,
EVP_PKEY **pparams,
X509 **pcert, STACK_OF(X509) **pcerts,
X509_CRL **pcrl, STACK_OF(X509_CRL) **pcrls)
{
@ -918,8 +917,9 @@ int load_key_certs_crls(const char *uri, int format, int maybe_stdin,
const OSSL_PARAM *params = NULL;
if (failed == NULL) {
BIO_printf(bio_err, "Internal error: nothing to load from %s\n",
uri != NULL ? uri : "<stdin>");
if (!quiet)
BIO_printf(bio_err, "Internal error: nothing to load from %s\n",
uri != NULL ? uri : "<stdin>");
return 0;
}
ERR_set_mark();
@ -930,7 +930,8 @@ int load_key_certs_crls(const char *uri, int format, int maybe_stdin,
SET_EXPECT1(pcert, OSSL_STORE_INFO_CERT);
if (pcerts != NULL) {
if (*pcerts == NULL && (*pcerts = sk_X509_new_null()) == NULL) {
BIO_printf(bio_err, "Out of memory loading");
if (!quiet)
BIO_printf(bio_err, "Out of memory loading");
goto end;
}
SET_EXPECT(OSSL_STORE_INFO_CERT);
@ -938,7 +939,8 @@ int load_key_certs_crls(const char *uri, int format, int maybe_stdin,
SET_EXPECT1(pcrl, OSSL_STORE_INFO_CRL);
if (pcrls != NULL) {
if (*pcrls == NULL && (*pcrls = sk_X509_CRL_new_null()) == NULL) {
BIO_printf(bio_err, "Out of memory loading");
if (!quiet)
BIO_printf(bio_err, "Out of memory loading");
goto end;
}
SET_EXPECT(OSSL_STORE_INFO_CRL);
@ -958,7 +960,8 @@ int load_key_certs_crls(const char *uri, int format, int maybe_stdin,
BIO *bio;
if (!maybe_stdin) {
BIO_printf(bio_err, "No filename or uri specified for loading");
if (!quiet)
BIO_printf(bio_err, "No filename or uri specified for loading");
goto end;
}
uri = "<stdin>";
@ -975,7 +978,8 @@ int load_key_certs_crls(const char *uri, int format, int maybe_stdin,
params, NULL, NULL);
}
if (ctx == NULL) {
BIO_printf(bio_err, "Could not open file or uri for loading");
if (!quiet)
BIO_printf(bio_err, "Could not open file or uri for loading");
goto end;
}
if (expect > 0 && !OSSL_STORE_expect(ctx, expect))
@ -1057,7 +1061,8 @@ int load_key_certs_crls(const char *uri, int format, int maybe_stdin,
OSSL_STORE_INFO_free(info);
if (!ok) {
failed = OSSL_STORE_INFO_type_string(type);
BIO_printf(bio_err, "Error reading");
if (!quiet)
BIO_printf(bio_err, "Error reading");
break;
}
}
@ -1070,12 +1075,12 @@ int load_key_certs_crls(const char *uri, int format, int maybe_stdin,
pcrls = NULL;
if (failed == NULL) {
failed = FAIL_NAME;
if (failed != NULL)
if (failed != NULL && !quiet)
BIO_printf(bio_err, "Could not find");
} else {
} else if (!quiet) {
BIO_printf(bio_err, "Could not read");
}
if (failed != NULL) {
if (failed != NULL && !quiet) {
unsigned long err = ERR_peek_last_error();
if (desc != NULL && strstr(desc, failed) != NULL) {
@ -1096,7 +1101,7 @@ int load_key_certs_crls(const char *uri, int format, int maybe_stdin,
BIO_printf(bio_err, "\n");
ERR_print_errors(bio_err);
}
if (bio_err == NULL || failed == NULL)
if (quiet || failed == NULL)
/* clear any suppressed or spurious errors */
ERR_pop_to_mark();
else
@ -1373,7 +1378,7 @@ X509_STORE *setup_verify(const char *CAfile, int noCAfile,
goto end;
if (CAfile != NULL) {
if (X509_LOOKUP_load_file_ex(lookup, CAfile, X509_FILETYPE_PEM,
libctx, propq) <= 0) {
libctx, propq) <= 0) {
BIO_printf(bio_err, "Error loading file %s\n", CAfile);
goto end;
}

View File

@ -69,8 +69,8 @@ const OPTIONS pkeyutl_options[] = {
OPT_SECTION("Input"),
{"in", OPT_IN, '<', "Input file - default stdin"},
{"rawin", OPT_RAWIN, '-', "Indicate the input data is in raw form"},
{"pubin", OPT_PUBIN, '-', "Input is a public key"},
{"inkey", OPT_INKEY, 's', "Input private key file"},
{"inkey", OPT_INKEY, 's', "Input key, by default private key"},
{"pubin", OPT_PUBIN, '-', "Input key is a public key"},
{"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
{"peerkey", OPT_PEERKEY, 's', "Peer key file used in key derivation"},
{"peerform", OPT_PEERFORM, 'E', "Peer key format (DER/PEM/P12/ENGINE)"},

View File

@ -47,9 +47,9 @@ const OPTIONS rsautl_options[] = {
OPT_SECTION("Input"),
{"in", OPT_IN, '<', "Input file"},
{"inkey", OPT_INKEY, 's', "Input key"},
{"inkey", OPT_INKEY, 's', "Input key, by default an RSA private key"},
{"keyform", OPT_KEYFORM, 'E', "Private key format (ENGINE, other values ignored)"},
{"pubin", OPT_PUBIN, '-', "Input is an RSA public"},
{"pubin", OPT_PUBIN, '-', "Input key is an RSA public pkey"},
{"certin", OPT_CERTIN, '-', "Input is a cert carrying an RSA public key"},
{"rev", OPT_REV, '-', "Reverse the order of the input buffer"},
{"passin", OPT_PASSIN, 's', "Input file pass phrase source"},

View File

@ -87,7 +87,8 @@ const OPTIONS x509_options[] = {
OPT_SECTION("Certificate printing"),
{"text", OPT_TEXT, '-', "Print the certificate in text form"},
{"dateopt", OPT_DATEOPT, 's', "Datetime format used for printing. (rfc_822/iso_8601). Default is rfc_822."},
{"dateopt", OPT_DATEOPT, 's',
"Datetime format used for printing. (rfc_822/iso_8601). Default is rfc_822."},
{"certopt", OPT_CERTOPT, 's', "Various certificate text printing options"},
{"fingerprint", OPT_FINGERPRINT, '-', "Print the certificate fingerprint"},
{"alias", OPT_ALIAS, '-', "Print certificate alias"},
@ -139,7 +140,7 @@ const OPTIONS x509_options[] = {
"Preserve existing validity dates"},
{"subj", OPT_SUBJ, 's', "Set or override certificate subject (and issuer)"},
{"force_pubkey", OPT_FORCE_PUBKEY, '<',
"Place the given key in new certificate"},
"Key to be placed in new certificate or certificate request"},
{"clrext", OPT_CLREXT, '-',
"Do not take over any extensions from the source certificate or request"},
{"extfile", OPT_EXTFILE, '<', "Config file with X509V3 extensions to add"},
@ -624,8 +625,7 @@ int x509_main(int argc, char **argv)
goto err;
}
if (newcert && reqfile) {
BIO_printf(bio_err,
"The -req option cannot be used with -new\n");
BIO_printf(bio_err, "The -req option cannot be used with -new\n");
goto err;
}
if (privkeyfile != NULL) {
@ -757,7 +757,7 @@ int x509_main(int argc, char **argv)
} else {
if (infile == NULL)
BIO_printf(bio_err,
"Warning: Reading certificate from stdin since no -in option is given\n");
"Warning: Reading certificate from stdin since no -in or -new option is given\n");
x = load_cert_pass(infile, informat, 1, passin, "certificate");
if (x == NULL)
goto end;
@ -893,9 +893,6 @@ int x509_main(int argc, char **argv)
}
}
noout = 1;
} else if (privkey != NULL) {
if (!do_X509_sign(x, 0, privkey, digest, sigopts, &ext_ctx))
goto end;
} else if (CAfile != NULL) {
if ((CAkey = load_key(CAkeyfile, CAkeyformat,
0, passin, e, "CA private key")) == NULL)
@ -908,6 +905,9 @@ int x509_main(int argc, char **argv)
if (!do_X509_sign(x, 0, CAkey, digest, sigopts, &ext_ctx))
goto end;
} else if (privkey != NULL) {
if (!do_X509_sign(x, 0, privkey, digest, sigopts, &ext_ctx))
goto end;
}
if (badsig) {
const ASN1_BIT_STRING *signature;

View File

@ -115,8 +115,9 @@ This option prints out the value of the public key component of the key.
=item B<-pubin>
By default, a private key is read from the input file. With this option a
public key is read instead.
By default, a private key is read from the input.
With this option a public key is read instead.
If the input contains no public key but a private key, its public part is used.
=item B<-pubout>

View File

@ -106,8 +106,9 @@ Print the elliptic curve parameters.
=item B<-pubin>
By default, a private key is read from the input file. With this option a
public key is read instead.
By default a private key is read from the input.
With this option a public key is read instead.
If the input contains no public key but a private key, its public part is used.
=item B<-pubout>

View File

@ -89,7 +89,8 @@ see L<openssl-passphrase-options(1)>.
=item B<-pubin>
By default a private key is read from the input.
With this option only the public components are read.
With this option a public key is read instead.
If the input contains no public key but a private key, its public part is used.
=back

View File

@ -108,7 +108,9 @@ See L<openssl-format-options(1)> for details.
=item B<-pubin>
The input file is a public key.
By default a private key is read from the key input.
With this option a public key is read instead.
If the input contains no public key but a private key, its public part is used.
=item B<-certin>

View File

@ -121,8 +121,9 @@ This option checks the consistency of an RSA private key.
=item B<-pubin>
By default a private key is read from the input file: with this
option a public key is read instead.
By default a private key is read from the input.
With this option a public key is read instead.
If the input contains no public key but a private key, its public part is used.
=item B<-pubout>

View File

@ -76,7 +76,9 @@ See L<openssl-format-options(1)> for details.
=item B<-pubin>
The input file is an RSA public key.
By default a private key is read from the key input.
With this option a public key is read instead.
If the input contains no public key but a private key, its public part is used.
=item B<-certin>

View File

@ -84,7 +84,7 @@ B<openssl> B<x509>
This command is a multi-purposes certificate handling command.
It can be used to print certificate information,
convert certificates to various forms, edit certificate trust settings,
generate certificates from scratch or from certificating requests
generate certificates from scratch or from certification requests
and then self-signing them or signing them like a "micro CA".
Generated certificates bear X.509 version 3.
@ -121,7 +121,8 @@ see L<openssl-passphrase-options(1)>.
=item B<-new>
Generate a certificate from scratch, not using an input certificate
or certificate request. So the B<-in> option must not be used in this case.
or certificate request.
So this excludes the B<-in> and B<-req> options.
Instead, the B<-subj> option needs to be given.
The public key to include can be given with the B<-force_pubkey> option
and defaults to the key given with the B<-key> (or B<-signkey>) option,
@ -176,9 +177,7 @@ the new certificate or certificate request, resulting in a self-signature.
This option cannot be used in conjunction with the B<-CA> option.
It sets the issuer name to the subject name (i.e., makes it self-issued)
and changes the public key to the supplied value (unless overridden
by B<-force_pubkey>).
It sets the issuer name to the subject name (i.e., makes it self-issued).
Unless the B<-preserve_dates> option is supplied,
it sets the validity start date to the current time
and the end date to a value determined by the B<-days> option.
@ -403,20 +402,22 @@ Example:
C</DC=org/DC=OpenSSL/DC=users/UID=123456+CN=John Doe>
This option can be used in conjunction with the B<-force_pubkey> option
to create a certificate even without providing an input certificate
or certificate request.
This option can be used with the B<-new> and B<-force_pubkey> options to create
a new certificate without providing an input certificate or certificate request.
=item B<-force_pubkey> I<filename>
When a certificate is created set its public key to the key in I<filename>
When a new certificate or certificate request is created
set its public key to the given key
instead of the key contained in the input
or given with the B<-key> (or B<-signkey>) option.
If the input contains no public key but a private key, its public part is used.
This option is useful for creating self-issued certificates that are not
This option can be used in conjunction with b<-new> and B<-subj>
to directly generate a certificate containing any desired public key.
This option is also useful for creating self-issued certificates that are not
self-signed, for instance when the key cannot be used for signing, such as DH.
It can also be used in conjunction with B<-new> and B<-subj> to directly
generate a certificate containing any desired public key.
=item B<-clrext>

View File

@ -16,7 +16,7 @@ use OpenSSL::Test qw/:DEFAULT srctop_file/;
setup("test_x509");
plan tests => 32;
plan tests => 33;
# Prevent MSys2 filename munging for arguments that look like file paths but
# aren't
@ -70,18 +70,25 @@ my $extfile = srctop_file("test", "v3_ca_exts.cnf");
my $pkey = srctop_file(@certs, "ca-key.pem"); # issuer private key
my $pubkey = "ca-pubkey.pem"; # the corresponding issuer public key
# use any (different) key for signing our self-issued cert:
my $signkey = srctop_file(@certs, "serverkey.pem");
my $key = srctop_file(@certs, "serverkey.pem");
my $selfout = "self-issued.out";
my $testcert = srctop_file(@certs, "ee-cert.pem");
ok(run(app(["openssl", "pkey", "-in", $pkey, "-pubout", "-out", $pubkey]))
&& run(app(["openssl", "x509", "-new", "-force_pubkey", $pubkey,
"-subj", $subj, "-extfile", $extfile,
"-signkey", $signkey, "-out", $selfout]))
&& run(app(["openssl", "x509", "-new", "-force_pubkey", $pubkey, "-subj", $subj,
"-extfile", $extfile, "-key", $key, "-out", $selfout]))
&& run(app(["openssl", "verify", "-no_check_time",
"-trusted", $selfout, "-partial_chain", $testcert])));
# not unlinking $pubkey
# not unlinking $selfout
# simple way of directly producing a CA-signed cert with private/pubkey input
my $ca = srctop_file(@certs, "ca-cert.pem"); # issuer cert
my $caout = "ca-issued.out";
ok(run(app(["openssl", "x509", "-new", "-force_pubkey", $key, "-subj", "/CN=EE",
"-extfile", $extfile, "-CA", $ca, "-CAkey", $pkey, "-out", $caout]))
&& run(app(["openssl", "verify", "-no_check_time",
"-trusted", $ca, "-partial_chain", $caout])));
subtest 'x509 -- x.509 v1 certificate' => sub {
tconversion( -type => 'x509', -prefix => 'x509v1',
-in => srctop_file("test", "testx509.pem") );

View File

@ -6,11 +6,17 @@
# in the file LICENSE in the source distribution or at
# https://www.openssl.org/source/license.html
# Utility to recreate S/MIME certificates
# Utility to recreate S/MIME certificates in this directory.
# Invoke when changes are need from within this directory.
OPENSSL=../../apps/openssl
OPENSSL_CONF=./ca.cnf
export OPENSSL_CONF
CONF=ca.cnf
export OPENSSL_CONF=./$CONF
gen() {
$OPENSSL x509 -CA smroot.pem -new -days 36524 -force_pubkey $1 -subj "$2" \
-extfile $CONF -extensions $3
}
# Root CA: create certificate directly
CN="Test S/MIME RSA Root" $OPENSSL req -config ca.cnf -x509 -noenc \
@ -18,35 +24,27 @@ CN="Test S/MIME RSA Root" $OPENSSL req -config ca.cnf -x509 -noenc \
# EE RSA certificates with respective extensions
cp ../certs/ee-key.pem smrsa1.pem
$OPENSSL x509 -new -key smrsa1.pem -subj "/CN=Test SMIME EE RSA #1" -days 36524 \
-CA smroot.pem -extfile ca.cnf -extensions usr_rsa_cert >>smrsa1.pem
gen smrsa1.pem "/CN=Test SMIME EE RSA #1" usr_rsa_cert >>smrsa1.pem
cp ../certs/ee-key-3072.pem smrsa2.pem
$OPENSSL x509 -new -key smrsa2.pem -subj "/CN=Test SMIME EE RSA #2" -days 36524 \
-CA smroot.pem -extfile ca.cnf -extensions usr_rsa_cert >>smrsa2.pem
gen smrsa2.pem "/CN=Test SMIME EE RSA #2" usr_rsa_cert >>smrsa2.pem
cp ../certs/ee-key-4096.pem smrsa3.pem
$OPENSSL x509 -new -key smrsa3.pem -subj "/CN=Test SMIME EE RSA #3" -days 36524 \
-CA smroot.pem -extfile ca.cnf -extensions usr_rsa_cert >>smrsa3.pem
gen smrsa3.pem "/CN=Test SMIME EE RSA #3" usr_rsa_cert >>smrsa3.pem
# Create DSA certificates with respective extensions
cp ../certs/server-dsa-key.pem smdsa1.pem
$OPENSSL x509 -new -key smdsa1.pem -subj "/CN=Test SMIME EE DSA #1" -days 36524 \
-CA smroot.pem -extfile ca.cnf -extensions signer_cert >>smdsa1.pem
gen smdsa1.pem "/CN=Test SMIME EE DSA #1" signer_cert >>smdsa1.pem
cp ../certs/server-dsa-key.pem smdsa2.pem
$OPENSSL x509 -new -key smdsa2.pem -subj "/CN=Test SMIME EE DSA #1" -days 36524 \
-CA smroot.pem -extfile ca.cnf -extensions signer_cert >>smdsa2.pem
gen smdsa2.pem "/CN=Test SMIME EE DSA #1" signer_cert >>smdsa2.pem
cp ../certs/server-dsa-key.pem smdsa3.pem
$OPENSSL x509 -new -key smdsa3.pem -subj "/CN=Test SMIME EE DSA #1" -days 36524 \
-CA smroot.pem -extfile ca.cnf -extensions signer_cert >>smdsa3.pem
gen smdsa3.pem "/CN=Test SMIME EE DSA #1" signer_cert >>smdsa3.pem
# Create EC certificates with respective extensions
cp ../certs/ee-ecdsa-key.pem smec1.pem
$OPENSSL x509 -new -key smec1.pem -subj "/CN=Test SMIME EE EC #1" -days 36524 \
-CA smroot.pem -extfile ca.cnf -extensions signer_cert >>smec1.pem
gen smec1.pem "/CN=Test SMIME EE EC #1" signer_cert >>smec1.pem
cp ../certs/server-ecdsa-key.pem smec2.pem
$OPENSSL x509 -new -key smec2.pem -subj "/CN=Test SMIME EE EC #2" -days 36524 \
-CA smroot.pem -extfile ca.cnf -extensions signer_cert >>smec2.pem
gen smec2.pem "/CN=Test SMIME EE EC #2" signer_cert >>smec2.pem
# Do not renew this cert as it is used for legacy data decrypt test
#$OPENSSL ecparam -out ecp.pem -name P-256
@ -61,10 +59,8 @@ $OPENSSL genpkey -genparam -algorithm DHX -out dhp.pem
$OPENSSL genpkey -paramfile dhp.pem -out smdh.pem
rm dhp.pem
# Create X9.42 DH certificate with respective extensions
$OPENSSL x509 -new -key smdh.pem -subj "/CN=Test SMIME EE DH" -days 36524 \
-CA smroot.pem -extfile ca.cnf -extensions dh_cert >>smdh.pem
gen smdh.pem "/CN=Test SMIME EE DH" dh_cert >>smdh.pem
# EE RSA code signing end entity certificate with respective extensions
cp ../certs/ee-key.pem csrsa1.pem
$OPENSSL x509 -new -key csrsa1.pem -subj "/CN=Test CodeSign EE RSA" -days 36524 \
-CA smroot.pem -extfile ca.cnf -extensions codesign_cert >>csrsa1.pem
gen csrsa1.pem "/CN=Test CodeSign EE RSA" codesign_cert >>csrsa1.pem