| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- /*
- * wincapi.c: implementation of wincapi.h.
- */
- #include "putty.h"
- #if !defined NO_SECURITY
- #include "putty.h"
- #include "ssh.h"
- #include "wincapi.h"
- DEF_WINDOWS_FUNCTION(CryptProtectMemory);
- bool got_crypt(void)
- {
- static bool attempted = false;
- static bool successful;
- static HMODULE crypt;
- if (!attempted) {
- attempted = true;
- crypt = load_system32_dll("crypt32.dll");
- successful = crypt &&
- GET_WINDOWS_FUNCTION(crypt, CryptProtectMemory);
- }
- return successful;
- }
- char *capi_obfuscate_string(const char *realname)
- {
- char *cryptdata;
- int cryptlen;
- unsigned char digest[32];
- char retbuf[65];
- int i;
- cryptlen = strlen(realname) + 1;
- cryptlen += CRYPTPROTECTMEMORY_BLOCK_SIZE - 1;
- cryptlen /= CRYPTPROTECTMEMORY_BLOCK_SIZE;
- cryptlen *= CRYPTPROTECTMEMORY_BLOCK_SIZE;
- cryptdata = snewn(cryptlen, char);
- memset(cryptdata, 0, cryptlen);
- strcpy(cryptdata, realname);
- /*
- * CRYPTPROTECTMEMORY_CROSS_PROCESS causes CryptProtectMemory to
- * use the same key in all processes with this user id, meaning
- * that the next PuTTY process calling this function with the same
- * input will get the same data.
- *
- * (Contrast with CryptProtectData, which invents a new session
- * key every time since its API permits returning more data than
- * was input, so calling _that_ and hashing the output would not
- * be stable.)
- *
- * We don't worry too much if this doesn't work for some reason.
- * Omitting this step still has _some_ privacy value (in that
- * another user can test-hash things to confirm guesses as to
- * where you might be connecting to, but cannot invert SHA-256 in
- * the absence of any plausible guess). So we don't abort if we
- * can't call CryptProtectMemory at all, or if it fails.
- */
- if (got_crypt())
- p_CryptProtectMemory(cryptdata, cryptlen,
- CRYPTPROTECTMEMORY_CROSS_PROCESS);
- /*
- * We don't want to give away the length of the hostname either,
- * so having got it back out of CryptProtectMemory we now hash it.
- */
- {
- ssh_hash *h = ssh_hash_new(&ssh_sha256);
- put_string(h, cryptdata, cryptlen);
- ssh_hash_final(h, digest);
- }
- sfree(cryptdata);
- /*
- * Finally, make printable.
- */
- for (i = 0; i < 32; i++) {
- sprintf(retbuf + 2*i, "%02x", digest[i]);
- /* the last of those will also write the trailing NUL */
- }
- return dupstr(retbuf);
- }
- #endif /* !defined NO_SECURITY */
|