[Cryptech-Commits] [sw/libhal] 01/02: Enforce key usage flags.

git at cryptech.is git at cryptech.is
Fri Apr 7 21:49:44 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 d52a62ab76003fffd04dfaee686aa1956e7b56a7
Author: Rob Austein <sra at hactrn.net>
AuthorDate: Fri Apr 7 13:57:56 2017 -0400

    Enforce key usage flags.
---
 libhal.py     |  2 +-
 rpc_pkey.c    | 14 +++++++++++++-
 unit-tests.py | 55 +++++++++++++++++++++++--------------------------------
 3 files changed, 37 insertions(+), 34 deletions(-)

diff --git a/libhal.py b/libhal.py
index 92f3987..2bc80f4 100644
--- a/libhal.py
+++ b/libhal.py
@@ -567,7 +567,7 @@ class HSM(object):
             logger.debug("Opened pkey %s", pkey.uuid)
             return pkey
 
-    def pkey_generate_rsa(self, keylen, exponent = "\x01\x00\x01", flags = 0, client = 0, session = 0):
+    def pkey_generate_rsa(self, keylen, flags = 0, exponent = "\x01\x00\x01", client = 0, session = 0):
         with self.rpc(RPC_FUNC_PKEY_GENERATE_RSA, session, keylen, exponent, flags, client = client) as r:
             pkey = PKey(self, r.unpack_uint(), UUID(bytes = r.unpack_bytes()))
             logger.debug("Generated RSA pkey %s", pkey.uuid)
diff --git a/rpc_pkey.c b/rpc_pkey.c
index e55ebf8..dca054f 100644
--- a/rpc_pkey.c
+++ b/rpc_pkey.c
@@ -268,7 +268,7 @@ static inline hal_error_t ks_open_from_flags(hal_ks_t **ks, const hal_key_flags_
  * return a key handle and the name.
  */
 
-#warning Convert hal_rpc_pkey_load() to use hal-asn1_guess_key_type()?
+#warning Convert hal_rpc_pkey_load() to use hal_asn1_guess_key_type()?
 
 static hal_error_t pkey_local_load(const hal_client_handle_t client,
                                    const hal_session_handle_t session,
@@ -809,6 +809,9 @@ static hal_error_t pkey_local_sign(const hal_pkey_handle_t pkey,
     return HAL_ERROR_UNSUPPORTED_KEY;
   }
 
+  if ((slot->flags & HAL_KEY_FLAG_USAGE_DIGITALSIGNATURE) == 0)
+    return HAL_ERROR_FORBIDDEN;
+
   uint8_t keybuf[hal_rsa_key_t_size > hal_ecdsa_key_t_size ? hal_rsa_key_t_size : hal_ecdsa_key_t_size];
   uint8_t der[HAL_KS_WRAPPED_KEYSIZE];
   size_t der_len;
@@ -957,6 +960,9 @@ static hal_error_t pkey_local_verify(const hal_pkey_handle_t pkey,
     return HAL_ERROR_UNSUPPORTED_KEY;
   }
 
+  if ((slot->flags & HAL_KEY_FLAG_USAGE_DIGITALSIGNATURE) == 0)
+    return HAL_ERROR_FORBIDDEN;
+
   uint8_t keybuf[hal_rsa_key_t_size > hal_ecdsa_key_t_size ? hal_rsa_key_t_size : hal_ecdsa_key_t_size];
   uint8_t der[HAL_KS_WRAPPED_KEYSIZE];
   size_t der_len;
@@ -1084,6 +1090,9 @@ static hal_error_t pkey_local_export(const hal_pkey_handle_t pkey_handle,
   if ((pkey->flags & HAL_KEY_FLAG_EXPORTABLE) == 0)
     return HAL_ERROR_FORBIDDEN;
 
+  if ((kekek->flags & HAL_KEY_FLAG_USAGE_KEYENCIPHERMENT) == 0)
+    return HAL_ERROR_FORBIDDEN;
+
   if (kekek->type != HAL_KEY_TYPE_RSA_PRIVATE && kekek->type != HAL_KEY_TYPE_RSA_PUBLIC)
     return HAL_ERROR_UNSUPPORTED_KEY;
 
@@ -1189,6 +1198,9 @@ static hal_error_t pkey_local_import(const hal_client_handle_t client,
   if (kekek == NULL)
     return HAL_ERROR_KEY_NOT_FOUND;
 
+  if ((kekek->flags & HAL_KEY_FLAG_USAGE_KEYENCIPHERMENT) == 0)
+    return HAL_ERROR_FORBIDDEN;
+
   if (kekek->type != HAL_KEY_TYPE_RSA_PRIVATE)
     return HAL_ERROR_UNSUPPORTED_KEY;
 
diff --git a/unit-tests.py b/unit-tests.py
index 2480506..83260e6 100644
--- a/unit-tests.py
+++ b/unit-tests.py
@@ -258,16 +258,18 @@ class TestPKeyGen(TestCaseLoggedIn):
         k2.verify(signature = sig, data = data)
 
     def gen_sign_verify_rsa(self, hashalg, keylen):
-        k1 = hsm.pkey_generate_rsa(keylen)
+        k1 = hsm.pkey_generate_rsa(keylen, HAL_KEY_FLAG_USAGE_DIGITALSIGNATURE)
         self.addCleanup(k1.delete)
-        k2 = hsm.pkey_load(HAL_KEY_TYPE_RSA_PUBLIC, HAL_CURVE_NONE, k1.public_key)
+        k2 = hsm.pkey_load(HAL_KEY_TYPE_RSA_PUBLIC, HAL_CURVE_NONE, k1.public_key,
+                           HAL_KEY_FLAG_USAGE_DIGITALSIGNATURE)
         self.addCleanup(k2.delete)
         self.sign_verify(hashalg, k1, k2)
 
     def gen_sign_verify_ecdsa(self, hashalg, curve):
-        k1 = hsm.pkey_generate_ec(curve)
+        k1 = hsm.pkey_generate_ec(curve, HAL_KEY_FLAG_USAGE_DIGITALSIGNATURE)
         self.addCleanup(k1.delete)
-        k2 = hsm.pkey_load(HAL_KEY_TYPE_EC_PUBLIC, curve, k1.public_key)
+        k2 = hsm.pkey_load(HAL_KEY_TYPE_EC_PUBLIC, curve, k1.public_key,
+                           HAL_KEY_FLAG_USAGE_DIGITALSIGNATURE)
         self.addCleanup(k2.delete)
         self.sign_verify(hashalg, k1, k2)
 
@@ -302,19 +304,23 @@ class TestPKeyHashing(TestCaseLoggedIn):
 
     def load_sign_verify_rsa(self, alg, keylen, method):
         k1 = hsm.pkey_load(HAL_KEY_TYPE_RSA_PRIVATE, HAL_CURVE_NONE,
-                           PreloadedKey.db[HAL_KEY_TYPE_RSA_PRIVATE, keylen].der)
+                           PreloadedKey.db[HAL_KEY_TYPE_RSA_PRIVATE, keylen].der,
+                           HAL_KEY_FLAG_USAGE_DIGITALSIGNATURE)
         self.addCleanup(k1.delete)
         k2 = hsm.pkey_load(HAL_KEY_TYPE_RSA_PUBLIC, HAL_CURVE_NONE,
-                           PreloadedKey.db[HAL_KEY_TYPE_RSA_PUBLIC, keylen].der)
+                           PreloadedKey.db[HAL_KEY_TYPE_RSA_PUBLIC, keylen].der,
+                           HAL_KEY_FLAG_USAGE_DIGITALSIGNATURE)
         self.addCleanup(k2.delete)
         method(alg, k1, k2)
 
     def load_sign_verify_ecdsa(self, alg, curve, method):
         k1 = hsm.pkey_load(HAL_KEY_TYPE_EC_PRIVATE, curve,
-                           PreloadedKey.db[HAL_KEY_TYPE_EC_PRIVATE, curve].der)
+                           PreloadedKey.db[HAL_KEY_TYPE_EC_PRIVATE, curve].der,
+                           HAL_KEY_FLAG_USAGE_DIGITALSIGNATURE)
         self.addCleanup(k1.delete)
         k2 = hsm.pkey_load(HAL_KEY_TYPE_EC_PUBLIC, curve,
-                           PreloadedKey.db[HAL_KEY_TYPE_EC_PUBLIC, curve].der)
+                           PreloadedKey.db[HAL_KEY_TYPE_EC_PUBLIC, curve].der,
+                           HAL_KEY_FLAG_USAGE_DIGITALSIGNATURE)
         self.addCleanup(k2.delete)
         method(alg, k1, k2)
 
@@ -484,9 +490,9 @@ class TestPKeyRSAInterop(TestCaseLoggedIn):
         hamster = "Your mother was a hamster"
         sk = PreloadedKey.db[HAL_KEY_TYPE_RSA_PRIVATE, keylen]
         vk = PreloadedKey.db[HAL_KEY_TYPE_RSA_PUBLIC,  keylen]
-        k1 = hsm.pkey_load(HAL_KEY_TYPE_RSA_PRIVATE, HAL_CURVE_NONE, sk.der)
+        k1 = hsm.pkey_load(HAL_KEY_TYPE_RSA_PRIVATE, HAL_CURVE_NONE, sk.der, HAL_KEY_FLAG_USAGE_DIGITALSIGNATURE)
         self.addCleanup(k1.delete)
-        k2 = hsm.pkey_load(HAL_KEY_TYPE_RSA_PUBLIC,  HAL_CURVE_NONE, vk.der)
+        k2 = hsm.pkey_load(HAL_KEY_TYPE_RSA_PUBLIC,  HAL_CURVE_NONE, vk.der, HAL_KEY_FLAG_USAGE_DIGITALSIGNATURE)
         self.addCleanup(k2.delete)
         sig1 = k1.sign(hash = self.h(alg, hamster))
         sig2 = sk.sign(hamster, pyhash)
@@ -519,9 +525,9 @@ class TestPKeyECDSAInterop(TestCaseLoggedIn):
         hamster = "Your mother was a hamster"
         sk = PreloadedKey.db[HAL_KEY_TYPE_EC_PRIVATE, curve]
         vk = PreloadedKey.db[HAL_KEY_TYPE_EC_PUBLIC,  curve]
-        k1 = hsm.pkey_load(HAL_KEY_TYPE_EC_PRIVATE, curve, sk.der)
+        k1 = hsm.pkey_load(HAL_KEY_TYPE_EC_PRIVATE, curve, sk.der, HAL_KEY_FLAG_USAGE_DIGITALSIGNATURE)
         self.addCleanup(k1.delete)
-        k2 = hsm.pkey_load(HAL_KEY_TYPE_EC_PUBLIC,  curve, vk.der)
+        k2 = hsm.pkey_load(HAL_KEY_TYPE_EC_PUBLIC,  curve, vk.der, HAL_KEY_FLAG_USAGE_DIGITALSIGNATURE)
         self.addCleanup(k2.delete)
         sig1 = k1.sign(hash = self.h(alg, hamster))
         sig2 = sk.sign(hamster, pyhash)
@@ -827,7 +833,7 @@ class TestPkeyECDSAVerificationNIST(TestCaseLoggedIn):
     def verify(self, Qx, Qy, H, r, s, hal_curve, py_curve, py_hash):
         Q = ECDSA_VerifyingKey.from_public_point(Point(py_curve.curve, Qx, Qy),
                                                  py_curve, py_hash).to_der()
-        k  = hsm.pkey_load(HAL_KEY_TYPE_EC_PUBLIC, hal_curve, Q)
+        k  = hsm.pkey_load(HAL_KEY_TYPE_EC_PUBLIC, hal_curve, Q, HAL_KEY_FLAG_USAGE_DIGITALSIGNATURE)
         self.addCleanup(k.delete)
         k.verify(signature = (r + s).decode("hex"), data = H.decode("hex"))
 
@@ -854,18 +860,6 @@ class TestPkeyECDSAVerificationNIST(TestCaseLoggedIn):
             py_hash   = SHA384)
 
 
-# Entire classes of tests still missing:
-#
-# * pkey attribute functions
-#
-# * pkey list and match functions
-#
-# * token vs session key tests
-#
-# Preloaded keys should suffice for all of these.
-
-
-
 class Pinwheel(object):
     """
     Activity pinwheel, as needed.
@@ -891,13 +885,10 @@ class Pinwheel(object):
 class PreloadedKey(object):
     """
     Keys for preload tests, here at the end because they're large.
-    For the moment, we use PKCS #1.5 format for RSA and secg format
-    for ECDSA, because those are the formats that everything
-    (including our own ASN.1 code) supports.  Arguably, we should be
-    using PKCS #8 to get a single, consistent, self-identifying
-    private key format, but we're not there yet and it's not
-    particularly urgent given widespread availablity of conversion
-    tools (eg, "openssl pkcs8").
+    These are now in PKCS #8 format, which gives us a single,
+    consistent, self-identifying private key format.  See tools
+    like "openssl pkcs8" if you need to convert from some other format
+    (eg, PKCS #1 or secg).
     """
 
     db = {}



More information about the Commits mailing list