common: Fix the previous commit.
[gnupg.git] / common / openpgp-oid.c
1 /* openpgp-oids.c - OID helper for OpenPGP
2  * Copyright (C) 2011 Free Software Foundation, Inc.
3  * Copyright (C) 2013 Werner Koch
4  *
5  * This file is part of GnuPG.
6  *
7  * This file is free software; you can redistribute it and/or modify
8  * it under the terms of either
9  *
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.
13  *
14  * or
15  *
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.
19  *
20  * or both in parallel, as here.
21  *
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.
26  *
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/>.
29  */
30
31 #include <config.h>
32 #include <stdlib.h>
33 #include <errno.h>
34 #include <ctype.h>
35 #include <assert.h>
36
37 #include "util.h"
38 #include "openpgpdefs.h"
39
40 /* A table with all our supported OpenPGP curves.  */
41 static struct {
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.  */
47 } oidtable[] = {
48
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 },
51
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" },
55
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 },
59
60   { "secp256k1",       "1.3.132.0.10",           256 },
61
62   { NULL, NULL, 0}
63 };
64
65
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 };
69
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 };
73
74
75 /* Helper for openpgp_oid_from_str.  */
76 static size_t
77 make_flagged_int (unsigned long value, char *buf, size_t buflen)
78 {
79   int more = 0;
80   int shift;
81
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)
87     {
88       if (more || value >= (1<<shift))
89         {
90           buf[buflen++] = 0x80 | (value >> shift);
91           value -= (value >> shift) << shift;
92           more = 1;
93         }
94     }
95   buf[buflen++] = value;
96   return buflen;
97 }
98
99
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
106  * character.  */
107 gpg_error_t
108 openpgp_oid_from_str (const char *string, gcry_mpi_t *r_mpi)
109 {
110   unsigned char *buf;
111   size_t buflen;
112   unsigned long val1, val;
113   const char *endp;
114   int arcno;
115
116   *r_mpi = NULL;
117
118   if (!string || !*string)
119     return gpg_error (GPG_ERR_INV_VALUE);
120
121   /* We can safely assume that the encoded OID is shorter than the string. */
122   buf = xtrymalloc (1 + strlen (string) + 2);
123   if (!buf)
124     return gpg_error_from_syserror ();
125   /* Save the first byte for the length.  */
126   buflen = 1;
127
128   val1 = 0; /* Avoid compiler warning.  */
129   arcno = 0;
130   do {
131     arcno++;
132     val = strtoul (string, (char**)&endp, 10);
133     if (!digitp (string) || !(*endp == '.' || !*endp))
134       {
135         xfree (buf);
136         return gpg_error (GPG_ERR_INV_OID_STRING);
137       }
138     if (*endp == '.')
139       string = endp+1;
140
141     if (arcno == 1)
142       {
143         if (val > 2)
144           break; /* Not allowed, error caught below.  */
145         val1 = val;
146       }
147     else if (arcno == 2)
148       { /* Need to combine the first two arcs in one octet.  */
149         if (val1 < 2)
150           {
151             if (val > 39)
152               {
153                 xfree (buf);
154                 return gpg_error (GPG_ERR_INV_OID_STRING);
155               }
156             buf[buflen++] = val1*40 + val;
157           }
158         else
159           {
160             val += 80;
161             buflen = make_flagged_int (val, buf, buflen);
162           }
163       }
164     else
165       {
166         buflen = make_flagged_int (val, buf, buflen);
167       }
168   } while (*endp == '.');
169
170   if (arcno == 1 || buflen < 2 || buflen > 254 )
171     { /* It is not possible to encode only the first arc.  */
172       xfree (buf);
173       return gpg_error (GPG_ERR_INV_OID_STRING);
174     }
175
176   *buf = buflen - 1;
177   *r_mpi = gcry_mpi_set_opaque (NULL, buf, buflen * 8);
178   if (!*r_mpi)
179     {
180       xfree (buf);
181       return gpg_error_from_syserror ();
182     }
183   return 0;
184 }
185
186
187 /* Return a malloced string representation of the OID in the buffer
188  * (BUF,LEN).  In case of an error NULL is returned and ERRNO is set.
189  * As per OpenPGP spec the first byte of the buffer is the length of
190  * the rest; the function performs a consistency check.  */
191 char *
192 openpgp_oidbuf_to_str (const unsigned char *buf, size_t len)
193 {
194   char *string, *p;
195   int n = 0;
196   unsigned long val, valmask;
197
198   valmask = (unsigned long)0xfe << (8 * (sizeof (valmask) - 1));
199   /* The first bytes gives the length; check consistency.  */
200
201   if (!len || buf[0] != len -1)
202     {
203       gpg_err_set_errno (EINVAL);
204       return NULL;
205     }
206   /* Skip length byte.  */
207   len--;
208   buf++;
209
210   /* To calculate the length of the string we can safely assume an
211      upper limit of 3 decimal characters per byte.  Two extra bytes
212      account for the special first octet */
213   string = p = xtrymalloc (len*(1+3)+2+1);
214   if (!string)
215     return NULL;
216   if (!len)
217     {
218       *p = 0;
219       return string;
220     }
221
222   if (buf[0] < 40)
223     p += sprintf (p, "0.%d", buf[n]);
224   else if (buf[0] < 80)
225     p += sprintf (p, "1.%d", buf[n]-40);
226   else {
227     val = buf[n] & 0x7f;
228     while ( (buf[n]&0x80) && ++n < len )
229       {
230         if ( (val & valmask) )
231           goto badoid;  /* Overflow.  */
232         val <<= 7;
233         val |= buf[n] & 0x7f;
234       }
235     if (val < 80)
236       goto badoid;
237     val -= 80;
238     sprintf (p, "2.%lu", val);
239     p += strlen (p);
240   }
241   for (n++; n < len; n++)
242     {
243       val = buf[n] & 0x7f;
244       while ( (buf[n]&0x80) && ++n < len )
245         {
246           if ( (val & valmask) )
247             goto badoid;  /* Overflow.  */
248           val <<= 7;
249           val |= buf[n] & 0x7f;
250         }
251       sprintf (p, ".%lu", val);
252       p += strlen (p);
253     }
254
255   *p = 0;
256   return string;
257
258  badoid:
259   /* Return a special OID (gnu.gnupg.badoid) to indicate the error
260      case.  The OID is broken and thus we return one which can't do
261      any harm.  Formally this does not need to be a bad OID but an OID
262      with an arc that can't be represented in a 32 bit word is more
263      than likely corrupt.  */
264   xfree (string);
265   return xtrystrdup ("1.3.6.1.4.1.11591.2.12242973");
266 }
267
268
269 /* Return a malloced string representation of the OID in the opaque
270  * MPI A.  In case of an error NULL is returned and ERRNO is set.  */
271 char *
272 openpgp_oid_to_str (gcry_mpi_t a)
273 {
274   const unsigned char *buf;
275   unsigned int lengthi;
276
277   if (!a
278       || !gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE)
279       || !(buf = gcry_mpi_get_opaque (a, &lengthi)))
280     {
281       gpg_err_set_errno (EINVAL);
282       return NULL;
283     }
284
285   buf = gcry_mpi_get_opaque (a, &lengthi);
286   return openpgp_oidbuf_to_str (buf, (lengthi+7)/8);
287 }
288
289
290 /* Return true if (BUF,LEN) represents the OID for Ed25519.  */
291 int
292 openpgp_oidbuf_is_ed25519 (const void *buf, size_t len)
293 {
294   return (buf && len == DIM (oid_ed25519)
295           && !memcmp (buf, oid_ed25519, DIM (oid_ed25519)));
296 }
297
298
299 /* Return true if A represents the OID for Ed25519.  */
300 int
301 openpgp_oid_is_ed25519 (gcry_mpi_t a)
302 {
303   const unsigned char *buf;
304   unsigned int nbits;
305
306   if (!a || !gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
307     return 0;
308
309   buf = gcry_mpi_get_opaque (a, &nbits);
310   return openpgp_oidbuf_is_ed25519 (buf, (nbits+7)/8);
311 }
312
313
314 /* Return true if (BUF,LEN) represents the OID for Curve25519.  */
315 int
316 openpgp_oidbuf_is_cv25519 (const void *buf, size_t len)
317 {
318   return (buf && len == DIM (oid_cv25519)
319           && !memcmp (buf, oid_cv25519, DIM (oid_cv25519)));
320 }
321
322
323 /* Return true if the MPI A represents the OID for Curve25519.  */
324 int
325 openpgp_oid_is_cv25519 (gcry_mpi_t a)
326 {
327   const unsigned char *buf;
328   unsigned int nbits;
329
330   if (!a || !gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
331     return 0;
332
333   buf = gcry_mpi_get_opaque (a, &nbits);
334   return openpgp_oidbuf_is_cv25519 (buf, (nbits+7)/8);
335 }
336
337
338 /* Map the Libgcrypt ECC curve NAME to an OID.  If R_NBITS is not NULL
339    store the bit size of the curve there.  Returns NULL for unknown
340    curve names.  */
341 const char *
342 openpgp_curve_to_oid (const char *name, unsigned int *r_nbits)
343 {
344   int i;
345   unsigned int nbits = 0;
346   const char *oidstr = NULL;
347
348   if (name)
349     {
350       for (i=0; oidtable[i].name; i++)
351         if (!strcmp (oidtable[i].name, name)
352             || (oidtable[i].alias && !strcmp (oidtable[i].alias, name)))
353           {
354             oidstr = oidtable[i].oidstr;
355             nbits  = oidtable[i].nbits;
356             break;
357           }
358       if (!oidtable[i].name)
359         {
360           /* If not found assume the input is already an OID and check
361              whether we support it.  */
362           for (i=0; oidtable[i].name; i++)
363             if (!strcmp (name, oidtable[i].oidstr))
364               {
365                 oidstr = oidtable[i].oidstr;
366                 nbits  = oidtable[i].nbits;
367                 break;
368               }
369         }
370     }
371
372   if (r_nbits)
373     *r_nbits = nbits;
374   return oidstr;
375 }
376
377
378 /* Map an OpenPGP OID to the Libgcrypt curve NAME.  Returns NULL for
379    unknown curve names.  Unless CANON is set we prefer an alias name
380    here which is more suitable for printing.  */
381 const char *
382 openpgp_oid_to_curve (const char *oidstr, int canon)
383 {
384   int i;
385
386   if (!oidstr)
387     return NULL;
388
389   for (i=0; oidtable[i].name; i++)
390     if (!strcmp (oidtable[i].oidstr, oidstr))
391       return !canon && oidtable[i].alias? oidtable[i].alias : oidtable[i].name;
392
393   return NULL;
394 }
395
396
397 /* Return true if the curve with NAME is supported.  */
398 static int
399 curve_supported_p (const char *name)
400 {
401   int result = 0;
402   gcry_sexp_t keyparms;
403
404   if (!gcry_sexp_build (&keyparms, NULL, "(public-key(ecc(curve %s)))", name))
405     {
406       result = !!gcry_pk_get_curve (keyparms, 0, NULL);
407       gcry_sexp_release (keyparms);
408     }
409   return result;
410 }
411
412
413 /* Enumerate available and supported OpenPGP curves.  The caller needs
414    to set the integer variable at ITERP to zero and keep on calling
415    this function until NULL is returned.  */
416 const char *
417 openpgp_enum_curves (int *iterp)
418 {
419   int idx = *iterp;
420
421   while (idx >= 0 && idx < DIM (oidtable) && oidtable[idx].name)
422     {
423       if (curve_supported_p (oidtable[idx].name))
424         {
425           *iterp = idx + 1;
426           return oidtable[idx].alias? oidtable[idx].alias : oidtable[idx].name;
427         }
428       idx++;
429     }
430   *iterp = idx;
431   return NULL;
432 }
433
434
435 /* Return the Libgcrypt name for the gpg curve NAME if supported.  If
436  * R_ALGO is not NULL the required OpenPGP public key algo or 0 is
437  * stored at that address.  If R_NBITS is not NULL the nominal bitsize
438  * of the curves is stored there.  NULL is returned if the curve is
439  * not supported. */
440 const char *
441 openpgp_is_curve_supported (const char *name, int *r_algo,
442                             unsigned int *r_nbits)
443 {
444   int idx;
445
446   if (r_algo)
447     *r_algo = 0;
448   if (r_nbits)
449     *r_nbits = 0;
450   for (idx = 0; idx < DIM (oidtable) && oidtable[idx].name; idx++)
451     {
452       if ((!strcmp (name, oidtable[idx].name)
453            || (oidtable[idx].alias && !strcmp (name, (oidtable[idx].alias))))
454           && curve_supported_p (oidtable[idx].name))
455         {
456           if (r_algo)
457             *r_algo = oidtable[idx].pubkey_algo;
458           if (r_nbits)
459             *r_nbits = oidtable[idx].nbits;
460           return oidtable[idx].name;
461         }
462     }
463   return NULL;
464 }