gnome-keyring [RFC 1/2] pkcs11: read TPM based ssh private keys



ssh private keys can be converted into TPM private keys using the
openssl_tpm_engine create_private_key code.  When this happens, they
have PEM guards 'TSS KEY BLOB'.  Teach the code to recognise these and
convert them to an s-expr of the form

(private-key
  (rsa
    (tpm
      (blob %b
      (auth %b)))))

Signed-off-by: James Bottomley <James Bottomley HansenPartnership com>
---
 pkcs11/gkm/gkm-data-der.c          | 34 ++++++++++++++++++++++++++++++++++
 pkcs11/gkm/gkm-data-der.h          |  4 ++++
 pkcs11/ssh-store/gkm-ssh-openssh.c | 21 +++++++++++++++++++++
 3 files changed, 59 insertions(+)

diff --git a/pkcs11/gkm/gkm-data-der.c b/pkcs11/gkm/gkm-data-der.c
index 78c16ca..7f21ef2 100644
--- a/pkcs11/gkm/gkm-data-der.c
+++ b/pkcs11/gkm/gkm-data-der.c
@@ -114,6 +114,40 @@ done:
        return ret;
 }
 
+#define SEXP_PRIVATE_TPM       \
+       "(private-key"          \
+       "  (rsa"                \
+       "    (tpm"              \
+       "      (blob %b)"       \
+       "      (auth %b))))"
+
+GkmDataResult
+gkm_data_der_read_private_tpm_key (GBytes *data,
+                                  const gchar *password,
+                                  gssize n_password,
+                                  gcry_sexp_t *s_key)
+{
+       const guchar *content;
+       char buf[1024];
+       gsize length;
+       int res;
+
+       /* assume all TPM keys require authorization */
+       if (n_password == 0)
+               return GKM_DATA_LOCKED;
+
+       content = egg_asn1x_element_content (g_bytes_get_data (data, NULL),
+                                            g_bytes_get_size (data),
+                                            &length);
+       res = gcry_sexp_build(s_key, NULL, SEXP_PRIVATE_TPM, length, content,
+                             n_password, password);
+       if (res)
+               return GKM_DATA_FAILURE;
+       gcry_sexp_sprint(*s_key, GCRYSEXP_FMT_DEFAULT, buf, sizeof(buf));
+
+       return GKM_DATA_SUCCESS;
+}
+
 #define SEXP_PRIVATE_RSA  \
        "(private-key"   \
        "  (rsa"         \
diff --git a/pkcs11/gkm/gkm-data-der.h b/pkcs11/gkm/gkm-data-der.h
index e496862..f6d2cd8 100644
--- a/pkcs11/gkm/gkm-data-der.h
+++ b/pkcs11/gkm/gkm-data-der.h
@@ -34,6 +34,10 @@
  * PRIVATE KEYS
  */
 
+GkmDataResult     gkm_data_der_read_private_tpm_key         (GBytes *data,
+                                                             const gchar *password,
+                                                             gssize n_password,
+                                                             gcry_sexp_t *s_key);
 GkmDataResult      gkm_data_der_read_private_key_rsa         (GBytes *data,
                                                               gcry_sexp_t *s_key);
 
diff --git a/pkcs11/ssh-store/gkm-ssh-openssh.c b/pkcs11/ssh-store/gkm-ssh-openssh.c
index c3a59a8..e6ae173 100644
--- a/pkcs11/ssh-store/gkm-ssh-openssh.c
+++ b/pkcs11/ssh-store/gkm-ssh-openssh.c
@@ -191,6 +191,21 @@ load_encrypted_key (GBytes *data,
 }
 
 static gboolean
+is_tpm_key_type (GQuark type)
+{
+       static GQuark PEM_TPM_KEY_BLOB;
+       static gsize quarks_inited = 0;
+
+       /* Initialize the first time through */
+       if (g_once_init_enter (&quarks_inited)) {
+               PEM_TPM_KEY_BLOB = g_quark_from_static_string ("TSS KEY BLOB");
+               g_once_init_leave (&quarks_inited, 1);
+       }
+
+       return (type == PEM_TPM_KEY_BLOB);
+}
+
+static gboolean
 is_private_key_type (GQuark type)
 {
        static GQuark PEM_RSA_PRIVATE_KEY;
@@ -218,6 +233,12 @@ parsed_pem_block (GQuark type,
        ParsePrivate *ctx = (ParsePrivate*)user_data;
        const gchar *dekinfo;
 
+       if (is_tpm_key_type(type)) {
+               ctx->result = gkm_data_der_read_private_tpm_key(data, ctx->password, ctx->n_password, 
&ctx->sexp);
+               ctx->seen = TRUE;
+               return;
+       }
+
        if (!is_private_key_type (type))
                return;
 
-- 
2.6.6



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]