diff --git a/src/libstrongswan/plugins/pkcs7/pkcs7_signed_data.c b/src/libstrongswan/plugins/pkcs7/pkcs7_signed_data.c index 1b9d13569..30d536911 100644 --- a/src/libstrongswan/plugins/pkcs7/pkcs7_signed_data.c +++ b/src/libstrongswan/plugins/pkcs7/pkcs7_signed_data.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2023 Tobias Brunner * Copyright (C) 2012 Martin Willi * * Copyright (C) secunet Security Networks AG @@ -86,9 +87,9 @@ typedef struct { identification_t *issuer; /** - * EncryptedDigest + * Signature */ - chunk_t encrypted_digest; + chunk_t signature; /** * Digesting algorithm OID @@ -96,9 +97,9 @@ typedef struct { int digest_alg; /** - * Public key encryption algorithm OID + * Signature algorithm */ - int enc_alg; + signature_params_t sig_alg; } signerinfo_t; @@ -110,7 +111,8 @@ static void signerinfo_destroy(signerinfo_t *this) DESTROY_IF(this->attributes); DESTROY_IF(this->serial); DESTROY_IF(this->issuer); - free(this->encrypted_digest.ptr); + signature_params_clear(&this->sig_alg); + free(this->signature.ptr); free(this); } @@ -142,8 +144,8 @@ static const asn1Object_t signedDataObjects[] = { { 3, "authenticatedAttributes", ASN1_CONTEXT_C_0, ASN1_OPT | ASN1_OBJ }, /* 19 */ { 3, "end opt", ASN1_EOC, ASN1_END }, /* 20 */ - { 3, "digestEncryptionAlgorithm", ASN1_EOC, ASN1_RAW }, /* 21 */ - { 3, "encryptedDigest", ASN1_OCTET_STRING, ASN1_BODY }, /* 22 */ + { 3, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 21 */ + { 3, "signature", ASN1_OCTET_STRING, ASN1_BODY }, /* 22 */ { 3, "unauthenticatedAttributes", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 23 */ { 3, "end opt", ASN1_EOC, ASN1_END }, /* 24 */ { 1, "end loop", ASN1_EOC, ASN1_END }, /* 25 */ @@ -159,8 +161,8 @@ static const asn1Object_t signedDataObjects[] = { #define PKCS7_SERIAL_NUMBER 17 #define PKCS7_DIGEST_ALGORITHM 18 #define PKCS7_AUTH_ATTRIBUTES 19 -#define PKCS7_DIGEST_ENC_ALGORITHM 21 -#define PKCS7_ENCRYPTED_DIGEST 22 +#define PKCS7_SIGNATURE_ALGORITHM 21 +#define PKCS7_SIGNATURE 22 METHOD(container_t, get_type, container_type_t, private_pkcs7_signed_data_t *this) @@ -188,7 +190,6 @@ METHOD(enumerator_t, enumerate, bool, signature_enumerator_t *this, va_list args) { signerinfo_t *info; - signature_scheme_t scheme; hash_algorithm_t algorithm; enumerator_t *enumerator; certificate_t *cert; @@ -206,25 +207,20 @@ METHOD(enumerator_t, enumerate, bool, DESTROY_IF(this->auth); this->auth = NULL; - scheme = signature_scheme_from_oid(info->digest_alg); - if (scheme == SIGN_UNKNOWN) - { - DBG1(DBG_LIB, "unsupported signature scheme"); - continue; - } if (!info->attributes) { DBG1(DBG_LIB, "no authenticatedAttributes object found"); continue; } - if (info->enc_alg != OID_RSA_ENCRYPTION) + if (info->sig_alg.scheme == SIGN_UNKNOWN) { - DBG1(DBG_LIB, "only RSA digest encryption supported"); + DBG1(DBG_LIB, "unsupported signature scheme"); continue; } enumerator = lib->credmgr->create_trusted_enumerator(lib->credmgr, - KEY_RSA, info->serial, FALSE); + key_type_from_signature_scheme(info->sig_alg.scheme), + info->serial, FALSE); while (enumerator->enumerate(enumerator, &cert, &auth)) { if (info->issuer->equals(info->issuer, cert->get_issuer(cert))) @@ -233,8 +229,8 @@ METHOD(enumerator_t, enumerate, bool, if (key) { chunk = info->attributes->get_encoding(info->attributes); - if (key->verify(key, scheme, NULL, chunk, - info->encrypted_digest)) + if (key->verify(key, info->sig_alg.scheme, + info->sig_alg.params, chunk, info->signature)) { this->auth = auth->clone(auth); key->destroy(key); @@ -448,7 +444,6 @@ static bool parse(private_pkcs7_signed_data_t *this, chunk_t content) case PKCS7_SIGNER_INFO: INIT(info, .digest_alg = OID_UNKNOWN, - .enc_alg = OID_UNKNOWN, ); this->signerinfos->insert_last(this->signerinfos, info); break; @@ -474,12 +469,22 @@ static bool parse(private_pkcs7_signed_data_t *this, chunk_t content) info->digest_alg = asn1_parse_algorithmIdentifier(object, level, NULL); break; - case PKCS7_DIGEST_ENC_ALGORITHM: - info->enc_alg = asn1_parse_algorithmIdentifier(object, - level, NULL); + case PKCS7_SIGNATURE_ALGORITHM: + if (!signature_params_parse(object, level, &info->sig_alg)) + { + if (asn1_parse_algorithmIdentifier(object, -1, + NULL) == OID_RSA_ENCRYPTION && + info->digest_alg != OID_UNKNOWN) + { + /* derive the signature scheme from the digest algorithm + * for the classic PKCS#7 RSA mechansim */ + info->sig_alg.scheme = signature_scheme_from_oid( + info->digest_alg); + } + } break; - case PKCS7_ENCRYPTED_DIGEST: - info->encrypted_digest = chunk_clone(object); + case PKCS7_SIGNATURE: + info->signature = chunk_clone(object); break; } }