fork(1) download
  1. #include <boost/filesystem.hpp>
  2. #include <boost/algorithm/string/trim.hpp>
  3. #include <boost/scoped_array.hpp>
  4.  
  5. #include <string>
  6. #include <fstream>
  7. #include <iomanip>
  8. #include <iostream>
  9.  
  10. #include <openssl/evp.h>
  11. #include <openssl/pem.h>
  12. #include <openssl/engine.h>
  13.  
  14.  
  15. using namespace std;
  16.  
  17. enum KeySize
  18. {
  19. Key_1024,
  20. Key_2048
  21. };
  22.  
  23. string getKeySize(const KeySize keySize)
  24. {
  25. switch (keySize)
  26. {
  27. case Key_1024: return "1024";
  28. case Key_2048: return "2048";
  29. }
  30. }
  31.  
  32. string privateKey(const KeySize size, const int keyIndex);
  33. string publicKey(const KeySize size, const int keyIndex);
  34.  
  35. RSA* createPrivateRSA(const string& key);
  36. RSA* createPublicRSA(const string& key);
  37.  
  38. bool RSASign(RSA *rsa,
  39. const unsigned char *Msg,
  40. size_t MsgLen,
  41. unsigned char **EncMsg,
  42. size_t *MsgLenEnc);
  43.  
  44. bool RSAVerifySignature(RSA *rsa,
  45. unsigned char *MsgHash,
  46. size_t MsgHashLen,
  47. const char *Msg,
  48. size_t MsgLen,
  49. bool *Authentic);
  50.  
  51. bool testSignVerify(const string& privateKey, const string& publicKey, const string& plainText);
  52.  
  53. void runTest(const string& text, const KeySize keySize, const int keyIndex)
  54. {
  55. bool success = testSignVerify(privateKey(keySize, keyIndex), publicKey(keySize, keyIndex), text);
  56. cout << getKeySize(keySize) << " bit [" << keyIndex << "] - Text: " << text << " - " << (success ? "Success" : "Failure") << endl;
  57. }
  58.  
  59. int main (int argc, char** argv)
  60. {
  61. // Run simple tests using first 2048 bit keys
  62. runTest("A", Key_2048, 1);
  63. runTest("AA", Key_2048, 1);
  64. runTest("AAA", Key_2048, 1);
  65.  
  66. // Run simple tests using second 2048 bit keys
  67. runTest("A", Key_2048, 2);
  68. runTest("AA", Key_2048, 2);
  69. runTest("AAA", Key_2048, 2);
  70.  
  71. // 1024 bit key seg faults
  72. // runTest("A", Key_1024, 2);
  73.  
  74. return 0;
  75. }
  76.  
  77. RSA* createPrivateRSA(const string& key)
  78. {
  79. RSA *rsa = NULL;
  80. const char *c_string = key.c_str();
  81. BIO *keybio = BIO_new_mem_buf((void *) c_string, -1);
  82. if (keybio == NULL)
  83. {
  84. return 0;
  85. }
  86. rsa = PEM_read_bio_RSAPrivateKey(keybio, &rsa, NULL, NULL);
  87. BIO_free_all(keybio);
  88. return rsa;
  89. }
  90.  
  91. RSA* createPublicRSA(const string& key)
  92. {
  93. RSA *rsa = NULL;
  94. BIO *keybio;
  95. const char *c_string = key.c_str();
  96. keybio = BIO_new_mem_buf((void *) c_string, -1);
  97. if (keybio == NULL)
  98. {
  99. return 0;
  100. }
  101. rsa = PEM_read_bio_RSA_PUBKEY(keybio, &rsa, NULL, NULL);
  102. BIO_free_all(keybio);
  103. return rsa;
  104. }
  105.  
  106. bool testSignVerify(const string& privateKey, const string& publicKey, const string& plainText)
  107. {
  108. // Create an RSA instance of the private key to be used in the hash generation
  109. RSA *privateRSA = createPrivateRSA(privateKey);
  110.  
  111. boost::scoped_array<unsigned char> pHash;
  112. unsigned char* hash;
  113. size_t hashLength;
  114.  
  115. // Generate a hash using <hashAlgorithm> and assign dynamically allocated buffer to scoped pointer
  116. RSASign(privateRSA,
  117. (unsigned char *) plainText.c_str(), plainText.length(),
  118. &hash, &hashLength);
  119. pHash.reset(hash);
  120.  
  121. string hashString((char*)pHash.get());
  122. hashString = hashString.substr(0, hashLength);
  123.  
  124.  
  125. // Verify with public key
  126. RSA *publicRSA = createPublicRSA(publicKey);
  127.  
  128. if (publicRSA == NULL)
  129. {
  130. cerr << "Invalid public key" << endl;
  131. return false;
  132. }
  133.  
  134. bool authentic;
  135. bool result = RSAVerifySignature(publicRSA,
  136. (unsigned char*)hashString.c_str(), hashLength,
  137. plainText.c_str(), plainText.length(),
  138. &authentic);
  139.  
  140. return result & authentic;
  141. }
  142.  
  143.  
  144. bool RSASign(RSA *rsa,
  145. const unsigned char *Msg,
  146. size_t MsgLen,
  147. unsigned char **EncMsg,
  148. size_t *MsgLenEnc)
  149. {
  150. EVP_MD_CTX *m_RSASignCtx = EVP_MD_CTX_create();
  151. EVP_PKEY *priKey = EVP_PKEY_new();
  152. EVP_PKEY_assign_RSA(priKey, rsa);
  153.  
  154. EVP_PKEY_CTX *pctx = NULL;
  155.  
  156. int ret = EVP_DigestSignInit(m_RSASignCtx, &pctx, EVP_sha512() , NULL, priKey);
  157. if (ret <= 0)
  158. {
  159. EVP_MD_CTX_destroy(m_RSASignCtx);
  160. EVP_PKEY_free(priKey);
  161. cerr << "EVP_DigestSignInit failed: " << ret << endl;
  162. return false;
  163. }
  164.  
  165. ret = EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PADDING);
  166. if (ret <= 0)
  167. {
  168. EVP_MD_CTX_destroy(m_RSASignCtx);
  169. EVP_PKEY_free(priKey);
  170. cerr << "EVP_PKEY_CTX_set_rsa_padding failed: " << ret << endl;
  171. return false;
  172. }
  173. ret = EVP_DigestSignUpdate(m_RSASignCtx, Msg, MsgLen);
  174. if (ret <= 0)
  175. {
  176. EVP_MD_CTX_destroy(m_RSASignCtx);
  177. EVP_PKEY_free(priKey);
  178. cerr << "EVP_DigestSignUpdate failed: " << ret << endl;
  179. return false;
  180. }
  181. if (EVP_DigestSignFinal(m_RSASignCtx, NULL, MsgLenEnc) <= 0)
  182. {
  183. EVP_MD_CTX_destroy(m_RSASignCtx);
  184. EVP_PKEY_free(priKey);
  185. cerr << "EVP_DigestSignFinal failed" << endl;
  186. return false;
  187. }
  188.  
  189. *EncMsg = new unsigned char[*MsgLenEnc];
  190.  
  191. if (EVP_DigestSignFinal(m_RSASignCtx, *EncMsg, MsgLenEnc) <= 0)
  192. {
  193. EVP_MD_CTX_destroy(m_RSASignCtx);
  194. EVP_PKEY_free(priKey);
  195. cerr << "EVP_DigestSignFinal failed" << endl;
  196. return false;
  197. }
  198.  
  199. EVP_MD_CTX_destroy(m_RSASignCtx);
  200. EVP_PKEY_free(priKey);
  201.  
  202. return true;
  203. }
  204.  
  205. bool RSAVerifySignature(RSA *rsa,
  206. unsigned char *MsgHash,
  207. size_t MsgHashLen,
  208. const char *Msg,
  209. size_t MsgLen,
  210. bool *Authentic)
  211. {
  212. *Authentic = false;
  213. EVP_PKEY *pubKey = EVP_PKEY_new();
  214.  
  215. EVP_PKEY_assign_RSA(pubKey, rsa);
  216. EVP_MD_CTX *m_RSAVerifyCtx = EVP_MD_CTX_create();
  217.  
  218. EVP_PKEY_CTX *pctx = NULL;
  219.  
  220. int ret = EVP_DigestVerifyInit(m_RSAVerifyCtx, &pctx, EVP_sha512(), NULL, pubKey);
  221. if (ret <= 0)
  222. {
  223. cerr << "EVP_DigestVerifyInit failed: " << ret << endl;
  224. return false;
  225. }
  226. ret = EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PADDING);
  227. if (ret <= 0)
  228. {
  229. cerr << "EVP_PKEY_CTX_set_rsa_padding failed: " << ret << endl;
  230. return false;
  231. }
  232. ret = EVP_DigestVerifyUpdate(m_RSAVerifyCtx, Msg, MsgLen);
  233. if (ret <= 0)
  234. {
  235. cerr << "EVP_DigestVerifyUpdate failed: " << ret << endl;
  236. return false;
  237. }
  238. int AuthStatus = EVP_DigestVerifyFinal(m_RSAVerifyCtx, MsgHash, MsgHashLen);
  239.  
  240. EVP_MD_CTX_destroy(m_RSAVerifyCtx);
  241. EVP_PKEY_free(pubKey);
  242.  
  243. if (AuthStatus == 1)
  244. {
  245. *Authentic = true;
  246. return true;
  247. }
  248. else if (AuthStatus == 0)
  249. {
  250. const char* file = NULL;
  251. int line;
  252. const char* data = NULL;
  253. int flags;
  254.  
  255. // Log errors
  256. unsigned long ret = ERR_get_error_line_data(&file, &line, &data, &flags);
  257. cerr << "Authentication failure: " << ret << ", " << file << ", " << line << ", " << data << ", " << flags << " " << __LINE__ << endl;
  258.  
  259. char errBuf[1000];
  260. cerr << "Error string: " << ERR_error_string(ret, errBuf) << endl;
  261.  
  262. *Authentic = false;
  263. return true;
  264. }
  265. else
  266. {
  267. cout << "Authentication failure: " << ERR_get_error() << " " << __LINE__ << endl;
  268. *Authentic = false;
  269. return false;
  270. }
  271. }
  272.  
  273. string privateKey(const KeySize keySize, const int keyIndex)
  274. {
  275. switch (keySize)
  276. {
  277. // 1024 bit keys
  278. case Key_1024:
  279. switch (keyIndex)
  280. {
  281. case 1:
  282. return "-----BEGIN RSA PRIVATE KEY-----\n"
  283. "MIICWwIBAAKBgQCh+J7AEuTVemaND4PraLV4KaRS8p4dYoCeWGZ7teCjumMmSwGR\n"
  284. "kjnu3B9vzNO/59z5KXii3dY2EIlb1dTn0Cwam696TWMvSfKspVKrgsPhJ3p5TzKA\n"
  285. "9W2iP2bk7u9bNKCOfey0SQRbqVzYA8NL1CDC8ony/gKJ/F/yPkr9dDMLUQIDAQAB\n"
  286. "AoGAU5+09p3Kn50uTS3xghzxdDSrrles4qb0mMwzPTPN4zpb7m1TRgEk//mOEX7C\n"
  287. "5JWlNM8AhbXa3tby1AM2hOipm80IcV+XF3uNdul2AqXZKOOCDUdzEiV8uxaIaSuI\n"
  288. "bYIRl98aaVLz2awG0zTj+Jf6lYUVmB+JOGJr8x5WDY48wUECQQD3Dtv5RBPE1ipf\n"
  289. "H/vrBU0SfTXouRD6TiTRlkPhxcL8VsmHfEaGK5XocrVnaE3cirOD1ioj+y/inqqg\n"
  290. "JS5UJw71AkEAp9VhSV/ZMT5ir+bf7MGlBkoJQKRmUpfnka5feHcXhSJhuRPZXkWY\n"
  291. "gqiXCX4GrvWul2Ifyl9MdFTdIg7W/dTZbQJAHXjOUPwIB7EsuNBN8wlc2lnJdout\n"
  292. "NM7hoYb1bhdzXTrVK65tk0/bwDD+5ukQcMCzDYUc3dH3MmePHy+QSUWniQJAHlgU\n"
  293. "+9gpg5685wK+D6c/N/Dg1WAj4+D1DEDToAsgJID/3B97mHDKzyy+CghQGwfuZg5m\n"
  294. "owcx4oKJbKP0OPZnzQJAdTYkS84V3LhIy5zz8ZvF1pi/8xVsgjClHINEmTzX/zat\n"
  295. "MQ34nMNULKVvZ3JCpxfc/aA91a";
  296.  
  297. default:
  298. return "";
  299. }
  300.  
  301. // 2048 bit keys
  302. case Key_2048:
  303. switch (keyIndex)
  304. {
  305. case 1:
  306. return "-----BEGIN RSA PRIVATE KEY-----\n"
  307. "MIIEogIBAAKCAQEAsuTQfBSGr1Ru8hcbGV7uRwB7P3MA3ErB3SErNtok0PAmbVfC\n"
  308. "G99uk3nm4mS5SaB60aWbUzf4R8naexZcyKqAaqnMrGsd3eMjzEY8XR7aGTzM00LK\n"
  309. "umG6lyaYr1z7rqNRso9IQmebIu9W3jpvKgw9wvmf4W2tuaviTZ0f/tHVB3VW4Wby\n"
  310. "xcgch04hhDkHX1dp1CSFZXRDSGp2MJQ3FAHB9rX+3UGjy2sjWLQqcoIs7KztI5/j\n"
  311. "gaOoQGSQj7gBM0+LNFoUXFDju/u7MYeob1KEBWvmQxa8XZlHcr6sGwIruC12cBjv\n"
  312. "7jxMlrjILxB2Vr+UQb3PDAlsESuahw6DTooi4QIDAQABAoIBAGgIaLW/uhN8Joji\n"
  313. "pv+6FRd1UDc1yepSDytpfpgHhCF9httPjbJn3QYmff5qVNZcXRBOHmXmxpv45vVt\n"
  314. "q8eGX+enlz8ti9DdppPExJXiuzKyCOtSjFKXQstjxqc0i6ijkX8llAAKAE3wobPa\n"
  315. "h4sMU15vjGqsPbscGh7IoTKvFBOhUEr+6LmdfbdfmQXNGsi7GGLqiuvZa8yFBUTd\n"
  316. "bG80Qwm+r+NVesz0WubjY7QK0GOC4eZH3SDgTCH/3326dq18lRMmjm+Ia3ofXs6/\n"
  317. "RvSusCERtoAbxxShkYHeUrO9hRCwAvkNZXE0dNGWas7p+53uHxUkTup4phXdkRFf\n"
  318. "8zEf4AECgYEA20ksmk2UfxW8tpGj8mU16c0DsEE/yAj5dzyj00RsVmYOBm0IQn9+\n"
  319. "fzLv/RKpuITrQFGhtA4UedetkTH92/ed5URDp+MW8qRNUScvRP/8HDCGC+Taiawg\n"
  320. "MPCaEzzbHXZXPwc8axhZR8hHhve17faaJHsajK5JfXn62h02IQNVVXECgYEA0Nhk\n"
  321. "/LzxQU6MyzT1lqhN/H6eRIw1nL1JU5MyDAc/9tzzPn87+NEWt71QdyiBzUvmLfDh\n"
  322. "JRNH8myA0j5ivZN6LNFhNs3C5UDgwknEXDUoKPYzuEl6RNp4L9lN8YTXW/jUJl44\n"
  323. "GIMsfVmmzOUa1pADfszZLuv+J6sn5GyGdYYwLHECgYBaNFSruMQgLwHtHCYT3Tx7\n"
  324. "S8F7rKufDsoIGaLOknP6aorUa9+c8zNHAd4k/ZthcxQO5kWderlDkcwtUSI7bTW/\n"
  325. "jQBDvK/A6oN/oZ3ZRXAg7HkHxYF8ZpjraN4Ikd0U1ox3OfPJnj+Dvshlpdpp5Cpu\n"
  326. "XVGDk2JZwmbFeIS+uc9NkQKBgHJyQ1UlDWhmbU1mZjb7YFE/6edSloagTDCad1CU\n"
  327. "IH9dsYbMHsdJfZOPEStbbVZdg3QljpvMpx64SxfrzBxrVwZ8bzOjKmyLUx/lYM/O\n"
  328. "6YUY9lrFGVXmCvrdsJLr40CpaUjlVQRJzfWbTYb2/fAa12+DPnkyJgMDDkdlGYIJ\n"
  329. "2RhhAoGAezeE0TOk/U1g7I3E/pYP3mtXE0Ok4Dy+3QxpA0pB9Wl0YfljceskFbq3\n"
  330. "1rtG+2Nnle3x1Y0dmr8/5JvCORBQqRVxOaLdnmZBlCjd+/zM+b6yzlHiAZkrNKij\n"
  331. "87fydFOTSAVGYcyd522CiMKFsKNMv4FL6DX/RZaKI+7m4WNaBYg=\n"
  332. "-----END RSA PRIVATE KEY-----";
  333.  
  334. case 2:
  335. return "-----BEGIN RSA PRIVATE KEY-----\n"
  336. "MIIEogIBAAKCAQBd9JlX4B1X6j6FMimSYyW7uMgjC3VtYPgvSp2++1jPJU0OXU7C\n"
  337. "kv6sKfSS1bUslTD1Vk6bmhacrTmVFdpLMWYhgUnSTTX9jcb1PJGvvLttHDsQooNC\n"
  338. "fTDTrE7W0u0bpwD6J882aEHVm+WER3nvYwKz3mLMA+J1ajiT8RmmSuHrUy1u/0iy\n"
  339. "OWTEgT/0mx0H3Pl2XktPsRM94XZTxj6Jf8RWLT830uicNkfjMGC221I+Civ0rO0k\n"
  340. "y270dWrcG74kVeR10jEmMvQNtlIKUscMQFhTu+57mMuiCeD5VnK1LHaW+N23bzks\n"
  341. "ccMKPeGlOFw586l/jvwM7FygooL18N0yOw5zAgMBAAECggEAE3c71fL+4VoMvffY\n"
  342. "mRWlmbD89hXHrHOst8+Twx+8FJ67ykAWs0VVMkI3A7z3HleCnzHUc3SHPsq85WBz\n"
  343. "q6R+bm6k5sdMak3XbLOx02Ecy8xPiHDDFSFu3kwSwXtN2K7PCwT4b2NGUIVOFgvg\n"
  344. "/XHb+3wVqAMeBgmN00jecY+OIv0GHoVgfOseIEZ4EhrdqqPBsOcKSSelNhto4Zc2\n"
  345. "jJ6QGAtrYqlEbIth2ohpx5vKltQlnrQH6a6jPg8qc/7WTD4DiF0gDpJWeDwH/jbM\n"
  346. "2Htz5STO8qo1DGMwU7dOgJeP1KHZjH3M0QpIUJLOQ32JnP1PS3dh7mprRIR+eOGB\n"
  347. "0Ea8IQKBgQCqXbMX2R84rJauZi2BisM9Yo3tMo2U17dRaXw2qb6YxuweI2tyw4Xa\n"
  348. "B6FafEDDlJiqAoJFtl6IS0NrMo/zjJfNO7L7Jsi24rJe/t9rGPXRM5viDtORXBo6\n"
  349. "ceCRKiSsLDrNyuLGT5Q2yL3ixuconAIKqjobyYjISnjaxU3sH9rUmwKBgQCNLpGN\n"
  350. "+zxHQTIE0a6B20S3M1yeg/hF/hQkSwIxu69IeF/yi+N/17ZhJtGmCQaWThAZZzgR\n"
  351. "BPIRhZdZKMlTTUNkmMtgw62Q3n8P2Vv/d00pCFsY/dloJxYjD9HYy/ZmORZCCBZ5\n"
  352. "JOegymWVi1NUhrLBeO8dA8TVoRfXEqiyq0WPCQKBgQCWXCZBaQZuLZy7hUCqcT7J\n"
  353. "gZ8DdreQYybO+ot/bybhjcc8/kPJwRj0igF1a+5470Ah5B73yfH61npFNRXpfO9J\n"
  354. "WmQn114UU1XcE5Q54Iirv6HXzQAa7a/UX0c0t34wWsT3dhXZssh75YX5jVTc+Xuv\n"
  355. "z/eDKMbJBzlM1BBm0uJ++wKBgEnJaPFXuS1UeZvjKt1biBJnmaSPPJb4L/a37TGo\n"
  356. "8fdiUmMlkYUjbIJiE3g/h13O9sMQG1Fp0EowE+XZVz9eRjaxVLoCCxiH8MiLxXVD\n"
  357. "GOS1JUduhM3Wf89bWUWBdAoBFAz2xSgTjauPnIAIDUlEDPDpD6+OZLVyOE+DxP98\n"
  358. "XCJhAoGACLEIDSzHlJmyNa1Ejciidsb7x816hBE7N56SDMj8HcTveU6W2usYmW+x\n"
  359. "v53dvftct3nIsNM6zvrxIT7TWraiC4yahR1ro8fDlgYerJSB5CXS7HHR+AqIgjuR\n"
  360. "TQLc9h404JCmoowuvXxCPVhS+OrTt8R2AXVBMQtCj2Nl55EbUwA=\n"
  361. "-----END RSA PRIVATE KEY-----";
  362.  
  363. default:
  364. return "";
  365. }
  366. }
  367. }
  368.  
  369. string publicKey(const KeySize keySize, const int keyIndex)
  370. {
  371. switch (keySize)
  372. {
  373. // 1024 bit keys
  374. case Key_1024:
  375. switch (keyIndex)
  376. {
  377. case 1:
  378. return "-----BEGIN PUBLIC KEY-----\n"
  379. "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCh+J7AEuTVemaND4PraLV4KaRS\n"
  380. "8p4dYoCeWGZ7teCjumMmSwGRkjnu3B9vzNO/59z5KXii3dY2EIlb1dTn0Cwam696\n"
  381. "TWMvSfKspVKrgsPhJ3p5TzKA9W2iP2bk7u9bNKCOfey0SQRbqVzYA8NL1CDC8ony\n"
  382. "/gKJ/F/yPkr9dDMLUQIDAQAB\n"
  383. "-----END PUBLIC KEY-----";
  384. }
  385.  
  386. // 2048 bit keys
  387. case Key_2048:
  388. switch (keyIndex)
  389. {
  390. // 2048 bit - 1
  391. case 1:
  392. return "-----BEGIN PUBLIC KEY-----\n"
  393. "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsuTQfBSGr1Ru8hcbGV7u\n"
  394. "RwB7P3MA3ErB3SErNtok0PAmbVfCG99uk3nm4mS5SaB60aWbUzf4R8naexZcyKqA\n"
  395. "aqnMrGsd3eMjzEY8XR7aGTzM00LKumG6lyaYr1z7rqNRso9IQmebIu9W3jpvKgw9\n"
  396. "wvmf4W2tuaviTZ0f/tHVB3VW4Wbyxcgch04hhDkHX1dp1CSFZXRDSGp2MJQ3FAHB\n"
  397. "9rX+3UGjy2sjWLQqcoIs7KztI5/jgaOoQGSQj7gBM0+LNFoUXFDju/u7MYeob1KE\n"
  398. "BWvmQxa8XZlHcr6sGwIruC12cBjv7jxMlrjILxB2Vr+UQb3PDAlsESuahw6DTooi\n"
  399. "4QIDAQAB\n"
  400. "-----END PUBLIC KEY-----";
  401.  
  402. // 2048 bit - 2
  403. case 2:
  404. return "-----BEGIN PUBLIC KEY-----\n"
  405. "MIIBITANBgkqhkiG9w0BAQEFAAOCAQ4AMIIBCQKCAQBd9JlX4B1X6j6FMimSYyW7\n"
  406. "uMgjC3VtYPgvSp2++1jPJU0OXU7Ckv6sKfSS1bUslTD1Vk6bmhacrTmVFdpLMWYh\n"
  407. "gUnSTTX9jcb1PJGvvLttHDsQooNCfTDTrE7W0u0bpwD6J882aEHVm+WER3nvYwKz\n"
  408. "3mLMA+J1ajiT8RmmSuHrUy1u/0iyOWTEgT/0mx0H3Pl2XktPsRM94XZTxj6Jf8RW\n"
  409. "LT830uicNkfjMGC221I+Civ0rO0ky270dWrcG74kVeR10jEmMvQNtlIKUscMQFhT\n"
  410. "u+57mMuiCeD5VnK1LHaW+N23bzksccMKPeGlOFw586l/jvwM7FygooL18N0yOw5z\n"
  411. "AgMBAAE=\n"
  412. "-----END PUBLIC KEY-----";
  413.  
  414. default:
  415. return "";
  416. }
  417. }
  418. }
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cpp:10:25: fatal error: openssl/evp.h: No such file or directory
 #include <openssl/evp.h>
                         ^
compilation terminated.
stdout
Standard output is empty