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
);