Pass MD5 fingerprints of client/server certificates to the CSD script
authorAdam Piątyszek <ediap@users.sourceforge.net>
Sun, 2 Aug 2009 17:20:32 +0000 (19:20 +0200)
committerAdam Piątyszek <ediap@users.sourceforge.net>
Tue, 4 Aug 2009 12:05:50 +0000 (14:05 +0200)
Signed-off-by: Adam Piątyszek <ediap@users.sourceforge.net>
http.c
openconnect.h
ssl.c

diff --git a/http.c b/http.c
index e5f6674..46da75d 100644 (file)
--- a/http.c
+++ b/http.c
@@ -333,14 +333,9 @@ static int run_csd_script(struct openconnect_info *vpninfo, char *buf, int bufle
                csd_argv[i++] = "\"0\"";
                csd_argv[i++] = "-group";
                asprintf(&csd_argv[i++], "\"%s\"", vpninfo->authgroup?:"");
-
-               if (0) {
-                       /* FIXME: This probably isn't the hash they wanted */
-                       get_cert_fingerprint(cert, certbuf);
-                       csd_argv[i++] = "-certhash";
-                       asprintf(&csd_argv[i++], "\"%s\"", certbuf);
-               }
-
+               get_cert_md5_fingerprint(cert, certbuf);
+               csd_argv[i++] = "-certhash";
+               asprintf(&csd_argv[i++], "\"%s:%s\"", certbuf, vpninfo->cert_md5_fingerprint ?: "");
                csd_argv[i++] = "-url";
                asprintf(&csd_argv[i++], "\"https://%s%s\"", vpninfo->hostname, vpninfo->csd_starturl);
                /* WTF would it want to know this for? */
@@ -351,7 +346,6 @@ static int run_csd_script(struct openconnect_info *vpninfo, char *buf, int bufle
                csd_argv[i++] = "-connectparam";
                asprintf(&csd_argv[i++], "#csdtoken=%s\"", vpninfo->csd_token);
                csd_argv[i++] = "-langselen";
-                       
                csd_argv[i++] = NULL;
 
                execv(fname, csd_argv);
index c46a1d9..c5d3288 100644 (file)
@@ -151,6 +151,7 @@ struct openconnect_info {
        const char *sslkey;
        int cert_type;
        char *cert_password;
+       char *cert_md5_fingerprint;
        const char *cafile;
        const char *servercert;
        const char *xmlconfig;
@@ -276,6 +277,7 @@ int  __attribute__ ((format (printf, 2, 3)))
 int openconnect_SSL_gets(SSL *ssl, char *buf, size_t len);
 int openconnect_open_https(struct openconnect_info *vpninfo);
 void openconnect_close_https(struct openconnect_info *vpninfo);
+int get_cert_md5_fingerprint(X509 *cert, char *buf);
 int get_cert_sha1_fingerprint(X509 *cert, char *buf);
 void report_ssl_errors(struct openconnect_info *vpninfo);
 int passphrase_from_fsid(struct openconnect_info *vpninfo);
diff --git a/ssl.c b/ssl.c
index 8fbbfd7..97c11fe 100644 (file)
--- a/ssl.c
+++ b/ssl.c
@@ -132,6 +132,7 @@ static int load_pkcs12_certificate(struct openconnect_info *vpninfo, PKCS12 *p12
        STACK_OF(X509) *ca = sk_X509_new_null();
        int ret = 0;
        char pass[PEM_BUFSIZE];
+       char certbuf[EVP_MAX_MD_SIZE * 2 + 1];
 
        if (!vpninfo->cert_password) {
                if (EVP_read_pw_string(pass, PEM_BUFSIZE,
@@ -146,6 +147,8 @@ static int load_pkcs12_certificate(struct openconnect_info *vpninfo, PKCS12 *p12
        }
        if (cert) {
                SSL_CTX_use_certificate(vpninfo->https_ctx, cert);
+               get_cert_md5_fingerprint(cert, certbuf);
+               vpninfo->cert_md5_fingerprint = strdup(certbuf);
                X509_free(cert);
        } else {
                vpninfo->progress(vpninfo, PRG_ERR,
@@ -340,6 +343,20 @@ static int load_certificate(struct openconnect_info *vpninfo)
        return 0;
 }
 
+int get_cert_md5_fingerprint(X509 *cert, char *buf)
+{
+       unsigned char md[EVP_MAX_MD_SIZE];
+       unsigned int i, n;
+
+       if (!X509_digest(cert, EVP_md5(), md, &n))
+               return -ENOMEM;
+
+       for (i=0; i < n; i++) {
+               sprintf(&buf[i*2], "%02X", md[i]);
+       }
+       return 0;
+}
+
 int get_cert_sha1_fingerprint(X509 *cert, char *buf)
 {
        unsigned char md[EVP_MAX_MD_SIZE];