1 /* SSL socket workshop */
8 #include <openssl/ssl.h>
9 #include <openssl/x509v3.h>
11 #elif defined(CONFIG_NSS_COMPAT_OSSL)
12 #include <nss_compat_ossl/nss_compat_ossl.h>
14 #elif defined(CONFIG_GNUTLS)
15 #include <gnutls/gnutls.h>
16 #include <gnutls/x509.h>
18 #error "Huh?! You have SSL enabled, but not OPENSSL nor GNUTLS!! And then you want exactly *what* from me?"
21 #ifdef HAVE_ARPA_INET_H
22 #include <arpa/inet.h>
25 #ifdef HAVE_NETINET_IN_H
26 #include <netinet/in.h>
31 #include "config/options.h"
32 #include "main/select.h"
33 #include "network/connection.h"
34 #include "network/socket.h"
35 #include "network/ssl/match-hostname.h"
36 #include "network/ssl/socket.h"
37 #include "network/ssl/ssl.h"
38 #include "protocol/uri.h"
39 #include "util/memory.h"
44 #define SSL_ERROR_WANT_READ2 9999 /* XXX */
45 #define SSL_ERROR_WANT_WRITE2 SSL_ERROR_WANT_WRITE
46 #define SSL_ERROR_SYSCALL2 SSL_ERROR_SYSCALL
47 #elif defined(CONFIG_GNUTLS)
48 #define SSL_ERROR_NONE GNUTLS_E_SUCCESS
49 #define SSL_ERROR_WANT_READ GNUTLS_E_AGAIN
50 #define SSL_ERROR_WANT_READ2 GNUTLS_E_INTERRUPTED
51 #define SSL_ERROR_WANT_WRITE GNUTLS_E_AGAIN
52 #define SSL_ERROR_WANT_WRITE2 GNUTLS_E_INTERRUPTED
53 #define SSL_ERROR_SYSCALL GNUTLS_E_PUSH_ERROR
54 #define SSL_ERROR_SYSCALL2 GNUTLS_E_PULL_ERROR
59 #define ssl_do_connect(socket) SSL_get_error(socket->ssl, SSL_connect(socket->ssl))
60 #define ssl_do_write(socket, data, len) SSL_write(socket->ssl, data, len)
61 #define ssl_do_read(socket, data, len) SSL_read(socket->ssl, data, len)
62 #define ssl_do_close(socket) /* Hmh? No idea.. */
64 #elif defined(CONFIG_GNUTLS)
66 #define ssl_do_connect(conn) gnutls_handshake(*((ssl_t *) socket->ssl))
67 #define ssl_do_write(socket, data, len) gnutls_record_send(*((ssl_t *) socket->ssl), data, len)
68 #define ssl_do_read(socket, data, len) gnutls_record_recv(*((ssl_t *) socket->ssl), data, len)
69 /* We probably don't handle this entirely correctly.. */
70 #define ssl_do_close(socket) gnutls_bye(*((ssl_t *) socket->ssl), GNUTLS_SHUT_RDWR);
75 /* Refuse to negotiate TLS 1.0 and later protocols on @socket->ssl.
76 * Without this, connecting to <https://www-s.uiuc.edu/> with GnuTLS
77 * 1.3.5 would result in an SSL error. The bug may be in the server
78 * (Netscape-Enterprise/3.6 SP3), in GnuTLS, or in ELinks; please log
79 * your findings to ELinks bug 712. */
81 ssl_set_no_tls(struct socket
*socket
)
84 ((ssl_t
*) socket
->ssl
)->options
|= SSL_OP_NO_TLSv1
;
85 #elif defined(CONFIG_GNUTLS)
86 /* There is another gnutls_priority_set_direct call elsewhere
87 * in ELinks. If you change the priorities here, please check
88 * whether that one needs to be changed as well.
90 * GnuTLS 2.12.x is said to support "-VERS-TLS-ALL" too, but
91 * that version hasn't yet been released as of May 2011. */
92 gnutls_priority_set_direct(*(ssl_t
*) socket
->ssl
,
93 "SECURE:-CTYPE-OPENPGP"
94 ":+VERS-SSL3.0:-VERS-TLS1.0"
95 ":-VERS-TLS1.1:-VERS-TLS1.2"
96 ":%SSL3_RECORD_VERSION",
104 verify_certificates(struct socket
*socket
)
106 gnutls_x509_crt_t cert
;
107 gnutls_session_t session
= *(ssl_t
*)socket
->ssl
;
108 struct connection
*conn
= socket
->conn
;
109 const gnutls_datum_t
*cert_list
;
110 unsigned char *hostname
;
112 unsigned int cert_list_size
, status
;
115 ret
= gnutls_certificate_verify_peers2(session
, &status
);
117 if (status
) return status
;
119 /* If the certificate is of a type for which verification has
120 * not yet been implemented, then reject it. This way, a fake
121 * server cannot avoid verification by using a strange type of
124 * OpenPGP certificates shouldn't even get this far anyway,
125 * because init_ssl_connection() tells GnuTLS to disable
126 * OpenPGP, and ELinks never calls
127 * gnutls_certificate_set_openpgp_keyring_file, so status
128 * should have been GNUTLS_CERT_SIGNER_NOT_FOUND. */
129 if (gnutls_certificate_type_get(session
) != GNUTLS_CRT_X509
)
132 if (gnutls_x509_crt_init(&cert
) < 0) {
136 cert_list
= gnutls_certificate_get_peers(session
, &cert_list_size
);
141 if (gnutls_x509_crt_import(cert
, &cert_list
[0],
142 GNUTLS_X509_FMT_DER
) < 0) {
145 if (gnutls_x509_crt_get_expiration_time(cert
) < time(NULL
)) {
146 gnutls_x509_crt_deinit(cert
);
150 if (gnutls_x509_crt_get_activation_time(cert
) > time(NULL
)) {
151 gnutls_x509_crt_deinit(cert
);
155 /* Because RFC 5280 defines dNSName as an IA5String, it can
156 * only contain ASCII characters. Internationalized domain
157 * names must thus be in Punycode form. Because GnuTLS 2.8.6
158 * does not itself support IDN, ELinks must convert. */
159 hostname
= get_uri_string(conn
->uri
, URI_HOST
| URI_IDN
);
160 if (!hostname
) return -6;
162 ret
= !gnutls_x509_crt_check_hostname(cert
, hostname
);
163 gnutls_x509_crt_deinit(cert
);
167 #endif /* CONFIG_GNUTLS */
171 /** Checks whether the host component of a URI matches a host name in
172 * the server certificate.
174 * @param[in] uri_host
175 * The host name (or IP address) to which the user wanted to connect.
176 * Should be in UTF-8.
177 * @param[in] cert_host_asn1
178 * A host name found in the server certificate: either as commonName
179 * in the subject field, or as a dNSName in the subjectAltName
180 * extension. This may contain wildcards, as specified in RFC 2818
184 * Nonzero if the host matches. Zero if it doesn't, or on error.
186 * If @a uri_host is an IP address literal rather than a host name,
187 * then this function returns 0, meaning that the host name does not match.
188 * According to RFC 2818, if the certificate is intended to match an
189 * IP address, then it must have that IP address as an iPAddress
190 * SubjectAltName, rather than in commonName. For comparing those,
191 * match_uri_host_ip() must be used instead of this function. */
193 match_uri_host_name(const unsigned char *uri_host
,
194 ASN1_STRING
*cert_host_asn1
)
196 const size_t uri_host_len
= strlen(uri_host
);
197 unsigned char *cert_host
= NULL
;
201 if (is_ip_address(uri_host
, uri_host_len
))
204 /* This function is used for both dNSName and commonName.
205 * Although dNSName is always an IA5 string, commonName allows
206 * many other encodings too. Normalize all to UTF-8. */
207 cert_host_len
= ASN1_STRING_to_UTF8(&cert_host
,
209 if (cert_host_len
< 0)
212 matched
= match_hostname_pattern(uri_host
, uri_host_len
,
213 cert_host
, cert_host_len
);
217 OPENSSL_free(cert_host
);
221 /** Checks whether the host component of a URI matches an IP address
222 * in the server certificate.
224 * @param[in] uri_host
225 * The IP address (or host name) to which the user wanted to connect.
226 * Should be in UTF-8.
227 * @param[in] cert_host_asn1
228 * An IP address found as iPAddress in the subjectAltName extension
229 * of the server certificate. According to RFC 5280 section 4.2.1.6,
230 * that is an octet string in network byte order. According to
231 * RFC 2818 section 3.1, wildcards are not allowed.
234 * Nonzero if the host matches. Zero if it doesn't, or on error.
236 * If @a uri_host is a host name rather than an IP address literal,
237 * then this function returns 0, meaning that the address does not match.
238 * This function does not try to resolve the host name to an IP address
239 * and compare that to @a cert_host_asn1, because such an approach would
240 * be vulnerable to DNS spoofing.
242 * This function does not support the address-and-netmask format used
243 * in the name constraints extension of a CA certificate (RFC 5280
244 * section 4.2.1.10). */
246 match_uri_host_ip(const unsigned char *uri_host
,
247 ASN1_OCTET_STRING
*cert_host_asn1
)
249 const unsigned char *cert_host_addr
= ASN1_STRING_data(cert_host_asn1
);
250 struct in_addr uri_host_in
;
252 struct in6_addr uri_host_in6
;
255 /* RFC 5280 defines the iPAddress alternative of GeneralName
256 * as an OCTET STRING. Verify that the type is indeed that.
257 * This is an assertion because, if someone puts the wrong
258 * type of data there, then it will not even be recognized as
259 * an iPAddress, and this function will not be called.
261 * (Because GeneralName is defined in an implicitly tagged
262 * ASN.1 module, the OCTET STRING tag is not part of the DER
263 * encoding. BER also allows a constructed encoding where
264 * each substring begins with the OCTET STRING tag; but ITU-T
265 * Rec. X.690 (07/2002) subclause 8.21 says those would be
266 * OCTET STRING even if the outer string were of some other
267 * type. "A Layman's Guide to a Subset of ASN.1, BER, and
268 * DER" (Kaliski, 1993) claims otherwise, though.) */
269 assert(ASN1_STRING_type(cert_host_asn1
) == V_ASN1_OCTET_STRING
);
270 if_assert_failed
return 0;
272 /* cert_host_addr, url_host_in, and url_host_in6 are all in
273 * network byte order. */
274 switch (ASN1_STRING_length(cert_host_asn1
)) {
276 return inet_aton(uri_host
, &uri_host_in
) != 0
277 && memcmp(cert_host_addr
, &uri_host_in
.s_addr
, 4) == 0;
281 return inet_pton(AF_INET6
, uri_host
, &uri_host_in6
) == 1
282 && memcmp(cert_host_addr
, &uri_host_in6
.s6_addr
, 16) == 0;
290 /** Verify one certificate in the server certificate chain.
291 * This callback is documented in SSL_set_verify(3). */
293 verify_callback(int preverify_ok
, X509_STORE_CTX
*ctx
)
297 struct socket
*socket
;
298 struct connection
*conn
;
299 unsigned char *host_in_uri
;
301 int saw_dns_name
= 0;
304 /* If OpenSSL already found a problem, keep that. */
308 /* Examine only the server certificate, not CA certificates. */
309 if (X509_STORE_CTX_get_error_depth(ctx
) != 0)
312 cert
= X509_STORE_CTX_get_current_cert(ctx
);
313 ssl
= X509_STORE_CTX_get_ex_data(ctx
, SSL_get_ex_data_X509_STORE_CTX_idx());
314 socket
= SSL_get_ex_data(ssl
, socket_SSL_ex_data_idx
);
316 host_in_uri
= get_uri_string(conn
->uri
, URI_HOST
| URI_IDN
);
320 /* RFC 5280 section 4.2.1.6 describes the subjectAltName extension.
321 * RFC 2818 section 3.1 says Common Name must not be used
322 * if dNSName is present. */
323 alts
= X509_get_ext_d2i(cert
, NID_subject_alt_name
, NULL
, NULL
);
329 alt_count
= sk_GENERAL_NAME_num(alts
);
330 for (alt_pos
= 0; !matched
&& alt_pos
< alt_count
; ++alt_pos
) {
331 alt
= sk_GENERAL_NAME_value(alts
, alt_pos
);
332 if (alt
->type
== GEN_DNS
) {
334 matched
= match_uri_host_name(host_in_uri
,
336 } else if (alt
->type
== GEN_IPADD
) {
337 matched
= match_uri_host_ip(host_in_uri
,
342 /* Free the GENERAL_NAMES list and each element. */
343 sk_GENERAL_NAME_pop_free(alts
, GENERAL_NAME_free
);
346 if (!matched
&& !saw_dns_name
) {
349 X509_NAME_ENTRY
*entry
= NULL
;
351 name
= X509_get_subject_name(cert
);
352 cn_index
= X509_NAME_get_index_by_NID(name
, NID_commonName
, -1);
354 entry
= X509_NAME_get_entry(name
, cn_index
);
356 matched
= match_uri_host_name(host_in_uri
,
357 X509_NAME_ENTRY_get_data(entry
));
360 mem_free(host_in_uri
);
364 #endif /* USE_OPENSSL */
367 ssl_want_read(struct socket
*socket
)
370 ssl_set_no_tls(socket
);
372 switch (ssl_do_connect(socket
)) {
375 if (get_opt_bool("connection.ssl.cert_verify", NULL
)
376 && verify_certificates(socket
)) {
377 socket
->ops
->retry(socket
, connection_state(S_SSL_ERROR
));
382 /* Report successful SSL connection setup. */
383 complete_connect_socket(socket
, NULL
, NULL
);
386 case SSL_ERROR_WANT_READ
:
387 case SSL_ERROR_WANT_READ2
:
391 socket
->no_tls
= !socket
->no_tls
;
392 socket
->ops
->retry(socket
, connection_state(S_SSL_ERROR
));
396 /* Return -1 on error, 0 or success. */
398 ssl_connect(struct socket
*socket
)
401 unsigned char *server_name
;
402 struct connection
*conn
= socket
->conn
;
404 /* TODO: Recode server_name to UTF-8. */
405 server_name
= get_uri_string(conn
->proxied_uri
, URI_HOST
);
407 socket
->ops
->done(socket
, connection_state(S_OUT_OF_MEM
));
411 /* RFC 3546 says literal IPv4 and IPv6 addresses are not allowed. */
412 if (is_ip_address(server_name
, strlen(server_name
)))
413 mem_free_set(&server_name
, NULL
);
415 if (init_ssl_connection(socket
, server_name
) == S_SSL_ERROR
) {
416 mem_free_if(server_name
);
417 socket
->ops
->done(socket
, connection_state(S_SSL_ERROR
));
421 mem_free_if(server_name
);
424 ssl_set_no_tls(socket
);
427 SSL_set_fd(socket
->ssl
, socket
->fd
);
429 if (get_opt_bool("connection.ssl.cert_verify", NULL
))
430 SSL_set_verify(socket
->ssl
, SSL_VERIFY_PEER
431 | SSL_VERIFY_FAIL_IF_NO_PEER_CERT
,
434 if (get_opt_bool("connection.ssl.client_cert.enable", NULL
)) {
435 unsigned char *client_cert
;
437 #ifdef CONFIG_NSS_COMPAT_OSSL
438 client_cert
= get_opt_str(
439 "connection.ssl.client_cert.nickname", NULL
);
441 client_cert
= get_opt_str(
442 "connection.ssl.client_cert.file", NULL
);
445 client_cert
= getenv("X509_CLIENT_CERT");
446 if (client_cert
&& !*client_cert
)
451 #ifdef CONFIG_NSS_COMPAT_OSSL
452 SSL_CTX_use_certificate_chain_file(
456 SSL_CTX
*ctx
= ((SSL
*) socket
->ssl
)->ctx
;
458 SSL_CTX_use_certificate_chain_file(ctx
, client_cert
);
459 SSL_CTX_use_PrivateKey_file(ctx
, client_cert
,
465 #elif defined(CONFIG_GNUTLS)
466 /* GnuTLS uses function pointers for network I/O. The default
467 * functions take a file descriptor, but it must be passed in
468 * as a pointer. GnuTLS uses the GNUTLS_INT_TO_POINTER and
469 * GNUTLS_POINTER_TO_INT macros for these conversions, but
470 * those are unfortunately not in any public header. So
471 * ELinks must just cast the pointer the best it can and hope
472 * that the conversions match. */
473 gnutls_transport_set_ptr(*((ssl_t
*) socket
->ssl
),
474 (gnutls_transport_ptr
) (longptr_T
) socket
->fd
);
476 /* TODO: Some certificates fuss. --pasky */
479 ret
= ssl_do_connect(socket
);
482 case SSL_ERROR_WANT_READ
:
483 case SSL_ERROR_WANT_READ2
:
484 socket
->ops
->set_state(socket
, connection_state(S_SSL_NEG
));
485 set_handlers(socket
->fd
, (select_handler_T
) ssl_want_read
,
486 NULL
, (select_handler_T
) dns_exception
, socket
);
491 if (!get_opt_bool("connection.ssl.cert_verify", NULL
))
494 if (!verify_certificates(socket
))
499 if (ret
!= SSL_ERROR_NONE
) {
500 /* DBG("sslerr %s", gnutls_strerror(ret)); */
501 socket
->no_tls
= !socket
->no_tls
;
504 connect_socket(socket
, connection_state(S_SSL_ERROR
));
511 /* Return enum socket_error on error, bytes written on success. */
513 ssl_write(struct socket
*socket
, unsigned char *data
, int len
)
515 ssize_t wr
= ssl_do_write(socket
, data
, len
);
519 int err
= SSL_get_error(socket
->ssl
, wr
);
520 #elif defined(CONFIG_GNUTLS)
523 if (err
== SSL_ERROR_WANT_WRITE
||
524 err
== SSL_ERROR_WANT_WRITE2
) {
528 if (!wr
) return SOCKET_CANT_WRITE
;
530 if (err
== SSL_ERROR_SYSCALL
)
531 return SOCKET_SYSCALL_ERROR
;
534 return SOCKET_INTERNAL_ERROR
;
540 /* Return enum socket_error on error, bytes read on success. */
542 ssl_read(struct socket
*socket
, unsigned char *data
, int len
)
544 ssize_t rd
= ssl_do_read(socket
, data
, len
);
548 int err
= SSL_get_error(socket
->ssl
, rd
);
549 #elif defined(CONFIG_GNUTLS)
554 if (err
== GNUTLS_E_REHANDSHAKE
)
558 if (err
== SSL_ERROR_WANT_READ
||
559 err
== SSL_ERROR_WANT_READ2
) {
560 return SOCKET_SSL_WANT_READ
;
563 if (!rd
) return SOCKET_CANT_READ
;
565 if (err
== SSL_ERROR_SYSCALL2
)
566 return SOCKET_SYSCALL_ERROR
;
569 return SOCKET_INTERNAL_ERROR
;
576 ssl_close(struct socket
*socket
)
578 ssl_do_close(socket
);
579 done_ssl_connection(socket
);