Imported Upstream version 1.3.4
[platform/upstream/libksba.git] / src / keyinfo.c
1 /* keyinfo.c - Parse and build a keyInfo structure
2  * Copyright (C) 2001, 2002, 2007, 2008, 2012 g10 Code GmbH
3  *
4  * This file is part of KSBA.
5  *
6  * KSBA is free software; you can redistribute it and/or modify
7  * it under the terms of either
8  *
9  *   - the GNU Lesser General Public License as published by the Free
10  *     Software Foundation; either version 3 of the License, or (at
11  *     your option) any later version.
12  *
13  * or
14  *
15  *   - the GNU General Public License as published by the Free
16  *     Software Foundation; either version 2 of the License, or (at
17  *     your option) any later version.
18  *
19  * or both in parallel, as here.
20  *
21  * KSBA is distributed in the hope that it will be useful, but WITHOUT
22  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
24  * License for more details.
25  *
26  * You should have received a copies of the GNU General Public License
27  * and the GNU Lesser General Public License along with this program;
28  * if not, see <http://www.gnu.org/licenses/>.
29  */
30
31 /* Instead of using the ASN parser - which is easily possible - we use
32    a simple handcoded one to speed up the operation and to make it
33    more robust. */
34
35 #include <config.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <assert.h>
40
41 #include "util.h"
42 #include "asn1-func.h"
43 #include "keyinfo.h"
44 #include "shared.h"
45 #include "convert.h"
46 #include "ber-help.h"
47
48
49 /* Constants used for the public key algorithms.  */
50 typedef enum
51   {
52     PKALGO_RSA,
53     PKALGO_DSA,
54     PKALGO_ECC
55   }
56 pkalgo_t;
57
58
59 struct algo_table_s {
60   const char *oidstring;
61   const unsigned char *oid;  /* NULL indicattes end of table */
62   int                  oidlen;
63   int supported;
64   pkalgo_t pkalgo;
65   const char *algo_string;
66   const char *elem_string; /* parameter name or '-' */
67   const char *ctrl_string; /* expected tag values (value > 127 are raw data)*/
68   const char *parmelem_string; /* parameter name or '-'. */
69   const char *parmctrl_string; /* expected tag values.  */
70   const char *digest_string; /* The digest algo if included in the OID. */
71 };
72
73
74
75 static const struct algo_table_s pk_algo_table[] = {
76
77   { /* iso.member-body.us.rsadsi.pkcs.pkcs-1.1 */
78     "1.2.840.113549.1.1.1", /* rsaEncryption (RSAES-PKCA1-v1.5) */
79     "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01", 9,
80     1, PKALGO_RSA, "rsa", "-ne", "\x30\x02\x02" },
81
82   { /* iso.member-body.us.rsadsi.pkcs.pkcs-1.7 */
83     "1.2.840.113549.1.1.7", /* RSAES-OAEP */
84     "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x07", 9,
85     0, PKALGO_RSA, "rsa", "-ne", "\x30\x02\x02"}, /* (patent problems) */
86
87   { /* */
88     "2.5.8.1.1", /* rsa (ambiguous due to missing padding rules)*/
89     "\x55\x08\x01\x01", 4,
90     1, PKALGO_RSA, "ambiguous-rsa", "-ne", "\x30\x02\x02" },
91
92   { /* iso.member-body.us.x9-57.x9cm.1 */
93     "1.2.840.10040.4.1", /*  dsa */
94     "\x2a\x86\x48\xce\x38\x04\x01", 7,
95     1, PKALGO_DSA, "dsa", "y", "\x02", "-pqg", "\x30\x02\x02\x02" },
96
97   { /* iso.member-body.us.ansi-x9-62.2.1 */
98     "1.2.840.10045.2.1", /*  ecPublicKey */
99     "\x2a\x86\x48\xce\x3d\x02\x01", 7,
100     1, PKALGO_ECC, "ecc", "q", "\x80" },
101
102   {NULL}
103 };
104
105
106 static const struct algo_table_s sig_algo_table[] = {
107   {  /* iso.member-body.us.rsadsi.pkcs.pkcs-1.5 */
108     "1.2.840.113549.1.1.5", /* sha1WithRSAEncryption */
109     "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05", 9,
110     1, PKALGO_RSA, "rsa", "s", "\x82", NULL, NULL, "sha1" },
111   { /* iso.member-body.us.rsadsi.pkcs.pkcs-1.4 */
112     "1.2.840.113549.1.1.4", /* md5WithRSAEncryption */
113     "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x04", 9,
114     1, PKALGO_RSA, "rsa", "s", "\x82", NULL, NULL, "md5" },
115   { /* iso.member-body.us.rsadsi.pkcs.pkcs-1.2 */
116     "1.2.840.113549.1.1.2", /* md2WithRSAEncryption */
117     "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x02", 9,
118     0, PKALGO_RSA, "rsa", "s", "\x82", NULL, NULL, "md2" },
119   { /* iso.member-body.us.x9-57.x9cm.1 */
120     "1.2.840.10040.4.3", /* dsa */
121     "\x2a\x86\x48\xce\x38\x04\x01", 7,
122     1, PKALGO_DSA, "dsa", "-rs", "\x30\x02\x02" },
123   { /* iso.member-body.us.x9-57.x9cm.3 */
124     "1.2.840.10040.4.3", /*  dsaWithSha1 */
125     "\x2a\x86\x48\xce\x38\x04\x03", 7,
126     1, PKALGO_DSA, "dsa", "-rs", "\x30\x02\x02", NULL, NULL, "sha1" },
127   { /* Teletrust signature algorithm.  */
128     "1.3.36.8.5.1.2.2", /* dsaWithRIPEMD160 */
129     "\x2b\x24\x08\x05\x01\x02\x02", 7,
130     1, PKALGO_DSA, "dsa", "-rs", "\x30\x02\x02", NULL, NULL, "rmd160" },
131   { /* NIST Algorithm */
132     "2.16.840.1.101.3.4.3.1", /* dsaWithSha224 */
133     "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x03\x01", 11,
134     1, PKALGO_DSA, "dsa", "-rs", "\x30\x02\x02", NULL, NULL, "sha224" },
135   { /* NIST Algorithm (the draft also used .1 but we better use .2) */
136     "2.16.840.1.101.3.4.3.2", /* dsaWithSha256 */
137     "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x03\x01", 11,
138     1, PKALGO_DSA, "dsa", "-rs", "\x30\x02\x02", NULL, NULL, "sha256" },
139
140   { /* iso.member-body.us.ansi-x9-62.signatures.ecdsa-with-sha1 */
141     "1.2.840.10045.4.1", /*  ecdsa */
142     "\x2a\x86\x48\xce\x3d\x04\x01", 7,
143     1, PKALGO_ECC, "ecdsa", "-rs", "\x30\x02\x02", NULL, NULL, "sha1" },
144
145   { /* iso.member-body.us.ansi-x9-62.signatures.ecdsa-with-specified */
146     "1.2.840.10045.4.3",
147     "\x2a\x86\x48\xce\x3d\x04\x03", 7,
148     1, PKALGO_ECC, "ecdsa", "-rs", "\x30\x02\x02", NULL, NULL, NULL },
149   /* The digest algorithm is given by the parameter.  */
150
151
152   { /* iso.member-body.us.ansi-x9-62.signatures.ecdsa-with-sha224 */
153     "1.2.840.10045.4.3.1",
154     "\x2a\x86\x48\xce\x3d\x04\x03\x01", 8,
155     1, PKALGO_ECC, "ecdsa", "-rs", "\x30\x02\x02", NULL, NULL, "sha224" },
156
157   { /* iso.member-body.us.ansi-x9-62.signatures.ecdsa-with-sha256 */
158     "1.2.840.10045.4.3.2",
159     "\x2a\x86\x48\xce\x3d\x04\x03\x02", 8,
160     1, PKALGO_ECC, "ecdsa", "-rs", "\x30\x02\x02", NULL, NULL, "sha256" },
161
162   { /* iso.member-body.us.ansi-x9-62.signatures.ecdsa-with-sha384 */
163     "1.2.840.10045.4.3.3",
164     "\x2a\x86\x48\xce\x3d\x04\x03\x03", 8,
165     1, PKALGO_ECC, "ecdsa", "-rs", "\x30\x02\x02", NULL, NULL, "sha384" },
166
167   { /* iso.member-body.us.ansi-x9-62.signatures.ecdsa-with-sha512 */
168     "1.2.840.10045.4.3.4",
169     "\x2a\x86\x48\xce\x3d\x04\x03\x04", 8,
170     1, PKALGO_ECC, "ecdsa", "-rs", "\x30\x02\x02", NULL, NULL, "sha512" },
171
172   { /* iso.member-body.us.rsadsi.pkcs.pkcs-1.1 */
173     "1.2.840.113549.1.1.1", /* rsaEncryption used without hash algo*/
174     "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01", 9,
175     1, PKALGO_RSA, "rsa", "s", "\x82" },
176   { /* from NIST's OIW - actually belongs in a pure hash table */
177     "1.3.14.3.2.26",  /* sha1 */
178     "\x2B\x0E\x03\x02\x1A", 5,
179     0, PKALGO_RSA, "sha-1", "", "", NULL, NULL, "sha1" },
180
181   { /* As used by telesec cards */
182     "1.3.36.3.3.1.2",  /* rsaSignatureWithripemd160 */
183     "\x2b\x24\x03\x03\x01\x02", 6,
184     1, PKALGO_RSA, "rsa", "s", "\x82", NULL, NULL, "rmd160" },
185
186   { /* from NIST's OIW - used by TU Darmstadt */
187     "1.3.14.3.2.29",  /* sha-1WithRSAEncryption */
188     "\x2B\x0E\x03\x02\x1D", 5,
189     1, PKALGO_RSA, "rsa", "s", "\x82", NULL, NULL, "sha1" },
190
191   { /* from PKCS#1  */
192     "1.2.840.113549.1.1.11", /* sha256WithRSAEncryption */
193     "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b", 9,
194     1, PKALGO_RSA, "rsa", "s", "\x82", NULL, NULL, "sha256" },
195
196   { /* from PKCS#1  */
197     "1.2.840.113549.1.1.12", /* sha384WithRSAEncryption */
198     "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0c", 9,
199     1, PKALGO_RSA, "rsa", "s", "\x82", NULL, NULL, "sha384" },
200
201   { /* from PKCS#1  */
202     "1.2.840.113549.1.1.13", /* sha512WithRSAEncryption */
203     "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0d", 9,
204     1, PKALGO_RSA, "rsa", "s", "\x82", NULL, NULL, "sha512" },
205
206   { /* TeleTrust signature scheme with RSA signature and DSI according
207        to ISO/IEC 9796-2 with random number and RIPEMD-160.  I am not
208        sure for what this is good; thus disabled. */
209     "1.3.36.3.4.3.2.2",     /* sigS_ISO9796-2rndWithrsa_ripemd160 */
210     "\x2B\x24\x03\x04\x03\x02\x02", 7,
211     0, PKALGO_RSA, "rsa", "s", "\x82", NULL, NULL, "rmd160" },
212
213   {NULL}
214 };
215
216 static const struct algo_table_s enc_algo_table[] = {
217   { /* iso.member-body.us.rsadsi.pkcs.pkcs-1.1 */
218     "1.2.840.113549.1.1.1", /* rsaEncryption (RSAES-PKCA1-v1.5) */
219     "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01", 9,
220     1, PKALGO_RSA, "rsa", "a", "\x82" },
221   {NULL}
222 };
223
224
225 /* This tables maps names of ECC curves names to OIDs.  A similar
226    table is used by lib gcrypt.  */
227 static const struct
228 {
229   const char *oid;
230   const char *name;
231 } curve_names[] =
232   {
233     { "1.3.6.1.4.1.3029.1.5.1", "Curve25519" },
234     { "1.3.6.1.4.1.11591.15.1", "Ed25519"    },
235
236     { "1.2.840.10045.3.1.1", "NIST P-192" },
237     { "1.2.840.10045.3.1.1", "nistp192"   },
238     { "1.2.840.10045.3.1.1", "prime192v1" },
239     { "1.2.840.10045.3.1.1", "secp192r1"  },
240
241     { "1.3.132.0.33",        "NIST P-224" },
242     { "1.3.132.0.33",        "nistp224"   },
243     { "1.3.132.0.33",        "secp224r1"  },
244
245     { "1.2.840.10045.3.1.7", "NIST P-256" },
246     { "1.2.840.10045.3.1.7", "nistp256"   },
247     { "1.2.840.10045.3.1.7", "prime256v1" },
248     { "1.2.840.10045.3.1.7", "secp256r1"  },
249
250     { "1.3.132.0.34",        "NIST P-384" },
251     { "1.3.132.0.34",        "nistp384"   },
252     { "1.3.132.0.34",        "secp384r1"  },
253
254     { "1.3.132.0.35",        "NIST P-521" },
255     { "1.3.132.0.35",        "nistp521"   },
256     { "1.3.132.0.35",        "secp521r1"  },
257
258     { "1.3.36.3.3.2.8.1.1.1" , "brainpoolP160r1" },
259     { "1.3.36.3.3.2.8.1.1.3" , "brainpoolP192r1" },
260     { "1.3.36.3.3.2.8.1.1.5" , "brainpoolP224r1" },
261     { "1.3.36.3.3.2.8.1.1.7" , "brainpoolP256r1" },
262     { "1.3.36.3.3.2.8.1.1.9" , "brainpoolP320r1" },
263     { "1.3.36.3.3.2.8.1.1.11", "brainpoolP384r1" },
264     { "1.3.36.3.3.2.8.1.1.13", "brainpoolP512r1" },
265
266
267     { "1.2.643.2.2.35.1",    "GOST2001-CryptoPro-A" },
268     { "1.2.643.2.2.35.2",    "GOST2001-CryptoPro-B" },
269     { "1.2.643.2.2.35.3",    "GOST2001-CryptoPro-C" },
270     { "1.2.643.7.1.2.1.2.1", "GOST2012-tc26-A"      },
271     { "1.2.643.7.1.2.1.2.2", "GOST2012-tc26-B"      },
272
273     { "1.3.132.0.10",        "secp256k1" },
274
275     { NULL, NULL}
276   };
277
278
279
280
281
282 struct stringbuf {
283   size_t len;
284   size_t size;
285   char *buf;
286   int out_of_core;
287 };
288
289
290 #define TLV_LENGTH(prefix) do {         \
291   if (!prefix ## len)                    \
292     return gpg_error (GPG_ERR_INV_KEYINFO);  \
293   c = *(prefix)++; prefix ## len--;           \
294   if (c == 0x80)                  \
295     return gpg_error (GPG_ERR_NOT_DER_ENCODED);  \
296   if (c == 0xff)                  \
297     return gpg_error (GPG_ERR_BAD_BER);        \
298                                   \
299   if ( !(c & 0x80) )              \
300     len = c;                      \
301   else                            \
302     {                             \
303       int count = c & 0x7f;       \
304                                   \
305       for (len=0; count; count--) \
306         {                         \
307           len <<= 8;              \
308           if (!prefix ## len)            \
309             return gpg_error (GPG_ERR_BAD_BER);\
310           c = *(prefix)++; prefix ## len--;   \
311           len |= c & 0xff;        \
312         }                         \
313     }                             \
314   if (len > prefix ## len)               \
315     return gpg_error (GPG_ERR_INV_KEYINFO);  \
316 } while (0)
317
318
319 /* Given a string BUF of length BUFLEN with either the name of an ECC
320    curve or its OID in dotted form return the DER encoding of the OID.
321    The caller must free the result.  On error NULL is returned.  */
322 static unsigned char *
323 get_ecc_curve_oid (const unsigned char *buf, size_t buflen, size_t *r_oidlen)
324 {
325   unsigned char *der_oid;
326
327   /* Skip an optional "oid." prefix. */
328   if (buflen > 4 && buf[3] == '.' && digitp (buf+4)
329       && ((buf[0] == 'o' && buf[1] == 'i' && buf[2] == 'd')
330           ||(buf[0] == 'O' && buf[1] == 'I' && buf[2] == 'D')))
331     {
332       buf += 4;
333       buflen -= 4;
334     }
335
336   /* If it does not look like an OID - map it through the table.  */
337   if (buflen && !digitp (buf))
338     {
339       int i;
340
341       for (i=0; curve_names[i].oid; i++)
342         if (buflen == strlen (curve_names[i].name)
343             && !memcmp (buf, curve_names[i].name, buflen))
344           break;
345       if (!curve_names[i].oid)
346         return NULL; /* Not found.  */
347       buf = curve_names[i].oid;
348       buflen = strlen (curve_names[i].oid);
349     }
350
351   if (_ksba_oid_from_buf (buf, buflen, &der_oid, r_oidlen))
352     return NULL;
353   return der_oid;
354 }
355
356
357
358 /* Return the OFF and the LEN of algorithm within DER.  Do some checks
359    and return the number of bytes read in r_nread, adding this to der
360    does point into the BIT STRING.
361
362    mode 0: just get the algorithm identifier. FIXME: should be able to
363            handle BER Encoding.
364    mode 1: as described.
365  */
366 static gpg_error_t
367 get_algorithm (int mode, const unsigned char *der, size_t derlen,
368                size_t *r_nread, size_t *r_pos, size_t *r_len, int *r_bitstr,
369                size_t *r_parm_pos, size_t *r_parm_len, int *r_parm_type)
370 {
371   int c;
372   const unsigned char *start = der;
373   const unsigned char *startseq;
374   unsigned long seqlen, len;
375
376   *r_bitstr = 0;
377   if (r_parm_pos)
378     *r_parm_pos = 0;
379   if (r_parm_len)
380     *r_parm_len = 0;
381   if (r_parm_type)
382     *r_parm_type = 0;
383   /* get the inner sequence */
384   if (!derlen)
385     return gpg_error (GPG_ERR_INV_KEYINFO);
386   c = *der++; derlen--;
387   if ( c != 0x30 )
388     return gpg_error (GPG_ERR_UNEXPECTED_TAG); /* not a SEQUENCE */
389   TLV_LENGTH(der);
390   seqlen = len;
391   startseq = der;
392
393   /* get the object identifier */
394   if (!derlen)
395     return gpg_error (GPG_ERR_INV_KEYINFO);
396   c = *der++; derlen--;
397   if ( c != 0x06 )
398     return gpg_error (GPG_ERR_UNEXPECTED_TAG); /* not an OBJECT IDENTIFIER */
399   TLV_LENGTH(der);
400
401   /* der does now point to an oid of length LEN */
402   *r_pos = der - start;
403   *r_len = len;
404 /*    { */
405 /*      char *p = ksba_oid_to_str (der, len); */
406 /*      printf ("algorithm: %s\n", p); */
407 /*      xfree (p); */
408 /*    } */
409   der += len;
410   derlen -= len;
411   seqlen -= der - startseq;;
412
413   /* Parse the parameter.  */
414   if (seqlen)
415     {
416       const unsigned char *startparm = der;
417
418       if (!derlen)
419         return gpg_error (GPG_ERR_INV_KEYINFO);
420       c = *der++; derlen--;
421       if ( c == 0x05 )
422         {
423           /*printf ("parameter: NULL \n"); the usual case */
424           if (!derlen)
425             return gpg_error (GPG_ERR_INV_KEYINFO);
426           c = *der++; derlen--;
427           if (c)
428             return gpg_error (GPG_ERR_BAD_BER);  /* NULL must have a
429                                                     length of 0 */
430           seqlen -= 2;
431         }
432       else if (r_parm_pos && r_parm_len && c == 0x04)
433         {
434           /*  This is an octet string parameter and we need it.  */
435           if (r_parm_type)
436             *r_parm_type = TYPE_OCTET_STRING;
437           TLV_LENGTH(der);
438           *r_parm_pos = der - start;
439           *r_parm_len = len;
440           seqlen -= der - startparm;
441           der += len;
442           derlen -= len;
443           seqlen -= len;
444         }
445       else if (r_parm_pos && r_parm_len && c == 0x06)
446         {
447           /*  This is an object identifier.  */
448           if (r_parm_type)
449             *r_parm_type = TYPE_OBJECT_ID;
450           TLV_LENGTH(der);
451           *r_parm_pos = der - start;
452           *r_parm_len = len;
453           seqlen -= der - startparm;
454           der += len;
455           derlen -= len;
456           seqlen -= len;
457         }
458       else if (r_parm_pos && r_parm_len && c == 0x30)
459         {
460           /*  This is a sequence. */
461           if (r_parm_type)
462             *r_parm_type = TYPE_SEQUENCE;
463           TLV_LENGTH(der);
464           *r_parm_pos = startparm - start;
465           *r_parm_len = len + (der - startparm);
466           seqlen -= der - startparm;
467           der += len;
468           derlen -= len;
469           seqlen -= len;
470         }
471       else
472         {
473 /*            printf ("parameter: with tag %02x - ignored\n", c); */
474           TLV_LENGTH(der);
475           seqlen -= der - startparm;
476           /* skip the value */
477           der += len;
478           derlen -= len;
479           seqlen -= len;
480         }
481     }
482
483   if (seqlen)
484     return gpg_error (GPG_ERR_INV_KEYINFO);
485
486   if (mode)
487     {
488       /* move forward to the BIT_STR */
489       if (!derlen)
490         return gpg_error (GPG_ERR_INV_KEYINFO);
491       c = *der++; derlen--;
492
493       if (c == 0x03)
494         *r_bitstr = 1; /* BIT STRING */
495       else if (c == 0x04)
496         ; /* OCTECT STRING */
497       else
498         return gpg_error (GPG_ERR_UNEXPECTED_TAG); /* not a BIT STRING */
499       TLV_LENGTH(der);
500     }
501
502   *r_nread = der - start;
503   return 0;
504 }
505
506
507 gpg_error_t
508 _ksba_parse_algorithm_identifier (const unsigned char *der, size_t derlen,
509                                   size_t *r_nread, char **r_oid)
510 {
511   return _ksba_parse_algorithm_identifier2 (der, derlen,
512                                             r_nread, r_oid, NULL, NULL);
513 }
514
515 gpg_error_t
516 _ksba_parse_algorithm_identifier2 (const unsigned char *der, size_t derlen,
517                                    size_t *r_nread, char **r_oid,
518                                    char **r_parm, size_t *r_parmlen)
519 {
520   gpg_error_t err;
521   int is_bitstr;
522   size_t nread, off, len, off2, len2;
523   int parm_type;
524
525   /* fixme: get_algorithm might return the error invalid keyinfo -
526      this should be invalid algorithm identifier */
527   *r_oid = NULL;
528   *r_nread = 0;
529   off2 = len2 = 0;
530   err = get_algorithm (0, der, derlen, &nread, &off, &len, &is_bitstr,
531                        &off2, &len2, &parm_type);
532   if (err)
533     return err;
534   *r_nread = nread;
535   *r_oid = ksba_oid_to_str (der+off, len);
536   if (!*r_oid)
537     return gpg_error (GPG_ERR_ENOMEM);
538
539   /* Special hack for ecdsaWithSpecified.  We replace the returned OID
540      by the one in the parameter. */
541   if (off2 && len2 && parm_type == TYPE_SEQUENCE
542       && !strcmp (*r_oid, "1.2.840.10045.4.3"))
543     {
544       xfree (*r_oid);
545       *r_oid = NULL;
546       err = get_algorithm (0, der+off2, len2, &nread, &off, &len, &is_bitstr,
547                            NULL, NULL, NULL);
548       if (err)
549         {
550           *r_nread = 0;
551           return err;
552         }
553       *r_oid = ksba_oid_to_str (der+off2+off, len);
554       if (!*r_oid)
555         {
556           *r_nread = 0;
557           return gpg_error (GPG_ERR_ENOMEM);
558         }
559
560       off2 = len2 = 0; /* So that R_PARM is set to NULL.  */
561     }
562
563   if (r_parm && r_parmlen)
564     {
565       if (off2 && len2)
566         {
567           *r_parm = xtrymalloc (len2);
568           if (!*r_parm)
569             {
570               xfree (*r_oid);
571               *r_oid = NULL;
572               return gpg_error (GPG_ERR_ENOMEM);
573             }
574           memcpy (*r_parm, der+off2, len2);
575           *r_parmlen = len2;
576         }
577       else
578         {
579           *r_parm = NULL;
580           *r_parmlen = 0;
581         }
582     }
583   return 0;
584 }
585
586
587
588 static void
589 init_stringbuf (struct stringbuf *sb, int initiallen)
590 {
591   sb->len = 0;
592   sb->size = initiallen;
593   sb->out_of_core = 0;
594   /* allocate one more, so that get_stringbuf can append a nul */
595   sb->buf = xtrymalloc (initiallen+1);
596   if (!sb->buf)
597       sb->out_of_core = 1;
598 }
599
600 static void
601 put_stringbuf_mem (struct stringbuf *sb, const char *text, size_t n)
602 {
603   if (sb->out_of_core)
604     return;
605
606   if (sb->len + n >= sb->size)
607     {
608       char *p;
609
610       sb->size += n + 100;
611       p = xtryrealloc (sb->buf, sb->size);
612       if ( !p)
613         {
614           sb->out_of_core = 1;
615           return;
616         }
617       sb->buf = p;
618     }
619   memcpy (sb->buf+sb->len, text, n);
620   sb->len += n;
621 }
622
623 static void
624 put_stringbuf (struct stringbuf *sb, const char *text)
625 {
626   put_stringbuf_mem (sb, text,strlen (text));
627 }
628
629 static void
630 put_stringbuf_mem_sexp (struct stringbuf *sb, const char *text, size_t length)
631 {
632   char buf[20];
633   sprintf (buf,"%u:", (unsigned int)length);
634   put_stringbuf (sb, buf);
635   put_stringbuf_mem (sb, text, length);
636 }
637
638 static void
639 put_stringbuf_sexp (struct stringbuf *sb, const char *text)
640 {
641   put_stringbuf_mem_sexp (sb, text, strlen (text));
642 }
643
644
645 static char *
646 get_stringbuf (struct stringbuf *sb)
647 {
648   char *p;
649
650   if (sb->out_of_core)
651     {
652       xfree (sb->buf); sb->buf = NULL;
653       return NULL;
654     }
655
656   sb->buf[sb->len] = 0;
657   p = sb->buf;
658   sb->buf = NULL;
659   sb->out_of_core = 1; /* make sure the caller does an init before reuse */
660   return p;
661 }
662
663
664 /* Assume that der is a buffer of length DERLEN with a DER encoded
665  Asn.1 structure like this:
666
667   keyInfo ::= SEQUENCE {
668                  SEQUENCE {
669                     algorithm    OBJECT IDENTIFIER,
670                     parameters   ANY DEFINED BY algorithm OPTIONAL }
671                  publicKey  BIT STRING }
672
673   The function parses this structure and create a SEXP suitable to be
674   used as a public key in Libgcrypt.  The S-Exp will be returned in a
675   string which the caller must free.
676
677   We don't pass an ASN.1 node here but a plain memory block.  */
678
679 gpg_error_t
680 _ksba_keyinfo_to_sexp (const unsigned char *der, size_t derlen,
681                        ksba_sexp_t *r_string)
682 {
683   gpg_error_t err;
684   int c;
685   size_t nread, off, len, parm_off, parm_len;
686   int parm_type;
687   char *parm_oid = NULL;
688   int algoidx;
689   int is_bitstr;
690   const unsigned char *parmder = NULL;
691   size_t parmderlen = 0;
692   const unsigned char *ctrl;
693   const char *elem;
694   struct stringbuf sb;
695
696   *r_string = NULL;
697
698   /* check the outer sequence */
699   if (!derlen)
700     return gpg_error (GPG_ERR_INV_KEYINFO);
701   c = *der++; derlen--;
702   if ( c != 0x30 )
703     return gpg_error (GPG_ERR_UNEXPECTED_TAG); /* not a SEQUENCE */
704   TLV_LENGTH(der);
705   /* and now the inner part */
706   err = get_algorithm (1, der, derlen, &nread, &off, &len, &is_bitstr,
707                        &parm_off, &parm_len, &parm_type);
708   if (err)
709     return err;
710
711   /* look into our table of supported algorithms */
712   for (algoidx=0; pk_algo_table[algoidx].oid; algoidx++)
713     {
714       if ( len == pk_algo_table[algoidx].oidlen
715            && !memcmp (der+off, pk_algo_table[algoidx].oid, len))
716         break;
717     }
718   if (!pk_algo_table[algoidx].oid)
719     return gpg_error (GPG_ERR_UNKNOWN_ALGORITHM);
720   if (!pk_algo_table[algoidx].supported)
721     return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
722
723   if (parm_off && parm_len && parm_type == TYPE_OBJECT_ID)
724     parm_oid = ksba_oid_to_str (der+parm_off, parm_len);
725   else if (parm_off && parm_len)
726     {
727       parmder = der + parm_off;
728       parmderlen = parm_len;
729     }
730
731   der += nread;
732   derlen -= nread;
733
734   if (is_bitstr)
735     { /* Funny: X.509 defines the signature value as a bit string but
736          CMS as an octet string - for ease of implementation we always
737          allow both */
738       if (!derlen)
739         {
740           xfree (parm_oid);
741           return gpg_error (GPG_ERR_INV_KEYINFO);
742         }
743       c = *der++; derlen--;
744       if (c)
745         fprintf (stderr, "warning: number of unused bits is not zero\n");
746     }
747
748   /* fixme: we should calculate the initial length form the size of the
749      sequence, so that we don't need a realloc later */
750   init_stringbuf (&sb, 100);
751   put_stringbuf (&sb, "(10:public-key(");
752
753   /* fixme: we can also use the oidstring here and prefix it with
754      "oid." - this way we can pass more information into Libgcrypt or
755      whatever library is used */
756   put_stringbuf_sexp (&sb, pk_algo_table[algoidx].algo_string);
757
758   /* Insert the curve name for ECC. */
759   if (pk_algo_table[algoidx].pkalgo == PKALGO_ECC && parm_oid)
760     {
761       put_stringbuf (&sb, "(");
762       put_stringbuf_sexp (&sb, "curve");
763       put_stringbuf_sexp (&sb, parm_oid);
764       put_stringbuf (&sb, ")");
765     }
766
767   /* If parameters are given and we have a description for them, parse
768      them. */
769   if (parmder && parmderlen
770       && pk_algo_table[algoidx].parmelem_string
771       && pk_algo_table[algoidx].parmctrl_string)
772     {
773       elem = pk_algo_table[algoidx].parmelem_string;
774       ctrl = pk_algo_table[algoidx].parmctrl_string;
775       for (; *elem; ctrl++, elem++)
776         {
777           int is_int;
778
779           if ( (*ctrl & 0x80) && !elem[1] )
780             {
781               /* Hack to allow reading a raw value.  */
782               is_int = 1;
783               len = parmderlen;
784             }
785           else
786             {
787               if (!parmderlen)
788                 {
789                   xfree (parm_oid);
790                   return gpg_error (GPG_ERR_INV_KEYINFO);
791                 }
792               c = *parmder++; parmderlen--;
793               if ( c != *ctrl )
794                 {
795                   xfree (parm_oid);
796                   return gpg_error (GPG_ERR_UNEXPECTED_TAG);
797                 }
798               is_int = c == 0x02;
799               TLV_LENGTH (parmder);
800             }
801           if (is_int && *elem != '-')  /* Take this integer.  */
802             {
803               char tmp[2];
804
805               put_stringbuf (&sb, "(");
806               tmp[0] = *elem; tmp[1] = 0;
807               put_stringbuf_sexp (&sb, tmp);
808               put_stringbuf_mem_sexp (&sb, parmder, len);
809               parmder += len;
810               parmderlen -= len;
811               put_stringbuf (&sb, ")");
812             }
813         }
814     }
815
816
817   /* FIXME: We don't release the stringbuf in case of error
818      better let the macro jump to a label */
819   elem = pk_algo_table[algoidx].elem_string;
820   ctrl = pk_algo_table[algoidx].ctrl_string;
821   for (; *elem; ctrl++, elem++)
822     {
823       int is_int;
824
825       if ( (*ctrl & 0x80) && !elem[1] )
826         {
827           /* Hack to allow reading a raw value.  */
828           is_int = 1;
829           len = derlen;
830         }
831       else
832         {
833           if (!derlen)
834             {
835               xfree (parm_oid);
836               return gpg_error (GPG_ERR_INV_KEYINFO);
837             }
838           c = *der++; derlen--;
839           if ( c != *ctrl )
840             {
841               xfree (parm_oid);
842               return gpg_error (GPG_ERR_UNEXPECTED_TAG);
843             }
844           is_int = c == 0x02;
845           TLV_LENGTH (der);
846         }
847       if (is_int && *elem != '-')  /* Take this integer.  */
848         {
849           char tmp[2];
850
851           put_stringbuf (&sb, "(");
852           tmp[0] = *elem; tmp[1] = 0;
853           put_stringbuf_sexp (&sb, tmp);
854           put_stringbuf_mem_sexp (&sb, der, len);
855           der += len;
856           derlen -= len;
857           put_stringbuf (&sb, ")");
858         }
859     }
860   put_stringbuf (&sb, "))");
861   xfree (parm_oid);
862
863   *r_string = get_stringbuf (&sb);
864   if (!*r_string)
865     return gpg_error (GPG_ERR_ENOMEM);
866
867   return 0;
868 }
869
870 \f
871 /* Match the algorithm string given in BUF which is of length BUFLEN
872    with the known algorithms from our table and returns the table
873    entries for the DER encoded OID.  If WITH_SIG is true, the table of
874    signature algorithms is consulted first.  */
875 static const unsigned char *
876 oid_from_buffer (const unsigned char *buf, int buflen, int *oidlen,
877                  pkalgo_t *r_pkalgo, int with_sig)
878 {
879   int i;
880
881   /* Ignore an optional "oid." prefix. */
882   if (buflen > 4 && buf[3] == '.' && digitp (buf+4)
883       && ((buf[0] == 'o' && buf[1] == 'i' && buf[2] == 'd')
884           ||(buf[0] == 'O' && buf[1] == 'I' && buf[2] == 'D')))
885     {
886       buf += 4;
887       buflen -= 4;
888     }
889
890   if (with_sig)
891     {
892       /* Scan the signature table first. */
893       for (i=0; sig_algo_table[i].oid; i++)
894         {
895           if (!sig_algo_table[i].supported)
896             continue;
897           if (buflen == strlen (sig_algo_table[i].oidstring)
898               && !memcmp (buf, sig_algo_table[i].oidstring, buflen))
899             break;
900           if (buflen == strlen (sig_algo_table[i].algo_string)
901               && !memcmp (buf, sig_algo_table[i].algo_string, buflen))
902             break;
903         }
904       if (sig_algo_table[i].oid)
905         {
906           *r_pkalgo = sig_algo_table[i].pkalgo;
907           *oidlen = sig_algo_table[i].oidlen;
908           return sig_algo_table[i].oid;
909         }
910     }
911
912   /* Scan the standard table. */
913   for (i=0; pk_algo_table[i].oid; i++)
914     {
915       if (!pk_algo_table[i].supported)
916         continue;
917       if (buflen == strlen (pk_algo_table[i].oidstring)
918           && !memcmp (buf, pk_algo_table[i].oidstring, buflen))
919         break;
920       if (buflen == strlen (pk_algo_table[i].algo_string)
921           && !memcmp (buf, pk_algo_table[i].algo_string, buflen))
922         break;
923     }
924   if (!pk_algo_table[i].oid)
925     return NULL;
926
927   *r_pkalgo = pk_algo_table[i].pkalgo;
928   *oidlen = pk_algo_table[i].oidlen;
929   return pk_algo_table[i].oid;
930 }
931
932
933 /* Take a public-key S-Exp and convert it into a DER encoded
934    publicKeyInfo */
935 gpg_error_t
936 _ksba_keyinfo_from_sexp (ksba_const_sexp_t sexp,
937                          unsigned char **r_der, size_t *r_derlen)
938 {
939   gpg_error_t err;
940   const unsigned char *s;
941   char *endp;
942   unsigned long n, n1;
943   const unsigned char *oid;
944   int oidlen;
945   unsigned char *curve_oid = NULL;
946   size_t curve_oidlen;
947   pkalgo_t pkalgo;
948   int i;
949   struct {
950     const char *name;
951     int namelen;
952     const unsigned char *value;
953     int valuelen;
954   } parm[10];
955   int parmidx;
956   int idxtbl[10];
957   int idxtbllen;
958   const char *parmdesc, *algoparmdesc;
959   ksba_writer_t writer = NULL;
960   void *algoparmseq_value = NULL;
961   size_t algoparmseq_len;
962   void *bitstr_value = NULL;
963   size_t bitstr_len;
964
965   if (!sexp)
966     return gpg_error (GPG_ERR_INV_VALUE);
967
968   s = sexp;
969   if (*s != '(')
970     return gpg_error (GPG_ERR_INV_SEXP);
971   s++;
972
973   n = strtoul (s, &endp, 10);
974   s = endp;
975   if (!n || *s != ':')
976     return gpg_error (GPG_ERR_INV_SEXP); /* we don't allow empty lengths */
977   s++;
978   if (n != 10 || memcmp (s, "public-key", 10))
979     return gpg_error (GPG_ERR_UNKNOWN_SEXP);
980   s += 10;
981   if (*s != '(')
982     return gpg_error (digitp (s)? GPG_ERR_UNKNOWN_SEXP : GPG_ERR_INV_SEXP);
983   s++;
984
985   /* Break out the algorithm ID */
986   n = strtoul (s, &endp, 10);
987   s = endp;
988   if (!n || *s != ':')
989     return gpg_error (GPG_ERR_INV_SEXP); /* we don't allow empty lengths */
990   s++;
991   oid = oid_from_buffer (s, n, &oidlen, &pkalgo, 0);
992   if (!oid)
993     return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
994   s += n;
995
996   /* Collect all the values */
997   for (parmidx = 0; *s != ')' ; parmidx++)
998     {
999       if (parmidx >= DIM(parm))
1000         return gpg_error (GPG_ERR_GENERAL);
1001       if (*s != '(')
1002         return gpg_error (digitp(s)? GPG_ERR_UNKNOWN_SEXP:GPG_ERR_INV_SEXP);
1003       s++;
1004       n = strtoul (s, &endp, 10);
1005       s = endp;
1006       if (!n || *s != ':')
1007         return gpg_error (GPG_ERR_INV_SEXP);
1008       s++;
1009       parm[parmidx].name = s;
1010       parm[parmidx].namelen = n;
1011       s += n;
1012       if (!digitp(s))
1013         return gpg_error (GPG_ERR_UNKNOWN_SEXP); /* ... or invalid S-Exp. */
1014
1015       n = strtoul (s, &endp, 10);
1016       s = endp;
1017       if (!n || *s != ':')
1018         return gpg_error (GPG_ERR_INV_SEXP);
1019       s++;
1020       parm[parmidx].value = s;
1021       parm[parmidx].valuelen = n;
1022       s += n;
1023       if ( *s != ')')
1024         return gpg_error (GPG_ERR_UNKNOWN_SEXP); /* ... or invalid S-Exp. */
1025       s++;
1026     }
1027   s++;
1028   /* We need another closing parenthesis. */
1029   if ( *s != ')' )
1030     return gpg_error (GPG_ERR_INV_SEXP);
1031
1032   /* Describe the parameters in the order we want them and construct
1033      IDXTBL to access them.  For DSA wie also set algoparmdesc so
1034      that we can later build the parameters for the
1035      algorithmIdentifier.  */
1036   algoparmdesc = NULL;
1037   switch (pkalgo)
1038     {
1039     case PKALGO_RSA: parmdesc = "ne"; break;
1040     case PKALGO_DSA: parmdesc = "y" ; algoparmdesc = "pqg"; break;
1041     case PKALGO_ECC: parmdesc = "Cq"; break;
1042     default: return gpg_error (GPG_ERR_UNKNOWN_ALGORITHM);
1043     }
1044
1045   idxtbllen = 0;
1046   for (s = parmdesc; *s; s++)
1047     {
1048       for (i=0; i < parmidx; i++)
1049         {
1050           assert (idxtbllen < DIM (idxtbl));
1051           switch (*s)
1052             {
1053             case 'C': /* Magic value for "curve".  */
1054               if (parm[i].namelen == 5 && !memcmp (parm[i].name, "curve", 5))
1055                 {
1056                   idxtbl[idxtbllen++] = i;
1057                   i = parmidx; /* Break inner loop.  */
1058                 }
1059               break;
1060             default:
1061               if (parm[i].namelen == 1 && parm[i].name[0] == *s)
1062                 {
1063                   idxtbl[idxtbllen++] = i;
1064                   i = parmidx; /* Break inner loop.  */
1065                 }
1066               break;
1067             }
1068         }
1069     }
1070   if (idxtbllen != strlen (parmdesc))
1071     return gpg_error (GPG_ERR_UNKNOWN_SEXP);
1072
1073   if (pkalgo == PKALGO_ECC)
1074     {
1075       curve_oid = get_ecc_curve_oid (parm[idxtbl[0]].value,
1076                                      parm[idxtbl[0]].valuelen,
1077                                      &curve_oidlen);
1078       if (!curve_oid)
1079         return gpg_error (GPG_ERR_UNKNOWN_SEXP);
1080     }
1081
1082
1083   /* Create write object. */
1084   err = ksba_writer_new (&writer);
1085   if (err)
1086     goto leave;
1087   err = ksba_writer_set_mem (writer, 1024);
1088   if (err)
1089     goto leave;
1090
1091   /* We create the keyinfo in 2 steps:
1092
1093      1. We build the inner one and encapsulate it in a bit string.
1094
1095      2. We create the outer sequence include the algorithm identifier
1096         and the bit string from step 1.
1097    */
1098   if (pkalgo == PKALGO_ECC)
1099     {
1100       /* Write the bit string header and the number of unused bits. */
1101       err = _ksba_ber_write_tl (writer, TYPE_BIT_STRING, CLASS_UNIVERSAL,
1102                                 0, parm[idxtbl[1]].valuelen + 1);
1103       if (!err)
1104         err = ksba_writer_write (writer, "", 1);
1105       /* And the actual raw value.  */
1106       if (!err)
1107         err = ksba_writer_write (writer, parm[idxtbl[1]].value,
1108                                  parm[idxtbl[1]].valuelen);
1109       if (err)
1110         goto leave;
1111
1112     }
1113   else /* RSA and DSA */
1114     {
1115       /* Calculate the size of the sequence value and the size of the
1116          bit string value.  NOt ethat in case there is only one
1117          integer to write, no sequence is used.  */
1118       for (n=0, i=0; i < idxtbllen; i++ )
1119         {
1120           n += _ksba_ber_count_tl (TYPE_INTEGER, CLASS_UNIVERSAL, 0,
1121                                    parm[idxtbl[i]].valuelen);
1122           n += parm[idxtbl[i]].valuelen;
1123         }
1124
1125       n1 = 1; /* # of unused bits.  */
1126       if (idxtbllen > 1)
1127         n1 += _ksba_ber_count_tl (TYPE_SEQUENCE, CLASS_UNIVERSAL, 1, n);
1128       n1 += n;
1129
1130       /* Write the bit string header and the number of unused bits. */
1131       err = _ksba_ber_write_tl (writer, TYPE_BIT_STRING, CLASS_UNIVERSAL,
1132                                 0, n1);
1133       if (!err)
1134         err = ksba_writer_write (writer, "", 1);
1135       if (err)
1136         goto leave;
1137
1138       /* Write the sequence tag and the integers. */
1139       if (idxtbllen > 1)
1140         err = _ksba_ber_write_tl (writer, TYPE_SEQUENCE, CLASS_UNIVERSAL, 1,n);
1141       if (err)
1142         goto leave;
1143       for (i=0; i < idxtbllen; i++)
1144         {
1145           /* fixme: we should make sure that the integer conforms to the
1146              ASN.1 encoding rules. */
1147           err  = _ksba_ber_write_tl (writer, TYPE_INTEGER, CLASS_UNIVERSAL, 0,
1148                                      parm[idxtbl[i]].valuelen);
1149           if (!err)
1150             err = ksba_writer_write (writer, parm[idxtbl[i]].value,
1151                                      parm[idxtbl[i]].valuelen);
1152           if (err)
1153             goto leave;
1154         }
1155     }
1156
1157   /* Get the encoded bit string. */
1158   bitstr_value = ksba_writer_snatch_mem (writer, &bitstr_len);
1159   if (!bitstr_value)
1160     {
1161       err = gpg_error (GPG_ERR_ENOMEM);
1162       goto leave;
1163     }
1164
1165   /* If the algorithmIdentifier requires a sequence with parameters,
1166      build them now.  We can reuse the IDXTBL for that.  */
1167   if (algoparmdesc)
1168     {
1169       idxtbllen = 0;
1170       for (s = algoparmdesc; *s; s++)
1171         {
1172           for (i=0; i < parmidx; i++)
1173             {
1174               assert (idxtbllen < DIM (idxtbl));
1175               if (parm[i].namelen == 1 && parm[i].name[0] == *s)
1176                 {
1177                   idxtbl[idxtbllen++] = i;
1178                   break;
1179                 }
1180             }
1181         }
1182       if (idxtbllen != strlen (algoparmdesc))
1183         return gpg_error (GPG_ERR_UNKNOWN_SEXP);
1184
1185       err = ksba_writer_set_mem (writer, 1024);
1186       if (err)
1187         goto leave;
1188
1189       /* Calculate the size of the sequence.  */
1190       for (n=0, i=0; i < idxtbllen; i++ )
1191         {
1192           n += _ksba_ber_count_tl (TYPE_INTEGER, CLASS_UNIVERSAL, 0,
1193                                    parm[idxtbl[i]].valuelen);
1194           n += parm[idxtbl[i]].valuelen;
1195         }
1196       /*  n += _ksba_ber_count_tl (TYPE_SEQUENCE, CLASS_UNIVERSAL, 1, n); */
1197
1198       /* Write the sequence tag followed by the integers. */
1199       err = _ksba_ber_write_tl (writer, TYPE_SEQUENCE, CLASS_UNIVERSAL, 1, n);
1200       if (err)
1201         goto leave;
1202       for (i=0; i < idxtbllen; i++)
1203         {
1204           err = _ksba_ber_write_tl (writer, TYPE_INTEGER, CLASS_UNIVERSAL, 0,
1205                                     parm[idxtbl[i]].valuelen);
1206           if (!err)
1207             err = ksba_writer_write (writer, parm[idxtbl[i]].value,
1208                                      parm[idxtbl[i]].valuelen);
1209           if (err)
1210             goto leave;
1211         }
1212
1213       /* Get the encoded sequence.  */
1214       algoparmseq_value = ksba_writer_snatch_mem (writer, &algoparmseq_len);
1215       if (!algoparmseq_value)
1216         {
1217           err = gpg_error (GPG_ERR_ENOMEM);
1218           goto leave;
1219         }
1220     }
1221   else
1222     algoparmseq_len = 0;
1223
1224   /* Reinitialize the buffer to create the outer sequence. */
1225   err = ksba_writer_set_mem (writer, 1024);
1226   if (err)
1227     goto leave;
1228
1229   /* Calulate lengths. */
1230   n  = _ksba_ber_count_tl (TYPE_OBJECT_ID, CLASS_UNIVERSAL, 0, oidlen);
1231   n += oidlen;
1232   if (algoparmseq_len)
1233     {
1234       n += algoparmseq_len;
1235     }
1236   else if (pkalgo == PKALGO_ECC)
1237     {
1238       n += _ksba_ber_count_tl (TYPE_OBJECT_ID, CLASS_UNIVERSAL,
1239                                0, curve_oidlen);
1240       n += curve_oidlen;
1241     }
1242   else if (pkalgo == PKALGO_RSA)
1243     {
1244       n += _ksba_ber_count_tl (TYPE_NULL, CLASS_UNIVERSAL, 0, 0);
1245     }
1246
1247   n1 = n;
1248   n1 += _ksba_ber_count_tl (TYPE_SEQUENCE, CLASS_UNIVERSAL, 1, n);
1249   n1 += bitstr_len;
1250
1251   /* The outer sequence.  */
1252   err = _ksba_ber_write_tl (writer, TYPE_SEQUENCE, CLASS_UNIVERSAL, 1, n1);
1253   if (err)
1254     goto leave;
1255
1256   /* The sequence.  */
1257   err = _ksba_ber_write_tl (writer, TYPE_SEQUENCE, CLASS_UNIVERSAL, 1, n);
1258   if (err)
1259     goto leave;
1260
1261   /* The object id.  */
1262   err = _ksba_ber_write_tl (writer, TYPE_OBJECT_ID,CLASS_UNIVERSAL, 0, oidlen);
1263   if (!err)
1264     err = ksba_writer_write (writer, oid, oidlen);
1265   if (err)
1266     goto leave;
1267
1268   /* The parameter. */
1269   if (algoparmseq_len)
1270     {
1271       err = ksba_writer_write (writer, algoparmseq_value, algoparmseq_len);
1272     }
1273   else if (pkalgo == PKALGO_ECC)
1274     {
1275       err = _ksba_ber_write_tl (writer, TYPE_OBJECT_ID, CLASS_UNIVERSAL,
1276                                 0, curve_oidlen);
1277       if (!err)
1278         err = ksba_writer_write (writer, curve_oid, curve_oidlen);
1279     }
1280   else if (pkalgo == PKALGO_RSA)
1281     {
1282       err = _ksba_ber_write_tl (writer, TYPE_NULL, CLASS_UNIVERSAL, 0, 0);
1283     }
1284   if (err)
1285     goto leave;
1286
1287   /* Append the pre-constructed bit string.  */
1288   err = ksba_writer_write (writer, bitstr_value, bitstr_len);
1289   if (err)
1290     goto leave;
1291
1292   /* Get the result. */
1293   *r_der = ksba_writer_snatch_mem (writer, r_derlen);
1294   if (!*r_der)
1295     err = gpg_error (GPG_ERR_ENOMEM);
1296
1297  leave:
1298   ksba_writer_release (writer);
1299   xfree (bitstr_value);
1300   xfree (curve_oid);
1301   return err;
1302 }
1303
1304
1305 /* Take a sig-val s-expression and convert it into a DER encoded
1306    algorithmInfo.  Unfortunately this function clones a lot of code
1307    from _ksba_keyinfo_from_sexp.  */
1308 gpg_error_t
1309 _ksba_algoinfo_from_sexp (ksba_const_sexp_t sexp,
1310                           unsigned char **r_der, size_t *r_derlen)
1311 {
1312   gpg_error_t err;
1313   const unsigned char *s;
1314   char *endp;
1315   unsigned long n;
1316   const unsigned char *oid;
1317   int oidlen;
1318   unsigned char *curve_oid = NULL;
1319   size_t curve_oidlen;
1320   pkalgo_t pkalgo;
1321   int i;
1322   struct {
1323     const char *name;
1324     int namelen;
1325     const unsigned char *value;
1326     int valuelen;
1327   } parm[10];
1328   int parmidx;
1329   int idxtbl[10];
1330   int idxtbllen;
1331   const char *parmdesc, *algoparmdesc;
1332   ksba_writer_t writer = NULL;
1333   void *algoparmseq_value = NULL;
1334   size_t algoparmseq_len;
1335
1336   if (!sexp)
1337     return gpg_error (GPG_ERR_INV_VALUE);
1338
1339   s = sexp;
1340   if (*s != '(')
1341     return gpg_error (GPG_ERR_INV_SEXP);
1342   s++;
1343
1344   n = strtoul (s, &endp, 10);
1345   s = endp;
1346   if (!n || *s != ':')
1347     return gpg_error (GPG_ERR_INV_SEXP); /* We don't allow empty lengths.  */
1348   s++;
1349   if (n == 7 && !memcmp (s, "sig-val", 7))
1350     s += 7;
1351   else if (n == 10 && !memcmp (s, "public-key", 10))
1352     s += 10;
1353   else
1354     return gpg_error (GPG_ERR_UNKNOWN_SEXP);
1355
1356   if (*s != '(')
1357     return gpg_error (digitp (s)? GPG_ERR_UNKNOWN_SEXP : GPG_ERR_INV_SEXP);
1358   s++;
1359
1360   /* Break out the algorithm ID */
1361   n = strtoul (s, &endp, 10);
1362   s = endp;
1363   if (!n || *s != ':')
1364     return gpg_error (GPG_ERR_INV_SEXP); /* We don't allow empty lengths.  */
1365   s++;
1366   oid = oid_from_buffer (s, n, &oidlen, &pkalgo, 1);
1367   if (!oid)
1368     return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
1369   s += n;
1370
1371   /* Collect all the values */
1372   for (parmidx = 0; *s != ')' ; parmidx++)
1373     {
1374       if (parmidx >= DIM(parm))
1375         return gpg_error (GPG_ERR_GENERAL);
1376       if (*s != '(')
1377         return gpg_error (digitp(s)? GPG_ERR_UNKNOWN_SEXP:GPG_ERR_INV_SEXP);
1378       s++;
1379       n = strtoul (s, &endp, 10);
1380       s = endp;
1381       if (!n || *s != ':')
1382         return gpg_error (GPG_ERR_INV_SEXP);
1383       s++;
1384       parm[parmidx].name = s;
1385       parm[parmidx].namelen = n;
1386       s += n;
1387       if (!digitp(s))
1388         return gpg_error (GPG_ERR_UNKNOWN_SEXP); /* ... or invalid S-Exp. */
1389
1390       n = strtoul (s, &endp, 10);
1391       s = endp;
1392       if (!n || *s != ':')
1393         return gpg_error (GPG_ERR_INV_SEXP);
1394       s++;
1395       parm[parmidx].value = s;
1396       parm[parmidx].valuelen = n;
1397       s += n;
1398       if ( *s != ')')
1399         return gpg_error (GPG_ERR_UNKNOWN_SEXP); /* ... or invalid S-Exp. */
1400       s++;
1401     }
1402   s++;
1403   /* We need another closing parenthesis. */
1404   if ( *s != ')' )
1405     return gpg_error (GPG_ERR_INV_SEXP);
1406
1407   /* Describe the parameters in the order we want them and construct
1408      IDXTBL to access them.  For DSA wie also set algoparmdesc so
1409      that we can later build the parameters for the
1410      algorithmIdentifier.  */
1411   algoparmdesc = NULL;
1412   switch (pkalgo)
1413     {
1414     case PKALGO_RSA: parmdesc = ""; break;
1415     case PKALGO_DSA: parmdesc = "" ; algoparmdesc = "pqg"; break;
1416     case PKALGO_ECC: parmdesc = "C"; break;
1417     default: return gpg_error (GPG_ERR_UNKNOWN_ALGORITHM);
1418     }
1419
1420   idxtbllen = 0;
1421   for (s = parmdesc; *s; s++)
1422     {
1423       for (i=0; i < parmidx; i++)
1424         {
1425           assert (idxtbllen < DIM (idxtbl));
1426           switch (*s)
1427             {
1428             case 'C': /* Magic value for "curve".  */
1429               if (parm[i].namelen == 5 && !memcmp (parm[i].name, "curve", 5))
1430                 {
1431                   idxtbl[idxtbllen++] = i;
1432                   i = parmidx; /* Break inner loop.  */
1433                 }
1434               break;
1435             default:
1436               if (parm[i].namelen == 1 && parm[i].name[0] == *s)
1437                 {
1438                   idxtbl[idxtbllen++] = i;
1439                   i = parmidx; /* Break inner loop.  */
1440                 }
1441               break;
1442             }
1443         }
1444     }
1445   if (idxtbllen != strlen (parmdesc))
1446     return gpg_error (GPG_ERR_UNKNOWN_SEXP);
1447
1448   if (pkalgo == PKALGO_ECC)
1449     {
1450       curve_oid = get_ecc_curve_oid (parm[idxtbl[0]].value,
1451                                      parm[idxtbl[0]].valuelen,
1452                                      &curve_oidlen);
1453       if (!curve_oid)
1454         return gpg_error (GPG_ERR_UNKNOWN_SEXP);
1455     }
1456
1457
1458   /* Create write object. */
1459   err = ksba_writer_new (&writer);
1460   if (err)
1461     goto leave;
1462   err = ksba_writer_set_mem (writer, 1024);
1463   if (err)
1464     goto leave;
1465
1466   /* Create the sequence of the algorithm identifier.  */
1467
1468   /* If the algorithmIdentifier requires a sequence with parameters,
1469      build them now.  We can reuse the IDXTBL for that.  */
1470   if (algoparmdesc)
1471     {
1472       idxtbllen = 0;
1473       for (s = algoparmdesc; *s; s++)
1474         {
1475           for (i=0; i < parmidx; i++)
1476             {
1477               assert (idxtbllen < DIM (idxtbl));
1478               if (parm[i].namelen == 1 && parm[i].name[0] == *s)
1479                 {
1480                   idxtbl[idxtbllen++] = i;
1481                   break;
1482                 }
1483             }
1484         }
1485       if (idxtbllen != strlen (algoparmdesc))
1486         return gpg_error (GPG_ERR_UNKNOWN_SEXP);
1487
1488       err = ksba_writer_set_mem (writer, 1024);
1489       if (err)
1490         goto leave;
1491
1492       /* Calculate the size of the sequence.  */
1493       for (n=0, i=0; i < idxtbllen; i++ )
1494         {
1495           n += _ksba_ber_count_tl (TYPE_INTEGER, CLASS_UNIVERSAL, 0,
1496                                    parm[idxtbl[i]].valuelen);
1497           n += parm[idxtbl[i]].valuelen;
1498         }
1499
1500       /* Write the sequence tag followed by the integers. */
1501       err = _ksba_ber_write_tl (writer, TYPE_SEQUENCE, CLASS_UNIVERSAL, 1, n);
1502       if (err)
1503         goto leave;
1504       for (i=0; i < idxtbllen; i++)
1505         {
1506           err = _ksba_ber_write_tl (writer, TYPE_INTEGER, CLASS_UNIVERSAL, 0,
1507                                     parm[idxtbl[i]].valuelen);
1508           if (!err)
1509             err = ksba_writer_write (writer, parm[idxtbl[i]].value,
1510                                      parm[idxtbl[i]].valuelen);
1511           if (err)
1512             goto leave;
1513         }
1514
1515       /* Get the encoded sequence.  */
1516       algoparmseq_value = ksba_writer_snatch_mem (writer, &algoparmseq_len);
1517       if (!algoparmseq_value)
1518         {
1519           err = gpg_error (GPG_ERR_ENOMEM);
1520           goto leave;
1521         }
1522     }
1523   else
1524     algoparmseq_len = 0;
1525
1526   /* Reinitialize the buffer to create the sequence. */
1527   err = ksba_writer_set_mem (writer, 1024);
1528   if (err)
1529     goto leave;
1530
1531   /* Calulate lengths. */
1532   n  = _ksba_ber_count_tl (TYPE_OBJECT_ID, CLASS_UNIVERSAL, 0, oidlen);
1533   n += oidlen;
1534   if (algoparmseq_len)
1535     {
1536       n += algoparmseq_len;
1537     }
1538   else if (pkalgo == PKALGO_ECC)
1539     {
1540       n += _ksba_ber_count_tl (TYPE_OBJECT_ID, CLASS_UNIVERSAL,
1541                                0, curve_oidlen);
1542       n += curve_oidlen;
1543     }
1544   else if (pkalgo == PKALGO_RSA)
1545     {
1546       n += _ksba_ber_count_tl (TYPE_NULL, CLASS_UNIVERSAL, 0, 0);
1547     }
1548
1549   /* Write the sequence.  */
1550   err = _ksba_ber_write_tl (writer, TYPE_SEQUENCE, CLASS_UNIVERSAL, 1, n);
1551   if (err)
1552     goto leave;
1553
1554   /* Write the object id.  */
1555   err = _ksba_ber_write_tl (writer, TYPE_OBJECT_ID, CLASS_UNIVERSAL, 0, oidlen);
1556   if (!err)
1557     err = ksba_writer_write (writer, oid, oidlen);
1558   if (err)
1559     goto leave;
1560
1561   /* Write the parameters. */
1562   if (algoparmseq_len)
1563     {
1564       err = ksba_writer_write (writer, algoparmseq_value, algoparmseq_len);
1565     }
1566   else if (pkalgo == PKALGO_ECC)
1567     {
1568       /* We only support the namedCuve choice for ECC parameters.  */
1569       err = _ksba_ber_write_tl (writer, TYPE_OBJECT_ID, CLASS_UNIVERSAL,
1570                                 0, curve_oidlen);
1571       if (!err)
1572         err = ksba_writer_write (writer, curve_oid, curve_oidlen);
1573     }
1574   else if (pkalgo == PKALGO_RSA)
1575     {
1576       err = _ksba_ber_write_tl (writer, TYPE_NULL, CLASS_UNIVERSAL, 0, 0);
1577     }
1578   if (err)
1579     goto leave;
1580
1581   /* Get the result. */
1582   *r_der = ksba_writer_snatch_mem (writer, r_derlen);
1583   if (!*r_der)
1584     err = gpg_error (GPG_ERR_ENOMEM);
1585
1586  leave:
1587   ksba_writer_release (writer);
1588   xfree (curve_oid);
1589   return err;
1590 }
1591
1592
1593
1594 /* Mode 0: work as described under _ksba_sigval_to_sexp
1595    mode 1: work as described under _ksba_encval_to_sexp */
1596 static gpg_error_t
1597 cryptval_to_sexp (int mode, const unsigned char *der, size_t derlen,
1598                   ksba_sexp_t *r_string)
1599 {
1600   gpg_error_t err;
1601   const struct algo_table_s *algo_table;
1602   int c;
1603   size_t nread, off, len;
1604   int algoidx;
1605   int is_bitstr;
1606   const unsigned char *ctrl;
1607   const char *elem;
1608   struct stringbuf sb;
1609
1610   /* FIXME: The entire function is very similar to keyinfo_to_sexp */
1611   *r_string = NULL;
1612
1613   if (!mode)
1614     algo_table = sig_algo_table;
1615   else
1616     algo_table = enc_algo_table;
1617
1618
1619   err = get_algorithm (1, der, derlen, &nread, &off, &len, &is_bitstr,
1620                        NULL, NULL, NULL);
1621   if (err)
1622     return err;
1623
1624   /* look into our table of supported algorithms */
1625   for (algoidx=0; algo_table[algoidx].oid; algoidx++)
1626     {
1627       if ( len == algo_table[algoidx].oidlen
1628            && !memcmp (der+off, algo_table[algoidx].oid, len))
1629         break;
1630     }
1631   if (!algo_table[algoidx].oid)
1632     return gpg_error (GPG_ERR_UNKNOWN_ALGORITHM);
1633   if (!algo_table[algoidx].supported)
1634     return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
1635
1636   der += nread;
1637   derlen -= nread;
1638
1639   if (is_bitstr)
1640     { /* Funny: X.509 defines the signature value as a bit string but
1641          CMS as an octet string - for ease of implementation we always
1642          allow both */
1643       if (!derlen)
1644         return gpg_error (GPG_ERR_INV_KEYINFO);
1645       c = *der++; derlen--;
1646       if (c)
1647         fprintf (stderr, "warning: number of unused bits is not zero\n");
1648     }
1649
1650   /* fixme: we should calculate the initial length form the size of the
1651      sequence, so that we don't neen a realloc later */
1652   init_stringbuf (&sb, 100);
1653   put_stringbuf (&sb, mode? "(7:enc-val(":"(7:sig-val(");
1654   put_stringbuf_sexp (&sb, algo_table[algoidx].algo_string);
1655
1656   /* FIXME: We don't release the stringbuf in case of error
1657      better let the macro jump to a label */
1658   elem = algo_table[algoidx].elem_string;
1659   ctrl = algo_table[algoidx].ctrl_string;
1660   for (; *elem; ctrl++, elem++)
1661     {
1662       int is_int;
1663
1664       if ( (*ctrl & 0x80) && !elem[1] )
1665         {  /* Hack to allow a raw value */
1666           is_int = 1;
1667           len = derlen;
1668         }
1669       else
1670         {
1671           if (!derlen)
1672             return gpg_error (GPG_ERR_INV_KEYINFO);
1673           c = *der++; derlen--;
1674           if ( c != *ctrl )
1675             return gpg_error (GPG_ERR_UNEXPECTED_TAG);
1676           is_int = c == 0x02;
1677           TLV_LENGTH (der);
1678         }
1679       if (is_int && *elem != '-')
1680         { /* take this integer */
1681           char tmp[2];
1682
1683           put_stringbuf (&sb, "(");
1684           tmp[0] = *elem; tmp[1] = 0;
1685           put_stringbuf_sexp (&sb, tmp);
1686           put_stringbuf_mem_sexp (&sb, der, len);
1687           der += len;
1688           derlen -= len;
1689           put_stringbuf (&sb, ")");
1690         }
1691     }
1692   put_stringbuf (&sb, ")");
1693   if (!mode && algo_table[algoidx].digest_string)
1694     {
1695       /* Insert the hash algorithm if included in the OID.  */
1696       put_stringbuf (&sb, "(4:hash");
1697       put_stringbuf_sexp (&sb, algo_table[algoidx].digest_string);
1698       put_stringbuf (&sb, ")");
1699     }
1700   put_stringbuf (&sb, ")");
1701
1702   *r_string = get_stringbuf (&sb);
1703   if (!*r_string)
1704     return gpg_error (GPG_ERR_ENOMEM);
1705
1706   return 0;
1707 }
1708
1709 /* Assume that DER is a buffer of length DERLEN with a DER encoded
1710    Asn.1 structure like this:
1711
1712      SEQUENCE {
1713         algorithm    OBJECT IDENTIFIER,
1714         parameters   ANY DEFINED BY algorithm OPTIONAL }
1715      signature  BIT STRING
1716
1717   We only allow parameters == NULL.
1718
1719   The function parses this structure and creates a S-Exp suitable to be
1720   used as signature value in Libgcrypt:
1721
1722   (sig-val
1723     (<algo>
1724       (<param_name1> <mpi>)
1725       ...
1726       (<param_namen> <mpi>))
1727     (hash algo))
1728
1729  The S-Exp will be returned in a string which the caller must free.
1730  We don't pass an ASN.1 node here but a plain memory block.  */
1731 gpg_error_t
1732 _ksba_sigval_to_sexp (const unsigned char *der, size_t derlen,
1733                       ksba_sexp_t *r_string)
1734 {
1735   return cryptval_to_sexp (0, der, derlen, r_string);
1736 }
1737
1738
1739 /* Assume that der is a buffer of length DERLEN with a DER encoded
1740  Asn.1 structure like this:
1741
1742      SEQUENCE {
1743         algorithm    OBJECT IDENTIFIER,
1744         parameters   ANY DEFINED BY algorithm OPTIONAL }
1745      encryptedKey  OCTET STRING
1746
1747   We only allow parameters == NULL.
1748
1749   The function parses this structure and creates a S-Exp suitable to be
1750   used as encrypted value in Libgcrypt's public key functions:
1751
1752   (enc-val
1753     (<algo>
1754       (<param_name1> <mpi>)
1755       ...
1756       (<param_namen> <mpi>)
1757     ))
1758
1759  The S-Exp will be returned in a string which the caller must free.
1760  We don't pass an ASN.1 node here but a plain memory block.  */
1761 gpg_error_t
1762 _ksba_encval_to_sexp (const unsigned char *der, size_t derlen,
1763                       ksba_sexp_t *r_string)
1764 {
1765   return cryptval_to_sexp (1, der, derlen, r_string);
1766 }