// // Calculates the sha256 from a block of data. Copy // pasta from https://msdn.microsoft.com/en-us/library/windows/desktop/aa382379(v=vs.85).aspx // bool GetSha256(void * data, size_t dataSize, char * sha256, size_t hashSize) { HCRYPTPROV hProv = NULL; HCRYPTHASH hHash = NULL; PBYTE pbHash = NULL; DWORD dwDataLen = 0; bool retCode = false; if (hashSize < 65) { goto cleanup; } if (!CryptAcquireContext( &hProv, // handle of the CSP NULL, // key container name NULL, // CSP name PROV_RSA_AES, // provider type CRYPT_VERIFYCONTEXT)) // no key access is requested { printf(" Error in AcquireContext 0x%08x \n", GetLastError()); goto cleanup; } if (!CryptCreateHash( hProv, // handle of the CSP CALG_SHA_256, // hash algorithm to use 0, // hash key 0, // reserved &hHash)) // address of hash object handle { printf("Error in CryptCreateHash 0x%08x \n", GetLastError()); goto cleanup; } if (!CryptHashData( hHash, // handle of the hash object (const BYTE*)data, // password to hash (DWORD)dataSize, // number of bytes of data to add 0)) // flags { printf("Error in CryptHashData 0x%08x \n", GetLastError()); goto cleanup; } if (!CryptGetHashParam( hHash, // handle of the hash object HP_HASHVAL, // query on the hash value NULL, // filled on second call &dwDataLen, // length, in bytes, of the hash 0)) { printf("Error in CryptGetHashParam 0x%08x \n", GetLastError()); goto cleanup; } pbHash = (BYTE*)malloc(dwDataLen); if (NULL == pbHash) { printf("unable to allocate memory\n"); goto cleanup; } if (!CryptGetHashParam( hHash, // handle of the hash object HP_HASHVAL, // query on the hash value pbHash, // pointer to the hash value &dwDataLen, // length, in bytes, of the hash 0)) { printf("Error in CryptGetHashParam 0x%08x \n", GetLastError()); goto cleanup; } retCode = true; ZeroMemory(sha256, hashSize); for (DWORD i = 0; i < dwDataLen; i++) { sprintf_s(&sha256[i * 2], 3, "%2.2X", pbHash[i]); } // Free resources. cleanup: if (hHash) CryptDestroyHash(hHash); if (hProv) CryptReleaseContext(hProv, 0); if (pbHash) free(pbHash); return retCode; }
HRESULT assembly_get_pubkey_token(ASSEMBLY *assembly, LPWSTR *token) { ULONG i, size; LONG offset; BYTE *hashdata, *pubkey, *ptr; HCRYPTPROV crypt; HCRYPTHASH hash; BYTE tokbytes[BYTES_PER_TOKEN]; HRESULT hr = E_FAIL; LPWSTR tok; DWORD idx; *token = NULL; offset = assembly->tables[TableFromToken(mdtAssembly)].offset; if (offset == -1) return E_FAIL; ptr = assembly_data_offset(assembly, offset); if (!ptr) return E_FAIL; ptr += FIELD_OFFSET(ASSEMBLYTABLE, PublicKey); if (assembly->blobsz == sizeof(DWORD)) idx = *(DWORD *)ptr; else idx = *(WORD *)ptr; pubkey = assembly_get_blob(assembly, idx, &size); if (!CryptAcquireContextA(&crypt, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) return E_FAIL; if (!CryptCreateHash(crypt, CALG_SHA1, 0, 0, &hash)) return E_FAIL; if (!CryptHashData(hash, pubkey, size, 0)) return E_FAIL; size = 0; if (!CryptGetHashParam(hash, HP_HASHVAL, NULL, &size, 0)) return E_FAIL; hashdata = HeapAlloc(GetProcessHeap(), 0, size); if (!hashdata) { hr = E_OUTOFMEMORY; goto done; } if (!CryptGetHashParam(hash, HP_HASHVAL, hashdata, &size, 0)) goto done; for (i = size - 1; i >= size - 8; i--) tokbytes[size - i - 1] = hashdata[i]; tok = HeapAlloc(GetProcessHeap(), 0, (TOKEN_LENGTH + 1) * sizeof(WCHAR)); if (!tok) { hr = E_OUTOFMEMORY; goto done; } token_to_str(tokbytes, tok); *token = tok; hr = S_OK; done: HeapFree(GetProcessHeap(), 0, hashdata); CryptDestroyHash(hash); CryptReleaseContext(crypt, 0); return hr; }
/** * 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); if (alg == 0) { log0(0, 0, 0, "Invalid hashtype"); return 0; } 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; }
void CWE328_Reversible_One_Way_Hash__w32_MD5_05_bad() { if(staticTrue) { { HCRYPTPROV hCryptProv; HCRYPTHASH hHash; FILE *pFile = NULL; char password[PASSWORD_INPUT_SIZE]; UCHAR savedHash[MD5_SUM_SIZE], calcHash[MD5_SUM_SIZE]; DWORD hashSize; char *replace; size_t i; pFile = fopen("password.txt", "r"); if (pFile == NULL) { exit(1); } for (i = 0; i < MD5_SUM_SIZE; i++) { ULONG val; if (fscanf(pFile, "%02x", &val) != 1) { fclose(pFile); exit(1); } if (val > 0xff) /* EXPECTED INCIDENTAL: Reliance on data memory layout, we assume char is at least 8 bits */ { fclose(pFile); exit(1); } savedHash[i] = (UCHAR)val; } if (pFile) { fclose(pFile); } if (fgets(password, PASSWORD_INPUT_SIZE, stdin) == NULL) { exit(1); } replace = strchr(password, '\r'); if (replace) { *replace = '\0'; } replace = strchr(password, '\n'); if (replace) { *replace = '\0'; } if (!CryptAcquireContextW(&hCryptProv, 0, 0, PROV_RSA_FULL, 0)) { exit(1); } /* FLAW: Use a reversible hash (MD5) */ if (!CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &hHash)) { CryptReleaseContext(hCryptProv, 0); exit(1); } /* EXPECTED INCIDENTAL: We did not salt the password, that may raise flags, * the password hash was not securely transmitted (via one form or another), * that may raise flags */ if (!CryptHashData(hHash, (BYTE*)password, strlen(password), 0)) { CryptDestroyHash(hHash); CryptReleaseContext(hCryptProv, 0); exit(1); } hashSize = MD5_SUM_SIZE; if (!CryptGetHashParam(hHash, HP_HASHVAL, (BYTE*)calcHash, &hashSize, 0)) { CryptDestroyHash(hHash); CryptReleaseContext(hCryptProv, 0); exit(1); } if (memcmp(savedHash, calcHash, MD5_SUM_SIZE * sizeof(UCHAR)) == 0) { printLine("Access granted"); } else { printLine("Access denied"); } if (hHash) { CryptDestroyHash(hHash); } if (hCryptProv) { CryptReleaseContext(hCryptProv, 0); } } } }
char * mit_krb5_pkinit_cert_hash_str(const mit_krb5_data *cert) { #ifdef HAVE_COMMONCRYPTO_COMMONDIGEST_H CC_SHA1_CTX ctx; char *outstr, *cpOut; unsigned char digest[CC_SHA1_DIGEST_LENGTH]; unsigned i; LOG_ENTRY(); CC_SHA1_Init(&ctx); CC_SHA1_Update(&ctx, cert->data, cert->length); CC_SHA1_Final(digest, &ctx); cpOut = outstr = (char *)malloc((2 * CC_SHA1_DIGEST_LENGTH) + 1); if(outstr == NULL) return NULL; for(i = 0; i < CC_SHA1_DIGEST_LENGTH; i++, cpOut += 2) sprintf(cpOut, "%02X", (unsigned)digest[i]); *cpOut = '\0'; return outstr; #elif defined(_WIN32) HCRYPTPROV hProv = 0; HCRYPTHASH hHash = 0; char *outstr = NULL; char *outpos; size_t cch_left; BYTE *hash = NULL; DWORD hashSize = 0; DWORD len, i; LOG_ENTRY(); if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SIG, CRYPT_VERIFYCONTEXT)) { LOG_LASTERROR("CryptAcquireContext failed"); goto done; } if (!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash)) { LOG_LASTERROR("CryptCreateHash failed"); goto done; } if (!CryptHashData(hHash, (BYTE *) cert->data, cert->length, 0)) { LOG_LASTERROR("CryptHashData failed"); goto done; } len = sizeof(hashSize); if (!CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE *) &hashSize, &len, 0)) { LOG_LASTERROR("CryptGetHashParam failed while getting hash size"); goto done; } hash = malloc(hashSize); if (hash == NULL) { goto done; } len = hashSize; if (!CryptGetHashParam(hHash, HP_HASHVAL, hash, &len, 0)) { LOG_LASTERROR("CryptGetHashParam failed while getting hash"); goto done; } outstr = malloc(hashSize * 2 + 1); if (outstr == NULL) { goto done; } outpos = outstr; cch_left = hashSize * 2 + 1; for (i = 0; i < hashSize; i++) { StringCchPrintfExA(outpos, cch_left, &outpos, &cch_left, STRSAFE_FILL_ON_FAILURE, "%02X", (unsigned) hash[i]); } *outpos = '\0'; done: if (hHash != 0) CryptDestroyHash(hHash); if (hProv != 0) CryptReleaseContext(hProv, 0); if (hash != NULL) free(hash); return outstr; #endif }
//----------------------------------------------------------------------------- // swCryptSaltAndHashPassword() // N'EST PLUS UTILISEE A PARTIR DE LA VERSION 0.93 ET PBKDF2 //----------------------------------------------------------------------------- // Sale et hashe le mot de passe maitre // si le buffer de sel est NULL, génération aléa (création, sinon c'est une vérif) // 0.72 : nouveau paramètre iNbIterations (nb d'itérations de hashage) // 0.73 : nouveau paramètre bV72 pour correction itération mal implémentée en 0.72 //----------------------------------------------------------------------------- int swCryptSaltAndHashPassword(char *bufSalt, const char *szPwd,char **pszHashedPwd,int iNbIterations,bool bV72) { TRACE((TRACE_ENTER,_F_,"bufSalt=0x%08lx",bufSalt)); int rc=-1; BOOL brc; HCRYPTHASH hHash=NULL; DWORD lenPwd; DWORD lenHashedPwd; unsigned char *bufSaltedPwd=NULL; DWORD lenSaltedPwd; unsigned char bufHash[HASH_LEN]; DWORD lenHash; // 0.73 unsigned char bufToHash[HASH_LEN]; lenPwd=strlen(szPwd); lenSaltedPwd=SALT_LEN+lenPwd; lenHashedPwd=SALT_LEN*2+HASH_LEN*2+1; int i; // allocation du buffer pour stocker le sel et le mot de passe // c'est ce buffer qu'on hache ensuite bufSaltedPwd=(unsigned char*)malloc(lenSaltedPwd); if (bufSaltedPwd==NULL) { TRACE((TRACE_ERROR,_F_,"malloc(%d)",lenSaltedPwd)); goto end; } if (bufSalt==NULL) // génère le sel { brc = CryptGenRandom(ghProv,SALT_LEN,bufSaltedPwd); if (!brc) { TRACE((TRACE_ERROR,_F_,"CryptGenRandom()")); goto end; } } else // utilise le sel passé en paramètre { memcpy(bufSaltedPwd,bufSalt,SALT_LEN); } TRACE_BUFFER((TRACE_DEBUG,_F_,bufSaltedPwd,SALT_LEN,"sel")); // concatène le mot de passe memcpy(bufSaltedPwd+SALT_LEN,szPwd,lenPwd); //TRACE_BUFFER((TRACE_PWD,_F_,bufSaltedPwd,lenSaltedPwd,"à hacher")); // 0.72 (trace déplacée) // hashe le tout brc= CryptCreateHash(ghProv,CALG_SHA1,0,0,&hHash); if (!brc) { TRACE((TRACE_ERROR,_F_,"CryptCreateHash()")); goto end; } if (bV72) { // 0.72 : boucle hashage anti-cassage de mot de passe // foireux, j'ai oublié de réinjecter le hash... honte à moi // corrigé ci-dessous en 0.73 for (i=0;i<iNbIterations;i++) { brc = CryptHashData(hHash,bufSaltedPwd,lenSaltedPwd,0); if (!brc) { TRACE((TRACE_ERROR,_F_,"CryptHashData()")); goto end; } } // récupère la valeur du hash lenHash=sizeof(bufHash); brc = CryptGetHashParam(hHash,HP_HASHVAL,bufHash,&lenHash,0); if (!brc) { TRACE((TRACE_ERROR,_F_,"CryptGetHashParam(HP_HASHVAL)")); goto end; } } else // version 073 corrige la 0.72... { // hashe le mot de passe brc = CryptHashData(hHash,bufSaltedPwd,lenSaltedPwd,0); if (!brc) { TRACE((TRACE_ERROR,_F_,"CryptHashData()")); goto end; } // récupère la valeur du hash lenHash=sizeof(bufHash); brc = CryptGetHashParam(hHash,HP_HASHVAL,bufHash,&lenHash,0); if (!brc) { TRACE((TRACE_ERROR,_F_,"CryptGetHashParam(HP_HASHVAL)")); goto end; } CryptDestroyHash(hHash); hHash=NULL; // itérations = hash le hash iNbIterations fois. for (i=0;i<iNbIterations;i++) { // copie le résultat du hash dans le buffer à hasher pour itérer memcpy(bufToHash,bufHash,lenHash); brc= CryptCreateHash(ghProv,CALG_SHA1,0,0,&hHash); if (!brc) { TRACE((TRACE_ERROR,_F_,"CryptCreateHash()")); goto end; } // hashe le hash brc = CryptHashData(hHash,bufToHash,lenHash,0); if (!brc) { TRACE((TRACE_ERROR,_F_,"CryptHashData()")); goto end; } // récupère la valeur du hash lenHash=sizeof(bufHash); brc = CryptGetHashParam(hHash,HP_HASHVAL,bufHash,&lenHash,0); if (!brc) { TRACE((TRACE_ERROR,_F_,"CryptGetHashParam(HP_HASHVAL)")); goto end; } CryptDestroyHash(hHash); hHash=NULL; } } TRACE_BUFFER((TRACE_DEBUG,_F_,bufHash,lenHash,"hash")); // il reste à convertir chaque morceau (sel et résultat du hash) en base 64 // et à concaténer les 2 // allocation de la destination *pszHashedPwd=(char*)malloc(lenHashedPwd); if (*pszHashedPwd==NULL) { TRACE((TRACE_ERROR,_F_,"malloc(%d)",lenHashedPwd)); goto end; } swCryptEncodeBase64(bufSaltedPwd,SALT_LEN,*pszHashedPwd); swCryptEncodeBase64(bufHash,HASH_LEN,*pszHashedPwd+SALT_LEN*2); TRACE((TRACE_DEBUG,_F_,"*pszHashedPwd=%s",*pszHashedPwd)); rc=0; end: if (bufSaltedPwd!=NULL) free(bufSaltedPwd); // 0.72 : libération du hash if (hHash!=NULL) CryptDestroyHash(hHash); TRACE((TRACE_LEAVE,_F_,"rc=%d",rc)); return rc; }
char *Cmd5::digest(unsigned char *pstr) { #ifdef WIN32 HCRYPTPROV hCryptProv; HCRYPTHASH hHash; unsigned char bHash[0x7f]; DWORD dwHashLen = 16; // The MD5 algorithm always returns 16 bytes. if (CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)) { if (CryptCreateHash(hCryptProv, CALG_MD5, // algorithm identifier definitions see: wincrypt.h 0, 0, &hHash)) { if (CryptHashData(hHash, pstr, strlen((const char *) pstr), 0)) { if (CryptGetHashParam(hHash, HP_HASHVAL, bHash, &dwHashLen, 0)) { // Make a string version of the numeric digest value *m_szDigest = 0; char tmp[ 10 ]; for (int i = 0; i < 16; i++) { sprintf(tmp, "%02x", bHash[i]); strcat(m_szDigest, tmp); } } else { return NULL; } } else { return NULL; } } else { return NULL; } } else { return NULL; } CryptDestroyHash(hHash); CryptReleaseContext(hCryptProv, 0); #else EVP_MD_CTX mdctx; const EVP_MD *md; unsigned char md_value[EVP_MAX_MD_SIZE]; unsigned int md_len; OpenSSL_add_all_digests(); md = EVP_get_digestbyname("md5"); EVP_MD_CTX_init(&mdctx); EVP_DigestInit_ex(&mdctx, md, NULL); EVP_DigestUpdate(&mdctx, pstr, strlen((const char *) pstr)); EVP_DigestFinal_ex(&mdctx, md_value, &md_len); EVP_MD_CTX_cleanup(&mdctx); memset(m_szDigest, 0, sizeof(m_szDigest)); sprintf(m_szDigest, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", md_value[0], md_value[1], md_value[2], md_value[3], md_value[4], md_value[5], md_value[6], md_value[7], md_value[8], md_value[9], md_value[10], md_value[11], md_value[12], md_value[13], md_value[14], md_value[15]); /* MD5_CTX *pctx; if ( 0 == MD5_Init( pctx ) ) return NULL; if ( 0 == MD5_Update( pctx, pstr, strlen( (const char *)pstr ) ) ) return NULL; unsigned char buf[ 17 ]; if ( 0 == MD5_Final( buf, pctx ) ) return NULL; sprintf( m_szDigest, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\0", buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7], buf[8],buf[9],buf[10],buf[11],buf[12],buf[13],buf[14],buf[15] ); */ #endif return m_szDigest; }
/* 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; }
static char *mkpass_sha1(char *para) { static char buf[128]; char result1[20+REALSALTLEN]; char result2[20]; char saltstr[REALSALTLEN]; /* b64 encoded printable string*/ char saltraw[RAWSALTLEN]; /* raw binary */ char xresult[64]; #ifndef _WIN32 SHA_CTX hash; #else HCRYPTPROV hProv; HCRYPTHASH hHash; DWORD size = 20; #endif int i; if (!para) return NULL; /* generate a random salt... */ for (i=0; i < RAWSALTLEN; i++) saltraw[i] = getrandom8(); i = b64_encode(saltraw, RAWSALTLEN, saltstr, REALSALTLEN); if (!i) return NULL; #ifdef _WIN32 if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) return NULL; #endif /* b64(SHA1(SHA1(<pass>)+salt)) * ^^^^^^^^^^^ * step 1 * ^^^^^^^^^^^^^^^^^^^^^ * step 2 * ^^^^^^^^^^^^^^^^^^^^^^^^^^ * step 3 */ /* STEP 1 */ #ifndef _WIN32 SHA1_Init(&hash); SHA1_Update(&hash, para, strlen(para)); SHA1_Final(result1, &hash); #else if (!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash)) return NULL; if (!CryptHashData(hHash, para, strlen(para), 0)) return NULL; if (!CryptGetHashParam(hHash, HP_HASHVAL, result1, &size, 0)) return NULL; CryptDestroyHash(hHash); #endif /* STEP 2 */ /* add salt to result */ memcpy(result1+20, saltraw, RAWSALTLEN); /* Then hash it all together */ #ifndef _WIN32 SHA1_Init(&hash); SHA1_Update(&hash, result1, RAWSALTLEN+20); SHA1_Final(result2, &hash); #else if (!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash)) return NULL; if (!CryptHashData(hHash, result1, RAWSALTLEN+20, 0)) return NULL; if (!CryptGetHashParam(hHash, HP_HASHVAL, result2, &size, 0)) return NULL; CryptDestroyHash(hHash); CryptReleaseContext(hProv, 0); #endif /* STEP 3 */ /* Then base64 encode it all together.. */ i = b64_encode(result2, sizeof(result2), xresult, sizeof(xresult)); if (!i) return NULL; /* Good.. now create the whole string: * $<saltb64d>$<totalhashb64d> */ ircsprintf(buf, "$%s$%s", saltstr, xresult); return buf; }
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; }
static int authcheck_sha1(aClient *cptr, anAuthStruct *as, char *para) { char buf[512]; int i, r; char *saltstr, *hashstr; if (!para) return -1; r = parsepass(as->data, &saltstr, &hashstr); if (r) { /* New method with salt: b64(SHA1(SHA1(<pass>)+salt)) */ char result1[MAXSALTLEN+20+1]; char result2[20]; char rsalt[MAXSALTLEN+1]; int rsaltlen; #ifndef _WIN32 SHA_CTX hash; #else HCRYPTPROV hProv; HCRYPTHASH hHash; DWORD size = 20; #endif /* First, decode the salt to something real... */ rsaltlen = b64_decode(saltstr, rsalt, sizeof(rsalt)); if (rsaltlen <= 0) return -1; #ifdef _WIN32 if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) return -1; #endif /* Then hash the password (1st round)... */ #ifndef _WIN32 SHA1_Init(&hash); SHA1_Update(&hash, para, strlen(para)); SHA1_Final(result1, &hash); #else if (!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash)) return -1; if (!CryptHashData(hHash, para, strlen(para), 0)) return -1; if (!CryptGetHashParam(hHash, HP_HASHVAL, result1, &size, 0)) return -1; CryptDestroyHash(hHash); #endif /* Add salt to result */ memcpy(result1+20, rsalt, rsaltlen); /* b64_decode already made sure bounds are ok */ /* Then hash it all together again (2nd round)... */ #ifndef _WIN32 SHA1_Init(&hash); SHA1_Update(&hash, result1, rsaltlen+20); SHA1_Final(result2, &hash); #else if (!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash)) return -1; if (!CryptHashData(hHash, result1, 20+rsaltlen, 0)) return -1; if (!CryptGetHashParam(hHash, HP_HASHVAL, result2, &size, 0)) return -1; CryptDestroyHash(hHash); CryptReleaseContext(hProv, 0); #endif /* Then base64 encode it all and we are done... */ if ((i = b64_encode(result2, sizeof(result2), buf, sizeof(buf)))) { if (!strcmp(buf, hashstr)) return 2; else return -1; } else return -1; } else { /* OLD auth */ #ifndef _WIN32 if ((i = b64_encode(SHA1(para, strlen(para), NULL), 20, buf, sizeof(buf)))) { if (!strcmp(buf, as->data)) return 2; else return -1; } else return -1; #else HCRYPTPROV hProv; HCRYPTHASH hHash; char buf2[512]; DWORD size = 512; if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) return -1; if (!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash)) return -1; if (!CryptHashData(hHash, para, strlen(para), 0)) return -1; if (!CryptGetHashParam(hHash, HP_HASHVAL, buf, &size, 0)) return -1; CryptDestroyHash(hHash); CryptReleaseContext(hProv, 0); b64_encode(buf, 20, buf2, sizeof(buf2)); if (!strcmp(buf2, as->data)) return 2; else return -1; #endif } }
/* Finalizes the digest context * Returns 1 if successful, 0 on failure or -1 on error */ int digest_context_finalize( digest_context_t *digest_context, digest_hash_t *digest_hash, size_t *size, liberror_error_t **error ) { static char *function = "digest_context_finalize"; if( digest_context == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_ARGUMENTS, LIBERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid digest context.", function ); return( -1 ); } if( digest_hash == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_ARGUMENTS, LIBERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid digest hash.", function ); return( -1 ); } if( *size > (size_t) SSIZE_MAX ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_ARGUMENTS, LIBERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid size value exceeds maximum.", function ); return( -1 ); } #if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) if( EVP_DigestFinal_ex( digest_context, (unsigned char *) digest_hash, (unsigned int *) size ) != 1 ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_RUNTIME, LIBERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to finalize digest hash.", function ); return( 0 ); } if( EVP_MD_CTX_cleanup( digest_context ) != 1 ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_RUNTIME, LIBERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to clean up digest context.", function ); } #elif defined( HAVE_WINCPRYPT_H ) if( digest_context->hash == 0 ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_RUNTIME, LIBERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: invalid digest context - missing hash.", function ); return( -1 ); } if( CryptGetHashParam( digest_context->hash, HP_HASHVAL, (BYTE *) digest_hash, (DWORD *) size, 0 ) != 1 ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_RUNTIME, LIBERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to finalize digest hash.", function ); return( 0 ); } if( digest_context->crypt_provider != 0 ) { CryptReleaseContext( digest_context->crypt_provider, 0 ); } if( digest_context->hash != 0 ) { CryptDestroyHash( digest_context->hash ); } #endif return( 1 ); }
HRESULT PasswordUtil_Check(LPCWSTR password, LPCWSTR salt, LPCWSTR passwordHash, BOOL* pResult) { if(IsBadStringPtrW(password,512)) return E_INVALIDARG; if(IsBadStringPtrW(salt,512)) return E_INVALIDARG; if(IsBadStringPtrW(passwordHash,512)) return E_INVALIDARG; if(IsBadWritePtr(pResult,sizeof(BOOL*))) return E_INVALIDARG; *pResult = FALSE; HRESULT hr = S_OK; HCRYPTPROV hProv = NULL; HCRYPTHASH hHash = NULL; WCHAR saltAndPwd[1024] = L""; wcsncat_s(saltAndPwd, 1024, password, 512); wcsncat_s(saltAndPwd, 1024, L"$",1); wcsncat_s(saltAndPwd, 1024, salt, 511); DWORD dwFlags = CRYPT_SILENT|CRYPT_MACHINE_KEYSET; TCHAR szContainer[50] = _T("{BDECD56B-6D48-4add-9AEE-265D537408DF}"); CString auditMessage; BOOL bCreated = FALSE; if(!CryptAcquireContext(&hProv, szContainer, MS_ENHANCED_PROV, PROV_RSA_FULL, dwFlags)) { hr = HRESULT_FROM_WIN32(GetLastError()); if(hr==0x80090016L) // Key Not Found { bCreated = TRUE; if(!CryptAcquireContext(&hProv, szContainer, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET|dwFlags)) { hr = HRESULT_FROM_WIN32(GetLastError()); if(hr == 0x8009000FL) // Key Exists { if(CryptAcquireContext(&hProv, szContainer, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_DELETEKEYSET|dwFlags)) { hr = S_OK; if(!CryptAcquireContext(&hProv, szContainer, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET|dwFlags)) { hr = HRESULT_FROM_WIN32(GetLastError()); } else { hr = S_OK; } } else { hr = HRESULT_FROM_WIN32(GetLastError()); } } else { hr = S_OK; } } else { hr = S_OK; } } } if(SUCCEEDED(hr)) { if(bCreated) { // Set DACL for this container to allow full control for everyone and for local system. PSECURITY_DESCRIPTOR pSd = NULL; LPBYTE pbDacl = NULL; HRESULT hr2 = CreateSecurityDescriptor(&pSd, &pbDacl); if(SUCCEEDED(hr2)) { CryptSetProvParam(hProv, PP_KEYSET_SEC_DESCR, reinterpret_cast<LPBYTE>(pSd), DACL_SECURITY_INFORMATION); delete pSd; delete[] pbDacl; } } if(CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) { //auditMessage.Format(_T("Step 2-2. Error Code: 0x%X."), hr); //CEventLog::AddAppLog(auditMessage, FAILED_LOGIN, EVENTLOG_WARNING_TYPE); if(CryptHashData(hHash, (BYTE*)saltAndPwd, (DWORD)(wcslen(saltAndPwd))*2, 0)) { //auditMessage.Format(_T("Step 2-3. Error Code: 0x%X."), hr); //CEventLog::AddAppLog(auditMessage, FAILED_LOGIN, EVENTLOG_WARNING_TYPE); BYTE szData[50] = {0}; DWORD dwDataLen = 50; if(CryptGetHashParam(hHash, HP_HASHVAL, szData, &dwDataLen, 0)) { /*auditMessage.Format(_T("Step 2-4. Error Code: 0x%X."), hr); CEventLog::AddAppLog(auditMessage, FAILED_LOGIN, EVENTLOG_WARNING_TYPE);*/ CW2A ansiPasswordHash(passwordHash); int passwordHashLen = static_cast<int>(strlen(ansiPasswordHash)); int nDestLen = Base64DecodeGetRequiredLength(passwordHashLen); CHeapPtr<BYTE> dataBuffer; if(dataBuffer.AllocateBytes(nDestLen)) { //auditMessage.Format(_T("Step 2-5. Error Code: 0x%X."), hr); //CEventLog::AddAppLog(auditMessage, FAILED_LOGIN, EVENTLOG_WARNING_TYPE); if(Base64Decode(ansiPasswordHash, passwordHashLen, dataBuffer, &nDestLen)) { size_t testHashLength = static_cast<size_t>(dwDataLen); size_t validHashLength = static_cast<size_t>(nDestLen); *pResult = (testHashLength == validHashLength && (memcmp(szData, dataBuffer, testHashLength) == 0)); } } else hr = E_OUTOFMEMORY; } else hr = HRESULT_FROM_WIN32(GetLastError()); } else hr = HRESULT_FROM_WIN32(GetLastError()); CryptDestroyHash(hHash); } else hr = HRESULT_FROM_WIN32(GetLastError()); CryptReleaseContext(hProv, 0); } //else // hr = HRESULT_FROM_WIN32(GetLastError()); //auditMessage.Format(_T("Step Final. Error Code: 0x%X."), hr); //CEventLog::AddAppLog(auditMessage, FAILED_LOGIN, EVENTLOG_WARNING_TYPE); return hr; }
int hashMD5(char *filename, char *dir, char *md5sum) { DWORD dwStatus = 0; BOOL bResult = FALSE; HCRYPTPROV hProv = 0; HCRYPTHASH hHash = 0; HANDLE hFile = NULL; BYTE rgbFile[BUF_SIZE]; DWORD cbRead = 0; BYTE rgbHash[MD5LEN]; DWORD cbHash = 0; CHAR rgbDigits[] = "0123456789abcdef"; char fileAndDir[MAX_PATH]; char dirLocal[MAX_PATH]; char *dirBegin = NULL; GetCurrentDirectory(sizeof(dirLocal), dirLocal); /*if (strcmp(dirLocal, config.directorioFiles) != 0) { control = 1; dirBegin = dirLocal; dirBegin += lstrlen(config.directorioFiles); wsprintf(filedir, "%s\\", dirBegin); } else control = 0;*/ memset(md5sum,'\0', sizeof(*md5sum)); memset(fileAndDir, '\0', sizeof(fileAndDir)); wsprintf(fileAndDir, "%s\\%s", dirLocal, filename); hFile = CreateFile(fileAndDir, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL); if (INVALID_HANDLE_VALUE == hFile) { dwStatus = GetLastError(); printf("Error opening file %s\nError: %d\r\n", filename, dwStatus); return dwStatus; } if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { dwStatus = GetLastError(); printf("CryptAcquireContext failed: %d\r\n", dwStatus); CloseHandle(hFile); return dwStatus; } if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) { dwStatus = GetLastError(); printf("CryptAcquireContext failed: %d\r\n", dwStatus); CloseHandle(hFile); CryptReleaseContext(hProv, 0); return dwStatus; } while (bResult = ReadFile(hFile, rgbFile, BUF_SIZE, &cbRead, NULL)) { if (0 == cbRead) { break; } if (!CryptHashData(hHash, rgbFile, cbRead, 0)) { dwStatus = GetLastError(); printf("CryptHashData failed: %d\r\n", dwStatus); CryptReleaseContext(hProv, 0); CryptDestroyHash(hHash); CloseHandle(hFile); return dwStatus; } } if (!bResult) { dwStatus = GetLastError(); printf("ReadFile failed: %d\r\n", dwStatus); CryptReleaseContext(hProv, 0); CryptDestroyHash(hHash); CloseHandle(hFile); return dwStatus; } cbHash = MD5LEN; if (CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0)) { DWORD i; for (i = 0; i < cbHash; i++) { char buf[5]; sprintf_s(buf, sizeof(buf), "%c%c", rgbDigits[rgbHash[i] >> 4], rgbDigits[rgbHash[i] & 0xf]); lstrcat(md5sum, buf); } }
BOOL WriteToFileWithHashAsFilename(PCCERT_CONTEXT pPrevCertContext) { #undef RETURN #define RETURN(rv) \ { \ if( hHash ) CryptDestroyHash(hHash); \ if( hProv ) CryptReleaseContext(hProv, 0); \ return rv; \ } HCRYPTPROV hProv = 0; HCRYPTHASH hHash = 0; BYTE byteFinalHash[20]; DWORD dwFinalHashSize = 20; if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { std::cout << "CryptAcquireContext failed: " << GetLastError() << std::endl; RETURN(FALSE); } if (!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash)) { std::cout << "CryptCreateHash failed: " << GetLastError() << std::endl; RETURN(FALSE); } if (!CryptHashData(hHash, pPrevCertContext->pbCertEncoded, pPrevCertContext->cbCertEncoded, 0)) { std::cout << "CryptHashData failed: " << GetLastError() << std::endl; RETURN(FALSE); } if (!CryptGetHashParam(hHash, HP_HASHVAL, byteFinalHash, &dwFinalHashSize, 0)) { std::cout << "CryptGetHashParam failed: " << GetLastError() << std::endl; RETURN(FALSE); } std::string strHash = GetHexRepresentation(byteFinalHash, dwFinalHashSize); std::wostringstream filename; filename << strHash.c_str() << ".der" <<std::ends; FILE* f = _wfopen(filename.str().c_str(), L"wb+"); if(!f) { std::wcout << "Failed to open file for writing: " << filename.str().c_str() << std::endl; RETURN(FALSE); } int bytesWritten = fwrite(pPrevCertContext->pbCertEncoded, 1, pPrevCertContext->cbCertEncoded, f); fclose(f); if(bytesWritten != pPrevCertContext->cbCertEncoded) { std::cout << "Failed to write file" << std::endl; RETURN(FALSE); } RETURN(TRUE); }
void Server::handleBtnRequest(SOCKET connection, Request & request) { // The button request must have a get variable name 'key'. If not, send a 400 error and return if (request.get.find("key") == request.get.end()) { ssend(connection, "HTTP/1.0 400 BAD REQUEST\r\n\r\n<h1>Need a key</h1>"); return ; } // The request must be a web-socket request, check that the request provided the needed WebSocket information headers // If not, send a 412 error and return if ( request.headers.find("connection") == request.headers.end() || _stricmp(request.headers["connection"].c_str(), "upgrade") != 0 || request.headers.find("upgrade") == request.headers.end() || _stricmp(request.headers["upgrade"].c_str(), "WebSocket") != 0) { ssend(connection, "HTTP/1.0 412 Precondition Failed\r\n\r\n<h1>Connection to this URL must use WebSockets</h1>"); return ; } // The request must have a host and a origin headers. If not, send a 400 error and return if (request.headers.find("host") == request.headers.end() || request.headers.find("origin") == request.headers.end()) { ssend(connection, "HTTP/1.0 400 BAD REQUEST\r\n\r\n<h1>Missing host or origin header</h1>"); return ; } // The request must have a sec-websocket-key 1 and 2 headers. If not, send a 400 error and return if (request.headers.find("sec-websocket-key1") == request.headers.end() || request.headers.find("sec-websocket-key2") == request.headers.end()) { ssend(connection, "HTTP/1.0 400 BAD REQUEST\r\n\r\n<h1>Missing sec-websocket-key1 or sec-websocket-key2 header</h1>"); return ; } // The MFD to use the buttons on ServerMFD *mfd = 0; // Open the MFD (with no image format) mfd = openMFD(request.get["key"]); // If the open of the MFD failed, send a 500 error and return if (!mfd) { ssend(connection, "HTTP/1.0 500 Internal Server Error\r\n\r\n<h1>Could not open the MFD</h1>"); return ; } // Used to calculate the response security string of the WebSocket protocol // C.f. decodeSecWebsocket note... union { struct { INT32 sec1; INT32 sec2; char key[8]; } head; BYTE ascii[16]; } handshake; // Getting the sec-websocket-key2 calculation results handshake.head.sec1 = getBigEndian(decodeSecWebsocket(request.headers["sec-websocket-key1"])); handshake.head.sec2 = getBigEndian(decodeSecWebsocket(request.headers["sec-websocket-key2"])); // Getting the 8 bytes of the body // As soHTTP does not ensure that all the body is read, // read from the socket and add the result to the body // while the body does not contains the 8 needed bytes while (request.body.length() < 8) { char tmp[8]; int r = recv(connection, tmp, 8, 0); request.body += std::string(tmp, r); } // Copying the body 8 bytes into the WebSocket security structure strncpy(handshake.head.key, request.body.substr(0, 8).c_str(), 8); // Getting a windows cryptography context HCRYPTPROV hProv = 0; CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); // Getting a windows MD5 Hash object from the cryptography context HCRYPTHASH hHash = 0; CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash); // Hashing the security handshake using the MD5 Hash object CryptHashData(hHash, handshake.ascii, 16, 0); // Getting the resultof the MD5 Hash into rgbHash DWORD cbHash = 16; // = MD5 Len BYTE rgbHash[16]; CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0); // Destroying the Hash object and cryptographic context CryptDestroyHash(hHash); CryptReleaseContext(hProv, 0); // Sending the WebSocket headers ssend(connection, "HTTP/1.1 101 WebSocket Protocol Handshake\r\n"); ssend(connection, "Connection: Upgrade\r\n"); ssend(connection, "Upgrade: WebSocket\r\n"); ssend(connection, "Sec-WebSocket-Origin: "); ssend(connection, request.headers["origin"].c_str()); ssend(connection, "\r\n"); ssend(connection, "Sec-WebSocket-Location: ws://"); ssend(connection, request.headers["host"].c_str()); ssend(connection, "/btn/?"); ssend(connection, request.getString.c_str()); ssend(connection, "\r\n"); ssend(connection, "Sec-WebSocket-Protocol: Orbiter-WebMFD-Buttons\r\n"); ssend(connection, "\r\n"); // Sending the WebSocket hashed handshake send(connection, (char*)rgbHash, 16, 0); // Set the connection socket to timeout. // This is necessary for regular button check int toVal = (int)WEBMFD_REFRESH_ASK_MS; setsockopt(connection, SOL_SOCKET, SO_RCVTIMEO, (char*)&toVal, sizeof(int)); // Id of the button labels, used to check if the button labels have changed unsigned int BtnPrevId = 0; // Infinite loop that will run until the connection stops for (;;) { // Get the JSON string if the button labels have changed std::string JSON = mfd->getJSONIf(BtnPrevId); // If the JSON string has evolved, it is returned if (!JSON.empty()) { // send the buttons status in JSON inside a WebMFD message send(connection, "\0", 1, 0); ssend(connection, JSON.c_str()); int sent = send(connection, "\xFF", 1, 0); // If the sending of the response has failed, break the connection if (sent == SOCKET_ERROR) break ; } // The buffer to read the buttons pressed unsigned char buf[5] = {0,}; // Read 4 bytes from the sockets which should be: // 255 <btnId-ascii-digit-tenth> <btnId-ascii-digit-unit> 0 int ret = recv(connection, (char*)buf, 4, 0); // If the read has failed if (ret <= 0) { // If the read has failed because of a timeout, continue the loop if (WSAGetLastError() == WSAETIMEDOUT) continue ; // If the read has failed for any other reason, break the connection break; } // If the packet is not a 4 bytes websocket message, ignores it if (ret != 4 || buf[0] != 0 || buf[3] != 255) continue ; // Reading the btnId (ignoring the first byte, which is 255) int btnId = atoi((const char *)buf + 1); // If the given button Id is a correct number if (btnId >= 0) { // Inform that we want to start a button press mfd->startBtnProcess(); // Register the button press into the corresponding event queue // We are probably not in the main (Orbiter) thread // Therefore, we cannot use directly the Orbiter API as Orbiter is not thread-safe (Martin Schweiger if you read this...) WaitForSingleObject(_mfdsMutex, INFINITE); _btnPress.push(std::pair<ServerMFD*, int>(mfd, btnId)); ReleaseMutex(_mfdsMutex); // Wait for the end of the button process mfd->waitForBtnProcess(); // If the button pressed was the close one, break the connection if (btnId == 99) break ; // Force the refresh of the MFD as the button press has probably a consequence on the display WaitForSingleObject(_mfdsMutex, INFINITE); _forceRefresh.push(mfd); ReleaseMutex(_mfdsMutex); } // If the given button id is -1, it means that this is just an enquiry and not a button press // Therefore, BtnPrevId is set to 0, which will force, in the begining of the next loop, the button JSON send else if (btnId == -1) BtnPrevId = 0; } // Close the MFD closeMFD(request.get["key"]); }
static int xmlSecMSCryptoDigestExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) { xmlSecMSCryptoDigestCtxPtr ctx; xmlSecBufferPtr in, out; int ret; xmlSecAssert2(xmlSecMSCryptoDigestCheckId(transform), -1); xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecMSCryptoDigestSize), -1); xmlSecAssert2(transformCtx != NULL, -1); in = &(transform->inBuf); xmlSecAssert2(in != NULL, -1); out = &(transform->outBuf); xmlSecAssert2(out != NULL, -1); ctx = xmlSecMSCryptoDigestGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); if(transform->status == xmlSecTransformStatusNone) { ret = CryptCreateHash(ctx->provider, ctx->alg_id, 0, 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); } transform->status = xmlSecTransformStatusWorking; } if (transform->status == xmlSecTransformStatusWorking) { xmlSecSize inSize; inSize = xmlSecBufferGetSize(in); if(inSize > 0) { ret = CryptHashData(ctx->mscHash, xmlSecBufferGetData(in), inSize, 0); if(ret == 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "CryptHashData", XMLSEC_ERRORS_R_CRYPTO_FAILED, "size=%d", inSize); return(-1); } ret = xmlSecBufferRemoveHead(in, inSize); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferRemoveHead", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", inSize); return(-1); } } if(last) { /* TODO: make a MSCrypto compatible assert here */ /* xmlSecAssert2((xmlSecSize)EVP_MD_size(ctx->digest) <= sizeof(ctx->dgst), -1); */ DWORD retLen; retLen = MSCRYPTO_MAX_HASH_SIZE; ret = CryptGetHashParam(ctx->mscHash, HP_HASHVAL, ctx->dgst, &retLen, 0); if (ret == 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "CryptGetHashParam(HP_HASHVAL)", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", MSCRYPTO_MAX_HASH_SIZE); return(-1); } ctx->dgstSize = (size_t)retLen; xmlSecAssert2(ctx->dgstSize > 0, -1); /* copy result to output */ if(transform->operation == xmlSecTransformOperationSign) { ret = xmlSecBufferAppend(out, ctx->dgst, ctx->dgstSize); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferAppend", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", ctx->dgstSize); return(-1); } } transform->status = xmlSecTransformStatusFinished; } } else if(transform->status == xmlSecTransformStatusFinished) { /* the only way we can get here is if there is no input */ xmlSecAssert2(xmlSecBufferGetSize(in) == 0, -1); } else { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_INVALID_STATUS, "status=%d", transform->status); return(-1); } return(0); }
//This method calculate the Salted SHA-1 hash of the given password //password must be a null terminated string //hash must be a preallocated buffer of at least 100 characters (99 character + null) void hashPassword(char* password, char* hash){ HCRYPTPROV hCryptProv; HCRYPTHASH hCryptHash; char salt[SHA1_SALT_LEN + 1]; char saltedpassword[100]; BYTE bytehash[100]; char resulthash[100]; BYTE bHashValue[SHA1_HASH_LEN]; DWORD dwSize = SHA1_HASH_LEN; memset(salt,'\0', SHA1_SALT_LEN +1 * sizeof(char)); memset(saltedpassword,'\0', 100 * sizeof(char)); memset(bytehash,'\0', 100* sizeof(char)); memset(resulthash,'\0', 100* sizeof(char)); memset(hash,'\0', 100 * sizeof(char)); // get random alphanumeric 8-byte salt CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); CryptGenRandom(hCryptProv, SHA1_SALT_LEN , (BYTE*)salt); CryptReleaseContext(hCryptProv, 0); // postfix hex-salt to password sprintf(saltedpassword,"%s%s",password,salt); // hash it with wincrypt-sha1 if ( CryptAcquireContext(&hCryptProv, NULL, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) ) { if (CryptCreateHash(hCryptProv, CALG_SHA1, 0, 0, &hCryptHash) ){ if (CryptHashData(hCryptHash, (BYTE*) saltedpassword, strlen(saltedpassword), 0) ){ if (CryptGetHashParam(hCryptHash, HP_HASHVAL, bHashValue, &dwSize, 0) ) { }else{ writeMessageToLog(L"ERROR: couldn't read (already created) hash ..."); } }else{ writeMessageToLog(L"ERROR: couldn't hash the salted password ..."); } }else{ writeMessageToLog(L"ERROR: couldn't create SHA1-Hash with CryptCreateHash ..."); } }else{ writeMessageToLog(L"ERROR: couldn't acquire WinCryptContext..."); } CryptDestroyHash(hCryptHash); CryptReleaseContext(hCryptProv, 0); // copy salt after byte-hash for (int i=0; i < SHA1_HASH_LEN; i++){ printf("",i); // please dear vc++, don't optimize me away bytehash[i] = bHashValue[i]; } for (int i=0; i < SHA1_SALT_LEN; i++){ printf("",i); // please dear vc++, don't optimize me away bytehash[SHA1_HASH_LEN+i] = salt[i]; } // to base64 if ( base64_encode((unsigned char*)bytehash, SHA1_HASH_LEN + SHA1_SALT_LEN, resulthash, 100) ) { writeMessageToLog(L"ERROR: base64 encode of salted hash failed..."); } strncat(hash,"{SSHA}",6); strncat(hash,resulthash,strlen(resulthash)); // secure wipe salted password SecureZeroMemory(saltedpassword,strlen(saltedpassword)); return; }
char* l_md5(const char* filename) { char *ret = (char*)malloc(33 * sizeof(char)); memset(ret, 0, 33); #ifdef WIN32 WCHAR wTMP[1024]; DWORD dwStatus = 0; BOOL bResult = FALSE; HCRYPTPROV hProv = 0; HCRYPTHASH hHash = 0; HANDLE hFile = NULL; BYTE rgbFile[BUFSIZE]; DWORD cbRead = 0; BYTE rgbHash[MD5LEN]; DWORD cbHash = 0; CHAR rgbDigits[] = "0123456789abcdef"; // Logic to check usage goes here. WCHAR Wfilename[strlen(filename)+1]; CPY_CHAR_to_WCHAR(filename, Wfilename); hFile = CreateFile(Wfilename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL); if (INVALID_HANDLE_VALUE == hFile) { dwStatus = GetLastError(); /* swprintf(wTMP, L"Error opening file %s\nError: %ld\n", to_WCHAR(filename), dwStatus); Info_Message(wTMP, 0); */ return ret; } // Get handle to the crypto provider if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { dwStatus = GetLastError(); swprintf(wTMP, L"CryptAcquireContext failed: %ld\n", dwStatus); Info_Message(wTMP, 0); CloseHandle(hFile); return ret; } if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) { dwStatus = GetLastError(); swprintf(wTMP, L"CryptCreateHash failed: %ld\n", dwStatus); Info_Message(wTMP, 0); CloseHandle(hFile); CryptReleaseContext(hProv, 0); return ret; } while ((bResult = ReadFile(hFile, rgbFile, BUFSIZE, &cbRead, NULL))) { if (0 == cbRead) { break; } if (!CryptHashData(hHash, rgbFile, cbRead, 0)) { dwStatus = GetLastError(); swprintf(wTMP, L"CryptHashData failed: %ld\n", dwStatus); Info_Message(wTMP, 0); CryptReleaseContext(hProv, 0); CryptDestroyHash(hHash); CloseHandle(hFile); return ret; } } if (!bResult) { dwStatus = GetLastError(); swprintf(wTMP, L"ReadFile failed: %ld\n", dwStatus); Info_Message(wTMP, 0); CryptReleaseContext(hProv, 0); CryptDestroyHash(hHash); CloseHandle(hFile); return ret; } cbHash = MD5LEN; if (CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0)) { DWORD i = 0; while (i < cbHash) { sprintf(&ret[i*2], "%c%c", rgbDigits[rgbHash[i] >> 4], rgbDigits[rgbHash[i] & 0xf]); i++; } }
//----------------------------------------------------------------------------- // 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; }
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; }
BOOL CreateSignatureHMACSHA1(wstring src, wstring secretKey, wstring& signature) { signature = L""; string hashSrc = ""; string hashKey = ""; WtoUTF8(src, hashSrc); WtoUTF8(secretKey, hashKey); HCRYPTPROV cryptProv = NULL; HCRYPTHASH cryptHash = NULL; BYTE key[65]; DWORD keySize = 0; BYTE ipad[65]; BYTE opad[65]; ZeroMemory(key, 65); ZeroMemory(ipad, 65); ZeroMemory(opad, 65); BYTE* firstHash = NULL; DWORD firstHashSize = 0; BYTE* secondHash = NULL; DWORD secondHashSize = 0; WCHAR* base64 = NULL; DWORD base64Size = 0; if ( CryptAcquireContext(&cryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) == FALSE ){ goto Err_End; } if( hashKey.size() > 64 ){ if ( CryptCreateHash(cryptProv, CALG_SHA1, 0, 0, &cryptHash) == FALSE ){ goto Err_End; } if( CryptHashData(cryptHash, (BYTE*)hashKey.c_str(), (DWORD)hashKey.length(), 0) == FALSE ){ goto Err_End; } if( CryptGetHashParam(cryptHash, HP_HASHVAL, NULL, &keySize, 0 ) == FALSE ){ goto Err_End; } if( CryptGetHashParam(cryptHash, HP_HASHVAL, key, &keySize, 0 ) == FALSE ){ goto Err_End; } CryptDestroyHash(cryptHash); cryptHash = NULL; }else{ keySize = (DWORD)hashKey.size(); memcpy(key, hashKey.c_str(), keySize); } memcpy(ipad, key, keySize); memcpy(opad, key, keySize); for( int i=0; i<64; i++ ){ ipad[i] ^= 0x36; opad[i] ^= 0x5c; } if ( CryptCreateHash(cryptProv, CALG_SHA1, 0, 0, &cryptHash) == FALSE ){ goto Err_End; } if( CryptHashData(cryptHash, ipad, 64, 0) == FALSE ){ goto Err_End; } if( CryptHashData(cryptHash, (BYTE*)hashSrc.c_str(), (DWORD)hashSrc.size(), 0) == FALSE ){ goto Err_End; } if( CryptGetHashParam(cryptHash, HP_HASHVAL, NULL, &firstHashSize, 0 ) == FALSE ){ goto Err_End; } firstHash = new BYTE[firstHashSize]; if( CryptGetHashParam(cryptHash, HP_HASHVAL, firstHash, &firstHashSize, 0 ) == FALSE ){ goto Err_End; } CryptDestroyHash(cryptHash); cryptHash = NULL; if ( CryptCreateHash(cryptProv, CALG_SHA1, 0, 0, &cryptHash) == FALSE ){ goto Err_End; } if( CryptHashData(cryptHash, opad, 64, 0) == FALSE ){ goto Err_End; } if( CryptHashData(cryptHash, firstHash, firstHashSize, 0) == FALSE ){ goto Err_End; } if( CryptGetHashParam(cryptHash, HP_HASHVAL, NULL, &secondHashSize, 0 ) == FALSE ){ goto Err_End; } secondHash = new BYTE[secondHashSize]; if( CryptGetHashParam(cryptHash, HP_HASHVAL, secondHash, &secondHashSize, 0 ) == FALSE ){ goto Err_End; } CryptDestroyHash(cryptHash); cryptHash = NULL; //Base64 if( CryptBinaryToString( secondHash, secondHashSize, CRYPT_STRING_BASE64, NULL, &base64Size ) == FALSE){ goto Err_End; } base64 = new WCHAR[ base64Size + 1 ]; if( CryptBinaryToString( secondHash, secondHashSize, CRYPT_STRING_BASE64, base64, &base64Size ) == FALSE ){ goto Err_End; } signature = base64; //最後に\r\n入ってしまうみたいなので除去 Replace(signature, L"\r\n", L""); Err_End: SAFE_DELETE_ARRAY(base64); SAFE_DELETE_ARRAY(secondHash); SAFE_DELETE_ARRAY(firstHash); if( cryptHash !=NULL ){ CryptDestroyHash(cryptHash); } if( cryptProv != NULL ){ CryptReleaseContext(cryptProv, 0); } if( signature.size() > 0 ){ return TRUE; }else{ return FALSE; } }
string HashFileMD5 ( string file ) { string hash_result; HCRYPTPROV crypto = 0; if (CryptAcquireContext(&crypto, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { CHAR file_hash[100]; BYTE buff[4096]; DWORD bytes = 0; HCRYPTHASH crypto_hash = 0; if (CryptCreateHash(crypto, CALG_MD5, 0, 0, &crypto_hash)) { HANDLE file_handle = CreateFileA(file.c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); if (file_handle != INVALID_HANDLE_VALUE) { bool ok = true; while (ReadFile(file_handle, buff, sizeof(buff), &bytes, 0) && bytes) { if (!CryptHashData(crypto_hash, buff, bytes, 0)) { ok = false; } } if (ok) { BYTE hash[16]; DWORD len = 16; if (CryptGetHashParam(crypto_hash, HP_HASHVAL, hash, &len, 0)) { sprintf(file_hash, "%02X%02X%02X%02X%02X%02X%02X%02X" "%02X%02X%02X%02X%02X%02X%02X%02X", hash[0], hash[1], hash[2], hash[3], hash[4], hash[5], hash[6], hash[7], hash[8], hash[9], hash[10], hash[11], hash[12], hash[13], hash[14], hash[15]); hash_result = file_hash; } } CloseHandle(file_handle); } CryptDestroyHash(crypto_hash); } CryptReleaseContext(crypto, 0); } return hash_result; }
/* good1() uses if(staticFalse) instead of if(staticTrue) */ static void good1() { if(staticFalse) { /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ printLine("Benign, fixed string"); } else { { HCRYPTPROV hCryptProv; HCRYPTHASH hHash; FILE *pFile = NULL; char password[PASSWORD_INPUT_SIZE]; UCHAR savedHash[SHA512_SUM_SIZE], calcHash[SHA512_SUM_SIZE]; DWORD hashSize; char *replace; size_t i; pFile = fopen("password.txt", "r"); if (pFile == NULL) { exit(1); } for (i = 0; i < SHA512_SUM_SIZE; i++) { ULONG val; if (fscanf(pFile, "%02x", &val) != 1) { fclose(pFile); exit(1); } if (val > 0xff) /* EXPECTED INCIDENTAL: Reliance on data memory layout, we assume char is at least 8 bits */ { fclose(pFile); exit(1); } savedHash[i] = (UCHAR)val; } fclose(pFile); if (fgets(password, PASSWORD_INPUT_SIZE, stdin) == NULL) { exit(1); } replace = strchr(password, '\r'); if (replace) { *replace = '\0'; } replace = strchr(password, '\n'); if (replace) { *replace = '\0'; } if (!CryptAcquireContextW(&hCryptProv, 0, 0, PROV_RSA_FULL, 0)) { exit(1); } /* FIX: use a non-reversible hash (SHA-512) */ if (!CryptCreateHash(hCryptProv, CALG_SHA_512, 0, 0, &hHash)) { CryptReleaseContext(hCryptProv, 0); exit(1); } /* EXPECTED INCIDENTAL: We did not salt the password, that may raise flags, * the password hash was not securely transmitted (via one form or another), * that may raise flags */ if (!CryptHashData(hHash, (BYTE*)password, strlen(password), 0)) { CryptDestroyHash(hHash); CryptReleaseContext(hCryptProv, 0); exit(1); } hashSize = SHA512_SUM_SIZE; if (!CryptGetHashParam(hHash, HP_HASHVAL, (BYTE*)calcHash, &hashSize, 0)) { CryptDestroyHash(hHash); CryptReleaseContext(hCryptProv, 0); exit(1); } if (memcmp(savedHash, calcHash, SHA512_SUM_SIZE * sizeof(UCHAR)) == 0) { printLine("Access granted"); } else { printLine("Access denied"); } if (hHash) { CryptDestroyHash(hHash); } if (hCryptProv) { CryptReleaseContext(hCryptProv, 0); } } } }
void Sha1Sum::_compute() { BOOL bResult = FALSE; HCRYPTPROV hProv = 0; HCRYPTHASH hHash = 0; HANDLE hFile; BYTE buffer[BUFSIZE]; DWORD cbRead = 0; BYTE rgbHash[SHA1LEN]; wchar_t digits[] = L"0123456789abcdef"; m_sum.erase(); hFile = CreateFile(m_file.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL); if (INVALID_HANDLE_VALUE == hFile) return; if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { CloseHandle(hFile); return; } if (!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash)) { CloseHandle(hFile); CryptReleaseContext(hProv, 0); return; } while (bResult = ReadFile(hFile, buffer, BUFSIZE, &cbRead, NULL)) { if (0 == cbRead) break; if (!CryptHashData(hHash, buffer, cbRead, 0)) { CryptReleaseContext(hProv, 0); CryptDestroyHash(hHash); CloseHandle(hFile); return; } } if (!bResult) { CryptReleaseContext(hProv, 0); CryptDestroyHash(hHash); CloseHandle(hFile); } cbRead = SHA1LEN; if (CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbRead, 0)) { for (DWORD i = 0; i < cbRead; i++) { wchar_t c[16]; wsprintf(c, L"%c%c", digits[rgbHash[i] >> 4], digits[rgbHash[i] & 0xf]); m_sum += c; } } CryptDestroyHash(hHash); CryptReleaseContext(hProv, 0); CloseHandle(hFile); }
HRESULT modmd5(LPSTR *hexhash) { HRESULT hRes; HANDLE hFile = NULL; DEBUG_MODULE_PARAMETERS ModParams; HCRYPTPROV hCryptProv = NULL; HCRYPTHASH hHash = NULL; BYTE *pbHashData = NULL; BYTE buffer[BUFSIZE]; DWORD cbHash; DWORD cbRead = 0; BOOL bResult = FALSE; /* msdn: returns parameters for modules in the target. */ hRes=g_ExtSymbols->GetModuleParameters(1, &g_Base, 0, &ModParams); if(FAILED(hRes)) { dprintf("[sync] modcheck: failed get module parameters\n"); return E_FAIL; } dprintf("[sync] modcheck:\n" " File: %s\n" " Size: 0x%x\n" " TimeDateStamp: 0x%x\n", g_NameBuffer, ModParams.Size, ModParams.TimeDateStamp); hRes=E_FAIL; hFile = CreateFile(g_NameBuffer, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL); if (hFile == INVALID_HANDLE_VALUE) { dprintf("[sync] failed at opening file: %d\n", GetLastError()); return hRes; } if (!(CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))) { dprintf("[sync] CryptAcquireContext failed\n"); goto Exit; } if (!(CryptCreateHash(hCryptProv, CALG_MD5, NULL, NULL, &hHash))) { dprintf("[sync] CryptCreateHash failed\n"); goto Exit; } while (bResult = ReadFile(hFile, buffer, BUFSIZE, &cbRead, NULL)) { if (cbRead == 0) break; if (!(CryptHashData(hHash, buffer, cbRead, NULL))) { dprintf("[sync] CryptHashData failed\n"); goto Exit; } } if (!bResult) { dprintf("[sync] ReadFile failed\n"); goto Exit; } if (!(CryptGetHashParam(hHash, HP_HASHVAL, NULL, &cbHash, 0))) { dprintf("[sync] CryptGetHashParam failed\n"); goto Exit; } pbHashData = (BYTE *) malloc(cbHash); if (pbHashData==NULL){ dprintf("[sync] failed at allocate buffer: %d\n", GetLastError()); goto Exit; } if (!(CryptGetHashParam(hHash, HP_HASHVAL, pbHashData, &cbHash, 0))) { dprintf("[sync] CryptGetHashParam failed\n"); goto Exit; } hRes = ToHexString((const byte *)pbHashData, (unsigned int)cbHash, hexhash); Exit: if (hFile) CloseHandle(hFile); if (pbHashData) free(pbHashData); if (hHash) CryptDestroyHash(hHash); if (hCryptProv) CryptReleaseContext(hCryptProv,0); return hRes; }
static int xmlSecMSCryptoHmacExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) { xmlSecMSCryptoHmacCtxPtr ctx; xmlSecBufferPtr in, out; int ret; xmlSecAssert2(xmlSecTransformIsValid(transform), -1); xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecMSCryptoHmacSize), -1); xmlSecAssert2(transformCtx != NULL, -1); in = &(transform->inBuf); out = &(transform->outBuf); ctx = xmlSecMSCryptoHmacGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); xmlSecAssert2(ctx->ctxInitialized != 0, -1); if(transform->status == xmlSecTransformStatusNone) { /* we should be already initialized when we set key */ transform->status = xmlSecTransformStatusWorking; } if(transform->status == xmlSecTransformStatusWorking) { xmlSecSize inSize; inSize = xmlSecBufferGetSize(in); if(inSize > 0) { ret = CryptHashData(ctx->mscHash, xmlSecBufferGetData(in), inSize, 0); if(ret == 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "CryptHashData", XMLSEC_ERRORS_R_CRYPTO_FAILED, "size=%d", inSize); return(-1); } ret = xmlSecBufferRemoveHead(in, inSize); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferRemoveHead", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", inSize); return(-1); } } if(last) { /* TODO: make a MSCrypto compatible assert here */ /* xmlSecAssert2((xmlSecSize)EVP_MD_size(ctx->digest) <= sizeof(ctx->dgst), -1); */ DWORD retLen; retLen = XMLSEC_MSCRYPTO_MAX_HMAC_SIZE; ret = CryptGetHashParam(ctx->mscHash, HP_HASHVAL, ctx->dgst, &retLen, 0); if (ret == 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "CryptGetHashParam", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", inSize); return(-1); } xmlSecAssert2(retLen > 0, -1); /* check/set the result digest size */ if(ctx->dgstSize == 0) { ctx->dgstSize = retLen * 8; /* no dgst size specified, use all we have */ } else if(ctx->dgstSize <= 8 * retLen) { retLen = ((ctx->dgstSize + 7) / 8); /* we need to truncate result digest */ } else { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_INVALID_SIZE, "result-bits=%d;required-bits=%d", 8 * retLen, ctx->dgstSize); return(-1); } /* copy result to output */ if(transform->operation == xmlSecTransformOperationSign) { ret = xmlSecBufferAppend(out, ctx->dgst, retLen); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferAppend", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", ctx->dgstSize); return(-1); } } transform->status = xmlSecTransformStatusFinished; } } else if(transform->status == xmlSecTransformStatusFinished) { /* the only way we can get here is if there is no input */ xmlSecAssert2(xmlSecBufferGetSize(in) == 0, -1); } else { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_INVALID_STATUS, "status=%d", transform->status); return(-1); } return(0); }