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)
251 fd = open(fname, O_RDONLY|O_CLOEXEC);
254 vpn_progress(vpninfo, PRG_ERR,
255 _("Failed to open key/certificate file %s: %s\n"),
256 fname, strerror(err));
259 if (fstat(fd, &st)) {
261 vpn_progress(vpninfo, PRG_ERR,
262 _("Failed to stat key/certificate file %s: %s\n"),
263 fname, strerror(err));
267 datum->size = st.st_size;
268 datum->data = gnutls_malloc(st.st_size + 1);
270 vpn_progress(vpninfo, PRG_ERR,
271 _("Failed to allocate certificate buffer\n"));
276 if (read(fd, datum->data, datum->size) != datum->size) {
278 vpn_progress(vpninfo, PRG_ERR,
279 _("Failed to read certificate into memory: %s\n"),
282 gnutls_free(datum->data);
285 datum->data[st.st_size] = 0;
290 /* A non-zero, non-error return to make load_certificate() continue and
291 interpreting the file as other types */
294 static int load_pkcs12_certificate(struct openconnect_info *vpninfo,
295 gnutls_datum_t *datum,
296 gnutls_x509_privkey_t *key,
297 gnutls_x509_crt_t **chain,
298 unsigned int *chain_len,
299 gnutls_x509_crt_t **extra_certs,
300 unsigned int *extra_certs_len,
301 gnutls_x509_crl_t *crl)
307 err = gnutls_pkcs12_init(&p12);
309 vpn_progress(vpninfo, PRG_ERR,
310 _("Failed to setup PKCS#12 data structure: %s\n"),
311 gnutls_strerror(err));
315 err = gnutls_pkcs12_import(p12, datum, GNUTLS_X509_FMT_DER, 0);
317 gnutls_pkcs12_deinit(p12);
318 if (vpninfo->cert_type == CERT_TYPE_UNKNOWN)
320 vpn_progress(vpninfo, PRG_ERR,
321 _("Failed to import PKCS#12 file: %s\n"),
322 gnutls_strerror(err));
326 pass = vpninfo->cert_password;
327 while ((err = gnutls_pkcs12_verify_mac(p12, pass)) == GNUTLS_E_MAC_VERIFY_FAILED) {
329 vpn_progress(vpninfo, PRG_ERR,
330 _("Failed to decrypt PKCS#12 certificate file\n"));
332 vpninfo->cert_password = NULL;
333 err = request_passphrase(vpninfo, "openconnect_pkcs12", &pass,
334 _("Enter PKCS#12 pass phrase:"));
336 gnutls_pkcs12_deinit(p12);
340 /* If it wasn't GNUTLS_E_MAC_VERIFY_FAILED, then the problem wasn't just a
341 bad password. Give up. */
346 gnutls_pkcs12_deinit(p12);
348 /* If the first attempt, and we didn't know for sure it was PKCS#12
349 anyway, bail out and try loading it as something different. */
350 if (pass == vpninfo->cert_password &&
351 vpninfo->cert_type == CERT_TYPE_UNKNOWN) {
352 /* Make it non-fatal... */
357 vpn_progress(vpninfo, level,
358 _("Failed to process PKCS#12 file: %s\n"),
359 gnutls_strerror(err));
362 err = gnutls_pkcs12_simple_parse(p12, pass, key, chain, chain_len,
363 extra_certs, extra_certs_len, crl, 0);
365 vpninfo->cert_password = NULL;
367 gnutls_pkcs12_deinit(p12);
369 vpn_progress(vpninfo, PRG_ERR,
370 _("Failed to load PKCS#12 certificate: %s\n"),
371 gnutls_strerror(err));
377 /* Older versions of GnuTLS didn't actually bother to check this, so we'll
379 static int check_issuer_sanity(gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer)
381 #if GNUTLS_VERSION_NUMBER > 0x300014
384 unsigned char id1[512], id2[512];
385 size_t id1_size = 512, id2_size = 512;
388 err = gnutls_x509_crt_get_authority_key_id(cert, id1, &id1_size, NULL);
392 err = gnutls_x509_crt_get_subject_key_id(issuer, id2, &id2_size, NULL);
395 if (id1_size == id2_size && !memcmp(id1, id2, id1_size))
403 static int count_x509_certificates(gnutls_datum_t *datum)
406 char *p = (char *)datum->data;
409 p = strstr(p, "-----BEGIN ");
413 if (!strncmp(p, "CERTIFICATE", 11) ||
414 !strncmp(p, "X509 CERTIFICATE", 16))
420 static int get_cert_name(gnutls_x509_crt_t cert, char *name, size_t namelen)
422 if (gnutls_x509_crt_get_dn_by_oid(cert, GNUTLS_OID_X520_COMMON_NAME,
423 0, 0, name, &namelen) &&
424 gnutls_x509_crt_get_dn(cert, name, &namelen)) {
426 snprintf(name, namelen-1, "<unknown>");
432 #if !defined (HAVE_GNUTLS_CERTIFICATE_SET_KEY) && \
433 (defined (HAVE_P11KIT) || defined (HAVE_TROUSERS))
434 /* For GnuTLS 2.12 even if we *have* a privkey (as we do for PKCS#11), we
435 can't register it. So we have to use the cert_callback function. This
436 just hands out the certificate chain we prepared in load_certificate().
437 If we have a pkey then return that too; otherwise leave the key NULL —
438 we'll also have registered a sign_callback for the session, which will
440 static int gtls_cert_cb(gnutls_session_t sess, const gnutls_datum_t *req_ca_dn,
441 int nreqs, const gnutls_pk_algorithm_t *pk_algos,
442 int pk_algos_length, gnutls_retr2_st *st) {
444 struct openconnect_info *vpninfo = gnutls_session_get_ptr(sess);
445 int algo = GNUTLS_PK_RSA; /* TPM */
449 if (vpninfo->my_p11key) {
450 st->key_type = GNUTLS_PRIVKEY_PKCS11;
451 st->key.pkcs11 = vpninfo->my_p11key;
452 algo = gnutls_pkcs11_privkey_get_pk_algorithm(vpninfo->my_p11key, NULL);
455 for (i = 0; i < pk_algos_length; i++) {
456 if (algo == pk_algos[i])
459 if (i == pk_algos_length)
460 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
462 st->cert_type = GNUTLS_CRT_X509;
463 st->cert.x509 = vpninfo->my_certs;
464 st->ncerts = vpninfo->nr_my_certs;
469 #endif /* !SET_KEY && (P11KIT || TROUSERS) */
471 static int load_certificate(struct openconnect_info *vpninfo)
473 gnutls_datum_t fdata;
474 gnutls_x509_privkey_t key = NULL;
475 #if defined (HAVE_P11KIT) || defined (HAVE_TROUSERS)
476 gnutls_privkey_t pkey = NULL;
477 gnutls_datum_t pkey_sig = {NULL, 0};
478 void *dummy_hash_data = &load_certificate;
481 char *cert_url = (char *)vpninfo->cert;
482 char *key_url = (char *)vpninfo->sslkey;
483 gnutls_pkcs11_privkey_t p11key = NULL;
485 gnutls_x509_crl_t crl = NULL;
486 gnutls_x509_crt_t last_cert, cert = NULL;
487 gnutls_x509_crt_t *extra_certs = NULL, *supporting_certs = NULL;
488 unsigned int nr_supporting_certs = 0, nr_extra_certs = 0;
489 unsigned int certs_to_free = 0; /* How many of supporting_certs */
490 int err; /* GnuTLS error */
493 int cert_is_p11 = 0, key_is_p11 = 0;
494 unsigned char key_id[20];
495 size_t key_id_size = sizeof(key_id);
500 key_is_p11 = !strncmp(vpninfo->sslkey, "pkcs11:", 7);
501 cert_is_p11 = !strncmp(vpninfo->cert, "pkcs11:", 7);
503 /* Install PIN handler if either certificate or key are coming from PKCS#11 */
504 if (key_is_p11 || cert_is_p11) {
506 CK_OBJECT_CLASS class;
511 sprintf(pin_source, "openconnect:%p", vpninfo);
512 p11_kit_pin_register_callback(pin_source, pin_callback, vpninfo, NULL);
514 uri = p11_kit_uri_new();
516 attr.type = CKA_CLASS;
517 attr.pValue = &class;
518 attr.ulValueLen = sizeof(class);
520 /* Add appropriate pin-source and object-type attributes to
521 both certificate and key URLs, unless they already exist. */
523 !p11_kit_uri_parse(cert_url, P11_KIT_URI_FOR_OBJECT, uri)) {
524 if (!p11_kit_uri_get_pin_source(uri))
525 p11_kit_uri_set_pin_source(uri, pin_source);
526 if (!p11_kit_uri_get_attribute(uri, CKA_CLASS)) {
527 class = CKO_CERTIFICATE;
528 p11_kit_uri_set_attribute(uri, &attr);
530 p11_kit_uri_format(uri, P11_KIT_URI_FOR_OBJECT, &cert_url);
534 !p11_kit_uri_parse(key_url, P11_KIT_URI_FOR_OBJECT, uri)) {
535 if (!p11_kit_uri_get_pin_source(uri))
536 p11_kit_uri_set_pin_source(uri, pin_source);
537 if (!p11_kit_uri_get_attribute(uri, CKA_CLASS)) {
538 class = CKO_PRIVATE_KEY;
539 p11_kit_uri_set_attribute(uri, &attr);
541 p11_kit_uri_format(uri, P11_KIT_URI_FOR_OBJECT, &key_url);
544 p11_kit_uri_free(uri);
546 vpn_progress(vpninfo, PRG_ERR,
547 _("This binary built without PKCS#11 support\n"));
552 /* Load certificate(s) first... */
555 vpn_progress(vpninfo, PRG_TRACE,
556 _("Using PKCS#11 certificate %s\n"), cert_url);
558 err = gnutls_x509_crt_init(&cert);
563 err = gnutls_x509_crt_import_pkcs11_url(cert, cert_url, 0);
564 if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
565 err = gnutls_x509_crt_import_pkcs11_url(cert, cert_url,
566 GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
568 vpn_progress(vpninfo, PRG_ERR,
569 _("Error loading certificate from PKCS#11: %s\n"),
570 gnutls_strerror(err));
576 #endif /* HAVE_P11KIT */
578 vpn_progress(vpninfo, PRG_TRACE,
579 _("Using certificate file %s\n"), vpninfo->cert);
581 ret = load_datum(vpninfo, &fdata, vpninfo->cert);
585 if (!key_is_p11 && (vpninfo->cert_type == CERT_TYPE_PKCS12 ||
586 vpninfo->cert_type == CERT_TYPE_UNKNOWN)) {
587 /* PKCS#12 should actually contain certificates *and* private key */
588 ret = load_pkcs12_certificate(vpninfo, &fdata, &key,
589 &supporting_certs, &nr_supporting_certs,
590 &extra_certs, &nr_extra_certs,
595 if (nr_supporting_certs) {
596 cert = supporting_certs[0];
599 vpn_progress(vpninfo, PRG_ERR,
600 _("PKCS#11 file contained no certificate\n"));
605 /* It returned NOT_PKCS12.
606 Fall through to try PEM formats. */
609 /* We need to know how many there are in *advance*; it won't just allocate
610 the array for us :( */
611 nr_extra_certs = count_x509_certificates(&fdata);
613 nr_extra_certs = 1; /* wtf? Oh well, we'll fail later... */
615 extra_certs = calloc(nr_extra_certs, sizeof(cert));
621 err = gnutls_x509_crt_list_import(extra_certs, &nr_extra_certs, &fdata,
622 GNUTLS_X509_FMT_PEM, 0);
625 if (!err || err == GNUTLS_E_NO_CERTIFICATE_FOUND)
626 reason = _("No certificate found in file");
628 reason = gnutls_strerror(err);
630 vpn_progress(vpninfo, PRG_ERR,
631 _("Loading certificate failed: %s\n"),
636 nr_extra_certs = err;
641 /* Now we have the certificate(s) and we're looking for the private key... */
642 #if defined (HAVE_P11KIT)
644 vpn_progress(vpninfo, PRG_TRACE,
645 _("Using PKCS#11 key %s\n"), key_url);
647 err = gnutls_pkcs11_privkey_init(&p11key);
649 vpn_progress(vpninfo, PRG_ERR,
650 _("Error initialising PKCS#11 key structure: %s\n"),
651 gnutls_strerror(err));
656 err = gnutls_pkcs11_privkey_import_url(p11key, key_url, 0);
658 vpn_progress(vpninfo, PRG_ERR,
659 _("Error importing PKCS#11 URL %s: %s\n"),
660 key_url, gnutls_strerror(err));
661 gnutls_pkcs11_privkey_deinit(p11key);
666 err = gnutls_privkey_init(&pkey);
668 vpn_progress(vpninfo, PRG_ERR,
669 _("Error initialising private key structure: %s\n"),
670 gnutls_strerror(err));
671 gnutls_pkcs11_privkey_deinit(p11key);
676 err = gnutls_privkey_import_pkcs11(pkey, p11key, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
678 vpn_progress(vpninfo, PRG_ERR,
679 _("Error importing PKCS#11 key into private key structure: %s\n"),
680 gnutls_strerror(err));
681 gnutls_pkcs11_privkey_deinit(p11key);
690 /* We're loading the private key from a file. Load the file into memory
691 unless it's the same as the certificate and we already loaded that. */
692 if (!fdata.data || vpninfo->sslkey != vpninfo->cert) {
693 gnutls_free(fdata.data);
696 vpn_progress(vpninfo, PRG_TRACE,
697 _("Using private key file %s\n"), vpninfo->sslkey);
699 ret = load_datum(vpninfo, &fdata, vpninfo->sslkey);
704 if (vpninfo->cert_type == CERT_TYPE_TPM ||
705 (vpninfo->cert_type == CERT_TYPE_UNKNOWN &&
706 strstr((char *)fdata.data, "-----BEGIN TSS KEY BLOB-----"))) {
707 #ifndef HAVE_TROUSERS
708 vpn_progress(vpninfo, PRG_ERR,
709 _("This version of OpenConnect was built without TPM support\n"));
712 ret = load_tpm_key(vpninfo, &fdata, &pkey, &pkey_sig);
720 gnutls_x509_privkey_init(&key);
721 /* Try PKCS#1 (and PKCS#8 without password) first. GnuTLS doesn't
722 support OpenSSL's old PKCS#1-based encrypted format. We should
723 probably check for it and give a more coherent failure mode. */
724 err = gnutls_x509_privkey_import(key, &fdata, GNUTLS_X509_FMT_PEM);
726 /* If that fails, try PKCS#8 */
727 char *pass = vpninfo->cert_password;
729 /* Yay, just for fun this is *different* to PKCS#12. Where we could
730 try an empty password there, in this case the empty-password case
731 has already been *tried* by gnutls_x509_privkey_import(). If we
732 just call gnutls_x509_privkey_import_pkcs8() with a NULL password,
733 it'll SEGV. You have to set the GNUTLS_PKCS_PLAIN flag if you want
734 to try without a password. Passing NULL evidently isn't enough of
735 a hint. And in GnuTLS 3.1 where that crash has been fixed, passing
736 NULL will cause it to return GNUTLS_E_ENCRYPTED_STRUCTURE (a new
737 error code) rather than GNUTLS_E_DECRYPTION_FAILED. So just pass ""
738 instead of NULL, and don't worry about either case. */
739 while ((err = gnutls_x509_privkey_import_pkcs8(key, &fdata,
742 if (err != GNUTLS_E_DECRYPTION_FAILED) {
743 vpn_progress(vpninfo, PRG_ERR,
744 _("Failed to load private key as PKCS#8: %s\n"),
745 gnutls_strerror(err));
749 vpninfo->cert_password = NULL;
751 vpn_progress(vpninfo, PRG_ERR,
752 _("Failed to decrypt PKCS#8 certificate file\n"));
755 err = request_passphrase(vpninfo, "openconnect_pem",
756 &pass, _("Enter PEM pass phrase:"));
763 vpninfo->cert_password = NULL;
766 /* Now attempt to make sure we use the *correct* certificate, to match the key */
767 err = gnutls_x509_privkey_get_key_id(key, 0, key_id, &key_id_size);
769 vpn_progress(vpninfo, PRG_ERR,
770 _("Failed to get key ID: %s\n"),
771 gnutls_strerror(err));
775 for (i = 0; i < (extra_certs?nr_extra_certs:1); i++) {
776 unsigned char cert_id[20];
777 size_t cert_id_size = sizeof(cert_id);
779 err = gnutls_x509_crt_get_key_id(extra_certs?extra_certs[i]:cert, 0, cert_id, &cert_id_size);
783 if (cert_id_size == key_id_size && !memcmp(cert_id, key_id, key_id_size)) {
785 cert = extra_certs[i];
787 /* Move the rest of the array down */
788 for (; i < nr_extra_certs - 1; i++)
789 extra_certs[i] = extra_certs[i+1];
796 /* There's no pkey (there's an x509 key), so we'll fall straight through the
797 * bit at match_cert: below, and go directly to the bit where it prints the
798 * 'no match found' error and exits. */
800 #if defined (HAVE_P11KIT) || defined (HAVE_TROUSERS)
802 /* If we have a privkey from PKCS#11 or TPM, we can't do the simple comparison
803 of key ID that we do for software keys to find which certificate is a
804 match. So sign some dummy data and then check the signature against each
805 of the available certificates until we find the right one. */
807 /* The TPM code may have already signed it, to test authorisation. We
808 only sign here for PKCS#11 keys, in which case fdata might be
809 empty too so point it at dummy data. */
810 if (!pkey_sig.data) {
812 fdata.data = dummy_hash_data;
816 err = sign_dummy_data(vpninfo, pkey, &fdata, &pkey_sig);
818 vpn_progress(vpninfo, PRG_ERR,
819 _("Error signing test data with private key: %s\n"),
820 gnutls_strerror(err));
826 for (i=0; i < (extra_certs?nr_extra_certs:1); i++) {
827 gnutls_pubkey_t pubkey;
829 gnutls_pubkey_init(&pubkey);
830 err = gnutls_pubkey_import_x509(pubkey, extra_certs?extra_certs[i]:cert, 0);
832 vpn_progress(vpninfo, PRG_ERR,
833 _("Error validating signature against certificate: %s\n"),
834 gnutls_strerror(err));
835 /* We'll probably fail shortly if we don't find it. */
836 gnutls_pubkey_deinit(pubkey);
839 err = gnutls_pubkey_verify_data(pubkey, 0, &fdata, &pkey_sig);
840 gnutls_pubkey_deinit(pubkey);
844 cert = extra_certs[i];
846 /* Move the rest of the array down */
847 for (; i < nr_extra_certs - 1; i++)
848 extra_certs[i] = extra_certs[i+1];
852 gnutls_free(pkey_sig.data);
856 gnutls_free(pkey_sig.data);
858 #endif /* P11KIT || TROUSERS */
860 /* We shouldn't reach this. It means that we didn't find *any* matching cert */
861 vpn_progress(vpninfo, PRG_ERR,
862 _("No SSL certificate found to match private key\n"));
866 /********************************************************************/
868 /* Now we have both cert(s) and key, and we should be ready to go. */
869 check_certificate_expiry(vpninfo, cert);
870 get_cert_name(cert, name, sizeof(name));
871 vpn_progress(vpninfo, PRG_INFO, _("Using client certificate '%s'\n"),
875 err = gnutls_certificate_set_x509_crl(vpninfo->https_cred, &crl, 1);
877 vpn_progress(vpninfo, PRG_ERR,
878 _("Setting certificate recovation list failed: %s\n"),
879 gnutls_strerror(err));
885 /* OpenSSL has problems with certificate chains — if there are
886 multiple certs with the same name, it doesn't necessarily
887 choose the _right_ one. (RT#1942)
888 Pick the right ones for ourselves and add them manually. */
890 if (nr_supporting_certs) {
891 /* We already got a bunch of certs from PKCS#12 file.
892 Remember how many need to be freed when we're done,
893 since we'll expand the supporting_certs array with
894 more from the cafile if we can. */
895 last_cert = supporting_certs[nr_supporting_certs-1];
896 certs_to_free = nr_supporting_certs;
899 certs_to_free = nr_supporting_certs = 1;
902 gnutls_x509_crt_t issuer;
904 for (i = 0; i < nr_extra_certs; i++) {
905 if (gnutls_x509_crt_check_issuer(last_cert, extra_certs[i]) &&
906 !check_issuer_sanity(last_cert, extra_certs[i]))
910 if (i < nr_extra_certs) {
911 issuer = extra_certs[i];
913 err = gnutls_certificate_get_issuer(vpninfo->https_cred,
914 last_cert, &issuer, 0);
919 /* The check_issuer_sanity() function works fine as a workaround where
920 it was used above, but when gnutls_certificate_get_issuer() returns
921 a bogus cert, there's nothing we can do to fix it up. We don't get
922 to iterate over all the available certs like we can over our own
924 if (check_issuer_sanity(last_cert, issuer)) {
925 /* Hm, is there a bug reference for this? Or just the git commit
926 reference (c1ef7efb in master, 5196786c in gnutls_3_0_x-2)? */
927 vpn_progress(vpninfo, PRG_ERR,
928 _("WARNING: GnuTLS returned incorrect issuer certs; authentication may fail!\n"));
932 if (issuer == last_cert) {
933 /* Don't actually include the root CA. If they don't already trust it,
934 then handing it to them isn't going to help. But don't omit the
935 original certificate if it's self-signed. */
936 if (nr_supporting_certs > 1)
937 nr_supporting_certs--;
941 /* OK, we found a new cert to add to our chain. */
942 supporting_certs = gnutls_realloc(supporting_certs,
943 sizeof(cert) * ++nr_supporting_certs);
944 if (!supporting_certs) {
945 vpn_progress(vpninfo, PRG_ERR,
946 _("Failed to allocate memory for supporting certificates\n"));
947 /* The world is probably about to end, but try without them anyway */
953 /* First time we actually allocated an array? Copy the first cert into it */
954 if (nr_supporting_certs == 2)
955 supporting_certs[0] = cert;
957 /* Append the new one */
958 supporting_certs[nr_supporting_certs-1] = issuer;
962 for (i = 1; i < nr_supporting_certs; i++) {
963 get_cert_name(supporting_certs[i], name, sizeof(name));
965 vpn_progress(vpninfo, PRG_DEBUG,
966 _("Adding supporting CA '%s'\n"), name);
969 #if defined (HAVE_P11KIT) || defined (HAVE_TROUSERS)
971 #if defined(HAVE_GNUTLS_CERTIFICATE_SET_KEY)
972 /* Ug. If we got a gnutls_privkey_t from PKCS#11 rather than the
973 gnutls_x509_privkey_t that we get from PEM or PKCS#12 files, then
974 we can't use gnutls_certificate_set_x509_key(). Instead we have
975 to convert our chain of X509 certificates to gnutls_pcert_st and
976 then use gnutls_certificate_set_key() with that instead. */
977 gnutls_pcert_st *pcerts = calloc(nr_supporting_certs, sizeof(*pcerts));
984 for (i=0 ; i < nr_supporting_certs; i++) {
985 err = gnutls_pcert_import_x509(pcerts + i, supporting_certs?supporting_certs[i]:cert, 0);
987 vpn_progress(vpninfo, PRG_ERR,
988 _("Importing X509 certificate failed: %s\n"),
989 gnutls_strerror(err));
994 err = gnutls_certificate_set_key(vpninfo->https_cred, NULL, 0, pcerts, nr_supporting_certs, pkey);
996 vpn_progress(vpninfo, PRG_ERR,
997 _("Setting PKCS#11 certificate failed: %s\n"),
998 gnutls_strerror(err));
1000 for (i=0 ; i < nr_supporting_certs; i++)
1001 gnutls_pcert_deinit(pcerts + i);
1006 #else /* !HAVE_GNUTLS_CERTIFICATE_SET_KEY so fake it using sign_callback */
1007 vpninfo->my_pkey = pkey;
1009 vpninfo->my_p11key = p11key;
1012 if (supporting_certs) {
1013 vpninfo->my_certs = supporting_certs;
1014 vpninfo->nr_my_certs = nr_supporting_certs;
1015 /* We are *keeping* the certs in supporting_certs, unlike in
1016 GnuTLS 3 where we can free them after calling g_c_set_key().
1017 So steal the ones we need out of the extra_certs array.
1018 The first one is 'cert', which was already stolen. So
1020 for (i = 1; i < nr_supporting_certs; i++) {
1022 for (j = 0; j < nr_extra_certs; j++) {
1023 if (supporting_certs[i] == extra_certs[j]) {
1024 extra_certs[j] = NULL;
1029 supporting_certs = NULL;
1031 vpninfo->my_certs = gnutls_calloc(1, sizeof(cert));
1032 if (!vpninfo->my_certs) {
1036 vpninfo->my_certs[0] = cert;
1037 vpninfo->nr_my_certs = 1;
1040 gnutls_certificate_set_retrieve_function(vpninfo->https_cred,
1043 vpninfo->my_pkey = pkey;
1045 pkey = NULL; /* we gave it away, along with pcerts */
1047 #endif /* P11KIT || TROUSERS */
1048 err = gnutls_certificate_set_x509_key(vpninfo->https_cred,
1049 supporting_certs ? supporting_certs : &cert,
1050 supporting_certs ? nr_supporting_certs : 1,
1054 vpn_progress(vpninfo, PRG_ERR,
1055 _("Setting certificate failed: %s\n"),
1056 gnutls_strerror(err));
1062 gnutls_x509_crl_deinit(crl);
1064 gnutls_x509_privkey_deinit(key);
1066 gnutls_x509_crt_deinit(cert);
1067 /* From 1 because cert is the first one (and might exist
1068 even if supporting_certs is NULL) */
1069 for (i = 1; i < certs_to_free; i++) {
1070 if (supporting_certs[i])
1071 gnutls_x509_crt_deinit(supporting_certs[i]);
1073 for (i = 0; i < nr_extra_certs; i++) {
1075 gnutls_x509_crt_deinit(extra_certs[i]);
1077 gnutls_free(extra_certs);
1078 gnutls_free(supporting_certs);
1079 #if defined (HAVE_P11KIT) || defined (HAVE_TROUSERS)
1080 if (pkey && pkey != OPENCONNECT_TPM_PKEY)
1081 gnutls_privkey_deinit(pkey);
1082 if (fdata.data != dummy_hash_data)
1083 #endif /* It's conditional if we support arbitrary privkeys: */
1084 gnutls_free(fdata.data);
1086 if (cert_url != vpninfo->cert)
1088 if (key_url != vpninfo->sslkey)
1094 static int get_cert_fingerprint(struct openconnect_info *vpninfo,
1095 gnutls_x509_crt_t cert,
1096 gnutls_digest_algorithm_t algo,
1099 unsigned char md[256];
1100 size_t md_size = sizeof(md);
1103 if (gnutls_x509_crt_get_fingerprint(cert, algo, md, &md_size))
1106 for (i=0; i < md_size; i++)
1107 sprintf(&buf[i*2], "%02X", md[i]);
1112 int get_cert_md5_fingerprint(struct openconnect_info *vpninfo,
1113 OPENCONNECT_X509 *cert, char *buf)
1115 return get_cert_fingerprint(vpninfo, cert, GNUTLS_DIG_MD5, buf);
1118 int openconnect_get_cert_sha1(struct openconnect_info *vpninfo,
1119 OPENCONNECT_X509 *cert, char *buf)
1121 return get_cert_fingerprint(vpninfo, cert, GNUTLS_DIG_SHA1, buf);
1124 char *openconnect_get_cert_details(struct openconnect_info *vpninfo,
1125 OPENCONNECT_X509 *cert)
1130 if (gnutls_x509_crt_print(cert, GNUTLS_CRT_PRINT_FULL, &buf))
1133 /* Just in case gnutls_free() isn't free(), we can't steal it. */
1134 ret = strdup((char *)buf.data);
1135 gnutls_free(buf.data);
1140 int openconnect_get_cert_DER(struct openconnect_info *vpninfo,
1141 OPENCONNECT_X509 *cert, unsigned char **buf)
1144 unsigned char *ret = NULL;
1146 if (gnutls_x509_crt_export(cert, GNUTLS_X509_FMT_DER, ret, &l) !=
1147 GNUTLS_E_SHORT_MEMORY_BUFFER)
1154 if (gnutls_x509_crt_export(cert, GNUTLS_X509_FMT_DER, ret, &l)) {
1162 static int verify_peer(gnutls_session_t session)
1164 struct openconnect_info *vpninfo = gnutls_session_get_ptr(session);
1165 const gnutls_datum_t *cert_list;
1166 gnutls_x509_crt_t cert;
1167 unsigned int status, cert_list_size;
1168 const char *reason = NULL;
1171 if (vpninfo->peer_cert) {
1172 gnutls_x509_crt_deinit(vpninfo->peer_cert);
1173 vpninfo->peer_cert = NULL;
1176 cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
1178 vpn_progress(vpninfo, PRG_ERR, _("Server presented no certificate\n"));
1179 return GNUTLS_E_CERTIFICATE_ERROR;
1182 if (vpninfo->servercert) {
1183 unsigned char sha1bin[SHA1_SIZE];
1184 char fingerprint[(SHA1_SIZE * 2) + 1];
1187 err = openconnect_sha1(sha1bin, cert_list[0].data, cert_list[0].size);
1189 vpn_progress(vpninfo, PRG_ERR,
1190 _("Could not calculate SHA1 of server's certificate\n"));
1191 return GNUTLS_E_CERTIFICATE_ERROR;
1193 for (i=0; i < SHA1_SIZE; i++)
1194 sprintf(&fingerprint[i*2], "%02X", sha1bin[i]);
1196 if (strcasecmp(vpninfo->servercert, fingerprint)) {
1197 vpn_progress(vpninfo, PRG_ERR,
1198 _("Server SSL certificate didn't match: %s\n"), fingerprint);
1199 return GNUTLS_E_CERTIFICATE_ERROR;
1204 err = gnutls_certificate_verify_peers2 (session, &status);
1206 vpn_progress(vpninfo, PRG_ERR, _("Error checking server cert status\n"));
1207 return GNUTLS_E_CERTIFICATE_ERROR;
1210 if (status & GNUTLS_CERT_REVOKED)
1211 reason = _("certificate revoked");
1212 else if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
1213 reason = _("signer not found");
1214 else if (status & GNUTLS_CERT_SIGNER_NOT_CA)
1215 reason = _("signer not a CA certificate");
1216 else if (status & GNUTLS_CERT_INSECURE_ALGORITHM)
1217 reason = _("insecure algorithm");
1218 else if (status & GNUTLS_CERT_NOT_ACTIVATED)
1219 reason = _("certificate not yet activated");
1220 else if (status & GNUTLS_CERT_EXPIRED)
1221 reason = _("certificate expired");
1222 else if (status & GNUTLS_CERT_INVALID)
1223 /* If this is set and no other reason, it apparently means
1224 that signature verification failed. Not entirely sure
1225 why we don't just set a bit for that too. */
1226 reason = _("signature verification failed");
1228 err = gnutls_x509_crt_init(&cert);
1230 vpn_progress(vpninfo, PRG_ERR, _("Error initialising X509 cert structure\n"));
1231 return GNUTLS_E_CERTIFICATE_ERROR;
1234 err = gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER);
1236 vpn_progress(vpninfo, PRG_ERR, _("Error importing server's cert\n"));
1237 gnutls_x509_crt_deinit(cert);
1238 return GNUTLS_E_CERTIFICATE_ERROR;
1241 if (!reason && !gnutls_x509_crt_check_hostname(cert, vpninfo->hostname))
1242 reason = _("certificate does not match hostname");
1245 vpn_progress(vpninfo, PRG_INFO, "Server certificate verify failed: %s\n",
1247 if (vpninfo->validate_peer_cert)
1248 err = vpninfo->validate_peer_cert(vpninfo->cbdata,
1250 reason) ? GNUTLS_E_CERTIFICATE_ERROR : 0;
1252 err = GNUTLS_E_CERTIFICATE_ERROR;
1255 vpninfo->peer_cert = cert;
1261 int openconnect_open_https(struct openconnect_info *vpninfo)
1266 if (vpninfo->https_sess)
1269 ssl_sock = connect_https_socket(vpninfo);
1273 if (!vpninfo->https_cred) {
1274 gnutls_certificate_allocate_credentials(&vpninfo->https_cred);
1275 #ifdef HAVE_GNUTLS_CERTIFICATE_SET_X509_SYSTEM_TRUST
1276 gnutls_certificate_set_x509_system_trust(vpninfo->https_cred);
1278 gnutls_certificate_set_x509_trust_file(vpninfo->https_cred,
1279 "/etc/pki/tls/certs/ca-bundle.crt",
1280 GNUTLS_X509_FMT_PEM);
1282 gnutls_certificate_set_verify_function (vpninfo->https_cred,
1285 if (vpninfo->cafile) {
1286 err = gnutls_certificate_set_x509_trust_file(vpninfo->https_cred,
1288 GNUTLS_X509_FMT_PEM);
1290 vpn_progress(vpninfo, PRG_ERR,
1291 _("Failed to open CA file '%s': %s\n"),
1292 vpninfo->cafile, gnutls_strerror(err));
1298 if (vpninfo->cert) {
1299 err = load_certificate(vpninfo);
1301 vpn_progress(vpninfo, PRG_ERR,
1302 _("Loading certificate failed. Aborting.\n"));
1307 gnutls_init (&vpninfo->https_sess, GNUTLS_CLIENT);
1308 gnutls_session_set_ptr (vpninfo->https_sess, (void *) vpninfo);
1309 #if defined(HAVE_TROUSERS) && !defined(HAVE_GNUTLS_CERTIFICATE_SET_KEY)
1310 if (vpninfo->my_pkey == OPENCONNECT_TPM_PKEY)
1311 gnutls_sign_callback_set(vpninfo->https_sess, gtls2_tpm_sign_cb, vpninfo);
1313 err = gnutls_priority_set_direct (vpninfo->https_sess, "NONE:+VERS-TLS1.0:+SHA1:+AES-128-CBC:+RSA:+COMP-NULL:%COMPAT:%DISABLE_SAFE_RENEGOTIATION", NULL);
1315 vpn_progress(vpninfo, PRG_ERR,
1316 _("Failed to set TLS priority string: %s\n"),
1317 gnutls_strerror(err));
1321 gnutls_record_disable_padding (vpninfo->https_sess);
1322 gnutls_credentials_set (vpninfo->https_sess, GNUTLS_CRD_CERTIFICATE, vpninfo->https_cred);
1323 gnutls_transport_set_ptr(vpninfo->https_sess, /* really? */(gnutls_transport_ptr_t)(long) ssl_sock);
1325 vpn_progress(vpninfo, PRG_INFO, _("SSL negotiation with %s\n"),
1328 while ((err = gnutls_handshake (vpninfo->https_sess))) {
1329 if (err == GNUTLS_E_AGAIN) {
1330 fd_set rd_set, wr_set;
1331 int maxfd = ssl_sock;
1336 if (gnutls_record_get_direction(vpninfo->https_sess))
1337 FD_SET(ssl_sock, &wr_set);
1339 FD_SET(ssl_sock, &rd_set);
1341 if (vpninfo->cancel_fd != -1) {
1342 FD_SET(vpninfo->cancel_fd, &rd_set);
1343 if (vpninfo->cancel_fd > ssl_sock)
1344 maxfd = vpninfo->cancel_fd;
1346 select(maxfd + 1, &rd_set, &wr_set, NULL, NULL);
1347 if (vpninfo->cancel_fd != -1 &&
1348 FD_ISSET(vpninfo->cancel_fd, &rd_set)) {
1349 vpn_progress(vpninfo, PRG_ERR, _("SSL connection cancelled\n"));
1350 gnutls_deinit(vpninfo->https_sess);
1351 vpninfo->https_sess = NULL;
1355 } else if (err == GNUTLS_E_INTERRUPTED || gnutls_error_is_fatal(err)) {
1356 vpn_progress(vpninfo, PRG_ERR, _("SSL connection failure: %s\n"),
1357 gnutls_strerror(err));
1358 gnutls_deinit(vpninfo->https_sess);
1359 vpninfo->https_sess = NULL;
1363 /* non-fatal error or warning. Ignore it and continue */
1364 vpn_progress(vpninfo, PRG_TRACE,
1365 _("GnuTLS non-fatal return during handshake: %s\n"),
1366 gnutls_strerror(err));
1370 vpninfo->ssl_fd = ssl_sock;
1372 vpn_progress(vpninfo, PRG_INFO, _("Connected to HTTPS on %s\n"),
1378 void openconnect_close_https(struct openconnect_info *vpninfo, int final)
1380 if (vpninfo->peer_cert) {
1381 gnutls_x509_crt_deinit(vpninfo->peer_cert);
1382 vpninfo->peer_cert = NULL;
1384 if (vpninfo->https_sess) {
1385 gnutls_deinit(vpninfo->https_sess);
1386 vpninfo->https_sess = NULL;
1388 if (vpninfo->ssl_fd != -1) {
1389 close(vpninfo->ssl_fd);
1390 FD_CLR(vpninfo->ssl_fd, &vpninfo->select_rfds);
1391 FD_CLR(vpninfo->ssl_fd, &vpninfo->select_wfds);
1392 FD_CLR(vpninfo->ssl_fd, &vpninfo->select_efds);
1393 vpninfo->ssl_fd = -1;
1395 if (final && vpninfo->https_cred) {
1396 gnutls_certificate_free_credentials(vpninfo->https_cred);
1397 vpninfo->https_cred = NULL;
1399 if (!strncmp(vpninfo->cert, "pkcs11:", 7) ||
1400 !strncmp(vpninfo->sslkey, "pkcs11:", 7)) {
1401 char pin_source[40];
1403 sprintf(pin_source, "openconnect:%p", vpninfo);
1404 p11_kit_pin_unregister_callback(pin_source, pin_callback, vpninfo);
1406 while (vpninfo->pin_cache) {
1407 struct pin_cache *cache = vpninfo->pin_cache;
1410 memset(cache->pin, 0x5a, strlen(cache->pin));
1412 vpninfo->pin_cache = cache->next;
1417 #ifdef HAVE_TROUSERS
1418 if (vpninfo->tpm_key_policy) {
1419 Tspi_Context_CloseObject(vpninfo->tpm_context, vpninfo->tpm_key_policy);
1420 vpninfo->tpm_key = 0;
1422 if (vpninfo->tpm_key) {
1423 Tspi_Context_CloseObject(vpninfo->tpm_context, vpninfo->tpm_key);
1424 vpninfo->tpm_key = 0;
1426 if (vpninfo->srk_policy) {
1427 Tspi_Context_CloseObject(vpninfo->tpm_context, vpninfo->srk_policy);
1428 vpninfo->srk_policy = 0;
1431 Tspi_Context_CloseObject(vpninfo->tpm_context, vpninfo->srk);
1434 if (vpninfo->tpm_context) {
1435 Tspi_Context_Close(vpninfo->tpm_context);
1436 vpninfo->tpm_context = 0;
1439 #ifndef HAVE_GNUTLS_CERTIFICATE_SET_KEY
1440 if (vpninfo->my_pkey && vpninfo->my_pkey != OPENCONNECT_TPM_PKEY) {
1441 gnutls_privkey_deinit(vpninfo->my_pkey);
1442 vpninfo->my_pkey = NULL;
1443 /* my_p11key went with it */
1445 if (vpninfo->my_certs) {
1447 for (i = 0; i < vpninfo->nr_my_certs; i++)
1448 gnutls_x509_crt_deinit(vpninfo->my_certs[i]);
1449 free(vpninfo->my_certs);
1450 vpninfo->my_certs = NULL;
1456 void openconnect_init_ssl(void)
1458 gnutls_global_init();
1461 int openconnect_sha1(unsigned char *result, void *data, int datalen)
1464 size_t shalen = SHA1_SIZE;
1468 if (gnutls_fingerprint(GNUTLS_DIG_SHA1, &d, result, &shalen))
1474 int openconnect_random(void *bytes, int len)
1476 if (gnutls_rnd(GNUTLS_RND_RANDOM, bytes, len))
1481 int openconnect_local_cert_md5(struct openconnect_info *vpninfo,
1484 const gnutls_datum_t *d;
1489 d = gnutls_certificate_get_ours(vpninfo->https_sess);
1493 if (gnutls_fingerprint(GNUTLS_DIG_MD5, d, buf, &md5len))
1500 static P11KitPin *pin_callback(const char *pin_source, P11KitUri *pin_uri,
1501 const char *pin_description,
1502 P11KitPinFlags flags,
1505 struct openconnect_info *vpninfo = _vpninfo;
1506 struct pin_cache **cache = &vpninfo->pin_cache;
1507 struct oc_auth_form f;
1508 struct oc_form_opt o;
1514 if (!vpninfo || !vpninfo->process_auth_form)
1517 if (p11_kit_uri_format(pin_uri, P11_KIT_URI_FOR_TOKEN, &uri))
1521 if (!strcmp(uri, (*cache)->token)) {
1524 if ((*cache)->pin) {
1525 if ((flags & P11_KIT_PIN_FLAGS_RETRY) != P11_KIT_PIN_FLAGS_RETRY)
1526 return p11_kit_pin_new_for_string((*cache)->pin);
1527 memset((*cache)->pin, 0x5a, strlen((*cache)->pin));
1528 free((*cache)->pin);
1529 (*cache)->pin = NULL;
1535 *cache = calloc(1, sizeof(struct pin_cache));
1540 (*cache)->token = uri;
1543 memset(&f, 0, sizeof(f));
1544 f.auth_id = (char *)"pkcs11_pin";
1547 message[sizeof(message)-1] = 0;
1548 snprintf(message, sizeof(message) - 1, _("PIN required for %s"), pin_description);
1549 f.message = message;
1552 * In p11-kit <= 0.12, these flags are *odd*.
1553 * RETRY is 0xa, FINAL_TRY is 0x14 and MANY_TRIES is 0x28.
1554 * So don't treat it like a sane bitmask. Fixed in
1555 * http://cgit.freedesktop.org/p11-glue/p11-kit/commit/?id=59774b11
1557 if ((flags & P11_KIT_PIN_FLAGS_RETRY) == P11_KIT_PIN_FLAGS_RETRY)
1558 f.error = (char *)_("Wrong PIN");
1560 if ((flags & P11_KIT_PIN_FLAGS_FINAL_TRY) == P11_KIT_PIN_FLAGS_FINAL_TRY)
1561 f.banner = (char *)_("This is the final try before locking!");
1562 else if ((flags & P11_KIT_PIN_FLAGS_MANY_TRIES) == P11_KIT_PIN_FLAGS_MANY_TRIES)
1563 f.banner = (char *)_("Only a few tries left before locking!");
1566 o.type = OC_FORM_OPT_PASSWORD;
1567 o.name = (char *)"pkcs11_pin";
1568 o.label = (char *)_("Enter PIN:");
1571 ret = vpninfo->process_auth_form(vpninfo->cbdata, &f);
1572 if (ret || !o.value)
1575 pin = p11_kit_pin_new_for_string(o.value);
1576 (*cache)->pin = o.value;