[Cryptech-Commits] [sw/libhal] 09/14: Rework PKCS #8 PrivateKeyInfo wrapper code.

git at cryptech.is git at cryptech.is
Thu Apr 6 23:38:08 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 34d240a491d0a5ccf2b9bf0f6cda8109d05f72ce
Author: Rob Austein <sra at hactrn.net>
AuthorDate: Tue Apr 4 00:32:22 2017 -0400

    Rework PKCS #8 PrivateKeyInfo wrapper code.
    
    Handle AlgorithmIdentifier.parameters as in SubjectPublicKeyInfo: the
    field is OPTIONAL, but it's usually set to NULL if no OID is present.
    I have a vague memory that this is fallout from a specification error
    years ago in which the OPTIONAL was accidently left out.  Whatever.
---
 asn1.c | 54 +++++++++++++++++++++++++++++-------------------------
 1 file changed, 29 insertions(+), 25 deletions(-)

diff --git a/asn1.c b/asn1.c
index 100dc3c..1d7e628 100644
--- a/asn1.c
+++ b/asn1.c
@@ -188,12 +188,14 @@ hal_error_t hal_asn1_encode_spki(const uint8_t * const alg_oid,   const size_t a
       (err = hal_asn1_encode_header(ASN1_BIT_STRING,        1 + pubkey_len, NULL, &hlen_bit,   0)) != HAL_OK)
     return err;
 
-  const size_t algid_len = hlen_alg + alg_oid_len + hlen_curve + curve_oid_len;
+  const size_t algid_len =
+    hlen_alg + alg_oid_len + hlen_curve + curve_oid_len;
 
   if ((err = hal_asn1_encode_header(ASN1_SEQUENCE,          algid_len,     NULL, &hlen_algid, 0)) != HAL_OK)
     return err;
 
-  const size_t vlen = hlen_algid + hlen_alg + alg_oid_len + hlen_curve + curve_oid_len + hlen_bit + 1 + pubkey_len;
+  const size_t vlen =
+    hlen_algid + hlen_alg + alg_oid_len + hlen_curve + curve_oid_len + hlen_bit + 1 + pubkey_len;
 
   if ((err = hal_asn1_encode_header(ASN1_SEQUENCE,          vlen,          NULL, &hlen_spki,  0)) != HAL_OK)
     return err;
@@ -236,7 +238,6 @@ hal_error_t hal_asn1_encode_spki(const uint8_t * const alg_oid,   const size_t a
     return err;
   d += hlen;
   *d++ = 0x00;
-
   d += pubkey_len;              /* pubkey handled early, above. */
 
   assert(d == der + hlen_spki + vlen);
@@ -258,47 +259,52 @@ hal_error_t hal_asn1_encode_pkcs8_privatekeyinfo(const uint8_t * const alg_oid,
       (der != NULL && privkey == NULL) || (curve_oid == NULL && curve_oid_len != 0))
     return HAL_ERROR_BAD_ARGUMENTS;
 
+  const uint8_t curve_oid_tag = curve_oid == NULL ? ASN1_NULL : ASN1_OBJECT_IDENTIFIER;
+
   fp_int version[1] = INIT_FP_INT;
 
   hal_error_t err;
 
-  size_t version_len, hlen, hlen_pkcs8, hlen_algid, hlen_alg, hlen_curve = 0, hlen_oct;
+  size_t version_len, hlen, hlen_algid, hlen_alg, hlen_curve, hlen_oct;
 
   if ((err = hal_asn1_encode_integer(version,                               NULL, &version_len, 0)) != HAL_OK ||
       (err = hal_asn1_encode_header(ASN1_OBJECT_IDENTIFIER, alg_oid_len,    NULL, &hlen_alg,    0)) != HAL_OK ||
+      (err = hal_asn1_encode_header(curve_oid_tag,          curve_oid_len,  NULL, &hlen_curve,  0)) != HAL_OK ||
       (err = hal_asn1_encode_header(ASN1_OCTET_STRING,      privkey_len,    NULL, &hlen_oct,    0)) != HAL_OK)
     return err;
 
-  if (curve_oid != NULL &&
-      (err = hal_asn1_encode_header(ASN1_OBJECT_IDENTIFIER, curve_oid_len,  NULL, &hlen_curve,  0)) != HAL_OK)
-    return err;
-
-  const size_t algid_len = hlen_alg + alg_oid_len + hlen_curve + curve_oid_len;
+  const size_t algid_len =
+    hlen_alg + alg_oid_len + hlen_curve + curve_oid_len;
 
   if ((err = hal_asn1_encode_header(ASN1_SEQUENCE,          algid_len,     NULL, &hlen_algid,   0)) != HAL_OK)
     return err;
 
-  const size_t vlen = version_len + hlen_algid + hlen_alg + alg_oid_len + hlen_curve + curve_oid_len + hlen_oct + privkey_len;
+  const size_t vlen =
+    version_len + hlen_algid + hlen_alg + alg_oid_len + hlen_curve + curve_oid_len + hlen_oct + privkey_len;
 
-  if ((err = hal_asn1_encode_header(ASN1_SEQUENCE,          vlen,          NULL, &hlen_pkcs8,   0)) != HAL_OK)
+  if ((err = hal_asn1_encode_header(ASN1_SEQUENCE,          vlen,          NULL, &hlen,         0)) != HAL_OK)
     return err;
 
+  if (der_len != NULL)
+    *der_len = hlen + vlen;
+
+  if (der == NULL)
+    return HAL_OK;
+
+  uint8_t * const der_end = der + hlen + vlen;
+
   /*
    * Handle privkey early, in case it was staged into our output buffer.
    */
-  if (der != NULL && hlen_pkcs8 + vlen <= der_max)
-    memmove(der + hlen_pkcs8 + vlen - privkey_len, privkey, privkey_len);
-
-  err = hal_asn1_encode_header(ASN1_SEQUENCE, vlen, der, &hlen, der_max);
+  if (der_end <= der + der_max)
+    memmove(der_end - privkey_len, privkey, privkey_len);
 
-  if (der_len != NULL)
-    *der_len = hlen + vlen;
+  uint8_t *d = der;
+  memset(d, 0, hlen + vlen - privkey_len);
 
-  if (der == NULL || err != HAL_OK)
+  if ((err = hal_asn1_encode_header(ASN1_SEQUENCE, vlen, d, &hlen, der + der_max - d)) != HAL_OK)
     return err;
-
-  uint8_t *d = der + hlen;
-  memset(d, 0, vlen - privkey_len);
+  d += hlen;
 
   if ((err = hal_asn1_encode_integer(version, d, NULL, der + der_max - d)) != HAL_OK)
     return err;
@@ -314,8 +320,7 @@ hal_error_t hal_asn1_encode_pkcs8_privatekeyinfo(const uint8_t * const alg_oid,
   memcpy(d, alg_oid, alg_oid_len);
   d += alg_oid_len;
 
-  if (curve_oid != NULL &&
-      (err = hal_asn1_encode_header(ASN1_OBJECT_IDENTIFIER, curve_oid_len, d, &hlen, der + der_max - d)) != HAL_OK)
+  if ((err = hal_asn1_encode_header(curve_oid_tag, curve_oid_len, d, &hlen, der + der_max - d)) != HAL_OK)
     return err;
   d += hlen;
   if (curve_oid != NULL)
@@ -325,10 +330,9 @@ hal_error_t hal_asn1_encode_pkcs8_privatekeyinfo(const uint8_t * const alg_oid,
   if ((err = hal_asn1_encode_header(ASN1_OCTET_STRING, privkey_len, d, &hlen, der + der_max - d)) != HAL_OK)
     return err;
   d += hlen;
-
   d += privkey_len;             /* privkey handled early, above. */
 
-  assert(d == der + hlen_pkcs8 + vlen);
+  assert(d == der_end);
   assert(d <= der + der_max);
 
   return HAL_OK;



More information about the Commits mailing list