Статус: Участник
Группы: Участники
Зарегистрирован: 20.02.2012(UTC) Сообщений: 15 Откуда: Msc
|
Как достоверно определить что сертификат является самоподписанным? Пытался делать так Код:
#pragma comment(lib, "crypt32.lib")
#include <windows.h>
#include <wincrypt.h>
#include <stdio.h>
#include <conio.h>
BOOL IsSelfSignedCert(PCCERT_CONTEXT pCertContext);
PCCERT_CONTEXT GetCertFromFile(LPWSTR fileName);
int main(void)
{
BOOL result = IsSelfSignedCert(GetCertFromFile(L"C:\\test\\WIN-RNR80913SK3-CA.cer"));
_getch();
return 0;
}
BOOL IsSelfSignedCert(PCCERT_CONTEXT pCertContext)
{
if(pCertContext == NULL)
return FALSE;
HCERTCHAINENGINE hChainEngine;
CERT_CHAIN_ENGINE_CONFIG ChainConfig;
PCCERT_CHAIN_CONTEXT pChainContext;
CERT_ENHKEY_USAGE EnhkeyUsage;
CERT_USAGE_MATCH CertUsage;
CERT_CHAIN_PARA ChainPara;
ZeroMemory(&EnhkeyUsage,sizeof(CERT_ENHKEY_USAGE));
CertUsage.dwType = USAGE_MATCH_TYPE_AND;
CertUsage.Usage = EnhkeyUsage;
ChainPara.cbSize = sizeof(CERT_CHAIN_PARA);
ChainPara.RequestedUsage = CertUsage;
ZeroMemory(&ChainConfig,sizeof(CERT_CHAIN_ENGINE_CONFIG));
ChainConfig.cbSize = sizeof(CERT_CHAIN_ENGINE_CONFIG);
ChainConfig.dwFlags = CERT_CHAIN_ENABLE_CACHE_AUTO_UPDATE;
if(!CertCreateCertificateChainEngine(&ChainConfig,&hChainEngine))
return FALSE;
if(!CertGetCertificateChain(NULL, pCertContext, NULL, NULL, &ChainPara, CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT, NULL, &pChainContext))
return FALSE;
switch(pChainContext->TrustStatus.dwErrorStatus)
{
case CERT_TRUST_NO_ERROR :
printf("No error found for this certificate or chain.\n");
break;
case CERT_TRUST_IS_NOT_TIME_VALID:
printf("This certificate or one of the certificates in the certificate chain is not time-valid.\n");
break;
case CERT_TRUST_IS_REVOKED:
printf("Trust for this certificate or one of the certificates in the certificate chain has been revoked.\n");
break;
case CERT_TRUST_IS_NOT_SIGNATURE_VALID:
printf("The certificate or one of the certificates in the certificate chain does not have a valid signature.\n");
break;
case CERT_TRUST_IS_NOT_VALID_FOR_USAGE:
printf("The certificate or certificate chain is not valid in its proposed usage.\n");
break;
case CERT_TRUST_IS_UNTRUSTED_ROOT:
printf("The certificate or certificate chain is based on an untrusted root.\n");
break;
case CERT_TRUST_REVOCATION_STATUS_UNKNOWN:
printf("The revocation status of the certificate or one of the certificates in the certificate chain is unknown.\n");
break;
case CERT_TRUST_IS_CYCLIC :
printf("One of the certificates in the chain was issued by a certification authority that the original certificate had certified.\n");
break;
case CERT_TRUST_IS_PARTIAL_CHAIN:
printf("The certificate chain is not complete.\n");
break;
case CERT_TRUST_CTL_IS_NOT_TIME_VALID:
printf("A CTL used to create this chain was not time-valid.\n");
break;
case CERT_TRUST_CTL_IS_NOT_SIGNATURE_VALID:
printf("A CTL used to create this chain did not have a valid signature.\n");
break;
case CERT_TRUST_CTL_IS_NOT_VALID_FOR_USAGE:
printf("A CTL used to create this chain is not valid for this usage.\n");
}
switch(pChainContext->TrustStatus.dwInfoStatus)
{
case CERT_TRUST_IS_SELF_SIGNED:
printf("This certificate is self-signed.\n");
return TRUE;
break;
case CERT_TRUST_HAS_PREFERRED_ISSUER:
printf("The certificate or chain has a preferred issuer.\n");
break;
}
CertFreeCertificateChain(pChainContext);
CertFreeCertificateChainEngine(hChainEngine);
return FALSE;
}
PCCERT_CONTEXT GetCertFromFile(LPWSTR fileName)
{
DWORD contentType;
HCERTSTORE store;
if(CryptQueryObject(CERT_QUERY_OBJECT_FILE, fileName, CERT_QUERY_CONTENT_FLAG_ALL, CERT_QUERY_FORMAT_FLAG_ALL, 0, NULL, &contentType, NULL, &store, NULL, NULL))
return CertFindCertificateInStore(store,X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,NULL,CERT_FIND_ANY,NULL,NULL);
return NULL;
}
Ожидал, что при проверке цепочки будет выставлен флаг CERT_TRUST_IS_SELF_SIGNED, но выставляется CERT_TRUST_HAS_PREFERRED_ISSUER. Вложение(я):  WIN-RNR80913SK3-CA.cer (1kb) загружен 9 раз(а).У Вас нет прав для просмотра или загрузки вложений. Попробуйте зарегистрироваться.
|
|
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 26.07.2011(UTC) Сообщений: 14,190   Сказал «Спасибо»: 621 раз Поблагодарили: 2397 раз в 1886 постах
|
а если проверять по идентификатору ключа издателя и субъекта? они будут совпадать ... хотя поле в примере (WIN-RNR80913SK3-CA.cer) - отсутствует... (как второй признак - что корневой :) Отредактировано пользователем 12 марта 2012 г. 14:45:30(UTC)
| Причина: Не указана |
|
|
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 26.07.2011(UTC) Сообщений: 14,190   Сказал «Спасибо»: 621 раз Поблагодарили: 2397 раз в 1886 постах
|
или сделать проверку подписи под сертификатом, открытым ключом из этого же сертификата Код:
CryptVerifyCertificateSignatureEx(
0,
X509_ASN_ENCODING,
CRYPT_VERIFY_CERT_SIGN_SUBJECT_CERT,
CERTCONTEXT,
CRYPT_VERIFY_CERT_SIGN_ISSUER_CERT,
CertCACONTEXT,
0,0
);
проверил на твоем - ОК - корневой... Отредактировано пользователем 12 марта 2012 г. 14:51:20(UTC)
| Причина: Не указана |
|
|
|
|
|
|
Статус: Участник
Группы: Участники
Зарегистрирован: 20.02.2012(UTC) Сообщений: 15 Откуда: Msc
|
Спасибо. А почему API глючит не известно?
|
|
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 26.07.2011(UTC) Сообщений: 14,190   Сказал «Спасибо»: 621 раз Поблагодарили: 2397 раз в 1886 постах
|
acoder написал:Спасибо. А почему API глючит не известно? про CERT_TRUST_HAS_PREFERRED_ISSUER ? |
|
|
|
|
|
|
Статус: Участник
Группы: Участники
Зарегистрирован: 20.02.2012(UTC) Сообщений: 15 Откуда: Msc
|
Да. Я думал будет CERT_TRUST_IS_SELF_SIGNED???
|
|
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 25.12.2007(UTC) Сообщений: 1,733  Откуда: КРИПТО-ПРО Поблагодарили: 177 раз в 168 постах
|
Вы смотрите статус цепочки, а Цитата:CERT_TRUST_IS_SELF_SIGNED This certificate is self-signed. This status code applies to certificates only. Посмотрите статус внутри CERT_CHAIN_ELEMENT. |
|
|
|
|
|
|
Статус: Участник
Группы: Участники
Зарегистрирован: 20.02.2012(UTC) Сообщений: 15 Откуда: Msc
|
Спасибо. Не сразу понял назначение rgpChain. Сделал так Код:
PCERT_SIMPLE_CHAIN pSimpleChain = *pChainContext->rgpChain;
PCERT_CHAIN_ELEMENT pCertChainElement = *pSimpleChain->rgpElement;
DWORD status = pCertChainElement->TrustStatus.dwInfoStatus;
if(status & CERT_TRUST_IS_SELF_SIGNED)
printf("CERT_TRUST_IS_SELF_SIGNED\n");
|
|
|
|
|
|
Быстрый переход
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.
Important Information:
The Форум КриптоПро uses cookies. By continuing to browse this site, you are agreeing to our use of cookies.
More Details
Close