summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2019-01-29 18:19:05 +0100
committerWerner Koch <wk@gnupg.org>2019-01-29 18:19:05 +0100
commit4a1558d0c7190cf13d35385e47291a7aa121be3e (patch)
treecfdd7a37f062ed9769b351b9eac64078d5eb81dc
parentcard: Support factory reset for Yubikey PIV application. (diff)
downloadgnupg2-4a1558d0c7190cf13d35385e47291a7aa121be3e.tar.xz
gnupg2-4a1558d0c7190cf13d35385e47291a7aa121be3e.zip
common: New helper functions for OpenPGP curve OIDs.
* 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>
-rw-r--r--common/openpgp-oid.c87
-rw-r--r--common/t-openpgp-oid.c10
-rw-r--r--common/util.h3
3 files changed, 66 insertions, 34 deletions
diff --git a/common/openpgp-oid.c b/common/openpgp-oid.c
index 86885e0aa..419471870 100644
--- a/common/openpgp-oid.c
+++ b/common/openpgp-oid.c
@@ -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);
}
diff --git a/common/t-openpgp-oid.c b/common/t-openpgp-oid.c
index cb5709d98..fd9de5dde 100644
--- a/common/t-openpgp-oid.c
+++ b/common/t-openpgp-oid.c
@@ -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);
+}
}
diff --git a/common/util.h b/common/util.h
index d3a846f00..8234b6257 100644
--- a/common/util.h
+++ b/common/util.h
@@ -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);