1 /* keyinfo.c - Parse and build a keyInfo structure
2 * Copyright (C) 2001, 2002, 2007, 2008, 2012 g10 Code GmbH
4 * This file is part of KSBA.
6 * KSBA is free software; you can redistribute it and/or modify
7 * it under the terms of either
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.
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.
19 * or both in parallel, as here.
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.
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/>.
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
42 #include "asn1-func.h"
49 /* Constants used for the public key algorithms. */
60 const char *oidstring;
61 const unsigned char *oid; /* NULL indicattes end of table */
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. */
75 static const struct algo_table_s pk_algo_table[] = {
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" },
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) */
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" },
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" },
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" },
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" },
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" },
145 { /* iso.member-body.us.ansi-x9-62.signatures.ecdsa-with-specified */
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. */
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" },
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" },
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" },
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" },
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" },
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" },
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" },
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" },
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" },
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" },
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" },
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" },
225 /* This tables maps names of ECC curves names to OIDs. A similar
226 table is used by lib gcrypt. */
233 { "1.3.6.1.4.1.3029.1.5.1", "Curve25519" },
234 { "1.3.6.1.4.1.11591.15.1", "Ed25519" },
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" },
241 { "1.3.132.0.33", "NIST P-224" },
242 { "1.3.132.0.33", "nistp224" },
243 { "1.3.132.0.33", "secp224r1" },
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" },
250 { "1.3.132.0.34", "NIST P-384" },
251 { "1.3.132.0.34", "nistp384" },
252 { "1.3.132.0.34", "secp384r1" },
254 { "1.3.132.0.35", "NIST P-521" },
255 { "1.3.132.0.35", "nistp521" },
256 { "1.3.132.0.35", "secp521r1" },
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" },
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" },
273 { "1.3.132.0.10", "secp256k1" },
290 #define TLV_LENGTH(prefix) do { \
291 if (!prefix ## len) \
292 return gpg_error (GPG_ERR_INV_KEYINFO); \
293 c = *(prefix)++; prefix ## len--; \
295 return gpg_error (GPG_ERR_NOT_DER_ENCODED); \
297 return gpg_error (GPG_ERR_BAD_BER); \
303 int count = c & 0x7f; \
305 for (len=0; count; count--) \
308 if (!prefix ## len) \
309 return gpg_error (GPG_ERR_BAD_BER);\
310 c = *(prefix)++; prefix ## len--; \
314 if (len > prefix ## len) \
315 return gpg_error (GPG_ERR_INV_KEYINFO); \
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)
325 unsigned char *der_oid;
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')))
336 /* If it does not look like an OID - map it through the table. */
337 if (buflen && !digitp (buf))
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))
345 if (!curve_names[i].oid)
346 return NULL; /* Not found. */
347 buf = curve_names[i].oid;
348 buflen = strlen (curve_names[i].oid);
351 if (_ksba_oid_from_buf (buf, buflen, &der_oid, r_oidlen))
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.
362 mode 0: just get the algorithm identifier. FIXME: should be able to
364 mode 1: as described.
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)
372 const unsigned char *start = der;
373 const unsigned char *startseq;
374 unsigned long seqlen, len;
383 /* get the inner sequence */
385 return gpg_error (GPG_ERR_INV_KEYINFO);
386 c = *der++; derlen--;
388 return gpg_error (GPG_ERR_UNEXPECTED_TAG); /* not a SEQUENCE */
393 /* get the object identifier */
395 return gpg_error (GPG_ERR_INV_KEYINFO);
396 c = *der++; derlen--;
398 return gpg_error (GPG_ERR_UNEXPECTED_TAG); /* not an OBJECT IDENTIFIER */
401 /* der does now point to an oid of length LEN */
402 *r_pos = der - start;
405 /* char *p = ksba_oid_to_str (der, len); */
406 /* printf ("algorithm: %s\n", p); */
411 seqlen -= der - startseq;;
413 /* Parse the parameter. */
416 const unsigned char *startparm = der;
419 return gpg_error (GPG_ERR_INV_KEYINFO);
420 c = *der++; derlen--;
423 /*printf ("parameter: NULL \n"); the usual case */
425 return gpg_error (GPG_ERR_INV_KEYINFO);
426 c = *der++; derlen--;
428 return gpg_error (GPG_ERR_BAD_BER); /* NULL must have a
432 else if (r_parm_pos && r_parm_len && c == 0x04)
434 /* This is an octet string parameter and we need it. */
436 *r_parm_type = TYPE_OCTET_STRING;
438 *r_parm_pos = der - start;
440 seqlen -= der - startparm;
445 else if (r_parm_pos && r_parm_len && c == 0x06)
447 /* This is an object identifier. */
449 *r_parm_type = TYPE_OBJECT_ID;
451 *r_parm_pos = der - start;
453 seqlen -= der - startparm;
458 else if (r_parm_pos && r_parm_len && c == 0x30)
460 /* This is a sequence. */
462 *r_parm_type = TYPE_SEQUENCE;
464 *r_parm_pos = startparm - start;
465 *r_parm_len = len + (der - startparm);
466 seqlen -= der - startparm;
473 /* printf ("parameter: with tag %02x - ignored\n", c); */
475 seqlen -= der - startparm;
484 return gpg_error (GPG_ERR_INV_KEYINFO);
488 /* move forward to the BIT_STR */
490 return gpg_error (GPG_ERR_INV_KEYINFO);
491 c = *der++; derlen--;
494 *r_bitstr = 1; /* BIT STRING */
496 ; /* OCTECT STRING */
498 return gpg_error (GPG_ERR_UNEXPECTED_TAG); /* not a BIT STRING */
502 *r_nread = der - start;
508 _ksba_parse_algorithm_identifier (const unsigned char *der, size_t derlen,
509 size_t *r_nread, char **r_oid)
511 return _ksba_parse_algorithm_identifier2 (der, derlen,
512 r_nread, r_oid, NULL, NULL);
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)
522 size_t nread, off, len, off2, len2;
525 /* fixme: get_algorithm might return the error invalid keyinfo -
526 this should be invalid algorithm identifier */
530 err = get_algorithm (0, der, derlen, &nread, &off, &len, &is_bitstr,
531 &off2, &len2, &parm_type);
535 *r_oid = ksba_oid_to_str (der+off, len);
537 return gpg_error (GPG_ERR_ENOMEM);
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"))
546 err = get_algorithm (0, der+off2, len2, &nread, &off, &len, &is_bitstr,
553 *r_oid = ksba_oid_to_str (der+off2+off, len);
557 return gpg_error (GPG_ERR_ENOMEM);
560 off2 = len2 = 0; /* So that R_PARM is set to NULL. */
563 if (r_parm && r_parmlen)
567 *r_parm = xtrymalloc (len2);
572 return gpg_error (GPG_ERR_ENOMEM);
574 memcpy (*r_parm, der+off2, len2);
589 init_stringbuf (struct stringbuf *sb, int initiallen)
592 sb->size = initiallen;
594 /* allocate one more, so that get_stringbuf can append a nul */
595 sb->buf = xtrymalloc (initiallen+1);
601 put_stringbuf_mem (struct stringbuf *sb, const char *text, size_t n)
606 if (sb->len + n >= sb->size)
611 p = xtryrealloc (sb->buf, sb->size);
619 memcpy (sb->buf+sb->len, text, n);
624 put_stringbuf (struct stringbuf *sb, const char *text)
626 put_stringbuf_mem (sb, text,strlen (text));
630 put_stringbuf_mem_sexp (struct stringbuf *sb, const char *text, size_t length)
633 sprintf (buf,"%u:", (unsigned int)length);
634 put_stringbuf (sb, buf);
635 put_stringbuf_mem (sb, text, length);
639 put_stringbuf_sexp (struct stringbuf *sb, const char *text)
641 put_stringbuf_mem_sexp (sb, text, strlen (text));
646 get_stringbuf (struct stringbuf *sb)
652 xfree (sb->buf); sb->buf = NULL;
656 sb->buf[sb->len] = 0;
659 sb->out_of_core = 1; /* make sure the caller does an init before reuse */
664 /* Assume that der is a buffer of length DERLEN with a DER encoded
665 Asn.1 structure like this:
667 keyInfo ::= SEQUENCE {
669 algorithm OBJECT IDENTIFIER,
670 parameters ANY DEFINED BY algorithm OPTIONAL }
671 publicKey BIT STRING }
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.
677 We don't pass an ASN.1 node here but a plain memory block. */
680 _ksba_keyinfo_to_sexp (const unsigned char *der, size_t derlen,
681 ksba_sexp_t *r_string)
685 size_t nread, off, len, parm_off, parm_len;
687 char *parm_oid = NULL;
690 const unsigned char *parmder = NULL;
691 size_t parmderlen = 0;
692 const unsigned char *ctrl;
698 /* check the outer sequence */
700 return gpg_error (GPG_ERR_INV_KEYINFO);
701 c = *der++; derlen--;
703 return gpg_error (GPG_ERR_UNEXPECTED_TAG); /* not a SEQUENCE */
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);
711 /* look into our table of supported algorithms */
712 for (algoidx=0; pk_algo_table[algoidx].oid; algoidx++)
714 if ( len == pk_algo_table[algoidx].oidlen
715 && !memcmp (der+off, pk_algo_table[algoidx].oid, len))
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);
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)
727 parmder = der + parm_off;
728 parmderlen = parm_len;
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
741 return gpg_error (GPG_ERR_INV_KEYINFO);
743 c = *der++; derlen--;
745 fprintf (stderr, "warning: number of unused bits is not zero\n");
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(");
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);
758 /* Insert the curve name for ECC. */
759 if (pk_algo_table[algoidx].pkalgo == PKALGO_ECC && parm_oid)
761 put_stringbuf (&sb, "(");
762 put_stringbuf_sexp (&sb, "curve");
763 put_stringbuf_sexp (&sb, parm_oid);
764 put_stringbuf (&sb, ")");
767 /* If parameters are given and we have a description for them, parse
769 if (parmder && parmderlen
770 && pk_algo_table[algoidx].parmelem_string
771 && pk_algo_table[algoidx].parmctrl_string)
773 elem = pk_algo_table[algoidx].parmelem_string;
774 ctrl = pk_algo_table[algoidx].parmctrl_string;
775 for (; *elem; ctrl++, elem++)
779 if ( (*ctrl & 0x80) && !elem[1] )
781 /* Hack to allow reading a raw value. */
790 return gpg_error (GPG_ERR_INV_KEYINFO);
792 c = *parmder++; parmderlen--;
796 return gpg_error (GPG_ERR_UNEXPECTED_TAG);
799 TLV_LENGTH (parmder);
801 if (is_int && *elem != '-') /* Take this integer. */
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);
811 put_stringbuf (&sb, ")");
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++)
825 if ( (*ctrl & 0x80) && !elem[1] )
827 /* Hack to allow reading a raw value. */
836 return gpg_error (GPG_ERR_INV_KEYINFO);
838 c = *der++; derlen--;
842 return gpg_error (GPG_ERR_UNEXPECTED_TAG);
847 if (is_int && *elem != '-') /* Take this integer. */
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);
857 put_stringbuf (&sb, ")");
860 put_stringbuf (&sb, "))");
863 *r_string = get_stringbuf (&sb);
865 return gpg_error (GPG_ERR_ENOMEM);
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)
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')))
892 /* Scan the signature table first. */
893 for (i=0; sig_algo_table[i].oid; i++)
895 if (!sig_algo_table[i].supported)
897 if (buflen == strlen (sig_algo_table[i].oidstring)
898 && !memcmp (buf, sig_algo_table[i].oidstring, buflen))
900 if (buflen == strlen (sig_algo_table[i].algo_string)
901 && !memcmp (buf, sig_algo_table[i].algo_string, buflen))
904 if (sig_algo_table[i].oid)
906 *r_pkalgo = sig_algo_table[i].pkalgo;
907 *oidlen = sig_algo_table[i].oidlen;
908 return sig_algo_table[i].oid;
912 /* Scan the standard table. */
913 for (i=0; pk_algo_table[i].oid; i++)
915 if (!pk_algo_table[i].supported)
917 if (buflen == strlen (pk_algo_table[i].oidstring)
918 && !memcmp (buf, pk_algo_table[i].oidstring, buflen))
920 if (buflen == strlen (pk_algo_table[i].algo_string)
921 && !memcmp (buf, pk_algo_table[i].algo_string, buflen))
924 if (!pk_algo_table[i].oid)
927 *r_pkalgo = pk_algo_table[i].pkalgo;
928 *oidlen = pk_algo_table[i].oidlen;
929 return pk_algo_table[i].oid;
933 /* Take a public-key S-Exp and convert it into a DER encoded
936 _ksba_keyinfo_from_sexp (ksba_const_sexp_t sexp,
937 unsigned char **r_der, size_t *r_derlen)
940 const unsigned char *s;
943 const unsigned char *oid;
945 unsigned char *curve_oid = NULL;
952 const unsigned char *value;
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;
966 return gpg_error (GPG_ERR_INV_VALUE);
970 return gpg_error (GPG_ERR_INV_SEXP);
973 n = strtoul (s, &endp, 10);
976 return gpg_error (GPG_ERR_INV_SEXP); /* we don't allow empty lengths */
978 if (n != 10 || memcmp (s, "public-key", 10))
979 return gpg_error (GPG_ERR_UNKNOWN_SEXP);
982 return gpg_error (digitp (s)? GPG_ERR_UNKNOWN_SEXP : GPG_ERR_INV_SEXP);
985 /* Break out the algorithm ID */
986 n = strtoul (s, &endp, 10);
989 return gpg_error (GPG_ERR_INV_SEXP); /* we don't allow empty lengths */
991 oid = oid_from_buffer (s, n, &oidlen, &pkalgo, 0);
993 return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
996 /* Collect all the values */
997 for (parmidx = 0; *s != ')' ; parmidx++)
999 if (parmidx >= DIM(parm))
1000 return gpg_error (GPG_ERR_GENERAL);
1002 return gpg_error (digitp(s)? GPG_ERR_UNKNOWN_SEXP:GPG_ERR_INV_SEXP);
1004 n = strtoul (s, &endp, 10);
1006 if (!n || *s != ':')
1007 return gpg_error (GPG_ERR_INV_SEXP);
1009 parm[parmidx].name = s;
1010 parm[parmidx].namelen = n;
1013 return gpg_error (GPG_ERR_UNKNOWN_SEXP); /* ... or invalid S-Exp. */
1015 n = strtoul (s, &endp, 10);
1017 if (!n || *s != ':')
1018 return gpg_error (GPG_ERR_INV_SEXP);
1020 parm[parmidx].value = s;
1021 parm[parmidx].valuelen = n;
1024 return gpg_error (GPG_ERR_UNKNOWN_SEXP); /* ... or invalid S-Exp. */
1028 /* We need another closing parenthesis. */
1030 return gpg_error (GPG_ERR_INV_SEXP);
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;
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);
1046 for (s = parmdesc; *s; s++)
1048 for (i=0; i < parmidx; i++)
1050 assert (idxtbllen < DIM (idxtbl));
1053 case 'C': /* Magic value for "curve". */
1054 if (parm[i].namelen == 5 && !memcmp (parm[i].name, "curve", 5))
1056 idxtbl[idxtbllen++] = i;
1057 i = parmidx; /* Break inner loop. */
1061 if (parm[i].namelen == 1 && parm[i].name[0] == *s)
1063 idxtbl[idxtbllen++] = i;
1064 i = parmidx; /* Break inner loop. */
1070 if (idxtbllen != strlen (parmdesc))
1071 return gpg_error (GPG_ERR_UNKNOWN_SEXP);
1073 if (pkalgo == PKALGO_ECC)
1075 curve_oid = get_ecc_curve_oid (parm[idxtbl[0]].value,
1076 parm[idxtbl[0]].valuelen,
1079 return gpg_error (GPG_ERR_UNKNOWN_SEXP);
1083 /* Create write object. */
1084 err = ksba_writer_new (&writer);
1087 err = ksba_writer_set_mem (writer, 1024);
1091 /* We create the keyinfo in 2 steps:
1093 1. We build the inner one and encapsulate it in a bit string.
1095 2. We create the outer sequence include the algorithm identifier
1096 and the bit string from step 1.
1098 if (pkalgo == PKALGO_ECC)
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);
1104 err = ksba_writer_write (writer, "", 1);
1105 /* And the actual raw value. */
1107 err = ksba_writer_write (writer, parm[idxtbl[1]].value,
1108 parm[idxtbl[1]].valuelen);
1113 else /* RSA and DSA */
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++ )
1120 n += _ksba_ber_count_tl (TYPE_INTEGER, CLASS_UNIVERSAL, 0,
1121 parm[idxtbl[i]].valuelen);
1122 n += parm[idxtbl[i]].valuelen;
1125 n1 = 1; /* # of unused bits. */
1127 n1 += _ksba_ber_count_tl (TYPE_SEQUENCE, CLASS_UNIVERSAL, 1, n);
1130 /* Write the bit string header and the number of unused bits. */
1131 err = _ksba_ber_write_tl (writer, TYPE_BIT_STRING, CLASS_UNIVERSAL,
1134 err = ksba_writer_write (writer, "", 1);
1138 /* Write the sequence tag and the integers. */
1140 err = _ksba_ber_write_tl (writer, TYPE_SEQUENCE, CLASS_UNIVERSAL, 1,n);
1143 for (i=0; i < idxtbllen; i++)
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);
1150 err = ksba_writer_write (writer, parm[idxtbl[i]].value,
1151 parm[idxtbl[i]].valuelen);
1157 /* Get the encoded bit string. */
1158 bitstr_value = ksba_writer_snatch_mem (writer, &bitstr_len);
1161 err = gpg_error (GPG_ERR_ENOMEM);
1165 /* If the algorithmIdentifier requires a sequence with parameters,
1166 build them now. We can reuse the IDXTBL for that. */
1170 for (s = algoparmdesc; *s; s++)
1172 for (i=0; i < parmidx; i++)
1174 assert (idxtbllen < DIM (idxtbl));
1175 if (parm[i].namelen == 1 && parm[i].name[0] == *s)
1177 idxtbl[idxtbllen++] = i;
1182 if (idxtbllen != strlen (algoparmdesc))
1183 return gpg_error (GPG_ERR_UNKNOWN_SEXP);
1185 err = ksba_writer_set_mem (writer, 1024);
1189 /* Calculate the size of the sequence. */
1190 for (n=0, i=0; i < idxtbllen; i++ )
1192 n += _ksba_ber_count_tl (TYPE_INTEGER, CLASS_UNIVERSAL, 0,
1193 parm[idxtbl[i]].valuelen);
1194 n += parm[idxtbl[i]].valuelen;
1196 /* n += _ksba_ber_count_tl (TYPE_SEQUENCE, CLASS_UNIVERSAL, 1, n); */
1198 /* Write the sequence tag followed by the integers. */
1199 err = _ksba_ber_write_tl (writer, TYPE_SEQUENCE, CLASS_UNIVERSAL, 1, n);
1202 for (i=0; i < idxtbllen; i++)
1204 err = _ksba_ber_write_tl (writer, TYPE_INTEGER, CLASS_UNIVERSAL, 0,
1205 parm[idxtbl[i]].valuelen);
1207 err = ksba_writer_write (writer, parm[idxtbl[i]].value,
1208 parm[idxtbl[i]].valuelen);
1213 /* Get the encoded sequence. */
1214 algoparmseq_value = ksba_writer_snatch_mem (writer, &algoparmseq_len);
1215 if (!algoparmseq_value)
1217 err = gpg_error (GPG_ERR_ENOMEM);
1222 algoparmseq_len = 0;
1224 /* Reinitialize the buffer to create the outer sequence. */
1225 err = ksba_writer_set_mem (writer, 1024);
1229 /* Calulate lengths. */
1230 n = _ksba_ber_count_tl (TYPE_OBJECT_ID, CLASS_UNIVERSAL, 0, oidlen);
1232 if (algoparmseq_len)
1234 n += algoparmseq_len;
1236 else if (pkalgo == PKALGO_ECC)
1238 n += _ksba_ber_count_tl (TYPE_OBJECT_ID, CLASS_UNIVERSAL,
1242 else if (pkalgo == PKALGO_RSA)
1244 n += _ksba_ber_count_tl (TYPE_NULL, CLASS_UNIVERSAL, 0, 0);
1248 n1 += _ksba_ber_count_tl (TYPE_SEQUENCE, CLASS_UNIVERSAL, 1, n);
1251 /* The outer sequence. */
1252 err = _ksba_ber_write_tl (writer, TYPE_SEQUENCE, CLASS_UNIVERSAL, 1, n1);
1257 err = _ksba_ber_write_tl (writer, TYPE_SEQUENCE, CLASS_UNIVERSAL, 1, n);
1261 /* The object id. */
1262 err = _ksba_ber_write_tl (writer, TYPE_OBJECT_ID,CLASS_UNIVERSAL, 0, oidlen);
1264 err = ksba_writer_write (writer, oid, oidlen);
1268 /* The parameter. */
1269 if (algoparmseq_len)
1271 err = ksba_writer_write (writer, algoparmseq_value, algoparmseq_len);
1273 else if (pkalgo == PKALGO_ECC)
1275 err = _ksba_ber_write_tl (writer, TYPE_OBJECT_ID, CLASS_UNIVERSAL,
1278 err = ksba_writer_write (writer, curve_oid, curve_oidlen);
1280 else if (pkalgo == PKALGO_RSA)
1282 err = _ksba_ber_write_tl (writer, TYPE_NULL, CLASS_UNIVERSAL, 0, 0);
1287 /* Append the pre-constructed bit string. */
1288 err = ksba_writer_write (writer, bitstr_value, bitstr_len);
1292 /* Get the result. */
1293 *r_der = ksba_writer_snatch_mem (writer, r_derlen);
1295 err = gpg_error (GPG_ERR_ENOMEM);
1298 ksba_writer_release (writer);
1299 xfree (bitstr_value);
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. */
1309 _ksba_algoinfo_from_sexp (ksba_const_sexp_t sexp,
1310 unsigned char **r_der, size_t *r_derlen)
1313 const unsigned char *s;
1316 const unsigned char *oid;
1318 unsigned char *curve_oid = NULL;
1319 size_t curve_oidlen;
1325 const unsigned char *value;
1331 const char *parmdesc, *algoparmdesc;
1332 ksba_writer_t writer = NULL;
1333 void *algoparmseq_value = NULL;
1334 size_t algoparmseq_len;
1337 return gpg_error (GPG_ERR_INV_VALUE);
1341 return gpg_error (GPG_ERR_INV_SEXP);
1344 n = strtoul (s, &endp, 10);
1346 if (!n || *s != ':')
1347 return gpg_error (GPG_ERR_INV_SEXP); /* We don't allow empty lengths. */
1349 if (n == 7 && !memcmp (s, "sig-val", 7))
1351 else if (n == 10 && !memcmp (s, "public-key", 10))
1354 return gpg_error (GPG_ERR_UNKNOWN_SEXP);
1357 return gpg_error (digitp (s)? GPG_ERR_UNKNOWN_SEXP : GPG_ERR_INV_SEXP);
1360 /* Break out the algorithm ID */
1361 n = strtoul (s, &endp, 10);
1363 if (!n || *s != ':')
1364 return gpg_error (GPG_ERR_INV_SEXP); /* We don't allow empty lengths. */
1366 oid = oid_from_buffer (s, n, &oidlen, &pkalgo, 1);
1368 return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
1371 /* Collect all the values */
1372 for (parmidx = 0; *s != ')' ; parmidx++)
1374 if (parmidx >= DIM(parm))
1375 return gpg_error (GPG_ERR_GENERAL);
1377 return gpg_error (digitp(s)? GPG_ERR_UNKNOWN_SEXP:GPG_ERR_INV_SEXP);
1379 n = strtoul (s, &endp, 10);
1381 if (!n || *s != ':')
1382 return gpg_error (GPG_ERR_INV_SEXP);
1384 parm[parmidx].name = s;
1385 parm[parmidx].namelen = n;
1388 return gpg_error (GPG_ERR_UNKNOWN_SEXP); /* ... or invalid S-Exp. */
1390 n = strtoul (s, &endp, 10);
1392 if (!n || *s != ':')
1393 return gpg_error (GPG_ERR_INV_SEXP);
1395 parm[parmidx].value = s;
1396 parm[parmidx].valuelen = n;
1399 return gpg_error (GPG_ERR_UNKNOWN_SEXP); /* ... or invalid S-Exp. */
1403 /* We need another closing parenthesis. */
1405 return gpg_error (GPG_ERR_INV_SEXP);
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;
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);
1421 for (s = parmdesc; *s; s++)
1423 for (i=0; i < parmidx; i++)
1425 assert (idxtbllen < DIM (idxtbl));
1428 case 'C': /* Magic value for "curve". */
1429 if (parm[i].namelen == 5 && !memcmp (parm[i].name, "curve", 5))
1431 idxtbl[idxtbllen++] = i;
1432 i = parmidx; /* Break inner loop. */
1436 if (parm[i].namelen == 1 && parm[i].name[0] == *s)
1438 idxtbl[idxtbllen++] = i;
1439 i = parmidx; /* Break inner loop. */
1445 if (idxtbllen != strlen (parmdesc))
1446 return gpg_error (GPG_ERR_UNKNOWN_SEXP);
1448 if (pkalgo == PKALGO_ECC)
1450 curve_oid = get_ecc_curve_oid (parm[idxtbl[0]].value,
1451 parm[idxtbl[0]].valuelen,
1454 return gpg_error (GPG_ERR_UNKNOWN_SEXP);
1458 /* Create write object. */
1459 err = ksba_writer_new (&writer);
1462 err = ksba_writer_set_mem (writer, 1024);
1466 /* Create the sequence of the algorithm identifier. */
1468 /* If the algorithmIdentifier requires a sequence with parameters,
1469 build them now. We can reuse the IDXTBL for that. */
1473 for (s = algoparmdesc; *s; s++)
1475 for (i=0; i < parmidx; i++)
1477 assert (idxtbllen < DIM (idxtbl));
1478 if (parm[i].namelen == 1 && parm[i].name[0] == *s)
1480 idxtbl[idxtbllen++] = i;
1485 if (idxtbllen != strlen (algoparmdesc))
1486 return gpg_error (GPG_ERR_UNKNOWN_SEXP);
1488 err = ksba_writer_set_mem (writer, 1024);
1492 /* Calculate the size of the sequence. */
1493 for (n=0, i=0; i < idxtbllen; i++ )
1495 n += _ksba_ber_count_tl (TYPE_INTEGER, CLASS_UNIVERSAL, 0,
1496 parm[idxtbl[i]].valuelen);
1497 n += parm[idxtbl[i]].valuelen;
1500 /* Write the sequence tag followed by the integers. */
1501 err = _ksba_ber_write_tl (writer, TYPE_SEQUENCE, CLASS_UNIVERSAL, 1, n);
1504 for (i=0; i < idxtbllen; i++)
1506 err = _ksba_ber_write_tl (writer, TYPE_INTEGER, CLASS_UNIVERSAL, 0,
1507 parm[idxtbl[i]].valuelen);
1509 err = ksba_writer_write (writer, parm[idxtbl[i]].value,
1510 parm[idxtbl[i]].valuelen);
1515 /* Get the encoded sequence. */
1516 algoparmseq_value = ksba_writer_snatch_mem (writer, &algoparmseq_len);
1517 if (!algoparmseq_value)
1519 err = gpg_error (GPG_ERR_ENOMEM);
1524 algoparmseq_len = 0;
1526 /* Reinitialize the buffer to create the sequence. */
1527 err = ksba_writer_set_mem (writer, 1024);
1531 /* Calulate lengths. */
1532 n = _ksba_ber_count_tl (TYPE_OBJECT_ID, CLASS_UNIVERSAL, 0, oidlen);
1534 if (algoparmseq_len)
1536 n += algoparmseq_len;
1538 else if (pkalgo == PKALGO_ECC)
1540 n += _ksba_ber_count_tl (TYPE_OBJECT_ID, CLASS_UNIVERSAL,
1544 else if (pkalgo == PKALGO_RSA)
1546 n += _ksba_ber_count_tl (TYPE_NULL, CLASS_UNIVERSAL, 0, 0);
1549 /* Write the sequence. */
1550 err = _ksba_ber_write_tl (writer, TYPE_SEQUENCE, CLASS_UNIVERSAL, 1, n);
1554 /* Write the object id. */
1555 err = _ksba_ber_write_tl (writer, TYPE_OBJECT_ID, CLASS_UNIVERSAL, 0, oidlen);
1557 err = ksba_writer_write (writer, oid, oidlen);
1561 /* Write the parameters. */
1562 if (algoparmseq_len)
1564 err = ksba_writer_write (writer, algoparmseq_value, algoparmseq_len);
1566 else if (pkalgo == PKALGO_ECC)
1568 /* We only support the namedCuve choice for ECC parameters. */
1569 err = _ksba_ber_write_tl (writer, TYPE_OBJECT_ID, CLASS_UNIVERSAL,
1572 err = ksba_writer_write (writer, curve_oid, curve_oidlen);
1574 else if (pkalgo == PKALGO_RSA)
1576 err = _ksba_ber_write_tl (writer, TYPE_NULL, CLASS_UNIVERSAL, 0, 0);
1581 /* Get the result. */
1582 *r_der = ksba_writer_snatch_mem (writer, r_derlen);
1584 err = gpg_error (GPG_ERR_ENOMEM);
1587 ksba_writer_release (writer);
1594 /* Mode 0: work as described under _ksba_sigval_to_sexp
1595 mode 1: work as described under _ksba_encval_to_sexp */
1597 cryptval_to_sexp (int mode, const unsigned char *der, size_t derlen,
1598 ksba_sexp_t *r_string)
1601 const struct algo_table_s *algo_table;
1603 size_t nread, off, len;
1606 const unsigned char *ctrl;
1608 struct stringbuf sb;
1610 /* FIXME: The entire function is very similar to keyinfo_to_sexp */
1614 algo_table = sig_algo_table;
1616 algo_table = enc_algo_table;
1619 err = get_algorithm (1, der, derlen, &nread, &off, &len, &is_bitstr,
1624 /* look into our table of supported algorithms */
1625 for (algoidx=0; algo_table[algoidx].oid; algoidx++)
1627 if ( len == algo_table[algoidx].oidlen
1628 && !memcmp (der+off, algo_table[algoidx].oid, len))
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);
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
1644 return gpg_error (GPG_ERR_INV_KEYINFO);
1645 c = *der++; derlen--;
1647 fprintf (stderr, "warning: number of unused bits is not zero\n");
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);
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++)
1664 if ( (*ctrl & 0x80) && !elem[1] )
1665 { /* Hack to allow a raw value */
1672 return gpg_error (GPG_ERR_INV_KEYINFO);
1673 c = *der++; derlen--;
1675 return gpg_error (GPG_ERR_UNEXPECTED_TAG);
1679 if (is_int && *elem != '-')
1680 { /* take this integer */
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);
1689 put_stringbuf (&sb, ")");
1692 put_stringbuf (&sb, ")");
1693 if (!mode && algo_table[algoidx].digest_string)
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, ")");
1700 put_stringbuf (&sb, ")");
1702 *r_string = get_stringbuf (&sb);
1704 return gpg_error (GPG_ERR_ENOMEM);
1709 /* Assume that DER is a buffer of length DERLEN with a DER encoded
1710 Asn.1 structure like this:
1713 algorithm OBJECT IDENTIFIER,
1714 parameters ANY DEFINED BY algorithm OPTIONAL }
1715 signature BIT STRING
1717 We only allow parameters == NULL.
1719 The function parses this structure and creates a S-Exp suitable to be
1720 used as signature value in Libgcrypt:
1724 (<param_name1> <mpi>)
1726 (<param_namen> <mpi>))
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. */
1732 _ksba_sigval_to_sexp (const unsigned char *der, size_t derlen,
1733 ksba_sexp_t *r_string)
1735 return cryptval_to_sexp (0, der, derlen, r_string);
1739 /* Assume that der is a buffer of length DERLEN with a DER encoded
1740 Asn.1 structure like this:
1743 algorithm OBJECT IDENTIFIER,
1744 parameters ANY DEFINED BY algorithm OPTIONAL }
1745 encryptedKey OCTET STRING
1747 We only allow parameters == NULL.
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:
1754 (<param_name1> <mpi>)
1756 (<param_namen> <mpi>)
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. */
1762 _ksba_encval_to_sexp (const unsigned char *der, size_t derlen,
1763 ksba_sexp_t *r_string)
1765 return cryptval_to_sexp (1, der, derlen, r_string);