pkcs7: Support rsa-pss signatures
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user