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