]> www.infradead.org Git - users/dwmw2/openconnect.git/commitdiff
Factor out openconnect_install_ctx_verify() for OpenSSL
authorDavid Woodhouse <dwmw2@infradead.org>
Sun, 11 Apr 2021 10:56:57 +0000 (11:56 +0100)
committerDavid Woodhouse <dwmw2@infradead.org>
Wed, 21 Apr 2021 12:12:31 +0000 (13:12 +0100)
For anonymous DTLS we need to set up the verifification in the dtls_ctx
because the *server* sure as hell isn't anonymous. There be dragons...

Signed-off-by: David Woodhouse <dwmw2@infradead.org>
openconnect-internal.h
openssl.c

index 0c87b738fe2e0ebfc9f52859c0b8d7b059601c97..84cbf746257ed1e8cdbe94f5499be302f85b3eb6 100644 (file)
@@ -1147,6 +1147,10 @@ int hotp_hmac(struct openconnect_info *vpninfo, const void *challenge);
 #elif defined (OPENCONNECT_GNUTLS)
 #define openconnect_https_connected(_v) ((_v)->https_sess)
 #endif
+#ifdef OPENCONNECT_OPENSSL
+int openconnect_install_ctx_verify(struct openconnect_info *vpninfo,
+                                  SSL_CTX *ctx);
+#endif
 
 /* mainloop.c */
 int tun_mainloop(struct openconnect_info *vpninfo, int *timeout, int readable);
index 63c896261aa8e09f71a3206ab537dc2713a3bf8d..e9750e381d865372c3bb84bc238c92e744ac0400 100644 (file)
--- a/openssl.c
+++ b/openssl.c
@@ -1678,6 +1678,72 @@ static int check_certificate_expiry(struct openconnect_info *vpninfo)
        return 0;
 }
 
+int openconnect_install_ctx_verify(struct openconnect_info *vpninfo, SSL_CTX *ctx)
+{
+       /* We've seen certificates in the wild which don't have the
+          purpose fields filled in correctly */
+       SSL_CTX_set_purpose(ctx, X509_PURPOSE_ANY);
+       SSL_CTX_set_cert_verify_callback(ctx, ssl_app_verify_callback,
+                                        vpninfo);
+
+       if (!vpninfo->no_system_trust)
+               SSL_CTX_set_default_verify_paths(ctx);
+
+#ifdef ANDROID_KEYSTORE
+       if (vpninfo->cafile && !strncmp(vpninfo->cafile, "keystore:", 9)) {
+               STACK_OF(X509_INFO) *stack;
+               X509_STORE *store;
+               X509_INFO *info;
+               BIO *b = BIO_from_keystore(vpninfo, vpninfo->cafile);
+
+               if (!b)
+                       return -EINVAL;
+
+               stack = PEM_X509_INFO_read_bio(b, NULL, NULL, NULL);
+               BIO_free(b);
+
+               if (!stack) {
+                       vpn_progress(vpninfo, PRG_ERR,
+                                    _("Failed to read certs from CA file '%s'\n"),
+                                    vpninfo->cafile);
+                       openconnect_report_ssl_errors(vpninfo);
+                       return -ENOENT;
+               }
+
+               store = SSL_CTX_get_cert_store(ctx);
+
+               while ((info = sk_X509_INFO_pop(stack))) {
+                       if (info->x509)
+                               X509_STORE_add_cert(store, info->x509);
+                       if (info->crl)
+                               X509_STORE_add_crl(store, info->crl);
+                       X509_INFO_free(info);
+               }
+               sk_X509_INFO_free(stack);
+       } else
+#endif
+       if (vpninfo->cafile) {
+               /* OpenSSL does actually manage to cope with UTF-8 for
+                  this one, under Windows. So only convert for legacy
+                  UNIX. */
+               char *cafile = openconnect_utf8_to_legacy(vpninfo,
+                                                         vpninfo->cafile);
+               int err = SSL_CTX_load_verify_locations(ctx, cafile, NULL);
+
+               if (cafile != vpninfo->cafile)
+                       free(cafile);
+               if (!err) {
+                       vpn_progress(vpninfo, PRG_ERR,
+                                    _("Failed to open CA file '%s'\n"),
+                                    vpninfo->cafile);
+                       openconnect_report_ssl_errors(vpninfo);
+                       return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+
 int openconnect_open_https(struct openconnect_info *vpninfo)
 {
        SSL *https_ssl;
@@ -1762,15 +1828,6 @@ int openconnect_open_https(struct openconnect_info *vpninfo)
                        check_certificate_expiry(vpninfo);
                }
 
-               /* We've seen certificates in the wild which don't have the
-                  purpose fields filled in correctly */
-               SSL_CTX_set_purpose(vpninfo->https_ctx, X509_PURPOSE_ANY);
-               SSL_CTX_set_cert_verify_callback(vpninfo->https_ctx,
-                                                ssl_app_verify_callback, vpninfo);
-
-               if (!vpninfo->no_system_trust)
-                       SSL_CTX_set_default_verify_paths(vpninfo->https_ctx);
-
                if (!vpninfo->ciphersuite_config) {
                        struct oc_text_buf *buf = buf_alloc();
                        if (vpninfo->pfs)
@@ -1805,68 +1862,13 @@ int openconnect_open_https(struct openconnect_info *vpninfo)
                        return -EIO;
                }
 
-#ifdef ANDROID_KEYSTORE
-               if (vpninfo->cafile && !strncmp(vpninfo->cafile, "keystore:", 9)) {
-                       STACK_OF(X509_INFO) *stack;
-                       X509_STORE *store;
-                       X509_INFO *info;
-                       BIO *b = BIO_from_keystore(vpninfo, vpninfo->cafile);
-
-                       if (!b) {
-                               SSL_CTX_free(vpninfo->https_ctx);
-                               vpninfo->https_ctx = NULL;
-                               closesocket(ssl_sock);
-                               return -EINVAL;
-                       }
-
-                       stack = PEM_X509_INFO_read_bio(b, NULL, NULL, NULL);
-                       BIO_free(b);
-
-                       if (!stack) {
-                               vpn_progress(vpninfo, PRG_ERR,
-                                            _("Failed to read certs from CA file '%s'\n"),
-                                            vpninfo->cafile);
-                               openconnect_report_ssl_errors(vpninfo);
-                               SSL_CTX_free(vpninfo->https_ctx);
-                               vpninfo->https_ctx = NULL;
-                               closesocket(ssl_sock);
-                               return -ENOENT;
-                       }
-
-                       store = SSL_CTX_get_cert_store(vpninfo->https_ctx);
-
-                       while ((info = sk_X509_INFO_pop(stack))) {
-                               if (info->x509)
-                                       X509_STORE_add_cert(store, info->x509);
-                               if (info->crl)
-                                       X509_STORE_add_crl(store, info->crl);
-                               X509_INFO_free(info);
-                       }
-                       sk_X509_INFO_free(stack);
-               } else
-#endif
-               if (vpninfo->cafile) {
-                       /* OpenSSL does actually manage to cope with UTF-8 for
-                          this one, under Windows. So only convert for legacy
-                          UNIX. */
-                       char *cafile = openconnect_utf8_to_legacy(vpninfo,
-                                                                 vpninfo->cafile);
-                       err = SSL_CTX_load_verify_locations(vpninfo->https_ctx,
-                                                           cafile, NULL);
-                       if (cafile != vpninfo->cafile)
-                               free(cafile);
-                       if (!err) {
-                               vpn_progress(vpninfo, PRG_ERR,
-                                            _("Failed to open CA file '%s'\n"),
-                                            vpninfo->cafile);
-                               openconnect_report_ssl_errors(vpninfo);
-                               SSL_CTX_free(vpninfo->https_ctx);
-                               vpninfo->https_ctx = NULL;
-                               closesocket(ssl_sock);
-                               return -EINVAL;
-                       }
+               err = openconnect_install_ctx_verify(vpninfo, vpninfo->https_ctx);
+               if (err) {
+                       SSL_CTX_free(vpninfo->https_ctx);
+                       vpninfo->https_ctx = NULL;
+                       closesocket(ssl_sock);
+                       return err;
                }
-
        }
        https_ssl = SSL_new(vpninfo->https_ctx);
        workaround_openssl_certchain_bug(vpninfo, https_ssl);