2 * uhttpd - Tiny single-threaded httpd - TLS helper
4 * Copyright (C) 2010 Jo-Philipp Wich <xm@subsignal.org>
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
20 #include "uhttpd-tls.h"
21 #include "uhttpd-utils.h"
24 #define dbg(...) syslog(LOG_INFO, __VA_ARGS__)
26 SSL_CTX * uh_tls_ctx_init(void)
30 SSL_load_error_strings();
34 if ((c = SSL_CTX_new(SSLv23_server_method())) != NULL)
36 if ((c = SSL_CTX_new(TLSv1_server_method())) != NULL)
38 SSL_CTX_set_verify(c, SSL_VERIFY_NONE, NULL);
43 int uh_tls_ctx_cert(SSL_CTX *c, const char *file)
47 if( (rv = SSL_CTX_use_certificate_file(c, file, SSL_FILETYPE_PEM)) < 1 )
48 rv = SSL_CTX_use_certificate_file(c, file, SSL_FILETYPE_ASN1);
53 int uh_tls_ctx_key(SSL_CTX *c, const char *file)
57 if( (rv = SSL_CTX_use_PrivateKey_file(c, file, SSL_FILETYPE_PEM)) < 1 )
58 rv = SSL_CTX_use_PrivateKey_file(c, file, SSL_FILETYPE_ASN1);
63 void uh_tls_ctx_free(struct listener *l)
69 int uh_tls_client_accept(struct client *c)
74 if (!c->server || !c->server->tls)
80 if ((c->tls = SSL_new(c->server->tls)))
82 if ((rv = SSL_set_fd(c->tls, fd)) < 1)
91 rv = SSL_accept(c->tls);
92 err = SSL_get_error(c->tls, rv);
95 (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE))
97 if (uh_socket_wait(fd, c->server->conf->network_timeout,
98 (err == SSL_ERROR_WANT_WRITE)))
100 D("TLS: accept(%d) = retry\n", fd);
104 D("TLS: accept(%d) = timeout\n", fd);
108 D("TLS: accept(%d) = %p\n", fd, c->tls);
112 #ifdef TLS_IS_OPENSSL
113 D("TLS: accept(%d) = failed: %s\n",
114 fd, ERR_error_string(ERR_get_error(), NULL));
127 int uh_tls_client_recv(struct client *c, char *buf, int len)
129 int rv = SSL_read(c->tls, buf, len);
130 int err = SSL_get_error(c->tls, 0);
132 if ((rv == -1) && (err == SSL_ERROR_WANT_READ))
134 D("TLS: recv(%d, %d) = retry\n", c->fd.fd, len);
139 D("TLS: recv(%d, %d) = %d\n", c->fd.fd, len, rv);
143 int uh_tls_client_send(struct client *c, const char *buf, int len)
145 int rv = SSL_write(c->tls, buf, len);
146 int err = SSL_get_error(c->tls, 0);
148 if ((rv == -1) && (err == SSL_ERROR_WANT_WRITE))
150 D("TLS: send(%d, %d) = retry\n", c->fd.fd, len);
155 D("TLS: send(%d, %d) = %d\n", c->fd.fd, len, rv);
159 void uh_tls_client_close(struct client *c)
163 D("TLS: close(%d)\n", c->fd.fd);
165 SSL_shutdown(c->tls);