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

Уведомление

Icon
Error

3 Страницы<123
Опции
К последнему сообщению К первому непрочитанному
Offline Kirill Sobolev  
#21 Оставлено : 14 ноября 2008 г. 18:35:59(UTC)
Кирилл Соболев

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

Группы: Участники
Зарегистрирован: 25.12.2007(UTC)
Сообщений: 1,732
Мужчина
Откуда: КРИПТО-ПРО

Поблагодарили: 177 раз в 168 постах
алгоритм создания правильный
Техническую поддержку оказываем тут
Наша база знаний
Offline akulema  
#22 Оставлено : 17 ноября 2008 г. 18:08:31(UTC)
akulema

Статус: Активный участник

Группы: Участники
Зарегистрирован: 17.10.2008(UTC)
Сообщений: 70

Уж не знаю. Я, пожалуй, выложу код. Может будет возможность глянуть и сказать, что не так.
Код:

int CCryptographicManager::CreateKeyAndCertificate(CString sFile, CString sPassword, TCertInfo &certInfo, bool bSelfSigned)																										
{
	int num;
	WORD wBits = 0, wMonths = 0;
	DWORD dwUsage = 0, dwKeyType = AT_KEYEXCHANGE;
	bool bSubjectUser = true;
	bool bIssuerUser = true;

	SYSTEMTIME sysTD;
	FILETIME udcTimeBefore, udcTimeAfter;
	BOOL bReturn = FALSE;
	BOOL bResult;
	LPBYTE pbNameBlob = NULL;
	LPSTR szContainer = NULL;
	HCRYPTPROV hProv = 0;
	HCRYPTPROV hIssuerProv = 0;
	HCRYPTPROV hCryptProvCA = 0;
	HCRYPTKEY hPubKey = 0;
	HCRYPTKEY hSessionKey = 0;
	HCRYPTKEY hPrKey= 0;
	HCRYPTHASH hHash = 0;
	HCERTSTORE hStore = 0;
	HANDLE hCertFile = INVALID_HANDLE_VALUE;
	HANDLE hKeyFile = INVALID_HANDLE_VALUE;
	PCRYPT_DATA_BLOB KeyId = NULL;
	PCERT_PUBLIC_KEY_INFO PublicKeyInfo = NULL;
	PCCERT_CONTEXT pIssuerCert = NULL;
	PCCERT_CONTEXT pCertContext = NULL;

	LPBYTE pbKeyIdentifier = NULL;
	LPBYTE SubjectKeyIdentifier = NULL;
	LPBYTE pbKeyUsage = NULL;
	LPBYTE pbEnhKeyUsage = NULL;
	LPBYTE pbBasicConstraints = NULL;
	LPBYTE pbAuthorityKeyId = NULL;
	LPBYTE bpEncodedCert = NULL;
	LPBYTE pbExportedKey = NULL;
	LPBYTE pbExtEncodedRole = NULL;
	PCRYPT_KEY_PROV_INFO KeyProvInfo = 0;

	CERT_ENHKEY_USAGE CertEnhKeyUsage = { 0, NULL };
	BYTE SerialNumber[8];
	CERT_BASIC_CONSTRAINTS2_INFO BasicConstraints;
	CERT_AUTHORITY_KEY_ID_INFO AuthorityKeyId;
	BYTE ByteData;
	CRYPT_BIT_BLOB KeyUsage;
	CERT_EXTENSION CertExtension[5];
	CRYPT_DATA_BLOB CertKeyIdentifier;
	CERT_NAME_BLOB IssuerName;
	HANDLE hHeap = GetProcessHeap();
	CERT_INFO CertInfo;
	DWORD dwSize, m, q;
	DWORD dwAcquireFlags, dwIssuerKeyType = 0;
	DWORD dwIssuerFlags, dwSubjectFlags;	
	CHAR szProvider[260] = { MS_DEF_PROV };
	DWORD dwProviderType = PROV_RSA_FULL;
	BOOL bAddAuthorityExtension = FALSE;
	DWORD cbExtEncodedRole;
	WCHAR *unicodeConvertedString;

	USES_CONVERSION;

	/************************************************************************/
	/*                                                                      */
	/************************************************************************/	

	// дополнительная инфорамция
	const int nConstAttrCount = 7;
	int nAttrCount = 0;
	CERT_RDN_ATTR rgNameAttr[nConstAttrCount];
	{
		nAttrCount = 0;

		// полное имя
		unicodeConvertedString = T2W(certInfo.sCommonName.GetBuffer());
		certInfo.sFullName.ReleaseBuffer();

		rgNameAttr[nAttrCount].dwValueType = CERT_RDN_UNICODE_STRING;
		rgNameAttr[nAttrCount].pszObjId = szOID_COMMON_NAME;
		rgNameAttr[nAttrCount].Value.cbData = strlen(certInfo.sCommonName)*2;
		rgNameAttr[nAttrCount++].Value.pbData = (BYTE*)(unicodeConvertedString);

		// электронаня почта
		unicodeConvertedString = T2W(certInfo.sMail.GetBuffer());
		certInfo.sFullName.ReleaseBuffer();

		rgNameAttr[nAttrCount].dwValueType = CERT_RDN_UNICODE_STRING;
		rgNameAttr[nAttrCount].pszObjId = szOID_RSA_emailAddr;
		rgNameAttr[nAttrCount].Value.cbData = strlen(certInfo.sMail)*2;
		rgNameAttr[nAttrCount++].Value.pbData = (BYTE*)(unicodeConvertedString);

		// организация
		unicodeConvertedString = T2W(certInfo.sOrganization.GetBuffer());
		certInfo.sFullName.ReleaseBuffer();

		rgNameAttr[nAttrCount].dwValueType = CERT_RDN_UNICODE_STRING;
		rgNameAttr[nAttrCount].pszObjId = szOID_ORGANIZATION_NAME;
		rgNameAttr[nAttrCount].Value.cbData = strlen(certInfo.sOrganization)*2;
		rgNameAttr[nAttrCount++].Value.pbData = (BYTE*)(unicodeConvertedString);			

		// подразделение
		unicodeConvertedString = T2W(certInfo.sDevision.GetBuffer());
		certInfo.sFullName.ReleaseBuffer();

		rgNameAttr[nAttrCount].dwValueType = CERT_RDN_UNICODE_STRING;
		rgNameAttr[nAttrCount].pszObjId = szOID_ORGANIZATIONAL_UNIT_NAME;
		rgNameAttr[nAttrCount].Value.cbData = strlen(certInfo.sDevision)*2;
		rgNameAttr[nAttrCount++].Value.pbData = (BYTE*)(unicodeConvertedString);

		// город
		unicodeConvertedString = T2W(certInfo.sTown.GetBuffer());
		certInfo.sFullName.ReleaseBuffer();

		rgNameAttr[nAttrCount].dwValueType = CERT_RDN_UNICODE_STRING;
		rgNameAttr[nAttrCount].pszObjId = szOID_LOCALITY_NAME;
		rgNameAttr[nAttrCount].Value.cbData = strlen(certInfo.sTown)*2;
		rgNameAttr[nAttrCount++].Value.pbData = (BYTE*)(unicodeConvertedString);

		// область
		unicodeConvertedString = T2W(certInfo.sRegion.GetBuffer());
		certInfo.sFullName.ReleaseBuffer();

		rgNameAttr[nAttrCount].dwValueType = CERT_RDN_UNICODE_STRING;
		rgNameAttr[nAttrCount].pszObjId = szOID_STATE_OR_PROVINCE_NAME;
		rgNameAttr[nAttrCount].Value.cbData = strlen(certInfo.sRegion)*2;
		rgNameAttr[nAttrCount++].Value.pbData = (BYTE*)(unicodeConvertedString);

		// страна
		unicodeConvertedString = T2W(certInfo.sCountry.GetBuffer());
		certInfo.sFullName.ReleaseBuffer();

		rgNameAttr[nAttrCount].dwValueType = CERT_RDN_UNICODE_STRING;
		rgNameAttr[nAttrCount].pszObjId = szOID_COUNTRY_NAME;
		rgNameAttr[nAttrCount].Value.cbData = strlen(certInfo.sCountry)*2;
		rgNameAttr[nAttrCount++].Value.pbData = (BYTE*)(unicodeConvertedString);

	}

	CERT_RDN rgRDN[nConstAttrCount]=
	{
		{1, &rgNameAttr[0]},
		{1, &rgNameAttr[1]},
		{1, &rgNameAttr[2]},
		{1, &rgNameAttr[3]},
		{1, &rgNameAttr[4]},
		{1, &rgNameAttr[5]},
		{1, &rgNameAttr[6]},
	};			
	CERT_NAME_INFO Name = {nConstAttrCount, &rgRDN[0]};

	if(CryptEncodeObject(
		(PKCS_7_ASN_ENCODING | X509_ASN_ENCODING), // Encoding type
		X509_NAME, // Structure type
		&Name, // Address of CERT_NAME_INFO structure
		NULL, // pbEncoded
		&dwSize)) // pbEncoded size
	{
		printf("The first call to CryptEncodeObject succeeded. \n");
	}
	else
	{
		printf("First call to CryptEncodeObject failed.\
			   \nA public/private key pair may not exit in the container. \n");
		ShowError(GetLastError());
	}
	//-------------------------------------------------------------------
	// Allocate memory for the encoded name.

	if(!(pbNameBlob = (BYTE*)malloc(dwSize)))
		printf("pbNamencoded malloc operation failed.\n");

	//-------------------------------------------------------------------
	// Call CryptEncodeObject to do the actual encoding of the name.

	if(CryptEncodeObject(
		(PKCS_7_ASN_ENCODING | X509_ASN_ENCODING), // Encoding type
		X509_NAME, // Structure type
		&Name, // Address of CERT_NAME_INFO structure
		pbNameBlob, // pbEncoded
		&dwSize)) // pbEncoded size
	{
		printf("The object is encoded. \n");
	}
	else
	{
		free(pbNameBlob);
		printf("Second call to CryptEncodeObject failed.\n");
	}

	IssuerName.cbData = dwSize;
	IssuerName.pbData = pbNameBlob;

	/************************************************************************/
	/*                                                                      */
	/************************************************************************/

	if (bSubjectUser)
	{
		/* Certificate will be in the User store and*/
		/* key container will be a User container*/
		dwAcquireFlags = 0;
		dwSubjectFlags = CERT_SYSTEM_STORE_CURRENT_USER;
		dwSubjectFlags = CERT_SYSTEM_STORE_LOCAL_MACHINE;
	}		

	if (bIssuerUser)
	{
		/* Get Issuer Certificate from User store*/
		dwIssuerFlags = CERT_SYSTEM_STORE_CURRENT_USER;
	}
	else
	{
		/* Get Issuer Certificate from Machine store*/
		dwIssuerFlags = CERT_SYSTEM_STORE_LOCAL_MACHINE;
	}

	/* Convert Enhanced Key usage number to*/
	/* Enhanced Key Usage extension*/

	/* Find Enhanced Key Usage extensions count*/
	for (m = 0; m < g_EnhKeyUsage.dwCount; m++)
	{
		if ((g_EnhKeyUsage.dwValue[m] & dwUsage) == g_EnhKeyUsage.dwValue[m])
		{
			CertEnhKeyUsage.cUsageIdentifier++;
		}
	}

	/* If extensions exist continue*/
	if (CertEnhKeyUsage.cUsageIdentifier != 0)
	{
		/* Allocate memory for Enhanced Key Usage array*/
		CertEnhKeyUsage.rgpszUsageIdentifier =
			(LPSTR *)HeapAlloc(hHeap, 0, CertEnhKeyUsage.cUsageIdentifier * sizeof(LPSTR));
		if (!CertEnhKeyUsage.rgpszUsageIdentifier)
		{
			printf("Unable to allocate memory for Enhanced Usage array\n");
			return false;
		}

		/* Initialize Enhanced Key Usage array to NULL*/
		for (m = 0; m < CertEnhKeyUsage.cUsageIdentifier; m++)
		{
			CertEnhKeyUsage.rgpszUsageIdentifier[m] = NULL;
		}

		/* Add proper extension OID to array*/
		q = 0;
		for (m = 0; m < g_EnhKeyUsage.dwCount; m++)
		{
			if ((g_EnhKeyUsage.dwValue[m] & dwUsage) == g_EnhKeyUsage.dwValue[m])
			{
				CertEnhKeyUsage.rgpszUsageIdentifier[q++] = g_EnhKeyUsage.szUsage[m];
			}
		}
	}	


	//загрузка закрытого ключа центра сертификации для подписи
	BYTE* pbData= NULL;
	int iDataLen = 0;

	// тут пока просто зашитый ключ УЦ
	iDataLen= _CurKeyBlob.GetLength()/2;
	pbData= new BYTE [iDataLen+1];
	LPTSTR szPKBitStr= _CurKeyBlob.GetBuffer(_CurKeyBlob.GetLength());
	StrToByte(_PrvKeyBlob.GetLength(), szPKBitStr, pbData);
	_CurKeyBlob.ReleaseBuffer();

	//Создание (получение) контекста и контейнера ключей по умолчанию с именем TempKey для кодирования ключа
	szContainer = "TempKeyCA";
	if(!CryptAcquireContext(&hCryptProvCA, szContainer, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET))
	{
		if(!CryptAcquireContext(&hCryptProvCA, szContainer, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET/**/)) 
		{
			HandleError(_T("Ошибка при вызове CryptAcquireContext для ключа подписи."));				
		}
		else
			TRACE0(_T("КРИПТОГРАФИЧЕСКИЙ КОНТЕКСТ СОЗДАН\n"));
	}
	else
		TRACE0(_T("КРИПТОГРАФИЧЕСКИЙ КОНТЕКСТ ПОЛУЧЕН\n"));

	if(!bSelfSigned)
	{
		//Загрузка закрытого ключа.
		if(!CryptImportKey(hCryptProvCA, pbData, iDataLen, 0, CRYPT_EXPORTABLE, &hPrKey))
		{
			ShowError(GetLastError());
		}		
	}

	/* Create new crypto context*/
	szContainer = "TempKey";
	if(!CryptAcquireContext(&hProv, szContainer, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET))
		if(!CryptAcquireContext(&hProv, szContainer, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET)) 
		{
			ShowError(GetLastError());
			return false;
		}
		else
			TRACE0(_T("КРИПТОГРАФИЧЕСКИЙ КОНТЕКСТ СОЗДАН\n"));
	else
		TRACE0(_T("КРИПТОГРАФИЧЕСКИЙ КОНТЕКСТ ПОЛУЧЕН\n"));


	/* Generate Private/Public key pair*/
	bResult = CryptGenKey(hProv, dwKeyType, CRYPT_EXPORTABLE+(wBits<<16), &hPubKey);
	if (!bResult)
	{
		printf("CryptGenKey failed with %x\n", GetLastError());
		return false;
	}

	/* Zero CERT_INFO structure*/
	ZeroMemory(&CertInfo, sizeof(CertInfo));

	/* Set Version of Certificate*/
	CertInfo.dwVersion = CERT_V3;

	/* Create Random Serial Number*/
	bResult = CryptGenRandom(hProv, 8, SerialNumber);
	if (!bResult)
	{
		printf("CryptGenRandom failed with %x\n", GetLastError());
		return false;
	}

	// запоминаем серийный номер
	int iSNLen= 2*8 + 1;
	LPTSTR szSerialNumber = new char[iSNLen];
	ByteToStr(8, SerialNumber, szSerialNumber);
	certInfo.sSerialNumber = szSerialNumber;	

	/* Set Serial Number of Certificate*/
	CertInfo.SerialNumber.cbData = 8;
	CertInfo.SerialNumber.pbData = SerialNumber;

	/* Set Signature Algorithm of Certificate*/
	CRYPT_ALGORITHM_IDENTIFIER SubjKeyInfo;
	CRYPT_OBJID_BLOB  Parameters;
	memset(&Parameters, 0, sizeof(Parameters));
	SubjKeyInfo.pszObjId= szOID_RSA_MD5RSA;
	SubjKeyInfo.Parameters = Parameters;

	CertInfo.SignatureAlgorithm = SubjKeyInfo;

	// дата начала действия
	ZeroMemory(&sysTD, sizeof(sysTD));
	sysTD.wYear= certInfo.dNotBefor.GetYear(); 
	sysTD.wMonth= certInfo.dNotBefor.GetMonth();
	sysTD.wDay= certInfo.dNotBefor.GetDay();
	SystemTimeToFileTime(&sysTD, &udcTimeBefore);
	CertInfo.NotBefore= udcTimeBefore;

	// дата окончания действия
	sysTD.wYear= certInfo.dNotAfter.GetYear(); 
	sysTD.wMonth= certInfo.dNotAfter.GetMonth();
	sysTD.wDay= certInfo.dNotAfter.GetDay();	
	SystemTimeToFileTime(&sysTD, &udcTimeAfter);
	CertInfo.NotAfter= udcTimeAfter;	

	/* Get Public Key Info size*/
	dwKeyType= AT_KEYEXCHANGE;
	bResult = CryptExportPublicKeyInfo(hProv, dwKeyType,
		ENCODING_TYPE, NULL, &dwSize);
	if (!bResult)
	{
		printf("CryptExportPublicKeyInfo failed with %x\n", GetLastError());
		return false;
	}

	/* Allocate memory for Public Key Info*/
	PublicKeyInfo = (PCERT_PUBLIC_KEY_INFO)HeapAlloc(hHeap, 0, dwSize);
	if (!PublicKeyInfo)
	{
		printf("Unable to allocate memory for public key info\n");
		return false;
	}

	/* Get Public Key Info*/
	bResult = CryptExportPublicKeyInfo(hProv, dwKeyType,
		ENCODING_TYPE,
		PublicKeyInfo, &dwSize);
	if (!bResult)
	{
		printf("CryptExportPublicKeyInfo failed with %x\n", GetLastError());
		return false;
	}

	/* Set Public Key info of Certificate*/
	CertInfo.SubjectPublicKeyInfo = *PublicKeyInfo;

	/* Create Hash*/
	bResult = CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash);
	if (!bResult)
	{
		printf("CryptCreateHash failed with %x\n", GetLastError());
		return false;
	}

	/* Hash Public Key Info*/
	bResult = CryptHashData(hHash, (LPBYTE)PublicKeyInfo, dwSize, 0);
	if (!bResult)
	{
		printf("CryptHashData failed with %x\n", GetLastError());
		return false;
	}

	/* Get Size of Hash*/
	bResult = CryptGetHashParam(hHash, HP_HASHVAL, NULL, &dwSize, 0);
	if (!bResult)
	{
		printf("CryptGetHashParam failed with %x\n", GetLastError());
		return false;
	}

	/* Allocate Memory for Key Identifier (hash of Public Key info)*/
	pbKeyIdentifier = (LPBYTE)HeapAlloc(hHeap, 0, dwSize);
	if (!pbKeyIdentifier)
	{
		printf("Unable to allocate memory for Hashed Public key Info\n");
		return false;
	}

	/* Get Hash of Public Key Info*/
	bResult = CryptGetHashParam(hHash, HP_HASHVAL, pbKeyIdentifier, &dwSize, 0);
	if (!bResult)
	{
		printf("CryptGetHashParam failed with %x\n", GetLastError());
		return false;
	}

	/* We will use this to set the Key Identifier extension*/
	CertKeyIdentifier.cbData = dwSize;
	CertKeyIdentifier.pbData = pbKeyIdentifier;

	/* Set Issuer of Certificate*/
	if (bSelfSigned) 
	{
		CertInfo.Subject = IssuerName;
		CertInfo.Issuer = IssuerName;
	}
	else
	{
		pIssuerCert= CertCreateCertificateContext(ENCODING_TYPE, certInfo.pbRootCertBlob, certInfo.nRootCertBlobSize);

		CertInfo.Subject = IssuerName;
		CertInfo.Issuer = pIssuerCert->pCertInfo->Subject;
	}

	/* Get Subject Key Identifier Extension size*/
	bResult = CryptEncodeObject(ENCODING,
		szOID_SUBJECT_KEY_IDENTIFIER,
		(LPVOID)&CertKeyIdentifier,
		NULL, &dwSize);
	if (!bResult)
	{
		printf("CryptEncodeObject failed with %x\n", GetLastError());
		return false;
	}

	/* Allocate Memory for Subject Key Identifier Blob*/
	SubjectKeyIdentifier = (LPBYTE)HeapAlloc(hHeap, 0, dwSize);
	if (!SubjectKeyIdentifier)
	{
		printf("Unable to allocate memory for Subject Key Identifier\n");
		return false;
	}

	/* Get Subject Key Identifier Extension*/
	bResult = CryptEncodeObject(ENCODING,
		szOID_SUBJECT_KEY_IDENTIFIER,
		(LPVOID)&CertKeyIdentifier,
		SubjectKeyIdentifier, &dwSize);
	if (!bResult)
	{
		printf("CryptEncodeObject failed with %x\n", GetLastError());
		return false;
	}

	/* Set Subject Key Identifier*/
	CertExtension[CertInfo.cExtension].pszObjId = szOID_SUBJECT_KEY_IDENTIFIER;
	CertExtension[CertInfo.cExtension].fCritical = FALSE;
	CertExtension[CertInfo.cExtension].Value.cbData = dwSize;
	CertExtension[CertInfo.cExtension].Value.pbData = SubjectKeyIdentifier;

	/* Increase extension count*/
	CertInfo.cExtension++;

	/* Set Key Usage according to Public Key Type*/
	ZeroMemory(&KeyUsage, sizeof(KeyUsage));
	KeyUsage.cbData = 1;
	KeyUsage.pbData = &ByteData;

	if (dwKeyType == AT_SIGNATURE)
	{
		ByteData = CERT_DIGITAL_SIGNATURE_KEY_USAGE|
			CERT_NON_REPUDIATION_KEY_USAGE|
			CERT_KEY_CERT_SIGN_KEY_USAGE |
			CERT_CRL_SIGN_KEY_USAGE;
	}

	if (dwKeyType == AT_KEYEXCHANGE)
	{
		ByteData = CERT_DIGITAL_SIGNATURE_KEY_USAGE | 
			CERT_NON_REPUDIATION_KEY_USAGE;		
	}

	/* Get Key Usage blob size*/
	bResult = CryptEncodeObject(ENCODING,
		X509_KEY_USAGE,
		(LPVOID)&KeyUsage,
		NULL, &dwSize);
	if (!bResult)
	{
		printf("CryptEncodeObject failed with %x\n", GetLastError());
		return false;
	}

	/* Allocate Memory for Key Usage Blob*/
	pbKeyUsage = (LPBYTE)HeapAlloc(hHeap, 0, dwSize);
	if (!pbKeyUsage)
	{
		printf("Unable to allocate memory for Subject Key Identifier\n");
		return false;
	}

	/* Get Key Usage Extension blob*/
	bResult = CryptEncodeObject(ENCODING,
		X509_KEY_USAGE,
		(LPVOID)&KeyUsage,
		pbKeyUsage, &dwSize);
	if (!bResult)
	{
		printf("CryptEncodeObject failed with %x\n", GetLastError());
		return false;
	}

	/* Set Key Usage extension*/
	CertExtension[CertInfo.cExtension].pszObjId = szOID_KEY_USAGE;
	CertExtension[CertInfo.cExtension].fCritical = FALSE;
	CertExtension[CertInfo.cExtension].Value.cbData = dwSize;
	CertExtension[CertInfo.cExtension].Value.pbData = pbKeyUsage;

	/* Increase extension count*/
	CertInfo.cExtension++;

	// записываем роли пользователя
	if(!certInfo.sUserRoles.IsEmpty())
	{
		certInfo.sUserRoles.Replace(";", "#");
		char *strRoles= new char [certInfo.sUserRoles.GetLength()+1];
		strcpy(strRoles, certInfo.sUserRoles);

		CRYPT_DATA_BLOB roles;
		roles.pbData= (PBYTE)strRoles;
		roles.cbData= certInfo.sUserRoles.GetLength()+1;

		CryptEncodeObject(ENCODING_TYPE, szOID_SUBJECT_KEY_IDENTIFIER, &roles,
			NULL, &cbExtEncodedRole);
		pbExtEncodedRole= new BYTE [cbExtEncodedRole];
		CryptEncodeObject(ENCODING_TYPE, szOID_SUBJECT_KEY_IDENTIFIER, &roles,
			pbExtEncodedRole, &cbExtEncodedRole);

		//запись ролей
		CertExtension[CertInfo.cExtension].pszObjId= szOID_USER_ROLE_SET;
		CertExtension[CertInfo.cExtension].fCritical= FALSE;
		CertExtension[CertInfo.cExtension].Value.cbData = cbExtEncodedRole;
		CertExtension[CertInfo.cExtension].Value.pbData = pbExtEncodedRole;

		CertInfo.cExtension++;

		// память
		delete [] strRoles;
		delete [] pbExtEncodedRole;
	}

	if (CertEnhKeyUsage.cUsageIdentifier != 0)
	{
		/* Get Enhanced Key Usage size*/
		bResult = CryptEncodeObject(ENCODING,
			X509_ENHANCED_KEY_USAGE,
			(LPVOID)&CertEnhKeyUsage,
			NULL, &dwSize);
		if (!bResult)
		{
			printf("CryptEncodeObject failed with %x\n", GetLastError());
			return false;
		}

		/* Allocate Memory for Enhanced Key usage Blob*/
		pbEnhKeyUsage = (LPBYTE)HeapAlloc(hHeap, 0, dwSize);
		if (!pbEnhKeyUsage)
		{
			printf("Unable to allocate memory for Subject Key Identifier\n");
			return false;
		}

		/* Get Enhanced Key Usage Extension blob*/
		bResult = CryptEncodeObject(ENCODING,
			X509_ENHANCED_KEY_USAGE,
			(LPVOID)&CertEnhKeyUsage,
			pbEnhKeyUsage, &dwSize);
		if (!bResult)
		{
			printf("CryptEncodeObject failed with %x\n", GetLastError());
			return false;
		}

		/* Set Enhanced Key Usage extension*/
		CertExtension[CertInfo.cExtension].pszObjId = szOID_ENHANCED_KEY_USAGE;
		CertExtension[CertInfo.cExtension].fCritical = FALSE;
		CertExtension[CertInfo.cExtension].Value.cbData = dwSize;
		CertExtension[CertInfo.cExtension].Value.pbData = pbEnhKeyUsage;

		/* Increase extension count*/
		CertInfo.cExtension++;
	}

	/* Zero Basic Constraints structure*/
	ZeroMemory(&BasicConstraints, sizeof(BasicConstraints));

	/* Self-signed is always a CA*/
	if (bSelfSigned)
	{
		BasicConstraints.fCA = TRUE;
		BasicConstraints.fPathLenConstraint = TRUE;
		BasicConstraints.dwPathLenConstraint = 1;
	}	
	else
	{
		BasicConstraints.fCA = false;
	}

	/* Get Basic Constraints blob size*/
	bResult = CryptEncodeObject(ENCODING,
		X509_BASIC_CONSTRAINTS2,
		(LPVOID)&BasicConstraints,
		NULL, &dwSize);
	if (!bResult)
	{
		printf("CryptEncodeObject failed with %x\n", GetLastError());
		return false;
	}

	/* Allocate Memory for Basic Constraints Blob*/
	pbBasicConstraints = (LPBYTE)HeapAlloc(hHeap, 0, dwSize);
	if (!pbBasicConstraints)
	{
		printf("Unable to allocate memory for Subject Key Identifier\n");
		return false;
	}

	/* Get Basic Constraints Extension blob*/
	bResult = CryptEncodeObject(ENCODING,
		X509_BASIC_CONSTRAINTS2,
		(LPVOID)&BasicConstraints,
		pbBasicConstraints, &dwSize);
	if (!bResult)
	{
		printf("CryptEncodeObject failed with %x\n", GetLastError());
		return false;
	}

	/* Set Basic Constraints extension*/
	CertExtension[CertInfo.cExtension].pszObjId = szOID_BASIC_CONSTRAINTS2;
	CertExtension[CertInfo.cExtension].fCritical = FALSE;
	CertExtension[CertInfo.cExtension].Value.cbData = dwSize;
	CertExtension[CertInfo.cExtension].Value.pbData = pbBasicConstraints;

	/* Increase extension count*/
	CertInfo.cExtension++;

	if (bSelfSigned)
	{
		AuthorityKeyId.KeyId = CertKeyIdentifier;
		AuthorityKeyId.CertIssuer = CertInfo.Issuer;
		AuthorityKeyId.CertSerialNumber = CertInfo.SerialNumber;
		bAddAuthorityExtension = TRUE;
	}
	else
	{
		if (pIssuerCert)
		{
			AuthorityKeyId.KeyId.cbData = 0;
			AuthorityKeyId.KeyId.pbData = NULL; 			

			AuthorityKeyId.CertIssuer = pIssuerCert->pCertInfo->Issuer;
			AuthorityKeyId.CertSerialNumber = pIssuerCert->pCertInfo->SerialNumber;
			bAddAuthorityExtension = TRUE;
		}
	}

	if (bAddAuthorityExtension)
	{
		/* Get Authority Key Id blob size*/
		bResult = CryptEncodeObject(ENCODING,
			X509_AUTHORITY_KEY_ID,
			(LPVOID)&AuthorityKeyId,
			NULL, &dwSize);
		if (!bResult)
		{
			printf("CryptEncodeObject failed with %x\n", GetLastError());
			return false;
		}

		/* Allocate Authority Key Id Blob*/
		pbAuthorityKeyId = (LPBYTE)HeapAlloc(hHeap, 0, dwSize);
		if (!pbAuthorityKeyId)
		{
			printf("Unable to allocate memory for Subject Key Identifier\n");
			return false;
		}

		/* Get Authority Key Id blob*/
		bResult = CryptEncodeObject(ENCODING,
			X509_AUTHORITY_KEY_ID,
			(LPVOID)&AuthorityKeyId,
			pbAuthorityKeyId, &dwSize);
		if (!bResult)
		{
			printf("CryptEncodeObject failed with %x\n", GetLastError());
			return false;
		}

		/* Set Authority Key Id extension*/
		CertExtension[CertInfo.cExtension].pszObjId = szOID_AUTHORITY_KEY_IDENTIFIER;
		CertExtension[CertInfo.cExtension].fCritical = FALSE;
		CertExtension[CertInfo.cExtension].Value.cbData = dwSize;
		CertExtension[CertInfo.cExtension].Value.pbData = pbAuthorityKeyId;

		/* Increase extension count*/
		CertInfo.cExtension++;
	}	

	CertInfo.rgExtension = CertExtension;

	if (bSelfSigned)
	{
		/* Get Encoded Certificate Size*/
		bResult = CryptSignAndEncodeCertificate(hProv, AT_KEYEXCHANGE,
			/*X509_ASN_ENCODING*/(PKCS_7_ASN_ENCODING | X509_ASN_ENCODING), X509_CERT_TO_BE_SIGNED,
			(LPVOID)&CertInfo,
			&(CertInfo.SignatureAlgorithm),
			NULL, NULL, &dwSize);
		if (!bResult)
		{
			printf("CryptSignAndEncodeCertificate failed with %x\n", GetLastError());
			ShowError(GetLastError());
			return false;
		}

		/* Allocate memory for encoded certificate*/
		bpEncodedCert = (LPBYTE)HeapAlloc(hHeap, 0, dwSize);
		if (!bpEncodedCert)
		{
			printf("Unable to allocate memory for encoded certficate\n");
			return false;
		}

		/* Sign and Encode certificate*/
		bResult = CryptSignAndEncodeCertificate(hProv, AT_KEYEXCHANGE,
			/*X509_ASN_ENCODING*/(PKCS_7_ASN_ENCODING | X509_ASN_ENCODING), X509_CERT_TO_BE_SIGNED,
			(LPVOID)&CertInfo,
			&(CertInfo.SignatureAlgorithm),
			NULL, bpEncodedCert, &dwSize);
		if (!bResult)
		{
			printf("CryptSignAndEncodeCertificate failed with %x\n", GetLastError());
			return false;
		}			
	}	
	else
	{
		/* Get Encoded Certificate Size*/
		bResult = CryptSignAndEncodeCertificate(hCryptProvCA, AT_SIGNATURE,
			(PKCS_7_ASN_ENCODING | X509_ASN_ENCODING), X509_CERT_TO_BE_SIGNED,
			(LPVOID)&CertInfo,
			&(CertInfo.SignatureAlgorithm),
			//&(pIssuerCert->pCertInfo->SignatureAlgorithm),
			NULL, NULL, &dwSize);
		if (!bResult)
		{
			ShowError(GetLastError());
			printf("CryptSignAndEncodeCertificate failed with %x\n", GetLastError());
			return false;
		}

		/* Allocate memory for encoded certificate*/
		bpEncodedCert = (LPBYTE)HeapAlloc(hHeap, 0, dwSize);
		if (!bpEncodedCert)
		{
			printf("Unable to allocate memory for encoded certficate\n");
			return false;
		}

		/* Sign and Encode certificate*/
		bResult = CryptSignAndEncodeCertificate(hCryptProvCA, AT_SIGNATURE,
			(PKCS_7_ASN_ENCODING | X509_ASN_ENCODING), X509_CERT_TO_BE_SIGNED,
			(LPVOID)&CertInfo,
			&(CertInfo.SignatureAlgorithm),
			//&(pIssuerCert->pCertInfo->SignatureAlgorithm),
			NULL, bpEncodedCert, &dwSize);
		if (!bResult)
		{
			printf("CryptSignAndEncodeCertificate failed with %x\n", GetLastError());
			return false;
		}
	}
	
	// Открытый ключ способ №2
	CString sOpenKey;
	int iOpenKeyLen= 2*CertInfo.SubjectPublicKeyInfo.PublicKey.cbData + 1;
	LPSTR szOpenKey= certInfo.sOpenKey.GetBuffer(iOpenKeyLen);
	ByteToStr(CertInfo.SubjectPublicKeyInfo.PublicKey.cbData, CertInfo.SubjectPublicKeyInfo.PublicKey.pbData, szOpenKey);

	// создаем сертификат
	num = dwSize;
	certInfo.sFilePath = getenv("TEMP");
	certInfo.sFilePath += "\\" + certInfo.sSerialNumber + ".cer";
	WriteToFile(certInfo.sFilePath, bpEncodedCert, num);

	// помещаем его в хранилище
	if(bSelfSigned)
	{
		WCHAR szwStore[50] = L"Trust";
		WCHAR szwProvider[260];
		WCHAR szwContainer[160];
		CRYPT_KEY_PROV_INFO CryptKeyProvInfo;

		/* Convert Store string to unicode*/
		int i = MultiByteToWideChar(0, 0, "Мое хранилище", -1, szwStore, 50);
		if (i == 0) return false;

		i = MultiByteToWideChar(0, 0, szProvider, -1, szwProvider, 260);
		if (i == 0) return false;

		/* Open Certificate store*/
		hStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_SYSTEM_STORE_CURRENT_USER, (LPVOID)L"Root");
		if (!hStore) return false;

		/* Place Certificate in store*/
		bResult = CertAddEncodedCertificateToStore(hStore, X509_ASN_ENCODING, bpEncodedCert, dwSize, /*CERT_STORE_ADD_REPLACE_EXISTING*/CERT_STORE_ADD_REPLACE_EXISTING, &pCertContext);
		if (!bResult) return false;

		/* Convert container to unicode*/
		i = MultiByteToWideChar(0, 0, szContainer, -1, szwContainer, 160);
		if (i == 0) return false;		

		/* Initialize CRYPT_KEY_PROV_INFO structure*/
		ZeroMemory(&CryptKeyProvInfo, sizeof(CryptKeyProvInfo));
		CryptKeyProvInfo.pwszContainerName = szwContainer;
		CryptKeyProvInfo.pwszProvName = szwProvider;
		CryptKeyProvInfo.dwProvType = dwProviderType;
		CryptKeyProvInfo.dwKeySpec = dwKeyType;
		CryptKeyProvInfo.dwFlags = dwAcquireFlags;

		/* Set Certificate's Key Provider info*/
		bResult = CertSetCertificateContextProperty(pCertContext, CERT_KEY_PROV_INFO_PROP_ID, 0, (LPVOID)&CryptKeyProvInfo);
		PCCERT_CONTEXT pContext= CertCreateCertificateContext(ENCODING_TYPE, bpEncodedCert, num);
		CertAddCertificateContextToStore(hStore, pContext, CERT_STORE_ADD_ALWAYS, 0);	
	}

	// создаем файл с секретным ключом
	MakeSecretKeyFile(&hProv, sFile, sPassword, hPubKey, dwSize, bpEncodedCert, certInfo.sContainer);

	// проверяем сертификат на подпись
	if(!bSelfSigned)
	{
		DWORD dwSignSize;
		BYTE *pbSign = 0;

		BOOL bRes = CryptSignCertificate(hCryptProvCA, AT_KEYEXCHANGE, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, bpEncodedCert, dwSize, &(CertInfo.SignatureAlgorithm), 0, 0, &dwSignSize);
		pbSign = new BYTE[dwSignSize];
		bRes = CryptSignCertificate(hCryptProvCA, AT_KEYEXCHANGE, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, bpEncodedCert, dwSize, &(CertInfo.SignatureAlgorithm), 0, pbSign, &dwSignSize);
		if(!bRes) ShowError(GetLastError());

		if(!CryptVerifyCertificateSignature(hCryptProvCA, X509_ASN_ENCODING, bpEncodedCert, dwSize, PublicKeyInfo))
			ShowError(GetLastError());

		if(!CryptVerifyCertificateSignature(hProv, X509_ASN_ENCODING, bpEncodedCert, dwSize, PublicKeyInfo))
			ShowError(GetLastError());
	}
	else
	{
		if(!CryptVerifyCertificateSignature(hProv, X509_ASN_ENCODING, bpEncodedCert, dwSize, PublicKeyInfo))
			ShowError(GetLastError());
	}

	// Clean up
	if (PublicKeyInfo) HeapFree(hHeap, 0, PublicKeyInfo);
	if (pbKeyIdentifier) HeapFree(hHeap, 0, pbKeyIdentifier);
	if (SubjectKeyIdentifier) HeapFree(hHeap, 0, SubjectKeyIdentifier);
	if (pbKeyUsage) HeapFree(hHeap, 0, pbKeyUsage);
	if (pbEnhKeyUsage) HeapFree(hHeap, 0, pbEnhKeyUsage);
	if (pbBasicConstraints) HeapFree(hHeap, 0, pbBasicConstraints);
	if (KeyId) HeapFree(hHeap, 0, KeyId);
	if (pbAuthorityKeyId) HeapFree(hHeap, 0, pbAuthorityKeyId);
	if (bpEncodedCert) HeapFree(hHeap, 0, bpEncodedCert);
	if (pbExportedKey) HeapFree(hHeap, 0, pbExportedKey);
	if (hCertFile) CloseHandle(hCertFile);
	if (hKeyFile) CloseHandle(hKeyFile);
	if (hPubKey) CryptDestroyKey(hPubKey);
	if (hSessionKey) CryptDestroyKey(hSessionKey);
	if (hHash) CryptDestroyHash(hHash);
	if (hProv) CryptReleaseContext(hProv, 0);
	if (hIssuerProv) CryptReleaseContext(hIssuerProv, 0);
	if (pIssuerCert) CertFreeCertificateContext(pIssuerCert);
	if (pCertContext) CertFreeCertificateContext(pCertContext);
	if (hStore) CertCloseStore(hStore, 0);
	if (pbData) delete [] pbData;
	if (szSerialNumber) delete [] szSerialNumber;

	return bReturn;
}
Offline Kirill Sobolev  
#23 Оставлено : 18 ноября 2008 г. 18:56:06(UTC)
Кирилл Соболев

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

Группы: Участники
Зарегистрирован: 25.12.2007(UTC)
Сообщений: 1,732
Мужчина
Откуда: КРИПТО-ПРО

Поблагодарили: 177 раз в 168 постах
а для самоподписанных сертификатов этот код нормально работает?
Техническую поддержку оказываем тут
Наша база знаний
Offline akulema  
#24 Оставлено : 18 ноября 2008 г. 19:05:02(UTC)
akulema

Статус: Активный участник

Группы: Участники
Зарегистрирован: 17.10.2008(UTC)
Сообщений: 70

Да, самоподписанные создаются нормально. На первый взгляд ничего криминального не увидели?

Отредактировано пользователем 18 ноября 2008 г. 19:05:49(UTC)  | Причина: Не указана

Offline Kirill Sobolev  
#25 Оставлено : 18 ноября 2008 г. 19:36:34(UTC)
Кирилл Соболев

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

Группы: Участники
Зарегистрирован: 25.12.2007(UTC)
Сообщений: 1,732
Мужчина
Откуда: КРИПТО-ПРО

Поблагодарили: 177 раз в 168 постах
значит проблема где-то в чтении ключей. попробуйте не импортировать ключи из файла а брать непосредственно из контейнера.
Техническую поддержку оказываем тут
Наша база знаний
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Guest
3 Страницы<123
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.