"Fossies" - the Fresh Open Source Software Archive

Member "libksba-1.6.0/src/keyinfo.c" (18 May 2021, 56953 Bytes) of package /linux/privat/libksba-1.6.0.tar.bz2:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "keyinfo.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.5.1_vs_1.6.0.

    1 /* keyinfo.c - Parse and build a keyInfo structure
    2  * Copyright (C) 2001, 2002, 2007, 2008, 2012, 2020 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 #include "sexp-parse.h"
   48 #include "stringbuf.h"
   49 #include "der-builder.h"
   50 
   51 /* Constants used for the public key algorithms.  */
   52 typedef enum
   53   {
   54     PKALGO_NONE,
   55     PKALGO_RSA,
   56     PKALGO_DSA,
   57     PKALGO_ECC,
   58     PKALGO_X25519,
   59     PKALGO_X448,
   60     PKALGO_ED25519,
   61     PKALGO_ED448
   62   }
   63 pkalgo_t;
   64 
   65 
   66 struct algo_table_s {
   67   const char *oidstring;
   68   const unsigned char *oid;  /* NULL indicattes end of table */
   69   int                  oidlen;
   70   int supported;  /* Values > 1 are also used to indicate hacks.  */
   71   pkalgo_t pkalgo;
   72   const char *algo_string;
   73   const char *elem_string; /* parameter names or '-', 'P' for plain ECDSA */
   74   const char *ctrl_string; /* expected tag values (value > 127 are raw data)*/
   75   const char *parmelem_string; /* parameter name or '-'. */
   76   const char *parmctrl_string; /* expected tag values.  */
   77   const char *digest_string; /* The digest algo if included in the OID. */
   78 };
   79 
   80 /* Special values for the supported field.  */
   81 #define SUPPORTED_RSAPSS 2
   82 
   83 
   84 static const struct algo_table_s pk_algo_table[] = {
   85 
   86   { /* iso.member-body.us.rsadsi.pkcs.pkcs-1.1 */
   87     "1.2.840.113549.1.1.1", /* rsaEncryption (RSAES-PKCA1-v1.5) */
   88     "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01", 9,
   89     1, PKALGO_RSA, "rsa", "-ne", "\x30\x02\x02" },
   90 
   91   { /* iso.member-body.us.rsadsi.pkcs.pkcs-1.7 */
   92     "1.2.840.113549.1.1.7", /* RSAES-OAEP */
   93     "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x07", 9,
   94     0, PKALGO_RSA, "rsa", "-ne", "\x30\x02\x02"},
   95 
   96   { /* iso.member-body.us.rsadsi.pkcs.pkcs-1.10 */
   97     "1.2.840.113549.1.1.10", /* rsaPSS */
   98     "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0a", 9,
   99     SUPPORTED_RSAPSS, PKALGO_RSA, "rsa", "-ne", "\x30\x02\x02"},
  100 
  101   { /* */
  102     "2.5.8.1.1", /* rsa (ambiguous due to missing padding rules)*/
  103     "\x55\x08\x01\x01", 4,
  104     1, PKALGO_RSA, "ambiguous-rsa", "-ne", "\x30\x02\x02" },
  105 
  106   { /* iso.member-body.us.x9-57.x9cm.1 */
  107     "1.2.840.10040.4.1", /*  dsa */
  108     "\x2a\x86\x48\xce\x38\x04\x01", 7,
  109     1, PKALGO_DSA, "dsa", "y", "\x02", "-pqg", "\x30\x02\x02\x02" },
  110 
  111   { /* iso.member-body.us.ansi-x9-62.2.1 */
  112     "1.2.840.10045.2.1", /*  ecPublicKey */
  113     "\x2a\x86\x48\xce\x3d\x02\x01", 7,
  114     1, PKALGO_ECC, "ecc", "q", "\x80" },
  115 
  116   { /* iso.identified-organization.thawte.110 */
  117     "1.3.101.110", /* X25519 */
  118     "\x2b\x65\x6e", 3,
  119     1, PKALGO_X25519, "ecc", "q", "\x80" },
  120 
  121   { /* iso.identified-organization.thawte.111 */
  122     "1.3.101.111", /* X448 */
  123     "\x2b\x65\x6f", 3,
  124     1, PKALGO_X448, "ecc", "q", "\x80" },
  125 
  126   { /* iso.identified-organization.thawte.112 */
  127     "1.3.101.112", /* Ed25519 */
  128     "\x2b\x65\x70", 3,
  129     1, PKALGO_ED25519, "ecc", "q", "\x80" },
  130 
  131   { /* iso.identified-organization.thawte.113 */
  132     "1.3.101.113", /* Ed448 */
  133     "\x2b\x65\x71", 3,
  134     1, PKALGO_ED448, "ecc", "q", "\x80" },
  135 
  136   {NULL}
  137 };
  138 
  139 
  140 static const struct algo_table_s sig_algo_table[] = {
  141   {  /* iso.member-body.us.rsadsi.pkcs.pkcs-1.5 */
  142     "1.2.840.113549.1.1.5", /* sha1WithRSAEncryption */
  143     "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05", 9,
  144     1, PKALGO_RSA, "rsa", "s", "\x82", NULL, NULL, "sha1" },
  145   { /* iso.member-body.us.rsadsi.pkcs.pkcs-1.4 */
  146     "1.2.840.113549.1.1.4", /* md5WithRSAEncryption */
  147     "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x04", 9,
  148     1, PKALGO_RSA, "rsa", "s", "\x82", NULL, NULL, "md5" },
  149   { /* iso.member-body.us.rsadsi.pkcs.pkcs-1.2 */
  150     "1.2.840.113549.1.1.2", /* md2WithRSAEncryption */
  151     "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x02", 9,
  152     0, PKALGO_RSA, "rsa", "s", "\x82", NULL, NULL, "md2" },
  153   { /* iso.member-body.us.x9-57.x9cm.1 */
  154     "1.2.840.10040.4.3", /* dsa */
  155     "\x2a\x86\x48\xce\x38\x04\x01", 7,
  156     1, PKALGO_DSA, "dsa", "-rs", "\x30\x02\x02" },
  157   { /* iso.member-body.us.x9-57.x9cm.3 */
  158     "1.2.840.10040.4.3", /*  dsaWithSha1 */
  159     "\x2a\x86\x48\xce\x38\x04\x03", 7,
  160     1, PKALGO_DSA, "dsa", "-rs", "\x30\x02\x02", NULL, NULL, "sha1" },
  161   { /* Teletrust signature algorithm.  */
  162     "1.3.36.8.5.1.2.2", /* dsaWithRIPEMD160 */
  163     "\x2b\x24\x08\x05\x01\x02\x02", 7,
  164     1, PKALGO_DSA, "dsa", "-rs", "\x30\x02\x02", NULL, NULL, "rmd160" },
  165   { /* NIST Algorithm */
  166     "2.16.840.1.101.3.4.3.1", /* dsaWithSha224 */
  167     "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x03\x01", 11,
  168     1, PKALGO_DSA, "dsa", "-rs", "\x30\x02\x02", NULL, NULL, "sha224" },
  169   { /* NIST Algorithm (the draft also used .1 but we better use .2) */
  170     "2.16.840.1.101.3.4.3.2", /* dsaWithSha256 */
  171     "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x03\x01", 11,
  172     1, PKALGO_DSA, "dsa", "-rs", "\x30\x02\x02", NULL, NULL, "sha256" },
  173 
  174   { /* iso.member-body.us.ansi-x9-62.signatures.ecdsa-with-sha1 */
  175     "1.2.840.10045.4.1", /*  ecdsa */
  176     "\x2a\x86\x48\xce\x3d\x04\x01", 7,
  177     1, PKALGO_ECC, "ecdsa", "-rs", "\x30\x02\x02", NULL, NULL, "sha1" },
  178 
  179   { /* iso.member-body.us.ansi-x9-62.signatures.ecdsa-with-specified */
  180     "1.2.840.10045.4.3",
  181     "\x2a\x86\x48\xce\x3d\x04\x03", 7,
  182     1, PKALGO_ECC, "ecdsa", "-rs", "\x30\x02\x02", NULL, NULL, NULL },
  183   /* The digest algorithm is given by the parameter.  */
  184 
  185 
  186   { /* iso.member-body.us.ansi-x9-62.signatures.ecdsa-with-sha224 */
  187     "1.2.840.10045.4.3.1",
  188     "\x2a\x86\x48\xce\x3d\x04\x03\x01", 8,
  189     1, PKALGO_ECC, "ecdsa", "-rs", "\x30\x02\x02", NULL, NULL, "sha224" },
  190 
  191   { /* iso.member-body.us.ansi-x9-62.signatures.ecdsa-with-sha256 */
  192     "1.2.840.10045.4.3.2",
  193     "\x2a\x86\x48\xce\x3d\x04\x03\x02", 8,
  194     1, PKALGO_ECC, "ecdsa", "-rs", "\x30\x02\x02", NULL, NULL, "sha256" },
  195 
  196   { /* iso.member-body.us.ansi-x9-62.signatures.ecdsa-with-sha384 */
  197     "1.2.840.10045.4.3.3",
  198     "\x2a\x86\x48\xce\x3d\x04\x03\x03", 8,
  199     1, PKALGO_ECC, "ecdsa", "-rs", "\x30\x02\x02", NULL, NULL, "sha384" },
  200 
  201   { /* iso.member-body.us.ansi-x9-62.signatures.ecdsa-with-sha512 */
  202     "1.2.840.10045.4.3.4",
  203     "\x2a\x86\x48\xce\x3d\x04\x03\x04", 8,
  204     1, PKALGO_ECC, "ecdsa", "-rs", "\x30\x02\x02", NULL, NULL, "sha512" },
  205 
  206   { /* BSI TR-03111 bsiEcdsaWithSHA1 */
  207     "0.4.0.127.0.7.1.1.4.1.1",
  208     "\x04\x00\x7f\x00\x07\x01\x01\x04\x01\x01", 10,
  209     1, PKALGO_ECC, "ecdsa", "P", "", NULL, NULL, "sha1" },
  210 
  211   { /* BSI TR-03111 bsiEcdsaWithSHA224 */
  212     "0.4.0.127.0.7.1.1.4.1.2",
  213     "\x04\x00\x7f\x00\x07\x01\x01\x04\x01\x02", 10,
  214     1, PKALGO_ECC, "ecdsa", "P", "", NULL, NULL, "sha224" },
  215 
  216   { /* BSI TR-03111 bsiEcdsaWithSHA256 */
  217     "0.4.0.127.0.7.1.1.4.1.3",
  218     "\x04\x00\x7f\x00\x07\x01\x01\x04\x01\x03", 10,
  219     1, PKALGO_ECC, "ecdsa", "P", "", NULL, NULL, "sha256" },
  220 
  221   { /* BSI TR-03111 bsiEcdsaWithSHA384 */
  222     "0.4.0.127.0.7.1.1.4.1.4",
  223     "\x04\x00\x7f\x00\x07\x01\x01\x04\x01\x04", 10,
  224     1, PKALGO_ECC, "ecdsa", "P", "", NULL, NULL, "sha384" },
  225 
  226   { /* BSI TR-03111 bsiEcdsaWithSHA512 */
  227     "0.4.0.127.0.7.1.1.4.1.5",
  228     "\x04\x00\x7f\x00\x07\x01\x01\x04\x01\x05", 10,
  229     1, PKALGO_ECC, "ecdsa", "P", "", NULL, NULL, "sha512" },
  230 
  231   { /* iso.member-body.us.rsadsi.pkcs.pkcs-1.1 */
  232     "1.2.840.113549.1.1.1", /* rsaEncryption used without hash algo*/
  233     "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01", 9,
  234     1, PKALGO_RSA, "rsa", "s", "\x82" },
  235   { /* from NIST's OIW - actually belongs in a pure hash table */
  236     "1.3.14.3.2.26",  /* sha1 */
  237     "\x2B\x0E\x03\x02\x1A", 5,
  238     0, PKALGO_RSA, "sha-1", "", "", NULL, NULL, "sha1" },
  239 
  240   { /* As used by telesec cards */
  241     "1.3.36.3.3.1.2",  /* rsaSignatureWithripemd160 */
  242     "\x2b\x24\x03\x03\x01\x02", 6,
  243     1, PKALGO_RSA, "rsa", "s", "\x82", NULL, NULL, "rmd160" },
  244 
  245   { /* from NIST's OIW - used by TU Darmstadt */
  246     "1.3.14.3.2.29",  /* sha-1WithRSAEncryption */
  247     "\x2B\x0E\x03\x02\x1D", 5,
  248     1, PKALGO_RSA, "rsa", "s", "\x82", NULL, NULL, "sha1" },
  249 
  250   { /* from PKCS#1  */
  251     "1.2.840.113549.1.1.11", /* sha256WithRSAEncryption */
  252     "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b", 9,
  253     1, PKALGO_RSA, "rsa", "s", "\x82", NULL, NULL, "sha256" },
  254 
  255   { /* from PKCS#1  */
  256     "1.2.840.113549.1.1.12", /* sha384WithRSAEncryption */
  257     "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0c", 9,
  258     1, PKALGO_RSA, "rsa", "s", "\x82", NULL, NULL, "sha384" },
  259 
  260   { /* from PKCS#1  */
  261     "1.2.840.113549.1.1.13", /* sha512WithRSAEncryption */
  262     "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0d", 9,
  263     1, PKALGO_RSA, "rsa", "s", "\x82", NULL, NULL, "sha512" },
  264 
  265   { /* iso.member-body.us.rsadsi.pkcs.pkcs-1.10 */
  266     "1.2.840.113549.1.1.10", /* rsaPSS */
  267     "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0a", 9,
  268     SUPPORTED_RSAPSS, PKALGO_RSA, "rsa", "s", "\x82", NULL, NULL, NULL},
  269 
  270   { /* TeleTrust signature scheme with RSA signature and DSI according
  271        to ISO/IEC 9796-2 with random number and RIPEMD-160.  I am not
  272        sure for what this is good; thus disabled. */
  273     "1.3.36.3.4.3.2.2",     /* sigS_ISO9796-2rndWithrsa_ripemd160 */
  274     "\x2B\x24\x03\x04\x03\x02\x02", 7,
  275     0, PKALGO_RSA, "rsa", "s", "\x82", NULL, NULL, "rmd160" },
  276 
  277 
  278   { /* iso.identified-organization.thawte.112 */
  279     "1.3.101.112", /* Ed25519 */
  280     "\x2b\x65\x70", 3,
  281     1, PKALGO_ED25519, "eddsa", "", "", NULL, NULL, NULL },
  282   { /* iso.identified-organization.thawte.113 */
  283     "1.3.101.113", /* Ed448 */
  284     "\x2b\x65\x71", 3,
  285     1, PKALGO_ED448, "eddsa", "", "", NULL, NULL, NULL },
  286 
  287   {NULL}
  288 };
  289 
  290 static const struct algo_table_s enc_algo_table[] = {
  291   {/* iso.member-body.us.rsadsi.pkcs.pkcs-1.1 */
  292    "1.2.840.113549.1.1.1", /* rsaEncryption (RSAES-PKCA1-v1.5) */
  293    "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01", 9,
  294    1, PKALGO_RSA, "rsa", "a", "\x82" },
  295   {/* iso.member-body.us.ansi-x9-62.2.1 */
  296    "1.2.840.10045.2.1", /* ecPublicKey */
  297    "\x2a\x86\x48\xce\x3d\x02\x01", 7,
  298    1, PKALGO_ECC, "ecdh", "e", "\x80" },
  299   {NULL}
  300 };
  301 
  302 
  303 /* This tables maps names of ECC curves names to OIDs.  A similar
  304    table is used by Libgcrypt.  */
  305 static const struct
  306 {
  307   const char *oid;
  308   const char *name;
  309   unsigned char pkalgo;  /* If not 0 force the use of ALGO.  */
  310 } curve_names[] =
  311   {
  312     { "1.3.101.112",         "Ed25519",    PKALGO_ED25519},
  313     { "1.3.101.110",         "Curve25519", PKALGO_X25519},
  314     { "1.3.101.110",         "X25519",     PKALGO_X25519},
  315 
  316     { "1.3.101.113",         "Ed448",      PKALGO_ED448 },
  317     { "1.3.101.111",         "X448",       PKALGO_X448  },
  318 
  319     { "1.2.840.10045.3.1.1", "NIST P-192" },
  320     { "1.2.840.10045.3.1.1", "nistp192"   },
  321     { "1.2.840.10045.3.1.1", "prime192v1" },
  322     { "1.2.840.10045.3.1.1", "secp192r1"  },
  323 
  324     { "1.3.132.0.33",        "NIST P-224" },
  325     { "1.3.132.0.33",        "nistp224"   },
  326     { "1.3.132.0.33",        "secp224r1"  },
  327 
  328     { "1.2.840.10045.3.1.7", "NIST P-256" },
  329     { "1.2.840.10045.3.1.7", "nistp256"   },
  330     { "1.2.840.10045.3.1.7", "prime256v1" },
  331     { "1.2.840.10045.3.1.7", "secp256r1"  },
  332 
  333     { "1.3.132.0.34",        "NIST P-384" },
  334     { "1.3.132.0.34",        "nistp384"   },
  335     { "1.3.132.0.34",        "secp384r1"  },
  336 
  337     { "1.3.132.0.35",        "NIST P-521" },
  338     { "1.3.132.0.35",        "nistp521"   },
  339     { "1.3.132.0.35",        "secp521r1"  },
  340 
  341     { "1.3.36.3.3.2.8.1.1.1" , "brainpoolP160r1" },
  342     { "1.3.36.3.3.2.8.1.1.3" , "brainpoolP192r1" },
  343     { "1.3.36.3.3.2.8.1.1.5" , "brainpoolP224r1" },
  344     { "1.3.36.3.3.2.8.1.1.7" , "brainpoolP256r1" },
  345     { "1.3.36.3.3.2.8.1.1.9" , "brainpoolP320r1" },
  346     { "1.3.36.3.3.2.8.1.1.11", "brainpoolP384r1" },
  347     { "1.3.36.3.3.2.8.1.1.13", "brainpoolP512r1" },
  348 
  349 
  350     { "1.2.643.2.2.35.1",    "GOST2001-CryptoPro-A" },
  351     { "1.2.643.2.2.35.2",    "GOST2001-CryptoPro-B" },
  352     { "1.2.643.2.2.35.3",    "GOST2001-CryptoPro-C" },
  353     { "1.2.643.7.1.2.1.2.1", "GOST2012-tc26-A"      },
  354     { "1.2.643.7.1.2.1.2.2", "GOST2012-tc26-B"      },
  355 
  356     { "1.3.132.0.10",        "secp256k1" },
  357 
  358     { NULL, NULL}
  359   };
  360 
  361 
  362 /* Table to map well known curve parameters to their name.  */
  363 static const struct
  364 {
  365   const char *name;
  366   unsigned int derlen;
  367   const unsigned char *der;
  368 } ecdomainparm_to_name[] =
  369   {
  370     { "brainpoolP256r1", 227,
  371       "\x30\x81\xe0\x02\x01\x01\x30\x2c\x06\x07\x2a\x86\x48\xce\x3d\x01"
  372       "\x01\x02\x21\x00\xa9\xfb\x57\xdb\xa1\xee\xa9\xbc\x3e\x66\x0a\x90"
  373       "\x9d\x83\x8d\x72\x6e\x3b\xf6\x23\xd5\x26\x20\x28\x20\x13\x48\x1d"
  374       "\x1f\x6e\x53\x77\x30\x44\x04\x20\x7d\x5a\x09\x75\xfc\x2c\x30\x57"
  375       "\xee\xf6\x75\x30\x41\x7a\xff\xe7\xfb\x80\x55\xc1\x26\xdc\x5c\x6c"
  376       "\xe9\x4a\x4b\x44\xf3\x30\xb5\xd9\x04\x20\x26\xdc\x5c\x6c\xe9\x4a"
  377       "\x4b\x44\xf3\x30\xb5\xd9\xbb\xd7\x7c\xbf\x95\x84\x16\x29\x5c\xf7"
  378       "\xe1\xce\x6b\xcc\xdc\x18\xff\x8c\x07\xb6\x04\x41\x04\x8b\xd2\xae"
  379       "\xb9\xcb\x7e\x57\xcb\x2c\x4b\x48\x2f\xfc\x81\xb7\xaf\xb9\xde\x27"
  380       "\xe1\xe3\xbd\x23\xc2\x3a\x44\x53\xbd\x9a\xce\x32\x62\x54\x7e\xf8"
  381       "\x35\xc3\xda\xc4\xfd\x97\xf8\x46\x1a\x14\x61\x1d\xc9\xc2\x77\x45"
  382       "\x13\x2d\xed\x8e\x54\x5c\x1d\x54\xc7\x2f\x04\x69\x97\x02\x21\x00"
  383       "\xa9\xfb\x57\xdb\xa1\xee\xa9\xbc\x3e\x66\x0a\x90\x9d\x83\x8d\x71"
  384       "\x8c\x39\x7a\xa3\xb5\x61\xa6\xf7\x90\x1e\x0e\x82\x97\x48\x56\xa7"
  385       "\x02\x01\x01"
  386     },
  387 
  388     { "brainpoolP384r1", 324,
  389       "\x30\x82\x01\x40\x02\x01\x01\x30\x3c\x06\x07\x2a\x86\x48\xce\x3d"
  390       "\x01\x01\x02\x31\x00\x8c\xb9\x1e\x82\xa3\x38\x6d\x28\x0f\x5d\x6f"
  391       "\x7e\x50\xe6\x41\xdf\x15\x2f\x71\x09\xed\x54\x56\xb4\x12\xb1\xda"
  392       "\x19\x7f\xb7\x11\x23\xac\xd3\xa7\x29\x90\x1d\x1a\x71\x87\x47\x00"
  393       "\x13\x31\x07\xec\x53\x30\x64\x04\x30\x7b\xc3\x82\xc6\x3d\x8c\x15"
  394       "\x0c\x3c\x72\x08\x0a\xce\x05\xaf\xa0\xc2\xbe\xa2\x8e\x4f\xb2\x27"
  395       "\x87\x13\x91\x65\xef\xba\x91\xf9\x0f\x8a\xa5\x81\x4a\x50\x3a\xd4"
  396       "\xeb\x04\xa8\xc7\xdd\x22\xce\x28\x26\x04\x30\x04\xa8\xc7\xdd\x22"
  397       "\xce\x28\x26\x8b\x39\xb5\x54\x16\xf0\x44\x7c\x2f\xb7\x7d\xe1\x07"
  398       "\xdc\xd2\xa6\x2e\x88\x0e\xa5\x3e\xeb\x62\xd5\x7c\xb4\x39\x02\x95"
  399       "\xdb\xc9\x94\x3a\xb7\x86\x96\xfa\x50\x4c\x11\x04\x61\x04\x1d\x1c"
  400       "\x64\xf0\x68\xcf\x45\xff\xa2\xa6\x3a\x81\xb7\xc1\x3f\x6b\x88\x47"
  401       "\xa3\xe7\x7e\xf1\x4f\xe3\xdb\x7f\xca\xfe\x0c\xbd\x10\xe8\xe8\x26"
  402       "\xe0\x34\x36\xd6\x46\xaa\xef\x87\xb2\xe2\x47\xd4\xaf\x1e\x8a\xbe"
  403       "\x1d\x75\x20\xf9\xc2\xa4\x5c\xb1\xeb\x8e\x95\xcf\xd5\x52\x62\xb7"
  404       "\x0b\x29\xfe\xec\x58\x64\xe1\x9c\x05\x4f\xf9\x91\x29\x28\x0e\x46"
  405       "\x46\x21\x77\x91\x81\x11\x42\x82\x03\x41\x26\x3c\x53\x15\x02\x31"
  406       "\x00\x8c\xb9\x1e\x82\xa3\x38\x6d\x28\x0f\x5d\x6f\x7e\x50\xe6\x41"
  407       "\xdf\x15\x2f\x71\x09\xed\x54\x56\xb3\x1f\x16\x6e\x6c\xac\x04\x25"
  408       "\xa7\xcf\x3a\xb6\xaf\x6b\x7f\xc3\x10\x3b\x88\x32\x02\xe9\x04\x65"
  409       "\x65\x02\x01\x01"
  410     },
  411 
  412     { "brainpoolP512r1", 422,
  413       "\x30\x82\x01\xa2\x02\x01\x01\x30\x4c\x06\x07\x2a\x86\x48\xce\x3d"
  414       "\x01\x01\x02\x41\x00\xaa\xdd\x9d\xb8\xdb\xe9\xc4\x8b\x3f\xd4\xe6"
  415       "\xae\x33\xc9\xfc\x07\xcb\x30\x8d\xb3\xb3\xc9\xd2\x0e\xd6\x63\x9c"
  416       "\xca\x70\x33\x08\x71\x7d\x4d\x9b\x00\x9b\xc6\x68\x42\xae\xcd\xa1"
  417       "\x2a\xe6\xa3\x80\xe6\x28\x81\xff\x2f\x2d\x82\xc6\x85\x28\xaa\x60"
  418       "\x56\x58\x3a\x48\xf3\x30\x81\x84\x04\x40\x78\x30\xa3\x31\x8b\x60"
  419       "\x3b\x89\xe2\x32\x71\x45\xac\x23\x4c\xc5\x94\xcb\xdd\x8d\x3d\xf9"
  420       "\x16\x10\xa8\x34\x41\xca\xea\x98\x63\xbc\x2d\xed\x5d\x5a\xa8\x25"
  421       "\x3a\xa1\x0a\x2e\xf1\xc9\x8b\x9a\xc8\xb5\x7f\x11\x17\xa7\x2b\xf2"
  422       "\xc7\xb9\xe7\xc1\xac\x4d\x77\xfc\x94\xca\x04\x40\x3d\xf9\x16\x10"
  423       "\xa8\x34\x41\xca\xea\x98\x63\xbc\x2d\xed\x5d\x5a\xa8\x25\x3a\xa1"
  424       "\x0a\x2e\xf1\xc9\x8b\x9a\xc8\xb5\x7f\x11\x17\xa7\x2b\xf2\xc7\xb9"
  425       "\xe7\xc1\xac\x4d\x77\xfc\x94\xca\xdc\x08\x3e\x67\x98\x40\x50\xb7"
  426       "\x5e\xba\xe5\xdd\x28\x09\xbd\x63\x80\x16\xf7\x23\x04\x81\x81\x04"
  427       "\x81\xae\xe4\xbd\xd8\x2e\xd9\x64\x5a\x21\x32\x2e\x9c\x4c\x6a\x93"
  428       "\x85\xed\x9f\x70\xb5\xd9\x16\xc1\xb4\x3b\x62\xee\xf4\xd0\x09\x8e"
  429       "\xff\x3b\x1f\x78\xe2\xd0\xd4\x8d\x50\xd1\x68\x7b\x93\xb9\x7d\x5f"
  430       "\x7c\x6d\x50\x47\x40\x6a\x5e\x68\x8b\x35\x22\x09\xbc\xb9\xf8\x22"
  431       "\x7d\xde\x38\x5d\x56\x63\x32\xec\xc0\xea\xbf\xa9\xcf\x78\x22\xfd"
  432       "\xf2\x09\xf7\x00\x24\xa5\x7b\x1a\xa0\x00\xc5\x5b\x88\x1f\x81\x11"
  433       "\xb2\xdc\xde\x49\x4a\x5f\x48\x5e\x5b\xca\x4b\xd8\x8a\x27\x63\xae"
  434       "\xd1\xca\x2b\x2f\xa8\xf0\x54\x06\x78\xcd\x1e\x0f\x3a\xd8\x08\x92"
  435       "\x02\x41\x00\xaa\xdd\x9d\xb8\xdb\xe9\xc4\x8b\x3f\xd4\xe6\xae\x33"
  436       "\xc9\xfc\x07\xcb\x30\x8d\xb3\xb3\xc9\xd2\x0e\xd6\x63\x9c\xca\x70"
  437       "\x33\x08\x70\x55\x3e\x5c\x41\x4c\xa9\x26\x19\x41\x86\x61\x19\x7f"
  438       "\xac\x10\x47\x1d\xb1\xd3\x81\x08\x5d\xda\xdd\xb5\x87\x96\x82\x9c"
  439       "\xa9\x00\x69\x02\x01\x01"
  440     },
  441 
  442     { NULL }
  443   };
  444 
  445 
  446 #define TLV_LENGTH(prefix) do {         \
  447   if (!prefix ## len)                    \
  448     return gpg_error (GPG_ERR_INV_KEYINFO);  \
  449   c = *(prefix)++; prefix ## len--;           \
  450   if (c == 0x80)                  \
  451     return gpg_error (GPG_ERR_NOT_DER_ENCODED);  \
  452   if (c == 0xff)                  \
  453     return gpg_error (GPG_ERR_BAD_BER);        \
  454                                   \
  455   if ( !(c & 0x80) )              \
  456     len = c;                      \
  457   else                            \
  458     {                             \
  459       int count = c & 0x7f;       \
  460                                   \
  461       for (len=0; count; count--) \
  462         {                         \
  463           len <<= 8;              \
  464           if (!prefix ## len)            \
  465             return gpg_error (GPG_ERR_BAD_BER);\
  466           c = *(prefix)++; prefix ## len--;   \
  467           len |= c & 0xff;        \
  468         }                         \
  469     }                             \
  470   if (len > prefix ## len)               \
  471     return gpg_error (GPG_ERR_INV_KEYINFO);  \
  472 } while (0)
  473 
  474 
  475 /* Given a string BUF of length BUFLEN with either a curve name or its
  476  * OID in dotted form return a string in dotted form of the name.  The
  477  * caller must free the result.  On error NULL is returned.  If a
  478  * curve requires the use of a certain algorithm, that algorithm is
  479  * stored at R_PKALGO.  */
  480 static char *
  481 get_ecc_curve_oid (const unsigned char *buf, size_t buflen, pkalgo_t *r_pkalgo)
  482 {
  483   unsigned char *result;
  484   int i, find_pkalgo;
  485 
  486   /* Skip an optional "oid." prefix. */
  487   if (buflen > 4 && buf[3] == '.' && digitp (buf+4)
  488       && ((buf[0] == 'o' && buf[1] == 'i' && buf[2] == 'd')
  489           ||(buf[0] == 'O' && buf[1] == 'I' && buf[2] == 'D')))
  490     {
  491       buf += 4;
  492       buflen -= 4;
  493     }
  494 
  495   /* If it does not look like an OID - map it through the table.  */
  496   if (buflen && !digitp (buf))
  497     {
  498       for (i=0; curve_names[i].oid; i++)
  499         if (buflen == strlen (curve_names[i].name)
  500             && !memcmp (buf, curve_names[i].name, buflen))
  501           break;
  502       if (!curve_names[i].oid)
  503         return NULL; /* Not found.  */
  504       buf = curve_names[i].oid;
  505       buflen = strlen (curve_names[i].oid);
  506       *r_pkalgo = curve_names[i].pkalgo;
  507       find_pkalgo = 0;
  508     }
  509   else
  510     find_pkalgo = 1;
  511 
  512   result = xtrymalloc (buflen + 1);
  513   if (!result)
  514     return NULL; /* Ooops */
  515   memcpy (result, buf, buflen);
  516   result[buflen] = 0;
  517 
  518   if (find_pkalgo)
  519     {
  520       /* We still need to check whether the OID requires a certain ALGO.  */
  521       for (i=0; curve_names[i].oid; i++)
  522         if (!strcmp (curve_names[i].oid, result))
  523           {
  524             *r_pkalgo = curve_names[i].pkalgo;
  525             break;
  526           }
  527     }
  528 
  529   return result;
  530 }
  531 
  532 
  533 
  534 /* Return the OFF and the LEN of algorithm within DER.  Do some checks
  535    and return the number of bytes read in r_nread, adding this to der
  536    does point into the BIT STRING.
  537 
  538    mode 0: just get the algorithm identifier. FIXME: should be able to
  539            handle BER Encoding.
  540    mode 1: as described.
  541  */
  542 static gpg_error_t
  543 get_algorithm (int mode, const unsigned char *der, size_t derlen, int firsttag,
  544                size_t *r_nread, size_t *r_pos, size_t *r_len, int *r_bitstr,
  545                size_t *r_parm_pos, size_t *r_parm_len, int *r_parm_type)
  546 {
  547   int c;
  548   const unsigned char *start = der;
  549   const unsigned char *startseq;
  550   unsigned long seqlen, len;
  551 
  552   *r_bitstr = 0;
  553   if (r_parm_pos)
  554     *r_parm_pos = 0;
  555   if (r_parm_len)
  556     *r_parm_len = 0;
  557   if (r_parm_type)
  558     *r_parm_type = 0;
  559   /* get the inner sequence */
  560   if (!derlen)
  561     return gpg_error (GPG_ERR_INV_KEYINFO);
  562   c = *der++; derlen--;
  563   if ( c != firsttag )
  564     return gpg_error (GPG_ERR_UNEXPECTED_TAG); /* not a SEQUENCE  or whatever */
  565   TLV_LENGTH(der);
  566   seqlen = len;
  567   startseq = der;
  568 
  569   /* get the object identifier */
  570   if (!derlen)
  571     return gpg_error (GPG_ERR_INV_KEYINFO);
  572   c = *der++; derlen--;
  573   if ( c != 0x06 )
  574     return gpg_error (GPG_ERR_UNEXPECTED_TAG); /* not an OBJECT IDENTIFIER */
  575   TLV_LENGTH(der);
  576 
  577   /* der does now point to an oid of length LEN */
  578   *r_pos = der - start;
  579   *r_len = len;
  580   der += len;
  581   derlen -= len;
  582   seqlen -= der - startseq;;
  583 
  584   /* Parse the parameter.  */
  585   if (seqlen)
  586     {
  587       const unsigned char *startparm = der;
  588 
  589       if (!derlen)
  590         return gpg_error (GPG_ERR_INV_KEYINFO);
  591       c = *der++; derlen--;
  592       if ( c == 0x05 )
  593         {
  594           /* gpgrt_log_debug ("%s: parameter: NULL \n", __func__); */
  595           if (!derlen)
  596             return gpg_error (GPG_ERR_INV_KEYINFO);
  597           c = *der++; derlen--;
  598           if (c)
  599             return gpg_error (GPG_ERR_BAD_BER);  /* NULL must have a
  600                                                     length of 0 */
  601           seqlen -= 2;
  602         }
  603       else if (r_parm_pos && r_parm_len && c == 0x04)
  604         {
  605           /*  This is an octet string parameter and we need it.  */
  606           if (r_parm_type)
  607             *r_parm_type = TYPE_OCTET_STRING;
  608           TLV_LENGTH(der);
  609           *r_parm_pos = der - start;
  610           *r_parm_len = len;
  611           seqlen -= der - startparm;
  612           der += len;
  613           derlen -= len;
  614           seqlen -= len;
  615         }
  616       else if (r_parm_pos && r_parm_len && c == 0x06)
  617         {
  618           /*  This is an object identifier.  */
  619           if (r_parm_type)
  620             *r_parm_type = TYPE_OBJECT_ID;
  621           TLV_LENGTH(der);
  622           *r_parm_pos = der - start;
  623           *r_parm_len = len;
  624           seqlen -= der - startparm;
  625           der += len;
  626           derlen -= len;
  627           seqlen -= len;
  628         }
  629       else if (r_parm_pos && r_parm_len && c == 0x30)
  630         {
  631           /*  This is a sequence. */
  632           if (r_parm_type)
  633             *r_parm_type = TYPE_SEQUENCE;
  634           TLV_LENGTH(der);
  635           *r_parm_pos = startparm - start;
  636           *r_parm_len = len + (der - startparm);
  637           seqlen -= der - startparm;
  638           der += len;
  639           derlen -= len;
  640           seqlen -= len;
  641         }
  642       else
  643         {
  644 /*            printf ("parameter: with tag %02x - ignored\n", c); */
  645           TLV_LENGTH(der);
  646           seqlen -= der - startparm;
  647           /* skip the value */
  648           der += len;
  649           derlen -= len;
  650           seqlen -= len;
  651         }
  652     }
  653 
  654   if (seqlen)
  655     return gpg_error (GPG_ERR_INV_KEYINFO);
  656 
  657   if (mode)
  658     {
  659       /* move forward to the BIT_STR */
  660       if (!derlen)
  661         return gpg_error (GPG_ERR_INV_KEYINFO);
  662       c = *der++; derlen--;
  663 
  664       if (c == 0x03)
  665         *r_bitstr = 1; /* BIT STRING */
  666       else if (c == 0x04)
  667         ; /* OCTECT STRING */
  668       else
  669         return gpg_error (GPG_ERR_UNEXPECTED_TAG); /* not a BIT STRING */
  670       TLV_LENGTH(der);
  671     }
  672 
  673   *r_nread = der - start;
  674   return 0;
  675 }
  676 
  677 
  678 gpg_error_t
  679 _ksba_parse_algorithm_identifier (const unsigned char *der, size_t derlen,
  680                                   size_t *r_nread, char **r_oid)
  681 {
  682   return _ksba_parse_algorithm_identifier3 (der, derlen, 0x30,
  683                                             r_nread, r_oid, NULL, NULL, NULL);
  684 }
  685 
  686 
  687 gpg_error_t
  688 _ksba_parse_algorithm_identifier2 (const unsigned char *der, size_t derlen,
  689                                    size_t *r_nread, char **r_oid,
  690                                    char **r_parm, size_t *r_parmlen)
  691 {
  692   return _ksba_parse_algorithm_identifier3 (der, derlen, 0x30,
  693                                             r_nread, r_oid,
  694                                             r_parm, r_parmlen, NULL);
  695 }
  696 
  697 
  698 /* Note that R_NREAD, R_PARM, and R_PARMLEN are optional.  */
  699 gpg_error_t
  700 _ksba_parse_algorithm_identifier3 (const unsigned char *der, size_t derlen,
  701                                    int firsttag,
  702                                    size_t *r_nread, char **r_oid,
  703                                    char **r_parm, size_t *r_parmlen,
  704                                    int *r_parmtype)
  705 {
  706   gpg_error_t err;
  707   int is_bitstr;
  708   size_t nread, off, len, off2, len2;
  709   int parm_type;
  710 
  711   /* fixme: get_algorithm might return the error invalid keyinfo -
  712      this should be invalid algorithm identifier */
  713   *r_oid = NULL;
  714   if (r_nread)
  715     *r_nread = 0;
  716   off2 = len2 = 0;
  717   err = get_algorithm (0, der, derlen, firsttag,
  718                        &nread, &off, &len, &is_bitstr,
  719                        &off2, &len2, &parm_type);
  720   if (err)
  721     return err;
  722   if (r_nread)
  723     *r_nread = nread;
  724   *r_oid = ksba_oid_to_str (der+off, len);
  725   if (!*r_oid)
  726     return gpg_error (GPG_ERR_ENOMEM);
  727 
  728   /* Special hack for ecdsaWithSpecified.  We replace the returned OID
  729      by the one in the parameter. */
  730   if (off2 && len2 && parm_type == TYPE_SEQUENCE && firsttag == 0x30
  731       && !strcmp (*r_oid, "1.2.840.10045.4.3"))
  732     {
  733       xfree (*r_oid);
  734       *r_oid = NULL;
  735       err = get_algorithm (0, der+off2, len2, 0x30,
  736                            &nread, &off, &len, &is_bitstr,
  737                            NULL, NULL, NULL);
  738       if (err)
  739         {
  740           if (r_nread)
  741             *r_nread = 0;
  742           return err;
  743         }
  744       *r_oid = ksba_oid_to_str (der+off2+off, len);
  745       if (!*r_oid)
  746         {
  747           if (r_nread)
  748             *r_nread = 0;
  749           return gpg_error (GPG_ERR_ENOMEM);
  750         }
  751 
  752       off2 = len2 = 0; /* So that R_PARM is set to NULL.  */
  753     }
  754 
  755   if (r_parm && r_parmlen)
  756     {
  757       if (off2 && len2)
  758         {
  759           *r_parm = xtrymalloc (len2);
  760           if (!*r_parm)
  761             {
  762               xfree (*r_oid);
  763               *r_oid = NULL;
  764               return gpg_error (GPG_ERR_ENOMEM);
  765             }
  766           memcpy (*r_parm, der+off2, len2);
  767           *r_parmlen = len2;
  768         }
  769       else
  770         {
  771           *r_parm = NULL;
  772           *r_parmlen = 0;
  773         }
  774     }
  775   if (r_parmtype)
  776     *r_parmtype = parm_type;
  777 
  778   return 0;
  779 }
  780 
  781 
  782 /* Assume that DER is a buffer of length DERLEN with a DER encoded
  783    ASN.1 structure like this:
  784 
  785   keyInfo ::= SEQUENCE {
  786                  SEQUENCE {
  787                     algorithm    OBJECT IDENTIFIER,
  788                     parameters   ANY DEFINED BY algorithm OPTIONAL }
  789                  publicKey  BIT STRING }
  790 
  791   The function parses this structure and create a SEXP suitable to be
  792   used as a public key in Libgcrypt.  The S-Exp will be returned in a
  793   string which the caller must free.
  794 
  795   We don't pass an ASN.1 node here but a plain memory block.  */
  796 
  797 gpg_error_t
  798 _ksba_keyinfo_to_sexp (const unsigned char *der, size_t derlen,
  799                        ksba_sexp_t *r_string)
  800 {
  801   gpg_error_t err;
  802   int c, i;
  803   size_t nread, off, len, parm_off, parm_len;
  804   int parm_type;
  805   char *parm_oid = NULL;
  806   int algoidx;
  807   int is_bitstr;
  808   int got_curve = 0;
  809   const unsigned char *parmder = NULL;
  810   size_t parmderlen = 0;
  811   const unsigned char *ctrl;
  812   const char *elem;
  813   struct stringbuf sb;
  814 
  815   *r_string = NULL;
  816 
  817   /* check the outer sequence */
  818   if (!derlen)
  819     return gpg_error (GPG_ERR_INV_KEYINFO);
  820   c = *der++; derlen--;
  821   if ( c != 0x30 )
  822     return gpg_error (GPG_ERR_UNEXPECTED_TAG); /* not a SEQUENCE */
  823   TLV_LENGTH(der);
  824   /* and now the inner part */
  825   err = get_algorithm (1, der, derlen, 0x30,
  826                        &nread, &off, &len, &is_bitstr,
  827                        &parm_off, &parm_len, &parm_type);
  828   if (err)
  829     return err;
  830 
  831   /* look into our table of supported algorithms */
  832   for (algoidx=0; pk_algo_table[algoidx].oid; algoidx++)
  833     {
  834       if ( len == pk_algo_table[algoidx].oidlen
  835            && !memcmp (der+off, pk_algo_table[algoidx].oid, len))
  836         break;
  837     }
  838   if (!pk_algo_table[algoidx].oid)
  839     return gpg_error (GPG_ERR_UNKNOWN_ALGORITHM);
  840   if (!pk_algo_table[algoidx].supported)
  841     return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
  842 
  843   if (parm_off && parm_len && parm_type == TYPE_OBJECT_ID)
  844     parm_oid = ksba_oid_to_str (der+parm_off, parm_len);
  845   else if (parm_off && parm_len)
  846     {
  847       parmder = der + parm_off;
  848       parmderlen = parm_len;
  849     }
  850 
  851   der += nread;
  852   derlen -= nread;
  853 
  854   if (is_bitstr)
  855     { /* Funny: X.509 defines the signature value as a bit string but
  856          CMS as an octet string - for ease of implementation we always
  857          allow both */
  858       if (!derlen)
  859         {
  860           xfree (parm_oid);
  861           return gpg_error (GPG_ERR_INV_KEYINFO);
  862         }
  863       c = *der++; derlen--;
  864       if (c)
  865         fprintf (stderr, "warning: number of unused bits is not zero\n");
  866     }
  867 
  868   /* fixme: we should calculate the initial length form the size of the
  869      sequence, so that we don't need a realloc later */
  870   init_stringbuf (&sb, 100);
  871   put_stringbuf (&sb, "(10:public-key(");
  872 
  873   /* fixme: we can also use the oidstring here and prefix it with
  874      "oid." - this way we can pass more information into Libgcrypt or
  875      whatever library is used */
  876   put_stringbuf_sexp (&sb, pk_algo_table[algoidx].algo_string);
  877 
  878   /* Insert the curve name for ECC. */
  879   if (pk_algo_table[algoidx].pkalgo == PKALGO_ECC && parm_oid)
  880     {
  881       put_stringbuf (&sb, "(");
  882       put_stringbuf_sexp (&sb, "curve");
  883       put_stringbuf_sexp (&sb, parm_oid);
  884       put_stringbuf (&sb, ")");
  885       got_curve = 1;
  886     }
  887   else if (pk_algo_table[algoidx].pkalgo == PKALGO_ED25519
  888            || pk_algo_table[algoidx].pkalgo == PKALGO_ED448
  889            || pk_algo_table[algoidx].pkalgo == PKALGO_X25519
  890            || pk_algo_table[algoidx].pkalgo == PKALGO_X448)
  891     {
  892       put_stringbuf (&sb, "(");
  893       put_stringbuf_sexp (&sb, "curve");
  894       put_stringbuf_sexp (&sb, pk_algo_table[algoidx].oidstring);
  895       put_stringbuf (&sb, ")");
  896     }
  897 
  898   /* If parameters are given and we have a description for them, parse
  899      them. */
  900   if (parmder && parmderlen
  901       && pk_algo_table[algoidx].parmelem_string
  902       && pk_algo_table[algoidx].parmctrl_string)
  903     {
  904       elem = pk_algo_table[algoidx].parmelem_string;
  905       ctrl = pk_algo_table[algoidx].parmctrl_string;
  906       for (; *elem; ctrl++, elem++)
  907         {
  908           int is_int;
  909 
  910           if ( (*ctrl & 0x80) && !elem[1] )
  911             {
  912               /* Hack to allow reading a raw value.  */
  913               is_int = 1;
  914               len = parmderlen;
  915             }
  916           else
  917             {
  918               if (!parmderlen)
  919                 {
  920                   xfree (parm_oid);
  921                   return gpg_error (GPG_ERR_INV_KEYINFO);
  922                 }
  923               c = *parmder++; parmderlen--;
  924               if ( c != *ctrl )
  925                 {
  926                   xfree (parm_oid);
  927                   return gpg_error (GPG_ERR_UNEXPECTED_TAG);
  928                 }
  929               is_int = c == 0x02;
  930               TLV_LENGTH (parmder);
  931             }
  932           if (is_int && *elem != '-')  /* Take this integer.  */
  933             {
  934               char tmp[2];
  935 
  936               put_stringbuf (&sb, "(");
  937               tmp[0] = *elem; tmp[1] = 0;
  938               put_stringbuf_sexp (&sb, tmp);
  939               put_stringbuf_mem_sexp (&sb, parmder, len);
  940               parmder += len;
  941               parmderlen -= len;
  942               put_stringbuf (&sb, ")");
  943             }
  944         }
  945     }
  946   else if (!got_curve && parmder && parmderlen
  947            && pk_algo_table[algoidx].pkalgo == PKALGO_ECC)
  948     {
  949       /* This is ecPublicKey but has no named curve.  This is not
  950        * allowed for PKIX but we try to figure the curve name out for
  951        * some well known curves by a simple parameter match.  */
  952       for (i=0; ecdomainparm_to_name[i].name; i++)
  953         if (ecdomainparm_to_name[i].derlen == parmderlen
  954             && !memcmp (ecdomainparm_to_name[i].der, parmder, parmderlen))
  955           {
  956             put_stringbuf (&sb, "(");
  957             put_stringbuf_sexp (&sb, "curve");
  958             put_stringbuf_sexp (&sb, ecdomainparm_to_name[i].name);
  959             put_stringbuf (&sb, ")");
  960             got_curve = 1;
  961             break;
  962           }
  963       /* if (!got_curve) */
  964       /*   gpgrt_log_printhex (parmder, parmderlen, "ECDomainParm:"); */
  965     }
  966 
  967 
  968   /* FIXME: We don't release the stringbuf in case of error
  969      better let the macro jump to a label */
  970   elem = pk_algo_table[algoidx].elem_string;
  971   ctrl = pk_algo_table[algoidx].ctrl_string;
  972   for (; *elem; ctrl++, elem++)
  973     {
  974       int is_int;
  975 
  976       if ( (*ctrl & 0x80) && !elem[1] )
  977         {
  978           /* Hack to allow reading a raw value.  */
  979           is_int = 1;
  980           len = derlen;
  981         }
  982       else
  983         {
  984           if (!derlen)
  985             {
  986               xfree (parm_oid);
  987               return gpg_error (GPG_ERR_INV_KEYINFO);
  988             }
  989           c = *der++; derlen--;
  990           if ( c != *ctrl )
  991             {
  992               xfree (parm_oid);
  993               return gpg_error (GPG_ERR_UNEXPECTED_TAG);
  994             }
  995           is_int = c == 0x02;
  996           TLV_LENGTH (der);
  997         }
  998       if (is_int && *elem != '-')  /* Take this integer.  */
  999         {
 1000           char tmp[2];
 1001 
 1002           put_stringbuf (&sb, "(");
 1003           tmp[0] = *elem; tmp[1] = 0;
 1004           put_stringbuf_sexp (&sb, tmp);
 1005           put_stringbuf_mem_sexp (&sb, der, len);
 1006           der += len;
 1007           derlen -= len;
 1008           put_stringbuf (&sb, ")");
 1009         }
 1010     }
 1011   put_stringbuf (&sb, "))");
 1012   xfree (parm_oid);
 1013 
 1014   *r_string = get_stringbuf (&sb);
 1015   if (!*r_string)
 1016     return gpg_error (GPG_ERR_ENOMEM);
 1017 
 1018   return 0;
 1019 }
 1020 
 1021 
 1022 /* Match the algorithm string given in BUF which is of length BUFLEN
 1023  * with the known algorithms from our table and return the table
 1024  * entriy with the OID string.  If WITH_SIG is true, the table of
 1025  * signature algorithms is consulted first.  */
 1026 static const char *
 1027 oid_from_buffer (const unsigned char *buf, unsigned int buflen,
 1028                  pkalgo_t *r_pkalgo, int with_sig)
 1029 {
 1030   int i;
 1031 
 1032   /* Ignore an optional "oid." prefix. */
 1033   if (buflen > 4 && buf[3] == '.' && digitp (buf+4)
 1034       && ((buf[0] == 'o' && buf[1] == 'i' && buf[2] == 'd')
 1035           ||(buf[0] == 'O' && buf[1] == 'I' && buf[2] == 'D')))
 1036     {
 1037       buf += 4;
 1038       buflen -= 4;
 1039     }
 1040 
 1041   if (with_sig)
 1042     {
 1043       /* Scan the signature table first. */
 1044       for (i=0; sig_algo_table[i].oid; i++)
 1045         {
 1046           if (!sig_algo_table[i].supported)
 1047             continue;
 1048           if (buflen == strlen (sig_algo_table[i].oidstring)
 1049               && !memcmp (buf, sig_algo_table[i].oidstring, buflen))
 1050             break;
 1051           if (buflen == strlen (sig_algo_table[i].algo_string)
 1052               && !memcmp (buf, sig_algo_table[i].algo_string, buflen))
 1053             break;
 1054         }
 1055       if (sig_algo_table[i].oid)
 1056         {
 1057           *r_pkalgo = sig_algo_table[i].pkalgo;
 1058           return sig_algo_table[i].oidstring;
 1059         }
 1060     }
 1061 
 1062   /* Scan the standard table. */
 1063   for (i=0; pk_algo_table[i].oid; i++)
 1064     {
 1065       if (!pk_algo_table[i].supported)
 1066         continue;
 1067       if (buflen == strlen (pk_algo_table[i].oidstring)
 1068           && !memcmp (buf, pk_algo_table[i].oidstring, buflen))
 1069         break;
 1070       if (buflen == strlen (pk_algo_table[i].algo_string)
 1071           && !memcmp (buf, pk_algo_table[i].algo_string, buflen))
 1072         break;
 1073     }
 1074   if (!pk_algo_table[i].oid)
 1075     return NULL;
 1076 
 1077   *r_pkalgo = pk_algo_table[i].pkalgo;
 1078   return pk_algo_table[i].oidstring;
 1079 }
 1080 
 1081 
 1082 /* If ALGOINFOMODE is false: Take the "public-key" s-expression SEXP
 1083  * and convert it into a DER encoded publicKeyInfo.
 1084  *
 1085  * If ALGOINFOMODE is true: Take the "sig-val" s-expression SEXP and
 1086  * convert it into a DER encoded algorithmInfo.  */
 1087 gpg_error_t
 1088 _ksba_keyinfo_from_sexp (ksba_const_sexp_t sexp, int algoinfomode,
 1089                          unsigned char **r_der, size_t *r_derlen)
 1090 {
 1091   gpg_error_t err;
 1092   const unsigned char *s;
 1093   char *endp;
 1094   unsigned long n;
 1095   const char *algo_oid;
 1096   char *curve_oid = NULL;
 1097   pkalgo_t pkalgo, force_pkalgo;
 1098   int i;
 1099   struct {
 1100     const char *name;
 1101     int namelen;
 1102     const unsigned char *value;
 1103     int valuelen;
 1104   } parm[10];
 1105   int parmidx;
 1106   const char *parmdesc, *algoparmdesc;
 1107   ksba_der_t dbld = NULL;
 1108   ksba_der_t dbld2 = NULL;
 1109   unsigned char *tmpder;
 1110   size_t tmpderlen;
 1111 
 1112   if (!sexp)
 1113     return gpg_error (GPG_ERR_INV_VALUE);
 1114 
 1115   s = sexp;
 1116   if (*s != '(')
 1117     return gpg_error (GPG_ERR_INV_SEXP);
 1118   s++;
 1119 
 1120   n = strtoul (s, &endp, 10);
 1121   s = endp;
 1122   if (!n || *s != ':')
 1123     return gpg_error (GPG_ERR_INV_SEXP); /* We don't allow empty lengths.  */
 1124   s++;
 1125 
 1126   if (algoinfomode && n == 7 && !memcmp (s, "sig-val", 7))
 1127     s += 7;
 1128   else if (n == 10 || !memcmp (s, "public-key", 10))
 1129     s += 10;
 1130   else
 1131     return gpg_error (GPG_ERR_UNKNOWN_SEXP);
 1132 
 1133   if (*s != '(')
 1134     return gpg_error (digitp (s)? GPG_ERR_UNKNOWN_SEXP : GPG_ERR_INV_SEXP);
 1135   s++;
 1136 
 1137   /* Break out the algorithm ID */
 1138   n = strtoul (s, &endp, 10);
 1139   s = endp;
 1140   if (!n || *s != ':')
 1141     return gpg_error (GPG_ERR_INV_SEXP); /* We don't allow empty lengths.  */
 1142   s++;
 1143 
 1144   algo_oid = oid_from_buffer (s, n, &pkalgo, algoinfomode);
 1145   if (!algo_oid)
 1146     return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
 1147   s += n;
 1148 
 1149   /* Collect all the values.  */
 1150   force_pkalgo = 0;
 1151   for (parmidx = 0; *s != ')' ; parmidx++)
 1152     {
 1153       if (parmidx >= DIM(parm))
 1154         {
 1155           err = gpg_error (GPG_ERR_GENERAL);
 1156           goto leave;
 1157         }
 1158       if (*s != '(')
 1159         {
 1160           err = gpg_error (digitp(s)? GPG_ERR_UNKNOWN_SEXP:GPG_ERR_INV_SEXP);
 1161           goto leave;
 1162         }
 1163       s++;
 1164       n = strtoul (s, &endp, 10);
 1165       s = endp;
 1166       if (!n || *s != ':')
 1167         {
 1168           err = gpg_error (GPG_ERR_INV_SEXP);
 1169           goto leave;
 1170         }
 1171       s++;
 1172       parm[parmidx].name = s;
 1173       parm[parmidx].namelen = n;
 1174       s += n;
 1175       if (!digitp(s))
 1176         {
 1177           err = gpg_error (GPG_ERR_UNKNOWN_SEXP); /* ... or invalid S-Exp. */
 1178           goto leave;
 1179         }
 1180 
 1181       n = strtoul (s, &endp, 10);
 1182       s = endp;
 1183       if (!n || *s != ':')
 1184         return gpg_error (GPG_ERR_INV_SEXP);
 1185       s++;
 1186       parm[parmidx].value = s;
 1187       parm[parmidx].valuelen = n;
 1188       s += n;
 1189       if ( *s != ')')
 1190         {
 1191           err = gpg_error (GPG_ERR_UNKNOWN_SEXP); /* ... or invalid S-Exp. */
 1192           goto leave;
 1193         }
 1194       s++;
 1195 
 1196       if (parm[parmidx].namelen == 5
 1197           && !memcmp (parm[parmidx].name, "curve", 5)
 1198           && !curve_oid)
 1199         {
 1200           curve_oid = get_ecc_curve_oid (parm[parmidx].value,
 1201                                          parm[parmidx].valuelen, &force_pkalgo);
 1202           parmidx--; /* No need to store this parameter.  */
 1203         }
 1204     }
 1205   s++;
 1206   /* Allow for optional elements.  */
 1207   if (*s == '(')
 1208     {
 1209       int depth = 1;
 1210       err = sskip (&s, &depth);
 1211       if (err)
 1212         goto leave;
 1213     }
 1214   /* We need another closing parenthesis. */
 1215   if ( *s != ')' )
 1216     {
 1217       err = gpg_error (GPG_ERR_INV_SEXP);
 1218       goto leave;
 1219     }
 1220 
 1221   if (force_pkalgo)
 1222     pkalgo = force_pkalgo;
 1223 
 1224   /* Describe the parameters in the order we want them.  For DSA wie
 1225    * also set algoparmdesc so that we can later build the parameters
 1226    * for the algorithmIdentifier.  */
 1227   algoparmdesc = NULL;
 1228   switch (pkalgo)
 1229     {
 1230     case PKALGO_RSA:
 1231       parmdesc = algoinfomode? "" : "ne";
 1232       break;
 1233     case PKALGO_DSA:
 1234       parmdesc = algoinfomode? "" : "y";
 1235       algoparmdesc = "pqg";
 1236       break;
 1237     case PKALGO_ECC:
 1238       parmdesc = algoinfomode? "" : "q";
 1239       break;
 1240     case PKALGO_ED25519:
 1241     case PKALGO_X25519:
 1242     case PKALGO_ED448:
 1243     case PKALGO_X448:
 1244       parmdesc = algoinfomode? "" : "q";
 1245       if (curve_oid)
 1246         algo_oid = curve_oid;
 1247       break;
 1248     default:
 1249       err = gpg_error (GPG_ERR_UNKNOWN_ALGORITHM);
 1250       goto leave;
 1251     }
 1252 
 1253   /* Create a builder. */
 1254   dbld = _ksba_der_builder_new (0);
 1255   if (!dbld)
 1256     {
 1257       err = gpg_error_from_syserror ();
 1258       goto leave;
 1259     }
 1260 
 1261   /* The outer sequence.  */
 1262   if (!algoinfomode)
 1263     _ksba_der_add_tag (dbld, 0, TYPE_SEQUENCE);
 1264   /* The sequence.  */
 1265   _ksba_der_add_tag (dbld, 0, TYPE_SEQUENCE);
 1266   /* The object id.  */
 1267   _ksba_der_add_oid (dbld, algo_oid);
 1268 
 1269   /* The parameter. */
 1270   if (algoparmdesc)
 1271     {
 1272       /* Write the sequence tag followed by the integers. */
 1273       _ksba_der_add_tag (dbld, 0, TYPE_SEQUENCE);
 1274       for (s = algoparmdesc; *s; s++)
 1275         for (i=0; i < parmidx; i++)
 1276           if (parm[i].namelen == 1 && parm[i].name[0] == *s)
 1277             {
 1278               _ksba_der_add_int (dbld, parm[i].value, parm[i].valuelen, 1);
 1279               break; /* inner loop */
 1280             }
 1281       _ksba_der_add_end (dbld);
 1282     }
 1283   else if (pkalgo == PKALGO_ECC && !algoinfomode)
 1284     {
 1285      /* We only support the namedCurve choice for ECC parameters.  */
 1286       if (!curve_oid)
 1287         {
 1288           err = gpg_error (GPG_ERR_UNKNOWN_CURVE);
 1289           goto leave;
 1290         }
 1291       _ksba_der_add_oid (dbld, curve_oid);
 1292     }
 1293   else if (pkalgo == PKALGO_RSA)
 1294     {
 1295       _ksba_der_add_ptr (dbld, 0, TYPE_NULL, NULL, 0);
 1296     }
 1297 
 1298   _ksba_der_add_end (dbld); /* sequence.  */
 1299 
 1300   /* Add the bit string if we are not in algoinfomode.  */
 1301   if (!algoinfomode)
 1302     {
 1303       if (*parmdesc == 'q' && !parmdesc[1])
 1304         {
 1305           /* This is ECC - Q is directly written as a bit string.  */
 1306           for (i=0; i < parmidx; i++)
 1307             if (parm[i].namelen == 1 && parm[i].name[0] == 'q')
 1308               {
 1309                 if ((parm[i].valuelen & 1) && parm[i].valuelen > 32
 1310                     && (parm[i].value[0] == 0x40
 1311                         || parm[i].value[0] == 0x41
 1312                         || parm[i].value[0] == 0x42))
 1313                   {
 1314                     /* Odd length and prefixed with 0x40 - this is the
 1315                      * rfc4880bis indicator octet for extended point
 1316                      * formats - we may not emit that octet here.  */
 1317                     _ksba_der_add_bts (dbld, parm[i].value+1,
 1318                                        parm[i].valuelen-1, 0);
 1319                   }
 1320                 else
 1321                   _ksba_der_add_bts (dbld, parm[i].value, parm[i].valuelen, 0);
 1322                 break;
 1323               }
 1324         }
 1325       else  /* Non-ECC - embed the values.  */
 1326         {
 1327           dbld2 = _ksba_der_builder_new (10);
 1328           if (!dbld2)
 1329             {
 1330               err = gpg_error_from_syserror ();
 1331               goto leave;
 1332             }
 1333 
 1334           /* Note that no sequence is used if only one integer is written.  */
 1335           if (parmdesc[0] && parmdesc[1])
 1336             _ksba_der_add_tag (dbld2, 0, TYPE_SEQUENCE);
 1337 
 1338           for (s = parmdesc; *s; s++)
 1339             for (i=0; i < parmidx; i++)
 1340               if (parm[i].namelen == 1 && parm[i].name[0] == *s)
 1341                 {
 1342                   _ksba_der_add_int (dbld2, parm[i].value, parm[i].valuelen, 1);
 1343                   break; /* inner loop */
 1344                 }
 1345 
 1346           if (parmdesc[0] && parmdesc[1])
 1347             _ksba_der_add_end (dbld2);
 1348 
 1349           err = _ksba_der_builder_get (dbld2, &tmpder, &tmpderlen);
 1350           if (err)
 1351             goto leave;
 1352           _ksba_der_add_bts (dbld, tmpder, tmpderlen, 0);
 1353           xfree (tmpder);
 1354         }
 1355 
 1356       _ksba_der_add_end (dbld);  /* Outer sequence.  */
 1357     }
 1358 
 1359   /* Get the result. */
 1360   err = _ksba_der_builder_get (dbld, r_der, r_derlen);
 1361 
 1362  leave:
 1363   _ksba_der_release (dbld2);
 1364   _ksba_der_release (dbld);
 1365   xfree (curve_oid);
 1366   return err;
 1367 }
 1368 
 1369 
 1370 /* Helper function to parse the parameters used for rsaPSS.
 1371  * Given this sample DER object in (DER,DERLEN):
 1372  *
 1373  *  SEQUENCE {
 1374  *    [0] {
 1375  *      SEQUENCE {
 1376  *        OBJECT IDENTIFIER sha-512 (2 16 840 1 101 3 4 2 3)
 1377  *        }
 1378  *      }
 1379  *    [1] {
 1380  *      SEQUENCE {
 1381  *        OBJECT IDENTIFIER pkcs1-MGF (1 2 840 113549 1 1 8)
 1382  *        SEQUENCE {
 1383  *          OBJECT IDENTIFIER sha-512 (2 16 840 1 101 3 4 2 3)
 1384  *          }
 1385  *        }
 1386  *      }
 1387  *    [2] {
 1388  *      INTEGER 64
 1389  *       }
 1390  *     }
 1391  *
 1392  * The function returns the first OID at R_PSSHASH and the salt length
 1393  * at R_SALTLEN.  If the salt length is missing its default value is
 1394  * returned.  In case object does not resemble a the expected rsaPSS
 1395  * parameters GPG_ERR_INV_OBJ is returned; other errors are returned
 1396  * for an syntatically invalid object.  On error NULL is stored at
 1397  * R_PSSHASH.
 1398  */
 1399 gpg_error_t
 1400 _ksba_keyinfo_get_pss_info (const unsigned char *der, size_t derlen,
 1401                             char **r_psshash, unsigned int *r_saltlen)
 1402 {
 1403   gpg_error_t err;
 1404   struct tag_info ti;
 1405   char *psshash = NULL;
 1406   char *tmpoid = NULL;
 1407   unsigned int saltlen;
 1408 
 1409   *r_psshash = NULL;
 1410   *r_saltlen = 0;
 1411 
 1412   err = parse_sequence (&der, &derlen, &ti);
 1413   if (err)
 1414     goto leave;
 1415 
 1416   /* Get the hash algo.  */
 1417   err = parse_context_tag (&der, &derlen, &ti, 0);
 1418   if (err)
 1419     goto unknown_parms;
 1420   err = parse_sequence (&der, &derlen, &ti);
 1421   if (err)
 1422     goto unknown_parms;
 1423   err = parse_object_id_into_str (&der, &derlen, &psshash);
 1424   if (err)
 1425     goto unknown_parms;
 1426   err = parse_optional_null (&der, &derlen, NULL);
 1427   if (err)
 1428     goto unknown_parms;
 1429 
 1430   /* Check the MGF OID and that its hash algo matches. */
 1431   err = parse_context_tag (&der, &derlen, &ti, 1);
 1432   if (err)
 1433     goto unknown_parms;
 1434   err = parse_sequence (&der, &derlen, &ti);
 1435   if (err)
 1436     goto leave;
 1437   err = parse_object_id_into_str (&der, &derlen, &tmpoid);
 1438   if (err)
 1439     goto unknown_parms;
 1440   if (strcmp (tmpoid, "1.2.840.113549.1.1.8"))  /* MGF1 */
 1441     goto unknown_parms;
 1442   err = parse_sequence (&der, &derlen, &ti);
 1443   if (err)
 1444     goto leave;
 1445   xfree (tmpoid);
 1446   err = parse_object_id_into_str (&der, &derlen, &tmpoid);
 1447   if (err)
 1448     goto unknown_parms;
 1449   if (strcmp (tmpoid, psshash))
 1450     goto unknown_parms;
 1451   err = parse_optional_null (&der, &derlen, NULL);
 1452   if (err)
 1453     goto unknown_parms;
 1454 
 1455   /* Get the optional saltLength.  */
 1456   err = parse_context_tag (&der, &derlen, &ti, 2);
 1457   if (gpg_err_code (err) == GPG_ERR_INV_OBJ
 1458       || gpg_err_code (err) == GPG_ERR_FALSE)
 1459     saltlen = 20; /* Optional element - use default value */
 1460   else if (err)
 1461     goto unknown_parms;
 1462   else
 1463     {
 1464       err = parse_integer (&der, &derlen, &ti);
 1465       if (err)
 1466         goto leave;
 1467       for (saltlen=0; ti.length; ti.length--)
 1468         {
 1469           saltlen <<= 8;
 1470           saltlen |= (*der++) & 0xff;
 1471           derlen--;
 1472         }
 1473     }
 1474 
 1475   /* All fine.  */
 1476   *r_psshash = psshash;
 1477   psshash = NULL;
 1478   *r_saltlen = saltlen;
 1479   err = 0;
 1480   goto leave;
 1481 
 1482  unknown_parms:
 1483   err = gpg_error (GPG_ERR_INV_OBJ);
 1484 
 1485  leave:
 1486   xfree (psshash);
 1487   xfree (tmpoid);
 1488   return err;
 1489 }
 1490 
 1491 
 1492 /* Mode 0: work as described under _ksba_sigval_to_sexp
 1493  * mode 1: work as described under _ksba_encval_to_sexp
 1494  * mode 2: same as mode 1 but for ECDH; in this mode
 1495  *         KEYENCRYALO, KEYWRAPALGO, ENCRKEY, ENCRYKLEYLEN
 1496  *         are also required.
 1497  */
 1498 static gpg_error_t
 1499 cryptval_to_sexp (int mode, const unsigned char *der, size_t derlen,
 1500                   const char *keyencralgo, const char *keywrapalgo,
 1501                   const void *encrkey, size_t encrkeylen,
 1502                   ksba_sexp_t *r_string)
 1503 {
 1504   gpg_error_t err;
 1505   const struct algo_table_s *algo_table;
 1506   int c;
 1507   size_t nread, off, len;
 1508   int algoidx;
 1509   int is_bitstr;
 1510   const unsigned char *ctrl;
 1511   const char *elem;
 1512   struct stringbuf sb;
 1513   size_t parm_off, parm_len;
 1514   int parm_type;
 1515   char *pss_hash = NULL;
 1516   unsigned int salt_length = 0;
 1517 
 1518   /* FIXME: The entire function is very similar to keyinfo_to_sexp */
 1519   *r_string = NULL;
 1520 
 1521   if (!mode)
 1522     algo_table = sig_algo_table;
 1523   else
 1524     algo_table = enc_algo_table;
 1525 
 1526   err = get_algorithm (1, der, derlen, 0x30,
 1527                        &nread, &off, &len, &is_bitstr,
 1528                        &parm_off, &parm_len, &parm_type);
 1529   if (err)
 1530     return err;
 1531 
 1532   /* look into our table of supported algorithms */
 1533   for (algoidx=0; algo_table[algoidx].oid; algoidx++)
 1534     {
 1535       if ( len == algo_table[algoidx].oidlen
 1536            && !memcmp (der+off, algo_table[algoidx].oid, len))
 1537         break;
 1538     }
 1539 
 1540   if (!algo_table[algoidx].oid)
 1541     return gpg_error (GPG_ERR_UNKNOWN_ALGORITHM);
 1542   if (!algo_table[algoidx].supported)
 1543     return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
 1544 
 1545   if (parm_type == TYPE_SEQUENCE
 1546       && algo_table[algoidx].supported == SUPPORTED_RSAPSS)
 1547     {
 1548       /* This is rsaPSS and we collect the parameters.  We simplify
 1549        * this by assuming that pkcs1-MGF is used with an identical
 1550        * hash algorithm.  All other kinds of parameters are ignored.  */
 1551       err = _ksba_keyinfo_get_pss_info (der + parm_off, parm_len,
 1552                                         &pss_hash, &salt_length);
 1553       if (gpg_err_code (err) == GPG_ERR_INV_OBJ)
 1554         err = 0;
 1555       if (err)
 1556         return err;
 1557     }
 1558 
 1559 
 1560   der += nread;
 1561   derlen -= nread;
 1562 
 1563   if (is_bitstr)
 1564     { /* Funny: X.509 defines the signature value as a bit string but
 1565          CMS as an octet string - for ease of implementation we always
 1566          allow both */
 1567       if (!derlen)
 1568         return gpg_error (GPG_ERR_INV_KEYINFO);
 1569       c = *der++; derlen--;
 1570       if (c)
 1571         fprintf (stderr, "warning: number of unused bits is not zero\n");
 1572     }
 1573 
 1574   /* fixme: we should calculate the initial length form the size of the
 1575      sequence, so that we don't neen a realloc later */
 1576   init_stringbuf (&sb, 100);
 1577   put_stringbuf (&sb, mode? "(7:enc-val(":"(7:sig-val(");
 1578   put_stringbuf_sexp (&sb, algo_table[algoidx].algo_string);
 1579 
 1580   /* FIXME: We don't release the stringbuf in case of error
 1581      better let the macro jump to a label */
 1582   if (!mode && (algo_table[algoidx].pkalgo == PKALGO_ED25519
 1583                 ||algo_table[algoidx].pkalgo == PKALGO_ED448
 1584                 || (algo_table[algoidx].pkalgo == PKALGO_ECC
 1585                     && *algo_table[algoidx].elem_string == 'P')))
 1586     {
 1587       /* EdDSA is special: R and S are simply concatenated; see
 1588        * rfc8410.  The same code is used for Plain ECDSA format as
 1589        * specified in BSI TR-03111; we indicate this with a 'P' in the
 1590        * elem string.  */
 1591       put_stringbuf (&sb, "(1:r");
 1592       put_stringbuf_mem_sexp (&sb, der, derlen/2);
 1593       put_stringbuf (&sb, ")");
 1594       der += derlen/2;
 1595       derlen /= 2;
 1596       put_stringbuf (&sb, "(1:s");
 1597       put_stringbuf_mem_sexp (&sb, der, derlen);
 1598       put_stringbuf (&sb, ")");
 1599     }
 1600   else
 1601     {
 1602       elem = algo_table[algoidx].elem_string;
 1603       ctrl = algo_table[algoidx].ctrl_string;
 1604       for (; *elem; ctrl++, elem++)
 1605         {
 1606           int is_int;
 1607 
 1608           if ( (*ctrl & 0x80) && !elem[1] )
 1609             {  /* Hack to allow a raw value */
 1610               is_int = 1;
 1611               len = derlen;
 1612             }
 1613           else
 1614             {
 1615               if (!derlen)
 1616                 return gpg_error (GPG_ERR_INV_KEYINFO);
 1617               c = *der++; derlen--;
 1618               if ( c != *ctrl )
 1619                 return gpg_error (GPG_ERR_UNEXPECTED_TAG);
 1620               is_int = c == 0x02;
 1621               TLV_LENGTH (der);
 1622             }
 1623           if (is_int && *elem != '-')
 1624             { /* take this integer */
 1625               char tmp[2];
 1626 
 1627               put_stringbuf (&sb, "(");
 1628               tmp[0] = *elem; tmp[1] = 0;
 1629               put_stringbuf_sexp (&sb, tmp);
 1630               put_stringbuf_mem_sexp (&sb, der, len);
 1631               der += len;
 1632               derlen -= len;
 1633               put_stringbuf (&sb, ")");
 1634             }
 1635         }
 1636     }
 1637   if (mode == 2)  /* ECDH */
 1638     {
 1639       put_stringbuf (&sb, "(1:s");
 1640       put_stringbuf_mem_sexp (&sb, encrkey, encrkeylen);
 1641       put_stringbuf (&sb, ")");
 1642     }
 1643   put_stringbuf (&sb, ")");
 1644   if (!mode && algo_table[algoidx].digest_string)
 1645     {
 1646       /* Insert the hash algorithm if included in the OID.  */
 1647       put_stringbuf (&sb, "(4:hash");
 1648       put_stringbuf_sexp (&sb, algo_table[algoidx].digest_string);
 1649       put_stringbuf (&sb, ")");
 1650     }
 1651   if (!mode && pss_hash)
 1652     {
 1653       put_stringbuf (&sb, "(5:flags3:pss)");
 1654       put_stringbuf (&sb, "(9:hash-algo");
 1655       put_stringbuf_sexp (&sb, pss_hash);
 1656       put_stringbuf (&sb, ")");
 1657       put_stringbuf (&sb, "(11:salt-length");
 1658       put_stringbuf_uint (&sb, salt_length);
 1659       put_stringbuf (&sb, ")");
 1660     }
 1661   if (mode == 2)  /* ECDH */
 1662     {
 1663       put_stringbuf (&sb, "(9:encr-algo");
 1664       put_stringbuf_sexp (&sb, keyencralgo);
 1665       put_stringbuf (&sb, ")(9:wrap-algo");
 1666       put_stringbuf_sexp (&sb, keywrapalgo);
 1667       put_stringbuf (&sb, ")");
 1668     }
 1669   put_stringbuf (&sb, ")");
 1670 
 1671   *r_string = get_stringbuf (&sb);
 1672   if (!*r_string)
 1673     return gpg_error (GPG_ERR_ENOMEM);
 1674 
 1675   xfree (pss_hash);
 1676   return 0;
 1677 }
 1678 
 1679 /* Assume that DER is a buffer of length DERLEN with a DER encoded
 1680    Asn.1 structure like this:
 1681 
 1682      SEQUENCE {
 1683         algorithm    OBJECT IDENTIFIER,
 1684         parameters   ANY DEFINED BY algorithm OPTIONAL }
 1685      signature  BIT STRING
 1686 
 1687   We only allow parameters == NULL.
 1688 
 1689   The function parses this structure and creates a S-Exp suitable to be
 1690   used as signature value in Libgcrypt:
 1691 
 1692   (sig-val
 1693     (<algo>
 1694       (<param_name1> <mpi>)
 1695       ...
 1696       (<param_namen> <mpi>))
 1697     (hash algo))
 1698 
 1699  The S-Exp will be returned in a string which the caller must free.
 1700  We don't pass an ASN.1 node here but a plain memory block.  */
 1701 gpg_error_t
 1702 _ksba_sigval_to_sexp (const unsigned char *der, size_t derlen,
 1703                       ksba_sexp_t *r_string)
 1704 {
 1705   return cryptval_to_sexp (0, der, derlen, NULL, NULL, NULL, 0, r_string);
 1706 }
 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  *    }
 1716  *    encryptedKey  OCTET STRING
 1717  *
 1718  * The function parses this structure and creates a S-expression
 1719  * suitable to be used as encrypted value in Libgcrypt's public key
 1720  * functions:
 1721  *
 1722  * (enc-val
 1723  *   (<algo>
 1724  *     (<param_name1> <mpi>)
 1725  *     ...
 1726  *     (<param_namen> <mpi>)
 1727  *   ))
 1728  *
 1729  * The S-expression will be returned in a string which the caller must
 1730  * free.  Note that the input buffer may not a proper ASN.1 object but
 1731  * a plain memory block; this is becuase the SEQUENCE is followed by
 1732  * an OCTET STRING or BIT STRING.
 1733  */
 1734 gpg_error_t
 1735 _ksba_encval_to_sexp (const unsigned char *der, size_t derlen,
 1736                       ksba_sexp_t *r_string)
 1737 {
 1738   return cryptval_to_sexp (1, der, derlen, NULL, NULL, NULL, 0, r_string);
 1739 }
 1740 
 1741 
 1742 /* Assume that der is a buffer of length DERLEN with a DER encoded
 1743  * ASN.1 structure like this:
 1744  *
 1745  *  [1] {
 1746  *    SEQUENCE {
 1747  *       algorithm    OBJECT IDENTIFIER,
 1748  *       parameters   ANY DEFINED BY algorithm OPTIONAL
 1749  *    }
 1750  *    encryptedKey  BIT STRING
 1751  *  }
 1752  *
 1753  * The function parses this structure and creates an S-expression
 1754  * conveying all parameters required for ECDH:
 1755  *
 1756  * (enc-val
 1757  *   (ecdh
 1758  *     (e <octetstring>)
 1759  *     (s <octetstring>)
 1760  *   (ukm <octetstring>)
 1761  *   (encr-algo <oid>)
 1762  *   (wrap-algo <oid>)))
 1763  *
 1764  * E is the ephemeral public key and S is the encrypted key.  The user
 1765  * keying material (ukm) is optional.  The S-expression will be
 1766  * returned in a string which the caller must free.
 1767  */
 1768 gpg_error_t
 1769 _ksba_encval_kari_to_sexp (const unsigned char *der, size_t derlen,
 1770                            const char *keyencralgo, const char *keywrapalgo,
 1771                            const void *enckey, size_t enckeylen,
 1772                            ksba_sexp_t *r_string)
 1773 {
 1774   gpg_error_t err;
 1775   struct tag_info ti;
 1776   size_t save_derlen = derlen;
 1777 
 1778   err = parse_context_tag (&der, &derlen, &ti, 1);
 1779   if (err)
 1780     return err;
 1781   if (save_derlen < ti.nhdr)
 1782     return gpg_error (GPG_ERR_INV_BER);
 1783   derlen = save_derlen - ti.nhdr;
 1784   return cryptval_to_sexp (2, der, derlen,
 1785                            keyencralgo, keywrapalgo, enckey, enckeylen,
 1786                            r_string);
 1787 }