1 /* openpgp-oids.c - OID helper for OpenPGP
2 * Copyright (C) 2011 Free Software Foundation, Inc.
3 * Copyright (C) 2013 Werner Koch
5 * This file is part of GnuPG.
7 * This file is free software; you can redistribute it and/or modify
8 * it under the terms of either
10 * - the GNU Lesser General Public License as published by the Free
11 * Software Foundation; either version 3 of the License, or (at
12 * your option) any later version.
16 * - the GNU General Public License as published by the Free
17 * Software Foundation; either version 2 of the License, or (at
18 * your option) any later version.
20 * or both in parallel, as here.
22 * This file is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, see <https://www.gnu.org/licenses/>.
38 #include "openpgpdefs.h"
40 /* A table with all our supported OpenPGP curves. */
42 const char *name; /* Standard name. */
43 const char *oidstr; /* IETF formatted OID. */
44 unsigned int nbits; /* Nominal bit length of the curve. */
45 const char *alias; /* NULL or alternative name of the curve. */
46 int pubkey_algo; /* Required OpenPGP algo or 0 for ECDSA/ECDH. */
49 { "Curve25519", "1.3.6.1.4.1.3029.1.5.1", 255, "cv25519", PUBKEY_ALGO_ECDH },
50 { "Ed25519", "1.3.6.1.4.1.11591.15.1", 255, "ed25519", PUBKEY_ALGO_EDDSA },
52 { "NIST P-256", "1.2.840.10045.3.1.7", 256, "nistp256" },
53 { "NIST P-384", "1.3.132.0.34", 384, "nistp384" },
54 { "NIST P-521", "1.3.132.0.35", 521, "nistp521" },
56 { "brainpoolP256r1", "1.3.36.3.3.2.8.1.1.7", 256 },
57 { "brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11", 384 },
58 { "brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13", 512 },
60 { "secp256k1", "1.3.132.0.10", 256 },
66 /* The OID for Curve Ed25519 in OpenPGP format. */
67 static const char oid_ed25519[] =
68 { 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xda, 0x47, 0x0f, 0x01 };
70 /* The OID for Curve25519 in OpenPGP format. */
71 static const char oid_cv25519[] =
72 { 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01 };
75 /* Helper for openpgp_oid_from_str. */
77 make_flagged_int (unsigned long value, char *buf, size_t buflen)
82 /* fixme: figure out the number of bits in an ulong and start with
83 that value as shift (after making it a multiple of 7) a more
84 straigtforward implementation is to do it in reverse order using
85 a temporary buffer - saves a lot of compares */
86 for (more=0, shift=28; shift > 0; shift -= 7)
88 if (more || value >= (1<<shift))
90 buf[buflen++] = 0x80 | (value >> shift);
91 value -= (value >> shift) << shift;
95 buf[buflen++] = value;
100 /* Convert the OID given in dotted decimal form in STRING to an DER
101 * encoding and store it as an opaque value at R_MPI. The format of
102 * the DER encoded is not a regular ASN.1 object but the modified
103 * format as used by OpenPGP for the ECC curve description. On error
104 * the function returns and error code an NULL is stored at R_BUG.
105 * Note that scanning STRING stops at the first white space
108 openpgp_oid_from_str (const char *string, gcry_mpi_t *r_mpi)
112 unsigned long val1, val;
118 if (!string || !*string)
119 return gpg_error (GPG_ERR_INV_VALUE);
121 /* We can safely assume that the encoded OID is shorter than the string. */
122 buf = xtrymalloc (1 + strlen (string) + 2);
124 return gpg_error_from_syserror ();
125 /* Save the first byte for the length. */
128 val1 = 0; /* Avoid compiler warning. */
132 val = strtoul (string, (char**)&endp, 10);
133 if (!digitp (string) || !(*endp == '.' || !*endp))
136 return gpg_error (GPG_ERR_INV_OID_STRING);
144 break; /* Not allowed, error catched below. */
148 { /* Need to combine the first two arcs in one octet. */
154 return gpg_error (GPG_ERR_INV_OID_STRING);
156 buf[buflen++] = val1*40 + val;
161 buflen = make_flagged_int (val, buf, buflen);
166 buflen = make_flagged_int (val, buf, buflen);
168 } while (*endp == '.');
170 if (arcno == 1 || buflen < 2 || buflen > 254 )
171 { /* It is not possible to encode only the first arc. */
173 return gpg_error (GPG_ERR_INV_OID_STRING);
177 *r_mpi = gcry_mpi_set_opaque (NULL, buf, buflen * 8);
181 return gpg_error_from_syserror ();
187 /* Return a malloced string represenation of the OID in the opaque MPI
188 A. In case of an error NULL is returned and ERRNO is set. */
190 openpgp_oid_to_str (gcry_mpi_t a)
192 const unsigned char *buf;
194 unsigned int lengthi;
197 unsigned long val, valmask;
199 valmask = (unsigned long)0xfe << (8 * (sizeof (valmask) - 1));
202 || !gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE)
203 || !(buf = gcry_mpi_get_opaque (a, &lengthi)))
205 gpg_err_set_errno (EINVAL);
209 buf = gcry_mpi_get_opaque (a, &lengthi);
210 length = (lengthi+7)/8;
212 /* The first bytes gives the length; check consistency. */
213 if (!length || buf[0] != length -1)
215 gpg_err_set_errno (EINVAL);
218 /* Skip length byte. */
222 /* To calculate the length of the string we can safely assume an
223 upper limit of 3 decimal characters per byte. Two extra bytes
224 account for the special first octect */
225 string = p = xtrymalloc (length*(1+3)+2+1);
235 p += sprintf (p, "0.%d", buf[n]);
236 else if (buf[0] < 80)
237 p += sprintf (p, "1.%d", buf[n]-40);
240 while ( (buf[n]&0x80) && ++n < length )
242 if ( (val & valmask) )
243 goto badoid; /* Overflow. */
245 val |= buf[n] & 0x7f;
250 sprintf (p, "2.%lu", val);
253 for (n++; n < length; n++)
256 while ( (buf[n]&0x80) && ++n < length )
258 if ( (val & valmask) )
259 goto badoid; /* Overflow. */
261 val |= buf[n] & 0x7f;
263 sprintf (p, ".%lu", val);
271 /* Return a special OID (gnu.gnupg.badoid) to indicate the error
272 case. The OID is broken and thus we return one which can't do
273 any harm. Formally this does not need to be a bad OID but an OID
274 with an arc that can't be represented in a 32 bit word is more
275 than likely corrupt. */
277 return xtrystrdup ("1.3.6.1.4.1.11591.2.12242973");
282 /* Return true if A represents the OID for Ed25519. */
284 openpgp_oid_is_ed25519 (gcry_mpi_t a)
286 const unsigned char *buf;
290 if (!a || !gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
293 buf = gcry_mpi_get_opaque (a, &nbits);
295 return (n == DIM (oid_ed25519)
296 && !memcmp (buf, oid_ed25519, DIM (oid_ed25519)));
301 openpgp_oid_is_cv25519 (gcry_mpi_t a)
303 const unsigned char *buf;
307 if (!a || !gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
310 buf = gcry_mpi_get_opaque (a, &nbits);
312 return (n == DIM (oid_cv25519)
313 && !memcmp (buf, oid_cv25519, DIM (oid_cv25519)));
317 /* Map the Libgcrypt ECC curve NAME to an OID. If R_NBITS is not NULL
318 store the bit size of the curve there. Returns NULL for unknown
321 openpgp_curve_to_oid (const char *name, unsigned int *r_nbits)
324 unsigned int nbits = 0;
325 const char *oidstr = NULL;
329 for (i=0; oidtable[i].name; i++)
330 if (!strcmp (oidtable[i].name, name)
331 || (oidtable[i].alias && !strcmp (oidtable[i].alias, name)))
333 oidstr = oidtable[i].oidstr;
334 nbits = oidtable[i].nbits;
337 if (!oidtable[i].name)
339 /* If not found assume the input is already an OID and check
340 whether we support it. */
341 for (i=0; oidtable[i].name; i++)
342 if (!strcmp (name, oidtable[i].oidstr))
344 oidstr = oidtable[i].oidstr;
345 nbits = oidtable[i].nbits;
357 /* Map an OpenPGP OID to the Libgcrypt curve NAME. Returns NULL for
358 unknown curve names. Unless CANON is set we prefer an alias name
359 here which is more suitable for printing. */
361 openpgp_oid_to_curve (const char *oidstr, int canon)
368 for (i=0; oidtable[i].name; i++)
369 if (!strcmp (oidtable[i].oidstr, oidstr))
370 return !canon && oidtable[i].alias? oidtable[i].alias : oidtable[i].name;
376 /* Return true if the curve with NAME is supported. */
378 curve_supported_p (const char *name)
381 gcry_sexp_t keyparms;
383 if (!gcry_sexp_build (&keyparms, NULL, "(public-key(ecc(curve %s)))", name))
385 result = !!gcry_pk_get_curve (keyparms, 0, NULL);
386 gcry_sexp_release (keyparms);
392 /* Enumerate available and supported OpenPGP curves. The caller needs
393 to set the integer variable at ITERP to zero and keep on calling
394 this function until NULL is returned. */
396 openpgp_enum_curves (int *iterp)
400 while (idx >= 0 && idx < DIM (oidtable) && oidtable[idx].name)
402 if (curve_supported_p (oidtable[idx].name))
405 return oidtable[idx].alias? oidtable[idx].alias : oidtable[idx].name;
414 /* Return the Libgcrypt name for the gpg curve NAME if supported. If
415 * R_ALGO is not NULL the required OpenPGP public key algo or 0 is
416 * stored at that address. If R_NBITS is not NULL the nominal bitsize
417 * of the curves is stored there. NULL is returned if the curve is
420 openpgp_is_curve_supported (const char *name, int *r_algo,
421 unsigned int *r_nbits)
429 for (idx = 0; idx < DIM (oidtable) && oidtable[idx].name; idx++)
431 if ((!strcmp (name, oidtable[idx].name)
432 || (oidtable[idx].alias && !strcmp (name, (oidtable[idx].alias))))
433 && curve_supported_p (oidtable[idx].name))
436 *r_algo = oidtable[idx].pubkey_algo;
438 *r_nbits = oidtable[idx].nbits;
439 return oidtable[idx].name;