Kill ugly old getSecureRandom() and replace with simple wrapper for Windows CAPI and *nix /dev/urandom, and some build fixes.

This commit is contained in:
Adam Ierymenko 2014-08-08 11:53:55 -07:00
parent 673aab5ba2
commit 502ea66f15
4 changed files with 58 additions and 63 deletions

View File

@ -110,7 +110,7 @@ bool Dictionary::verify(const Identity &id) const
if (sig == end())
return false;
std::string sigbin(Utils::unhex(sig->second));
return id.verify(buf.data(),buf.length(),sigbin.data(),sigbin.length());
return id.verify(buf.data(),(unsigned int)buf.length(),sigbin.data(),sigbin.length());
} catch ( ... ) {
return false;
}

View File

@ -43,9 +43,12 @@
#include <dirent.h>
#endif
#ifdef __WINDOWS__
#include <wincrypt.h>
#endif
#include "Utils.hpp"
#include "Mutex.hpp"
#include "Salsa20.hpp"
namespace ZeroTier {
@ -189,68 +192,64 @@ unsigned int Utils::unhex(const char *hex,unsigned int maxlen,void *buf,unsigned
void Utils::getSecureRandom(void *buf,unsigned int bytes)
{
static Mutex randomLock;
static char randbuf[16384];
static unsigned int randptr = sizeof(randbuf);
static Salsa20 s20;
static bool randInitialized = false;
#ifdef __WINDOWS__
Mutex::Lock _l(randomLock);
static HCRYPTPROV cryptProvider = NULL;
static Mutex globalLock;
// A Salsa20/8 instance is used to further mangle whatever our base
// random source happens to be.
if (!randInitialized) {
randInitialized = true;
memset(randbuf,0,sizeof(randbuf));
char s20key[33];
uint64_t s20iv = now();
Utils::snprintf(s20key,sizeof(s20key),"%.16llx%.16llx",(unsigned long long)now(),(unsigned long long)((void *)&s20iv));
s20.init(s20key,256,&s20iv,8);
Mutex::Lock _l(globalLock);
if (cryptProvider == NULL) {
if (!CryptAcquireContextA(&cryptProvider,NULL,NULL,PROV_RSA_FULL,CRYPT_VERIFYCONTEXT|CRYPT_SILENT)) {
fprintf(stderr,"FATAL ERROR: Utils::getSecureRandom() unable to obtain WinCrypt context!\r\n");
exit(1);
return;
}
}
if (!CryptGenRandom(cryptProvider,(DWORD)bytes,(BYTE *)buf)) {
fprintf(stderr,"FATAL ERROR: Utils::getSecureRandom() CryptGenRandom failed!\r\n");
exit(1);
}
#else // not __WINDOWS__
#ifdef __UNIX_LIKE__
static char randomBuf[65536];
static unsigned int randomPtr = sizeof(randomBuf);
static int devURandomFd = -1;
static Mutex globalLock;
Mutex::Lock _l(globalLock);
if (devURandomFd <= 0) {
devURandomFd = ::open("/dev/urandom",O_RDONLY);
if (devURandomFd <= 0) {
fprintf(stderr,"FATAL ERROR: Utils::getSecureRandom() unable to open /dev/urandom\r\n");
exit(1);
return;
}
}
for(unsigned int i=0;i<bytes;++i) {
if (randptr >= sizeof(randbuf)) {
#ifdef __UNIX_LIKE__
{
int fd = ::open("/dev/urandom",O_RDONLY);
if (fd < 0) {
fprintf(stderr,"FATAL ERROR: unable to open /dev/urandom (%d)"ZT_EOL_S,errno);
exit(-1);
}
if ((int)::read(fd,randbuf,sizeof(randbuf)) != (int)sizeof(randbuf)) {
fprintf(stderr,"FATAL ERROR: unable to read from /dev/urandom"ZT_EOL_S);
exit(-1);
}
::close(fd);
if (randomPtr >= sizeof(randomBuf)) {
if ((int)::read(devURandomFd,randomBuf,sizeof(randomBuf)) != (int)sizeof(randomBuf)) {
fprintf(stderr,"FATAL ERROR: Utils::getSecureRandom() unable to read from /dev/urandom\r\n");
exit(1);
return;
}
#else
#ifdef __WINDOWS__
{
struct {
double nowf;
DWORD processId;
DWORD tickCount;
uint64_t nowi;
char padding[32];
} keyMaterial;
keyMaterial.nowf = Utils::nowf();
keyMaterial.processId = GetCurrentProcessId();
keyMaterial.tickCount = GetTickCount();
keyMaterial.nowi = Utils::now();
for(int i=0;i<sizeof(keyMaterial.padding);++i)
keyMaterial.padding[i] = (char)rand();
Salsa20 s20tmp(&keyMaterial,256,&(keyMaterial.nowi),8);
s20tmp.encrypt(randbuf,randbuf,sizeof(randbuf));
}
#else
no getSecureRandom() implementation;
#endif
#endif
s20.encrypt(randbuf,randbuf,sizeof(randbuf));
randptr = 0;
randomPtr = 0;
}
((char *)buf)[i] = randbuf[randptr++];
((char *)buf)[i] = randomBuf[randomPtr++];
}
#else // not __UNIX_LIKE__
#error No getSecureRandom() implementation available.
#endif // __UNIX_LIKE__
#endif // __WINDOWS__
}
void Utils::lockDownFile(const char *path,bool isDir)

View File

@ -60,7 +60,6 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\ext\lz4\lz4.h" />
<ClInclude Include="..\..\ext\lz4\lz4hc.h" />
<ClInclude Include="..\..\node\Address.hpp" />
<ClInclude Include="..\..\node\AntiRecursion.hpp" />
<ClInclude Include="..\..\node\Array.hpp" />

View File

@ -90,9 +90,6 @@
<ClCompile Include="..\..\node\Utils.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ServiceBase.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@ -129,14 +126,14 @@
<ClCompile Include="..\..\node\Dictionary.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\ext\lz4\lz4.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\ext\lz4\lz4hc.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\node\Address.hpp">
<Filter>Header Files</Filter>
</ClInclude>