From: Andreas Steffen Date: Sun, 2 Oct 2022 11:01:34 +0000 (+0200) Subject: pkcs7: Support rsa-pss signatures X-Git-Tag: 5.9.8~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6bf60221f501d83faded9dba5d50070175a102fa;p=thirdparty%2Fstrongswan.git pkcs7: Support rsa-pss signatures --- diff --git a/src/libstrongswan/plugins/pkcs7/pkcs7_signed_data.c b/src/libstrongswan/plugins/pkcs7/pkcs7_signed_data.c index c74af9d828..be020e761d 100644 --- a/src/libstrongswan/plugins/pkcs7/pkcs7_signed_data.c +++ b/src/libstrongswan/plugins/pkcs7/pkcs7_signed_data.c @@ -44,6 +44,11 @@ struct private_pkcs7_signed_data_t { */ container_t *content; + /** + * Signature scheme + */ + signature_params_t *scheme; + /** * Encoded PKCS#7 signed-data */ @@ -365,6 +370,7 @@ METHOD(container_t, destroy, void, this->creds->destroy(this->creds); this->signerinfos->destroy_function(this->signerinfos, (void*)signerinfo_destroy); + signature_params_destroy(this->scheme); DESTROY_IF(this->content); free(this->encoding.ptr); free(this); @@ -527,31 +533,45 @@ static bool generate(private_pkcs7_signed_data_t *this, private_key_t *key, { chunk_t authenticatedAttributes = chunk_empty; chunk_t encryptedDigest = chunk_empty; - chunk_t data, signerInfo, encoding = chunk_empty; - chunk_t messageDigest, signingTime, attributes; - signature_scheme_t scheme; + chunk_t data = chunk_empty, encoding = chunk_empty; + chunk_t digest_alg = chunk_empty, sig_scheme = chunk_empty; + chunk_t signerInfo = chunk_empty, messageDigest, signingTime, attributes; hasher_t *hasher; time_t now; - int digest_oid; - digest_oid = hasher_algorithm_to_oid(alg); - scheme = signature_scheme_from_oid(digest_oid); - - if (!this->content->get_data(this->content, &data)) + /* select signature scheme, if not already specified */ + if (!this->scheme) + { + INIT(this->scheme, + .scheme = signature_scheme_from_oid( + hasher_signature_algorithm_to_oid(alg, + key->get_type(key))), + ); + } + if (this->scheme->scheme == SIGN_UNKNOWN) + { + return FALSE; + } + if (!signature_params_build(this->scheme, &sig_scheme)) { return FALSE; } + if (!this->content->get_data(this->content, &data)) + { + goto err; + } hasher = lib->crypto->create_hasher(lib->crypto, alg); if (!hasher || !hasher->allocate_hash(hasher, data, &messageDigest)) { DESTROY_IF(hasher); - DBG1(DBG_LIB, " hash algorithm %N not support", + DBG1(DBG_LIB, " hash algorithm %N not supported", hash_algorithm_names, alg); - free(data.ptr); - return FALSE; + goto err; } + chunk_free(&data); hasher->destroy(hasher); + pkcs9->add_attribute(pkcs9, OID_PKCS9_MESSAGE_DIGEST, asn1_wrap(ASN1_OCTET_STRING, "m", messageDigest)); @@ -562,40 +582,38 @@ static bool generate(private_pkcs7_signed_data_t *this, private_key_t *key, pkcs9->add_attribute(pkcs9, OID_PKCS9_SIGNING_TIME, signingTime); pkcs9->add_attribute(pkcs9, OID_PKCS9_CONTENT_TYPE, asn1_build_known_oid(OID_PKCS7_DATA)); - attributes = pkcs9->get_encoding(pkcs9); - if (!key->sign(key, scheme, NULL, attributes, &encryptedDigest)) + if (!key->sign(key, this->scheme->scheme, this->scheme->params, attributes, + &encryptedDigest)) { - free(data.ptr); - return FALSE; + goto err; } authenticatedAttributes = chunk_clone(attributes); *authenticatedAttributes.ptr = ASN1_CONTEXT_C_0; - free(data.ptr); if (encryptedDigest.ptr) { encryptedDigest = asn1_wrap(ASN1_OCTET_STRING, "m", encryptedDigest); } - signerInfo = asn1_wrap(ASN1_SEQUENCE, "cmmmmm", + + digest_alg = asn1_algorithmIdentifier(hasher_algorithm_to_oid(alg)); + signerInfo = asn1_wrap(ASN1_SEQUENCE, "cmcmmm", ASN1_INTEGER_1, build_issuerAndSerialNumber(cert), - asn1_algorithmIdentifier(digest_oid), + digest_alg, authenticatedAttributes, - asn1_algorithmIdentifier(OID_RSA_ENCRYPTION), + sig_scheme, encryptedDigest); + sig_scheme = chunk_empty; if (!cert->get_encoding(cert, CERT_ASN1_DER, &encoding)) { - free(signerInfo.ptr); - return FALSE; + goto err; } if (!this->content->get_encoding(this->content, &data)) { - free(encoding.ptr); - free(signerInfo.ptr); - return FALSE; + goto err; } this->encoding = asn1_wrap(ASN1_SEQUENCE, "mm", @@ -603,15 +621,22 @@ static bool generate(private_pkcs7_signed_data_t *this, private_key_t *key, asn1_wrap(ASN1_CONTEXT_C_0, "m", asn1_wrap(ASN1_SEQUENCE, "cmmmm", ASN1_INTEGER_1, - asn1_wrap(ASN1_SET, "m", asn1_algorithmIdentifier(digest_oid)), + asn1_wrap(ASN1_SET, "m", digest_alg), data, asn1_wrap(ASN1_CONTEXT_C_0, "m", encoding), asn1_wrap(ASN1_SET, "m", signerInfo)))); - pkcs9->destroy(pkcs9); /* TODO: create signerInfos entry */ return TRUE; + +err: + chunk_free(&data); + chunk_free(&digest_alg); + chunk_free(&sig_scheme); + chunk_free(&signerInfo); + chunk_free(&encoding); + return FALSE; } /** @@ -621,7 +646,8 @@ pkcs7_t *pkcs7_signed_data_gen(container_type_t type, va_list args) { private_pkcs7_signed_data_t *this; chunk_t blob = chunk_empty; - hash_algorithm_t alg = HASH_SHA1; + hash_algorithm_t alg = HASH_SHA256; + signature_params_t *scheme = NULL; private_key_t *key = NULL; certificate_t *cert = NULL; pkcs7_attributes_t *pkcs9; @@ -646,6 +672,9 @@ pkcs7_t *pkcs7_signed_data_gen(container_type_t type, va_list args) case BUILD_BLOB: blob = va_arg(args, chunk_t); continue; + case BUILD_SIGNATURE_SCHEME: + scheme = va_arg(args, signature_params_t*); + continue; case BUILD_PKCS7_ATTRIBUTE: oid = va_arg(args, int); value = va_arg(args, chunk_t); @@ -663,11 +692,11 @@ pkcs7_t *pkcs7_signed_data_gen(container_type_t type, va_list args) { this = create_empty(); + this->scheme = signature_params_clone(scheme); this->creds->add_cert(this->creds, FALSE, cert->get_ref(cert)); this->content = lib->creds->create(lib->creds, CRED_CONTAINER, CONTAINER_PKCS7_DATA, BUILD_BLOB, blob, BUILD_END); - if (this->content && generate(this, key, cert, alg, pkcs9)) { return &this->public; diff --git a/src/pki/commands/scep.c b/src/pki/commands/scep.c index 78102e460c..de36d0abd2 100644 --- a/src/pki/commands/scep.c +++ b/src/pki/commands/scep.c @@ -465,7 +465,7 @@ static int scep() /* build pkcs7 request */ pkcs7_req = scep_build_request(pkcs10_encoding, transID, scep_msg_type, x509_ca_enc, cipher, key_size, x509_signer, - digest_alg, priv_signer); + digest_alg, scheme, priv_signer); if (!pkcs7_req.ptr) { DBG1(DBG_APP, "failed to build SCEP request"); @@ -525,7 +525,7 @@ static int scep() certPoll = scep_build_request(issuerAndSubject, transID, SCEP_CertPoll_MSG, x509_ca_enc, cipher, key_size, x509_signer, - digest_alg, priv_signer); + digest_alg, scheme, priv_signer); if (!certPoll.ptr) { DBG1(DBG_APP, "failed to build SCEP certPoll request"); diff --git a/src/pki/scep/scep.c b/src/pki/scep/scep.c index 0b3772dca7..abe246f819 100644 --- a/src/pki/scep/scep.c +++ b/src/pki/scep/scep.c @@ -163,7 +163,8 @@ bool scep_generate_transaction_id(public_key_t *public, chunk_t scep_build_request(chunk_t data, chunk_t transID, scep_msg_t msg, certificate_t *enc_cert, encryption_algorithm_t enc_alg, size_t key_size, certificate_t *signer_cert, - hash_algorithm_t digest_alg, private_key_t *private_key) + hash_algorithm_t digest_alg, signature_params_t *scheme, + private_key_t *private_key) { chunk_t request; container_t *container; @@ -212,6 +213,7 @@ chunk_t scep_build_request(chunk_t data, chunk_t transID, scep_msg_t msg, BUILD_SIGNING_CERT, signer_cert, BUILD_SIGNING_KEY, private_key, BUILD_DIGEST_ALG, digest_alg, + BUILD_SIGNATURE_SCHEME, scheme, BUILD_PKCS7_ATTRIBUTE, OID_PKI_SENDER_NONCE, senderNonce, BUILD_PKCS7_ATTRIBUTE, OID_PKI_TRANS_ID, transID, BUILD_PKCS7_ATTRIBUTE, OID_PKI_MESSAGE_TYPE, msgType, diff --git a/src/pki/scep/scep.h b/src/pki/scep/scep.h index 015945d081..4e97110136 100644 --- a/src/pki/scep/scep.h +++ b/src/pki/scep/scep.h @@ -108,7 +108,8 @@ bool scep_generate_transaction_id(public_key_t *key, chunk_t scep_build_request(chunk_t data, chunk_t transID, scep_msg_t msg, certificate_t *enc_cert, encryption_algorithm_t enc_alg, size_t key_size, certificate_t *signer_cert, - hash_algorithm_t digest_alg, private_key_t *private_key); + hash_algorithm_t digest_alg, signature_params_t *scheme, + private_key_t *private_key); /** * Send a SCEP request via HTTP and wait for a response