int TestCryptoCertEnumCertificatesInStore(int argc, char* argv[])
{
	int index;
	DWORD status;
	LPTSTR pszNameString; 
	HCERTSTORE hCertStore = NULL;
	PCCERT_CONTEXT pCertContext = NULL;

	/**
	 * System Store Locations:
	 * http://msdn.microsoft.com/en-us/library/windows/desktop/aa388136/
	 */

	/**
	 * Requires elevated rights:
	 * hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, (HCRYPTPROV_LEGACY) NULL, CERT_SYSTEM_STORE_LOCAL_MACHINE, _T("Remote Desktop"));
	 */

	hCertStore = CertOpenSystemStore((HCRYPTPROV_LEGACY) NULL, _T("MY"));
	// hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, (HCRYPTPROV_LEGACY) NULL, CERT_SYSTEM_STORE_CURRENT_USER, _T("MY"));

	if (!hCertStore)
	{
		printf("Failed to open system store\n");
		return -1;
	}

	index = 0;

	while ((pCertContext = CertEnumCertificatesInStore(hCertStore, pCertContext)))
	{
		status = CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, NULL, 0);

		pszNameString = (LPTSTR) malloc(status * sizeof(TCHAR));
		if (!pszNameString)
		{
			printf("Unable to allocate memory\n");
			return -1;
		}

		status = CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, pszNameString, status);

		_tprintf(_T("Certificate #%d: %s\n"), index++, pszNameString);

#ifdef WITH_CRYPTUI
		CryptUIDlgViewContext(CERT_STORE_CERTIFICATE_CONTEXT, pCertContext, NULL, NULL, 0, NULL);
#endif
	}

	if (!CertCloseStore(hCertStore, 0))
	{
		printf("Failed to close system store\n");
		return -1;
	}

	return 0;
}
void ca_generate_root_ca_cert_t::generate_ca_cert_clicked(){
	GIE_QT_DEF_EXCEPTION_GUARD_BEGIN

		stcrypt::cert_name_t cert_subject_name;


		#define STCRYPT_TOYCA_CP_NAME(x) { auto str = ui.x##_edit->text().toStdWString(); cert_subject_name.set_##x( std::move(str) ); }

		STCRYPT_TOYCA_CP_NAME(common_name);
 		STCRYPT_TOYCA_CP_NAME(country_name);
 		STCRYPT_TOYCA_CP_NAME(locality_name);
 		STCRYPT_TOYCA_CP_NAME(organization_name);
 		STCRYPT_TOYCA_CP_NAME(organization_unit_name);
		STCRYPT_TOYCA_CP_NAME(state_or_province_name);
		STCRYPT_TOYCA_CP_NAME(email_name);

		#undef STCRYPT_TOYCA_CP_NAME

		// generate key pair
		NCRYPT_PROV_HANDLE cng_provider=0;
		NCRYPT_KEY_HANDLE  cng_n_key_pair=0;
		
		auto status = NCryptOpenStorageProvider(&cng_provider, CNG_STCRYPT_KEYSTORAGE, 0);
		STCRYPT_CHECK(!FAILED(status));
		BOOST_SCOPE_EXIT((&cng_provider)) { auto const status = NCryptFreeObject (cng_provider);  assert( !FAILED(status) ); } BOOST_SCOPE_EXIT_END

		boost::uuids::uuid const key_container_id( (boost::uuids::random_generator()()) );
		auto const& key_pair_container_name = boost::lexical_cast<std::wstring>( key_container_id );

		status = NCryptCreatePersistedKey(cng_provider, &cng_n_key_pair, NCNG_DSTU4145, key_pair_container_name.c_str(), AT_KEYEXCHANGE, 0/*NCRYPT_OVERWRITE_KEY_FLAG*/);
		STCRYPT_CHECK(!FAILED(status));
		BOOST_SCOPE_EXIT((&cng_n_key_pair)) { auto const status = NCryptFreeObject (cng_n_key_pair);  assert( !FAILED(status) ); } BOOST_SCOPE_EXIT_END

		status = NCryptFinalizeKey(cng_n_key_pair, 0);
		STCRYPT_CHECK(!FAILED(status));

		auto const& to_be_signed_cert_blob = ms_cert::create_req_blob(cert_subject_name, cng_n_key_pair, cert_subject_name);

		DWORD size;
		STCRYPT_CHECK( CryptDecodeObjectEx(X509_ASN_ENCODING, X509_CERT_TO_BE_SIGNED, reinterpret_cast<BYTE const*> (to_be_signed_cert_blob.data()), to_be_signed_cert_blob.size(), CRYPT_DECODE_TO_BE_SIGNED_FLAG, 0, 0, &size) );
		STCRYPT_CHECK(size!=0);

		std::vector<unsigned char> to_be_signed_cert_blob_combined(size);
		STCRYPT_CHECK( CryptDecodeObjectEx(X509_ASN_ENCODING, X509_CERT_TO_BE_SIGNED, reinterpret_cast<BYTE const*> (to_be_signed_cert_blob.data()), to_be_signed_cert_blob.size(), CRYPT_DECODE_TO_BE_SIGNED_FLAG, 0, to_be_signed_cert_blob_combined.data(), &size) );
		to_be_signed_cert_blob_combined.resize(size);

		CERT_INFO* const cert_to_be_signed = static_cast<CERT_INFO*>( static_cast<void*>( to_be_signed_cert_blob_combined.data() ) );

		// do sign
		CRYPT_ALGORITHM_IDENTIFIER signature_alg={OID_G34311_DSTU4145_SIGN,0};

		DWORD encoded_cert_size = 0;
 		if( !CryptSignAndEncodeCertificate(cng_n_key_pair, 0, X509_ASN_ENCODING, X509_CERT_TO_BE_SIGNED, cert_to_be_signed, &signature_alg, 0, 0, &encoded_cert_size) ){ //TODO: this CryptSignAndEncodeCertificate leaks memory
 			STCRYPT_UNEXPECTED();
 		}
 		STCRYPT_CHECK(encoded_cert_size!=0);
 
 		std::vector<BYTE> signed_certificate(encoded_cert_size);
 		if( !CryptSignAndEncodeCertificate(cng_n_key_pair, 0, X509_ASN_ENCODING, X509_CERT_TO_BE_SIGNED, cert_to_be_signed, &signature_alg, 0, signed_certificate.data(), &encoded_cert_size) ){
 			STCRYPT_UNEXPECTED();
 		}
 		signed_certificate.resize(encoded_cert_size);

		// context from signed blob
		ms_cert::pccert_context_t signed_cert_context( CertCreateCertificateContext (X509_ASN_ENCODING, reinterpret_cast<BYTE const*>( signed_certificate.data() ), signed_certificate.size() ) );
		STCRYPT_CHECK( signed_cert_context );

		// assign private key container name
		CRYPT_KEY_PROV_INFO key_prov_info = {0};
		key_prov_info.pwszContainerName = const_cast<wchar_t*>( key_pair_container_name.c_str() );
		key_prov_info.pwszProvName = CNG_STCRYPT_KEYSTORAGE;
		key_prov_info.dwProvType = 0;
		key_prov_info.dwFlags = 0;
		key_prov_info.cProvParam = 0;
		key_prov_info.rgProvParam = 0;
		key_prov_info.dwKeySpec = 0;

		STCRYPT_CHECK( CertSetCertificateContextProperty(signed_cert_context.handle(), CERT_KEY_PROV_INFO_PROP_ID, 0, &key_prov_info) );
		STCRYPT_CHECK( CryptUIDlgViewContext (CERT_STORE_CERTIFICATE_CONTEXT, signed_cert_context.handle(), this->winId(), L"Generated CA certificate [NOT YET INSTALLED]", 0, 0) );

		ms_cert::import_into_ms_store2(signed_cert_context.handle(), L"ROOT");

		STCRYPT_CHECK( CryptUIDlgViewContext (CERT_STORE_CERTIFICATE_CONTEXT, signed_cert_context.handle(), this->winId(), L"Generated CA certificate", 0, 0) );

		toy_ca::initialize_accept_requests_mode( dynamic_cast<QMainWindow*>( this->parent() ), std::move(signed_cert_context) );

	GIE_QT_DEF_EXCEPTION_GUARD_END
}
Esempio n. 3
0
// Display a UI with the certificate info and also write it to the debug output
HRESULT ShowCertInfo(PCCERT_CONTEXT pCertContext, CString Title)
{
	TCHAR pszNameString[256];
	void*            pvData;
	DWORD            cbData;
	DWORD            dwPropId = 0;


	//  Display the certificate.
	if (!CryptUIDlgViewContext(
		CERT_STORE_CERTIFICATE_CONTEXT,
		pCertContext,
		NULL,
		CStringW(Title),
		0,
		NULL))
	{
		DebugMsg("UI failed.");
	}

	if (CertGetNameString(
		pCertContext,
		CERT_NAME_SIMPLE_DISPLAY_TYPE,
		0,
		NULL,
		pszNameString,
		128))
	{
		DebugMsg("Certificate for %S", ATL::CT2W(pszNameString));
	}
	else
		DebugMsg("CertGetName failed.");


	int Extensions = pCertContext->pCertInfo->cExtension;

	auto *p = pCertContext->pCertInfo->rgExtension;
	for (int i = 0; i < Extensions; i++)
	{
		DebugMsg("Extension %s", (p++)->pszObjId);
	}

	//-------------------------------------------------------------------
	// Loop to find all of the property identifiers for the specified  
	// certificate. The loop continues until 
	// CertEnumCertificateContextProperties returns zero.
	while (0 != (dwPropId = CertEnumCertificateContextProperties(
		pCertContext, // The context whose properties are to be listed.
		dwPropId)))    // Number of the last property found.  
		// This must be zero to find the first 
		// property identifier.
	{
		//-------------------------------------------------------------------
		// When the loop is executed, a property identifier has been found.
		// Print the property number.

		DebugMsg("Property # %d found->", dwPropId);

		//-------------------------------------------------------------------
		// Indicate the kind of property found.

		switch (dwPropId)
		{
		case CERT_FRIENDLY_NAME_PROP_ID:
		{
			DebugMsg("Friendly name: ");
			break;
		}
		case CERT_SIGNATURE_HASH_PROP_ID:
		{
			DebugMsg("Signature hash identifier ");
			break;
		}
		case CERT_KEY_PROV_HANDLE_PROP_ID:
		{
			DebugMsg("KEY PROVE HANDLE");
			break;
		}
		case CERT_KEY_PROV_INFO_PROP_ID:
		{
			DebugMsg("KEY PROV INFO PROP ID ");
			break;
		}
		case CERT_SHA1_HASH_PROP_ID:
		{
			DebugMsg("SHA1 HASH identifier");
			break;
		}
		case CERT_MD5_HASH_PROP_ID:
		{
			DebugMsg("md5 hash identifier ");
			break;
		}
		case CERT_KEY_CONTEXT_PROP_ID:
		{
			DebugMsg("KEY CONTEXT PROP identifier");
			break;
		}
		case CERT_KEY_SPEC_PROP_ID:
		{
			DebugMsg("KEY SPEC PROP identifier");
			break;
		}
		case CERT_ENHKEY_USAGE_PROP_ID:
		{
			DebugMsg("ENHKEY USAGE PROP identifier");
			break;
		}
		case CERT_NEXT_UPDATE_LOCATION_PROP_ID:
		{
			DebugMsg("NEXT UPDATE LOCATION PROP identifier");
			break;
		}
		case CERT_PVK_FILE_PROP_ID:
		{
			DebugMsg("PVK FILE PROP identifier ");
			break;
		}
		case CERT_DESCRIPTION_PROP_ID:
		{
			DebugMsg("DESCRIPTION PROP identifier ");
			break;
		}
		case CERT_ACCESS_STATE_PROP_ID:
		{
			DebugMsg("ACCESS STATE PROP identifier ");
			break;
		}
		case CERT_SMART_CARD_DATA_PROP_ID:
		{
			DebugMsg("SMART_CARD DATA PROP identifier ");
			break;
		}
		case CERT_EFS_PROP_ID:
		{
			DebugMsg("EFS PROP identifier ");
			break;
		}
		case CERT_FORTEZZA_DATA_PROP_ID:
		{
			DebugMsg("FORTEZZA DATA PROP identifier ");
			break;
		}
		case CERT_ARCHIVED_PROP_ID:
		{
			DebugMsg("ARCHIVED PROP identifier ");
			break;
		}
		case CERT_KEY_IDENTIFIER_PROP_ID:
		{
			DebugMsg("KEY IDENTIFIER PROP identifier ");
			break;
		}
		case CERT_AUTO_ENROLL_PROP_ID:
		{
			DebugMsg("AUTO ENROLL identifier. ");
			break;
		}
		case CERT_ISSUER_PUBLIC_KEY_MD5_HASH_PROP_ID:
		{
			DebugMsg("ISSUER PUBLIC KEY MD5 HASH identifier. ");
			break;
		}
		} // End switch.

		//-------------------------------------------------------------------
		// Retrieve information on the property by first getting the 
		// property size. 
		// For more information, see CertGetCertificateContextProperty.

		if (CertGetCertificateContextProperty(
			pCertContext,
			dwPropId,
			NULL,
			&cbData))
		{
			//  Continue.
		}
		else
		{
			// If the first call to the function failed,
			// exit to an error routine.
			DebugMsg("Call #1 to GetCertContextProperty failed.");
			return E_FAIL;
		}
		//-------------------------------------------------------------------
		// The call succeeded. Use the size to allocate memory 
		// for the property.

		if (NULL != (pvData = (void*)malloc(cbData)))
		{
			// Memory is allocated. Continue.
		}
		else
		{
			// If memory allocation failed, exit to an error routine.
			DebugMsg("Memory allocation failed.");
			return E_FAIL;
		}
		//----------------------------------------------------------------
		// Allocation succeeded. Retrieve the property data.

		if (CertGetCertificateContextProperty(
			pCertContext,
			dwPropId,
			pvData,
			&cbData))
		{
			// The data has been retrieved. Continue.
		}
		else
		{
			// If an error occurred in the second call, 
			// exit to an error routine.
			DebugMsg("Call #2 failed.");
			return E_FAIL;
		}
		//---------------------------------------------------------------
		// Show the results.

		DebugMsg("The Property Content is");
		PrintHexDump(cbData, pvData);

		//----------------------------------------------------------------
		// Free the certificate context property memory.

		free(pvData);
	}
	return S_OK;
}