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; container_t *content;
/**
* Signature scheme
*/
signature_params_t *scheme;
/** /**
* Encoded PKCS#7 signed-data * Encoded PKCS#7 signed-data
*/ */
@@ -365,6 +370,7 @@ METHOD(container_t, destroy, void,
this->creds->destroy(this->creds); this->creds->destroy(this->creds);
this->signerinfos->destroy_function(this->signerinfos, this->signerinfos->destroy_function(this->signerinfos,
(void*)signerinfo_destroy); (void*)signerinfo_destroy);
signature_params_destroy(this->scheme);
DESTROY_IF(this->content); DESTROY_IF(this->content);
free(this->encoding.ptr); free(this->encoding.ptr);
free(this); 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 authenticatedAttributes = chunk_empty;
chunk_t encryptedDigest = chunk_empty; chunk_t encryptedDigest = chunk_empty;
chunk_t data, signerInfo, encoding = chunk_empty; chunk_t data = chunk_empty, encoding = chunk_empty;
chunk_t messageDigest, signingTime, attributes; chunk_t digest_alg = chunk_empty, sig_scheme = chunk_empty;
signature_scheme_t scheme; chunk_t signerInfo = chunk_empty, messageDigest, signingTime, attributes;
hasher_t *hasher; hasher_t *hasher;
time_t now; time_t now;
int digest_oid;
digest_oid = hasher_algorithm_to_oid(alg); /* select signature scheme, if not already specified */
scheme = signature_scheme_from_oid(digest_oid); if (!this->scheme)
{
if (!this->content->get_data(this->content, &data)) 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; 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); hasher = lib->crypto->create_hasher(lib->crypto, alg);
if (!hasher || !hasher->allocate_hash(hasher, data, &messageDigest)) if (!hasher || !hasher->allocate_hash(hasher, data, &messageDigest))
{ {
DESTROY_IF(hasher); DESTROY_IF(hasher);
DBG1(DBG_LIB, " hash algorithm %N not support", DBG1(DBG_LIB, " hash algorithm %N not supported",
hash_algorithm_names, alg); hash_algorithm_names, alg);
free(data.ptr); goto err;
return FALSE;
} }
chunk_free(&data);
hasher->destroy(hasher); hasher->destroy(hasher);
pkcs9->add_attribute(pkcs9, pkcs9->add_attribute(pkcs9,
OID_PKCS9_MESSAGE_DIGEST, OID_PKCS9_MESSAGE_DIGEST,
asn1_wrap(ASN1_OCTET_STRING, "m", messageDigest)); 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_SIGNING_TIME, signingTime);
pkcs9->add_attribute(pkcs9, OID_PKCS9_CONTENT_TYPE, pkcs9->add_attribute(pkcs9, OID_PKCS9_CONTENT_TYPE,
asn1_build_known_oid(OID_PKCS7_DATA)); asn1_build_known_oid(OID_PKCS7_DATA));
attributes = pkcs9->get_encoding(pkcs9); 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); goto err;
return FALSE;
} }
authenticatedAttributes = chunk_clone(attributes); authenticatedAttributes = chunk_clone(attributes);
*authenticatedAttributes.ptr = ASN1_CONTEXT_C_0; *authenticatedAttributes.ptr = ASN1_CONTEXT_C_0;
free(data.ptr);
if (encryptedDigest.ptr) if (encryptedDigest.ptr)
{ {
encryptedDigest = asn1_wrap(ASN1_OCTET_STRING, "m", encryptedDigest); 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, ASN1_INTEGER_1,
build_issuerAndSerialNumber(cert), build_issuerAndSerialNumber(cert),
asn1_algorithmIdentifier(digest_oid), digest_alg,
authenticatedAttributes, authenticatedAttributes,
asn1_algorithmIdentifier(OID_RSA_ENCRYPTION), sig_scheme,
encryptedDigest); encryptedDigest);
sig_scheme = chunk_empty;
if (!cert->get_encoding(cert, CERT_ASN1_DER, &encoding)) if (!cert->get_encoding(cert, CERT_ASN1_DER, &encoding))
{ {
free(signerInfo.ptr); goto err;
return FALSE;
} }
if (!this->content->get_encoding(this->content, &data)) if (!this->content->get_encoding(this->content, &data))
{ {
free(encoding.ptr); goto err;
free(signerInfo.ptr);
return FALSE;
} }
this->encoding = asn1_wrap(ASN1_SEQUENCE, "mm", 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_CONTEXT_C_0, "m",
asn1_wrap(ASN1_SEQUENCE, "cmmmm", asn1_wrap(ASN1_SEQUENCE, "cmmmm",
ASN1_INTEGER_1, ASN1_INTEGER_1,
asn1_wrap(ASN1_SET, "m", asn1_algorithmIdentifier(digest_oid)), asn1_wrap(ASN1_SET, "m", digest_alg),
data, data,
asn1_wrap(ASN1_CONTEXT_C_0, "m", encoding), asn1_wrap(ASN1_CONTEXT_C_0, "m", encoding),
asn1_wrap(ASN1_SET, "m", signerInfo)))); asn1_wrap(ASN1_SET, "m", signerInfo))));
pkcs9->destroy(pkcs9); pkcs9->destroy(pkcs9);
/* TODO: create signerInfos entry */ /* TODO: create signerInfos entry */
return TRUE; 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; private_pkcs7_signed_data_t *this;
chunk_t blob = chunk_empty; 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; private_key_t *key = NULL;
certificate_t *cert = NULL; certificate_t *cert = NULL;
pkcs7_attributes_t *pkcs9; pkcs7_attributes_t *pkcs9;
@@ -646,6 +672,9 @@ pkcs7_t *pkcs7_signed_data_gen(container_type_t type, va_list args)
case BUILD_BLOB: case BUILD_BLOB:
blob = va_arg(args, chunk_t); blob = va_arg(args, chunk_t);
continue; continue;
case BUILD_SIGNATURE_SCHEME:
scheme = va_arg(args, signature_params_t*);
continue;
case BUILD_PKCS7_ATTRIBUTE: case BUILD_PKCS7_ATTRIBUTE:
oid = va_arg(args, int); oid = va_arg(args, int);
value = va_arg(args, chunk_t); 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 = create_empty();
this->scheme = signature_params_clone(scheme);
this->creds->add_cert(this->creds, FALSE, cert->get_ref(cert)); this->creds->add_cert(this->creds, FALSE, cert->get_ref(cert));
this->content = lib->creds->create(lib->creds, this->content = lib->creds->create(lib->creds,
CRED_CONTAINER, CONTAINER_PKCS7_DATA, CRED_CONTAINER, CONTAINER_PKCS7_DATA,
BUILD_BLOB, blob, BUILD_END); BUILD_BLOB, blob, BUILD_END);
if (this->content && generate(this, key, cert, alg, pkcs9)) if (this->content && generate(this, key, cert, alg, pkcs9))
{ {
return &this->public; return &this->public;
+2 -2
View File
@@ -465,7 +465,7 @@ static int scep()
/* build pkcs7 request */ /* build pkcs7 request */
pkcs7_req = scep_build_request(pkcs10_encoding, transID, scep_msg_type, pkcs7_req = scep_build_request(pkcs10_encoding, transID, scep_msg_type,
x509_ca_enc, cipher, key_size, x509_signer, x509_ca_enc, cipher, key_size, x509_signer,
digest_alg, priv_signer); digest_alg, scheme, priv_signer);
if (!pkcs7_req.ptr) if (!pkcs7_req.ptr)
{ {
DBG1(DBG_APP, "failed to build SCEP request"); DBG1(DBG_APP, "failed to build SCEP request");
@@ -525,7 +525,7 @@ static int scep()
certPoll = scep_build_request(issuerAndSubject, transID, SCEP_CertPoll_MSG, certPoll = scep_build_request(issuerAndSubject, transID, SCEP_CertPoll_MSG,
x509_ca_enc, cipher, key_size, x509_signer, x509_ca_enc, cipher, key_size, x509_signer,
digest_alg, priv_signer); digest_alg, scheme, priv_signer);
if (!certPoll.ptr) if (!certPoll.ptr)
{ {
DBG1(DBG_APP, "failed to build SCEP certPoll request"); 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, chunk_t scep_build_request(chunk_t data, chunk_t transID, scep_msg_t msg,
certificate_t *enc_cert, encryption_algorithm_t enc_alg, certificate_t *enc_cert, encryption_algorithm_t enc_alg,
size_t key_size, certificate_t *signer_cert, 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; chunk_t request;
container_t *container; 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_CERT, signer_cert,
BUILD_SIGNING_KEY, private_key, BUILD_SIGNING_KEY, private_key,
BUILD_DIGEST_ALG, digest_alg, BUILD_DIGEST_ALG, digest_alg,
BUILD_SIGNATURE_SCHEME, scheme,
BUILD_PKCS7_ATTRIBUTE, OID_PKI_SENDER_NONCE, senderNonce, BUILD_PKCS7_ATTRIBUTE, OID_PKI_SENDER_NONCE, senderNonce,
BUILD_PKCS7_ATTRIBUTE, OID_PKI_TRANS_ID, transID, BUILD_PKCS7_ATTRIBUTE, OID_PKI_TRANS_ID, transID,
BUILD_PKCS7_ATTRIBUTE, OID_PKI_MESSAGE_TYPE, msgType, 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, chunk_t scep_build_request(chunk_t data, chunk_t transID, scep_msg_t msg,
certificate_t *enc_cert, encryption_algorithm_t enc_alg, certificate_t *enc_cert, encryption_algorithm_t enc_alg,
size_t key_size, certificate_t *signer_cert, 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 * Send a SCEP request via HTTP and wait for a response