[Cryptech-Commits] [sw/libhal] 13/14: Shake bugs out of hal_rpc_pkey_export().

git at cryptech.is git at cryptech.is
Thu Apr 6 23:38:12 UTC 2017


This is an automated email from the git hooks/post-receive script.

sra at hactrn.net pushed a commit to branch pkcs8
in repository sw/libhal.

commit 29e55d64972fa094b7b55d432767f7d26726d034
Author: Rob Austein <sra at hactrn.net>
AuthorDate: Thu Apr 6 19:29:26 2017 -0400

    Shake bugs out of hal_rpc_pkey_export().
    
    Among other things, it turns out that this works better if one
    remembers to write the RPC server dispatch code as well as the client
    code, doh.
---
 rpc_api.c    |  4 +++-
 rpc_pkey.c   | 42 ++++++++--------------------------
 rpc_server.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 87 insertions(+), 33 deletions(-)

diff --git a/rpc_api.c b/rpc_api.c
index 099ffcd..825afe6 100644
--- a/rpc_api.c
+++ b/rpc_api.c
@@ -75,7 +75,9 @@ static inline int check_pkey_flags(const hal_key_flags_t flags)
   return (flags &~ (HAL_KEY_FLAG_USAGE_DIGITALSIGNATURE |
                     HAL_KEY_FLAG_USAGE_KEYENCIPHERMENT  |
                     HAL_KEY_FLAG_USAGE_DATAENCIPHERMENT |
-                    HAL_KEY_FLAG_TOKEN)) == 0;
+                    HAL_KEY_FLAG_TOKEN                  |
+                    HAL_KEY_FLAG_PUBLIC                 |
+                    HAL_KEY_FLAG_EXPORTABLE)) == 0;
 }
 
 static inline int check_pkey_type_curve_flags(const hal_key_type_t type,
diff --git a/rpc_pkey.c b/rpc_pkey.c
index 4867f97..ce67614 100644
--- a/rpc_pkey.c
+++ b/rpc_pkey.c
@@ -1062,33 +1062,6 @@ static hal_error_t pkey_local_get_attributes(const hal_pkey_handle_t pkey,
   return err;
 }
 
-/*
- * This is an RPC function, so the NULL pointer input convention for
- * querying required buffer length isn't all that useful, but buffer
- * lengths are predictable anyway:
- *
- *   Size of the pkcs8 buffer is a constant, determined by
- *   oid_aes_aesKeyWrap_len, HAL_KS_WRAPPED_KEYSIZE, and some ASN.1
- *   overhead;
- *
- *   Size of the kek buffer is the same as the length of the
- *   modulus of the RSA public key indicated by wrap_handle.
- *
- * Except that we might want ASN.1 around the KEK, something like:
- *
- *   SEQUENCE {
- *     keyEncryptionAlgorithm AlgorithmIdentifier { rsaEncryption },
- *     encryptedKey OCTET STRING
- *   }
- *
- * which would still be constant-length, just a bit more verbose.
- *
- * Oddly enough, this is exactly the syntax of PKCS #8
- * EncryptedPrivateKeyInfo, which we already use for other purposes.
- * Using it to wrap an AES key encrypted with an RSA key seems a bit
- * odd, but it's a good fit and lets us reuse ASN.1 code.  Cool.
- */
-
 static hal_error_t pkey_local_export(const hal_pkey_handle_t pkey_handle,
                                      const hal_pkey_handle_t kekek_handle,
                                      uint8_t *pkcs8, size_t *pkcs8_len, const size_t pkcs8_max,
@@ -1158,11 +1131,14 @@ static hal_error_t pkey_local_export(const hal_pkey_handle_t pkey_handle,
   if ((err = hal_get_random(NULL, kek, KEK_LENGTH)) != HAL_OK)
     goto fail;
 
-  if ((err = hal_aes_keywrap(NULL, kek, KEK_LENGTH, pkcs8, len, pkcs8, &len)) != HAL_OK)
+  *pkcs8_len = pkcs8_max;
+  if ((err = hal_aes_keywrap(NULL, kek, KEK_LENGTH, pkcs8, len, pkcs8, pkcs8_len)) != HAL_OK)
     goto fail;
 
-  if ((err = hal_asn1_encode_pkcs8_encryptedprivatekeyinfo(hal_asn1_oid_aesKeyWrap, hal_asn1_oid_aesKeyWrap_len,
-                                                           pkcs8, len, pkcs8, pkcs8_len, pkcs8_max)) != HAL_OK)
+  if ((err = hal_asn1_encode_pkcs8_encryptedprivatekeyinfo(hal_asn1_oid_aesKeyWrap,
+                                                           hal_asn1_oid_aesKeyWrap_len,
+                                                           pkcs8, *pkcs8_len,
+                                                           pkcs8, pkcs8_len, pkcs8_max)) != HAL_OK)
     goto fail;
 
   if ((err = pkcs1_5_pad(kek, KEK_LENGTH, kek, *kek_len, 0x02)) != HAL_OK)
@@ -1171,8 +1147,10 @@ static hal_error_t pkey_local_export(const hal_pkey_handle_t pkey_handle,
   if ((err = hal_rsa_encrypt(NULL, rsa, kek, *kek_len, kek, *kek_len)) != HAL_OK)
     goto fail;
 
-  if ((err = hal_asn1_encode_pkcs8_encryptedprivatekeyinfo(hal_asn1_oid_rsaEncryption, hal_asn1_oid_rsaEncryption_len,
-                                                           kek, *kek_len, kek, kek_len, kek_max)) != HAL_OK)
+  if ((err = hal_asn1_encode_pkcs8_encryptedprivatekeyinfo(hal_asn1_oid_rsaEncryption,
+                                                           hal_asn1_oid_rsaEncryption_len,
+                                                           kek, *kek_len,
+                                                           kek, kek_len, kek_max)) != HAL_OK)
     goto fail;
 
   memset(rsabuf,  0, sizeof(rsabuf));
diff --git a/rpc_server.c b/rpc_server.c
index a21679a..4aa5de4 100644
--- a/rpc_server.c
+++ b/rpc_server.c
@@ -782,6 +782,74 @@ static hal_error_t pkey_get_attributes(const uint8_t **iptr, const uint8_t * con
     return ret;
 }
 
+static hal_error_t pkey_export(const uint8_t **iptr, const uint8_t * const ilimit,
+                               uint8_t **optr, const uint8_t * const olimit)
+{
+    hal_client_handle_t client;
+    hal_pkey_handle_t pkey;
+    hal_pkey_handle_t kekek;
+    size_t   pkcs8_len, kek_len;
+    uint32_t pkcs8_max, kek_max;
+    uint8_t *optr_orig = *optr;
+    hal_error_t ret;
+
+    check(hal_xdr_decode_int(iptr, ilimit, &client.handle));
+    check(hal_xdr_decode_int(iptr, ilimit, &pkey.handle));
+    check(hal_xdr_decode_int(iptr, ilimit, &kekek.handle));
+    check(hal_xdr_decode_int(iptr, ilimit, &pkcs8_max));
+    check(hal_xdr_decode_int(iptr, ilimit, &kek_max));
+
+    uint8_t pkcs8[pkcs8_max], kek[kek_max];
+
+    ret = hal_rpc_pkey_export(pkey, kekek, pkcs8, &pkcs8_len, sizeof(pkcs8), kek, &kek_len, sizeof(kek));
+
+    if (ret == HAL_OK)
+        ret = hal_xdr_encode_buffer(optr, olimit, pkcs8, pkcs8_len);
+
+    if (ret == HAL_OK)
+        ret = hal_xdr_encode_buffer(optr, olimit, kek, kek_len);
+
+    if (ret != HAL_OK)
+        *optr = optr_orig;
+
+    return ret;
+}
+
+static hal_error_t pkey_import(const uint8_t **iptr, const uint8_t * const ilimit,
+                               uint8_t **optr, const uint8_t * const olimit)
+{
+    hal_client_handle_t client;
+    hal_session_handle_t session;
+    hal_pkey_handle_t pkey;
+    hal_pkey_handle_t kekek;
+    hal_uuid_t name;
+    const uint8_t *pkcs8, *kek;
+    uint32_t pkcs8_len, kek_len;
+    uint8_t *optr_orig = *optr;
+    hal_key_flags_t flags;
+    hal_error_t ret;
+
+    check(hal_xdr_decode_int(iptr, ilimit, &client.handle));
+    check(hal_xdr_decode_int(iptr, ilimit, &session.handle));
+    check(hal_xdr_decode_int(iptr, ilimit, &kekek.handle));
+    check(hal_xdr_decode_buffer_in_place(iptr, ilimit, &pkcs8, &pkcs8_len));
+    check(hal_xdr_decode_buffer_in_place(iptr, ilimit, &kek, &kek_len));
+    check(hal_xdr_decode_int(iptr, ilimit, &flags));
+
+    ret = hal_rpc_pkey_import(client, session, &pkey, &name, kekek, pkcs8, pkcs8_len, kek, kek_len, flags);
+
+    if (ret == HAL_OK)
+        ret = hal_xdr_encode_int(optr, olimit, pkey.handle);
+
+    if (ret == HAL_OK)
+        ret = hal_xdr_encode_buffer(optr, olimit, name.uuid, sizeof(name.uuid));
+
+    if (ret != HAL_OK)
+        *optr = optr_orig;
+
+    return ret;
+}
+
 
 hal_error_t hal_rpc_server_dispatch(const uint8_t * const ibuf, const size_t ilen,
                                     uint8_t * const obuf, size_t * const olen)
@@ -888,6 +956,12 @@ hal_error_t hal_rpc_server_dispatch(const uint8_t * const ibuf, const size_t ile
     case RPC_FUNC_PKEY_GET_ATTRIBUTES:
         handler = pkey_get_attributes;
         break;
+    case RPC_FUNC_PKEY_EXPORT:
+        handler = pkey_export;
+        break;
+    case RPC_FUNC_PKEY_IMPORT:
+        handler = pkey_import;
+        break;
     }
 
     if (handler)



More information about the Commits mailing list