| 1011 | } |
| 1012 | |
| 1013 | String RandomString(int length) |
| 1014 | { |
| 1015 | auto *bytes = new unsigned char[length]; |
| 1016 | |
| 1017 | /* Ensure that password generation is atomic. RAND_bytes is not thread-safe |
| 1018 | * in OpenSSL < 1.1.0. |
| 1019 | */ |
| 1020 | std::unique_lock<std::mutex> lock(l_RandomMutex); |
| 1021 | |
| 1022 | if (!RAND_bytes(bytes, length)) { |
| 1023 | delete [] bytes; |
| 1024 | |
| 1025 | char errbuf[256]; |
| 1026 | ERR_error_string_n(ERR_peek_error(), errbuf, sizeof errbuf); |
| 1027 | |
| 1028 | Log(LogCritical, "SSL") |
| 1029 | << "Error for RAND_bytes: " << ERR_peek_error() << ", \"" << errbuf << "\""; |
| 1030 | BOOST_THROW_EXCEPTION(openssl_error() |
| 1031 | << boost::errinfo_api_function("RAND_bytes") |
| 1032 | << errinfo_openssl_error(ERR_peek_error())); |
| 1033 | } |
| 1034 | |
| 1035 | lock.unlock(); |
| 1036 | |
| 1037 | auto *output = new char[length * 2 + 1]; |
| 1038 | for (int i = 0; i < length; i++) |
| 1039 | sprintf(output + 2 * i, "%02x", bytes[i]); |
| 1040 | |
| 1041 | String result = output; |
| 1042 | delete [] bytes; |
| 1043 | delete [] output; |
| 1044 | |
| 1045 | return result; |
| 1046 | } |
| 1047 | |
| 1048 | String BinaryToHex(const unsigned char* data, size_t length) { |
| 1049 | static const char hexdigits[] = "0123456789abcdef"; |
no test coverage detected