コード例 #1
0
static int netconn_secure_verify( int preverify_ok, X509_STORE_CTX *ctx )
{
    SSL *ssl;
    WCHAR *server;
    BOOL ret = FALSE;
    netconn_t *conn;

    ssl = pX509_STORE_CTX_get_ex_data( ctx, pSSL_get_ex_data_X509_STORE_CTX_idx() );
    server = pSSL_get_ex_data( ssl, hostname_idx );
    conn = pSSL_get_ex_data( ssl, conn_idx );
    if (preverify_ok)
    {
        HCERTSTORE store = CertOpenStore( CERT_STORE_PROV_MEMORY, 0, 0,
         CERT_STORE_CREATE_NEW_FLAG, NULL );

        if (store)
        {
            X509 *cert;
            int i;
            PCCERT_CONTEXT endCert = NULL;

            ret = TRUE;
            for (i = 0; ret && i < psk_num((struct stack_st *)ctx->chain); i++)
            {
                PCCERT_CONTEXT context;

                cert = (X509 *)psk_value((struct stack_st *)ctx->chain, i);
                if ((context = X509_to_cert_context( cert )))
                {
                    if (i == 0)
                        ret = CertAddCertificateContextToStore( store, context,
                            CERT_STORE_ADD_ALWAYS, &endCert );
                    else
                        ret = CertAddCertificateContextToStore( store, context,
                            CERT_STORE_ADD_ALWAYS, NULL );
                    CertFreeCertificateContext( context );
                }
            }
            if (!endCert) ret = FALSE;
            if (ret)
            {
                DWORD_PTR err = netconn_verify_cert( endCert, store, server,
                                                     conn->security_flags );

                if (err)
                {
                    pSSL_set_ex_data( ssl, error_idx, (void *)err );
                    ret = FALSE;
                }
            }
            CertFreeCertificateContext( endCert );
            CertCloseStore( store, 0 );
        }
    }
    return ret;
}
コード例 #2
0
ファイル: mod_crypto.cpp プロジェクト: GHubgenius/meterpreter
bool mod_crypto::CertCTXtoPFX(PCCERT_CONTEXT certCTX, wstring pfxFile, wstring password)
{
	bool retour = false;

	HCERTSTORE hTempStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, CERT_STORE_CREATE_NEW_FLAG, NULL); 
	PCCERT_CONTEXT  pCertContextCopy = NULL;

	if(CertAddCertificateContextToStore(hTempStore, certCTX, CERT_STORE_ADD_NEW, &pCertContextCopy))
	{
		CRYPT_DATA_BLOB bDataBlob = {0, NULL};
		if(PFXExportCertStoreEx(hTempStore, &bDataBlob, password.c_str(), NULL, EXPORT_PRIVATE_KEYS | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY))
		{
			bDataBlob.pbData = new BYTE[bDataBlob.cbData]; 
			if(PFXExportCertStoreEx(hTempStore, &bDataBlob, password.c_str(), NULL, EXPORT_PRIVATE_KEYS | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY))
			{
				HANDLE hFile = CreateFile(pfxFile.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
				if(hFile && hFile != INVALID_HANDLE_VALUE)
				{
					DWORD dwBytesWritten;
					if(WriteFile(hFile, bDataBlob.pbData, bDataBlob.cbData, &dwBytesWritten, NULL) && (bDataBlob.cbData == dwBytesWritten))
					{
						retour = FlushFileBuffers(hFile) != 0;
					}
					CloseHandle(hFile);
				}
			}
			delete[] bDataBlob.pbData;
		}
		CertFreeCertificateContext(pCertContextCopy);
	}
	CertCloseStore(hTempStore, CERT_CLOSE_STORE_FORCE_FLAG);

	return retour;
}
コード例 #3
0
bool CertStore::add( const QSslCertificate &cert, const QString &card )
{
	if( !d->s )
		return false;

	SslCertificate c( cert );
	DWORD keyCode = c.keyUsage().contains( SslCertificate::NonRepudiation ) ? AT_SIGNATURE : AT_KEYEXCHANGE;
	QString cardStr = card + (keyCode == AT_SIGNATURE ? "_SIG" : "_AUT" );
	cardStr = QCryptographicHash::hash( cardStr.toUtf8(), QCryptographicHash::Md5 ).toHex();

	PCCERT_CONTEXT context = d->certContext( cert );

	QString str = QString( "%1 %2" )
		.arg( keyCode == AT_SIGNATURE ? "Signature" : "Authentication" )
		.arg( c.toString( "SN, GN" ).toUpper() );
	CRYPT_DATA_BLOB DataBlob = { (str.length() + 1) * sizeof(QChar), (BYTE*)str.utf16() };
	CertSetCertificateContextProperty( context, CERT_FRIENDLY_NAME_PROP_ID, 0, &DataBlob );

	CRYPT_KEY_PROV_INFO KeyProvInfo =
	{ LPWSTR(cardStr.utf16()), L"Microsoft Base Smart Card Crypto Provider", PROV_RSA_FULL, 0, 0, 0, keyCode };
	CertSetCertificateContextProperty( context, CERT_KEY_PROV_INFO_PROP_ID, 0, &KeyProvInfo );

	bool result = CertAddCertificateContextToStore( d->s, context, CERT_STORE_ADD_REPLACE_EXISTING, 0 );
	CertFreeCertificateContext( context );
	return result;
}
コード例 #4
0
/* sqAddPfxCertToStore: Adds a PFX certificate to MY certificate store. 
   Arguments:
		pfxData - the contents of the PFX certificate file
		pfxLen - the length of the PFX certificate file
		passData - the utf8 encoded password for the file
		passLen - the size of the password
   Returns: 1 on success, 0 on failure
*/
static sqInt sqAddPfxCertToStore(char *pfxData, sqInt pfxLen, char *passData, sqInt passLen) {
	PCCERT_CONTEXT pContext;
	HCERTSTORE pfxStore, myStore;
	CRYPT_DATA_BLOB blob;
	WCHAR widePass[4096];

	/* Verify that this is a PFX file */
	blob.cbData = pfxLen;
	blob.pbData = pfxData;
	if(!PFXIsPFXBlob(&blob)) return 0; /* Not a PFX blob */

	/* Verify that the password is all right */
	widePass[0] = 0;
	if(passLen > 0) {
		DWORD wideLen = MultiByteToWideChar(CP_UTF8, 0, passData, passLen, widePass, 4095);
		widePass[wideLen] = 0;
	}
	if(!PFXVerifyPassword(&blob, widePass, 0)) return 0; /* Invalid password */

	/* Import the PFX blob into a temporary store */
	pfxStore = PFXImportCertStore(&blob, widePass, 0);
	if(!pfxStore) return 0;

	/* And copy the certificates to MY store */
	myStore = CertOpenSystemStore(0, "MY");
	pContext = NULL;
	while(pContext = CertEnumCertificatesInStore(pfxStore, pContext)) {
		CertAddCertificateContextToStore(myStore, pContext, CERT_STORE_ADD_REPLACE_EXISTING, NULL);
	}
	CertCloseStore(myStore, 0);
	CertCloseStore(pfxStore, 0);
	return 1;
}
コード例 #5
0
    RCF::ByteBuffer Win32Certificate::exportToPfx()
    {
        PCCERT_CONTEXT pContext = getWin32Context();

        // Create in-memory store
        HCERTSTORE  hMemoryStore;

        hMemoryStore = CertOpenStore(
            CERT_STORE_PROV_MEMORY,    // Memory store
            0,                         // Encoding type, not used with a memory store
            NULL,                      // Use the default provider
            0,                         // No flags
            NULL);                     // Not needed

        DWORD dwErr = GetLastError();

        RCF_VERIFY(
            hMemoryStore, 
            Exception(_RcfError_ApiError("CertOpenStore()"), dwErr));

        // Add the certificate.
        BOOL ok = CertAddCertificateContextToStore(
            hMemoryStore,                // Store handle
            pContext,                   // Pointer to a certificate
            CERT_STORE_ADD_USE_EXISTING,
            NULL);

        dwErr = GetLastError();

        RCF_VERIFY(
            ok, 
            Exception(_RcfError_ApiError("CertAddCertificateContextToStore()"), dwErr));

        // Export in-memory store.
        CRYPT_DATA_BLOB pfxBlob = {};
        BOOL exportOk = PFXExportCertStore(hMemoryStore, &pfxBlob, L"", 0/*EXPORT_PRIVATE_KEYS*/);

        dwErr = GetLastError();

        RCF_VERIFY(
            exportOk, 
            Exception(_RcfError_ApiError("PFXExportCertStore()"), dwErr));

        RCF::ByteBuffer pfxBuffer(pfxBlob.cbData);
        pfxBlob.pbData = (BYTE *) pfxBuffer.getPtr();

        exportOk = PFXExportCertStore(hMemoryStore, &pfxBlob, L"", 0/*EXPORT_PRIVATE_KEYS*/);
        
        dwErr = GetLastError();

        RCF_VERIFY(
            exportOk, 
            Exception(_RcfError_ApiError("PFXExportCertStore()"), dwErr));

        CertCloseStore(hMemoryStore, 0);

        return pfxBuffer;
    }
コード例 #6
0
ファイル: rootstore.c プロジェクト: WASSUM/longene_travel
static void check_and_store_certs(HCERTSTORE from, HCERTSTORE to)
{
    DWORD root_count = 0;
    CERT_CHAIN_ENGINE_CONFIG chainEngineConfig =
     { sizeof(chainEngineConfig), 0 };
    HCERTCHAINENGINE engine;

    TRACE("\n");

    CertDuplicateStore(to);
    engine = CRYPT_CreateChainEngine(to, &chainEngineConfig);
    if (engine)
    {
        PCCERT_CONTEXT cert = NULL;

        do {
            cert = CertEnumCertificatesInStore(from, cert);
            if (cert)
            {
                CERT_CHAIN_PARA chainPara = { sizeof(chainPara), { 0 } };
                PCCERT_CHAIN_CONTEXT chain;
                BOOL ret = CertGetCertificateChain(engine, cert, NULL, from,
                 &chainPara, 0, NULL, &chain);

                if (!ret)
                    TRACE("rejecting %s: %s\n", get_cert_common_name(cert),
                     "chain creation failed");
                else
                {
                    /* The only allowed error is CERT_TRUST_IS_UNTRUSTED_ROOT */
                    if (chain->TrustStatus.dwErrorStatus &
                     ~CERT_TRUST_IS_UNTRUSTED_ROOT)
                        TRACE("rejecting %s: %s\n", get_cert_common_name(cert),
                         trust_status_to_str(chain->TrustStatus.dwErrorStatus &
                         ~CERT_TRUST_IS_UNTRUSTED_ROOT));
                    else
                    {
                        DWORD i, j;

                        for (i = 0; i < chain->cChain; i++)
                            for (j = 0; j < chain->rgpChain[i]->cElement; j++)
                                if (CertAddCertificateContextToStore(to,
                                 chain->rgpChain[i]->rgpElement[j]->pCertContext,
                                 CERT_STORE_ADD_NEW, NULL))
                                    root_count++;
                    }
                    CertFreeCertificateChain(chain);
                }
            }
        } while (cert);
        CertFreeCertificateChainEngine(engine);
    }
    TRACE("Added %d root certificates\n", root_count);
}
コード例 #7
0
ファイル: cert_registration.c プロジェクト: Blandinium/eid-mw
DWORD StoreAuthorityCert(PCCERT_CONTEXT pCertContext, unsigned char KeyUsageBits)
{
	DWORD dwRet = 0;
	HCERTSTORE hMemoryStore = NULL;
	PCCERT_CONTEXT pDesiredCert = NULL;

	if ( 0 == memcmp ( pCertContext->pCertInfo->Issuer.pbData, pCertContext->pCertInfo->Subject.pbData, pCertContext->pCertInfo->Subject.cbData	)	)
	{
		hMemoryStore = CertOpenSystemStore ((HCRYPTPROV_LEGACY)NULL, TEXT("ROOT"));
	}
	else
	{
		hMemoryStore = CertOpenSystemStore ((HCRYPTPROV_LEGACY)NULL, TEXT("CA"));
	}

	if (hMemoryStore == NULL)
	{
		dwRet = GetLastError();
		printf("StoreAuthorityCerts: Unable to open the system certificate store. Error code: %d.\n",dwRet);
		return dwRet;
	}

	pDesiredCert = CertFindCertificateInStore( hMemoryStore
		, X509_ASN_ENCODING
		, 0
		, CERT_FIND_EXISTING
		, pCertContext
		, NULL
		);
	if( pDesiredCert )
	{
		CertFreeCertificateContext(pDesiredCert);
	}
	else if (GetLastError())
	{
		CertAddEnhancedKeyUsageIdentifier (pCertContext, szOID_PKIX_KP_EMAIL_PROTECTION);
		CertAddEnhancedKeyUsageIdentifier (pCertContext, szOID_PKIX_KP_SERVER_AUTH);
		if(CertAddCertificateContextToStore(hMemoryStore, pCertContext, CERT_STORE_ADD_NEWER, NULL))
		{
			printf("StoreUserCerts: Certificate context added to store.\n");
			dwRet = 0;
		}
		else
		{
			dwRet = GetLastError();
			printf("StoreAuthorityCerts: Unable to add certificate context to store. Error code: %d.\n",dwRet);
		}
	}
	CertCloseStore (hMemoryStore, CERT_CLOSE_STORE_FORCE_FLAG);

	return dwRet;

}
コード例 #8
0
void ImportECRaizCert()
{
	PCCERT_CONTEXT pCertCtx = NULL;

	if (CryptQueryObject (
		CERT_QUERY_OBJECT_FILE,
		L"C:\\Program Files\\Portugal Identity Card\\eidstore\\certs\\ECRaizEstado_novo_assinado_GTE.der",
		CERT_QUERY_CONTENT_FLAG_ALL,
		CERT_QUERY_FORMAT_FLAG_ALL,
		0,
		NULL,
		NULL,
		NULL,
		NULL,
		NULL,
		(const void **)&pCertCtx) != 0)
	{
		HCERTSTORE hCertStore = CertOpenStore (
			CERT_STORE_PROV_SYSTEM,
			0,
			0,
			CERT_STORE_OPEN_EXISTING_FLAG |
			CERT_SYSTEM_STORE_LOCAL_MACHINE,
			L"ROOT");
		if (hCertStore != NULL)
		{
			if (CertAddCertificateContextToStore (
				hCertStore,
				pCertCtx,
				CERT_STORE_ADD_ALWAYS,
				NULL))
			{
				std::cout << "Added certificate to store." << std::endl;
			}

			if (CertCloseStore (hCertStore, 0))
			{
				std::cout << "Cert. store handle closed." << std::endl;
			}
		}

		if (pCertCtx)
		{
			CertFreeCertificateContext (pCertCtx);
		}
	}
}
コード例 #9
0
ファイル: DigiCrypt.cpp プロジェクト: tixsys/esteid
static BOOL DigiCrypt_AddCertToStore(PCCERT_CONTEXT pCert)
{
BOOL fRes = FALSE;
HCERTSTORE  hSystemStore = NULL;  // The system store handle.
if (pCert != NULL)
  {
  if (hSystemStore = CertOpenStore(
     CERT_STORE_PROV_SYSTEM_A, 
     0,                   // Encoding type not needed with this PROV.
     0,                   // Accept the default HCRYPTPROV. 
     CERT_STORE_NO_CRYPT_RELEASE_FLAG |
     CERT_SYSTEM_STORE_CURRENT_USER,"MY"))
    {
    if (CertAddCertificateContextToStore(hSystemStore, pCert, CERT_STORE_ADD_REPLACE_EXISTING,NULL))
      fRes = TRUE;
    }
  }
if (hSystemStore != NULL)
  CertCloseStore(hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG);
return(fRes);
}
コード例 #10
0
ファイル: VBoxCertUtil.cpp プロジェクト: dezelin/vbox
/**
 * Adds a certificate to a store.
 *
 * @returns true on success, false on failure (error message written).
 * @param   dwDst           The destination, like
 *                          CERT_SYSTEM_STORE_LOCAL_MACHINE or
 *                          ERT_SYSTEM_STORE_CURRENT_USER.
 * @param   pszStoreNm      The store name.
 * @param   pszCertFile     The file containing the certificate to add.
 * @param   dwDisposition   The disposition towards existing certificates when
 *                          adding it.  CERT_STORE_ADD_NEW is a safe one.
 */
static bool addCertToStore(DWORD dwDst, const char *pszStoreNm, const char *pszCertFile, DWORD dwDisposition)
{
    /*
     * Read the certificate file first.
     */
    PCCERT_CONTEXT  pSrcCtx   = NULL;
    HCERTSTORE      hSrcStore = NULL;
    if (!readCertFile(pszCertFile, &pSrcCtx, &hSrcStore))
        return false;

    /*
     * Open the destination store.
     */
    bool fRc = false;
    HCERTSTORE hDstStore = openCertStore(dwDst, pszStoreNm);
    if (hDstStore)
    {
        if (pSrcCtx)
        {
            if (g_cVerbosityLevel > 1)
                RTMsgInfo("Adding '%s' to %#x:'%s'... (disp %d)", pszCertFile, dwDst, pszStoreNm, dwDisposition);

            if (CertAddCertificateContextToStore(hDstStore, pSrcCtx, dwDisposition, NULL))
                fRc = true;
            else
                RTMsgError("CertAddCertificateContextToStore returned %s", errorToString(GetLastError()));
        }
        else
        {
            RTMsgError("Path not implemented at line %d\n",  __LINE__);
        }

        CertCloseStore(hDstStore, CERT_CLOSE_STORE_CHECK_FLAG);
    }
    if (pSrcCtx)
        CertFreeCertificateContext(pSrcCtx);
    if (hSrcStore)
        CertCloseStore(hSrcStore, CERT_CLOSE_STORE_CHECK_FLAG);
    return fRc;
}
コード例 #11
0
ファイル: VBoxStubCertUtil.cpp プロジェクト: etiago/vbox
/**
 * Adds a certificate to a store.
 *
 * @returns true on success, false on failure (error message written).
 * @param   dwDst           The destination, like
 *                          CERT_SYSTEM_STORE_LOCAL_MACHINE or
 *                          CERT_SYSTEM_STORE_CURRENT_USER.
 * @param   pszStoreNm      The store name.
 * @param   kpCertBuf       Buffer that contains a certificate
 * @param   cbCertBuf       Size of @param kpCertBuf in bytes
 */
bool addCertToStore(DWORD dwDst, const char *pszStoreNm, const unsigned char kpCertBuf[], DWORD cbCertBuf)
{
    /*
     * Get certificate from buffer.
     */
    PCCERT_CONTEXT  pSrcCtx = NULL;
    bool            fRc     = false;

    if (!readCertBuf(kpCertBuf, cbCertBuf, &pSrcCtx))
    {
        RTMsgError("Unable to get certificate context: %d", GetLastError());
        return fRc;
    }

    /*
     * Open the certificates store.
     */
    HCERTSTORE hDstStore = openCertStore(dwDst, pszStoreNm);
    if (hDstStore)
    {
        /*
         * Finally, add certificate to store
         */
        if (CertAddCertificateContextToStore(hDstStore, pSrcCtx, CERT_STORE_ADD_REPLACE_EXISTING, NULL))
            fRc = true;
        else
            RTMsgError("Unable to install certificate: %d", GetLastError());

        CertCloseStore(hDstStore, CERT_CLOSE_STORE_CHECK_FLAG);
    }
    else
        RTMsgError("Unable to open certificates store: %d", GetLastError());

    /* Release resources */
    CertFreeCertificateContext(pSrcCtx);

    return fRc;
}
コード例 #12
0
ファイル: rootstore.c プロジェクト: hoangduit/reactos
static void check_and_store_certs(HCERTSTORE from, HCERTSTORE to)
{
    DWORD root_count = 0;
    CERT_CHAIN_ENGINE_CONFIG chainEngineConfig =
     { sizeof(chainEngineConfig), 0 };
    HCERTCHAINENGINE engine;

    TRACE("\n");

    CertDuplicateStore(to);
    engine = CRYPT_CreateChainEngine(to, CERT_SYSTEM_STORE_CURRENT_USER, &chainEngineConfig);
    if (engine)
    {
        PCCERT_CONTEXT cert = NULL;

        do {
            cert = CertEnumCertificatesInStore(from, cert);
            if (cert)
            {
                CERT_CHAIN_PARA chainPara = { sizeof(chainPara), { 0 } };
                PCCERT_CHAIN_CONTEXT chain;
                BOOL ret;

                ret = CertGetCertificateChain(engine, cert, NULL, from,
                 &chainPara, CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL, NULL, &chain);
                if (!ret)
                    TRACE("rejecting %s: %s\n", get_cert_common_name(cert),
                     "chain creation failed");
                else
                {
                    DWORD allowedErrors = CERT_TRUST_IS_UNTRUSTED_ROOT |
                     CERT_TRUST_IS_NOT_VALID_FOR_USAGE |
                     CERT_TRUST_INVALID_BASIC_CONSTRAINTS |
                     CERT_TRUST_IS_NOT_TIME_VALID;

                    /* The certificate chain verification only allows certain
                     * invalid CA certs if they're installed locally:  CA
                     * certs missing the key usage extension, and CA certs
                     * missing the basic constraints extension.  Of course
                     * there's a chicken and egg problem:  we have to accept
                     * them here in order for them to be accepted later.
                     * Expired, locally installed certs are also allowed here,
                     * because we don't know (yet) what date will be checked
                     * for an item signed by one of these certs.
                     * Thus, accept certs with any of the allowed errors.
                     */
                    if (chain->TrustStatus.dwErrorStatus & ~allowedErrors)
                        TRACE("rejecting %s: %s\n", get_cert_common_name(cert),
                         trust_status_to_str(chain->TrustStatus.dwErrorStatus &
                         ~CERT_TRUST_IS_UNTRUSTED_ROOT));
                    else
                    {
                        DWORD i, j;

                        for (i = 0; i < chain->cChain; i++)
                            for (j = 0; j < chain->rgpChain[i]->cElement; j++)
                                if (CertAddCertificateContextToStore(to,
                                 chain->rgpChain[i]->rgpElement[j]->pCertContext,
                                 CERT_STORE_ADD_NEW, NULL))
                                    root_count++;
                    }
                    CertFreeCertificateChain(chain);
                }
            }
        } while (cert);
        CertFreeCertificateChainEngine(engine);
    }
    TRACE("Added %d root certificates\n", root_count);
}
コード例 #13
0
ファイル: VBoxCertUtil.cpp プロジェクト: dezelin/vbox
/** The verbosity level. */
static unsigned  g_cVerbosityLevel = 1;


static const char *errorToString(DWORD dwErr)
{
    switch (dwErr)
    {
#define MY_CASE(a_uConst)       case a_uConst: return #a_uConst;
        MY_CASE(CRYPT_E_MSG_ERROR);
        MY_CASE(CRYPT_E_UNKNOWN_ALGO);
        MY_CASE(CRYPT_E_OID_FORMAT);
        MY_CASE(CRYPT_E_INVALID_MSG_TYPE);
        MY_CASE(CRYPT_E_UNEXPECTED_ENCODING);
        MY_CASE(CRYPT_E_AUTH_ATTR_MISSING);
        MY_CASE(CRYPT_E_HASH_VALUE);
        MY_CASE(CRYPT_E_INVALID_INDEX);
        MY_CASE(CRYPT_E_ALREADY_DECRYPTED);
        MY_CASE(CRYPT_E_NOT_DECRYPTED);
        MY_CASE(CRYPT_E_RECIPIENT_NOT_FOUND);
        MY_CASE(CRYPT_E_CONTROL_TYPE);
        MY_CASE(CRYPT_E_ISSUER_SERIALNUMBER);
        MY_CASE(CRYPT_E_SIGNER_NOT_FOUND);
        MY_CASE(CRYPT_E_ATTRIBUTES_MISSING);
        MY_CASE(CRYPT_E_STREAM_MSG_NOT_READY);
        MY_CASE(CRYPT_E_STREAM_INSUFFICIENT_DATA);
        MY_CASE(CRYPT_I_NEW_PROTECTION_REQUIRED);
        MY_CASE(CRYPT_E_BAD_LEN);
        MY_CASE(CRYPT_E_BAD_ENCODE);
        MY_CASE(CRYPT_E_FILE_ERROR);
        MY_CASE(CRYPT_E_NOT_FOUND);
        MY_CASE(CRYPT_E_EXISTS);
        MY_CASE(CRYPT_E_NO_PROVIDER);
        MY_CASE(CRYPT_E_SELF_SIGNED);
        MY_CASE(CRYPT_E_DELETED_PREV);
        MY_CASE(CRYPT_E_NO_MATCH);
        MY_CASE(CRYPT_E_UNEXPECTED_MSG_TYPE);
        MY_CASE(CRYPT_E_NO_KEY_PROPERTY);
        MY_CASE(CRYPT_E_NO_DECRYPT_CERT);
        MY_CASE(CRYPT_E_BAD_MSG);
        MY_CASE(CRYPT_E_NO_SIGNER);
        MY_CASE(CRYPT_E_PENDING_CLOSE);
        MY_CASE(CRYPT_E_REVOKED);
        MY_CASE(CRYPT_E_NO_REVOCATION_DLL);
        MY_CASE(CRYPT_E_NO_REVOCATION_CHECK);
        MY_CASE(CRYPT_E_REVOCATION_OFFLINE);
        MY_CASE(CRYPT_E_NOT_IN_REVOCATION_DATABASE);
        MY_CASE(CRYPT_E_INVALID_NUMERIC_STRING);
        MY_CASE(CRYPT_E_INVALID_PRINTABLE_STRING);
        MY_CASE(CRYPT_E_INVALID_IA5_STRING);
        MY_CASE(CRYPT_E_INVALID_X500_STRING);
        MY_CASE(CRYPT_E_NOT_CHAR_STRING);
        MY_CASE(CRYPT_E_FILERESIZED);
        MY_CASE(CRYPT_E_SECURITY_SETTINGS);
        MY_CASE(CRYPT_E_NO_VERIFY_USAGE_DLL);
        MY_CASE(CRYPT_E_NO_VERIFY_USAGE_CHECK);
        MY_CASE(CRYPT_E_VERIFY_USAGE_OFFLINE);
        MY_CASE(CRYPT_E_NOT_IN_CTL);
        MY_CASE(CRYPT_E_NO_TRUSTED_SIGNER);
        MY_CASE(CRYPT_E_MISSING_PUBKEY_PARA);
        MY_CASE(CRYPT_E_OSS_ERROR);
        default:
        {
            PCRTCOMERRMSG pWinComMsg = RTErrCOMGet(dwErr);
            if (pWinComMsg)
                return pWinComMsg->pszDefine;

            static char s_szErr[32];
            RTStrPrintf(s_szErr, sizeof(s_szErr), "%#x (%d)", dwErr, dwErr);
            return s_szErr;
        }
    }
}

#if 0 /* hacking */
static RTEXITCODE addToStore(const char *pszFilename, PCRTUTF16 pwszStore)
{
    /*
     * Open the source.
     */
    void   *pvFile;
    size_t  cbFile;
    int rc = RTFileReadAll(pszFilename, &pvFile, &cbFile);
    if (RT_FAILURE(rc))
        return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTFileReadAll failed on '%s': %Rrc", pszFilename, rc);

    RTEXITCODE rcExit = RTEXITCODE_FAILURE;

    PCCERT_CONTEXT pCertCtx = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                                                           (PBYTE)pvFile,
                                                           (DWORD)cbFile);
    if (pCertCtx)
    {
        /*
         * Open the destination.
         */
        HCERTSTORE hDstStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
                                             PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
                                             NULL /* hCryptProv = default */,
                                             /*CERT_SYSTEM_STORE_LOCAL_MACHINE*/ CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG,
                                             pwszStore);
        if (hDstStore != NULL)
        {
#if 0
            DWORD dwContextType;
            if (CertAddSerializedElementToStore(hDstStore,
                                                pCertCtx->pbCertEncoded,
                                                pCertCtx->cbCertEncoded,
                                                CERT_STORE_ADD_NEW,
                                                0 /* dwFlags (reserved) */,
                                                CERT_STORE_ALL_CONTEXT_FLAG,
                                                &dwContextType,
                                                NULL))
            {
                RTMsgInfo("Successfully added '%s' to the '%ls' store (ctx type %u)", pszFilename, pwszStore, dwContextType);
                rcExit = RTEXITCODE_SUCCESS;
            }
            else
                RTMsgError("CertAddSerializedElementToStore returned %s", errorToString(GetLastError()));
#else
            if (CertAddCertificateContextToStore(hDstStore, pCertCtx, CERT_STORE_ADD_NEW, NULL))
            {
                RTMsgInfo("Successfully added '%s' to the '%ls' store", pszFilename, pwszStore);
                rcExit = RTEXITCODE_SUCCESS;
            }
            else
                RTMsgError("CertAddCertificateContextToStore returned %s", errorToString(GetLastError()));
#endif

            CertCloseStore(hDstStore, CERT_CLOSE_STORE_CHECK_FLAG);
        }
        else
            RTMsgError("CertOpenStore returned %s", errorToString(GetLastError()));
        CertFreeCertificateContext(pCertCtx);
    }
    else
        RTMsgError("CertCreateCertificateContext returned %s", errorToString(GetLastError()));
    RTFileReadAllFree(pvFile, cbFile);
    return rcExit;

#if 0

    CRYPT_DATA_BLOB Blob;
    Blob.cbData = (DWORD)cbData;
    Blob.pbData = (PBYTE)pvData;
    HCERTSTORE hSrcStore = PFXImportCertStore(&Blob, L"", )

#endif
}
コード例 #14
0
ファイル: cert_registration.c プロジェクト: Blandinium/eid-mw
DWORD StoreUserCert (PCCERT_CONTEXT pCertContext, unsigned char KeyUsageBits, CK_BYTE* cardSerialNumber, CK_ULONG cardSerialNumberLen)
{
	unsigned long dwFlags 		= CERT_STORE_NO_CRYPT_RELEASE_FLAG;
	PCCERT_CONTEXT  pDesiredCert	= NULL;
	PCCERT_CONTEXT  pPrevCert		= NULL;
	DWORD dwRet					= 0;
	wchar_t* pContainerName		= NULL;
	size_t pContainerNameCharLen = cardSerialNumberLen+20;
	CK_CHAR_PTR pcardSerialNrString = NULL;
	wchar_t* pProviderName		= NULL;
	CK_ULONG counter=0;
	HCERTSTORE hMyStore 		= CertOpenSystemStore((HCRYPTPROV_LEGACY)NULL, TEXT("MY"));


	CRYPT_KEY_PROV_INFO cryptKeyProvInfo;
	unsigned long dwPropId = CERT_KEY_PROV_INFO_PROP_ID;

	if (hMyStore == NULL)
	{
		dwRet = GetLastError();
		printf("StoreUserCerts: Unable to open the system certificate store. Error code: %d.\n",dwRet);
		return dwRet;
	}

		// ----------------------------------------------------
		// look if we already have a certificate with the same 
		// subject (contains name and NNR) in the store
		// If the certificate is not found --> NULL
		// ----------------------------------------------------
		do
		{
			if( NULL != (pDesiredCert = CertFindCertificateInStore(hMyStore, X509_ASN_ENCODING, 0, CERT_FIND_SUBJECT_NAME, &(pCertContext->pCertInfo->Subject) , pPrevCert)))
			{
				// ----------------------------------------------------
				// If the certificates are identical and function 
				// succeeds, the return value is nonzero, or TRUE.
				// ----------------------------------------------------
				if(FALSE == CertCompareCertificate(X509_ASN_ENCODING,pCertContext->pCertInfo,pDesiredCert->pCertInfo) || !ProviderNameCorrect(pDesiredCert) )
				{
					// ----------------------------------------------------
					// certificates are not identical, but have the same 
					// subject (contains name and NNR),
					// so we remove the one that was already in the store
					// ----------------------------------------------------
					if(FALSE == CertDeleteCertificateFromStore(pDesiredCert))
					{
						if (E_ACCESSDENIED == GetLastError())
						{
							continue;
						}
					}
					pPrevCert = NULL;
					continue;
				}
			}
			pPrevCert = pDesiredCert;
		}while (NULL != pDesiredCert);

	// ----------------------------------------------------
	// look if we already have the certificate in the store
	// If the certificate is not found --> NULL
	// ----------------------------------------------------
	if( NULL != (pDesiredCert = CertFindCertificateInStore(hMyStore, X509_ASN_ENCODING, 0, CERT_FIND_EXISTING, pCertContext , NULL)))
	{
		// ----------------------------------------------------
		// certificate is already in the store, then just return
		// ----------------------------------------------------
		CertFreeCertificateContext(pDesiredCert);
		CertCloseStore (hMyStore, CERT_CLOSE_STORE_FORCE_FLAG);
		return 0;
	}

	pContainerName = (wchar_t*)malloc(sizeof(wchar_t) * (pContainerNameCharLen));
	if(pContainerName == NULL)
		return E_OUTOFMEMORY;
	pcardSerialNrString = (CK_CHAR_PTR)malloc(cardSerialNumberLen*2 + 1);
	if(pcardSerialNrString == NULL)
		return E_OUTOFMEMORY;

	if(-1 == ByteArrayToString( &pcardSerialNrString, cardSerialNumberLen*2 + 1,cardSerialNumber ,cardSerialNumberLen))
		return -1;

	if(pContainerName == NULL)
	{
		CertFreeCertificateContext(pDesiredCert);
		CertCloseStore (hMyStore, CERT_CLOSE_STORE_FORCE_FLAG);
		return -1;
	}
	if (UseMinidriver())
	{
		if (KeyUsageBits & CERT_NON_REPUDIATION_KEY_USAGE)
		{
			swprintf_s(pContainerName,pContainerNameCharLen,L"NR_%hS",pcardSerialNrString);
		}
		else
		{
			swprintf_s(pContainerName,pContainerNameCharLen,L"DS_%hS",pcardSerialNrString);
		}
		cryptKeyProvInfo.pwszProvName			= L"Microsoft Base Smart Card Crypto Provider";
		cryptKeyProvInfo.dwKeySpec			= AT_SIGNATURE;
	}
	else
	{
		if (KeyUsageBits & CERT_NON_REPUDIATION_KEY_USAGE)
		{
			swprintf_s(pContainerName,pContainerNameCharLen,L"Signature(%hS)",pcardSerialNrString);
		}
		else
		{
			swprintf_s(pContainerName,pContainerNameCharLen,L"Authentication(%hS)",pcardSerialNrString);
		}

		cryptKeyProvInfo.pwszProvName		= L"Belgium Identity Card CSP";
		cryptKeyProvInfo.dwKeySpec		= AT_KEYEXCHANGE;
	}
	cryptKeyProvInfo.pwszContainerName	= pContainerName;

	cryptKeyProvInfo.dwProvType = PROV_RSA_FULL;
	cryptKeyProvInfo.dwFlags = 0;
	cryptKeyProvInfo.cProvParam = 0;
	cryptKeyProvInfo.rgProvParam = NULL;


/*
			// Set friendly names for the certificates
			DWORD dwsize = 0;
			dwsize = CertGetNameStringW(pCertContext, CERT_NAME_ATTR_TYPE, 0, szOID_COMMON_NAME, NULL, dwsize);
			auto_vec<WCHAR> pname(new WCHAR[dwsize]);
			dwsize = CertGetNameStringW(pCertContext, CERT_NAME_ATTR_TYPE, 0, szOID_COMMON_NAME, pname.get(), dwsize);
			CRYPT_DATA_BLOB tpFriendlyName = {0, 0};
			tpFriendlyName.pbData = (BYTE *)pname.get();
			tpFriendlyName.cbData = dwsize * sizeof(WCHAR);

			if (CertSetCertificateContextProperty(
				pCertContext,       // A pointer to the certificate
				// where the propertiy will be set.
				CERT_FRIENDLY_NAME_PROP_ID,           // An identifier of the property to be set. 
				// In this case, CERT_KEY_PROV_INFO_PROP_ID
				// is to be set to provide a pointer with the
				// certificate to its associated private key 
				// container.
				dwFlags,            // The flag used in this case is   
				// CERT_STORE_NO_CRYPT_RELEASE_FLAG
				// indicating that the cryptographic 
				// context aquired should not
				// be released when the function finishes.
				&tpFriendlyName   // A pointer to a data structure that holds
				// infomation on the private key container to
				// be associated with this certificate.
				))
*/

	// Set the property.
	if (CertSetCertificateContextProperty(
		pCertContext, 		// A pointer to the certificate where the property will be set.
		dwPropId, 			// An identifier of the property to be set.
		// In this case, CERT_KEY_PROV_INFO_PROP_ID is to be set to provide a pointer with the certificate to its associated private key container.
		dwFlags, 			// The flag used in this case is
		// CERT_STORE_NO_CRYPT_RELEASE_FLAG indicating that the cryptographic context acquired should not be released when the function finishes.
		&cryptKeyProvInfo 	// A pointer to a data structure that holds infomation on the private key container to be associated with this certificate.
		))
	{
		if (KeyUsageBits & CERT_NON_REPUDIATION_KEY_USAGE)
		{
			CertAddEnhancedKeyUsageIdentifier (pCertContext, szOID_PKIX_KP_EMAIL_PROTECTION);
		}
		else
		{
			CertAddEnhancedKeyUsageIdentifier (pCertContext, szOID_PKIX_KP_EMAIL_PROTECTION);
			CertAddEnhancedKeyUsageIdentifier (pCertContext, szOID_PKIX_KP_CLIENT_AUTH);
		}
		if (CertAddCertificateContextToStore(hMyStore, pCertContext, CERT_STORE_ADD_REPLACE_EXISTING, NULL))
		{
			printf("StoreUserCerts: Certificate context added to store.");
			dwRet = 0;
		}
		else
		{
			dwRet = GetLastError();
			printf("StoreUserCerts: Unable to add certificate context to store. Error code: %d.",dwRet);
		}
		CertCloseStore (hMyStore, CERT_CLOSE_STORE_FORCE_FLAG);
		hMyStore = NULL;
	}

	if(pContainerName != NULL)
		free (pContainerName);

	return dwRet;
}
コード例 #15
0
DWORD do_low_verify (const char *infile, const char *outfile)
{
    HCRYPTPROV hCryptProv = 0;               // CSP handle
    PCCERT_CONTEXT pUserCert = NULL;		// User certificate to be used
    DWORD ret = 1;
    FILE *tbs = NULL;
    BYTE *mem_tbs = NULL;
    DWORD mem_len = 0;
    FILE *signature = NULL;
    BYTE *mem_signature = NULL;
    DWORD signature_len = 0;
	HCRYPTMSG hMsg = 0;
	
    DWORD cbDecoded;
    BYTE *pbDecoded;
    DWORD cbSignerCertInfo;
    PCERT_INFO pSignerCertInfo;
    PCCERT_CONTEXT pSignerCertContext;
    PCERT_INFO pSignerCertificateInfo;
    HCERTSTORE hStoreHandle = NULL;
	
    if (! infile) {
		fprintf (stderr, "No input file was specified\n");
		goto err;
    }
	
	
    tbs = fopen (infile, "rb");
    if (!tbs) {
		fprintf (stderr, "Cannot open input file\n");
		goto err;
    }
	
    mem_len = 0;
    while (!feof(tbs)) {
		int r = 0;
		BYTE tmp[1024];
		r = fread (tmp, 1, 1024, tbs);
		mem_tbs = (BYTE *)realloc (mem_tbs, mem_len+r);
		memcpy (&mem_tbs[mem_len], tmp, r);
		mem_len += r;
    }
    fclose (tbs);
    tbs = NULL;
	
	
    if (signature) {
		signature_len = 0;
		while (!feof(signature)) {
			int r = 0;
			BYTE tmp[1024];
			r = fread (tmp, 1, 1024, signature);
			mem_signature = (BYTE *)realloc (mem_signature , signature_len+r);
			memcpy (&mem_signature [signature_len], tmp, r);
			signature_len += r;
		}
		fclose (signature);
		signature = NULL;
    }
	
    //--------------------------------------------------------------------
    // Open a message for decoding.
    
    hMsg = CryptMsgOpenToDecode(
								TYPE_DER,      // Encoding type.
								0,                     // Flags.
								0,                     // Use the default message type.
								hCryptProv,            // Cryptographic provider.
								NULL,                  // Recipient information.
								NULL);                 // Stream information.
    if (hMsg) 
		printf("The message to decode is open. \n");
    else{
    	fprintf (stderr, "OpenToDecode failed");
		ret = CSP_GetLastError();
		goto err;
	}
    //--------------------------------------------------------------------
    // Update the message with an encoded blob.
    // Both pbEncodedBlob, the encoded data, 
    // and cbEnclodeBlob, the length of the encoded data,
    // must be available. 
    
	
    if (CryptMsgUpdate(
					   hMsg,                 // Handle to the message
					   mem_tbs,        // Pointer to the encoded blob
					   mem_len,        // Size of the encoded blob
					   TRUE)){               // Last call) 
		printf("The encoded blob has been added to the message. \n");
	}
    else { 
		
		fprintf (stderr, "Decode MsgUpdate failed");
		ret = CSP_GetLastError();
		goto err;
    }
    //--------------------------------------------------------------------
    // Get the size of the content.
    
    ret = CryptMsgGetParam(
						   hMsg,                  // Handle to the message
						   CMSG_CONTENT_PARAM,    // Parameter type
						   0,                     // Index
						   NULL,                  // Address for returned info
						   &cbDecoded);           // Size of the returned info
    if (ret)
		printf("The message parameter (CMSG_CONTENT_PARAM) has been acquired. Message size: %d\n", cbDecoded);
    else{
		fprintf (stderr, "Decode CMSG_CONTENT_PARAM failed");
		ret = CSP_GetLastError();
		goto err;
	}
    //--------------------------------------------------------------------
    // Allocate memory.
    
    pbDecoded = (BYTE *) malloc(cbDecoded);
    if (!pbDecoded){
		
		fprintf (stderr, "Decode memory allocation failed");
		ret = CSP_GetLastError();
		goto err;
	}
    //--------------------------------------------------------------------
    // Get a pointer to the content.
    
    ret = CryptMsgGetParam(
						   hMsg,                 // Handle to the message
						   CMSG_CONTENT_PARAM,   // Parameter type
						   0,                    // Index
						   pbDecoded,            // Address for returned 
						   &cbDecoded);          // Size of the returned        
    if (ret)
		printf("The message param (CMSG_CONTENT_PARAM) updated. Length is %lu.\n",(unsigned long)cbDecoded);
    else{
		
		fprintf (stderr, "Decode CMSG_CONTENT_PARAM #2 failed");
		ret = CSP_GetLastError();
		goto err;
	}
    //--------------------------------------------------------------------
    // Verify the signature.
    // First, get the signer CERT_INFO from the message.
    
    //--------------------------------------------------------------------
    // Get the size of memory required.
	
    if (! pUserCert) { 
		ret = CryptMsgGetParam(
							   hMsg,                         // Handle to the message
							   CMSG_SIGNER_CERT_INFO_PARAM,  // Parameter type
							   0,                            // Index
							   NULL,                        // Address for returned 
							   &cbSignerCertInfo);          // Size of the returned 
		if (ret)
			printf("Try to get user cert. OK. Length %d.\n",cbSignerCertInfo);
		else {
			printf("No user certificate found in message.\n");
		}
    }
	
    if (pUserCert) {
		hStoreHandle = CertOpenStore(CERT_STORE_PROV_MEMORY, TYPE_DER, 0, CERT_STORE_CREATE_NEW_FLAG,NULL);
		if (!hStoreHandle){
			printf("Cannot create temporary store in memory.");
		    return CSP_GetLastError();
		}
		if (pUserCert) {
			ret = CertAddCertificateContextToStore(hStoreHandle, pUserCert, CERT_STORE_ADD_ALWAYS, NULL);
			pSignerCertInfo = pUserCert->pCertInfo;
		}
		else
			ret = 0;
		if (!ret){
			printf("Cannot add user certificate to store.");
			return CSP_GetLastError();
		}
    }
    
    //--------------------------------------------------------------------
    // Allocate memory.
    
    if (!pUserCert) {
		pSignerCertInfo = (PCERT_INFO) malloc(cbSignerCertInfo);
		if (!pSignerCertInfo){
			printf("Verify memory allocation failed");
			return CSP_GetLastError();
		}
    }
    
    //--------------------------------------------------------------------
    // Get the message certificate information (CERT_INFO
    // structure).
    
    if (! pUserCert) {
		ret = CryptMsgGetParam(
							   hMsg,                         // Handle to the message
							   CMSG_SIGNER_CERT_INFO_PARAM,  // Parameter type
							   0,                            // Index
							   pSignerCertInfo,              // Address for returned 
							   &cbSignerCertInfo);           // Size of the returned 
	    if (ret) 
			printf("The signer info has been returned. \n");
	    else{
			printf("Verify SIGNER_CERT_INFO #2 failed");
			return CSP_GetLastError();
		}
    }
    //--------------------------------------------------------------------
    // Open a certificate store in memory using CERT_STORE_PROV_MSG,
    // which initializes it with the certificates from the message.
    
    if (! hStoreHandle) {
		hStoreHandle = CertOpenStore(
									 CERT_STORE_PROV_MSG,        // Store provider type 
									 TYPE_DER,		    // Encoding type
									 hCryptProv,                 // Cryptographic provider
									 0,                          // Flags
									 hMsg);                      // Handle to the message
		if (hStoreHandle)
			printf("The message certificate store be used for verifying\n");
    }
	
    if (! hStoreHandle) {
	    printf("Cannot open certificate store form message\n");
		return CSP_GetLastError();
    }
    //--------------------------------------------------------------------
    // Find the signer's certificate in the store.
    
    if(pSignerCertContext = CertGetSubjectCertificateFromStore(
															   hStoreHandle,       // Handle to store
															   TYPE_DER,   // Encoding type
															   pSignerCertInfo))   // Pointer to retrieved CERT_CONTEXT
    {
		DWORD errCode=0;
		DWORD err;
		printf("A signer certificate has been retrieved. \n");
		err=VerifyCertificate(pSignerCertContext,&errCode);
		if (err)
		{
			printf("Subject cert verification failed: err=%x\n",err);
			return err;
		}
		if (errCode)
		{
			printf("Subject cert BAD: errCode=%x\n",errCode);
			return errCode;
		}
	}
    else
    {
		printf("Verify GetSubjectCert failed");
		return CSP_GetLastError();
    }
    //--------------------------------------------------------------------
    // Use the CERT_INFO from the signer certificate to verify
    // the signature.

    
    pSignerCertificateInfo = pSignerCertContext->pCertInfo;
    if(CryptMsgControl(
					   hMsg,                       // Handle to the message
					   0,                          // Flags
					   CMSG_CTRL_VERIFY_SIGNATURE, // Control type
					   pSignerCertificateInfo))    // Pointer to the CERT_INFO
    {
		printf("\nSignature was VERIFIED.\n");
    }
    else
    {
		printf("\nThe signature was NOT VEIFIED.\n");
    }
    if(hStoreHandle)
		CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_FORCE_FLAG);
	
	ret = 0;
err:
    return ret;
	
}
コード例 #16
0
ファイル: sspi.c プロジェクト: jianglei12138/ghostscript
/*
 * '_sspiGetCredentials()' - Retrieve an SSL/TLS certificate from the system store
 *                              If one cannot be found, one is created.
 */
BOOL					/* O - 1 on success, 0 on failure */
_sspiGetCredentials(_sspi_struct_t *conn,
					/* I - Client connection */
                    const LPWSTR   container,
					/* I - Cert container name */
                    const TCHAR    *cn,	/* I - Common name of certificate */
                    BOOL           isServer)
					/* I - Is caller a server? */
{
  HCERTSTORE		store = NULL;	/* Certificate store */
  PCCERT_CONTEXT	storedContext = NULL;
					/* Context created from the store */
  PCCERT_CONTEXT	createdContext = NULL;
					/* Context created by us */
  DWORD			dwSize = 0;	/* 32 bit size */
  PBYTE			p = NULL;	/* Temporary storage */
  HCRYPTPROV		hProv = (HCRYPTPROV) NULL;
					/* Handle to a CSP */
  CERT_NAME_BLOB	sib;		/* Arbitrary array of bytes */
  SCHANNEL_CRED		SchannelCred;	/* Schannel credential data */
  TimeStamp		tsExpiry;	/* Time stamp */
  SECURITY_STATUS	Status;		/* Status */
  HCRYPTKEY		hKey = (HCRYPTKEY) NULL;
					/* Handle to crypto key */
  CRYPT_KEY_PROV_INFO	kpi;		/* Key container info */
  SYSTEMTIME		et;		/* System time */
  CERT_EXTENSIONS	exts;		/* Array of cert extensions */
  CRYPT_KEY_PROV_INFO	ckp;		/* Handle to crypto key */
  BOOL			ok = TRUE;	/* Return value */


  DEBUG_printf(("_sspiGetCredentials(conn=%p, container=%p, cn=\"%s\", isServer=%d)", conn, container, cn, isServer));

  if (!conn)
    return (FALSE);
  if (!cn)
    return (FALSE);

  if (!CryptAcquireContextW(&hProv, (LPWSTR) container, MS_DEF_PROV_W,
                           PROV_RSA_FULL,
                           CRYPT_NEWKEYSET | CRYPT_MACHINE_KEYSET))
  {
    if (GetLastError() == NTE_EXISTS)
    {
      if (!CryptAcquireContextW(&hProv, (LPWSTR) container, MS_DEF_PROV_W,
                               PROV_RSA_FULL, CRYPT_MACHINE_KEYSET))
      {
        DEBUG_printf(("_sspiGetCredentials: CryptAcquireContext failed: %x\n",
                      GetLastError()));
        ok = FALSE;
        goto cleanup;
      }
    }
  }

  store = CertOpenStore(CERT_STORE_PROV_SYSTEM,
                        X509_ASN_ENCODING|PKCS_7_ASN_ENCODING,
                        hProv,
                        CERT_SYSTEM_STORE_LOCAL_MACHINE |
                        CERT_STORE_NO_CRYPT_RELEASE_FLAG |
                        CERT_STORE_OPEN_EXISTING_FLAG,
                        L"MY");

  if (!store)
  {
    DEBUG_printf(("_sspiGetCredentials: CertOpenSystemStore failed: %x\n",
                  GetLastError()));
    ok = FALSE;
    goto cleanup;
  }

  dwSize = 0;

  if (!CertStrToName(X509_ASN_ENCODING, cn, CERT_OID_NAME_STR,
                     NULL, NULL, &dwSize, NULL))
  {
    DEBUG_printf(("_sspiGetCredentials: CertStrToName failed: %x\n",
                   GetLastError()));
    ok = FALSE;
    goto cleanup;
  }

  p = (PBYTE) malloc(dwSize);

  if (!p)
  {
    DEBUG_printf(("_sspiGetCredentials: malloc failed for %d bytes", dwSize));
    ok = FALSE;
    goto cleanup;
  }

  if (!CertStrToName(X509_ASN_ENCODING, cn, CERT_OID_NAME_STR, NULL,
                     p, &dwSize, NULL))
  {
    DEBUG_printf(("_sspiGetCredentials: CertStrToName failed: %x",
                 GetLastError()));
    ok = FALSE;
    goto cleanup;
  }

  sib.cbData = dwSize;
  sib.pbData = p;

  storedContext = CertFindCertificateInStore(store, X509_ASN_ENCODING|PKCS_7_ASN_ENCODING,
                                             0, CERT_FIND_SUBJECT_NAME, &sib, NULL);

  if (!storedContext)
  {
   /*
    * If we couldn't find the context, then we'll
    * create a new one
    */
    if (!CryptGenKey(hProv, AT_KEYEXCHANGE, CRYPT_EXPORTABLE, &hKey))
    {
      DEBUG_printf(("_sspiGetCredentials: CryptGenKey failed: %x",
                    GetLastError()));
      ok = FALSE;
      goto cleanup;
    }

    ZeroMemory(&kpi, sizeof(kpi));
    kpi.pwszContainerName = (LPWSTR) container;
    kpi.pwszProvName = MS_DEF_PROV_W;
    kpi.dwProvType = PROV_RSA_FULL;
    kpi.dwFlags = CERT_SET_KEY_CONTEXT_PROP_ID;
    kpi.dwKeySpec = AT_KEYEXCHANGE;

    GetSystemTime(&et);
    et.wYear += 10;

    ZeroMemory(&exts, sizeof(exts));

    createdContext = CertCreateSelfSignCertificate(hProv, &sib, 0, &kpi, NULL, NULL,
                                                   &et, &exts);

    if (!createdContext)
    {
      DEBUG_printf(("_sspiGetCredentials: CertCreateSelfSignCertificate failed: %x",
                   GetLastError()));
      ok = FALSE;
      goto cleanup;
    }

    if (!CertAddCertificateContextToStore(store, createdContext,
                                          CERT_STORE_ADD_REPLACE_EXISTING,
                                          &storedContext))
    {
      DEBUG_printf(("_sspiGetCredentials: CertAddCertificateContextToStore failed: %x",
                    GetLastError()));
      ok = FALSE;
      goto cleanup;
    }

    ZeroMemory(&ckp, sizeof(ckp));
    ckp.pwszContainerName = (LPWSTR) container;
    ckp.pwszProvName = MS_DEF_PROV_W;
    ckp.dwProvType = PROV_RSA_FULL;
    ckp.dwFlags = CRYPT_MACHINE_KEYSET;
    ckp.dwKeySpec = AT_KEYEXCHANGE;

    if (!CertSetCertificateContextProperty(storedContext,
                                           CERT_KEY_PROV_INFO_PROP_ID,
                                           0, &ckp))
    {
      DEBUG_printf(("_sspiGetCredentials: CertSetCertificateContextProperty failed: %x",
                    GetLastError()));
      ok = FALSE;
      goto cleanup;
    }
  }

  ZeroMemory(&SchannelCred, sizeof(SchannelCred));

  SchannelCred.dwVersion = SCHANNEL_CRED_VERSION;
  SchannelCred.cCreds = 1;
  SchannelCred.paCred = &storedContext;

 /*
  * SSPI doesn't seem to like it if grbitEnabledProtocols
  * is set for a client
  */
  if (isServer)
    SchannelCred.grbitEnabledProtocols = SP_PROT_SSL3TLS1;

 /*
  * Create an SSPI credential.
  */
  Status = AcquireCredentialsHandle(NULL, UNISP_NAME,
                                    isServer ? SECPKG_CRED_INBOUND:SECPKG_CRED_OUTBOUND,
                                    NULL, &SchannelCred, NULL, NULL, &conn->creds,
                                    &tsExpiry);
  if (Status != SEC_E_OK)
  {
    DEBUG_printf(("_sspiGetCredentials: AcquireCredentialsHandle failed: %x", Status));
    ok = FALSE;
    goto cleanup;
  }

cleanup:

 /*
  * Cleanup
  */
  if (hKey)
    CryptDestroyKey(hKey);

  if (createdContext)
    CertFreeCertificateContext(createdContext);

  if (storedContext)
    CertFreeCertificateContext(storedContext);

  if (p)
    free(p);

  if (store)
    CertCloseStore(store, 0);

  if (hProv)
    CryptReleaseContext(hProv, 0);

  return (ok);
}
コード例 #17
0
    void PfxCertificate::addToStore(
        Win32CertificateLocation certStoreLocation, 
        Win32CertificateStore certStore)
    {

        std::wstring wStoreName;
        switch (certStore)
        {
        case Cs_AddressBook:            wStoreName = L"AddressBook";      break;
        case Cs_AuthRoot:               wStoreName = L"AuthRoot";         break;
        case Cs_CertificateAuthority:   wStoreName = L"CA";               break;
        case Cs_Disallowed:             wStoreName = L"Disallowed";       break;
        case Cs_My:                     wStoreName = L"MY";               break;
        case Cs_Root:                   wStoreName = L"Root";             break;
        case Cs_TrustedPeople:          wStoreName = L"TrustedPeople";    break;
        case Cs_TrustedPublisher:       wStoreName = L"TrustedPublisher"; break;
        default:
            RCF_ASSERT(0 && "Invalid certificate store value.");
        }

        DWORD dwFlags = 0;
        switch (certStoreLocation)
        {
        case Cl_CurrentUser:            dwFlags = CERT_SYSTEM_STORE_CURRENT_USER;   break;
        case Cl_LocalMachine:           dwFlags = CERT_SYSTEM_STORE_LOCAL_MACHINE;  break;
        default:
            RCF_ASSERT(0 && "Invalid certificate store location value.");
        }

        HCERTSTORE hCertStore = CertOpenStore(
            (LPCSTR) CERT_STORE_PROV_SYSTEM,
            X509_ASN_ENCODING,
            0,
            dwFlags,
            wStoreName.c_str());

        DWORD dwErr = GetLastError();

        RCF_VERIFY(
            hCertStore, 
            RCF::Exception(
                _RcfError_CryptoApiError("CertOpenStore()"), 
                dwErr, 
                RCF::RcfSubsystem_Os));

        BOOL ret = CertAddCertificateContextToStore(
            hCertStore,
            mpCert,
            CERT_STORE_ADD_USE_EXISTING,
            NULL);

        dwErr = GetLastError();

        RCF_VERIFY(
            ret, 
            RCF::Exception(
                _RcfError_CryptoApiError("CertAddCertificateContextToStore()"), 
                dwErr, 
                RCF::RcfSubsystem_Os));

        CertCloseStore(hCertStore, 0);
    }
コード例 #18
0
/* {{{ static int ma_tls_set_client_certs(MARIADB_TLS *ctls) */
static int ma_tls_set_client_certs(MARIADB_TLS *ctls)
{
  MYSQL *mysql= ctls->pvio->mysql;
  char *certfile= mysql->options.ssl_cert,
       *keyfile= mysql->options.ssl_key,
       *cafile= mysql->options.ssl_ca;
  PCERT_CONTEXT ca_ctx= NULL;
  PCRL_CONTEXT crl_ctx = NULL;
       
  SC_CTX *sctx= (SC_CTX *)ctls->ssl;
  MARIADB_PVIO *pvio= ctls->pvio;

  if (cafile)
  {
    if (!(ca_ctx = ma_schannel_create_cert_context(pvio, cafile)))
      goto end;

    /* Add ca to in-memory certificate store */
    if (CertAddCertificateContextToStore(ca_CertStore, ca_ctx, CERT_STORE_ADD_NEWER, NULL) != TRUE &&
        GetLastError() != CRYPT_E_EXISTS)
    {
      ma_schannel_set_win_error(sctx->mysql);
      goto end;
    }
    ca_Check= 0;
    CertFreeCertificateContext(ca_ctx);
  }

  if (!certfile && keyfile)
    certfile= keyfile;
  if (!keyfile && certfile)
    keyfile= certfile;

  if (certfile && certfile[0])
    if (!(sctx->client_cert_ctx = ma_schannel_create_cert_context(ctls->pvio, certfile)))
      goto end;

  if (sctx->client_cert_ctx && keyfile[0])
    if (!ma_schannel_load_private_key(pvio, sctx->client_cert_ctx, keyfile))
      goto end;
 
  if (mysql->options.extension && mysql->options.extension->ssl_crl)
  {
    if (!(crl_ctx= (CRL_CONTEXT *)ma_schannel_create_crl_context(pvio, mysql->options.extension->ssl_crl)))
      goto end;
    /* Add ca to in-memory certificate store */
    if (CertAddCRLContextToStore(crl_CertStore, crl_ctx, CERT_STORE_ADD_NEWER, NULL) != TRUE &&
        GetLastError() != CRYPT_E_EXISTS)
    {
      ma_schannel_set_win_error(sctx->mysql);
      goto end;
    }
    crl_Check = 1;
    CertFreeCertificateContext(ca_ctx);
  }
  return 0;
  
end:
  if (ca_ctx)
    CertFreeCertificateContext(ca_ctx);
  if (sctx->client_cert_ctx)
    CertFreeCertificateContext(sctx->client_cert_ctx);
  if (crl_ctx)
    CertFreeCRLContext(crl_ctx);
  sctx->client_cert_ctx= NULL;
  return 1;
}
コード例 #19
0
/*****************************************************************************
 wmain

*****************************************************************************/
DWORD
__cdecl
wmain(
    int     argc,
    LPWSTR  argv[]
    )
{
    HRESULT                 hr = S_OK;

    HCERTSTORE              hStore = NULL;
    PCCERT_CONTEXT          pCert = NULL;
    PCCERT_CONTEXT          pStoreCert = NULL;

    char                    szStoreProvider[ 256 ] = { "TestExt" };

    // Store provider name
    LPWSTR pwszStoreProvider = NULL;
    // Store name
    LPWSTR pwszStoreName = L"TestStoreName";

    LPWSTR pwszCertPath = NULL;


    int i;

    //
    // options
    //

    for( i=1; i<argc; i++ )
    {
        if ( lstrcmpW (argv[i], L"/?") == 0 ||
             lstrcmpW (argv[i], L"-?") == 0 ) 
        {
            Usage( L"SampleStoreProvider.exe" );
            goto CleanUp;
        }

        if( *argv[i] != L'-' )
            break;

        if ( lstrcmpW (argv[i], L"-s") == 0 )
        {
            if( i+1 >= argc )
            {
                hr = E_INVALIDARG;
                
                goto CleanUp;
            }

            pwszStoreName = argv[++i];
        }
        else
        if ( lstrcmpW (argv[i], L"-p") == 0 )
        {
            if( i+1 >= argc )
            {
                hr = E_INVALIDARG;
                
                goto CleanUp;
            }

            pwszStoreProvider = argv[++i];
        }

    }

    if( i >= argc )
    {
        hr = E_INVALIDARG;
        
        goto CleanUp;
    }

    pwszCertPath = argv[i++];

    // Load the certificate from the file passed in as cmd line parameter;    
    if (!CryptQueryObject(
                                CERT_QUERY_OBJECT_FILE,         //dwObjectType 
                                pwszCertPath,                   //pvObject
                                CERT_QUERY_CONTENT_FLAG_CERT,   //dwExpectedContentTypeFlags
                                CERT_QUERY_FORMAT_FLAG_ALL,     //dwExpectedFormatTypeFlags 
                                0,                              //dwFlags
                                0,                              //pdwMsgAndCertEncodingType 
                                0,                              //pdwContentType 
                                0,                              //pdwFormatType 
                                0,                              //phCertStore
                                0,                              //phMsg 
                                (const void**)&pCert            //ppvContext
                                ))
    {
        hr = HRESULT_FROM_WIN32( GetLastError() );
        
        goto CleanUp;
    }

    // Open the store using the sample provider name
    if( NULL != pwszStoreProvider )
    {
        if( 1 < WideCharToMultiByte(
                                CP_ACP, 
                                WC_ERR_INVALID_CHARS, 
                                pwszStoreProvider,
                                -1, 
                                szStoreProvider, 
                                sizeof(szStoreProvider),
                                NULL,    
                                NULL
                                ))
        {
            hr = HRESULT_FROM_WIN32( GetLastError() );
            
            goto CleanUp;
        }
    }

    hStore = CertOpenStore(
                                szStoreProvider,        // lpszStoreProvider
                                X509_ASN_ENCODING,      // dwMsgAndCertEncodingType
                                NULL,                   // hCryptProv
                                0,                      // dwFlags (will create it if does not exists)
                                (void*)pwszStoreName);  // pvPara
    if (hStore == NULL)
    {
        hr = HRESULT_FROM_WIN32( GetLastError() );
        
        goto CleanUp;
    }

    // Add a certificate to store
    if(!CertAddCertificateContextToStore(
                                hStore,                             // hCertStore
                                pCert,                              // pCertContext
                                CERT_STORE_ADD_REPLACE_EXISTING,    // dwAddDisposition
                                NULL                                // ppStoreContext
                                ))
    {
        hr = HRESULT_FROM_WIN32( GetLastError() );
        
        goto CleanUp;
    }


    pStoreCert = CertFindCertificateInStore(
                                hStore,                             // hCertStore
                                X509_ASN_ENCODING,                  // dwCertEncodingType
                                0,                                  // dwFindFlags
                                CERT_FIND_EXISTING,                 // dwFindType        
                                pCert,                              // pvFindPara
                                NULL                                // pPrevCertContext
                                );
    if (pStoreCert == NULL)
    {
        hr = HRESULT_FROM_WIN32( GetLastError() );
        
        goto CleanUp;
    }

    hr = S_OK;

CleanUp:

    if( NULL != pCert )
        CertFreeCertificateContext(pCert);
    
    if( NULL != pStoreCert )
        CertFreeCertificateContext(pStoreCert);

    if( NULL != hStore )
        CertCloseStore(hStore, 0);

    if( FAILED( hr ))
    {
        ReportError( NULL, hr  );
    }

    return (DWORD)hr;
}
コード例 #20
0
ファイル: SoffidEssoManager.cpp プロジェクト: SoffidIAM/esso
// Read URL server
LPSTR SoffidEssoManager::readURL (HINTERNET hSession, const wchar_t* host, int port,
		LPCWSTR path, BOOL allowUnknownCA, size_t *pSize)
{
	BOOL bResults = FALSE;
	HINTERNET hConnect = NULL, hRequest = NULL;

	DWORD dwDownloaded = -1;
	BYTE *buffer = NULL;

	if (debug)
	{
		log("Connecting to %s:%d...\n", host, port);
	}

	hConnect = WinHttpConnect(hSession, host, port, 0);

	if (hConnect)
	{
		if (debug)
		{
			log("Performing request %s...\n", path);
		}

		hRequest = WinHttpOpenRequest(hConnect, L"GET", path, NULL, WINHTTP_NO_REFERER,
				WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE);
	}

	// Send a request.
	if (hRequest)
	{
		if (debug)
			log("Sending request ...\n");

		WinHttpSetOption(hRequest, WINHTTP_OPTION_CLIENT_CERT_CONTEXT, NULL, 0);

		if (allowUnknownCA)
		{
			DWORD flags = SECURITY_FLAG_IGNORE_UNKNOWN_CA;
			WinHttpSetOption(hRequest, WINHTTP_OPTION_SECURITY_FLAGS, (LPVOID) &flags,
					sizeof flags);
		}

		bResults = WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0,
				WINHTTP_NO_REQUEST_DATA, 0, 0, 0);
	}

	if (bResults && allowUnknownCA)
	{
		// Agreagar la CA ROOT
		PCERT_CONTEXT context;
		DWORD dwSize = sizeof context;
		BOOL result = WinHttpQueryOption(hRequest, WINHTTP_OPTION_SERVER_CERT_CONTEXT,
				&context, &dwSize);

		if (!result)
		{
			log("Cannot get context\n");
//			notifyError();
		}

		PCCERT_CONTEXT issuerContext = CertFindCertificateInStore(context->hCertStore,
				X509_ASN_ENCODING, 0, CERT_FIND_ISSUER_OF, context, NULL);
		HCERTSTORE systemStore = CertOpenStore((LPCSTR) 13, // CERT_STORE_PROV_SYSTEM_REGISTRY_W
				0, (HCRYPTPROV) NULL, (2 << 16) | // CERT_SYSTEM_STORE_LOCAL_MACHINE
						0x1000, // CERT_STORE_MAXIMUM_ALLOWED
				L"ROOT");
		CertAddCertificateContextToStore(systemStore, issuerContext,
				1 /*CERT_STORE_ADD_NEW*/, NULL);

		CertFreeCertificateContext(issuerContext);
		CertFreeCertificateContext(context);
	}

	// End the request.
	if (bResults)
	{
		if (debug)
			log("Waiting for response....\n");

		bResults = WinHttpReceiveResponse(hRequest, NULL);
	}

	// Keep checking for data until there is nothing left.
	DWORD used = 0;
	if (bResults)
	{
		const DWORD chunk = 4096;
		DWORD allocated = 0;
		do
		{
			if (used + chunk > allocated)
			{
				allocated += chunk;
				buffer = (LPBYTE) realloc(buffer, allocated);
			}

			dwDownloaded = 0;
			if (!WinHttpReadData(hRequest, &buffer[used], chunk, &dwDownloaded))
				dwDownloaded = -1;

			else
				used += dwDownloaded;
		} while (dwDownloaded > 0);

		buffer[used] = '\0';
	}

	DWORD dw = GetLastError();
	if (!bResults && debug)
	{
		if (dw == ERROR_WINHTTP_CANNOT_CONNECT)
			log("Error: Cannot connect\n");
		else if (dw == ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED)
			log("Error: Client CERT required\n");
		else if (dw == ERROR_WINHTTP_CONNECTION_ERROR)
			log("Error: Connection error\n");
		else if (dw == ERROR_WINHTTP_INCORRECT_HANDLE_STATE)
			log("Error: ERROR_WINHTTP_INCORRECT_HANDLE_STATE\n");
		else if (dw == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE)
			log("Error: ERROR_WINHTTP_INCORRECT_HANDLE_TYPE\n");
		else if (dw == ERROR_WINHTTP_INTERNAL_ERROR)
			log("Error: ERROR_WINHTTP_INTERNAL_ERROR\n");
		else if (dw == ERROR_WINHTTP_INVALID_URL)
			log("Error: ERROR_WINHTTP_INVALID_URL\n");
		else if (dw == ERROR_WINHTTP_LOGIN_FAILURE)
			log("Error: ERROR_WINHTTP_LOGIN_FAILURE\n");
		else if (dw == ERROR_WINHTTP_NAME_NOT_RESOLVED)
			log("Error: ERROR_WINHTTP_NAME_NOT_RESOLVED\n");
		else if (dw == ERROR_WINHTTP_OPERATION_CANCELLED)
			log("Error: ERROR_WINHTTP_OPERATION_CANCELLED\n");
		else if (dw == ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW)
			log("Error: ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW\n");
		else if (dw == ERROR_WINHTTP_SECURE_FAILURE)
			log("Error: ERROR_WINHTTP_SECURE_FAILURE\n");
		else if (dw == ERROR_WINHTTP_SHUTDOWN)
			log("Error: ERROR_WINHTTP_SHUTDOWN\n");
		else if (dw == ERROR_WINHTTP_TIMEOUT)
			log("Error: ERROR_WINHTTP_TIMEOUT\n");
		else if (dw == ERROR_WINHTTP_UNRECOGNIZED_SCHEME)
			log("Error: ERROR_WINHTTP_UNRECOGNIZED_SCHEME\n");
		else if (dw == ERROR_NOT_ENOUGH_MEMORY)
			log("Error: ERROR_NOT_ENOUGH_MEMORY\n");
		else if (dw == ERROR_INVALID_PARAMETER)
			log("Error: ERROR_INVALID_PARAMETER\n");
		else if (dw == ERROR_WINHTTP_RESEND_REQUEST)
			log("Error:  ERROR_WINHTTP_RESEND_REQUEST\n");
		else if (dw != ERROR_SUCCESS)
		{
			log("Unkonwn error %d\n", dw);
		}
//		notifyError();
	}

	// Close any open handles.
	if (hRequest)
		WinHttpCloseHandle(hRequest);
	if (hConnect)
		WinHttpCloseHandle(hConnect);
	if (hSession)
		WinHttpCloseHandle(hSession);

	SetLastError(dw);

	if (pSize != NULL)
		*pSize = used;

	return (LPSTR) buffer;
}
コード例 #21
0
ファイル: RegisterEDL.cpp プロジェクト: ash2005/javacardsign
DWORD ShowCertsDlg(LPCTSTR szProviderName,
				  LPCTSTR szReaderName /* Can be NULL */
				  )
{
	HCRYPTPROV HMainCryptProv = NULL;
	BOOL bStatus = FALSE;
	LPTSTR szMainContainerName = NULL;
	CHAR szContainerName[1024];
	DWORD dwContainerNameLen = sizeof(szContainerName);
	DWORD dwErr = 0;
	DWORD dwFlags = CRYPT_FIRST;
	PCCERT_CONTEXT pContextArray[128];
	DWORD dwContextArrayLen = 0;
	HCRYPTPROV hProv = NULL;
	HCRYPTKEY hKey = NULL;
	LPBYTE pbCert = NULL;
	DWORD dwCertLen = 0;
	PCCERT_CONTEXT pCertContext = NULL;
	DWORD pKeySpecs[2] = { AT_KEYEXCHANGE, AT_SIGNATURE};

	if (szReaderName)
	{
		size_t ulNameLen = _tcslen(szReaderName);
		szMainContainerName = (LPTSTR) LocalAlloc(0, (ulNameLen + 6) * sizeof(TCHAR));
		if (!szMainContainerName)
		{
			return GetLastError();
		}
		_stprintf(szMainContainerName, _T("\\\\.\\%s\\"), szReaderName);
	}			

	bStatus = CryptAcquireContext(&HMainCryptProv,szMainContainerName,szProviderName,PROV_RSA_FULL,0);

	if (!bStatus)
	{
		dwErr = GetLastError();
		goto end;
	}

	/* Enumerate all the containers */
	while (CryptGetProvParam(HMainCryptProv,PP_ENUMCONTAINERS,(LPBYTE) szContainerName,&dwContainerNameLen,dwFlags) &&(dwContextArrayLen < 128))
	{
#ifndef _UNICODE
		if (CryptAcquireContext(&hProv,
				szContainerName,
				szProviderName,
				PROV_RSA_FULL,
				0))
#else
		// convert the container name to unicode
		int wLen = MultiByteToWideChar(CP_ACP, 0, szContainerName, -1, NULL, 0);
		LPWSTR szWideContainerName = (LPWSTR) LocalAlloc(0, wLen * sizeof(WCHAR));
		MultiByteToWideChar(CP_ACP, 0, szContainerName, -1, szWideContainerName, wLen);

		// Acquire a context on the current container
		if (CryptAcquireContext(&hProv,szWideContainerName,szProviderName,PROV_RSA_FULL,0))
#endif
		{
			// Loop over all the key specs
			for (int i = 0; i < 2; i++)
			{
				if (CryptGetUserKey(hProv,pKeySpecs[i],&hKey) )
				{
					if (CryptGetKeyParam(hKey,KP_CERTIFICATE,NULL,&dwCertLen,0))
					{
						pbCert = (LPBYTE) LocalAlloc(0, dwCertLen);
						if (!pbCert)
						{
							dwErr = GetLastError();
							goto end;
						}
						if (CryptGetKeyParam(hKey,KP_CERTIFICATE,pbCert,&dwCertLen,0))
						{
							pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING|PKCS_7_ASN_ENCODING, pbCert,dwCertLen);
							if (pCertContext)
							{
								pContextArray[dwContextArrayLen++] = pCertContext;

								CRYPT_KEY_PROV_INFO ProvInfo;
								ProvInfo.pwszContainerName = szWideContainerName;
								ProvInfo.pwszProvName = L"Microsoft Base Smart Card Crypto Provider";
								ProvInfo.dwProvType = PROV_RSA_FULL;
								ProvInfo.dwFlags = 0;
								ProvInfo.dwKeySpec = AT_SIGNATURE;
								ProvInfo.cProvParam = 0;
								ProvInfo.rgProvParam = NULL;
								
								CertSetCertificateContextProperty(pCertContext,CERT_KEY_PROV_INFO_PROP_ID, 0, &ProvInfo);

								HCERTSTORE dest = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL,
								CERT_STORE_OPEN_EXISTING_FLAG | CERT_SYSTEM_STORE_CURRENT_USER,L"My");
								if(CertAddCertificateContextToStore(dest, pCertContext,CERT_STORE_ADD_REPLACE_EXISTING, NULL))
								{
									//char certName[1024];
									//LPWSTR certName = (LPWSTR)new wchar_t[1024];
									LPTSTR certName;
									int cbSize = CertNameToStrW(pCertContext->dwCertEncodingType, &(pCertContext->pCertInfo->Subject),CERT_X500_NAME_STR,NULL,0);
									certName = (LPTSTR)malloc(cbSize * sizeof(TCHAR));

									if (CertNameToStrW(pCertContext->dwCertEncodingType, &(pCertContext->pCertInfo->Subject),CERT_X500_NAME_STR,certName,sizeof(certName)))
									{
									}
									printf("Installed certificate.");
								}
								else
									printf("Error while adding certificate to store");
							}
						}
						LocalFree(pbCert);
					}
					CryptDestroyKey(hKey);
					hKey = NULL;
				}
			}
			CryptReleaseContext(hProv, 0);
			hProv = NULL;
		}

#ifdef _UNICODE
		LocalFree(szWideContainerName);
#endif
		
		// prepare parameters for the next loop
		dwContainerNameLen = sizeof(szContainerName);
		dwFlags = 0;
	}

	if (dwContextArrayLen == 0)
		printf("No certificate contexts found on card\n");
	
end:
	while (dwContextArrayLen--)
	{
		CertFreeCertificateContext(pContextArray[dwContextArrayLen]);
	}
	if (hKey)
		CryptDestroyKey(hKey);
	if (hProv)
		CryptReleaseContext(hProv, 0);
	if (szMainContainerName)
		LocalFree(szMainContainerName);
	if (HMainCryptProv)
		CryptReleaseContext(HMainCryptProv, 0);
	return dwErr;
}