goahead-openssl.c 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912
  1. /*
  2. goahead-openssl.c - OpensSSL socket layer for GoAhead
  3. This is the interface between GoAhead and the OpenSSL stack.
  4. Copyright (c) All Rights Reserved. See details at the end of the file.
  5. */
  6. /************************************ Include *********************************/
  7. #include "goahead.h"
  8. #if ME_COM_OPENSSL
  9. #if ME_UNIX_LIKE
  10. /*
  11. Mac OS X OpenSSL stack is deprecated. Suppress those warnings.
  12. */
  13. #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
  14. #endif
  15. /* Clashes with WinCrypt.h */
  16. #undef OCSP_RESPONSE
  17. #ifndef ME_GOAHEAD_SSL_HANDSHAKES
  18. #define ME_GOAHEAD_SSL_HANDSHAKES 0 /* Defaults to infinite */
  19. #endif
  20. #ifndef ME_GOAHEAD_SSL_RENEGOTIATE
  21. #define ME_GOAHEAD_SSL_RENEGOTIATE 1
  22. #endif
  23. /*
  24. Indent includes to bypass MakeMe dependencies
  25. */
  26. #include <openssl/ssl.h>
  27. #include <openssl/evp.h>
  28. #include <openssl/rand.h>
  29. #include <openssl/err.h>
  30. #include <openssl/dh.h>
  31. /************************************* Defines ********************************/
  32. /*
  33. Default ciphers from Mozilla (https://wiki.mozilla.org/Security/Server_Side_TLS) without SSLv3 ciphers.
  34. TLSv1 and TLSv2 only. Recommended RSA and DH parameter size: 2048 bits.
  35. See cipher mappings at: https://wiki.mozilla.org/Security/Server_Side_TLS#Cipher_names_correspondence_table
  36. Rationale:
  37. * AES256-GCM is prioritized above its 128 bits variant, and ChaCha20 because we assume that most modern
  38. devices support AESNI instructions and thus benefit from fast and constant time AES.
  39. * We recommend ECDSA certificates with P256 as other curves may not be supported everywhere. RSA signatures
  40. on ECDSA certificates are permitted because very few CAs sign with ECDSA at the moment.
  41. * DHE is removed entirely because it is slow in comparison with ECDHE, and all modern clients support
  42. elliptic curve key exchanges.
  43. * SHA1 signature algorithm is removed in favor of SHA384 for AES256 and SHA256 for AES128.
  44. */
  45. #if OPENSSL_VERSION_NUMBER >= 0x10100000L
  46. #define OPENSSL_DEFAULT_CIPHERS "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256"
  47. #else
  48. #define OPENSSL_DEFAULT_CIPHERS "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4:!SSLv3"
  49. #endif
  50. /*
  51. Map Iana names to OpenSSL names
  52. */
  53. typedef struct CipherMap {
  54. int code;
  55. char *name;
  56. char *ossName;
  57. } CipherMap;
  58. static CipherMap cipherMap[] = {
  59. { 0x0004, "TLS_RSA_WITH_RC4_128_MD5", "RC4-MD5" },
  60. { 0x0005, "TLS_RSA_WITH_RC4_128_SHA", "RC4-SHA" },
  61. { 0x0007, "TLS_RSA_WITH_IDEA_CBC_SHA", "IDEA-CBC-SHA" },
  62. { 0x0009, "TLS_RSA_WITH_DES_CBC_SHA", "DES-CBC-SHA" },
  63. { 0x000A, "TLS_RSA_WITH_3DES_EDE_CBC_SHA", "DES-CBC3-SHA" },
  64. { 0x000C, "TLS_DH_DSS_WITH_DES_CBC_SHA", "DH-DSS-DES-CBC-SHA" },
  65. { 0x000D, "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA", "DH-DSS-DES-CBC3-SHA" },
  66. { 0x000F, "TLS_DH_RSA_WITH_DES_CBC_SHA", "DH-RSA-DES-CBC-SHA" },
  67. { 0x0010, "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA", "DH-RSA-DES-CBC3-SHA" },
  68. { 0x0012, "TLS_DHE_DSS_WITH_DES_CBC_SHA", "EDH-DSS-DES-CBC-SHA" },
  69. { 0x0013, "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA", "EDH-DSS-DES-CBC3-SHA" },
  70. { 0x0015, "TLS_DHE_RSA_WITH_DES_CBC_SHA", "EDH-RSA-DES-CBC-SHA" },
  71. { 0x0016, "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA", "EDH-RSA-DES-CBC3-SHA" },
  72. { 0x002F, "TLS_RSA_WITH_AES_128_CBC_SHA", "AES128-SHA" },
  73. { 0x0030, "TLS_DH_DSS_WITH_AES_128_CBC_SHA", "DH-DSS-AES128-SHA" },
  74. { 0x0031, "TLS_DH_RSA_WITH_AES_128_CBC_SHA", "DH-RSA-AES128-SHA" },
  75. { 0x0032, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", "DHE-DSS-AES128-SHA" },
  76. { 0x0033, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", "DHE-RSA-AES128-SHA" },
  77. { 0x0035, "TLS_RSA_WITH_AES_256_CBC_SHA", "AES256-SHA" },
  78. { 0x0036, "TLS_DH_DSS_WITH_AES_256_CBC_SHA", "DH-DSS-AES256-SHA" },
  79. { 0x0037, "TLS_DH_RSA_WITH_AES_256_CBC_SHA", "DH-RSA-AES256-SHA" },
  80. { 0x0038, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA", "DHE-DSS-AES256-SHA" },
  81. { 0x0039, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", "DHE-RSA-AES256-SHA" },
  82. { 0x003C, "TLS_RSA_WITH_AES_128_CBC_SHA256", "AES128-SHA256" },
  83. { 0x003D, "TLS_RSA_WITH_AES_256_CBC_SHA256", "AES256-SHA256" },
  84. { 0x003E, "TLS_DH_DSS_WITH_AES_128_CBC_SHA256", "DH-DSS-AES128-SHA256" },
  85. { 0x003F, "TLS_DH_RSA_WITH_AES_128_CBC_SHA256", "DH-RSA-AES128-SHA256" },
  86. { 0x0040, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256", "DHE-DSS-AES128-SHA256" },
  87. { 0x0041, "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA", "CAMELLIA128-SHA" },
  88. { 0x0042, "TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA", "DH-DSS-CAMELLIA128-SHA" },
  89. { 0x0043, "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA", "DH-RSA-CAMELLIA128-SHA" },
  90. { 0x0044, "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA", "DHE-DSS-CAMELLIA128-SHA" },
  91. { 0x0045, "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA", "DHE-RSA-CAMELLIA128-SHA" },
  92. { 0x0067, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", "DHE-RSA-AES128-SHA256" },
  93. { 0x0068, "TLS_DH_DSS_WITH_AES_256_CBC_SHA256", "DH-DSS-AES256-SHA256" },
  94. { 0x0069, "TLS_DH_RSA_WITH_AES_256_CBC_SHA256", "DH-RSA-AES256-SHA256" },
  95. { 0x006A, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256", "DHE-DSS-AES256-SHA256" },
  96. { 0x006B, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", "DHE-RSA-AES256-SHA256" },
  97. { 0x0084, "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA", "CAMELLIA256-SHA" },
  98. { 0x0085, "TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA", "DH-DSS-CAMELLIA256-SHA" },
  99. { 0x0086, "TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA", "DH-RSA-CAMELLIA256-SHA" },
  100. { 0x0087, "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA", "DHE-DSS-CAMELLIA256-SHA" },
  101. { 0x0088, "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA", "DHE-RSA-CAMELLIA256-SHA" },
  102. { 0x008A, "TLS_PSK_WITH_RC4_128_SHA", "PSK-RC4-SHA" },
  103. { 0x008B, "TLS_PSK_WITH_3DES_EDE_CBC_SHA", "PSK-3DES-EDE-CBC-SHA" },
  104. { 0x008C, "TLS_PSK_WITH_AES_128_CBC_SHA", "PSK-AES128-CBC-SHA" },
  105. { 0x008D, "TLS_PSK_WITH_AES_256_CBC_SHA", "PSK-AES256-CBC-SHA" },
  106. { 0x0096, "TLS_RSA_WITH_SEED_CBC_SHA", "SEED-SHA" },
  107. { 0x0097, "TLS_DH_DSS_WITH_SEED_CBC_SHA", "DH-DSS-SEED-SHA" },
  108. { 0x0098, "TLS_DH_RSA_WITH_SEED_CBC_SHA", "DH-RSA-SEED-SHA" },
  109. { 0x0099, "TLS_DHE_DSS_WITH_SEED_CBC_SHA", "DHE-DSS-SEED-SHA" },
  110. { 0x009A, "TLS_DHE_RSA_WITH_SEED_CBC_SHA", "DHE-RSA-SEED-SHA" },
  111. { 0x009C, "TLS_RSA_WITH_AES_128_GCM_SHA256", "AES128-GCM-SHA256" },
  112. { 0x009D, "TLS_RSA_WITH_AES_256_GCM_SHA384", "AES256-GCM-SHA384" },
  113. { 0x009E, "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", "DHE-RSA-AES128-GCM-SHA256" },
  114. { 0x009F, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", "DHE-RSA-AES256-GCM-SHA384" },
  115. { 0x00A0, "TLS_DH_RSA_WITH_AES_128_GCM_SHA256", "DH-RSA-AES128-GCM-SHA256" },
  116. { 0x00A1, "TLS_DH_RSA_WITH_AES_256_GCM_SHA384", "DH-RSA-AES256-GCM-SHA384" },
  117. { 0x00A2, "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256", "DHE-DSS-AES128-GCM-SHA256" },
  118. { 0x00A3, "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384", "DHE-DSS-AES256-GCM-SHA384" },
  119. { 0x00A4, "TLS_DH_DSS_WITH_AES_128_GCM_SHA256", "DH-DSS-AES128-GCM-SHA256" },
  120. { 0x00A5, "TLS_DH_DSS_WITH_AES_256_GCM_SHA384", "DH-DSS-AES256-GCM-SHA384" },
  121. { 0xC002, "TLS_ECDH_ECDSA_WITH_RC4_128_SHA", "ECDH-ECDSA-RC4-SHA" },
  122. { 0xC003, "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA", "ECDH-ECDSA-DES-CBC3-SHA" },
  123. { 0xC004, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", "ECDH-ECDSA-AES128-SHA" },
  124. { 0xC005, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", "ECDH-ECDSA-AES256-SHA" },
  125. { 0xC007, "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", "ECDHE-ECDSA-RC4-SHA" },
  126. { 0xC008, "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA", "ECDHE-ECDSA-DES-CBC3-SHA" },
  127. { 0xC009, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", "ECDHE-ECDSA-AES128-SHA" },
  128. { 0xC00A, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", "ECDHE-ECDSA-AES256-SHA" },
  129. { 0xC00C, "TLS_ECDH_RSA_WITH_RC4_128_SHA", "ECDH-RSA-RC4-SHA" },
  130. { 0xC00D, "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA", "ECDH-RSA-DES-CBC3-SHA" },
  131. { 0xC00E, "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", "ECDH-RSA-AES128-SHA" },
  132. { 0xC00F, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", "ECDH-RSA-AES256-SHA" },
  133. { 0xC011, "TLS_ECDHE_RSA_WITH_RC4_128_SHA", "ECDHE-RSA-RC4-SHA" },
  134. { 0xC012, "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", "ECDHE-RSA-DES-CBC3-SHA" },
  135. { 0xC013, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", "ECDHE-RSA-AES128-SHA" },
  136. { 0xC014, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", "ECDHE-RSA-AES256-SHA" },
  137. { 0xC01A, "TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA", "SRP-3DES-EDE-CBC-SHA" },
  138. { 0xC01B, "TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA", "SRP-RSA-3DES-EDE-CBC-SHA" },
  139. { 0xC01C, "TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA", "SRP-DSS-3DES-EDE-CBC-SHA" },
  140. { 0xC01D, "TLS_SRP_SHA_WITH_AES_128_CBC_SHA", "SRP-AES-128-CBC-SHA" },
  141. { 0xC01E, "TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA", "SRP-RSA-AES-128-CBC-SHA" },
  142. { 0xC01F, "TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA", "SRP-DSS-AES-128-CBC-SHA" },
  143. { 0xC020, "TLS_SRP_SHA_WITH_AES_256_CBC_SHA", "SRP-AES-256-CBC-SHA" },
  144. { 0xC021, "TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA", "SRP-RSA-AES-256-CBC-SHA" },
  145. { 0xC022, "TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA", "SRP-DSS-AES-256-CBC-SHA" },
  146. { 0xC023, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", "ECDHE-ECDSA-AES128-SHA256" },
  147. { 0xC024, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", "ECDHE-ECDSA-AES256-SHA384" },
  148. { 0xC025, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256", "ECDH-ECDSA-AES128-SHA256" },
  149. { 0xC026, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384", "ECDH-ECDSA-AES256-SHA384" },
  150. { 0xC027, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", "ECDHE-RSA-AES128-SHA256" },
  151. { 0xC028, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", "ECDHE-RSA-AES256-SHA384" },
  152. { 0xC029, "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256", "ECDH-RSA-AES128-SHA256" },
  153. { 0xC02A, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384", "ECDH-RSA-AES256-SHA384" },
  154. { 0xC02B, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "ECDHE-ECDSA-AES128-GCM-SHA256" },
  155. { 0xC02C, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "ECDHE-ECDSA-AES256-GCM-SHA384" },
  156. { 0xC02D, "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256", "ECDH-ECDSA-AES128-GCM-SHA256" },
  157. { 0xC02E, "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384", "ECDH-ECDSA-AES256-GCM-SHA384" },
  158. { 0xC02F, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "ECDHE-RSA-AES128-GCM-SHA256" },
  159. { 0xC030, "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "ECDHE-RSA-AES256-GCM-SHA384" },
  160. { 0xC031, "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256", "ECDH-RSA-AES128-GCM-SHA256" },
  161. { 0xC032, "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384", "ECDH-RSA-AES256-GCM-SHA384" },
  162. { 0x0000, 0 },
  163. };
  164. /*
  165. OpenSSL context (singleton)
  166. */
  167. static SSL_CTX *sslctx = NULL;
  168. typedef struct RandBuf {
  169. time_t now;
  170. int pid;
  171. } RandBuf;
  172. #define VERIFY_DEPTH 10
  173. /*
  174. Used for OpenSSL versions < 1.0.2
  175. */
  176. #ifndef ME_GOAHEAD_SSL_CURVE
  177. #define ME_GOAHEAD_SSL_CURVE "prime256v1"
  178. #endif
  179. /*
  180. DH parameters
  181. */
  182. static DH *dhKey;
  183. static int maxHandshakes;
  184. /************************************ Forwards ********************************/
  185. static DH *dhcallback(SSL *handle, int is_export, int keylength);
  186. static DH *getDhKey();
  187. static char *mapCipherNames(char *ciphers);
  188. static int sslSetCertFile(char *certFile);
  189. static int sslSetKeyFile(char *keyFile);
  190. static int verifyClientCertificate(int ok, X509_STORE_CTX *ctx);
  191. static void infoCallback(const SSL *ssl, int where, int rc);
  192. /************************************** Code **********************************/
  193. /*
  194. Open the SSL module
  195. */
  196. PUBLIC int sslOpen()
  197. {
  198. RandBuf randBuf;
  199. X509_STORE *store;
  200. uchar resume[16];
  201. char *ciphers;
  202. trace(7, "Initializing SSL");
  203. randBuf.now = time(0);
  204. randBuf.pid = getpid();
  205. RAND_seed((void*) &randBuf, sizeof(randBuf));
  206. #if ME_UNIX_LIKE
  207. trace(6, "OpenSsl: Before calling RAND_load_file");
  208. RAND_load_file("/dev/urandom", 256);
  209. trace(6, "OpenSsl: After calling RAND_load_file");
  210. #endif
  211. #if !ME_WIN_LIKE
  212. OpenSSL_add_all_algorithms();
  213. #endif
  214. SSL_library_init();
  215. SSL_load_error_strings();
  216. SSLeay_add_ssl_algorithms();
  217. if ((sslctx = SSL_CTX_new(SSLv23_server_method())) == 0) {
  218. error("Unable to create SSL context");
  219. return -1;
  220. }
  221. /*
  222. Set the server certificate and key files
  223. */
  224. if (*ME_GOAHEAD_SSL_KEY && sslSetKeyFile(ME_GOAHEAD_SSL_KEY) < 0) {
  225. sslClose();
  226. return -1;
  227. }
  228. if (*ME_GOAHEAD_SSL_CERTIFICATE && sslSetCertFile(ME_GOAHEAD_SSL_CERTIFICATE) < 0) {
  229. sslClose();
  230. return -1;
  231. }
  232. if (ME_GOAHEAD_SSL_VERIFY_PEER) {
  233. SSL_CTX_set_verify(sslctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verifyClientCertificate);
  234. SSL_CTX_set_verify_depth(sslctx, VERIFY_DEPTH);
  235. } else {
  236. SSL_CTX_set_verify(sslctx, SSL_VERIFY_NONE, verifyClientCertificate);
  237. }
  238. /*
  239. Set the client certificate verification locations
  240. */
  241. if (ME_GOAHEAD_SSL_AUTHORITY && *ME_GOAHEAD_SSL_AUTHORITY) {
  242. if ((!SSL_CTX_load_verify_locations(sslctx, ME_GOAHEAD_SSL_AUTHORITY, NULL)) ||
  243. (!SSL_CTX_set_default_verify_paths(sslctx))) {
  244. error("Unable to read cert verification locations");
  245. sslClose();
  246. return -1;
  247. }
  248. /*
  249. Define the list of CA certificates to send to the client before they send their client
  250. certificate for validation
  251. */
  252. SSL_CTX_set_client_CA_list(sslctx, SSL_load_client_CA_file(ME_GOAHEAD_SSL_AUTHORITY));
  253. }
  254. if (ME_GOAHEAD_SSL_REVOKE && *ME_GOAHEAD_SSL_REVOKE) {
  255. store = SSL_CTX_get_cert_store(sslctx);
  256. if (!X509_STORE_load_locations(store, ME_GOAHEAD_SSL_REVOKE, 0)) {
  257. error("Cannot load certificate revoke list: %s", ME_GOAHEAD_SSL_REVOKE);
  258. sslClose();
  259. return -1;
  260. }
  261. }
  262. /*
  263. Configure DH parameters
  264. */
  265. dhKey = getDhKey();
  266. SSL_CTX_set_tmp_dh_callback(sslctx, dhcallback);
  267. /*
  268. Configure cipher suite
  269. */
  270. if (ME_GOAHEAD_SSL_CIPHERS && *ME_GOAHEAD_SSL_CIPHERS) {
  271. ciphers = ME_GOAHEAD_SSL_CIPHERS;
  272. } else {
  273. ciphers = OPENSSL_DEFAULT_CIPHERS;
  274. }
  275. ciphers = mapCipherNames(ciphers);
  276. trace(5, "Using OpenSSL ciphers: %s", ciphers);
  277. if (SSL_CTX_set_cipher_list(sslctx, ciphers) != 1) {
  278. error("Unable to set cipher list \"%s\"", ciphers);
  279. sslClose();
  280. wfree(ciphers);
  281. return -1;
  282. }
  283. wfree(ciphers);
  284. /*
  285. Define default OpenSSL options
  286. */
  287. SSL_CTX_set_options(sslctx, SSL_OP_ALL);
  288. /*
  289. Ensure we generate a new private key for each connection
  290. */
  291. SSL_CTX_set_options(sslctx, SSL_OP_SINGLE_DH_USE);
  292. /*
  293. Define a session reuse context
  294. */
  295. RAND_bytes(resume, sizeof(resume));
  296. SSL_CTX_set_session_id_context(sslctx, resume, sizeof(resume));
  297. /*
  298. Elliptic Curve initialization
  299. */
  300. #if SSL_OP_SINGLE_ECDH_USE
  301. #ifdef SSL_CTX_set_ecdh_auto
  302. SSL_CTX_set_ecdh_auto(sslctx, 1);
  303. #else
  304. {
  305. EC_KEY *ecdh;
  306. cchar *name;
  307. int nid;
  308. name = ME_GOAHEAD_SSL_CURVE;
  309. if ((nid = OBJ_sn2nid(name)) == 0) {
  310. error("Unknown curve name \"%s\"", name);
  311. sslClose();
  312. return -1;
  313. }
  314. if ((ecdh = EC_KEY_new_by_curve_name(nid)) == 0) {
  315. error("Unable to create curve \"%s\"", name);
  316. sslClose();
  317. return -1;
  318. }
  319. SSL_CTX_set_options(sslctx, SSL_OP_SINGLE_ECDH_USE);
  320. SSL_CTX_set_tmp_ecdh(sslctx, ecdh);
  321. EC_KEY_free(ecdh);
  322. }
  323. #endif
  324. #endif
  325. SSL_CTX_set_mode(sslctx, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_AUTO_RETRY | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
  326. #ifdef SSL_OP_MSIE_SSLV2_RSA_PADDING
  327. SSL_CTX_set_options(sslctx, SSL_OP_MSIE_SSLV2_RSA_PADDING);
  328. #endif
  329. #ifdef SSL_MODE_RELEASE_BUFFERS
  330. SSL_CTX_set_mode(sslctx, SSL_MODE_RELEASE_BUFFERS);
  331. #endif
  332. #ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
  333. SSL_CTX_set_mode(sslctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
  334. #endif
  335. /*
  336. Select the required protocols
  337. Disable both SSLv2 and SSLv3 by default - they are insecure
  338. */
  339. SSL_CTX_set_options(sslctx, SSL_OP_NO_SSLv2);
  340. SSL_CTX_set_options(sslctx, SSL_OP_NO_SSLv3);
  341. #if defined(SSL_OP_NO_TLSv1) && ME_GOAHEAD_SSL_NO_V1
  342. SSL_CTX_set_options(sslctx, SSL_OP_NO_TLSv1);
  343. #endif
  344. #if defined(SSL_OP_NO_TLSv1_1) && ME_GOAHEAD_SSL_NO_V1_1
  345. SSL_CTX_set_options(sslctx, SSL_OP_NO_TLSv1_1);
  346. #endif
  347. #if defined(SSL_OP_NO_TLSv1_2) && ME_GOAHEAD_SSL_NO_V1_2
  348. SSL_CTX_set_options(sslctx, SSL_OP_NO_TLSv1_2);
  349. #endif
  350. #if defined(SSL_OP_NO_TLSv1_3) && ME_GOAHEAD_SSL_NO_V1_3
  351. SSL_CTX_set_options(sslctx, SSL_OP_NO_TLSv1_3);
  352. #endif
  353. #if defined(SSL_OP_NO_TICKET)
  354. /*
  355. Ticket based session reuse is enabled by default
  356. */
  357. #if defined(ME_GOAHEAD_SSL_TICKET)
  358. if (ME_GOAHEAD_SSL_TICKET) {
  359. SSL_CTX_clear_options(sslctx, SSL_OP_NO_TICKET);
  360. } else {
  361. SSL_CTX_set_options(sslctx, SSL_OP_NO_TICKET);
  362. }
  363. #else
  364. SSL_CTX_clear_options(sslctx, SSL_OP_NO_TICKET);
  365. #endif
  366. #endif
  367. #if defined(SSL_OP_NO_COMPRESSION)
  368. /*
  369. CRIME attack targets compression
  370. */
  371. SSL_CTX_clear_options(sslctx, SSL_OP_NO_COMPRESSION);
  372. #endif
  373. #if defined(ME_GOAHEAD_SSL_HANDSHAKES)
  374. maxHandshakes = ME_GOAHEAD_SSL_HANDSHAKES;
  375. #endif
  376. #if defined(SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)
  377. /*
  378. Disables a countermeasure against a SSL 3.0/TLS 1.0 protocol vulnerability affecting CBC ciphers.
  379. Defaults to true.
  380. */
  381. #if defined(ME_GOAHEAD_SSL_EMPTY_FRAGMENTS)
  382. if (ME_GOAHEAD_SSL_EMPTY_FRAGMENTS) {
  383. /* SSL_OP_ALL disables empty fragments. Only needed for ancient browsers like IE-6 on SSL-3.0/TLS-1.0 */
  384. SSL_CTX_clear_options(sslctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
  385. } else {
  386. SSL_CTX_set_options(sslctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
  387. }
  388. #else
  389. SSL_CTX_set_options(sslctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
  390. #endif
  391. #endif
  392. #if defined(ME_GOAHEAD_SSL_CACHE)
  393. /*
  394. Set the number of sessions supported. Default in OpenSSL is 20K.
  395. */
  396. SSL_CTX_sess_set_cache_size(sslctx, ME_GOAHEAD_SSL_CACHE);
  397. #else
  398. SSL_CTX_sess_set_cache_size(sslctx, 256);
  399. #endif
  400. return 0;
  401. }
  402. /*
  403. Close the SSL module
  404. */
  405. PUBLIC void sslClose()
  406. {
  407. if (sslctx != NULL) {
  408. SSL_CTX_free(sslctx);
  409. sslctx = NULL;
  410. if (dhKey) {
  411. DH_free(dhKey);
  412. dhKey = NULL;
  413. }
  414. }
  415. }
  416. /*
  417. Upgrade a socket to use SSL
  418. */
  419. PUBLIC int sslUpgrade(Webs *wp)
  420. {
  421. WebsSocket *sptr;
  422. BIO *bio;
  423. assert(wp);
  424. sptr = socketPtr(wp->sid);
  425. if ((wp->ssl = SSL_new(sslctx)) == 0) {
  426. return -1;
  427. }
  428. /*
  429. Create a socket bio. We don't use the BIO except as storage for the fd.
  430. */
  431. if ((bio = BIO_new_socket((int) sptr->sock, BIO_NOCLOSE)) == 0) {
  432. return -1;
  433. }
  434. SSL_set_bio(wp->ssl, bio, bio);
  435. SSL_set_accept_state(wp->ssl);
  436. SSL_set_app_data(wp->ssl, (void*) wp);
  437. if (ME_GOAHEAD_SSL_HANDSHAKES) {
  438. SSL_CTX_set_info_callback(sslctx, infoCallback);
  439. }
  440. return 0;
  441. }
  442. static void infoCallback(const SSL *ssl, int where, int rc)
  443. {
  444. Webs *wp;
  445. WebsSocket *sp;
  446. if (where & SSL_CB_HANDSHAKE_START) {
  447. if ((wp = (Webs*) SSL_get_app_data(ssl)) == 0) {
  448. return;
  449. }
  450. if ((sp = socketPtr(wp->sid)) != 0) {
  451. sp->handshakes++;
  452. }
  453. }
  454. }
  455. PUBLIC void sslFree(Webs *wp)
  456. {
  457. if (wp->ssl) {
  458. SSL_set_shutdown(wp->ssl, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
  459. SSL_free(wp->ssl);
  460. wp->ssl = 0;
  461. }
  462. }
  463. /*
  464. Return the number of bytes read. Return -1 on errors and EOF. Distinguish EOF via mprIsSocketEof.
  465. If non-blocking, may return zero if no data or still handshaking.
  466. */
  467. PUBLIC ssize sslRead(Webs *wp, void *buf, ssize len)
  468. {
  469. WebsSocket *sp;
  470. char ebuf[ME_GOAHEAD_LIMIT_STRING];
  471. ulong serror;
  472. int rc, err, retries, i;
  473. if (wp->ssl == 0 || len <= 0) {
  474. return -1;
  475. }
  476. /*
  477. Limit retries on WANT_READ. If non-blocking and no data, then this can spin forever.
  478. */
  479. sp = socketPtr(wp->sid);
  480. retries = 5;
  481. for (i = 0; i < retries; i++) {
  482. rc = SSL_read(wp->ssl, buf, (int) len);
  483. if (rc < 0) {
  484. err = SSL_get_error(wp->ssl, rc);
  485. if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_CONNECT || err == SSL_ERROR_WANT_ACCEPT) {
  486. continue;
  487. }
  488. serror = ERR_get_error();
  489. ERR_error_string_n(serror, ebuf, sizeof(ebuf) - 1);
  490. trace(5, "SSL_read %s", ebuf);
  491. }
  492. break;
  493. }
  494. if (maxHandshakes && sp->handshakes > maxHandshakes) {
  495. error("TLS renegotiation attack");
  496. rc = -1;
  497. sp->flags |= SOCKET_EOF;
  498. return -1;
  499. }
  500. if (rc <= 0) {
  501. err = SSL_get_error(wp->ssl, rc);
  502. if (err == SSL_ERROR_WANT_READ) {
  503. rc = 0;
  504. } else if (err == SSL_ERROR_WANT_WRITE) {
  505. rc = 0;
  506. } else if (err == SSL_ERROR_ZERO_RETURN) {
  507. sp->flags |= SOCKET_EOF;
  508. rc = -1;
  509. } else if (err == SSL_ERROR_SYSCALL) {
  510. sp->flags |= SOCKET_EOF;
  511. rc = -1;
  512. } else if (err != SSL_ERROR_ZERO_RETURN) {
  513. serror = ERR_get_error();
  514. ERR_error_string_n(serror, ebuf, sizeof(ebuf) - 1);
  515. trace(4, "OpenSSL: connection with protocol error: %s", ebuf);
  516. rc = -1;
  517. sp->flags |= SOCKET_EOF;
  518. }
  519. } else if (SSL_pending(wp->ssl) > 0) {
  520. socketHiddenData(sp, SSL_pending(wp->ssl), SOCKET_READABLE);
  521. }
  522. return rc;
  523. }
  524. PUBLIC ssize sslWrite(Webs *wp, void *buf, ssize len)
  525. {
  526. WebsSocket *sp;
  527. ssize totalWritten;
  528. int err, rc;
  529. if (wp->ssl == 0 || len <= 0) {
  530. return -1;
  531. }
  532. sp = socketPtr(wp->sid);
  533. totalWritten = 0;
  534. err = 0;
  535. ERR_clear_error();
  536. do {
  537. rc = SSL_write(wp->ssl, buf, (int) len);
  538. trace(7, "OpenSSL: written %d, requested len %d", rc, len);
  539. if (rc <= 0) {
  540. err = SSL_get_error(wp->ssl, rc);
  541. if (err == SSL_ERROR_NONE || err == SSL_ERROR_WANT_WRITE) {
  542. break;
  543. }
  544. trace(7, "OpenSSL: error %d", err);
  545. return -1;
  546. } else if (maxHandshakes && sp->handshakes > maxHandshakes) {
  547. error("TLS renegotiation attack");
  548. rc = -1;
  549. sp->flags |= SOCKET_EOF;
  550. return -1;
  551. }
  552. totalWritten += rc;
  553. buf = (void*) ((char*) buf + rc);
  554. len -= rc;
  555. trace(7, "OpenSSL: write: len %d, written %d, total %d", len, rc, totalWritten);
  556. } while (len > 0);
  557. if (totalWritten == 0 && err == SSL_ERROR_WANT_WRITE) {
  558. socketSetError(EAGAIN);
  559. return -1;
  560. }
  561. return totalWritten;
  562. }
  563. /*
  564. Set certificate file for SSL context
  565. */
  566. static int sslSetCertFile(char *certFile)
  567. {
  568. X509 *cert;
  569. BIO *bio;
  570. char *buf;
  571. int rc;
  572. assert(sslctx);
  573. assert(certFile);
  574. rc = -1;
  575. bio = 0;
  576. buf = 0;
  577. cert = 0;
  578. if (sslctx == NULL) {
  579. return rc;
  580. }
  581. if ((buf = websReadWholeFile(certFile)) == 0) {
  582. error("Unable to read certificate %s", certFile);
  583. } else if ((bio = BIO_new_mem_buf(buf, -1)) == 0) {
  584. error("Unable to allocate memory for certificate %s", certFile);
  585. } else if ((cert = PEM_read_bio_X509(bio, NULL, 0, NULL)) == 0) {
  586. error("Unable to parse certificate %s", certFile);
  587. } else if (SSL_CTX_use_certificate(sslctx, cert) != 1) {
  588. error("Unable to use certificate %s", certFile);
  589. } else if (!SSL_CTX_check_private_key(sslctx)) {
  590. error("Unable to check certificate key %s", certFile);
  591. } else {
  592. rc = 0;
  593. }
  594. wfree(buf);
  595. if (bio) {
  596. BIO_free(bio);
  597. }
  598. if (cert) {
  599. X509_free(cert);
  600. }
  601. return rc;
  602. }
  603. /*
  604. Set key file for SSL context
  605. */
  606. static int sslSetKeyFile(char *keyFile)
  607. {
  608. RSA *key;
  609. BIO *bio;
  610. char *buf;
  611. int rc;
  612. assert(sslctx);
  613. assert(keyFile);
  614. key = 0;
  615. bio = 0;
  616. buf = 0;
  617. rc = -1;
  618. if (sslctx == NULL) {
  619. ;
  620. } else if ((buf = websReadWholeFile(keyFile)) == 0) {
  621. error("Unable to read certificate %s", keyFile);
  622. } else if ((bio = BIO_new_mem_buf(buf, -1)) == 0) {
  623. error("Unable to allocate memory for key %s", keyFile);
  624. } else if ((key = PEM_read_bio_RSAPrivateKey(bio, NULL, 0, NULL)) == 0) {
  625. error("Unable to parse key %s", keyFile);
  626. } else if (SSL_CTX_use_RSAPrivateKey(sslctx, key) != 1) {
  627. error("Unable to use key %s", keyFile);
  628. } else {
  629. rc = 0;
  630. }
  631. wfree(buf);
  632. if (bio) {
  633. BIO_free(bio);
  634. }
  635. if (key) {
  636. RSA_free(key);
  637. }
  638. return rc;
  639. }
  640. static int verifyClientCertificate(int ok, X509_STORE_CTX *xContext)
  641. {
  642. X509 *cert;
  643. char subject[260], issuer[260], peer[260];
  644. int error, depth;
  645. subject[0] = issuer[0] = '\0';
  646. cert = X509_STORE_CTX_get_current_cert(xContext);
  647. error = X509_STORE_CTX_get_error(xContext);
  648. depth = X509_STORE_CTX_get_error_depth(xContext);
  649. ok = 1;
  650. if (X509_NAME_oneline(X509_get_subject_name(cert), subject, sizeof(subject) - 1) < 0) {
  651. ok = 0;
  652. }
  653. if (X509_NAME_oneline(X509_get_issuer_name(cert), issuer, sizeof(issuer) - 1) < 0) {
  654. ok = 0;
  655. }
  656. if (X509_NAME_get_text_by_NID(X509_get_subject_name(cert), NID_commonName, peer, sizeof(peer) - 1) < 0) {
  657. ok = 0;
  658. }
  659. if (ok && VERIFY_DEPTH < depth) {
  660. if (error == 0) {
  661. error = X509_V_ERR_CERT_CHAIN_TOO_LONG;
  662. }
  663. }
  664. switch (error) {
  665. case X509_V_OK:
  666. break;
  667. case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
  668. case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
  669. if (ME_GOAHEAD_SSL_VERIFY_ISSUER) {
  670. logmsg(3, "Self-signed certificate");
  671. ok = 0;
  672. }
  673. case X509_V_ERR_CERT_UNTRUSTED:
  674. case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
  675. if (ME_GOAHEAD_SSL_VERIFY_ISSUER) {
  676. logmsg(3, "Certificate not trusted");
  677. ok = 0;
  678. }
  679. break;
  680. case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
  681. case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
  682. if (ME_GOAHEAD_SSL_VERIFY_ISSUER) {
  683. logmsg(3, "Certificate not trusted");
  684. ok = 0;
  685. }
  686. break;
  687. case X509_V_ERR_CERT_CHAIN_TOO_LONG:
  688. case X509_V_ERR_CERT_HAS_EXPIRED:
  689. case X509_V_ERR_CERT_NOT_YET_VALID:
  690. case X509_V_ERR_CERT_REJECTED:
  691. case X509_V_ERR_CERT_SIGNATURE_FAILURE:
  692. case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
  693. case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
  694. case X509_V_ERR_INVALID_CA:
  695. default:
  696. logmsg(3, "Certificate verification error %d", error);
  697. ok = 0;
  698. break;
  699. }
  700. if (ok) {
  701. trace(3, "OpenSSL: Certificate verified: subject %s", subject);
  702. } else {
  703. trace(1, "OpenSSL: Certification failed: subject %s (more trace at level 4)", subject);
  704. trace(4, "OpenSSL: Error: %d: %s", error, X509_verify_cert_error_string(error));
  705. }
  706. trace(4, "OpenSSL: Issuer: %s", issuer);
  707. trace(4, "OpenSSL: Peer: %s", peer);
  708. return ok;
  709. }
  710. /*
  711. Map iana names to OpenSSL names so users can provide IANA names as well as OpenSSL cipher names
  712. */
  713. static char *mapCipherNames(char *ciphers)
  714. {
  715. WebsBuf buf;
  716. CipherMap *cp;
  717. char *cipher, *next, *str;
  718. if (!ciphers || *ciphers == 0) {
  719. return 0;
  720. }
  721. bufCreate(&buf, 0, 0);
  722. ciphers = sclone(ciphers);
  723. for (next = ciphers; (cipher = stok(next, ":, \t", &next)) != 0; ) {
  724. for (cp = cipherMap; cp->name; cp++) {
  725. if (smatch(cp->name, cipher)) {
  726. bufPut(&buf, "%s:", cp->ossName);
  727. break;
  728. }
  729. }
  730. if (cp->name == 0) {
  731. bufPut(&buf, "%s:", cipher);
  732. }
  733. }
  734. wfree(ciphers);
  735. str = sclone(bufStart(&buf));
  736. bufFree(&buf);
  737. return str;
  738. }
  739. /*
  740. Get the DH parameters
  741. */
  742. static DH *getDhKey()
  743. {
  744. static unsigned char dh2048_p[] = {
  745. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
  746. 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
  747. 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
  748. 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
  749. 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
  750. 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
  751. 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
  752. 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
  753. 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
  754. 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
  755. 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
  756. 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
  757. 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
  758. 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
  759. 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
  760. 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  761. };
  762. static unsigned char dh2048_g[] = {
  763. 0x02,
  764. };
  765. DH *dh;
  766. if ((dh = DH_new()) == 0) {
  767. return 0;
  768. }
  769. #if OPENSSL_VERSION_NUMBER >= 0x10100000L
  770. {
  771. BIGNUM *p, *g;
  772. p = BN_bin2bn(dh2048_p, sizeof(dh2048_p), NULL);
  773. g = BN_bin2bn(dh2048_g, sizeof(dh2048_g), NULL);
  774. if (!DH_set0_pqg(dh, p, NULL, g)) {
  775. BN_free(p);
  776. BN_free(g);
  777. DH_free(dh);
  778. return 0;
  779. }
  780. }
  781. #else
  782. dh->p = BN_bin2bn(dh2048_p, sizeof(dh2048_p), NULL);
  783. dh->g = BN_bin2bn(dh2048_g, sizeof(dh2048_g), NULL);
  784. if ((dh->p == 0) || (dh->g == 0)) {
  785. DH_free(dh);
  786. return 0;
  787. }
  788. #endif
  789. return dh;
  790. }
  791. /*
  792. Set the ephemeral DH key
  793. */
  794. static DH *dhcallback(SSL *handle, int isExport, int keyLength)
  795. {
  796. return dhKey;
  797. }
  798. void opensslDummy() {}
  799. #endif
  800. /*
  801. Copyright (c) Embedthis Software. All Rights Reserved.
  802. This software is distributed under commercial and open source licenses.
  803. You may use the Embedthis GoAhead open source license or you may acquire
  804. a commercial license from Embedthis Software. You agree to be fully bound
  805. by the terms of either license. Consult the LICENSE.md distributed with
  806. this software for full details and other copyrights.
  807. */