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