lighttpd 1.4.x https://www.lighttpd.net/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3519 lines
129 KiB

  1. /*
  2. * mod_nss - Network Security Services (NSS) support for lighttpd
  3. *
  4. * Copyright(c) 2020 Glenn Strauss gstrauss()gluelogic.com All rights reserved
  5. * License: BSD 3-clause (same as lighttpd)
  6. *
  7. * Portions supporting mod_nss_ssl_conf_ciphersuites() (see end of file)
  8. * Copyright 2001-2004 The Apache Software Foundation
  9. */
  10. /*
  11. * WARNING: EXPERIMENTAL code sketch; mod_nss is INCOMPLETE and UNTESTED
  12. *
  13. * NSS docs: https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS
  14. *
  15. * NSS documentation is seriously lacking and man pages exist only for apps;
  16. * be prepared to slog through organic piles of NSS library code
  17. *
  18. * Note: If session tickets are -not- disabled with
  19. * ssl.openssl.ssl-conf-cmd = ("Options" => "-SessionTicket")
  20. * NSS never rotates server ticket encryption key (STEK) while running.
  21. * Therefore, if session tickets are enabled, lighttpd server should be
  22. * restarted (by an external job) at least every 24 hours. Restarting
  23. * lighttpd generates a new key that is shared by lighttpd workers. There
  24. * is no mechanism implemented in lighttpd mod_nss to share STEK between
  25. * independent lighttpd servers. ssl.stek-file is not used in mod_nss.
  26. *
  27. * NSS provides SSL_SetSessionTicketKeyPair(pubKey, privKey) to set RSA keys.
  28. * However, to match behavior of other lighttpd TLS modules, it seems we want
  29. * to set the private struct ssl_self_encrypt_keys in lib/ssl/sslsnce.c
  30. * instead of the private struct ssl_self_encrypt_key_pair.
  31. * sslSelfEncryptKeys ssl_self_encrypt_keys contains:
  32. * PRUint8 keyName[SELF_ENCRYPT_KEY_NAME_LEN];
  33. * PK11SymKey *encKey;
  34. * PK11SymKey *macKey;
  35. * (see lib/ssl/sslsnce.c:GenerateSelfEncryptKeys())
  36. * PK11SymKey *masterSecret in ssl3CipherSpec in ssl3State in sslSessionID
  37. * is private in lib/ssl/ssl3con.c
  38. *
  39. * XXX: due to limitations, consider disabling session tickets in mod_nss
  40. *
  41. * not implemented:
  42. * - session ticket rotation (see comments above)
  43. * - OCSP Must Staple detection
  44. * - ssl.honor-cipher-order
  45. * - ssl.verifyclient.depth
  46. * - ssl.dh-file
  47. * - ssl.ec-curve
  48. * - ssl.openssl.ssl-conf-cmd Ciphersuite
  49. *
  50. * future:
  51. * - consider SSL_AlertReceivedCallback() to set SSLAlertCallback
  52. * in order to (optionally) log alerts, and to abort connection if fatal alert
  53. * - consider using experimental API for cipher suite choice in lib/ssl/sslexp.h
  54. * SSL_CipherSuiteOrderGet
  55. * SSL_CipherSuiteOrderSet
  56. * - detect CLOSE_NOTIFY from client
  57. * - feature options
  58. * - SSL_ENABLE_FALSE_START
  59. * - SSL_ENABLE_DELEGATED_CREDENTIALS
  60. * - SSL_ENABLE_0RTT_DATA
  61. * - SSL_SUPPRESS_END_OF_EARLY_DATA
  62. * - crypto option using FreeBL
  63. * "A core element of NSS is FreeBL, a base library providing hash functions,
  64. * big number calculations, and cryptographic algorithms."
  65. * "Softoken is an NSS module that exposes most FreeBL functionality as a
  66. * PKCS#11 module."
  67. * "PR_GetRandomNoise - Produces a random value for use as a seed value for
  68. * another random number generator."
  69. */
  70. #include "first.h"
  71. #include <sys/types.h>
  72. #include <sys/stat.h>
  73. #include <errno.h>
  74. #include <fcntl.h>
  75. #include <stdarg.h>
  76. #include <stdlib.h>
  77. #include <stdio.h> /* vsnprintf() */
  78. #include <string.h>
  79. #ifdef __has_include
  80. #if __has_include(<nss3/nss.h>)
  81. #define NSS_VER_INCLUDE
  82. #endif
  83. #endif
  84. #ifndef NSS_VER_INCLUDE
  85. #include <nspr/nspr.h>
  86. #include <nspr/private/pprio.h> /* see mod_nss_io_ctor() comments */
  87. #include <nss/nss.h>
  88. #include <nss/nssb64.h>
  89. #include <nss/keyhi.h>
  90. #include <nss/pk11pub.h>
  91. #include <nss/secder.h>
  92. #include <nss/secerr.h>
  93. #include <nss/ssl.h>
  94. #include <nss/sslproto.h>
  95. #else
  96. #include <nspr4/nspr.h>
  97. #include <nspr4/private/pprio.h> /* see mod_nss_io_ctor() comments */
  98. #include <nss3/nss.h>
  99. #include <nss3/nssb64.h>
  100. #include <nss3/keyhi.h>
  101. #include <nss3/pk11pub.h>
  102. #include <nss3/secder.h>
  103. #include <nss3/secerr.h>
  104. #include <nss3/ssl.h>
  105. #include <nss3/sslproto.h>
  106. #endif
  107. #include "base.h"
  108. #include "fdevent.h"
  109. #include "http_header.h"
  110. #include "http_kv.h"
  111. #include "log.h"
  112. #include "plugin.h"
  113. #include "safe_memclear.h"
  114. typedef struct {
  115. /* SNI per host: with COMP_SERVER_SOCKET, COMP_HTTP_SCHEME, COMP_HTTP_HOST */
  116. char must_staple;
  117. CERTCertificate *ssl_pemfile_x509;
  118. SECKEYPrivateKey *ssl_pemfile_pkey;
  119. SSLExtraServerCertData ssl_credex;
  120. const buffer *ssl_stapling_file;
  121. time_t ssl_stapling_loadts;
  122. time_t ssl_stapling_nextts;
  123. SECItemArray OCSPResponses;
  124. SECItem OCSPResponse;
  125. } plugin_cert;
  126. typedef struct {
  127. PRFileDesc *model;
  128. SSLVersionRange protos;
  129. PRBool ssl_compression;
  130. int8_t ssl_session_ticket;
  131. } plugin_ssl_ctx;
  132. typedef struct {
  133. plugin_cert *pc;
  134. /*(used only during startup; not patched)*/
  135. unsigned char ssl_enabled; /* only interesting for setting up listening sockets. don't use at runtime */
  136. unsigned char ssl_honor_cipher_order; /* determine SSL cipher in server-preferred order, not client-order */
  137. unsigned char ssl_empty_fragments;
  138. unsigned char ssl_use_sslv2;
  139. unsigned char ssl_use_sslv3;
  140. const buffer *ssl_cipher_list;
  141. const buffer *ssl_ec_curve;
  142. array *ssl_conf_cmd;
  143. /*(copied from plugin_data for socket ssl_ctx config)*/
  144. unsigned char ssl_session_ticket;
  145. unsigned char ssl_verifyclient;
  146. unsigned char ssl_verifyclient_enforce;
  147. unsigned char ssl_verifyclient_depth;
  148. PRFileDesc *model;
  149. SSLVersionRange protos;
  150. PRBool ssl_compression;
  151. } plugin_config_socket; /*(used at startup during configuration)*/
  152. typedef struct {
  153. /* SNI per host: w/ COMP_SERVER_SOCKET, COMP_HTTP_SCHEME, COMP_HTTP_HOST */
  154. plugin_cert *pc;
  155. CERTCertList *ssl_ca_file;
  156. CERTCertList *ssl_ca_dn_file;
  157. unsigned char ssl_verifyclient;
  158. unsigned char ssl_verifyclient_enforce;
  159. unsigned char ssl_verifyclient_depth;
  160. unsigned char ssl_verifyclient_export_cert;
  161. unsigned char ssl_read_ahead;
  162. unsigned char ssl_log_noise;
  163. unsigned char ssl_disable_client_renegotiation;
  164. const buffer *ssl_verifyclient_username;
  165. const buffer *ssl_acme_tls_1;
  166. } plugin_config;
  167. typedef struct {
  168. PLUGIN_DATA;
  169. plugin_ssl_ctx *ssl_ctxs;
  170. plugin_config defaults;
  171. server *srv;
  172. } plugin_data;
  173. static int ssl_is_init;
  174. /* need assigned p->id for deep access of module handler_ctx for connection
  175. * i.e. handler_ctx *hctx = con->plugin_ctx[plugin_data_singleton->id]; */
  176. static plugin_data *plugin_data_singleton;
  177. #define LOCAL_SEND_BUFSIZE 16384 /* DEFAULT_MAX_RECORD_SIZE */
  178. static char *local_send_buffer;
  179. typedef struct {
  180. PRFileDesc *ssl;
  181. request_st *r;
  182. connection *con;
  183. int8_t close_notify;
  184. uint8_t alpn;
  185. int8_t ssl_session_ticket;
  186. int handshake;
  187. size_t pending_write;
  188. plugin_config conf;
  189. int verify_status;
  190. buffer *tmp_buf;
  191. log_error_st *errh;
  192. } handler_ctx;
  193. static handler_ctx *
  194. handler_ctx_init (void)
  195. {
  196. handler_ctx *hctx = calloc(1, sizeof(*hctx));
  197. force_assert(hctx);
  198. return hctx;
  199. }
  200. static void mod_nss_io_dtor (PRFileDesc *ssl);
  201. static void
  202. handler_ctx_free (handler_ctx *hctx)
  203. {
  204. mod_nss_io_dtor(hctx->ssl);
  205. free(hctx);
  206. }
  207. __attribute_cold__
  208. static void elog(log_error_st * const errh,
  209. const char * const file, const int line,
  210. const char * const msg)
  211. {
  212. /* error logging convenience function that decodes NSS result codes */
  213. const PRErrorCode rc = PR_GetError();
  214. const char *s = PR_ErrorToName(rc);
  215. log_error(errh, file, line, "NSS: %s: (%s) %s",
  216. msg, s ? s : "", PR_ErrorToString(rc, 0));
  217. }
  218. __attribute_cold__
  219. __attribute_format__((__printf__, 4, 5))
  220. static void elogf(log_error_st * const errh,
  221. const char * const file, const int line,
  222. const char * const fmt, ...)
  223. {
  224. char msg[1024];
  225. va_list ap;
  226. va_start(ap, fmt);
  227. vsnprintf(msg, sizeof(msg), fmt, ap);
  228. va_end(ap);
  229. elog(errh, file, line, msg);
  230. }
  231. static PRFileDesc *
  232. mod_nss_io_ctor (int fd, PRFileDesc *model, log_error_st *errh)
  233. {
  234. /* WTH? Why not a public PR_ImportTCPSocket() interface from NSPR?
  235. * (and PR_GetInheritedFD() is not a great replacement interface to
  236. * fudge NSPR_INHERIT_FDS in environment for each connection)
  237. *
  238. * #include <nspr4/private/pprio.h>
  239. * Use internal routines to set up PRFileDesc. Perform actions underlying
  240. * PR_ImportTCPSocket() to avoid excess work done by PR_ImportTCPSocket(),
  241. * which includes closing the fd if there is a failure. Could pass 0 as fd
  242. * to PR_AllocFileDesc() to avoid NSPR setting O_NONBLOCK since already set.
  243. * Instead, employ simpler PR_CreateSocketPollFd() and change methods table,
  244. * which handles _PR_ImplicitInitialization() (PR_AllocFileDesc() does not).
  245. * (WTH?: PR_AllocFileDesc() has limit fd < FD_SETSIZE when XP_UNIX defined)
  246. * Note: since bypassing PR_ImportTCPSocket() this might not work on Windows
  247. * which expects prfd->secret->af to be set to AF_INET.
  248. */
  249. #if defined(_WIN32) && !defined(__CYGWIN__)
  250. PRFileDesc *prfd = PR_ImportTCPSocket(fd);
  251. if (NULL == prfd) {
  252. elog(errh, __FILE__, __LINE__, "PR_ImportTCPSocket()");
  253. return NULL;
  254. }
  255. #else
  256. /*PRFileDesc *prfd = PR_AllocFileDesc(0, PR_GetTCPMethods());*/
  257. PRFileDesc *prfd = PR_CreateSocketPollFd(fd);
  258. if (NULL == prfd) {
  259. elog(errh, __FILE__, __LINE__, "PR_CreateSocketPollFd()");
  260. return NULL;
  261. }
  262. /*PR_ChangeFileDescNativeHandle(prfd, fd);*/
  263. prfd->methods = PR_GetTCPMethods();
  264. /*prfd->dtor = PR_FreeFileDesc();*/ /* PR_FreeFileDesc() is private */
  265. #endif
  266. /* set prfd->secret->nonblocking flag */
  267. PRSocketOptionData data;
  268. data.option = PR_SockOpt_Nonblocking;
  269. data.value.non_blocking = PR_TRUE;
  270. if (PR_SetSocketOption(prfd, &data) != PR_SUCCESS) {
  271. elog(errh, __FILE__, __LINE__, "PR_SocketSetSocketOption()");
  272. PR_DestroySocketPollFd(prfd); /* PR_FreeFileDesc() is private */
  273. return NULL;
  274. }
  275. PRFileDesc *ssl = SSL_ImportFD(model, prfd);
  276. if (NULL == ssl) {
  277. elog(errh, __FILE__, __LINE__, "SSL_ImportFD()");
  278. PR_DestroySocketPollFd(prfd); /* PR_FreeFileDesc() is private */
  279. return NULL;
  280. }
  281. return ssl;
  282. }
  283. static void
  284. mod_nss_io_detach (PRFileDesc *ssl)
  285. {
  286. #if 0 /* PR_PopIOLayer() forbids pop of PR_NSPR_IO_LAYER */
  287. PRFileDesc *prfd = PR_PopIOLayer(ssl, PR_NSPR_IO_LAYER);
  288. if (prfd) {
  289. PR_ChangeFileDescNativeHandle(prfd, -1);
  290. PR_DestroySocketPollFd(prfd); /* PR_FreeFileDesc() is private */
  291. }
  292. #else
  293. /*(results in close(-1) and EBADF from PR_Close() in mod_nss_io_dtor())*/
  294. PRFileDesc *prfd = PR_GetIdentitiesLayer(ssl, PR_NSPR_IO_LAYER);
  295. if (prfd)
  296. PR_ChangeFileDescNativeHandle(prfd, -1);
  297. #endif
  298. }
  299. static void
  300. mod_nss_io_dtor (PRFileDesc *ssl)
  301. {
  302. if (NULL == ssl) return;
  303. mod_nss_io_detach(ssl);
  304. PR_Close(ssl);
  305. }
  306. static int
  307. mod_nss_load_file (const char * const fn, SECItem * const d, log_error_st *errh)
  308. {
  309. off_t dlen = 512*1024*1024;/*(arbitrary limit: 512 MB file; expect < 1 MB)*/
  310. char *data = fdevent_load_file(fn, &dlen, errh, PORT_Alloc, PORT_Free);
  311. if (NULL == data) return -1;
  312. d->type = siBuffer;
  313. d->data = (unsigned char *)data;
  314. d->len = (unsigned int)dlen;
  315. return 0;
  316. }
  317. static void
  318. mod_nss_secitem_wipe (SECItem * const d)
  319. {
  320. /* safer than SECITEM_ZfreeItem() */
  321. if (NULL == d) return;
  322. if (d->data) {
  323. if (d->len) safe_memclear(d->data, d->len); /*safer than PORT_Memset()*/
  324. PORT_Free(d->data); /* safe_memclear() is safer than PORT_ZFree() */
  325. d->data = NULL;
  326. }
  327. d->len = 0;
  328. }
  329. INIT_FUNC(mod_nss_init)
  330. {
  331. plugin_data_singleton = (plugin_data *)calloc(1, sizeof(plugin_data));
  332. return plugin_data_singleton;
  333. }
  334. static int mod_nss_init_once_nss (void)
  335. {
  336. if (ssl_is_init) return 1;
  337. ssl_is_init = 1;
  338. /*PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);*//*implicit on first use*/
  339. if (!NSS_IsInitialized() && NSS_NoDB_Init(NULL) < 0)
  340. return 0;
  341. if (SSL_OptionSetDefault(SSL_ENABLE_SSL2, PR_FALSE) < 0)
  342. return 0;
  343. if (SSL_OptionSetDefault(SSL_ENABLE_SSL3, PR_FALSE) < 0)
  344. return 0;
  345. /* XXX: lighttpd is single threaded and so SSL_NO_LOCKS is desirable,
  346. * but NSS crashes if SSL_NO_LOCKS option is set to PR_TRUE.
  347. * (Crash in SSL3_SendAlert() call to PR_GetMonitorEntryCount()
  348. * with NULL ptr to monitor (mon))
  349. * NSS lib/ssl/sslimpl.h macros such as ssl_HaveSSL3HandshakeLock(ss),
  350. * plus some other .c files use macros without first checking if
  351. * (!ss->opt.noLocks): PZ_InMonitor() PZ_InMonitor() PZ_InMonitor() */
  352. /*if (SSL_OptionSetDefault(SSL_NO_LOCKS, PR_TRUE) < 0)*/
  353. if (SSL_OptionSetDefault(SSL_NO_LOCKS, PR_FALSE) < 0)
  354. return 0;
  355. if (SSL_OptionSetDefault(SSL_NO_CACHE, PR_TRUE) < 0)
  356. return 0;
  357. if (SSL_OptionSetDefault(SSL_ENABLE_SESSION_TICKETS, PR_TRUE) < 0)
  358. return 0;
  359. if (SSL_OptionSetDefault(SSL_ENABLE_ALPN, PR_TRUE) < 0)
  360. return 0;
  361. if (SSL_OptionSetDefault(SSL_ENABLE_RENEGOTIATION,
  362. SSL_RENEGOTIATE_NEVER) < 0)
  363. return 0;
  364. if (NSS_SetDomesticPolicy() < 0)
  365. return 0;
  366. local_send_buffer = malloc(LOCAL_SEND_BUFSIZE);
  367. force_assert(NULL != local_send_buffer);
  368. return 1;
  369. }
  370. static void mod_nss_free_nss (void)
  371. {
  372. if (!ssl_is_init) return;
  373. NSS_Shutdown();
  374. free(local_send_buffer);
  375. ssl_is_init = 0;
  376. }
  377. #define PEM_BEGIN "-----BEGIN "
  378. #define PEM_END "-----END "
  379. #define PEM_BEGIN_CERT "-----BEGIN CERTIFICATE-----"
  380. #define PEM_END_CERT "-----END CERTIFICATE-----"
  381. #define PEM_BEGIN_TRUSTED_CERT "-----BEGIN TRUSTED CERTIFICATE-----"
  382. #define PEM_END_TRUSTED_CERT "-----END TRUSTED CERTIFICATE-----"
  383. #define PEM_BEGIN_PKEY "-----BEGIN PRIVATE KEY-----"
  384. #define PEM_END_PKEY "-----END PRIVATE KEY-----"
  385. #define PEM_BEGIN_EC_PKEY "-----BEGIN EC PRIVATE KEY-----"
  386. #define PEM_END_EC_PKEY "-----END EC PRIVATE KEY-----"
  387. #define PEM_BEGIN_RSA_PKEY "-----BEGIN RSA PRIVATE KEY-----"
  388. #define PEM_END_RSA_PKEY "-----END RSA PRIVATE KEY-----"
  389. #define PEM_BEGIN_DSA_PKEY "-----BEGIN DSA PRIVATE KEY-----"
  390. #define PEM_END_DSA_PKEY "-----END DSA PRIVATE KEY-----"
  391. #define PEM_BEGIN_ANY_PKEY "-----BEGIN ANY PRIVATE KEY-----"
  392. #define PEM_END_ANY_PKEY "-----END ANY PRIVATE KEY-----"
  393. /* (not implemented: support to get password from user for encrypted key) */
  394. #define PEM_BEGIN_ENCRYPTED_PKEY "-----BEGIN ENCRYPTED PRIVATE KEY-----"
  395. #define PEM_END_ENCRYPTED_PKEY "-----END ENCRYPTED PRIVATE KEY-----"
  396. #define PEM_BEGIN_X509_CRL "-----BEGIN X509 CRL-----"
  397. #define PEM_END_X509_CRL "-----END X509 CRL-----"
  398. static CERTCertificateList *
  399. mod_nss_load_pem_file (const char *fn, log_error_st *errh)
  400. {
  401. if (!mod_nss_init_once_nss()) return NULL;
  402. SECItem f;
  403. int rc = mod_nss_load_file(fn, &f, errh);
  404. if (rc < 0) return NULL;
  405. rc = -1;
  406. CERTCertificateList *chain = NULL;
  407. do {
  408. int count = 0;
  409. char *b = (char *)f.data;
  410. for (; (b = strstr(b, PEM_BEGIN_CERT)); b += sizeof(PEM_BEGIN_CERT)-1)
  411. ++count;
  412. b = (char *)f.data;
  413. for (; (b = strstr(b, PEM_BEGIN_TRUSTED_CERT));
  414. b += sizeof(PEM_BEGIN_TRUSTED_CERT)-1)
  415. ++count;
  416. if (0 == count) {
  417. rc = 0;
  418. break;
  419. }
  420. PLArenaPool *arena = PORT_NewArena(4096);
  421. if (NULL == arena)
  422. break;
  423. chain = (CERTCertificateList *)
  424. PORT_ArenaAlloc(arena, sizeof(CERTCertificateList));
  425. if (NULL == chain) {
  426. PORT_FreeArena(arena, PR_FALSE);
  427. break;
  428. }
  429. chain->arena = arena;
  430. chain->len = count;
  431. chain->certs = (SECItem *)PORT_ArenaAlloc(arena, count*sizeof(SECItem));
  432. if (NULL == chain->certs)
  433. break;
  434. int i = 0;
  435. for (char *e = (char *)f.data; (b = strstr(e, PEM_BEGIN_CERT)); ++i) {
  436. b += sizeof(PEM_BEGIN_CERT)-1;
  437. if (*b == '\r') ++b;
  438. if (*b == '\n') ++b;
  439. e = strstr(b, PEM_END_CERT);
  440. if (NULL == e) break;
  441. uint32_t len = (uint32_t)(e - b);
  442. e += sizeof(PEM_END_CERT)-1;
  443. chain->certs[i].type = 0;
  444. chain->certs[i].data = NULL;
  445. chain->certs[i].len = 0;
  446. if (NULL == NSSBase64_DecodeBuffer(arena, chain->certs+i, b, len))
  447. break;
  448. }
  449. for (char *e=(char *)f.data; (b=strstr(e,PEM_BEGIN_TRUSTED_CERT)); ++i){
  450. b += sizeof(PEM_BEGIN_TRUSTED_CERT)-1;
  451. if (*b == '\r') ++b;
  452. if (*b == '\n') ++b;
  453. e = strstr(b, PEM_END_TRUSTED_CERT);
  454. if (NULL == e) break;
  455. uint32_t len = (uint32_t)(e - b);
  456. e += sizeof(PEM_END_TRUSTED_CERT)-1;
  457. chain->certs[i].type = 0;
  458. chain->certs[i].data = NULL;
  459. chain->certs[i].len = 0;
  460. if (NULL == NSSBase64_DecodeBuffer(arena, chain->certs+i, b, len))
  461. break;
  462. }
  463. if (i == count)
  464. rc = 0;
  465. else
  466. PORT_SetError(SEC_ERROR_IO);
  467. } while (0);
  468. mod_nss_secitem_wipe(&f);
  469. if (rc < 0) {
  470. elogf(errh, __FILE__, __LINE__, "error loading %s", fn);
  471. if (chain)
  472. CERT_DestroyCertificateList(chain);
  473. return NULL;
  474. }
  475. return chain;
  476. }
  477. static CERTCertificate *
  478. mod_nss_load_pem_crts (const char *fn, log_error_st *errh, CERTCertificateList **pchain)
  479. {
  480. *pchain = mod_nss_load_pem_file(fn, errh);
  481. if (NULL == *pchain) return NULL;
  482. CERTCertificate *cert = CERT_NewTempCertificate(NULL, (*pchain)->certs+0,
  483. NULL, PR_FALSE, PR_TRUE);
  484. if (NULL == cert) {
  485. CERT_DestroyCertificateList(*pchain);
  486. *pchain = NULL;
  487. }
  488. return cert;
  489. }
  490. static CERTCertList *
  491. mod_nss_cert_list (CERTCertificateList *crts)
  492. {
  493. SECStatus rc = SECFailure;
  494. CERTCertificate *cert = NULL;
  495. CERTCertList *clist = CERT_NewCertList();
  496. if (NULL != clist) {
  497. for (int i = 0; i < crts->len; ++i) {
  498. cert = CERT_NewTempCertificate(NULL, crts->certs+i,
  499. NULL, PR_FALSE, PR_TRUE);
  500. if (NULL == cert) break;
  501. rc = CERT_AddCertToListTail(clist, cert);
  502. if (rc < 0) break;
  503. }
  504. }
  505. if (rc < 0 || NULL == cert) {
  506. if (cert) CERT_DestroyCertificate(cert);
  507. if (clist) CERT_DestroyCertList(clist);
  508. PORT_SetError(SEC_ERROR_NO_MEMORY);
  509. return NULL;
  510. }
  511. return clist;
  512. }
  513. static CERTCertList *
  514. mod_nss_load_config_crts (const char *fn, log_error_st *errh)
  515. {
  516. CERTCertificateList *crts = mod_nss_load_pem_file(fn, errh);
  517. if (NULL == crts) return NULL;
  518. CERTCertList *clist = NULL;
  519. SECStatus rc =
  520. CERT_ImportCAChainTrusted(crts->certs,crts->len,certUsageUserCertImport);
  521. if (rc == SECSuccess)
  522. clist = mod_nss_cert_list(crts);
  523. else {
  524. elogf(errh, __FILE__, __LINE__, "CERT_ImportCAChainTrusted() %s", fn);
  525. CERT_DestroyCertificateList(crts);
  526. return NULL;
  527. }
  528. CERT_DestroyCertificateList(crts);
  529. return clist;
  530. }
  531. static CERTCertList *
  532. mod_nss_load_config_dncrts (const char *fn, log_error_st *errh)
  533. {
  534. CERTCertificateList *crts = mod_nss_load_pem_file(fn, errh);
  535. if (NULL == crts) return NULL;
  536. CERTCertList *clist = mod_nss_cert_list(crts);
  537. CERT_DestroyCertificateList(crts);
  538. return clist;
  539. }
  540. static void
  541. mod_nss_free_config_crls (CERTCertificateList *crls)
  542. {
  543. if (NULL == crls) return;
  544. CERTCertDBHandle * const dbhandle = CERT_GetDefaultCertDB();
  545. for (int i = 0; i < crls->len; ++i)
  546. CERT_UncacheCRL(dbhandle, crls->certs+i);
  547. CERT_DestroyCertificateList(crls);
  548. }
  549. static CERTCertificateList *
  550. mod_nss_load_config_crls (const char *fn, log_error_st *errh)
  551. {
  552. /*(similar start to other mod_nss_load_config_*())*/
  553. if (!mod_nss_init_once_nss()) return NULL;
  554. SECItem f;
  555. int rc = mod_nss_load_file(fn, &f, errh);
  556. if (rc < 0) return NULL;
  557. rc = -1;
  558. CERTCertificateList *chain = NULL;
  559. CERTCertDBHandle * const dbhandle = CERT_GetDefaultCertDB();
  560. do {
  561. int count = 0;
  562. char *b = (char *)f.data;
  563. for (; (b = strstr(b, PEM_BEGIN_X509_CRL));
  564. b += sizeof(PEM_BEGIN_X509_CRL)-1)
  565. ++count;
  566. if (0 == count) {
  567. rc = 0;
  568. break;
  569. }
  570. PLArenaPool *arena = PORT_NewArena(4096);
  571. if (NULL == arena)
  572. break;
  573. chain = (CERTCertificateList *)
  574. PORT_ArenaAlloc(arena, sizeof(CERTCertificateList));
  575. if (NULL == chain) {
  576. PORT_FreeArena(arena, PR_FALSE);
  577. break;
  578. }
  579. chain->arena = arena;
  580. chain->len = count;
  581. chain->certs = (SECItem *)PORT_ArenaAlloc(arena, count*sizeof(SECItem));
  582. if (NULL == chain->certs)
  583. break;
  584. int i = 0;
  585. for (char *e = (char *)f.data; (b = strstr(e,PEM_BEGIN_X509_CRL)); ++i){
  586. b += sizeof(PEM_BEGIN_X509_CRL)-1;
  587. if (*b == '\r') ++b;
  588. if (*b == '\n') ++b;
  589. e = strstr(b, PEM_END_X509_CRL);
  590. if (NULL == e) break;
  591. uint32_t len = (uint32_t)(e - b);
  592. e += sizeof(PEM_END_X509_CRL)-1;
  593. chain->certs[i].type = 0;
  594. chain->certs[i].data = NULL;
  595. chain->certs[i].len = 0;
  596. if (NULL == NSSBase64_DecodeBuffer(arena, chain->certs+i, b, len))
  597. break;
  598. /* using ephemeral db, so cache CRL instead of CERT_ImportCRL() */
  599. if (CERT_CacheCRL(dbhandle, chain->certs+i) < 0)
  600. break;
  601. }
  602. if (i == count)
  603. rc = 0;
  604. else
  605. PORT_SetError(SEC_ERROR_IO);
  606. } while (0);
  607. mod_nss_secitem_wipe(&f);
  608. if (rc < 0) {
  609. elogf(errh, __FILE__, __LINE__, "error loading %s", fn);
  610. if (chain)
  611. CERT_DestroyCertificateList(chain);
  612. return NULL;
  613. }
  614. return chain;
  615. }
  616. static SECItem *
  617. mod_nss_cert_get_publicValue (SECKEYPublicKey *pubKey)
  618. {
  619. /*(lib/pkcs12/p12d.c:sec_pkcs12_get_public_value_and_type() private)*/
  620. /*(lib/pk11wrap/pk11akey.c:pk11_MakeIDFromPublicKey() private, hashes)*/
  621. /*(lib/crmf/crmfcont.c:crmf_get_public_value() public but incomplete)*/
  622. switch (pubKey->keyType) {
  623. case dsaKey: return &pubKey->u.dsa.publicValue;
  624. case dhKey: return &pubKey->u.dh.publicValue;
  625. case rsaKey: return &pubKey->u.rsa.modulus;
  626. case ecKey: return &pubKey->u.ec.publicValue;
  627. default: return NULL;
  628. }
  629. }
  630. static SECKEYPrivateKey *
  631. mod_nss_load_config_pkey (const char *fn, CERTCertificate *cert, log_error_st *errh)
  632. {
  633. /* NSS does not provide convenient mechanisms to read PEM or DER private key
  634. * instead expecting PKCS12-format, which is not the convention used by many
  635. * other TLS modules */
  636. /*(similar start to other mod_nss_load_config_*())*/
  637. if (!mod_nss_init_once_nss()) return NULL;
  638. SECItem f;
  639. int rc = mod_nss_load_file(fn, &f, errh);
  640. if (rc < 0) return NULL;
  641. SECItem der = { 0, NULL, 0 };
  642. PK11SlotInfo *slot = NULL;
  643. SECKEYPrivateKey *pkey = NULL;
  644. SECStatus src = SECFailure;
  645. do {
  646. /*(expecting single private key in file, so first match)*/
  647. char *b, *e;
  648. if ((b = strstr((char *)f.data, PEM_BEGIN_PKEY))
  649. && (e = strstr(b, PEM_END_PKEY)))
  650. b += sizeof(PEM_BEGIN_PKEY)-1;
  651. else if ((b = strstr((char *)f.data, PEM_BEGIN_EC_PKEY))
  652. && (e = strstr(b, PEM_END_EC_PKEY)))
  653. b += sizeof(PEM_BEGIN_EC_PKEY)-1;
  654. else if ((b = strstr((char *)f.data, PEM_BEGIN_RSA_PKEY))
  655. && (e = strstr(b, PEM_END_RSA_PKEY)))
  656. b += sizeof(PEM_BEGIN_RSA_PKEY)-1;
  657. else if ((b = strstr((char *)f.data, PEM_BEGIN_DSA_PKEY))
  658. && (e = strstr(b, PEM_END_DSA_PKEY)))
  659. b += sizeof(PEM_BEGIN_DSA_PKEY)-1;
  660. else if ((b = strstr((char *)f.data, PEM_BEGIN_ANY_PKEY))
  661. && (e = strstr(b, PEM_END_ANY_PKEY)))
  662. b += sizeof(PEM_BEGIN_ANY_PKEY)-1;
  663. else
  664. break;
  665. if (*b == '\r') ++b;
  666. if (*b == '\n') ++b;
  667. if (NULL == NSSBase64_DecodeBuffer(NULL, &der, b, (uint32_t)(e - b)))
  668. break;
  669. slot = PK11_GetInternalKeySlot();
  670. if (NULL == slot) break;
  671. SECItem nickname = { 0, NULL, strlen(fn) };
  672. *(const unsigned char **)&nickname.data = (unsigned char *)fn;
  673. unsigned int keyUsage = KU_ALL; /* XXX: limit to fewer flags? */
  674. PRBool isPerm = PR_FALSE;
  675. PRBool isPrivate = PR_TRUE;
  676. SECKEYPublicKey *pubKey = CERT_ExtractPublicKey(cert);
  677. SECItem *pubValue = mod_nss_cert_get_publicValue(pubKey);
  678. src =
  679. PK11_ImportDERPrivateKeyInfoAndReturnKey(slot, &der, &nickname,
  680. pubValue, isPerm, isPrivate,
  681. keyUsage, &pkey, NULL);
  682. /* nickname attribute has reference taken to data;
  683. * data must persist longer than SECKEYPrivateKey */
  684. /* (pubValue data is of decoded type SEC_ASN1_INTEGER and is copied) */
  685. SECKEY_DestroyPublicKey(pubKey);
  686. } while (0);
  687. if (slot) PK11_FreeSlot(slot);
  688. if (der.data) {
  689. mod_nss_secitem_wipe(&der);
  690. PORT_Free(der.data);
  691. }
  692. mod_nss_secitem_wipe(&f);
  693. if (src < 0) {
  694. elogf(errh, __FILE__, __LINE__,
  695. "PK11_ImportDERPrivateKeyInfoAndReturnKey() %s", fn);
  696. return NULL;
  697. }
  698. return pkey;
  699. }
  700. static void
  701. mod_nss_free_config (server *srv, plugin_data * const p)
  702. {
  703. if (NULL != p->ssl_ctxs) {
  704. PRFileDesc *global_model = p->ssl_ctxs->model;
  705. /* free from $SERVER["socket"] (if not copy of global scope) */
  706. for (uint32_t i = 1; i < srv->config_context->used; ++i) {
  707. plugin_ssl_ctx * const s = p->ssl_ctxs + i;
  708. if (s->model && s->model != global_model)
  709. PR_Close(s->model);
  710. }
  711. /* free from global scope */
  712. if (global_model)
  713. PR_Close(global_model);
  714. free(p->ssl_ctxs);
  715. }
  716. if (NULL == p->cvlist) return;
  717. /* (init i to 0 if global context; to 1 to skip empty global context) */
  718. for (int i = !p->cvlist[0].v.u2[1], used = p->nconfig; i < used; ++i) {
  719. config_plugin_value_t *cpv = p->cvlist + p->cvlist[i].v.u2[0];
  720. for (; -1 != cpv->k_id; ++cpv) {
  721. switch (cpv->k_id) {
  722. case 0: /* ssl.pemfile */
  723. if (cpv->vtype == T_CONFIG_LOCAL) {
  724. plugin_cert *pc = cpv->v.v;
  725. CERT_DestroyCertificate(pc->ssl_pemfile_x509);
  726. SECKEY_DestroyPrivateKey(pc->ssl_pemfile_pkey);
  727. CERTCertificateList *certChain;
  728. *(const CERTCertificateList **)&certChain =
  729. pc->ssl_credex.certChain;
  730. CERT_DestroyCertificateList(certChain);
  731. PORT_Free(pc->OCSPResponse.data);
  732. //CERT_Destroy...(pc->ssl_credex.signedCertTimestamps);
  733. //CERT_Destroy...(pc->ssl_credex.delegCred);
  734. //CERT_Destroy...(pc->ssl_credex.delegCredPrivKey);
  735. free(pc);
  736. }
  737. break;
  738. case 2: /* ssl.ca-file */
  739. case 3: /* ssl.ca-dn-file */
  740. if (cpv->vtype == T_CONFIG_LOCAL)
  741. CERT_DestroyCertList(cpv->v.v);
  742. break;
  743. case 4: /* ssl.ca-crl-file */
  744. if (cpv->vtype == T_CONFIG_LOCAL)
  745. mod_nss_free_config_crls(cpv->v.v);
  746. break;
  747. default:
  748. break;
  749. }
  750. }
  751. }
  752. }
  753. FREE_FUNC(mod_nss_free)
  754. {
  755. plugin_data *p = p_d;
  756. if (NULL == p->srv) return;
  757. mod_nss_free_config(p->srv, p);
  758. mod_nss_free_nss();
  759. }
  760. static void
  761. mod_nss_merge_config_cpv (plugin_config * const pconf, const config_plugin_value_t * const cpv)
  762. {
  763. switch (cpv->k_id) { /* index into static config_plugin_keys_t cpk[] */
  764. case 0: /* ssl.pemfile */
  765. if (cpv->vtype == T_CONFIG_LOCAL)
  766. pconf->pc = cpv->v.v;
  767. break;
  768. case 1: /* ssl.privkey */
  769. break;
  770. case 2: /* ssl.ca-file */
  771. if (cpv->vtype == T_CONFIG_LOCAL)
  772. pconf->ssl_ca_file = cpv->v.v;
  773. break;
  774. case 3: /* ssl.ca-dn-file */
  775. if (cpv->vtype == T_CONFIG_LOCAL)
  776. pconf->ssl_ca_dn_file = cpv->v.v;
  777. break;
  778. case 4: /* ssl.ca-crl-file */
  779. break;
  780. case 5: /* ssl.read-ahead */
  781. pconf->ssl_read_ahead = (0 != cpv->v.u);
  782. break;
  783. case 6: /* ssl.disable-client-renegotiation */
  784. pconf->ssl_disable_client_renegotiation = (0 != cpv->v.u);
  785. break;
  786. case 7: /* ssl.verifyclient.activate */
  787. pconf->ssl_verifyclient = (0 != cpv->v.u);
  788. break;
  789. case 8: /* ssl.verifyclient.enforce */
  790. pconf->ssl_verifyclient_enforce = (0 != cpv->v.u);
  791. break;
  792. case 9: /* ssl.verifyclient.depth */
  793. pconf->ssl_verifyclient_depth = (unsigned char)cpv->v.shrt;
  794. break;
  795. case 10:/* ssl.verifyclient.username */
  796. pconf->ssl_verifyclient_username = cpv->v.b;
  797. break;
  798. case 11:/* ssl.verifyclient.exportcert */
  799. pconf->ssl_verifyclient_export_cert = (0 != cpv->v.u);
  800. break;
  801. case 12:/* ssl.acme-tls-1 */
  802. pconf->ssl_acme_tls_1 = cpv->v.b;
  803. break;
  804. case 13:/* ssl.stapling-file */
  805. break;
  806. case 14:/* debug.log-ssl-noise */
  807. pconf->ssl_log_noise = (unsigned char)cpv->v.shrt;
  808. break;
  809. default:/* should not happen */
  810. return;
  811. }
  812. }
  813. static void
  814. mod_nss_merge_config(plugin_config * const pconf, const config_plugin_value_t *cpv)
  815. {
  816. do {
  817. mod_nss_merge_config_cpv(pconf, cpv);
  818. } while ((++cpv)->k_id != -1);
  819. }
  820. static void
  821. mod_nss_patch_config (request_st * const r, plugin_config * const pconf)
  822. {
  823. plugin_data * const p = plugin_data_singleton;
  824. memcpy(pconf, &p->defaults, sizeof(plugin_config));
  825. for (int i = 1, used = p->nconfig; i < used; ++i) {
  826. if (config_check_cond(r, (uint32_t)p->cvlist[i].k_id))
  827. mod_nss_merge_config(pconf, p->cvlist + p->cvlist[i].v.u2[0]);
  828. }
  829. }
  830. static SECStatus
  831. mod_nss_verify_cb (void *arg, PRFileDesc *ssl, PRBool checkSig, PRBool isServer)
  832. {
  833. handler_ctx * const hctx = arg;
  834. if (!hctx->conf.ssl_verifyclient) return SECSuccess;
  835. /* Notes
  836. * trusted CAs in ssl.ca-file were loaded into default cert db at startup
  837. * OCSP checking (querying OCSP Responder) is disabled by default
  838. * CERT_EnableOCSPChecking()
  839. * CERT_DisableOCSPChecking()
  840. * cert_VerifyCertWithFlags() is not public,
  841. * so unable to use CERT_VERIFYCERT_SKIP_OCSP
  842. * hctx->verify_status is set here; not setting SSL_BadCertHook()
  843. * XXX: not implemented (yet) here: hctx->conf.ssl_verifyclient_depth)
  844. */
  845. CERTCertificate *peer = NULL;
  846. #if 0
  847. peer = SSL_PeerCertificate(ssl);
  848. if (NULL == peer)
  849. return (PORT_GetError() == SSL_ERROR_NO_CERTIFICATE)
  850. ? SECSuccess
  851. : SECFailure;
  852. if (CERT_VerifyCert(CERT_GetDefaultCertDB(), peer, PR_TRUE,
  853. certUsageSSLClient, (PRInt64)log_epoch_secs * 1000000,
  854. SSL_RevealPinArg(ssl), NULL) < 0)
  855. #else
  856. if (SSL_AuthCertificate((void *)CERT_GetDefaultCertDB(),
  857. ssl, checkSig, isServer) < 0)
  858. #endif
  859. {
  860. hctx->verify_status = PORT_GetError();
  861. if (0 == hctx->verify_status)
  862. hctx->verify_status = SEC_ERROR_UNTRUSTED_CERT;
  863. }
  864. if (hctx->verify_status == 0 && hctx->conf.ssl_ca_dn_file) {
  865. /* verify that client cert is issued by CA in ssl.ca-dn-file
  866. * if both ssl.ca-dn-file and ssl.ca-file were configured */
  867. if (NULL == peer) peer = SSL_PeerCertificate(ssl);
  868. if (peer) {
  869. CERTCertList * const certList = hctx->conf.ssl_ca_dn_file;
  870. SECItem * const derIssuer = &peer->derIssuer;
  871. CERTCertListNode *node = CERT_LIST_HEAD(certList);
  872. for (; !CERT_LIST_END(node, certList); node = CERT_LIST_NEXT(node)){
  873. SECItem * const derSubject = &node->cert->derSubject;
  874. if (SECITEM_CompareItem(derIssuer, derSubject) == SECEqual)
  875. break;
  876. }
  877. if (CERT_LIST_END(node, certList))
  878. hctx->verify_status = SEC_ERROR_UNTRUSTED_CERT;
  879. }
  880. }
  881. if (peer) CERT_DestroyCertificate(peer);
  882. if (hctx->verify_status != 0 && hctx->conf.ssl_verifyclient_enforce) {
  883. PORT_SetError(SEC_ERROR_UNTRUSTED_CERT);
  884. return SECFailure;
  885. }
  886. return SECSuccess;
  887. }
  888. static int
  889. mod_nss_reload_stapling_file (server *srv, plugin_cert *pc, const time_t cur_ts)
  890. {
  891. SECItem f;
  892. int rc = mod_nss_load_file(pc->ssl_stapling_file->ptr, &f, srv->errh);
  893. if (rc < 0) return rc;
  894. /* NSS has the ability to include multiple OCSP responses for
  895. * certificate chain as allowed in TLSv1.3, but that is not utilized here.
  896. * If implemented, it will probably operate on a new directive,
  897. * e.g. ssl.stapling-pemfile
  898. */
  899. /* Note that the credentials structure should be read-only when in
  900. * use, thus when reloading, either the credentials structure must not
  901. * be in use by any sessions, or a new credentials structure should be
  902. * allocated for new sessions.
  903. * XXX: lighttpd is not threaded, so this is probably not an issue (?)
  904. */
  905. PORT_Free(pc->OCSPResponse.data);
  906. pc->OCSPResponse.data = f.data;
  907. pc->OCSPResponse.len = f.len;
  908. pc->OCSPResponses.items = &pc->OCSPResponse;
  909. pc->OCSPResponses.len = 1;
  910. pc->ssl_credex.stapledOCSPResponses = &pc->OCSPResponses;
  911. /* NSS does not expose CERTOCSPSingleResponse member nextUpdate
  912. * to allow getting (PRTime) of nextUpdate from the OCSP response.
  913. * (PRTime is (PRInt64) of microseconds since epoch)
  914. * e.g. DER_GeneralizedTimeToTime(&nextUpdate, single->nextUpdate);
  915. * XXX: *not* implementing our own ASN.1 DER decoder for OCSP response
  916. * ssl.stapling-file will be reloaded hourly
  917. */
  918. time_t nextupd = (time_t)-1;
  919. pc->ssl_stapling_loadts = cur_ts;
  920. pc->ssl_stapling_nextts = nextupd;
  921. if (pc->ssl_stapling_nextts == (time_t)-1) {
  922. /* "Next Update" might not be provided by OCSP responder
  923. * Use 3600 sec (1 hour) in that case. */
  924. /* retry in 1 hour if unable to determine Next Update */
  925. pc->ssl_stapling_nextts = cur_ts + 3600;
  926. pc->ssl_stapling_loadts = 0;
  927. }
  928. return 0;
  929. }
  930. static int
  931. mod_nss_refresh_stapling_file (server *srv, plugin_cert *pc, const time_t cur_ts)
  932. {
  933. if (pc->ssl_stapling_nextts >= 256
  934. && pc->ssl_stapling_nextts - 256 > cur_ts)
  935. return 0; /* skip check for refresh unless close to expire */
  936. struct stat st;
  937. if (0 != stat(pc->ssl_stapling_file->ptr, &st)
  938. || st.st_mtime <= pc->ssl_stapling_loadts) {
  939. if (pc->ssl_stapling_nextts < cur_ts) {
  940. /* discard expired OCSP stapling response */
  941. pc->ssl_credex.stapledOCSPResponses = NULL;
  942. if (pc->must_staple) {
  943. log_error(srv->errh, __FILE__, __LINE__,
  944. "certificate marked OCSP Must-Staple, "
  945. "but OCSP response expired from ssl.stapling-file %s",
  946. pc->ssl_stapling_file->ptr);
  947. }
  948. }
  949. return 0;
  950. }
  951. return mod_nss_reload_stapling_file(srv, pc, cur_ts);
  952. }
  953. static void
  954. mod_nss_refresh_stapling_files (server *srv, const plugin_data *p, const time_t cur_ts)
  955. {
  956. /* future: might construct array of (plugin_cert *) at startup
  957. * to avoid the need to search for them here */
  958. for (int i = 0, used = p->nconfig; i < used; ++i) {
  959. const config_plugin_value_t *cpv = p->cvlist + p->cvlist[i].v.u2[0];
  960. for (; cpv->k_id != -1; ++cpv) {
  961. if (cpv->k_id != 0) continue; /* k_id == 0 for ssl.pemfile */
  962. if (cpv->vtype != T_CONFIG_LOCAL) continue;
  963. plugin_cert *pc = cpv->v.v;
  964. if (!buffer_string_is_empty(pc->ssl_stapling_file))
  965. mod_nss_refresh_stapling_file(srv, pc, cur_ts);
  966. }
  967. }
  968. }
  969. static int
  970. mod_nss_crt_must_staple (CERTCertificate *crt)
  971. {
  972. /* Look for TLS features X.509 extension with value 5
  973. * RFC 7633 https://tools.ietf.org/html/rfc7633#appendix-A
  974. * 5 = OCSP Must-Staple (security mechanism)
  975. *
  976. * id-pe-tlsfeature 1.3.6.1.5.5.7.1.24
  977. * 1.3.6.1.5.5.7.1.24 = DER:30:03:02:01:05
  978. */
  979. int rc;
  980. /* XXX: not implemented */
  981. UNUSED(crt);
  982. rc = 0;
  983. return rc; /* 1 if OCSP Must-Staple found; 0 if not */
  984. }
  985. static void *
  986. network_nss_load_pemfile (server *srv, const buffer *pemfile, const buffer *privkey, const buffer *ssl_stapling_file)
  987. {
  988. CERTCertificateList *ssl_pemfile_chain;
  989. CERTCertificate *ssl_pemfile_x509 =
  990. mod_nss_load_pem_crts(pemfile->ptr, srv->errh, &ssl_pemfile_chain);
  991. if (NULL == ssl_pemfile_x509)
  992. return NULL;
  993. SECKEYPrivateKey *pkey =
  994. mod_nss_load_config_pkey(privkey->ptr, ssl_pemfile_x509, srv->errh);
  995. if (NULL == pkey) {
  996. CERT_DestroyCertificate(ssl_pemfile_x509);
  997. if (ssl_pemfile_chain) CERT_DestroyCertificateList(ssl_pemfile_chain);
  998. return NULL;
  999. }
  1000. if (NULL == ssl_pemfile_chain)
  1001. ssl_pemfile_chain = CERT_CertChainFromCert(ssl_pemfile_x509,
  1002. certUsageSSLServer,
  1003. PR_FALSE);
  1004. plugin_cert *pc = calloc(1, sizeof(plugin_cert));
  1005. force_assert(pc);
  1006. pc->ssl_pemfile_pkey = pkey;
  1007. pc->ssl_pemfile_x509 = ssl_pemfile_x509;
  1008. pc->ssl_credex.certChain = ssl_pemfile_chain;
  1009. pc->ssl_stapling_file= ssl_stapling_file;
  1010. pc->ssl_stapling_loadts = 0;
  1011. pc->ssl_stapling_nextts = 0;
  1012. pc->OCSPResponse.type = 0;
  1013. pc->OCSPResponse.data = NULL;
  1014. pc->OCSPResponse.len = 0;
  1015. pc->OCSPResponses.items = NULL;
  1016. pc->OCSPResponses.len = 0;
  1017. pc->must_staple = mod_nss_crt_must_staple(ssl_pemfile_x509);
  1018. if (!buffer_string_is_empty(pc->ssl_stapling_file)) {
  1019. if (mod_nss_reload_stapling_file(srv, pc, log_epoch_secs) < 0) {
  1020. /* continue without OCSP response if there is an error */
  1021. }
  1022. }
  1023. else if (pc->must_staple) {
  1024. log_error(srv->errh, __FILE__, __LINE__,
  1025. "certificate %s marked OCSP Must-Staple, "
  1026. "but ssl.stapling-file not provided", pemfile->ptr);
  1027. }
  1028. return pc;
  1029. }
  1030. static int
  1031. mod_nss_acme_tls_1 (handler_ctx *hctx)
  1032. {
  1033. buffer * const b = hctx->tmp_buf;
  1034. const buffer * const name = &hctx->r->uri.authority;
  1035. log_error_st * const errh = hctx->r->conf.errh;
  1036. /* check if acme-tls/1 protocol is enabled (path to dir of cert(s) is set)*/
  1037. if (buffer_string_is_empty(hctx->conf.ssl_acme_tls_1))
  1038. return SECFailure; /*(should not happen)*/
  1039. buffer_copy_buffer(b, hctx->conf.ssl_acme_tls_1);
  1040. buffer_append_slash(b);
  1041. /* check if SNI set server name (required for acme-tls/1 protocol)
  1042. * and perform simple path checks for no '/'
  1043. * and no leading '.' (e.g. ignore "." or ".." or anything beginning '.') */
  1044. if (buffer_string_is_empty(name)) return SECFailure;
  1045. if (NULL != strchr(name->ptr, '/')) return SECFailure;
  1046. if (name->ptr[0] == '.') return SECFailure;
  1047. #if 0
  1048. if (0 != http_request_host_policy(name, hctx->r->conf.http_parseopts, 443))
  1049. return SECFailure;
  1050. #endif
  1051. buffer_append_string_buffer(b, name);
  1052. /* cert and key load is similar to network_nss_load_pemfile() */
  1053. uint32_t len = buffer_string_length(b);
  1054. buffer_append_string_len(b, CONST_STR_LEN(".crt.pem"));
  1055. CERTCertificateList *ssl_pemfile_chain;
  1056. CERTCertificate *ssl_pemfile_x509 =
  1057. mod_nss_load_pem_crts(b->ptr, errh, &ssl_pemfile_chain);
  1058. if (NULL == ssl_pemfile_x509)
  1059. return SECFailure;
  1060. buffer_string_set_length(b, len);
  1061. buffer_append_string_len(b, CONST_STR_LEN(".key.pem"));
  1062. SECKEYPrivateKey *pkey =
  1063. mod_nss_load_config_pkey(b->ptr, ssl_pemfile_x509, errh);
  1064. if (NULL == pkey) {
  1065. CERT_DestroyCertificate(ssl_pemfile_x509);
  1066. if (ssl_pemfile_chain) CERT_DestroyCertificateList(ssl_pemfile_chain);
  1067. return SECFailure;
  1068. }
  1069. /* use NSS deprecated functions to unconfigure an already-configured cert.
  1070. * This is because SSL_ConfigServerCert() will replace an existing cert
  1071. * of the same type, but not if an existing cert is of a different type */
  1072. if (hctx->conf.pc) {
  1073. SSLKEAType certType =
  1074. NSS_FindCertKEAType(hctx->conf.pc->ssl_pemfile_x509);
  1075. SSL_ConfigSecureServerWithCertChain(hctx->ssl,NULL,NULL,NULL,certType);
  1076. }
  1077. unsigned int dlen = 0;
  1078. SSLExtraServerCertData *data = NULL;
  1079. SSLExtraServerCertData d;
  1080. if (ssl_pemfile_chain) {
  1081. data = &d;
  1082. dlen = sizeof(d);
  1083. memset(&d, 0, sizeof(d));
  1084. d.certChain = ssl_pemfile_chain;
  1085. }
  1086. SECStatus rc =
  1087. SSL_ConfigServerCert(hctx->ssl, ssl_pemfile_x509, pkey, data, dlen);
  1088. CERT_DestroyCertificate(ssl_pemfile_x509);
  1089. SECKEY_DestroyPrivateKey(pkey);
  1090. if (ssl_pemfile_chain) CERT_DestroyCertificateList(ssl_pemfile_chain);
  1091. if (hctx->conf.ssl_verifyclient) {
  1092. /*(disable client certificate verification for "acme-tls/1")*/
  1093. hctx->conf.ssl_verifyclient = 0;
  1094. SSL_OptionSet(hctx->ssl, SSL_REQUEST_CERTIFICATE, PR_FALSE);
  1095. SSL_OptionSet(hctx->ssl, SSL_REQUIRE_CERTIFICATE, SSL_REQUIRE_NEVER);
  1096. }
  1097. return rc;
  1098. }
  1099. enum {
  1100. MOD_NSS_ALPN_HTTP11 = 1
  1101. ,MOD_NSS_ALPN_HTTP10 = 2
  1102. ,MOD_NSS_ALPN_H2 = 3
  1103. ,MOD_NSS_ALPN_ACME_TLS_1 = 4
  1104. };
  1105. static SECStatus
  1106. mod_nss_alpn_select_cb (void *arg, PRFileDesc *ssl,
  1107. const unsigned char *protos, unsigned int protosLen,
  1108. unsigned char *protoOut, unsigned int *protoOutLen,
  1109. unsigned int protoMaxOut)
  1110. {
  1111. /* https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids */
  1112. static const SECItem alpn[] = {
  1113. { 0, (unsigned char *)CONST_STR_LEN("h2") }
  1114. ,{ 0, (unsigned char *)CONST_STR_LEN("http/1.1") }
  1115. ,{ 0, (unsigned char *)CONST_STR_LEN("http/1.0") }
  1116. ,{ 0, (unsigned char *)CONST_STR_LEN("acme-tls/1") }
  1117. };
  1118. UNUSED(ssl);
  1119. /* reference: lib/ssl/sslsock.c:ssl_NextProtoNegoCallback() */
  1120. for (unsigned int i = 0; i < protosLen; i += 1 + protos[i]) {
  1121. for (unsigned int j = 0; j < sizeof(alpn)/sizeof(*alpn); ++j) {
  1122. if (protos[i] == alpn[j].len && i+1+protos[i] <= protosLen
  1123. && 0 == PORT_Memcmp(protos+i+1, alpn[j].data, alpn[j].len)) {
  1124. if (protoMaxOut < alpn[j].len) {
  1125. PORT_SetError(SEC_ERROR_OUTPUT_LEN);
  1126. return SECFailure;
  1127. }
  1128. handler_ctx *hctx = arg;
  1129. switch (j) { /*(must match SECItem alpn[] above)*/
  1130. case 0:
  1131. if (!hctx->r->conf.h2proto) continue;
  1132. hctx->alpn = MOD_NSS_ALPN_H2;
  1133. hctx->r->http_version = HTTP_VERSION_2;
  1134. break;
  1135. case 1:
  1136. hctx->alpn = MOD_NSS_ALPN_HTTP11;
  1137. break;
  1138. case 2:
  1139. hctx->alpn = MOD_NSS_ALPN_HTTP10;
  1140. break;
  1141. case 3:
  1142. if (buffer_string_is_empty(hctx->conf.ssl_acme_tls_1))
  1143. continue;
  1144. if (0 == mod_nss_acme_tls_1(hctx))
  1145. hctx->alpn = MOD_NSS_ALPN_ACME_TLS_1;
  1146. else {
  1147. log_error(hctx->r->conf.errh, __FILE__, __LINE__,
  1148. "failed to set acme-tls/1 certificate for TLS"
  1149. " server name %s",hctx->r->uri.authority.ptr);
  1150. return SECFailure;
  1151. }
  1152. break;
  1153. default:
  1154. break;
  1155. }
  1156. memcpy(protoOut, alpn[j].data, alpn[j].len);
  1157. *protoOutLen = alpn[j].len;
  1158. return SECSuccess;
  1159. }
  1160. }
  1161. }
  1162. return SECSuccess;
  1163. }
  1164. static PRInt32
  1165. mod_nss_SNI (PRFileDesc *ssl, const SECItem *srvNameArr, PRUint32 srvNameArrSize,
  1166. void *arg)
  1167. {
  1168. if (0 == srvNameArrSize) /* should not happen */
  1169. return SSL_SNI_CURRENT_CONFIG_IS_USED;
  1170. handler_ctx * const hctx = (handler_ctx *)arg;
  1171. request_st * const r = hctx->r;
  1172. buffer_copy_string(&r->uri.scheme, "https");
  1173. PRUint32 i = 0; /* index into srvNameArr; always take first element */
  1174. const SECItem *sn = srvNameArr+i;
  1175. if (sn->len >= 1024) { /*(expecting < 256; TLSEXT_MAXLEN_host_name is 255)*/
  1176. log_error(r->conf.errh, __FILE__, __LINE__,
  1177. "NSS: SNI name too long %.*s", (int)sn->len,(char *)sn->data);
  1178. return SSL_SNI_SEND_ALERT;
  1179. }
  1180. /* use SNI to patch mod_nss config and then reset COMP_HTTP_HOST */
  1181. buffer_copy_string_len(&r->uri.authority, (const char *)sn->data, sn->len);
  1182. buffer_to_lower(&r->uri.authority);
  1183. #if 0
  1184. /*(r->uri.authority used below for configuration before request read;
  1185. * revisit for h2)*/
  1186. if (0 != http_request_host_policy(&r->uri.authority,
  1187. r->conf.http_parseopts, 443))
  1188. return SSL_SNI_SEND_ALERT;
  1189. #endif
  1190. r->conditional_is_valid |= (1 << COMP_HTTP_SCHEME)
  1191. | (1 << COMP_HTTP_HOST);
  1192. plugin_cert *pc = hctx->conf.pc;
  1193. mod_nss_patch_config(r, &hctx->conf);
  1194. /* reset COMP_HTTP_HOST so that conditions re-run after request hdrs read */
  1195. /*(done in configfile-glue.c:config_cond_cache_reset() after request hdrs read)*/
  1196. /*config_cond_cache_reset_item(r, COMP_HTTP_HOST);*/
  1197. /*buffer_clear(&r->uri.authority);*/
  1198. if (pc == hctx->conf.pc)
  1199. return SSL_SNI_CURRENT_CONFIG_IS_USED;
  1200. /* use NSS deprecated functions to unconfigure an already-configured cert.
  1201. * This is because SSL_ConfigServerCert() will replace an existing cert
  1202. * of the same type, but not if an existing cert is of a different type */
  1203. SSLKEAType certType =
  1204. NSS_FindCertKEAType(hctx->conf.pc->ssl_pemfile_x509);
  1205. SSL_ConfigSecureServerWithCertChain(ssl, NULL, NULL, NULL, certType);
  1206. SECStatus rc =
  1207. SSL_ConfigServerCert(ssl, hctx->conf.pc->ssl_pemfile_x509,
  1208. hctx->conf.pc->ssl_pemfile_pkey,
  1209. &hctx->conf.pc->ssl_credex,
  1210. sizeof(hctx->conf.pc->ssl_credex));
  1211. if (rc < 0) {
  1212. elogf(r->conf.errh, __FILE__, __LINE__,
  1213. "failed to set SNI certificate for TLS server name %s",
  1214. r->uri.authority.ptr);
  1215. return SSL_SNI_SEND_ALERT;
  1216. }
  1217. if (hctx->conf.ssl_verifyclient) {
  1218. /*(XXX: technically do not need to redo if it has not changed)*/
  1219. if (SSL_AuthCertificateHook(ssl, mod_nss_verify_cb, hctx) < 0) {
  1220. elog(r->conf.errh, __FILE__, __LINE__, "SSL_AuthCertificateHook");
  1221. return SSL_SNI_SEND_ALERT;
  1222. }
  1223. CERTCertList * const certList = hctx->conf.ssl_ca_dn_file
  1224. ? hctx->conf.ssl_ca_dn_file
  1225. : hctx->conf.ssl_ca_file;
  1226. if (NULL == certList)
  1227. log_error(hctx->r->conf.errh, __FILE__, __LINE__,
  1228. "NSS: can't verify client without ssl.ca-file "
  1229. "for TLS server name %s",
  1230. hctx->r->uri.authority.ptr); /*(might not be set yet if no SNI)*/
  1231. if (certList && SSL_SetTrustAnchors(ssl, certList) < 0) {
  1232. elog(r->conf.errh, __FILE__, __LINE__, "SSL_SetTrustAnchors");
  1233. return SSL_SNI_SEND_ALERT;
  1234. }
  1235. SSL_OptionSet(ssl, SSL_REQUEST_CERTIFICATE, PR_TRUE);
  1236. SSL_OptionSet(ssl, SSL_REQUIRE_CERTIFICATE,
  1237. hctx->conf.ssl_verifyclient_enforce
  1238. ? SSL_REQUIRE_ALWAYS
  1239. : SSL_REQUIRE_NEVER);
  1240. }
  1241. else {
  1242. SSL_OptionSet(ssl, SSL_REQUEST_CERTIFICATE, PR_FALSE);
  1243. SSL_OptionSet(ssl, SSL_REQUIRE_CERTIFICATE, SSL_REQUIRE_NEVER);
  1244. }
  1245. return (PRInt32)i;
  1246. }
  1247. static int
  1248. mod_nss_ssl_conf_ciphersuites (server *srv, plugin_config_socket *s, buffer *ciphersuites, const buffer *cipherstring);
  1249. static int
  1250. mod_nss_ssl_conf_curves(server *srv, plugin_config_socket *s, const buffer *curvelist);
  1251. static void
  1252. mod_nss_ssl_conf_proto (server *srv, plugin_config_socket *s, const buffer *minb, const buffer *maxb);
  1253. static int
  1254. mod_nss_ssl_conf_cmd (server *srv, plugin_config_socket *s)
  1255. {
  1256. /* reference:
  1257. * https://www.openssl.org/docs/man1.1.1/man3/SSL_CONF_cmd.html */
  1258. int rc = 0;
  1259. buffer *cipherstring = NULL;
  1260. buffer *ciphersuites = NULL;
  1261. buffer *minb = NULL;
  1262. buffer *maxb = NULL;
  1263. buffer *curves = NULL;
  1264. for (size_t i = 0; i < s->ssl_conf_cmd->used; ++i) {
  1265. data_string *ds = (data_string *)s->ssl_conf_cmd->data[i];
  1266. if (buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("CipherString")))
  1267. cipherstring = &ds->value;
  1268. else if (buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("Ciphersuites")))
  1269. ciphersuites = &ds->value;
  1270. else if (buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("Curves"))
  1271. || buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("Groups")))
  1272. curves = &ds->value;
  1273. else if (buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("MaxProtocol")))
  1274. maxb = &ds->value;
  1275. else if (buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("MinProtocol")))
  1276. minb = &ds->value;
  1277. else if (buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("Protocol"))) {
  1278. /* openssl config for Protocol=... is complex and deprecated */
  1279. log_error(srv->errh, __FILE__, __LINE__,
  1280. "NSS: ssl.openssl.ssl-conf-cmd %s ignored; "
  1281. "use MinProtocol=... and MaxProtocol=... instead",
  1282. ds->key.ptr);
  1283. }
  1284. else if (buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("Options"))) {
  1285. for (char *v = ds->value.ptr, *e; *v; v = e) {
  1286. while (*v == ' ' || *v == '\t' || *v == ',') ++v;
  1287. int flag = 1;
  1288. if (*v == '-') {
  1289. flag = 0;
  1290. ++v;
  1291. }
  1292. for (e = v; light_isalpha(*e); ++e) ;
  1293. switch ((int)(e-v)) {
  1294. case 11:
  1295. if (buffer_eq_icase_ssn(v, "Compression", 11)) {
  1296. s->ssl_compression = flag;
  1297. continue;
  1298. }
  1299. break;
  1300. case 13:
  1301. if (buffer_eq_icase_ssn(v, "SessionTicket", 13)) {
  1302. /*(translates to "%NO_TICKETS" priority str if !flag)*/
  1303. s->ssl_session_ticket = flag;
  1304. continue;
  1305. }
  1306. break;
  1307. case 16:
  1308. if (buffer_eq_icase_ssn(v, "ServerPreference", 16)) {
  1309. /*(translates to "%SERVER_PRECEDENCE" priority string)*/
  1310. s->ssl_honor_cipher_order = flag;
  1311. continue;
  1312. }
  1313. break;
  1314. default:
  1315. break;
  1316. }
  1317. /* warn if not explicitly handled or ignored above */
  1318. if (!flag) --v;
  1319. log_error(srv->errh, __FILE__, __LINE__,
  1320. "NSS: ssl.openssl.ssl-conf-cmd Options %.*s "
  1321. "ignored", (int)(e-v), v);
  1322. }
  1323. }
  1324. #if 0
  1325. else if (buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("..."))) {
  1326. }
  1327. #endif
  1328. else {
  1329. /* warn if not explicitly handled or ignored above */
  1330. log_error(srv->errh, __FILE__, __LINE__,
  1331. "NSS: ssl.openssl.ssl-conf-cmd %s ignored",
  1332. ds->key.ptr);
  1333. }
  1334. }
  1335. if (minb || maxb) /*(if at least one was set)*/
  1336. mod_nss_ssl_conf_proto(srv, s, minb, maxb);
  1337. if (!mod_nss_ssl_conf_ciphersuites(srv, s, ciphersuites, cipherstring))
  1338. rc = -1;
  1339. if (curves) {
  1340. if (!mod_nss_ssl_conf_curves(srv, s, curves))
  1341. rc = -1;
  1342. }
  1343. return rc;
  1344. }
  1345. static int
  1346. network_init_ssl (server *srv, plugin_config_socket *s, plugin_data *p)
  1347. {
  1348. UNUSED(p);
  1349. const int disable_sess_cache =
  1350. srv->srvconf.feature_flags
  1351. && !config_plugin_value_tobool(
  1352. array_get_element_klen(srv->srvconf.feature_flags,
  1353. CONST_STR_LEN("ssl.session-cache")), 0);
  1354. if (!disable_sess_cache) /* undo disable from mod_nss_init_once_nss() */
  1355. SSL_OptionSetDefault(SSL_NO_CACHE, PR_FALSE);
  1356. /* use PR_CreateSocketPollFd() for dummy;
  1357. * PR_CreateIOLayerStub() was resulting in crashes
  1358. * when SSL_ImportFD() attempted ssl_DefGetpeername() */
  1359. s->model = PR_CreateSocketPollFd(-1);
  1360. if (NULL == s->model) return -1;
  1361. s->model->methods = PR_GetTCPMethods();
  1362. PRFileDesc *model = SSL_ImportFD(NULL, s->model);
  1363. if (NULL == model) return -1;
  1364. s->model = model;
  1365. if (!buffer_string_is_empty(s->ssl_cipher_list)) {
  1366. if (!mod_nss_ssl_conf_ciphersuites(srv,s,NULL,s->ssl_cipher_list))
  1367. return -1;
  1368. }
  1369. if (!buffer_string_is_empty(s->ssl_ec_curve)) {
  1370. if (!mod_nss_ssl_conf_curves(srv, s, s->ssl_ec_curve))
  1371. return -1;
  1372. }
  1373. if (!s->ssl_use_sslv3 && !s->ssl_use_sslv2)
  1374. mod_nss_ssl_conf_proto(srv, s, NULL, NULL); /* set default range */
  1375. if (s->ssl_conf_cmd && s->ssl_conf_cmd->used) {
  1376. if (0 != mod_nss_ssl_conf_cmd(srv, s)) return -1;
  1377. }
  1378. if (s->ssl_use_sslv3)
  1379. s->protos.min = SSL_LIBRARY_VERSION_3_0;
  1380. if (s->ssl_use_sslv2)
  1381. s->protos.min = SSL_LIBRARY_VERSION_2;
  1382. /* future: add additional configuration of s->model here
  1383. * rather than in mod_nss_handle_con_accept() */
  1384. if (SSL_OptionSet(model, SSL_SECURITY, PR_TRUE) < 0) {
  1385. elog(srv->errh, __FILE__, __LINE__, "SSL_SECURITY");
  1386. return -1;
  1387. }
  1388. if (SSL_VersionRangeSet(model, &s->protos)) {
  1389. elog(srv->errh, __FILE__, __LINE__, "SSL_VersionRangeSet()");
  1390. return -1;
  1391. }
  1392. if (s->protos.min == SSL_LIBRARY_VERSION_2
  1393. && SSL_OptionSet(model, SSL_ENABLE_SSL2, PR_TRUE) < 0) {
  1394. elog(srv->errh, __FILE__, __LINE__, "SSL_ENABLE_SSL2");
  1395. return -1;
  1396. }
  1397. if (s->protos.min == SSL_LIBRARY_VERSION_3_0
  1398. && SSL_OptionSet(model, SSL_ENABLE_SSL3, PR_TRUE) < 0) {
  1399. elog(srv->errh, __FILE__, __LINE__, "SSL_ENABLE_SSL3");
  1400. return -1;
  1401. }
  1402. if (!s->ssl_session_ticket
  1403. && SSL_OptionSet(model, SSL_ENABLE_SESSION_TICKETS, PR_FALSE) < 0) {
  1404. elog(srv->errh, __FILE__, __LINE__, "!SSL_ENABLE_SESSION_TICKETS");
  1405. return -1;
  1406. }
  1407. if (SSL_OptionSet(model, SSL_ENABLE_DEFLATE, s->ssl_compression) < 0) {
  1408. elog(srv->errh, __FILE__, __LINE__, "SSL_ENABLE_DEFLATE");
  1409. return HANDLER_ERROR;
  1410. }
  1411. SSL_OptionSet(model, SSL_REQUEST_CERTIFICATE, PR_FALSE);
  1412. SSL_OptionSet(model, SSL_REQUIRE_CERTIFICATE, SSL_REQUIRE_NEVER);
  1413. SECStatus rc =
  1414. SSL_ConfigServerCert(model, s->pc->ssl_pemfile_x509,
  1415. s->pc->ssl_pemfile_pkey,
  1416. &s->pc->ssl_credex,
  1417. sizeof(s->pc->ssl_credex));
  1418. if (rc < 0) {
  1419. elogf(srv->errh, __FILE__, __LINE__,
  1420. "failed to set default certificate for socket");
  1421. return -1;
  1422. }
  1423. return 0;
  1424. }
  1425. static int
  1426. mod_nss_set_defaults_sockets(server *srv, plugin_data *p)
  1427. {
  1428. static const config_plugin_keys_t cpk[] = {
  1429. { CONST_STR_LEN("ssl.engine"),
  1430. T_CONFIG_BOOL,
  1431. T_CONFIG_SCOPE_CONNECTION }
  1432. ,{ CONST_STR_LEN("ssl.cipher-list"),
  1433. T_CONFIG_STRING,
  1434. T_CONFIG_SCOPE_CONNECTION }
  1435. ,{ CONST_STR_LEN("ssl.honor-cipher-order"),
  1436. T_CONFIG_BOOL,
  1437. T_CONFIG_SCOPE_CONNECTION }
  1438. ,{ CONST_STR_LEN("ssl.dh-file"),
  1439. T_CONFIG_STRING,
  1440. T_CONFIG_SCOPE_CONNECTION }
  1441. ,{ CONST_STR_LEN("ssl.ec-curve"),
  1442. T_CONFIG_STRING,
  1443. T_CONFIG_SCOPE_CONNECTION }
  1444. ,{ CONST_STR_LEN("ssl.openssl.ssl-conf-cmd"),
  1445. T_CONFIG_ARRAY_KVSTRING,
  1446. T_CONFIG_SCOPE_CONNECTION }
  1447. ,{ CONST_STR_LEN("ssl.pemfile"), /* included to process global scope */
  1448. T_CONFIG_STRING,
  1449. T_CONFIG_SCOPE_CONNECTION }
  1450. ,{ CONST_STR_LEN("ssl.empty-fragments"),
  1451. T_CONFIG_BOOL,
  1452. T_CONFIG_SCOPE_CONNECTION }
  1453. ,{ CONST_STR_LEN("ssl.use-sslv2"),
  1454. T_CONFIG_BOOL,
  1455. T_CONFIG_SCOPE_CONNECTION }
  1456. ,{ CONST_STR_LEN("ssl.use-sslv3"),
  1457. T_CONFIG_BOOL,
  1458. T_CONFIG_SCOPE_CONNECTION }
  1459. ,{ CONST_STR_LEN("ssl.stek-file"),
  1460. T_CONFIG_STRING,
  1461. T_CONFIG_SCOPE_SERVER }
  1462. ,{ NULL, 0,
  1463. T_CONFIG_UNSET,
  1464. T_CONFIG_SCOPE_UNSET }
  1465. };
  1466. static const buffer default_ssl_cipher_list = { CONST_STR_LEN("HIGH"), 0 };
  1467. p->ssl_ctxs = calloc(srv->config_context->used, sizeof(plugin_ssl_ctx));
  1468. force_assert(p->ssl_ctxs);
  1469. int rc = HANDLER_GO_ON;
  1470. plugin_data_base srvplug;
  1471. memset(&srvplug, 0, sizeof(srvplug));
  1472. plugin_data_base * const ps = &srvplug;
  1473. if (!config_plugin_values_init(srv, ps, cpk, "mod_nss"))
  1474. return HANDLER_ERROR;
  1475. plugin_config_socket defaults;
  1476. memset(&defaults, 0, sizeof(defaults));
  1477. defaults.ssl_honor_cipher_order = 1; /* default server preference for PFS */
  1478. defaults.ssl_session_ticket = 1; /* enabled by default */
  1479. defaults.ssl_compression = 0; /* disable for security */
  1480. defaults.ssl_cipher_list = &default_ssl_cipher_list;
  1481. /* process and validate config directives for global and $SERVER["socket"]
  1482. * (init i to 0 if global context; to 1 to skip empty global context) */
  1483. for (int i = !ps->cvlist[0].v.u2[1]; i < ps->nconfig; ++i) {
  1484. config_cond_info cfginfo;
  1485. config_get_config_cond_info(&cfginfo, (uint32_t)ps->cvlist[i].k_id);
  1486. int is_socket_scope = (0 == i || cfginfo.comp == COMP_SERVER_SOCKET);
  1487. int count_not_engine = 0;
  1488. plugin_config_socket conf;
  1489. memcpy(&conf, &defaults, sizeof(conf));
  1490. /*(preserve prior behavior; not inherited)*/
  1491. /*(forcing inheritance might break existing configs where SSL is enabled
  1492. * by default in the global scope, but not $SERVER["socket"]=="*:80") */
  1493. conf.ssl_enabled = 0;
  1494. config_plugin_value_t *cpv = ps->cvlist + ps->cvlist[i].v.u2[0];
  1495. for (; -1 != cpv->k_id; ++cpv) {
  1496. /* ignore ssl.pemfile (k_id=10); included to process global scope */
  1497. if (!is_socket_scope && cpv->k_id != 10) {
  1498. log_error(srv->errh, __FILE__, __LINE__,
  1499. "NSS: %s is valid only in global scope or "
  1500. "$SERVER[\"socket\"] condition", cpk[cpv->k_id].k);
  1501. continue;
  1502. }
  1503. ++count_not_engine;
  1504. switch (cpv->k_id) {
  1505. case 0: /* ssl.engine */
  1506. conf.ssl_enabled = (0 != cpv->v.u);
  1507. --count_not_engine;
  1508. break;
  1509. case 1: /* ssl.cipher-list */
  1510. conf.ssl_cipher_list = cpv->v.b;
  1511. break;
  1512. case 2: /* ssl.honor-cipher-order */
  1513. conf.ssl_honor_cipher_order = (0 != cpv->v.u);
  1514. break;
  1515. case 3: /* ssl.dh-file */
  1516. log_error(srv->errh, __FILE__, __LINE__,
  1517. "NSS: ignoring ssl.dh-file; not implemented"
  1518. "obsoleted by RFC7919");
  1519. break;
  1520. case 4: /* ssl.ec-curve */
  1521. conf.ssl_ec_curve = cpv->v.b;
  1522. break;
  1523. case 5: /* ssl.openssl.ssl-conf-cmd */
  1524. *(const array **)&conf.ssl_conf_cmd = cpv->v.a;
  1525. break;
  1526. case 6: /* ssl.pemfile */
  1527. /* ignore here; included to process global scope when
  1528. * ssl.pemfile is set, but ssl.engine is not "enable" */
  1529. break;
  1530. case 7: /* ssl.empty-fragments */
  1531. conf.ssl_empty_fragments = (0 != cpv->v.u);
  1532. log_error(srv->errh, __FILE__, __LINE__,
  1533. "NSS: ignoring ssl.empty-fragments; openssl-specific "
  1534. "counter-measure against a SSL 3.0/TLS 1.0 protocol "
  1535. "vulnerability affecting CBC ciphers, which cannot be handled"
  1536. " by some broken (Microsoft) SSL implementations.");
  1537. break;
  1538. case 8: /* ssl.use-sslv2 */
  1539. conf.ssl_use_sslv2 = (0 != cpv->v.u);
  1540. log_error(srv->errh, __FILE__, __LINE__, "NSS: "
  1541. "ssl.use-sslv2 is deprecated and will soon be removed. "
  1542. "Many modern TLS libraries no longer support SSLv2.");
  1543. break;
  1544. case 9: /* ssl.use-sslv3 */
  1545. conf.ssl_use_sslv3 = (0 != cpv->v.u);
  1546. log_error(srv->errh, __FILE__, __LINE__, "NSS: "
  1547. "ssl.use-sslv3 is deprecated and will soon be removed. "
  1548. "Many modern TLS libraries no longer support SSLv3. "
  1549. "If needed, use: "
  1550. "ssl.openssl.ssl-conf-cmd = (\"MinProtocol\" => \"SSLv3\")");
  1551. break;
  1552. case 10:/* ssl.stek-file */
  1553. log_error(srv->errh, __FILE__, __LINE__, "NSS: "
  1554. "ssl.stek-file is not supported in mod_nss; ignoring.");
  1555. break;
  1556. default:/* should not happen */
  1557. break;
  1558. }
  1559. }
  1560. if (HANDLER_GO_ON != rc) break;
  1561. if (0 == i) memcpy(&defaults, &conf, sizeof(conf));
  1562. if (0 != i && !conf.ssl_enabled) continue;
  1563. /* fill plugin_config_socket with global context then $SERVER["socket"]
  1564. * only for directives directly in current $SERVER["socket"] condition*/
  1565. /*conf.pc = p->defaults.pc;*/
  1566. conf.ssl_verifyclient = p->defaults.ssl_verifyclient;
  1567. conf.ssl_verifyclient_enforce = p->defaults.ssl_verifyclient_enforce;
  1568. conf.ssl_verifyclient_depth = p->defaults.ssl_verifyclient_depth;
  1569. int sidx = ps->cvlist[i].k_id;
  1570. for (int j = !p->cvlist[0].v.u2[1]; j < p->nconfig; ++j) {
  1571. if (p->cvlist[j].k_id != sidx) continue;
  1572. /*if (0 == sidx) break;*//*(repeat to get ssl_pemfile,ssl_privkey)*/
  1573. cpv = p->cvlist + p->cvlist[j].v.u2[0];
  1574. for (; -1 != cpv->k_id; ++cpv) {
  1575. ++count_not_engine;
  1576. switch (cpv->k_id) {
  1577. case 0: /* ssl.pemfile */
  1578. if (cpv->vtype == T_CONFIG_LOCAL)
  1579. conf.pc = cpv->v.v;
  1580. break;
  1581. case 7: /* ssl.verifyclient.activate */
  1582. conf.ssl_verifyclient = (0 != cpv->v.u);
  1583. break;
  1584. case 8: /* ssl.verifyclient.enforce */
  1585. conf.ssl_verifyclient_enforce = (0 != cpv->v.u);
  1586. break;
  1587. case 9: /* ssl.verifyclient.depth */
  1588. conf.ssl_verifyclient_depth = (unsigned char)cpv->v.shrt;
  1589. break;
  1590. default:
  1591. break;
  1592. }
  1593. }
  1594. break;
  1595. }
  1596. if (NULL == conf.pc) {
  1597. if (0 == i && !conf.ssl_enabled) continue;
  1598. if (0 != i) {
  1599. /* inherit ssl settings from global scope
  1600. * (if only ssl.engine = "enable" and no other ssl.* settings)
  1601. * (This is for convenience when defining both IPv4 and IPv6
  1602. * and desiring to inherit the ssl config from global context
  1603. * without having to duplicate the directives)*/
  1604. if (count_not_engine
  1605. || (conf.ssl_enabled && NULL == p->ssl_ctxs[0].model)) {
  1606. log_error(srv->errh, __FILE__, __LINE__,
  1607. "NSS: ssl.pemfile has to be set in same "
  1608. "$SERVER[\"socket\"] scope as other ssl.* directives, "
  1609. "unless only ssl.engine is set, inheriting ssl.* from "
  1610. "global scope");
  1611. rc = HANDLER_ERROR;
  1612. continue;
  1613. }
  1614. plugin_ssl_ctx * const s = p->ssl_ctxs + sidx;
  1615. *s = *p->ssl_ctxs;/*(copy struct of ssl_ctx from global scope)*/
  1616. continue;
  1617. }
  1618. /* PEM file is required */
  1619. log_error(srv->errh, __FILE__, __LINE__,
  1620. "NSS: ssl.pemfile has to be set when ssl.engine = \"enable\"");
  1621. rc = HANDLER_ERROR;
  1622. continue;
  1623. }
  1624. /* (initialize once if module enabled) */
  1625. if (!mod_nss_init_once_nss()) {
  1626. rc = HANDLER_ERROR;
  1627. break;
  1628. }
  1629. /* configure ssl_ctx for socket */
  1630. /*conf.ssl_ctx = NULL;*//*(filled by network_init_ssl() even on error)*/
  1631. if (0 == network_init_ssl(srv, &conf, p)) {
  1632. plugin_ssl_ctx * const s = p->ssl_ctxs + sidx;
  1633. s->model = conf.model;
  1634. s->protos = conf.protos;
  1635. s->ssl_compression = conf.ssl_compression;
  1636. s->ssl_session_ticket = conf.ssl_session_ticket;
  1637. }
  1638. else {
  1639. if (conf.model) PR_Close(conf.model);
  1640. rc = HANDLER_ERROR;
  1641. }
  1642. }
  1643. free(srvplug.cvlist);
  1644. return rc;
  1645. }
  1646. SETDEFAULTS_FUNC(mod_nss_set_defaults)
  1647. {
  1648. static const config_plugin_keys_t cpk[] = {
  1649. { CONST_STR_LEN("ssl.pemfile"),
  1650. T_CONFIG_STRING,
  1651. T_CONFIG_SCOPE_CONNECTION }
  1652. ,{ CONST_STR_LEN("ssl.privkey"),
  1653. T_CONFIG_STRING,
  1654. T_CONFIG_SCOPE_CONNECTION }
  1655. ,{ CONST_STR_LEN("ssl.ca-file"),
  1656. T_CONFIG_STRING,
  1657. T_CONFIG_SCOPE_CONNECTION }
  1658. ,{ CONST_STR_LEN("ssl.ca-dn-file"),
  1659. T_CONFIG_STRING,
  1660. T_CONFIG_SCOPE_CONNECTION }
  1661. ,{ CONST_STR_LEN("ssl.ca-crl-file"),
  1662. T_CONFIG_STRING,
  1663. T_CONFIG_SCOPE_CONNECTION }
  1664. ,{ CONST_STR_LEN("ssl.read-ahead"),
  1665. T_CONFIG_BOOL,
  1666. T_CONFIG_SCOPE_CONNECTION }
  1667. ,{ CONST_STR_LEN("ssl.disable-client-renegotiation"),
  1668. T_CONFIG_BOOL,
  1669. T_CONFIG_SCOPE_CONNECTION }
  1670. ,{ CONST_STR_LEN("ssl.verifyclient.activate"),
  1671. T_CONFIG_BOOL,
  1672. T_CONFIG_SCOPE_CONNECTION }
  1673. ,{ CONST_STR_LEN("ssl.verifyclient.enforce"),
  1674. T_CONFIG_BOOL,
  1675. T_CONFIG_SCOPE_CONNECTION }
  1676. ,{ CONST_STR_LEN("ssl.verifyclient.depth"),
  1677. T_CONFIG_SHORT,
  1678. T_CONFIG_SCOPE_CONNECTION }
  1679. ,{ CONST_STR_LEN("ssl.verifyclient.username"),
  1680. T_CONFIG_STRING,
  1681. T_CONFIG_SCOPE_CONNECTION }
  1682. ,{ CONST_STR_LEN("ssl.verifyclient.exportcert"),
  1683. T_CONFIG_BOOL,
  1684. T_CONFIG_SCOPE_CONNECTION }
  1685. ,{ CONST_STR_LEN("ssl.acme-tls-1"),
  1686. T_CONFIG_STRING,
  1687. T_CONFIG_SCOPE_CONNECTION }
  1688. ,{ CONST_STR_LEN("ssl.stapling-file"),
  1689. T_CONFIG_STRING,
  1690. T_CONFIG_SCOPE_CONNECTION }
  1691. ,{ CONST_STR_LEN("debug.log-ssl-noise"),
  1692. T_CONFIG_SHORT,
  1693. T_CONFIG_SCOPE_CONNECTION }
  1694. ,{ NULL, 0,
  1695. T_CONFIG_UNSET,
  1696. T_CONFIG_SCOPE_UNSET }
  1697. };
  1698. plugin_data * const p = p_d;
  1699. p->srv = srv;
  1700. if (!config_plugin_values_init(srv, p, cpk, "mod_nss"))
  1701. return HANDLER_ERROR;
  1702. /* process and validate config directives
  1703. * (init i to 0 if global context; to 1 to skip empty global context) */
  1704. for (int i = !p->cvlist[0].v.u2[1]; i < p->nconfig; ++i) {
  1705. config_plugin_value_t *cpv = p->cvlist + p->cvlist[i].v.u2[0];
  1706. config_plugin_value_t *pemfile = NULL;
  1707. config_plugin_value_t *privkey = NULL;
  1708. const buffer *ssl_stapling_file = NULL;
  1709. for (; -1 != cpv->k_id; ++cpv) {
  1710. switch (cpv->k_id) {
  1711. case 0: /* ssl.pemfile */
  1712. if (!buffer_string_is_empty(cpv->v.b)) pemfile = cpv;
  1713. break;
  1714. case 1: /* ssl.privkey */
  1715. if (!buffer_string_is_empty(cpv->v.b)) privkey = cpv;
  1716. break;
  1717. case 2: /* ssl.ca-file */
  1718. if (!buffer_string_is_empty(cpv->v.b)) {
  1719. CERTCertList *d =
  1720. mod_nss_load_config_crts(cpv->v.b->ptr, srv->errh);
  1721. if (d != NULL) {
  1722. cpv->vtype = T_CONFIG_LOCAL;
  1723. cpv->v.v = d;
  1724. }
  1725. else {
  1726. log_error(srv->errh, __FILE__, __LINE__,
  1727. "%s = %s", cpk[cpv->k_id].k, cpv->v.b->ptr);
  1728. return HANDLER_ERROR;
  1729. }
  1730. }
  1731. break;
  1732. case 3: /* ssl.ca-dn-file */
  1733. if (!buffer_string_is_empty(cpv->v.b)) {
  1734. CERTCertList *d =
  1735. mod_nss_load_config_dncrts(cpv->v.b->ptr, srv->errh);
  1736. if (d != NULL) {
  1737. cpv->vtype = T_CONFIG_LOCAL;
  1738. cpv->v.v = d;
  1739. }
  1740. else {
  1741. log_error(srv->errh, __FILE__, __LINE__,
  1742. "%s = %s", cpk[cpv->k_id].k, cpv->v.b->ptr);
  1743. return HANDLER_ERROR;
  1744. }
  1745. }
  1746. break;
  1747. case 4: /* ssl.ca-crl-file */
  1748. if (!buffer_string_is_empty(cpv->v.b)) {
  1749. CERTCertificateList *d =
  1750. mod_nss_load_config_crls(cpv->v.b->ptr, srv->errh);
  1751. if (d != NULL) {
  1752. cpv->vtype = T_CONFIG_LOCAL;
  1753. cpv->v.v = d;
  1754. }
  1755. else {
  1756. log_error(srv->errh, __FILE__, __LINE__,
  1757. "%s = %s", cpk[cpv->k_id].k, cpv->v.b->ptr);
  1758. return HANDLER_ERROR;
  1759. }
  1760. }
  1761. break;
  1762. case 5: /* ssl.read-ahead */
  1763. case 6: /* ssl.disable-client-renegotiation */
  1764. case 7: /* ssl.verifyclient.activate */
  1765. case 8: /* ssl.verifyclient.enforce */
  1766. break;
  1767. case 9: /* ssl.verifyclient.depth */
  1768. if (cpv->v.shrt > 255) {
  1769. log_error(srv->errh, __FILE__, __LINE__,
  1770. "NSS: %s is absurdly large (%hu); limiting to 255",
  1771. cpk[cpv->k_id].k, cpv->v.shrt);
  1772. cpv->v.shrt = 255;
  1773. }
  1774. break;
  1775. case 10:/* ssl.verifyclient.username */
  1776. case 11:/* ssl.verifyclient.exportcert */
  1777. case 12:/* ssl.acme-tls-1 */
  1778. break;
  1779. case 13:/* ssl.stapling-file */
  1780. ssl_stapling_file = cpv->v.b;
  1781. break;
  1782. case 14:/* debug.log-ssl-noise */
  1783. break;
  1784. default:/* should not happen */
  1785. break;
  1786. }
  1787. }
  1788. if (pemfile) {
  1789. if (NULL == privkey) privkey = pemfile;
  1790. pemfile->v.v =
  1791. network_nss_load_pemfile(srv, pemfile->v.b, privkey->v.b,
  1792. ssl_stapling_file);
  1793. if (pemfile->v.v)
  1794. pemfile->vtype = T_CONFIG_LOCAL;
  1795. else
  1796. return HANDLER_ERROR;
  1797. }
  1798. }
  1799. p->defaults.ssl_verifyclient = 0;
  1800. p->defaults.ssl_verifyclient_enforce = 1;
  1801. p->defaults.ssl_verifyclient_depth = 9;
  1802. p->defaults.ssl_verifyclient_export_cert = 0;
  1803. p->defaults.ssl_disable_client_renegotiation = 1;
  1804. p->defaults.ssl_read_ahead = 0;
  1805. /* initialize p->defaults from global config context */
  1806. if (p->nconfig > 0 && p->cvlist->v.u2[1]) {
  1807. const config_plugin_value_t *cpv = p->cvlist + p->cvlist->v.u2[0];
  1808. if (-1 != cpv->k_id)
  1809. mod_nss_merge_config(&p->defaults, cpv);
  1810. }
  1811. return mod_nss_set_defaults_sockets(srv, p);
  1812. }
  1813. /* local_send_buffer is a static buffer of size (LOCAL_SEND_BUFSIZE)
  1814. *
  1815. * buffer is allocated once, is NOT realloced (note: not thread-safe)
  1816. * */
  1817. /* copy small mem chunks into single large buffer
  1818. * before PR_Write() to reduce number times write() called
  1819. * underneath PR_Write() and potentially reduce number of packets
  1820. * generated if TCP_NODELAY */
  1821. __attribute_cold__
  1822. static int
  1823. mod_nss_write_err(connection *con, handler_ctx *hctx, size_t wr_len)
  1824. {
  1825. switch (PR_GetError()) {
  1826. case PR_WOULD_BLOCK_ERROR:
  1827. case PR_PENDING_INTERRUPT_ERROR:
  1828. con->is_writable = -1;
  1829. /* XXX: not handled: protocol might be blocked waiting on read */
  1830. /*if (0) con->is_readable = -1;*/
  1831. break; /* try again later */
  1832. case PR_CONNECT_RESET_ERROR:
  1833. if (!hctx->conf.ssl_log_noise) return -1;
  1834. __attribute_fallthrough__
  1835. default:
  1836. elog(hctx->r->conf.errh, __FILE__, __LINE__, __func__);
  1837. return -1;
  1838. }
  1839. /* partial write; save attempted wr_len */
  1840. hctx->pending_write = wr_len;
  1841. return 0; /* try again later */
  1842. }
  1843. __attribute_cold__
  1844. static int
  1845. mod_nss_read_err(connection *con, handler_ctx *hctx)
  1846. {
  1847. switch (PR_GetError()) {
  1848. case PR_WOULD_BLOCK_ERROR:
  1849. case PR_PENDING_INTERRUPT_ERROR:
  1850. /* XXX: not handled: protocol might be blocked waiting on write */
  1851. /*if (0) con->is_writable = -1;*/
  1852. con->is_readable = 0;
  1853. return 0;
  1854. case PR_CONNECT_ABORTED_ERROR:
  1855. case PR_CONNECT_RESET_ERROR:
  1856. if (!hctx->conf.ssl_log_noise) return -1;
  1857. __attribute_fallthrough__
  1858. default:
  1859. elog(hctx->errh, __FILE__, __LINE__, __func__);
  1860. return -1;
  1861. }
  1862. }
  1863. static int
  1864. mod_nss_close_notify(handler_ctx *hctx);
  1865. static int
  1866. connection_write_cq_ssl (connection *con, chunkqueue *cq, off_t max_bytes)
  1867. {
  1868. handler_ctx *hctx = con->plugin_ctx[plugin_data_singleton->id];
  1869. PRFileDesc *ssl = hctx->ssl;
  1870. log_error_st * const errh = hctx->errh;
  1871. if (0 != hctx->close_notify) return mod_nss_close_notify(hctx);
  1872. chunkqueue_remove_finished_chunks(cq);
  1873. /* future: for efficiency/performance might consider using NSS
  1874. * PR_Writev() PR_TransmitFile() PR_SendFile()
  1875. */
  1876. while (max_bytes > 0 && !chunkqueue_is_empty(cq)) {
  1877. char *data = local_send_buffer;
  1878. uint32_t data_len = LOCAL_SEND_BUFSIZE < max_bytes
  1879. ? LOCAL_SEND_BUFSIZE
  1880. : (uint32_t)max_bytes;
  1881. int wr;
  1882. if (0 != chunkqueue_peek_data(cq, &data, &data_len, errh)) return -1;
  1883. /*(if partial write occurred, expect that subsequent writes will have
  1884. * at least that much data available from chunkqueue_peek_data(), which
  1885. * is what should happen, but is not checked here)*/
  1886. size_t lim = hctx->pending_write;
  1887. if (lim && data_len > lim) data_len = lim;
  1888. hctx->pending_write = 0;
  1889. /*
  1890. * XXX: above comments modified from mod_mbedtls; should be verified
  1891. */
  1892. int wr_total = 0;
  1893. do {
  1894. size_t wr_len = data_len;
  1895. wr = PR_Write(ssl, data, (PRInt32)wr_len);
  1896. if (wr <= 0) {
  1897. if (wr_total) chunkqueue_mark_written(cq, wr_total);
  1898. return mod_nss_write_err(con, hctx, wr_len);
  1899. }
  1900. wr_total += wr;
  1901. data += wr;
  1902. } while ((data_len -= wr));
  1903. chunkqueue_mark_written(cq, wr_total);
  1904. max_bytes -= wr_total;
  1905. }
  1906. return 0;
  1907. }
  1908. static void
  1909. mod_nss_SSLHandshakeCallback (PRFileDesc *fd, void *arg)
  1910. {
  1911. UNUSED(fd);
  1912. handler_ctx *hctx = arg;
  1913. hctx->handshake = 1;
  1914. }
  1915. static int
  1916. connection_read_cq_ssl (connection *con, chunkqueue *cq, off_t max_bytes)
  1917. {
  1918. handler_ctx *hctx = con->plugin_ctx[plugin_data_singleton->id];
  1919. UNUSED(max_bytes);
  1920. if (0 != hctx->close_notify) return mod_nss_close_notify(hctx);
  1921. PRFileDesc *ssl = hctx->ssl;
  1922. ssize_t len;
  1923. char *mem = NULL;
  1924. size_t mem_len = 0;
  1925. do {
  1926. int pend = SSL_DataPending(ssl);
  1927. if (pend < 0) {
  1928. len = pend;
  1929. break;
  1930. }
  1931. mem_len = pend < 2048 ? 2048 : (uint32_t)pend;
  1932. chunk * const ckpt = cq->last;
  1933. mem = chunkqueue_get_memory(cq, &mem_len);
  1934. len = PR_Read(ssl, mem, (PRInt32)mem_len);
  1935. if (len > 0) {
  1936. chunkqueue_use_memory(cq, ckpt, len);
  1937. con->bytes_read += len;
  1938. } else {
  1939. chunkqueue_use_memory(cq, ckpt, 0);
  1940. }
  1941. } while (len > 0);
  1942. if (hctx->alpn && hctx->handshake) {
  1943. if (hctx->alpn == MOD_NSS_ALPN_ACME_TLS_1) {
  1944. /* Once TLS handshake is complete, return -1 to result in
  1945. * CON_STATE_ERROR so that socket connection is quickly closed */
  1946. return -1;
  1947. }
  1948. hctx->alpn = 0;
  1949. }
  1950. if (len < 0) {
  1951. return mod_nss_read_err(con, hctx);
  1952. } else if (len == 0) {
  1953. con->is_readable = 0;
  1954. /* the other end closed the connection -> KEEP-ALIVE */
  1955. return -2;
  1956. } else {
  1957. return 0;
  1958. }
  1959. }
  1960. CONNECTION_FUNC(mod_nss_handle_con_accept)
  1961. {
  1962. server_socket *srv_sock = con->srv_socket;
  1963. if (!srv_sock->is_ssl) return HANDLER_GO_ON;
  1964. plugin_data *p = p_d;
  1965. handler_ctx * const hctx = handler_ctx_init();
  1966. request_st * const r = &con->request;
  1967. hctx->r = r;
  1968. hctx->con = con;
  1969. hctx->tmp_buf = con->srv->tmp_buf;
  1970. hctx->errh = r->conf.errh;
  1971. con->plugin_ctx[p->id] = hctx;
  1972. plugin_ssl_ctx * const s = p->ssl_ctxs + srv_sock->sidx;
  1973. hctx->ssl_session_ticket = s->ssl_session_ticket;
  1974. con->network_read = connection_read_cq_ssl;
  1975. con->network_write = connection_write_cq_ssl;
  1976. con->proto_default_port = 443; /* "https" */
  1977. mod_nss_patch_config(r, &hctx->conf);
  1978. hctx->ssl = mod_nss_io_ctor(con->fd, s->model, r->conf.errh);
  1979. if (NULL == hctx->ssl)
  1980. return HANDLER_ERROR;
  1981. /* future: move more config from here to config model in network_init_ssl().
  1982. * Callbacks need to be set here to be able to set callback arg to hctx */
  1983. if (!hctx->conf.ssl_disable_client_renegotiation
  1984. && SSL_OptionSet(hctx->ssl, SSL_ENABLE_RENEGOTIATION,
  1985. SSL_RENEGOTIATE_REQUIRES_XTN) < 0) {
  1986. elog(r->conf.errh, __FILE__, __LINE__, "SSL_ENABLE_RENEGOTIATION");
  1987. return HANDLER_ERROR;
  1988. }
  1989. if (SSL_ResetHandshake(hctx->ssl, PR_TRUE) < 0) {
  1990. elog(r->conf.errh, __FILE__, __LINE__, "SSL_ResetHandshake()");
  1991. return HANDLER_ERROR;
  1992. }
  1993. if (SSL_HandshakeCallback(hctx->ssl, mod_nss_SSLHandshakeCallback, hctx)<0){
  1994. elog(r->conf.errh, __FILE__, __LINE__, "SSL_HandshakeCallback()");
  1995. return HANDLER_ERROR;
  1996. }
  1997. if (SSL_SNISocketConfigHook(hctx->ssl, mod_nss_SNI, hctx) < 0) {
  1998. elog(r->conf.errh, __FILE__, __LINE__, "SSL_SNISocketConfigHook()");
  1999. return HANDLER_ERROR;
  2000. }
  2001. if (SSL_SetNextProtoCallback(hctx->ssl, mod_nss_alpn_select_cb, hctx) < 0) {
  2002. elog(r->conf.errh, __FILE__, __LINE__, "SSL_SetNextProtoCallback()");
  2003. return HANDLER_ERROR;
  2004. }
  2005. hctx->verify_status = -1;
  2006. if (hctx->conf.ssl_verifyclient) {
  2007. if (SSL_AuthCertificateHook(hctx->ssl, mod_nss_verify_cb, hctx) < 0) {
  2008. elog(r->conf.errh, __FILE__, __LINE__, "SSL_AuthCertificateHook()");
  2009. return HANDLER_ERROR;
  2010. }
  2011. CERTCertList * const certList = hctx->conf.ssl_ca_dn_file
  2012. ? hctx->conf.ssl_ca_dn_file
  2013. : hctx->conf.ssl_ca_file;
  2014. if (NULL == certList)
  2015. log_error(hctx->r->conf.errh, __FILE__, __LINE__,
  2016. "NSS: can't verify client without ssl.ca-file "
  2017. "for TLS server name %s",
  2018. hctx->r->uri.authority.ptr); /*(might not be set yet if no SNI)*/
  2019. if (certList && SSL_SetTrustAnchors(hctx->ssl, certList) < 0) {
  2020. elog(r->conf.errh, __FILE__, __LINE__, "SSL_SetTrustAnchors()");
  2021. return HANDLER_ERROR;
  2022. }
  2023. SSL_OptionSet(hctx->ssl, SSL_REQUEST_CERTIFICATE, PR_TRUE);
  2024. SSL_OptionSet(hctx->ssl, SSL_REQUIRE_CERTIFICATE,
  2025. hctx->conf.ssl_verifyclient_enforce
  2026. ? SSL_REQUIRE_ALWAYS
  2027. : SSL_REQUIRE_NEVER);
  2028. }
  2029. else {
  2030. SSL_OptionSet(hctx->ssl, SSL_REQUEST_CERTIFICATE, PR_FALSE);
  2031. SSL_OptionSet(hctx->ssl, SSL_REQUIRE_CERTIFICATE, SSL_REQUIRE_NEVER);
  2032. }
  2033. return HANDLER_GO_ON;
  2034. }
  2035. static void
  2036. mod_nss_detach(handler_ctx *hctx)
  2037. {
  2038. /* step aside from further SSL processing
  2039. * (note: additional data might be buffered/discarded by this layer)
  2040. * (used after handle_connection_shut_wr hook) */
  2041. /* future: might restore prior network_read and network_write fn ptrs */
  2042. mod_nss_io_detach(hctx->ssl);
  2043. hctx->con->is_ssl_sock = 0;
  2044. /* if called after handle_connection_shut_wr hook, shutdown SHUT_WR */
  2045. if (-1 == hctx->close_notify) shutdown(hctx->con->fd, SHUT_WR);
  2046. hctx->close_notify = 1;
  2047. }
  2048. CONNECTION_FUNC(mod_nss_handle_con_shut_wr)
  2049. {
  2050. plugin_data *p = p_d;
  2051. handler_ctx *hctx = con->plugin_ctx[p->id];
  2052. if (NULL == hctx) return HANDLER_GO_ON;
  2053. hctx->close_notify = -2;
  2054. if (hctx->handshake) {
  2055. mod_nss_close_notify(hctx);
  2056. }
  2057. else {
  2058. mod_nss_detach(hctx);
  2059. }
  2060. return HANDLER_GO_ON;
  2061. }
  2062. static int
  2063. mod_nss_close_notify (handler_ctx *hctx)
  2064. {
  2065. if (1 == hctx->close_notify) return -2;
  2066. /* note: this sends close_notify TLS alert and calls shutdown() on fd */
  2067. switch (PR_Shutdown(hctx->ssl, PR_SHUTDOWN_SEND)) {
  2068. case PR_SUCCESS:
  2069. mod_nss_detach(hctx);
  2070. return -2;
  2071. case PR_FAILURE:
  2072. default:
  2073. if (PR_GetError() != PR_NOT_CONNECTED_ERROR)
  2074. elog(hctx->r->conf.errh, __FILE__, __LINE__, "PR_Shutdown()");
  2075. mod_nss_detach(hctx);
  2076. return -1;
  2077. }
  2078. }
  2079. CONNECTION_FUNC(mod_nss_handle_con_close)
  2080. {
  2081. plugin_data *p = p_d;
  2082. handler_ctx *hctx = con->plugin_ctx[p->id];
  2083. if (NULL != hctx) {
  2084. con->plugin_ctx[p->id] = NULL;
  2085. if (1 != hctx->close_notify)
  2086. mod_nss_close_notify(hctx); /*(one final try)*/
  2087. handler_ctx_free(hctx);
  2088. }
  2089. return HANDLER_GO_ON;
  2090. }
  2091. __attribute_noinline__
  2092. static void
  2093. https_add_ssl_client_cert (request_st * const r, CERTCertificate *peer)
  2094. {
  2095. char *pem = NSSBase64_EncodeItem(NULL, NULL, 0, &peer->derCert);
  2096. if (NULL == pem) return;
  2097. uint32_t len = 0;
  2098. for (uint32_t i = 0; pem[i]; ++i) {
  2099. if (pem[i] != '\r') pem[len++] = pem[i]; /*(translate \r\n to \n)*/
  2100. }
  2101. buffer * const tb = r->tmp_buf;
  2102. buffer_copy_string_len(tb, CONST_STR_LEN(PEM_BEGIN_CERT"\n"));
  2103. buffer_append_string_len(tb, pem, len);
  2104. buffer_append_string_len(tb,CONST_STR_LEN("\n"PEM_END_CERT"\n"));
  2105. http_header_env_set(r, CONST_STR_LEN("SSL_CLIENT_CERT"), CONST_BUF_LEN(tb));
  2106. PORT_Free(pem);
  2107. }
  2108. static void
  2109. https_add_ssl_client_subject (request_st * const r, CERTName * const subj)
  2110. {
  2111. /* add components of client Subject DN */
  2112. /* not complete list; NSS does not expose enough of lib/certdb/alg1485.c
  2113. * for friendly names, though we could consider using CERT_GetOidString()
  2114. * and CERT_RFC1485_EscapeAndQuote() */
  2115. static const
  2116. struct { const char *tag; uint32_t tlen; char *(*fn)(const CERTName *); }
  2117. comp[] = {
  2118. { CONST_STR_LEN("CN"), CERT_GetCommonName },
  2119. { CONST_STR_LEN("ST"), CERT_GetStateName },
  2120. { CONST_STR_LEN("O"), CERT_GetOrgName },
  2121. { CONST_STR_LEN("OU"), CERT_GetOrgUnitName },
  2122. { CONST_STR_LEN("C"), CERT_GetCountryName },
  2123. { CONST_STR_LEN("L"), CERT_GetLocalityName },
  2124. { CONST_STR_LEN("UID"), CERT_GetCertUid },
  2125. { CONST_STR_LEN("emailAddress"), CERT_GetCertEmailAddress },
  2126. { CONST_STR_LEN("DC"), CERT_GetDomainComponentName },
  2127. };
  2128. buffer * const tb = r->tmp_buf;
  2129. buffer_copy_string_len(tb, CONST_STR_LEN("SSL_CLIENT_S_DN_"));
  2130. for (uint32_t i = 0; i < sizeof(comp)/sizeof(*comp); ++i) {
  2131. char *s = comp[i].fn(subj);
  2132. if (NULL == s) continue;
  2133. unsigned int n;
  2134. unsigned char c;
  2135. for (n = 0; (c = ((unsigned char *)s)[n]); ++n) {
  2136. if (c < 32 || c == 127 || (c > 128 && c < 160)) s[n] = '?';
  2137. }
  2138. buffer_string_set_length(tb, sizeof("SSL_CLIENT_S_DN_")-1);
  2139. buffer_append_string_len(tb, comp[i].tag, comp[i].tlen);
  2140. http_header_env_set(r, CONST_BUF_LEN(tb), s, n);
  2141. PR_Free(s);
  2142. }
  2143. }
  2144. static void
  2145. https_add_ssl_client_entries (request_st * const r, handler_ctx * const hctx)
  2146. {
  2147. PRFileDesc *ssl = hctx->ssl;
  2148. CERTCertificate *crt = NULL;
  2149. buffer * const tb = r->tmp_buf;
  2150. if (hctx->verify_status != -1)
  2151. crt = SSL_PeerCertificate(ssl);
  2152. if (NULL == crt) { /* || hctx->verify_status == -1) */
  2153. /*(e.g. no cert, or verify result not available)*/
  2154. http_header_env_set(r,
  2155. CONST_STR_LEN("SSL_CLIENT_VERIFY"),
  2156. CONST_STR_LEN("NONE"));
  2157. return;
  2158. }
  2159. else if (0 != hctx->verify_status) {
  2160. buffer_copy_string_len(tb, CONST_STR_LEN("FAILED:"));
  2161. const char *s = PR_ErrorToName(hctx->verify_status);
  2162. if (s)
  2163. buffer_append_string_len(tb, s, strlen(s));
  2164. buffer_append_string_len(tb, CONST_STR_LEN(":"));
  2165. s = PR_ErrorToString(hctx->verify_status, PR_LANGUAGE_I_DEFAULT);
  2166. buffer_append_string_len(tb, s, strlen(s));
  2167. http_header_env_set(r,
  2168. CONST_STR_LEN("SSL_CLIENT_VERIFY"),
  2169. CONST_BUF_LEN(tb));
  2170. CERT_DestroyCertificate(crt);
  2171. return;
  2172. }
  2173. else {
  2174. http_header_env_set(r,
  2175. CONST_STR_LEN("SSL_CLIENT_VERIFY"),
  2176. CONST_STR_LEN("SUCCESS"));
  2177. }
  2178. char *s = CERT_NameToAsciiInvertible(&crt->subject, CERT_N2A_STRICT);
  2179. if (s) {
  2180. http_header_env_set(r,
  2181. CONST_STR_LEN("SSL_CLIENT_S_DN"),
  2182. s, strlen(s));
  2183. PR_Free(s);
  2184. }
  2185. https_add_ssl_client_subject(r, &crt->subject);
  2186. buffer_string_set_length(tb, 0);
  2187. buffer_append_uint_hex_lc(tb, DER_GetInteger(&crt->serialNumber));
  2188. http_header_env_set(r,
  2189. CONST_STR_LEN("SSL_CLIENT_M_SERIAL"),
  2190. CONST_BUF_LEN(tb));
  2191. if (!buffer_string_is_empty(hctx->conf.ssl_verifyclient_username)) {
  2192. /* pick one of the exported values as "REMOTE_USER", for example
  2193. * ssl.verifyclient.username = "SSL_CLIENT_S_DN_UID"
  2194. * or
  2195. * ssl.verifyclient.username = "SSL_CLIENT_S_DN_emailAddress"
  2196. */
  2197. const buffer *varname = hctx->conf.ssl_verifyclient_username;
  2198. const buffer *vb = http_header_env_get(r, CONST_BUF_LEN(varname));
  2199. if (vb) { /* same as http_auth.c:http_auth_setenv() */
  2200. http_header_env_set(r,
  2201. CONST_STR_LEN("REMOTE_USER"),
  2202. CONST_BUF_LEN(vb));
  2203. http_header_env_set(r,
  2204. CONST_STR_LEN("AUTH_TYPE"),
  2205. CONST_STR_LEN("SSL_CLIENT_VERIFY"));
  2206. }
  2207. }
  2208. if (hctx->conf.ssl_verifyclient_export_cert)
  2209. https_add_ssl_client_cert(r, crt);
  2210. CERT_DestroyCertificate(crt);
  2211. }
  2212. static void
  2213. http_cgi_ssl_env (request_st * const r, handler_ctx * const hctx)
  2214. {
  2215. PRFileDesc *ssl = hctx->ssl;
  2216. /* (quite a bit of work just to get protocol version)
  2217. * (could not find better NSS interface) */
  2218. SSLChannelInfo inf;
  2219. if (SSL_GetChannelInfo(ssl, &inf, sizeof(inf)) < 0)
  2220. inf.protocolVersion = 0;
  2221. size_t n;
  2222. const char *s = NULL;
  2223. switch (inf.protocolVersion) {
  2224. case SSL_LIBRARY_VERSION_TLS_1_3: s="TLSv1.3";n=sizeof("TLSv1.3")-1;break;
  2225. case SSL_LIBRARY_VERSION_TLS_1_2: s="TLSv1.2";n=sizeof("TLSv1.2")-1;break;
  2226. case SSL_LIBRARY_VERSION_TLS_1_1: s="TLSv1.1";n=sizeof("TLSv1.1")-1;break;
  2227. case SSL_LIBRARY_VERSION_TLS_1_0: s="TLSv1.0";n=sizeof("TLSv1.0")-1;break;
  2228. case SSL_LIBRARY_VERSION_3_0: s="SSLv3.0";n=sizeof("SSLv3.0")-1;break;
  2229. case SSL_LIBRARY_VERSION_2: s="SSLv2.0";n=sizeof("SSLv2.0")-1;break;
  2230. default: break;
  2231. }
  2232. if (s) http_header_env_set(r, CONST_STR_LEN("SSL_PROTOCOL"), s, n);
  2233. char *cipher;
  2234. int algkeysize;
  2235. int usekeysize;
  2236. if (SSL_SecurityStatus(ssl, NULL, &cipher, &algkeysize, &usekeysize,
  2237. NULL, NULL) < 0)
  2238. return;
  2239. if (cipher) {
  2240. n = strlen(cipher);
  2241. http_header_env_set(r, CONST_STR_LEN("SSL_CIPHER"), cipher, n);
  2242. PR_Free(cipher);
  2243. }
  2244. /* SSL_CIPHER_ALGKEYSIZE - Number of cipher bits (possible) */
  2245. /* SSL_CIPHER_USEKEYSIZE - Number of cipher bits (actually used) */
  2246. char buf[LI_ITOSTRING_LENGTH];
  2247. http_header_env_set(r, CONST_STR_LEN("SSL_CIPHER_USEKEYSIZE"),
  2248. buf, li_utostrn(buf, sizeof(buf), usekeysize));
  2249. http_header_env_set(r, CONST_STR_LEN("SSL_CIPHER_ALGKEYSIZE"),
  2250. buf, li_utostrn(buf, sizeof(buf), algkeysize));
  2251. }
  2252. REQUEST_FUNC(mod_nss_handle_request_env)
  2253. {
  2254. plugin_data *p = p_d;
  2255. /* simple flag for request_env_patched */
  2256. if (r->plugin_ctx[p->id]) return HANDLER_GO_ON;
  2257. handler_ctx *hctx = r->con->plugin_ctx[p->id];
  2258. if (NULL == hctx) return HANDLER_GO_ON;
  2259. r->plugin_ctx[p->id] = (void *)(uintptr_t)1u;
  2260. http_cgi_ssl_env(r, hctx);
  2261. if (hctx->conf.ssl_verifyclient) {
  2262. https_add_ssl_client_entries(r, hctx);
  2263. }
  2264. return HANDLER_GO_ON;
  2265. }
  2266. REQUEST_FUNC(mod_nss_handle_uri_raw)
  2267. {
  2268. /* mod_nss must be loaded prior to mod_auth
  2269. * if mod_nss is configured to set REMOTE_USER based on client cert */
  2270. /* mod_nss must be loaded after mod_extforward
  2271. * if mod_nss config is based on lighttpd.conf remote IP conditional
  2272. * using remote IP address set by mod_extforward, *unless* PROXY protocol
  2273. * is enabled with extforward.hap-PROXY = "enable", in which case the
  2274. * reverse is true: mod_extforward must be loaded after mod_nss */
  2275. plugin_data *p = p_d;
  2276. handler_ctx *hctx = r->con->plugin_ctx[p->id];
  2277. if (NULL == hctx) return HANDLER_GO_ON;
  2278. mod_nss_patch_config(r, &hctx->conf);
  2279. if (hctx->conf.ssl_verifyclient) {
  2280. mod_nss_handle_request_env(r, p);
  2281. }
  2282. return HANDLER_GO_ON;
  2283. }
  2284. REQUEST_FUNC(mod_nss_handle_request_reset)
  2285. {
  2286. plugin_data *p = p_d;
  2287. r->plugin_ctx[p->id] = NULL; /* simple flag for request_env_patched */
  2288. return HANDLER_GO_ON;
  2289. }
  2290. TRIGGER_FUNC(mod_nss_handle_trigger) {
  2291. const plugin_data * const p = p_d;
  2292. const time_t cur_ts = log_epoch_secs;
  2293. if (cur_ts & 0x3f) return HANDLER_GO_ON; /*(continue once each 64 sec)*/
  2294. mod_nss_refresh_stapling_files(srv, p, cur_ts);
  2295. return HANDLER_GO_ON;
  2296. }
  2297. int mod_nss_plugin_init (plugin *p);
  2298. int mod_nss_plugin_init (plugin *p)
  2299. {
  2300. p->version = LIGHTTPD_VERSION_ID;
  2301. p->name = "nss";
  2302. p->init = mod_nss_init;
  2303. p->cleanup = mod_nss_free;
  2304. p->priv_defaults= mod_nss_set_defaults;
  2305. p->handle_connection_accept = mod_nss_handle_con_accept;
  2306. p->handle_connection_shut_wr = mod_nss_handle_con_shut_wr;
  2307. p->handle_connection_close = mod_nss_handle_con_close;
  2308. p->handle_uri_raw = mod_nss_handle_uri_raw;
  2309. p->handle_request_env = mod_nss_handle_request_env;
  2310. p->handle_request_reset = mod_nss_handle_request_reset;
  2311. p->handle_trigger = mod_nss_handle_trigger;
  2312. return 0;
  2313. }
  2314. static int
  2315. mod_nss_ssl_conf_curves(server *srv, plugin_config_socket *s, const buffer *curvelist)
  2316. {
  2317. log_error(srv->errh, __FILE__, __LINE__,
  2318. "NSS: ignoring Curves/Groups; not implemented (%s)",
  2319. curvelist->ptr);
  2320. UNUSED(s);
  2321. UNUSED(curvelist);
  2322. /* XXX: TODO: see ssl/sslt.h enum SSLNamedGroup */
  2323. return 1;
  2324. }
  2325. static PRUint16
  2326. mod_nss_ssl_conf_proto_val (server *srv, plugin_config_socket *s, const buffer *b, int max)
  2327. {
  2328. /* use of SSL v3 should be avoided, and SSL v2 is not supported here */
  2329. /*(choosing not to support s->ssl_use_sslv2 or SSL_LIBRARY_VERSION_2 here)*/
  2330. if (NULL == b) /* default: min TLSv1.2, max TLSv1.3 */
  2331. return max ? SSL_LIBRARY_VERSION_TLS_1_3 : SSL_LIBRARY_VERSION_TLS_1_2;
  2332. else if (buffer_eq_icase_slen(b, CONST_STR_LEN("None"))) /*"disable" limit*/
  2333. return max
  2334. ? SSL_LIBRARY_VERSION_TLS_1_3
  2335. : (s->ssl_use_sslv3
  2336. ? SSL_LIBRARY_VERSION_3_0
  2337. : SSL_LIBRARY_VERSIO