Use OpenSSL TPM engine
authorDavid Woodhouse <David.Woodhouse@intel.com>
Sat, 27 Sep 2008 05:27:59 +0000 (23:27 -0600)
committerDavid Woodhouse <David.Woodhouse@intel.com>
Sat, 27 Sep 2008 05:27:59 +0000 (23:27 -0600)
anyconnect.h
main.c
ssl.c

index 0025b91..c45779a 100644 (file)
@@ -40,6 +40,7 @@ struct anyconnect_info {
        const char *localname;
        const char *hostname;
        const char *cert;
+       const char *tpmkey;
 
        const char *cookie;
        struct vpn_option *cstp_options;
diff --git a/main.c b/main.c
index a798990..12cfe67 100644 (file)
--- a/main.c
+++ b/main.c
@@ -46,6 +46,7 @@ static struct option long_options[] = {
        {"deflate", 0, 0, 'd'},
        {"useragent", 1, 0, 'u'},
        {"interface", 1, 0, 'i'},
+       {"tpm-key", 1, 0, 't'},
 };
 
 int main(int argc, char **argv)
@@ -78,11 +79,14 @@ int main(int argc, char **argv)
        else
                vpninfo->localname = "localhost";
 
-       while ((opt = getopt_long(argc, argv, "C:c:h:vdu:i:", long_options, &optind))) {
+       while ((opt = getopt_long(argc, argv, "C:c:h:vdu:i:t:", long_options, &optind))) {
                if (opt < 0)
                        break;
 
                switch (opt) {
+               case 't':
+                       vpninfo->tpmkey = optarg;
+                       break;
                case 'i':
                        vpninfo->ifname = optarg;
                        break;
diff --git a/ssl.c b/ssl.c
index ac608d5..677229d 100644 (file)
--- a/ssl.c
+++ b/ssl.c
@@ -25,6 +25,7 @@
 
 #include <openssl/ssl.h>
 #include <openssl/err.h>
+#include <openssl/engine.h>
 
 #include "anyconnect.h"
 
@@ -77,7 +78,67 @@ static int my_SSL_gets(SSL *ssl, char *buf, size_t len)
        buf[i] = 0;
        return i?:ret;
 }
+static int load_certificate(struct anyconnect_info *vpninfo, 
+                           SSL_CTX *https_ctx)
+{
+       printf("Using Certificate file %s\n", vpninfo->cert);
+       if (!SSL_CTX_use_certificate_file(https_ctx, vpninfo->cert,
+                                         SSL_FILETYPE_PEM)) {
+               fprintf(stderr, "Certificate failed\n");
+               ERR_print_errors_fp(stderr);
+               return -EINVAL;
+       }
+       
+       if (vpninfo->tpmkey) {
+               ENGINE *e;
+               EVP_PKEY *key;
 
+               ENGINE_load_builtin_engines();
+
+               e = ENGINE_by_id("tpm");
+               if (!e) {
+                       fprintf(stderr, "Can't load TPM engine.\n");
+                       ERR_print_errors_fp(stderr);
+                       return -EINVAL;
+               }
+               if (!ENGINE_init(e) || !ENGINE_set_default_RSA(e) ||
+                   !ENGINE_set_default_RAND(e)) {
+                       fprintf(stderr, "Failed to init TPM engine\n");
+                       ERR_print_errors_fp(stderr);
+                       ENGINE_free(e);
+                       ENGINE_finish(e);
+                       return -EINVAL;
+               }     
+
+               key = ENGINE_load_private_key(e, vpninfo->tpmkey,
+                                                     NULL, NULL);
+               if (!key) {
+                       fprintf(stderr, 
+                               "Failed to load TPM private key\n");
+                       ERR_print_errors_fp(stderr);
+                       ENGINE_free(e);
+                       ENGINE_finish(e);
+                       return -EINVAL;
+               }
+               if (!SSL_CTX_use_PrivateKey(https_ctx, key)) {
+                       fprintf(stderr, "Add key from TPM failed\n");
+                       ERR_print_errors_fp(stderr);
+                       ENGINE_free(e);
+                       ENGINE_finish(e);
+                       return -EINVAL;
+               }
+       } else {
+               /* Key should be in cert file too*/
+               if (!SSL_CTX_use_RSAPrivateKey_file(https_ctx, vpninfo->cert,
+                                                   SSL_FILETYPE_PEM)) {
+                       fprintf(stderr, "Private key failed\n");
+                       ERR_print_errors_fp(stderr);
+                       return -EINVAL;
+               }
+       }
+       return 0;
+}
 static int open_https(struct anyconnect_info *vpninfo)
 {
        SSL_METHOD *ssl3_method;
@@ -133,18 +194,10 @@ static int open_https(struct anyconnect_info *vpninfo)
 
        ssl3_method = SSLv23_client_method();
        https_ctx = SSL_CTX_new(ssl3_method);
-       if (vpninfo->cert) {
-               printf("Using Certificate file %s\n", vpninfo->cert);
-               if (!SSL_CTX_use_certificate_file(https_ctx, vpninfo->cert,
-                                                 SSL_FILETYPE_PEM))
-                       fprintf(stderr, "Certificate failed\n");
 
-               if (!SSL_CTX_use_RSAPrivateKey_file(https_ctx, vpninfo->cert,
-                                                   SSL_FILETYPE_PEM))
-                       fprintf(stderr, "Private key failed\n");
+       if (vpninfo->cert)
+               load_certificate(vpninfo, https_ctx);
 
-
-       }
                
        https_ssl = SSL_new(https_ctx);