mirror of
https://github.com/strongswan/strongswan.git
synced 2025-10-04 00:00:14 -04:00
Merge branch 'pkcs7-signatures'
Adds support for CMS-style signatures in PKCS#7 containers, which allows verifying RSA-PSS and ECDSA signatures. Ed25519 signatures should be supported when verifying, however, they currently can't be created. Ed448 signatures are currently not supported. That's because RFC 8419 has very strict requirements in regards to the hash algorithms used for signed attributes. With Ed25519 only SHA-512 is allowed (pki currently has an issue with Ed25519 in combination with SHA-512 due to its associated HASH_IDENTITY) and with Ed448 only SHAKE256 with 512-bit output, which has to be encoded in the algorithmIdentifier parameters (something we currently don't support at all). Closes strongswan/strongswan#1615
This commit is contained in:
commit
7a47adb4f0
@ -648,18 +648,27 @@ int asn1_parse_algorithmIdentifier(chunk_t blob, int level0, chunk_t *parameters
|
||||
|
||||
if (asn1_unwrap(&blob, &blob) == ASN1_SEQUENCE)
|
||||
{
|
||||
DBG2(DBG_ASN, "L%d - algorithmIdentifier:", level0);
|
||||
if (level0 >= 0)
|
||||
{
|
||||
DBG2(DBG_ASN, "L%d - algorithmIdentifier:", level0);
|
||||
}
|
||||
|
||||
if (asn1_unwrap(&blob, &object) == ASN1_OID)
|
||||
{
|
||||
DBG2(DBG_ASN, "L%d - algorithm:", level0+1);
|
||||
asn1_debug_simple_object(object, ASN1_OID, FALSE);
|
||||
if (level0 >= 0)
|
||||
{
|
||||
DBG2(DBG_ASN, "L%d - algorithm:", level0+1);
|
||||
asn1_debug_simple_object(object, ASN1_OID, FALSE);
|
||||
}
|
||||
alg = asn1_known_oid(object);
|
||||
|
||||
if (blob.len)
|
||||
{
|
||||
DBG2(DBG_ASN, "L%d - parameters:", level0+1);
|
||||
DBG3(DBG_ASN, "%B", &blob);
|
||||
if (level0 >= 0)
|
||||
{
|
||||
DBG2(DBG_ASN, "L%d - parameters:", level0+1);
|
||||
DBG3(DBG_ASN, "%B", &blob);
|
||||
}
|
||||
if (parameters)
|
||||
{
|
||||
*parameters = blob;
|
||||
|
@ -163,7 +163,7 @@ int asn1_unwrap(chunk_t *blob, chunk_t *content);
|
||||
* Parses an ASN.1 algorithmIdentifier object
|
||||
*
|
||||
* @param blob ASN.1 coded blob
|
||||
* @param level0 top-most level offset
|
||||
* @param level0 top-most level offset (-1 to suppress log messages)
|
||||
* @param params returns optional [ASN.1 coded] parameters
|
||||
* @return known OID index or OID_UNKNOWN
|
||||
*/
|
||||
|
@ -213,7 +213,8 @@ typedef struct {
|
||||
/**
|
||||
* Verify signerInfo signature
|
||||
*/
|
||||
static auth_cfg_t *verify_signature(CMS_SignerInfo *si, int hash_oid)
|
||||
static auth_cfg_t *verify_signature(CMS_SignerInfo *si,
|
||||
signature_params_t *sig_alg)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
public_key_t *key;
|
||||
@ -249,7 +250,8 @@ static auth_cfg_t *verify_signature(CMS_SignerInfo *si, int hash_oid)
|
||||
/* TODO: find a better way to access and verify the signature */
|
||||
sig = openssl_asn1_str2chunk(si->signature);
|
||||
enumerator = lib->credmgr->create_trusted_enumerator(lib->credmgr,
|
||||
KEY_RSA, serial, FALSE);
|
||||
key_type_from_signature_scheme(sig_alg->scheme),
|
||||
serial, FALSE);
|
||||
while (enumerator->enumerate(enumerator, &cert, &auth))
|
||||
{
|
||||
if (issuer->equals(issuer, cert->get_issuer(cert)))
|
||||
@ -257,7 +259,7 @@ static auth_cfg_t *verify_signature(CMS_SignerInfo *si, int hash_oid)
|
||||
key = cert->get_public_key(cert);
|
||||
if (key)
|
||||
{
|
||||
if (key->verify(key, signature_scheme_from_oid(hash_oid), NULL,
|
||||
if (key->verify(key, sig_alg->scheme, sig_alg->params,
|
||||
attrs, sig))
|
||||
{
|
||||
found = auth->clone(auth);
|
||||
@ -340,6 +342,8 @@ METHOD(enumerator_t, signature_enumerate, bool,
|
||||
{
|
||||
CMS_SignerInfo *si;
|
||||
X509_ALGOR *digest, *sig;
|
||||
signature_params_t sig_alg = {};
|
||||
chunk_t sig_scheme;
|
||||
int hash_oid;
|
||||
|
||||
/* clean up previous round */
|
||||
@ -350,12 +354,24 @@ METHOD(enumerator_t, signature_enumerate, bool,
|
||||
|
||||
CMS_SignerInfo_get0_algs(si, NULL, NULL, &digest, &sig);
|
||||
hash_oid = openssl_asn1_known_oid(digest->algorithm);
|
||||
if (openssl_asn1_known_oid(sig->algorithm) != OID_RSA_ENCRYPTION)
|
||||
if (openssl_asn1_known_oid(sig->algorithm) == OID_RSA_ENCRYPTION)
|
||||
{
|
||||
DBG1(DBG_LIB, "only RSA digest encryption supported");
|
||||
continue;
|
||||
/* derive the signature scheme from the digest algorithm
|
||||
* for the classic PKCS#7 RSA mechansim */
|
||||
sig_alg.scheme = signature_scheme_from_oid(hash_oid);
|
||||
}
|
||||
this->auth = verify_signature(si, hash_oid);
|
||||
else
|
||||
{
|
||||
sig_scheme = openssl_i2chunk(X509_ALGOR, sig);
|
||||
if (!signature_params_parse(sig_scheme, 0, &sig_alg))
|
||||
{
|
||||
free(sig_scheme.ptr);
|
||||
continue;
|
||||
}
|
||||
free(sig_scheme.ptr);
|
||||
}
|
||||
this->auth = verify_signature(si, &sig_alg);
|
||||
signature_params_clear(&sig_alg);
|
||||
if (!this->auth)
|
||||
{
|
||||
DBG1(DBG_LIB, "unable to verify pkcs7 attributes signature");
|
||||
|
@ -1,4 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Tobias Brunner
|
||||
* Copyright (C) 2012 Martin Willi
|
||||
*
|
||||
* Copyright (C) secunet Security Networks AG
|
||||
@ -86,9 +87,9 @@ typedef struct {
|
||||
identification_t *issuer;
|
||||
|
||||
/**
|
||||
* EncryptedDigest
|
||||
* Signature
|
||||
*/
|
||||
chunk_t encrypted_digest;
|
||||
chunk_t signature;
|
||||
|
||||
/**
|
||||
* Digesting algorithm OID
|
||||
@ -96,9 +97,9 @@ typedef struct {
|
||||
int digest_alg;
|
||||
|
||||
/**
|
||||
* Public key encryption algorithm OID
|
||||
* Signature algorithm
|
||||
*/
|
||||
int enc_alg;
|
||||
signature_params_t sig_alg;
|
||||
|
||||
} signerinfo_t;
|
||||
|
||||
@ -110,7 +111,8 @@ static void signerinfo_destroy(signerinfo_t *this)
|
||||
DESTROY_IF(this->attributes);
|
||||
DESTROY_IF(this->serial);
|
||||
DESTROY_IF(this->issuer);
|
||||
free(this->encrypted_digest.ptr);
|
||||
signature_params_clear(&this->sig_alg);
|
||||
free(this->signature.ptr);
|
||||
free(this);
|
||||
}
|
||||
|
||||
@ -142,8 +144,8 @@ static const asn1Object_t signedDataObjects[] = {
|
||||
{ 3, "authenticatedAttributes", ASN1_CONTEXT_C_0, ASN1_OPT |
|
||||
ASN1_OBJ }, /* 19 */
|
||||
{ 3, "end opt", ASN1_EOC, ASN1_END }, /* 20 */
|
||||
{ 3, "digestEncryptionAlgorithm", ASN1_EOC, ASN1_RAW }, /* 21 */
|
||||
{ 3, "encryptedDigest", ASN1_OCTET_STRING, ASN1_BODY }, /* 22 */
|
||||
{ 3, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 21 */
|
||||
{ 3, "signature", ASN1_OCTET_STRING, ASN1_BODY }, /* 22 */
|
||||
{ 3, "unauthenticatedAttributes", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 23 */
|
||||
{ 3, "end opt", ASN1_EOC, ASN1_END }, /* 24 */
|
||||
{ 1, "end loop", ASN1_EOC, ASN1_END }, /* 25 */
|
||||
@ -159,8 +161,8 @@ static const asn1Object_t signedDataObjects[] = {
|
||||
#define PKCS7_SERIAL_NUMBER 17
|
||||
#define PKCS7_DIGEST_ALGORITHM 18
|
||||
#define PKCS7_AUTH_ATTRIBUTES 19
|
||||
#define PKCS7_DIGEST_ENC_ALGORITHM 21
|
||||
#define PKCS7_ENCRYPTED_DIGEST 22
|
||||
#define PKCS7_SIGNATURE_ALGORITHM 21
|
||||
#define PKCS7_SIGNATURE 22
|
||||
|
||||
METHOD(container_t, get_type, container_type_t,
|
||||
private_pkcs7_signed_data_t *this)
|
||||
@ -188,7 +190,6 @@ METHOD(enumerator_t, enumerate, bool,
|
||||
signature_enumerator_t *this, va_list args)
|
||||
{
|
||||
signerinfo_t *info;
|
||||
signature_scheme_t scheme;
|
||||
hash_algorithm_t algorithm;
|
||||
enumerator_t *enumerator;
|
||||
certificate_t *cert;
|
||||
@ -206,25 +207,20 @@ METHOD(enumerator_t, enumerate, bool,
|
||||
DESTROY_IF(this->auth);
|
||||
this->auth = NULL;
|
||||
|
||||
scheme = signature_scheme_from_oid(info->digest_alg);
|
||||
if (scheme == SIGN_UNKNOWN)
|
||||
{
|
||||
DBG1(DBG_LIB, "unsupported signature scheme");
|
||||
continue;
|
||||
}
|
||||
if (!info->attributes)
|
||||
{
|
||||
DBG1(DBG_LIB, "no authenticatedAttributes object found");
|
||||
continue;
|
||||
}
|
||||
if (info->enc_alg != OID_RSA_ENCRYPTION)
|
||||
if (info->sig_alg.scheme == SIGN_UNKNOWN)
|
||||
{
|
||||
DBG1(DBG_LIB, "only RSA digest encryption supported");
|
||||
DBG1(DBG_LIB, "unsupported signature scheme");
|
||||
continue;
|
||||
}
|
||||
|
||||
enumerator = lib->credmgr->create_trusted_enumerator(lib->credmgr,
|
||||
KEY_RSA, info->serial, FALSE);
|
||||
key_type_from_signature_scheme(info->sig_alg.scheme),
|
||||
info->serial, FALSE);
|
||||
while (enumerator->enumerate(enumerator, &cert, &auth))
|
||||
{
|
||||
if (info->issuer->equals(info->issuer, cert->get_issuer(cert)))
|
||||
@ -233,8 +229,8 @@ METHOD(enumerator_t, enumerate, bool,
|
||||
if (key)
|
||||
{
|
||||
chunk = info->attributes->get_encoding(info->attributes);
|
||||
if (key->verify(key, scheme, NULL, chunk,
|
||||
info->encrypted_digest))
|
||||
if (key->verify(key, info->sig_alg.scheme,
|
||||
info->sig_alg.params, chunk, info->signature))
|
||||
{
|
||||
this->auth = auth->clone(auth);
|
||||
key->destroy(key);
|
||||
@ -448,7 +444,6 @@ static bool parse(private_pkcs7_signed_data_t *this, chunk_t content)
|
||||
case PKCS7_SIGNER_INFO:
|
||||
INIT(info,
|
||||
.digest_alg = OID_UNKNOWN,
|
||||
.enc_alg = OID_UNKNOWN,
|
||||
);
|
||||
this->signerinfos->insert_last(this->signerinfos, info);
|
||||
break;
|
||||
@ -474,12 +469,22 @@ static bool parse(private_pkcs7_signed_data_t *this, chunk_t content)
|
||||
info->digest_alg = asn1_parse_algorithmIdentifier(object,
|
||||
level, NULL);
|
||||
break;
|
||||
case PKCS7_DIGEST_ENC_ALGORITHM:
|
||||
info->enc_alg = asn1_parse_algorithmIdentifier(object,
|
||||
level, NULL);
|
||||
case PKCS7_SIGNATURE_ALGORITHM:
|
||||
if (!signature_params_parse(object, level, &info->sig_alg))
|
||||
{
|
||||
if (asn1_parse_algorithmIdentifier(object, -1,
|
||||
NULL) == OID_RSA_ENCRYPTION &&
|
||||
info->digest_alg != OID_UNKNOWN)
|
||||
{
|
||||
/* derive the signature scheme from the digest algorithm
|
||||
* for the classic PKCS#7 RSA mechansim */
|
||||
info->sig_alg.scheme = signature_scheme_from_oid(
|
||||
info->digest_alg);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PKCS7_ENCRYPTED_DIGEST:
|
||||
info->encrypted_digest = chunk_clone(object);
|
||||
case PKCS7_SIGNATURE:
|
||||
info->signature = chunk_clone(object);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -81,11 +81,11 @@ START_TEST(test_asn1_parse_algorithmIdentifier)
|
||||
parameters = chunk_empty;
|
||||
if (i == 2)
|
||||
{
|
||||
alg = asn1_parse_algorithmIdentifier(algid, 0, NULL);
|
||||
alg = asn1_parse_algorithmIdentifier(algid, _i, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
alg = asn1_parse_algorithmIdentifier(algid, 0, ¶meters);
|
||||
alg = asn1_parse_algorithmIdentifier(algid, _i, ¶meters);
|
||||
if (test[i].empty)
|
||||
{
|
||||
ck_assert(parameters.len == 0 && parameters.ptr == NULL);
|
||||
@ -824,7 +824,7 @@ Suite *asn1_suite_create()
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("parse_algorithmIdentifier");
|
||||
tcase_add_test(tc, test_asn1_parse_algorithmIdentifier);
|
||||
tcase_add_loop_test(tc, test_asn1_parse_algorithmIdentifier, -1, 1);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("known_oid");
|
||||
|
@ -64,11 +64,7 @@ static int acert()
|
||||
}
|
||||
continue;
|
||||
case 'R':
|
||||
if (streq(arg, "pss"))
|
||||
{
|
||||
pss = TRUE;
|
||||
}
|
||||
else if (!streq(arg, "pkcs1"))
|
||||
if (!parse_rsa_padding(arg, &pss))
|
||||
{
|
||||
error = "invalid RSA padding";
|
||||
goto usage;
|
||||
|
@ -185,11 +185,7 @@ static int issue()
|
||||
}
|
||||
continue;
|
||||
case 'R':
|
||||
if (streq(arg, "pss"))
|
||||
{
|
||||
pss = TRUE;
|
||||
}
|
||||
else if (!streq(arg, "pkcs1"))
|
||||
if (!parse_rsa_padding(arg, &pss))
|
||||
{
|
||||
error = "invalid RSA padding";
|
||||
goto usage;
|
||||
|
@ -151,7 +151,8 @@ static int verify(chunk_t chunk)
|
||||
/**
|
||||
* Sign data into PKCS#7 signed-data
|
||||
*/
|
||||
static int sign(chunk_t chunk, certificate_t *cert, private_key_t *key)
|
||||
static int sign(chunk_t chunk, certificate_t *cert, private_key_t *key,
|
||||
hash_algorithm_t digest, signature_params_t *scheme)
|
||||
{
|
||||
container_t *container;
|
||||
chunk_t encoding;
|
||||
@ -162,6 +163,8 @@ static int sign(chunk_t chunk, certificate_t *cert, private_key_t *key)
|
||||
BUILD_BLOB, chunk,
|
||||
BUILD_SIGNING_CERT, cert,
|
||||
BUILD_SIGNING_KEY, key,
|
||||
BUILD_SIGNATURE_SCHEME, scheme,
|
||||
BUILD_DIGEST_ALG, digest,
|
||||
BUILD_END);
|
||||
if (container)
|
||||
{
|
||||
@ -171,6 +174,7 @@ static int sign(chunk_t chunk, certificate_t *cert, private_key_t *key)
|
||||
free(encoding.ptr);
|
||||
}
|
||||
container->destroy(container);
|
||||
res = 0;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@ -196,6 +200,7 @@ static int encrypt(chunk_t chunk, certificate_t *cert)
|
||||
free(encoding.ptr);
|
||||
}
|
||||
container->destroy(container);
|
||||
res = 0;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@ -277,12 +282,14 @@ static int show(chunk_t chunk)
|
||||
*/
|
||||
static int pkcs7()
|
||||
{
|
||||
char *arg, *file = NULL;
|
||||
char *arg, *file = NULL, *error = NULL;
|
||||
private_key_t *key = NULL;
|
||||
certificate_t *cert = NULL;
|
||||
chunk_t data = chunk_empty;
|
||||
hash_algorithm_t digest = HASH_UNKNOWN;
|
||||
signature_params_t *scheme = NULL;
|
||||
mem_cred_t *creds;
|
||||
int res = 1;
|
||||
int res = 0;
|
||||
FILE *in;
|
||||
enum {
|
||||
OP_NONE,
|
||||
@ -292,6 +299,8 @@ static int pkcs7()
|
||||
OP_DECRYPT,
|
||||
OP_SHOW,
|
||||
} op = OP_NONE;
|
||||
bool pss = lib->settings->get_bool(lib->settings, "%s.rsa_pss", FALSE,
|
||||
lib->ns);
|
||||
|
||||
creds = mem_cred_create();
|
||||
|
||||
@ -300,8 +309,7 @@ static int pkcs7()
|
||||
switch (command_getopt(&arg))
|
||||
{
|
||||
case 'h':
|
||||
creds->destroy(creds);
|
||||
return command_usage(NULL);
|
||||
goto usage;
|
||||
case 'i':
|
||||
file = arg;
|
||||
continue;
|
||||
@ -342,12 +350,12 @@ static int pkcs7()
|
||||
continue;
|
||||
case 'k':
|
||||
key = lib->creds->create(lib->creds,
|
||||
CRED_PRIVATE_KEY, KEY_RSA,
|
||||
CRED_PRIVATE_KEY, KEY_ANY,
|
||||
BUILD_FROM_FILE, arg, BUILD_END);
|
||||
if (!key)
|
||||
{
|
||||
fprintf(stderr, "parsing private key failed\n");
|
||||
goto end;
|
||||
error = "parsing private key failed";
|
||||
goto usage;
|
||||
}
|
||||
creds->add_key(creds, key);
|
||||
continue;
|
||||
@ -357,17 +365,31 @@ static int pkcs7()
|
||||
BUILD_FROM_FILE, arg, BUILD_END);
|
||||
if (!cert)
|
||||
{
|
||||
fprintf(stderr, "parsing certificate failed\n");
|
||||
goto end;
|
||||
error = "parsing certificate failed";
|
||||
goto usage;
|
||||
}
|
||||
creds->add_cert(creds, TRUE, cert);
|
||||
continue;
|
||||
case 'g':
|
||||
if (!enum_from_name(hash_algorithm_short_names, arg, &digest))
|
||||
{
|
||||
error = "invalid --digest type";
|
||||
goto usage;
|
||||
}
|
||||
continue;
|
||||
case 'R':
|
||||
if (!parse_rsa_padding(arg, &pss))
|
||||
{
|
||||
error = "invalid RSA padding";
|
||||
goto usage;
|
||||
}
|
||||
continue;
|
||||
case EOF:
|
||||
break;
|
||||
default:
|
||||
invalid:
|
||||
creds->destroy(creds);
|
||||
return command_usage("invalid --pkcs7 option");
|
||||
error = "invalid --pkcs7 option";
|
||||
goto usage;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -388,12 +410,12 @@ static int pkcs7()
|
||||
|
||||
if (!data.len)
|
||||
{
|
||||
fprintf(stderr, "reading input failed!\n");
|
||||
error = "reading input failed";
|
||||
goto end;
|
||||
}
|
||||
if (op != OP_SHOW && !cert)
|
||||
{
|
||||
fprintf(stderr, "requiring a certificate!\n");
|
||||
error = "requiring a certificate";
|
||||
goto end;
|
||||
}
|
||||
|
||||
@ -404,11 +426,21 @@ static int pkcs7()
|
||||
case OP_SIGN:
|
||||
if (!key)
|
||||
{
|
||||
fprintf(stderr, "signing requires a private key\n");
|
||||
res = 1;
|
||||
error = "signing requires a private key";
|
||||
break;
|
||||
}
|
||||
res = sign(data, cert, key);
|
||||
scheme = get_signature_scheme(key, digest, pss);
|
||||
if (!scheme)
|
||||
{
|
||||
error = "no signature scheme found";
|
||||
break;
|
||||
}
|
||||
if (digest == HASH_UNKNOWN)
|
||||
{
|
||||
digest = hasher_from_signature_scheme(scheme->scheme,
|
||||
scheme->params);
|
||||
}
|
||||
res = sign(data, cert, key, digest, scheme);
|
||||
break;
|
||||
case OP_VERIFY:
|
||||
res = verify(data);
|
||||
@ -420,7 +452,6 @@ static int pkcs7()
|
||||
if (!key)
|
||||
{
|
||||
fprintf(stderr, "decryption requires a private key\n");
|
||||
res = 1;
|
||||
break;
|
||||
}
|
||||
res = decrypt(data);
|
||||
@ -435,9 +466,19 @@ static int pkcs7()
|
||||
lib->credmgr->remove_local_set(lib->credmgr, &creds->set);
|
||||
|
||||
end:
|
||||
signature_params_destroy(scheme);
|
||||
creds->destroy(creds);
|
||||
free(data.ptr);
|
||||
if (error)
|
||||
{
|
||||
fprintf(stderr, "%s\n", error);
|
||||
return 1;
|
||||
}
|
||||
return res;
|
||||
|
||||
usage:
|
||||
creds->destroy(creds);
|
||||
return command_usage(error);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -448,17 +489,21 @@ static void __attribute__ ((constructor))reg()
|
||||
command_register((command_t) {
|
||||
pkcs7, '7', "pkcs7", "PKCS#7 wrap/unwrap functions",
|
||||
{"--sign|--verify|--encrypt|--decrypt|--show",
|
||||
"[--in file] [--cert file]+ [--key file]"},
|
||||
"[--in file] [--cert file]+ [--key file]",
|
||||
"[--digest md5|sha1|sha224|sha256|sha384|sha512|sha3_224|sha3_256|sha3_384|sha3_512]",
|
||||
"[--rsa-padding pkcs1|pss]"},
|
||||
{
|
||||
{"help", 'h', 0, "show usage information"},
|
||||
{"sign", 's', 0, "create PKCS#7 signed-data"},
|
||||
{"verify", 'u', 0, "verify PKCS#7 signed-data"},
|
||||
{"encrypt", 'e', 0, "create PKCS#7 enveloped-data"},
|
||||
{"decrypt", 'd', 0, "decrypt PKCS#7 enveloped-data"},
|
||||
{"show", 'p', 0, "show info about PKCS#7, print certificates"},
|
||||
{"in", 'i', 1, "input file, default: stdin"},
|
||||
{"key", 'k', 1, "path to private key for sign/decrypt"},
|
||||
{"cert", 'c', 1, "path to certificate for sign/verify/encrypt"},
|
||||
{"help", 'h', 0, "show usage information"},
|
||||
{"sign", 's', 0, "create PKCS#7 signed-data"},
|
||||
{"verify", 'u', 0, "verify PKCS#7 signed-data"},
|
||||
{"encrypt", 'e', 0, "create PKCS#7 enveloped-data"},
|
||||
{"decrypt", 'd', 0, "decrypt PKCS#7 enveloped-data"},
|
||||
{"show", 'p', 0, "show info about PKCS#7, print certificates"},
|
||||
{"in", 'i', 1, "input file, default: stdin"},
|
||||
{"key", 'k', 1, "path to private key for sign/decrypt"},
|
||||
{"cert", 'c', 1, "path to certificate for sign/verify/encrypt"},
|
||||
{"digest", 'g', 1, "digest for signature creation, default: key-specific"},
|
||||
{"rsa-padding", 'R', 1, "padding for RSA signatures, default: pkcs1"},
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -105,12 +105,7 @@ static int req()
|
||||
}
|
||||
continue;
|
||||
case 'R': /* --rsa-padding */
|
||||
if (streq(arg, "pss"))
|
||||
{
|
||||
|
||||
pss = TRUE;
|
||||
}
|
||||
else if (!streq(arg, "pkcs1"))
|
||||
if (!parse_rsa_padding(arg, &pss))
|
||||
{
|
||||
error = "invalid RSA padding";
|
||||
goto usage;
|
||||
|
@ -162,15 +162,7 @@ static int scep()
|
||||
}
|
||||
continue;
|
||||
case 'R': /* --rsa-padding */
|
||||
if (streq(arg, "pss"))
|
||||
{
|
||||
pss = TRUE;
|
||||
}
|
||||
else if (streq(arg, "pkcs1"))
|
||||
{
|
||||
pss = FALSE;
|
||||
}
|
||||
else
|
||||
if (!parse_rsa_padding(arg, &pss))
|
||||
{
|
||||
error = "invalid RSA padding";
|
||||
goto usage;
|
||||
|
@ -129,11 +129,7 @@ static int self()
|
||||
}
|
||||
continue;
|
||||
case 'R':
|
||||
if (streq(arg, "pss"))
|
||||
{
|
||||
pss = TRUE;
|
||||
}
|
||||
else if (!streq(arg, "pkcs1"))
|
||||
if (!parse_rsa_padding(arg, &pss))
|
||||
{
|
||||
error = "invalid RSA padding";
|
||||
goto usage;
|
||||
|
@ -146,11 +146,7 @@ static int sign_crl()
|
||||
}
|
||||
continue;
|
||||
case 'R':
|
||||
if (streq(arg, "pss"))
|
||||
{
|
||||
pss = TRUE;
|
||||
}
|
||||
else if (!streq(arg, "pkcs1"))
|
||||
if (!parse_rsa_padding(arg, &pss))
|
||||
{
|
||||
error = "invalid RSA padding";
|
||||
goto usage;
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH "PKI \-\-PKCS7" 1 "2013-07-31" "@PACKAGE_VERSION@" "strongSwan"
|
||||
.TH "PKI \-\-PKCS7" 1 "2023-03-30" "@PACKAGE_VERSION@" "strongSwan"
|
||||
.
|
||||
.SH "NAME"
|
||||
.
|
||||
@ -11,6 +11,8 @@ pki \-\-pkcs7 \- Provides PKCS#7 wrap/unwrap functions
|
||||
.OP \-\-in file
|
||||
.OP \-\-cert file
|
||||
.OP \-\-key file
|
||||
.OP \-\-digest digest
|
||||
.OP \-\-rsa\-padding padding
|
||||
.OP \-\-debug level
|
||||
.YS
|
||||
.
|
||||
@ -73,6 +75,15 @@ Certificate for
|
||||
and
|
||||
.BR \-\-encrypt.
|
||||
Can be used multiple times.
|
||||
.TP
|
||||
.BI "\-g, \-\-digest " digest
|
||||
Digest to use for signature creation. One of \fImd5\fR, \fIsha1\fR,
|
||||
\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR. The default is
|
||||
determined based on the type and size of the signature key.
|
||||
.TP
|
||||
.BI "\-R, \-\-rsa\-padding " padding
|
||||
Padding to use for RSA signatures. Either \fIpkcs1\fR or \fIpss\fR, defaults
|
||||
to \fIpkcs1\fR.
|
||||
.
|
||||
.SH "SEE ALSO"
|
||||
.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2012-2018 Tobias Brunner
|
||||
* Copyright (C) 2012-2023 Tobias Brunner
|
||||
* Copyright (C) 2009 Martin Willi
|
||||
*
|
||||
* Copyright (C) secunet Security Networks AG
|
||||
@ -238,6 +238,26 @@ void set_file_mode(FILE *stream, cred_encoding_type_t enc)
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
bool parse_rsa_padding(char *padding, bool *pss)
|
||||
{
|
||||
if (streq(padding, "pss"))
|
||||
{
|
||||
*pss = TRUE;
|
||||
}
|
||||
else if (streq(padding, "pkcs1"))
|
||||
{
|
||||
*pss = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine a default hash algorithm for the given key
|
||||
*/
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2017 Tobias Brunner
|
||||
* Copyright (C) 2015-2023 Tobias Brunner
|
||||
* Copyright (C) 2009 Martin Willi
|
||||
*
|
||||
* Copyright (C) secunet Security Networks AG
|
||||
@ -58,6 +58,15 @@ bool calculate_lifetime(char *format, char *nbstr, char *nastr, time_t span,
|
||||
*/
|
||||
void set_file_mode(FILE *stream, cred_encoding_type_t enc);
|
||||
|
||||
/**
|
||||
* Parse RSA padding configuration.
|
||||
*
|
||||
* @param padding input string to parse
|
||||
* @param pss set to TRUE if PSS padding should be used, FALSE otherwise
|
||||
* @return TRUE if successfully parsed
|
||||
*/
|
||||
bool parse_rsa_padding(char *padding, bool *pss);
|
||||
|
||||
/**
|
||||
* Determine the signature scheme and parameters for the given private key and
|
||||
* hash algorithm and whether to use PSS padding for RSA.
|
||||
|
Loading…
x
Reference in New Issue
Block a user