diff options
author | Adam Ierymenko <adam.ierymenko@zerotier.com> | 2014-08-08 11:53:55 -0700 |
---|---|---|
committer | Adam Ierymenko <adam.ierymenko@zerotier.com> | 2014-08-08 11:53:55 -0700 |
commit | 502ea66f151b0bef05c5a4183e955c2d358a837a (patch) | |
tree | a538415bb663afaed58c24020ddccdb1a50cf981 | |
parent | 673aab5ba24acf91961972b71ae2b92f5ffe4b83 (diff) | |
download | infinitytier-502ea66f151b0bef05c5a4183e955c2d358a837a.tar.gz infinitytier-502ea66f151b0bef05c5a4183e955c2d358a837a.zip |
Kill ugly old getSecureRandom() and replace with simple wrapper for Windows CAPI and *nix /dev/urandom, and some build fixes.
-rw-r--r-- | node/Dictionary.cpp | 2 | ||||
-rw-r--r-- | node/Utils.cpp | 113 | ||||
-rw-r--r-- | windows/ZeroTierOne/ZeroTierOne.vcxproj | 1 | ||||
-rw-r--r-- | windows/ZeroTierOne/ZeroTierOne.vcxproj.filters | 9 |
4 files changed, 60 insertions, 65 deletions
diff --git a/node/Dictionary.cpp b/node/Dictionary.cpp index 835cc0c9..e050143b 100644 --- a/node/Dictionary.cpp +++ b/node/Dictionary.cpp @@ -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; } diff --git a/node/Utils.cpp b/node/Utils.cpp index 8a27fc9f..86106386 100644 --- a/node/Utils.cpp +++ b/node/Utils.cpp @@ -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; - - Mutex::Lock _l(randomLock); - - // 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); +#ifdef __WINDOWS__ + + static HCRYPTPROV cryptProvider = NULL; + static Mutex globalLock; + + 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; + } } - for(unsigned int i=0;i<bytes;++i) { - if (randptr >= sizeof(randbuf)) { + 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__ - { - 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); - } -#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)); + + 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 (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 -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) diff --git a/windows/ZeroTierOne/ZeroTierOne.vcxproj b/windows/ZeroTierOne/ZeroTierOne.vcxproj index c84d9570..778b7b99 100644 --- a/windows/ZeroTierOne/ZeroTierOne.vcxproj +++ b/windows/ZeroTierOne/ZeroTierOne.vcxproj @@ -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" /> diff --git a/windows/ZeroTierOne/ZeroTierOne.vcxproj.filters b/windows/ZeroTierOne/ZeroTierOne.vcxproj.filters index ee552627..6e7b8804 100644 --- a/windows/ZeroTierOne/ZeroTierOne.vcxproj.filters +++ b/windows/ZeroTierOne/ZeroTierOne.vcxproj.filters @@ -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> |