1
/* SSL socket workshop */
2
/* $Id: connect.c,v 1.86 2004/11/04 21:10:10 jonas Exp $ */
9
#include <openssl/ssl.h>
10
#elif defined(CONFIG_GNUTLS)
11
#include <gnutls/gnutls.h>
13
#error "Huh?! You have SSL enabled, but not OPENSSL nor GNUTLS!! And then you want exactly *what* from me?"
20
#include "config/options.h"
21
#include "lowlevel/connect.h"
22
#include "lowlevel/dns.h"
23
#include "lowlevel/select.h"
24
#include "sched/connection.h"
25
#include "ssl/connect.h"
27
#include "util/memory.h"
32
#define SSL_ERROR_WANT_READ2 9999 /* XXX */
33
#define SSL_ERROR_WANT_WRITE2 SSL_ERROR_WANT_WRITE
34
#define SSL_ERROR_SYSCALL2 SSL_ERROR_SYSCALL
35
#elif defined(CONFIG_GNUTLS)
36
#define SSL_ERROR_NONE GNUTLS_E_SUCCESS
37
#define SSL_ERROR_WANT_READ GNUTLS_E_AGAIN
38
#define SSL_ERROR_WANT_READ2 GNUTLS_E_INTERRUPTED
39
#define SSL_ERROR_WANT_WRITE GNUTLS_E_AGAIN
40
#define SSL_ERROR_WANT_WRITE2 GNUTLS_E_INTERRUPTED
41
#define SSL_ERROR_SYSCALL GNUTLS_E_PUSH_ERROR
42
#define SSL_ERROR_SYSCALL2 GNUTLS_E_PULL_ERROR
47
#define ssl_do_connect(socket) SSL_get_error(socket->ssl, SSL_connect(socket->ssl))
48
#define ssl_do_write(socket, data, len) SSL_write(socket->ssl, data, len)
49
#define ssl_do_read(socket, rb) SSL_read(socket->ssl, rb->data + rb->len, rb->freespace)
50
#define ssl_do_close(socket) /* Hmh? No idea.. */
52
#elif defined(CONFIG_GNUTLS)
54
#define ssl_do_connect(conn) gnutls_handshake(*((ssl_t *) socket->ssl))
55
#define ssl_do_write(socket, data, len) gnutls_record_send(*((ssl_t *) socket->ssl), data, len)
56
#define ssl_do_read(socket, rb) gnutls_record_recv(*((ssl_t *) socket->ssl), rb->data + rb->len, rb->freespace)
57
/* We probably don't handle this entirely correctly.. */
58
#define ssl_do_close(socket) gnutls_bye(*((ssl_t *) socket->ssl), GNUTLS_SHUT_RDWR);
64
ssl_set_no_tls(struct connection_socket *socket)
67
((ssl_t *) socket->ssl)->options |= SSL_OP_NO_TLSv1;
68
#elif defined(CONFIG_GNUTLS)
69
/* We do a little more work here, setting up all these priorities (like
70
* they couldn't have some reasonable defaults there).. */
73
int protocol_priority[3] = {
79
gnutls_protocol_set_priority(*((ssl_t *) socket->ssl), protocol_priority);
82
/* Note that I have no clue about these; I just put all I found here
83
* ;-). It is all a bit confusing for me, and I just want this to work.
84
* Feel free to send me patch removing useless superfluous bloat,
85
* thanks in advance. --pasky */
88
int cipher_priority[5] = {
89
GNUTLS_CIPHER_RIJNDAEL_128_CBC,
90
GNUTLS_CIPHER_3DES_CBC,
91
GNUTLS_CIPHER_ARCFOUR,
92
GNUTLS_CIPHER_RIJNDAEL_256_CBC,
96
gnutls_cipher_set_priority(*((ssl_t *) socket->ssl), cipher_priority);
100
/* Does any httpd support this..? ;) */
101
int comp_priority[3] = {
107
gnutls_compression_set_priority(*((ssl_t *) socket->ssl), comp_priority);
111
int kx_priority[5] = {
115
/* Looks like we don't want SRP, do we? */
120
gnutls_kx_set_priority(*((ssl_t *) socket->ssl), kx_priority);
124
int mac_priority[3] = {
130
gnutls_mac_set_priority(*((ssl_t *) socket->ssl), mac_priority);
134
int cert_type_priority[2] = {
136
/* We don't link with -extra now; by time of writing
137
* this, it's unclear where OpenPGP will end up. */
141
gnutls_certificate_type_set_priority(*((ssl_t *) socket->ssl), cert_type_priority);
144
gnutls_dh_set_prime_bits(*((ssl_t *) socket->ssl), 1024);
149
ssl_want_read(struct connection *conn)
151
struct conn_info *conn_info = conn->conn_info;
152
struct connection_socket *socket;
154
if (!conn_info) return;
156
socket = conn_info->socket;
159
ssl_set_no_tls(socket);
161
switch (ssl_do_connect(socket)) {
164
if (get_opt_bool("connection.ssl.cert_verify")
165
&& gnutls_certificate_verify_peers(*((ssl_t *) socket->ssl))) {
166
retry_conn_with_state(conn, S_SSL_ERROR);
171
done_connection_info(conn);
173
case SSL_ERROR_WANT_READ:
174
case SSL_ERROR_WANT_READ2:
179
retry_conn_with_state(conn, S_SSL_ERROR);
183
/* Return -1 on error, 0 or success. */
185
ssl_connect(struct connection *conn, struct connection_socket *socket)
189
if (init_ssl_connection(&conn->socket) == S_SSL_ERROR) {
190
abort_conn_with_state(conn, S_SSL_ERROR);
195
ssl_set_no_tls(socket);
197
#ifdef CONFIG_OPENSSL
198
SSL_set_fd(socket->ssl, socket->fd);
200
if (get_opt_bool("connection.ssl.cert_verify"))
201
SSL_set_verify(socket->ssl, SSL_VERIFY_PEER
202
| SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
205
if (get_opt_bool("connection.ssl.client_cert.enable")) {
206
unsigned char *client_cert;
208
client_cert = get_opt_str("connection.ssl.client_cert.file");
210
client_cert = getenv("X509_CLIENT_CERT");
211
if (client_cert && !*client_cert)
216
SSL_CTX *ctx = ((SSL *) socket->ssl)->ctx;
218
SSL_CTX_use_certificate_chain_file(ctx, client_cert);
219
SSL_CTX_use_PrivateKey_file(ctx, client_cert,
224
#elif defined(CONFIG_GNUTLS)
225
gnutls_transport_set_ptr(*((ssl_t *) socket->ssl),
226
(gnutls_transport_ptr) socket->fd);
228
/* TODO: Some certificates fuss. --pasky */
231
ret = ssl_do_connect(socket);
234
case SSL_ERROR_WANT_READ:
235
case SSL_ERROR_WANT_READ2:
236
set_connection_state(conn, S_SSL_NEG);
237
set_handlers(socket->fd, (void (*)(void *)) ssl_want_read,
238
NULL, dns_exception, conn);
243
if (!get_opt_bool("connection.ssl.cert_verify"))
246
if (!gnutls_certificate_verify_peers(*((ssl_t *) socket->ssl)))
251
if (ret != SSL_ERROR_NONE) {
252
/* DBG("sslerr %s", gnutls_strerror(ret)); */
256
set_connection_state(conn, S_SSL_ERROR);
257
close_socket(NULL, conn->conn_info->socket);
265
/* Return -1 on error, wr or success. */
267
ssl_write(struct connection *conn, struct connection_socket *socket,
268
unsigned char *data, int len)
270
int wr = ssl_do_write(socket, data, len);
273
#ifdef CONFIG_OPENSSL
274
int err = SSL_get_error(socket->ssl, wr);
275
#elif defined(CONFIG_GNUTLS)
279
if (err == SSL_ERROR_WANT_WRITE ||
280
err == SSL_ERROR_WANT_WRITE2) {
284
set_connection_state(conn, wr ? (err == SSL_ERROR_SYSCALL ? -errno
288
if (!wr || err == SSL_ERROR_SYSCALL)
289
retry_connection(conn);
291
abort_connection(conn);
299
/* Return -1 on error, rd or success. */
301
ssl_read(struct connection *conn, struct connection_socket *socket,
302
struct read_buffer *rb)
304
int rd = ssl_do_read(socket, rb);
307
#ifdef CONFIG_OPENSSL
308
int err = SSL_get_error(socket->ssl, rd);
309
#elif defined(CONFIG_GNUTLS)
314
if (err == GNUTLS_E_REHANDSHAKE)
318
if (err == SSL_ERROR_WANT_READ ||
319
err == SSL_ERROR_WANT_READ2) {
320
read_from_socket(conn, rb->socket, rb, rb->done);
324
if (rb->close != READ_BUFFER_RETRY_ONCLOSE && !rd) {
325
rb->close = READ_BUFFER_END;
330
set_connection_state(conn, rd ? (err == SSL_ERROR_SYSCALL2 ? -errno
336
if (!rd || err == SSL_ERROR_SYSCALL2)
337
retry_connection(conn);
339
abort_connection(conn);
348
ssl_close(struct connection *conn, struct connection_socket *socket)
350
ssl_do_close(socket);
351
done_ssl_connection(socket);