Example #1
0
void WinCAPICryptoX509::loadX509Base64Bin(const char * buf, unsigned int len) {

	unsigned char * rawCert;
	XSECnew(rawCert, unsigned char [len]);
	ArrayJanitor<unsigned char> j_rawCert(rawCert);

	// Base64 Decode
	XSCryptCryptoBase64 b64;

	b64.decodeInit();
	unsigned int rawCertLen = b64.decode((unsigned char *) buf, len, rawCert, len);
	rawCertLen += b64.decodeFinish(&rawCert[rawCertLen], len - rawCertLen);

	// Now load certificate into Win32 CSP

	mp_certContext = CertCreateCertificateContext(
		X509_ASN_ENCODING,
		rawCert,
		rawCertLen);

	if (mp_certContext == 0) {
		throw XSECCryptoException(XSECCryptoException::X509Error,
			"WinCAPIX509:loadX509Base64Bin - Error decoding certificate");
	}


	m_DERX509.sbMemcpyIn(buf, len);
	m_DERX509[len] = '\0';

}
static void setup_x509_schannel_create_ecc_mocks(void)
{
    STRICT_EXPECTED_CALL(gballoc_malloc(IGNORED_NUM_ARG)); /*this is creating the handle storage space*/
    STRICT_EXPECTED_CALL(CryptStringToBinaryA("certificate", 0, CRYPT_STRING_ANY, NULL, IGNORED_PTR_ARG, NULL, NULL)); /*this is asking for "how big is the certificate binary size?"*/
    STRICT_EXPECTED_CALL(gballoc_malloc(IGNORED_NUM_ARG)); /*this is creating the binary storage for the certificate*/
    STRICT_EXPECTED_CALL(CryptStringToBinaryA("certificate", 0, CRYPT_STRING_ANY, IGNORED_PTR_ARG, IGNORED_PTR_ARG, NULL, NULL)); /*this is asking for "fill in the certificate in this binary buffer"*/
    STRICT_EXPECTED_CALL(CryptStringToBinaryA("private key", 0, CRYPT_STRING_ANY, NULL, IGNORED_PTR_ARG, NULL, NULL)); /*this is asking for "how big is the private key binary size?"*/
    STRICT_EXPECTED_CALL(gballoc_malloc(IGNORED_NUM_ARG)); /*this is creating the binary storage for the private key*/
    STRICT_EXPECTED_CALL(CryptStringToBinaryA("private key", 0, CRYPT_STRING_ANY, IGNORED_PTR_ARG, IGNORED_PTR_ARG, NULL, NULL)); /*this is asking for "fill in the private key in this binary buffer"*/
    STRICT_EXPECTED_CALL(CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, PKCS_RSA_PRIVATE_KEY, IGNORED_PTR_ARG, IGNORED_NUM_ARG, 0, NULL, NULL, IGNORED_PTR_ARG)).SetReturn(FALSE); /*this is asking "how big is the decoded private key? (from binary)*/
    STRICT_EXPECTED_CALL(CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_ECC_PRIVATE_KEY, IGNORED_PTR_ARG, IGNORED_NUM_ARG, 0, NULL, NULL, IGNORED_PTR_ARG)); /*this is asking "how big is the decoded private key? (from binary)*/
    STRICT_EXPECTED_CALL(gballoc_malloc(IGNORED_NUM_ARG)); /*this is allocating space for the decoded private key*/
    STRICT_EXPECTED_CALL(CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_ECC_PRIVATE_KEY, IGNORED_PTR_ARG, IGNORED_NUM_ARG, 0, NULL, IGNORED_PTR_ARG, IGNORED_PTR_ARG)); /*this is asking "how big is the decoded private key? (from binary)*/
    STRICT_EXPECTED_CALL(CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, IGNORED_PTR_ARG, IGNORED_NUM_ARG)); /*create a certificate context from an encoded certificate*/

    STRICT_EXPECTED_CALL(gballoc_malloc(IGNORED_NUM_ARG));
    STRICT_EXPECTED_CALL(NCryptOpenStorageProvider(IGNORED_PTR_ARG, MS_KEY_STORAGE_PROVIDER, 0))
        .IgnoreArgument_pszProviderName();
    STRICT_EXPECTED_CALL(NCryptImportKey((NCRYPT_PROV_HANDLE)IGNORED_PTR_ARG, (NCRYPT_KEY_HANDLE)IGNORED_PTR_ARG, IGNORED_PTR_ARG, IGNORED_PTR_ARG, IGNORED_PTR_ARG, IGNORED_PTR_ARG, IGNORED_NUM_ARG, NCRYPT_OVERWRITE_KEY_FLAG))
        .IgnoreArgument_hProvider()
        .IgnoreArgument_hImportKey();
    STRICT_EXPECTED_CALL(NCryptFreeObject((HCRYPTKEY)IGNORED_PTR_ARG))
        .IgnoreArgument_hObject();
    STRICT_EXPECTED_CALL(NCryptFreeObject((HCRYPTKEY)IGNORED_PTR_ARG))
        .IgnoreArgument_hObject();

    STRICT_EXPECTED_CALL(CertSetCertificateContextProperty(IGNORED_PTR_ARG, CERT_KEY_PROV_INFO_PROP_ID, 0, IGNORED_PTR_ARG)); /*give the private key*/
    STRICT_EXPECTED_CALL(gballoc_free(IGNORED_PTR_ARG));
    STRICT_EXPECTED_CALL(gballoc_free(IGNORED_PTR_ARG));
    STRICT_EXPECTED_CALL(gballoc_free(IGNORED_PTR_ARG));
    STRICT_EXPECTED_CALL(gballoc_free(IGNORED_PTR_ARG));
}
		LRESULT OnUnhandled(const Context& context)
		{
			if (context.message == WM_USER+1)
			{
				auto consumer = scenario->monitor.getconsumer();
				auto readers = consumer.pop();
				for (auto& reader : readers)
				{
					if (reader.card.valid())
					{
						auto card = reader.card.get();
						for (auto& key : card.certificates)
						{
							unique_winerror winerror;

							PCCERT_CONTEXT certcontext = CertCreateCertificateContext(
								X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
								&key.cert[0],
								key.cert.size()
							);
							winerror = make_winerror_if(!certcontext);

							if (!winerror)
							{

								continue;
							}

							DWORD sizesubject = 0;
							std::wstring subjectname;
							for (bool getsize = true; ; getsize = false)
							{
								sizesubject = CertGetNameString(
									certcontext,
									CERT_ALT_NAME_RFC822_NAME,//CERT_NAME_FRIENDLY_DISPLAY_TYPE,
									0,
									NULL,
									getsize ? nullptr : &subjectname[0],
									sizesubject
								);
								if (sizesubject == 1)
								{
									break;
								}
								if (getsize)
								{
									subjectname.resize(sizesubject - 1);
								}
								else
								{
									break;
								}
							}
						}
					}
				}
				return 0;
			}
			return DefWindowProc(context.window, context.message, context.wParam, context.lParam);
		}
Example #4
0
/**
 * Reads a certificate from a file, returning a context or a the handle to a
 * temporary memory store.
 *
 * @returns true on success, false on failure (error message written).
 * @param   pszCertFile         The name of the file containing the
 *                              certificates.
 * @param   ppOutCtx            Where to return the certificate context.
 * @param   phSrcStore          Where to return the handle to the temporary
 *                              memory store.
 */
static bool readCertFile(const char *pszCertFile, PCCERT_CONTEXT *ppOutCtx, HCERTSTORE *phSrcStore)
{
    *ppOutCtx   = NULL;
    *phSrcStore = NULL;

    bool    fRc = false;
    void   *pvFile;
    size_t  cbFile;
    int rc = RTFileReadAll(pszCertFile, &pvFile, &cbFile);
    if (RT_SUCCESS(rc))
    {
        *ppOutCtx = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                                                 (PBYTE)pvFile, (DWORD)cbFile);
        if (*ppOutCtx)
            fRc = true;
        else
        {
            /** @todo figure out if it's some other format... */
            RTMsgError("CertCreateCertificateContext returned %s parsing the content of '%s'",
                       errorToString(GetLastError()), pszCertFile);
        }
    }
    else
        RTMsgError("RTFileReadAll failed on '%s': %Rrc", pszCertFile, rc);
    RTFileReadAllFree(pvFile, cbFile);
    return fRc;
}
Example #5
0
DWORD WinVerifySslCert(const QByteArray& cert) {
	DWORD errorStatus = -1;

	PCCERT_CONTEXT certContext = CertCreateCertificateContext(X509_ASN_ENCODING, reinterpret_cast<const BYTE*>(cert.constData()), cert.size());
	if (!certContext) {
		return errorStatus;
	}

	LPSTR usage[] = {
		szOID_PKIX_KP_SERVER_AUTH,
		szOID_SERVER_GATED_CRYPTO,
		szOID_SGC_NETSCAPE
	};

	CERT_CHAIN_PARA chainParameter;
	memset(&chainParameter, 0, sizeof(CERT_CHAIN_PARA));
	chainParameter.cbSize = sizeof(CERT_CHAIN_PARA);
	chainParameter.RequestedUsage.dwType = USAGE_MATCH_TYPE_OR;
	chainParameter.RequestedUsage.Usage.cUsageIdentifier = ARRAYSIZE(usage);
	chainParameter.RequestedUsage.Usage.rgpszUsageIdentifier = usage;

	PCCERT_CHAIN_CONTEXT chainContext = NULL;
	CertGetCertificateChain(NULL, certContext, NULL, NULL, &chainParameter, 0, NULL, &chainContext);

	if (chainContext) {
		errorStatus = chainContext->TrustStatus.dwErrorStatus;
		CertFreeCertificateChain(chainContext);
	}

	CertFreeCertificateContext(certContext);

	return errorStatus;
}
Example #6
0
/**
 * xmlSecMSCryptoAppKeyCertLoadMemory:
 * @key:		the pointer to key.
 * @data:		the binary certificate.
 * @dataSize:           size of certificate binary (data)
 * @format:		the certificate file format.
 *
 * Reads the certificate from $@data and adds it to key.
 * 
 * Returns 0 on success or a negative value otherwise.
 */
int		
xmlSecMSCryptoAppKeyCertLoadMemory(xmlSecKeyPtr key, const xmlSecByte* data, xmlSecSize dataSize, 
				   xmlSecKeyDataFormat format) {
    PCCERT_CONTEXT pCert;
    xmlSecKeyDataPtr kdata;
    int ret;
        
    xmlSecAssert2(key != NULL, -1);
    xmlSecAssert2(data != NULL, -1);
    xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, -1);

    kdata = xmlSecKeyEnsureData(key, xmlSecMSCryptoKeyDataX509Id);
    if(kdata == NULL) {
	xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE,
		    NULL,
	    	    "xmlSecKeyEnsureData",		    
		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
		    "transform=%s",
		    xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecMSCryptoKeyDataX509Id)));
	return(-1);
    }

    /* For now only DER certificates are supported */
    /* adjust cert format */
    switch(format) {
    case xmlSecKeyDataFormatDer:
    case xmlSecKeyDataFormatCertDer:
        pCert = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, data, dataSize);
        if (NULL == pCert) {
            xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE,
                        NULL,
                        "CertCreateCertificateContext", 
                        XMLSEC_ERRORS_R_XMLSEC_FAILED,
                        "format=%d", format);
            return(-1);    
        }    	

        ret = xmlSecMSCryptoKeyDataX509AdoptCert(kdata, pCert);
        if(ret < 0) {
            xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE,
                        NULL,
                        "xmlSecMSCryptoKeyDataX509AdoptCert",
                        XMLSEC_ERRORS_R_XMLSEC_FAILED,
                        "data=%s",
                        xmlSecErrorsSafeString(xmlSecKeyDataGetName(kdata)));
            CertFreeCertificateContext(pCert);
            return(-1);    
        }
	break;
    default:
	xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE,
		    NULL,
		    NULL,
		    XMLSEC_ERRORS_R_INVALID_FORMAT,
		    "format=%d", (int)format);
	return(-1);
    }
    
    return(0);        
}
Example #7
0
File: net.c Project: mikekap/wine
static PCCERT_CONTEXT X509_to_cert_context(X509 *cert)
{
    unsigned char *buffer, *p;
    int len;
    BOOL malloc = FALSE;
    PCCERT_CONTEXT ret;

    p = NULL;
    if ((len = pi2d_X509( cert, &p )) < 0) return NULL;
    /*
     * SSL 0.9.7 and above malloc the buffer if it is null.
     * however earlier version do not and so we would need to alloc the buffer.
     *
     * see the i2d_X509 man page for more details.
     */
    if (!p)
    {
        if (!(buffer = heap_alloc( len ))) return NULL;
        p = buffer;
        len = pi2d_X509( cert, &p );
    }
    else
    {
        buffer = p;
        malloc = TRUE;
    }

    ret = CertCreateCertificateContext( X509_ASN_ENCODING, buffer, len );

    if (malloc) free( buffer );
    else heap_free( buffer );

    return ret;
}
Example #8
0
File: str.c Project: bilboed/wine
static void test_CertNameToStrA(void)
{
    PCCERT_CONTEXT context;

    if (!pCertNameToStrA)
    {
        win_skip("CertNameToStrA is not available\n");
        return;
    }

    context = CertCreateCertificateContext(X509_ASN_ENCODING, cert,
     sizeof(cert));
    ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
     GetLastError());
    if (context)
    {
        DWORD ret;

        /* This crashes
        ret = pCertNameToStrA(0, NULL, 0, NULL, 0);
         */
        /* Test with a bogus encoding type */
        SetLastError(0xdeadbeef);
        ret = pCertNameToStrA(0, &context->pCertInfo->Issuer, 0, NULL, 0);
        ok(ret == 1 && GetLastError() == ERROR_FILE_NOT_FOUND,
         "Expected retval 1 and ERROR_FILE_NOT_FOUND, got %d - %08x\n",
         ret, GetLastError());
        SetLastError(0xdeadbeef);
        ret = pCertNameToStrA(X509_ASN_ENCODING, &context->pCertInfo->Issuer,
         0, NULL, 0);
        ok(ret && GetLastError() == ERROR_SUCCESS,
         "Expected positive return and ERROR_SUCCESS, got %d - %08x\n",
         ret, GetLastError());

        test_NameToStrConversionA(&context->pCertInfo->Issuer,
         CERT_SIMPLE_NAME_STR, issuerStr);
        test_NameToStrConversionA(&context->pCertInfo->Issuer,
         CERT_SIMPLE_NAME_STR | CERT_NAME_STR_SEMICOLON_FLAG,
         issuerStrSemicolon);
        test_NameToStrConversionA(&context->pCertInfo->Issuer,
         CERT_SIMPLE_NAME_STR | CERT_NAME_STR_CRLF_FLAG,
         issuerStrCRLF);
        test_NameToStrConversionA(&context->pCertInfo->Subject,
         CERT_OID_NAME_STR, subjectStr);
        test_NameToStrConversionA(&context->pCertInfo->Subject,
         CERT_OID_NAME_STR | CERT_NAME_STR_SEMICOLON_FLAG,
         subjectStrSemicolon);
        test_NameToStrConversionA(&context->pCertInfo->Subject,
         CERT_OID_NAME_STR | CERT_NAME_STR_CRLF_FLAG,
         subjectStrCRLF);
        test_NameToStrConversionA(&context->pCertInfo->Subject,
         CERT_X500_NAME_STR, x500SubjectStr);
        test_NameToStrConversionA(&context->pCertInfo->Subject,
         CERT_X500_NAME_STR | CERT_NAME_STR_SEMICOLON_FLAG | CERT_NAME_STR_REVERSE_FLAG, x500SubjectStrSemicolonReverse);

        CertFreeCertificateContext(context);
    }
}
Example #9
0
/**
 * Reads a certificate from a (const char []) buffer, returning a context
 * or a the handle to a temporary memory store.
 *
 * @returns true on success, false on failure (error message written).
 * @param   kpCertBuf           The pointer to the buffer containing the
 *                              certificates.
 * @param   cbCertBuf           Size of @param kpCertBuf in bytes.
 * @param   ppOutCtx            Where to return the handle to the temporary
 *                              memory store.
 */
static bool readCertBuf(const unsigned char kpCertBuf[], DWORD cbCertBuf, PCCERT_CONTEXT *ppOutCtx)
{
    *ppOutCtx = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                                             (PBYTE)kpCertBuf, cbCertBuf);
    if (*ppOutCtx)
        return true;

    return false;
}
Example #10
0
int KSI_PKICertificate_new(KSI_CTX *ctx, const void *der, size_t der_len, KSI_PKICertificate **cert) {
	int res = KSI_UNKNOWN_ERROR;
	PCCERT_CONTEXT x509 = NULL;
	KSI_PKICertificate *tmp = NULL;
	char buf[1024];

	KSI_ERR_clearErrors(ctx);
	if (ctx == NULL || der == NULL || der_len == 0 || cert == NULL){
		res = KSI_INVALID_ARGUMENT;
		goto cleanup;
	}

	if (der_len > UINT_MAX) {
		KSI_pushError(ctx, res = KSI_INVALID_ARGUMENT, "Length is more than MAX_INT.");
		goto cleanup;
	}

	x509 = CertCreateCertificateContext(X509_ASN_ENCODING, der, (unsigned)der_len);
	if (x509 == NULL) {
		DWORD error = GetLastError();
		const char *errmsg = getMSError(GetLastError(), buf, sizeof(buf));
		KSI_LOG_debug(ctx, "%s", errmsg);

		if (error == CRYPT_E_ASN1_EOD)
			KSI_pushError(ctx, res = KSI_INVALID_FORMAT, "Invalid PKI certificate. ASN.1 unexpected end of data.");
		else if (error == CRYPT_E_ASN1_MEMORY	)
			KSI_pushError(ctx, res = KSI_OUT_OF_MEMORY, NULL);
		else
			KSI_pushError(ctx, res = KSI_INVALID_FORMAT, errmsg);

		goto cleanup;
	}

	tmp = KSI_new(KSI_PKICertificate);
	if (tmp == NULL) {
		KSI_pushError(ctx, res = KSI_OUT_OF_MEMORY, NULL);
		goto cleanup;
	}

	tmp->ctx = ctx;
	tmp->x509 = x509;
	x509 = NULL;

	*cert = tmp;
	tmp = NULL;

	res = KSI_OK;


cleanup:

	if (x509 != NULL) CertFreeCertificateContext(x509);
	KSI_PKICertificate_free(tmp);

	return res;
}
void printCertificates(lib::rng::range<Certificate> certificates)
{
	for (auto& key : certificates)
	{
		unique_winerror winerror;

		PCCERT_CONTEXT certcontext = CertCreateCertificateContext(
			X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
			&key.cert[0],
			key.cert.size()
		);
		winerror = make_winerror_if(!certcontext);

		if (!winerror)
		{
			std::wcout << L"could not get cert context" << std::endl; 
			continue;
		}

		DWORD sizesubject = 0;
		std::wstring subjectname;
		for (bool getsize = true; ; getsize = false)
		{
			sizesubject = CertGetNameString(
				certcontext,
				CERT_NAME_FRIENDLY_DISPLAY_TYPE,
				0,
				NULL,
				getsize ? nullptr : &subjectname[0],
				sizesubject
			);
			if (sizesubject == 1)
			{
				std::wcout << L"could not get subject name" << std::endl; 
				break;
			}
			if (getsize)
			{
				subjectname.resize(sizesubject - 1);
			}
			else
			{
				std::wcout << L"key name: " << key.key.c_str() << L" subject name: " << subjectname.c_str() << std::endl; 
				break;
			}
		}
	}
}
Example #12
0
LPCVOID NETCON_GetCert(WININET_NETCONNECTION *connection)
{
#ifdef SONAME_LIBSSL
    X509* cert;
    unsigned char* buffer,*p;
    INT len;
    BOOL malloced = FALSE;
    LPCVOID r = NULL;

    if (!connection->useSSL)
        return NULL;

    cert = pSSL_get_peer_certificate(connection->ssl_s);
    p = NULL;
    len = pi2d_X509(cert,&p);
    /*
     * SSL 0.9.7 and above malloc the buffer if it is null. 
     * however earlier version do not and so we would need to alloc the buffer.
     *
     * see the i2d_X509 man page for more details.
     */
    if (!p)
    {
        buffer = HeapAlloc(GetProcessHeap(),0,len);
        p = buffer;
        len = pi2d_X509(cert,&p);
    }
    else
    {
        buffer = p;
        malloced = TRUE;
    }

    r = CertCreateCertificateContext(X509_ASN_ENCODING,buffer,len);

    if (malloced)
        free(buffer);
    else
        HeapFree(GetProcessHeap(),0,buffer);

    return r;
#else
    return NULL;
#endif
}
Example #13
0
/* Helper to create CryptoAPI CERT_CONTEXT from base64 encoded BASE64_CERT.
 * Returns NULL on error.
 */
static PCCERT_CONTEXT
certcontext_from_base64(const char *base64_cert, apr_pool_t *pool)
{
  PCCERT_CONTEXT cert_context = NULL;
  int cert_len;
  BYTE *binary_cert;

  /* Use apr-util as CryptStringToBinaryA is available only on XP+. */
  binary_cert = apr_palloc(pool,
                           apr_base64_decode_len(base64_cert));
  cert_len = apr_base64_decode((char*)binary_cert, base64_cert);

  /* Parse the certificate into a context. */
  cert_context = CertCreateCertificateContext
    (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, binary_cert, cert_len);

  return cert_context;
}
/*
  Create a certification context from ca or cert file

  SYNOPSIS
    ma_schannel_create_cert_context()
    pvio                    pvio object
    pem_file               name of certificate or ca file

  DESCRIPTION
    Loads a PEM file (certificate authority or certificate) creates a certification
    context and loads the binary representation into context.
    The returned context must be freed by caller.
    If the function failed, error can be retrieved by GetLastError().

  RETURNS
    NULL                   If loading of the file or creating context failed
    CERT_CONTEXT *         A pointer to a certification context structure
*/
CERT_CONTEXT *ma_schannel_create_cert_context(MARIADB_PVIO *pvio, const char *pem_file)
{
  DWORD der_buffer_length;
  LPBYTE der_buffer= NULL;

  CERT_CONTEXT *ctx= NULL;

  /* create DER binary object from ca/certification file */
  if (!(der_buffer= ma_schannel_load_pem(pvio, pem_file, (DWORD *)&der_buffer_length)))
    goto end;
  if (!(ctx= (CERT_CONTEXT *)CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                                    der_buffer, der_buffer_length)))
    ma_schannel_set_win_error(pvio);

end:
  if (der_buffer)
    LocalFree(der_buffer);
  return ctx;
}
Example #15
0
BOOL Csp::CPExportKey(
		IN  HCRYPTPROV hProv,
		IN  HCRYPTKEY hKey,
		IN  HCRYPTKEY hPubKey,
		IN  DWORD dwBlobType,
		IN  DWORD dwFlags,
		OUT LPBYTE pbData,
		IN OUT LPDWORD pcbDataLen){
	DECL_RET(ret);
	try {
		CSPContext * it = *findContext(hProv);
		CSPKeyContext * key =  *it->findKeyContext(hKey);

		switch (dwBlobType) {
			case PUBLICKEYBLOB: {
				if (hPubKey) throw err_badKey();
				packData dat(pbData,pcbDataLen);
				struct {
					PUBLICKEYSTRUC  pubkeyStruc;
					RSAPUBKEY		rsaKey;
					BYTE			modulus[2048 / 8];
				} RSABlob;
				PCCERT_CONTEXT ctx = CertCreateCertificateContext(X509_ASN_ENCODING,
					&key->m_certificateBlob[0],(DWORD)key->m_certificateBlob.size());
				PCRYPT_BIT_BLOB pubKey = &ctx->pCertInfo->SubjectPublicKeyInfo.PublicKey;
				DWORD actSize = sizeof(RSABlob);
				err_crypto::check(CryptDecodeObject(X509_ASN_ENCODING,
					RSA_CSP_PUBLICKEYBLOB,pubKey->pbData,pubKey->cbData,
					0, &RSABlob, &actSize));
				dat.setValue(RSABlob);
				//key->m_certificateBlo
				ret.SetOk();
				break;
				}
			default:
				throw std::runtime_error("not implemented");
			}
	} catch(std::runtime_error &err) {
		ret.logReturn(err);
	}
	return ret;
}
Example #16
0
const void *netconn_get_certificate( netconn_t *conn )
{
#ifdef SONAME_LIBSSL
    X509 *cert;
    unsigned char *buffer, *p;
    int len;
    BOOL malloc = FALSE;
    const CERT_CONTEXT *ret;

    if (!conn->secure) return NULL;

    if (!(cert = pSSL_get_peer_certificate( conn->ssl_conn ))) return NULL;
    p = NULL;
    if ((len = pi2d_X509( cert, &p )) < 0) return NULL;
    /*
     * SSL 0.9.7 and above malloc the buffer if it is null.
     * however earlier version do not and so we would need to alloc the buffer.
     *
     * see the i2d_X509 man page for more details.
     */
    if (!p)
    {
        if (!(buffer = heap_alloc( len ))) return NULL;
        p = buffer;
        len = pi2d_X509( cert, &p );
    }
    else
    {
        buffer = p;
        malloc = TRUE;
    }

    ret = CertCreateCertificateContext( X509_ASN_ENCODING, buffer, len );

    if (malloc) free( buffer );
    else heap_free( buffer );

    return ret;
#else
    return NULL;
#endif
}
Example #17
0
SECURITY_STATUS schan_imp_get_session_peer_certificate(schan_imp_session session,
                                                       PCCERT_CONTEXT *cert)
{
    gnutls_session_t s = (gnutls_session_t)session;
    unsigned int list_size;
    const gnutls_datum_t *datum;

    datum = pgnutls_certificate_get_peers(s, &list_size);
    if (datum)
    {
        *cert = CertCreateCertificateContext(X509_ASN_ENCODING, datum->data,
                                             datum->size);
        if (!*cert)
            return GetLastError();
        else
            return SEC_E_OK;
    }
    else
        return SEC_E_INTERNAL_ERROR;
}
Example #18
0
struct crypto_public_key * crypto_public_key_from_cert(const u8 *buf,
						       size_t len)
{
	struct crypto_public_key *pk;
	PCCERT_CONTEXT cc;

	pk = os_zalloc(sizeof(*pk));
	if (pk == NULL)
		return NULL;

	cc = CertCreateCertificateContext(X509_ASN_ENCODING |
					  PKCS_7_ASN_ENCODING, buf, len);
	if (!cc) {
 		cryptoapi_report_error("CryptCreateCertificateContext");
		os_free(pk);
		return NULL;
	}

	if (!CryptAcquireContext(&pk->prov, NULL, MS_DEF_PROV, PROV_RSA_FULL,
				 0)) {
 		cryptoapi_report_error("CryptAcquireContext");
		os_free(pk);
		CertFreeCertificateContext(cc);
		return NULL;
	}

	if (!CryptImportPublicKeyInfo(pk->prov, X509_ASN_ENCODING |
				      PKCS_7_ASN_ENCODING,
				      &cc->pCertInfo->SubjectPublicKeyInfo,
				      &pk->rsa)) {
 		cryptoapi_report_error("CryptImportPublicKeyInfo");
		CryptReleaseContext(pk->prov, 0);
		os_free(pk);
		CertFreeCertificateContext(cc);
		return NULL;
	}

	CertFreeCertificateContext(cc);

	return pk;
}
static void setup_x509_schannel_create_mocks(void)
{
    STRICT_EXPECTED_CALL(gballoc_malloc(IGNORED_NUM_ARG)); /*this is creating the handle storage space*/
    STRICT_EXPECTED_CALL(CryptStringToBinaryA("certificate", 0, CRYPT_STRING_ANY, NULL, IGNORED_PTR_ARG, NULL, NULL)); /*this is asking for "how big is the certificate binary size?"*/
    STRICT_EXPECTED_CALL(gballoc_malloc(IGNORED_NUM_ARG)); /*this is creating the binary storage for the certificate*/
    STRICT_EXPECTED_CALL(CryptStringToBinaryA("certificate", 0, CRYPT_STRING_ANY, IGNORED_PTR_ARG, IGNORED_PTR_ARG, NULL, NULL)); /*this is asking for "fill in the certificate in this binary buffer"*/
    STRICT_EXPECTED_CALL(CryptStringToBinaryA("private key", 0, CRYPT_STRING_ANY, NULL, IGNORED_PTR_ARG, NULL, NULL)); /*this is asking for "how big is the private key binary size?"*/
    STRICT_EXPECTED_CALL(gballoc_malloc(IGNORED_NUM_ARG)); /*this is creating the binary storage for the private key*/
    STRICT_EXPECTED_CALL(CryptStringToBinaryA("private key", 0, CRYPT_STRING_ANY, IGNORED_PTR_ARG, IGNORED_PTR_ARG, NULL, NULL)); /*this is asking for "fill in the private key in this binary buffer"*/
    STRICT_EXPECTED_CALL(CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, PKCS_RSA_PRIVATE_KEY, IGNORED_PTR_ARG, IGNORED_NUM_ARG, 0, NULL, NULL, IGNORED_PTR_ARG)); /*this is asking "how big is the decoded private key? (from binary)*/
    STRICT_EXPECTED_CALL(gballoc_malloc(IGNORED_NUM_ARG)); /*this is allocating space for the decoded private key*/
    STRICT_EXPECTED_CALL(CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, PKCS_RSA_PRIVATE_KEY, IGNORED_PTR_ARG, IGNORED_NUM_ARG, 0, NULL, IGNORED_PTR_ARG, IGNORED_PTR_ARG)); /*this is asking "how big is the decoded private key? (from binary)*/
    STRICT_EXPECTED_CALL(CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, IGNORED_PTR_ARG, IGNORED_NUM_ARG)); /*create a certificate context from an encoded certificate*/
    STRICT_EXPECTED_CALL(CryptAcquireContextA(IGNORED_PTR_ARG, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)); /*this is acquire a handle to a key container within a cryptographic service provider*/
    STRICT_EXPECTED_CALL(CryptImportKey((HCRYPTPROV)IGNORED_PTR_ARG, IGNORED_PTR_ARG, IGNORED_NUM_ARG, (HCRYPTKEY)NULL, 0, IGNORED_PTR_ARG)) /*tranferring the key from the blob to the cryptrographic key provider*/
        .IgnoreArgument_hProv();
    STRICT_EXPECTED_CALL(CertSetCertificateContextProperty(IGNORED_PTR_ARG, CERT_KEY_PROV_HANDLE_PROP_ID, 0, IGNORED_PTR_ARG)); /*give the private key*/
    STRICT_EXPECTED_CALL(gballoc_free(IGNORED_PTR_ARG));
    STRICT_EXPECTED_CALL(gballoc_free(IGNORED_PTR_ARG));
    STRICT_EXPECTED_CALL(gballoc_free(IGNORED_PTR_ARG));
}
Example #20
0
SECURITY_STATUS schan_imp_get_session_peer_certificate(schan_imp_session session,
                                                       PCCERT_CONTEXT *cert)
{
    struct mac_session* s = (struct mac_session*)session;
    SECURITY_STATUS ret = SEC_E_INTERNAL_ERROR;
    CFArrayRef certs;
    OSStatus status;

    TRACE("(%p/%p, %p)\n", s, s->context, cert);

    status = SSLCopyPeerCertificates(s->context, &certs);
    if (status == noErr && certs)
    {
        SecCertificateRef mac_cert;
        CFDataRef data;
        if (CFArrayGetCount(certs) &&
            (mac_cert = (SecCertificateRef)CFArrayGetValueAtIndex(certs, 0)) &&
            (SecKeychainItemExport(mac_cert, kSecFormatX509Cert, 0, NULL, &data) == noErr))
        {
            *cert = CertCreateCertificateContext(X509_ASN_ENCODING,
                    CFDataGetBytePtr(data), CFDataGetLength(data));
            if (*cert)
                ret = SEC_E_OK;
            else
            {
                ret = GetLastError();
                WARN("CertCreateCertificateContext failed: %x\n", ret);
            }
            CFRelease(data);
        }
        else
            WARN("Couldn't extract certificate data\n");
        CFRelease(certs);
    }
    else
        WARN("SSLCopyPeerCertificates failed: %ld\n", (long)status);

    return ret;
}
Example #21
0
DWORD ImportCertificate(CK_BYTE* certData, DWORD certSize, CK_BYTE* cardSerialNumber, CK_ULONG cardSerialNumberLen)
{
	PCCERT_CONTEXT		pCertContext = NULL;
	DWORD				dwRet = 0;
	// ------------------------------------------------------------
	// create the certificate context with the certificate raw data
	// ------------------------------------------------------------
	pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, certData,certSize);

	if( pCertContext == NULL )
	{
		dwRet = GetLastError();
		if (dwRet == E_INVALIDARG)
			printf("ImportCertificates: Unable to create certificate context. The certificate encoding type is not supported.Error code: %d.\n",dwRet);
		else
			printf("ImportCertificates: Unable to create certificate context. Error code: %d.\n",dwRet);
	}
	else
	{
		unsigned char KeyUsageBits = 0; // Intended key usage bits copied to here.
		CertGetIntendedKeyUsage(X509_ASN_ENCODING, pCertContext->pCertInfo, &KeyUsageBits, 1);
		// ----------------------------------------------------------------------
		// Only store the context of the certificates with usages for an end-user
		// i.e. no CA or root certificates
		// ----------------------------------------------------------------------
		if((KeyUsageBits & CERT_KEY_CERT_SIGN_KEY_USAGE) == CERT_KEY_CERT_SIGN_KEY_USAGE)
		{
			dwRet = StoreAuthorityCert (pCertContext, KeyUsageBits);
		}
		else
		{
			dwRet = StoreUserCert (pCertContext, KeyUsageBits, cardSerialNumber, cardSerialNumberLen);
		}
		if (pCertContext)
			CertFreeCertificateContext(pCertContext);
	}
	return dwRet;
}
Example #22
0
/***********************************************************************
 *           ShowX509EncodedCertificate (@)
 */
DWORD WINAPI ShowX509EncodedCertificate(HWND parent, LPBYTE cert, DWORD len)
{
    PCCERT_CONTEXT certContext = CertCreateCertificateContext(X509_ASN_ENCODING,
        cert, len);
    DWORD ret;

    if (certContext)
    {
        CRYPTUI_VIEWCERTIFICATE_STRUCTW view;

        memset(&view, 0, sizeof(view));
        view.hwndParent = parent;
        view.pCertContext = certContext;
        if (CryptUIDlgViewCertificateW(&view, NULL))
            ret = ERROR_SUCCESS;
        else
            ret = GetLastError();
        CertFreeCertificateContext(certContext);
    }
    else
        ret = GetLastError();
    return ret;
}
   bool CertificateVerifier::operator() (bool preverified, boost::asio::ssl::verify_context& ctx) const
   {
      // We're only interested in checking the certificate at the end of the chain.
      int depth = X509_STORE_CTX_get_error_depth(ctx.native_handle());
      if (depth > 0)
         return OverrideResult_(true);

      // Read the cert and convert it to a raw DER-format which we can hand off to Windows.
      X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle());
      BIO* bio = BIO_new(BIO_s_mem());

      // Convert the certificate from the internal structure to a DER structure in memory ('bio').
      if (i2d_X509_bio(bio,cert) != 1) 
      {
         ErrorManager::Instance()->ReportError(ErrorManager::Medium, 5512, "CertificateVerifier::operator()", "Failed to convert OpenSSL internal X509 to DER-format.");
         BIO_free(bio);
         return OverrideResult_(false);
      }

      // Read the cert from the BIO structure in memory to a char array.
      int raw_size = BIO_pending(bio);
      unsigned char *raw_certificate = new unsigned char[raw_size];

      int actual_read = BIO_read(bio, raw_certificate, raw_size);

      if (raw_size != actual_read) 
      {
         String errorMessage = Formatter::Format(_T("BIO_read returned an unexpected number of characters. Expected: {0}, Returned: {1}"), raw_size, actual_read);
         ErrorManager::Instance()->ReportError(ErrorManager::Medium, 5513, "CertificateVerifier::operator()", errorMessage);
         BIO_free(bio);
         delete[] raw_certificate;
         return OverrideResult_(false);
      }
      
      // Create a Windows certificate context, using the raw DER data.
      PCCERT_CONTEXT context = CertCreateCertificateContext(X509_ASN_ENCODING, (BYTE*) raw_certificate, raw_size);

      if (context == NULL) 
      {
         String errorMessage = Formatter::Format(_T("Call to CertCreateCertificateContext failed. Error: {0}"), (int) GetLastError());
         ErrorManager::Instance()->ReportError(ErrorManager::Medium, 5513, "CertificateVerifier::operator()", errorMessage);
         BIO_free(bio);
         delete[] raw_certificate;
         return OverrideResult_(false);
      }

      String expected_host_name = host_name_;

      int windows_error_code = 0;
      if (VerifyCertificate_(context, expected_host_name.GetBuffer(-1), windows_error_code))
      {
         LOG_DEBUG(Formatter::Format("Certificate verification succeeded for session {0}.", session_id_));
         
         BIO_free(bio);
         delete[] raw_certificate;
         CertFreeCertificateContext(context);

         return OverrideResult_(true);
      }
      else
      {
         String windows_error_text = ErrorManager::Instance()->GetWindowsErrorText(windows_error_code);
         String formattedDebugMessage = Formatter::Format("Certificate verification failed for session {0}. Expected host: {1}, Windows error code: {2}, Windows error message: {3}", 
            session_id_, host_name_, windows_error_code, windows_error_text);

         LOG_DEBUG(formattedDebugMessage);

         BIO_free(bio);
         delete[] raw_certificate;
         CertFreeCertificateContext(context);

         return OverrideResult_(false);
      }

   }
Example #24
0
	PCCERT_CONTEXT certContext( const QSslCertificate &cert ) const
	{
		QByteArray data = cert.toDer();
		return CertCreateCertificateContext( X509_ASN_ENCODING,
			(const PBYTE)data.constData(), data.size() );
	}
Example #25
0
static void test_verifyRevocation(void)
{
    HMODULE hCryptNet = GetModuleHandleA("cryptnet.dll");
    BOOL ret;
    CERT_REVOCATION_STATUS status = { sizeof(status), 0 };
    PCCERT_CONTEXT certs[2];
    CERT_REVOCATION_PARA revPara = { sizeof(revPara), 0 };
    FILETIME time;

    pCertVerifyRevocation = (void *)GetProcAddress(hCryptNet,
     "CertDllVerifyRevocation");
    if (!pCertVerifyRevocation)
    {
        win_skip("no CertDllVerifyRevocation\n");
        return;
    }
    if (0)
    {
        /* Crash */
        pCertVerifyRevocation(0, 0, 0, NULL, 0, NULL, NULL);
    }
    SetLastError(0xdeadbeef);
    ret = pCertVerifyRevocation(0, 0, 0, NULL, 0, NULL, &status);
    ok(!ret && GetLastError() == E_INVALIDARG,
     "expected E_INVALIDARG, got %08x\n", GetLastError());
    SetLastError(0xdeadbeef);
    ret = pCertVerifyRevocation(X509_ASN_ENCODING, 0, 0, NULL, 0, NULL,
     &status);
    ok(!ret && GetLastError() == E_INVALIDARG,
     "expected E_INVALIDARG, got %08x\n", GetLastError());
    SetLastError(0xdeadbeef);
    ret = pCertVerifyRevocation(0, CERT_CONTEXT_REVOCATION_TYPE, 0, NULL, 0,
     NULL, &status);
    ok(!ret && GetLastError() == E_INVALIDARG,
     "expected E_INVALIDARG, got %08x\n", GetLastError());
    certs[0] = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
     sizeof(bigCert));
    SetLastError(0xdeadbeef);
    ret = pCertVerifyRevocation(0, CERT_CONTEXT_REVOCATION_TYPE,
     1, (void **)certs, 0, NULL, &status);
    ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_CHECK,
     "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", GetLastError());
    ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK,
     "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", status.dwError);
    ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex);
    CertFreeCertificateContext(certs[0]);
    certs[0] = CertCreateCertificateContext(X509_ASN_ENCODING,
     rootWithKeySignAndCRLSign, sizeof(rootWithKeySignAndCRLSign));
    certs[1] = CertCreateCertificateContext(X509_ASN_ENCODING,
     revokedCert, sizeof(revokedCert));
    /* The root cert itself can't be checked for revocation */
    SetLastError(0xdeadbeef);
    ret = pCertVerifyRevocation(0, CERT_CONTEXT_REVOCATION_TYPE,
     1, (void **)certs, 0, NULL, &status);
    ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_CHECK,
     "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", GetLastError());
    ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK,
     "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", status.dwError);
    ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex);
    /* Neither can the end cert */
    SetLastError(0xdeadbeef);
    ret = pCertVerifyRevocation(0, CERT_CONTEXT_REVOCATION_TYPE,
     1, (void **)&certs[1], 0, NULL, &status);
    ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_CHECK,
     "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", GetLastError());
    ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK,
     "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", status.dwError);
    ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex);
    /* Both certs together can't, either (they're not CRLs) */
    SetLastError(0xdeadbeef);
    ret = pCertVerifyRevocation(0, CERT_CONTEXT_REVOCATION_TYPE,
     2, (void **)certs, 0, NULL, &status);
    ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_CHECK,
     "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", GetLastError());
    ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK,
     "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", status.dwError);
    ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex);
    /* Now add a CRL to the hCrlStore */
    revPara.hCrlStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
     CERT_STORE_CREATE_NEW_FLAG, NULL);
    CertAddEncodedCRLToStore(revPara.hCrlStore, X509_ASN_ENCODING,
     rootSignedCRLWithBadAKI, sizeof(rootSignedCRLWithBadAKI),
     CERT_STORE_ADD_ALWAYS, NULL);
    SetLastError(0xdeadbeef);
    ret = pCertVerifyRevocation(0, CERT_CONTEXT_REVOCATION_TYPE,
     2, (void **)certs, 0, &revPara, &status);
    ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_CHECK,
     "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", GetLastError());
    ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK,
     "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", status.dwError);
    ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex);
    /* Specifying CERT_VERIFY_REV_CHAIN_FLAG doesn't change things either */
    SetLastError(0xdeadbeef);
    ret = pCertVerifyRevocation(0, CERT_CONTEXT_REVOCATION_TYPE,
     2, (void **)certs, CERT_VERIFY_REV_CHAIN_FLAG, &revPara, &status);
    ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_CHECK,
     "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", GetLastError());
    ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK,
     "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", status.dwError);
    ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex);
    /* Again, specifying the issuer cert: no change */
    revPara.pIssuerCert = certs[0];
    SetLastError(0xdeadbeef);
    ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE,
     1, (void **)&certs[1], 0, &revPara, &status);
    /* Win2k thinks the cert is revoked, and it is, except the CRL contains a
     * bad authority key ID extension and can't be matched with the issuer
     * cert, hence the revocation status should be unknown.
     */
    if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
    {
        win_skip("CERT_CONTEXT_REVOCATION_TYPE unsupported, skipping\n");
        return;
    }
    ok(!ret && (GetLastError() == CRYPT_E_NO_REVOCATION_CHECK ||
     broken(GetLastError() == CRYPT_E_REVOKED /* Win2k */)),
     "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", GetLastError());
    ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK ||
     broken(status.dwError == CRYPT_E_REVOKED /* Win2k */),
     "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", status.dwError);
    ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex);
    /* Specifying the time to check: still no change */
    SystemTimeToFileTime(&oct2007, &time);
    revPara.pftTimeToUse = &time;
    ret = pCertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE,
     1, (void **)&certs[1], 0, &revPara, &status);
    ok(!ret, "Expected failure\n");
    ok(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK ||
     broken(GetLastError() == CRYPT_E_REVOKED), /* W2K SP3/SP4 */
     "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", GetLastError());
    ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK ||
     broken(GetLastError() == CRYPT_E_REVOKED), /* W2K SP3/SP4 */
     "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", status.dwError);
    ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex);
    CertCloseStore(revPara.hCrlStore, 0);
    /* Test again with a valid CRL.  This time, the cert should be revoked when
     * the time is after the validity period of the CRL, or considered
     * "revocation offline" when the checked time precedes the validity
     * period of the CRL.
     */
    revPara.hCrlStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
     CERT_STORE_CREATE_NEW_FLAG, NULL);
    ret = CertAddEncodedCRLToStore(revPara.hCrlStore, X509_ASN_ENCODING,
     rootSignedCRL, sizeof(rootSignedCRL), CERT_STORE_ADD_ALWAYS, NULL);
    ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
    revPara.pftTimeToUse = NULL;
    SetLastError(0xdeadbeef);
    ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE,
     1, (void **)&certs[1], 0, &revPara, &status);
    ok(!ret && (GetLastError() == CRYPT_E_REVOKED ||
     broken(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK /* NT4 */)),
     "expected CRYPT_E_REVOKED, got %08x\n", GetLastError());
    revPara.pftTimeToUse = &time;
    SetLastError(0xdeadbeef);
    ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE,
     1, (void **)&certs[1], 0, &revPara, &status);
    ok(!ret && (GetLastError() == CRYPT_E_REVOKED ||
     broken(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK /* NT4 */)),
     "expected CRYPT_E_REVOKED, got %08x\n", GetLastError());
    SystemTimeToFileTime(&may2007, &time);
    SetLastError(0xdeadbeef);
    ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE,
     1, (void **)&certs[1], 0, &revPara, &status);
    ok(!ret && (GetLastError() == CRYPT_E_REVOCATION_OFFLINE ||
     broken(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK /* NT4 */)),
     "expected CRYPT_E_REVOCATION_OFFLINE, got %08x\n", GetLastError());
    CertFreeCertificateContext(certs[1]);
    /* Test again with a valid CRL and an un-revoked cert.  No matter the
     * time checked, it's reported as revocation offline.
     */
    certs[1] = CertCreateCertificateContext(X509_ASN_ENCODING,
     unRevokedCert, sizeof(unRevokedCert));
    ok(certs[1] != NULL, "CertCreateCertificateContext failed: %08x\n",
     GetLastError());
    revPara.pftTimeToUse = NULL;
    SetLastError(0xdeadbeef);
    ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE,
     1, (void **)&certs[1], 0, &revPara, &status);
    ok(!ret && (GetLastError() == CRYPT_E_REVOCATION_OFFLINE ||
     broken(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK /* NT4 */)),
     "expected CRYPT_E_REVOCATION_OFFLINE, got %08x\n", GetLastError());
    revPara.pftTimeToUse = &time;
    SetLastError(0xdeadbeef);
    ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE,
     1, (void **)&certs[1], 0, &revPara, &status);
    ok(!ret && (GetLastError() == CRYPT_E_REVOCATION_OFFLINE ||
     broken(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK /* NT4 */)),
     "expected CRYPT_E_REVOCATION_OFFLINE, got %08x\n", GetLastError());
    SystemTimeToFileTime(&may2007, &time);
    SetLastError(0xdeadbeef);
    ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE,
     1, (void **)&certs[1], 0, &revPara, &status);
    ok(!ret && (GetLastError() == CRYPT_E_REVOCATION_OFFLINE ||
     broken(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK /* NT4 */)),
     "expected CRYPT_E_REVOCATION_OFFLINE, got %08x\n", GetLastError());
    CertCloseStore(revPara.hCrlStore, 0);
    CertFreeCertificateContext(certs[1]);
    CertFreeCertificateContext(certs[0]);
}
Example #26
0
static void testAcquireSecurityContext(void)
{
    BOOL has_schannel = FALSE;
    SecPkgInfoA *package_info;
    ULONG i;
    SECURITY_STATUS st;
    CredHandle cred;
    SecPkgCredentials_NamesA names;
    TimeStamp exp;
    SCHANNEL_CRED schanCred;
    PCCERT_CONTEXT certs[2];
    HCRYPTPROV csp;
    WCHAR ms_def_prov_w[MAX_PATH];
    BOOL ret;
    HCRYPTKEY key;
    CRYPT_KEY_PROV_INFO keyProvInfo;

    if (!pAcquireCredentialsHandleA ||
        !pEnumerateSecurityPackagesA || !pFreeContextBuffer ||
        !pFreeCredentialsHandle)
    {
        win_skip("Needed functions are not available\n");
        return;
    }

    if (SUCCEEDED(pEnumerateSecurityPackagesA(&i, &package_info)))
    {
        while(i--)
        {
            if (!strcmp(package_info[i].Name, unisp_name_a))
            {
                has_schannel = TRUE;
                break;
            }
        }
        pFreeContextBuffer(package_info);
    }
    if (!has_schannel)
    {
        skip("Schannel not available\n");
        return;
    }

    lstrcpyW(ms_def_prov_w, MS_DEF_PROV_W);

    keyProvInfo.pwszContainerName = cspNameW;
    keyProvInfo.pwszProvName = ms_def_prov_w;
    keyProvInfo.dwProvType = PROV_RSA_FULL;
    keyProvInfo.dwFlags = 0;
    keyProvInfo.cProvParam = 0;
    keyProvInfo.rgProvParam = NULL;
    keyProvInfo.dwKeySpec = AT_SIGNATURE;

    certs[0] = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert));
    certs[1] = CertCreateCertificateContext(X509_ASN_ENCODING, selfSignedCert, sizeof(selfSignedCert));

    SetLastError(0xdeadbeef);
    ret = CryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
     CRYPT_DELETEKEYSET);
    if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
    {
        /* WinMe would crash on some tests */
        win_skip("CryptAcquireContextW is not implemented\n");
        return;
    }

    st = pAcquireCredentialsHandleA(NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL,
     NULL);
    ok(st == SEC_E_SECPKG_NOT_FOUND,
     "Expected SEC_E_SECPKG_NOT_FOUND, got %08x\n", st);
    if (0)
    {
        /* Crashes on Win2K */
        st = pAcquireCredentialsHandleA(NULL, unisp_name_a, 0, NULL, NULL, NULL,
         NULL, NULL, NULL);
        ok(st == SEC_E_NO_CREDENTIALS, "Expected SEC_E_NO_CREDENTIALS, got %08x\n", st);

        /* Crashes on WinNT */
        st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_BOTH, NULL,
         NULL, NULL, NULL, NULL, NULL);
        ok(st == SEC_E_NO_CREDENTIALS, "Expected SEC_E_NO_CREDENTIALS, got %08x\n", st);

        st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
         NULL, NULL, NULL, NULL, NULL, NULL);
        ok(st == SEC_E_NO_CREDENTIALS, "Expected SEC_E_NO_CREDENTIALS, got %08x\n", st);

        /* Crashes */
        pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
         NULL, NULL, NULL, NULL, NULL, NULL);
    }
    st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
     NULL, NULL, NULL, NULL, &cred, NULL);
    ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", st);
    if(st == SEC_E_OK)
        pFreeCredentialsHandle(&cred);
    memset(&cred, 0, sizeof(cred));
    st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
     NULL, NULL, NULL, NULL, &cred, &exp);
    ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", st);
    /* expriy is indeterminate in win2k3 */
    trace("expiry: %08x%08x\n", exp.HighPart, exp.LowPart);

    st = pQueryCredentialsAttributesA(&cred, SECPKG_CRED_ATTR_NAMES, &names);
    ok(st == SEC_E_NO_CREDENTIALS || st == SEC_E_UNSUPPORTED_FUNCTION /* before Vista */, "expected SEC_E_NO_CREDENTIALS, got %08x\n", st);

    pFreeCredentialsHandle(&cred);

    /* Bad version in SCHANNEL_CRED */
    memset(&schanCred, 0, sizeof(schanCred));
    st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
     NULL, &schanCred, NULL, NULL, NULL, NULL);
    ok(st == SEC_E_INTERNAL_ERROR ||
       st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */ ||
       st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %08x\n", st);
    st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
     NULL, &schanCred, NULL, NULL, NULL, NULL);
    ok(st == SEC_E_INTERNAL_ERROR ||
       st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */ ||
       st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %08x\n", st);

    /* No cert in SCHANNEL_CRED succeeds for outbound.. */
    schanCred.dwVersion = SCHANNEL_CRED_VERSION;
    st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
     NULL, &schanCred, NULL, NULL, &cred, NULL);
    ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", st);
    pFreeCredentialsHandle(&cred);
    /* but fails for inbound. */
    st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
     NULL, &schanCred, NULL, NULL, &cred, NULL);
    ok(st == SEC_E_NO_CREDENTIALS ||
       st == SEC_E_OK /* Vista/win2k8 */,
       "Expected SEC_E_NO_CREDENTIALS or SEC_E_OK, got %08x\n", st);

    if (0)
    {
        /* Crashes with bad paCred pointer */
        schanCred.cCreds = 1;
        pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
         NULL, &schanCred, NULL, NULL, NULL, NULL);
    }

    /* Bogus cert in SCHANNEL_CRED. Windows fails with
     * SEC_E_UNKNOWN_CREDENTIALS, but I'll accept SEC_E_NO_CREDENTIALS too.
     */
    schanCred.cCreds = 1;
    schanCred.paCred = &certs[0];
    st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
     NULL, &schanCred, NULL, NULL, NULL, NULL);
    ok(st == SEC_E_UNKNOWN_CREDENTIALS ||
       st == SEC_E_NO_CREDENTIALS ||
       st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %08x\n", st);
    st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
     NULL, &schanCred, NULL, NULL, NULL, NULL);
    ok(st == SEC_E_UNKNOWN_CREDENTIALS ||
       st == SEC_E_NO_CREDENTIALS ||
       st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %08x\n", st);

    /* Good cert, but missing private key. Windows fails with
     * SEC_E_NO_CREDENTIALS, but I'll accept SEC_E_UNKNOWN_CREDENTIALS too.
     */
    schanCred.cCreds = 1;
    schanCred.paCred = &certs[1];
    st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
     NULL, &schanCred, NULL, NULL, &cred, NULL);
    ok(st == SEC_E_UNKNOWN_CREDENTIALS || st == SEC_E_NO_CREDENTIALS ||
       st == SEC_E_INTERNAL_ERROR, /* win2k */
     "Expected SEC_E_UNKNOWN_CREDENTIALS, SEC_E_NO_CREDENTIALS "
     "or SEC_E_INTERNAL_ERROR, got %08x\n", st);
    st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
     NULL, &schanCred, NULL, NULL, NULL, NULL);
    ok(st == SEC_E_UNKNOWN_CREDENTIALS || st == SEC_E_NO_CREDENTIALS ||
       st == SEC_E_INTERNAL_ERROR, /* win2k */
     "Expected SEC_E_UNKNOWN_CREDENTIALS, SEC_E_NO_CREDENTIALS "
     "or SEC_E_INTERNAL_ERROR, got %08x\n", st);

    /* Good cert, with CRYPT_KEY_PROV_INFO set before it's had a key loaded. */
    ret = CertSetCertificateContextProperty(certs[1],
          CERT_KEY_PROV_INFO_PROP_ID, 0, &keyProvInfo);
    schanCred.dwVersion = SCH_CRED_V3;
    ok(ret, "CertSetCertificateContextProperty failed: %08x\n", GetLastError());
    st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
        NULL, &schanCred, NULL, NULL, &cred, NULL);
    ok(st == SEC_E_UNKNOWN_CREDENTIALS || st == SEC_E_INTERNAL_ERROR /* WinNT */,
       "Expected SEC_E_UNKNOWN_CREDENTIALS or SEC_E_INTERNAL_ERROR, got %08x\n", st);
    st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
        NULL, &schanCred, NULL, NULL, &cred, NULL);
    ok(st == SEC_E_UNKNOWN_CREDENTIALS || st == SEC_E_INTERNAL_ERROR /* WinNT */,
        "Expected SEC_E_UNKNOWN_CREDENTIALS or SEC_E_INTERNAL_ERROR, got %08x\n", st);

    ret = CryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
     CRYPT_NEWKEYSET);
    ok(ret, "CryptAcquireContextW failed: %08x\n", GetLastError());
    ret = 0;

    ret = CryptImportKey(csp, privKey, sizeof(privKey), 0, 0, &key);
    ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
    if (ret)
    {
        PCCERT_CONTEXT tmp;

        if (0)
        {
            /* Crashes */
            pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
             NULL, &schanCred, NULL, NULL, NULL, NULL);

            /* Crashes on WinNT */
            /* Good cert with private key, bogus version */
            schanCred.dwVersion = SCH_CRED_V1;
            st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
                NULL, &schanCred, NULL, NULL, &cred, NULL);
            ok(st == SEC_E_INTERNAL_ERROR ||
                st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */,
                "Expected SEC_E_INTERNAL_ERROR or SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
            st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
                NULL, &schanCred, NULL, NULL, &cred, NULL);
            ok(st == SEC_E_INTERNAL_ERROR ||
                st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */,
                "Expected SEC_E_INTERNAL_ERROR or SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
            schanCred.dwVersion = SCH_CRED_V2;
            st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
                NULL, &schanCred, NULL, NULL, &cred, NULL);
            ok(st == SEC_E_INTERNAL_ERROR ||
                st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */,
                "Expected SEC_E_INTERNAL_ERROR or SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
            st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
                NULL, &schanCred, NULL, NULL, &cred, NULL);
            ok(st == SEC_E_INTERNAL_ERROR ||
                st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */,
                "Expected SEC_E_INTERNAL_ERROR or SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
        }

        /* Succeeds on V3 or higher */
        schanCred.dwVersion = SCH_CRED_V3;
        st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
         NULL, &schanCred, NULL, NULL, &cred, NULL);
        ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", st);
        pFreeCredentialsHandle(&cred);
        st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
         NULL, &schanCred, NULL, NULL, &cred, NULL);
        ok(st == SEC_E_OK ||
           st == SEC_E_UNKNOWN_CREDENTIALS, /* win2k3 */
           "AcquireCredentialsHandleA failed: %08x\n", st);
        pFreeCredentialsHandle(&cred);
        schanCred.dwVersion = SCHANNEL_CRED_VERSION;
        st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
         NULL, &schanCred, NULL, NULL, &cred, NULL);
        ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", st);
        pFreeCredentialsHandle(&cred);
        st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
         NULL, &schanCred, NULL, NULL, &cred, NULL);
        ok(st == SEC_E_OK ||
           st == SEC_E_UNKNOWN_CREDENTIALS, /* win2k3 */
           "AcquireCredentialsHandleA failed: %08x\n", st);
        if (st == SEC_E_OK) test_strength(&cred);
        pFreeCredentialsHandle(&cred);

        /* How about more than one cert? */
        schanCred.cCreds = 2;
        schanCred.paCred = certs;
        st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
         NULL, &schanCred, NULL, NULL, &cred, NULL);
        ok(st == SEC_E_UNKNOWN_CREDENTIALS ||
           st == SEC_E_NO_CREDENTIALS /* Vista/win2k8 */ ||
           st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %08x\n", st);
        st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
         NULL, &schanCred, NULL, NULL, &cred, NULL);
        ok(st == SEC_E_UNKNOWN_CREDENTIALS ||
           st == SEC_E_NO_CREDENTIALS ||
           st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %08x\n", st);
        tmp = certs[0];
        certs[0] = certs[1];
        certs[1] = tmp;
        st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
         NULL, &schanCred, NULL, NULL, &cred, NULL);
        ok(st == SEC_E_UNKNOWN_CREDENTIALS ||
           st == SEC_E_NO_CREDENTIALS ||
           st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %08x\n", st);
        st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
         NULL, &schanCred, NULL, NULL, &cred, NULL);
        ok(st == SEC_E_UNKNOWN_CREDENTIALS,
         "Expected SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
        /* FIXME: what about two valid certs? */

        CryptDestroyKey(key);
    }

    CryptReleaseContext(csp, 0);
    CryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL, CRYPT_DELETEKEYSET);

    CertFreeCertificateContext(certs[0]);
    CertFreeCertificateContext(certs[1]);
}
Example #27
0
PCCERT_CONTEXT DigiCrypt_ReadCertFromCard(void)
{
HCRYPTPROV hCryptProv;
BYTE       *pbData = NULL;   
HCRYPTKEY  hKey;          
DWORD cbData = 0;
DWORD dwKeyType=0;
DWORD dwErrCode=0;
DWORD cspType=0;
DWORD cspFlag=CRYPT_SILENT;
char *psCspName = NULL;
char *psKeyContainer;
BOOL fRes = FALSE;
PCCERT_CONTEXT  pCertContext = NULL; 
CRYPT_KEY_PROV_INFO KeyProvInfo;
LPWSTR wszContainerName=NULL;
LPWSTR wszProvName=NULL;
DWORD cchContainerName;
DWORD cchCSPName;
HCRYPTPROV hProv;


DigiCrypt_ReleaseFirstAllowedCSP();

psCspName=DigiCrypt_GetFirstAllowedCSPNameNew();

//very dummy thing.. i check from csp creators why i should do so...
if(!lstrcmp(psCspName,"EstEID Card CSP"))
   fRes = CryptAcquireContext(&hProv,"XXX",psCspName,2, CRYPT_SILENT);
// end dummy//

if (psCspName == NULL || strstr(psCspName,psData_Est_CSP_Name) == NULL)
  return(pCertContext);

cspType=DigiCrypt_FindContext_GetCSPType(psCspName);

psKeyContainer=DigiCrypt_GetDefaultKeyContainerName(psCspName);

fRes = CryptAcquireContext(&hCryptProv,psKeyContainer,psCspName,cspType, CRYPT_SILENT);
if (fRes == FALSE)
  return(pCertContext);

fRes=CryptGetUserKey(hCryptProv, AT_SIGNATURE, &hKey);
if (fRes == TRUE)
  {
  fRes=CryptGetKeyParam(hKey, KP_CERTIFICATE, NULL, &cbData, 0);
  if (fRes == TRUE)
    {
    pbData = (unsigned char*)malloc(cbData);
    if (pbData == NULL)
      fRes = FALSE;
    }
  if (fRes == TRUE)
    fRes=CryptGetKeyParam(hKey, KP_CERTIFICATE, pbData, &cbData, 0);
  if (fRes == TRUE)
    {
    pCertContext = CertCreateCertificateContext(MY_ENCODING_TYPE,pbData,cbData);
    if (pCertContext != NULL)
      { 
	  wszContainerName=NULL;
	  wszProvName=NULL;
	  cchContainerName = (lstrlen(psKeyContainer) + 1)  * sizeof(WCHAR);
	  cchCSPName = (lstrlen(psCspName) + 1) * sizeof(WCHAR);
      wszContainerName = (LPWSTR) malloc(cchContainerName);
      wszProvName = (LPWSTR) malloc(cchCSPName);
      mbstowcs(wszContainerName, psKeyContainer,cchContainerName);
	  mbstowcs(wszProvName, psCspName, cchCSPName);
      ZeroMemory((PVOID)&KeyProvInfo, sizeof(CRYPT_KEY_PROV_INFO));
      KeyProvInfo.pwszContainerName = (LPWSTR) wszContainerName;
      KeyProvInfo.pwszProvName      = (LPWSTR) wszProvName;
      KeyProvInfo.dwProvType        = PROV_RSA_SIG;
      KeyProvInfo.dwFlags           = 0;
      KeyProvInfo.dwKeySpec         = dwKeyType;
      fRes = CertSetCertificateContextProperty(pCertContext,CERT_KEY_PROV_INFO_PROP_ID, 0, (const void *) &KeyProvInfo);
      if (wszContainerName != NULL)
        free(wszContainerName);
      if (wszProvName != NULL)
        free(wszProvName);

      }
    }
  }

//if (pCertContext != NULL)
//  DigiCrypt_AddCertToStore(pCertContext);
if (fRes == FALSE && pCertContext != NULL)
  {
  CertFreeCertificateContext(pCertContext);
  pCertContext = NULL;
  }
if (pbData != NULL)
  free(pbData);
if (hCryptProv != 0)
  CryptReleaseContext(hCryptProv, 0);
return(pCertContext);
}
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
}
Example #29
0
static void test_crypt_ui_wiz_import(void)
{
    BOOL ret;
    CRYPTUI_WIZ_IMPORT_SRC_INFO info;
    HCERTSTORE store;
    PCCERT_CONTEXT cert;
    PCCRL_CONTEXT crl;
    DWORD count;

    if (!pCryptUIWizImport)
    {
        skip("No CryptUIWizImport\n");
        return;
    }

    /* Set CBT hook to disallow MessageBox and wizard creation in current
     * thread.
     */
    hook = SetWindowsHookExA(WH_CBT, cbt_hook_proc, 0, GetCurrentThreadId());

    /* Brings up UI.  Cancelling yields ret = 1. */
    if (0)
    {
        pCryptUIWizImport(0, 0, NULL, NULL, NULL);
    }
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI, 0, NULL, NULL, NULL);
    ok(!ret && GetLastError() == E_INVALIDARG,
     "expected E_INVALIDARG, got %08x\n", GetLastError());
    memset(&info, 0, sizeof(info));
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI, 0, NULL, &info, NULL);
    ok(!ret && GetLastError() == E_INVALIDARG,
     "expected E_INVALIDARG, got %08x\n", GetLastError());
    info.dwSize = sizeof(info);
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI, 0, NULL, &info, NULL);
    ok(!ret && GetLastError() == E_INVALIDARG,
     "expected E_INVALIDARG, got %08x\n", GetLastError());
    info.dwSubjectChoice = CRYPTUI_WIZ_IMPORT_SUBJECT_CERT_CONTEXT;
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI, 0, NULL, &info, NULL);
    ok(!ret && GetLastError() == E_INVALIDARG,
     "expected E_INVALIDARG, got %08x\n", GetLastError());
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI | CRYPTUI_WIZ_IMPORT_ALLOW_CERT,
     0, NULL, &info, NULL);
    ok(!ret && GetLastError() == E_INVALIDARG,
     "expected E_INVALIDARG, got %08x\n", GetLastError());
    /* Check allowed vs. given type mismatches */
    info.u.pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING,
     v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey));
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI | CRYPTUI_WIZ_IMPORT_ALLOW_CRL,
     0, NULL, &info, NULL);
    ok(!ret && GetLastError() == E_INVALIDARG,
     "expected E_INVALIDARG, got %08x\n", GetLastError());
    CertFreeCertificateContext(info.u.pCertContext);
    info.dwSubjectChoice = CRYPTUI_WIZ_IMPORT_SUBJECT_CRL_CONTEXT;
    info.u.pCRLContext = CertCreateCRLContext(X509_ASN_ENCODING,
     signedCRL, sizeof(signedCRL));
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI | CRYPTUI_WIZ_IMPORT_ALLOW_CERT,
     0, NULL, &info, NULL);
    ok(!ret && GetLastError() == E_INVALIDARG,
     "expected E_INVALIDARG, got %08x\n", GetLastError());
    CertFreeCRLContext(info.u.pCRLContext);
    /* Imports the following cert--self-signed, with no basic constraints set--
     * to the CA store.  Puts up a dialog at the end if it succeeds or fails.
     */
    info.dwSubjectChoice = CRYPTUI_WIZ_IMPORT_SUBJECT_CERT_CONTEXT;
    info.u.pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING,
     v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey));
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI, 0, NULL, &info, NULL);
    ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError());
    if (ret)
    {
        static const WCHAR CA[] = { 'C','A',0 };
        HCERTSTORE ca = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0,
         CERT_SYSTEM_STORE_CURRENT_USER, CA);

        if (ca)
        {
            ret = find_and_delete_cert_in_store(ca, info.u.pCertContext);
            ok(ret ||
             broken(!ret) /* Win9x/NT4 */,
             "expected to find v1CertWithValidPubKey in CA store\n");
            CertCloseStore(ca, 0);
        }
    }
    CertFreeCertificateContext(info.u.pCertContext);
    /* Imports the following cert--not self-signed, with a basic constraints2
     * extensions--to the "AddressBook" store.  Puts up a dialog at the end if
     * it succeeds or fails.
     */
    info.u.pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING,
     iTunesCert3, sizeof(iTunesCert3));
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI, 0, NULL, &info, NULL);
    ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError());
    if (ret)
    {
        static const WCHAR AddressBook[] = { 'A','d','d','r','e','s','s',
         'B','o','o','k',0 };
        HCERTSTORE addressBook = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0,
         CERT_SYSTEM_STORE_CURRENT_USER, AddressBook);

        if (addressBook)
        {
            ret = find_and_delete_cert_in_store(addressBook,
             info.u.pCertContext);
            ok(ret ||
             broken(!ret),  /* Windows 2000 and earlier */
             "expected to find iTunesCert3 in AddressBook store\n");
            CertCloseStore(addressBook, 0);
        }
    }
    /* Displays the wizard, but disables the "Certificate store" edit and
     * the Browse button.  Confusingly, the "Place all certificates in the
     * following store" radio button is not disabled.
     */
    if (0)
    {
        ret = pCryptUIWizImport(CRYPTUI_WIZ_IMPORT_NO_CHANGE_DEST_STORE, 0,
         NULL, &info, NULL);
        ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError());
    }
    store = CertOpenStore(CERT_STORE_PROV_MEMORY, X509_ASN_ENCODING, 0,
     CERT_STORE_CREATE_NEW_FLAG, NULL);
    /* Displays the wizard, but sets the "Certificate store" edit to the
     * string "Determined by the program", and disables it and the Browse
     * button, as well as the "Automatically select the certificate store
     * based on the type of certificate" radio button.
     */
    if (0)
    {
        ret = pCryptUIWizImport(CRYPTUI_WIZ_IMPORT_NO_CHANGE_DEST_STORE, 0,
         NULL, &info, store);
        ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError());
    }
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI |
     CRYPTUI_WIZ_IMPORT_NO_CHANGE_DEST_STORE, 0, NULL, &info, store);
    ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError());
    ret = find_and_delete_cert_in_store(store, info.u.pCertContext);
    ok(ret ||
     broken(!ret) /* Win9x/NT4 */,
     "expected to find iTunesCert3 in memory store\n");
    CertFreeCertificateContext(info.u.pCertContext);
    CertCloseStore(store, 0);

    info.u.pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING,
     iTunesCert1, sizeof(iTunesCert1));
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI, 0, NULL, &info, NULL);
    ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError());
    if (ret)
    {
        static const WCHAR AddressBook[] = { 'A','d','d','r','e','s','s',
         'B','o','o','k',0 };
        HCERTSTORE addressBook = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0,
         CERT_SYSTEM_STORE_CURRENT_USER, AddressBook);

        if (addressBook)
        {
            ret = find_and_delete_cert_in_store(addressBook,
             info.u.pCertContext);
            ok(ret ||
             broken(!ret),  /* Windows 2000 and earlier */
             "expected to find iTunesCert1 in AddressBook store\n");
            CertCloseStore(addressBook, 0);
        }
    }
    CertFreeCertificateContext(info.u.pCertContext);

    info.u.pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING,
     iTunesCert2, sizeof(iTunesCert2));
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI, 0, NULL, &info, NULL);
    ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError());
    if (ret)
    {
        static const WCHAR CA[] = { 'C','A',0 };
        HCERTSTORE ca = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0,
         CERT_SYSTEM_STORE_CURRENT_USER, CA);

        if (ca)
        {
            ret = find_and_delete_cert_in_store(ca, info.u.pCertContext);
            ok(ret ||
             broken(!ret) /* Win9x/NT4 */,
             "expected to find iTunesCert2 in CA store\n");
            CertCloseStore(ca, 0);
        }
    }
    CertFreeCertificateContext(info.u.pCertContext);

    info.u.hCertStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
     CERT_STORE_CREATE_NEW_FLAG, NULL);
    CertAddEncodedCertificateToStore(info.u.hCertStore, X509_ASN_ENCODING,
     v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey),
     CERT_STORE_ADD_ALWAYS, NULL);
    CertAddEncodedCRLToStore(info.u.hCertStore, X509_ASN_ENCODING, signedCRL,
     sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, NULL);
    info.dwSubjectChoice = CRYPTUI_WIZ_IMPORT_SUBJECT_CERT_STORE;
    /* The ALLOW flags aren't allowed with a store as the source if the source
     * contains types other than those allowed.
     */
    store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
     CERT_STORE_CREATE_NEW_FLAG, NULL);
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI | CRYPTUI_WIZ_IMPORT_ALLOW_CERT,
     0, NULL, &info, store);
    ok(!ret && GetLastError() == E_INVALIDARG,
     "expected E_INVALIDARG, got %08x\n", GetLastError());
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI | CRYPTUI_WIZ_IMPORT_ALLOW_CRL,
     0, NULL, &info, store);
    ok(!ret && GetLastError() == E_INVALIDARG,
     "expected E_INVALIDARG, got %08x\n", GetLastError());
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI |
     CRYPTUI_WIZ_IMPORT_NO_CHANGE_DEST_STORE |
     CRYPTUI_WIZ_IMPORT_ALLOW_CERT | CRYPTUI_WIZ_IMPORT_ALLOW_CRL, 0, NULL,
     &info, store);
    ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError());
    if (ret)
    {
        count = 0;
        cert = NULL;
        do {
            cert = CertEnumCertificatesInStore(store, cert);
            if (cert)
                count++;
        } while (cert);
        ok(count == 1, "expected 1 cert, got %d\n", count);
        count = 0;
        crl = NULL;
        do {
            crl = CertEnumCRLsInStore(store, crl);
            if (crl)
                count++;
        } while (crl);
        ok(count == 1, "expected 1 CRL, got %d\n", count);
    }
    CertCloseStore(store, 0);
    CertCloseStore(info.u.hCertStore, 0);

    /* If the ALLOW flags match the content of the store, the store can be
     * imported.
     */
    info.u.hCertStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
     CERT_STORE_CREATE_NEW_FLAG, NULL);
    CertAddEncodedCertificateToStore(info.u.hCertStore, X509_ASN_ENCODING,
     v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey),
     CERT_STORE_ADD_ALWAYS, NULL);
    store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
     CERT_STORE_CREATE_NEW_FLAG, NULL);
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI | CRYPTUI_WIZ_IMPORT_ALLOW_CERT,
     0, NULL, &info, store);
    ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError());
    if (ret)
    {
        count = 0;
        cert = NULL;
        do {
            cert = CertEnumCertificatesInStore(store, cert);
            if (cert)
                count++;
        } while (cert);
        ok(count == 1, "expected 1 cert, got %d\n", count);
        count = 0;
        crl = NULL;
        do {
            crl = CertEnumCRLsInStore(store, crl);
            if (crl)
                count++;
        } while (crl);
        ok(count == 0, "expected 0 CRLs, got %d\n", count);
    }
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI | CRYPTUI_WIZ_IMPORT_ALLOW_CRL,
     0, NULL, &info, store);
    ok(!ret && GetLastError() == E_INVALIDARG,
     "expected E_INVALIDARG, got %08x\n", GetLastError());
    CertCloseStore(store, 0);
    CertCloseStore(info.u.hCertStore, 0);

    /* Again, if the ALLOW flags match the content of the store, the store can
     * be imported.
     */
    info.u.hCertStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
     CERT_STORE_CREATE_NEW_FLAG, NULL);
    CertAddEncodedCRLToStore(info.u.hCertStore, X509_ASN_ENCODING, signedCRL,
     sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, NULL);
    store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
     CERT_STORE_CREATE_NEW_FLAG, NULL);
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI | CRYPTUI_WIZ_IMPORT_ALLOW_CRL,
     0, NULL, &info, store);
    ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError());
    if (ret)
    {
        count = 0;
        cert = NULL;
        do {
            cert = CertEnumCertificatesInStore(store, cert);
            if (cert)
                count++;
        } while (cert);
        ok(count == 0, "expected 0 certs, got %d\n", count);
        count = 0;
        crl = NULL;
        do {
            crl = CertEnumCRLsInStore(store, crl);
            if (crl)
                count++;
        } while (crl);
        ok(count == 1, "expected 1 CRL, got %d\n", count);
    }
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI | CRYPTUI_WIZ_IMPORT_ALLOW_CERT,
     0, NULL, &info, store);
    ok(!ret && GetLastError() == E_INVALIDARG,
     "expected E_INVALIDARG, got %08x\n", GetLastError());
    CertCloseStore(store, 0);
    CertCloseStore(info.u.hCertStore, 0);

    UnhookWindowsHookEx(hook);
}
Example #30
0
/** 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
}