Beispiel #1
0
/*
* SfcValidateFileHeader
*
* Purpose:
*
* Verify fileheader from retL packet.
*
*/
BOOL SfcValidateFileHeader(
	HCRYPTPROV hCryptoProv,
	HCRYPTKEY hCryptKey,
	ZA_FILEHEADER *FileHeader
	)
{
	BOOL bResult, cond = FALSE;
	HCRYPTHASH   hCryptHash = 0;
	MD5_CTX      ctx;

	bResult = FALSE;

	do {

		if (!CryptCreateHash(hCryptoProv, CALG_MD5, 0, 0, &hCryptHash))
			break;

		MD5Init(&ctx);
		MD5Update(&ctx, (UCHAR*)FileHeader, (UINT)3 * sizeof(ULONG));
		MD5Final(&ctx);

		if (!CryptSetHashParam(hCryptHash, HP_HASHVAL, (const BYTE *)&ctx.digest, 0))
			break;
		
		bResult = CryptVerifySignatureW(hCryptHash, (const BYTE *)&FileHeader->Signature, sizeof(FileHeader->Signature), hCryptKey, 0, 0);

	} while (cond);

	if (hCryptHash != 0) {
		CryptDestroyHash(hCryptHash);
	}
	return bResult;
}
Beispiel #2
0
BOOL kull_m_crypto_hmac(DWORD calgid, LPCVOID key, DWORD keyLen, LPCVOID message, DWORD messageLen, LPVOID hash, DWORD hashWanted) // for keyLen > 1
{
	BOOL status = FALSE;
	DWORD hashLen;
	HCRYPTPROV hProv;
	HCRYPTKEY hKey;
	HCRYPTHASH hHash;
	HMAC_INFO HmacInfo = {calgid, NULL, 0, NULL, 0};
	PBYTE buffer;

	if(CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT))
	{
		if(kull_m_crypto_hkey(hProv, CALG_RC2, key, keyLen, CRYPT_IPSEC_HMAC_KEY, &hKey, NULL))
		{
			if(CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash))
			{
				if(CryptSetHashParam(hHash, HP_HMAC_INFO, (LPCBYTE) &HmacInfo, 0))
					if(CryptHashData(hHash, (LPCBYTE) message, messageLen, 0))
						if(CryptGetHashParam(hHash, HP_HASHVAL, NULL, &hashLen, 0))
						{
							if(buffer = (PBYTE) LocalAlloc(LPTR, hashLen))
							{
								status = CryptGetHashParam(hHash, HP_HASHVAL, buffer, &hashLen, 0);
								RtlCopyMemory(hash, buffer, KIWI_MINIMUM(hashLen, hashWanted));
								LocalFree(buffer);
							}
						}
						CryptDestroyHash(hHash);
			}
			CryptDestroyKey(hKey);
		}
		CryptReleaseContext(hProv, 0);
	}
	return status;
}
Beispiel #3
0
static int HCSP_setHashContext(void)
{
   int result = TRUE;

#ifdef DEBUG
   BIO_printf(err, "Call HCSP_setHashContext()\n");
#endif

   /* Create a hash object. */

   if (!CryptCreateHash(hCryptProvider, Algid, 0, 0, &hHash))
      {
#  ifdef DEBUG
      routine = "CryptCreateHash";
#  endif

      goto error;
      }

   /* Set data to hash object. */

   if (!CryptSetHashParam(hHash, HP_HASHVAL, pbBuffer, 0))
      {
#  ifdef DEBUG
      routine = "CryptSetHashParam";
#  endif

      goto error;
      }

   /* Determine size of signature. */

   if (!CryptSignHash(hHash, dwKeySpec, NULL, 0, NULL, &dwSignatureLen))
      {
#  ifdef DEBUG
      routine = "CryptSignHash";
#  endif

      goto error;
      }

#ifdef DEBUG
   BIO_printf(err, "size of signature %d\n", dwSignatureLen);
#endif

   goto end;

error:

   result = FALSE;

end:

#ifdef DEBUG
   BIO_printf(err, "Return HCSP_setHashContext(%d)\n", result);
#endif

   return result;
}
bool testVerifyHash(bool bVerbose){

	BYTE bSignature[64];
	strtobyte( "41AA28D2F1AB148280CD9ED56FEDA41974053554A42767B83AD043FD39DC049301456C64BA4642A1653C235A98A60249BCD6D3F746B631DF928014F6C5BF9C40" , bSignature );
	DWORD dwSigLen = 64;
	HCRYPTHASH hHash;
	HCRYPTKEY hPub;
	
	BYTE bHashVal[32+1] = "\x2D\xFB\xC1\xB3\x72\xD8\x9A\x11\x88\xC0\x9C\x52\xE0\xEE\xC6\x1F\xCE\x52\x03\x2A\xB1\x02\x2E\x8E\x67\xEC\xE6\x67\x2B\x04\x3E\xE5";
	if ( bVerbose )
		std::cout << "Supplied hash value is: \n" <<  bHashVal << std::endl;

	if (!(CryptCreateHash(hProv,
					  CALG_GOST_HASH,
					  0,
					  0,
					  &hHash)))
	{   
		if ( bVerbose )
			printf("CryptCreateHash Failed\n");
		return false;
	} 

	if ( !CryptSetHashParam(
		hHash,
		HP_HASHVAL,
		bHashVal,
		0))
	{
		if ( bVerbose )
			printf("CryptSetHashParam Failed\n");
		return false;
	}


	if ( !CryptGetUserKey( 
		hProv,
		AT_SIGNATURE,
		&hPub ))
	{
		if ( bVerbose )
			printf("CryptGetUserKey Failed\n");
		return false;
	}
	if (!CryptVerifySignature(hHash,
					       bSignature,
					       dwSigLen,
					       hPub,
					       NULL,
					       0))
	{
		if ( bVerbose )
			printf("Test Failed\n");
		return false;
	}

	return true;
}
Beispiel #5
0
/*
* SfcVerifyFile
*
* Purpose:
*
* Verify file to be legit ZeroAccess signed binary.
*
*/
BOOL SfcVerifyFile(
	_In_ HCRYPTPROV  hProv,
	_In_ HCRYPTKEY hKey,
	_In_ MD5_CTX *ctx,
	_In_ PBYTE Image,
	_In_ DWORD ImageSize
	)
{
	HCRYPTHASH          lh_hash = 0;
	ULONG               CRC, SignSize = 0;
	BYTE                e_sign[128];
	PBYTE               p_resource_sign;
	PIMAGE_NT_HEADERS32 phdr;
	BOOL                bResult = FALSE;
	LDR_RESOURCE_INFO   resInfo;

	phdr = (PIMAGE_NT_HEADERS32)RtlImageNtHeader(Image);
	while (phdr != NULL) {

		resInfo.Type = (ULONG_PTR)RT_RCDATA; //type
		resInfo.Name = 1;           //id
		resInfo.Lang = 0;          //lang

		p_resource_sign = SfLdrQueryResourceDataEx(Image, &resInfo, &SignSize);
		if (p_resource_sign == NULL)
			break;

		if (SignSize != 128)
			break;

		if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &lh_hash))
			break;

		CRC = phdr->OptionalHeader.CheckSum;

		memcpy(e_sign, p_resource_sign, sizeof(e_sign));
		memset(p_resource_sign, 0, sizeof(e_sign));

		phdr->OptionalHeader.CheckSum = 0;

		MD5Update(ctx, Image, ImageSize);

		phdr->OptionalHeader.CheckSum = CRC;
		memcpy(p_resource_sign, e_sign, sizeof(e_sign));

		MD5Final(ctx);

		if (!CryptSetHashParam(lh_hash, HP_HASHVAL, (const BYTE *)&ctx->digest, 0)) {
			CryptDestroyHash(lh_hash);
			break;
		}

		bResult = CryptVerifySignatureW(lh_hash, (const BYTE *)&e_sign, sizeof(e_sign), hKey, 0, 0);
		CryptDestroyHash(lh_hash);
		break;
	}
	return bResult;
}
Beispiel #6
0
JNIEXPORT void JNICALL Java_org_company_security_csp_NativeCrypto_digestSetParameter(
		JNIEnv *env, jclass clazz, jlong hCryptHash, jint param, jbyteArray jBytes, jint offset, jint len) {

	if(hCryptHash) {
		jbyte *buffer = (jbyte*) malloc(len * sizeof(jbyte));
		(*env)->GetByteArrayRegion(env, jBytes, offset, len, buffer);

		if(!CryptSetHashParam((HCRYPTHASH) hCryptHash, (DWORD) param, (BYTE*) buffer, 0)) {
			ThrowException(env, DIGEST_EXCEPTION, GetLastError());
		}

		free(buffer);
	}
}
Beispiel #7
0
//move to zacrypto.c
//@@implemented in harusame
VOID SfcZAVerifyFile(
	HCRYPTPROV  hProv,
	HCRYPTKEY hKey,
	MD5_CTX *ctx,		
	PBYTE Image,		
	DWORD ImageSize		
	)
{
	HCRYPTHASH          lh_hash = 0; 
	ULONG               CRC, SignSize = 0; 
	BYTE                e_sign[128];
	PBYTE               p_resource_sign; 
	PIMAGE_NT_HEADERS32 phdr; 

	phdr = (PIMAGE_NT_HEADERS32)RtlImageNtHeader(Image);
	while (phdr != NULL) {

		p_resource_sign = SfuQueryResourceData(3, Image, &SignSize);
		if (p_resource_sign == NULL)
			break;

		if (SignSize != 128)
			break;

		if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &lh_hash))
			break;

		CRC = phdr->OptionalHeader.CheckSum;

		memcpy(e_sign, p_resource_sign, sizeof(e_sign));
		memset(p_resource_sign, 0, sizeof(e_sign));

		phdr->OptionalHeader.CheckSum = 0;

		MD5Update(ctx, Image, ImageSize);

		phdr->OptionalHeader.CheckSum = CRC;

		memcpy(p_resource_sign, e_sign, sizeof(e_sign));
		MD5Final(ctx);
		if (!CryptSetHashParam(lh_hash, HP_HASHVAL, (const BYTE *)&ctx->digest, 0)) {
			CryptDestroyHash(lh_hash);
			break;
		}

		CryptVerifySignatureW(lh_hash, (const BYTE *)&e_sign, sizeof(e_sign), hKey, 0, 0);
		break;
	}
}
Beispiel #8
0
///////////////////////////////////////////////////////////////////////////////////////
// Function: SignHashString
// Description: hash string signing
/////////////////////////////////////////////////////////////////////////////////////////
BOOL SignHashString(
/////////////////////////////////////////////////////////////////////////////////////////
    HCRYPTPROV hProv,
    HCRYPTKEY hPubKey,
    DWORD dwKeySpec,
    LPBYTE pbHash,
    LPBYTE pbSignature,
    DWORD *dwSignature)
{
    HCRYPTHASH hHash = NULL;

    BOOL fResult;
    BOOL fReturn = FALSE;

    __try
    {
        // Create Hash
        fResult = CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash);
        if (!fResult)
            __leave;



        // Set Hash
        fResult=CryptSetHashParam(hHash,HP_HASHVAL,pbHash,0);


        fResult = CryptSignHash(hHash, dwKeySpec, NULL, 0, pbSignature, dwSignature);
        if (!fResult)
            __leave;

        fReturn = TRUE;
    }

    __finally
    {
        if (hHash != NULL) CryptDestroyHash(hHash);
    }

    return fReturn;
}
Beispiel #9
0
void checkSig(unsigned char *tucHashBuf,
			  unsigned char *tucSignature, DWORD dwSignatureLen,
			  unsigned char *tucPubKeyBlob, DWORD dwPubKeyBlobLen)
{
	HCRYPTPROV hProv;
	HCRYPTKEY hPubKey;
	HCRYPTHASH hHash;
	DWORD err;
	int errors = 0;

	if(!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0))
		ERR_LOG_RET("CryptAcquireContext()");

	if (!CryptImportKey(hProv, tucPubKeyBlob, dwPubKeyBlobLen, 0, 0, &hPubKey))
		ERR_LOG_RET("CryptImportKey()");

	if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash))
		ERR_LOG_RET("CryptCreateHash(CALG_MD5)");

	if (!CryptSetHashParam(hHash, HP_HASHVAL, tucHashBuf, 0))
		ERR_LOG_RET("CryptSetHashParam(HP_HASHVAL)");

	if (!CryptVerifySignature(hHash, tucSignature, dwSignatureLen, hPubKey, NULL, 0))
	{
		err = GetLastError();
		printf("ERR (line %d): CryptVerifySignature() returned %s (0x%0x)\n", __LINE__, e2str(err), err);
		errors++;
	}

	if (!CryptDestroyHash(hHash))
		ERR_LOG_RET("CryptDestroyHash()");

	if (!CryptDestroyKey(hPubKey))
		ERR_LOG_RET("CryptDestroyKey()");

	CryptReleaseContext(hProv, 0);

done:
	return;
}
Beispiel #10
0
QByteArray QCSP::sign( int method, const QByteArray &digest )
{
	ALG_ID alg = 0;
	switch( method )
	{
	case NID_sha1: alg = CALG_SHA1; break;
	case NID_sha256: alg = CALG_SHA_256; break;
	case NID_sha384: alg = CALG_SHA_384; break;
	case NID_sha512: alg = CALG_SHA_512; break;
	case NID_sha224:
	default: return QByteArray();
	}

	HCRYPTHASH hash = 0;
	if( !CryptCreateHash( d->h, alg, 0, 0, &hash ) )
		return QByteArray();

	if( !CryptSetHashParam( hash, HP_HASHVAL, (BYTE*)digest.constData(), 0 ) )
	{
		CryptDestroyHash( hash );
		return QByteArray();
	}

	DWORD size = 256;
	QByteArray sig;
	sig.resize( size );
	if( !CryptSignHashW( hash, AT_SIGNATURE, 0, 0, (BYTE*)sig.data(), &size ) )
		sig.clear();
	CryptDestroyHash( hash );

	QByteArray reverse;
	for( QByteArray::const_iterator i = sig.constEnd(); i != sig.constBegin(); )
	{
		--i;
		reverse += *i;
	}

	return reverse;
}
Beispiel #11
0
QByteArray QCSP::sign( int method, const QByteArray &digest )
{
	ALG_ID alg = 0;
	switch( method )
	{
	case NID_sha1: alg = CALG_SHA1; break;
	case NID_sha256: alg = CALG_SHA_256; break;
	case NID_sha384: alg = CALG_SHA_384; break;
	case NID_sha512: alg = CALG_SHA_512; break;
	case NID_sha224:
	default: return QByteArray();
	}

	HCRYPTHASH hash = 0;
	if( !CryptCreateHash( d->h, alg, 0, 0, &hash ) )
		return QByteArray();

	if( !CryptSetHashParam( hash, HP_HASHVAL, LPBYTE(digest.constData()), 0 ) )
	{
		CryptDestroyHash( hash );
		return QByteArray();
	}

	DWORD size = 256;
	QByteArray sig( size, 0 );
	if( CryptSignHashW( hash, AT_SIGNATURE, 0, 0, LPBYTE(sig.data()), &size ) )
		sig.resize( size );
	else
		sig.clear();
	switch( GetLastError() )
	{
	case ERROR_CANCELLED: d->error = PinCanceled; break;
	default: break;
	}

	CryptDestroyHash( hash );
	return reverse( sig );
}
Beispiel #12
0
/**
 * Calculates the HMAC of the given message, hashtype, and hashkey.
 * dest must be at least the hash length.
 */
int create_hmac(int hashtype, const unsigned char *key, unsigned int keylen,
                const unsigned char *src, unsigned int srclen,
                unsigned char *dest, unsigned int *destlen)
{
    // TODO: right now we reimport the hmac key each time.  Test to see if this
    // is quick enough or if we need to cache an imported hmac key.
    HCRYPTKEY hmackey;
    HCRYPTHASH hash;
    char keyblob[BLOBLEN];
    BLOBHEADER *bheader;
    DWORD *keysize;
    BYTE *keydata;
    HMAC_INFO info;
    ALG_ID alg;
    int bloblen, hashlen, rval;
    DWORD _destlen;

    hashlen = get_hash_len(hashtype);
    alg = get_hash(hashtype);

    bheader = (BLOBHEADER *)keyblob;
    keysize = (DWORD *)(keyblob + sizeof(BLOBHEADER));
    keydata = (BYTE *)((char *)keysize + sizeof(DWORD));

    memset(keyblob, 0, sizeof(keyblob));
    bheader->bType = PLAINTEXTKEYBLOB;
    bheader->bVersion = CUR_BLOB_VERSION;
    bheader->aiKeyAlg = CALG_RC2;
    *keysize = keylen;
    memcpy(keydata, key, keylen);
    bloblen = sizeof(BLOBHEADER) + sizeof(DWORD) + hashlen;

    if (!CryptImportKey(base_prov, keyblob, bloblen, 0,
                        CRYPT_IPSEC_HMAC_KEY, &hmackey)) {
        mserror("CryptImportKey failed");
        return 0;
    }

    if (!CryptCreateHash(base_prov, CALG_HMAC, hmackey, 0, &hash)) {
        mserror("CryptCreateHash failed");
        rval = 0;
        goto end1;
    }
    memset(&info, 0, sizeof(info));
    info.HashAlgid = alg;
    if (!CryptSetHashParam(hash, HP_HMAC_INFO, (BYTE *)&info, 0)) {
        mserror("CryptSetHashParam failed");
        rval = 0;
        goto end2;
    }
    if (!CryptHashData(hash, src, srclen, 0)) {
        mserror("CryptHashData failed");
        rval = 0;
        goto end2;
    }
    _destlen = hashlen;
    if (!CryptGetHashParam(hash, HP_HASHVAL, dest, &_destlen, 0)) {
        mserror("CryptGetHashParam failed");
        rval = 0;
        goto end2;
    }
    *destlen = _destlen;
    rval = 1;

end2:
    if (!CryptDestroyHash(hash)) {
        mserror("CryptDestroyHash failed");
    }
end1:
    if (!CryptDestroyKey(hmackey)) {
        mserror("CryptDestroyKey failed");
    }
    return rval;
}
static SECStatus
ssl3_CAPIPlatformSignHashes(SSL3Hashes *hash, PlatformKey key, SECItem *buf,
                            PRBool isTLS, KeyType keyType)
{
    SECStatus    rv             = SECFailure;
    PRBool       doDerEncode    = PR_FALSE;
    SECItem      hashItem;
    DWORD        argLen         = 0;
    DWORD        signatureLen   = 0;
    ALG_ID       hashAlg        = 0;
    HCRYPTHASH   hHash          = 0;
    DWORD        hashLen        = 0;
    unsigned int i              = 0;

    buf->data = NULL;

    switch (hash->hashAlg) {
        case SEC_OID_UNKNOWN:
            hashAlg = 0;
            break;
        case SEC_OID_SHA1:
            hashAlg = CALG_SHA1;
            break;
        case SEC_OID_SHA256:
            hashAlg = CALG_SHA_256;
            break;
        case SEC_OID_SHA384:
            hashAlg = CALG_SHA_384;
            break;
        case SEC_OID_SHA512:
            hashAlg = CALG_SHA_512;
            break;
        default:
            PORT_SetError(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM);
            return SECFailure;
    }

    switch (keyType) {
        case rsaKey:
            if (hashAlg == 0) {
                hashAlg = CALG_SSL3_SHAMD5;
            }
            hashItem.data = hash->u.raw;
            hashItem.len = hash->len;
            break;
        case dsaKey:
        case ecKey:
            if (keyType == ecKey) {
                doDerEncode = PR_TRUE;
            } else {
                doDerEncode = isTLS;
            }
            if (hashAlg == 0) {
                hashAlg = CALG_SHA1;
                hashItem.data = hash->u.s.sha;
                hashItem.len = sizeof(hash->u.s.sha);
            } else {
                hashItem.data = hash->u.raw;
                hashItem.len = hash->len;
            }
            break;
        default:
            PORT_SetError(SEC_ERROR_INVALID_KEY);
            goto done;
    }
    PRINT_BUF(60, (NULL, "hash(es) to be signed", hashItem.data, hashItem.len));

    if (!CryptCreateHash(key->hCryptProv, hashAlg, 0, 0, &hHash)) {
        PR_SetError(SSL_ERROR_SIGN_HASHES_FAILURE, GetLastError());
        goto done;
    }
    argLen = sizeof(hashLen);
    if (!CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashLen, &argLen, 0)) {
        PR_SetError(SSL_ERROR_SIGN_HASHES_FAILURE, GetLastError());
        goto done;
    }
    if (hashLen != hashItem.len) {
        PR_SetError(SSL_ERROR_SIGN_HASHES_FAILURE, 0);
        goto done;
    }
    if (!CryptSetHashParam(hHash, HP_HASHVAL, (BYTE*)hashItem.data, 0)) {
        PR_SetError(SSL_ERROR_SIGN_HASHES_FAILURE, GetLastError());
        goto done;
    }
    if (!CryptSignHash(hHash, key->dwKeySpec, NULL, 0,
                       NULL, &signatureLen) || signatureLen == 0) {
        PR_SetError(SSL_ERROR_SIGN_HASHES_FAILURE, GetLastError());
        goto done;
    }
    buf->data = (unsigned char *)PORT_Alloc(signatureLen);
    if (!buf->data)
        goto done;    /* error code was set. */

    if (!CryptSignHash(hHash, key->dwKeySpec, NULL, 0,
                       (BYTE*)buf->data, &signatureLen)) {
        PR_SetError(SSL_ERROR_SIGN_HASHES_FAILURE, GetLastError());
        goto done;
    }
    buf->len = signatureLen;

    /* CryptoAPI signs in little-endian, so reverse */
    for (i = 0; i < buf->len / 2; ++i) {
        unsigned char tmp = buf->data[i];
        buf->data[i] = buf->data[buf->len - 1 - i];
        buf->data[buf->len - 1 - i] = tmp;
    }
    if (doDerEncode) {
        SECItem   derSig = {siBuffer, NULL, 0};

        /* This also works for an ECDSA signature */
        rv = DSAU_EncodeDerSigWithLen(&derSig, buf, buf->len);
        if (rv == SECSuccess) {
            PORT_Free(buf->data);     /* discard unencoded signature. */
            *buf = derSig;            /* give caller encoded signature. */
        } else if (derSig.data) {
            PORT_Free(derSig.data);
        }
    } else {
        rv = SECSuccess;
    }

    PRINT_BUF(60, (NULL, "signed hashes", buf->data, buf->len));
done:
    if (hHash)
        CryptDestroyHash(hHash);
    if (rv != SECSuccess && buf->data) {
        PORT_Free(buf->data);
        buf->data = NULL;
    }
    return rv;
}
void WinCAPICryptoHashHMAC::setKey(XSECCryptoKey *key) {

	
	BOOL fResult;

	// Use this to initialise the ipadKeyed/opadKeyed values

	if (key->getKeyType() != XSECCryptoKey::KEY_HMAC) {

		throw XSECCryptoException(XSECCryptoException::MDError,
			"WinCAPI:HashHMAC - Non HMAC Key passed to HashHMAC");

	}

	if (m_blockSize > XSEC_MAX_HASH_BLOCK_SIZE) {

		throw XSECCryptoException(XSECCryptoException::MDError,
			"WinCAPI:HashHMAC - Internal error - have got a blocksize bigger than I can handle");

	}

	// Check to see if this is an internal Windows Key
	if (strEquals(key->getProviderName(), DSIGConstants::s_unicodeStrPROVWinCAPI) &&
		((WinCAPICryptoKeyHMAC *) key)->getWinKey() != 0) {

		// Over-ride the local provider for this 

		HCRYPTPROV p = ((WinCAPICryptoKeyHMAC *) key)->getWinKeyProv();
		HCRYPTKEY k = ((WinCAPICryptoKeyHMAC *) key)->getWinKey();

		fResult = CryptCreateHash(
			p,
			CALG_HMAC,
			k,
			0,
			&m_h);

		if (fResult == 0 || m_h == 0) {
			DWORD error = GetLastError();
			throw XSECCryptoException(XSECCryptoException::MDError,
				"WinCAPI:Hash::setKey - Error creating internally keyed hash object"); 
		}

		// Set the HMAC algorithm
		HMAC_INFO hi;

		hi.HashAlgid = m_algId;
		hi.pbInnerString = NULL;		// Use default inner and outer strings
		hi.cbInnerString = 0;
		hi.pbOuterString = NULL;
		hi.cbOuterString = 0;

		fResult = CryptSetHashParam(
			m_h,
			HP_HMAC_INFO,
			(BYTE *) &hi,
			0);

		if (fResult == 0 || m_h == 0) {
			DWORD error = GetLastError();
			throw XSECCryptoException(XSECCryptoException::MDError,
				"WinCAPI:Hash::setKey - Error setting HASH_INFO object"); 
		}



		return;

	}

	// Need to load from raw bit string

	safeBuffer keyBuf;
	unsigned int keyLen = ((XSECCryptoKeyHMAC *) key)->getKey(keyBuf);
	
	if (keyLen > m_blockSize) {

		HCRYPTHASH h;

		fResult = CryptCreateHash(
			m_p,
			m_algId,
			0,
			0,
			&h);

		if (fResult == 0 || h == 0) {
			throw XSECCryptoException(XSECCryptoException::MDError,
				"WinCAPI:Hash::setKey - Error creating hash object"); 
		}

		fResult = CryptHashData(
			h,
			keyBuf.rawBuffer(),
			keyLen,
			0);

		if (fResult == 0 || h == 0) {
			if (h)
				CryptDestroyHash(h);
			throw XSECCryptoException(XSECCryptoException::MDError,
				"WinCAPI:Hash::setKey - Error hashing key data"); 
		}

		BYTE outData[XSEC_MAX_HASH_SIZE];
		DWORD outDataLen = XSEC_MAX_HASH_SIZE;

		CryptGetHashParam(
			h,
			HP_HASHVAL,
			outData,
			&outDataLen,
			0);

		if (fResult == 0 || h == 0) {
			if (h)
				CryptDestroyHash(h);
			throw XSECCryptoException(XSECCryptoException::MDError,
				"WinCAPI:Hash::setKey - Error getting hash result"); 
		}

		keyBuf.sbMemcpyIn(outData, outDataLen);
		keyLen = outDataLen;

		if (h)
			CryptDestroyHash(h);


	}

	// Now create the ipad and opad keyed values
	memcpy(m_ipadKeyed, ipad, m_blockSize);
	memcpy(m_opadKeyed, opad, m_blockSize);

	// XOR with the key
	for (unsigned int i = 0; i < keyLen; ++i) {
		m_ipadKeyed[i] = keyBuf[i] ^ m_ipadKeyed[i];
		m_opadKeyed[i] = keyBuf[i] ^ m_opadKeyed[i];
	}


	// Now create the hash object, and start with the ipad operation
	fResult = CryptCreateHash(
		m_p,
		m_algId,
		0,
		0,
		&m_h);

	if (fResult == 0 || m_h == 0) {
		throw XSECCryptoException(XSECCryptoException::MDError,
			"WinCAPI:HashHMAC - Error creating hash object"); 
	}

	fResult = CryptHashData(
		m_h,
		m_ipadKeyed,
		m_blockSize,
		0);

	if (fResult == 0 || m_h == 0) {
		throw XSECCryptoException(XSECCryptoException::MDError,
			"WinCAPI:HashHMAC - Error performing initial ipad digest"); 
	}

}
bool testSignHash(bool bVerbose){

	BYTE *pbSignature;
	DWORD dwSigLen;
	HCRYPTHASH hHash;
	
	BYTE bHashVal[32+1] = "\x2D\xFB\xC1\xB3\x72\xD8\x9A\x11\x88\xC0\x9C\x52\xE0\xEE\xC6\x1F\xCE\x52\x03\x2A\xB1\x02\x2E\x8E\x67\xEC\xE6\x67\x2B\x04\x3E\xE5";
	if ( bVerbose )
		std::cout << "Supplied hash value is: \n" <<  bHashVal << std::endl;

	if (!(CryptCreateHash(hProv,
					  CALG_GOST_HASH,
					  0,
					  0,
					  &hHash)))
	{   
		if ( bVerbose )
			printf("CryptCreateHash Failed\n");
		return false;
	} 

	if ( !CryptSetHashParam(
		hHash,
		HP_HASHVAL,
		bHashVal,
		0))
	{
		if ( bVerbose )
			printf("CryptSetHashParam Failed\n");
		return false;
	}

	if (!CryptSignHash(hHash,
					AT_SIGNATURE,
					NULL,
					0,
					NULL,
					&dwSigLen))
	{
		if ( bVerbose )
			printf("First call to CryptSignHash Failed\n");
		return false;
	}

	pbSignature = new BYTE[dwSigLen];
	if (!CryptSignHash(hHash,
					AT_SIGNATURE,
					NULL,
					0,
					pbSignature,
					&dwSigLen))
	{
		if ( bVerbose )
			printf("Second call to CryptSignHash Failed\n");
		return false;
	}
	if ( bVerbose )
		std::cout << "Signature:\n" << pbSignature << pbSignature + GOSTR34102001SigLen/2 << std::endl;
	
	BYTE bBenchmarkSignature[64];
	strtobyte( "41AA28D2F1AB148280CD9ED56FEDA41974053554A42767B83AD043FD39DC049301456C64BA4642A1653C235A98A60249BCD6D3F746B631DF928014F6C5BF9C40" , bBenchmarkSignature );
	if ( memcmp ( bBenchmarkSignature, pbSignature, 64 )==0 )
		return TRUE;
	else
		return false;
}
void CEstEIDIEPluginBHO::signWithCSP(BSTR id, BSTR hash, BSTR *signature) {
	LOG_LOCATION;

	HCRYPTPROV cryptoProvider = NULL;
	HCRYPTHASH _hash = NULL ;
	PCCERT_CONTEXT certContext = NULL;
	HCERTSTORE cert_store;
	BOOL must_release_provider;		

	try{
		if(!id || !strlen(CW2A(id))) {
			throw CryptoException(ESTEID_CERT_NOT_FOUND_ERROR);
		}
		EstEID_log("signing started, selected certificate id = %s", CW2A(id));	

#define VALID_HASH_LENGTH 40
		if (_bstr_t(hash).length() != VALID_HASH_LENGTH) {
			throw CryptoException("invalid hash");
		}

		cert_store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_READONLY_FLAG, L"MY");
		if(!cert_store) throw CryptoException();
		
		while(certContext = CertFindCertificateInStore(cert_store, X509_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, certContext)) {
			if(certificateMatchesId(certContext, id)) {
				DWORD key_type = 0;
				if (CryptAcquireCertificatePrivateKey(certContext, CRYPT_ACQUIRE_CACHE_FLAG, 
					NULL, &cryptoProvider, &key_type, &must_release_provider)) {
						BYTE hashBytes[21];
						DWORD hashBytesLength = 20;
						
						CryptStringToBinary(hash, VALID_HASH_LENGTH, CRYPT_STRING_HEX, hashBytes, &hashBytesLength, 0, 0);
						hashBytes[hashBytesLength] = '\0';
						EstEID_log("Number of bytes stored in hashBytes buffer = %u", hashBytesLength);

						CryptoErrorHandler(CryptCreateHash(cryptoProvider, CALG_SHA1, 0, 0, &_hash));
						EstEID_log("CryptCreateHash() set hash object pointer to %p", _hash);  

						CryptoErrorHandler(CryptSetHashParam(_hash, HP_HASHVAL, hashBytes, 0));

						#define SIGNATURE_LENGTH 1024 
						BYTE _signature[SIGNATURE_LENGTH];
						DWORD signatureLength = SIGNATURE_LENGTH;
						INT retCode = CryptSignHash(_hash, AT_SIGNATURE, NULL, 0, _signature, &signatureLength);
						DWORD lastError = GetLastError();
						EstEID_log("CryptSignHash() return code: %u (%s) %x", retCode, retCode ? "SUCCESS" : "FAILURE", lastError);
						if(!retCode) throw CryptoException(lastError);

						CryptDestroyHash(_hash);
						CryptReleaseContext(cryptoProvider, 0);	
						CertFreeCertificateContext(certContext);
						if(must_release_provider) CertCloseStore(cert_store, 0);

						std::stringstream ss;
						for (DWORD i = 0; i < signatureLength; i++) {
							ss << std::hex << std::setfill('0') << std::setw(2) << (short)_signature[signatureLength - i - 1];
						}

						*signature = _bstr_t(ss.str().c_str()).Detach();
				}
				else {
					INT lastError = GetLastError();
					EstEID_log("ERROR: CryptAcquireCertificatePrivateKey() failed, error code = %lXh", GetLastError());
					switch(lastError) {
					case NTE_BAD_PUBLIC_KEY:
						EstEID_log("       error code %lXh: NTE_BAD_PUBLIC_KEY", lastError);
						break;
					case NTE_SILENT_CONTEXT:
						EstEID_log("       error code %lXh: NTE_SILENT_CONTEXT", lastError);
					}
				}				
				break;
			}
		}	
	}
	catch(CryptoException e) {
		*signature = _bstr_t("").Detach();
		if(_hash) CryptDestroyHash(_hash);
		if(cryptoProvider) CryptReleaseContext(cryptoProvider, 0);
		if(certContext) CertFreeCertificateContext(certContext);
		if(must_release_provider && cert_store) CertCloseStore(cert_store, 0);

		throw(CryptoException(e.windowsErrorCode));
	}
}
Beispiel #17
0
/* sign arbitrary data */
static int rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding)
{
    CAPI_DATA *cd = (CAPI_DATA *) rsa->meth->app_data;
    HCRYPTHASH hash;
    DWORD hash_size, len, i;
    unsigned char *buf;

    if (cd == NULL) {
	RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_PASSED_NULL_PARAMETER);
	return 0;
    }
    if (padding != RSA_PKCS1_PADDING) {
	/* AFAICS, CryptSignHash() *always* uses PKCS1 padding. */
	RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE);
	return 0;
    }
    /* Unfortunately, there is no "CryptSign()" function in CryptoAPI, that would
     * be way to straightforward for M$, I guess... So we have to do it this
     * tricky way instead, by creating a "Hash", and load the already-made hash
     * from 'from' into it.  */
    /* For now, we only support NID_md5_sha1 */
    if (flen != SSL_SIG_LENGTH) {
	RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, RSA_R_INVALID_MESSAGE_LENGTH);
	return 0;
    }
    if (!CryptCreateHash(cd->crypt_prov, CALG_SSL3_SHAMD5, 0, 0, &hash)) {
	CRYPTOAPIerr(CRYPTOAPI_F_CRYPT_CREATE_HASH);
	return 0;
    }
    len = sizeof(hash_size);
    if (!CryptGetHashParam(hash, HP_HASHSIZE, (BYTE *) &hash_size, &len, 0)) {
	CRYPTOAPIerr(CRYPTOAPI_F_CRYPT_GET_HASH_PARAM);
        CryptDestroyHash(hash);
	return 0;
    }
    if ((int) hash_size != flen) {
	RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, RSA_R_INVALID_MESSAGE_LENGTH);
        CryptDestroyHash(hash);
	return 0;
    }
    if (!CryptSetHashParam(hash, HP_HASHVAL, (BYTE * ) from, 0)) {
	CRYPTOAPIerr(CRYPTOAPI_F_CRYPT_SET_HASH_PARAM);
        CryptDestroyHash(hash);
	return 0;
    }

    len = RSA_size(rsa);
    buf = malloc(len);
    if (buf == NULL) {
	RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE);
        CryptDestroyHash(hash);
	return 0;
    }
    if (!CryptSignHash(hash, cd->key_spec, NULL, 0, buf, &len)) {
	CRYPTOAPIerr(CRYPTOAPI_F_CRYPT_SIGN_HASH);
        CryptDestroyHash(hash);
        free(buf);
	return 0;
    }
    /* and now, we have to reverse the byte-order in the result from CryptSignHash()... */
    for (i = 0; i < len; i++)
	to[i] = buf[len - i - 1];
    free(buf);

    CryptDestroyHash(hash);
    return len;
}
Beispiel #18
0
/*
 * Compute the Base64-encoded HmacSha256 for the given key and content, optionally URL
 * encoding the Base64 result.
 */
CharHolder
HmacSha256::getEncodedHMAC(const std::string& secretKey, const std::string& signContent, bool urlEncode)
{
	// get the crypt provider
	CryptProviderHolder provider;
	if (!CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT))
		throw FormattedException(GetLastError(), "CryptAcquireContext: %08x", GetLastError());

	// import the supplied key into a crypt library key object using PLAINTEXTKEYBLOB
	typedef struct _PLAINTEXTKEYBLOBSTRUCT {
		BLOBHEADER hdr;
		DWORD dwKeyLen;
	} PLAINTEXTKEYBLOBSTRUCT;

	UCharHolder keyImport(sizeof(PLAINTEXTKEYBLOBSTRUCT) + secretKey.length());
	((PLAINTEXTKEYBLOBSTRUCT*) keyImport.get())->hdr.bType = PLAINTEXTKEYBLOB;
	((PLAINTEXTKEYBLOBSTRUCT*) keyImport.get())->hdr.bVersion = CUR_BLOB_VERSION;
	((PLAINTEXTKEYBLOBSTRUCT*) keyImport.get())->hdr.reserved = 0;
	((PLAINTEXTKEYBLOBSTRUCT*) keyImport.get())->hdr.aiKeyAlg = CALG_RC2;
	((PLAINTEXTKEYBLOBSTRUCT*) keyImport.get())->dwKeyLen = secretKey.length();
	CopyMemory(keyImport.get() + sizeof(PLAINTEXTKEYBLOBSTRUCT), secretKey.c_str(), secretKey.length());

	CryptKeyHolder key;
	if (!CryptImportKey(provider.get(), (const BYTE *) keyImport.get(), sizeof(PLAINTEXTKEYBLOBSTRUCT), 0,
			CRYPT_IPSEC_HMAC_KEY, &key))
		throw FormattedException(GetLastError(), "CryptImportKey(key): %08x", GetLastError());

	// create the hash object using the imported key
	CryptHashHolder hash;
	if (!CryptCreateHash(provider.get(), CALG_HMAC, key.get(), 0, &hash))
		throw FormattedException(GetLastError(), "CryptCreateHash(data): %08x", GetLastError());
	HMAC_INFO hmacInfo;
	ZeroMemory(&hmacInfo, sizeof(HMAC_INFO));
	hmacInfo.HashAlgid = CALG_SHA_256;
	if (!CryptSetHashParam(hash.get(), HP_HMAC_INFO, (BYTE *) &hmacInfo, 0))
		throw FormattedException(GetLastError(), "CryptSetHashParam(data): %08x", GetLastError());

	// hash the content data
	if (!CryptHashData(hash.get(), (const BYTE *) signContent.c_str(), signContent.length(), 0))
		throw FormattedException("CryptHashData(data): %08x", GetLastError());

	// query the size of the hash that will be returned
	DWORD hashSize = 0;
	if (!CryptGetHashParam(hash.get(), HP_HASHVAL, NULL, &hashSize, 0))
		throw FormattedException(GetLastError(), "CryptGetHashParam(data): %08x", GetLastError());

	// create a managed buffer to receive the hash value and then store it there
	UCharHolder buffer(hashSize);
	if (!CryptGetHashParam(hash.get(), HP_HASHVAL, (BYTE *) buffer.get(), &hashSize, 0))
		throw FormattedException(GetLastError(), "CryptGetHashParam(data): %08x", GetLastError());

	// convert hash to Base64, store that in a managed buffer
	size_t base64Size;
	Base64Codec base64Codec;
	char* base64 = base64Codec.base64_encode((const unsigned char *) buffer.get(), buffer.getSize(), &base64Size);
	CharHolder base64Holder(base64, base64Size);

	if (!urlEncode)
		return base64Holder;

	// poor-man's URL encoding for Base64'd data -- only need to worry about + / and =
	int count = 0;
	for (unsigned int i=0; i<base64Holder.getSize(); i++) {
		if ((base64Holder.get()[i] == '+') || (base64Holder.get()[i] == '/') || (base64Holder.get()[i] == '='))
			count++;
	}
	CharHolder urlHolder(base64Holder.getSize() + 2 * count); // 2 additional characters for each + / or =

	int j = 0;
	for (unsigned int i=0; i<base64Holder.getSize(); i++) {
		if (base64Holder.get()[i] == '+') {
			urlHolder.get()[j++] = '%';
			urlHolder.get()[j++] = '2';
			urlHolder.get()[j++] = 'B';
		}
		else if (base64Holder.get()[i] == '/') {
			urlHolder.get()[j++] = '%';
			urlHolder.get()[j++] = '2';
			urlHolder.get()[j++] = 'F';
		}
		else if (base64Holder.get()[i] == '=') {
			urlHolder.get()[j++] = '%';
			urlHolder.get()[j++] = '3';
			urlHolder.get()[j++] = 'D';
		}
		else {
			urlHolder.get()[j++] = base64Holder.get()[i];
		}
	}
	return urlHolder;
}
Beispiel #19
0
struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,
				      size_t key_len)
{
	struct crypto_hash *ctx;
	ALG_ID calg;
	struct {
		BLOBHEADER hdr;
		DWORD len;
		BYTE key[32];
	} key_blob;

	os_memset(&key_blob, 0, sizeof(key_blob));
	switch (alg) {
	case CRYPTO_HASH_ALG_MD5:
		calg = CALG_MD5;
		break;
	case CRYPTO_HASH_ALG_SHA1:
		calg = CALG_SHA;
		break;
	case CRYPTO_HASH_ALG_HMAC_MD5:
	case CRYPTO_HASH_ALG_HMAC_SHA1:
		calg = CALG_HMAC;
		key_blob.hdr.bType = PLAINTEXTKEYBLOB;
		key_blob.hdr.bVersion = CUR_BLOB_VERSION;
		key_blob.hdr.reserved = 0;
		/*
		 * Note: RC2 is not really used, but that can be used to
		 * import HMAC keys of up to 16 byte long.
		 * CRYPT_IPSEC_HMAC_KEY flag for CryptImportKey() is needed to
		 * be able to import longer keys (HMAC-SHA1 uses 20-byte key).
		 */
		key_blob.hdr.aiKeyAlg = CALG_RC2;
		key_blob.len = key_len;
		if (key_len > sizeof(key_blob.key))
			return NULL;
		os_memcpy(key_blob.key, key, key_len);
		break;
	default:
		return NULL;
	}

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

	ctx->alg = alg;

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

	if (calg == CALG_HMAC) {
#ifndef CRYPT_IPSEC_HMAC_KEY
#define CRYPT_IPSEC_HMAC_KEY 0x00000100
#endif
		if (!CryptImportKey(ctx->prov, (BYTE *) &key_blob,
				    sizeof(key_blob), 0, CRYPT_IPSEC_HMAC_KEY,
				    &ctx->key)) {
			cryptoapi_report_error("CryptImportKey");
			CryptReleaseContext(ctx->prov, 0);
			os_free(ctx);
			return NULL;
		}
	}

	if (!CryptCreateHash(ctx->prov, calg, ctx->key, 0, &ctx->hash)) {
		cryptoapi_report_error("CryptCreateHash");
		CryptReleaseContext(ctx->prov, 0);
		os_free(ctx);
		return NULL;
	}

	if (calg == CALG_HMAC) {
		HMAC_INFO info;
		os_memset(&info, 0, sizeof(info));
		switch (alg) {
		case CRYPTO_HASH_ALG_HMAC_MD5:
			info.HashAlgid = CALG_MD5;
			break;
		case CRYPTO_HASH_ALG_HMAC_SHA1:
			info.HashAlgid = CALG_SHA;
			break;
		default:
			/* unreachable */
			break;
		}

		if (!CryptSetHashParam(ctx->hash, HP_HMAC_INFO, (BYTE *) &info,
				       0)) {
			cryptoapi_report_error("CryptSetHashParam");
			CryptDestroyHash(ctx->hash);
			CryptReleaseContext(ctx->prov, 0);
			os_free(ctx);
			return NULL;
		}
	}

	return ctx;
}
Beispiel #20
0
//-----------------------------------------------------------------------------
// swPBKDF2() : implémentation de PBKDF2 RFC 2898 (http://www.ietf.org/rfc/rfc2898.txt)
// Limitée à 2 blocs de 160 bits en sortie, dont seuls les 256 premiers sont
// fournis à l'appelant. Ce résultat est utilisé pour :
// 1) Alimenter la fonction de dérivation de clé AES-256 (CryptDeriveKey)
// 2) Stocker le mot de passe maître
//-----------------------------------------------------------------------------
// Avec 2 blocs, l'algo proposé par la RFC donne :
// DK = T_1 || T_2
// T_1 = F (P, S, c, 1)
// T_2 = F (P, S, c, 2)
// où :
// P = password, an octet string
// S = salt, an octet string
// c = iteration count, a positive integer
// F (P, S, c, i) = U_1 \xor U_2 \xor ... \xor U_c
//   U_1 = PRF (P, S || INT (i))
//   U_2 = PRF (P, U_1)
//   ...
//   U_c = PRF (P, U_{c-1})
//-----------------------------------------------------------------------------
// MERCI A GUILLAUME POUR SA PROPOSITION D'IMPLEMENTATION !
//-----------------------------------------------------------------------------
// [out]bufResult    = pointeur vers un buffer de bytes (alloué par l'appelant)
// [in] bufResultLen = taille de clé souhaitée (max HASH_LENx2)
// [in] szPwd = mot de passe maitre a deriver
// [in] bufSalt = buffer contenant le sel 
// [in] bufSaltLen = taille du buffer de sel (PBKDF2_SALT_LEN)
// [in] iNbIterations = nombre d'itérations
//-----------------------------------------------------------------------------
int swPBKDF2(BYTE *bufResult,int bufResultLen,const char *szPwd,const BYTE *bufSalt,int bufSaltLen,int iNbIterations)
{
    TRACE((TRACE_ENTER,_F_,"bufResultLen=%d iNbIterations=%d",bufResultLen,iNbIterations));
	//TRACE((TRACE_PWD,_F_,"szPwd=%s",szPwd));
	TRACE_BUFFER((TRACE_DEBUG,_F_,(BYTE*)bufSalt,bufSaltLen,"sel"));
	
	int brc;
	int c; // itérations
    int rc=-1;
    HCRYPTKEY hKey=NULL;
    HCRYPTHASH hHMAC=NULL;
    HMAC_INFO  hmacinfo;
    KEYBLOB *pKey=NULL;
	int iKeySize;
    DWORD dwLenHash;
    BYTE bufU_c[HASH_LEN]; // stocke successivement U_1, U_2, ..., U_c
	BYTE bufT[HASH_LEN*2]; // stocke le résultat final : T_1 à l'index 0 et T_2 à l'index HASH_LEN
	BYTE bufSaltWithBlocIndex[PBKDF2_SALT_LEN+4];
	int iBloc;

	if (bufResultLen>HASH_LEN*2) { TRACE((TRACE_ERROR,_F_,"bufResultLen=%d > valeur autorisée HASH_LEN*2=%d",bufResultLen,HASH_LEN*2)); goto end; }
	if (bufSaltLen!=PBKDF2_SALT_LEN) { TRACE((TRACE_ERROR,_F_,"bufSaltLen=%d != valeur imposée PBKDF2_SALT_LEN=%d",bufSaltLen,PBKDF2_SALT_LEN)); goto end; }

    // Création de la clé HMAC en mode PLAINTEXTKEYBLOB, à partir du mot de passe
	iKeySize=sizeof(KEYBLOB)+strlen(szPwd);
    pKey=(KEYBLOB*)malloc(iKeySize);
	if (pKey==NULL) { TRACE((TRACE_ERROR,_F_,"malloc(%d)",iKeySize)); goto end; }
    ZeroMemory(pKey,iKeySize);

	// Création de la clé symétrique pour le HMAC
	// cf. doc de CryptImportKey() -> http://msdn.microsoft.com/en-us/library/aa380207(v=vs.85).aspx :
	// "When importing a Hash-Based Message Authentication Code (HMAC) key, the caller must identify 
	// the imported key as a PLAINTEXTKEYBLOB type"
	// "The HMAC algorithms do not have their own algorithm identifiers; use CALG_RC2 instead. 
	// CRYPT_IPSEC_HMAC_KEY allows the import of RC2 keys longer than 16 bytes."
	// cf. tests vectors de la RFC 2202 HMAC-SHA1
    pKey->header.bType=PLAINTEXTKEYBLOB;
    pKey->header.bVersion=CUR_BLOB_VERSION;
    pKey->header.reserved=0;
    pKey->header.aiKeyAlg=CALG_RC2;
    pKey->dwKeySize=strlen(szPwd);
	memcpy(pKey->KeyData,szPwd,pKey->dwKeySize);

	// test case 1 RFC 2202 HMAC-SHA1
	/*pKey->dwKeySize=20;
	memset(pKey->KeyData,0x0b,pKey->dwKeySize);*/
	// fin test case 1 RFC 2202 HMAC-SHA1
	// test case 7 RFC 2202 HMAC-SHA1
	/*pKey->dwKeySize=80;
	memset(pKey->KeyData,0xaa,pKey->dwKeySize);*/
	// fin test case 7 RFC 2202 HMAC-SHA1

	//TRACE_BUFFER((TRACE_PWD,_F_,(BYTE*)pKey,iKeySize,"pKey (iKeySize=%d)",iKeySize));
    brc= CryptImportKey(ghProv,(LPBYTE)pKey,iKeySize,NULL,CRYPT_IPSEC_HMAC_KEY,&hKey);
    if (!brc) { TRACE((TRACE_ERROR,_F_,"CryptImportKey()=0x%08lx",GetLastError())); goto end; }

	// Initialisation du buffer resultat a zero 
	ZeroMemory(bufT,HASH_LEN*2);

	// Itération pour sortir 2 blocs de 160 bits chacun (T_1 et T_2)
	for (iBloc=1;iBloc<=2;iBloc++) 
	{
		// concaténation de l'index de bloc au sel
		memcpy(bufSaltWithBlocIndex,bufSalt,PBKDF2_SALT_LEN);
		bufSaltWithBlocIndex[bufSaltLen]=0x00;
		bufSaltWithBlocIndex[bufSaltLen+1]=0x00;
		bufSaltWithBlocIndex[bufSaltLen+2]=0x00;
		bufSaltWithBlocIndex[bufSaltLen+3]=(BYTE)iBloc;
		TRACE_BUFFER((TRACE_DEBUG,_F_,bufSaltWithBlocIndex,bufSaltLen+4,"bufSaltWithBlocIndex"));

	    // Création du HMAC
		// cf. http://msdn.microsoft.com/en-us/library/aa382379(VS.85).aspx
		
		brc=CryptCreateHash(ghProv,CALG_HMAC,hKey,0,&hHMAC);
		if (!brc) { TRACE((TRACE_ERROR,_F_,"CryptCreateHash()=0x%08lx",GetLastError())); goto end; }
    
		// Initialisation des paramètres du HMAC
		ZeroMemory(&hmacinfo,sizeof(hmacinfo));
		hmacinfo.HashAlgid=CALG_SHA1;
		brc=CryptSetHashParam(hHMAC,HP_HMAC_INFO, (BYTE*)&hmacinfo,0);
		if (!brc) { TRACE((TRACE_ERROR,_F_,"CryptSetHashParam()=0x%08lx",GetLastError())); goto end; }

		// test case 1 RFC 2202 HMAC-SHA1
		/*brc=CryptHashData(hHMAC,(const BYTE*)"Hi There",8, 0);
		if (!brc) { TRACE((TRACE_ERROR,_F_,"CryptCreateHash()=0x%08lx",GetLastError())); goto end; }
		brc=CryptGetHashParam(hHMAC,HP_HASHVAL,bufU_c,&dwLenHash,0);
		if (!brc) { TRACE((TRACE_ERROR,_F_,"CryptGetHashParam()=0x%08lx",GetLastError())); goto end; }
		TRACE_BUFFER((TRACE_DEBUG,_F_,bufU_c,HASH_LEN,"Test case 1 RFC 2202 HMAC-SHA1"));
		if (brc) goto end;*/
		// fin test case 1 RFC 2202 HMAC-SHA1
		// test case 7 RFC 2202 HMAC-SHA1
		/*brc=CryptHashData(hHMAC,(const BYTE*)"Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data",73, 0);
		if (!brc) { TRACE((TRACE_ERROR,_F_,"CryptCreateHash()=0x%08lx",GetLastError())); goto end; }
		brc=CryptGetHashParam(hHMAC,HP_HASHVAL,bufU_c,&dwLenHash,0);
		if (!brc) { TRACE((TRACE_ERROR,_F_,"CryptGetHashParam()=0x%08lx",GetLastError())); goto end; }
		TRACE_BUFFER((TRACE_DEBUG,_F_,bufU_c,HASH_LEN,"Test case 1 RFC 2202 HMAC-SHA1"));
		if (brc) goto end;*/
		// fin test case 7 RFC 2202 HMAC-SHA1

		// HMAC du sel enrichi de l'id de bloc
		brc=CryptHashData(hHMAC,bufSaltWithBlocIndex,bufSaltLen+4, 0);
		if (!brc) { TRACE((TRACE_ERROR,_F_,"CryptHashData(bufSaltWithBlocIndex)=0x%08lx",GetLastError())); goto end; }
	
		// Récupération du hash
		dwLenHash=sizeof(bufU_c);
		brc=CryptGetHashParam(hHMAC,HP_HASHVAL,bufU_c,&dwLenHash,0);
		if (!brc) { TRACE((TRACE_ERROR,_F_,"CryptGetHashParam(bufU_1)=0x%08lx",GetLastError())); goto end; }
		TRACE_BUFFER((TRACE_DEBUG,_F_,bufU_c,HASH_LEN,"bufU_1"));
		
		// Destruction du HMAC
		brc=CryptDestroyHash(hHMAC);
		if (!brc) { TRACE((TRACE_ERROR,_F_,"CryptDestroyHash()=0x%08lx",GetLastError())); goto end; }
		hHMAC=NULL;

		// XOR dans le buffer résultat
		swXORBuff(bufT+(iBloc-1)*HASH_LEN,bufU_c,HASH_LEN);

		// Iterations
		for (c=2;c<=iNbIterations;c++) // on démarre à 1, la 1ère itération étant faite précédemment hors de la boucle
		{
		    // Création du HMAC
			brc=CryptCreateHash(ghProv,CALG_HMAC,hKey,0,&hHMAC);
			if (!brc) { TRACE((TRACE_ERROR,_F_,"CryptCreateHash()=0x%08lx",GetLastError())); goto end; }
    
			// Initialisation des paramètres du HMAC
			ZeroMemory(&hmacinfo,sizeof(hmacinfo));
			hmacinfo.HashAlgid=CALG_SHA1;
			brc=CryptSetHashParam(hHMAC,HP_HMAC_INFO,(BYTE*)&hmacinfo,0);
			if (!brc) { TRACE((TRACE_ERROR,_F_,"CryptSetHashParam()=0x%08lx",GetLastError())); goto end; }

			// HMAC du résultat de l'itération précédente
			brc=CryptHashData(hHMAC,bufU_c,HASH_LEN,0);
			if (!brc) { TRACE((TRACE_ERROR,_F_,"CryptHashData(bufU_%d)=0x%08lx",c,GetLastError())); goto end; }

			// Recup du hash
			brc=CryptGetHashParam(hHMAC,HP_HASHVAL,bufU_c,&dwLenHash,0);
			if (!brc) { TRACE((TRACE_ERROR,_F_,"CryptGetHashParam(bufU_%d)=0x%08lx",c,GetLastError())); goto end; }

			// Détruire le HMAC
			brc=CryptDestroyHash(hHMAC);
			if (!brc) { TRACE((TRACE_ERROR,_F_,"CryptDestroyHash()=0x%08lx",GetLastError())); goto end; }
			hHMAC=NULL;

			// XOR dans le resultat
			swXORBuff(bufT+(iBloc-1)*HASH_LEN,bufU_c,HASH_LEN);
		}
		TRACE_BUFFER((TRACE_DEBUG,_F_,bufT+(iBloc-1)*HASH_LEN,HASH_LEN,"bufT_%d",iBloc));
	}
	// Les 2 blocs sont alimentés, on extrait les bufResultLen pour alimenter bufResult
	memcpy(bufResult,bufT,bufResultLen);
	TRACE_BUFFER((TRACE_DEBUG,_F_,bufResult,bufResultLen,"bufResult"));
	rc=0;
end:
	if (hHMAC!=NULL) CryptDestroyHash(hHMAC);
    if (hKey!=NULL) CryptDestroyKey(hKey);
    if (pKey!=NULL) free(pKey);
	
	TRACE((TRACE_LEAVE,_F_,"rc=%d",rc));   
    return rc;
}
Beispiel #21
0
static
int capi_sign(gnutls_privkey_t key, void *userdata,
	      const gnutls_datum_t * raw_data, gnutls_datum_t * signature)
{
	priv_st *priv = (priv_st *) userdata;
	ALG_ID Algid;
	HCRYPTHASH hHash = NULL;
	uint8_t digest[MAX_HASH_SIZE];
	unsigned int digest_size;
	gnutls_digest_algorithm_t algo;
	DWORD size1 = 0, sizesize = sizeof(DWORD);
	DWORD ret_sig = 0;
	int ret;

	signature->data = NULL;
	signature->size = 0;

	digest_size = raw_data->size;

	switch (digest_size) {
	case 16:
		Algid = CALG_MD5;
		break;
		//case 35:  size=20;                                    // DigestInfo SHA1
	case 20:
		Algid = CALG_SHA1;
		break;
		//case 51:  size=32;                                    // DigestInto SHA-256
	case 32:
		Algid = CALG_SHA_256;
		break;
	case 36:
		Algid = CALG_SSL3_SHAMD5;
		break;
	case 48:
		Algid = CALG_SHA_384;
		break;
	case 64:
		Algid = CALG_SHA_512;
		break;
	default:
		digest_size = sizeof(digest);
		ret =
		    decode_ber_digest_info(raw_data, &algo, digest,
					   &digest_size);
		if (ret < 0)
			return gnutls_assert_val(ret);

		switch (algo) {
		case GNUTLS_DIG_SHA1:
			Algid = CALG_SHA1;
			break;
#ifdef NCRYPT_SHA224_ALGORITHM
		case GNUTLS_DIG_SHA224:
			Algid = CALG_SHA_224;
			break;
#endif
		case GNUTLS_DIG_SHA256:
			Algid = CALG_SHA_256;
			break;
		case GNUTLS_DIG_SHA384:
			Algid = CALG_SHA_384;
			break;
		case GNUTLS_DIG_SHA512:
			Algid = CALG_SHA_512;
			break;
		default:
			return
			    gnutls_assert_val(GNUTLS_E_UNKNOWN_HASH_ALGORITHM);
		}
	}

	if (!CryptCreateHash(priv->hCryptProv, Algid, 0, 0, &hHash)) {
		gnutls_assert();
		_gnutls_debug_log("error in create hash: %d\n",
				  (int)GetLastError());
		ret = GNUTLS_E_PK_SIGN_FAILED;
		goto fail;
	}

	if (!CryptSetHashParam(hHash, HP_HASHVAL, digest, 0)) {
		gnutls_assert();
		_gnutls_debug_log("error in set hash val: %d\n",
				  (int)GetLastError());
		ret = GNUTLS_E_PK_SIGN_FAILED;
		goto fail;
	}

	if (!CryptGetHashParam
	    (hHash, HP_HASHSIZE, (BYTE *) & size1, &sizesize, 0)
	    || digest_size != size1) {
		gnutls_assert();
		_gnutls_debug_log("error in hash size: %d\n", (int)size1);
		ret = GNUTLS_E_PK_SIGN_FAILED;
		goto fail;
	}

	if (!CryptSignHash(hHash, priv->dwKeySpec, NULL, 0, NULL, &ret_sig)) {
		gnutls_assert();
		_gnutls_debug_log("error in pre-signing: %d\n",
				  (int)GetLastError());
		ret = GNUTLS_E_PK_SIGN_FAILED;
		goto fail;
	}

	signature->size = ret_sig;
	signature->data = (unsigned char *)gnutls_malloc(signature->size);

	if (signature->data == NULL)
		return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);

	if (!CryptSignHash
	    (hHash, priv->dwKeySpec, NULL, 0, signature->data, &ret_sig)) {
		gnutls_assert();
		_gnutls_debug_log("error in signing: %d\n",
				  (int)GetLastError());
		ret = GNUTLS_E_PK_SIGN_FAILED;
		goto fail;
	}

	memrev(signature->data, signature->size);

	CryptDestroyHash(hHash);
	signature->size = ret_sig;

	return 0;
 fail:
	if (hHash != 0)
		CryptDestroyHash(hHash);
	gnutls_free(signature->data);
	return ret;
}
Beispiel #22
0
int capi_rsa_sign(int dtype, const unsigned char *m, unsigned int m_len,
             unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
	{
	ALG_ID alg;
	HCRYPTHASH hash;
	DWORD slen;
	unsigned int i;
	int ret = -1;
	CAPI_KEY *capi_key;
	CAPI_CTX *ctx;

	ctx = ENGINE_get_ex_data(rsa->engine, capi_idx);

	CAPI_trace(ctx, "Called CAPI_rsa_sign()\n");

	capi_key = RSA_get_ex_data(rsa, rsa_capi_idx);
	if (!capi_key)
		{
		CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_GET_KEY);
		return -1;
		}
/* Convert the signature type to a CryptoAPI algorithm ID */
	switch(dtype)
		{
	case NID_sha1:
		alg = CALG_SHA1;
		break;

	case NID_md5:
		alg = CALG_MD5;
		break;

	case NID_md5_sha1:
		alg = CALG_SSL3_SHAMD5;
		break;
	default:
		{
		char algstr[10];
		BIO_snprintf(algstr, 10, "%lx", dtype);
		CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_UNSUPPORTED_ALGORITHM_NID);
		ERR_add_error_data(2, "NID=0x", algstr);
		return -1;
		}
	}



/* Create the hash object */
	if(!CryptCreateHash(capi_key->hprov, alg, 0, 0, &hash))
		{
		CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_CREATE_HASH_OBJECT);
		capi_addlasterror();
		return -1;
		}
/* Set the hash value to the value passed */

	if(!CryptSetHashParam(hash, HP_HASHVAL, (unsigned char *)m, 0))
		{
		CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_SET_HASH_VALUE);
		capi_addlasterror();
		goto err;
		}


/* Finally sign it */
	slen = RSA_size(rsa);
	if(!CryptSignHashA(hash, capi_key->keyspec, NULL, 0, sigret, &slen))
		{
		CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_ERROR_SIGNING_HASH);
		capi_addlasterror();
		goto err;
		}
	else
		{
		ret = 1;
		/* Inplace byte reversal of signature */
		for(i = 0; i < slen / 2; i++)
			{
			unsigned char c;
			c = sigret[i];
			sigret[i] = sigret[slen - i - 1];
			sigret[slen - i - 1] = c;
			}
		*siglen = slen;
		}

	/* Now cleanup */

err:
	CryptDestroyHash(hash);

	return ret;
	}
Beispiel #23
0
static DSA_SIG *capi_dsa_do_sign(const unsigned char *digest, int dlen,
								DSA *dsa)
	{
	HCRYPTHASH hash;
	DWORD slen;
	DSA_SIG *ret = NULL;
	CAPI_KEY *capi_key;
	CAPI_CTX *ctx;
	unsigned char csigbuf[40];

	ctx = ENGINE_get_ex_data(dsa->engine, capi_idx);

	CAPI_trace(ctx, "Called CAPI_dsa_do_sign()\n");

	capi_key = DSA_get_ex_data(dsa, dsa_capi_idx);

	if (!capi_key)
		{
		CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_GET_KEY);
		return NULL;
		}

	if (dlen != 20)
		{
		CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_INVALID_DIGEST_LENGTH);
		return NULL;
		}

	/* Create the hash object */
	if(!CryptCreateHash(capi_key->hprov, CALG_SHA1, 0, 0, &hash))
		{
		CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_CREATE_HASH_OBJECT);
		capi_addlasterror();
		return NULL;
		}

	/* Set the hash value to the value passed */
	if(!CryptSetHashParam(hash, HP_HASHVAL, (unsigned char *)digest, 0))
		{
		CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_SET_HASH_VALUE);
		capi_addlasterror();
		goto err;
		}


	/* Finally sign it */
	slen = sizeof(csigbuf);
	if(!CryptSignHashA(hash, capi_key->keyspec, NULL, 0, csigbuf, &slen))
		{
		CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_ERROR_SIGNING_HASH);
		capi_addlasterror();
		goto err;
		}
	else
		{
		ret = DSA_SIG_new();
		if (!ret)
			goto err;
		ret->r = BN_new();
		ret->s = BN_new();
		if (!ret->r || !ret->s)
			goto err;
		if (!lend_tobn(ret->r, csigbuf, 20)
			|| !lend_tobn(ret->s, csigbuf + 20, 20))
			{
			DSA_SIG_free(ret);
			ret = NULL;
			goto err;
			}
		}

	/* Now cleanup */

err:
	OPENSSL_cleanse(csigbuf, 40);
	CryptDestroyHash(hash);
	return ret;
	}
Beispiel #24
0
static int
xmlSecMSCryptoHmacSetKey(xmlSecTransformPtr transform, xmlSecKeyPtr key) {
    xmlSecMSCryptoHmacCtxPtr ctx;
    xmlSecKeyDataPtr value;
    xmlSecBufferPtr buffer;
    HMAC_INFO hmacInfo;
    int ret;

    xmlSecAssert2(xmlSecMSCryptoHmacCheckId(transform), -1);
    xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1);
    xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecMSCryptoHmacSize), -1);
    xmlSecAssert2(key != NULL, -1);

    ctx = xmlSecMSCryptoHmacGetCtx(transform);
    xmlSecAssert2(ctx != NULL, -1);
    xmlSecAssert2(ctx->ctxInitialized == 0, -1);
    xmlSecAssert2(ctx->provider != 0, -1);
    xmlSecAssert2(ctx->pubPrivKey != 0, -1);
    xmlSecAssert2(ctx->cryptKey == 0, -1);
    xmlSecAssert2(ctx->mscHash == 0, -1);

    value = xmlSecKeyGetValue(key);
    xmlSecAssert2(xmlSecKeyDataCheckId(value, xmlSecMSCryptoKeyDataHmacId), -1);

    buffer = xmlSecKeyDataBinaryValueGetBuffer(value);
    xmlSecAssert2(buffer != NULL, -1);

    if(xmlSecBufferGetSize(buffer) == 0) {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
                    NULL,
                    XMLSEC_ERRORS_R_INVALID_KEY_DATA_SIZE,
                    "keySize=0");
        return(-1);
    }

    xmlSecAssert2(xmlSecBufferGetData(buffer) != NULL, -1);

    /* Import this key and get an HCRYPTKEY handle. 
     * 
     * HACK!!! HACK!!! HACK!!! 
     * 
     * Using CALG_RC2 instead of CALG_HMAC for the key algorithm so we don't want to check key length
     */
    if (!xmlSecMSCryptoImportPlainSessionBlob(ctx->provider,
        ctx->pubPrivKey,
        CALG_RC2,
        xmlSecBufferGetData(buffer),
        xmlSecBufferGetSize(buffer),
        FALSE,
        &(ctx->cryptKey)
        ) || (ctx->cryptKey == 0))  {

        xmlSecError(XMLSEC_ERRORS_HERE,
                    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
                    "xmlSecMSCryptoImportPlainSessionBlob",
                    XMLSEC_ERRORS_R_XMLSEC_FAILED,
                    XMLSEC_ERRORS_NO_MESSAGE);
        return(-1);
    }   

    /* create hash */
    ret = CryptCreateHash(ctx->provider,
        CALG_HMAC,
        ctx->cryptKey,
        0,
        &(ctx->mscHash));
    if((ret == 0) || (ctx->mscHash == 0)) {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
                    "CryptCreateHash",
                    XMLSEC_ERRORS_R_CRYPTO_FAILED,
                    XMLSEC_ERRORS_NO_MESSAGE);
        return(-1);
    }

    /* set parameters */
    memset(&hmacInfo, 0, sizeof(hmacInfo));
    hmacInfo.HashAlgid = ctx->alg_id;
    ret = CryptSetHashParam(ctx->mscHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
    if(ret == 0) {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
                    "CryptSetHashParam",
                    XMLSEC_ERRORS_R_CRYPTO_FAILED,
                    XMLSEC_ERRORS_NO_MESSAGE);
        return(-1);
    }

    /* done */
    ctx->ctxInitialized = 1;
    return(0);
}