LCOV - code coverage report
Current view: top level - libpkg - pkgsign.c (source / functions) Hit Total Coverage
Test: plop Lines: 69 84 82.1 %
Date: 2024-12-28 18:40:32 Functions: 12 13 92.3 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 19 38 50.0 %

           Branch data     Line data    Source code
       1                 :            : /*-
       2                 :            :  * Copyright (c) 2021 Kyle Evans <kevans@FreeBSD.org>
       3                 :            :  *
       4                 :            :  * Redistribution and use in source and binary forms, with or without
       5                 :            :  * modification, are permitted provided that the following conditions
       6                 :            :  * are met:
       7                 :            :  * 1. Redistributions of source code must retain the above copyright
       8                 :            :  *    notice, this list of conditions and the following disclaimer
       9                 :            :  *    in this position and unchanged.
      10                 :            :  * 2. Redistributions in binary form must reproduce the above copyright
      11                 :            :  *    notice, this list of conditions and the following disclaimer in the
      12                 :            :  *    documentation and/or other materials provided with the distribution.
      13                 :            :  *
      14                 :            :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
      15                 :            :  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
      16                 :            :  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
      17                 :            :  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
      18                 :            :  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      19                 :            :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      20                 :            :  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      21                 :            :  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      22                 :            :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
      23                 :            :  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      24                 :            :  */
      25                 :            : 
      26                 :            : #include <sys/cdefs.h>
      27                 :            : 
      28                 :            : #include <assert.h>
      29                 :            : #include <errno.h>
      30                 :            : #include <stdlib.h>
      31                 :            : #include <string.h>
      32                 :            : 
      33                 :            : #include "private/pkg.h"
      34                 :            : #include "private/pkgsign.h"
      35                 :            : #include "pkghash.h"
      36                 :            : #include "xmalloc.h"
      37                 :            : 
      38                 :            : /* Other parts of libpkg should use pkgsign instead of rsa directly. */
      39                 :            : extern const struct pkgsign_ops pkgsign_ossl;
      40                 :            : extern const struct pkgsign_ops pkgsign_ecc;
      41                 :            : 
      42                 :            : static pkghash *pkgsign_verifiers;
      43                 :            : 
      44                 :            : /*
      45                 :            :  * The eventual goal is to allow plugins to register their own pkgsign
      46                 :            :  * implementations as needed.  The initial sketch was to add a constructor
      47                 :            :  * to register the builtin pkgsign implementations since there should only be
      48                 :            :  * a couple of them, but this is saved for later work.
      49                 :            :  */
      50                 :            : static struct pkgsign_impl {
      51                 :            :         const char                      *pi_name;
      52                 :            :         const struct pkgsign_ops        *pi_ops;
      53                 :            :         int                              pi_refs; /* XXX */
      54                 :            : } pkgsign_builtins[] = {
      55                 :            :         {
      56                 :            :                 .pi_name = "rsa",
      57                 :            :                 .pi_ops = &pkgsign_ossl,
      58                 :            :         },
      59                 :            :         {
      60                 :            :                 .pi_name = "ecc",
      61                 :            :                 .pi_ops = &pkgsign_ecc,
      62                 :            :         },
      63                 :            :         {
      64                 :            :                 .pi_name = "ecdsa",
      65                 :            :                 .pi_ops = &pkgsign_ecc,
      66                 :            :         },
      67                 :            :         {
      68                 :            :                 .pi_name = "eddsa",
      69                 :            :                 .pi_ops = &pkgsign_ecc,
      70                 :            :         },
      71                 :            : };
      72                 :            : 
      73                 :            : static int
      74                 :         26 : pkgsign_new(const char *name, struct pkgsign_ctx **ctx)
      75                 :            : {
      76                 :            :         struct pkgsign_impl *impl;
      77                 :            :         const struct pkgsign_ops *ops;
      78                 :            :         struct pkgsign_ctx *nctx;
      79                 :            :         size_t ctx_size;
      80                 :            :         int ret;
      81                 :            : 
      82         [ +  - ]:         26 :         assert(*ctx == NULL);
      83                 :            : 
      84                 :         26 :         ops = NULL;
      85         [ -  + ]:         51 :         for (size_t i = 0; i < NELEM(pkgsign_builtins); i++) {
      86                 :         51 :                 impl = &pkgsign_builtins[i];
      87         [ +  + ]:         51 :                 if (STREQ(name, impl->pi_name)) {
      88                 :         26 :                         ops = impl->pi_ops;
      89                 :         26 :                         break;
      90                 :            :                 }
      91                 :         25 :         }
      92                 :            : 
      93         [ +  - ]:         26 :         if (ops == NULL)
      94                 :          0 :                 return (EPKG_FATAL);
      95                 :            : 
      96                 :         26 :         ctx_size = ops->pkgsign_ctx_size;
      97   [ +  -  +  - ]:         26 :         assert(ctx_size == 0 || ctx_size >= sizeof(struct pkgsign_ctx));
      98         [ +  - ]:         26 :         if (ctx_size == 0)
      99                 :          0 :                 ctx_size = sizeof(struct pkgsign_ctx);
     100                 :            : 
     101                 :         26 :         nctx = xcalloc(1, ctx_size);
     102                 :         26 :         nctx->impl = impl;
     103                 :            : 
     104                 :         26 :         ret = EPKG_OK;
     105         [ -  + ]:         26 :         if (ops->pkgsign_new != NULL)
     106                 :         26 :                 ret = (*ops->pkgsign_new)(name, nctx);
     107                 :            : 
     108         [ -  + ]:         26 :         if (ret != EPKG_OK) {
     109                 :          0 :                 free(nctx);
     110                 :          0 :                 return (ret);
     111                 :            :         }
     112                 :            : 
     113                 :         26 :         impl->pi_refs++;
     114                 :         26 :         *ctx = nctx;
     115                 :         26 :         return (EPKG_OK);
     116                 :         26 : }
     117                 :            : 
     118                 :            : int
     119                 :          7 : pkgsign_new_verify(const char *name, const struct pkgsign_ctx **octx)
     120                 :            : {
     121                 :            :         struct pkgsign_ctx *ctx;
     122                 :            :         pkghash_entry *entry;
     123                 :            :         int ret;
     124                 :            : 
     125                 :          7 :         entry = pkghash_get(pkgsign_verifiers, name);
     126         [ -  + ]:          7 :         if (entry != NULL) {
     127                 :          0 :                 *octx = entry->value;
     128                 :          0 :                 return (EPKG_OK);
     129                 :            :         }
     130                 :            : 
     131                 :          7 :         ctx = NULL;
     132         [ -  + ]:          7 :         if ((ret = pkgsign_new(name, &ctx)) != EPKG_OK)
     133                 :          0 :                 return (ret);
     134                 :            : 
     135   [ -  +  #  # ]:          7 :         pkghash_safe_add(pkgsign_verifiers, name, ctx, NULL);
     136                 :          7 :         *octx = ctx;
     137                 :          7 :         return (EPKG_OK);
     138                 :          7 : }
     139                 :            : 
     140                 :            : int
     141                 :         19 : pkgsign_new_sign(const char *name, struct pkgsign_ctx **ctx)
     142                 :            : {
     143                 :            : 
     144                 :         19 :         return (pkgsign_new(name, ctx));
     145                 :            : }
     146                 :            : 
     147                 :            : void
     148                 :         19 : pkgsign_set(struct pkgsign_ctx *sctx, pkg_password_cb *cb, const char *keyfile)
     149                 :            : {
     150                 :            : 
     151                 :         19 :         sctx->pw_cb = cb;
     152                 :         19 :         sctx->path = keyfile;
     153                 :         19 : }
     154                 :            : 
     155                 :            : void
     156                 :         90 : pkgsign_free(struct pkgsign_ctx *ctx)
     157                 :            : {
     158                 :            :         struct pkgsign_impl *impl;
     159                 :            :         const struct pkgsign_ops *ops;
     160                 :            : 
     161         [ +  + ]:         90 :         if (ctx == NULL)
     162                 :         71 :                 return;
     163                 :         19 :         impl = ctx->impl;
     164                 :         19 :         ops = impl->pi_ops;
     165         [ -  + ]:         19 :         if (ops->pkgsign_free != NULL)
     166                 :         19 :                 (*ops->pkgsign_free)(ctx);
     167                 :            : 
     168                 :         19 :         impl->pi_refs--;
     169                 :         19 :         free(ctx);
     170                 :         90 : }
     171                 :            : 
     172                 :            : int
     173                 :          8 : pkgsign_sign(struct pkgsign_ctx *ctx, const char *path, unsigned char **sigret,
     174                 :            :     size_t *siglen)
     175                 :            : {
     176                 :            : 
     177                 :          8 :         return (*ctx->impl->pi_ops->pkgsign_sign)(ctx, path, sigret, siglen);
     178                 :            : }
     179                 :            : 
     180                 :            : int
     181                 :          4 : pkgsign_verify(const struct pkgsign_ctx *ctx, const char *key,
     182                 :            :     unsigned char *sig, size_t siglen, int fd)
     183                 :            : {
     184                 :            : 
     185                 :          4 :         return (*ctx->impl->pi_ops->pkgsign_verify)(ctx, key, sig, siglen, fd);
     186                 :            : }
     187                 :            : 
     188                 :            : int
     189                 :          3 : pkgsign_verify_cert(const struct pkgsign_ctx *ctx, unsigned char *key, size_t keylen,
     190                 :            :     unsigned char *sig, size_t siglen, int fd)
     191                 :            : {
     192                 :            : 
     193                 :          6 :         return (*ctx->impl->pi_ops->pkgsign_verify_cert)(ctx, key, keylen, sig,
     194                 :          3 :             siglen, fd);
     195                 :            : }
     196                 :            : 
     197                 :            : const char *
     198                 :         11 : pkgsign_impl_name(const struct pkgsign_ctx *ctx)
     199                 :            : {
     200                 :            : 
     201                 :         11 :         return (ctx->impl->pi_name);
     202                 :            : }
     203                 :            : 
     204                 :            : int
     205                 :         12 : pkgsign_generate(struct pkgsign_ctx *ctx, const struct iovec *iov, int niov)
     206                 :            : {
     207                 :            : 
     208         [ +  - ]:         12 :         if (ctx->impl->pi_ops->pkgsign_generate == NULL)
     209                 :          0 :                 return (EPKG_OPNOTSUPP);
     210                 :         12 :         return (*ctx->impl->pi_ops->pkgsign_generate)(ctx, iov, niov);
     211                 :         12 : }
     212                 :            : 
     213                 :            : int
     214                 :          2 : pkgsign_sign_data(struct pkgsign_ctx *ctx, const unsigned char *msg, size_t msgsz,
     215                 :            :     unsigned char **sig, size_t *siglen)
     216                 :            : {
     217                 :            : 
     218         [ +  - ]:          2 :         if (ctx->impl->pi_ops->pkgsign_sign_data == NULL)
     219                 :          0 :                 return (EPKG_OPNOTSUPP);
     220                 :          2 :         return (*ctx->impl->pi_ops->pkgsign_sign_data)(ctx, msg, msgsz, sig, siglen);
     221                 :          2 : }
     222                 :            : 
     223                 :            : int
     224                 :          0 : pkgsign_keyinfo(struct pkgsign_ctx *ctx, struct iovec **iov, int *niov)
     225                 :            : {
     226                 :            : 
     227         [ #  # ]:          0 :         if (ctx->impl->pi_ops->pkgsign_keyinfo == NULL)
     228                 :          0 :                 return (EPKG_OPNOTSUPP);
     229                 :          0 :         return (*ctx->impl->pi_ops->pkgsign_keyinfo)(ctx, iov, niov);
     230                 :          0 : }
     231                 :            : 
     232                 :            : int
     233                 :         13 : pkgsign_pubkey(struct pkgsign_ctx *ctx, char **pubkey, size_t *pubkeylen)
     234                 :            : {
     235                 :            : 
     236         [ +  - ]:         13 :         if (ctx->impl->pi_ops->pkgsign_pubkey == NULL)
     237                 :          0 :                 return (EPKG_OPNOTSUPP);
     238                 :         13 :         return (*ctx->impl->pi_ops->pkgsign_pubkey)(ctx, pubkey, pubkeylen);
     239                 :         13 : }

Generated by: LCOV version 1.15