示例#1
0
文件: cryptox.c 项目: CloCkWeRX/core
/**
 * Obtains the public key for the passed in cert data
 *
 * @param provider        The crypto provider
 * @param certData        Data of the certificate to extract the public key from
 * @param sizeOfCertData  The size of the certData buffer
 * @param certStore       Pointer to the handle of the certificate store to use
 * @param CryptoX_Success on success
*/
CryptoX_Result
CryptoAPI_LoadPublicKey(HCRYPTPROV provider,
                        BYTE *certData,
                        DWORD sizeOfCertData,
                        HCRYPTKEY *publicKey)
{
  CRYPT_DATA_BLOB blob;
  CERT_CONTEXT *context;
  if (!provider || !certData || !publicKey) {
    return CryptoX_Error;
  }

  blob.cbData = sizeOfCertData;
  blob.pbData = certData;
  if (!CryptQueryObject(CERT_QUERY_OBJECT_BLOB, &blob,
                        CERT_QUERY_CONTENT_FLAG_CERT,
                        CERT_QUERY_FORMAT_FLAG_BINARY,
                        0, NULL, NULL, NULL,
                        NULL, NULL, (const void **)&context)) {
    return CryptoX_Error;
  }

  if (!CryptImportPublicKeyInfo(provider,
                                PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
                                &context->pCertInfo->SubjectPublicKeyInfo,
                                publicKey)) {
    CertFreeCertificateContext(context);
    return CryptoX_Error;
  }

  CertFreeCertificateContext(context);
  return CryptoX_Success;
}
示例#2
0
/**
 *
 * save public or private key to PEM format
 *
 * ifile   : name of file to write PEM encoded key
 * pemType : type of key being saved
 * rsa     : RSA object with public and private keys
 *
 */
int rsa_read_key(RSA* rsa,
                 const char* ifile, int pemType)
{
    LPVOID                  derData, keyData;
    PCRYPT_PRIVATE_KEY_INFO pki = 0;
    DWORD                   pkiLen, derLen, keyLen;
    BOOL                    ok = FALSE;
    // decode base64 string ignoring headers
    derData = rsa_read_pem(ifile, &derLen);

    if (derData != NULL) {
        // decode DER
        // is it a public key?
        if (pemType == RSA_PUBLIC_KEY) {
            if (CryptDecodeObjectEx(
                    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                    X509_PUBLIC_KEY_INFO, derData, derLen,
                    CRYPT_DECODE_ALLOC_FLAG, NULL,
                    &keyData, &keyLen)) {
                // if decode ok, import it
                ok = CryptImportPublicKeyInfo(rsa->prov, X509_ASN_ENCODING,
                                              (PCERT_PUBLIC_KEY_INFO)keyData, &rsa->pubkey);
                // release allocated memory
                LocalFree(keyData);
            }
        } else {
            // convert the PKCS#8 data to private key info
            if (CryptDecodeObjectEx(
                    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                    PKCS_PRIVATE_KEY_INFO, derData, derLen,
                    CRYPT_DECODE_ALLOC_FLAG,
                    NULL, &pki, &pkiLen)) {
                // then convert the private key to private key blob
                if (CryptDecodeObjectEx(
                        X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                        PKCS_RSA_PRIVATE_KEY,
                        pki->PrivateKey.pbData,
                        pki->PrivateKey.cbData,
                        CRYPT_DECODE_ALLOC_FLAG, NULL,
                        &keyData, &keyLen)) {
                    // if decode ok, import it
                    ok = CryptImportKey(rsa->prov, keyData, keyLen,
                                        0, CRYPT_EXPORTABLE, &rsa->privkey);
                    // release data
                    LocalFree(keyData);
                }

                // release private key info
                LocalFree(pki);
            }
        }

        xfree(derData);
    }

    return ok;
}
示例#3
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;
}
示例#4
0
// Get functions
XSECCryptoKey * WinCAPICryptoX509::clonePublicKey() const {


	if (mp_certContext == NULL) {
		throw XSECCryptoException(XSECCryptoException::X509Error,
			"WinCAPI:X509 - clonePublicKey called before X509 loaded");
	}

	// Import the key into the provider to get a pointer to the key

	HCRYPTKEY key;
	BOOL fResult;
                 
	if (getPublicKeyType() == XSECCryptoKey::KEY_DSA_PUBLIC) {

		fResult= CryptImportPublicKeyInfo(
			   m_pDSS,
			   X509_ASN_ENCODING,
			   &(mp_certContext->pCertInfo->SubjectPublicKeyInfo),
			   &key);
                 

		if (fResult == FALSE) {
			throw XSECCryptoException(XSECCryptoException::X509Error,
				"WinCAPI:X509 - Error loading public key info from certificate");
		}

		// Now that we have a handle for the DSA key, create a DSA Key object to
		// wrap it in

		WinCAPICryptoKeyDSA * ret;
		XSECnew(ret, WinCAPICryptoKeyDSA(m_pDSS, key));

		return ret;

	}

	if (getPublicKeyType() == XSECCryptoKey::KEY_RSA_PUBLIC) {

		fResult= CryptImportPublicKeyInfo(
			   m_pRSA,
			   X509_ASN_ENCODING,
			   &(mp_certContext->pCertInfo->SubjectPublicKeyInfo),
			   &key);
                 

		if (fResult == FALSE) {
			throw XSECCryptoException(XSECCryptoException::X509Error,
				"WinCAPI:X509 - Error loading public key info from certificate");
		}

		// Now that we have a handle for the DSA key, create a DSA Key object to
		// wrap it in

		WinCAPICryptoKeyRSA * ret;
		XSECnew(ret, WinCAPICryptoKeyRSA(m_pRSA, key));

		return ret;

	}

	return NULL;		// Unknown key type, but not necessarily an error

}
BOOL AcquireAndGetRSAKey(PCCERT_CONTEXT pCertContext,
                         HCRYPTPROV *phProv,
                         HCRYPTKEY *phRSAKey,
                         BOOL fEncrypt,
                         BOOL *pfCallerFreeProv)
{
    BOOL fSuccess = FALSE;
    DWORD dwKeySpec = 0;

    __try
    {
        *phProv = NULL;
        *phRSAKey = NULL;
        *pfCallerFreeProv = FALSE;

        if (fEncrypt)
        {
            // Acquire context for RSA key
            fSuccess = CryptAcquireContext(phProv,
                                           NULL,
                                           MS_DEF_PROV,
                                           PROV_RSA_FULL,
                                           CRYPT_VERIFYCONTEXT);
            if (!fSuccess)
            {
                MyPrintf(_T("CryptAcquireContext failed with %X\n"), GetLastError());
                __leave;
            }

            // Import the RSA public key from the certificate context
            fSuccess = CryptImportPublicKeyInfo(*phProv,
                                                MY_ENCODING,
                                                &(pCertContext->pCertInfo->SubjectPublicKeyInfo),
                                                phRSAKey);
            if (!fSuccess)
            {
                MyPrintf(_T("CryptImportPublicKeyInfo failed with %X\n"), GetLastError());
                __leave;
            }

            *pfCallerFreeProv = TRUE;
        }
        else
        {
            // Acquire the RSA private key
            fSuccess = CryptAcquireCertificatePrivateKey(pCertContext,
                       CRYPT_ACQUIRE_USE_PROV_INFO_FLAG|CRYPT_ACQUIRE_COMPARE_KEY_FLAG,
                       NULL, phProv, &dwKeySpec, pfCallerFreeProv);
            if (!fSuccess)
            {
                MyPrintf(_T("CryptAcquireCertificatePrivateKey failed with %X\n"), GetLastError());
                __leave;
            }

            // Get the RSA key handle
            fSuccess = CryptGetUserKey(*phProv, dwKeySpec, phRSAKey);
            if (!fSuccess)
            {
                MyPrintf(_T("CryptGetUserKey failed with %X\n"), GetLastError());
                __leave;
            }
        }
    }
    __finally
    {
        if (fSuccess == FALSE)
        {
            if (phProv && *phProv != NULL)
            {
                CryptReleaseContext(*phProv, 0);
                *phProv = NULL;
            }
            if (phRSAKey && *phRSAKey != NULL)
            {
                CryptDestroyKey(*phRSAKey);
                *phRSAKey = NULL;
            }
        }
    }

    return fSuccess;
}
示例#6
0
int KSI_PKITruststore_verifyRawSignature(KSI_CTX *ctx, const unsigned char *data, unsigned data_len, const char *algoOid, const unsigned char *signature, unsigned signature_len, const KSI_PKICertificate *certificate) {
	int res = KSI_UNKNOWN_ERROR;
	ALG_ID algorithm=0;
	HCRYPTPROV hCryptProv = 0;
    PCCERT_CONTEXT subjectCert = NULL;
	HCRYPTKEY publicKey = 0;
	DWORD i=0;
	BYTE *little_endian_pkcs1= NULL;
	DWORD pkcs1_len = 0;
	HCRYPTHASH hash = 0;
	char buf[1024];

	KSI_ERR_clearErrors(ctx);
	if (ctx == NULL || data == NULL || signature == NULL ||
		signature_len >= UINT_MAX || algoOid == NULL || certificate == NULL){
		res = KSI_INVALID_ARGUMENT;
		goto cleanup;
	}


	algorithm = algIdFromOID(algoOid);
	if (algorithm == 0) {
		KSI_pushError(ctx, res = KSI_UNAVAILABLE_HASH_ALGORITHM, NULL);
		goto cleanup;
	}

	// Get the CSP context
	if (!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)){
		KSI_LOG_debug(ctx, "%s", getMSError(GetLastError(), buf, sizeof(buf)));
		KSI_pushError(ctx, res = KSI_CRYPTO_FAILURE, "Unable to get cryptographic provider.");
		goto cleanup;
	}

	// Get the public key from the issuer certificate
	subjectCert = certificate->x509;
	if (!CryptImportPublicKeyInfo(hCryptProv, X509_ASN_ENCODING,&subjectCert->pCertInfo->SubjectPublicKeyInfo,&publicKey)){
		KSI_LOG_debug(ctx, "%s", getMSError(GetLastError(), buf, sizeof(buf)));
		KSI_pushError(ctx, res = KSI_PKI_CERTIFICATE_NOT_TRUSTED, "Failed to read PKI public key.");
		goto cleanup;
	}

	/*Convert big-endian to little-endian PKCS#1 signature*/
	pkcs1_len = signature_len;
	little_endian_pkcs1 = (BYTE*)KSI_malloc(pkcs1_len);

	if (little_endian_pkcs1 == NULL){
		KSI_pushError(ctx, res = KSI_OUT_OF_MEMORY, NULL);
		goto cleanup;
	}

	for (i=0; i<pkcs1_len; i++){
		little_endian_pkcs1[pkcs1_len-1-i] = signature[i];
	}

	// Create the hash object and hash input data.
	if (!CryptCreateHash(hCryptProv, algorithm, 0, 0, &hash)){
		KSI_LOG_debug(ctx, "%s", getMSError(GetLastError(), buf, sizeof(buf)));
		KSI_pushError(ctx, res = KSI_CRYPTO_FAILURE, "Unable to create hasher.");
		goto cleanup;
	}

	if (!CryptHashData(hash, (BYTE*)data, data_len,0)){
		KSI_LOG_debug(ctx, "%s", getMSError(GetLastError(), buf, sizeof(buf)));
		KSI_pushError(ctx, res = KSI_CRYPTO_FAILURE, "Unable to hash data.");
		goto cleanup;
	}

	/*Verify the signature. The format MUST be PKCS#1*/
	if (!CryptVerifySignature(hash, (BYTE*)little_endian_pkcs1, pkcs1_len, publicKey, NULL, 0)){
		DWORD error = GetLastError();
		const char *errmsg = getMSError(GetLastError(), buf, sizeof(buf));
		KSI_LOG_debug(ctx, "%s", errmsg);

		if (error == NTE_BAD_SIGNATURE)
			KSI_pushError(ctx, res = KSI_PKI_CERTIFICATE_NOT_TRUSTED, "Invalid PKI signature.");
		else if (error == NTE_NO_MEMORY)
			KSI_pushError(ctx, res = KSI_OUT_OF_MEMORY, "Unable to verify PKI signature. CSP out of memory.");
		else
			KSI_pushError(ctx, res = KSI_PKI_CERTIFICATE_NOT_TRUSTED, errmsg);

		goto cleanup;
	}

	KSI_LOG_debug(certificate->ctx, "CryptoAPI: PKI signature verified successfully.");

	res = KSI_OK;

cleanup:

	KSI_free(little_endian_pkcs1);
	if (hCryptProv) CryptReleaseContext(hCryptProv, 0);
	if (hash) CryptDestroyHash(hash);

	return res;
}
int VerifyDataSignWithHashAlg(const char * userData,  const char * hashAlg, const char * certDataB64, const char * signatureDataB64)
{
	int rv = -1;
	int ulHashAlg = 0;
	HCRYPTHASH hHash = NULL;
	char * pbCert = NULL;
	char * pbSignature = NULL;
	unsigned int ulCert = 0;
	unsigned int ulSignature = 0;
	PCCERT_CONTEXT pCertContext = NULL;  
	HCRYPTPROV hProv = NULL;  
	HCRYPTKEY hPubKey = NULL;  

	{
		ulCert = modp_b64_decode_len(strlen(certDataB64));
		ulSignature = modp_b64_decode_len(strlen(signatureDataB64));

		pbCert = (char *)malloc(ulCert);
		pbSignature =  (char *) malloc(ulSignature);

		if (NULL == pbCert || NULL == pbSignature)
		{
			sprintf(m_errMsg, "%s","memroy less.\n" );
			goto err;
		}

		ulCert = modp_b64_decode(pbCert, certDataB64,strlen(certDataB64));
		ulSignature = modp_b64_decode(pbSignature, signatureDataB64,strlen(signatureDataB64));
	}

	if (0 == strcmp(hashAlg, "MD5"))
	{
		ulHashAlg = CALG_MD5;
	}
	else if (0 == strcmp(hashAlg, "SHA"))
	{
		ulHashAlg = CALG_SHA;
	}
	else if (0 == strcmp(hashAlg, "SHA1"))
	{
		ulHashAlg = CALG_SHA1;
	}
	else if (0 == strcmp(hashAlg, "SHA_256"))
	{
		ulHashAlg = CALG_SHA_256;
	}
	else if (0 == strcmp(hashAlg, "SHA_384"))
	{
		ulHashAlg = CALG_SHA_384;
	}

	pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, (BYTE *)pbCert,ulCert);
	if (!pCertContext)
	{
		sprintf(m_errMsg, "%s","Select Certificate UI failed.\n" );
		goto err;
	}


	//Ò»¡¢»ñµÃÒ»¸öCSP¾ä±ú  
	if(!CryptAcquireContext(  
		&hProv,  
		NULL,           //ÃÜÔ¿ÈÝÆ÷Ãû£¬NULL±íʾʹÓÃĬÈÏÈÝÆ÷  
		NULL,           //CSP_NAME  
		PROV_RSA_FULL,  
		0  
		)) 
	{  
		if(!CryptAcquireContext(  
			&hProv,  
			NULL,           //ÃÜÔ¿ÈÝÆ÷Ãû£¬NULL±íʾʹÓÃĬÈÏÈÝÆ÷  
			NULL,           //CSP_NAME  
			PROV_RSA_FULL,  
			CRYPT_NEWKEYSET //´´½¨ÃÜÔ¿ÈÝÆ÷  
			))
		{
			sprintf(m_errMsg, "%s","CryptAcquireContext fail.\n");
			goto err;
		}
	}  


	if(CryptImportPublicKeyInfo(
		hProv,
		X509_ASN_ENCODING,
		&(pCertContext->pCertInfo->SubjectPublicKeyInfo),
		&hPubKey
		))
	{
		sprintf(m_errMsg,"CryptImportPublicKeyInfo OK. \n");
	}
	else
	{
		sprintf(m_errMsg,"Error CryptImportPublicKeyInfo.\n");
		goto err;
	}

	//if(CryptImportKey(hProv,pCertContext->pCertInfo->SubjectPublicKeyInfo.PublicKey.pbData, pCertContext->pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData, NULL, 0, &hPubKey))
	//{
	//	sprintf(m_errMsg,"CryptImportKey OK. \n");
	//}
	//else
	//{
	//	sprintf(m_errMsg,"Error CryptImportKey.\n");
	//	goto err;
	//}

	if(CryptCreateHash(
		hProv, 
		ulHashAlg, 
		0, 
		0, 
		&hHash)) 
	{
		sprintf(m_errMsg, "%s","An empty hash object has been created. \n");
	}
	else
	{
		sprintf(m_errMsg, "%s","Error during CryptBeginHash!\n");
		goto err;
	}


	//--------------------------------------------------------------------
	//  This code assumes that the handle of a cryptographic context 
	//  has been acquired and that a hash object has been created 
	//  and its handle (hHash) is available.
	if(CryptHashData(
		hHash, 
		(unsigned char *)userData, 
		strlen(userData), 
		0)) 
	{
		sprintf(m_errMsg, "%s","The data buffer has been added to the hash.\n");
	}
	else
	{
		sprintf(m_errMsg, "%s","Error during CryptHashData.\n");
		goto err;
	}

	if(CryptVerifySignature(hHash, (const BYTE *)pbSignature, ulSignature,hPubKey,NULL,0))
	{
		sprintf(m_errMsg,"verify OK.\n");
	}
	else
	{
		sprintf(m_errMsg,"Error during CryptVerifySignature.\n");
		goto err;
	}

	rv = 0;

err:
	if(hHash) 
	{
		CryptDestroyHash(hHash);
	}

	if (pbSignature)
	{
		free(pbSignature);
	}

	if (pbCert)
	{
		free(pbCert);
	}

	if (pCertContext)
	{
		CertFreeCertificateContext(pCertContext);
	}

	if(hProv)  
	{
		CryptReleaseContext(hProv,0);  
	}


	return rv;
}
BOOL GetRSAKeyFromCert(PCCERT_CONTEXT pCertContext,
                       BOOL fSign,
                       HCRYPTPROV *hProv,
                       HCRYPTKEY *hPubKey,
                       DWORD *dwKeySpec,
                       BOOL *fFreeProv)
{   
   BOOL fResult;
   BOOL fReturn = FALSE;
   
   __try
   {  
      if (hProv == NULL || hPubKey == NULL || 
          dwKeySpec == NULL || fFreeProv == NULL)
      {
         __leave;
      }

      *hProv = 0;
      *hPubKey = 0;
      *fFreeProv = FALSE;
    
      if (fSign)
      {
         // Acquire the certificate's private key
         fResult = CryptAcquireCertificatePrivateKey(pCertContext,
                                                     CRYPT_ACQUIRE_USE_PROV_INFO_FLAG|
                                                     CRYPT_ACQUIRE_COMPARE_KEY_FLAG,
                                                     NULL,
                                                     hProv,
                                                     dwKeySpec,
                                                     fFreeProv);
         if (!fResult)
         {
            MyPrintf(_T("CryptAcquireCertificatePrivateKey failed with %x\n"), GetLastError());
            __leave;
         }
      }
      else
      {
         fResult = CryptAcquireContext(hProv, 
                                       NULL, 
                                       MS_DEF_PROV,
                                       PROV_RSA_FULL, 
                                       CRYPT_VERIFYCONTEXT);
         if (!fResult)
         {
            MyPrintf(_T("CryptAcquireContext failed with %x\n"), GetLastError());
            __leave;
         }

         *fFreeProv = TRUE;

         // Import the public key from the certificate so we can verify
         fResult = CryptImportPublicKeyInfo(*hProv,
                                            ENCODING,
                                            &(pCertContext->pCertInfo->SubjectPublicKeyInfo),
                                            hPubKey);
         if (!fResult)
         {
            MyPrintf(_T("CryptImportPublicKeyInfo failed with %x\n"), GetLastError());
            __leave;
         }         
      }

      fReturn = TRUE;
   }
   __finally
   {
      if (!fReturn)
      {
         if (*hPubKey != NULL) 
         {
            CryptDestroyKey(*hPubKey);
            *hPubKey = NULL;
         }

         if ((*fFreeProv == TRUE) && (*hProv != NULL)) 
         {
            CryptReleaseContext(*hProv, 0);
            *hProv = NULL;
            *fFreeProv = FALSE;
         }
      }
   }

   return fReturn;
}