1 /* SSL socket workshop */
8 #include <openssl/ssl.h>
9 #elif defined(CONFIG_GNUTLS)
10 #include <gnutls/gnutls.h>
12 #error "Huh?! You have SSL enabled, but not OPENSSL nor GNUTLS!! And then you want exactly *what* from me?"
19 #include "config/options.h"
20 #include "main/select.h"
21 #include "network/connection.h"
22 #include "network/socket.h"
23 #include "network/ssl/socket.h"
24 #include "network/ssl/ssl.h"
25 #include "util/memory.h"
30 #define SSL_ERROR_WANT_READ2 9999 /* XXX */
31 #define SSL_ERROR_WANT_WRITE2 SSL_ERROR_WANT_WRITE
32 #define SSL_ERROR_SYSCALL2 SSL_ERROR_SYSCALL
33 #elif defined(CONFIG_GNUTLS)
34 #define SSL_ERROR_NONE GNUTLS_E_SUCCESS
35 #define SSL_ERROR_WANT_READ GNUTLS_E_AGAIN
36 #define SSL_ERROR_WANT_READ2 GNUTLS_E_INTERRUPTED
37 #define SSL_ERROR_WANT_WRITE GNUTLS_E_AGAIN
38 #define SSL_ERROR_WANT_WRITE2 GNUTLS_E_INTERRUPTED
39 #define SSL_ERROR_SYSCALL GNUTLS_E_PUSH_ERROR
40 #define SSL_ERROR_SYSCALL2 GNUTLS_E_PULL_ERROR
45 #define ssl_do_connect(socket) SSL_get_error(socket->ssl, SSL_connect(socket->ssl))
46 #define ssl_do_write(socket, data, len) SSL_write(socket->ssl, data, len)
47 #define ssl_do_read(socket, data, len) SSL_read(socket->ssl, data, len)
48 #define ssl_do_close(socket) /* Hmh? No idea.. */
50 #elif defined(CONFIG_GNUTLS)
52 #define ssl_do_connect(conn) gnutls_handshake(*((ssl_t *) socket->ssl))
53 #define ssl_do_write(socket, data, len) gnutls_record_send(*((ssl_t *) socket->ssl), data, len)
54 #define ssl_do_read(socket, data, len) gnutls_record_recv(*((ssl_t *) socket->ssl), data, len)
55 /* We probably don't handle this entirely correctly.. */
56 #define ssl_do_close(socket) gnutls_bye(*((ssl_t *) socket->ssl), GNUTLS_SHUT_RDWR);
61 /* Refuse to negotiate TLS 1.0 and later protocols on @socket->ssl.
62 * Without this, connecting to <https://www-s.uiuc.edu/> with GnuTLS
63 * 1.3.5 would result in an SSL error. The bug may be in the server
64 * (Netscape-Enterprise/3.6 SP3), in GnuTLS, or in ELinks; please log
65 * your findings to ELinks bug 712. */
67 ssl_set_no_tls(struct socket
*socket
)
70 ((ssl_t
*) socket
->ssl
)->options
|= SSL_OP_NO_TLSv1
;
71 #elif defined(CONFIG_GNUTLS)
73 /* GnuTLS does not support SSLv2 because it is "insecure".
74 * That leaves only SSLv3. */
75 static const int protocol_priority
[] = {
80 gnutls_protocol_set_priority(*(ssl_t
*) socket
->ssl
, protocol_priority
);
86 ssl_want_read(struct socket
*socket
)
89 ssl_set_no_tls(socket
);
91 switch (ssl_do_connect(socket
)) {
94 if (get_opt_bool("connection.ssl.cert_verify")
95 && gnutls_certificate_verify_peers(*((ssl_t
*) socket
->ssl
))) {
96 socket
->ops
->retry(socket
, connection_state(S_SSL_ERROR
));
101 /* Report successful SSL connection setup. */
102 complete_connect_socket(socket
, NULL
, NULL
);
105 case SSL_ERROR_WANT_READ
:
106 case SSL_ERROR_WANT_READ2
:
110 socket
->no_tls
= !socket
->no_tls
;
111 socket
->ops
->retry(socket
, connection_state(S_SSL_ERROR
));
115 /* Return -1 on error, 0 or success. */
117 ssl_connect(struct socket
*socket
)
121 if (init_ssl_connection(socket
) == S_SSL_ERROR
) {
122 socket
->ops
->done(socket
, connection_state(S_SSL_ERROR
));
127 ssl_set_no_tls(socket
);
129 #ifdef CONFIG_OPENSSL
130 SSL_set_fd(socket
->ssl
, socket
->fd
);
132 if (get_opt_bool("connection.ssl.cert_verify"))
133 SSL_set_verify(socket
->ssl
, SSL_VERIFY_PEER
134 | SSL_VERIFY_FAIL_IF_NO_PEER_CERT
,
137 if (get_opt_bool("connection.ssl.client_cert.enable")) {
138 unsigned char *client_cert
;
140 client_cert
= get_opt_str("connection.ssl.client_cert.file");
142 client_cert
= getenv("X509_CLIENT_CERT");
143 if (client_cert
&& !*client_cert
)
148 SSL_CTX
*ctx
= ((SSL
*) socket
->ssl
)->ctx
;
150 SSL_CTX_use_certificate_chain_file(ctx
, client_cert
);
151 SSL_CTX_use_PrivateKey_file(ctx
, client_cert
,
156 #elif defined(CONFIG_GNUTLS)
157 /* GnuTLS uses function pointers for network I/O. The default
158 * functions take a file descriptor, but it must be passed in
159 * as a pointer. GnuTLS uses the GNUTLS_INT_TO_POINTER and
160 * GNUTLS_POINTER_TO_INT macros for these conversions, but
161 * those are unfortunately not in any public header. So
162 * ELinks must just cast the pointer the best it can and hope
163 * that the conversions match. */
164 gnutls_transport_set_ptr(*((ssl_t
*) socket
->ssl
),
165 (gnutls_transport_ptr
) (longptr_T
) socket
->fd
);
167 /* TODO: Some certificates fuss. --pasky */
170 ret
= ssl_do_connect(socket
);
173 case SSL_ERROR_WANT_READ
:
174 case SSL_ERROR_WANT_READ2
:
175 socket
->ops
->set_state(socket
, connection_state(S_SSL_NEG
));
176 set_handlers(socket
->fd
, (select_handler_T
) ssl_want_read
,
177 NULL
, (select_handler_T
) dns_exception
, socket
);
182 if (!get_opt_bool("connection.ssl.cert_verify"))
185 if (!gnutls_certificate_verify_peers(*((ssl_t
*) socket
->ssl
)))
190 if (ret
!= SSL_ERROR_NONE
) {
191 /* DBG("sslerr %s", gnutls_strerror(ret)); */
192 socket
->no_tls
= !socket
->no_tls
;
195 connect_socket(socket
, connection_state(S_SSL_ERROR
));
202 /* Return enum socket_error on error, bytes written on success. */
204 ssl_write(struct socket
*socket
, unsigned char *data
, int len
)
206 ssize_t wr
= ssl_do_write(socket
, data
, len
);
209 #ifdef CONFIG_OPENSSL
210 int err
= SSL_get_error(socket
->ssl
, wr
);
211 #elif defined(CONFIG_GNUTLS)
214 if (err
== SSL_ERROR_WANT_WRITE
||
215 err
== SSL_ERROR_WANT_WRITE2
) {
219 if (!wr
) return SOCKET_CANT_WRITE
;
221 if (err
== SSL_ERROR_SYSCALL
)
222 return SOCKET_SYSCALL_ERROR
;
225 return SOCKET_INTERNAL_ERROR
;
231 /* Return enum socket_error on error, bytes read on success. */
233 ssl_read(struct socket
*socket
, unsigned char *data
, int len
)
235 ssize_t rd
= ssl_do_read(socket
, data
, len
);
238 #ifdef CONFIG_OPENSSL
239 int err
= SSL_get_error(socket
->ssl
, rd
);
240 #elif defined(CONFIG_GNUTLS)
245 if (err
== GNUTLS_E_REHANDSHAKE
)
249 if (err
== SSL_ERROR_WANT_READ
||
250 err
== SSL_ERROR_WANT_READ2
) {
251 return SOCKET_SSL_WANT_READ
;
254 if (!rd
) return SOCKET_CANT_READ
;
256 if (err
== SSL_ERROR_SYSCALL2
)
257 return SOCKET_SYSCALL_ERROR
;
260 return SOCKET_INTERNAL_ERROR
;
267 ssl_close(struct socket
*socket
)
269 ssl_do_close(socket
);
270 done_ssl_connection(socket
);