LCOV - code coverage report
Current view: top level - libpkg - pkgsign_ecc.c (source / functions) Hit Total Coverage
Test: plop Lines: 363 646 56.2 %
Date: 2024-12-28 18:40:32 Functions: 19 25 76.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 153 399 38.3 %

           Branch data     Line data    Source code
       1                 :            : /*-
       2                 :            :  * Copyright (c) 2011-2013 Baptiste Daroussin <bapt@FreeBSD.org>
       3                 :            :  * Copyright (c) 2011-2012 Julien Laffaye <jlaffaye@FreeBSD.org>
       4                 :            :  * All rights reserved.
       5                 :            :  * Copyright (c) 2021 Kyle Evans <kevans@FreeBSD.org>
       6                 :            :  *
       7                 :            :  * Redistribution and use in source and binary forms, with or without
       8                 :            :  * modification, are permitted provided that the following conditions
       9                 :            :  * are met:
      10                 :            :  * 1. Redistributions of source code must retain the above copyright
      11                 :            :  *    notice, this list of conditions and the following disclaimer
      12                 :            :  *    in this position and unchanged.
      13                 :            :  * 2. Redistributions in binary form must reproduce the above copyright
      14                 :            :  *    notice, this list of conditions and the following disclaimer in the
      15                 :            :  *    documentation and/or other materials provided with the distribution.
      16                 :            :  *
      17                 :            :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
      18                 :            :  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
      19                 :            :  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
      20                 :            :  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
      21                 :            :  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      22                 :            :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      23                 :            :  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      24                 :            :  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      25                 :            :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
      26                 :            :  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      27                 :            :  */
      28                 :            : 
      29                 :            : #include <sys/stat.h>
      30                 :            : #include <sys/param.h>
      31                 :            : 
      32                 :            : #include <ctype.h>
      33                 :            : #include <fcntl.h>
      34                 :            : #include <strings.h>
      35                 :            : 
      36                 :            : #include <libder.h>
      37                 :            : 
      38                 :            : #define WITH_STDLIB
      39                 :            : #include <libecc/libsig.h>
      40                 :            : #undef WITH_STDLIB
      41                 :            : 
      42                 :            : #include "pkg.h"
      43                 :            : #include "private/event.h"
      44                 :            : #include "private/pkg.h"
      45                 :            : #include "private/pkgsign.h"
      46                 :            : 
      47                 :            : struct ecc_sign_ctx {
      48                 :            :         struct pkgsign_ctx      sctx;
      49                 :            :         ec_params               params;
      50                 :            :         ec_key_pair             keypair;
      51                 :            :         ec_alg_type             sig_alg;
      52                 :            :         hash_alg_type           sig_hash;
      53                 :            :         bool                    loaded;
      54                 :            : };
      55                 :            : 
      56                 :            : /* Grab the ossl context from a pkgsign_ctx. */
      57                 :            : #define ECC_CTX(c)      ((struct ecc_sign_ctx *)(c))
      58                 :            : 
      59                 :            : #define PUBKEY_UNCOMPRESSED     0x04
      60                 :            : 
      61                 :            : #ifndef MAX
      62                 :            : #define MAX(a,b)        (((a)>(b))?(a):(b))
      63                 :            : #endif
      64                 :            : 
      65                 :            : static const uint8_t oid_ecpubkey[] = \
      66                 :            :     { 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01 };
      67                 :            : 
      68                 :            : static const uint8_t oid_secp[] = \
      69                 :            :     { 0x2b, 0x81, 0x04, 0x00 };
      70                 :            : static const uint8_t oid_secp256k1[] = \
      71                 :            :     { 0x2b, 0x81, 0x04, 0x00, 0x0a };
      72                 :            : static const uint8_t oid_brainpoolP[] = \
      73                 :            :     { 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01 };
      74                 :            : 
      75                 :            : #define ENTRY(name, params)     { #name, sizeof(#name) - 1, params }
      76                 :            : static const struct pkgkey_map_entry {
      77                 :            :         const char              *name;
      78                 :            :         size_t                   namesz;
      79                 :            :         const ec_str_params     *params;
      80                 :            : } pkgkey_map[] = {
      81                 :            :         ENTRY(WEI25519, &wei25519_str_params),
      82                 :            :         ENTRY(SECP256K1, &secp256k1_str_params),
      83                 :            :         ENTRY(SECP384R1, &secp384r1_str_params),
      84                 :            :         ENTRY(SECP512R1, &secp521r1_str_params),
      85                 :            :         ENTRY(BRAINPOOLP256R1, &brainpoolp256r1_str_params),
      86                 :            :         ENTRY(BRAINPOOLP256T1, &brainpoolp256t1_str_params),
      87                 :            :         ENTRY(BRAINPOOLP320R1, &brainpoolp320r1_str_params),
      88                 :            :         ENTRY(BRAINPOOLP320T1, &brainpoolp320t1_str_params),
      89                 :            :         ENTRY(BRAINPOOLP384R1, &brainpoolp384r1_str_params),
      90                 :            :         ENTRY(BRAINPOOLP384T1, &brainpoolp384t1_str_params),
      91                 :            :         ENTRY(BRAINPOOLP512R1, &brainpoolp512r1_str_params),
      92                 :            :         ENTRY(BRAINPOOLP512T1, &brainpoolp512t1_str_params),
      93                 :            : };
      94                 :            : 
      95                 :            : static const char pkgkey_app[] = "pkg";
      96                 :            : static const char pkgkey_signer[] = "ecc";
      97                 :            : 
      98                 :            : static const ec_str_params *
      99                 :          2 : ecc_pkgkey_params(const uint8_t *curve, size_t curvesz)
     100                 :            : {
     101                 :            :         const struct pkgkey_map_entry *entry;
     102                 :            : 
     103         [ +  - ]:          3 :         for (size_t i = 0; i < NELEM(pkgkey_map); i++) {
     104                 :          3 :                 entry = &pkgkey_map[i];
     105         [ +  + ]:          3 :                 if (curvesz != entry->namesz)
     106                 :          1 :                         continue;
     107         [ +  - ]:          2 :                 if (memcmp(curve, entry->name, curvesz) == 0)
     108                 :          2 :                         return (entry->params);
     109                 :          0 :         }
     110                 :            : 
     111                 :          0 :         return (NULL);
     112                 :          2 : }
     113                 :            : 
     114                 :            : /*
     115                 :            :  * PKCS#8 Key:
     116                 :            :  *     PublicKeyInfo ::= SEQUENCE {
     117                 :            :  *       algorithm   AlgorithmIdentifier,
     118                 :            :  *       PublicKey   BIT STRING
     119                 :            :  *     }
     120                 :            :  *
     121                 :            :  *     AlgorithmIdentifier ::= SEQUENCE {
     122                 :            :  *       algorithm   OBJECT IDENTIFIER,
     123                 :            :  *       parameters  ANY DEFINED BY algorithm OPTIONAL
     124                 :            :  *      }
     125                 :            :  *
     126                 :            :  */
     127                 :            : /* XXX Should eventually support other kinds of keys. */
     128                 :            : static int
     129                 :          2 : ecc_pubkey_write_pkcs8(const uint8_t *keydata, size_t keysz,
     130                 :            :     uint8_t **buf, size_t *buflen)
     131                 :            : {
     132                 :            :         uint8_t keybuf[EC_PUB_KEY_MAX_SIZE + 2], *outbuf;
     133                 :            :         struct libder_ctx *ctx;
     134                 :            :         struct libder_object *keybits, *oid, *params, *root;
     135                 :            :         int rc;
     136                 :            :         bool ok;
     137                 :            : 
     138         [ -  + ]:          2 :         if (keysz > sizeof(keybuf) - 2)
     139                 :          0 :                 return (EPKG_FATAL);
     140                 :            : 
     141                 :          2 :         ctx = libder_open();
     142         [ +  - ]:          2 :         if (ctx == NULL)
     143                 :          0 :                 return (EPKG_FATAL);
     144                 :            : 
     145                 :          2 :         rc = EPKG_FATAL;
     146                 :          2 :         root = libder_obj_alloc_simple(ctx, BT_SEQUENCE, NULL, 0);
     147         [ +  - ]:          2 :         if (root == NULL)
     148                 :          0 :                 goto out;
     149                 :            : 
     150                 :          2 :         params = libder_obj_alloc_simple(ctx, BT_SEQUENCE, NULL, 0);
     151         [ +  - ]:          2 :         if (params == NULL)
     152                 :          0 :                 goto out;
     153                 :            : 
     154                 :          2 :         ok = libder_obj_append(root, params);
     155         [ +  - ]:          2 :         assert(ok);
     156                 :            : 
     157                 :            :         /* id-ecPublicKey */
     158                 :          2 :         oid = libder_obj_alloc_simple(ctx, BT_OID, oid_ecpubkey,
     159                 :            :             sizeof(oid_ecpubkey));
     160         [ +  - ]:          2 :         if (oid == NULL)
     161                 :          0 :                 goto out;
     162                 :          2 :         ok = libder_obj_append(params, oid);
     163         [ +  - ]:          2 :         assert(ok);
     164                 :            : 
     165                 :            :         /*
     166                 :            :          * secp256k1, we should eventually allow other curves and actually
     167                 :            :          * construct the OID.
     168                 :            :          */
     169                 :          2 :         oid = libder_obj_alloc_simple(ctx, BT_OID, oid_secp256k1,
     170                 :            :             sizeof(oid_secp256k1));
     171         [ +  - ]:          2 :         if (oid == NULL)
     172                 :          0 :                 goto out;
     173                 :          2 :         ok = libder_obj_append(params, oid);
     174         [ +  - ]:          2 :         assert(ok);
     175                 :            : 
     176                 :          2 :         memset(keybuf, 0, sizeof(keybuf));
     177                 :          2 :         keybuf[0] = 0;  /* No unused bits */
     178                 :          2 :         keybuf[1] = PUBKEY_UNCOMPRESSED;
     179                 :          2 :         memcpy(&keybuf[2], keydata, keysz);
     180                 :            : 
     181                 :          4 :         keybits = libder_obj_alloc_simple(ctx, BT_BITSTRING, &keybuf[0],
     182                 :          2 :             keysz + 2);
     183         [ +  - ]:          2 :         if (keybits == NULL)
     184                 :          0 :                 goto out;
     185                 :          2 :         ok = libder_obj_append(root, keybits);
     186         [ +  - ]:          2 :         assert(ok);
     187                 :            : 
     188                 :            :         /* Finally, write it out. */
     189                 :          2 :         *buflen = 0;
     190                 :          2 :         outbuf = libder_write(ctx, root, NULL, buflen);
     191         [ +  - ]:          4 :         if (outbuf != NULL) {
     192                 :          2 :                 *buf = outbuf;
     193                 :          2 :                 rc = EPKG_OK;
     194                 :          2 :         }
     195                 :            : 
     196                 :            : out:
     197                 :          2 :         libder_obj_free(root);
     198                 :          2 :         libder_close(ctx);
     199                 :          2 :         return (rc);
     200                 :          2 : }
     201                 :            : 
     202                 :            : /*
     203                 :            :  * pkg key (only for EdDSA):
     204                 :            :  *     PkgPublicKeyInfo ::= SEQUENCE {
     205                 :            :  *       Application UTF8String
     206                 :            :  *       Version     INTEGER
     207                 :            :  *       Signer      UTF8String
     208                 :            :  *       KeyType     UTF8String
     209                 :            :  *       Public      BOOLEAN
     210                 :            :  *       Key         BIT STRING
     211                 :            :  *     }
     212                 :            :  *
     213                 :            :  * "Application" will literally contain the string: "pkg"
     214                 :            :  * "Version" must be 1
     215                 :            :  * "Signer" must contain the part after "pkgsign_"
     216                 :            :  * "KeyType" is signer-defined; for ECC, it must be the curve_name
     217                 :            :  * "Public" is self-explanatory
     218                 :            :  * "Key" is the key data itself, encoded as the PKCS#8 public key bit string
     219                 :            :  *   with a lead byte indicating uncompressed (0x04)
     220                 :            :  */
     221                 :            : static int
     222                 :          8 : ecc_write_pkgkey(const ec_params *params, uint8_t public,
     223                 :            :     const uint8_t *keydata, size_t keysz, uint8_t **buf, size_t *buflen)
     224                 :            : {
     225                 :            :         uint8_t keybuf[MAX(EC_PRIV_KEY_MAX_SIZE, EC_PUB_KEY_MAX_SIZE) + 2];
     226                 :            :         uint8_t *outbuf;
     227                 :            :         struct libder_ctx *ctx;
     228                 :            :         struct libder_object *keybits, *obj, *root;
     229                 :            :         int rc;
     230                 :          8 :         uint8_t version = 1;
     231                 :            :         bool ok;
     232                 :            : 
     233         [ -  + ]:          8 :         if (keysz > sizeof(keybuf) - 2)
     234                 :          0 :                 return (EPKG_FATAL);
     235                 :            : 
     236                 :          8 :         ctx = libder_open();
     237         [ +  - ]:          8 :         if (ctx == NULL)
     238                 :          0 :                 return (EPKG_FATAL);
     239                 :            : 
     240                 :          8 :         rc = EPKG_FATAL;
     241                 :          8 :         root = libder_obj_alloc_simple(ctx, BT_SEQUENCE, NULL, 0);
     242         [ +  - ]:          8 :         if (root == NULL)
     243                 :          0 :                 goto out;
     244                 :            : 
     245                 :            :         /* Application */
     246                 :          8 :         obj = libder_obj_alloc_simple(ctx, BT_UTF8STRING, pkgkey_app,
     247                 :            :             sizeof(pkgkey_app) - 1);
     248         [ +  - ]:          8 :         if (obj == NULL)
     249                 :          0 :                 goto out;
     250                 :          8 :         ok = libder_obj_append(root, obj);
     251         [ +  - ]:          8 :         assert(ok);
     252                 :            : 
     253                 :            :         /* Version */
     254                 :          8 :         obj = libder_obj_alloc_simple(ctx, BT_INTEGER, &version, sizeof(version));
     255         [ +  - ]:          8 :         if (obj == NULL)
     256                 :          0 :                 goto out;
     257                 :          8 :         ok = libder_obj_append(root, obj);
     258         [ +  - ]:          8 :         assert(ok);
     259                 :            : 
     260                 :            :         /* Signer */
     261                 :          8 :         obj = libder_obj_alloc_simple(ctx, BT_UTF8STRING, pkgkey_signer,
     262                 :            :             sizeof(pkgkey_signer) - 1);
     263         [ +  - ]:          8 :         if (obj == NULL)
     264                 :          0 :                 goto out;
     265                 :          8 :         ok = libder_obj_append(root, obj);
     266         [ +  - ]:          8 :         assert(ok);
     267                 :            : 
     268                 :            :         /* KeyType */
     269                 :         16 :         obj = libder_obj_alloc_simple(ctx, BT_UTF8STRING, params->curve_name,
     270                 :          8 :             strlen(params->curve_name));
     271         [ +  - ]:          8 :         if (obj == NULL)
     272                 :          0 :                 goto out;
     273                 :          8 :         ok = libder_obj_append(root, obj);
     274         [ +  - ]:          8 :         assert(ok);
     275                 :            : 
     276                 :            :         /* Public */
     277                 :          8 :         obj = libder_obj_alloc_simple(ctx, BT_BOOLEAN, &public, sizeof(public));
     278         [ +  - ]:          8 :         if (obj == NULL)
     279                 :          0 :                 goto out;
     280                 :          8 :         ok = libder_obj_append(root, obj);
     281         [ +  - ]:          8 :         assert(ok);
     282                 :            : 
     283                 :          8 :         memset(keybuf, 0, sizeof(keybuf));
     284                 :          8 :         keybuf[0] = 0;  /* No unused bits */
     285                 :          8 :         keybuf[1] = PUBKEY_UNCOMPRESSED;
     286                 :          8 :         memcpy(&keybuf[2], keydata, keysz);
     287                 :            : 
     288                 :         16 :         keybits = libder_obj_alloc_simple(ctx, BT_BITSTRING, &keybuf[0],
     289                 :          8 :             keysz + 2);
     290         [ +  - ]:          8 :         if (keybits == NULL)
     291                 :          0 :                 goto out;
     292                 :          8 :         ok = libder_obj_append(root, keybits);
     293         [ +  - ]:          8 :         assert(ok);
     294                 :            : 
     295                 :            :         /* Finally, write it out. */
     296                 :          8 :         *buflen = 0;
     297                 :          8 :         outbuf = libder_write(ctx, root, NULL, buflen);
     298         [ -  + ]:         16 :         if (outbuf != NULL) {
     299                 :          8 :                 *buf = outbuf;
     300                 :          8 :                 rc = EPKG_OK;
     301                 :          8 :         }
     302                 :            : 
     303                 :            : out:
     304                 :          8 :         libder_obj_free(root);
     305                 :          8 :         libder_close(ctx);
     306                 :          8 :         return (rc);
     307                 :          8 : }
     308                 :            : 
     309                 :            : static int
     310                 :          2 : ecc_read_pkgkey(struct libder_object *root, ec_params *params, int public,
     311                 :            :     uint8_t *rawkey, size_t *rawlen)
     312                 :            : {
     313                 :            :         struct libder_object *obj;
     314                 :            :         const uint8_t *data;
     315                 :            :         const ec_str_params *sparams;
     316                 :            :         size_t datasz;
     317                 :            :         int ret;
     318                 :            : 
     319         [ -  + ]:          2 :         if (libder_obj_type_simple(root) != BT_SEQUENCE)
     320                 :          0 :                 return (EPKG_FATAL);
     321                 :            : 
     322                 :            :         /* Application */
     323                 :          2 :         obj = libder_obj_child(root, 0);
     324   [ +  -  -  + ]:          2 :         if (obj == NULL || libder_obj_type_simple(obj) != BT_UTF8STRING)
     325                 :          0 :                 return (EPKG_FATAL);
     326                 :          2 :         data = libder_obj_data(obj, &datasz);
     327   [ +  -  -  + ]:          2 :         if (datasz != sizeof(pkgkey_app) - 1 ||
     328                 :          2 :             memcmp(data, pkgkey_app, datasz) != 0)
     329                 :          0 :                 return (EPKG_FATAL);
     330                 :            : 
     331                 :            :         /* Version */
     332                 :          2 :         obj = libder_obj_child(root, 1);
     333   [ +  -  -  + ]:          2 :         if (obj == NULL || libder_obj_type_simple(obj) != BT_INTEGER)
     334                 :          0 :                 return (EPKG_FATAL);
     335                 :          2 :         data = libder_obj_data(obj, &datasz);
     336   [ +  -  -  + ]:          2 :         if (datasz != 1 || *data != 1 /* XXX */)
     337                 :          0 :                 return (EPKG_FATAL);
     338                 :            : 
     339                 :            :         /* Signer */
     340                 :          2 :         obj = libder_obj_child(root, 2);
     341   [ +  -  -  + ]:          2 :         if (obj == NULL || libder_obj_type_simple(obj) != BT_UTF8STRING)
     342                 :          0 :                 return (EPKG_FATAL);
     343                 :          2 :         data = libder_obj_data(obj, &datasz);
     344   [ +  -  -  + ]:          2 :         if (datasz != sizeof(pkgkey_signer) - 1 ||
     345                 :          2 :             memcmp(data, pkgkey_signer, datasz) != 0)
     346                 :          0 :                 return (EPKG_FATAL);
     347                 :            : 
     348                 :            :         /* KeyType (curve) */
     349                 :          2 :         obj = libder_obj_child(root, 3);
     350   [ +  -  -  + ]:          2 :         if (obj == NULL || libder_obj_type_simple(obj) != BT_UTF8STRING)
     351                 :          0 :                 return (EPKG_FATAL);
     352                 :          2 :         data = libder_obj_data(obj, &datasz);
     353                 :          2 :         sparams = ecc_pkgkey_params(data, datasz);
     354         [ +  - ]:          2 :         if (sparams == NULL)
     355                 :          0 :                 return (EPKG_FATAL);
     356                 :            : 
     357                 :          2 :         ret = import_params(params, sparams);
     358         [ -  + ]:          2 :         if (ret != 0)
     359                 :          0 :                 return (EPKG_FATAL);
     360                 :            : 
     361                 :            :         /* Public? */
     362                 :          2 :         obj = libder_obj_child(root, 4);
     363   [ +  -  -  + ]:          2 :         if (obj == NULL || libder_obj_type_simple(obj) != BT_BOOLEAN)
     364                 :          0 :                 return (EPKG_FATAL);
     365                 :          2 :         data = libder_obj_data(obj, &datasz);
     366   [ +  -  -  + ]:          2 :         if (datasz != 1 || !data[0] != !public)
     367                 :          0 :                 return (EPKG_FATAL);
     368                 :            : 
     369                 :            :         /* Key */
     370                 :          2 :         obj = libder_obj_child(root, 5);
     371   [ +  -  -  + ]:          2 :         if (obj == NULL || libder_obj_type_simple(obj) != BT_BITSTRING)
     372                 :          0 :                 return (EPKG_FATAL);
     373                 :          2 :         data = libder_obj_data(obj, &datasz);
     374   [ +  -  -  +  :          2 :         if (datasz <= 2 || data[0] != 0 || data[1] != PUBKEY_UNCOMPRESSED)
                   -  + ]
     375                 :          0 :                 return (EPKG_FATAL);
     376                 :            : 
     377                 :          2 :         data += 2;
     378                 :          2 :         datasz -= 2;
     379                 :            : 
     380         [ -  + ]:          2 :         if (datasz > *rawlen)
     381                 :          0 :                 return (EPKG_FATAL);
     382                 :            : 
     383                 :            : 
     384                 :          2 :         memcpy(rawkey, data, datasz);
     385                 :          2 :         *rawlen = datasz;
     386                 :            : 
     387                 :          2 :         return (EPKG_OK);
     388                 :          2 : }
     389                 :            : 
     390                 :            : static int
     391                 :         10 : ecc_write_signature_component(struct libder_ctx *ctx, struct libder_object *root,
     392                 :            :     const uint8_t *sigpart, size_t partlen)
     393                 :            : {
     394                 :            :         uint8_t sigbounce[EC_MAX_SIGLEN];
     395                 :            :         struct libder_object *obj;
     396                 :            :         size_t curlen;
     397                 :            :         bool ok;
     398                 :            : 
     399                 :            :         /*
     400                 :            :          * If we need a leading 0 because the sign bit is set, we may need to
     401                 :            :          * bounce through sigbounce.  We may also need to bounce if there's some
     402                 :            :          * leading zeros.
     403                 :            :          */
     404                 :         10 :         curlen = partlen;
     405   [ +  -  +  -  :         10 :         while (curlen > 0 && sigpart[0] == 0) {
                   -  + ]
     406                 :          0 :                 curlen--;
     407                 :          0 :                 sigpart++;
     408                 :            :         }
     409                 :            : 
     410         [ +  + ]:         10 :         if ((sigpart[0] & 0x80) != 0) {
     411                 :            :                 /*
     412                 :            :                  * If the high bit is set, we need to bounce it through
     413                 :            :                  * sigbounce and insert a leading 0.
     414                 :            :                  */
     415                 :          6 :                 sigbounce[0] = 0;
     416                 :          6 :                 memcpy(&sigbounce[1], sigpart, curlen);
     417                 :            : 
     418                 :         12 :                 obj = libder_obj_alloc_simple(ctx, BT_INTEGER, sigbounce,
     419                 :          6 :                     curlen + 1);
     420                 :          6 :         } else {
     421                 :            :                 /*
     422                 :            :                  * Otherwise, we can just leave it be.
     423                 :            :                  */
     424                 :            : 
     425                 :          4 :                 obj = libder_obj_alloc_simple(ctx, BT_INTEGER, sigpart, curlen);
     426                 :            :         }
     427                 :            : 
     428         [ +  - ]:         10 :         if (obj == NULL)
     429                 :          0 :                 return (EPKG_FATAL);
     430                 :            : 
     431                 :         10 :         ok = libder_obj_append(root, obj);
     432         [ +  - ]:         10 :         assert(ok);
     433                 :         10 :         return (EPKG_OK);
     434                 :         10 : }
     435                 :            : 
     436                 :            : /*
     437                 :            :  *       Ecdsa-Sig-Value  ::=  SEQUENCE  {
     438                 :            :  *            r     INTEGER,
     439                 :            :  *            s     INTEGER  }
     440                 :            :  */
     441                 :            : static int
     442                 :          5 : ecc_write_signature(const uint8_t *sig, size_t siglen, uint8_t **sigret,
     443                 :            :     size_t *sigretlen)
     444                 :            : {
     445                 :            :         struct libder_ctx *ctx;
     446                 :            :         struct libder_object *obj, *root;
     447                 :            :         uint8_t *outbuf;
     448                 :            :         size_t complen;
     449                 :            :         int rc;
     450                 :            : 
     451                 :          5 :         ctx = libder_open();
     452         [ +  - ]:          5 :         if (ctx == NULL)
     453                 :          0 :                 return (EPKG_FATAL);
     454                 :            : 
     455                 :          5 :         rc = EPKG_FATAL;
     456                 :          5 :         obj = NULL;
     457                 :          5 :         root = libder_obj_alloc_simple(ctx, BT_SEQUENCE, NULL, 0);
     458         [ +  - ]:          5 :         if (root == NULL)
     459                 :          0 :                 goto out;
     460                 :            : 
     461                 :          5 :         complen = siglen / 2;
     462                 :          5 :         rc = ecc_write_signature_component(ctx, root, sig, complen);
     463         [ -  + ]:          5 :         if (rc != EPKG_OK)
     464                 :          0 :                 goto out;
     465                 :            : 
     466                 :          5 :         sig += complen;
     467                 :          5 :         siglen -= complen;
     468                 :          5 :         rc = ecc_write_signature_component(ctx, root, sig, complen);
     469         [ -  + ]:          5 :         if (rc != EPKG_OK)
     470                 :          0 :                 goto out;
     471                 :            : 
     472                 :          5 :         *sigretlen = 0;
     473                 :          5 :         outbuf = libder_write(ctx, root, NULL, sigretlen);
     474         [ -  + ]:         10 :         if (outbuf != NULL) {
     475                 :          5 :                 *sigret = outbuf;
     476                 :          5 :                 rc = EPKG_OK;
     477                 :          5 :         }
     478                 :            : out:
     479                 :          5 :         libder_obj_free(obj);
     480                 :          5 :         libder_close(ctx);
     481                 :          5 :         return (rc);
     482                 :          5 : }
     483                 :            : 
     484                 :            : static int
     485                 :          0 : ecc_extract_signature(const uint8_t *sig, size_t siglen, uint8_t *rawsig,
     486                 :            :     size_t rawlen)
     487                 :            : {
     488                 :            :         struct libder_ctx *ctx;
     489                 :            :         struct libder_object *obj, *root;
     490                 :            :         const uint8_t *sigdata;
     491                 :            :         size_t compsz, datasz, sigoff;
     492                 :            :         int rc;
     493                 :            : 
     494                 :          0 :         ctx = libder_open();
     495         [ #  # ]:          0 :         if (ctx == NULL)
     496                 :          0 :                 return (EPKG_FATAL);
     497                 :            : 
     498                 :          0 :         rc = EPKG_FATAL;
     499                 :          0 :         root = libder_read(ctx, sig, &siglen);
     500   [ #  #  #  # ]:          0 :         if (root == NULL || libder_obj_type_simple(root) != BT_SEQUENCE)
     501                 :          0 :                 goto out;
     502                 :            : 
     503                 :            :         /* Descend into the sequence's payload, extract both numbers. */
     504                 :          0 :         compsz = rawlen / 2;
     505                 :          0 :         sigoff = 0;
     506         [ #  # ]:          0 :         for (int i = 0; i < 2; i++) {
     507                 :          0 :                 obj = libder_obj_child(root, i);
     508         [ #  # ]:          0 :                 if (libder_obj_type_simple(obj) != BT_INTEGER)
     509                 :          0 :                         goto out;
     510                 :            : 
     511                 :          0 :                 sigdata = libder_obj_data(obj, &datasz);
     512   [ #  #  #  # ]:          0 :                 if (datasz < 2 || datasz > compsz + 1)
     513                 :          0 :                         goto out;
     514                 :            : 
     515                 :            :                 /*
     516                 :            :                  * We may see an extra lead byte if our high bit of the first
     517                 :            :                  * byte was set, since these numbers are positive by definition.
     518                 :            :                  */
     519   [ #  #  #  # ]:          0 :                 if (sigdata[0] == 0 && (sigdata[1] & 0x80) != 0) {
     520                 :          0 :                         sigdata++;
     521                 :          0 :                         datasz--;
     522                 :          0 :                 }
     523                 :            : 
     524                 :            :                 /* Sanity check: don't overflow the output. */
     525         [ #  # ]:          0 :                 if (sigoff + datasz > rawlen)
     526                 :          0 :                         goto out;
     527                 :            : 
     528                 :            :                 /* Padding to the significant end if we're too small. */
     529         [ #  # ]:          0 :                 if (datasz < compsz) {
     530                 :          0 :                         memset(&rawsig[sigoff], 0, compsz - datasz);
     531                 :          0 :                         sigoff += compsz - datasz;
     532                 :          0 :                 }
     533                 :            : 
     534                 :          0 :                 memcpy(&rawsig[sigoff], sigdata, datasz);
     535                 :          0 :                 sigoff += datasz;
     536                 :          0 :         }
     537                 :            : 
     538                 :            :         /* Sanity check: must have exactly the required # of signature bits. */
     539                 :          0 :         rc = (sigoff == rawlen) ? EPKG_OK : EPKG_FATAL;
     540                 :            : 
     541                 :            : out:
     542                 :          0 :         libder_obj_free(root);
     543                 :          0 :         libder_close(ctx);
     544                 :          0 :         return (rc);
     545                 :          0 : }
     546                 :            : 
     547                 :            : static int
     548                 :          0 : ecc_extract_pubkey_string(const uint8_t *data, size_t datalen, uint8_t *rawkey,
     549                 :            :     size_t *rawlen)
     550                 :            : {
     551                 :            :         uint8_t prefix, usebit;
     552                 :            : 
     553         [ #  # ]:          0 :         if (datalen <= 2)
     554                 :          0 :                 return (EPKG_FATAL);
     555                 :            : 
     556                 :          0 :         usebit = *data++;
     557                 :          0 :         datalen--;
     558                 :            : 
     559         [ #  # ]:          0 :         if (usebit != 0)
     560                 :          0 :                 return (EPKG_FATAL);
     561                 :            : 
     562                 :          0 :         prefix = *data++;
     563                 :          0 :         datalen--;
     564                 :            : 
     565         [ #  # ]:          0 :         if (prefix != PUBKEY_UNCOMPRESSED)
     566                 :          0 :                 return (EPKG_FATAL);
     567                 :            : 
     568         [ #  # ]:          0 :         if (datalen > *rawlen)
     569                 :          0 :                 return (EPKG_FATAL);
     570                 :            : 
     571                 :          0 :         memcpy(rawkey, data, datalen);
     572                 :          0 :         *rawlen = datalen;
     573                 :            : 
     574                 :          0 :         return (EPKG_OK);
     575                 :          0 : }
     576                 :            : 
     577                 :            : static int
     578                 :          1 : ecc_extract_key_params(const uint8_t *oid, size_t oidlen,
     579                 :            :     ec_params *rawparams)
     580                 :            : {
     581                 :            :         int ret;
     582                 :            : 
     583   [ +  -  -  + ]:          1 :         if (oidlen >= sizeof(oid_secp) &&
     584                 :          1 :             memcmp(oid, oid_secp, sizeof(oid_secp)) >= 0) {
     585                 :          1 :                 oid += sizeof(oid_secp);
     586                 :          1 :                 oidlen -= sizeof(oid_secp);
     587                 :            : 
     588         [ -  + ]:          1 :                 if (oidlen != 1)
     589                 :          0 :                         return (EPKG_FATAL);
     590                 :            : 
     591                 :          1 :                 ret = -1;
     592   [ -  -  +  - ]:          1 :                 switch (*oid) {
     593                 :            :                 case 0x0a:      /* secp256k1 */
     594                 :          1 :                         ret = import_params(rawparams, &secp256k1_str_params);
     595                 :          1 :                         break;
     596                 :            :                 case 0x22:      /* secp384r1 */
     597                 :          0 :                         ret = import_params(rawparams, &secp384r1_str_params);
     598                 :          0 :                         break;
     599                 :            :                 case 0x23:      /* secp521r1 */
     600                 :          0 :                         ret = import_params(rawparams, &secp521r1_str_params);
     601                 :          0 :                         break;
     602                 :            :                 default:
     603                 :          0 :                         return (EPKG_FATAL);
     604                 :            :                 }
     605                 :            : 
     606         [ -  + ]:          1 :                 if (ret == 0)
     607                 :          1 :                         return (EPKG_OK);
     608                 :          0 :                 return (EPKG_FATAL);
     609                 :            :         }
     610                 :            : 
     611   [ #  #  #  # ]:          0 :         if (oidlen >= sizeof(oid_brainpoolP) &&
     612                 :          0 :             memcmp(oid, oid_brainpoolP, sizeof(oid_brainpoolP)) >= 0) {
     613                 :          0 :                 oid += sizeof(oid_brainpoolP);
     614                 :          0 :                 oidlen -= sizeof(oid_brainpoolP);
     615                 :            : 
     616         [ #  # ]:          0 :                 if (oidlen != 1)
     617                 :          0 :                         return (EPKG_FATAL);
     618                 :            : 
     619                 :          0 :                 ret = -1;
     620   [ #  #  #  #  :          0 :                 switch (*oid) {
             #  #  #  #  
                      # ]
     621                 :            :                 case 0x07:      /* brainpoolP256r1 */
     622                 :          0 :                         ret = import_params(rawparams, &brainpoolp256r1_str_params);
     623                 :          0 :                         break;
     624                 :            :                 case 0x08:      /* brainpoolP256t1 */
     625                 :          0 :                         ret = import_params(rawparams, &brainpoolp256t1_str_params);
     626                 :          0 :                         break;
     627                 :            :                 case 0x09:      /* brainpoolP320r1 */
     628                 :          0 :                         ret = import_params(rawparams, &brainpoolp320r1_str_params);
     629                 :          0 :                         break;
     630                 :            :                 case 0x0a:      /* brainpoolP320t1 */
     631                 :          0 :                         ret = import_params(rawparams, &brainpoolp320t1_str_params);
     632                 :          0 :                         break;
     633                 :            :                 case 0x0b:      /* brainpoolP384r1 */
     634                 :          0 :                         ret = import_params(rawparams, &brainpoolp384r1_str_params);
     635                 :          0 :                         break;
     636                 :            :                 case 0x0c:      /* brainpoolP384t1 */
     637                 :          0 :                         ret = import_params(rawparams, &brainpoolp384t1_str_params);
     638                 :          0 :                         break;
     639                 :            :                 case 0x0d:      /* brainpoolP512r1 */
     640                 :          0 :                         ret = import_params(rawparams, &brainpoolp512r1_str_params);
     641                 :          0 :                         break;
     642                 :            :                 case 0x0e:      /* brainpoolP512t1 */
     643                 :          0 :                         ret = import_params(rawparams, &brainpoolp512t1_str_params);
     644                 :          0 :                         break;
     645                 :            :                 default:
     646                 :          0 :                         return (EPKG_FATAL);
     647                 :            :                 }
     648                 :            : 
     649         [ #  # ]:          0 :                 if (ret == 0)
     650                 :          0 :                         return (EPKG_OK);
     651                 :          0 :                 return (EPKG_FATAL);
     652                 :            :         }
     653                 :            : 
     654                 :            : #ifdef ECC_DEBUG
     655                 :            :         for (size_t i = 0; i < oidlen; i++) {
     656                 :            :                 fprintf(stderr, "%.02x ", oid[i]);
     657                 :            :         }
     658                 :            : 
     659                 :            :         fprintf(stderr, "\n");
     660                 :            : #endif
     661                 :            : 
     662                 :          0 :         return (EPKG_FATAL);
     663                 :          1 : }
     664                 :            : 
     665                 :            : /*
     666                 :            :  * On entry, *rawparams should point to an ec_params that we can import the
     667                 :            :  * key parameters to.  We'll either do that, or we'll set it to NULL if we could
     668                 :            :  * not deduce the curve.
     669                 :            :  */
     670                 :            : static int
     671                 :          0 : ecc_extract_pubkey(const uint8_t *key, size_t keylen, uint8_t *rawkey,
     672                 :            :     size_t *rawlen, ec_params *rawparams)
     673                 :            : {
     674                 :            :         const uint8_t *oidp;
     675                 :            :         struct libder_ctx *ctx;
     676                 :            :         struct libder_object *keydata, *oid, *params, *root;
     677                 :            :         size_t oidsz;
     678                 :            :         int rc;
     679                 :            : 
     680                 :          0 :         ctx = libder_open();
     681         [ #  # ]:          0 :         if (ctx == NULL)
     682                 :          0 :                 return (EPKG_FATAL);
     683                 :            : 
     684                 :          0 :         rc = EPKG_FATAL;
     685                 :          0 :         root = libder_read(ctx, key, &keylen);
     686   [ #  #  #  # ]:          0 :         if (root == NULL || libder_obj_type_simple(root) != BT_SEQUENCE)
     687                 :          0 :                 goto out;
     688                 :            : 
     689                 :          0 :         params = libder_obj_child(root, 0);
     690                 :            : 
     691         [ #  # ]:          0 :         if (params == NULL) {
     692                 :          0 :                 goto out;
     693         [ #  # ]:          0 :         } else if (libder_obj_type_simple(params) != BT_SEQUENCE) {
     694                 :          0 :                 rc = ecc_read_pkgkey(root, rawparams, 1, rawkey, rawlen);
     695                 :          0 :                 goto out;
     696                 :            :         }
     697                 :            : 
     698                 :            :         /* Is a sequence */
     699                 :          0 :         keydata = libder_obj_child(root, 1);
     700   [ #  #  #  # ]:          0 :         if (keydata == NULL || libder_obj_type_simple(keydata) != BT_BITSTRING)
     701                 :          0 :                 goto out;
     702                 :            : 
     703                 :            :         /* Key type */
     704                 :          0 :         oid = libder_obj_child(params, 0);
     705   [ #  #  #  # ]:          0 :         if (oid == NULL || libder_obj_type_simple(oid) != BT_OID)
     706                 :          0 :                 goto out;
     707                 :            : 
     708                 :          0 :         oidp = libder_obj_data(oid, &oidsz);
     709   [ #  #  #  # ]:          0 :         if (oidsz != sizeof(oid_ecpubkey) ||
     710                 :          0 :             memcmp(oidp, oid_ecpubkey, oidsz) != 0)
     711                 :          0 :                 return (EPKG_FATAL);
     712                 :            : 
     713                 :            :         /* Curve */
     714                 :          0 :         oid = libder_obj_child(params, 1);
     715   [ #  #  #  # ]:          0 :         if (oid == NULL || libder_obj_type_simple(oid) != BT_OID)
     716                 :          0 :                 goto out;
     717                 :            : 
     718                 :          0 :         oidp = libder_obj_data(oid, &oidsz);
     719         [ #  # ]:          0 :         if (ecc_extract_key_params(oidp, oidsz, rawparams) != EPKG_OK)
     720                 :          0 :                 goto out;
     721                 :            : 
     722                 :            :         /* Finally, peel off the key material */
     723                 :          0 :         key = libder_obj_data(keydata, &keylen);
     724         [ #  # ]:          0 :         if (ecc_extract_pubkey_string(key, keylen, rawkey, rawlen) != EPKG_OK)
     725                 :          0 :                 goto out;
     726                 :            : 
     727                 :          0 :         rc = EPKG_OK;
     728                 :            : out:
     729                 :          0 :         libder_obj_free(root);
     730                 :          0 :         libder_close(ctx);
     731                 :          0 :         return (rc);
     732                 :          0 : }
     733                 :            : 
     734                 :            : static int
     735                 :          3 : ecc_extract_privkey(const uint8_t *key, size_t keylen, uint8_t *rawkey,
     736                 :            :     size_t *rawlen, ec_params *rawparams)
     737                 :            : {
     738                 :            :         const uint8_t *data;
     739                 :            :         struct libder_ctx *ctx;
     740                 :            :         struct libder_object *obj, *root;
     741                 :            :         size_t datasz;
     742                 :            :         int rc;
     743                 :            : 
     744                 :          3 :         ctx = libder_open();
     745         [ +  - ]:          3 :         if (ctx == NULL)
     746                 :          0 :                 return (EPKG_FATAL);
     747                 :            : 
     748                 :          3 :         rc = EPKG_FATAL;
     749                 :          3 :         root = libder_read(ctx, key, &keylen);
     750   [ +  -  -  + ]:          3 :         if (root == NULL || libder_obj_type_simple(root) != BT_SEQUENCE)
     751                 :          0 :                 goto out;
     752                 :            : 
     753                 :            :         /* Sanity check the version, we're expecting version 1. */
     754                 :          3 :         obj = libder_obj_child(root, 0);
     755         [ +  - ]:          3 :         if (obj == NULL)
     756                 :          0 :                 goto out;
     757         [ +  + ]:          3 :         if (libder_obj_type_simple(obj) != BT_INTEGER) {
     758                 :          2 :                 rc = ecc_read_pkgkey(root, rawparams, 0, rawkey, rawlen);
     759                 :          2 :                 goto out;
     760                 :            :         }
     761                 :            : 
     762                 :          1 :         data = libder_obj_data(obj, &datasz);
     763   [ +  -  -  + ]:          1 :         if (datasz != 1 || *data != 1)
     764                 :          0 :                 goto out;
     765                 :            : 
     766                 :            :         /* Grab the key data itself. */
     767                 :          1 :         obj = libder_obj_child(root, 1);
     768   [ +  -  -  + ]:          1 :         if (obj == NULL || libder_obj_type_simple(obj) != BT_OCTETSTRING)
     769                 :          0 :                 goto out;
     770                 :            : 
     771                 :          1 :         data = libder_obj_data(obj, &datasz);
     772   [ +  -  -  + ]:          1 :         if (datasz == 0 || datasz > *rawlen)
     773                 :          0 :                 goto out;
     774                 :            : 
     775                 :          1 :         memcpy(rawkey, data, datasz);
     776                 :          1 :         *rawlen = datasz;
     777                 :            : 
     778                 :            :         /* Next, extract the OID describing the key type. */
     779                 :          1 :         obj = libder_obj_child(root, 2);
     780   [ +  -  -  + ]:          1 :         if (obj == NULL || libder_obj_type_simple(obj) !=
     781                 :            :             ((BC_CONTEXT << 6) | BER_TYPE_CONSTRUCTED_MASK))
     782                 :          0 :                 goto out;
     783                 :            : 
     784                 :          1 :         obj = libder_obj_child(obj, 0);
     785   [ +  -  -  + ]:          1 :         if (obj == NULL || libder_obj_type_simple(obj) != BT_OID)
     786                 :          0 :                 goto out;
     787                 :            : 
     788                 :          1 :         data = libder_obj_data(obj, &datasz);
     789         [ -  + ]:          1 :         if (ecc_extract_key_params(data, datasz, rawparams) != EPKG_OK)
     790                 :          0 :                 goto out;
     791                 :            : 
     792                 :          1 :         rc = EPKG_OK;
     793                 :            : out:
     794                 :          3 :         libder_obj_free(root);
     795                 :          3 :         libder_close(ctx);
     796                 :          3 :         return (rc);
     797                 :          3 : }
     798                 :            : 
     799                 :            : static int
     800                 :          5 : _generate_private_key(struct ecc_sign_ctx *keyinfo)
     801                 :            : {
     802                 :            :         int ret;
     803                 :            : 
     804                 :         10 :         ret = ec_key_pair_gen(&keyinfo->keypair, &keyinfo->params,
     805                 :          5 :             keyinfo->sig_alg);
     806                 :            : 
     807         [ -  + ]:          5 :         if (ret != 0) {
     808                 :          0 :                 pkg_emit_error("failed to generate ecc keypair");
     809                 :          0 :                 return (EPKG_FATAL);
     810                 :            :         }
     811                 :            : 
     812                 :          5 :         keyinfo->loaded = true;
     813                 :          5 :         return (EPKG_OK);
     814                 :          5 : }
     815                 :            : 
     816                 :            : static inline void
     817                 :         11 : _specific_explicit_bzero(void *buf, size_t bufsz)
     818                 :            : {
     819                 :            : 
     820                 :            : #ifdef __APPLE__
     821                 :            :         memset_s(buf, bufsz, 0, bufsz);
     822                 :            : #else
     823                 :         11 :         explicit_bzero(buf, bufsz);
     824                 :            : #endif
     825                 :         11 : }
     826                 :            : 
     827                 :            : 
     828                 :            : static int
     829                 :          3 : _load_private_key(struct ecc_sign_ctx *keyinfo)
     830                 :            : {
     831                 :            :         struct stat st;
     832                 :            :         uint8_t keybuf[EC_PRIV_KEY_MAX_SIZE];
     833                 :            :         uint8_t *filedata;
     834                 :            :         ssize_t readsz;
     835                 :            :         size_t keysz;
     836                 :            :         int fd, rc, ret;
     837                 :            :         size_t offset, resid;
     838                 :            : 
     839                 :          3 :         filedata = NULL;
     840                 :          3 :         fd = -1;
     841                 :          3 :         rc = EPKG_FATAL;
     842                 :            : 
     843                 :          3 :         keyinfo->loaded = false;
     844         [ +  - ]:          3 :         if ((fd = open(keyinfo->sctx.path, O_RDONLY)) == -1)
     845                 :          0 :                 return (EPKG_FATAL);
     846                 :            : 
     847         [ +  - ]:          3 :         if (fstat(fd, &st) == -1)
     848                 :          0 :                 goto out;
     849                 :            : 
     850                 :          3 :         filedata = xmalloc(st.st_size);
     851                 :          3 :         resid = st.st_size;
     852                 :          3 :         offset = 0;
     853         [ +  + ]:          6 :         while (resid != 0) {
     854                 :          3 :                 readsz = read(fd, &filedata[offset], resid);
     855         [ -  + ]:          3 :                 if (readsz <= 0)
     856                 :          0 :                         break;
     857                 :          3 :                 resid -= readsz;
     858                 :          3 :                 offset += readsz;
     859                 :            :         }
     860                 :            : 
     861         [ +  - ]:          3 :         if (readsz < 0) {
     862                 :          0 :                 pkg_emit_errno("read", keyinfo->sctx.path);
     863                 :          0 :                 goto out;
     864         [ -  + ]:          3 :         } else if (resid != 0) {
     865                 :          0 :                 pkg_emit_error("%s: failed to read key",
     866                 :          0 :                     keyinfo->sctx.path);
     867                 :          0 :                 goto out;
     868                 :            :         }
     869                 :            : 
     870                 :            :         /*
     871                 :            :          * Try DER-decoding it.  Unlike with loading a pubkey, anything
     872                 :            :          * requiring the privkey requires a new context for each operation, so
     873                 :            :          * we can just clobber keyinfo->params at will.
     874                 :            :          */
     875                 :          3 :         keysz = sizeof(keybuf);
     876   [ -  +  -  +  :          9 :         if (ecc_extract_privkey(filedata, offset, keybuf, &keysz,
                   -  + ]
     877                 :          6 :             &keyinfo->params) != EPKG_OK) {
     878                 :          0 :                 pkg_emit_error("failed to decode private key");
     879                 :          0 :                 goto out;
     880                 :            :         }
     881                 :            : 
     882                 :          6 :         ret = ec_priv_key_import_from_buf(&keyinfo->keypair.priv_key,
     883                 :          3 :             &keyinfo->params, keybuf, keysz, keyinfo->sig_alg);
     884         [ -  + ]:          6 :         if (ret == 0) {
     885                 :          6 :                 ret = init_pubkey_from_privkey(&keyinfo->keypair.pub_key,
     886                 :          3 :                         &keyinfo->keypair.priv_key);
     887         [ -  + ]:          3 :                 if (ret == 0) {
     888                 :          3 :                         keyinfo->loaded = true;
     889                 :          3 :                         rc = EPKG_OK;
     890                 :          3 :                 } else {
     891                 :          0 :                         pkg_emit_error("%s: failed to derive public key",
     892                 :          0 :                             keyinfo->sctx.path);
     893                 :          0 :                         rc = EPKG_FATAL;
     894                 :            :                 }
     895                 :          3 :         } else {
     896                 :          0 :                 pkg_emit_error("%s: failed to import private key",
     897                 :          0 :                     keyinfo->sctx.path);
     898                 :          0 :                 rc = EPKG_FATAL;
     899                 :            :         }
     900                 :            : 
     901                 :            : out:
     902                 :          3 :         _specific_explicit_bzero(keybuf, sizeof(keybuf));
     903                 :          3 :         free(filedata);
     904         [ +  - ]:          3 :         if (fd != -1)
     905                 :          3 :                 close(fd);
     906                 :          3 :         return (rc);
     907                 :          3 : }
     908                 :            : 
     909                 :            : struct ecc_verify_cbdata {
     910                 :            :         const struct pkgsign_ctx *sctx;
     911                 :            :         unsigned char *key;
     912                 :            :         size_t keylen;
     913                 :            :         unsigned char *sig;
     914                 :            :         size_t siglen;
     915                 :            : };
     916                 :            : 
     917                 :            : static int
     918                 :          0 : ecc_verify_internal(struct ecc_verify_cbdata *cbdata, const uint8_t *hash,
     919                 :            :     size_t hashsz)
     920                 :            : {
     921                 :            :         ec_pub_key pubkey;
     922                 :            :         ec_params derparams;
     923                 :          0 :         struct ecc_sign_ctx *keyinfo = ECC_CTX(cbdata->sctx);
     924                 :            :         uint8_t keybuf[EC_PUB_KEY_MAX_SIZE];
     925                 :            :         uint8_t rawsig[EC_MAX_SIGLEN];
     926                 :            :         size_t keysz;
     927                 :            :         int ret;
     928                 :            :         uint8_t ecsiglen;
     929                 :            : 
     930         [ #  # ]:          0 :         keysz = MIN(sizeof(keybuf), cbdata->keylen / 2);
     931                 :            : 
     932                 :          0 :         keysz = sizeof(keybuf);
     933   [ #  #  #  # ]:          0 :         if (ecc_extract_pubkey(cbdata->key, cbdata->keylen, keybuf,
     934                 :          0 :             &keysz, &derparams) != EPKG_OK) {
     935                 :          0 :                 pkg_emit_error("failed to parse key");
     936                 :          0 :                 return (EPKG_FATAL);
     937                 :            :         }
     938                 :            : 
     939                 :          0 :         ret = ec_get_sig_len(&derparams, keyinfo->sig_alg, keyinfo->sig_hash,
     940                 :            :             &ecsiglen);
     941         [ #  # ]:          0 :         if (ret != 0)
     942                 :          0 :                 return (EPKG_FATAL);
     943                 :            : 
     944                 :            :         /*
     945                 :            :          * Signatures are DER-encoded, whether by OpenSSL or pkg.
     946                 :            :          */
     947   [ #  #  #  #  :          0 :         if (ecc_extract_signature(cbdata->sig, cbdata->siglen,
                   #  # ]
     948                 :          0 :             rawsig, ecsiglen) != EPKG_OK) {
     949                 :          0 :                 pkg_emit_error("failed to decode signature");
     950                 :          0 :                 return (EPKG_FATAL);
     951                 :            :         }
     952                 :            : 
     953                 :          0 :         ret = ec_pub_key_import_from_aff_buf(&pubkey, &derparams,
     954                 :          0 :             keybuf, keysz, keyinfo->sig_alg);
     955         [ #  # ]:          0 :         if (ret != 0) {
     956                 :          0 :                 pkg_emit_error("failed to import key");
     957                 :          0 :                 return (EPKG_FATAL);
     958                 :            :         }
     959                 :            : 
     960                 :          0 :         ret = ec_verify(rawsig, ecsiglen, &pubkey, hash, hashsz, keyinfo->sig_alg,
     961                 :          0 :             keyinfo->sig_hash, NULL, 0);
     962         [ #  # ]:          0 :         if (ret != 0) {
     963                 :          0 :                 pkg_emit_error("failed to verify signature");
     964                 :          0 :                 return (EPKG_FATAL);
     965                 :            :         }
     966                 :            : 
     967                 :          0 :         return (EPKG_OK);
     968                 :          0 : }
     969                 :            : 
     970                 :            : 
     971                 :            : static int
     972                 :          0 : ecc_verify_cert_cb(int fd, void *ud)
     973                 :            : {
     974                 :          0 :         struct ecc_verify_cbdata *cbdata = ud;
     975                 :            :         char *sha256;
     976                 :            :         int ret;
     977                 :            : 
     978                 :          0 :         sha256 = pkg_checksum_fd(fd, PKG_HASH_TYPE_SHA256_HEX);
     979         [ #  # ]:          0 :         if (sha256 == NULL)
     980                 :          0 :                 return (EPKG_FATAL);
     981                 :            : 
     982                 :          0 :         ret = ecc_verify_internal(cbdata, sha256, strlen(sha256));
     983         [ #  # ]:          0 :         if (ret != 0) {
     984                 :          0 :                 pkg_emit_error("ecc signature verification failure");
     985                 :          0 :                 return (EPKG_FATAL);
     986                 :            :         }
     987                 :            : 
     988                 :          0 :         return (EPKG_OK);
     989                 :          0 : }
     990                 :            : 
     991                 :            : static int
     992                 :          1 : ecc_verify_cert(const struct pkgsign_ctx *sctx, unsigned char *key,
     993                 :            :     size_t keylen, unsigned char *sig, size_t siglen, int fd)
     994                 :            : {
     995                 :            :         int ret;
     996                 :            :         struct ecc_verify_cbdata cbdata;
     997                 :            : 
     998                 :          1 :         (void)lseek(fd, 0, SEEK_SET);
     999                 :            : 
    1000                 :          1 :         cbdata.sctx = sctx;
    1001                 :          1 :         cbdata.key = key;
    1002                 :          1 :         cbdata.keylen = keylen;
    1003                 :          1 :         cbdata.sig = sig;
    1004                 :          1 :         cbdata.siglen = siglen;
    1005                 :            : 
    1006                 :          1 :         ret = pkg_emit_sandbox_call(ecc_verify_cert_cb, fd, &cbdata);
    1007                 :            : 
    1008                 :          1 :         return (ret);
    1009                 :            : }
    1010                 :            : 
    1011                 :            : static int
    1012                 :          0 : ecc_verify_cb(int fd, void *ud)
    1013                 :            : {
    1014                 :          0 :         struct ecc_verify_cbdata *cbdata = ud;
    1015                 :            :         uint8_t *blake2;
    1016                 :            :         int ret;
    1017                 :            : 
    1018                 :          0 :         blake2 = pkg_checksum_fd(fd, PKG_HASH_TYPE_BLAKE2_RAW);
    1019         [ #  # ]:          0 :         if (blake2 == NULL)
    1020                 :          0 :                 return (EPKG_FATAL);
    1021                 :            : 
    1022                 :          0 :         ret = ecc_verify_internal(cbdata, blake2,
    1023                 :          0 :             pkg_checksum_type_size(PKG_HASH_TYPE_BLAKE2_RAW));
    1024                 :            : 
    1025                 :          0 :         free(blake2);
    1026         [ #  # ]:          0 :         if (ret != 0) {
    1027                 :          0 :                 pkg_emit_error("ecc signature verification failure");
    1028                 :          0 :                 return (EPKG_FATAL);
    1029                 :            :         }
    1030                 :            : 
    1031                 :          0 :         return (EPKG_OK);
    1032                 :          0 : }
    1033                 :            : 
    1034                 :            : static int
    1035                 :          2 : ecc_verify(const struct pkgsign_ctx *sctx, const char *keypath,
    1036                 :            :     unsigned char *sig, size_t sig_len, int fd)
    1037                 :            : {
    1038                 :            :         int ret;
    1039                 :            :         struct ecc_verify_cbdata cbdata;
    1040                 :            :         char *key_buf;
    1041                 :            :         off_t key_len;
    1042                 :            : 
    1043         [ -  + ]:          2 :         if (file_to_buffer(keypath, (char**)&key_buf, &key_len) != EPKG_OK) {
    1044                 :          0 :                 pkg_emit_errno("ecc_verify", "cannot read key");
    1045                 :          0 :                 return (EPKG_FATAL);
    1046                 :            :         }
    1047                 :            : 
    1048                 :          2 :         (void)lseek(fd, 0, SEEK_SET);
    1049                 :            : 
    1050                 :          2 :         cbdata.sctx = sctx;
    1051                 :          2 :         cbdata.key = key_buf;
    1052                 :          2 :         cbdata.keylen = key_len;
    1053                 :          2 :         cbdata.sig = sig;
    1054                 :          2 :         cbdata.siglen = sig_len;
    1055                 :            : 
    1056                 :          2 :         ret = pkg_emit_sandbox_call(ecc_verify_cb, fd, &cbdata);
    1057                 :            : 
    1058                 :          2 :         free(key_buf);
    1059                 :            : 
    1060                 :          2 :         return (ret);
    1061                 :          2 : }
    1062                 :            : 
    1063                 :            : static int
    1064                 :          5 : ecc_sign_data(struct pkgsign_ctx *sctx, const unsigned char *msg, size_t msgsz,
    1065                 :            :     unsigned char **sigret, size_t *siglen)
    1066                 :            : {
    1067                 :            :         uint8_t rawsig[EC_MAX_SIGLEN];
    1068                 :          5 :         struct ecc_sign_ctx *keyinfo = ECC_CTX(sctx);
    1069                 :            :         int ret;
    1070                 :            :         uint8_t rawlen;
    1071                 :            : 
    1072   [ +  +  +  - ]:          5 :         if (!keyinfo->loaded && _load_private_key(keyinfo) != EPKG_OK) {
    1073                 :          0 :                 pkg_emit_error("%s: failed to load key", keyinfo->sctx.path);
    1074                 :          0 :                 return (EPKG_FATAL);
    1075                 :            :         }
    1076                 :            : 
    1077                 :          5 :         ret = ec_get_sig_len(&keyinfo->params, keyinfo->sig_alg, keyinfo->sig_hash,
    1078                 :            :                 &rawlen);
    1079         [ -  + ]:          5 :         if (ret != 0)
    1080                 :          0 :                 return (EPKG_FATAL);
    1081                 :            : 
    1082         [ +  - ]:          5 :         assert(rawlen <= sizeof(rawsig));
    1083                 :            : 
    1084         [ +  - ]:          5 :         assert(priv_key_check_initialized_and_type(&keyinfo->keypair.priv_key,
    1085                 :            :             keyinfo->sig_alg) == 0);
    1086         [ +  - ]:          5 :         assert(pub_key_check_initialized_and_type(&keyinfo->keypair.pub_key,
    1087                 :            :             keyinfo->sig_alg) == 0);
    1088                 :            : 
    1089                 :         10 :         ret = ec_sign(rawsig, rawlen, &keyinfo->keypair, msg, msgsz,
    1090                 :          5 :             keyinfo->sig_alg, keyinfo->sig_hash, NULL, 0);
    1091                 :            : 
    1092         [ -  + ]:          5 :         if (ret != 0) {
    1093                 :          0 :                 pkg_emit_error("%s: ecc signing failure", keyinfo->sctx.path);
    1094                 :          0 :                 return (EPKG_FATAL);
    1095                 :            :         }
    1096                 :            : 
    1097         [ -  + ]:          5 :         if (ecc_write_signature(rawsig, rawlen, sigret, siglen) != EPKG_OK) {
    1098                 :          0 :                 pkg_emit_error("failed to encode signature");
    1099                 :          0 :                 return (EPKG_FATAL);
    1100                 :            :         }
    1101                 :            : 
    1102                 :          5 :         return (EPKG_OK);
    1103                 :          5 : }
    1104                 :            : 
    1105                 :            : static int
    1106                 :          4 : ecc_sign(struct pkgsign_ctx *sctx, const char *path, unsigned char **sigret,
    1107                 :            :     size_t *siglen)
    1108                 :            : {
    1109                 :            :         uint8_t *blake2;
    1110                 :          4 :         struct ecc_sign_ctx *keyinfo = ECC_CTX(sctx);
    1111                 :            :         int ret;
    1112                 :            : 
    1113         [ +  - ]:          4 :         if (access(keyinfo->sctx.path, R_OK) == -1) {
    1114                 :          0 :                 pkg_emit_errno("access", keyinfo->sctx.path);
    1115                 :          0 :                 return (EPKG_FATAL);
    1116                 :            :         }
    1117                 :            : 
    1118                 :          4 :         blake2 = pkg_checksum_file(path, PKG_HASH_TYPE_BLAKE2_RAW);
    1119         [ +  - ]:          4 :         if (blake2 == NULL)
    1120                 :          0 :                 return (EPKG_FATAL);
    1121                 :            : 
    1122                 :          8 :         ret = ecc_sign_data(sctx, blake2,
    1123                 :          4 :             pkg_checksum_type_size(PKG_HASH_TYPE_BLAKE2_RAW), sigret, siglen);
    1124                 :          4 :         free(blake2);
    1125                 :            : 
    1126                 :          4 :         return (ret);
    1127                 :          4 : }
    1128                 :            : 
    1129                 :            : static int
    1130                 :          5 : ecc_generate(struct pkgsign_ctx *sctx, const struct iovec *iov __unused,
    1131                 :            :     int niov __unused)
    1132                 :            : {
    1133                 :            :         uint8_t keybuf[EC_PRIV_KEY_MAX_SIZE], *outbuf;
    1134                 :          5 :         struct ecc_sign_ctx *keyinfo = ECC_CTX(sctx);
    1135                 :          5 :         const char *path = sctx->path;
    1136                 :            :         FILE *fp;
    1137                 :            :         size_t keysz, outsz;
    1138                 :            : 
    1139         [ -  + ]:          5 :         if (niov != 0)
    1140                 :          0 :                 return (EPKG_FATAL);
    1141                 :            : 
    1142         [ -  + ]:          5 :         if (_generate_private_key(keyinfo) != 0)
    1143                 :          0 :                 return (EPKG_FATAL);
    1144                 :            : 
    1145         [ +  - ]:          5 :         assert(priv_key_check_initialized_and_type(&keyinfo->keypair.priv_key,
    1146                 :            :             keyinfo->sig_alg) == 0);
    1147         [ +  - ]:          5 :         assert(pub_key_check_initialized_and_type(&keyinfo->keypair.pub_key,
    1148                 :            :             keyinfo->sig_alg) == 0);
    1149                 :            : 
    1150   [ -  +  +  -  :          5 :         keysz = EC_PRIV_KEY_EXPORT_SIZE(&keyinfo->keypair.priv_key);
                   #  # ]
    1151   [ -  +  -  +  :         15 :         if (ec_priv_key_export_to_buf(&keyinfo->keypair.priv_key,
                   -  + ]
    1152                 :         10 :             keybuf, keysz) != 0) {
    1153                 :          0 :                 pkg_emit_error("failed to export ecc key");
    1154                 :          0 :                 return (EPKG_FATAL);
    1155                 :            :         }
    1156                 :            : 
    1157                 :          5 :         outbuf = NULL;
    1158                 :          5 :         outsz = 0;
    1159   [ -  +  -  + ]:         10 :         if (ecc_write_pkgkey(&keyinfo->params, 0, keybuf, keysz, &outbuf,
    1160                 :          5 :             &outsz) != EPKG_OK) {
    1161                 :          0 :                 pkg_emit_error("%s: failed to write DER-encoded key",
    1162                 :          0 :                     sctx->path);
    1163                 :          0 :                 return (EPKG_FATAL);
    1164                 :            :         }
    1165                 :            : 
    1166                 :          5 :         fp = fopen(path, "wb");
    1167         [ +  - ]:          5 :         if (fp == NULL) {
    1168                 :          0 :                 pkg_emit_errno("fopen write", path);
    1169                 :          0 :                 free(outbuf);
    1170                 :          0 :                 return (EPKG_FATAL);
    1171                 :            :         }
    1172                 :            : 
    1173         [ -  + ]:          5 :         if (fchmod(fileno(fp), 0400) != 0) {
    1174                 :          0 :                 pkg_emit_errno("fchmod", path);
    1175                 :          0 :                 free(outbuf);
    1176                 :          0 :                 fclose(fp);
    1177                 :          0 :                 return (EPKG_FATAL);
    1178                 :            :         }
    1179                 :            : 
    1180                 :          5 :         fwrite(outbuf, outsz, 1, fp);
    1181                 :          5 :         free(outbuf);
    1182                 :          5 :         outbuf = NULL;
    1183   [ -  +  +  -  :          5 :         if (ferror(fp) != 0 || fflush(fp) != 0) {
                   -  + ]
    1184                 :          0 :                 pkg_emit_errno("fwrite", path);
    1185                 :          0 :                 fclose(fp);
    1186                 :          0 :                 return (EPKG_FATAL);
    1187                 :            :         }
    1188                 :            : 
    1189                 :          5 :         fclose(fp);
    1190                 :          5 :         return (EPKG_OK);
    1191                 :          5 : }
    1192                 :            : 
    1193                 :            : static int
    1194                 :          5 : ecc_pubkey(struct pkgsign_ctx *sctx, char **pubkey, size_t *pubkeylen)
    1195                 :            : {
    1196                 :          5 :         struct ecc_sign_ctx *keyinfo = ECC_CTX(sctx);
    1197                 :            :         uint8_t keybuf[EC_PUB_KEY_MAX_SIZE];
    1198                 :            :         size_t keylen;
    1199                 :            :         int ret;
    1200                 :            : 
    1201   [ -  +  #  # ]:          5 :         if (!keyinfo->loaded && _load_private_key(keyinfo) != EPKG_OK) {
    1202                 :          0 :                 pkg_emit_error("%s: failed to load key", sctx->path);
    1203                 :          0 :                 return (EPKG_FATAL);
    1204                 :            :         }
    1205                 :            : 
    1206         [ +  - ]:          5 :         assert(keyinfo->loaded);
    1207         [ +  - ]:          5 :         assert(pub_key_check_initialized_and_type(&keyinfo->keypair.pub_key,
    1208                 :            :             keyinfo->sig_alg) == 0);
    1209                 :            : 
    1210                 :          5 :         keylen = 2 * BYTECEIL(keyinfo->params.ec_fp.p_bitlen);
    1211                 :          5 :         ret = ec_pub_key_export_to_aff_buf(&keyinfo->keypair.pub_key, keybuf, keylen);
    1212         [ -  + ]:          5 :         if (ret != 0) {
    1213                 :          0 :                 pkg_emit_error("%s: failed to export key", sctx->path);
    1214                 :          0 :                 return (EPKG_FATAL);
    1215                 :            :         }
    1216                 :            : 
    1217                 :            :         /*
    1218                 :            :          * We'll write a custom format for anything but ECDSA that includes our
    1219                 :            :          * params wholesale so that we can just import them directly.
    1220                 :            :          *
    1221                 :            :          * ECDSA keys get exported as PKCS#8 for interoperability with OpenSSL.
    1222                 :            :          */
    1223         [ +  + ]:          5 :         if (keyinfo->sig_alg != ECDSA) {
    1224   [ -  +  -  +  :          9 :                 if (ecc_write_pkgkey(&keyinfo->params, 1, keybuf, keylen,
                   -  + ]
    1225                 :          6 :                     (uint8_t **)pubkey, pubkeylen) != EPKG_OK) {
    1226                 :          0 :                         pkg_emit_error("%s: failed to write DER-encoded key",
    1227                 :            : 
    1228                 :          0 :                             sctx->path);
    1229                 :          0 :                         return (EPKG_FATAL);
    1230                 :            :                 }
    1231   [ -  +  -  +  :          9 :         } else if (ecc_pubkey_write_pkcs8(keybuf, keylen,
                   -  + ]
    1232                 :          4 :             (uint8_t **)pubkey, pubkeylen) != EPKG_OK) {
    1233                 :          0 :                 pkg_emit_error("%s: failed to write DER-encoded key", sctx->path);
    1234                 :          0 :                 return (EPKG_FATAL);
    1235                 :            :         }
    1236                 :            : 
    1237                 :          5 :         return (EPKG_OK);
    1238                 :          5 : }
    1239                 :            : 
    1240                 :            : static int
    1241                 :         11 : ecc_new(const char *name __unused, struct pkgsign_ctx *sctx)
    1242                 :            : {
    1243                 :         11 :         struct ecc_sign_ctx *keyinfo = ECC_CTX(sctx);
    1244                 :            :         int ret;
    1245                 :            : 
    1246                 :         11 :         ret = EPKG_FATAL;
    1247   [ +  +  +  + ]:         11 :         if (STREQ(name, "ecc") || STREQ(name, "eddsa")) {
    1248                 :          5 :                         keyinfo->sig_alg = EDDSA25519;
    1249                 :          5 :                         keyinfo->sig_hash = SHA512;
    1250                 :          5 :                         ret = import_params(&keyinfo->params, &wei25519_str_params);
    1251         [ -  + ]:         11 :         } else if (STREQ(name, "ecdsa")) {
    1252                 :          6 :                         keyinfo->sig_alg = ECDSA;
    1253                 :          6 :                         keyinfo->sig_hash = SHA256;
    1254                 :          6 :                         ret = import_params(&keyinfo->params, &secp256k1_str_params);
    1255                 :          6 :         }
    1256                 :            : 
    1257         [ -  + ]:         11 :         if (ret != 0)
    1258                 :          0 :                 return (EPKG_FATAL);
    1259                 :            : 
    1260                 :         11 :         return (0);
    1261                 :         11 : }
    1262                 :            : 
    1263                 :            : static void
    1264                 :          8 : ecc_free(struct pkgsign_ctx *sctx)
    1265                 :            : {
    1266                 :          8 :         struct ecc_sign_ctx *keyinfo = ECC_CTX(sctx);
    1267                 :            : 
    1268                 :          8 :         _specific_explicit_bzero(&keyinfo->keypair, sizeof(keyinfo->keypair));
    1269                 :          8 : }
    1270                 :            : 
    1271                 :            : const struct pkgsign_ops pkgsign_ecc = {
    1272                 :            :         .pkgsign_ctx_size = sizeof(struct ecc_sign_ctx),
    1273                 :            :         .pkgsign_new = ecc_new,
    1274                 :            :         .pkgsign_free = ecc_free,
    1275                 :            : 
    1276                 :            :         .pkgsign_sign = ecc_sign,
    1277                 :            :         .pkgsign_verify = ecc_verify,
    1278                 :            :         .pkgsign_verify_cert = ecc_verify_cert,
    1279                 :            : 
    1280                 :            :         .pkgsign_generate = ecc_generate,
    1281                 :            :         .pkgsign_pubkey = ecc_pubkey,
    1282                 :            :         .pkgsign_sign_data = ecc_sign_data,
    1283                 :            : };

Generated by: LCOV version 1.15