Handle detection of PKCS#12 certificates a bit better
authorDavid Woodhouse <David.Woodhouse@intel.com>
Mon, 1 Jun 2009 13:07:18 +0000 (14:07 +0100)
committerDavid Woodhouse <David.Woodhouse@intel.com>
Mon, 1 Jun 2009 13:07:39 +0000 (14:07 +0100)
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
openconnect.h
ssl.c

index 7d78723..7914dac 100644 (file)
@@ -122,9 +122,10 @@ struct split_include {
 #define RECONNECT_INTERVAL_MIN 10
 #define RECONNECT_INTERVAL_MAX 100
 
-#define CERT_TYPE_PEM          0
-#define CERT_TYPE_PKCS12       1
-#define CERT_TYPE_TPM          2
+#define CERT_TYPE_UNKNOWN      0
+#define CERT_TYPE_PEM          1
+#define CERT_TYPE_PKCS12       2
+#define CERT_TYPE_TPM          3
 
 struct openconnect_info {
        char *redirect_url;
diff --git a/ssl.c b/ssl.c
index 86a8d1c..c51c2a0 100644 (file)
--- a/ssl.c
+++ b/ssl.c
@@ -116,30 +116,14 @@ static int pem_pw_cb(char *buf, int len, int w, void *v)
        return strlen(vpninfo->tpmpass);
 }
 
-static int load_pkcs12_certificate(struct openconnect_info *vpninfo)
+static int load_pkcs12_certificate(struct openconnect_info *vpninfo, PKCS12 *p12)
 {
-       PKCS12 *p12;
        EVP_PKEY *pkey = NULL;
        X509 *cert = NULL;
        STACK_OF(X509) *ca = sk_X509_new_null();
-       FILE *f;
        int ret = 0;
        char pass[PEM_BUFSIZE];
 
-       f = fopen(vpninfo->cert, "r");
-       if (!f) {
-               vpninfo->progress(vpninfo, PRG_ERR,
-                                 "Failed to open certificate file %s\n",
-                                 vpninfo->cert);
-               return -ENOENT;
-       }
-       p12 = d2i_PKCS12_fp(f, NULL);
-       fclose(f);
-       if (!p12) {
-               vpninfo->progress(vpninfo, PRG_ERR, "Read PKCS#12 failed\n");
-               report_ssl_errors(vpninfo);
-               return -EINVAL;
-       }
        if (!vpninfo->tpmpass) {
                if (EVP_read_pw_string(pass, PEM_BUFSIZE,
                                       "Enter PKCS#12 pass phrase:", 0))
@@ -202,23 +186,38 @@ static int load_certificate(struct openconnect_info *vpninfo)
        vpninfo->progress(vpninfo, PRG_TRACE,
                          "Using certificate file %s\n", vpninfo->cert);
 
-       if (vpninfo->cert_type == CERT_TYPE_PKCS12)
-               return load_pkcs12_certificate(vpninfo);
+       if (vpninfo->cert_type == CERT_TYPE_PKCS12 ||
+           vpninfo->cert_type == CERT_TYPE_UNKNOWN) {
+               FILE *f;
+               PKCS12 *p12;
+
+               f = fopen(vpninfo->cert, "r");
+               if (!f) {
+                       vpninfo->progress(vpninfo, PRG_ERR,
+                                         "Failed to open certificate file %s\n",
+                                         vpninfo->cert);
+                       return -ENOENT;
+               }
+               p12 = d2i_PKCS12_fp(f, NULL);
+               fclose(f);
+               if (p12)
+                       return load_pkcs12_certificate(vpninfo, p12);
+
+               /* Not PKCS#12 */
+               if (vpninfo->cert_type == CERT_TYPE_PKCS12) {
+                       vpninfo->progress(vpninfo, PRG_ERR, "Read PKCS#12 failed\n");
+                       report_ssl_errors(vpninfo);
+                       return -EINVAL;
+               }
+               /* Clear error and fall through to see if it's a PEM file... */
+               ERR_clear_error();
+       }
 
        if (!SSL_CTX_use_certificate_file(vpninfo->https_ctx, vpninfo->cert,
                                          SSL_FILETYPE_PEM)) {
-
-               unsigned long err = ERR_peek_error();
-
                vpninfo->progress(vpninfo, PRG_ERR,
                                  "Load certificate failed\n");
                report_ssl_errors(vpninfo);
-
-               if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
-                   ERR_GET_FUNC(err) == PEM_F_PEM_READ_BIO &&
-                   ERR_GET_REASON(err) == PEM_R_NO_START_LINE)
-                       return load_pkcs12_certificate(vpninfo);
-
                return -EINVAL;
        }