From: Tobias Brunner Date: Thu, 30 Mar 2023 09:19:28 +0000 (+0200) Subject: pki: Allow specifying signature scheme for PKCS#7 signatures X-Git-Tag: 5.9.11dr2~3^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b4e1863fa64512d1a61aa587f7807d356b29677e;p=thirdparty%2Fstrongswan.git pki: Allow specifying signature scheme for PKCS#7 signatures Also changed the error handling a bit so it is more like in the other pki commands. --- diff --git a/src/pki/commands/pkcs7.c b/src/pki/commands/pkcs7.c index fd474a1a4c..8d3528fdc1 100644 --- a/src/pki/commands/pkcs7.c +++ b/src/pki/commands/pkcs7.c @@ -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"}, } }); } diff --git a/src/pki/man/pki---pkcs7.1.in b/src/pki/man/pki---pkcs7.1.in index 38186cf709..b4abdf33c7 100644 --- a/src/pki/man/pki---pkcs7.1.in +++ b/src/pki/man/pki---pkcs7.1.in @@ -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" .