chiark / gitweb /
Import gnupg2_2.1.17.orig.tar.bz2
[gnupg2.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 catched 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 represenation of the OID in the opaque MPI
188    A.  In case of an error NULL is returned and ERRNO is set.  */
189 char *
190 openpgp_oid_to_str (gcry_mpi_t a)
191 {
192   const unsigned char *buf;
193   size_t length;
194   unsigned int lengthi;
195   char *string, *p;
196   int n = 0;
197   unsigned long val, valmask;
198
199   valmask = (unsigned long)0xfe << (8 * (sizeof (valmask) - 1));
200
201   if (!a
202       || !gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE)
203       || !(buf = gcry_mpi_get_opaque (a, &lengthi)))
204     {
205       gpg_err_set_errno (EINVAL);
206       return NULL;
207     }
208
209   buf = gcry_mpi_get_opaque (a, &lengthi);
210   length = (lengthi+7)/8;
211
212   /* The first bytes gives the length; check consistency.  */
213   if (!length || buf[0] != length -1)
214     {
215       gpg_err_set_errno (EINVAL);
216       return NULL;
217     }
218   /* Skip length byte.  */
219   length--;
220   buf++;
221
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);
226   if (!string)
227     return NULL;
228   if (!length)
229     {
230       *p = 0;
231       return string;
232     }
233
234   if (buf[0] < 40)
235     p += sprintf (p, "0.%d", buf[n]);
236   else if (buf[0] < 80)
237     p += sprintf (p, "1.%d", buf[n]-40);
238   else {
239     val = buf[n] & 0x7f;
240     while ( (buf[n]&0x80) && ++n < length )
241       {
242         if ( (val & valmask) )
243           goto badoid;  /* Overflow.  */
244         val <<= 7;
245         val |= buf[n] & 0x7f;
246       }
247     if (val < 80)
248       goto badoid;
249     val -= 80;
250     sprintf (p, "2.%lu", val);
251     p += strlen (p);
252   }
253   for (n++; n < length; n++)
254     {
255       val = buf[n] & 0x7f;
256       while ( (buf[n]&0x80) && ++n < length )
257         {
258           if ( (val & valmask) )
259             goto badoid;  /* Overflow.  */
260           val <<= 7;
261           val |= buf[n] & 0x7f;
262         }
263       sprintf (p, ".%lu", val);
264       p += strlen (p);
265     }
266
267   *p = 0;
268   return string;
269
270  badoid:
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.  */
276   xfree (string);
277   return xtrystrdup ("1.3.6.1.4.1.11591.2.12242973");
278 }
279
280
281
282 /* Return true if A represents the OID for Ed25519.  */
283 int
284 openpgp_oid_is_ed25519 (gcry_mpi_t a)
285 {
286   const unsigned char *buf;
287   unsigned int nbits;
288   size_t n;
289
290   if (!a || !gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
291     return 0;
292
293   buf = gcry_mpi_get_opaque (a, &nbits);
294   n = (nbits+7)/8;
295   return (n == DIM (oid_ed25519)
296           && !memcmp (buf, oid_ed25519, DIM (oid_ed25519)));
297 }
298
299
300 int
301 openpgp_oid_is_cv25519 (gcry_mpi_t a)
302 {
303   const unsigned char *buf;
304   unsigned int nbits;
305   size_t n;
306
307   if (!a || !gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
308     return 0;
309
310   buf = gcry_mpi_get_opaque (a, &nbits);
311   n = (nbits+7)/8;
312   return (n == DIM (oid_cv25519)
313           && !memcmp (buf, oid_cv25519, DIM (oid_cv25519)));
314 }
315
316
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
319    curve names.  */
320 const char *
321 openpgp_curve_to_oid (const char *name, unsigned int *r_nbits)
322 {
323   int i;
324   unsigned int nbits = 0;
325   const char *oidstr = NULL;
326
327   if (name)
328     {
329       for (i=0; oidtable[i].name; i++)
330         if (!strcmp (oidtable[i].name, name)
331             || (oidtable[i].alias && !strcmp (oidtable[i].alias, name)))
332           {
333             oidstr = oidtable[i].oidstr;
334             nbits  = oidtable[i].nbits;
335             break;
336           }
337       if (!oidtable[i].name)
338         {
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))
343               {
344                 oidstr = oidtable[i].oidstr;
345                 nbits  = oidtable[i].nbits;
346                 break;
347               }
348         }
349     }
350
351   if (r_nbits)
352     *r_nbits = nbits;
353   return oidstr;
354 }
355
356
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.  */
360 const char *
361 openpgp_oid_to_curve (const char *oidstr, int canon)
362 {
363   int i;
364
365   if (!oidstr)
366     return NULL;
367
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;
371
372   return NULL;
373 }
374
375
376 /* Return true if the curve with NAME is supported.  */
377 static int
378 curve_supported_p (const char *name)
379 {
380   int result = 0;
381   gcry_sexp_t keyparms;
382
383   if (!gcry_sexp_build (&keyparms, NULL, "(public-key(ecc(curve %s)))", name))
384     {
385       result = !!gcry_pk_get_curve (keyparms, 0, NULL);
386       gcry_sexp_release (keyparms);
387     }
388   return result;
389 }
390
391
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.  */
395 const char *
396 openpgp_enum_curves (int *iterp)
397 {
398   int idx = *iterp;
399
400   while (idx >= 0 && idx < DIM (oidtable) && oidtable[idx].name)
401     {
402       if (curve_supported_p (oidtable[idx].name))
403         {
404           *iterp = idx + 1;
405           return oidtable[idx].alias? oidtable[idx].alias : oidtable[idx].name;
406         }
407       idx++;
408     }
409   *iterp = idx;
410   return NULL;
411 }
412
413
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
418  * not supported. */
419 const char *
420 openpgp_is_curve_supported (const char *name, int *r_algo,
421                             unsigned int *r_nbits)
422 {
423   int idx;
424
425   if (r_algo)
426     *r_algo = 0;
427   if (r_nbits)
428     *r_nbits = 0;
429   for (idx = 0; idx < DIM (oidtable) && oidtable[idx].name; idx++)
430     {
431       if ((!strcmp (name, oidtable[idx].name)
432            || (oidtable[idx].alias && !strcmp (name, (oidtable[idx].alias))))
433           && curve_supported_p (oidtable[idx].name))
434         {
435           if (r_algo)
436             *r_algo = oidtable[idx].pubkey_algo;
437           if (r_nbits)
438             *r_nbits = oidtable[idx].nbits;
439           return oidtable[idx].name;
440         }
441     }
442   return NULL;
443 }