common: New helper functions for OpenPGP curve OIDs.
authorWerner Koch <wk@gnupg.org>
Tue, 29 Jan 2019 17:19:05 +0000 (18:19 +0100)
committerWerner Koch <wk@gnupg.org>
Tue, 29 Jan 2019 17:19:05 +0000 (18:19 +0100)
* common/openpgp-oid.c (openpgp_oidbuf_to_str): Factor most code out
to ...
(openpgp_oidbuf_to_str): new.
(openpgp_oidbuf_is_ed25519): New.
(openpgp_oidbuf_is_cv25519): New.
--

At some places it is more convenient (and faster) to directly work on
buffers and avoid the way via opaque MPIs.  These 3 new functions
allow for that.

Signed-off-by: Werner Koch <wk@gnupg.org>
common/openpgp-oid.c
common/t-openpgp-oid.c
common/util.h

index 86885e0..4194718 100644 (file)
@@ -184,48 +184,36 @@ openpgp_oid_from_str (const char *string, gcry_mpi_t *r_mpi)
 }
 
 
-/* Return a malloced string representation of the OID in the opaque MPI
-   A.  In case of an error NULL is returned and ERRNO is set.  */
+/* Return a malloced string representation of the OID in the buffer
+ * (BUF,LEN).  In case of an error NULL is returned and ERRNO is set.
+ * As per OpenPGP spec the first byte of the buffer is the length of
+ * the rest; the function performs a consistency check.  */
 char *
-openpgp_oid_to_str (gcry_mpi_t a)
+openpgp_oidbuf_to_str (const unsigned char *buf, size_t len)
 {
-  const unsigned char *buf;
-  size_t length;
-  unsigned int lengthi;
   char *string, *p;
   int n = 0;
   unsigned long val, valmask;
 
   valmask = (unsigned long)0xfe << (8 * (sizeof (valmask) - 1));
-
-  if (!a
-      || !gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE)
-      || !(buf = gcry_mpi_get_opaque (a, &lengthi)))
-    {
-      gpg_err_set_errno (EINVAL);
-      return NULL;
-    }
-
-  buf = gcry_mpi_get_opaque (a, &lengthi);
-  length = (lengthi+7)/8;
-
   /* The first bytes gives the length; check consistency.  */
-  if (!length || buf[0] != length -1)
+
+  if (!len || buf[0] != len -1)
     {
       gpg_err_set_errno (EINVAL);
       return NULL;
     }
   /* Skip length byte.  */
-  length--;
+  len--;
   buf++;
 
   /* To calculate the length of the string we can safely assume an
      upper limit of 3 decimal characters per byte.  Two extra bytes
      account for the special first octet */
-  string = p = xtrymalloc (length*(1+3)+2+1);
+  string = p = xtrymalloc (len*(1+3)+2+1);
   if (!string)
     return NULL;
-  if (!length)
+  if (!len)
     {
       *p = 0;
       return string;
@@ -237,7 +225,7 @@ openpgp_oid_to_str (gcry_mpi_t a)
     p += sprintf (p, "1.%d", buf[n]-40);
   else {
     val = buf[n] & 0x7f;
-    while ( (buf[n]&0x80) && ++n < length )
+    while ( (buf[n]&0x80) && ++n < len )
       {
         if ( (val & valmask) )
           goto badoid;  /* Overflow.  */
@@ -250,10 +238,10 @@ openpgp_oid_to_str (gcry_mpi_t a)
     sprintf (p, "2.%lu", val);
     p += strlen (p);
   }
-  for (n++; n < length; n++)
+  for (n++; n < len; n++)
     {
       val = buf[n] & 0x7f;
-      while ( (buf[n]&0x80) && ++n < length )
+      while ( (buf[n]&0x80) && ++n < len )
         {
           if ( (val & valmask) )
             goto badoid;  /* Overflow.  */
@@ -278,6 +266,35 @@ openpgp_oid_to_str (gcry_mpi_t a)
 }
 
 
+/* Return a malloced string representation of the OID in the opaque
+ * MPI A.  In case of an error NULL is returned and ERRNO is set.  */
+char *
+openpgp_oid_to_str (gcry_mpi_t a)
+{
+  const unsigned char *buf;
+  unsigned int lengthi;
+
+  if (!a
+      || !gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE)
+      || !(buf = gcry_mpi_get_opaque (a, &lengthi)))
+    {
+      gpg_err_set_errno (EINVAL);
+      return NULL;
+    }
+
+  buf = gcry_mpi_get_opaque (a, &lengthi);
+  return openpgp_oidbuf_to_str (buf, (lengthi+7)/8);
+}
+
+
+/* Return true if (BUF,LEN) represents the OID for Ed25519.  */
+int
+openpgp_oidbuf_is_ed25519 (const void *buf, size_t len)
+{
+  return (buf && len == DIM (oid_ed25519)
+          && !memcmp (buf, oid_ed25519, DIM (oid_ed25519)));
+}
+
 
 /* Return true if A represents the OID for Ed25519.  */
 int
@@ -285,32 +302,36 @@ openpgp_oid_is_ed25519 (gcry_mpi_t a)
 {
   const unsigned char *buf;
   unsigned int nbits;
-  size_t n;
 
   if (!a || !gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
     return 0;
 
   buf = gcry_mpi_get_opaque (a, &nbits);
-  n = (nbits+7)/8;
-  return (n == DIM (oid_ed25519)
-          && !memcmp (buf, oid_ed25519, DIM (oid_ed25519)));
+  return openpgp_oidbuf_is_ed25519 (buf, (nbits+7)/8);
 }
 
 
+/* Return true if (BUF,LEN) represents the OID for Curve25519.  */
+int
+openpgp_oidbuf_is_cv25519 (const void *buf, size_t len)
+{
+  return (buf && len == DIM (oid_cv25519)
+          && !memcmp (buf, oid_cv25519, DIM (oid_cv25519)));
+}
+
+
+/* Return true if the MPI A represents the OID for Curve25519.  */
 int
 openpgp_oid_is_cv25519 (gcry_mpi_t a)
 {
   const unsigned char *buf;
   unsigned int nbits;
-  size_t n;
 
   if (!a || !gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
     return 0;
 
   buf = gcry_mpi_get_opaque (a, &nbits);
-  n = (nbits+7)/8;
-  return (n == DIM (oid_cv25519)
-          && !memcmp (buf, oid_cv25519, DIM (oid_cv25519)));
+  return openpgp_oidbuf_is_cv25519 (buf, (nbits+7)/8);
 }
 
 
index cb5709d..fd9de5d 100644 (file)
@@ -142,7 +142,15 @@ test_openpgp_oid_to_str (void)
         fail (idx, 0);
       xfree (string);
       gcry_mpi_release (a);
-    }
+
+      /* Again using the buffer variant. */
+      string = openpgp_oidbuf_to_str (samples[idx].der, samples[idx].der[0]+1);
+      if (!string)
+        fail (idx, gpg_error_from_syserror ());
+      if (strcmp (string, samples[idx].string))
+        fail (idx, 0);
+      xfree (string);
+}
 
 }
 
index d3a846f..8234b62 100644 (file)
@@ -211,8 +211,11 @@ size_t percent_unescape_inplace (char *string, int nulrepl);
 
 /*-- openpgp-oid.c --*/
 gpg_error_t openpgp_oid_from_str (const char *string, gcry_mpi_t *r_mpi);
+char *openpgp_oidbuf_to_str (const unsigned char *buf, size_t len);
 char *openpgp_oid_to_str (gcry_mpi_t a);
+int openpgp_oidbuf_is_ed25519 (const void *buf, size_t len);
 int openpgp_oid_is_ed25519 (gcry_mpi_t a);
+int openpgp_oidbuf_is_cv25519 (const void *buf, size_t len);
 int openpgp_oid_is_cv25519 (gcry_mpi_t a);
 const char *openpgp_curve_to_oid (const char *name, unsigned int *r_nbits);
 const char *openpgp_oid_to_curve (const char *oid, int canon);