[Cryptech-Commits] [sw/libhal] 01/04: Support queries for attribute length and presence.

git at cryptech.is git at cryptech.is
Tue Nov 22 05:27:02 UTC 2016


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

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

commit 306c1dec5eb20da03bc9569aab83ae97a2ca9e7a
Author: Rob Austein <sra at hactrn.net>
AuthorDate: Sat Nov 19 21:16:52 2016 -0500

    Support queries for attribute length and presence.
    
    Calling hal_rpc_pkey_get_attributes() with attribute_buffer_len = 0
    now changes the return behavior so that it reports the lengths of
    attributes listed in the query, with a length of zero for attributes
    not present at all.  This is mostly to support C_GetAttributeValue()
    in PKCS #11, but we also use it to make the Python interface a bit
    kinder to the user.
---
 hal_internal.h |  3 +--
 ks_flash.c     | 14 +++++++++-----
 ks_volatile.c  | 23 ++++++++++++++---------
 libhal.py      | 14 +++++++++++---
 rpc_client.c   | 17 ++++++++++++-----
 rpc_server.c   |  5 ++++-
 6 files changed, 51 insertions(+), 25 deletions(-)

diff --git a/hal_internal.h b/hal_internal.h
index 9685b0c..0794d37 100644
--- a/hal_internal.h
+++ b/hal_internal.h
@@ -649,8 +649,7 @@ static inline hal_error_t hal_ks_get_attributes(hal_ks_t *ks,
                                                 const size_t attributes_buffer_len)
 {
   if (ks == NULL || ks->driver == NULL || slot == NULL ||
-      attributes == NULL || attributes_len == 0 ||
-      attributes_buffer == NULL || attributes_buffer_len == 0)
+      attributes == NULL || attributes_len == 0)
     return HAL_ERROR_BAD_ARGUMENTS;
 
   if (ks->driver->get_attributes == NULL)
diff --git a/ks_flash.c b/ks_flash.c
index 5b38ec5..9b1bf7c 100644
--- a/ks_flash.c
+++ b/ks_flash.c
@@ -1579,7 +1579,7 @@ static  hal_error_t ks_get_attributes(hal_ks_t *ks,
                                       const size_t attributes_buffer_len)
 {
   if (ks != &db.ks || slot == NULL || attributes == NULL || attributes_len == 0 ||
-      attributes_buffer == NULL || attributes_buffer_len == 0)
+      attributes_buffer == NULL)
     return HAL_ERROR_BAD_ARGUMENTS;
 
   for (int i = 0; i < attributes_len; i++) {
@@ -1626,7 +1626,7 @@ static  hal_error_t ks_get_attributes(hal_ks_t *ks,
 
     for (int i = 0; i < attributes_len; i++) {
 
-      if (attributes[i].value != NULL)
+      if (attributes[i].length > 0)
         continue;
 
       int j = 0;
@@ -1634,20 +1634,24 @@ static  hal_error_t ks_get_attributes(hal_ks_t *ks,
         j++;
       if (j >= *attrs_len)
         continue;
+      found++;
+
+      attributes[i].length = attrs[j].length;
+
+      if (attributes_buffer_len == 0)
+        continue;
 
       if (attrs[j].length > attributes_buffer + attributes_buffer_len - abuf)
         return HAL_ERROR_RESULT_TOO_LONG;
 
       memcpy(abuf, attrs[j].value, attrs[j].length);
       attributes[i].value  = abuf;
-      attributes[i].length = attrs[j].length;
       abuf += attrs[j].length;
-      found++;
     }
 
   } while (found < attributes_len && ++chunk < block->header.total_chunks);
 
-  if (found < attributes_len)
+  if (found < attributes_len && attributes_buffer_len > 0)
     return HAL_ERROR_ATTRIBUTE_NOT_FOUND;
 
   return HAL_OK;
diff --git a/ks_volatile.c b/ks_volatile.c
index e23aefe..9588639 100644
--- a/ks_volatile.c
+++ b/ks_volatile.c
@@ -493,7 +493,7 @@ static hal_error_t ks_get_attributes(hal_ks_t *ks,
                                      const size_t attributes_buffer_len)
 {
   if (ks == NULL || slot == NULL || attributes == NULL || attributes_len == 0 ||
-      attributes_buffer == NULL || attributes_buffer_len == 0)
+      attributes_buffer == NULL)
     return HAL_ERROR_BAD_ARGUMENTS;
 
   ks_t *ksv = ks_to_ksv(ks);
@@ -511,10 +511,7 @@ static hal_error_t ks_get_attributes(hal_ks_t *ks,
   if (!key_visible_to_session(ksv, slot->client_handle, slot->session_handle, k))
     return HAL_ERROR_KEY_NOT_FOUND;
 
-  if (k->attributes_len == 0)
-    return HAL_ERROR_ATTRIBUTE_NOT_FOUND;
-
-  hal_rpc_pkey_attribute_t attrs[k->attributes_len];
+  hal_rpc_pkey_attribute_t attrs[k->attributes_len > 0 ? k->attributes_len : 1];
 
   if ((err = hal_ks_attribute_scan(k->der + k->der_len, sizeof(k->der) - k->der_len,
                                    attrs, k->attributes_len, NULL)) != HAL_OK)
@@ -523,11 +520,19 @@ static hal_error_t ks_get_attributes(hal_ks_t *ks,
   uint8_t *abuf = attributes_buffer;
 
   for (int i = 0; i < attributes_len; i++) {
-
     int j = 0;
-    while (attrs[j].type != attributes[i].type)
-      if (++j >= k->attributes_len)
-        return HAL_ERROR_ATTRIBUTE_NOT_FOUND;
+    while (j < k->attributes_len && attrs[j].type != attributes[i].type)
+      j++;
+    const int found = j < k->attributes_len;
+
+    if (attributes_buffer_len == 0) {
+      attributes[i].value  = NULL;
+      attributes[i].length = found ? attrs[j].length : 0;
+      continue;
+    }
+
+    if (!found)
+      return HAL_ERROR_ATTRIBUTE_NOT_FOUND;
 
     if (attrs[j].length > attributes_buffer + attributes_buffer_len - abuf)
       return HAL_ERROR_RESULT_TOO_LONG;
diff --git a/libhal.py b/libhal.py
index 8dad622..dc8d07d 100644
--- a/libhal.py
+++ b/libhal.py
@@ -382,8 +382,13 @@ class PKey(Handle):
     def set_attributes(self, attributes):
         self.hsm.pkey_set_attributes(self, attributes)
 
-    def get_attributes(self, attributes, attributes_buffer_len = 2048):
-        return self.hsm.pkey_get_attributes(self, attributes, attributes_buffer_len)
+    def get_attributes(self, attributes):
+        lengths = self.hsm.pkey_get_attributes(self, attributes, 0)
+        attributes = (k for k, v in lengths.iteritems() if v > 0)
+        buffer_length = sum(lengths.itervalues())
+        result = dict((a, None) for a in lengths)
+        result.update(self.hsm.pkey_get_attributes(self, attributes, buffer_length))
+        return result
 
 
 class HSM(object):
@@ -650,4 +655,7 @@ class HSM(object):
             n = r.unpack_uint()
             if n != len(attributes):
                 raise HAL_ERROR_RPC_PROTOCOL_ERROR
-            return dict((r.unpack_uint(), r.unpack_bytes()) for i in xrange(n))
+            if attributes_buffer_len > 0:
+                return dict((r.unpack_uint(), r.unpack_bytes()) for i in xrange(n))
+            else:
+                return dict((r.unpack_uint(), r.unpack_uint()) for i in xrange(n))
diff --git a/rpc_client.c b/rpc_client.c
index 0c57d51..4da0cb9 100644
--- a/rpc_client.c
+++ b/rpc_client.c
@@ -895,11 +895,18 @@ static hal_error_t pkey_remote_get_attributes(const hal_pkey_handle_t pkey,
       check(hal_xdr_decode_int(&iptr, ilimit, &u32));
       if (u32 != attributes[i].type)
         return HAL_ERROR_RPC_PROTOCOL_ERROR;
-      u32 = attributes_buffer + attributes_buffer_len - abuf;
-      check(hal_xdr_decode_buffer(&iptr, ilimit, abuf, &u32));
-      attributes[i].value  = abuf;
-      attributes[i].length = u32;
-      abuf += u32;
+      if (attributes_buffer_len == 0) {
+        check(hal_xdr_decode_int(&iptr, ilimit, &u32));
+        attributes[i].value  = NULL;
+        attributes[i].length = u32;
+      }
+      else {
+        u32 = attributes_buffer + attributes_buffer_len - abuf;
+        check(hal_xdr_decode_buffer(&iptr, ilimit, abuf, &u32));
+        attributes[i].value  = abuf;
+        attributes[i].length = u32;
+        abuf += u32;
+      }
     }
   }
   return rpc_ret;
diff --git a/rpc_server.c b/rpc_server.c
index ed9a8d5..ae891a4 100644
--- a/rpc_server.c
+++ b/rpc_server.c
@@ -759,7 +759,10 @@ static hal_error_t pkey_get_attributes(const uint8_t **iptr, const uint8_t * con
             ret = hal_xdr_encode_int(optr, olimit, attributes[i].type);
             if (ret != HAL_OK)
                 break;
-            ret = hal_xdr_encode_buffer(optr, olimit, attributes[i].value, attributes[i].length);
+            if (attributes_buffer_len == 0)
+              ret = hal_xdr_encode_int(optr, olimit, attributes[i].length);
+            else
+              ret = hal_xdr_encode_buffer(optr, olimit, attributes[i].value, attributes[i].length);
         }
     }
 



More information about the Commits mailing list