2 * OpenConnect (SSL + DTLS) VPN client
4 * Copyright © 2008-2012 Intel Corporation.
6 * Author: David Woodhouse <dwmw2@infradead.org>
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * version 2.1, as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to:
20 * Free Software Foundation, Inc.
21 * 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301 USA
26 #include <sys/types.h>
27 #include <netinet/in.h>
28 #include <arpa/inet.h>
31 #include <openssl/ssl.h>
32 #include <openssl/err.h>
33 #include <openssl/engine.h>
34 #include <openssl/evp.h>
35 #include <openssl/rand.h>
36 #include <openssl/pkcs12.h>
37 #include <openssl/x509v3.h>
38 #include <openssl/x509.h>
39 #include <openssl/bio.h>
41 #include "openconnect-internal.h"
43 int openconnect_sha1(unsigned char *result, void *data, int len)
48 EVP_Digest(data, len, result, NULL, EVP_sha1(), NULL);
49 EVP_MD_CTX_cleanup(&c);
54 int openconnect_get_cert_DER(struct openconnect_info *vpninfo,
55 OPENCONNECT_X509 *cert, unsigned char **buf)
57 BIO *bp = BIO_new(BIO_s_mem());
61 if (!i2d_X509_bio(bp, cert)) {
66 BIO_get_mem_ptr(bp, &certinfo);
73 memcpy(*buf, certinfo->data, l);
78 int openconnect_random(void *bytes, int len)
80 if (RAND_bytes(bytes, len) != 1)
85 /* Helper functions for reading/writing lines over SSL.
86 We could use cURL for the HTTP stuff, but it's overkill */
88 int openconnect_SSL_write(struct openconnect_info *vpninfo, char *buf, size_t len)
90 size_t orig_len = len;
93 int done = SSL_write(vpninfo->https_ssl, buf, len);
98 int err = SSL_get_error(vpninfo->https_ssl, done);
99 fd_set wr_set, rd_set;
100 int maxfd = vpninfo->ssl_fd;
105 if (err == SSL_ERROR_WANT_READ)
106 FD_SET(vpninfo->ssl_fd, &rd_set);
107 else if (err == SSL_ERROR_WANT_WRITE)
108 FD_SET(vpninfo->ssl_fd, &wr_set);
110 vpn_progress(vpninfo, PRG_ERR, _("Failed to write to SSL socket\n"));
111 openconnect_report_ssl_errors(vpninfo);
114 if (vpninfo->cancel_fd != -1) {
115 FD_SET(vpninfo->cancel_fd, &rd_set);
116 if (vpninfo->cancel_fd > vpninfo->ssl_fd)
117 maxfd = vpninfo->cancel_fd;
119 select(maxfd + 1, &rd_set, &wr_set, NULL, NULL);
120 if (vpninfo->cancel_fd != -1 &&
121 FD_ISSET(vpninfo->cancel_fd, &rd_set)) {
122 vpn_progress(vpninfo, PRG_ERR, _("SSL write cancelled\n"));
130 int openconnect_SSL_read(struct openconnect_info *vpninfo, char *buf, size_t len)
134 while ((done = SSL_read(vpninfo->https_ssl, buf, len)) == -1) {
135 int err = SSL_get_error(vpninfo->https_ssl, done);
136 fd_set wr_set, rd_set;
137 int maxfd = vpninfo->ssl_fd;
142 if (err == SSL_ERROR_WANT_READ)
143 FD_SET(vpninfo->ssl_fd, &rd_set);
144 else if (err == SSL_ERROR_WANT_WRITE)
145 FD_SET(vpninfo->ssl_fd, &wr_set);
147 vpn_progress(vpninfo, PRG_ERR, _("Failed to read from SSL socket\n"));
148 openconnect_report_ssl_errors(vpninfo);
151 if (vpninfo->cancel_fd != -1) {
152 FD_SET(vpninfo->cancel_fd, &rd_set);
153 if (vpninfo->cancel_fd > vpninfo->ssl_fd)
154 maxfd = vpninfo->cancel_fd;
156 select(maxfd + 1, &rd_set, &wr_set, NULL, NULL);
157 if (vpninfo->cancel_fd != -1 &&
158 FD_ISSET(vpninfo->cancel_fd, &rd_set)) {
159 vpn_progress(vpninfo, PRG_ERR, _("SSL read cancelled\n"));
166 int openconnect_SSL_gets(struct openconnect_info *vpninfo, char *buf, size_t len)
175 ret = SSL_read(vpninfo->https_ssl, buf + i, 1);
177 if (buf[i] == '\n') {
179 if (i && buf[i-1] == '\r') {
192 fd_set rd_set, wr_set;
193 int maxfd = vpninfo->ssl_fd;
198 ret = SSL_get_error(vpninfo->https_ssl, ret);
199 if (ret == SSL_ERROR_WANT_READ)
200 FD_SET(vpninfo->ssl_fd, &rd_set);
201 else if (ret == SSL_ERROR_WANT_WRITE)
202 FD_SET(vpninfo->ssl_fd, &wr_set);
204 vpn_progress(vpninfo, PRG_ERR, _("Failed to read from SSL socket\n"));
205 openconnect_report_ssl_errors(vpninfo);
209 if (vpninfo->cancel_fd != -1) {
210 FD_SET(vpninfo->cancel_fd, &rd_set);
211 if (vpninfo->cancel_fd > vpninfo->ssl_fd)
212 maxfd = vpninfo->cancel_fd;
214 select(maxfd + 1, &rd_set, &wr_set, NULL, NULL);
215 if (vpninfo->cancel_fd != -1 &&
216 FD_ISSET(vpninfo->cancel_fd, &rd_set)) {
217 vpn_progress(vpninfo, PRG_ERR, _("SSL read cancelled\n"));
228 /* UI handling. All this just to handle the PIN callback from the TPM ENGINE,
229 and turn it into a call to our ->process_auth_form function */
232 struct openconnect_info *vpninfo;
233 struct oc_form_opt **last_opt;
234 struct oc_auth_form form;
238 struct oc_form_opt opt;
242 /* Ick. But there is no way to pass this sanely through OpenSSL */
243 static struct openconnect_info *ui_vpninfo;
245 static int ui_open(UI *ui)
247 struct openconnect_info *vpninfo = ui_vpninfo; /* Ick */
248 struct ui_data *ui_data;
250 if (!vpninfo || !vpninfo->process_auth_form)
253 ui_data = malloc(sizeof(*ui_data));
257 memset(ui_data, 0, sizeof(*ui_data));
258 ui_data->last_opt = &ui_data->form.opts;
259 ui_data->vpninfo = vpninfo;
260 ui_data->form.auth_id = (char *)"openssl_ui";
261 UI_add_user_data(ui, ui_data);
266 static int ui_write(UI *ui, UI_STRING *uis)
268 struct ui_data *ui_data = UI_get0_user_data(ui);
269 struct ui_form_opt *opt;
271 switch(UI_get_string_type(uis)) {
273 ui_data->form.error = (char *)UI_get0_output_string(uis);
276 ui_data->form.message = (char *)UI_get0_output_string(uis);
279 opt = malloc(sizeof(*opt));
282 memset(opt, 0, sizeof(*opt));
284 opt->opt.label = opt->opt.name = (char *)UI_get0_output_string(uis);
285 if (UI_get_input_flags(uis) & UI_INPUT_FLAG_ECHO)
286 opt->opt.type = OC_FORM_OPT_TEXT;
288 opt->opt.type = OC_FORM_OPT_PASSWORD;
289 *(ui_data->last_opt) = &opt->opt;
290 ui_data->last_opt = &opt->opt.next;
294 fprintf(stderr, "Unhandled SSL UI request type %d\n",
295 UI_get_string_type(uis));
301 static int ui_flush(UI *ui)
303 struct ui_data *ui_data = UI_get0_user_data(ui);
304 struct openconnect_info *vpninfo = ui_data->vpninfo;
305 struct ui_form_opt *opt;
308 ret = vpninfo->process_auth_form(vpninfo->cbdata, &ui_data->form);
312 for (opt = (struct ui_form_opt *)ui_data->form.opts; opt;
313 opt = (struct ui_form_opt *)opt->opt.next) {
314 if (opt->opt.value && opt->uis)
315 UI_set_result(ui, opt->uis, opt->opt.value);
320 static int ui_close(UI *ui)
322 struct ui_data *ui_data = UI_get0_user_data(ui);
323 struct ui_form_opt *opt, *next_opt;
325 opt = (struct ui_form_opt *)ui_data->form.opts;
327 next_opt = (struct ui_form_opt *)opt->opt.next;
329 free(opt->opt.value);
334 UI_add_user_data(ui, NULL);
339 static UI_METHOD *create_openssl_ui(struct openconnect_info *vpninfo)
341 UI_METHOD *ui_method = UI_create_method((char *)"AnyConnect VPN UI");
343 /* There is a race condition here because of the use of the
344 static ui_vpninfo pointer. This sucks, but it's OpenSSL's
345 fault and in practice it's *never* going to hurt us.
347 This UI is only used for loading certificates from a TPM; for
348 PKCS#12 and PEM files we hook the passphrase request differently.
349 The ui_vpninfo variable is set here, and is used from ui_open()
350 when the TPM ENGINE decides it needs to ask the user for a PIN.
352 The race condition exists because theoretically, there
353 could be more than one thread using libopenconnect and
354 trying to authenticate to a VPN server, within the *same*
355 process. And if *both* are using certificates from the TPM,
356 and *both* manage to be within that short window of time
357 between setting ui_vpninfo and invoking ui_open() to fetch
358 the PIN, then one connection's ->process_auth_form() could
359 get a PIN request for the *other* connection.
361 However, the only thing that ever does run libopenconnect more
362 than once from the same process is KDE's NetworkManager support,
363 and NetworkManager doesn't *support* having more than one VPN
364 connected anyway, so first that would have to be fixed and then
365 you'd have to connect to two VPNs simultaneously by clicking
366 'connect' on both at *exactly* the same time and then getting
369 Oh, and the KDE support won't be using OpenSSL anyway because of
370 licensing conflicts... so although this sucks, I'm not going to
373 ui_vpninfo = vpninfo;
375 /* Set up a UI method of our own for password/passphrase requests */
376 UI_method_set_opener(ui_method, ui_open);
377 UI_method_set_writer(ui_method, ui_write);
378 UI_method_set_flusher(ui_method, ui_flush);
379 UI_method_set_closer(ui_method, ui_close);
384 static int pem_pw_cb(char *buf, int len, int w, void *v)
386 struct openconnect_info *vpninfo = v;
390 if (vpninfo->cert_password) {
391 pass = vpninfo->cert_password;
392 vpninfo->cert_password = NULL;
393 } else if (request_passphrase(vpninfo, "openconnect_pem",
394 &pass, _("Enter PEM pass phrase:")))
400 vpn_progress(vpninfo, PRG_ERR,
401 _("PEM password too long (%d >= %d)\n"),
407 memcpy(buf, pass, plen+1);
412 static int load_pkcs12_certificate(struct openconnect_info *vpninfo, PKCS12 *p12)
414 EVP_PKEY *pkey = NULL;
420 pass = vpninfo->cert_password;
421 vpninfo->cert_password = NULL;
423 /* We do this every time round the loop, to work around a bug in
424 OpenSSL < 1.0.0-beta2 -- where the stack at *ca will be freed
425 when PKCS12_parse() returns an error, but *ca is left pointing
426 to the freed memory. */
428 if (!pass && request_passphrase(vpninfo, "openconnect_pkcs12", &pass,
429 _("Enter PKCS#12 pass phrase:")) < 0) {
433 if (!PKCS12_parse(p12, pass, &pkey, &cert, &ca)) {
434 unsigned long err = ERR_peek_error();
436 openconnect_report_ssl_errors(vpninfo);
438 if (ERR_GET_LIB(err) == ERR_LIB_PKCS12 &&
439 ERR_GET_FUNC(err) == PKCS12_F_PKCS12_PARSE &&
440 ERR_GET_REASON(err) == PKCS12_R_MAC_VERIFY_FAILURE) {
441 vpn_progress(vpninfo, PRG_ERR,
442 _("Parse PKCS#12 failed (wrong passphrase?)\n"));
448 vpn_progress(vpninfo, PRG_ERR,
449 _("Parse PKCS#12 failed (see above errors)\n"));
457 vpninfo->cert_x509 = cert;
458 SSL_CTX_use_certificate(vpninfo->https_ctx, cert);
459 X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf));
460 vpn_progress(vpninfo, PRG_INFO,
461 _("Using client certificate '%s'\n"), buf);
463 vpn_progress(vpninfo, PRG_ERR,
464 _("PKCS#12 contained no certificate!"));
469 SSL_CTX_use_PrivateKey(vpninfo->https_ctx, pkey);
472 vpn_progress(vpninfo, PRG_ERR,
473 _("PKCS#12 contained no private key!"));
477 /* Only include supporting certificates which are actually necessary */
481 for (i = 0; i < sk_X509_num(ca); i++) {
482 X509 *cert2 = sk_X509_value(ca, i);
483 if (X509_check_issued(cert2, cert) == X509_V_OK) {
488 if (X509_check_issued(cert2, cert2) == X509_V_OK)
491 X509_NAME_oneline(X509_get_subject_name(cert2),
493 vpn_progress(vpninfo, PRG_DEBUG,
494 _("Extra cert from PKCS#12: '%s'\n"), buf);
495 CRYPTO_add(&cert2->references, 1, CRYPTO_LOCK_X509);
496 SSL_CTX_add_extra_chain_cert(vpninfo->https_ctx, cert2);
501 sk_X509_pop_free(ca, X509_free);
509 static int load_tpm_certificate(struct openconnect_info *vpninfo)
513 UI_METHOD *meth = NULL;
516 ENGINE_load_builtin_engines();
518 e = ENGINE_by_id("tpm");
520 vpn_progress(vpninfo, PRG_ERR, _("Can't load TPM engine.\n"));
521 openconnect_report_ssl_errors(vpninfo);
524 if (!ENGINE_init(e) || !ENGINE_set_default_RSA(e) ||
525 !ENGINE_set_default_RAND(e)) {
526 vpn_progress(vpninfo, PRG_ERR, _("Failed to init TPM engine\n"));
527 openconnect_report_ssl_errors(vpninfo);
532 if (vpninfo->cert_password) {
533 if (!ENGINE_ctrl_cmd(e, "PIN", strlen(vpninfo->cert_password),
534 vpninfo->cert_password, NULL, 0)) {
535 vpn_progress(vpninfo, PRG_ERR,
536 _("Failed to set TPM SRK password\n"));
537 openconnect_report_ssl_errors(vpninfo);
539 vpninfo->cert_password = NULL;
540 free(vpninfo->cert_password);
542 /* Provide our own UI method to handle the PIN callback. */
543 meth = create_openssl_ui(vpninfo);
545 key = ENGINE_load_private_key(e, vpninfo->sslkey, meth, NULL);
547 UI_destroy_method(meth);
549 vpn_progress(vpninfo, PRG_ERR,
550 _("Failed to load TPM private key\n"));
551 openconnect_report_ssl_errors(vpninfo);
555 if (!SSL_CTX_use_PrivateKey(vpninfo->https_ctx, key)) {
556 vpn_progress(vpninfo, PRG_ERR, _("Add key from TPM failed\n"));
557 openconnect_report_ssl_errors(vpninfo);
567 static int load_tpm_certificate(struct openconnect_info *vpninfo)
569 vpn_progress(vpninfo, PRG_ERR,
570 _("This version of OpenConnect was built without TPM support\n"));
575 static int reload_pem_cert(struct openconnect_info *vpninfo)
577 BIO *b = BIO_new(BIO_s_file_internal());
583 if (BIO_read_filename(b, vpninfo->cert) <= 0) {
586 vpn_progress(vpninfo, PRG_ERR,
587 _("Failed to reload X509 cert for expiry check\n"));
588 openconnect_report_ssl_errors(vpninfo);
591 vpninfo->cert_x509 = PEM_read_bio_X509_AUX(b, NULL, NULL, NULL);
593 if (!vpninfo->cert_x509)
596 X509_NAME_oneline(X509_get_subject_name(vpninfo->cert_x509), buf, sizeof(buf));
597 vpn_progress(vpninfo, PRG_INFO,
598 _("Using client certificate '%s'\n"), buf);
603 #ifdef ANDROID_KEYSTORE
604 static BIO *BIO_from_keystore(struct openconnect_info *vpninfo, const char *item)
606 unsigned char *content;
609 const char *p = item + 9;
611 /* Skip first two slashes if the user has given it as
612 keystore://foo ... */
618 len = keystore_fetch(p, &content);
620 vpn_progress(vpninfo, PRG_ERR,
621 _("Failed to load item '%s' from keystore: %s\n"),
622 p, keystore_strerror(len));
625 if (!(b = BIO_new(BIO_s_mem())) || BIO_write(b, content, len) != len) {
626 vpn_progress(vpninfo, PRG_ERR,
627 _("Failed to create BIO for keystore item '%s'\n"),
638 static int is_pem_password_error(struct openconnect_info *vpninfo)
640 unsigned long err = ERR_peek_error();
642 openconnect_report_ssl_errors(vpninfo);
644 #ifndef EVP_F_EVP_DECRYPTFINAL_EX
645 #define EVP_F_EVP_DECRYPTFINAL_EX EVP_F_EVP_DECRYPTFINAL
647 /* If the user fat-fingered the passphrase, try again */
648 if (ERR_GET_LIB(err) == ERR_LIB_EVP &&
649 ERR_GET_FUNC(err) == EVP_F_EVP_DECRYPTFINAL_EX &&
650 ERR_GET_REASON(err) == EVP_R_BAD_DECRYPT) {
651 vpn_progress(vpninfo, PRG_ERR,
652 _("Loading private key failed (wrong passphrase?)\n"));
657 vpn_progress(vpninfo, PRG_ERR,
658 _("Loading private key failed (see above errors)\n"));
662 static int load_certificate(struct openconnect_info *vpninfo)
664 if (!strncmp(vpninfo->sslkey, "pkcs11:", 7) ||
665 !strncmp(vpninfo->cert, "pkcs11:", 7)) {
666 vpn_progress(vpninfo, PRG_ERR,
667 _("This binary built without PKCS#11 support\n"));
671 vpn_progress(vpninfo, PRG_TRACE,
672 _("Using certificate file %s\n"), vpninfo->cert);
674 if (strncmp(vpninfo->cert, "keystore:", 9) &&
675 (vpninfo->cert_type == CERT_TYPE_PKCS12 ||
676 vpninfo->cert_type == CERT_TYPE_UNKNOWN)) {
680 f = fopen(vpninfo->cert, "r");
682 vpn_progress(vpninfo, PRG_ERR,
683 _("Failed to open certificate file %s: %s\n"),
684 vpninfo->cert, strerror(errno));
687 p12 = d2i_PKCS12_fp(f, NULL);
690 return load_pkcs12_certificate(vpninfo, p12);
693 if (vpninfo->cert_type == CERT_TYPE_PKCS12) {
694 vpn_progress(vpninfo, PRG_ERR, _("Read PKCS#12 failed\n"));
695 openconnect_report_ssl_errors(vpninfo);
698 /* Clear error and fall through to see if it's a PEM file... */
702 /* It's PEM or TPM now, and either way we need to load the plain cert: */
703 #ifdef ANDROID_KEYSTORE
704 if (!strncmp(vpninfo->cert, "keystore:", 9)) {
705 BIO *b = BIO_from_keystore(vpninfo, vpninfo->cert);
708 vpninfo->cert_x509 = PEM_read_bio_X509_AUX(b, NULL, pem_pw_cb, vpninfo);
710 if (!vpninfo->cert_x509) {
711 vpn_progress(vpninfo, PRG_ERR,
712 _("Failed to load X509 certificate from keystore\n"));
713 openconnect_report_ssl_errors(vpninfo);
716 if (!SSL_CTX_use_certificate(vpninfo->https_ctx, vpninfo->cert_x509)) {
717 vpn_progress(vpninfo, PRG_ERR,
718 _("Failed to use X509 certificate from keystore\n"));
719 openconnect_report_ssl_errors(vpninfo);
720 X509_free(vpninfo->cert_x509);
721 vpninfo->cert_x509 = NULL;
725 #endif /* ANDROID_KEYSTORE */
727 if (!SSL_CTX_use_certificate_chain_file(vpninfo->https_ctx,
729 vpn_progress(vpninfo, PRG_ERR,
730 _("Loading certificate failed\n"));
731 openconnect_report_ssl_errors(vpninfo);
735 /* Ew, we can't get it back from the OpenSSL CTX in any sane fashion */
736 reload_pem_cert(vpninfo);
739 #ifdef ANDROID_KEYSTORE
740 if (!strncmp(vpninfo->sslkey, "keystore:", 9)) {
745 b = BIO_from_keystore(vpninfo, vpninfo->sslkey);
748 key = PEM_read_bio_PrivateKey(b, NULL, pem_pw_cb, vpninfo);
751 if (is_pem_password_error(vpninfo))
755 if (!SSL_CTX_use_PrivateKey(vpninfo->https_ctx, key)) {
756 vpn_progress(vpninfo, PRG_ERR,
757 _("Failed to use private key from keystore\n"));
759 X509_free(vpninfo->cert_x509);
760 vpninfo->cert_x509 = NULL;
767 if (vpninfo->cert_type == CERT_TYPE_UNKNOWN) {
768 FILE *f = fopen(vpninfo->sslkey, "r");
772 vpn_progress(vpninfo, PRG_ERR,
773 _("Failed to open private key file %s: %s\n"),
774 vpninfo->cert, strerror(errno));
779 while (fgets(buf, 255, f)) {
780 if (!strcmp(buf, "-----BEGIN TSS KEY BLOB-----\n")) {
781 vpninfo->cert_type = CERT_TYPE_TPM;
783 } else if (!strcmp(buf, "-----BEGIN RSA PRIVATE KEY-----\n") ||
784 !strcmp(buf, "-----BEGIN DSA PRIVATE KEY-----\n") ||
785 !strcmp(buf, "-----BEGIN ENCRYPTED PRIVATE KEY-----\n")) {
786 vpninfo->cert_type = CERT_TYPE_PEM;
791 if (vpninfo->cert_type == CERT_TYPE_UNKNOWN) {
792 vpn_progress(vpninfo, PRG_ERR,
793 _("Failed to identify private key type in '%s'\n"),
799 if (vpninfo->cert_type == CERT_TYPE_TPM)
800 return load_tpm_certificate(vpninfo);
802 /* Standard PEM certificate */
803 SSL_CTX_set_default_passwd_cb(vpninfo->https_ctx, pem_pw_cb);
804 SSL_CTX_set_default_passwd_cb_userdata(vpninfo->https_ctx, vpninfo);
806 if (!SSL_CTX_use_RSAPrivateKey_file(vpninfo->https_ctx, vpninfo->sslkey,
808 if (is_pem_password_error(vpninfo))
815 static int get_cert_fingerprint(struct openconnect_info *vpninfo,
816 OPENCONNECT_X509 *cert, const EVP_MD *type,
819 unsigned char md[EVP_MAX_MD_SIZE];
822 if (!X509_digest(cert, type, md, &n))
825 for (i=0; i < n; i++)
826 sprintf(&buf[i*2], "%02X", md[i]);
831 int get_cert_md5_fingerprint(struct openconnect_info *vpninfo,
832 OPENCONNECT_X509 *cert, char *buf)
834 return get_cert_fingerprint(vpninfo, cert, EVP_md5(), buf);
837 int openconnect_get_cert_sha1(struct openconnect_info *vpninfo,
838 OPENCONNECT_X509 *cert, char *buf)
840 return get_cert_fingerprint(vpninfo, cert, EVP_sha1(), buf);
843 static int check_server_cert(struct openconnect_info *vpninfo, X509 *cert)
845 char fingerprint[EVP_MAX_MD_SIZE * 2 + 1];
848 ret = openconnect_get_cert_sha1(vpninfo, cert, fingerprint);
852 if (strcasecmp(vpninfo->servercert, fingerprint)) {
853 vpn_progress(vpninfo, PRG_ERR,
854 _("Server SSL certificate didn't match: %s\n"), fingerprint);
860 static int match_hostname_elem(const char *hostname, int helem_len,
861 const char *match, int melem_len)
863 if (!helem_len && !melem_len)
866 if (!helem_len || !melem_len)
870 if (match[0] == '*') {
873 for (i = 1 ; i <= helem_len; i++) {
874 if (!match_hostname_elem(hostname + i, helem_len - i,
875 match + 1, melem_len - 1))
881 /* From the NetBSD (5.1) man page for ctype(3):
882 Values of type char or signed char must first be cast to unsigned char,
883 to ensure that the values are within the correct range. The result
884 should then be cast to int to avoid warnings from some compilers.
885 We do indeed get warning "array subscript has type 'char'" without
887 if (toupper((int)(unsigned char)hostname[0]) ==
888 toupper((int)(unsigned char)match[0]))
889 return match_hostname_elem(hostname + 1, helem_len - 1,
890 match + 1, melem_len - 1);
895 static int match_hostname(const char *hostname, const char *match)
898 const char *h_dot, *m_dot;
899 int helem_len, melem_len;
901 h_dot = strchr(hostname, '.');
902 m_dot = strchr(match, '.');
904 if (h_dot && m_dot) {
905 helem_len = h_dot - hostname + 1;
906 melem_len = m_dot - match + 1;
907 } else if (!h_dot && !m_dot) {
908 helem_len = strlen(hostname);
909 melem_len = strlen(match);
914 if (match_hostname_elem(hostname, helem_len,
918 hostname += helem_len;
927 /* cf. RFC2818 and RFC2459 */
928 static int match_cert_hostname(struct openconnect_info *vpninfo, X509 *peer_cert)
930 STACK_OF(GENERAL_NAME) *altnames;
932 ASN1_STRING *subjasn1;
933 char *subjstr = NULL;
936 char addrbuf[sizeof(struct in6_addr)];
939 /* Allow GEN_IP in the certificate only if we actually connected
940 by IP address rather than by name. */
941 if (inet_pton(AF_INET, vpninfo->hostname, addrbuf) > 0)
943 else if (inet_pton(AF_INET6, vpninfo->hostname, addrbuf) > 0)
945 else if (vpninfo->hostname[0] == '[' &&
946 vpninfo->hostname[strlen(vpninfo->hostname)-1] == ']') {
947 char *p = &vpninfo->hostname[strlen(vpninfo->hostname)-1];
949 if (inet_pton(AF_INET6, vpninfo->hostname + 1, addrbuf) > 0)
954 altnames = X509_get_ext_d2i(peer_cert, NID_subject_alt_name,
956 for (i = 0; i < sk_GENERAL_NAME_num(altnames); i++) {
957 const GENERAL_NAME *this = sk_GENERAL_NAME_value(altnames, i);
959 if (this->type == GEN_DNS) {
962 int len = ASN1_STRING_to_UTF8((void *)&str, this->d.ia5);
968 /* We don't like names with embedded NUL */
969 if (strlen(str) != len)
972 if (!match_hostname(vpninfo->hostname, str)) {
973 vpn_progress(vpninfo, PRG_TRACE,
974 _("Matched DNS altname '%s'\n"),
976 GENERAL_NAMES_free(altnames);
980 vpn_progress(vpninfo, PRG_TRACE,
981 _("No match for altname '%s'\n"),
985 } else if (this->type == GEN_IPADD && addrlen) {
989 if (this->d.ip->length == 4) {
991 } else if (this->d.ip->length == 16) {
994 vpn_progress(vpninfo, PRG_ERR,
995 _("Certificate has GEN_IPADD altname with bogus length %d\n"),
1000 /* We only do this for the debug messages */
1001 inet_ntop(family, this->d.ip->data, host, sizeof(host));
1003 if (this->d.ip->length == addrlen &&
1004 !memcmp(addrbuf, this->d.ip->data, addrlen)) {
1005 vpn_progress(vpninfo, PRG_TRACE,
1006 _("Matched %s address '%s'\n"),
1007 (family == AF_INET6)?"IPv6":"IPv4",
1009 GENERAL_NAMES_free(altnames);
1012 vpn_progress(vpninfo, PRG_TRACE,
1013 _("No match for %s address '%s'\n"),
1014 (family == AF_INET6)?"IPv6":"IPv4",
1017 } else if (this->type == GEN_URI) {
1019 char *url_proto, *url_host, *url_path, *url_host2;
1021 int len = ASN1_STRING_to_UTF8((void *)&str, this->d.ia5);
1026 /* We don't like names with embedded NUL */
1027 if (strlen(str) != len)
1030 if (internal_parse_url(str, &url_proto, &url_host, &url_port, &url_path, 0)) {
1035 if (!url_proto || strcasecmp(url_proto, "https"))
1038 if (url_port != vpninfo->port)
1041 /* Leave url_host as it was so that it can be freed */
1042 url_host2 = url_host;
1043 if (addrlen == 16 && vpninfo->hostname[0] != '[' &&
1044 url_host[0] == '[' && url_host[strlen(url_host)-1] == ']') {
1045 /* Cope with https://[IPv6]/ when the hostname is bare IPv6 */
1046 url_host[strlen(url_host)-1] = 0;
1050 if (strcasecmp(vpninfo->hostname, url_host2))
1054 vpn_progress(vpninfo, PRG_TRACE,
1055 _("URI '%s' has non-empty path; ignoring\n"),
1057 goto no_uri_match_silent;
1059 vpn_progress(vpninfo, PRG_TRACE,
1060 _("Matched URI '%s'\n"),
1066 GENERAL_NAMES_free(altnames);
1070 vpn_progress(vpninfo, PRG_TRACE,
1071 _("No match for URI '%s'\n"),
1073 no_uri_match_silent:
1080 GENERAL_NAMES_free(altnames);
1082 /* According to RFC2818, we don't use the legacy subject name if
1083 there was an altname with DNS type. */
1085 vpn_progress(vpninfo, PRG_ERR,
1086 _("No altname in peer cert matched '%s'\n"),
1091 subjname = X509_get_subject_name(peer_cert);
1093 vpn_progress(vpninfo, PRG_ERR,
1094 _("No subject name in peer cert!\n"));
1098 /* Find the _last_ (most specific) commonName */
1101 int j = X509_NAME_get_index_by_NID(subjname, NID_commonName, i);
1108 subjasn1 = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subjname, i));
1110 i = ASN1_STRING_to_UTF8((void *)&subjstr, subjasn1);
1112 if (!subjstr || strlen(subjstr) != i) {
1113 vpn_progress(vpninfo, PRG_ERR,
1114 _("Failed to parse subject name in peer cert\n"));
1119 if (match_hostname(vpninfo->hostname, subjstr)) {
1120 vpn_progress(vpninfo, PRG_ERR,
1121 _("Peer cert subject mismatch ('%s' != '%s')\n"),
1122 subjstr, vpninfo->hostname);
1125 vpn_progress(vpninfo, PRG_TRACE,
1126 _("Matched peer certificate subject name '%s'\n"),
1130 OPENSSL_free(subjstr);
1134 static int verify_peer(struct openconnect_info *vpninfo, SSL *https_ssl)
1139 peer_cert = SSL_get_peer_certificate(https_ssl);
1141 if (vpninfo->servercert) {
1142 /* If given a cert fingerprint on the command line, that's
1144 ret = check_server_cert(vpninfo, peer_cert);
1146 int vfy = SSL_get_verify_result(https_ssl);
1147 const char *err_string = NULL;
1149 if (vfy != X509_V_OK)
1150 err_string = X509_verify_cert_error_string(vfy);
1151 else if (match_cert_hostname(vpninfo, peer_cert))
1152 err_string = _("certificate does not match hostname");
1155 vpn_progress(vpninfo, PRG_INFO,
1156 _("Server certificate verify failed: %s\n"),
1159 if (vpninfo->validate_peer_cert)
1160 ret = vpninfo->validate_peer_cert(vpninfo->cbdata,
1169 X509_free(peer_cert);
1174 static void workaround_openssl_certchain_bug(struct openconnect_info *vpninfo,
1177 /* OpenSSL has problems with certificate chains -- if there are
1178 multiple certs with the same name, it doesn't necessarily
1179 choose the _right_ one. (RT#1942)
1180 Pick the right ones for ourselves and add them manually. */
1181 X509 *cert = SSL_get_certificate(ssl);
1183 X509_STORE *store = SSL_CTX_get_cert_store(vpninfo->https_ctx);
1186 if (!cert || !store)
1189 /* If we already have 'supporting' certs, don't add them again */
1190 if (vpninfo->https_ctx->extra_certs)
1193 if (!X509_STORE_CTX_init(&ctx, store, NULL, NULL))
1196 while (ctx.get_issuer(&cert2, &ctx, cert) == 1) {
1200 if (X509_check_issued(cert2, cert2) == X509_V_OK)
1203 X509_NAME_oneline(X509_get_subject_name(cert),
1205 vpn_progress(vpninfo, PRG_DEBUG,
1206 _("Extra cert from cafile: '%s'\n"), buf);
1207 SSL_CTX_add_extra_chain_cert(vpninfo->https_ctx, cert);
1209 X509_STORE_CTX_cleanup(&ctx);
1212 #if OPENSSL_VERSION_NUMBER >= 0x00908000
1213 static int ssl_app_verify_callback(X509_STORE_CTX *ctx, void *arg)
1215 /* We've seen certificates in the wild which don't have the
1216 purpose fields filled in correctly */
1217 X509_VERIFY_PARAM_set_purpose(ctx->param, X509_PURPOSE_ANY);
1218 return X509_verify_cert(ctx);
1222 static int check_certificate_expiry(struct openconnect_info *vpninfo)
1224 ASN1_TIME *notAfter;
1225 const char *reason = NULL;
1229 if (!vpninfo->cert_x509)
1233 notAfter = X509_get_notAfter(vpninfo->cert_x509);
1234 i = X509_cmp_time(notAfter, &t);
1236 vpn_progress(vpninfo, PRG_ERR,
1237 _("Error in client cert notAfter field\n"));
1240 reason = _("Client certificate has expired at");
1242 t += vpninfo->cert_expire_warning;
1243 i = X509_cmp_time(notAfter, &t);
1245 reason = _("Client certificate expires soon at");
1249 BIO *bp = BIO_new(BIO_s_mem());
1251 const char *expiry = _("<error>");
1255 ASN1_TIME_print(bp, notAfter);
1256 BIO_write(bp, &zero, 1);
1257 BIO_get_mem_ptr(bp, &bm);
1260 vpn_progress(vpninfo, PRG_ERR, "%s: %s\n", reason, expiry);
1266 int openconnect_open_https(struct openconnect_info *vpninfo)
1268 method_const SSL_METHOD *ssl3_method;
1274 if (vpninfo->https_ssl)
1277 if (vpninfo->peer_cert) {
1278 X509_free(vpninfo->peer_cert);
1279 vpninfo->peer_cert = NULL;
1282 ssl_sock = connect_https_socket(vpninfo);
1286 ssl3_method = TLSv1_client_method();
1287 if (!vpninfo->https_ctx) {
1288 vpninfo->https_ctx = SSL_CTX_new(ssl3_method);
1290 /* Some servers (or their firewalls) really don't like seeing
1292 #ifdef SSL_OP_NO_TICKET
1293 SSL_CTX_set_options (vpninfo->https_ctx, SSL_OP_NO_TICKET);
1296 if (vpninfo->cert) {
1297 err = load_certificate(vpninfo);
1299 vpn_progress(vpninfo, PRG_ERR,
1300 _("Loading certificate failed. Aborting.\n"));
1301 SSL_CTX_free(vpninfo->https_ctx);
1302 vpninfo->https_ctx = NULL;
1306 check_certificate_expiry(vpninfo);
1309 /* We just want to do:
1310 SSL_CTX_set_purpose(vpninfo->https_ctx, X509_PURPOSE_ANY);
1311 ... but it doesn't work with OpenSSL < 0.9.8k because of
1312 problems with inheritance (fixed in v1.1.4.6 of
1313 crypto/x509/x509_vpm.c) so we have to play silly buggers
1314 instead. This trick doesn't work _either_ in < 0.9.7 but
1315 I don't know of _any_ workaround which will, and can't
1316 be bothered to find out either. */
1317 #if OPENSSL_VERSION_NUMBER >= 0x00908000
1318 SSL_CTX_set_cert_verify_callback(vpninfo->https_ctx,
1319 ssl_app_verify_callback, NULL);
1321 SSL_CTX_set_default_verify_paths(vpninfo->https_ctx);
1323 #ifdef ANDROID_KEYSTORE
1324 if (vpninfo->cafile && !strncmp(vpninfo->cafile, "keystore:", 9)) {
1325 STACK_OF(X509_INFO) *stack;
1328 BIO *b = BIO_from_keystore(vpninfo, vpninfo->cafile);
1331 SSL_CTX_free(vpninfo->https_ctx);
1332 vpninfo->https_ctx = NULL;
1337 stack = PEM_X509_INFO_read_bio(b, NULL, NULL, NULL);
1341 vpn_progress(vpninfo, PRG_ERR,
1342 _("Failed to read certs from CA file '%s'\n"),
1344 openconnect_report_ssl_errors(vpninfo);
1345 SSL_CTX_free(vpninfo->https_ctx);
1346 vpninfo->https_ctx = NULL;
1351 store = SSL_CTX_get_cert_store(vpninfo->https_ctx);
1353 while ((info = sk_X509_INFO_pop(stack))) {
1355 X509_STORE_add_cert(store, info->x509);
1357 X509_STORE_add_crl(store, info->crl);
1358 X509_INFO_free(info);
1360 sk_X509_INFO_free(stack);
1363 if (vpninfo->cafile) {
1364 if (!SSL_CTX_load_verify_locations(vpninfo->https_ctx, vpninfo->cafile, NULL)) {
1365 vpn_progress(vpninfo, PRG_ERR,
1366 _("Failed to open CA file '%s'\n"),
1368 openconnect_report_ssl_errors(vpninfo);
1369 SSL_CTX_free(vpninfo->https_ctx);
1370 vpninfo->https_ctx = NULL;
1377 https_ssl = SSL_new(vpninfo->https_ctx);
1378 workaround_openssl_certchain_bug(vpninfo, https_ssl);
1380 https_bio = BIO_new_socket(ssl_sock, BIO_NOCLOSE);
1381 BIO_set_nbio(https_bio, 1);
1382 SSL_set_bio(https_ssl, https_bio, https_bio);
1384 vpn_progress(vpninfo, PRG_INFO, _("SSL negotiation with %s\n"),
1387 while ((err = SSL_connect(https_ssl)) <= 0) {
1388 fd_set wr_set, rd_set;
1389 int maxfd = ssl_sock;
1394 err = SSL_get_error(https_ssl, err);
1395 if (err == SSL_ERROR_WANT_READ)
1396 FD_SET(ssl_sock, &rd_set);
1397 else if (err == SSL_ERROR_WANT_WRITE)
1398 FD_SET(ssl_sock, &wr_set);
1400 vpn_progress(vpninfo, PRG_ERR, _("SSL connection failure\n"));
1401 openconnect_report_ssl_errors(vpninfo);
1402 SSL_free(https_ssl);
1407 if (vpninfo->cancel_fd != -1) {
1408 FD_SET(vpninfo->cancel_fd, &rd_set);
1409 if (vpninfo->cancel_fd > ssl_sock)
1410 maxfd = vpninfo->cancel_fd;
1412 select(maxfd + 1, &rd_set, &wr_set, NULL, NULL);
1413 if (vpninfo->cancel_fd != -1 &&
1414 FD_ISSET(vpninfo->cancel_fd, &rd_set)) {
1415 vpn_progress(vpninfo, PRG_ERR, _("SSL connection cancelled\n"));
1416 SSL_free(https_ssl);
1422 if (verify_peer(vpninfo, https_ssl)) {
1423 SSL_free(https_ssl);
1428 vpninfo->ssl_fd = ssl_sock;
1429 vpninfo->https_ssl = https_ssl;
1431 /* Stash this now, because it might not be available later if the
1432 server has disconnected. */
1433 vpninfo->peer_cert = SSL_get_peer_certificate(vpninfo->https_ssl);
1435 vpn_progress(vpninfo, PRG_INFO, _("Connected to HTTPS on %s\n"),
1441 void openconnect_close_https(struct openconnect_info *vpninfo, int final)
1443 if (vpninfo->peer_cert) {
1444 X509_free(vpninfo->peer_cert);
1445 vpninfo->peer_cert = NULL;
1447 if (vpninfo->https_ssl) {
1448 SSL_free(vpninfo->https_ssl);
1449 vpninfo->https_ssl = NULL;
1451 if (vpninfo->ssl_fd != -1) {
1452 close(vpninfo->ssl_fd);
1453 FD_CLR(vpninfo->ssl_fd, &vpninfo->select_rfds);
1454 FD_CLR(vpninfo->ssl_fd, &vpninfo->select_wfds);
1455 FD_CLR(vpninfo->ssl_fd, &vpninfo->select_efds);
1456 vpninfo->ssl_fd = -1;
1459 if (vpninfo->https_ctx) {
1460 SSL_CTX_free(vpninfo->https_ctx);
1461 vpninfo->https_ctx = NULL;
1463 if (vpninfo->cert_x509) {
1464 X509_free(vpninfo->cert_x509);
1465 vpninfo->cert_x509 = NULL;
1470 void openconnect_init_ssl(void)
1472 SSL_library_init ();
1474 SSL_load_error_strings ();
1475 OpenSSL_add_all_algorithms ();
1478 char *openconnect_get_cert_details(struct openconnect_info *vpninfo,
1479 OPENCONNECT_X509 *cert)
1481 BIO *bp = BIO_new(BIO_s_mem());
1486 X509_print_ex(bp, cert, 0, 0);
1487 BIO_write(bp, &zero, 1);
1488 BIO_get_mem_ptr(bp, &certinfo);
1490 ret = strdup(certinfo->data);
1496 int openconnect_local_cert_md5(struct openconnect_info *vpninfo,
1501 if (!vpninfo->cert_x509)
1504 if (get_cert_md5_fingerprint(vpninfo, vpninfo->cert_x509, buf))