pkcs7: Support rsa-pss signatures

This commit is contained in:
Andreas Steffen
2022-10-03 09:52:07 +02:00
parent e0fd191f31
commit 6bf60221f5
4 changed files with 64 additions and 32 deletions
@@ -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;
+2 -2
View File
@@ -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");
+3 -1
View File
@@ -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,
+2 -1
View File
@@ -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