"Fossies" - the Fresh Open Source Software Archive

Member "libksba-1.5.0/src/keyinfo.c" (17 Jun 2020, 50508 Bytes) of package /linux/privat/libksba-1.5.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.4.0_vs_1.5.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 
  363 #define TLV_LENGTH(prefix) do {         \
  364   if (!prefix ## len)                    \
  365     return gpg_error (GPG_ERR_INV_KEYINFO);  \
  366   c = *(prefix)++; prefix ## len--;           \
  367   if (c == 0x80)                  \
  368     return gpg_error (GPG_ERR_NOT_DER_ENCODED);  \
  369   if (c == 0xff)                  \
  370     return gpg_error (GPG_ERR_BAD_BER);        \
  371                                   \
  372   if ( !(c & 0x80) )              \
  373     len = c;                      \
  374   else                            \
  375     {                             \
  376       int count = c & 0x7f;       \
  377                                   \
  378       for (len=0; count; count--) \
  379         {                         \
  380           len <<= 8;              \
  381           if (!prefix ## len)            \
  382             return gpg_error (GPG_ERR_BAD_BER);\
  383           c = *(prefix)++; prefix ## len--;   \
  384           len |= c & 0xff;        \
  385         }                         \
  386     }                             \
  387   if (len > prefix ## len)               \
  388     return gpg_error (GPG_ERR_INV_KEYINFO);  \
  389 } while (0)
  390 
  391 
  392 /* Given a string BUF of length BUFLEN with either a curve name or its
  393  * OID in dotted form return a string in dotted form of the name.  The
  394  * caller must free the result.  On error NULL is returned.  If a
  395  * curve requires the use of a certain algorithm, that algorithm is
  396  * stored at R_PKALGO.  */
  397 static char *
  398 get_ecc_curve_oid (const unsigned char *buf, size_t buflen, pkalgo_t *r_pkalgo)
  399 {
  400   unsigned char *result;
  401   int i, find_pkalgo;
  402 
  403   /* Skip an optional "oid." prefix. */
  404   if (buflen > 4 && buf[3] == '.' && digitp (buf+4)
  405       && ((buf[0] == 'o' && buf[1] == 'i' && buf[2] == 'd')
  406           ||(buf[0] == 'O' && buf[1] == 'I' && buf[2] == 'D')))
  407     {
  408       buf += 4;
  409       buflen -= 4;
  410     }
  411 
  412   /* If it does not look like an OID - map it through the table.  */
  413   if (buflen && !digitp (buf))
  414     {
  415       for (i=0; curve_names[i].oid; i++)
  416         if (buflen == strlen (curve_names[i].name)
  417             && !memcmp (buf, curve_names[i].name, buflen))
  418           break;
  419       if (!curve_names[i].oid)
  420         return NULL; /* Not found.  */
  421       buf = curve_names[i].oid;
  422       buflen = strlen (curve_names[i].oid);
  423       *r_pkalgo = curve_names[i].pkalgo;
  424       find_pkalgo = 0;
  425     }
  426   else
  427     find_pkalgo = 1;
  428 
  429   result = xtrymalloc (buflen + 1);
  430   if (!result)
  431     return NULL; /* Ooops */
  432   memcpy (result, buf, buflen);
  433   result[buflen] = 0;
  434 
  435   if (find_pkalgo)
  436     {
  437       /* We still need to check whether the OID requires a certain ALGO.  */
  438       for (i=0; curve_names[i].oid; i++)
  439         if (!strcmp (curve_names[i].oid, result))
  440           {
  441             *r_pkalgo = curve_names[i].pkalgo;
  442             break;
  443           }
  444     }
  445 
  446   return result;
  447 }
  448 
  449 
  450 
  451 /* Return the OFF and the LEN of algorithm within DER.  Do some checks
  452    and return the number of bytes read in r_nread, adding this to der
  453    does point into the BIT STRING.
  454 
  455    mode 0: just get the algorithm identifier. FIXME: should be able to
  456            handle BER Encoding.
  457    mode 1: as described.
  458  */
  459 static gpg_error_t
  460 get_algorithm (int mode, const unsigned char *der, size_t derlen,
  461                size_t *r_nread, size_t *r_pos, size_t *r_len, int *r_bitstr,
  462                size_t *r_parm_pos, size_t *r_parm_len, int *r_parm_type)
  463 {
  464   int c;
  465   const unsigned char *start = der;
  466   const unsigned char *startseq;
  467   unsigned long seqlen, len;
  468 
  469   *r_bitstr = 0;
  470   if (r_parm_pos)
  471     *r_parm_pos = 0;
  472   if (r_parm_len)
  473     *r_parm_len = 0;
  474   if (r_parm_type)
  475     *r_parm_type = 0;
  476   /* get the inner sequence */
  477   if (!derlen)
  478     return gpg_error (GPG_ERR_INV_KEYINFO);
  479   c = *der++; derlen--;
  480   if ( c != 0x30 )
  481     return gpg_error (GPG_ERR_UNEXPECTED_TAG); /* not a SEQUENCE */
  482   TLV_LENGTH(der);
  483   seqlen = len;
  484   startseq = der;
  485 
  486   /* get the object identifier */
  487   if (!derlen)
  488     return gpg_error (GPG_ERR_INV_KEYINFO);
  489   c = *der++; derlen--;
  490   if ( c != 0x06 )
  491     return gpg_error (GPG_ERR_UNEXPECTED_TAG); /* not an OBJECT IDENTIFIER */
  492   TLV_LENGTH(der);
  493 
  494   /* der does now point to an oid of length LEN */
  495   *r_pos = der - start;
  496   *r_len = len;
  497   der += len;
  498   derlen -= len;
  499   seqlen -= der - startseq;;
  500 
  501   /* Parse the parameter.  */
  502   if (seqlen)
  503     {
  504       const unsigned char *startparm = der;
  505 
  506       if (!derlen)
  507         return gpg_error (GPG_ERR_INV_KEYINFO);
  508       c = *der++; derlen--;
  509       if ( c == 0x05 )
  510         {
  511           /* gpgrt_log_debug ("%s: parameter: NULL \n", __func__); */
  512           if (!derlen)
  513             return gpg_error (GPG_ERR_INV_KEYINFO);
  514           c = *der++; derlen--;
  515           if (c)
  516             return gpg_error (GPG_ERR_BAD_BER);  /* NULL must have a
  517                                                     length of 0 */
  518           seqlen -= 2;
  519         }
  520       else if (r_parm_pos && r_parm_len && c == 0x04)
  521         {
  522           /*  This is an octet string parameter and we need it.  */
  523           if (r_parm_type)
  524             *r_parm_type = TYPE_OCTET_STRING;
  525           TLV_LENGTH(der);
  526           *r_parm_pos = der - start;
  527           *r_parm_len = len;
  528           seqlen -= der - startparm;
  529           der += len;
  530           derlen -= len;
  531           seqlen -= len;
  532         }
  533       else if (r_parm_pos && r_parm_len && c == 0x06)
  534         {
  535           /*  This is an object identifier.  */
  536           if (r_parm_type)
  537             *r_parm_type = TYPE_OBJECT_ID;
  538           TLV_LENGTH(der);
  539           *r_parm_pos = der - start;
  540           *r_parm_len = len;
  541           seqlen -= der - startparm;
  542           der += len;
  543           derlen -= len;
  544           seqlen -= len;
  545         }
  546       else if (r_parm_pos && r_parm_len && c == 0x30)
  547         {
  548           /*  This is a sequence. */
  549           if (r_parm_type)
  550             *r_parm_type = TYPE_SEQUENCE;
  551           TLV_LENGTH(der);
  552           *r_parm_pos = startparm - start;
  553           *r_parm_len = len + (der - startparm);
  554           seqlen -= der - startparm;
  555           der += len;
  556           derlen -= len;
  557           seqlen -= len;
  558         }
  559       else
  560         {
  561 /*            printf ("parameter: with tag %02x - ignored\n", c); */
  562           TLV_LENGTH(der);
  563           seqlen -= der - startparm;
  564           /* skip the value */
  565           der += len;
  566           derlen -= len;
  567           seqlen -= len;
  568         }
  569     }
  570 
  571   if (seqlen)
  572     return gpg_error (GPG_ERR_INV_KEYINFO);
  573 
  574   if (mode)
  575     {
  576       /* move forward to the BIT_STR */
  577       if (!derlen)
  578         return gpg_error (GPG_ERR_INV_KEYINFO);
  579       c = *der++; derlen--;
  580 
  581       if (c == 0x03)
  582         *r_bitstr = 1; /* BIT STRING */
  583       else if (c == 0x04)
  584         ; /* OCTECT STRING */
  585       else
  586         return gpg_error (GPG_ERR_UNEXPECTED_TAG); /* not a BIT STRING */
  587       TLV_LENGTH(der);
  588     }
  589 
  590   *r_nread = der - start;
  591   return 0;
  592 }
  593 
  594 
  595 gpg_error_t
  596 _ksba_parse_algorithm_identifier (const unsigned char *der, size_t derlen,
  597                                   size_t *r_nread, char **r_oid)
  598 {
  599   return _ksba_parse_algorithm_identifier2 (der, derlen,
  600                                             r_nread, r_oid, NULL, NULL);
  601 }
  602 
  603 
  604 /* Note that R_NREAD, R_PARM, and R_PARMLEN are optional.  */
  605 gpg_error_t
  606 _ksba_parse_algorithm_identifier2 (const unsigned char *der, size_t derlen,
  607                                    size_t *r_nread, char **r_oid,
  608                                    char **r_parm, size_t *r_parmlen)
  609 {
  610   gpg_error_t err;
  611   int is_bitstr;
  612   size_t nread, off, len, off2, len2;
  613   int parm_type;
  614 
  615   /* fixme: get_algorithm might return the error invalid keyinfo -
  616      this should be invalid algorithm identifier */
  617   *r_oid = NULL;
  618   if (r_nread)
  619     *r_nread = 0;
  620   off2 = len2 = 0;
  621   err = get_algorithm (0, der, derlen, &nread, &off, &len, &is_bitstr,
  622                        &off2, &len2, &parm_type);
  623   if (err)
  624     return err;
  625   if (r_nread)
  626     *r_nread = nread;
  627   *r_oid = ksba_oid_to_str (der+off, len);
  628   if (!*r_oid)
  629     return gpg_error (GPG_ERR_ENOMEM);
  630 
  631   /* Special hack for ecdsaWithSpecified.  We replace the returned OID
  632      by the one in the parameter. */
  633   if (off2 && len2 && parm_type == TYPE_SEQUENCE
  634       && !strcmp (*r_oid, "1.2.840.10045.4.3"))
  635     {
  636       xfree (*r_oid);
  637       *r_oid = NULL;
  638       err = get_algorithm (0, der+off2, len2, &nread, &off, &len, &is_bitstr,
  639                            NULL, NULL, NULL);
  640       if (err)
  641         {
  642           if (r_nread)
  643             *r_nread = 0;
  644           return err;
  645         }
  646       *r_oid = ksba_oid_to_str (der+off2+off, len);
  647       if (!*r_oid)
  648         {
  649           if (r_nread)
  650             *r_nread = 0;
  651           return gpg_error (GPG_ERR_ENOMEM);
  652         }
  653 
  654       off2 = len2 = 0; /* So that R_PARM is set to NULL.  */
  655     }
  656 
  657   if (r_parm && r_parmlen)
  658     {
  659       if (off2 && len2)
  660         {
  661           *r_parm = xtrymalloc (len2);
  662           if (!*r_parm)
  663             {
  664               xfree (*r_oid);
  665               *r_oid = NULL;
  666               return gpg_error (GPG_ERR_ENOMEM);
  667             }
  668           memcpy (*r_parm, der+off2, len2);
  669           *r_parmlen = len2;
  670         }
  671       else
  672         {
  673           *r_parm = NULL;
  674           *r_parmlen = 0;
  675         }
  676     }
  677   return 0;
  678 }
  679 
  680 
  681 
  682 /* Assume that der is a buffer of length DERLEN with a DER encoded
  683    ASN.1 structure like this:
  684 
  685   keyInfo ::= SEQUENCE {
  686                  SEQUENCE {
  687                     algorithm    OBJECT IDENTIFIER,
  688                     parameters   ANY DEFINED BY algorithm OPTIONAL }
  689                  publicKey  BIT STRING }
  690 
  691   The function parses this structure and create a SEXP suitable to be
  692   used as a public key in Libgcrypt.  The S-Exp will be returned in a
  693   string which the caller must free.
  694 
  695   We don't pass an ASN.1 node here but a plain memory block.  */
  696 
  697 gpg_error_t
  698 _ksba_keyinfo_to_sexp (const unsigned char *der, size_t derlen,
  699                        ksba_sexp_t *r_string)
  700 {
  701   gpg_error_t err;
  702   int c;
  703   size_t nread, off, len, parm_off, parm_len;
  704   int parm_type;
  705   char *parm_oid = NULL;
  706   int algoidx;
  707   int is_bitstr;
  708   const unsigned char *parmder = NULL;
  709   size_t parmderlen = 0;
  710   const unsigned char *ctrl;
  711   const char *elem;
  712   struct stringbuf sb;
  713 
  714   *r_string = NULL;
  715 
  716   /* check the outer sequence */
  717   if (!derlen)
  718     return gpg_error (GPG_ERR_INV_KEYINFO);
  719   c = *der++; derlen--;
  720   if ( c != 0x30 )
  721     return gpg_error (GPG_ERR_UNEXPECTED_TAG); /* not a SEQUENCE */
  722   TLV_LENGTH(der);
  723   /* and now the inner part */
  724   err = get_algorithm (1, der, derlen, &nread, &off, &len, &is_bitstr,
  725                        &parm_off, &parm_len, &parm_type);
  726   if (err)
  727     return err;
  728 
  729   /* look into our table of supported algorithms */
  730   for (algoidx=0; pk_algo_table[algoidx].oid; algoidx++)
  731     {
  732       if ( len == pk_algo_table[algoidx].oidlen
  733            && !memcmp (der+off, pk_algo_table[algoidx].oid, len))
  734         break;
  735     }
  736   if (!pk_algo_table[algoidx].oid)
  737     return gpg_error (GPG_ERR_UNKNOWN_ALGORITHM);
  738   if (!pk_algo_table[algoidx].supported)
  739     return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
  740 
  741   if (parm_off && parm_len && parm_type == TYPE_OBJECT_ID)
  742     parm_oid = ksba_oid_to_str (der+parm_off, parm_len);
  743   else if (parm_off && parm_len)
  744     {
  745       parmder = der + parm_off;
  746       parmderlen = parm_len;
  747     }
  748 
  749   der += nread;
  750   derlen -= nread;
  751 
  752   if (is_bitstr)
  753     { /* Funny: X.509 defines the signature value as a bit string but
  754          CMS as an octet string - for ease of implementation we always
  755          allow both */
  756       if (!derlen)
  757         {
  758           xfree (parm_oid);
  759           return gpg_error (GPG_ERR_INV_KEYINFO);
  760         }
  761       c = *der++; derlen--;
  762       if (c)
  763         fprintf (stderr, "warning: number of unused bits is not zero\n");
  764     }
  765 
  766   /* fixme: we should calculate the initial length form the size of the
  767      sequence, so that we don't need a realloc later */
  768   init_stringbuf (&sb, 100);
  769   put_stringbuf (&sb, "(10:public-key(");
  770 
  771   /* fixme: we can also use the oidstring here and prefix it with
  772      "oid." - this way we can pass more information into Libgcrypt or
  773      whatever library is used */
  774   put_stringbuf_sexp (&sb, pk_algo_table[algoidx].algo_string);
  775 
  776   /* Insert the curve name for ECC. */
  777   if (pk_algo_table[algoidx].pkalgo == PKALGO_ECC && parm_oid)
  778     {
  779       put_stringbuf (&sb, "(");
  780       put_stringbuf_sexp (&sb, "curve");
  781       put_stringbuf_sexp (&sb, parm_oid);
  782       put_stringbuf (&sb, ")");
  783     }
  784   else if (pk_algo_table[algoidx].pkalgo == PKALGO_ED25519
  785            || pk_algo_table[algoidx].pkalgo == PKALGO_ED448
  786            || pk_algo_table[algoidx].pkalgo == PKALGO_X25519
  787            || pk_algo_table[algoidx].pkalgo == PKALGO_X448)
  788     {
  789       put_stringbuf (&sb, "(");
  790       put_stringbuf_sexp (&sb, "curve");
  791       put_stringbuf_sexp (&sb, pk_algo_table[algoidx].oidstring);
  792       put_stringbuf (&sb, ")");
  793     }
  794 
  795   /* If parameters are given and we have a description for them, parse
  796      them. */
  797   if (parmder && parmderlen
  798       && pk_algo_table[algoidx].parmelem_string
  799       && pk_algo_table[algoidx].parmctrl_string)
  800     {
  801       elem = pk_algo_table[algoidx].parmelem_string;
  802       ctrl = pk_algo_table[algoidx].parmctrl_string;
  803       for (; *elem; ctrl++, elem++)
  804         {
  805           int is_int;
  806 
  807           if ( (*ctrl & 0x80) && !elem[1] )
  808             {
  809               /* Hack to allow reading a raw value.  */
  810               is_int = 1;
  811               len = parmderlen;
  812             }
  813           else
  814             {
  815               if (!parmderlen)
  816                 {
  817                   xfree (parm_oid);
  818                   return gpg_error (GPG_ERR_INV_KEYINFO);
  819                 }
  820               c = *parmder++; parmderlen--;
  821               if ( c != *ctrl )
  822                 {
  823                   xfree (parm_oid);
  824                   return gpg_error (GPG_ERR_UNEXPECTED_TAG);
  825                 }
  826               is_int = c == 0x02;
  827               TLV_LENGTH (parmder);
  828             }
  829           if (is_int && *elem != '-')  /* Take this integer.  */
  830             {
  831               char tmp[2];
  832 
  833               put_stringbuf (&sb, "(");
  834               tmp[0] = *elem; tmp[1] = 0;
  835               put_stringbuf_sexp (&sb, tmp);
  836               put_stringbuf_mem_sexp (&sb, parmder, len);
  837               parmder += len;
  838               parmderlen -= len;
  839               put_stringbuf (&sb, ")");
  840             }
  841         }
  842     }
  843 
  844 
  845   /* FIXME: We don't release the stringbuf in case of error
  846      better let the macro jump to a label */
  847   elem = pk_algo_table[algoidx].elem_string;
  848   ctrl = pk_algo_table[algoidx].ctrl_string;
  849   for (; *elem; ctrl++, elem++)
  850     {
  851       int is_int;
  852 
  853       if ( (*ctrl & 0x80) && !elem[1] )
  854         {
  855           /* Hack to allow reading a raw value.  */
  856           is_int = 1;
  857           len = derlen;
  858         }
  859       else
  860         {
  861           if (!derlen)
  862             {
  863               xfree (parm_oid);
  864               return gpg_error (GPG_ERR_INV_KEYINFO);
  865             }
  866           c = *der++; derlen--;
  867           if ( c != *ctrl )
  868             {
  869               xfree (parm_oid);
  870               return gpg_error (GPG_ERR_UNEXPECTED_TAG);
  871             }
  872           is_int = c == 0x02;
  873           TLV_LENGTH (der);
  874         }
  875       if (is_int && *elem != '-')  /* Take this integer.  */
  876         {
  877           char tmp[2];
  878 
  879           put_stringbuf (&sb, "(");
  880           tmp[0] = *elem; tmp[1] = 0;
  881           put_stringbuf_sexp (&sb, tmp);
  882           put_stringbuf_mem_sexp (&sb, der, len);
  883           der += len;
  884           derlen -= len;
  885           put_stringbuf (&sb, ")");
  886         }
  887     }
  888   put_stringbuf (&sb, "))");
  889   xfree (parm_oid);
  890 
  891   *r_string = get_stringbuf (&sb);
  892   if (!*r_string)
  893     return gpg_error (GPG_ERR_ENOMEM);
  894 
  895   return 0;
  896 }
  897 
  898 
  899 /* Match the algorithm string given in BUF which is of length BUFLEN
  900  * with the known algorithms from our table and return the table
  901  * entriy with the OID string.  If WITH_SIG is true, the table of
  902  * signature algorithms is consulted first.  */
  903 static const char *
  904 oid_from_buffer (const unsigned char *buf, unsigned int buflen,
  905                  pkalgo_t *r_pkalgo, int with_sig)
  906 {
  907   int i;
  908 
  909   /* Ignore an optional "oid." prefix. */
  910   if (buflen > 4 && buf[3] == '.' && digitp (buf+4)
  911       && ((buf[0] == 'o' && buf[1] == 'i' && buf[2] == 'd')
  912           ||(buf[0] == 'O' && buf[1] == 'I' && buf[2] == 'D')))
  913     {
  914       buf += 4;
  915       buflen -= 4;
  916     }
  917 
  918   if (with_sig)
  919     {
  920       /* Scan the signature table first. */
  921       for (i=0; sig_algo_table[i].oid; i++)
  922         {
  923           if (!sig_algo_table[i].supported)
  924             continue;
  925           if (buflen == strlen (sig_algo_table[i].oidstring)
  926               && !memcmp (buf, sig_algo_table[i].oidstring, buflen))
  927             break;
  928           if (buflen == strlen (sig_algo_table[i].algo_string)
  929               && !memcmp (buf, sig_algo_table[i].algo_string, buflen))
  930             break;
  931         }
  932       if (sig_algo_table[i].oid)
  933         {
  934           *r_pkalgo = sig_algo_table[i].pkalgo;
  935           return sig_algo_table[i].oidstring;
  936         }
  937     }
  938 
  939   /* Scan the standard table. */
  940   for (i=0; pk_algo_table[i].oid; i++)
  941     {
  942       if (!pk_algo_table[i].supported)
  943         continue;
  944       if (buflen == strlen (pk_algo_table[i].oidstring)
  945           && !memcmp (buf, pk_algo_table[i].oidstring, buflen))
  946         break;
  947       if (buflen == strlen (pk_algo_table[i].algo_string)
  948           && !memcmp (buf, pk_algo_table[i].algo_string, buflen))
  949         break;
  950     }
  951   if (!pk_algo_table[i].oid)
  952     return NULL;
  953 
  954   *r_pkalgo = pk_algo_table[i].pkalgo;
  955   return pk_algo_table[i].oidstring;
  956 }
  957 
  958 
  959 /* If ALGOINFOMODE is false: Take the "public-key" s-expression SEXP
  960  * and convert it into a DER encoded publicKeyInfo.
  961  *
  962  * If ALGOINFOMODE is true: Take the "sig-val" s-expression SEXP and
  963  * convert it into a DER encoded algorithmInfo.  */
  964 gpg_error_t
  965 _ksba_keyinfo_from_sexp (ksba_const_sexp_t sexp, int algoinfomode,
  966                          unsigned char **r_der, size_t *r_derlen)
  967 {
  968   gpg_error_t err;
  969   const unsigned char *s;
  970   char *endp;
  971   unsigned long n;
  972   const char *algo_oid;
  973   char *curve_oid = NULL;
  974   pkalgo_t pkalgo, force_pkalgo;
  975   int i;
  976   struct {
  977     const char *name;
  978     int namelen;
  979     const unsigned char *value;
  980     int valuelen;
  981   } parm[10];
  982   int parmidx;
  983   const char *parmdesc, *algoparmdesc;
  984   ksba_der_t dbld = NULL;
  985   ksba_der_t dbld2 = NULL;
  986   unsigned char *tmpder;
  987   size_t tmpderlen;
  988 
  989   if (!sexp)
  990     return gpg_error (GPG_ERR_INV_VALUE);
  991 
  992   s = sexp;
  993   if (*s != '(')
  994     return gpg_error (GPG_ERR_INV_SEXP);
  995   s++;
  996 
  997   n = strtoul (s, &endp, 10);
  998   s = endp;
  999   if (!n || *s != ':')
 1000     return gpg_error (GPG_ERR_INV_SEXP); /* We don't allow empty lengths.  */
 1001   s++;
 1002 
 1003   if (algoinfomode && n == 7 && !memcmp (s, "sig-val", 7))
 1004     s += 7;
 1005   else if (n == 10 || !memcmp (s, "public-key", 10))
 1006     s += 10;
 1007   else
 1008     return gpg_error (GPG_ERR_UNKNOWN_SEXP);
 1009 
 1010   if (*s != '(')
 1011     return gpg_error (digitp (s)? GPG_ERR_UNKNOWN_SEXP : GPG_ERR_INV_SEXP);
 1012   s++;
 1013 
 1014   /* Break out the algorithm ID */
 1015   n = strtoul (s, &endp, 10);
 1016   s = endp;
 1017   if (!n || *s != ':')
 1018     return gpg_error (GPG_ERR_INV_SEXP); /* We don't allow empty lengths.  */
 1019   s++;
 1020 
 1021   algo_oid = oid_from_buffer (s, n, &pkalgo, algoinfomode);
 1022   if (!algo_oid)
 1023     return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
 1024   s += n;
 1025 
 1026   /* Collect all the values.  */
 1027   force_pkalgo = 0;
 1028   for (parmidx = 0; *s != ')' ; parmidx++)
 1029     {
 1030       if (parmidx >= DIM(parm))
 1031         {
 1032           err = gpg_error (GPG_ERR_GENERAL);
 1033           goto leave;
 1034         }
 1035       if (*s != '(')
 1036         {
 1037           err = gpg_error (digitp(s)? GPG_ERR_UNKNOWN_SEXP:GPG_ERR_INV_SEXP);
 1038           goto leave;
 1039         }
 1040       s++;
 1041       n = strtoul (s, &endp, 10);
 1042       s = endp;
 1043       if (!n || *s != ':')
 1044         {
 1045           err = gpg_error (GPG_ERR_INV_SEXP);
 1046           goto leave;
 1047         }
 1048       s++;
 1049       parm[parmidx].name = s;
 1050       parm[parmidx].namelen = n;
 1051       s += n;
 1052       if (!digitp(s))
 1053         {
 1054           err = gpg_error (GPG_ERR_UNKNOWN_SEXP); /* ... or invalid S-Exp. */
 1055           goto leave;
 1056         }
 1057 
 1058       n = strtoul (s, &endp, 10);
 1059       s = endp;
 1060       if (!n || *s != ':')
 1061         return gpg_error (GPG_ERR_INV_SEXP);
 1062       s++;
 1063       parm[parmidx].value = s;
 1064       parm[parmidx].valuelen = n;
 1065       s += n;
 1066       if ( *s != ')')
 1067         {
 1068           err = gpg_error (GPG_ERR_UNKNOWN_SEXP); /* ... or invalid S-Exp. */
 1069           goto leave;
 1070         }
 1071       s++;
 1072 
 1073       if (parm[parmidx].namelen == 5
 1074           && !memcmp (parm[parmidx].name, "curve", 5)
 1075           && !curve_oid)
 1076         {
 1077           curve_oid = get_ecc_curve_oid (parm[parmidx].value,
 1078                                          parm[parmidx].valuelen, &force_pkalgo);
 1079           parmidx--; /* No need to store this parameter.  */
 1080         }
 1081     }
 1082   s++;
 1083   /* Allow for optional elements.  */
 1084   if (*s == '(')
 1085     {
 1086       int depth = 1;
 1087       err = sskip (&s, &depth);
 1088       if (err)
 1089         goto leave;
 1090     }
 1091   /* We need another closing parenthesis. */
 1092   if ( *s != ')' )
 1093     {
 1094       err = gpg_error (GPG_ERR_INV_SEXP);
 1095       goto leave;
 1096     }
 1097 
 1098   if (force_pkalgo)
 1099     pkalgo = force_pkalgo;
 1100 
 1101   /* Describe the parameters in the order we want them.  For DSA wie
 1102    * also set algoparmdesc so that we can later build the parameters
 1103    * for the algorithmIdentifier.  */
 1104   algoparmdesc = NULL;
 1105   switch (pkalgo)
 1106     {
 1107     case PKALGO_RSA:
 1108       parmdesc = algoinfomode? "" : "ne";
 1109       break;
 1110     case PKALGO_DSA:
 1111       parmdesc = algoinfomode? "" : "y";
 1112       algoparmdesc = "pqg";
 1113       break;
 1114     case PKALGO_ECC:
 1115       parmdesc = algoinfomode? "" : "q";
 1116       break;
 1117     case PKALGO_ED25519:
 1118     case PKALGO_X25519:
 1119     case PKALGO_ED448:
 1120     case PKALGO_X448:
 1121       parmdesc = algoinfomode? "" : "q";
 1122       if (curve_oid)
 1123         algo_oid = curve_oid;
 1124       break;
 1125     default:
 1126       err = gpg_error (GPG_ERR_UNKNOWN_ALGORITHM);
 1127       goto leave;
 1128     }
 1129 
 1130   /* Create a builder. */
 1131   dbld = _ksba_der_builder_new (0);
 1132   if (!dbld)
 1133     {
 1134       err = gpg_error_from_syserror ();
 1135       goto leave;
 1136     }
 1137 
 1138   /* The outer sequence.  */
 1139   if (!algoinfomode)
 1140     _ksba_der_add_tag (dbld, 0, TYPE_SEQUENCE);
 1141   /* The sequence.  */
 1142   _ksba_der_add_tag (dbld, 0, TYPE_SEQUENCE);
 1143   /* The object id.  */
 1144   _ksba_der_add_oid (dbld, algo_oid);
 1145 
 1146   /* The parameter. */
 1147   if (algoparmdesc)
 1148     {
 1149       /* Write the sequence tag followed by the integers. */
 1150       _ksba_der_add_tag (dbld, 0, TYPE_SEQUENCE);
 1151       for (s = algoparmdesc; *s; s++)
 1152         for (i=0; i < parmidx; i++)
 1153           if (parm[i].namelen == 1 && parm[i].name[0] == *s)
 1154             {
 1155               _ksba_der_add_int (dbld, parm[i].value, parm[i].valuelen, 1);
 1156               break; /* inner loop */
 1157             }
 1158       _ksba_der_add_end (dbld);
 1159     }
 1160   else if (pkalgo == PKALGO_ECC && !algoinfomode)
 1161     {
 1162      /* We only support the namedCurve choice for ECC parameters.  */
 1163       if (!curve_oid)
 1164         {
 1165           err = gpg_error (GPG_ERR_UNKNOWN_CURVE);
 1166           goto leave;
 1167         }
 1168       _ksba_der_add_oid (dbld, curve_oid);
 1169     }
 1170   else if (pkalgo == PKALGO_RSA)
 1171     {
 1172       _ksba_der_add_ptr (dbld, 0, TYPE_NULL, NULL, 0);
 1173     }
 1174 
 1175   _ksba_der_add_end (dbld); /* sequence.  */
 1176 
 1177   /* Add the bit string if we are not in algoinfomode.  */
 1178   if (!algoinfomode)
 1179     {
 1180       if (*parmdesc == 'q' && !parmdesc[1])
 1181         {
 1182           /* This is ECC - Q is directly written as a bit string.  */
 1183           for (i=0; i < parmidx; i++)
 1184             if (parm[i].namelen == 1 && parm[i].name[0] == 'q')
 1185               {
 1186                 if ((parm[i].valuelen & 1) && parm[i].valuelen > 32
 1187                     && (parm[i].value[0] == 0x40
 1188                         || parm[i].value[0] == 0x41
 1189                         || parm[i].value[0] == 0x42))
 1190                   {
 1191                     /* Odd length and prefixed with 0x40 - this is the
 1192                      * rfc4880bis indicator octet for extended point
 1193                      * formats - we may not emit that octet here.  */
 1194                     _ksba_der_add_bts (dbld, parm[i].value+1,
 1195                                        parm[i].valuelen-1, 0);
 1196                   }
 1197                 else
 1198                   _ksba_der_add_bts (dbld, parm[i].value, parm[i].valuelen, 0);
 1199                 break;
 1200               }
 1201         }
 1202       else  /* Non-ECC - embed the values.  */
 1203         {
 1204           dbld2 = _ksba_der_builder_new (10);
 1205           if (!dbld2)
 1206             {
 1207               err = gpg_error_from_syserror ();
 1208               goto leave;
 1209             }
 1210 
 1211           /* Note that no sequence is used if only one integer is written.  */
 1212           if (parmdesc[0] && parmdesc[1])
 1213             _ksba_der_add_tag (dbld2, 0, TYPE_SEQUENCE);
 1214 
 1215           for (s = parmdesc; *s; s++)
 1216             for (i=0; i < parmidx; i++)
 1217               if (parm[i].namelen == 1 && parm[i].name[0] == *s)
 1218                 {
 1219                   _ksba_der_add_int (dbld2, parm[i].value, parm[i].valuelen, 1);
 1220                   break; /* inner loop */
 1221                 }
 1222 
 1223           if (parmdesc[0] && parmdesc[1])
 1224             _ksba_der_add_end (dbld2);
 1225 
 1226           err = _ksba_der_builder_get (dbld2, &tmpder, &tmpderlen);
 1227           if (err)
 1228             goto leave;
 1229           _ksba_der_add_bts (dbld, tmpder, tmpderlen, 0);
 1230           xfree (tmpder);
 1231         }
 1232 
 1233       _ksba_der_add_end (dbld);  /* Outer sequence.  */
 1234     }
 1235 
 1236   /* Get the result. */
 1237   err = _ksba_der_builder_get (dbld, r_der, r_derlen);
 1238 
 1239  leave:
 1240   _ksba_der_release (dbld2);
 1241   _ksba_der_release (dbld);
 1242   xfree (curve_oid);
 1243   return err;
 1244 }
 1245 
 1246 
 1247 /* Helper function to parse the parameters used for rsaPSS.
 1248  * Given this sample DER object in (DER,DERLEN):
 1249  *
 1250  *  SEQUENCE {
 1251  *    [0] {
 1252  *      SEQUENCE {
 1253  *        OBJECT IDENTIFIER sha-512 (2 16 840 1 101 3 4 2 3)
 1254  *        }
 1255  *      }
 1256  *    [1] {
 1257  *      SEQUENCE {
 1258  *        OBJECT IDENTIFIER pkcs1-MGF (1 2 840 113549 1 1 8)
 1259  *        SEQUENCE {
 1260  *          OBJECT IDENTIFIER sha-512 (2 16 840 1 101 3 4 2 3)
 1261  *          }
 1262  *        }
 1263  *      }
 1264  *    [2] {
 1265  *      INTEGER 64
 1266  *       }
 1267  *     }
 1268  *
 1269  * The function returns the first OID at R_PSSHASH and the salt length
 1270  * at R_SALTLEN.  If the salt length is missing its default value is
 1271  * returned.  In case object does not resemble a the expected rsaPSS
 1272  * parameters GPG_ERR_INV_OBJ is returned; other errors are returned
 1273  * for an syntatically invalid object.  On error NULL is stored at
 1274  * R_PSSHASH.
 1275  */
 1276 gpg_error_t
 1277 _ksba_keyinfo_get_pss_info (const unsigned char *der, size_t derlen,
 1278                             char **r_psshash, unsigned int *r_saltlen)
 1279 {
 1280   gpg_error_t err;
 1281   struct tag_info ti;
 1282   char *psshash = NULL;
 1283   char *tmpoid = NULL;
 1284   unsigned int saltlen;
 1285 
 1286   *r_psshash = NULL;
 1287   *r_saltlen = 0;
 1288 
 1289   err = parse_sequence (&der, &derlen, &ti);
 1290   if (err)
 1291     goto leave;
 1292 
 1293   /* Get the hash algo.  */
 1294   err = parse_context_tag (&der, &derlen, &ti, 0);
 1295   if (err)
 1296     goto unknown_parms;
 1297   err = parse_sequence (&der, &derlen, &ti);
 1298   if (err)
 1299     goto unknown_parms;
 1300   err = parse_object_id_into_str (&der, &derlen, &psshash);
 1301   if (err)
 1302     goto unknown_parms;
 1303   err = parse_optional_null (&der, &derlen, NULL);
 1304   if (err)
 1305     goto unknown_parms;
 1306 
 1307   /* Check the MGF OID and that its hash algo matches. */
 1308   err = parse_context_tag (&der, &derlen, &ti, 1);
 1309   if (err)
 1310     goto unknown_parms;
 1311   err = parse_sequence (&der, &derlen, &ti);
 1312   if (err)
 1313     goto leave;
 1314   err = parse_object_id_into_str (&der, &derlen, &tmpoid);
 1315   if (err)
 1316     goto unknown_parms;
 1317   if (strcmp (tmpoid, "1.2.840.113549.1.1.8"))  /* MGF1 */
 1318     goto unknown_parms;
 1319   err = parse_sequence (&der, &derlen, &ti);
 1320   if (err)
 1321     goto leave;
 1322   xfree (tmpoid);
 1323   err = parse_object_id_into_str (&der, &derlen, &tmpoid);
 1324   if (err)
 1325     goto unknown_parms;
 1326   if (strcmp (tmpoid, psshash))
 1327     goto unknown_parms;
 1328   err = parse_optional_null (&der, &derlen, NULL);
 1329   if (err)
 1330     goto unknown_parms;
 1331 
 1332   /* Get the optional saltLength.  */
 1333   err = parse_context_tag (&der, &derlen, &ti, 2);
 1334   if (gpg_err_code (err) == GPG_ERR_INV_OBJ
 1335       || gpg_err_code (err) == GPG_ERR_FALSE)
 1336     saltlen = 20; /* Optional element - use default value */
 1337   else if (err)
 1338     goto unknown_parms;
 1339   else
 1340     {
 1341       err = parse_integer (&der, &derlen, &ti);
 1342       if (err)
 1343         goto leave;
 1344       for (saltlen=0; ti.length; ti.length--)
 1345         {
 1346           saltlen <<= 8;
 1347           saltlen |= (*der++) & 0xff;
 1348           derlen--;
 1349         }
 1350     }
 1351 
 1352   /* All fine.  */
 1353   *r_psshash = psshash;
 1354   psshash = NULL;
 1355   *r_saltlen = saltlen;
 1356   err = 0;
 1357   goto leave;
 1358 
 1359  unknown_parms:
 1360   err = gpg_error (GPG_ERR_INV_OBJ);
 1361 
 1362  leave:
 1363   xfree (psshash);
 1364   xfree (tmpoid);
 1365   return err;
 1366 }
 1367 
 1368 
 1369 /* Mode 0: work as described under _ksba_sigval_to_sexp
 1370  * mode 1: work as described under _ksba_encval_to_sexp
 1371  * mode 2: same as mode 1 but for ECDH; in this mode
 1372  *         KEYENCRYALO, KEYWRAPALGO, ENCRKEY, ENCRYKLEYLEN
 1373  *         are also required.
 1374  */
 1375 static gpg_error_t
 1376 cryptval_to_sexp (int mode, const unsigned char *der, size_t derlen,
 1377                   const char *keyencralgo, const char *keywrapalgo,
 1378                   const void *encrkey, size_t encrkeylen,
 1379                   ksba_sexp_t *r_string)
 1380 {
 1381   gpg_error_t err;
 1382   const struct algo_table_s *algo_table;
 1383   int c;
 1384   size_t nread, off, len;
 1385   int algoidx;
 1386   int is_bitstr;
 1387   const unsigned char *ctrl;
 1388   const char *elem;
 1389   struct stringbuf sb;
 1390   size_t parm_off, parm_len;
 1391   int parm_type;
 1392   char *pss_hash = NULL;
 1393   unsigned int salt_length = 0;
 1394 
 1395   /* FIXME: The entire function is very similar to keyinfo_to_sexp */
 1396   *r_string = NULL;
 1397 
 1398   if (!mode)
 1399     algo_table = sig_algo_table;
 1400   else
 1401     algo_table = enc_algo_table;
 1402 
 1403   err = get_algorithm (1, der, derlen, &nread, &off, &len, &is_bitstr,
 1404                        &parm_off, &parm_len, &parm_type);
 1405   if (err)
 1406     return err;
 1407 
 1408   /* look into our table of supported algorithms */
 1409   for (algoidx=0; algo_table[algoidx].oid; algoidx++)
 1410     {
 1411       if ( len == algo_table[algoidx].oidlen
 1412            && !memcmp (der+off, algo_table[algoidx].oid, len))
 1413         break;
 1414     }
 1415 
 1416   if (!algo_table[algoidx].oid)
 1417     return gpg_error (GPG_ERR_UNKNOWN_ALGORITHM);
 1418   if (!algo_table[algoidx].supported)
 1419     return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
 1420 
 1421   if (parm_type == TYPE_SEQUENCE
 1422       && algo_table[algoidx].supported == SUPPORTED_RSAPSS)
 1423     {
 1424       /* This is rsaPSS and we collect the parameters.  We simplify
 1425        * this by assuming that pkcs1-MGF is used with an identical
 1426        * hash algorithm.  All other kinds of parameters are ignored.  */
 1427       err = _ksba_keyinfo_get_pss_info (der + parm_off, parm_len,
 1428                                         &pss_hash, &salt_length);
 1429       if (gpg_err_code (err) == GPG_ERR_INV_OBJ)
 1430         err = 0;
 1431       if (err)
 1432         return err;
 1433     }
 1434 
 1435 
 1436   der += nread;
 1437   derlen -= nread;
 1438 
 1439   if (is_bitstr)
 1440     { /* Funny: X.509 defines the signature value as a bit string but
 1441          CMS as an octet string - for ease of implementation we always
 1442          allow both */
 1443       if (!derlen)
 1444         return gpg_error (GPG_ERR_INV_KEYINFO);
 1445       c = *der++; derlen--;
 1446       if (c)
 1447         fprintf (stderr, "warning: number of unused bits is not zero\n");
 1448     }
 1449 
 1450   /* fixme: we should calculate the initial length form the size of the
 1451      sequence, so that we don't neen a realloc later */
 1452   init_stringbuf (&sb, 100);
 1453   put_stringbuf (&sb, mode? "(7:enc-val(":"(7:sig-val(");
 1454   put_stringbuf_sexp (&sb, algo_table[algoidx].algo_string);
 1455 
 1456   /* FIXME: We don't release the stringbuf in case of error
 1457      better let the macro jump to a label */
 1458   if (!mode && (algo_table[algoidx].pkalgo == PKALGO_ED25519
 1459                 ||algo_table[algoidx].pkalgo == PKALGO_ED448
 1460                 || (algo_table[algoidx].pkalgo == PKALGO_ECC
 1461                     && *algo_table[algoidx].elem_string == 'P')))
 1462     {
 1463       /* EdDSA is special: R and S are simply concatenated; see
 1464        * rfc8410.  The same code is used for Plain ECDSA format as
 1465        * specified in BSI TR-03111; we indicate this with a 'P' in the
 1466        * elem string.  */
 1467       put_stringbuf (&sb, "(1:r");
 1468       put_stringbuf_mem_sexp (&sb, der, derlen/2);
 1469       put_stringbuf (&sb, ")");
 1470       der += derlen/2;
 1471       derlen /= 2;
 1472       put_stringbuf (&sb, "(1:s");
 1473       put_stringbuf_mem_sexp (&sb, der, derlen);
 1474       put_stringbuf (&sb, ")");
 1475     }
 1476   else
 1477     {
 1478       elem = algo_table[algoidx].elem_string;
 1479       ctrl = algo_table[algoidx].ctrl_string;
 1480       for (; *elem; ctrl++, elem++)
 1481         {
 1482           int is_int;
 1483 
 1484           if ( (*ctrl & 0x80) && !elem[1] )
 1485             {  /* Hack to allow a raw value */
 1486               is_int = 1;
 1487               len = derlen;
 1488             }
 1489           else
 1490             {
 1491               if (!derlen)
 1492                 return gpg_error (GPG_ERR_INV_KEYINFO);
 1493               c = *der++; derlen--;
 1494               if ( c != *ctrl )
 1495                 return gpg_error (GPG_ERR_UNEXPECTED_TAG);
 1496               is_int = c == 0x02;
 1497               TLV_LENGTH (der);
 1498             }
 1499           if (is_int && *elem != '-')
 1500             { /* take this integer */
 1501               char tmp[2];
 1502 
 1503               put_stringbuf (&sb, "(");
 1504               tmp[0] = *elem; tmp[1] = 0;
 1505               put_stringbuf_sexp (&sb, tmp);
 1506               put_stringbuf_mem_sexp (&sb, der, len);
 1507               der += len;
 1508               derlen -= len;
 1509               put_stringbuf (&sb, ")");
 1510             }
 1511         }
 1512     }
 1513   if (mode == 2)  /* ECDH */
 1514     {
 1515       put_stringbuf (&sb, "(1:s");
 1516       put_stringbuf_mem_sexp (&sb, encrkey, encrkeylen);
 1517       put_stringbuf (&sb, ")");
 1518     }
 1519   put_stringbuf (&sb, ")");
 1520   if (!mode && algo_table[algoidx].digest_string)
 1521     {
 1522       /* Insert the hash algorithm if included in the OID.  */
 1523       put_stringbuf (&sb, "(4:hash");
 1524       put_stringbuf_sexp (&sb, algo_table[algoidx].digest_string);
 1525       put_stringbuf (&sb, ")");
 1526     }
 1527   if (!mode && pss_hash)
 1528     {
 1529       put_stringbuf (&sb, "(5:flags3:pss)");
 1530       put_stringbuf (&sb, "(9:hash-algo");
 1531       put_stringbuf_sexp (&sb, pss_hash);
 1532       put_stringbuf (&sb, ")");
 1533       put_stringbuf (&sb, "(11:salt-length");
 1534       put_stringbuf_uint (&sb, salt_length);
 1535       put_stringbuf (&sb, ")");
 1536     }
 1537   if (mode == 2)  /* ECDH */
 1538     {
 1539       put_stringbuf (&sb, "(9:encr-algo");
 1540       put_stringbuf_sexp (&sb, keyencralgo);
 1541       put_stringbuf (&sb, ")(9:wrap-algo");
 1542       put_stringbuf_sexp (&sb, keywrapalgo);
 1543       put_stringbuf (&sb, ")");
 1544     }
 1545   put_stringbuf (&sb, ")");
 1546 
 1547   *r_string = get_stringbuf (&sb);
 1548   if (!*r_string)
 1549     return gpg_error (GPG_ERR_ENOMEM);
 1550 
 1551   xfree (pss_hash);
 1552   return 0;
 1553 }
 1554 
 1555 /* Assume that DER is a buffer of length DERLEN with a DER encoded
 1556    Asn.1 structure like this:
 1557 
 1558      SEQUENCE {
 1559         algorithm    OBJECT IDENTIFIER,
 1560         parameters   ANY DEFINED BY algorithm OPTIONAL }
 1561      signature  BIT STRING
 1562 
 1563   We only allow parameters == NULL.
 1564 
 1565   The function parses this structure and creates a S-Exp suitable to be
 1566   used as signature value in Libgcrypt:
 1567 
 1568   (sig-val
 1569     (<algo>
 1570       (<param_name1> <mpi>)
 1571       ...
 1572       (<param_namen> <mpi>))
 1573     (hash algo))
 1574 
 1575  The S-Exp will be returned in a string which the caller must free.
 1576  We don't pass an ASN.1 node here but a plain memory block.  */
 1577 gpg_error_t
 1578 _ksba_sigval_to_sexp (const unsigned char *der, size_t derlen,
 1579                       ksba_sexp_t *r_string)
 1580 {
 1581   return cryptval_to_sexp (0, der, derlen, NULL, NULL, NULL, 0, r_string);
 1582 }
 1583 
 1584 
 1585 /* Assume that der is a buffer of length DERLEN with a DER encoded
 1586  * ASN.1 structure like this:
 1587  *
 1588  *    SEQUENCE {
 1589  *       algorithm    OBJECT IDENTIFIER,
 1590  *       parameters   ANY DEFINED BY algorithm OPTIONAL
 1591  *    }
 1592  *    encryptedKey  OCTET STRING
 1593  *
 1594  * The function parses this structure and creates a S-expression
 1595  * suitable to be used as encrypted value in Libgcrypt's public key
 1596  * functions:
 1597  *
 1598  * (enc-val
 1599  *   (<algo>
 1600  *     (<param_name1> <mpi>)
 1601  *     ...
 1602  *     (<param_namen> <mpi>)
 1603  *   ))
 1604  *
 1605  * The S-expression will be returned in a string which the caller must
 1606  * free.  Note that the input buffer may not a proper ASN.1 object but
 1607  * a plain memory block; this is becuase the SEQUENCE is followed by
 1608  * an OCTET STRING or BIT STRING.
 1609  */
 1610 gpg_error_t
 1611 _ksba_encval_to_sexp (const unsigned char *der, size_t derlen,
 1612                       ksba_sexp_t *r_string)
 1613 {
 1614   return cryptval_to_sexp (1, der, derlen, NULL, NULL, NULL, 0, r_string);
 1615 }
 1616 
 1617 
 1618 /* Assume that der is a buffer of length DERLEN with a DER encoded
 1619  * ASN.1 structure like this:
 1620  *
 1621  *  [1] {
 1622  *    SEQUENCE {
 1623  *       algorithm    OBJECT IDENTIFIER,
 1624  *       parameters   ANY DEFINED BY algorithm OPTIONAL
 1625  *    }
 1626  *    encryptedKey  BIT STRING
 1627  *  }
 1628  *
 1629  * The function parses this structure and creates an S-expression
 1630  * conveying all parameters required for ECDH:
 1631  *
 1632  * (enc-val
 1633  *   (ecdh
 1634  *     (e <octetstring>)
 1635  *     (s <octetstring>)
 1636  *   (ukm <octetstring>)
 1637  *   (encr-algo <oid>)
 1638  *   (wrap-algo <oid>)))
 1639  *
 1640  * E is the ephemeral public key and S is the encrypted key.  The user
 1641  * keying material (ukm) is optional.  The S-expression will be
 1642  * returned in a string which the caller must free.
 1643  */
 1644 gpg_error_t
 1645 _ksba_encval_kari_to_sexp (const unsigned char *der, size_t derlen,
 1646                            const char *keyencralgo, const char *keywrapalgo,
 1647                            const void *enckey, size_t enckeylen,
 1648                            ksba_sexp_t *r_string)
 1649 {
 1650   gpg_error_t err;
 1651   struct tag_info ti;
 1652   size_t save_derlen = derlen;
 1653 
 1654   err = parse_context_tag (&der, &derlen, &ti, 1);
 1655   if (err)
 1656     return err;
 1657   if (save_derlen < ti.nhdr)
 1658     return gpg_error (GPG_ERR_INV_BER);
 1659   derlen = save_derlen - ti.nhdr;
 1660   return cryptval_to_sexp (2, der, derlen,
 1661                            keyencralgo, keywrapalgo, enckey, enckeylen,
 1662                            r_string);
 1663 }