SUPPORT-8924. Добавлена проверка KeyUsage сертификата для подписи

This commit is contained in:
alashkova 2025-02-14 16:26:36 +03:00
parent 43fe9be6fa
commit 6d835c0958
3 changed files with 61 additions and 16 deletions

View file

@ -32,6 +32,7 @@ capi_function_list_init(library_t *lib, capi_function_list_t *fl)
LIBRARY_RESOLVE(fl->CertVerifyCertificateChainPolicy, lib, "CertVerifyCertificateChainPolicy"); LIBRARY_RESOLVE(fl->CertVerifyCertificateChainPolicy, lib, "CertVerifyCertificateChainPolicy");
LIBRARY_RESOLVE(fl->CertFreeCertificateChain, lib, "CertFreeCertificateChain"); LIBRARY_RESOLVE(fl->CertFreeCertificateChain, lib, "CertFreeCertificateChain");
LIBRARY_RESOLVE(fl->CryptGenRandom, lib, "CryptGenRandom"); LIBRARY_RESOLVE(fl->CryptGenRandom, lib, "CryptGenRandom");
LIBRARY_RESOLVE(fl->CertGetIntendedKeyUsage, lib, "CertGetIntendedKeyUsage");
#ifdef UNICODE #ifdef UNICODE
LIBRARY_RESOLVE(fl->CryptSignHash, lib, "CryptSignHashW"); LIBRARY_RESOLVE(fl->CryptSignHash, lib, "CryptSignHashW");

View file

@ -207,6 +207,14 @@ DECLARE_FN(WINADVAPI,
DWORD dwLen, DWORD dwLen,
BYTE *pbBuffer)); BYTE *pbBuffer));
DECLARE_FN(WINADVAPI,
BOOL,
CERT_GET_INTENDED_KEY_USAGE,
(DWORD dwCertEncodingType,
PCERT_INFO pCertInfo,
BYTE *pbKeyUsage,
IN DWORD cbKeyUsage));
#ifdef UNICODE #ifdef UNICODE
#define CRYPT_SIGN_HASH_FN CRYPT_SIGN_HASH_W_FN #define CRYPT_SIGN_HASH_FN CRYPT_SIGN_HASH_W_FN
#define CRYPT_VERIFY_SIGNATURE_FN CRYPT_VERIFY_SIGNATURE_W_FN #define CRYPT_VERIFY_SIGNATURE_FN CRYPT_VERIFY_SIGNATURE_W_FN
@ -241,6 +249,7 @@ typedef struct {
CERT_VERIFY_CERTIFICATE_CHAIN_POLICY_FN CertVerifyCertificateChainPolicy; CERT_VERIFY_CERTIFICATE_CHAIN_POLICY_FN CertVerifyCertificateChainPolicy;
CERT_FREE_CERTIFICATE_CHAIN_FN CertFreeCertificateChain; CERT_FREE_CERTIFICATE_CHAIN_FN CertFreeCertificateChain;
CRYPT_GEN_RANDOM_FN CryptGenRandom; CRYPT_GEN_RANDOM_FN CryptGenRandom;
CERT_GET_INTENDED_KEY_USAGE_FN CertGetIntendedKeyUsage;
} capi_function_list_t; } capi_function_list_t;

View file

@ -210,26 +210,34 @@ exit:
return is_verified; return is_verified;
} }
static void static bool
log_sign_hash_data_last_error() check_cert_key_usage(PCCERT_CONTEXT certificate)
{ {
DWORD error = cp_function_list.GetLastError(); bool is_digital_signature_key_usage = false;
BYTE key_usage;
switch (error) { LOG_TRACE("check_cert_key_usage enter");
case ERROR_FUNCTION_FAILED:
LOG_ERROR("sign_hash_data exit with error. Last error code: "
"license is expired or not yet valid (0x%08x)", error);
break;
case SCARD_W_WRONG_CHV: if (cp_function_list.CertGetIntendedKeyUsage(
LOG_ERROR("sign_hash_data exit with error. Last error code: " X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
"the wrong PIN was presented (0x%08x)", error); certificate->pCertInfo,
break; &key_usage,
sizeof(key_usage))) {
default: if (key_usage & CERT_DIGITAL_SIGNATURE_KEY_USAGE) {
LOG_ERROR("sign_hash_data exit with error. Last error code: 0x%08x", error); is_digital_signature_key_usage = true;
break; }
} else {
LOG_ERROR("CertGetIntendedKeyUsage failed: 0x%08x", cp_function_list.GetLastError());
} }
if (is_digital_signature_key_usage) {
LOG_DEBUG("Certificate KeyUsage contains digitalSignature");
} else {
LOG_ERROR("Certificate KeyUsage does not contain digitalSignature");
}
LOG_TRACE("check_cert_key_usage exit");
return is_digital_signature_key_usage;
} }
int int
@ -247,6 +255,11 @@ open_signer_cert(cryptopro_context_t *ctx)
goto error; goto error;
} }
if (!check_cert_key_usage(ctx->signer_cert)) {
goto error;
}
LOG_TRACE("open_signer_cert exit"); LOG_TRACE("open_signer_cert exit");
return 0; return 0;
@ -274,6 +287,28 @@ close_signer_cert(cryptopro_context_t *ctx)
LOG_TRACE("close_signer_cert exit"); LOG_TRACE("close_signer_cert exit");
} }
static void
log_sign_hash_data_last_error()
{
DWORD error = cp_function_list.GetLastError();
switch (error) {
case ERROR_FUNCTION_FAILED:
LOG_ERROR("sign_hash_data exit with error. Last error code: "
"license is expired or not yet valid (0x%08x)", error);
break;
case SCARD_W_WRONG_CHV:
LOG_ERROR("sign_hash_data exit with error. Last error code: "
"the wrong PIN was presented (0x%08x)", error);
break;
default:
LOG_ERROR("sign_hash_data exit with error. Last error code: 0x%08x", error);
break;
}
}
static int static int
sign_hash_data(const cryptopro_context_t *ctx, const str_t *data, /*out*/ str_t *sign) sign_hash_data(const cryptopro_context_t *ctx, const str_t *data, /*out*/ str_t *sign)
{ {