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\n"),
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 /* We only use the first 8 bytes of the salt for this */
617 err = gnutls_hash(hash, salt->data, 8);
621 gnutls_hash_deinit(hash, md5);
623 if (key->size - count <= sizeof(md5)) {
624 memcpy(&key->data[count], md5, key->size - count);
628 memcpy(&key->data[count], md5, sizeof(md5));
629 count += sizeof(md5);
635 static int import_openssl_pem(struct openconnect_info *vpninfo,
636 gnutls_x509_privkey_t key,
637 char type, char *pem_header, size_t pem_size)
639 gnutls_cipher_hd_t handle;
640 gnutls_cipher_algorithm_t cipher;
641 gnutls_datum_t constructed_pem;
642 gnutls_datum_t b64_data;
643 gnutls_datum_t salt, enc_key;
644 unsigned char *key_data;
647 char *pem_start = pem_header;
651 begin = "EC PRIVATE KEY";
652 else if (type == 'R')
653 begin = "RSA PRIVATE KEY";
654 else if (type == 'D')
655 begin = "DSA PRIVATE KEY";
659 while (*pem_header == '\r' || *pem_header == '\n')
662 if (strncmp(pem_header, "DEK-Info: ", 10)) {
663 vpn_progress(vpninfo, PRG_ERR,
664 _("Missing DEK-Info: header from OpenSSL encrypted key\n"));
668 p = strchr(pem_header, ',');
670 vpn_progress(vpninfo, PRG_ERR,
671 _("Cannot determine PEM encryption type\n"));
676 cipher = gnutls_cipher_get_id(pem_header);
677 /* GnuTLS calls this '3DES-CBC' but all other names match */
678 if (cipher == GNUTLS_CIPHER_UNKNOWN &&
679 !strcmp(pem_header, "DES-EDE3-CBC"))
680 cipher = GNUTLS_CIPHER_3DES_CBC;
682 if (cipher == GNUTLS_CIPHER_UNKNOWN) {
683 vpn_progress(vpninfo, PRG_ERR,
684 _("Unsupported PEM encryption type: %s\n"),
690 /* No supported algorithms have an IV larger than this, and dynamically
691 allocating it would be painful. */
693 salt.data = malloc(salt.size);
696 for (i = 0; i < salt.size * 2; i++) {
698 char *c = &pem_header[i];
700 if (*c >= '0' && *c <= '9')
702 else if (*c >= 'A' && *c <= 'F')
704 else if ((*c == '\r' || *c == '\n') && i >= 16 && !(i % 16)) {
708 vpn_progress(vpninfo, PRG_ERR,
709 _("Invalid salt in encrypted PEM file\n"));
716 salt.data[i/2] = x << 4;
719 pem_header += salt.size * 2;
720 if (*pem_header != '\r' && *pem_header != '\n') {
721 vpn_progress(vpninfo, PRG_ERR,
722 _("Invalid salt in encrypted PEM file\n"));
726 while (*pem_header == '\n' || *pem_header == '\r')
729 /* pem_header should now point to the start of the base64 content.
730 Put a -----BEGIN banner in place before it, so that we can use
731 gnutls_pem_base64_decode_alloc(). The banner has to match the
732 -----END banner, so make sure we get it right... */
734 memcpy(pem_header, "-----\n", 6);
735 pem_header -= strlen(begin);
736 memcpy(pem_header, begin, strlen(begin));
738 memcpy(pem_header, "-----BEGIN ", 11);
740 constructed_pem.data = (void *)pem_header;
741 constructed_pem.size = pem_size - (pem_header - pem_start);
743 err = gnutls_pem_base64_decode_alloc(begin, &constructed_pem, &b64_data);
745 vpn_progress(vpninfo, PRG_ERR,
746 _("Error base64-decoding encrypted PEM file: %s\n"),
747 gnutls_strerror(err));
751 if (b64_data.size < 16) {
752 /* Just to be sure our parsing is OK */
753 vpn_progress(vpninfo, PRG_ERR,
754 _("Encrypted PEM file too short\n"));
760 enc_key.size = gnutls_cipher_get_key_size(cipher);
761 enc_key.data = malloc(enc_key.size);
765 key_data = malloc(b64_data.size);
769 pass = vpninfo->cert_password;
770 vpninfo->cert_password = NULL;
773 memcpy(key_data, b64_data.data, b64_data.size);
775 ret = openssl_hash_password(vpninfo, pass, &enc_key, &salt);
779 err = gnutls_cipher_init(&handle, cipher, &enc_key, &salt);
781 vpn_progress(vpninfo, PRG_ERR,
782 _("Failed to initialise cipher for decrypting PEM file: %s\n"),
783 gnutls_strerror(err));
784 gnutls_cipher_deinit(handle);
789 err = gnutls_cipher_decrypt(handle, key_data, b64_data.size);
790 gnutls_cipher_deinit(handle);
792 vpn_progress(vpninfo, PRG_ERR,
793 _("Failed to decrypt PEM key: %s\n"),
794 gnutls_strerror(err));
799 /* We have to strip any padding for GnuTLS to accept it.
800 So a bit more ASN.1 parsing for us.
801 FIXME: Consolidate with similar code in gnutls_tpm.c */
802 if (key_data[0] == 0x30) {
803 gnutls_datum_t key_datum;
804 int blocksize = gnutls_cipher_get_block_size(cipher);
805 int keylen = key_data[1];
809 int lenlen = keylen & 0x7f;
817 keylen |= key_data[ofs++];
823 /* If there appears to be more padding than required, fail */
824 if (b64_data.size - keylen >= blocksize)
827 /* If the padding bytes aren't all equal to the amount of padding, fail */
829 while (ofs < b64_data.size) {
830 if (key_data[ofs] != b64_data.size - keylen)
835 key_datum.data = key_data;
836 key_datum.size = keylen;
837 err = gnutls_x509_privkey_import(key, &key_datum, GNUTLS_X509_FMT_DER);
845 vpn_progress(vpninfo, PRG_ERR, _("Decrypting PEM key failed\n"));
848 err = request_passphrase(vpninfo, "openconnect_pem",
849 &pass, _("Enter PEM pass phrase:"));
867 static int load_certificate(struct openconnect_info *vpninfo)
869 gnutls_datum_t fdata;
870 gnutls_x509_privkey_t key = NULL;
871 #if defined (HAVE_P11KIT) || defined (HAVE_TROUSERS)
872 gnutls_privkey_t pkey = NULL;
873 gnutls_datum_t pkey_sig = {NULL, 0};
874 void *dummy_hash_data = &load_certificate;
877 char *cert_url = (char *)vpninfo->cert;
878 char *key_url = (char *)vpninfo->sslkey;
879 gnutls_pkcs11_privkey_t p11key = NULL;
882 gnutls_x509_crl_t crl = NULL;
883 gnutls_x509_crt_t last_cert, cert = NULL;
884 gnutls_x509_crt_t *extra_certs = NULL, *supporting_certs = NULL;
885 unsigned int nr_supporting_certs = 0, nr_extra_certs = 0;
886 unsigned int certs_to_free = 0; /* How many of supporting_certs */
887 int err; /* GnuTLS error */
890 int cert_is_p11 = 0, key_is_p11 = 0;
891 unsigned char key_id[20];
892 size_t key_id_size = sizeof(key_id);
897 key_is_p11 = !strncmp(vpninfo->sslkey, "pkcs11:", 7);
898 cert_is_p11 = !strncmp(vpninfo->cert, "pkcs11:", 7);
901 if (key_is_p11 || cert_is_p11) {
902 vpn_progress(vpninfo, PRG_ERR,
903 _("This binary built without PKCS#11 support\n"));
907 /* Install PIN handler if either certificate or key are coming from PKCS#11 */
908 if (key_is_p11 || cert_is_p11) {
909 CK_OBJECT_CLASS class;
914 sprintf(pin_source, "openconnect:%p", vpninfo);
915 p11_kit_pin_register_callback(pin_source, pin_callback, vpninfo, NULL);
917 uri = p11_kit_uri_new();
919 attr.type = CKA_CLASS;
920 attr.pValue = &class;
921 attr.ulValueLen = sizeof(class);
923 /* Add appropriate pin-source and object-type attributes to
924 both certificate and key URLs, unless they already exist. */
926 !p11_kit_uri_parse(cert_url, P11_KIT_URI_FOR_ANY, uri)) {
927 if (!p11_kit_uri_get_pin_source(uri))
928 p11_kit_uri_set_pin_source(uri, pin_source);
929 if (!p11_kit_uri_get_attribute(uri, CKA_CLASS)) {
930 class = CKO_CERTIFICATE;
931 p11_kit_uri_set_attribute(uri, &attr);
933 p11_kit_uri_format(uri, P11_KIT_URI_FOR_ANY, &cert_url);
937 !p11_kit_uri_parse(key_url, P11_KIT_URI_FOR_ANY, uri)) {
938 if (!p11_kit_uri_get_pin_source(uri))
939 p11_kit_uri_set_pin_source(uri, pin_source);
940 if (!p11_kit_uri_get_attribute(uri, CKA_CLASS)) {
941 class = CKO_PRIVATE_KEY;
942 p11_kit_uri_set_attribute(uri, &attr);
944 p11_kit_uri_format(uri, P11_KIT_URI_FOR_ANY, &key_url);
947 p11_kit_uri_free(uri);
950 /* Load certificate(s) first... */
952 vpn_progress(vpninfo, PRG_TRACE,
953 _("Using PKCS#11 certificate %s\n"), cert_url);
955 err = gnutls_x509_crt_init(&cert);
960 err = gnutls_x509_crt_import_pkcs11_url(cert, cert_url, 0);
961 if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
962 err = gnutls_x509_crt_import_pkcs11_url(cert, cert_url,
963 GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
965 vpn_progress(vpninfo, PRG_ERR,
966 _("Error loading certificate from PKCS#11: %s\n"),
967 gnutls_strerror(err));
973 #endif /* HAVE_P11KIT */
975 /* OK, not a PKCS#11 certificate so it must be coming from a file... */
976 vpn_progress(vpninfo, PRG_TRACE,
977 _("Using certificate file %s\n"), vpninfo->cert);
979 /* Load file contents */
980 ret = load_datum(vpninfo, &fdata, vpninfo->cert);
985 if (!key_is_p11 && (vpninfo->cert_type == CERT_TYPE_PKCS12 ||
986 vpninfo->cert_type == CERT_TYPE_UNKNOWN)) {
987 /* PKCS#12 should actually contain certificates *and* private key */
988 ret = load_pkcs12_certificate(vpninfo, &fdata, &key,
989 &supporting_certs, &nr_supporting_certs,
990 &extra_certs, &nr_extra_certs,
995 if (nr_supporting_certs) {
996 cert = supporting_certs[0];
999 vpn_progress(vpninfo, PRG_ERR,
1000 _("PKCS#11 file contained no certificate\n"));
1005 /* It returned NOT_PKCS12.
1006 Fall through to try PEM formats. */
1009 /* We need to know how many there are in *advance*; it won't just allocate
1010 the array for us :( */
1011 nr_extra_certs = count_x509_certificates(&fdata);
1012 if (!nr_extra_certs)
1013 nr_extra_certs = 1; /* wtf? Oh well, we'll fail later... */
1015 extra_certs = calloc(nr_extra_certs, sizeof(cert));
1021 err = gnutls_x509_crt_list_import(extra_certs, &nr_extra_certs, &fdata,
1022 GNUTLS_X509_FMT_PEM, 0);
1025 if (!err || err == GNUTLS_E_NO_CERTIFICATE_FOUND)
1026 reason = _("No certificate found in file");
1028 reason = gnutls_strerror(err);
1030 vpn_progress(vpninfo, PRG_ERR,
1031 _("Loading certificate failed: %s\n"),
1036 nr_extra_certs = err;
1041 /* Now we have either a single certificate in 'cert', or an array of
1042 them in extra_certs[]. Next we look for the private key ... */
1043 #if defined (HAVE_P11KIT)
1045 vpn_progress(vpninfo, PRG_TRACE,
1046 _("Using PKCS#11 key %s\n"), key_url);
1048 err = gnutls_pkcs11_privkey_init(&p11key);
1050 vpn_progress(vpninfo, PRG_ERR,
1051 _("Error initialising PKCS#11 key structure: %s\n"),
1052 gnutls_strerror(err));
1057 err = gnutls_pkcs11_privkey_import_url(p11key, key_url, 0);
1059 /* Annoyingly, some tokens don't even admit the *existence* of
1060 the key until they're logged in. And thus a search doesn't
1061 work unless it specifies the *token* too. But if the URI for
1062 key and cert are the same, and the cert was found, then we
1063 can work out what token the *cert* was found in and try that
1064 before we give up... */
1065 if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE &&
1066 vpninfo->cert == vpninfo->sslkey) {
1067 gnutls_pkcs11_obj_t crt;
1069 CK_TOKEN_INFO *token;
1073 if (gnutls_pkcs11_obj_init(&crt))
1075 if (gnutls_pkcs11_obj_import_url(crt, cert_url, 0))
1077 uri = p11_kit_uri_new();
1080 if (p11_kit_uri_parse(key_url, P11_KIT_URI_FOR_ANY, uri))
1082 token = p11_kit_uri_get_token_info(uri);
1086 if (!token->label[0]) {
1087 s = sizeof(token->label) + 1;
1088 if (!gnutls_pkcs11_obj_get_info(crt, GNUTLS_PKCS11_OBJ_TOKEN_LABEL,
1091 memcpy(token->label, buf, s);
1092 memset(token->label + s, ' ',
1093 sizeof(token->label) - s);
1096 if (!token->manufacturerID[0]) {
1097 s = sizeof(token->manufacturerID) + 1;
1098 if (!gnutls_pkcs11_obj_get_info(crt, GNUTLS_PKCS11_OBJ_TOKEN_MANUFACTURER,
1101 memcpy(token->manufacturerID, buf, s);
1102 memset(token->manufacturerID + s, ' ',
1103 sizeof(token->manufacturerID) - s);
1106 if (!token->model[0]) {
1107 s = sizeof(token->model) + 1;
1108 if (!gnutls_pkcs11_obj_get_info(crt, GNUTLS_PKCS11_OBJ_TOKEN_MODEL,
1111 memcpy(token->model, buf, s);
1112 memset(token->model + s, ' ',
1113 sizeof(token->model) - s);
1116 if (!token->serialNumber[0]) {
1117 s = sizeof(token->serialNumber) + 1;
1118 if (!gnutls_pkcs11_obj_get_info(crt, GNUTLS_PKCS11_OBJ_TOKEN_SERIAL,
1121 memcpy(token->serialNumber, buf, s);
1122 memset(token->serialNumber + s, ' ',
1123 sizeof(token->serialNumber) - s);
1130 if (!p11_kit_uri_format(uri, P11_KIT_URI_FOR_ANY, &key_url))
1131 err = gnutls_pkcs11_privkey_import_url(p11key, key_url, 0);
1133 p11_kit_uri_free(uri);
1135 gnutls_pkcs11_obj_deinit(crt);
1140 vpn_progress(vpninfo, PRG_ERR,
1141 _("Error importing PKCS#11 URL %s: %s\n"),
1142 key_url, gnutls_strerror(err));
1143 gnutls_pkcs11_privkey_deinit(p11key);
1148 err = gnutls_privkey_init(&pkey);
1150 vpn_progress(vpninfo, PRG_ERR,
1151 _("Error initialising private key structure: %s\n"),
1152 gnutls_strerror(err));
1153 gnutls_pkcs11_privkey_deinit(p11key);
1158 err = gnutls_privkey_import_pkcs11(pkey, p11key, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
1160 vpn_progress(vpninfo, PRG_ERR,
1161 _("Error importing PKCS#11 key into private key structure: %s\n"),
1162 gnutls_strerror(err));
1163 gnutls_pkcs11_privkey_deinit(p11key);
1167 #ifndef HAVE_GNUTLS_CERTIFICATE_SET_KEY
1168 /* This can be set now and doesn't need to be separately freed.
1169 It goes with the pkey. This is a PITA; it would be better
1170 if there was a way to get the p11key *back* from a privkey
1171 that we *know* is based on one. In fact, since this is only
1172 for GnuTLS 2.12 and we *know* the gnutls_privkey_st won't
1173 ever change there, so we *could* do something evil... but
1175 vpninfo->my_p11key = p11key;
1176 #endif /* !SET_KEY */
1179 #endif /* HAVE_P11KIT */
1181 /* OK, not a PKCS#11 key so it must be coming from a file... load the
1182 file into memory, unless it's the same as the cert file and we
1183 already loaded that. */
1184 if (!fdata.data || vpninfo->sslkey != vpninfo->cert) {
1185 gnutls_free(fdata.data);
1188 vpn_progress(vpninfo, PRG_TRACE,
1189 _("Using private key file %s\n"), vpninfo->sslkey);
1191 ret = load_datum(vpninfo, &fdata, vpninfo->sslkey);
1196 /* Is it a PEM file with a TPM key blob? */
1197 if (vpninfo->cert_type == CERT_TYPE_TPM ||
1198 (vpninfo->cert_type == CERT_TYPE_UNKNOWN &&
1199 strstr((char *)fdata.data, "-----BEGIN TSS KEY BLOB-----"))) {
1200 #ifndef HAVE_TROUSERS
1201 vpn_progress(vpninfo, PRG_ERR,
1202 _("This version of OpenConnect was built without TPM support\n"));
1205 ret = load_tpm_key(vpninfo, &fdata, &pkey, &pkey_sig);
1213 /* OK, try other PEM files... */
1214 gnutls_x509_privkey_init(&key);
1215 if ((pem_header = strstr((char *)fdata.data, "-----BEGIN RSA PRIVATE KEY-----")) ||
1216 (pem_header = strstr((char *)fdata.data, "-----BEGIN DSA PRIVATE KEY-----")) ||
1217 (pem_header = strstr((char *)fdata.data, "-----BEGIN EC PRIVATE KEY-----"))) {
1218 /* PKCS#1 files, including OpenSSL's odd encrypted version */
1219 char type = pem_header[11];
1220 char *p = strchr(pem_header, '\n');
1222 vpn_progress(vpninfo, PRG_ERR,
1223 _("Failed to interpret PEM file\n"));
1227 while (*p == '\n' || *p == '\r')
1230 if (!strncmp(p, "Proc-Type: 4,ENCRYPTED", 22)) {
1232 while (*p == '\n' || *p == '\r')
1234 ret = import_openssl_pem(vpninfo, key, type, p,
1235 fdata.size - (p - (char *)fdata.data));
1239 err = gnutls_x509_privkey_import(key, &fdata, GNUTLS_X509_FMT_PEM);
1241 vpn_progress(vpninfo, PRG_ERR,
1242 _("Failed to load PKCS#1 private key: %s\n"),
1243 gnutls_strerror(err));
1248 } else if (strstr((char *)fdata.data, "-----BEGIN PRIVATE KEY-----")) {
1249 /* Unencrypted PKCS#8 */
1250 err = gnutls_x509_privkey_import_pkcs8(key, &fdata,
1251 GNUTLS_X509_FMT_PEM,
1252 NULL, GNUTLS_PKCS_PLAIN);
1254 vpn_progress(vpninfo, PRG_ERR,
1255 _("Failed to load private key as PKCS#8: %s\n"),
1256 gnutls_strerror(err));
1260 } else if (strstr((char *)fdata.data, "-----BEGIN ENCRYPTED PRIVATE KEY-----")) {
1261 /* Encrypted PKCS#8 */
1262 char *pass = vpninfo->cert_password;
1264 while ((err = gnutls_x509_privkey_import_pkcs8(key, &fdata,
1265 GNUTLS_X509_FMT_PEM,
1267 if (err != GNUTLS_E_DECRYPTION_FAILED) {
1268 vpn_progress(vpninfo, PRG_ERR,
1269 _("Failed to load private key as PKCS#8: %s\n"),
1270 gnutls_strerror(err));
1274 vpninfo->cert_password = NULL;
1276 vpn_progress(vpninfo, PRG_ERR,
1277 _("Failed to decrypt PKCS#8 certificate file\n"));
1280 err = request_passphrase(vpninfo, "openconnect_pem",
1281 &pass, _("Enter PEM pass phrase:"));
1288 vpninfo->cert_password = NULL;
1290 vpn_progress(vpninfo, PRG_ERR,
1291 _("Failed to determine type of private key %s\n"),
1297 /* Now attempt to make sure we use the *correct* certificate, to match
1298 the key. Since we have a software key, we can easily query it and
1299 compare its key_id with each certificate till we find a match. */
1300 err = gnutls_x509_privkey_get_key_id(key, 0, key_id, &key_id_size);
1302 vpn_progress(vpninfo, PRG_ERR,
1303 _("Failed to get key ID: %s\n"),
1304 gnutls_strerror(err));
1308 /* If extra_certs[] is NULL, we have one candidate in 'cert' to check. */
1309 for (i = 0; i < (extra_certs?nr_extra_certs:1); i++) {
1310 unsigned char cert_id[20];
1311 size_t cert_id_size = sizeof(cert_id);
1313 err = gnutls_x509_crt_get_key_id(extra_certs?extra_certs[i]:cert, 0, cert_id, &cert_id_size);
1317 if (cert_id_size == key_id_size && !memcmp(cert_id, key_id, key_id_size)) {
1319 cert = extra_certs[i];
1320 extra_certs[i] = NULL;
1325 /* There's no pkey (there's an x509 key), so even if p11-kit or trousers is
1326 enabled we'll fall straight through the bit at match_cert: below, and go
1327 directly to the bit where it prints the 'no match found' error and exits. */
1329 #if defined (HAVE_P11KIT) || defined (HAVE_TROUSERS)
1331 /* If we have a privkey from PKCS#11 or TPM, we can't do the simple comparison
1332 of key ID that we do for software keys to find which certificate is a
1333 match. So sign some dummy data and then check the signature against each
1334 of the available certificates until we find the right one. */
1336 /* The TPM code may have already signed it, to test authorisation. We
1337 only sign here for PKCS#11 keys, in which case fdata might be
1338 empty too so point it at dummy data. */
1339 if (!pkey_sig.data) {
1341 fdata.data = dummy_hash_data;
1345 err = sign_dummy_data(vpninfo, pkey, &fdata, &pkey_sig);
1347 vpn_progress(vpninfo, PRG_ERR,
1348 _("Error signing test data with private key: %s\n"),
1349 gnutls_strerror(err));
1355 /* If extra_certs[] is NULL, we have one candidate in 'cert' to check. */
1356 for (i=0; i < (extra_certs?nr_extra_certs:1); i++) {
1357 gnutls_pubkey_t pubkey;
1359 gnutls_pubkey_init(&pubkey);
1360 err = gnutls_pubkey_import_x509(pubkey, extra_certs?extra_certs[i]:cert, 0);
1362 vpn_progress(vpninfo, PRG_ERR,
1363 _("Error validating signature against certificate: %s\n"),
1364 gnutls_strerror(err));
1365 /* We'll probably fail shortly if we don't find it. */
1366 gnutls_pubkey_deinit(pubkey);
1369 err = gnutls_pubkey_verify_data(pubkey, 0, &fdata, &pkey_sig);
1370 gnutls_pubkey_deinit(pubkey);
1374 cert = extra_certs[i];
1375 extra_certs[i] = NULL;
1377 gnutls_free(pkey_sig.data);
1381 gnutls_free(pkey_sig.data);
1383 #endif /* P11KIT || TROUSERS */
1385 /* We shouldn't reach this. It means that we didn't find *any* matching cert */
1386 vpn_progress(vpninfo, PRG_ERR,
1387 _("No SSL certificate found to match private key\n"));
1391 /********************************************************************/
1393 /* Now we have a key in either 'key' or 'pkey', a matching cert in 'cert',
1394 and potentially a list of other certs in 'extra_certs[]'. If we loaded
1395 a PKCS#12 file we may have a trust chain in 'supporting_certs[]' too. */
1396 check_certificate_expiry(vpninfo, cert);
1397 get_cert_name(cert, name, sizeof(name));
1398 vpn_progress(vpninfo, PRG_INFO, _("Using client certificate '%s'\n"),
1402 err = gnutls_certificate_set_x509_crl(vpninfo->https_cred, &crl, 1);
1404 vpn_progress(vpninfo, PRG_ERR,
1405 _("Setting certificate recovation list failed: %s\n"),
1406 gnutls_strerror(err));
1412 /* OpenSSL has problems with certificate chains — if there are
1413 multiple certs with the same name, it doesn't necessarily
1414 choose the _right_ one. (RT#1942)
1415 Pick the right ones for ourselves and add them manually. */
1417 if (nr_supporting_certs) {
1418 /* We already got a bunch of certs from PKCS#12 file. Remember
1419 how many need to be freed when we're done, since we'll
1420 expand the supporting_certs array with more from the cafile
1421 and extra_certs[] array if we can, and those extra certs
1422 must not be freed (twice). */
1423 last_cert = supporting_certs[nr_supporting_certs-1];
1424 certs_to_free = nr_supporting_certs;
1427 certs_to_free = nr_supporting_certs = 1;
1430 gnutls_x509_crt_t issuer;
1432 for (i = 0; i < nr_extra_certs; i++) {
1433 if (extra_certs[i] &&
1434 gnutls_x509_crt_check_issuer(last_cert, extra_certs[i]) &&
1435 !check_issuer_sanity(last_cert, extra_certs[i]))
1439 if (i < nr_extra_certs) {
1440 /* We found the next cert in the chain in extra_certs[] */
1441 issuer = extra_certs[i];
1443 /* Look for it in the system trust cafile too. */
1444 err = gnutls_certificate_get_issuer(vpninfo->https_cred,
1445 last_cert, &issuer, 0);
1449 /* The check_issuer_sanity() function works fine as a workaround where
1450 it was used above, but when gnutls_certificate_get_issuer() returns
1451 a bogus cert, there's nothing we can do to fix it up. We don't get
1452 to iterate over all the available certs like we can over our own
1454 if (check_issuer_sanity(last_cert, issuer)) {
1455 /* Hm, is there a bug reference for this? Or just the git commit
1456 reference (c1ef7efb in master, 5196786c in gnutls_3_0_x-2)? */
1457 vpn_progress(vpninfo, PRG_ERR,
1458 _("WARNING: GnuTLS returned incorrect issuer certs; authentication may fail!\n"));
1463 if (issuer == last_cert) {
1464 /* Don't actually include the root CA. If they don't already trust it,
1465 then handing it to them isn't going to help. But don't omit the
1466 original certificate if it's self-signed. */
1467 if (nr_supporting_certs > 1)
1468 nr_supporting_certs--;
1472 /* OK, we found a new cert to add to our chain. */
1473 supporting_certs = gnutls_realloc(supporting_certs,
1474 sizeof(cert) * ++nr_supporting_certs);
1475 if (!supporting_certs) {
1476 vpn_progress(vpninfo, PRG_ERR,
1477 _("Failed to allocate memory for supporting certificates\n"));
1478 /* The world is probably about to end, but try without them anyway */
1484 /* First time we actually allocated an array? Copy the first cert into it */
1485 if (nr_supporting_certs == 2)
1486 supporting_certs[0] = cert;
1488 /* Append the new one */
1489 supporting_certs[nr_supporting_certs-1] = issuer;
1492 for (i = 1; i < nr_supporting_certs; i++) {
1493 get_cert_name(supporting_certs[i], name, sizeof(name));
1495 vpn_progress(vpninfo, PRG_DEBUG,
1496 _("Adding supporting CA '%s'\n"), name);
1499 /* OK, now we've checked the cert expiry and warned the user if it's
1500 going to expire soon, and we've built up as much of a trust chain
1501 in supporting_certs[] as we can find, to help the server work around
1502 OpenSSL RT#1942. Set up the GnuTLS credentials with the appropriate
1503 key and certs. GnuTLS makes us do this differently for X509 privkeys
1504 vs. TPM/PKCS#11 "generic" privkeys, and the latter is particularly
1505 'fun' for GnuTLS 2.12... */
1506 #if defined (HAVE_P11KIT) || defined (HAVE_TROUSERS)
1508 err = assign_privkey(vpninfo, pkey,
1509 supporting_certs ? supporting_certs : &cert,
1510 nr_supporting_certs,
1511 extra_certs, nr_extra_certs);
1513 pkey = NULL; /* we gave it away, and potentially also some
1514 of extra_certs[] may have been zeroed. */
1517 #endif /* P11KIT || TROUSERS */
1518 err = gnutls_certificate_set_x509_key(vpninfo->https_cred,
1519 supporting_certs ? supporting_certs : &cert,
1520 nr_supporting_certs, key);
1523 vpn_progress(vpninfo, PRG_ERR,
1524 _("Setting certificate failed: %s\n"),
1525 gnutls_strerror(err));
1531 gnutls_x509_crl_deinit(crl);
1533 gnutls_x509_privkey_deinit(key);
1534 if (supporting_certs) {
1535 for (i = 0; i < certs_to_free; i++) {
1536 if (supporting_certs[i])
1537 gnutls_x509_crt_deinit(supporting_certs[i]);
1539 gnutls_free(supporting_certs);
1541 /* Not if supporting_certs. It's supporting_certs[0] then and
1542 was already freed. */
1543 gnutls_x509_crt_deinit(cert);
1545 for (i = 0; i < nr_extra_certs; i++) {
1547 gnutls_x509_crt_deinit(extra_certs[i]);
1549 gnutls_free(extra_certs);
1551 #if defined (HAVE_P11KIT) || defined (HAVE_TROUSERS)
1552 if (pkey && pkey != OPENCONNECT_TPM_PKEY)
1553 gnutls_privkey_deinit(pkey);
1554 /* If we support arbitrary privkeys, we might have abused fdata.data
1555 just to point to something to hash. Don't free it in that case! */
1556 if (fdata.data != dummy_hash_data)
1558 gnutls_free(fdata.data);
1561 if (cert_url != vpninfo->cert)
1563 if (key_url != vpninfo->sslkey)
1569 static int get_cert_fingerprint(struct openconnect_info *vpninfo,
1570 gnutls_x509_crt_t cert,
1571 gnutls_digest_algorithm_t algo,
1574 unsigned char md[256];
1575 size_t md_size = sizeof(md);
1578 if (gnutls_x509_crt_get_fingerprint(cert, algo, md, &md_size))
1581 for (i=0; i < md_size; i++)
1582 sprintf(&buf[i*2], "%02X", md[i]);
1587 int get_cert_md5_fingerprint(struct openconnect_info *vpninfo,
1588 OPENCONNECT_X509 *cert, char *buf)
1590 return get_cert_fingerprint(vpninfo, cert, GNUTLS_DIG_MD5, buf);
1593 int openconnect_get_cert_sha1(struct openconnect_info *vpninfo,
1594 OPENCONNECT_X509 *cert, char *buf)
1596 return get_cert_fingerprint(vpninfo, cert, GNUTLS_DIG_SHA1, buf);
1599 char *openconnect_get_cert_details(struct openconnect_info *vpninfo,
1600 OPENCONNECT_X509 *cert)
1605 if (gnutls_x509_crt_print(cert, GNUTLS_CRT_PRINT_FULL, &buf))
1608 /* Just in case gnutls_free() isn't free(), we can't steal it. */
1609 ret = strdup((char *)buf.data);
1610 gnutls_free(buf.data);
1615 int openconnect_get_cert_DER(struct openconnect_info *vpninfo,
1616 OPENCONNECT_X509 *cert, unsigned char **buf)
1619 unsigned char *ret = NULL;
1621 if (gnutls_x509_crt_export(cert, GNUTLS_X509_FMT_DER, ret, &l) !=
1622 GNUTLS_E_SHORT_MEMORY_BUFFER)
1629 if (gnutls_x509_crt_export(cert, GNUTLS_X509_FMT_DER, ret, &l)) {
1637 static int verify_peer(gnutls_session_t session)
1639 struct openconnect_info *vpninfo = gnutls_session_get_ptr(session);
1640 const gnutls_datum_t *cert_list;
1641 gnutls_x509_crt_t cert;
1642 unsigned int status, cert_list_size;
1643 const char *reason = NULL;
1646 if (vpninfo->peer_cert) {
1647 gnutls_x509_crt_deinit(vpninfo->peer_cert);
1648 vpninfo->peer_cert = NULL;
1651 cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
1653 vpn_progress(vpninfo, PRG_ERR, _("Server presented no certificate\n"));
1654 return GNUTLS_E_CERTIFICATE_ERROR;
1657 if (vpninfo->servercert) {
1658 unsigned char sha1bin[SHA1_SIZE];
1659 char fingerprint[(SHA1_SIZE * 2) + 1];
1662 err = openconnect_sha1(sha1bin, cert_list[0].data, cert_list[0].size);
1664 vpn_progress(vpninfo, PRG_ERR,
1665 _("Could not calculate SHA1 of server's certificate\n"));
1666 return GNUTLS_E_CERTIFICATE_ERROR;
1668 for (i=0; i < SHA1_SIZE; i++)
1669 sprintf(&fingerprint[i*2], "%02X", sha1bin[i]);
1671 if (strcasecmp(vpninfo->servercert, fingerprint)) {
1672 vpn_progress(vpninfo, PRG_ERR,
1673 _("Server SSL certificate didn't match: %s\n"), fingerprint);
1674 return GNUTLS_E_CERTIFICATE_ERROR;
1679 err = gnutls_certificate_verify_peers2 (session, &status);
1681 vpn_progress(vpninfo, PRG_ERR, _("Error checking server cert status\n"));
1682 return GNUTLS_E_CERTIFICATE_ERROR;
1685 if (status & GNUTLS_CERT_REVOKED)
1686 reason = _("certificate revoked");
1687 else if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
1688 reason = _("signer not found");
1689 else if (status & GNUTLS_CERT_SIGNER_NOT_CA)
1690 reason = _("signer not a CA certificate");
1691 else if (status & GNUTLS_CERT_INSECURE_ALGORITHM)
1692 reason = _("insecure algorithm");
1693 else if (status & GNUTLS_CERT_NOT_ACTIVATED)
1694 reason = _("certificate not yet activated");
1695 else if (status & GNUTLS_CERT_EXPIRED)
1696 reason = _("certificate expired");
1697 else if (status & GNUTLS_CERT_INVALID)
1698 /* If this is set and no other reason, it apparently means
1699 that signature verification failed. Not entirely sure
1700 why we don't just set a bit for that too. */
1701 reason = _("signature verification failed");
1703 err = gnutls_x509_crt_init(&cert);
1705 vpn_progress(vpninfo, PRG_ERR, _("Error initialising X509 cert structure\n"));
1706 return GNUTLS_E_CERTIFICATE_ERROR;
1709 err = gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER);
1711 vpn_progress(vpninfo, PRG_ERR, _("Error importing server's cert\n"));
1712 gnutls_x509_crt_deinit(cert);
1713 return GNUTLS_E_CERTIFICATE_ERROR;
1716 if (!reason && !gnutls_x509_crt_check_hostname(cert, vpninfo->hostname))
1717 reason = _("certificate does not match hostname");
1720 vpn_progress(vpninfo, PRG_INFO, "Server certificate verify failed: %s\n",
1722 if (vpninfo->validate_peer_cert)
1723 err = vpninfo->validate_peer_cert(vpninfo->cbdata,
1725 reason) ? GNUTLS_E_CERTIFICATE_ERROR : 0;
1727 err = GNUTLS_E_CERTIFICATE_ERROR;
1730 vpninfo->peer_cert = cert;
1736 int openconnect_open_https(struct openconnect_info *vpninfo)
1741 if (vpninfo->https_sess)
1744 ssl_sock = connect_https_socket(vpninfo);
1748 if (!vpninfo->https_cred) {
1749 gnutls_certificate_allocate_credentials(&vpninfo->https_cred);
1750 #ifdef HAVE_GNUTLS_CERTIFICATE_SET_X509_SYSTEM_TRUST
1751 gnutls_certificate_set_x509_system_trust(vpninfo->https_cred);
1753 gnutls_certificate_set_x509_trust_file(vpninfo->https_cred,
1754 DEFAULT_SYSTEM_CAFILE,
1755 GNUTLS_X509_FMT_PEM);
1757 gnutls_certificate_set_verify_function (vpninfo->https_cred,
1760 #ifdef ANDROID_KEYSTORE
1761 if (vpninfo->cafile && !strncmp(vpninfo->cafile, "keystore:", 9)) {
1762 gnutls_datum_t datum;
1763 unsigned int nr_certs;
1765 err = load_datum(vpninfo, &datum, vpninfo->cafile);
1769 /* For GnuTLS 3.x We should use gnutls_x509_crt_list_import2() */
1770 nr_certs = count_x509_certificates(&datum);
1772 gnutls_x509_crt *certs;
1775 certs = calloc(nr_certs, sizeof(*certs));
1777 vpn_progress(vpninfo, PRG_ERR,
1778 _("Failed to allocate memory for cafile certs\n"));
1779 gnutls_free(datum.data);
1783 err = gnutls_x509_crt_list_import(certs, &nr_certs, &datum,
1784 GNUTLS_X509_FMT_PEM, 0);
1785 gnutls_free(datum.data);
1788 err = gnutls_certificate_set_x509_trust(vpninfo->https_cred,
1791 for (i = 0; i < nr_certs; i++)
1792 gnutls_x509_crt_deinit(certs[i]);
1795 /* From crt_list_import or set_x509_trust */
1796 vpn_progress(vpninfo, PRG_ERR,
1797 _("Failed to read certs from cafile: %s\n"),
1798 gnutls_strerror(err));
1805 if (vpninfo->cafile) {
1806 err = gnutls_certificate_set_x509_trust_file(vpninfo->https_cred,
1808 GNUTLS_X509_FMT_PEM);
1810 vpn_progress(vpninfo, PRG_ERR,
1811 _("Failed to open CA file '%s': %s\n"),
1812 vpninfo->cafile, gnutls_strerror(err));
1818 if (vpninfo->cert) {
1819 err = load_certificate(vpninfo);
1821 vpn_progress(vpninfo, PRG_ERR,
1822 _("Loading certificate failed. Aborting.\n"));
1828 gnutls_init (&vpninfo->https_sess, GNUTLS_CLIENT);
1829 gnutls_session_set_ptr (vpninfo->https_sess, (void *) vpninfo);
1830 #if defined(HAVE_TROUSERS) && !defined(HAVE_GNUTLS_CERTIFICATE_SET_KEY)
1831 if (vpninfo->my_pkey == OPENCONNECT_TPM_PKEY)
1832 gnutls_sign_callback_set(vpninfo->https_sess, gtls2_tpm_sign_cb, vpninfo);
1835 err = gnutls_priority_set_direct (vpninfo->https_sess,
1836 "NORMAL:-VERS-TLS-ALL:+VERS-TLS1.0:"
1837 #if GNUTLS_VERSION_MAJOR >= 3
1840 "%COMPAT:%DISABLE_SAFE_RENEGOTIATION:%LATEST_RECORD_VERSION",
1843 vpn_progress(vpninfo, PRG_ERR,
1844 _("Failed to set TLS priority string: %s\n"),
1845 gnutls_strerror(err));
1846 gnutls_deinit(vpninfo->https_sess);
1847 vpninfo->https_sess = NULL;
1852 gnutls_record_disable_padding (vpninfo->https_sess);
1853 gnutls_credentials_set (vpninfo->https_sess, GNUTLS_CRD_CERTIFICATE, vpninfo->https_cred);
1854 gnutls_transport_set_ptr(vpninfo->https_sess, /* really? */(gnutls_transport_ptr_t)(long) ssl_sock);
1856 vpn_progress(vpninfo, PRG_INFO, _("SSL negotiation with %s\n"),
1859 while ((err = gnutls_handshake (vpninfo->https_sess))) {
1860 if (err == GNUTLS_E_AGAIN) {
1861 fd_set rd_set, wr_set;
1862 int maxfd = ssl_sock;
1867 if (gnutls_record_get_direction(vpninfo->https_sess))
1868 FD_SET(ssl_sock, &wr_set);
1870 FD_SET(ssl_sock, &rd_set);
1872 if (vpninfo->cancel_fd != -1) {
1873 FD_SET(vpninfo->cancel_fd, &rd_set);
1874 if (vpninfo->cancel_fd > ssl_sock)
1875 maxfd = vpninfo->cancel_fd;
1877 select(maxfd + 1, &rd_set, &wr_set, NULL, NULL);
1878 if (vpninfo->cancel_fd != -1 &&
1879 FD_ISSET(vpninfo->cancel_fd, &rd_set)) {
1880 vpn_progress(vpninfo, PRG_ERR, _("SSL connection cancelled\n"));
1881 gnutls_deinit(vpninfo->https_sess);
1882 vpninfo->https_sess = NULL;
1886 } else if (err == GNUTLS_E_INTERRUPTED || gnutls_error_is_fatal(err)) {
1887 vpn_progress(vpninfo, PRG_ERR, _("SSL connection failure: %s\n"),
1888 gnutls_strerror(err));
1889 gnutls_deinit(vpninfo->https_sess);
1890 vpninfo->https_sess = NULL;
1894 /* non-fatal error or warning. Ignore it and continue */
1895 vpn_progress(vpninfo, PRG_TRACE,
1896 _("GnuTLS non-fatal return during handshake: %s\n"),
1897 gnutls_strerror(err));
1901 vpninfo->ssl_fd = ssl_sock;
1903 vpn_progress(vpninfo, PRG_INFO, _("Connected to HTTPS on %s\n"),
1909 void openconnect_close_https(struct openconnect_info *vpninfo, int final)
1911 if (vpninfo->peer_cert) {
1912 gnutls_x509_crt_deinit(vpninfo->peer_cert);
1913 vpninfo->peer_cert = NULL;
1915 if (vpninfo->https_sess) {
1916 gnutls_deinit(vpninfo->https_sess);
1917 vpninfo->https_sess = NULL;
1919 if (vpninfo->ssl_fd != -1) {
1920 close(vpninfo->ssl_fd);
1921 FD_CLR(vpninfo->ssl_fd, &vpninfo->select_rfds);
1922 FD_CLR(vpninfo->ssl_fd, &vpninfo->select_wfds);
1923 FD_CLR(vpninfo->ssl_fd, &vpninfo->select_efds);
1924 vpninfo->ssl_fd = -1;
1926 if (final && vpninfo->https_cred) {
1927 gnutls_certificate_free_credentials(vpninfo->https_cred);
1928 vpninfo->https_cred = NULL;
1930 if ((vpninfo->cert && !strncmp(vpninfo->cert, "pkcs11:", 7)) ||
1931 (vpninfo->sslkey && !strncmp(vpninfo->sslkey, "pkcs11:", 7))) {
1932 char pin_source[40];
1934 sprintf(pin_source, "openconnect:%p", vpninfo);
1935 p11_kit_pin_unregister_callback(pin_source, pin_callback, vpninfo);
1937 while (vpninfo->pin_cache) {
1938 struct pin_cache *cache = vpninfo->pin_cache;
1941 memset(cache->pin, 0x5a, strlen(cache->pin));
1943 vpninfo->pin_cache = cache->next;
1948 #ifdef HAVE_TROUSERS
1949 if (vpninfo->tpm_key_policy) {
1950 Tspi_Context_CloseObject(vpninfo->tpm_context, vpninfo->tpm_key_policy);
1951 vpninfo->tpm_key = 0;
1953 if (vpninfo->tpm_key) {
1954 Tspi_Context_CloseObject(vpninfo->tpm_context, vpninfo->tpm_key);
1955 vpninfo->tpm_key = 0;
1957 if (vpninfo->srk_policy) {
1958 Tspi_Context_CloseObject(vpninfo->tpm_context, vpninfo->srk_policy);
1959 vpninfo->srk_policy = 0;
1962 Tspi_Context_CloseObject(vpninfo->tpm_context, vpninfo->srk);
1965 if (vpninfo->tpm_context) {
1966 Tspi_Context_Close(vpninfo->tpm_context);
1967 vpninfo->tpm_context = 0;
1970 #ifndef HAVE_GNUTLS_CERTIFICATE_SET_KEY
1971 if (vpninfo->my_pkey && vpninfo->my_pkey != OPENCONNECT_TPM_PKEY) {
1972 gnutls_privkey_deinit(vpninfo->my_pkey);
1973 vpninfo->my_pkey = NULL;
1974 /* my_p11key went with it */
1976 if (vpninfo->my_certs) {
1978 for (i = 0; i < vpninfo->nr_my_certs; i++)
1979 gnutls_x509_crt_deinit(vpninfo->my_certs[i]);
1980 free(vpninfo->my_certs);
1981 vpninfo->my_certs = NULL;
1987 void openconnect_init_ssl(void)
1989 gnutls_global_init();
1992 int openconnect_sha1(unsigned char *result, void *data, int datalen)
1995 size_t shalen = SHA1_SIZE;
1999 if (gnutls_fingerprint(GNUTLS_DIG_SHA1, &d, result, &shalen))
2005 int openconnect_random(void *bytes, int len)
2007 if (gnutls_rnd(GNUTLS_RND_RANDOM, bytes, len))
2012 int openconnect_local_cert_md5(struct openconnect_info *vpninfo,
2015 const gnutls_datum_t *d;
2020 d = gnutls_certificate_get_ours(vpninfo->https_sess);
2024 if (gnutls_fingerprint(GNUTLS_DIG_MD5, d, buf, &md5len))
2031 static P11KitPin *pin_callback(const char *pin_source, P11KitUri *pin_uri,
2032 const char *pin_description,
2033 P11KitPinFlags flags,
2036 struct openconnect_info *vpninfo = _vpninfo;
2037 struct pin_cache **cache = &vpninfo->pin_cache;
2038 struct oc_auth_form f;
2039 struct oc_form_opt o;
2045 if (!vpninfo || !vpninfo->process_auth_form)
2048 if (p11_kit_uri_format(pin_uri, P11_KIT_URI_FOR_TOKEN, &uri))
2052 if (!strcmp(uri, (*cache)->token)) {
2055 if ((*cache)->pin) {
2056 if ((flags & P11_KIT_PIN_FLAGS_RETRY) != P11_KIT_PIN_FLAGS_RETRY)
2057 return p11_kit_pin_new_for_string((*cache)->pin);
2058 memset((*cache)->pin, 0x5a, strlen((*cache)->pin));
2059 free((*cache)->pin);
2060 (*cache)->pin = NULL;
2064 cache = &(*cache)->next;
2067 *cache = calloc(1, sizeof(struct pin_cache));
2072 (*cache)->token = uri;
2075 memset(&f, 0, sizeof(f));
2076 f.auth_id = (char *)"pkcs11_pin";
2079 message[sizeof(message)-1] = 0;
2080 snprintf(message, sizeof(message) - 1, _("PIN required for %s"), pin_description);
2081 f.message = message;
2084 * In p11-kit <= 0.12, these flags are *odd*.
2085 * RETRY is 0xa, FINAL_TRY is 0x14 and MANY_TRIES is 0x28.
2086 * So don't treat it like a sane bitmask. Fixed in
2087 * http://cgit.freedesktop.org/p11-glue/p11-kit/commit/?id=59774b11
2089 if ((flags & P11_KIT_PIN_FLAGS_RETRY) == P11_KIT_PIN_FLAGS_RETRY)
2090 f.error = (char *)_("Wrong PIN");
2092 if ((flags & P11_KIT_PIN_FLAGS_FINAL_TRY) == P11_KIT_PIN_FLAGS_FINAL_TRY)
2093 f.banner = (char *)_("This is the final try before locking!");
2094 else if ((flags & P11_KIT_PIN_FLAGS_MANY_TRIES) == P11_KIT_PIN_FLAGS_MANY_TRIES)
2095 f.banner = (char *)_("Only a few tries left before locking!");
2098 o.type = OC_FORM_OPT_PASSWORD;
2099 o.name = (char *)"pkcs11_pin";
2100 o.label = (char *)_("Enter PIN:");
2103 ret = vpninfo->process_auth_form(vpninfo->cbdata, &f);
2104 if (ret || !o.value)
2107 pin = p11_kit_pin_new_for_string(o.value);
2108 (*cache)->pin = o.value;