securesocket.cpp 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems®.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. // Some ssl prototypes use char* where they should be using const char *, resulting in lots of spurious warnings
  14. #ifndef _MSC_VER
  15. #pragma GCC diagnostic ignored "-Wwrite-strings"
  16. #endif
  17. //jlib
  18. #include "jliball.hpp"
  19. #include "string.h"
  20. #ifdef _WIN32
  21. #include <windows.h>
  22. #include <winsock2.h>
  23. #include <ws2tcpip.h>
  24. #include <signal.h>
  25. #else
  26. #include <sys/types.h>
  27. #include <sys/socket.h>
  28. #include <netinet/tcp.h>
  29. #include <netinet/in.h>
  30. #include <arpa/inet.h>
  31. #include <stddef.h>
  32. #include <errno.h>
  33. #endif
  34. //openssl
  35. #include <openssl/rsa.h>
  36. #include <openssl/crypto.h>
  37. #ifndef _WIN32
  38. //x509.h includes evp.h, which in turn includes des.h which defines
  39. //crypt() that throws different exception than in unistd.h
  40. //(this causes build break on linux) so exclude it
  41. #define crypt DONT_DEFINE_CRYPT
  42. #include <openssl/x509.h>
  43. #undef crypt
  44. #else
  45. #include <openssl/x509.h>
  46. #endif
  47. #include <openssl/ssl.h>
  48. #include <openssl/pem.h>
  49. #include <openssl/err.h>
  50. #include <openssl/conf.h>
  51. #include <openssl/x509v3.h>
  52. #include "securesocket.hpp"
  53. Owned<ISecureSocketContext> server_securesocket_context;
  54. bool accept_selfsigned = false;
  55. #define CHK_NULL(x) if((x)==NULL) exit(1)
  56. #define CHK_ERR(err, s) if((err)==-1){perror(s);exit(1);}
  57. #define CHK_SSL(err) if((err) ==-1){ERR_print_errors_fp(stderr); exit(2);}
  58. #define THROWSECURESOCKETEXCEPTION(err) \
  59. throw MakeStringException(-1, "SecureSocket Exception Raised in: %s, line %d - %s", __FILE__, __LINE__, err);
  60. static int pem_passwd_cb(char* buf, int size, int rwflag, void* password)
  61. {
  62. strncpy(buf, (char*)password, size);
  63. buf[size - 1] = '\0';
  64. return(strlen(buf));
  65. }
  66. static void readBio(BIO* bio, StringBuffer& buf)
  67. {
  68. char readbuf[1024];
  69. int len = 0;
  70. while((len = BIO_read(bio, readbuf, 1024)) > 0)
  71. {
  72. buf.append(len, readbuf);
  73. }
  74. }
  75. //Use a namespace to prevent clashes with a class of the same name in jhtree
  76. namespace securesocket
  77. {
  78. class CStringSet : public CInterface, implements IInterface
  79. {
  80. class StringHolder : public CInterface
  81. {
  82. public:
  83. StringBuffer m_str;
  84. StringHolder(const char* str)
  85. {
  86. m_str.clear().append(str);
  87. }
  88. const char *queryFindString() const { return m_str.str(); }
  89. };
  90. private:
  91. OwningStringSuperHashTableOf<StringHolder> strhash;
  92. public:
  93. IMPLEMENT_IINTERFACE;
  94. void add(const char* val)
  95. {
  96. StringHolder* h1 = strhash.find(val);
  97. if(h1 == NULL)
  98. strhash.add(*(new StringHolder(val)));
  99. }
  100. bool contains(const char* val)
  101. {
  102. StringHolder* h1 = strhash.find(val);
  103. return (h1 != NULL);
  104. }
  105. };
  106. class CSecureSocket : public CInterface, implements ISecureSocket
  107. {
  108. private:
  109. SSL* m_ssl;
  110. Owned<ISocket> m_socket;
  111. bool m_verify;
  112. bool m_address_match;
  113. CStringSet* m_peers;
  114. int m_loglevel;
  115. private:
  116. StringBuffer& get_cn(X509* cert, StringBuffer& cn);
  117. bool verify_cert(X509* cert);
  118. public:
  119. IMPLEMENT_IINTERFACE;
  120. CSecureSocket(ISocket* sock, SSL_CTX* ctx, bool verify = false, bool addres_match = false, CStringSet* m_peers = NULL, int loglevel=SSLogNormal);
  121. CSecureSocket(int sockfd, SSL_CTX* ctx, bool verify = false, bool addres_match = false, CStringSet* m_peers = NULL, int loglevel=SSLogNormal);
  122. ~CSecureSocket();
  123. virtual int secure_accept();
  124. virtual int secure_connect();
  125. virtual int wait_read(unsigned timeoutms);
  126. virtual void read(void* buf, size32_t min_size, size32_t max_size, size32_t &size_read,unsigned timeoutsecs);
  127. virtual void readtms(void* buf, size32_t min_size, size32_t max_size, size32_t &size_read, unsigned timeoutms);
  128. virtual size32_t write(void const* buf, size32_t size);
  129. virtual size32_t writetms(void const* buf, size32_t size, unsigned timeoutms=WAIT_FOREVER);
  130. void readTimeout(void* buf, size32_t min_size, size32_t max_size, size32_t &size_read, unsigned timeout, bool useSeconds);
  131. //The following are the functions from ISocket that haven't been implemented.
  132. virtual void read(void* buf, size32_t size)
  133. {
  134. size32_t size_read;
  135. readTimeout(buf, size, size, size_read, 0, false);
  136. }
  137. virtual size32_t get_max_send_size()
  138. {
  139. throw MakeStringException(-1, "not implemented");
  140. }
  141. //
  142. // This method is called by server to accept client connection
  143. //
  144. virtual ISocket* accept(bool allowcancel=false) // not needed for UDP
  145. {
  146. throw MakeStringException(-1, "not implemented");
  147. }
  148. //
  149. // This method is called to check whether a socket is ready to write (i.e. some free buffer space)
  150. //
  151. virtual int wait_write(unsigned timeout)
  152. {
  153. throw MakeStringException(-1, "not implemented");
  154. }
  155. //
  156. // can be used with write to allow it to return if it would block
  157. // be sure and restore to old state before calling other functions on this socket
  158. //
  159. virtual bool set_nonblock(bool on) // returns old state
  160. {
  161. throw MakeStringException(-1, "not implemented");
  162. }
  163. // enable 'nagling' - small packet coalescing (implies delayed transmission)
  164. //
  165. virtual bool set_nagle(bool on) // returns old state
  166. {
  167. throw MakeStringException(-1, "not implemented");
  168. }
  169. // set 'linger' time - time close will linger so that outstanding unsent data will be transmited
  170. //
  171. virtual void set_linger(int lingersecs)
  172. {
  173. throw MakeStringException(-1, "not implemented");
  174. }
  175. //
  176. // Cancel accept operation and close socket
  177. //
  178. virtual void cancel_accept() // not needed for UDP
  179. {
  180. throw MakeStringException(-1, "not implemented");
  181. }
  182. //
  183. // Shutdown socket: prohibit write and read operations on socket
  184. //
  185. virtual void shutdown(unsigned mode) // not needed for UDP
  186. {
  187. m_socket->shutdown(mode);
  188. }
  189. // Get name of accepted socket and returns port
  190. virtual int name(char *name,size32_t namemax)
  191. {
  192. return m_socket->name(name, namemax);
  193. }
  194. // Get peer name of socket and returns port - in UDP returns return addr
  195. virtual int peer_name(char *name,size32_t namemax)
  196. {
  197. return m_socket->peer_name(name, namemax);
  198. }
  199. // Get peer endpoint of socket - in UDP returns return addr
  200. virtual SocketEndpoint &getPeerEndpoint(SocketEndpoint &ep)
  201. {
  202. return m_socket->getPeerEndpoint(ep);
  203. }
  204. // Get peer ip of socket - in UDP returns return addr
  205. virtual IpAddress &getPeerAddress(IpAddress &addr)
  206. {
  207. return m_socket->getPeerAddress(addr);
  208. }
  209. //
  210. // Close socket
  211. //
  212. virtual bool connectionless() // true if accept need not be called (i.e. UDP)
  213. {
  214. throw MakeStringException(-1, "not implemented");
  215. }
  216. virtual void set_return_addr(int port,const char *name) // used for UDP servers only
  217. {
  218. throw MakeStringException(-1, "not implemented");
  219. }
  220. // Block functions
  221. virtual void set_block_mode ( // must be called before block operations
  222. unsigned flags, // BF_* flags (must match receive_block)
  223. size32_t recsize=0, // record size (required for rec compression)
  224. unsigned timeout=0 // timeout in msecs (0 for no timeout)
  225. )
  226. {
  227. throw MakeStringException(-1, "not implemented");
  228. }
  229. virtual bool send_block(
  230. const void *blk, // data to send
  231. size32_t sz // size to send (0 for eof)
  232. )
  233. {
  234. throw MakeStringException(-1, "not implemented");
  235. }
  236. virtual size32_t receive_block_size () // get size of next block (always must call receive_block after)
  237. {
  238. throw MakeStringException(-1, "not implemented");
  239. }
  240. virtual size32_t receive_block(
  241. void *blk, // receive pointer
  242. size32_t sz // max size to read (0 for sync eof)
  243. // if less than block size truncates block
  244. )
  245. {
  246. throw MakeStringException(-1, "not implemented");
  247. }
  248. virtual void close()
  249. {
  250. m_socket->close();
  251. }
  252. virtual unsigned OShandle() // for internal use
  253. {
  254. return m_socket->OShandle();
  255. }
  256. virtual size32_t avail_read() // called after wait_read to see how much data available
  257. {
  258. int pending = SSL_pending(m_ssl);
  259. if(pending > 0)
  260. return pending;
  261. return m_socket->avail_read();
  262. }
  263. virtual size32_t write_multiple(unsigned num,const void **buf, size32_t *size)
  264. {
  265. throw MakeStringException(-1, "not implemented");
  266. }
  267. virtual size32_t get_send_buffer_size() // get OS send buffer
  268. {
  269. throw MakeStringException(-1, "not implemented");
  270. }
  271. void set_send_buffer_size(size32_t sz) // set OS send buffer size
  272. {
  273. throw MakeStringException(-1, "not implemented");
  274. }
  275. bool join_multicast_group(SocketEndpoint &ep) // for udp multicast
  276. {
  277. throw MakeStringException(-1, "not implemented");
  278. return false;
  279. }
  280. bool leave_multicast_group(SocketEndpoint &ep) // for udp multicast
  281. {
  282. throw MakeStringException(-1, "not implemented");
  283. return false;
  284. }
  285. void set_ttl(unsigned _ttl) // set ttl
  286. {
  287. throw MakeStringException(-1, "not implemented");
  288. }
  289. size32_t get_receive_buffer_size() // get OS send buffer
  290. {
  291. throw MakeStringException(-1, "not implemented");
  292. }
  293. void set_receive_buffer_size(size32_t sz) // set OS send buffer size
  294. {
  295. throw MakeStringException(-1, "not implemented");
  296. }
  297. virtual void set_keep_alive(bool set) // set option SO_KEEPALIVE
  298. {
  299. throw MakeStringException(-1, "not implemented");
  300. }
  301. virtual size32_t udp_write_to(const SocketEndpoint &ep, void const* buf, size32_t size)
  302. {
  303. throw MakeStringException(-1, "not implemented");
  304. }
  305. virtual bool check_connection()
  306. {
  307. throw MakeStringException(-1, "not implemented");
  308. }
  309. };
  310. /**************************************************************************
  311. * CSecureSocket -- secure socket layer implementation using openssl *
  312. **************************************************************************/
  313. CSecureSocket::CSecureSocket(ISocket* sock, SSL_CTX* ctx, bool verify, bool address_match, CStringSet* peers, int loglevel)
  314. {
  315. m_socket.setown(sock);
  316. m_ssl = SSL_new(ctx);
  317. m_verify = verify;
  318. m_address_match = address_match;
  319. m_peers = peers;;
  320. m_loglevel = loglevel;
  321. if(m_ssl == NULL)
  322. {
  323. throw MakeStringException(-1, "Can't create ssl");
  324. }
  325. SSL_set_fd(m_ssl, sock->OShandle());
  326. }
  327. CSecureSocket::CSecureSocket(int sockfd, SSL_CTX* ctx, bool verify, bool address_match, CStringSet* peers, int loglevel)
  328. {
  329. //m_socket.setown(sock);
  330. //m_socket.setown(ISocket::attach(sockfd));
  331. m_ssl = SSL_new(ctx);
  332. m_verify = verify;
  333. m_address_match = address_match;
  334. m_peers = peers;;
  335. m_loglevel = loglevel;
  336. if(m_ssl == NULL)
  337. {
  338. throw MakeStringException(-1, "Can't create ssl");
  339. }
  340. SSL_set_fd(m_ssl, sockfd);
  341. }
  342. CSecureSocket::~CSecureSocket()
  343. {
  344. SSL_free(m_ssl);
  345. }
  346. StringBuffer& CSecureSocket::get_cn(X509* cert, StringBuffer& cn)
  347. {
  348. X509_NAME *subj;
  349. char data[256];
  350. int extcount;
  351. int found = 0;
  352. if ((extcount = X509_get_ext_count(cert)) > 0)
  353. {
  354. int i;
  355. for (i = 0; i < extcount; i++)
  356. {
  357. const char *extstr;
  358. X509_EXTENSION *ext;
  359. ext = X509_get_ext(cert, i);
  360. extstr = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext)));
  361. if (!strcmp(extstr, "subjectAltName"))
  362. {
  363. int j;
  364. unsigned char *data;
  365. STACK_OF(CONF_VALUE) *val;
  366. CONF_VALUE *nval;
  367. #if (OPENSSL_VERSION_NUMBER > 0x00909000L)
  368. const X509V3_EXT_METHOD *meth;
  369. #else
  370. X509V3_EXT_METHOD *meth;
  371. #endif
  372. void *ext_str = NULL;
  373. if (!(meth = X509V3_EXT_get(ext)))
  374. break;
  375. data = ext->value->data;
  376. #if (OPENSSL_VERSION_NUMBER > 0x00908000L)
  377. if (meth->it)
  378. ext_str = ASN1_item_d2i(NULL, (const unsigned char **)&data, ext->value->length,
  379. ASN1_ITEM_ptr(meth->it));
  380. else
  381. ext_str = meth->d2i(NULL, (const unsigned char **) &data, ext->value->length);
  382. #elif (OPENSSL_VERSION_NUMBER > 0x00907000L)
  383. if (meth->it)
  384. ext_str = ASN1_item_d2i(NULL, (unsigned char **)&data, ext->value->length,
  385. ASN1_ITEM_ptr(meth->it));
  386. else
  387. ext_str = meth->d2i(NULL, (unsigned char **) &data, ext->value->length);
  388. #else
  389. ext_str = meth->d2i(NULL, &data, ext->value->length);
  390. #endif
  391. val = meth->i2v(meth, ext_str, NULL);
  392. for (j = 0; j < sk_CONF_VALUE_num(val); j++)
  393. {
  394. nval = sk_CONF_VALUE_value(val, j);
  395. if (!strcmp(nval->name, "DNS"))
  396. {
  397. cn.append(nval->value);
  398. found = 1;
  399. break;
  400. }
  401. }
  402. }
  403. if (found)
  404. break;
  405. }
  406. }
  407. if (!found && (subj = X509_get_subject_name(cert)) &&
  408. X509_NAME_get_text_by_NID(subj, NID_commonName, data, 256) > 0)
  409. {
  410. data[255] = 0;
  411. cn.append(data);
  412. }
  413. return cn;
  414. }
  415. bool CSecureSocket::verify_cert(X509* cert)
  416. {
  417. DBGLOG ("peer's certificate:\n");
  418. char *s, oneline[1024];
  419. s = X509_NAME_oneline (X509_get_subject_name (cert), oneline, 1024);
  420. if(s != NULL)
  421. {
  422. DBGLOG ("\t subject: %s", oneline);
  423. }
  424. s = X509_NAME_oneline (X509_get_issuer_name (cert), oneline, 1024);
  425. if(s != NULL)
  426. {
  427. DBGLOG ("\t issuer: %s", oneline);
  428. }
  429. StringBuffer cn;
  430. get_cn(cert, cn);
  431. if(cn.length() == 0)
  432. throw MakeStringException(-1, "cn of the certificate can't be found");
  433. if(m_address_match)
  434. {
  435. SocketEndpoint ep;
  436. m_socket->getPeerEndpoint(ep);
  437. StringBuffer iptxt;
  438. ep.getIpText(iptxt);
  439. SocketEndpoint cnep(cn.str());
  440. StringBuffer cniptxt;
  441. cnep.getIpText(cniptxt);
  442. DBGLOG("peer ip=%s, certificate ip=%s", iptxt.str(), cniptxt.str());
  443. if(!(cniptxt.length() > 0 && stricmp(iptxt.str(), cniptxt.str()) == 0))
  444. {
  445. DBGLOG("Source address of the request doesn't match the certificate");
  446. return false;
  447. }
  448. }
  449. if (m_peers->contains("anyone") || m_peers->contains(cn.str()))
  450. {
  451. DBGLOG("%s among trusted peers", cn.str());
  452. return true;
  453. }
  454. else
  455. {
  456. DBGLOG("%s not among trusted peers, verification failed", cn.str());
  457. return false;
  458. }
  459. }
  460. int CSecureSocket::secure_accept()
  461. {
  462. int err;
  463. err = SSL_accept(m_ssl);
  464. if(err == 0)
  465. {
  466. char errbuf[512];
  467. ERR_error_string_n(ERR_get_error(), errbuf, 512);
  468. DBGLOG("SSL_accept returned 0, error - %s", errbuf);
  469. return -1;
  470. }
  471. else if(err < 0)
  472. {
  473. int ret = SSL_get_error(m_ssl, err);
  474. char errbuf[512];
  475. ERR_error_string_n(ERR_get_error(), errbuf, 512);
  476. errbuf[511] = '\0';
  477. DBGLOG("SSL_accept returned %d, SSL_get_error=%d, error - %s", err, ret, errbuf);
  478. if(strstr(errbuf, "error:1408F455:") != NULL)
  479. {
  480. DBGLOG("Unrecoverable SSL library error.");
  481. _exit(0);
  482. }
  483. return err;
  484. }
  485. DBGLOG("SSL connection using %s", SSL_get_cipher(m_ssl));
  486. if(m_verify)
  487. {
  488. bool verified = false;
  489. // Get client's certificate (note: beware of dynamic allocation) - opt
  490. X509* client_cert = SSL_get_peer_certificate (m_ssl);
  491. if (client_cert != NULL)
  492. {
  493. // We could do all sorts of certificate verification stuff here before
  494. // deallocating the certificate.
  495. verified = verify_cert(client_cert);
  496. X509_free (client_cert);
  497. }
  498. if(!verified)
  499. throw MakeStringException(-1, "certificate verification failed");
  500. }
  501. return 0;
  502. }
  503. int CSecureSocket::secure_connect()
  504. {
  505. int err = SSL_connect (m_ssl);
  506. if(err <= 0)
  507. {
  508. int ret = SSL_get_error(m_ssl, err);
  509. char errbuf[512];
  510. ERR_error_string_n(ERR_get_error(), errbuf, 512);
  511. DBGLOG("SSL_connect error - %s, SSL_get_error=%d, error - %d", errbuf,ret, err);
  512. throw MakeStringException(-1, "SSL_connect failed: %s", errbuf);
  513. }
  514. // Currently only do fake verify - simply logging the subject and issuer
  515. // The verify parameter makes it possible for the application to verify only
  516. // once per session and cache the result of the verification.
  517. if(m_verify)
  518. {
  519. // Following two steps are optional and not required for
  520. // data exchange to be successful.
  521. // Get the cipher - opt
  522. DBGLOG("SSL connection using %s\n", SSL_get_cipher (m_ssl));
  523. // Get server's certificate (note: beware of dynamic allocation) - opt
  524. X509* server_cert = SSL_get_peer_certificate (m_ssl);
  525. bool verified = false;
  526. if(server_cert != NULL)
  527. {
  528. // We could do all sorts of certificate verification stuff here before
  529. // deallocating the certificate.
  530. verified = verify_cert(server_cert);
  531. X509_free (server_cert);
  532. }
  533. if(!verified)
  534. throw MakeStringException(-1, "certificate verification failed");
  535. }
  536. return 0;
  537. }
  538. //
  539. // This method is called to check whether a socket has data ready
  540. //
  541. int CSecureSocket::wait_read(unsigned timeoutms)
  542. {
  543. int pending = SSL_pending(m_ssl);
  544. if(pending > 0)
  545. return pending;
  546. return m_socket->wait_read(timeoutms);
  547. }
  548. inline unsigned socketTime(bool useSeconds)
  549. {
  550. if (useSeconds)
  551. {
  552. time_t timenow;
  553. return (unsigned) time(&timenow);
  554. }
  555. return msTick();
  556. }
  557. inline unsigned socketTimeRemaining(bool useSeconds, unsigned start, unsigned timeout)
  558. {
  559. unsigned elapsed = socketTime(useSeconds) - start;
  560. if (elapsed < timeout)
  561. {
  562. unsigned timeleft = timeout - elapsed;
  563. if (useSeconds)
  564. timeleft *= 1000;
  565. return timeleft;
  566. }
  567. return 0;
  568. }
  569. void CSecureSocket::readTimeout(void* buf, size32_t min_size, size32_t max_size, size32_t &size_read, unsigned timeout, bool useSeconds)
  570. {
  571. size_read = 0;
  572. unsigned start;
  573. unsigned timeleft;
  574. if (timeout != WAIT_FOREVER) {
  575. start = socketTime(useSeconds);
  576. timeleft = timeout;
  577. if (useSeconds)
  578. timeleft *= 1000;
  579. }
  580. do {
  581. int rc;
  582. if (timeout != WAIT_FOREVER) {
  583. rc = wait_read(timeleft);
  584. if (rc < 0) {
  585. THROWSECURESOCKETEXCEPTION("wait_read error");
  586. }
  587. if (rc == 0) {
  588. THROWSECURESOCKETEXCEPTION("timeout expired");
  589. }
  590. timeleft = socketTimeRemaining(useSeconds, start, timeout);
  591. }
  592. rc = SSL_read(m_ssl, (char*)buf + size_read, max_size - size_read);
  593. if(rc > 0)
  594. {
  595. size_read += rc;
  596. }
  597. else
  598. {
  599. int err = SSL_get_error(m_ssl, rc);
  600. // Ignoring SSL_ERROR_SYSCALL because IE prompting user acceptance of the certificate
  601. // causes this error, but is harmless.
  602. if((err != SSL_ERROR_NONE) && (err != SSL_ERROR_SYSCALL))
  603. {
  604. if(m_loglevel >= SSLogMax)
  605. {
  606. char errbuf[512];
  607. ERR_error_string_n(ERR_get_error(), errbuf, 512);
  608. DBGLOG("Warning: SSL_read error %d - %s", err, errbuf);
  609. }
  610. }
  611. break;
  612. }
  613. } while (size_read < min_size);
  614. }
  615. void CSecureSocket::readtms(void* buf, size32_t min_size, size32_t max_size, size32_t &size_read, unsigned timeoutms)
  616. {
  617. readTimeout(buf, min_size, max_size, size_read, timeoutms, false);
  618. }
  619. void CSecureSocket::read(void* buf, size32_t min_size, size32_t max_size, size32_t &size_read,unsigned timeoutsecs)
  620. {
  621. readTimeout(buf, min_size, max_size, size_read, timeoutsecs, true);
  622. }
  623. size32_t CSecureSocket::write(void const* buf, size32_t size)
  624. {
  625. int numwritten = SSL_write(m_ssl, buf, size);
  626. return numwritten;
  627. }
  628. size32_t CSecureSocket::writetms(void const* buf, size32_t size, unsigned timeoutms)
  629. {
  630. // timeoutms not implemented yet ...
  631. int numwritten = SSL_write(m_ssl, buf, size);
  632. return numwritten;
  633. }
  634. int verify_callback(int ok, X509_STORE_CTX *store)
  635. {
  636. if(!ok)
  637. {
  638. X509 *cert = X509_STORE_CTX_get_current_cert(store);
  639. int err = X509_STORE_CTX_get_error(store);
  640. char issuer[256], subject[256];
  641. X509_NAME_oneline(X509_get_issuer_name(cert), issuer, 256);
  642. X509_NAME_oneline(X509_get_subject_name(cert), subject, 256);
  643. if(accept_selfsigned && (stricmp(issuer, subject) == 0))
  644. {
  645. DBGLOG("accepting selfsigned certificate, subject=%s", subject);
  646. ok = true;
  647. }
  648. else
  649. DBGLOG("Error with certificate: issuer=%s,subject=%s,err %d - %s", issuer, subject,err,X509_verify_cert_error_string(err));
  650. }
  651. return ok;
  652. }
  653. const char* strtok__(const char* s, const char* d, StringBuffer& tok)
  654. {
  655. if(!s || !*s || !d || !*d)
  656. return s;
  657. while(*s && strchr(d, *s))
  658. s++;
  659. while(*s && !strchr(d, *s))
  660. {
  661. tok.append(*s);
  662. s++;
  663. }
  664. return s;
  665. }
  666. static Mutex** mutexArray = NULL;
  667. static int numMutexes = 0;
  668. static CriticalSection mutexCrit;
  669. static void locking_function(int mode, int n, const char * file, int line)
  670. {
  671. assertex(mutexArray != NULL && n < numMutexes);
  672. if (mode & CRYPTO_LOCK)
  673. mutexArray[n]->lock();
  674. else
  675. mutexArray[n]->unlock();
  676. }
  677. #ifndef _WIN32
  678. unsigned long pthreads_thread_id(void)
  679. {
  680. return((unsigned long)pthread_self());
  681. }
  682. #endif
  683. static void initSSLLibrary()
  684. {
  685. CriticalBlock b(mutexCrit);
  686. if(mutexArray == NULL)
  687. {
  688. SSL_load_error_strings();
  689. SSLeay_add_ssl_algorithms();
  690. numMutexes= CRYPTO_num_locks();
  691. mutexArray = new Mutex*[numMutexes];
  692. for(int i = 0; i < numMutexes; i++)
  693. {
  694. mutexArray[i] = new Mutex;
  695. }
  696. CRYPTO_set_locking_callback(locking_function);
  697. #ifndef _WIN32
  698. CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id);
  699. #endif
  700. }
  701. }
  702. class CSecureSocketContext : public CInterface, implements ISecureSocketContext
  703. {
  704. private:
  705. SSL_CTX* m_ctx;
  706. #if (OPENSSL_VERSION_NUMBER > 0x00909000L)
  707. const SSL_METHOD* m_meth;
  708. #else
  709. SSL_METHOD* m_meth;
  710. #endif
  711. bool m_verify;
  712. bool m_address_match;
  713. Owned<CStringSet> m_peers;
  714. StringAttr password;
  715. public:
  716. IMPLEMENT_IINTERFACE;
  717. CSecureSocketContext(SecureSocketType sockettype)
  718. {
  719. m_verify = false;
  720. m_address_match = false;
  721. initSSLLibrary();
  722. if(sockettype == ClientSocket)
  723. m_meth = SSLv23_client_method();
  724. else
  725. m_meth = SSLv23_server_method();
  726. m_ctx = SSL_CTX_new(m_meth);
  727. if(!m_ctx)
  728. {
  729. throw MakeStringException(-1, "ctx can't be created");
  730. }
  731. SSL_CTX_set_mode(m_ctx, SSL_CTX_get_mode(m_ctx) | SSL_MODE_AUTO_RETRY);
  732. }
  733. CSecureSocketContext(const char* certfile, const char* privkeyfile, const char* passphrase, SecureSocketType sockettype)
  734. {
  735. m_verify = false;
  736. m_address_match = false;
  737. initSSLLibrary();
  738. if(sockettype == ClientSocket)
  739. m_meth = SSLv23_client_method();
  740. else
  741. m_meth = SSLv23_server_method();
  742. m_ctx = SSL_CTX_new(m_meth);
  743. if(!m_ctx)
  744. {
  745. throw MakeStringException(-1, "ctx can't be created");
  746. }
  747. password.set(passphrase);
  748. SSL_CTX_set_default_passwd_cb_userdata(m_ctx, (void*)password.str());
  749. SSL_CTX_set_default_passwd_cb(m_ctx, pem_passwd_cb);
  750. if(SSL_CTX_use_certificate_file(m_ctx, certfile, SSL_FILETYPE_PEM) <= 0)
  751. {
  752. char errbuf[512];
  753. ERR_error_string_n(ERR_get_error(), errbuf, 512);
  754. throw MakeStringException(-1, "error loading certificate file %s - %s", certfile, errbuf);
  755. }
  756. if(SSL_CTX_use_PrivateKey_file(m_ctx, privkeyfile, SSL_FILETYPE_PEM) <= 0)
  757. {
  758. char errbuf[512];
  759. ERR_error_string_n(ERR_get_error(), errbuf, 512);
  760. throw MakeStringException(-1, "error loading private key file %s - %s", privkeyfile, errbuf);
  761. }
  762. if(!SSL_CTX_check_private_key(m_ctx))
  763. {
  764. throw MakeStringException(-1, "Private key does not match the certificate public key");
  765. }
  766. SSL_CTX_set_mode(m_ctx, SSL_CTX_get_mode(m_ctx) | SSL_MODE_AUTO_RETRY);
  767. }
  768. CSecureSocketContext(IPropertyTree* config, SecureSocketType sockettype)
  769. {
  770. assertex(config);
  771. m_verify = false;
  772. m_address_match = false;
  773. initSSLLibrary();
  774. if(sockettype == ClientSocket)
  775. m_meth = SSLv23_client_method();
  776. else
  777. m_meth = SSLv23_server_method();
  778. m_ctx = SSL_CTX_new(m_meth);
  779. if(!m_ctx)
  780. {
  781. throw MakeStringException(-1, "ctx can't be created");
  782. }
  783. const char* passphrase = config->queryProp("passphrase");
  784. if(passphrase && *passphrase)
  785. {
  786. StringBuffer pwd;
  787. decrypt(pwd, passphrase);
  788. password.set(pwd);
  789. SSL_CTX_set_default_passwd_cb_userdata(m_ctx, (void*)password.str());
  790. SSL_CTX_set_default_passwd_cb(m_ctx, pem_passwd_cb);
  791. }
  792. const char* certfile = config->queryProp("certificate");
  793. if(certfile && *certfile)
  794. {
  795. if(SSL_CTX_use_certificate_file(m_ctx, certfile, SSL_FILETYPE_PEM) <= 0)
  796. {
  797. char errbuf[512];
  798. ERR_error_string_n(ERR_get_error(), errbuf, 512);
  799. throw MakeStringException(-1, "error loading certificate file %s - %s", certfile, errbuf);
  800. }
  801. }
  802. const char* privkeyfile = config->queryProp("privatekey");
  803. if(privkeyfile && *privkeyfile)
  804. {
  805. if(SSL_CTX_use_PrivateKey_file(m_ctx, privkeyfile, SSL_FILETYPE_PEM) <= 0)
  806. {
  807. char errbuf[512];
  808. ERR_error_string_n(ERR_get_error(), errbuf, 512);
  809. throw MakeStringException(-1, "error loading private key file %s - %s", privkeyfile, errbuf);
  810. }
  811. if(!SSL_CTX_check_private_key(m_ctx))
  812. {
  813. throw MakeStringException(-1, "Private key does not match the certificate public key");
  814. }
  815. }
  816. SSL_CTX_set_mode(m_ctx, SSL_CTX_get_mode(m_ctx) | SSL_MODE_AUTO_RETRY);
  817. m_verify = config->getPropBool("verify/@enable");
  818. m_address_match = config->getPropBool("verify/@address_match");
  819. accept_selfsigned = config->getPropBool("verify/@accept_selfsigned");
  820. if(m_verify)
  821. {
  822. const char* capath = config->queryProp("verify/ca_certificates/@path");
  823. if(capath && *capath)
  824. {
  825. if(SSL_CTX_load_verify_locations(m_ctx, capath, NULL) != 1)
  826. {
  827. throw MakeStringException(-1, "Error loading CA certificates from %s", capath);
  828. }
  829. }
  830. SSL_CTX_set_verify(m_ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT | SSL_VERIFY_CLIENT_ONCE, verify_callback);
  831. m_peers.setown(new CStringSet());
  832. const char* peersstr = config->queryProp("verify/trusted_peers");
  833. while(peersstr && *peersstr)
  834. {
  835. StringBuffer onepeerbuf;
  836. peersstr = strtok__(peersstr, "|", onepeerbuf);
  837. if(onepeerbuf.length() == 0)
  838. break;
  839. char* onepeer = onepeerbuf.detach();
  840. if (isdigit(*onepeer))
  841. {
  842. char *dash = strrchr(onepeer, '-');
  843. if (dash)
  844. {
  845. *dash = 0;
  846. int last = atoi(dash+1);
  847. char *dot = strrchr(onepeer, '.');
  848. *dot = 0;
  849. int first = atoi(dot+1);
  850. for (int i = first; i <= last; i++)
  851. {
  852. StringBuffer t;
  853. t.append(onepeer).append('.').append(i);
  854. m_peers->add(t.str());
  855. }
  856. }
  857. else
  858. {
  859. m_peers->add(onepeer);
  860. }
  861. }
  862. else
  863. {
  864. m_peers->add(onepeer);
  865. }
  866. free(onepeer);
  867. }
  868. }
  869. }
  870. ~CSecureSocketContext()
  871. {
  872. SSL_CTX_free(m_ctx);
  873. }
  874. ISecureSocket* createSecureSocket(ISocket* sock, int loglevel)
  875. {
  876. return new CSecureSocket(sock, m_ctx, m_verify, m_address_match, m_peers);
  877. }
  878. ISecureSocket* createSecureSocket(int sockfd, int loglevel)
  879. {
  880. return new CSecureSocket(sockfd, m_ctx, m_verify, m_address_match, m_peers);
  881. }
  882. };
  883. class CRsaCertificate : public CInterface, implements ICertificate
  884. {
  885. private:
  886. StringAttr m_destaddr;
  887. StringAttr m_passphrase;
  888. int m_days;
  889. StringAttr m_c;
  890. StringAttr m_s;
  891. StringAttr m_l;
  892. StringAttr m_o;
  893. StringAttr m_ou;
  894. StringAttr m_e;
  895. int m_bits;
  896. void addNameEntry(X509_NAME *subj, const char* name, const char* value)
  897. {
  898. int nid;
  899. X509_NAME_ENTRY *ent;
  900. if ((nid = OBJ_txt2nid ((char*)name)) == NID_undef)
  901. throw MakeStringException(-1, "Error finding NID for %s\n", name);
  902. if (!(ent = X509_NAME_ENTRY_create_by_NID(NULL, nid, MBSTRING_ASC, (unsigned char*)value, -1)))
  903. throw MakeStringException(-1, "Error creating Name entry from NID");
  904. if (X509_NAME_add_entry (subj, ent, -1, 0) != 1)
  905. throw MakeStringException(-1, "Error adding entry to subject");
  906. }
  907. public:
  908. IMPLEMENT_IINTERFACE;
  909. CRsaCertificate()
  910. {
  911. m_days = 365;
  912. m_bits = 1024;
  913. }
  914. virtual ~CRsaCertificate()
  915. {
  916. }
  917. virtual void setDestAddr(const char* destaddr)
  918. {
  919. m_destaddr.set(destaddr);
  920. }
  921. virtual void setDays(int days)
  922. {
  923. m_days = days;
  924. }
  925. virtual void setPassphrase(const char* passphrase)
  926. {
  927. m_passphrase.set(passphrase);
  928. }
  929. virtual void setCountry(const char* country)
  930. {
  931. m_c.set(country);
  932. }
  933. virtual void setState(const char* state)
  934. {
  935. m_s.set(state);
  936. }
  937. virtual void setCity(const char* city)
  938. {
  939. m_l.set(city);
  940. }
  941. virtual void setOrganization(const char* o)
  942. {
  943. m_o.set(o);
  944. }
  945. virtual void setOrganizationalUnit(const char* ou)
  946. {
  947. m_ou.set(ou);
  948. }
  949. virtual void setEmail(const char* email)
  950. {
  951. m_e.set(email);
  952. }
  953. virtual int generate(StringBuffer& certificate, StringBuffer& privkey)
  954. {
  955. if(m_destaddr.length() == 0)
  956. throw MakeStringException(-1, "Common Name (server's hostname or IP address) not set for certificate");
  957. if(m_passphrase.length() == 0)
  958. throw MakeStringException(-1, "passphrase not set.");
  959. if(m_days <= 0)
  960. throw MakeStringException(-1, "The number of days should be a positive integer");
  961. if(m_c.length() == 0)
  962. m_c.set("US");
  963. if(m_o.length() == 0)
  964. m_o.set("Customer Of Seisint");
  965. BIO *bio_err;
  966. BIO *pmem, *cmem;
  967. X509 *x509=NULL;
  968. EVP_PKEY *pkey=NULL;
  969. CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
  970. bio_err=BIO_new_fp(stderr, BIO_NOCLOSE);
  971. if ((pkey=EVP_PKEY_new()) == NULL)
  972. throw MakeStringException(-1, "can't create private key");
  973. if ((x509=X509_new()) == NULL)
  974. throw MakeStringException(-1, "can't create X509 structure");
  975. RSA *rsa=RSA_generate_key(m_bits, RSA_F4, NULL, NULL);
  976. if (!EVP_PKEY_assign_RSA(pkey, rsa))
  977. {
  978. char errbuf[512];
  979. ERR_error_string_n(ERR_get_error(), errbuf, 512);
  980. throw MakeStringException(-1, "EVP_PKEY_ASSIGN_RSA error - %s", errbuf);
  981. }
  982. X509_NAME *name=NULL;
  983. X509_set_version(x509,3);
  984. ASN1_INTEGER_set(X509_get_serialNumber(x509), 0); // serial number set to 0
  985. X509_gmtime_adj(X509_get_notBefore(x509),0);
  986. X509_gmtime_adj(X509_get_notAfter(x509),(long)60*60*24*m_days);
  987. X509_set_pubkey(x509, pkey);
  988. name=X509_get_subject_name(x509);
  989. /* This function creates and adds the entry, working out the
  990. * correct string type and performing checks on its length.
  991. * Normally we'd check the return value for errors...
  992. */
  993. X509_NAME_add_entry_by_txt(name,"C",
  994. MBSTRING_ASC, (unsigned char*)m_c.get(), -1, -1, 0);
  995. if(m_s.length() > 0)
  996. {
  997. X509_NAME_add_entry_by_txt(name,"S",
  998. MBSTRING_ASC, (unsigned char*)m_s.get(), -1, -1, 0);
  999. }
  1000. if(m_l.length() > 0)
  1001. {
  1002. X509_NAME_add_entry_by_txt(name,"L",
  1003. MBSTRING_ASC, (unsigned char*)m_l.get(), -1, -1, 0);
  1004. }
  1005. X509_NAME_add_entry_by_txt(name,"O",
  1006. MBSTRING_ASC, (unsigned char*)m_o.get(), -1, -1, 0);
  1007. if(m_ou.length() > 0)
  1008. {
  1009. X509_NAME_add_entry_by_txt(name,"OU",
  1010. MBSTRING_ASC, (unsigned char*)m_ou.get(), -1, -1, 0);
  1011. }
  1012. if(m_e.length() > 0)
  1013. {
  1014. X509_NAME_add_entry_by_txt(name,"E",
  1015. MBSTRING_ASC, (unsigned char*)m_e.get(), -1, -1, 0);
  1016. }
  1017. X509_NAME_add_entry_by_txt(name,"CN",
  1018. MBSTRING_ASC, (unsigned char*)m_destaddr.get(), -1, -1, 0);
  1019. X509_set_issuer_name(x509,name);
  1020. /* Add extension using V3 code: we can set the config file as NULL
  1021. * because we wont reference any other sections. We can also set
  1022. * the context to NULL because none of these extensions below will need
  1023. * to access it.
  1024. */
  1025. X509_EXTENSION *ex = X509V3_EXT_conf_nid(NULL, NULL, NID_netscape_cert_type, "server");
  1026. if(ex != NULL)
  1027. {
  1028. X509_add_ext(x509, ex, -1);
  1029. X509_EXTENSION_free(ex);
  1030. }
  1031. ex = X509V3_EXT_conf_nid(NULL, NULL, NID_netscape_ssl_server_name,
  1032. (char*)m_destaddr.get());
  1033. if(ex != NULL)
  1034. {
  1035. X509_add_ext(x509, ex,-1);
  1036. X509_EXTENSION_free(ex);
  1037. }
  1038. if (!X509_sign(x509, pkey, EVP_md5()))
  1039. {
  1040. char errbuf[512];
  1041. ERR_error_string_n(ERR_get_error(), errbuf, 512);
  1042. throw MakeStringException(-1, "X509_sign error %s", errbuf);
  1043. }
  1044. const EVP_CIPHER *enc = EVP_des_ede3_cbc();
  1045. pmem = BIO_new(BIO_s_mem());
  1046. PEM_write_bio_PrivateKey(pmem, pkey, enc, (unsigned char*)m_passphrase.get(), m_passphrase.length(), NULL, NULL);
  1047. readBio(pmem, privkey);
  1048. cmem = BIO_new(BIO_s_mem());
  1049. PEM_write_bio_X509(cmem, x509);
  1050. readBio(cmem, certificate);
  1051. X509_free(x509);
  1052. EVP_PKEY_free(pkey);
  1053. CRYPTO_mem_leaks(bio_err);
  1054. BIO_free(bio_err);
  1055. BIO_free(pmem);
  1056. BIO_free(cmem);
  1057. return 0;
  1058. }
  1059. virtual int generate(StringBuffer& certificate, const char* privkey)
  1060. {
  1061. if(m_destaddr.length() == 0)
  1062. throw MakeStringException(-1, "Common Name (server's hostname or IP address) not set for certificate");
  1063. if(m_passphrase.length() == 0)
  1064. throw MakeStringException(-1, "passphrase not set.");
  1065. if(m_days <= 0)
  1066. throw MakeStringException(-1, "The number of days should be a positive integer");
  1067. if(m_c.length() == 0)
  1068. m_c.set("US");
  1069. if(m_o.length() == 0)
  1070. m_o.set("Customer Of Seisint");
  1071. BIO *bio_err;
  1072. BIO *pmem, *cmem;
  1073. X509 *x509=NULL;
  1074. EVP_PKEY *pkey=NULL;
  1075. CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
  1076. bio_err=BIO_new_fp(stderr, BIO_NOCLOSE);
  1077. OpenSSL_add_all_algorithms ();
  1078. ERR_load_crypto_strings ();
  1079. pmem = BIO_new(BIO_s_mem());
  1080. BIO_puts(pmem, privkey);
  1081. if (!(pkey = PEM_read_bio_PrivateKey (pmem, NULL, NULL, (void*)m_passphrase.get())))
  1082. throw MakeStringException(-1, "Error reading private key");
  1083. if ((x509=X509_new()) == NULL)
  1084. throw MakeStringException(-1, "can't create X509 structure");
  1085. X509_NAME *name=NULL;
  1086. X509_set_version(x509,3);
  1087. ASN1_INTEGER_set(X509_get_serialNumber(x509), 0); // serial number set to 0
  1088. X509_gmtime_adj(X509_get_notBefore(x509),0);
  1089. X509_gmtime_adj(X509_get_notAfter(x509),(long)60*60*24*m_days);
  1090. X509_set_pubkey(x509, pkey);
  1091. name=X509_get_subject_name(x509);
  1092. /* This function creates and adds the entry, working out the
  1093. * correct string type and performing checks on its length.
  1094. * Normally we'd check the return value for errors...
  1095. */
  1096. X509_NAME_add_entry_by_txt(name,"C",
  1097. MBSTRING_ASC, (unsigned char*)m_c.get(), -1, -1, 0);
  1098. if(m_s.length() > 0)
  1099. {
  1100. X509_NAME_add_entry_by_txt(name,"S",
  1101. MBSTRING_ASC, (unsigned char*)m_s.get(), -1, -1, 0);
  1102. }
  1103. if(m_l.length() > 0)
  1104. {
  1105. X509_NAME_add_entry_by_txt(name,"L",
  1106. MBSTRING_ASC, (unsigned char*)m_l.get(), -1, -1, 0);
  1107. }
  1108. X509_NAME_add_entry_by_txt(name,"O",
  1109. MBSTRING_ASC, (unsigned char*)m_o.get(), -1, -1, 0);
  1110. if(m_ou.length() > 0)
  1111. {
  1112. X509_NAME_add_entry_by_txt(name,"OU",
  1113. MBSTRING_ASC, (unsigned char*)m_ou.get(), -1, -1, 0);
  1114. }
  1115. if(m_e.length() > 0)
  1116. {
  1117. X509_NAME_add_entry_by_txt(name,"E",
  1118. MBSTRING_ASC, (unsigned char*)m_e.get(), -1, -1, 0);
  1119. }
  1120. X509_NAME_add_entry_by_txt(name,"CN",
  1121. MBSTRING_ASC, (unsigned char*)m_destaddr.get(), -1, -1, 0);
  1122. X509_set_issuer_name(x509,name);
  1123. /* Add extension using V3 code: we can set the config file as NULL
  1124. * because we wont reference any other sections. We can also set
  1125. * the context to NULL because none of these extensions below will need
  1126. * to access it.
  1127. */
  1128. X509_EXTENSION *ex = X509V3_EXT_conf_nid(NULL, NULL, NID_netscape_cert_type, "server");
  1129. if(ex != NULL)
  1130. {
  1131. X509_add_ext(x509, ex, -1);
  1132. X509_EXTENSION_free(ex);
  1133. }
  1134. ex = X509V3_EXT_conf_nid(NULL, NULL, NID_netscape_ssl_server_name,
  1135. (char*)m_destaddr.get());
  1136. if(ex != NULL)
  1137. {
  1138. X509_add_ext(x509, ex,-1);
  1139. X509_EXTENSION_free(ex);
  1140. }
  1141. if (!X509_sign(x509, pkey, EVP_md5()))
  1142. {
  1143. char errbuf[512];
  1144. ERR_error_string_n(ERR_get_error(), errbuf, 512);
  1145. throw MakeStringException(-1, "X509_sign error %s", errbuf);
  1146. }
  1147. cmem = BIO_new(BIO_s_mem());
  1148. PEM_write_bio_X509(cmem, x509);
  1149. readBio(cmem, certificate);
  1150. X509_free(x509);
  1151. EVP_PKEY_free(pkey);
  1152. CRYPTO_mem_leaks(bio_err);
  1153. BIO_free(bio_err);
  1154. BIO_free(pmem);
  1155. BIO_free(cmem);
  1156. return 0;
  1157. }
  1158. virtual int generateCSR(StringBuffer& privkey, StringBuffer& csr)
  1159. {
  1160. StringBuffer mycert;
  1161. generate(mycert, privkey);
  1162. return generateCSR(privkey.str(), csr);
  1163. }
  1164. virtual int generateCSR(const char* privkey, StringBuffer& csr)
  1165. {
  1166. if(m_destaddr.length() == 0)
  1167. throw MakeStringException(-1, "Common Name (server's hostname or IP address) not set for certificate");
  1168. if(m_passphrase.length() == 0)
  1169. throw MakeStringException(-1, "passphrase not set.");
  1170. if(m_c.length() == 0)
  1171. m_c.set("US");
  1172. if(m_o.length() == 0)
  1173. m_o.set("Customer Of Seisint");
  1174. BIO *bio_err;
  1175. X509_REQ *req;
  1176. X509_NAME *subj;
  1177. EVP_PKEY *pkey = NULL;
  1178. const EVP_MD *digest;
  1179. BIO *pmem;
  1180. CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
  1181. bio_err=BIO_new_fp(stderr, BIO_NOCLOSE);
  1182. OpenSSL_add_all_algorithms ();
  1183. ERR_load_crypto_strings ();
  1184. pmem = BIO_new(BIO_s_mem());
  1185. BIO_puts(pmem, privkey);
  1186. if (!(pkey = PEM_read_bio_PrivateKey (pmem, NULL, NULL, (void*)m_passphrase.get())))
  1187. throw MakeStringException(-1, "Error reading private key");
  1188. /* create a new request and add the key to it */
  1189. if (!(req = X509_REQ_new ()))
  1190. throw MakeStringException(-1, "Failed to create X509_REQ object");
  1191. X509_REQ_set_version(req,0L);
  1192. X509_REQ_set_pubkey (req, pkey);
  1193. if (!(subj = X509_NAME_new ()))
  1194. throw MakeStringException(-1, "Failed to create X509_NAME object");
  1195. addNameEntry(subj, "countryName", m_c.get());
  1196. if(m_s.length() > 0)
  1197. addNameEntry(subj, "stateOrProvinceName", m_s.get());
  1198. if(m_l.length() > 0)
  1199. addNameEntry(subj, "localityName", m_l.get());
  1200. addNameEntry(subj, "organizationName", m_o.get());
  1201. if(m_ou.length() > 0)
  1202. addNameEntry(subj, "organizationalUnitName", m_ou.get());
  1203. if(m_e.length() > 0)
  1204. addNameEntry(subj, "emailAddress", m_e.get());
  1205. addNameEntry(subj, "commonName", m_destaddr.get());
  1206. if (X509_REQ_set_subject_name (req, subj) != 1)
  1207. throw MakeStringException(-1, "Error adding subject to request");
  1208. /* pick the correct digest and sign the request */
  1209. if (EVP_PKEY_type (pkey->type) == EVP_PKEY_DSA)
  1210. digest = EVP_dss1 ();
  1211. else if (EVP_PKEY_type (pkey->type) == EVP_PKEY_RSA)
  1212. digest = EVP_sha1 ();
  1213. else
  1214. throw MakeStringException(-1, "Error checking public key for a valid digest");
  1215. if (!(X509_REQ_sign (req, pkey, digest)))
  1216. throw MakeStringException(-1, "Error signing request");
  1217. /* write the completed request */
  1218. BIO* reqmem = BIO_new(BIO_s_mem());
  1219. if (PEM_write_bio_X509_REQ(reqmem, req) != 1)
  1220. throw MakeStringException(-1, "Error while writing request");
  1221. readBio(reqmem, csr);
  1222. CRYPTO_mem_leaks(bio_err);
  1223. BIO_free(pmem);
  1224. BIO_free(reqmem);
  1225. EVP_PKEY_free (pkey);
  1226. X509_REQ_free (req);
  1227. return 0;
  1228. }
  1229. };
  1230. }
  1231. extern "C" {
  1232. CriticalSection factoryCrit;
  1233. SECURESOCKET_API ISecureSocketContext* createSecureSocketContext(SecureSocketType sockettype)
  1234. {
  1235. CriticalBlock b(factoryCrit);
  1236. if(sockettype == ClientSocket)
  1237. {
  1238. return new securesocket::CSecureSocketContext(sockettype);
  1239. }
  1240. else
  1241. {
  1242. if(server_securesocket_context.get() == NULL)
  1243. server_securesocket_context.setown(new securesocket::CSecureSocketContext(sockettype));
  1244. return server_securesocket_context.getLink();
  1245. }
  1246. }
  1247. SECURESOCKET_API ISecureSocketContext* createSecureSocketContextEx(const char* certfile, const char* privkeyfile, const char* passphrase, SecureSocketType sockettype)
  1248. {
  1249. CriticalBlock b(factoryCrit);
  1250. if(sockettype == ClientSocket)
  1251. {
  1252. return new securesocket::CSecureSocketContext(certfile, privkeyfile, passphrase, sockettype);
  1253. }
  1254. else
  1255. {
  1256. if(server_securesocket_context.get() == NULL)
  1257. server_securesocket_context.setown(new securesocket::CSecureSocketContext(certfile, privkeyfile, passphrase, sockettype));
  1258. return server_securesocket_context.getLink();
  1259. }
  1260. }
  1261. SECURESOCKET_API ISecureSocketContext* createSecureSocketContextEx2(IPropertyTree* config, SecureSocketType sockettype)
  1262. {
  1263. if(config == NULL)
  1264. return createSecureSocketContext(sockettype);
  1265. CriticalBlock b(factoryCrit);
  1266. if(sockettype == ClientSocket)
  1267. {
  1268. return new securesocket::CSecureSocketContext(config, sockettype);
  1269. }
  1270. else
  1271. {
  1272. if(server_securesocket_context.get() == NULL)
  1273. server_securesocket_context.setown(new securesocket::CSecureSocketContext(config, sockettype));
  1274. return server_securesocket_context.getLink();
  1275. }
  1276. }
  1277. SECURESOCKET_API ICertificate *createCertificate()
  1278. {
  1279. return new securesocket::CRsaCertificate();
  1280. }
  1281. SECURESOCKET_API int signCertificate(const char* csr, const char* ca_certificate, const char* ca_privkey, const char* ca_passphrase, int days, StringBuffer& certificate)
  1282. {
  1283. EVP_PKEY *pkey, *CApkey;
  1284. const EVP_MD *digest;
  1285. X509 *cert, *CAcert;
  1286. X509_REQ *req;
  1287. X509_NAME *name;
  1288. if(days <= 0)
  1289. days = 365;
  1290. OpenSSL_add_all_algorithms ();
  1291. ERR_load_crypto_strings ();
  1292. BIO *bio_err;
  1293. bio_err=BIO_new_fp(stderr, BIO_NOCLOSE);
  1294. // Read in and verify signature on the request
  1295. BIO *csrmem = BIO_new(BIO_s_mem());
  1296. BIO_puts(csrmem, csr);
  1297. if (!(req = PEM_read_bio_X509_REQ(csrmem, NULL, NULL, NULL)))
  1298. throw MakeStringException(-1, "Error reading request from buffer");
  1299. if (!(pkey = X509_REQ_get_pubkey(req)))
  1300. throw MakeStringException(-1, "Error getting public key from request");
  1301. if (X509_REQ_verify (req, pkey) != 1)
  1302. throw MakeStringException(-1, "Error verifying signature on certificate");
  1303. // read in the CA certificate and private key
  1304. BIO *cacertmem = BIO_new(BIO_s_mem());
  1305. BIO_puts(cacertmem, ca_certificate);
  1306. if (!(CAcert = PEM_read_bio_X509(cacertmem, NULL, NULL, NULL)))
  1307. throw MakeStringException(-1, "Error reading CA's certificate from buffer");
  1308. BIO *capkeymem = BIO_new(BIO_s_mem());
  1309. BIO_puts(capkeymem, ca_privkey);
  1310. if (!(CApkey = PEM_read_bio_PrivateKey (capkeymem, NULL, NULL, (void*)ca_passphrase)))
  1311. throw MakeStringException(-1, "Error reading CA private key");
  1312. cert = X509_new();
  1313. X509_set_version(cert,3);
  1314. ASN1_INTEGER_set(X509_get_serialNumber(cert), 0); // serial number set to 0
  1315. // set issuer and subject name of the cert from the req and the CA
  1316. name = X509_REQ_get_subject_name (req);
  1317. X509_set_subject_name (cert, name);
  1318. name = X509_get_subject_name (CAcert);
  1319. X509_set_issuer_name (cert, name);
  1320. //set public key in the certificate
  1321. X509_set_pubkey (cert, pkey);
  1322. // set duration for the certificate
  1323. X509_gmtime_adj (X509_get_notBefore (cert), 0);
  1324. X509_gmtime_adj (X509_get_notAfter (cert), days*24*60*60);
  1325. // sign the certificate with the CA private key
  1326. if (EVP_PKEY_type (CApkey->type) == EVP_PKEY_DSA)
  1327. digest = EVP_dss1 ();
  1328. else if (EVP_PKEY_type (CApkey->type) == EVP_PKEY_RSA)
  1329. digest = EVP_sha1 ();
  1330. else
  1331. throw MakeStringException(-1, "Error checking public key for a valid digest");
  1332. if (!(X509_sign (cert, CApkey, digest)))
  1333. throw MakeStringException(-1, "Error signing certificate");
  1334. // write the completed certificate
  1335. BIO* cmem = BIO_new(BIO_s_mem());
  1336. PEM_write_bio_X509(cmem, cert);
  1337. readBio(cmem, certificate);
  1338. CRYPTO_mem_leaks(bio_err);
  1339. BIO_free(csrmem);
  1340. BIO_free(cacertmem);
  1341. BIO_free(cmem);
  1342. EVP_PKEY_free(pkey);
  1343. X509_REQ_free(req);
  1344. return 0;
  1345. }
  1346. }