Do not translate messages printed with log_debug.
[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 <http://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
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 } oidtable[] = {
47
48   { "Curve25519",      "1.3.6.1.4.1.3029.1.5.1", 255, "cv25519" },
49   { "Ed25519",         "1.3.6.1.4.1.11591.15.1", 255, "ed25519" },
50
51   { "NIST P-256",      "1.2.840.10045.3.1.7",    256, "nistp256" },
52   { "NIST P-384",      "1.3.132.0.34",           384, "nistp384" },
53   { "NIST P-521",      "1.3.132.0.35",           521, "nistp521" },
54
55   { "brainpoolP256r1", "1.3.36.3.3.2.8.1.1.7",   256 },
56   { "brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11",  384 },
57   { "brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13",  512 },
58
59   { "secp256k1",       "1.3.132.0.10",           256 },
60
61   { NULL, NULL, 0}
62 };
63
64
65 /* The OID for Curve Ed25519 in OpenPGP format.  */
66 static const char oid_ed25519[] =
67   { 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xda, 0x47, 0x0f, 0x01 };
68
69 /* The OID for Curve25519 in OpenPGP format.  */
70 static const char oid_crv25519[] =
71   { 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01 };
72
73
74 /* Helper for openpgp_oid_from_str.  */
75 static size_t
76 make_flagged_int (unsigned long value, char *buf, size_t buflen)
77 {
78   int more = 0;
79   int shift;
80
81   /* fixme: figure out the number of bits in an ulong and start with
82      that value as shift (after making it a multiple of 7) a more
83      straigtforward implementation is to do it in reverse order using
84      a temporary buffer - saves a lot of compares */
85   for (more=0, shift=28; shift > 0; shift -= 7)
86     {
87       if (more || value >= (1<<shift))
88         {
89           buf[buflen++] = 0x80 | (value >> shift);
90           value -= (value >> shift) << shift;
91           more = 1;
92         }
93     }
94   buf[buflen++] = value;
95   return buflen;
96 }
97
98
99 /* Convert the OID given in dotted decimal form in STRING to an DER
100  * encoding and store it as an opaque value at R_MPI.  The format of
101  * the DER encoded is not a regular ASN.1 object but the modified
102  * format as used by OpenPGP for the ECC curve description.  On error
103  * the function returns and error code an NULL is stored at R_BUG.
104  * Note that scanning STRING stops at the first white space
105  * character.  */
106 gpg_error_t
107 openpgp_oid_from_str (const char *string, gcry_mpi_t *r_mpi)
108 {
109   unsigned char *buf;
110   size_t buflen;
111   unsigned long val1, val;
112   const char *endp;
113   int arcno;
114
115   *r_mpi = NULL;
116
117   if (!string || !*string)
118     return gpg_error (GPG_ERR_INV_VALUE);
119
120   /* We can safely assume that the encoded OID is shorter than the string. */
121   buf = xtrymalloc (1 + strlen (string) + 2);
122   if (!buf)
123     return gpg_error_from_syserror ();
124   /* Save the first byte for the length.  */
125   buflen = 1;
126
127   val1 = 0; /* Avoid compiler warning.  */
128   arcno = 0;
129   do {
130     arcno++;
131     val = strtoul (string, (char**)&endp, 10);
132     if (!digitp (string) || !(*endp == '.' || !*endp))
133       {
134         xfree (buf);
135         return gpg_error (GPG_ERR_INV_OID_STRING);
136       }
137     if (*endp == '.')
138       string = endp+1;
139
140     if (arcno == 1)
141       {
142         if (val > 2)
143           break; /* Not allowed, error catched below.  */
144         val1 = val;
145       }
146     else if (arcno == 2)
147       { /* Need to combine the first two arcs in one octet.  */
148         if (val1 < 2)
149           {
150             if (val > 39)
151               {
152                 xfree (buf);
153                 return gpg_error (GPG_ERR_INV_OID_STRING);
154               }
155             buf[buflen++] = val1*40 + val;
156           }
157         else
158           {
159             val += 80;
160             buflen = make_flagged_int (val, buf, buflen);
161           }
162       }
163     else
164       {
165         buflen = make_flagged_int (val, buf, buflen);
166       }
167   } while (*endp == '.');
168
169   if (arcno == 1 || buflen < 2 || buflen > 254 )
170     { /* It is not possible to encode only the first arc.  */
171       xfree (buf);
172       return gpg_error (GPG_ERR_INV_OID_STRING);
173     }
174
175   *buf = buflen - 1;
176   *r_mpi = gcry_mpi_set_opaque (NULL, buf, buflen * 8);
177   if (!*r_mpi)
178     {
179       xfree (buf);
180       return gpg_error_from_syserror ();
181     }
182   return 0;
183 }
184
185
186 /* Return a malloced string represenation of the OID in the opaque MPI
187    A.  In case of an error NULL is returned and ERRNO is set.  */
188 char *
189 openpgp_oid_to_str (gcry_mpi_t a)
190 {
191   const unsigned char *buf;
192   size_t length;
193   unsigned int lengthi;
194   char *string, *p;
195   int n = 0;
196   unsigned long val, valmask;
197
198   valmask = (unsigned long)0xfe << (8 * (sizeof (valmask) - 1));
199
200   if (!a
201       || !gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE)
202       || !(buf = gcry_mpi_get_opaque (a, &lengthi)))
203     {
204       gpg_err_set_errno (EINVAL);
205       return NULL;
206     }
207
208   buf = gcry_mpi_get_opaque (a, &lengthi);
209   length = (lengthi+7)/8;
210
211   /* The first bytes gives the length; check consistency.  */
212   if (!length || buf[0] != length -1)
213     {
214       gpg_err_set_errno (EINVAL);
215       return NULL;
216     }
217   /* Skip length byte.  */
218   length--;
219   buf++;
220
221   /* To calculate the length of the string we can safely assume an
222      upper limit of 3 decimal characters per byte.  Two extra bytes
223      account for the special first octect */
224   string = p = xtrymalloc (length*(1+3)+2+1);
225   if (!string)
226     return NULL;
227   if (!length)
228     {
229       *p = 0;
230       return string;
231     }
232
233   if (buf[0] < 40)
234     p += sprintf (p, "0.%d", buf[n]);
235   else if (buf[0] < 80)
236     p += sprintf (p, "1.%d", buf[n]-40);
237   else {
238     val = buf[n] & 0x7f;
239     while ( (buf[n]&0x80) && ++n < length )
240       {
241         if ( (val & valmask) )
242           goto badoid;  /* Overflow.  */
243         val <<= 7;
244         val |= buf[n] & 0x7f;
245       }
246     if (val < 80)
247       goto badoid;
248     val -= 80;
249     sprintf (p, "2.%lu", val);
250     p += strlen (p);
251   }
252   for (n++; n < length; n++)
253     {
254       val = buf[n] & 0x7f;
255       while ( (buf[n]&0x80) && ++n < length )
256         {
257           if ( (val & valmask) )
258             goto badoid;  /* Overflow.  */
259           val <<= 7;
260           val |= buf[n] & 0x7f;
261         }
262       sprintf (p, ".%lu", val);
263       p += strlen (p);
264     }
265
266   *p = 0;
267   return string;
268
269  badoid:
270   /* Return a special OID (gnu.gnupg.badoid) to indicate the error
271      case.  The OID is broken and thus we return one which can't do
272      any harm.  Formally this does not need to be a bad OID but an OID
273      with an arc that can't be represented in a 32 bit word is more
274      than likely corrupt.  */
275   xfree (string);
276   return xtrystrdup ("1.3.6.1.4.1.11591.2.12242973");
277 }
278
279
280
281 /* Return true if A represents the OID for Ed25519.  */
282 int
283 openpgp_oid_is_ed25519 (gcry_mpi_t a)
284 {
285   const unsigned char *buf;
286   unsigned int nbits;
287   size_t n;
288
289   if (!a || !gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
290     return 0;
291
292   buf = gcry_mpi_get_opaque (a, &nbits);
293   n = (nbits+7)/8;
294   return (n == DIM (oid_ed25519)
295           && !memcmp (buf, oid_ed25519, DIM (oid_ed25519)));
296 }
297
298
299 int
300 openpgp_oid_is_crv25519 (gcry_mpi_t a)
301 {
302   const unsigned char *buf;
303   unsigned int nbits;
304   size_t n;
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   n = (nbits+7)/8;
311   return (n == DIM (oid_crv25519)
312           && !memcmp (buf, oid_crv25519, DIM (oid_crv25519)));
313 }
314
315
316 /* Map the Libgcrypt ECC curve NAME to an OID.  If R_NBITS is not NULL
317    store the bit size of the curve there.  Returns NULL for unknown
318    curve names.  */
319 const char *
320 openpgp_curve_to_oid (const char *name, unsigned int *r_nbits)
321 {
322   int i;
323   unsigned int nbits = 0;
324   const char *oidstr = NULL;
325
326   if (name)
327     {
328       for (i=0; oidtable[i].name; i++)
329         if (!strcmp (oidtable[i].name, name)
330             || (oidtable[i].alias && !strcmp (oidtable[i].alias, name)))
331           {
332             oidstr = oidtable[i].oidstr;
333             nbits  = oidtable[i].nbits;
334             break;
335           }
336       if (!oidtable[i].name)
337         {
338           /* If not found assume the input is already an OID and check
339              whether we support it.  */
340           for (i=0; oidtable[i].name; i++)
341             if (!strcmp (name, oidtable[i].oidstr))
342               {
343                 oidstr = oidtable[i].oidstr;
344                 nbits  = oidtable[i].nbits;
345                 break;
346               }
347         }
348     }
349
350   if (r_nbits)
351     *r_nbits = nbits;
352   return oidstr;
353 }
354
355
356 /* Map an OpenPGP OID to the Libgcrypt curve NAME.  Returns NULL for
357    unknown curve names.  Unless CANON is set we prefer an alias name
358    here which is more suitable for printing.  */
359 const char *
360 openpgp_oid_to_curve (const char *oidstr, int canon)
361 {
362   int i;
363
364   if (!oidstr)
365     return NULL;
366
367   for (i=0; oidtable[i].name; i++)
368     if (!strcmp (oidtable[i].oidstr, oidstr))
369       return !canon && oidtable[i].alias? oidtable[i].alias : oidtable[i].name;
370
371   return NULL;
372 }
373
374
375 /* Return true if the curve with NAME is supported.  */
376 static int
377 curve_supported_p (const char *name)
378 {
379   int result = 0;
380   gcry_sexp_t keyparms;
381
382   if (!gcry_sexp_build (&keyparms, NULL, "(public-key(ecc(curve %s)))", name))
383     {
384       result = !!gcry_pk_get_curve (keyparms, 0, NULL);
385       gcry_sexp_release (keyparms);
386     }
387   return result;
388 }
389
390
391 /* Enumerate available and supported OpenPGP curves.  The caller needs
392    to set the integer variable at ITERP to zero and keep on calling
393    this function until NULL is returned.  */
394 const char *
395 openpgp_enum_curves (int *iterp)
396 {
397   int idx = *iterp;
398
399   while (idx >= 0 && idx < DIM (oidtable) && oidtable[idx].name)
400     {
401       if (curve_supported_p (oidtable[idx].name))
402         {
403           *iterp = idx + 1;
404           return oidtable[idx].alias? oidtable[idx].alias : oidtable[idx].name;
405         }
406       idx++;
407     }
408   *iterp = idx;
409   return NULL;
410 }