mirror of
https://github.com/strongswan/strongswan.git
synced 2025-10-04 00:00:14 -04:00
pki: pki --req can use old certreq as template
When an X.509 certificate has to be renewed it is helpful to use the old PKCS#10 certificate request as a template, so that the distinguishedName (DN), the subjectAlternativeName (SAN) and a certificate profile name don't have to be typed-in again. The old public key in the existing certreq is replaced with the new key and the signature is re-generated using the new private key.
This commit is contained in:
parent
359b5739f4
commit
3fa3d2666a
@ -62,6 +62,16 @@ struct pkcs10_t {
|
|||||||
* @return enumerator over subjectAltNames as identification_t*
|
* @return enumerator over subjectAltNames as identification_t*
|
||||||
*/
|
*/
|
||||||
enumerator_t* (*create_subjectAltName_enumerator)(pkcs10_t *this);
|
enumerator_t* (*create_subjectAltName_enumerator)(pkcs10_t *this);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace the public key and private key signature
|
||||||
|
*
|
||||||
|
* @param private new private key to be used
|
||||||
|
* @param scheme signature scheme
|
||||||
|
* @param password optionally set new password
|
||||||
|
*/
|
||||||
|
certificate_t* (*replace_key)(pkcs10_t *this, private_key_t *private,
|
||||||
|
signature_params_t *scheme, chunk_t password);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /** PKCS10_H_ @}*/
|
#endif /** PKCS10_H_ @}*/
|
||||||
|
@ -270,6 +270,125 @@ METHOD(pkcs10_t, create_subjectAltName_enumerator, enumerator_t*,
|
|||||||
return this->subjectAltNames->create_enumerator(this->subjectAltNames);
|
return this->subjectAltNames->create_enumerator(this->subjectAltNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate and sign a new certificate request
|
||||||
|
*/
|
||||||
|
static bool generate(private_x509_pkcs10_t *cert, private_key_t *sign_key,
|
||||||
|
int digest_alg)
|
||||||
|
{
|
||||||
|
chunk_t key_info, subjectAltNames, attributes;
|
||||||
|
chunk_t extensionRequest = chunk_empty, certTypeExt = chunk_empty;
|
||||||
|
chunk_t challengePassword = chunk_empty, sig_scheme = chunk_empty;
|
||||||
|
identification_t *subject;
|
||||||
|
|
||||||
|
subject = cert->subject;
|
||||||
|
cert->public_key = sign_key->get_public_key(sign_key);
|
||||||
|
|
||||||
|
/* select signature scheme, if not already specified */
|
||||||
|
if (!cert->scheme)
|
||||||
|
{
|
||||||
|
INIT(cert->scheme,
|
||||||
|
.scheme = signature_scheme_from_oid(
|
||||||
|
hasher_signature_algorithm_to_oid(digest_alg,
|
||||||
|
sign_key->get_type(sign_key))),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (cert->scheme->scheme == SIGN_UNKNOWN)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (!signature_params_build(cert->scheme, &sig_scheme))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cert->public_key->get_encoding(cert->public_key,
|
||||||
|
PUBKEY_SPKI_ASN1_DER, &key_info))
|
||||||
|
{
|
||||||
|
chunk_free(&sig_scheme);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* encode subjectAltNames */
|
||||||
|
subjectAltNames = x509_build_subjectAltNames(cert->subjectAltNames);
|
||||||
|
|
||||||
|
/* encode certTypeExt */
|
||||||
|
if (cert->certTypeExt.len > 0)
|
||||||
|
{
|
||||||
|
certTypeExt = asn1_wrap(ASN1_SEQUENCE, "mm",
|
||||||
|
asn1_build_known_oid(OID_MS_CERT_TYPE_EXT),
|
||||||
|
asn1_wrap(ASN1_OCTET_STRING, "m",
|
||||||
|
asn1_simple_object(ASN1_UTF8STRING, cert->certTypeExt)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* encode extensionRequest attribute */
|
||||||
|
if (subjectAltNames.ptr || certTypeExt.ptr)
|
||||||
|
{
|
||||||
|
extensionRequest = asn1_wrap(ASN1_SEQUENCE, "mm",
|
||||||
|
asn1_build_known_oid(OID_EXTENSION_REQUEST),
|
||||||
|
asn1_wrap(ASN1_SET, "m",
|
||||||
|
asn1_wrap(ASN1_SEQUENCE, "mm", subjectAltNames, certTypeExt)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* encode challengePassword attribute */
|
||||||
|
if (cert->challengePassword.len > 0)
|
||||||
|
{
|
||||||
|
challengePassword = asn1_wrap(ASN1_SEQUENCE, "mm",
|
||||||
|
asn1_build_known_oid(OID_CHALLENGE_PASSWORD),
|
||||||
|
asn1_wrap(ASN1_SET, "m",
|
||||||
|
asn1_simple_object(ASN1_UTF8STRING, cert->challengePassword)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
attributes = asn1_wrap(ASN1_CONTEXT_C_0, "mm", extensionRequest,
|
||||||
|
challengePassword);
|
||||||
|
|
||||||
|
cert->certificationRequestInfo = asn1_wrap(ASN1_SEQUENCE, "ccmm",
|
||||||
|
ASN1_INTEGER_0,
|
||||||
|
subject->get_encoding(subject),
|
||||||
|
key_info,
|
||||||
|
attributes);
|
||||||
|
if (!sign_key->sign(sign_key, cert->scheme->scheme, cert->scheme->params,
|
||||||
|
cert->certificationRequestInfo, &cert->signature))
|
||||||
|
{
|
||||||
|
chunk_free(&sig_scheme);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
cert->encoding = asn1_wrap(ASN1_SEQUENCE, "cmm",
|
||||||
|
cert->certificationRequestInfo,
|
||||||
|
sig_scheme,
|
||||||
|
asn1_bitstring("c", cert->signature));
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(pkcs10_t, replace_key, certificate_t*,
|
||||||
|
private_x509_pkcs10_t *this, private_key_t *private,
|
||||||
|
signature_params_t *scheme, chunk_t password)
|
||||||
|
{
|
||||||
|
/* remove old public key and signature */
|
||||||
|
this->public_key->destroy(this->public_key);
|
||||||
|
this->signature = chunk_empty;
|
||||||
|
|
||||||
|
/* copy existing attributes from old certreq encoding */
|
||||||
|
this->certificationRequestInfo = chunk_empty;
|
||||||
|
this->certTypeExt = chunk_clone(this->certTypeExt);
|
||||||
|
this->challengePassword = chunk_clone((password.len > 0) ?
|
||||||
|
password : this->challengePassword);
|
||||||
|
chunk_free(&this->encoding);
|
||||||
|
signature_params_destroy(this->scheme);
|
||||||
|
this->scheme = signature_params_clone(scheme);
|
||||||
|
this->parsed = FALSE;
|
||||||
|
|
||||||
|
if (generate(this, private, HASH_SHA256))
|
||||||
|
{
|
||||||
|
return &this->public.interface.interface;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ASN.1 definition of a PKCS#10 extension request
|
* ASN.1 definition of a PKCS#10 extension request
|
||||||
*/
|
*/
|
||||||
@ -378,6 +497,8 @@ static bool parse_challengePassword(private_x509_pkcs10_t *this, chunk_t blob, i
|
|||||||
}
|
}
|
||||||
DBG2(DBG_ASN, "L%d - challengePassword:", level);
|
DBG2(DBG_ASN, "L%d - challengePassword:", level);
|
||||||
DBG4(DBG_ASN, " '%.*s'", (int)blob.len, blob.ptr);
|
DBG4(DBG_ASN, " '%.*s'", (int)blob.len, blob.ptr);
|
||||||
|
this->challengePassword = blob;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -558,6 +679,7 @@ static private_x509_pkcs10_t* create_empty(void)
|
|||||||
.get_challengePassword = _get_challengePassword,
|
.get_challengePassword = _get_challengePassword,
|
||||||
.get_flags = _get_flags,
|
.get_flags = _get_flags,
|
||||||
.create_subjectAltName_enumerator = _create_subjectAltName_enumerator,
|
.create_subjectAltName_enumerator = _create_subjectAltName_enumerator,
|
||||||
|
.replace_key = _replace_key,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
.subjectAltNames = linked_list_create(),
|
.subjectAltNames = linked_list_create(),
|
||||||
@ -567,100 +689,6 @@ static private_x509_pkcs10_t* create_empty(void)
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate and sign a new certificate request
|
|
||||||
*/
|
|
||||||
static bool generate(private_x509_pkcs10_t *cert, private_key_t *sign_key,
|
|
||||||
int digest_alg)
|
|
||||||
{
|
|
||||||
chunk_t key_info, subjectAltNames, attributes;
|
|
||||||
chunk_t extensionRequest = chunk_empty, certTypeExt = chunk_empty;
|
|
||||||
chunk_t challengePassword = chunk_empty, sig_scheme = chunk_empty;
|
|
||||||
identification_t *subject;
|
|
||||||
|
|
||||||
subject = cert->subject;
|
|
||||||
cert->public_key = sign_key->get_public_key(sign_key);
|
|
||||||
|
|
||||||
/* select signature scheme, if not already specified */
|
|
||||||
if (!cert->scheme)
|
|
||||||
{
|
|
||||||
INIT(cert->scheme,
|
|
||||||
.scheme = signature_scheme_from_oid(
|
|
||||||
hasher_signature_algorithm_to_oid(digest_alg,
|
|
||||||
sign_key->get_type(sign_key))),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (cert->scheme->scheme == SIGN_UNKNOWN)
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
if (!signature_params_build(cert->scheme, &sig_scheme))
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!cert->public_key->get_encoding(cert->public_key,
|
|
||||||
PUBKEY_SPKI_ASN1_DER, &key_info))
|
|
||||||
{
|
|
||||||
chunk_free(&sig_scheme);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* encode subjectAltNames */
|
|
||||||
subjectAltNames = x509_build_subjectAltNames(cert->subjectAltNames);
|
|
||||||
|
|
||||||
/* encode certTypeExt */
|
|
||||||
if (cert->certTypeExt.len > 0)
|
|
||||||
{
|
|
||||||
certTypeExt = asn1_wrap(ASN1_SEQUENCE, "mm",
|
|
||||||
asn1_build_known_oid(OID_MS_CERT_TYPE_EXT),
|
|
||||||
asn1_wrap(ASN1_OCTET_STRING, "m",
|
|
||||||
asn1_simple_object(ASN1_UTF8STRING, cert->certTypeExt)
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* encode extensionRequest attribute */
|
|
||||||
if (subjectAltNames.ptr || certTypeExt.ptr)
|
|
||||||
{
|
|
||||||
extensionRequest = asn1_wrap(ASN1_SEQUENCE, "mm",
|
|
||||||
asn1_build_known_oid(OID_EXTENSION_REQUEST),
|
|
||||||
asn1_wrap(ASN1_SET, "m",
|
|
||||||
asn1_wrap(ASN1_SEQUENCE, "mm", subjectAltNames, certTypeExt)
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* encode challengePassword attribute */
|
|
||||||
if (cert->challengePassword.len > 0)
|
|
||||||
{
|
|
||||||
challengePassword = asn1_wrap(ASN1_SEQUENCE, "mm",
|
|
||||||
asn1_build_known_oid(OID_CHALLENGE_PASSWORD),
|
|
||||||
asn1_wrap(ASN1_SET, "m",
|
|
||||||
asn1_simple_object(ASN1_UTF8STRING, cert->challengePassword)
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
attributes = asn1_wrap(ASN1_CONTEXT_C_0, "mm", extensionRequest,
|
|
||||||
challengePassword);
|
|
||||||
|
|
||||||
cert->certificationRequestInfo = asn1_wrap(ASN1_SEQUENCE, "ccmm",
|
|
||||||
ASN1_INTEGER_0,
|
|
||||||
subject->get_encoding(subject),
|
|
||||||
key_info,
|
|
||||||
attributes);
|
|
||||||
if (!sign_key->sign(sign_key, cert->scheme->scheme, cert->scheme->params,
|
|
||||||
cert->certificationRequestInfo, &cert->signature))
|
|
||||||
{
|
|
||||||
chunk_free(&sig_scheme);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
cert->encoding = asn1_wrap(ASN1_SEQUENCE, "cmm",
|
|
||||||
cert->certificationRequestInfo,
|
|
||||||
sig_scheme,
|
|
||||||
asn1_bitstring("c", cert->signature));
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See header.
|
* See header.
|
||||||
*/
|
*/
|
||||||
@ -705,7 +733,7 @@ x509_pkcs10_t *x509_pkcs10_gen(certificate_type_t type, va_list args)
|
|||||||
{
|
{
|
||||||
private_x509_pkcs10_t *cert;
|
private_x509_pkcs10_t *cert;
|
||||||
private_key_t *sign_key = NULL;
|
private_key_t *sign_key = NULL;
|
||||||
hash_algorithm_t digest_alg = HASH_SHA1;
|
hash_algorithm_t digest_alg = HASH_SHA256;
|
||||||
|
|
||||||
cert = create_empty();
|
cert = create_empty();
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#include <collections/linked_list.h>
|
#include <collections/linked_list.h>
|
||||||
#include <credentials/certificates/certificate.h>
|
#include <credentials/certificates/certificate.h>
|
||||||
|
#include <credentials/certificates/pkcs10.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a self-signed PKCS#10 certificate request.
|
* Create a self-signed PKCS#10 certificate request.
|
||||||
@ -32,9 +33,11 @@ static int req()
|
|||||||
key_type_t type = KEY_ANY;
|
key_type_t type = KEY_ANY;
|
||||||
hash_algorithm_t digest = HASH_UNKNOWN;
|
hash_algorithm_t digest = HASH_UNKNOWN;
|
||||||
signature_params_t *scheme = NULL;
|
signature_params_t *scheme = NULL;
|
||||||
certificate_t *cert = NULL;
|
certificate_t *cert = NULL, *oldreq = NULL;
|
||||||
|
pkcs10_t *pkcs10;
|
||||||
private_key_t *private = NULL;
|
private_key_t *private = NULL;
|
||||||
char *file = NULL, *keyid = NULL, *dn = NULL, *error = NULL;
|
char *file = NULL, *keyid = NULL, *dn = NULL, *error = NULL;
|
||||||
|
char *oldreq_file = NULL;
|
||||||
identification_t *id = NULL;
|
identification_t *id = NULL;
|
||||||
linked_list_t *san;
|
linked_list_t *san;
|
||||||
chunk_t encoding = chunk_empty;
|
chunk_t encoding = chunk_empty;
|
||||||
@ -50,9 +53,9 @@ static int req()
|
|||||||
{
|
{
|
||||||
switch (command_getopt(&arg))
|
switch (command_getopt(&arg))
|
||||||
{
|
{
|
||||||
case 'h':
|
case 'h': /* --help */
|
||||||
goto usage;
|
goto usage;
|
||||||
case 't':
|
case 't': /* --type */
|
||||||
if (streq(arg, "rsa"))
|
if (streq(arg, "rsa"))
|
||||||
{
|
{
|
||||||
type = KEY_RSA;
|
type = KEY_RSA;
|
||||||
@ -75,16 +78,17 @@ static int req()
|
|||||||
goto usage;
|
goto usage;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
case 'g':
|
case 'g': /* --digest */
|
||||||
if (!enum_from_name(hash_algorithm_short_names, arg, &digest))
|
if (!enum_from_name(hash_algorithm_short_names, arg, &digest))
|
||||||
{
|
{
|
||||||
error = "invalid --digest type";
|
error = "invalid --digest type";
|
||||||
goto usage;
|
goto usage;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
case 'R':
|
case 'R': /* --rsa-padding */
|
||||||
if (streq(arg, "pss"))
|
if (streq(arg, "pss"))
|
||||||
{
|
{
|
||||||
|
|
||||||
pss = TRUE;
|
pss = TRUE;
|
||||||
}
|
}
|
||||||
else if (!streq(arg, "pkcs1"))
|
else if (!streq(arg, "pkcs1"))
|
||||||
@ -93,31 +97,34 @@ static int req()
|
|||||||
goto usage;
|
goto usage;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
case 'i':
|
case 'i': /* --in */
|
||||||
file = arg;
|
file = arg;
|
||||||
continue;
|
continue;
|
||||||
case 'd':
|
case 'd': /* --dn */
|
||||||
dn = arg;
|
dn = arg;
|
||||||
continue;
|
continue;
|
||||||
case 'a':
|
case 'a': /* --san */
|
||||||
san->insert_last(san, identification_create_from_string(arg));
|
san->insert_last(san, identification_create_from_string(arg));
|
||||||
continue;
|
continue;
|
||||||
case 'P':
|
case 'P': /* --profile */
|
||||||
cert_type_ext = chunk_create(arg, strlen(arg));
|
cert_type_ext = chunk_create(arg, strlen(arg));
|
||||||
continue;
|
continue;
|
||||||
case 'p':
|
case 'p': /* --password */
|
||||||
challenge_password = chunk_create(arg, strlen(arg));
|
challenge_password = chunk_create(arg, strlen(arg));
|
||||||
continue;
|
continue;
|
||||||
case 'f':
|
case 'f': /* --outform */
|
||||||
if (!get_form(arg, &form, CRED_CERTIFICATE))
|
if (!get_form(arg, &form, CRED_CERTIFICATE))
|
||||||
{
|
{
|
||||||
error = "invalid output format";
|
error = "invalid output format";
|
||||||
goto usage;
|
goto usage;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
case 'x':
|
case 'x': /* --keyid */
|
||||||
keyid = arg;
|
keyid = arg;
|
||||||
continue;
|
continue;
|
||||||
|
case 'o': /* --oldreq */
|
||||||
|
oldreq_file = arg;
|
||||||
|
continue;
|
||||||
case EOF:
|
case EOF:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -127,17 +134,12 @@ static int req()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dn)
|
if (!dn && !oldreq_file)
|
||||||
{
|
{
|
||||||
error = "--dn is required";
|
error = "--dn or --oldreq is required";
|
||||||
goto usage;
|
goto usage;
|
||||||
}
|
}
|
||||||
id = identification_create_from_string(dn);
|
|
||||||
if (id->get_type(id) != ID_DER_ASN1_DN)
|
|
||||||
{
|
|
||||||
error = "supplied --dn is not a distinguished name";
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
if (file)
|
if (file)
|
||||||
{
|
{
|
||||||
private = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
|
private = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
|
||||||
@ -179,18 +181,46 @@ static int req()
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_PKCS10_REQUEST,
|
if (oldreq_file)
|
||||||
BUILD_SIGNING_KEY, private,
|
|
||||||
BUILD_SUBJECT, id,
|
|
||||||
BUILD_SUBJECT_ALTNAMES, san,
|
|
||||||
BUILD_CHALLENGE_PWD, challenge_password,
|
|
||||||
BUILD_CERT_TYPE_EXT, cert_type_ext,
|
|
||||||
BUILD_SIGNATURE_SCHEME, scheme,
|
|
||||||
BUILD_END);
|
|
||||||
if (!cert)
|
|
||||||
{
|
{
|
||||||
error = "generating certificate request failed";
|
oldreq = lib->creds->create(lib->creds, CRED_CERTIFICATE,
|
||||||
goto end;
|
CERT_PKCS10_REQUEST,
|
||||||
|
BUILD_FROM_FILE, oldreq_file, BUILD_END);
|
||||||
|
if (!oldreq)
|
||||||
|
{
|
||||||
|
error = "parsing certificate request failed";
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
pkcs10 = (pkcs10_t*)oldreq;
|
||||||
|
cert = pkcs10->replace_key(pkcs10, private, scheme, challenge_password);
|
||||||
|
if (!cert)
|
||||||
|
{
|
||||||
|
error = "key replacement in certificate request failed";
|
||||||
|
oldreq->destroy(oldreq);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
id = identification_create_from_string(dn);
|
||||||
|
if (id->get_type(id) != ID_DER_ASN1_DN)
|
||||||
|
{
|
||||||
|
error = "supplied --dn is not a distinguished name";
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_PKCS10_REQUEST,
|
||||||
|
BUILD_SIGNING_KEY, private,
|
||||||
|
BUILD_SUBJECT, id,
|
||||||
|
BUILD_SUBJECT_ALTNAMES, san,
|
||||||
|
BUILD_CHALLENGE_PWD, challenge_password,
|
||||||
|
BUILD_CERT_TYPE_EXT, cert_type_ext,
|
||||||
|
BUILD_SIGNATURE_SCHEME, scheme,
|
||||||
|
BUILD_END);
|
||||||
|
if (!cert)
|
||||||
|
{
|
||||||
|
error = "generating certificate request failed";
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!cert->get_encoding(cert, form, &encoding))
|
if (!cert->get_encoding(cert, form, &encoding))
|
||||||
{
|
{
|
||||||
@ -232,23 +262,24 @@ static void __attribute__ ((constructor))reg()
|
|||||||
command_register((command_t) {
|
command_register((command_t) {
|
||||||
req, 'r', "req",
|
req, 'r', "req",
|
||||||
"create a PKCS#10 certificate request",
|
"create a PKCS#10 certificate request",
|
||||||
{"[--in file|--keyid hex] [--type rsa|ecdsa|bliss|priv] --dn distinguished-name",
|
{"[--in file|--keyid hex] [--type rsa|ecdsa|bliss|priv]",
|
||||||
"[--san subjectAltName]+ [--profile server|client|dual|ocsp]",
|
" --oldreq file|--dn distinguished-name [--san subjectAltName]+",
|
||||||
"[--password challengePassword] [--rsa-padding pkcs1|pss]",
|
"[--profile server|client|dual|ocsp] [--password challengePassword]",
|
||||||
"[--digest md5|sha1|sha224|sha256|sha384|sha512|sha3_224|sha3_256|sha3_384|sha3_512]",
|
"[--digest sha1|sha224|sha256|sha384|sha512|sha3_224|sha3_256|sha3_384|sha3_512]",
|
||||||
"[--outform der|pem]"},
|
"[--rsa-padding pkcs1|pss] [--outform der|pem]"},
|
||||||
{
|
{
|
||||||
{"help", 'h', 0, "show usage information"},
|
{"help", 'h', 0, "show usage information"},
|
||||||
{"in", 'i', 1, "private key input file, default: stdin"},
|
{"in", 'i', 1, "private key input file, default: stdin"},
|
||||||
{"keyid", 'x', 1, "smartcard or TPM private key object handle"},
|
{"keyid", 'x', 1, "smartcard or TPM private key object handle"},
|
||||||
{"type", 't', 1, "type of input key, default: priv"},
|
{"type", 't', 1, "type of input key, default: priv"},
|
||||||
{"dn", 'd', 1, "subject distinguished name"},
|
{"oldreq", 'o', 1, "old certificate request to be used as a template"},
|
||||||
{"san", 'a', 1, "subjectAltName to include in cert request"},
|
{"dn", 'd', 1, "subject distinguished name"},
|
||||||
|
{"san", 'a', 1, "subjectAltName to include in cert request"},
|
||||||
{"profile", 'P', 1, "certificate profile name to include in cert request"},
|
{"profile", 'P', 1, "certificate profile name to include in cert request"},
|
||||||
{"password", 'p', 1, "challengePassword to include in cert request"},
|
{"password", 'p', 1, "challengePassword to include in cert request"},
|
||||||
{"digest", 'g', 1, "digest for signature creation, default: key-specific"},
|
{"digest", 'g', 1, "digest for signature creation, default: key-specific"},
|
||||||
{"rsa-padding", 'R', 1, "padding for RSA signatures, default: pkcs1"},
|
{"rsa-padding", 'R', 1, "padding for RSA signatures, default: pkcs1"},
|
||||||
{"outform", 'f', 1, "encoding of generated request, default: der"},
|
{"outform", 'f', 1, "encoding of generated request, default: der"},
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
.TH "PKI \-\-REQ" 1 "2022-08-11" "@PACKAGE_VERSION@" "strongSwan"
|
.TH "PKI \-\-REQ" 1 "2022-08-30" "@PACKAGE_VERSION@" "strongSwan"
|
||||||
.
|
.
|
||||||
.SH "NAME"
|
.SH "NAME"
|
||||||
.
|
.
|
||||||
@ -22,6 +22,19 @@ pki \-\-req \- Create a PKCS#10 certificate request
|
|||||||
.YS
|
.YS
|
||||||
.
|
.
|
||||||
.SY pki\ \-\-req
|
.SY pki\ \-\-req
|
||||||
|
.RB [ \-\-in
|
||||||
|
.IR file | \fB\-\-keyid\fR
|
||||||
|
.IR hex ]
|
||||||
|
.OP \-\-type type
|
||||||
|
.BI \-\-oldreq\~ file
|
||||||
|
.OP \-\-password password
|
||||||
|
.OP \-\-digest digest
|
||||||
|
.OP \-\-rsa\-padding padding
|
||||||
|
.OP \-\-outform encoding
|
||||||
|
.OP \-\-debug level
|
||||||
|
.YS
|
||||||
|
.
|
||||||
|
.SY pki\ \-\-req
|
||||||
.BI \-\-options\~ file
|
.BI \-\-options\~ file
|
||||||
.YS
|
.YS
|
||||||
.
|
.
|
||||||
@ -61,7 +74,9 @@ Type of the input key. Either \fIpriv\fR, \fIrsa\fR, \fIecdsa\fR or \fIbliss\fR,
|
|||||||
defaults to \fIpriv\fR.
|
defaults to \fIpriv\fR.
|
||||||
.TP
|
.TP
|
||||||
.BI "\-d, \-\-dn " distinguished-name
|
.BI "\-d, \-\-dn " distinguished-name
|
||||||
Subject distinguished name (DN). Required.
|
Subject distinguished name (DN). Required if the
|
||||||
|
.B \-\-dn
|
||||||
|
option is not set.
|
||||||
.TP
|
.TP
|
||||||
.BI "\-a, \-\-san " subjectAltName
|
.BI "\-a, \-\-san " subjectAltName
|
||||||
subjectAltName extension to include in request. Can be used multiple times.
|
subjectAltName extension to include in request. Can be used multiple times.
|
||||||
@ -70,18 +85,29 @@ subjectAltName extension to include in request. Can be used multiple times.
|
|||||||
Certificate profile name to be included in the certificate request. Can be any
|
Certificate profile name to be included in the certificate request. Can be any
|
||||||
UTF8 string. Supported e.g. by
|
UTF8 string. Supported e.g. by
|
||||||
.B openxpki
|
.B openxpki
|
||||||
with profiles (\fIpc-client\fR, \fItls-server\fR, etc.) or
|
(with profiles \fIpc-client\fR, \fItls-server\fR, etc.) or
|
||||||
.B pki \-\-issue
|
.B pki \-\-issue
|
||||||
with (\fIserver\fR, \fIclient\fR, \fIdual\fR, or \fIocsp\fR) that are translated into
|
(with profiles \fIserver\fR, \fIclient\fR, \fIdual\fR, or \fIocsp\fR) that are
|
||||||
corresponding Extended Key Usage (EKU) flags in the generated X.509 certificate.
|
translated into corresponding Extended Key Usage (EKU) flags in the generated
|
||||||
|
X.509 certificate.
|
||||||
.TP
|
.TP
|
||||||
.BI "\-p, \-\-password " password
|
.BI "\-p, \-\-password " password
|
||||||
The challengePassword to include in the certificate request.
|
The challengePassword to include in the certificate request.
|
||||||
.TP
|
.TP
|
||||||
|
.BI "\-o, \-\-oldreq " file
|
||||||
|
Old certificate request to be used as a template. Required if the
|
||||||
|
.B --dn
|
||||||
|
option is not set. The public key in the old certificate request is replaced and
|
||||||
|
a fresh signature is generated using the new private key. Optionally a new
|
||||||
|
challengePassword may be set using the
|
||||||
|
.B --password
|
||||||
|
option.
|
||||||
|
.TP
|
||||||
.BI "\-g, \-\-digest " digest
|
.BI "\-g, \-\-digest " digest
|
||||||
Digest to use for signature creation. One of \fImd5\fR, \fIsha1\fR,
|
Digest to use for signature creation. One of \fIsha1\fR, \fIsha224\fR,
|
||||||
\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR. The default is
|
\fIsha256\fR, \fIsha384\fR, \fIsha512\fR, \fIsha3_224\fR, \fIsha3_256\fR,
|
||||||
determined based on the type and size of the signature key.
|
\fIsha3_384\fR, or \fIsha3_512\fR. The default is determined based on
|
||||||
|
the type and size of the signature key.
|
||||||
.TP
|
.TP
|
||||||
.BI "\-R, \-\-rsa\-padding " padding
|
.BI "\-R, \-\-rsa\-padding " padding
|
||||||
Padding to use for RSA signatures. Either \fIpkcs1\fR or \fIpss\fR, defaults
|
Padding to use for RSA signatures. Either \fIpkcs1\fR or \fIpss\fR, defaults
|
||||||
@ -98,7 +124,13 @@ and a TLS-server profile:
|
|||||||
.PP
|
.PP
|
||||||
.EX
|
.EX
|
||||||
pki \-\-req \-\-in key.der \-\-dn "C=CH, O=strongSwan, CN=moon" \\
|
pki \-\-req \-\-in key.der \-\-dn "C=CH, O=strongSwan, CN=moon" \\
|
||||||
\-\-san moon@strongswan.org \-\-profile server > req.der
|
\-\-san moon@strongswan.org \-\-profile server > req.der
|
||||||
|
.EE
|
||||||
|
.PP
|
||||||
|
Generate a certificate request for a renewed key based on an existing template
|
||||||
|
.PP
|
||||||
|
.EX
|
||||||
|
pki \-\-req \-\-in myNewKey.der \-\-oldreq myReq.der > myNewReq.der
|
||||||
.EE
|
.EE
|
||||||
.PP
|
.PP
|
||||||
Generate a certificate request for an ECDSA key and a different digest:
|
Generate a certificate request for an ECDSA key and a different digest:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user