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
25 #include <sys/types.h>
27 #include <sys/socket.h>
34 #include <netinet/in.h>
35 #include <arpa/inet.h>
40 #ifndef HAVE_GNUTLS_CERTIFICATE_SET_KEY
41 /* Shut up about gnutls_sign_callback_set() being deprecated. We only use it
42 in the GnuTLS 2.12 case, and there just isn't another way of doing it. */
43 #define GNUTLS_INTERNAL_BUILD 1
46 #include <gnutls/gnutls.h>
47 #include <gnutls/x509.h>
48 #include <gnutls/crypto.h>
49 #include <gnutls/pkcs12.h>
50 #include <gnutls/abstract.h>
53 #include <trousers/tss.h>
54 #include <trousers/trousers.h>
57 #include <p11-kit/p11-kit.h>
58 #include <p11-kit/pkcs11.h>
59 #include <p11-kit/pin.h>
61 static P11KitPin *pin_callback(const char *pin_source, P11KitUri *pin_uri,
62 const char *pin_description,
68 #include "openconnect-internal.h"
70 /* Helper functions for reading/writing lines over SSL.
71 We could use cURL for the HTTP stuff, but it's overkill */
73 int openconnect_SSL_write(struct openconnect_info *vpninfo, char *buf, size_t len)
75 size_t orig_len = len;
78 int done = gnutls_record_send(vpninfo->https_sess, buf, len);
81 else if (done != GNUTLS_E_AGAIN) {
82 vpn_progress(vpninfo, PRG_ERR, _("Failed to write to SSL socket: %s"),
83 gnutls_strerror(done));
86 fd_set wr_set, rd_set;
87 int maxfd = vpninfo->ssl_fd;
92 if (gnutls_record_get_direction(vpninfo->https_sess))
93 FD_SET(vpninfo->ssl_fd, &wr_set);
95 FD_SET(vpninfo->ssl_fd, &rd_set);
97 if (vpninfo->cancel_fd != -1) {
98 FD_SET(vpninfo->cancel_fd, &rd_set);
99 if (vpninfo->cancel_fd > vpninfo->ssl_fd)
100 maxfd = vpninfo->cancel_fd;
102 select(maxfd + 1, &rd_set, &wr_set, NULL, NULL);
103 if (vpninfo->cancel_fd != -1 &&
104 FD_ISSET(vpninfo->cancel_fd, &rd_set)) {
105 vpn_progress(vpninfo, PRG_ERR, _("SSL write cancelled\n"));
113 int openconnect_SSL_read(struct openconnect_info *vpninfo, char *buf, size_t len)
117 while ((done = gnutls_record_recv(vpninfo->https_sess, buf, len)) < 0) {
118 fd_set wr_set, rd_set;
119 int maxfd = vpninfo->ssl_fd;
121 if (done != GNUTLS_E_AGAIN) {
122 vpn_progress(vpninfo, PRG_ERR, _("Failed to read from SSL socket: %s"),
123 gnutls_strerror(done));
129 if (gnutls_record_get_direction(vpninfo->https_sess))
130 FD_SET(vpninfo->ssl_fd, &wr_set);
132 FD_SET(vpninfo->ssl_fd, &rd_set);
134 if (vpninfo->cancel_fd != -1) {
135 FD_SET(vpninfo->cancel_fd, &rd_set);
136 if (vpninfo->cancel_fd > vpninfo->ssl_fd)
137 maxfd = vpninfo->cancel_fd;
139 select(maxfd + 1, &rd_set, &wr_set, NULL, NULL);
140 if (vpninfo->cancel_fd != -1 &&
141 FD_ISSET(vpninfo->cancel_fd, &rd_set)) {
142 vpn_progress(vpninfo, PRG_ERR, _("SSL read cancelled\n"));
150 int openconnect_SSL_gets(struct openconnect_info *vpninfo, char *buf, size_t len)
159 ret = gnutls_record_recv(vpninfo->https_sess, buf + i, 1);
161 if (buf[i] == '\n') {
163 if (i && buf[i-1] == '\r') {
175 } else if (ret != GNUTLS_E_AGAIN) {
176 vpn_progress(vpninfo, PRG_ERR, _("Failed to read from SSL socket: %s\n"),
177 gnutls_strerror(ret));
181 fd_set rd_set, wr_set;
182 int maxfd = vpninfo->ssl_fd;
187 if (gnutls_record_get_direction(vpninfo->https_sess))
188 FD_SET(vpninfo->ssl_fd, &wr_set);
190 FD_SET(vpninfo->ssl_fd, &rd_set);
192 if (vpninfo->cancel_fd != -1) {
193 FD_SET(vpninfo->cancel_fd, &rd_set);
194 if (vpninfo->cancel_fd > vpninfo->ssl_fd)
195 maxfd = vpninfo->cancel_fd;
197 select(maxfd + 1, &rd_set, &wr_set, NULL, NULL);
198 if (vpninfo->cancel_fd != -1 &&
199 FD_ISSET(vpninfo->cancel_fd, &rd_set)) {
200 vpn_progress(vpninfo, PRG_ERR, _("SSL read cancelled\n"));
210 static int check_certificate_expiry(struct openconnect_info *vpninfo, gnutls_x509_crt_t cert)
212 const char *reason = NULL;
213 time_t expires = gnutls_x509_crt_get_expiration_time(cert);
214 time_t now = time(NULL);
217 vpn_progress(vpninfo, PRG_ERR,
218 _("Could not extract expiration time of certificate\n"));
223 reason = _("Client certificate has expired at");
224 else if (expires < now + vpninfo->cert_expire_warning)
225 reason = _("Client certificate expires soon at");
231 gmtime_r(&expires, &tm);
232 strftime(buf, 80, "%a, %d %b %Y %T %Z", &tm);
234 vpn_progress(vpninfo, PRG_ERR, "%s: %s\n", reason, buf);
239 /* For systems that don't support O_CLOEXEC, just don't bother.
240 It's not open for long anyway. */
245 static int load_datum(struct openconnect_info *vpninfo,
246 gnutls_datum_t *datum, const char *fname)
250 #ifdef ANDROID_KEYSTORE
251 if (!strncmp(fname, "keystore:", 9)) {
253 const char *p = fname + 9;
255 /* Skip first two slashes if the user has given it as
256 keystore://foo ... */
261 len = keystore_fetch(p, &datum->data);
263 vpn_progress(vpninfo, PRG_ERR,
264 _("Failed to load item '%s' from keystore: %s\n"),
265 p, keystore_strerror(len));
273 fd = open(fname, O_RDONLY|O_CLOEXEC);
276 vpn_progress(vpninfo, PRG_ERR,
277 _("Failed to open key/certificate file %s: %s\n"),
278 fname, strerror(err));
281 if (fstat(fd, &st)) {
283 vpn_progress(vpninfo, PRG_ERR,
284 _("Failed to stat key/certificate file %s: %s\n"),
285 fname, strerror(err));
289 datum->size = st.st_size;
290 datum->data = gnutls_malloc(st.st_size + 1);
292 vpn_progress(vpninfo, PRG_ERR,
293 _("Failed to allocate certificate buffer\n"));
298 if (read(fd, datum->data, datum->size) != datum->size) {
300 vpn_progress(vpninfo, PRG_ERR,
301 _("Failed to read certificate into memory: %s\n"),
304 gnutls_free(datum->data);
307 datum->data[st.st_size] = 0;
312 /* A non-zero, non-error return to make load_certificate() continue and
313 interpreting the file as other types */
316 static int load_pkcs12_certificate(struct openconnect_info *vpninfo,
317 gnutls_datum_t *datum,
318 gnutls_x509_privkey_t *key,
319 gnutls_x509_crt_t **chain,
320 unsigned int *chain_len,
321 gnutls_x509_crt_t **extra_certs,
322 unsigned int *extra_certs_len,
323 gnutls_x509_crl_t *crl)
329 err = gnutls_pkcs12_init(&p12);
331 vpn_progress(vpninfo, PRG_ERR,
332 _("Failed to setup PKCS#12 data structure: %s\n"),
333 gnutls_strerror(err));
337 err = gnutls_pkcs12_import(p12, datum, GNUTLS_X509_FMT_DER, 0);
339 gnutls_pkcs12_deinit(p12);
340 if (vpninfo->cert_type == CERT_TYPE_UNKNOWN)
342 vpn_progress(vpninfo, PRG_ERR,
343 _("Failed to import PKCS#12 file: %s\n"),
344 gnutls_strerror(err));
348 pass = vpninfo->cert_password;
349 while ((err = gnutls_pkcs12_verify_mac(p12, pass)) == GNUTLS_E_MAC_VERIFY_FAILED) {
351 vpn_progress(vpninfo, PRG_ERR,
352 _("Failed to decrypt PKCS#12 certificate file\n"));
354 vpninfo->cert_password = NULL;
355 err = request_passphrase(vpninfo, "openconnect_pkcs12", &pass,
356 _("Enter PKCS#12 pass phrase:"));
358 gnutls_pkcs12_deinit(p12);
362 /* If it wasn't GNUTLS_E_MAC_VERIFY_FAILED, then the problem wasn't just a
363 bad password. Give up. */
368 gnutls_pkcs12_deinit(p12);
370 /* If the first attempt, and we didn't know for sure it was PKCS#12
371 anyway, bail out and try loading it as something different. */
372 if (pass == vpninfo->cert_password &&
373 vpninfo->cert_type == CERT_TYPE_UNKNOWN) {
374 /* Make it non-fatal... */
379 vpn_progress(vpninfo, level,
380 _("Failed to process PKCS#12 file: %s\n"),
381 gnutls_strerror(err));
384 err = gnutls_pkcs12_simple_parse(p12, pass, key, chain, chain_len,
385 extra_certs, extra_certs_len, crl, 0);
387 vpninfo->cert_password = NULL;
389 gnutls_pkcs12_deinit(p12);
391 vpn_progress(vpninfo, PRG_ERR,
392 _("Failed to load PKCS#12 certificate: %s\n"),
393 gnutls_strerror(err));
399 /* Older versions of GnuTLS didn't actually bother to check this, so we'll
401 static int check_issuer_sanity(gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer)
403 #if GNUTLS_VERSION_NUMBER > 0x300014
406 unsigned char id1[512], id2[512];
407 size_t id1_size = 512, id2_size = 512;
410 err = gnutls_x509_crt_get_authority_key_id(cert, id1, &id1_size, NULL);
414 err = gnutls_x509_crt_get_subject_key_id(issuer, id2, &id2_size, NULL);
417 if (id1_size == id2_size && !memcmp(id1, id2, id1_size))
425 static int count_x509_certificates(gnutls_datum_t *datum)
428 char *p = (char *)datum->data;
431 p = strstr(p, "-----BEGIN ");
435 if (!strncmp(p, "CERTIFICATE", 11) ||
436 !strncmp(p, "X509 CERTIFICATE", 16))
442 static int get_cert_name(gnutls_x509_crt_t cert, char *name, size_t namelen)
444 if (gnutls_x509_crt_get_dn_by_oid(cert, GNUTLS_OID_X520_COMMON_NAME,
445 0, 0, name, &namelen) &&
446 gnutls_x509_crt_get_dn(cert, name, &namelen)) {
448 snprintf(name, namelen-1, "<unknown>");
454 #if defined (HAVE_P11KIT) || defined (HAVE_TROUSERS)
455 #ifndef HAVE_GNUTLS_CERTIFICATE_SET_KEY
456 /* For GnuTLS 2.12 even if we *have* a privkey (as we do for PKCS#11), we
457 can't register it. So we have to use the cert_callback function. This
458 just hands out the certificate chain we prepared in load_certificate().
459 If we have a pkey then return that too; otherwise leave the key NULL —
460 we'll also have registered a sign_callback for the session, which will
462 static int gtls_cert_cb(gnutls_session_t sess, const gnutls_datum_t *req_ca_dn,
463 int nreqs, const gnutls_pk_algorithm_t *pk_algos,
464 int pk_algos_length, gnutls_retr2_st *st) {
466 struct openconnect_info *vpninfo = gnutls_session_get_ptr(sess);
467 int algo = GNUTLS_PK_RSA; /* TPM */
471 if (vpninfo->my_p11key) {
472 st->key_type = GNUTLS_PRIVKEY_PKCS11;
473 st->key.pkcs11 = vpninfo->my_p11key;
474 algo = gnutls_pkcs11_privkey_get_pk_algorithm(vpninfo->my_p11key, NULL);
477 for (i = 0; i < pk_algos_length; i++) {
478 if (algo == pk_algos[i])
481 if (i == pk_algos_length)
482 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
484 st->cert_type = GNUTLS_CRT_X509;
485 st->cert.x509 = vpninfo->my_certs;
486 st->ncerts = vpninfo->nr_my_certs;
492 /* For GnuTLS 2.12, this has to set the cert_callback to the function
493 above, which will return the pkey and certs on demand. Or in the
494 case of TPM we can't make a suitable pkey, so we have to set a
495 sign_callback too (which is done in openconnect_open_https() since
496 it has to be done on the *session*). */
497 static int assign_privkey(struct openconnect_info *vpninfo,
498 gnutls_privkey_t pkey,
499 gnutls_x509_crt_t *certs,
500 unsigned int nr_certs,
501 gnutls_x509_crt_t *extra_certs,
502 unsigned int nr_extra_certs)
506 vpninfo->my_certs = gnutls_calloc(nr_certs, sizeof(*certs));
507 if (!vpninfo->my_certs)
508 return GNUTLS_E_MEMORY_ERROR;
510 memcpy(vpninfo->my_certs, certs, nr_certs * sizeof(*certs));
511 vpninfo->nr_my_certs = nr_certs;
513 /* We are *keeping* the certs, unlike in GnuTLS 3 where our caller
514 can free them after gnutls_certificate_set_key() has been called.
515 So first wipe the 'certs' array (which is either '&cert' or
516 'supporting_certs' in load_certificate())... */
517 memset(certs, 0, nr_certs * sizeof(*certs));
519 /* ... and then also zero out the entries in extra_certs[] that
520 correspond to the certs that we're stealing.
521 We know certs[0] was already stolen by the load_certificate()
522 function so we might as well start at certs[1]. */
523 for (i = 1; i < nr_certs; i++) {
525 for (j = 0; j < nr_extra_certs; j++) {
526 if (vpninfo->my_certs[i] == extra_certs[j]) {
527 extra_certs[j] = NULL;
533 gnutls_certificate_set_retrieve_function(vpninfo->https_cred,
535 vpninfo->my_pkey = pkey;
541 /* For GnuTLS 3+ this is saner than the GnuTLS 2.12 version. But still we
542 have to convert the array of X509 certificates to gnutls_pcert_st for
543 ourselves. There's no function that takes a gnutls_privkey_t as the key
544 and gnutls_x509_crt_t certificates. */
545 static int assign_privkey(struct openconnect_info *vpninfo,
546 gnutls_privkey_t pkey,
547 gnutls_x509_crt_t *certs,
548 unsigned int nr_certs,
549 gnutls_x509_crt_t *extra_certs,
550 unsigned int nr_extra_certs)
552 gnutls_pcert_st *pcerts = calloc(nr_certs, sizeof(*pcerts));
556 return GNUTLS_E_MEMORY_ERROR;
558 for (i=0 ; i < nr_certs; i++) {
559 err = gnutls_pcert_import_x509(pcerts + i, certs[i], 0);
561 vpn_progress(vpninfo, PRG_ERR,
562 _("Importing X509 certificate failed: %s\n"),
563 gnutls_strerror(err));
568 err = gnutls_certificate_set_key(vpninfo->https_cred, NULL, 0,
569 pcerts, nr_certs, pkey);
571 vpn_progress(vpninfo, PRG_ERR,
572 _("Setting PKCS#11 certificate failed: %s\n"),
573 gnutls_strerror(err));
575 for (i=0 ; i < nr_certs; i++)
576 gnutls_pcert_deinit(pcerts + i);
581 #endif /* !SET_KEY */
582 #endif /* (P11KIT || TROUSERS) */
584 static int openssl_hash_password(struct openconnect_info *vpninfo, char *pass,
585 gnutls_datum_t *key, gnutls_datum_t *salt)
587 unsigned char md5[16];
588 gnutls_hash_hd_t hash;
592 while (count < key->size) {
593 err = gnutls_hash_init(&hash, GNUTLS_DIG_MD5);
595 vpn_progress(vpninfo, PRG_ERR,
596 _("Could not initialise MD5 hash: %s\n"),
597 gnutls_strerror(err));
601 err = gnutls_hash(hash, md5, sizeof(md5));
604 gnutls_hash_deinit(hash, NULL);
605 vpn_progress(vpninfo, PRG_ERR,
606 _("MD5 hash error: %s\n"),
607 gnutls_strerror(err));
612 err = gnutls_hash(hash, pass, strlen(pass));
616 err = gnutls_hash(hash, salt->data, salt->size);
620 gnutls_hash_deinit(hash, md5);
622 if (key->size - count <= sizeof(md5)) {
623 memcpy(&key->data[count], md5, key->size - count);
627 memcpy(&key->data[count], md5, sizeof(md5));
628 count += sizeof(md5);
634 static int import_openssl_pem(struct openconnect_info *vpninfo,
635 gnutls_x509_privkey_t key,
636 char type, char *pem_header, size_t pem_size)
638 gnutls_cipher_hd_t handle;
639 gnutls_cipher_algorithm_t cipher;
640 gnutls_datum_t constructed_pem;
641 gnutls_datum_t b64_data;
642 gnutls_datum_t salt, enc_key;
643 unsigned char *key_data;
646 char *pem_start = pem_header;
647 int ret, err, i, iv_size;
650 begin = "EC PRIVATE KEY";
651 else if (type == 'R')
652 begin = "RSA PRIVATE KEY";
653 else if (type == 'D')
654 begin = "DSA PRIVATE KEY";
658 while (*pem_header == '\r' || *pem_header == '\n')
661 if (strncmp(pem_header, "DEK-Info: ", 10)) {
662 vpn_progress(vpninfo, PRG_ERR,
663 _("Missing DEK-Info: header from OpenSSL encrypted key\n"));
667 if (!strncmp(pem_header, "DES-EDE3-CBC,", 13)) {
669 cipher = GNUTLS_CIPHER_3DES_CBC;
670 /* Pfft. _gnutls_cipher_get_iv_size() is internal */
673 char *p = pem_header;
676 if (*p == ',' || *p == '\r' || *p == '\n' || p == pem_header+20) {
682 vpn_progress(vpninfo, PRG_ERR,
683 _("Unsupported PEM encryption type: %s\n"),
688 salt.data = malloc(salt.size);
691 for (i = 0; i < salt.size * 2; i++) {
693 char *c = &pem_header[i];
695 if (*c >= '0' && *c <= '9')
697 else if (*c >= 'A' && *c <= 'F')
700 vpn_progress(vpninfo, PRG_ERR,
701 _("Invalid salt in encrypted PEM file\n"));
708 salt.data[i/2] = x << 4;
711 pem_header += salt.size * 2;
712 if (*pem_header != '\r' && *pem_header != '\n') {
713 vpn_progress(vpninfo, PRG_ERR,
714 _("Invalid encrypted PEM file\n"));
718 while (*pem_header == '\n' || *pem_header == '\r')
721 /* pem_header should now point to the start of the base64 content.
722 Put a -----BEGIN banner in place before it, so that we can use
723 gnutls_pem_base64_decode_alloc(). The banner has to match the
724 -----END banner, so make sure we get it right... */
726 memcpy(pem_header, "-----\n", 6);
727 pem_header -= strlen(begin);
728 memcpy(pem_header, begin, strlen(begin));
730 memcpy(pem_header, "-----BEGIN ", 11);
732 constructed_pem.data = (void *)pem_header;
733 constructed_pem.size = pem_size - (pem_header - pem_start);
735 err = gnutls_pem_base64_decode_alloc(begin, &constructed_pem, &b64_data);
737 vpn_progress(vpninfo, PRG_ERR,
738 _("Error base64-decoding encrypted PEM file: %s\n"),
739 gnutls_strerror(err));
743 if (b64_data.size < 16) {
744 /* Just to be sure our parsing is OK */
745 vpn_progress(vpninfo, PRG_ERR,
746 _("Encrypted PEM file too short\n"));
752 enc_key.size = gnutls_cipher_get_key_size(cipher);
753 enc_key.data = malloc(enc_key.size);
757 key_data = malloc(b64_data.size);
761 pass = vpninfo->cert_password;
762 vpninfo->cert_password = NULL;
765 memcpy(key_data, b64_data.data, b64_data.size);
767 ret = openssl_hash_password(vpninfo, pass, &enc_key, &salt);
771 err = gnutls_cipher_init(&handle, cipher, &enc_key, &salt);
773 vpn_progress(vpninfo, PRG_ERR,
774 _("Failed to initialise cipher for decrypting PEM file: %s\n"),
775 gnutls_strerror(err));
776 gnutls_cipher_deinit(handle);
781 err = gnutls_cipher_decrypt(handle, key_data, b64_data.size);
782 gnutls_cipher_deinit(handle);
784 vpn_progress(vpninfo, PRG_ERR,
785 _("Failed to decrypt PEM key: %s\n"),
786 gnutls_strerror(err));
791 /* We have to strip any padding for GnuTLS to accept it.
792 So a bit more ASN.1 parsing for us.
793 FIXME: Consolidate with similar code in gnutls_tpm.c */
794 if (key_data[0] == 0x30) {
795 gnutls_datum_t key_datum;
796 int blocksize = gnutls_cipher_get_block_size(cipher);
797 int keylen = key_data[1];
801 int lenlen = keylen & 0x7f;
809 keylen |= key_data[ofs++];
815 /* If there appears to be more padding than required, fail */
816 if (b64_data.size - keylen >= blocksize)
819 /* If the padding bytes aren't all equal to the amount of padding, fail */
821 while (ofs < b64_data.size) {
822 if (key_data[ofs] != b64_data.size - keylen)
827 key_datum.data = key_data;
828 key_datum.size = keylen;
829 err = gnutls_x509_privkey_import(key, &key_datum, GNUTLS_X509_FMT_DER);
837 vpn_progress(vpninfo, PRG_ERR, _("Decrypting PEM key failed\n"));
840 err = request_passphrase(vpninfo, "openconnect_pem",
841 &pass, _("Enter PEM pass phrase:"));
859 static int load_certificate(struct openconnect_info *vpninfo)
861 gnutls_datum_t fdata;
862 gnutls_x509_privkey_t key = NULL;
863 #if defined (HAVE_P11KIT) || defined (HAVE_TROUSERS)
864 gnutls_privkey_t pkey = NULL;
865 gnutls_datum_t pkey_sig = {NULL, 0};
866 void *dummy_hash_data = &load_certificate;
869 char *cert_url = (char *)vpninfo->cert;
870 char *key_url = (char *)vpninfo->sslkey;
871 gnutls_pkcs11_privkey_t p11key = NULL;
874 gnutls_x509_crl_t crl = NULL;
875 gnutls_x509_crt_t last_cert, cert = NULL;
876 gnutls_x509_crt_t *extra_certs = NULL, *supporting_certs = NULL;
877 unsigned int nr_supporting_certs = 0, nr_extra_certs = 0;
878 unsigned int certs_to_free = 0; /* How many of supporting_certs */
879 int err; /* GnuTLS error */
882 int cert_is_p11 = 0, key_is_p11 = 0;
883 unsigned char key_id[20];
884 size_t key_id_size = sizeof(key_id);
889 key_is_p11 = !strncmp(vpninfo->sslkey, "pkcs11:", 7);
890 cert_is_p11 = !strncmp(vpninfo->cert, "pkcs11:", 7);
893 if (key_is_p11 || cert_is_p11) {
894 vpn_progress(vpninfo, PRG_ERR,
895 _("This binary built without PKCS#11 support\n"));
899 /* Install PIN handler if either certificate or key are coming from PKCS#11 */
900 if (key_is_p11 || cert_is_p11) {
901 CK_OBJECT_CLASS class;
906 sprintf(pin_source, "openconnect:%p", vpninfo);
907 p11_kit_pin_register_callback(pin_source, pin_callback, vpninfo, NULL);
909 uri = p11_kit_uri_new();
911 attr.type = CKA_CLASS;
912 attr.pValue = &class;
913 attr.ulValueLen = sizeof(class);
915 /* Add appropriate pin-source and object-type attributes to
916 both certificate and key URLs, unless they already exist. */
918 !p11_kit_uri_parse(cert_url, P11_KIT_URI_FOR_OBJECT, uri)) {
919 if (!p11_kit_uri_get_pin_source(uri))
920 p11_kit_uri_set_pin_source(uri, pin_source);
921 if (!p11_kit_uri_get_attribute(uri, CKA_CLASS)) {
922 class = CKO_CERTIFICATE;
923 p11_kit_uri_set_attribute(uri, &attr);
925 p11_kit_uri_format(uri, P11_KIT_URI_FOR_OBJECT, &cert_url);
929 !p11_kit_uri_parse(key_url, P11_KIT_URI_FOR_OBJECT, uri)) {
930 if (!p11_kit_uri_get_pin_source(uri))
931 p11_kit_uri_set_pin_source(uri, pin_source);
932 if (!p11_kit_uri_get_attribute(uri, CKA_CLASS)) {
933 class = CKO_PRIVATE_KEY;
934 p11_kit_uri_set_attribute(uri, &attr);
936 p11_kit_uri_format(uri, P11_KIT_URI_FOR_OBJECT, &key_url);
939 p11_kit_uri_free(uri);
942 /* Load certificate(s) first... */
944 vpn_progress(vpninfo, PRG_TRACE,
945 _("Using PKCS#11 certificate %s\n"), cert_url);
947 err = gnutls_x509_crt_init(&cert);
952 err = gnutls_x509_crt_import_pkcs11_url(cert, cert_url, 0);
953 if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
954 err = gnutls_x509_crt_import_pkcs11_url(cert, cert_url,
955 GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
957 vpn_progress(vpninfo, PRG_ERR,
958 _("Error loading certificate from PKCS#11: %s\n"),
959 gnutls_strerror(err));
965 #endif /* HAVE_P11KIT */
967 /* OK, not a PKCS#11 certificate so it must be coming from a file... */
968 vpn_progress(vpninfo, PRG_TRACE,
969 _("Using certificate file %s\n"), vpninfo->cert);
971 /* Load file contents */
972 ret = load_datum(vpninfo, &fdata, vpninfo->cert);
977 if (!key_is_p11 && (vpninfo->cert_type == CERT_TYPE_PKCS12 ||
978 vpninfo->cert_type == CERT_TYPE_UNKNOWN)) {
979 /* PKCS#12 should actually contain certificates *and* private key */
980 ret = load_pkcs12_certificate(vpninfo, &fdata, &key,
981 &supporting_certs, &nr_supporting_certs,
982 &extra_certs, &nr_extra_certs,
987 if (nr_supporting_certs) {
988 cert = supporting_certs[0];
991 vpn_progress(vpninfo, PRG_ERR,
992 _("PKCS#11 file contained no certificate\n"));
997 /* It returned NOT_PKCS12.
998 Fall through to try PEM formats. */
1001 /* We need to know how many there are in *advance*; it won't just allocate
1002 the array for us :( */
1003 nr_extra_certs = count_x509_certificates(&fdata);
1004 if (!nr_extra_certs)
1005 nr_extra_certs = 1; /* wtf? Oh well, we'll fail later... */
1007 extra_certs = calloc(nr_extra_certs, sizeof(cert));
1013 err = gnutls_x509_crt_list_import(extra_certs, &nr_extra_certs, &fdata,
1014 GNUTLS_X509_FMT_PEM, 0);
1017 if (!err || err == GNUTLS_E_NO_CERTIFICATE_FOUND)
1018 reason = _("No certificate found in file");
1020 reason = gnutls_strerror(err);
1022 vpn_progress(vpninfo, PRG_ERR,
1023 _("Loading certificate failed: %s\n"),
1028 nr_extra_certs = err;
1033 /* Now we have either a single certificate in 'cert', or an array of
1034 them in extra_certs[]. Next we look for the private key ... */
1035 #if defined (HAVE_P11KIT)
1037 vpn_progress(vpninfo, PRG_TRACE,
1038 _("Using PKCS#11 key %s\n"), key_url);
1040 err = gnutls_pkcs11_privkey_init(&p11key);
1042 vpn_progress(vpninfo, PRG_ERR,
1043 _("Error initialising PKCS#11 key structure: %s\n"),
1044 gnutls_strerror(err));
1049 err = gnutls_pkcs11_privkey_import_url(p11key, key_url, 0);
1051 vpn_progress(vpninfo, PRG_ERR,
1052 _("Error importing PKCS#11 URL %s: %s\n"),
1053 key_url, gnutls_strerror(err));
1054 gnutls_pkcs11_privkey_deinit(p11key);
1059 err = gnutls_privkey_init(&pkey);
1061 vpn_progress(vpninfo, PRG_ERR,
1062 _("Error initialising private key structure: %s\n"),
1063 gnutls_strerror(err));
1064 gnutls_pkcs11_privkey_deinit(p11key);
1069 err = gnutls_privkey_import_pkcs11(pkey, p11key, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
1071 vpn_progress(vpninfo, PRG_ERR,
1072 _("Error importing PKCS#11 key into private key structure: %s\n"),
1073 gnutls_strerror(err));
1074 gnutls_pkcs11_privkey_deinit(p11key);
1078 #ifndef HAVE_GNUTLS_CERTIFICATE_SET_KEY
1079 /* This can be set now and doesn't need to be separately freed.
1080 It goes with the pkey. This is a PITA; it would be better
1081 if there was a way to get the p11key *back* from a privkey
1082 that we *know* is based on one. In fact, since this is only
1083 for GnuTLS 2.12 and we *know* the gnutls_privkey_st won't
1084 ever change there, so we *could* do something evil... but
1086 vpninfo->my_p11key = p11key;
1087 #endif /* !SET_KEY */
1090 #endif /* HAVE_P11KIT */
1092 /* OK, not a PKCS#11 key so it must be coming from a file... load the
1093 file into memory, unless it's the same as the cert file and we
1094 already loaded that. */
1095 if (!fdata.data || vpninfo->sslkey != vpninfo->cert) {
1096 gnutls_free(fdata.data);
1099 vpn_progress(vpninfo, PRG_TRACE,
1100 _("Using private key file %s\n"), vpninfo->sslkey);
1102 ret = load_datum(vpninfo, &fdata, vpninfo->sslkey);
1107 /* Is it a PEM file with a TPM key blob? */
1108 if (vpninfo->cert_type == CERT_TYPE_TPM ||
1109 (vpninfo->cert_type == CERT_TYPE_UNKNOWN &&
1110 strstr((char *)fdata.data, "-----BEGIN TSS KEY BLOB-----"))) {
1111 #ifndef HAVE_TROUSERS
1112 vpn_progress(vpninfo, PRG_ERR,
1113 _("This version of OpenConnect was built without TPM support\n"));
1116 ret = load_tpm_key(vpninfo, &fdata, &pkey, &pkey_sig);
1124 /* OK, try other PEM files... */
1125 gnutls_x509_privkey_init(&key);
1126 if ((pem_header = strstr((char *)fdata.data, "-----BEGIN RSA PRIVATE KEY-----")) ||
1127 (pem_header = strstr((char *)fdata.data, "-----BEGIN DSA PRIVATE KEY-----")) ||
1128 (pem_header = strstr((char *)fdata.data, "-----BEGIN EC PRIVATE KEY-----"))) {
1129 /* PKCS#1 files, including OpenSSL's odd encrypted version */
1130 char type = pem_header[11];
1131 char *p = strchr(pem_header, '\n');
1133 vpn_progress(vpninfo, PRG_ERR,
1134 _("Failed to interpret PEM file\n"));
1138 while (*p == '\n' || *p == '\r')
1141 if (!strncmp(p, "Proc-Type: 4,ENCRYPTED", 22)) {
1143 while (*p == '\n' || *p == '\r')
1145 ret = import_openssl_pem(vpninfo, key, type, p,
1146 fdata.size - (p - (char *)fdata.data));
1150 err = gnutls_x509_privkey_import(key, &fdata, GNUTLS_X509_FMT_PEM);
1152 vpn_progress(vpninfo, PRG_ERR,
1153 _("Failed to load PKCS#1 private key: %s\n"),
1154 gnutls_strerror(err));
1159 } else if (strstr((char *)fdata.data, "-----BEGIN ENCRYPTED PRIVATE KEY-----") ||
1160 strstr((char *)fdata.data, "-----BEGIN PRIVATE KEY-----")) {
1162 char *pass = vpninfo->cert_password;
1164 while ((err = gnutls_x509_privkey_import_pkcs8(key, &fdata,
1165 GNUTLS_X509_FMT_PEM,
1166 pass, pass?0:GNUTLS_PKCS_PLAIN))) {
1167 if (err != GNUTLS_E_DECRYPTION_FAILED) {
1168 vpn_progress(vpninfo, PRG_ERR,
1169 _("Failed to load private key as PKCS#8: %s\n"),
1170 gnutls_strerror(err));
1174 vpninfo->cert_password = NULL;
1176 vpn_progress(vpninfo, PRG_ERR,
1177 _("Failed to decrypt PKCS#8 certificate file\n"));
1180 err = request_passphrase(vpninfo, "openconnect_pem",
1181 &pass, _("Enter PEM pass phrase:"));
1188 vpninfo->cert_password = NULL;
1190 vpn_progress(vpninfo, PRG_ERR,
1191 _("Failed to determine type of private key %s\n"),
1197 /* Now attempt to make sure we use the *correct* certificate, to match
1198 the key. Since we have a software key, we can easily query it and
1199 compare its key_id with each certificate till we find a match. */
1200 err = gnutls_x509_privkey_get_key_id(key, 0, key_id, &key_id_size);
1202 vpn_progress(vpninfo, PRG_ERR,
1203 _("Failed to get key ID: %s\n"),
1204 gnutls_strerror(err));
1208 /* If extra_certs[] is NULL, we have one candidate in 'cert' to check. */
1209 for (i = 0; i < (extra_certs?nr_extra_certs:1); i++) {
1210 unsigned char cert_id[20];
1211 size_t cert_id_size = sizeof(cert_id);
1213 err = gnutls_x509_crt_get_key_id(extra_certs?extra_certs[i]:cert, 0, cert_id, &cert_id_size);
1217 if (cert_id_size == key_id_size && !memcmp(cert_id, key_id, key_id_size)) {
1219 cert = extra_certs[i];
1220 extra_certs[i] = NULL;
1225 /* There's no pkey (there's an x509 key), so even if p11-kit or trousers is
1226 enabled we'll fall straight through the bit at match_cert: below, and go
1227 directly to the bit where it prints the 'no match found' error and exits. */
1229 #if defined (HAVE_P11KIT) || defined (HAVE_TROUSERS)
1231 /* If we have a privkey from PKCS#11 or TPM, we can't do the simple comparison
1232 of key ID that we do for software keys to find which certificate is a
1233 match. So sign some dummy data and then check the signature against each
1234 of the available certificates until we find the right one. */
1236 /* The TPM code may have already signed it, to test authorisation. We
1237 only sign here for PKCS#11 keys, in which case fdata might be
1238 empty too so point it at dummy data. */
1239 if (!pkey_sig.data) {
1241 fdata.data = dummy_hash_data;
1245 err = sign_dummy_data(vpninfo, pkey, &fdata, &pkey_sig);
1247 vpn_progress(vpninfo, PRG_ERR,
1248 _("Error signing test data with private key: %s\n"),
1249 gnutls_strerror(err));
1255 /* If extra_certs[] is NULL, we have one candidate in 'cert' to check. */
1256 for (i=0; i < (extra_certs?nr_extra_certs:1); i++) {
1257 gnutls_pubkey_t pubkey;
1259 gnutls_pubkey_init(&pubkey);
1260 err = gnutls_pubkey_import_x509(pubkey, extra_certs?extra_certs[i]:cert, 0);
1262 vpn_progress(vpninfo, PRG_ERR,
1263 _("Error validating signature against certificate: %s\n"),
1264 gnutls_strerror(err));
1265 /* We'll probably fail shortly if we don't find it. */
1266 gnutls_pubkey_deinit(pubkey);
1269 err = gnutls_pubkey_verify_data(pubkey, 0, &fdata, &pkey_sig);
1270 gnutls_pubkey_deinit(pubkey);
1274 cert = extra_certs[i];
1275 extra_certs[i] = NULL;
1277 gnutls_free(pkey_sig.data);
1281 gnutls_free(pkey_sig.data);
1283 #endif /* P11KIT || TROUSERS */
1285 /* We shouldn't reach this. It means that we didn't find *any* matching cert */
1286 vpn_progress(vpninfo, PRG_ERR,
1287 _("No SSL certificate found to match private key\n"));
1291 /********************************************************************/
1293 /* Now we have a key in either 'key' or 'pkey', a matching cert in 'cert',
1294 and potentially a list of other certs in 'extra_certs[]'. If we loaded
1295 a PKCS#12 file we may have a trust chain in 'supporting_certs[]' too. */
1296 check_certificate_expiry(vpninfo, cert);
1297 get_cert_name(cert, name, sizeof(name));
1298 vpn_progress(vpninfo, PRG_INFO, _("Using client certificate '%s'\n"),
1302 err = gnutls_certificate_set_x509_crl(vpninfo->https_cred, &crl, 1);
1304 vpn_progress(vpninfo, PRG_ERR,
1305 _("Setting certificate recovation list failed: %s\n"),
1306 gnutls_strerror(err));
1312 /* OpenSSL has problems with certificate chains — if there are
1313 multiple certs with the same name, it doesn't necessarily
1314 choose the _right_ one. (RT#1942)
1315 Pick the right ones for ourselves and add them manually. */
1317 if (nr_supporting_certs) {
1318 /* We already got a bunch of certs from PKCS#12 file. Remember
1319 how many need to be freed when we're done, since we'll
1320 expand the supporting_certs array with more from the cafile
1321 and extra_certs[] array if we can, and those extra certs
1322 must not be freed (twice). */
1323 last_cert = supporting_certs[nr_supporting_certs-1];
1324 certs_to_free = nr_supporting_certs;
1327 certs_to_free = nr_supporting_certs = 1;
1330 gnutls_x509_crt_t issuer;
1332 for (i = 0; i < nr_extra_certs; i++) {
1333 if (extra_certs[i] &&
1334 gnutls_x509_crt_check_issuer(last_cert, extra_certs[i]) &&
1335 !check_issuer_sanity(last_cert, extra_certs[i]))
1339 if (i < nr_extra_certs) {
1340 /* We found the next cert in the chain in extra_certs[] */
1341 issuer = extra_certs[i];
1343 /* Look for it in the system trust cafile too. */
1344 err = gnutls_certificate_get_issuer(vpninfo->https_cred,
1345 last_cert, &issuer, 0);
1349 /* The check_issuer_sanity() function works fine as a workaround where
1350 it was used above, but when gnutls_certificate_get_issuer() returns
1351 a bogus cert, there's nothing we can do to fix it up. We don't get
1352 to iterate over all the available certs like we can over our own
1354 if (check_issuer_sanity(last_cert, issuer)) {
1355 /* Hm, is there a bug reference for this? Or just the git commit
1356 reference (c1ef7efb in master, 5196786c in gnutls_3_0_x-2)? */
1357 vpn_progress(vpninfo, PRG_ERR,
1358 _("WARNING: GnuTLS returned incorrect issuer certs; authentication may fail!\n"));
1363 if (issuer == last_cert) {
1364 /* Don't actually include the root CA. If they don't already trust it,
1365 then handing it to them isn't going to help. But don't omit the
1366 original certificate if it's self-signed. */
1367 if (nr_supporting_certs > 1)
1368 nr_supporting_certs--;
1372 /* OK, we found a new cert to add to our chain. */
1373 supporting_certs = gnutls_realloc(supporting_certs,
1374 sizeof(cert) * ++nr_supporting_certs);
1375 if (!supporting_certs) {
1376 vpn_progress(vpninfo, PRG_ERR,
1377 _("Failed to allocate memory for supporting certificates\n"));
1378 /* The world is probably about to end, but try without them anyway */
1384 /* First time we actually allocated an array? Copy the first cert into it */
1385 if (nr_supporting_certs == 2)
1386 supporting_certs[0] = cert;
1388 /* Append the new one */
1389 supporting_certs[nr_supporting_certs-1] = issuer;
1392 for (i = 1; i < nr_supporting_certs; i++) {
1393 get_cert_name(supporting_certs[i], name, sizeof(name));
1395 vpn_progress(vpninfo, PRG_DEBUG,
1396 _("Adding supporting CA '%s'\n"), name);
1399 /* OK, now we've checked the cert expiry and warned the user if it's
1400 going to expire soon, and we've built up as much of a trust chain
1401 in supporting_certs[] as we can find, to help the server work around
1402 OpenSSL RT#1942. Set up the GnuTLS credentials with the appropriate
1403 key and certs. GnuTLS makes us do this differently for X509 privkeys
1404 vs. TPM/PKCS#11 "generic" privkeys, and the latter is particularly
1405 'fun' for GnuTLS 2.12... */
1406 #if defined (HAVE_P11KIT) || defined (HAVE_TROUSERS)
1408 err = assign_privkey(vpninfo, pkey,
1409 supporting_certs ? supporting_certs : &cert,
1410 nr_supporting_certs,
1411 extra_certs, nr_extra_certs);
1413 pkey = NULL; /* we gave it away, and potentially also some
1414 of extra_certs[] may have been zeroed. */
1417 #endif /* P11KIT || TROUSERS */
1418 err = gnutls_certificate_set_x509_key(vpninfo->https_cred,
1419 supporting_certs ? supporting_certs : &cert,
1420 nr_supporting_certs, key);
1423 vpn_progress(vpninfo, PRG_ERR,
1424 _("Setting certificate failed: %s\n"),
1425 gnutls_strerror(err));
1431 gnutls_x509_crl_deinit(crl);
1433 gnutls_x509_privkey_deinit(key);
1434 if (supporting_certs) {
1435 for (i = 0; i < certs_to_free; i++) {
1436 if (supporting_certs[i])
1437 gnutls_x509_crt_deinit(supporting_certs[i]);
1439 gnutls_free(supporting_certs);
1441 /* Not if supporting_certs. It's supporting_certs[0] then and
1442 was already freed. */
1443 gnutls_x509_crt_deinit(cert);
1445 for (i = 0; i < nr_extra_certs; i++) {
1447 gnutls_x509_crt_deinit(extra_certs[i]);
1449 gnutls_free(extra_certs);
1451 #if defined (HAVE_P11KIT) || defined (HAVE_TROUSERS)
1452 if (pkey && pkey != OPENCONNECT_TPM_PKEY)
1453 gnutls_privkey_deinit(pkey);
1454 /* If we support arbitrary privkeys, we might have abused fdata.data
1455 just to point to something to hash. Don't free it in that case! */
1456 if (fdata.data != dummy_hash_data)
1458 gnutls_free(fdata.data);
1461 if (cert_url != vpninfo->cert)
1463 if (key_url != vpninfo->sslkey)
1469 static int get_cert_fingerprint(struct openconnect_info *vpninfo,
1470 gnutls_x509_crt_t cert,
1471 gnutls_digest_algorithm_t algo,
1474 unsigned char md[256];
1475 size_t md_size = sizeof(md);
1478 if (gnutls_x509_crt_get_fingerprint(cert, algo, md, &md_size))
1481 for (i=0; i < md_size; i++)
1482 sprintf(&buf[i*2], "%02X", md[i]);
1487 int get_cert_md5_fingerprint(struct openconnect_info *vpninfo,
1488 OPENCONNECT_X509 *cert, char *buf)
1490 return get_cert_fingerprint(vpninfo, cert, GNUTLS_DIG_MD5, buf);
1493 int openconnect_get_cert_sha1(struct openconnect_info *vpninfo,
1494 OPENCONNECT_X509 *cert, char *buf)
1496 return get_cert_fingerprint(vpninfo, cert, GNUTLS_DIG_SHA1, buf);
1499 char *openconnect_get_cert_details(struct openconnect_info *vpninfo,
1500 OPENCONNECT_X509 *cert)
1505 if (gnutls_x509_crt_print(cert, GNUTLS_CRT_PRINT_FULL, &buf))
1508 /* Just in case gnutls_free() isn't free(), we can't steal it. */
1509 ret = strdup((char *)buf.data);
1510 gnutls_free(buf.data);
1515 int openconnect_get_cert_DER(struct openconnect_info *vpninfo,
1516 OPENCONNECT_X509 *cert, unsigned char **buf)
1519 unsigned char *ret = NULL;
1521 if (gnutls_x509_crt_export(cert, GNUTLS_X509_FMT_DER, ret, &l) !=
1522 GNUTLS_E_SHORT_MEMORY_BUFFER)
1529 if (gnutls_x509_crt_export(cert, GNUTLS_X509_FMT_DER, ret, &l)) {
1537 static int verify_peer(gnutls_session_t session)
1539 struct openconnect_info *vpninfo = gnutls_session_get_ptr(session);
1540 const gnutls_datum_t *cert_list;
1541 gnutls_x509_crt_t cert;
1542 unsigned int status, cert_list_size;
1543 const char *reason = NULL;
1546 if (vpninfo->peer_cert) {
1547 gnutls_x509_crt_deinit(vpninfo->peer_cert);
1548 vpninfo->peer_cert = NULL;
1551 cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
1553 vpn_progress(vpninfo, PRG_ERR, _("Server presented no certificate\n"));
1554 return GNUTLS_E_CERTIFICATE_ERROR;
1557 if (vpninfo->servercert) {
1558 unsigned char sha1bin[SHA1_SIZE];
1559 char fingerprint[(SHA1_SIZE * 2) + 1];
1562 err = openconnect_sha1(sha1bin, cert_list[0].data, cert_list[0].size);
1564 vpn_progress(vpninfo, PRG_ERR,
1565 _("Could not calculate SHA1 of server's certificate\n"));
1566 return GNUTLS_E_CERTIFICATE_ERROR;
1568 for (i=0; i < SHA1_SIZE; i++)
1569 sprintf(&fingerprint[i*2], "%02X", sha1bin[i]);
1571 if (strcasecmp(vpninfo->servercert, fingerprint)) {
1572 vpn_progress(vpninfo, PRG_ERR,
1573 _("Server SSL certificate didn't match: %s\n"), fingerprint);
1574 return GNUTLS_E_CERTIFICATE_ERROR;
1579 err = gnutls_certificate_verify_peers2 (session, &status);
1581 vpn_progress(vpninfo, PRG_ERR, _("Error checking server cert status\n"));
1582 return GNUTLS_E_CERTIFICATE_ERROR;
1585 if (status & GNUTLS_CERT_REVOKED)
1586 reason = _("certificate revoked");
1587 else if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
1588 reason = _("signer not found");
1589 else if (status & GNUTLS_CERT_SIGNER_NOT_CA)
1590 reason = _("signer not a CA certificate");
1591 else if (status & GNUTLS_CERT_INSECURE_ALGORITHM)
1592 reason = _("insecure algorithm");
1593 else if (status & GNUTLS_CERT_NOT_ACTIVATED)
1594 reason = _("certificate not yet activated");
1595 else if (status & GNUTLS_CERT_EXPIRED)
1596 reason = _("certificate expired");
1597 else if (status & GNUTLS_CERT_INVALID)
1598 /* If this is set and no other reason, it apparently means
1599 that signature verification failed. Not entirely sure
1600 why we don't just set a bit for that too. */
1601 reason = _("signature verification failed");
1603 err = gnutls_x509_crt_init(&cert);
1605 vpn_progress(vpninfo, PRG_ERR, _("Error initialising X509 cert structure\n"));
1606 return GNUTLS_E_CERTIFICATE_ERROR;
1609 err = gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER);
1611 vpn_progress(vpninfo, PRG_ERR, _("Error importing server's cert\n"));
1612 gnutls_x509_crt_deinit(cert);
1613 return GNUTLS_E_CERTIFICATE_ERROR;
1616 if (!reason && !gnutls_x509_crt_check_hostname(cert, vpninfo->hostname))
1617 reason = _("certificate does not match hostname");
1620 vpn_progress(vpninfo, PRG_INFO, "Server certificate verify failed: %s\n",
1622 if (vpninfo->validate_peer_cert)
1623 err = vpninfo->validate_peer_cert(vpninfo->cbdata,
1625 reason) ? GNUTLS_E_CERTIFICATE_ERROR : 0;
1627 err = GNUTLS_E_CERTIFICATE_ERROR;
1630 vpninfo->peer_cert = cert;
1636 int openconnect_open_https(struct openconnect_info *vpninfo)
1641 if (vpninfo->https_sess)
1644 ssl_sock = connect_https_socket(vpninfo);
1648 if (!vpninfo->https_cred) {
1649 gnutls_certificate_allocate_credentials(&vpninfo->https_cred);
1650 #ifdef HAVE_GNUTLS_CERTIFICATE_SET_X509_SYSTEM_TRUST
1651 gnutls_certificate_set_x509_system_trust(vpninfo->https_cred);
1653 gnutls_certificate_set_x509_trust_file(vpninfo->https_cred,
1654 "/etc/pki/tls/certs/ca-bundle.crt",
1655 GNUTLS_X509_FMT_PEM);
1657 gnutls_certificate_set_verify_function (vpninfo->https_cred,
1660 #ifdef ANDROID_KEYSTORE
1661 if (vpninfo->cafile && !strncmp(vpninfo->cafile, "keystore:", 9)) {
1662 gnutls_datum_t datum;
1663 unsigned int nr_certs;
1665 err = load_datum(vpninfo, &datum, vpninfo->cafile);
1669 /* For GnuTLS 3.x We should use gnutls_x509_crt_list_import2() */
1670 nr_certs = count_x509_certificates(&datum);
1672 gnutls_x509_crt *certs;
1675 certs = calloc(nr_certs, sizeof(*certs));
1677 vpn_progress(vpninfo, PRG_ERR,
1678 _("Failed to allocate memory for cafile certs\n"));
1679 gnutls_free(datum.data);
1683 err = gnutls_x509_crt_list_import(certs, &nr_certs, &datum,
1684 GNUTLS_X509_FMT_PEM, 0);
1685 gnutls_free(datum.data);
1688 err = gnutls_certificate_set_x509_trust(vpninfo->https_cred,
1691 for (i = 0; i < nr_certs; i++)
1692 gnutls_x509_crt_deinit(certs[i]);
1695 /* From crt_list_import or set_x509_trust */
1696 vpn_progress(vpninfo, PRG_ERR,
1697 _("Failed to read certs from cafile: %s\n"),
1698 gnutls_strerror(err));
1705 if (vpninfo->cafile) {
1706 err = gnutls_certificate_set_x509_trust_file(vpninfo->https_cred,
1708 GNUTLS_X509_FMT_PEM);
1710 vpn_progress(vpninfo, PRG_ERR,
1711 _("Failed to open CA file '%s': %s\n"),
1712 vpninfo->cafile, gnutls_strerror(err));
1718 if (vpninfo->cert) {
1719 err = load_certificate(vpninfo);
1721 vpn_progress(vpninfo, PRG_ERR,
1722 _("Loading certificate failed. Aborting.\n"));
1728 gnutls_init (&vpninfo->https_sess, GNUTLS_CLIENT);
1729 gnutls_session_set_ptr (vpninfo->https_sess, (void *) vpninfo);
1730 #if defined(HAVE_TROUSERS) && !defined(HAVE_GNUTLS_CERTIFICATE_SET_KEY)
1731 if (vpninfo->my_pkey == OPENCONNECT_TPM_PKEY)
1732 gnutls_sign_callback_set(vpninfo->https_sess, gtls2_tpm_sign_cb, vpninfo);
1734 err = gnutls_priority_set_direct (vpninfo->https_sess, "NONE:+VERS-TLS1.0:+SHA1:+AES-128-CBC:+RSA:+COMP-NULL:%COMPAT:%DISABLE_SAFE_RENEGOTIATION", NULL);
1736 vpn_progress(vpninfo, PRG_ERR,
1737 _("Failed to set TLS priority string: %s\n"),
1738 gnutls_strerror(err));
1742 gnutls_record_disable_padding (vpninfo->https_sess);
1743 gnutls_credentials_set (vpninfo->https_sess, GNUTLS_CRD_CERTIFICATE, vpninfo->https_cred);
1744 gnutls_transport_set_ptr(vpninfo->https_sess, /* really? */(gnutls_transport_ptr_t)(long) ssl_sock);
1746 vpn_progress(vpninfo, PRG_INFO, _("SSL negotiation with %s\n"),
1749 while ((err = gnutls_handshake (vpninfo->https_sess))) {
1750 if (err == GNUTLS_E_AGAIN) {
1751 fd_set rd_set, wr_set;
1752 int maxfd = ssl_sock;
1757 if (gnutls_record_get_direction(vpninfo->https_sess))
1758 FD_SET(ssl_sock, &wr_set);
1760 FD_SET(ssl_sock, &rd_set);
1762 if (vpninfo->cancel_fd != -1) {
1763 FD_SET(vpninfo->cancel_fd, &rd_set);
1764 if (vpninfo->cancel_fd > ssl_sock)
1765 maxfd = vpninfo->cancel_fd;
1767 select(maxfd + 1, &rd_set, &wr_set, NULL, NULL);
1768 if (vpninfo->cancel_fd != -1 &&
1769 FD_ISSET(vpninfo->cancel_fd, &rd_set)) {
1770 vpn_progress(vpninfo, PRG_ERR, _("SSL connection cancelled\n"));
1771 gnutls_deinit(vpninfo->https_sess);
1772 vpninfo->https_sess = NULL;
1776 } else if (err == GNUTLS_E_INTERRUPTED || gnutls_error_is_fatal(err)) {
1777 vpn_progress(vpninfo, PRG_ERR, _("SSL connection failure: %s\n"),
1778 gnutls_strerror(err));
1779 gnutls_deinit(vpninfo->https_sess);
1780 vpninfo->https_sess = NULL;
1784 /* non-fatal error or warning. Ignore it and continue */
1785 vpn_progress(vpninfo, PRG_TRACE,
1786 _("GnuTLS non-fatal return during handshake: %s\n"),
1787 gnutls_strerror(err));
1791 vpninfo->ssl_fd = ssl_sock;
1793 vpn_progress(vpninfo, PRG_INFO, _("Connected to HTTPS on %s\n"),
1799 void openconnect_close_https(struct openconnect_info *vpninfo, int final)
1801 if (vpninfo->peer_cert) {
1802 gnutls_x509_crt_deinit(vpninfo->peer_cert);
1803 vpninfo->peer_cert = NULL;
1805 if (vpninfo->https_sess) {
1806 gnutls_deinit(vpninfo->https_sess);
1807 vpninfo->https_sess = NULL;
1809 if (vpninfo->ssl_fd != -1) {
1810 close(vpninfo->ssl_fd);
1811 FD_CLR(vpninfo->ssl_fd, &vpninfo->select_rfds);
1812 FD_CLR(vpninfo->ssl_fd, &vpninfo->select_wfds);
1813 FD_CLR(vpninfo->ssl_fd, &vpninfo->select_efds);
1814 vpninfo->ssl_fd = -1;
1816 if (final && vpninfo->https_cred) {
1817 gnutls_certificate_free_credentials(vpninfo->https_cred);
1818 vpninfo->https_cred = NULL;
1820 if ((vpninfo->cert && !strncmp(vpninfo->cert, "pkcs11:", 7)) ||
1821 (vpninfo->sslkey && !strncmp(vpninfo->sslkey, "pkcs11:", 7))) {
1822 char pin_source[40];
1824 sprintf(pin_source, "openconnect:%p", vpninfo);
1825 p11_kit_pin_unregister_callback(pin_source, pin_callback, vpninfo);
1827 while (vpninfo->pin_cache) {
1828 struct pin_cache *cache = vpninfo->pin_cache;
1831 memset(cache->pin, 0x5a, strlen(cache->pin));
1833 vpninfo->pin_cache = cache->next;
1838 #ifdef HAVE_TROUSERS
1839 if (vpninfo->tpm_key_policy) {
1840 Tspi_Context_CloseObject(vpninfo->tpm_context, vpninfo->tpm_key_policy);
1841 vpninfo->tpm_key = 0;
1843 if (vpninfo->tpm_key) {
1844 Tspi_Context_CloseObject(vpninfo->tpm_context, vpninfo->tpm_key);
1845 vpninfo->tpm_key = 0;
1847 if (vpninfo->srk_policy) {
1848 Tspi_Context_CloseObject(vpninfo->tpm_context, vpninfo->srk_policy);
1849 vpninfo->srk_policy = 0;
1852 Tspi_Context_CloseObject(vpninfo->tpm_context, vpninfo->srk);
1855 if (vpninfo->tpm_context) {
1856 Tspi_Context_Close(vpninfo->tpm_context);
1857 vpninfo->tpm_context = 0;
1860 #ifndef HAVE_GNUTLS_CERTIFICATE_SET_KEY
1861 if (vpninfo->my_pkey && vpninfo->my_pkey != OPENCONNECT_TPM_PKEY) {
1862 gnutls_privkey_deinit(vpninfo->my_pkey);
1863 vpninfo->my_pkey = NULL;
1864 /* my_p11key went with it */
1866 if (vpninfo->my_certs) {
1868 for (i = 0; i < vpninfo->nr_my_certs; i++)
1869 gnutls_x509_crt_deinit(vpninfo->my_certs[i]);
1870 free(vpninfo->my_certs);
1871 vpninfo->my_certs = NULL;
1877 void openconnect_init_ssl(void)
1879 gnutls_global_init();
1882 int openconnect_sha1(unsigned char *result, void *data, int datalen)
1885 size_t shalen = SHA1_SIZE;
1889 if (gnutls_fingerprint(GNUTLS_DIG_SHA1, &d, result, &shalen))
1895 int openconnect_random(void *bytes, int len)
1897 if (gnutls_rnd(GNUTLS_RND_RANDOM, bytes, len))
1902 int openconnect_local_cert_md5(struct openconnect_info *vpninfo,
1905 const gnutls_datum_t *d;
1910 d = gnutls_certificate_get_ours(vpninfo->https_sess);
1914 if (gnutls_fingerprint(GNUTLS_DIG_MD5, d, buf, &md5len))
1921 static P11KitPin *pin_callback(const char *pin_source, P11KitUri *pin_uri,
1922 const char *pin_description,
1923 P11KitPinFlags flags,
1926 struct openconnect_info *vpninfo = _vpninfo;
1927 struct pin_cache **cache = &vpninfo->pin_cache;
1928 struct oc_auth_form f;
1929 struct oc_form_opt o;
1935 if (!vpninfo || !vpninfo->process_auth_form)
1938 if (p11_kit_uri_format(pin_uri, P11_KIT_URI_FOR_TOKEN, &uri))
1942 if (!strcmp(uri, (*cache)->token)) {
1945 if ((*cache)->pin) {
1946 if ((flags & P11_KIT_PIN_FLAGS_RETRY) != P11_KIT_PIN_FLAGS_RETRY)
1947 return p11_kit_pin_new_for_string((*cache)->pin);
1948 memset((*cache)->pin, 0x5a, strlen((*cache)->pin));
1949 free((*cache)->pin);
1950 (*cache)->pin = NULL;
1956 *cache = calloc(1, sizeof(struct pin_cache));
1961 (*cache)->token = uri;
1964 memset(&f, 0, sizeof(f));
1965 f.auth_id = (char *)"pkcs11_pin";
1968 message[sizeof(message)-1] = 0;
1969 snprintf(message, sizeof(message) - 1, _("PIN required for %s"), pin_description);
1970 f.message = message;
1973 * In p11-kit <= 0.12, these flags are *odd*.
1974 * RETRY is 0xa, FINAL_TRY is 0x14 and MANY_TRIES is 0x28.
1975 * So don't treat it like a sane bitmask. Fixed in
1976 * http://cgit.freedesktop.org/p11-glue/p11-kit/commit/?id=59774b11
1978 if ((flags & P11_KIT_PIN_FLAGS_RETRY) == P11_KIT_PIN_FLAGS_RETRY)
1979 f.error = (char *)_("Wrong PIN");
1981 if ((flags & P11_KIT_PIN_FLAGS_FINAL_TRY) == P11_KIT_PIN_FLAGS_FINAL_TRY)
1982 f.banner = (char *)_("This is the final try before locking!");
1983 else if ((flags & P11_KIT_PIN_FLAGS_MANY_TRIES) == P11_KIT_PIN_FLAGS_MANY_TRIES)
1984 f.banner = (char *)_("Only a few tries left before locking!");
1987 o.type = OC_FORM_OPT_PASSWORD;
1988 o.name = (char *)"pkcs11_pin";
1989 o.label = (char *)_("Enter PIN:");
1992 ret = vpninfo->process_auth_form(vpninfo->cbdata, &f);
1993 if (ret || !o.value)
1996 pin = p11_kit_pin_new_for_string(o.value);
1997 (*cache)->pin = o.value;