Ключевое слово в защите информации
ключевое слово
в защите информации
Получить ГОСТ TLS-сертификат для домена (SSL-сертификат)
Добро пожаловать, Гость! Чтобы использовать все возможности Вход. Новые регистрации запрещены.

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline acoder  
#1 Оставлено : 12 марта 2012 г. 14:40:31(UTC)
acoder

Статус: Участник

Группы: Участники
Зарегистрирован: 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 раз(а).

У Вас нет прав для просмотра или загрузки вложений. Попробуйте зарегистрироваться.
Offline Андрей Писарев  
#2 Оставлено : 12 марта 2012 г. 14:42:12(UTC)
Андрей *

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 26.07.2011(UTC)
Сообщений: 14,190
Мужчина
Российская Федерация

Сказал «Спасибо»: 621 раз
Поблагодарили: 2397 раз в 1886 постах
а если проверять по идентификатору ключа издателя и субъекта?
они будут совпадать ...

хотя поле в примере (WIN-RNR80913SK3-CA.cer) - отсутствует... (как второй признак - что корневой :)

Отредактировано пользователем 12 марта 2012 г. 14:45:30(UTC)  | Причина: Не указана

Техническую поддержку оказываем тут
Наша база знаний
Offline Андрей Писарев  
#3 Оставлено : 12 марта 2012 г. 14:48:33(UTC)
Андрей *

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 26.07.2011(UTC)
Сообщений: 14,190
Мужчина
Российская Федерация

Сказал «Спасибо»: 621 раз
Поблагодарили: 2397 раз в 1886 постах
или сделать проверку подписи под сертификатом, открытым ключом из этого же сертификата Anxious

Код:


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)  | Причина: Не указана

Техническую поддержку оказываем тут
Наша база знаний
Offline acoder  
#4 Оставлено : 12 марта 2012 г. 15:40:41(UTC)
acoder

Статус: Участник

Группы: Участники
Зарегистрирован: 20.02.2012(UTC)
Сообщений: 15
Откуда: Msc

Спасибо.
А почему API глючит не известно?
Offline Андрей Писарев  
#5 Оставлено : 12 марта 2012 г. 16:25:05(UTC)
Андрей *

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 26.07.2011(UTC)
Сообщений: 14,190
Мужчина
Российская Федерация

Сказал «Спасибо»: 621 раз
Поблагодарили: 2397 раз в 1886 постах
acoder написал:
Спасибо.
А почему API глючит не известно?


про CERT_TRUST_HAS_PREFERRED_ISSUER ?
Техническую поддержку оказываем тут
Наша база знаний
Offline acoder  
#6 Оставлено : 12 марта 2012 г. 16:31:04(UTC)
acoder

Статус: Участник

Группы: Участники
Зарегистрирован: 20.02.2012(UTC)
Сообщений: 15
Откуда: Msc

Да. Я думал будет CERT_TRUST_IS_SELF_SIGNED???
Offline Kirill Sobolev  
#7 Оставлено : 12 марта 2012 г. 18:16:58(UTC)
Кирилл Соболев

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 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.
Техническую поддержку оказываем тут
Наша база знаний
Offline acoder  
#8 Оставлено : 12 марта 2012 г. 19:28:46(UTC)
acoder

Статус: Участник

Группы: Участники
Зарегистрирован: 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");
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Guest
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.