This patch adds a feature to allow the mod_ssl key to be bound to a platform TPM (Trusted Platform Module described in specifications by the Trusted Computing Group). This feature is desirable to protect the key from being stolen by an attacker and used on another machine to spoof the secure site. The feature works by encrypting the mod_ssl key with an AES key which is then bound to a TPM and thus usable only on that platform.
The tpm_unseal library and tpm_sealdata command for binding the key to the TPM can be found at www.sourceforge.net/projects/trousers in the tpm-tools package. Thanks, Kylie Hall --- Index: modules/ssl/ssl_util_ssl.c =================================================================== --- modules/ssl/ssl_util_ssl.c (revision 384633) +++ modules/ssl/ssl_util_ssl.c (working copy) @@ -1,6 +1,8 @@ /* Copyright 2001-2005 The Apache Software Foundation or its licensors, as * applicable. * + * TPMUNSEAL Portions Copyright (C) 2006 IBM Corporation + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -25,6 +27,9 @@ */ #include "ssl_private.h" +#ifdef HAVE_TPMUNSEAL +#include <tpm_tools/tpm_unseal.h> +#endif /* _________________________________________________________________ ** @@ -127,35 +132,49 @@ EVP_PKEY *SSL_read_PrivateKey(char* filename, EVP_PKEY **key, modssl_read_bio_cb_fn *cb, void *s) { - EVP_PKEY *rc; - BIO *bioS; - BIO *bioF; + EVP_PKEY *rc = NULL; + BIO *bioS = NULL; + BIO *bioF = NULL; +#ifdef HAVE_TPMUNSEAL + unsigned char *data = NULL; + int data_len; + int tpmRc = tpmUnsealFile(filename, &data, &data_len); + + if (tpmRc != 0) { + ap_log_error(APLOG_MARK, + ((tpmRc == TPMSEAL_FILE_ERROR && tpm_errno == ENOTSSHDR) + ? APLOG_DEBUG : APLOG_ERR), 0, s, "%s", + tpmUnsealStrerror(tpmRc)); + } + else { + if ((bioS = BIO_new_mem_buf(data, data_len)) == NULL) + return NULL; + BIO_set_close(bioS, BIO_NOCLOSE); + } +#endif + + if (bioS == NULL && (bioS = BIO_new_file(filename, "r")) == NULL) + return NULL; + /* 1. try PEM (= DER+Base64+headers) */ - if ((bioS=BIO_new_file(filename, "r")) == NULL) - return NULL; rc = modssl_PEM_read_bio_PrivateKey(bioS, key, cb, s); - BIO_free(bioS); + BIO_reset(bioS); if (rc == NULL) { /* 2. try DER+Base64 */ - if ((bioS = BIO_new_file(filename, "r")) == NULL) - return NULL; + if ((bioF = BIO_new(BIO_f_base64())) == NULL) + goto out; - if ((bioF = BIO_new(BIO_f_base64())) == NULL) { - BIO_free(bioS); - return NULL; - } - bioS = BIO_push(bioF, bioS); - rc = d2i_PrivateKey_bio(bioS, NULL); - BIO_free_all(bioS); + BIO_push(bioF, bioS); + rc = d2i_PrivateKey_bio(bioF, NULL); + BIO_pop(bioF); + BIO_free(bioF); + BIO_reset(bioS); if (rc == NULL) { /* 3. try plain DER */ - if ((bioS = BIO_new_file(filename, "r")) == NULL) - return NULL; rc = d2i_PrivateKey_bio(bioS, NULL); - BIO_free(bioS); } } if (rc != NULL && key != NULL) { @@ -163,6 +182,13 @@ EVP_PKEY_free(*key); *key = rc; } + + out: +#ifdef HAVE_TPMUNSEAL + if (data) + tpmUnsealShred(data, data_len); +#endif + BIO_free(bioS); return rc; } Index: modules/ssl/config.m4 =================================================================== --- modules/ssl/config.m4 (revision 384633) +++ modules/ssl/config.m4 (working copy) @@ -12,6 +12,26 @@ dnl See the License for the specific language governing permissions and dnl limitations under the License. +AC_DEFUN([CHECK_TPMUNSEAL], [ + AC_MSG_CHECKING(for tpm-tools unseal library) + save_libs=$LIBS + LIBS="$LIBS -ltpm_unseal" + AC_TRY_LINK( + [#include <tpm_tools/tpm_unseal.h>], + [tpmUnsealStrerror(0);], + [], + [tmp_no_message="failed to link with tpm_unseal library" + ap_ssltk_ts="no"]) + LIBS=$save_libs + AC_MSG_RESULT($ap_ssltk_ts) + if test "x$ap_ssltk_ts" = "xno"; then + AC_MSG_WARN(tpm_unseal support failed: $tmp_nomessage) + else + APR_ADDTO(MOD_SSL_LDADD,[-ltpm_unseal]) + AC_DEFINE(HAVE_TPMUNSEAL, 1, [Define if tpm_unseal support is enabled]) + fi +]) + AC_DEFUN([CHECK_DISTCACHE], [ AC_MSG_CHECKING(whether Distcache is required) ap_ssltk_dc="no" @@ -117,6 +137,7 @@ APACHE_CHECK_SSL_TOOLKIT APR_SETVAR(MOD_SSL_LDADD, [\$(SSL_LIBS)]) CHECK_DISTCACHE + CHECK_TPMUNSEAL if test "x$enable_ssl" = "xshared"; then # The only symbol which needs to be exported is the module # structure, so ask libtool to hide everything else: