aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorlv-426 <oxcafebaby@yahoo.com>2008-07-07 02:38:41 +0000
committerlv-426 <oxcafebaby@yahoo.com>2008-07-07 02:38:41 +0000
commitb9f09651e6217396171d0ee25eb3f1a5087a3ad6 (patch)
tree34e6ee9fe24d7a2d3c68e5931a15626c72d150b4 /src
parenteb391a612d2c1a3bea1cbfecfa008079c8a6320c (diff)
downloadlibmicrohttpd-b9f09651e6217396171d0ee25eb3f1a5087a3ad6.tar.gz
libmicrohttpd-b9f09651e6217396171d0ee25eb3f1a5087a3ad6.zip
migrated code to connection_https
fixed gcrypt lib initialization to support mt removed some gnutls psk code added CIPHER_ALGORITHM & KX_PRIORITY options added certificate loading test added TLS GET test
Diffstat (limited to 'src')
-rw-r--r--src/daemon/Makefile.am11
-rw-r--r--src/daemon/connection.c293
-rw-r--r--src/daemon/connection.h47
-rw-r--r--src/daemon/connection_https.c309
-rw-r--r--src/daemon/daemon.c220
-rw-r--r--src/daemon/https/errcodes.c41
-rw-r--r--src/daemon/https/includes/gnutls.h6
-rw-r--r--src/daemon/https/tls/auth_dh_common.c48
-rw-r--r--src/daemon/https/tls/gnutls_algorithms.c44
-rw-r--r--src/daemon/https/tls/gnutls_global.c161
-rw-r--r--src/daemon/https/tls/gnutls_int.h17
-rw-r--r--src/daemon/https/tls/gnutls_priority.c48
-rw-r--r--src/daemon/https/tls/gnutls_session_pack.c17
-rw-r--r--src/daemon/internal.c7
-rw-r--r--src/daemon/internal.h25
-rw-r--r--src/include/microhttpd.h17
-rw-r--r--src/testcurl/https/Makefile.am2
-rw-r--r--src/testcurl/https/daemon_https_test_get.c142
-rw-r--r--src/testcurl/https/mhds_test_session_info.c2
19 files changed, 708 insertions, 749 deletions
diff --git a/src/daemon/Makefile.am b/src/daemon/Makefile.am
index ed1818a4..b8f586b2 100644
--- a/src/daemon/Makefile.am
+++ b/src/daemon/Makefile.am
@@ -22,11 +22,6 @@ lib_LTLIBRARIES = \
22SUBDIRS = 22SUBDIRS =
23libmicrohttpd_la_LIBADD = 23libmicrohttpd_la_LIBADD =
24 24
25if ENABLE_HTTPS
26SUBDIRS += https .
27libmicrohttpd_la_LIBADD += https/libhttps.la
28endif
29
30libmicrohttpd_la_SOURCES = \ 25libmicrohttpd_la_SOURCES = \
31connection.c connection.h \ 26connection.c connection.h \
32reason_phrase.c reason_phrase.h \ 27reason_phrase.c reason_phrase.h \
@@ -38,6 +33,12 @@ postprocessor.c \
38response.c response.h 33response.c response.h
39libmicrohttpd_la_LDFLAGS = \ 34libmicrohttpd_la_LDFLAGS = \
40 -export-dynamic -version-info 4:3:0 $(retaincommand) 35 -export-dynamic -version-info 4:3:0 $(retaincommand)
36
37if ENABLE_HTTPS
38SUBDIRS += https .
39libmicrohttpd_la_SOURCES += connection_https.c
40libmicrohttpd_la_LIBADD += https/libhttps.la
41endif
41 42
42check_PROGRAMS = \ 43check_PROGRAMS = \
43 postprocessor_test \ 44 postprocessor_test \
diff --git a/src/daemon/connection.c b/src/daemon/connection.c
index 38f60a3a..fc4b7954 100644
--- a/src/daemon/connection.c
+++ b/src/daemon/connection.c
@@ -161,33 +161,6 @@ MHD_get_connection_values (struct MHD_Connection *connection,
161 return ret; 161 return ret;
162} 162}
163 163
164#if HTTPS_SUPPORT
165/* get cipher spec for this connection */
166gnutls_cipher_algorithm_t
167MHDS_get_session_cipher (struct MHD_Connection * session)
168{
169 return gnutls_cipher_get (session->tls_session);
170}
171
172gnutls_mac_algorithm_t
173MHDS_get_session_mac (struct MHD_Connection * session)
174{
175 return gnutls_mac_get (session->tls_session);
176}
177
178gnutls_compression_method_t
179MHDS_get_session_compression (struct MHD_Connection * session)
180{
181 return gnutls_compression_get (session->tls_session);
182}
183
184gnutls_certificate_type_t
185MHDS_get_session_cert_type (struct MHD_Connection * session)
186{
187 return gnutls_certificate_type_get (session->tls_session);
188}
189#endif
190
191/** 164/**
192 * Get a particular header value. If multiple 165 * Get a particular header value. If multiple
193 * values match the kind, return any one of them. 166 * values match the kind, return any one of them.
@@ -1276,8 +1249,7 @@ do_write (struct MHD_Connection *connection)
1276 return MHD_YES; 1249 return MHD_YES;
1277} 1250}
1278 1251
1279 1252static int
1280int
1281MHD_con_read (struct MHD_Connection *connection) 1253MHD_con_read (struct MHD_Connection *connection)
1282{ 1254{
1283 return RECV (connection->socket_fd, 1255 return RECV (connection->socket_fd,
@@ -1286,18 +1258,6 @@ MHD_con_read (struct MHD_Connection *connection)
1286 connection->read_buffer_offset, MSG_NOSIGNAL); 1258 connection->read_buffer_offset, MSG_NOSIGNAL);
1287} 1259}
1288 1260
1289#if HTTPS_SUPPORT
1290ssize_t
1291MHDS_con_read (struct MHD_Connection * connection)
1292{
1293 ssize_t size = gnutls_record_recv (connection->tls_session,
1294 &connection->read_buffer[connection->
1295 read_buffer_offset],
1296 connection->read_buffer_size);
1297 return size;
1298}
1299#endif
1300
1301/** 1261/**
1302 * Check if we are done sending the write-buffer. 1262 * Check if we are done sending the write-buffer.
1303 * If so, transition into "next_state". 1263 * If so, transition into "next_state".
@@ -1549,122 +1509,7 @@ MHD_connection_handle_read (struct MHD_Connection *connection)
1549 return MHD_YES; 1509 return MHD_YES;
1550} 1510}
1551 1511
1552#if HTTPS_SUPPORT 1512static int
1553int
1554MHDS_connection_handle_read (struct MHD_Connection *connection)
1555{
1556 int ret;
1557
1558 connection->last_activity = time (NULL);
1559
1560 if (connection->s_state == MHDS_CONNECTION_CLOSED)
1561 return MHD_NO;
1562
1563 /* discover content type */
1564 unsigned char msg_type;
1565 if (recv (connection->socket_fd, &msg_type, 1, MSG_PEEK) == -1)
1566 {
1567#if HAVE_MESSAGES
1568 MHD_DLOG (connection->daemon, "Failed to peek into TLS content type\n");
1569#endif
1570 return MHD_NO;
1571 }
1572
1573 switch (msg_type)
1574 {
1575 case GNUTLS_CHANGE_CIPHER_SPEC:
1576
1577 break;
1578 case GNUTLS_ALERT:
1579 /*
1580 * this call of _gnutls_recv_int expects 0 bytes read.
1581 * done to decrypt alert message
1582 */
1583 _gnutls_recv_int (connection->tls_session, GNUTLS_ALERT,
1584 GNUTLS_HANDSHAKE_FINISHED, 0);
1585
1586 /* CLOSE_NOTIFY */
1587 if (connection->tls_session->internals.last_alert ==
1588 GNUTLS_A_CLOSE_NOTIFY)
1589 {
1590 gnutls_bye (connection->tls_session, GNUTLS_SHUT_WR);
1591 connection->tls_session->internals.read_eof = 1;
1592 connection->socket_fd = -1;
1593 gnutls_deinit (connection->tls_session);
1594 return MHD_YES;
1595 }
1596 /* non FATAL or WARNING */
1597 else if (connection->tls_session->internals.last_alert !=
1598 GNUTLS_AL_FATAL)
1599 {
1600#if HAVE_MESSAGES
1601 MHD_DLOG (connection->daemon,
1602 "Received TLS alert: %s\n",
1603 gnutls_alert_get_name ((int) connection->tls_session->
1604 internals.last_alert));
1605#endif
1606 return MHD_YES;
1607 }
1608 /* FATAL */
1609 else if (connection->tls_session->internals.last_alert ==
1610 GNUTLS_AL_FATAL)
1611 {
1612 connection->tls_session->internals.resumable = RESUME_FALSE;
1613 connection->tls_session->internals.valid_connection = VALID_FALSE;
1614 connection->socket_fd = -1;
1615 gnutls_deinit (connection->tls_session);
1616
1617 return MHD_NO;
1618 }
1619 /* this should never execut */
1620 else
1621 {
1622#if HAVE_MESSAGES
1623 MHD_DLOG (connection->daemon,
1624 "Received unrecognized alert: %s\n",
1625 connection->tls_session->internals.last_alert);
1626#endif
1627 return MHD_NO;
1628 }
1629
1630
1631 /* forward application level content to MHD */
1632 case GNUTLS_APPLICATION_DATA:
1633 return MHD_connection_handle_read (connection);
1634
1635 case GNUTLS_HANDSHAKE:
1636 ret = gnutls_handshake (connection->tls_session);
1637 if (ret == 0)
1638 {
1639 connection->s_state = MHDS_HANDSHAKE_COMPLETE;
1640 connection->state = MHD_CONNECTION_INIT;
1641 }
1642 /* set connection as closed */
1643 else
1644 {
1645#if HAVE_MESSAGES
1646 MHD_DLOG (connection->daemon,
1647 "Error: Handshake has failed (%s)\n",
1648 ret);
1649#endif
1650 connection->s_state = MHDS_HANDSHAKE_FAILED;
1651 gnutls_bye (connection->tls_session, GNUTLS_SHUT_WR);
1652 gnutls_deinit (connection->tls_session);
1653 connection->socket_fd = -1;
1654 return MHD_NO;
1655
1656 }
1657 break;
1658 case GNUTLS_INNER_APPLICATION:
1659 break;
1660 }
1661
1662 return MHD_YES;
1663}
1664#endif
1665
1666
1667int
1668MHD_con_write (struct MHD_Connection *connection) 1513MHD_con_write (struct MHD_Connection *connection)
1669{ 1514{
1670 return SEND (connection->socket_fd, 1515 return SEND (connection->socket_fd,
@@ -1674,19 +1519,6 @@ MHD_con_write (struct MHD_Connection *connection)
1674 connection->write_buffer_send_offset, MSG_NOSIGNAL); 1519 connection->write_buffer_send_offset, MSG_NOSIGNAL);
1675} 1520}
1676 1521
1677#if HTTPS_SUPPORT
1678ssize_t
1679MHDS_con_write (struct MHD_Connection * connection)
1680{
1681 ssize_t sent = gnutls_record_send (connection->tls_session,
1682 &connection->write_buffer[connection->
1683 write_buffer_send_offset],
1684 connection->write_buffer_append_offset
1685 - connection->write_buffer_send_offset);
1686 return sent;
1687}
1688#endif
1689
1690/** 1522/**
1691 * This function was created to handle writes to sockets when it has 1523 * This function was created to handle writes to sockets when it has
1692 * been determined that the socket can be written to. All 1524 * been determined that the socket can be written to. All
@@ -1849,52 +1681,6 @@ MHD_connection_handle_write (struct MHD_Connection *connection)
1849 return MHD_YES; 1681 return MHD_YES;
1850} 1682}
1851 1683
1852#if HTTPS_SUPPORT
1853int
1854MHDS_connection_handle_write (struct MHD_Connection *connection)
1855{
1856 connection->last_activity = time (NULL);
1857 while (1)
1858 {
1859#if HAVE_MESSAGES
1860 MHD_DLOG (connection->daemon, "MHDS reached case: %d, l: %d, f: %s\n",
1861 connection->s_state, __LINE__, __FUNCTION__);
1862#endif
1863 switch (connection->s_state)
1864 {
1865
1866 /* these cases shouldn't occur */
1867 case MHDS_CONNECTION_INIT:
1868 // TODO do we have to write back a responce ?
1869 case MHDS_HANDSHAKE_FAILED:
1870 /* we should first exit MHDS_REPLY_SENDING */
1871 case MHDS_REQUEST_READING:
1872 /* these should go through the idle state at first */
1873 case MHDS_REQUEST_READ:
1874 connection->s_state = MHDS_REPLY_SENDING;
1875 do_write (connection);
1876 break;
1877
1878 case MHDS_CONNECTION_CLOSED:
1879 if (connection->socket_fd != -1)
1880 connection_close_error (connection);
1881 return MHD_NO;
1882 case MHDS_HANDSHAKE_COMPLETE:
1883
1884 case MHDS_REPLY_SENDING:
1885 do_write (connection);
1886 // TODO check write done
1887 break;
1888
1889 case MHDS_REPLY_READY:
1890 /* switch to MHDS_REPLY_SENDING through idle */
1891 break;
1892 }
1893 }
1894 return MHD_YES;
1895}
1896#endif
1897
1898/** 1684/**
1899 * This function was created to handle per-connection processing that 1685 * This function was created to handle per-connection processing that
1900 * has to happen even if the socket cannot be read or written to. All 1686 * has to happen even if the socket cannot be read or written to. All
@@ -2223,77 +2009,14 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
2223 2009
2224} 2010}
2225 2011
2226#if HTTPS_SUPPORT
2227int 2012int
2228MHDS_connection_handle_idle (struct MHD_Connection *connection) 2013MHD_set_http_calbacks (struct MHD_Connection *connection)
2229{ 2014{
2230 unsigned int timeout; 2015 connection->recv_cls = &MHD_con_read;
2231 const char *end; 2016 connection->send_cls = &MHD_con_write;
2232 char *line; 2017 connection->read_handler = &MHD_connection_handle_read;
2233 ssize_t msgLength; 2018 connection->write_handler = &MHD_connection_handle_write;
2234 while (1) 2019 connection->idle_handler = &MHD_connection_handle_idle;
2235 {
2236#if HAVE_MESSAGES
2237 MHD_DLOG (connection->daemon, "MHDS reached case: %d, l: %d, f: %s\n",
2238 connection->s_state, __LINE__, __FUNCTION__);
2239#endif
2240 switch (connection->s_state)
2241 {
2242 case MHDS_HANDSHAKE_FAILED:
2243 connection->socket_fd = -1;
2244 case MHDS_CONNECTION_INIT:
2245 /* wait for request */
2246 case MHDS_HANDSHAKE_COMPLETE:
2247
2248 case MHDS_REPLY_SENDING:
2249 connection->s_state = MHDS_REPLY_SENT;
2250 break;
2251
2252 case MHDS_REPLY_READY:
2253 /* send data for encryption */
2254 //memcpy (connection->write_buffer,
2255 //connection->tls_session->internals.application_data_buffer.
2256 // data, connection->write_buffer_size);
2257 //connection->s_state = MHDS_REPLY_SENDING;
2258 break;
2259
2260 case MHDS_REQUEST_READING:
2261 // TODO mv handshake here
2262 connection->s_state = MHDS_REQUEST_READ;
2263
2264 case MHDS_REQUEST_READ:
2265 /* pipe data to HTTP state machine */
2266
2267 // msgLength = connection->tls_session->internals.application_data_buffer.length;
2268 // memcpy (connection->tls_session->internals.application_data_buffer.data, connection->read_buffer, msgLength);
2269 // connection->read_buffer_offset = msgLength;
2270 /* pass connection to MHD */
2271 MHD_connection_handle_idle (connection);
2272
2273 break;
2274
2275 case MHDS_CONNECTION_CLOSED:
2276 if (connection->socket_fd != -1)
2277 connection_close_error (connection);
2278 break;
2279
2280 default:
2281 EXTRA_CHECK (0);
2282 break;
2283 }
2284 break;
2285 }
2286
2287 timeout = connection->daemon->connection_timeout;
2288
2289 if ((connection->socket_fd != -1) && (timeout != 0)
2290 && (time (NULL) - timeout > connection->last_activity))
2291 {
2292 connection_close_error (connection);
2293 return MHD_NO;
2294 }
2295 return MHD_YES;
2296} 2020}
2297#endif
2298 2021
2299/* end of connection.c */ 2022/* end of connection.c */
diff --git a/src/daemon/connection.h b/src/daemon/connection.h
index ee96cfc4..6df81e77 100644
--- a/src/daemon/connection.h
+++ b/src/daemon/connection.h
@@ -40,50 +40,9 @@ MHD_connection_get_fdset (struct MHD_Connection *connection,
40 fd_set * write_fd_set, 40 fd_set * write_fd_set,
41 fd_set * except_fd_set, int *max_fd); 41 fd_set * except_fd_set, int *max_fd);
42 42
43/** 43int MHD_set_http_calbacks (struct MHD_Connection *connection);
44 * This function handles a particular connection when it has been
45 * determined that there is data to be read off a socket. All implementations
46 * (multithreaded, external select, internal select) call this function
47 * to handle reads.
48 *
49 * @return MHD_YES if we should continue to process the
50 * connection (not dead yet), MHD_NO if it died
51 */
52int MHD_connection_handle_read (struct MHD_Connection *connection);
53
54
55/**
56 * This function was created to handle writes to sockets when it has been
57 * determined that the socket can be written to. If there is no data
58 * to be written, however, the function call does nothing. All implementations
59 * (multithreaded, external select, internal select) call this function
60 *
61 * @return MHD_YES if we should continue to process the
62 * connection (not dead yet), MHD_NO if it died
63 */
64int MHD_connection_handle_write (struct MHD_Connection *connection);
65
66
67/**
68 * This function was created to handle per-connection processing that
69 * has to happen even if the socket cannot be read or written to. All
70 * implementations (multithreaded, external select, internal select)
71 * call this function.
72 *
73 * @return MHD_YES if we should continue to process the
74 * connection (not dead yet), MHD_NO if it died
75 */
76int MHD_connection_handle_idle (struct MHD_Connection *connection);
77
78int MHD_con_read(struct MHD_Connection *connection);
79int MHD_con_write(struct MHD_Connection *connection);
80
81#if HTTPS_SUPPORT 44#if HTTPS_SUPPORT
82int MHDS_connection_handle_read(struct MHD_Connection *connection); 45int MHD_set_https_calbacks (struct MHD_Connection *connection);
83int MHDS_connection_handle_write(struct MHD_Connection *connection);
84int MHDS_connection_handle_idle(struct MHD_Connection *connection);
85
86ssize_t MHDS_con_read(struct MHD_Connection *connection);
87ssize_t MHDS_con_write(struct MHD_Connection *connection);
88#endif 46#endif
47
89#endif 48#endif
diff --git a/src/daemon/connection_https.c b/src/daemon/connection_https.c
new file mode 100644
index 00000000..f3b44bc3
--- /dev/null
+++ b/src/daemon/connection_https.c
@@ -0,0 +1,309 @@
1/*
2 This file is part of libmicrohttpd
3 (C) 2007, 2008 Daniel Pittman and Christian Grothoff
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
19*/
20
21/**
22 * @file connection.c
23 * @brief Methods for managing SSL/TLS connections. This file is only
24 * compiled if ENABLE_HTTPS is set.
25 * @author Sagie Amir
26 * @author Christian Grothoff
27 */
28
29#include "internal.h"
30#include "connection.h"
31#include "memorypool.h"
32#include "response.h"
33#include "reason_phrase.h"
34
35// get opaque type
36#include "gnutls_int.h"
37
38// TODO clean
39#undef MAX
40#define MAX(a,b) ((a)<(b)) ? (b) : (a)
41#undef MIN
42#define MIN(a,b) ((a)<(b)) ? (a) : (b)
43
44// TODO rm - appears in a switch default clause
45#if EXTRA_CHECKS
46#define EXTRA_CHECK(a) if (!(a)) abort();
47#else
48#define EXTRA_CHECK(a)
49#endif
50
51/* forward declarations used when setting secure connection callbacks */
52int MHD_connection_handle_read (struct MHD_Connection *connection);
53int MHD_connection_handle_write (struct MHD_Connection *connection);
54int MHD_connection_handle_idle (struct MHD_Connection *connection);
55
56// TODO rm - appears in a switch default clause
57static void
58connection_close_error (struct MHD_Connection *connection)
59{
60 SHUTDOWN (connection->socket_fd, SHUT_RDWR);
61 CLOSE (connection->socket_fd);
62 connection->socket_fd = -1;
63 connection->state = MHD_CONNECTION_CLOSED;
64 if (connection->daemon->notify_completed != NULL)
65 connection->daemon->notify_completed (connection->daemon->
66 notify_completed_cls, connection,
67 &connection->client_context,
68 MHD_REQUEST_TERMINATED_WITH_ERROR);
69}
70
71/* get cipher spec for this connection */
72gnutls_cipher_algorithm_t
73MHDS_get_session_cipher (struct MHD_Connection *session)
74{
75 return gnutls_cipher_get (session->tls_session);
76}
77
78gnutls_mac_algorithm_t
79MHDS_get_session_mac (struct MHD_Connection * session)
80{
81 return gnutls_mac_get (session->tls_session);
82}
83
84gnutls_compression_method_t
85MHDS_get_session_compression (struct MHD_Connection * session)
86{
87 return gnutls_compression_get (session->tls_session);
88}
89
90gnutls_certificate_type_t
91MHDS_get_session_cert_type (struct MHD_Connection * session)
92{
93 return gnutls_certificate_type_get (session->tls_session);
94}
95
96static ssize_t
97MHDS_con_read (struct MHD_Connection *connection)
98{
99 ssize_t size = gnutls_record_recv (connection->tls_session,
100 &connection->read_buffer[connection->
101 read_buffer_offset],
102 connection->read_buffer_size);
103 return size;
104}
105
106static ssize_t
107MHDS_con_write (struct MHD_Connection *connection)
108{
109 ssize_t sent = gnutls_record_send (connection->tls_session,
110 &connection->write_buffer[connection->
111 write_buffer_send_offset],
112 connection->write_buffer_append_offset
113 - connection->write_buffer_send_offset);
114 return sent;
115}
116
117int
118MHDS_connection_handle_idle (struct MHD_Connection *connection)
119{
120 unsigned int timeout;
121 const char *end;
122 char *line;
123 ssize_t msgLength;
124 while (1)
125 {
126#if HAVE_MESSAGES
127 MHD_DLOG (connection->daemon, "MHDS reached case: %d, l: %d, f: %s\n",
128 connection->s_state, __LINE__, __FUNCTION__);
129#endif
130 switch (connection->s_state)
131 {
132 case MHDS_HANDSHAKE_FAILED:
133 connection->socket_fd = -1;
134 case MHDS_CONNECTION_INIT:
135 /* wait for request */
136 case MHDS_HANDSHAKE_COMPLETE:
137
138 case MHDS_CONNECTION_CLOSED:
139 if (connection->socket_fd != -1)
140 connection_close_error (connection);
141 break;
142
143 default:
144 EXTRA_CHECK (0);
145 break;
146 }
147 break;
148 }
149
150 timeout = connection->daemon->connection_timeout;
151
152 if ((connection->socket_fd != -1) && (timeout != 0)
153 && (time (NULL) - timeout > connection->last_activity))
154 {
155 connection_close_error (connection);
156 return MHD_NO;
157 }
158 return MHD_YES;
159}
160
161int
162MHDS_connection_handle_read (struct MHD_Connection *connection)
163{
164 int ret;
165
166 connection->last_activity = time (NULL);
167
168 if (connection->s_state == MHDS_CONNECTION_CLOSED)
169 return MHD_NO;
170
171 /* discover content type */
172 unsigned char msg_type;
173 if (recv (connection->socket_fd, &msg_type, 1, MSG_PEEK) == -1)
174 {
175#if HAVE_MESSAGES
176 MHD_DLOG (connection->daemon, "Failed to peek into TLS content type\n");
177#endif
178 return MHD_NO;
179 }
180
181 switch (msg_type)
182 {
183 case GNUTLS_CHANGE_CIPHER_SPEC:
184
185 break;
186 case GNUTLS_ALERT:
187 /*
188 * this call of _gnutls_recv_int expects 0 bytes read.
189 * done to decrypt alert message
190 */
191 _gnutls_recv_int (connection->tls_session, GNUTLS_ALERT,
192 GNUTLS_HANDSHAKE_FINISHED, 0);
193
194 /* CLOSE_NOTIFY */
195 if (connection->tls_session->internals.last_alert ==
196 GNUTLS_A_CLOSE_NOTIFY)
197 {
198 gnutls_bye (connection->tls_session, GNUTLS_SHUT_WR);
199 connection->tls_session->internals.read_eof = 1;
200 connection->socket_fd = -1;
201 gnutls_deinit (connection->tls_session);
202 return MHD_YES;
203 }
204 /* non FATAL or WARNING */
205 else if (connection->tls_session->internals.last_alert !=
206 GNUTLS_AL_FATAL)
207 {
208#if HAVE_MESSAGES
209 MHD_DLOG (connection->daemon,
210 "Received TLS alert: %s\n",
211 gnutls_alert_get_name ((int) connection->tls_session->
212 internals.last_alert));
213#endif
214 return MHD_YES;
215 }
216 /* FATAL */
217 else if (connection->tls_session->internals.last_alert ==
218 GNUTLS_AL_FATAL)
219 {
220 connection->tls_session->internals.resumable = RESUME_FALSE;
221 connection->tls_session->internals.valid_connection = VALID_FALSE;
222 connection->socket_fd = -1;
223 gnutls_deinit (connection->tls_session);
224
225 return MHD_NO;
226 }
227 /* this should never execut */
228 else
229 {
230#if HAVE_MESSAGES
231 MHD_DLOG (connection->daemon,
232 "Received unrecognized alert: %s\n",
233 connection->tls_session->internals.last_alert);
234#endif
235 return MHD_NO;
236 }
237
238
239 /* forward application level content to MHD */
240 case GNUTLS_APPLICATION_DATA:
241 return MHD_connection_handle_read (connection);
242
243 case GNUTLS_HANDSHAKE:
244 ret = gnutls_handshake (connection->tls_session);
245 if (ret == 0)
246 {
247 connection->s_state = MHDS_HANDSHAKE_COMPLETE;
248 connection->state = MHD_CONNECTION_INIT;
249 }
250 /* set connection as closed */
251 else
252 {
253#if HAVE_MESSAGES
254 MHD_DLOG (connection->daemon,
255 "Error: Handshake has failed (%s)\n", ret);
256#endif
257 connection->s_state = MHDS_HANDSHAKE_FAILED;
258 gnutls_bye (connection->tls_session, GNUTLS_SHUT_WR);
259 gnutls_deinit (connection->tls_session);
260 connection->socket_fd = -1;
261 return MHD_NO;
262
263 }
264 break;
265 case GNUTLS_INNER_APPLICATION:
266 break;
267 }
268
269 return MHD_YES;
270}
271
272int
273MHDS_connection_handle_write (struct MHD_Connection *connection)
274{
275 connection->last_activity = time (NULL);
276 while (1)
277 {
278#if HAVE_MESSAGES
279 MHD_DLOG (connection->daemon, "MHDS reached case: %d, l: %d, f: %s\n",
280 connection->s_state, __LINE__, __FUNCTION__);
281#endif
282 switch (connection->s_state)
283 {
284
285 /* these cases shouldn't occur */
286 case MHDS_HANDSHAKE_COMPLETE:
287 case MHDS_CONNECTION_INIT:
288 // TODO do we have to write back a responce ?
289 case MHDS_HANDSHAKE_FAILED:
290 /* we should first exit MHDS_REPLY_SENDING */
291
292 case MHDS_CONNECTION_CLOSED:
293 if (connection->socket_fd != -1)
294 connection_close_error (connection);
295 return MHD_NO;
296 }
297 }
298 return MHD_YES;
299}
300
301int
302MHD_set_https_calbacks (struct MHD_Connection *connection)
303{
304 connection->recv_cls = &MHDS_con_read;
305 connection->send_cls = &MHDS_con_write;
306 connection->read_handler = &MHDS_connection_handle_read;
307 connection->write_handler = &MHD_connection_handle_write;
308 connection->idle_handler = &MHD_connection_handle_idle;
309}
diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c
index d667b5cb..937cd642 100644
--- a/src/daemon/daemon.c
+++ b/src/daemon/daemon.c
@@ -28,7 +28,9 @@
28#include "response.h" 28#include "response.h"
29#include "connection.h" 29#include "connection.h"
30#include "memorypool.h" 30#include "memorypool.h"
31#include "gnutls.h" 31
32#include "gnutls_int.h"
33#include "gnutls_datum.h"
32 34
33/** 35/**
34 * Default connection limit. 36 * Default connection limit.
@@ -53,97 +55,86 @@
53#define DEBUG_CONNECT MHD_NO 55#define DEBUG_CONNECT MHD_NO
54 56
55#if HTTPS_SUPPORT 57#if HTTPS_SUPPORT
56// TODO rm 58/* initialize security aspects of the HTTPS daemon */
57static void
58tls_log_func (int level, const char *str)
59{
60 fprintf (stdout, "|<%d>| %s", level, str);
61}
62
63/**
64 * Initialize security aspects of the HTTPS daemon
65 */
66static int 59static int
67MHDS_init (struct MHD_Daemon *daemon) 60MHDS_init (struct MHD_Daemon *daemon){
68{ 61 gnutls_global_set_log_function (MHD_tls_log_func);
69 // TODO rm 62 /* TODO let user access log level */
70 gnutls_global_set_log_level (11); 63
71 gnutls_global_set_log_function (tls_log_func); 64 /* setup server certificate */
72 65 gnutls_certificate_allocate_credentials (&daemon->x509_cret);
73 gnutls_global_init (); 66
74 67 /* Generate Diffie Hellman parameters - for use with DHE kx algorithms. */
75 /* Generate Diffie Hellman parameters - for use with DHE kx algorithms. */ 68 // TODO should we be initializing RSA params or DH params ?
76 // TODO should we be initializing RSA params or DH params ? 69
77 gnutls_dh_params_init (&daemon->dh_params); 70 gnutls_dh_params_init (&daemon->dh_params);
78 gnutls_dh_params_generate2 (daemon->dh_params, DH_BITS); 71 gnutls_dh_params_generate2 (daemon->dh_params, 1024);
79 72
80 // TODO rm NONE:+AES-256-CBC:+RSA:+SHA1:+COMP-NULL", NULL); 73 // TODO remove if unused
81 gnutls_priority_init (&daemon->priority_cache, 74 /* add trusted CAs to certificate */
82 "NONE:+AES-256-CBC:+RSA:+SHA1:+COMP-NULL", NULL); 75 // gnutls_certificate_set_x509_trust_file(x509_cret, CAFILE,GNUTLS_X509_FMT_PEM);
83 76
84 /* setup server certificate */ 77 /* add Certificate revocation list to certificate */
85 gnutls_certificate_allocate_credentials (&daemon->x509_cret); 78 //gnutls_certificate_set_x509_crl_file(x509_cret, CRLFILE, GNUTLS_X509_FMT_PEM);
86 79
87 // TODO remove if unused 80 /* sets a certificate private key pair */
88 /* add trusted CAs to certificate */ 81 if (daemon->https_cert_path && daemon->https_key_path)
89 // gnutls_certificate_set_x509_trust_file(x509_cret, CAFILE,GNUTLS_X509_FMT_PEM); 82 {
90 83 /* test for private key & certificate file exsitance */
91 /* add Certificate revocation list to certificate */ 84 if (access (daemon->https_cert_path, R_OK))
92 //gnutls_certificate_set_x509_crl_file(x509_cret, CRLFILE, GNUTLS_X509_FMT_PEM); 85 {
93 86 #if HAVE_MESSAGES
94 /* sets a certificate private key pair */ 87 MHD_DLOG (daemon, "Missing X.509 certificate file\n");
95 if (daemon->https_cert_path && daemon->https_key_path ) 88 #endif
96 { 89 free (daemon);
97 /* test for private key & certificate file exsitance */ 90 CLOSE (daemon->socket_fd);
98 FILE *cert_file = fopen (daemon->https_cert_path, "r"); 91 return -1;
99 FILE *key_file = fopen (daemon->https_key_path, "r"); 92 }
100 if (key_file == NULL || cert_file == NULL) 93
101 { 94 if (access (daemon->https_key_path, R_OK))
102 printf ("missing cert files"); 95 {
103#if HAVE_MESSAGES 96 #if HAVE_MESSAGES
104 MHD_DLOG (daemon, "Missing X.509 key or certificate file\n"); 97 MHD_DLOG (daemon, "Missing X.509 key file\n");
105#endif 98 #endif
106 free (daemon); 99 free (daemon);
107 CLOSE (daemon->socket_fd); 100 CLOSE (daemon->socket_fd);
108 return MHD_NO; 101 return -1;
109 } 102 }
110 fclose (cert_file); 103 gnutls_certificate_set_x509_key_file (daemon->x509_cret,
111 fclose (key_file); 104 daemon->https_cert_path,
112 gnutls_certificate_set_x509_key_file (daemon->x509_cret, 105 daemon->https_key_path,
113 daemon->https_cert_path, 106 GNUTLS_X509_FMT_PEM);
114 daemon->https_key_path, 107 }
115 GNUTLS_X509_FMT_PEM); 108 else if (daemon->https_mem_cert && daemon->https_mem_key)
116 } 109 {
117 else if (daemon->https_mem_cert && daemon->https_mem_key ) 110 gnutls_datum_t *key =
118 { 111 (gnutls_datum_t *) malloc (sizeof (gnutls_datum_t));
119 // TODO free 112 gnutls_datum_t *cert =
120 gnutls_datum_t * key = ( gnutls_datum_t * ) malloc (sizeof(gnutls_datum_t)); 113 (gnutls_datum_t *) malloc (sizeof (gnutls_datum_t));
121 gnutls_datum_t * cert = ( gnutls_datum_t * ) malloc (sizeof(gnutls_datum_t)); 114
122 115 _gnutls_set_datum_m (key, daemon->https_mem_key,
123 _gnutls_set_datum_m(key,daemon->https_mem_key,strlen (daemon->https_mem_key), &malloc); 116 strlen (daemon->https_mem_key), &malloc);
124 _gnutls_set_datum_m(cert,daemon->https_mem_cert,strlen (daemon->https_mem_cert), &malloc); 117 _gnutls_set_datum_m (cert, daemon->https_mem_cert,
125 118 strlen (daemon->https_mem_cert), &malloc);
126 gnutls_certificate_set_x509_key_mem (daemon->x509_cret, cert, key, 119
127 GNUTLS_X509_FMT_PEM); 120 gnutls_certificate_set_x509_key_mem (daemon->x509_cret, cert, key,
128 printf(""); 121 GNUTLS_X509_FMT_PEM);
129 } 122 }
130 else 123 else
131 { 124 {
132#if HAVE_MESSAGES 125 #if HAVE_MESSAGES
133 MHD_DLOG (daemon, "Failed to load certificate\n"); 126 MHD_DLOG (daemon, "Failed to load certificate\n");
134#endif 127 #endif
135 return MHD_NO; 128 return MHD_NO;
136 } 129 }
137 130
138 gnutls_certificate_set_dh_params (daemon->x509_cret, daemon->dh_params); 131 gnutls_certificate_set_dh_params (daemon->x509_cret, daemon->dh_params);
139 132
140 // TODO address error case return value 133 // TODO address error case return value
141 return MHD_YES; 134 return MHD_YES;
142} 135}
143#endif 136#endif
144 137
145
146
147/** 138/**
148 * Obtain the select sets for this daemon. 139 * Obtain the select sets for this daemon.
149 * 140 *
@@ -257,7 +248,7 @@ MHD_handle_connection (void *data)
257 248
258#if 0 249#if 0
259/* TODO rm if unused - gnutls parameter adapter , used to set gnutls pull function */ 250/* TODO rm if unused - gnutls parameter adapter , used to set gnutls pull function */
260long 251static long
261gnutls_pull_param_adapter (void *connection, void *other, unsigned long i) 252gnutls_pull_param_adapter (void *connection, void *other, unsigned long i)
262{ 253{
263 ssize_t bytes; 254 ssize_t bytes;
@@ -268,7 +259,7 @@ gnutls_pull_param_adapter (void *connection, void *other, unsigned long i)
268 259
269} 260}
270 261
271long 262static long
272gnutls_push_param_adapter (void *connection, 263gnutls_push_param_adapter (void *connection,
273 const void *other, unsigned long i) 264 const void *other, unsigned long i)
274{ 265{
@@ -311,7 +302,7 @@ MHDS_handle_connection (void *data)
311 302
312 gnutls_transport_set_ptr (tls_session, con->socket_fd); 303 gnutls_transport_set_ptr (tls_session, con->socket_fd);
313 304
314 MHD_handle_connection (data); 305 return MHD_handle_connection (data);
315} 306}
316#endif 307#endif
317 308
@@ -454,21 +445,12 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
454 connection->daemon = daemon; 445 connection->daemon = daemon;
455 446
456 /* set default connection handlers */ 447 /* set default connection handlers */
457 connection->recv_cls = &MHD_con_read; 448 MHD_set_http_calbacks (connection);
458 connection->send_cls = &MHD_con_write;
459 connection->read_handler = &MHD_connection_handle_read;
460 connection->write_handler = &MHD_connection_handle_write;
461 connection->idle_handler = &MHD_connection_handle_idle;
462 449
463#if HTTPS_SUPPORT 450#if HTTPS_SUPPORT
464 if (daemon->options & MHD_USE_SSL) 451 if (daemon->options & MHD_USE_SSL)
465 { 452 {
466 /* set HTTPS connection handlers */ 453 MHD_set_https_calbacks (connection);
467 connection->recv_cls = &MHDS_con_read;
468 connection->send_cls = &MHDS_con_write;
469 connection->read_handler = &MHDS_connection_handle_read;
470 connection->write_handler = &MHD_connection_handle_write;
471 connection->idle_handler = &MHD_connection_handle_idle;
472 } 454 }
473#endif 455#endif
474 456
@@ -739,6 +721,27 @@ MHD_select_thread (void *cls)
739 return NULL; 721 return NULL;
740} 722}
741 723
724/* TODO unite with code in gnutls_priority.c */
725/* this is used to set HTTPS related daemon priorities */
726inline static int
727_set_priority (priority_st * st, const int *list)
728{
729 int num = 0, i;
730
731 while (list[num] != 0)
732 num++;
733 if (num > MAX_ALGOS)
734 num = MAX_ALGOS;
735 st->algorithms = num;
736
737 for (i = 0; i < num; i++)
738 {
739 st->priority[i] = list[i];
740 }
741
742 return 0;
743}
744
742/** 745/**
743 * Start a webserver on the given port. 746 * Start a webserver on the given port.
744 * 747 *
@@ -758,7 +761,7 @@ MHD_start_daemon (unsigned int options,
758 MHD_AccessHandlerCallback dh, void *dh_cls, ...) 761 MHD_AccessHandlerCallback dh, void *dh_cls, ...)
759{ 762{
760 const int on = 1; 763 const int on = 1;
761 struct MHD_Daemon *retVal; 764 struct MHD_Daemon * retVal;
762 765
763 /* listeningss sockets used by the daemon */ 766 /* listeningss sockets used by the daemon */
764 int socket_fd; 767 int socket_fd;
@@ -851,6 +854,13 @@ MHD_start_daemon (unsigned int options,
851 retVal->max_connections = MHD_MAX_CONNECTIONS_DEFAULT; 854 retVal->max_connections = MHD_MAX_CONNECTIONS_DEFAULT;
852 retVal->pool_size = MHD_POOL_SIZE_DEFAULT; 855 retVal->pool_size = MHD_POOL_SIZE_DEFAULT;
853 retVal->connection_timeout = 0; /* no timeout */ 856 retVal->connection_timeout = 0; /* no timeout */
857 if (options & MHD_USE_SSL)
858 {
859 gnutls_global_init ();
860 gnutls_priority_init (&retVal->priority_cache,
861 "NONE:+AES-256-CBC:+RSA:+SHA1:+COMP-NULL", NULL);
862 }
863
854 864
855 /* initializes the argument pointer variable */ 865 /* initializes the argument pointer variable */
856 va_start (ap, dh_cls); 866 va_start (ap, dh_cls);
@@ -890,6 +900,14 @@ MHD_start_daemon (unsigned int options,
890 case MHD_OPTION_HTTPS_MEM_CERT: 900 case MHD_OPTION_HTTPS_MEM_CERT:
891 retVal->https_mem_cert = va_arg (ap, const char *); 901 retVal->https_mem_cert = va_arg (ap, const char *);
892 break; 902 break;
903 case MHDS_KX_PRIORITY:
904 _set_priority (&retVal->priority_cache->kx,
905 va_arg (ap, const int *));
906 break;
907 case MHDS_CIPHER_ALGORITHM:
908 _set_priority (&retVal->priority_cache->cipher,
909 va_arg (ap, const int *));
910 break;
893 default: 911 default:
894#if HAVE_MESSAGES 912#if HAVE_MESSAGES
895 fprintf (stderr, 913 fprintf (stderr,
diff --git a/src/daemon/https/errcodes.c b/src/daemon/https/errcodes.c
index 96d04240..0177eccc 100644
--- a/src/daemon/https/errcodes.c
+++ b/src/daemon/https/errcodes.c
@@ -15,7 +15,6 @@ typedef struct
15 int error_index; 15 int error_index;
16} error_name; 16} error_name;
17 17
18
19static int 18static int
20compar (const void *_n1, const void *_n2) 19compar (const void *_n1, const void *_n2)
21{ 20{
@@ -23,43 +22,3 @@ compar (const void *_n1, const void *_n2)
23 *n2 = (const error_name *) _n2; 22 *n2 = (const error_name *) _n2;
24 return strcmp (n1->name, n2->name); 23 return strcmp (n1->name, n2->name);
25} 24}
26
27//int
28//main (int argc, char *argv[])
29//{
30// int i, j;
31// const char *desc;
32// const char *_name;
33// error_name names_to_sort[400]; /* up to 400 names */
34//
35// printf ("@table @code\n");
36//
37// memset (names_to_sort, 0, sizeof (names_to_sort));
38// j = 0;
39// for (i = 0; i > -400; i--)
40// {
41// _name = _gnutls_strerror (i);
42// if (_name == NULL)
43// continue;
44//
45// strcpy (names_to_sort[j].name, _name);
46// names_to_sort[j].error_index = i;
47// j++;
48// }
49//
50// qsort (names_to_sort, j, sizeof (error_name), compar);
51//
52// for (i = 0; i < j; i++)
53// {
54// _name = names_to_sort[i].name;
55// desc = gnutls_strerror (names_to_sort[i].error_index);
56// if (desc == NULL || _name == NULL)
57// continue;
58//
59// printf ("@item %s:\n%s\n\n", _name, desc);
60// }
61//
62// printf ("@end table\n");
63//
64// return 0;
65//}
diff --git a/src/daemon/https/includes/gnutls.h b/src/daemon/https/includes/gnutls.h
index 535e89ed..5178609b 100644
--- a/src/daemon/https/includes/gnutls.h
+++ b/src/daemon/https/includes/gnutls.h
@@ -93,8 +93,6 @@ extern "C"
93 GNUTLS_KX_RSA_EXPORT, 93 GNUTLS_KX_RSA_EXPORT,
94 GNUTLS_KX_SRP_RSA, 94 GNUTLS_KX_SRP_RSA,
95 GNUTLS_KX_SRP_DSS, 95 GNUTLS_KX_SRP_DSS,
96 GNUTLS_KX_PSK,
97 GNUTLS_KX_DHE_PSK
98 } gnutls_kx_algorithm_t; 96 } gnutls_kx_algorithm_t;
99 97
100 typedef enum 98 typedef enum
@@ -318,7 +316,7 @@ extern "C"
318 typedef struct gnutls_x509_privkey_int *gnutls_rsa_params_t; /* XXX ugly. */ 316 typedef struct gnutls_x509_privkey_int *gnutls_rsa_params_t; /* XXX ugly. */
319 317
320 struct gnutls_priority_st; 318 struct gnutls_priority_st;
321 typedef struct gnutls_priority_st *gnutls_priority_t; 319 typedef struct gnutls_priority_st * gnutls_priority_t;
322 320
323 typedef struct 321 typedef struct
324 { 322 {
@@ -508,7 +506,7 @@ extern "C"
508 506
509/* if you just want some defaults, use the following. 507/* if you just want some defaults, use the following.
510 */ 508 */
511 int gnutls_priority_init( gnutls_priority_t*, const char *priority, const char** err_pos); 509 int gnutls_priority_init( gnutls_priority_t * , const char *priority, const char** err_pos);
512 void gnutls_priority_deinit( gnutls_priority_t); 510 void gnutls_priority_deinit( gnutls_priority_t);
513 511
514 int gnutls_priority_set(gnutls_session_t session, gnutls_priority_t); 512 int gnutls_priority_set(gnutls_session_t session, gnutls_priority_t);
diff --git a/src/daemon/https/tls/auth_dh_common.c b/src/daemon/https/tls/auth_dh_common.c
index f1b82bf9..f6354cb6 100644
--- a/src/daemon/https/tls/auth_dh_common.c
+++ b/src/daemon/https/tls/auth_dh_common.c
@@ -23,7 +23,7 @@
23 */ 23 */
24 24
25/* This file contains common stuff in Ephemeral Diffie Hellman (DHE) and 25/* This file contains common stuff in Ephemeral Diffie Hellman (DHE) and
26 * Anonymous DH key exchange(DHA). These are used in the handshake procedure 26 * Anonymous DH key exchange(DHA). These are used in the handshake procedure
27 * of the certificate and anoymous authentication. 27 * of the certificate and anoymous authentication.
28 */ 28 */
29 29
@@ -86,29 +86,7 @@ _gnutls_proc_dh_common_client_kx (gnutls_session_t session,
86 _gnutls_mpi_release (&session->key->client_Y); 86 _gnutls_mpi_release (&session->key->client_Y);
87 _gnutls_mpi_release (&session->key->dh_secret); 87 _gnutls_mpi_release (&session->key->dh_secret);
88 88
89 89 ret = _gnutls_mpi_dprint (&session->key->key, session->key->KEY);
90 if (_gnutls_cipher_suite_get_kx_algo
91 (&session->security_parameters.current_cipher_suite)
92 != GNUTLS_KX_DHE_PSK)
93 {
94 ret = _gnutls_mpi_dprint (&session->key->key, session->key->KEY);
95 }
96 /* In DHE_PSK the key is set differently
97 else
98 {
99 gnutls_datum_t tmp_dh_key;
100 ret = _gnutls_mpi_dprint (&tmp_dh_key, session->key->KEY);
101 if (ret < 0)
102 {
103 gnutls_assert ();
104 return ret;
105 }
106
107 ret = _gnutls_set_psk_session_key (session, &tmp_dh_key);
108 _gnutls_free_datum (&tmp_dh_key);
109
110 }
111 */
112 90
113 _gnutls_mpi_release (&session->key->KEY); 91 _gnutls_mpi_release (&session->key->KEY);
114 92
@@ -170,27 +148,7 @@ _gnutls_gen_dh_common_client_kx (gnutls_session_t session, opaque ** data)
170 _gnutls_mpi_release (&session->key->client_p); 148 _gnutls_mpi_release (&session->key->client_p);
171 _gnutls_mpi_release (&session->key->client_g); 149 _gnutls_mpi_release (&session->key->client_g);
172 150
173 if (_gnutls_cipher_suite_get_kx_algo 151 ret = _gnutls_mpi_dprint (&session->key->key, session->key->KEY);
174 (&session->security_parameters.current_cipher_suite)
175 != GNUTLS_KX_DHE_PSK)
176 {
177 ret = _gnutls_mpi_dprint (&session->key->key, session->key->KEY);
178 }
179 /* In DHE_PSK the key is set differently
180 else
181 {
182 gnutls_datum_t tmp_dh_key;
183 ret = _gnutls_mpi_dprint (&tmp_dh_key, session->key->KEY);
184 if (ret < 0)
185 {
186 gnutls_assert ();
187 goto error;
188 }
189
190 ret = _gnutls_set_psk_session_key (session, &tmp_dh_key);
191 _gnutls_free_datum (&tmp_dh_key);
192
193 }*/
194 152
195 _gnutls_mpi_release (&session->key->KEY); 153 _gnutls_mpi_release (&session->key->KEY);
196 154
diff --git a/src/daemon/https/tls/gnutls_algorithms.c b/src/daemon/https/tls/gnutls_algorithms.c
index 82bf9bf6..9921d076 100644
--- a/src/daemon/https/tls/gnutls_algorithms.c
+++ b/src/daemon/https/tls/gnutls_algorithms.c
@@ -29,7 +29,7 @@
29/* x509 */ 29/* x509 */
30#include "common.h" 30#include "common.h"
31 31
32/* Cred type mappings to KX algorithms 32/* Cred type mappings to KX algorithms
33 * FIXME: The mappings are not 1-1. Some KX such as SRP_RSA require 33 * FIXME: The mappings are not 1-1. Some KX such as SRP_RSA require
34 * more than one credentials type. 34 * more than one credentials type.
35 */ 35 */
@@ -57,12 +57,6 @@ static const gnutls_cred_map cred_mappings[] = {
57 {GNUTLS_KX_DHE_RSA, 57 {GNUTLS_KX_DHE_RSA,
58 GNUTLS_CRD_CERTIFICATE, 58 GNUTLS_CRD_CERTIFICATE,
59 GNUTLS_CRD_CERTIFICATE}, 59 GNUTLS_CRD_CERTIFICATE},
60 {GNUTLS_KX_PSK,
61 GNUTLS_CRD_PSK,
62 GNUTLS_CRD_PSK},
63 {GNUTLS_KX_DHE_PSK,
64 GNUTLS_CRD_PSK,
65 GNUTLS_CRD_PSK},
66 {GNUTLS_KX_SRP, 60 {GNUTLS_KX_SRP,
67 GNUTLS_CRD_SRP, 61 GNUTLS_CRD_SRP,
68 GNUTLS_CRD_SRP}, 62 GNUTLS_CRD_SRP},
@@ -197,7 +191,7 @@ struct gnutls_cipher_entry
197}; 191};
198typedef struct gnutls_cipher_entry gnutls_cipher_entry; 192typedef struct gnutls_cipher_entry gnutls_cipher_entry;
199 193
200/* Note that all algorithms are in CBC or STREAM modes. 194/* Note that all algorithms are in CBC or STREAM modes.
201 * Do not add any algorithms in other modes (avoid modified algorithms). 195 * Do not add any algorithms in other modes (avoid modified algorithms).
202 * View first: "The order of encryption and authentication for 196 * View first: "The order of encryption and authentication for
203 * protecting communications" by Hugo Krawczyk - CRYPTO 2001 197 * protecting communications" by Hugo Krawczyk - CRYPTO 2001
@@ -614,34 +608,6 @@ static const gnutls_cipher_suite_entry cs_algorithms[] = {
614 GNUTLS_MAC_SHA1, GNUTLS_TLS1), 608 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
615#endif 609#endif
616 610
617 /* PSK */
618 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_PSK_SHA_ARCFOUR_SHA1,
619 GNUTLS_CIPHER_ARCFOUR, GNUTLS_KX_PSK,
620 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
621 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_PSK_SHA_3DES_EDE_CBC_SHA1,
622 GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_PSK,
623 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
624 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_PSK_SHA_AES_128_CBC_SHA1,
625 GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_PSK,
626 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
627 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_PSK_SHA_AES_256_CBC_SHA1,
628 GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_PSK,
629 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
630
631 /* DHE-PSK */
632 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_PSK_SHA_ARCFOUR_SHA1,
633 GNUTLS_CIPHER_ARCFOUR, GNUTLS_KX_DHE_PSK,
634 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
635 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_PSK_SHA_3DES_EDE_CBC_SHA1,
636 GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_DHE_PSK,
637 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
638 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_PSK_SHA_AES_128_CBC_SHA1,
639 GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_DHE_PSK,
640 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
641 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_PSK_SHA_AES_256_CBC_SHA1,
642 GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_DHE_PSK,
643 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
644
645 /* SRP */ 611 /* SRP */
646 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_3DES_EDE_CBC_SHA1, 612 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_3DES_EDE_CBC_SHA1,
647 GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_SRP, 613 GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_SRP,
@@ -1689,8 +1655,8 @@ _gnutls_qsort (gnutls_session_t session,
1689 compar); 1655 compar);
1690} 1656}
1691 1657
1692/* a compare function for KX algorithms (using priorities). 1658/* a compare function for KX algorithms (using priorities).
1693 * For use with qsort 1659 * For use with qsort
1694 */ 1660 */
1695static int 1661static int
1696_gnutls_compare_algo (gnutls_session_t session, 1662_gnutls_compare_algo (gnutls_session_t session,
@@ -1894,7 +1860,7 @@ _gnutls_supported_ciphersuites (gnutls_session_t session,
1894 1860
1895#define MIN_PRIVATE_COMP_ALGO 0xEF 1861#define MIN_PRIVATE_COMP_ALGO 0xEF
1896 1862
1897/* returns the TLS numbers of the compression methods we support 1863/* returns the TLS numbers of the compression methods we support
1898 */ 1864 */
1899#define SUPPORTED_COMPRESSION_METHODS session->internals.priorities.compression.algorithms 1865#define SUPPORTED_COMPRESSION_METHODS session->internals.priorities.compression.algorithms
1900int 1866int
diff --git a/src/daemon/https/tls/gnutls_global.c b/src/daemon/https/tls/gnutls_global.c
index d019dcda..822293ac 100644
--- a/src/daemon/https/tls/gnutls_global.c
+++ b/src/daemon/https/tls/gnutls_global.c
@@ -27,10 +27,19 @@
27#include <libtasn1.h> 27#include <libtasn1.h>
28#include <gnutls_dh.h> 28#include <gnutls_dh.h>
29 29
30/* this is used in order to make the multi-threaded initialization call to libgcrypt */
31#include <pthread.h>
32#include <gcrypt.h>
33/* TODO fix : needed by GCRY_THREAD_OPTION_PTHREAD_IMPL but missing otherwise */
34#define ENOMEM 12 /* Out of memory */
35
30#ifdef HAVE_WINSOCK 36#ifdef HAVE_WINSOCK
31# include <winsock2.h> 37# include <winsock2.h>
32#endif 38#endif
33 39
40
41GCRY_THREAD_OPTION_PTHREAD_IMPL;
42
34#include "gettext.h" 43#include "gettext.h"
35 44
36#define gnutls_log_func LOG_FUNC 45#define gnutls_log_func LOG_FUNC
@@ -57,7 +66,8 @@ ASN1_TYPE _gnutls_gnutls_asn;
57 * gnutls_log_func is of the form, 66 * gnutls_log_func is of the form,
58 * void (*gnutls_log_func)( int level, const char*); 67 * void (*gnutls_log_func)( int level, const char*);
59 **/ 68 **/
60void gnutls_global_set_log_function(gnutls_log_func log_func) 69void
70gnutls_global_set_log_function (gnutls_log_func log_func)
61{ 71{
62 _gnutls_log_func = log_func; 72 _gnutls_log_func = log_func;
63} 73}
@@ -74,7 +84,8 @@ void gnutls_global_set_log_function(gnutls_log_func log_func)
74 * Use a log level over 10 to enable all debugging options. 84 * Use a log level over 10 to enable all debugging options.
75 * 85 *
76 **/ 86 **/
77void gnutls_global_set_log_level(int level) 87void
88gnutls_global_set_log_level (int level)
78{ 89{
79 _gnutls_log_level = level; 90 _gnutls_log_level = level;
80} 91}
@@ -83,21 +94,20 @@ void gnutls_global_set_log_level(int level)
83/* default logging function */ 94/* default logging function */
84static void 95static void
85dlog (int level, const char *str) 96dlog (int level, const char *str)
86 { 97{
87 fputs (str, stderr); 98 fputs (str, stderr);
88 } 99}
89#endif 100#endif
90 101
91extern gnutls_alloc_function gnutls_secure_malloc; 102extern gnutls_alloc_function gnutls_secure_malloc;
92extern gnutls_alloc_function gnutls_malloc; 103extern gnutls_alloc_function gnutls_malloc;
93extern gnutls_free_function gnutls_free; 104extern gnutls_free_function gnutls_free;
94extern int (*_gnutls_is_secure_memory)(const void *); 105extern int (*_gnutls_is_secure_memory) (const void *);
95extern gnutls_realloc_function gnutls_realloc; 106extern gnutls_realloc_function gnutls_realloc;
96extern char *(*gnutls_strdup)(const char *); 107extern char *(*gnutls_strdup) (const char *);
97extern void *(*gnutls_calloc)(size_t, 108extern void *(*gnutls_calloc) (size_t, size_t);
98 size_t);
99 109
100int _gnutls_is_secure_mem_null(const void *); 110int _gnutls_is_secure_mem_null (const void *);
101 111
102/** 112/**
103 * gnutls_global_set_mem_functions - This function sets the memory allocation functions 113 * gnutls_global_set_mem_functions - This function sets the memory allocation functions
@@ -116,13 +126,14 @@ int _gnutls_is_secure_mem_null(const void *);
116 * This function must be called before gnutls_global_init() is called. 126 * This function must be called before gnutls_global_init() is called.
117 * 127 *
118 **/ 128 **/
119void gnutls_global_set_mem_functions(gnutls_alloc_function alloc_func, 129void
120 gnutls_alloc_function 130gnutls_global_set_mem_functions (gnutls_alloc_function alloc_func,
121 secure_alloc_func, 131 gnutls_alloc_function
122 gnutls_is_secure_function 132 secure_alloc_func,
123 is_secure_func, 133 gnutls_is_secure_function
124 gnutls_realloc_function realloc_func, 134 is_secure_func,
125 gnutls_free_function free_func) 135 gnutls_realloc_function realloc_func,
136 gnutls_free_function free_func)
126{ 137{
127 gnutls_secure_malloc = secure_alloc_func; 138 gnutls_secure_malloc = secure_alloc_func;
128 gnutls_malloc = alloc_func; 139 gnutls_malloc = alloc_func;
@@ -152,10 +163,10 @@ void gnutls_global_set_mem_functions(gnutls_alloc_function alloc_func,
152#ifdef DEBUG 163#ifdef DEBUG
153static void 164static void
154_gnutls_gcry_log_handler (void *dummy, int level, 165_gnutls_gcry_log_handler (void *dummy, int level,
155 const char *fmt, va_list list) 166 const char *fmt, va_list list)
156 { 167{
157 _gnutls_log (fmt, list); 168 _gnutls_log (fmt, list);
158 } 169}
159#endif 170#endif
160 171
161static int _gnutls_init = 0; 172static int _gnutls_init = 0;
@@ -190,7 +201,8 @@ static int _gnutls_init = 0;
190 * memory leak is also an option. 201 * memory leak is also an option.
191 * 202 *
192 **/ 203 **/
193int gnutls_global_init(void) 204int
205gnutls_global_init (void)
194{ 206{
195 int result = 0; 207 int result = 0;
196 int res; 208 int res;
@@ -200,41 +212,62 @@ int gnutls_global_init(void)
200 return; 212 return;
201 213
202#if HAVE_WINSOCK 214#if HAVE_WINSOCK
215 {
216 WORD requested;
217 WSADATA data;
218 int err;
219
220 requested = MAKEWORD (1, 1);
221 err = WSAStartup (requested, &data);
222 if (err != 0)
223 {
224 _gnutls_debug_log ("WSAStartup failed: %d.\n", err);
225 return GNUTLS_E_LIBRARY_VERSION_MISMATCH;
226 }
227
228 if (data.wVersion < requested)
229 {
230 _gnutls_debug_log ("WSAStartup version check failed (%d < %d).\n",
231 data.wVersion, requested);
232 WSACleanup ();
233 return GNUTLS_E_LIBRARY_VERSION_MISMATCH;
234 }
235 }
236#endif
237
238
239 // bindtextdomain("mhd", "./");
240
241 if (gcry_control (GCRYCTL_ANY_INITIALIZATION_P) == 0)
203 { 242 {
204 WORD requested; 243 const char *p;
205 WSADATA data;
206 int err;
207 244
208 requested = MAKEWORD (1, 1); 245 /* to enable multi-threading this call must precede any other call made to libgcrypt */
209 err = WSAStartup (requested, &data); 246 gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
210 if (err != 0)
211 {
212 _gnutls_debug_log ("WSAStartup failed: %d.\n", err);
213 return GNUTLS_E_LIBRARY_VERSION_MISMATCH;
214 }
215 247
216 if (data.wVersion < requested) 248 /* set p to point at the required version of gcrypt */
249 p = strchr(MHD_GCRYPT_VERSION, ':');
250 if (p == NULL)
251 p = MHD_GCRYPT_VERSION;
252 else
253 p++;
254
255 /* this call initializes libgcrypt */
256 if (gcry_check_version(p) == NULL)
217 { 257 {
218 _gnutls_debug_log ("WSAStartup version check failed (%d < %d).\n", 258 gnutls_assert();
219 data.wVersion, requested); 259 _gnutls_debug_log("Checking for libgcrypt failed '%s'\n", p);
220 WSACleanup (); 260 return GNUTLS_E_INCOMPATIBLE_GCRYPT_LIBRARY;
221 return GNUTLS_E_LIBRARY_VERSION_MISMATCH;
222 } 261 }
223 }
224#endif
225 262
226 // TODO rm ? bindtextdomain(PACKAGE, LOCALEDIR);
227
228 if (gcry_control(GCRYCTL_ANY_INITIALIZATION_P) == 0)
229 {
230 /* for gcrypt in order to be able to allocate memory */ 263 /* for gcrypt in order to be able to allocate memory */
231 gcry_set_allocation_handler(gnutls_malloc, gnutls_secure_malloc, 264 gcry_set_allocation_handler (gnutls_malloc, gnutls_secure_malloc,
232 _gnutls_is_secure_memory, gnutls_realloc, 265 _gnutls_is_secure_memory, gnutls_realloc,
233 gnutls_free); 266 gnutls_free);
234 267
235 /* gcry_control (GCRYCTL_DISABLE_INTERNAL_LOCKING, NULL, 0); */ 268 /* gcry_control (GCRYCTL_DISABLE_INTERNAL_LOCKING, NULL, 0); */
236 269
237 gcry_control(GCRYCTL_INITIALIZATION_FINISHED, NULL, 0); 270 gcry_control (GCRYCTL_INITIALIZATION_FINISHED, NULL, 0);
238 271
239#ifdef DEBUG 272#ifdef DEBUG
240 /* applications may want to override that, so we only use 273 /* applications may want to override that, so we only use
@@ -244,7 +277,7 @@ int gnutls_global_init(void)
244#endif 277#endif
245 } 278 }
246 279
247 if (gc_init() != GC_OK) 280 if (gc_init () != GC_OK)
248 { 281 {
249 gnutls_assert (); 282 gnutls_assert ();
250 _gnutls_debug_log ("Initializing crypto backend failed\n"); 283 _gnutls_debug_log ("Initializing crypto backend failed\n");
@@ -267,16 +300,16 @@ int gnutls_global_init(void)
267 return result; 300 return result;
268 } 301 }
269 302
270 res = asn1_array2tree(gnutls_asn1_tab, &_gnutls_gnutls_asn, NULL); 303 res = asn1_array2tree (gnutls_asn1_tab, &_gnutls_gnutls_asn, NULL);
271 if (res != ASN1_SUCCESS) 304 if (res != ASN1_SUCCESS)
272 { 305 {
273 asn1_delete_structure(&_gnutls_pkix1_asn); 306 asn1_delete_structure (&_gnutls_pkix1_asn);
274 result = _gnutls_asn2err(res); 307 result = _gnutls_asn2err (res);
275 return result; 308 return result;
276 } 309 }
277 310
278 /* Initialize the gcrypt (if used random generator) */ 311 /* Initialize the gcrypt (if used random generator) */
279 gc_pseudo_random(&c, 1); 312 gc_pseudo_random (&c, 1);
280 313
281 return result; 314 return result;
282} 315}
@@ -291,16 +324,17 @@ int gnutls_global_init(void)
291 * gnutls_global_init() for more information. 324 * gnutls_global_init() for more information.
292 * 325 *
293 **/ 326 **/
294void gnutls_global_deinit(void) 327void
328gnutls_global_deinit (void)
295{ 329{
296 if (_gnutls_init == 1) 330 if (_gnutls_init == 1)
297 { 331 {
298#if HAVE_WINSOCK 332#if HAVE_WINSOCK
299 WSACleanup (); 333 WSACleanup ();
300#endif 334#endif
301 asn1_delete_structure(&_gnutls_gnutls_asn); 335 asn1_delete_structure (&_gnutls_gnutls_asn);
302 asn1_delete_structure(&_gnutls_pkix1_asn); 336 asn1_delete_structure (&_gnutls_pkix1_asn);
303 gc_done(); 337 gc_done ();
304 } 338 }
305 _gnutls_init--; 339 _gnutls_init--;
306} 340}
@@ -322,8 +356,9 @@ void gnutls_global_deinit(void)
322 * PULL_FUNC is of the form, 356 * PULL_FUNC is of the form,
323 * ssize_t (*gnutls_pull_func)(gnutls_transport_ptr_t, void*, size_t); 357 * ssize_t (*gnutls_pull_func)(gnutls_transport_ptr_t, void*, size_t);
324 **/ 358 **/
325void gnutls_transport_set_pull_function(gnutls_session_t session, 359void
326 gnutls_pull_func pull_func) 360gnutls_transport_set_pull_function (gnutls_session_t session,
361 gnutls_pull_func pull_func)
327{ 362{
328 session->internals._gnutls_pull_func = pull_func; 363 session->internals._gnutls_pull_func = pull_func;
329} 364}
@@ -342,8 +377,9 @@ void gnutls_transport_set_pull_function(gnutls_session_t session,
342 * PUSH_FUNC is of the form, 377 * PUSH_FUNC is of the form,
343 * ssize_t (*gnutls_push_func)(gnutls_transport_ptr_t, const void*, size_t); 378 * ssize_t (*gnutls_push_func)(gnutls_transport_ptr_t, const void*, size_t);
344 **/ 379 **/
345void gnutls_transport_set_push_function(gnutls_session_t session, 380void
346 gnutls_push_func push_func) 381gnutls_transport_set_push_function (gnutls_session_t session,
382 gnutls_push_func push_func)
347{ 383{
348 session->internals._gnutls_push_func = push_func; 384 session->internals._gnutls_push_func = push_func;
349} 385}
@@ -366,9 +402,10 @@ void gnutls_transport_set_push_function(gnutls_session_t session,
366 * %NULL is passed to this function no check is done and only the 402 * %NULL is passed to this function no check is done and only the
367 * version string is returned. 403 * version string is returned.
368 **/ 404 **/
369const char * gnutls_check_version(const char *req_version) 405const char *
406gnutls_check_version (const char *req_version)
370{ 407{
371 if (!req_version || strverscmp(req_version, VERSION) <= 0) 408 if (!req_version || strverscmp (req_version, VERSION) <= 0)
372 return VERSION; 409 return VERSION;
373 410
374 return NULL; 411 return NULL;
diff --git a/src/daemon/https/tls/gnutls_int.h b/src/daemon/https/tls/gnutls_int.h
index 5161c966..c1e501a0 100644
--- a/src/daemon/https/tls/gnutls_int.h
+++ b/src/daemon/https/tls/gnutls_int.h
@@ -28,9 +28,9 @@
28 28
29#include <defines.h> 29#include <defines.h>
30 30
31#include <gnutls.h> 31#include "gnutls.h"
32#include <extra.h> 32#include "extra.h"
33#include <gnutls_mem.h> 33#include "gnutls_mem.h"
34 34
35/* FIXME: delete this once opencdk has reentrant keyring functions 35/* FIXME: delete this once opencdk has reentrant keyring functions
36 */ 36 */
@@ -210,7 +210,7 @@ struct gnutls_key_st
210 */ 210 */
211 void *auth_info; 211 void *auth_info;
212 gnutls_credentials_type_t auth_info_type; 212 gnutls_credentials_type_t auth_info_type;
213 int auth_info_size; /* needed in order to store to db for restoring 213 int auth_info_size; /* needed in order to store to db for restoring
214 */ 214 */
215 uint8_t crypt_algo; 215 uint8_t crypt_algo;
216 216
@@ -424,7 +424,7 @@ typedef struct
424typedef struct 424typedef struct
425 { 425 {
426 gnutls_buffer application_data_buffer; /* holds data to be delivered to application layer */ 426 gnutls_buffer application_data_buffer; /* holds data to be delivered to application layer */
427 gnutls_buffer handshake_hash_buffer; /* used to keep the last received handshake 427 gnutls_buffer handshake_hash_buffer; /* used to keep the last received handshake
428 * message */ 428 * message */
429 mac_hd_t handshake_mac_handle_sha; /* hash of the handshake messages */ 429 mac_hd_t handshake_mac_handle_sha; /* hash of the handshake messages */
430 mac_hd_t handshake_mac_handle_md5; /* hash of the handshake messages */ 430 mac_hd_t handshake_mac_handle_md5; /* hash of the handshake messages */
@@ -500,10 +500,12 @@ typedef struct
500 500
501 int expire_time; /* after expire_time seconds this session will expire */ 501 int expire_time; /* after expire_time seconds this session will expire */
502 struct mod_auth_st_int *auth_struct; /* used in handshake packets and KX algorithms */ 502 struct mod_auth_st_int *auth_struct; /* used in handshake packets and KX algorithms */
503
504 /* TODO rm */
503 int v2_hello; /* 0 if the client hello is v3+. 505 int v2_hello; /* 0 if the client hello is v3+.
504 * non-zero if we got a v2 hello. 506 * non-zero if we got a v2 hello.
505 */ 507 */
506 /* keeps the headers of the handshake packet 508 /* keeps the headers of the handshake packet
507 */ 509 */
508 handshake_header_buffer_st handshake_header_buffer; 510 handshake_header_buffer_st handshake_header_buffer;
509 511
@@ -653,8 +655,7 @@ struct gnutls_session_int
653 gnutls_key_st key; 655 gnutls_key_st key;
654 }; 656 };
655 657
656/* functions 658/* functions */
657 */
658void _gnutls_set_current_version(gnutls_session_t session, 659void _gnutls_set_current_version(gnutls_session_t session,
659 gnutls_protocol_t version); 660 gnutls_protocol_t version);
660 661
diff --git a/src/daemon/https/tls/gnutls_priority.c b/src/daemon/https/tls/gnutls_priority.c
index 1b20cd1a..29132f8a 100644
--- a/src/daemon/https/tls/gnutls_priority.c
+++ b/src/daemon/https/tls/gnutls_priority.c
@@ -32,10 +32,6 @@
32 32
33#define MAX_ELEMENTS 48 33#define MAX_ELEMENTS 48
34 34
35static void break_comma_list (char *etag,
36 char **broken_etag,
37 int *elements, int max_elements, char sep);
38
39/** 35/**
40 * gnutls_cipher_set_priority - Sets the priority on the ciphers supported by gnutls. 36 * gnutls_cipher_set_priority - Sets the priority on the ciphers supported by gnutls.
41 * @session: is a #gnutls_session_t structure. 37 * @session: is a #gnutls_session_t structure.
@@ -87,7 +83,6 @@ _set_priority (priority_st * st, const int *list)
87 } 83 }
88 84
89 return 0; 85 return 0;
90
91} 86}
92 87
93/** 88/**
@@ -215,7 +210,8 @@ gnutls_certificate_type_set_priority (gnutls_session_t session,
215} 210}
216 211
217static const int protocol_priority[] = { GNUTLS_TLS1_1, 212static const int protocol_priority[] = { GNUTLS_TLS1_1,
218 GNUTLS_TLS1_0, GNUTLS_SSL3, 213 GNUTLS_TLS1_0,
214 GNUTLS_SSL3,
219 0 215 0
220}; 216};
221 217
@@ -336,10 +332,6 @@ int
336gnutls_priority_init (gnutls_priority_t * priority_cache, 332gnutls_priority_init (gnutls_priority_t * priority_cache,
337 const char *priorities, const char **err_pos) 333 const char *priorities, const char **err_pos)
338{ 334{
339 int broken_list_size, i, j;
340 char *darg;
341 int algo;
342
343 *priority_cache = gnutls_calloc (1, sizeof (struct gnutls_priority_st)); 335 *priority_cache = gnutls_calloc (1, sizeof (struct gnutls_priority_st));
344 if (*priority_cache == NULL) 336 if (*priority_cache == NULL)
345 { 337 {
@@ -354,8 +346,8 @@ gnutls_priority_init (gnutls_priority_t * priority_cache,
354 _set_priority (&(*priority_cache)->mac, mac_priority_secure); 346 _set_priority (&(*priority_cache)->mac, mac_priority_secure);
355 _set_priority (&(*priority_cache)->cert_type, cert_type_priority); 347 _set_priority (&(*priority_cache)->cert_type, cert_type_priority);
356 _set_priority (&(*priority_cache)->compression, comp_priority); 348 _set_priority (&(*priority_cache)->compression, comp_priority);
357 (*priority_cache)->no_padding = 0;
358 349
350 (*priority_cache)->no_padding = 0;
359 return 0; 351 return 0;
360} 352}
361 353
@@ -412,40 +404,6 @@ gnutls_priority_set_direct (gnutls_session_t session,
412 return 0; 404 return 0;
413} 405}
414 406
415/* Breaks a list of "xxx", "yyy", to a character array, of
416 * MAX_COMMA_SEP_ELEMENTS size; Note that the given string is modified.
417 */
418static void
419break_comma_list (char *etag,
420 char **broken_etag,
421 int *elements, int max_elements, char sep)
422{
423 char *p = etag;
424 if (sep == 0)
425 sep = ',';
426
427 *elements = 0;
428
429 do
430 {
431 broken_etag[*elements] = p;
432
433 (*elements)++;
434
435 p = strchr (p, sep);
436 if (p)
437 {
438 *p = 0;
439 p++; /* move to next entry and skip white
440 * space.
441 */
442 while (*p == ' ')
443 p++;
444 }
445 }
446 while (p != NULL && *elements < max_elements);
447}
448
449/** 407/**
450 * gnutls_set_default_priority - Sets some default priority on the cipher suites supported by gnutls. 408 * gnutls_set_default_priority - Sets some default priority on the cipher suites supported by gnutls.
451 * @session: is a #gnutls_session_t structure. 409 * @session: is a #gnutls_session_t structure.
diff --git a/src/daemon/https/tls/gnutls_session_pack.c b/src/daemon/https/tls/gnutls_session_pack.c
index f18fe97a..c05e27cb 100644
--- a/src/daemon/https/tls/gnutls_session_pack.c
+++ b/src/daemon/https/tls/gnutls_session_pack.c
@@ -49,21 +49,6 @@ static int unpack_certificate_auth_info (gnutls_session_t,
49 const gnutls_datum_t * 49 const gnutls_datum_t *
50 packed_session); 50 packed_session);
51 51
52static int unpack_srp_auth_info (gnutls_session_t session,
53 const gnutls_datum_t * packed_session);
54static int pack_srp_auth_info (gnutls_session_t session,
55 gnutls_datum_t * packed_session);
56
57static int unpack_psk_auth_info (gnutls_session_t session,
58 const gnutls_datum_t * packed_session);
59static int pack_psk_auth_info (gnutls_session_t session,
60 gnutls_datum_t * packed_session);
61
62static int unpack_anon_auth_info (gnutls_session_t session,
63 const gnutls_datum_t * packed_session);
64static int pack_anon_auth_info (gnutls_session_t session,
65 gnutls_datum_t * packed_session);
66
67static int unpack_security_parameters (gnutls_session_t session, 52static int unpack_security_parameters (gnutls_session_t session,
68 const gnutls_datum_t * packed_session); 53 const gnutls_datum_t * packed_session);
69static int pack_security_parameters (gnutls_session_t session, 54static int pack_security_parameters (gnutls_session_t session,
@@ -230,7 +215,7 @@ _gnutls_session_unpack (gnutls_session_t session,
230} 215}
231 216
232 217
233/* Format: 218/* Format:
234 * 1 byte the credentials type 219 * 1 byte the credentials type
235 * 4 bytes the size of the whole structure 220 * 4 bytes the size of the whole structure
236 * DH stuff 221 * DH stuff
diff --git a/src/daemon/internal.c b/src/daemon/internal.c
index 8a56a6a6..a86c70d8 100644
--- a/src/daemon/internal.c
+++ b/src/daemon/internal.c
@@ -42,6 +42,13 @@ MHD_DLOG (const struct MHD_Daemon *daemon, const char *format, ...)
42 VFPRINTF (stderr, format, va); 42 VFPRINTF (stderr, format, va);
43 va_end (va); 43 va_end (va);
44} 44}
45
46void
47MHD_tls_log_func (int level, const char *str)
48{
49 fprintf (stdout, "|<%d>| %s", level, str);
50}
51
45#endif 52#endif
46 53
47/** 54/**
diff --git a/src/daemon/internal.h b/src/daemon/internal.h
index b916e22d..99566073 100644
--- a/src/daemon/internal.h
+++ b/src/daemon/internal.h
@@ -60,15 +60,13 @@
60 */ 60 */
61#define MHD_BUF_INC_SIZE 2048 61#define MHD_BUF_INC_SIZE 2048
62 62
63/* TLS Diffie-Hellman parameter */
64#define DH_BITS 1024
65
66#if HAVE_MESSAGES 63#if HAVE_MESSAGES
67/** 64/**
68 * fprintf-like helper function for logging debug 65 * fprintf-like helper function for logging debug
69 * messages. 66 * messages.
70 */ 67 */
71void MHD_DLOG (const struct MHD_Daemon *daemon, const char *format, ...); 68void MHD_DLOG (const struct MHD_Daemon *daemon, const char *format, ...);
69void MHD_tls_log_func (int level, const char *str);
72#endif 70#endif
73 71
74/** 72/**
@@ -288,6 +286,11 @@ enum MHD_CONNECTION_STATE
288 286
289}; 287};
290 288
289
290/**
291 * States in a state machine for a secure SSL/TLS connection.
292 *
293 */
291enum MHDS_CONNECTION_STATE 294enum MHDS_CONNECTION_STATE
292{ 295{
293 /* initial HTTPS state */ 296 /* initial HTTPS state */
@@ -297,20 +300,6 @@ enum MHDS_CONNECTION_STATE
297 300
298 MHDS_HANDSHAKE_COMPLETE, 301 MHDS_HANDSHAKE_COMPLETE,
299 302
300 /* while receiving an HTTP request through the encrypted channel */
301 MHDS_REQUEST_READING,
302
303 /* msg waiting to be forwarded to the internal HTTP daemon */
304 MHDS_REQUEST_READ,
305
306 /* http msg waiting to be sent */
307 MHDS_REPLY_READY,
308
309 /* while receiving an HTTP request through the encrypted channel */
310 MHDS_REPLY_SENDING,
311
312 MHDS_REPLY_SENT,
313
314 MHDS_CONNECTION_CLOSED 303 MHDS_CONNECTION_CLOSED
315}; 304};
316 305
@@ -558,9 +547,9 @@ struct MHD_Connection
558 int (*send_cls) (struct MHD_Connection * connection); 547 int (*send_cls) (struct MHD_Connection * connection);
559 548
560#if HTTPS_SUPPORT 549#if HTTPS_SUPPORT
550 /* TODO rename as this might be an SSL connection */
561 gnutls_session_t tls_session; 551 gnutls_session_t tls_session;
562#endif 552#endif
563
564}; 553};
565 554
566struct MHD_Daemon 555struct MHD_Daemon
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
index 2cf77f17..f65b0aba 100644
--- a/src/include/microhttpd.h
+++ b/src/include/microhttpd.h
@@ -349,6 +349,7 @@ enum MHD_OPTION
349 */ 349 */
350 MHD_OPTION_PER_IP_CONNECTION_LIMIT = 5, 350 MHD_OPTION_PER_IP_CONNECTION_LIMIT = 5,
351 351
352#if HTTPS_SUPPORT
352 // TODO rename 353 // TODO rename
353 /** 354 /**
354 * Filename for the private key (key.pem) to be used by the 355 * Filename for the private key (key.pem) to be used by the
@@ -383,6 +384,22 @@ enum MHD_OPTION
383 * This should be used in conjunction with 'MHD_OPTION_HTTPS_MEM_KEY'. 384 * This should be used in conjunction with 'MHD_OPTION_HTTPS_MEM_KEY'.
384 */ 385 */
385 MHD_OPTION_HTTPS_MEM_CERT = 9, 386 MHD_OPTION_HTTPS_MEM_CERT = 9,
387
388
389 /*
390 * Memory pointer to a zero terminated int array representing the
391 * cipher priority order to which the HTTPS daemon should adhere.
392 * "const int *" argument.
393 */
394 MHDS_CIPHER_ALGORITHM,
395
396 /*
397 * Memory pointer to a zero terminated int array representing the
398 * key exchange algorithm priority order to which the HTTPS daemon should adhere.
399 * "const int *" argument.
400 */
401 MHDS_KX_PRIORITY,
402#endif
386}; 403};
387 404
388/** 405/**
diff --git a/src/testcurl/https/Makefile.am b/src/testcurl/https/Makefile.am
index 36f97082..4dab41dc 100644
--- a/src/testcurl/https/Makefile.am
+++ b/src/testcurl/https/Makefile.am
@@ -1,6 +1,6 @@
1SUBDIRS = . 1SUBDIRS = .
2 2
3AM_CPPFLAGS = -ggdb \ 3AM_CPPFLAGS = \
4-I$(top_srcdir)/src/daemon/https/includes \ 4-I$(top_srcdir)/src/daemon/https/includes \
5-I$(top_srcdir)/src/daemon \ 5-I$(top_srcdir)/src/daemon \
6-I$(top_srcdir)/src/include 6-I$(top_srcdir)/src/include
diff --git a/src/testcurl/https/daemon_https_test_get.c b/src/testcurl/https/daemon_https_test_get.c
index 9cfb7ec4..981fc705 100644
--- a/src/testcurl/https/daemon_https_test_get.c
+++ b/src/testcurl/https/daemon_https_test_get.c
@@ -21,7 +21,7 @@
21/** 21/**
22 * @file daemon_HTTPS_test_get.c 22 * @file daemon_HTTPS_test_get.c
23 * @brief Testcase for libmicrohttpd GET operations 23 * @brief Testcase for libmicrohttpd GET operations
24 * @author lv-426 24 * @author Sagie Amir
25 */ 25 */
26 26
27#include "config.h" 27#include "config.h"
@@ -43,6 +43,11 @@
43 43
44#define PAGE_NOT_FOUND "<html><head><title>File not found</title></head><body>File not found</body></html>" 44#define PAGE_NOT_FOUND "<html><head><title>File not found</title></head><body>File not found</body></html>"
45 45
46#define MHD_E_SERVER_INIT "Error: failed to start server\n"
47#define MHD_E_TEST_FILE_CREAT "Error: failed to setup test file\n"
48#define MHD_E_CERT_FILE_CREAT "Error: failed to setup test certificate\n"
49#define MHD_E_KEY_FILE_CREAT "Error: failed to setup test certificate\n"
50
46/* Test Certificate */ 51/* Test Certificate */
47const char cert_pem[] = 52const char cert_pem[] =
48 "-----BEGIN CERTIFICATE-----\n" 53 "-----BEGIN CERTIFICATE-----\n"
@@ -173,9 +178,8 @@ http_ahc (void *cls, struct MHD_Connection *connection,
173 * @param test_fd: file to attempt transfering 178 * @param test_fd: file to attempt transfering
174 */ 179 */
175static int 180static int
176test_HTTPS_Get (FILE * test_fd, char * cipher_suite, int proto_version) 181test_daemon_get (FILE * test_fd, char *cipher_suite, int proto_version)
177{ 182{
178 struct MHD_Daemon *d;
179 CURL *c; 183 CURL *c;
180 struct CBC cbc; 184 struct CBC cbc;
181 CURLcode errornum; 185 CURLcode errornum;
@@ -192,7 +196,7 @@ test_HTTPS_Get (FILE * test_fd, char * cipher_suite, int proto_version)
192 196
193 mem_test_file_local = malloc (len); 197 mem_test_file_local = malloc (len);
194 fseek (test_fd, 0, SEEK_SET); 198 fseek (test_fd, 0, SEEK_SET);
195 if (fread (mem_test_file_local, sizeof(char), len, test_fd) != len) 199 if (fread (mem_test_file_local, sizeof (char), len, test_fd) != len)
196 { 200 {
197 fclose (test_fd); 201 fclose (test_fd);
198 fprintf (stderr, "Error: failed to read test file. %s\n", 202 fprintf (stderr, "Error: failed to read test file. %s\n",
@@ -202,30 +206,20 @@ test_HTTPS_Get (FILE * test_fd, char * cipher_suite, int proto_version)
202 206
203 if (NULL == (cbc.buf = malloc (sizeof (char) * len))) 207 if (NULL == (cbc.buf = malloc (sizeof (char) * len)))
204 { 208 {
205 fclose (test_fd); 209 fclose (test_fd);
206 fprintf (stderr, "Error: failed to read test file. %s\n", 210 fprintf (stderr, "Error: failed to read test file. %s\n",
207 strerror (errno)); 211 strerror (errno));
208 return -1; 212 return -1;
209 } 213 }
210 cbc.size = len; 214 cbc.size = len;
211 cbc.pos = 0; 215 cbc.pos = 0;
212 216
213 /* setup test */
214 d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_SSL |
215 MHD_USE_DEBUG, 42433,
216 NULL, NULL, &http_ahc, NULL,
217 MHD_OPTION_HTTPS_MEM_KEY, key_pem,
218 MHD_OPTION_HTTPS_MEM_CERT, cert_pem, MHD_OPTION_END);
219
220 if (d == NULL)
221 return 2;
222
223 /* construct url - this might use doc_path */ 217 /* construct url - this might use doc_path */
224 sprintf (url, "%s%s/%s", "https://localhost:42433", 218 sprintf (url, "%s%s/%s", "https://localhost:42433",
225 doc_path, test_file_name); 219 doc_path, test_file_name);
226 220
227 c = curl_easy_init (); 221 c = curl_easy_init ();
228 //curl_easy_setopt (c, CURLOPT_VERBOSE, 1); 222 // curl_easy_setopt (c, CURLOPT_VERBOSE, 1);
229 curl_easy_setopt (c, CURLOPT_URL, url); 223 curl_easy_setopt (c, CURLOPT_URL, url);
230 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); 224 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
231 curl_easy_setopt (c, CURLOPT_TIMEOUT, 10L); 225 curl_easy_setopt (c, CURLOPT_TIMEOUT, 10L);
@@ -252,36 +246,107 @@ test_HTTPS_Get (FILE * test_fd, char * cipher_suite, int proto_version)
252 fprintf (stderr, "curl_easy_perform failed: `%s'\n", 246 fprintf (stderr, "curl_easy_perform failed: `%s'\n",
253 curl_easy_strerror (errornum)); 247 curl_easy_strerror (errornum));
254 curl_easy_cleanup (c); 248 curl_easy_cleanup (c);
255 MHD_stop_daemon (d); 249 return errornum;
256 return 4;
257 } 250 }
258 251
259 curl_easy_cleanup (c); 252 curl_easy_cleanup (c);
260 MHD_stop_daemon (d);
261 253
262 if (memcmp (cbc.buf, mem_test_file_local, len) != 0) 254 if (memcmp (cbc.buf, mem_test_file_local, len) != 0)
263 { 255 {
264 fprintf (stderr, "Error: local file & received file differ. %s\n"); 256 fprintf (stderr, "Error: local file & received file differ.\n");
265 return 8; 257 return -1;
266 } 258 }
267 259
268 return 0; 260 return 0;
269} 261}
270 262
263/* perform a HTTP GET request via SSL/TLS */
264int
265test_secure_get (FILE * test_fd, char *cipher_suite, int proto_version)
266{
267
268 int ret;
269 struct MHD_Daemon *d;
270 d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_SSL |
271 MHD_USE_DEBUG, 42433,
272 NULL, NULL, &http_ahc, NULL,
273 MHD_OPTION_HTTPS_MEM_KEY, key_pem,
274 MHD_OPTION_HTTPS_MEM_CERT, cert_pem, MHD_OPTION_END);
275
276 if (d == NULL)
277 {
278 fprintf (stderr, MHD_E_SERVER_INIT);
279 return -1;
280 }
281
282 ret = test_daemon_get (test_fd, cipher_suite, proto_version);
283 MHD_stop_daemon (d);
284 return ret;
285}
286
287/* test server works with key & certificate files */
288int
289test_file_certificates (FILE * test_fd, char *cipher_suite, int proto_version)
290{
291 int ret;
292 struct MHD_Daemon *d;
293 FILE *cert_fd, *key_fd;
294 char cert_path[255], key_path[255];
295
296 sprintf (cert_path, "%s/%s", get_current_dir_name (), "cert.pem");
297 sprintf (key_path, "%s/%s", get_current_dir_name (), "key.pem");
298
299 if (NULL == (key_fd = fopen (key_path, "w+")))
300 {
301 fprintf (stderr, MHD_E_KEY_FILE_CREAT);
302 return -1;
303 }
304 if (NULL == (cert_fd = fopen (cert_path, "w+")))
305 {
306 fprintf (stderr, MHD_E_CERT_FILE_CREAT);
307 return -1;
308 }
309
310 fwrite (key_pem, strlen (key_pem), sizeof (char), key_fd);
311 fwrite (cert_pem, strlen (cert_pem), sizeof (char), cert_fd);
312 fclose (key_fd);
313 fclose (cert_fd);
314
315 d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_SSL |
316 MHD_USE_DEBUG, 42433,
317 NULL, NULL, &http_ahc, NULL,
318 MHD_OPTION_HTTPS_KEY_PATH, key_path,
319 MHD_OPTION_HTTPS_CERT_PATH, cert_path,
320 MHD_OPTION_END);
321
322 if (d == NULL)
323 {
324 fprintf (stderr, MHD_E_SERVER_INIT);
325 return -1;
326 }
327
328 ret = test_daemon_get (test_fd, cipher_suite, proto_version);
329 MHD_stop_daemon (d);
330
331 remove (cert_path);
332 remove (key_path);
333 return ret;
334}
335
271/* setup a temporary transfer test file */ 336/* setup a temporary transfer test file */
272FILE * 337FILE *
273setupTestFile () 338setupTestFile ()
274{ 339{
275 FILE *test_fd; 340 FILE *test_fd;
276 341
277 if ( NULL == (test_fd = fopen (test_file_name, "w+"))) 342 if (NULL == (test_fd = fopen (test_file_name, "w+")))
278 { 343 {
279 fprintf (stderr, "Error: failed to open `%s': %s\n", 344 fprintf (stderr, "Error: failed to open `%s': %s\n",
280 test_file_name, strerror (errno)); 345 test_file_name, strerror (errno));
281 return NULL; 346 return NULL;
282 } 347 }
283 if (fwrite (test_file_data, sizeof(char), strlen (test_file_data), test_fd) != 348 if (fwrite (test_file_data, sizeof (char), strlen (test_file_data), test_fd)
284 strlen (test_file_data)) 349 != strlen (test_file_data))
285 { 350 {
286 fprintf (stderr, "Error: failed to write `%s. %s'\n", 351 fprintf (stderr, "Error: failed to write `%s. %s'\n",
287 test_file_name, strerror (errno)); 352 test_file_name, strerror (errno));
@@ -302,19 +367,27 @@ main (int argc, char *const *argv)
302{ 367{
303 FILE *test_fd; 368 FILE *test_fd;
304 unsigned int errorCount = 0; 369 unsigned int errorCount = 0;
305 if ((test_fd = setupTestFile ()) == NULL ) 370
371 gnutls_global_set_log_level (0);
372
373 if ((test_fd = setupTestFile ()) == NULL)
306 { 374 {
307 return 16; 375 fprintf (stderr, MHD_E_TEST_FILE_CREAT);
376 return -1;
308 } 377 }
309 378
310 if (0 != curl_global_init (CURL_GLOBAL_ALL)) 379 if (0 != curl_global_init (CURL_GLOBAL_ALL))
311 { 380 {
312 fprintf (stderr, "Error (code: %u)\n", errorCount); 381 fprintf (stderr, "Error (code: %u)\n", errorCount);
313 return 32; 382 return -1;
314 } 383 }
315 384
316 errorCount += test_HTTPS_Get (test_fd, "AES256-SHA", CURL_SSLVERSION_SSLv3); 385 errorCount +=
317 errorCount += test_HTTPS_Get (test_fd, "AES256-SHA", CURL_SSLVERSION_TLSv1); 386 test_secure_get (test_fd, "AES256-SHA", CURL_SSLVERSION_TLSv1);
387 errorCount +=
388 test_secure_get (test_fd, "AES256-SHA", CURL_SSLVERSION_SSLv3);
389 errorCount +=
390 test_file_certificates (test_fd, "AES256-SHA", CURL_SSLVERSION_TLSv1);
318 391
319 if (errorCount != 0) 392 if (errorCount != 0)
320 fprintf (stderr, "Error (code: %u)\n", errorCount); 393 fprintf (stderr, "Error (code: %u)\n", errorCount);
@@ -322,6 +395,7 @@ main (int argc, char *const *argv)
322 curl_global_cleanup (); 395 curl_global_cleanup ();
323 fclose (test_fd); 396 fclose (test_fd);
324 397
325 398 remove (test_file_name);
399
326 return errorCount != 0; 400 return errorCount != 0;
327} 401}
diff --git a/src/testcurl/https/mhds_test_session_info.c b/src/testcurl/https/mhds_test_session_info.c
index c7aa3317..35266a19 100644
--- a/src/testcurl/https/mhds_test_session_info.c
+++ b/src/testcurl/https/mhds_test_session_info.c
@@ -21,7 +21,7 @@
21/** 21/**
22 * @file mhds_test_session_info.c 22 * @file mhds_test_session_info.c
23 * @brief Testcase for libmicrohttpd GET operations 23 * @brief Testcase for libmicrohttpd GET operations
24 * @author lv-426 24 * @author Sagie Amir
25 */ 25 */
26 26
27#include "config.h" 27#include "config.h"