/ libpkg / pkg_key.c
pkg_key.c
  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 <assert.h>
 27  #include <errno.h>
 28  #include <stdlib.h>
 29  #include <string.h>
 30  
 31  #include "pkg.h"
 32  #include "xmalloc.h"
 33  #include "private/pkg.h"
 34  #include "private/pkgsign.h"
 35  
 36  int
 37  pkg_key_new(struct pkg_key **key, const char *keytype, const char *keypath,
 38      pkg_password_cb *cb)
 39  {
 40  	struct pkg_key *nkey;
 41  	struct pkgsign_ctx *nctx = NULL;
 42  	int ret;
 43  
 44  	assert(*key == NULL);
 45  	assert(keytype != NULL);	/* XXX for now. */
 46  	if (*keypath == '\0')
 47  		return (EPKG_FATAL);
 48  
 49  	ret = pkgsign_new_sign(keytype, &nctx);
 50  	if (ret != 0)
 51  		return (EPKG_FATAL);
 52  
 53  	pkgsign_set(nctx, cb, keypath);
 54  
 55  	nkey = xcalloc(1, sizeof(*nkey));
 56  	nkey->ctx = nctx;
 57  
 58  	*key = nkey;
 59  	return (EPKG_OK);
 60  }
 61  
 62  void
 63  pkg_key_free(struct pkg_key *key)
 64  {
 65  
 66  	pkgsign_free(key->ctx);
 67  	free(key);
 68  }
 69  
 70  /*
 71   * Key generation callbacks may take any number of options, so we handle those
 72   * with an iovec.  The pkg_key layer does not discriminate, beyond enforcing
 73   * that options come in pairs.  The intention is that the first option in every
 74   * pair names the option.
 75   */
 76  int
 77  pkg_key_create(struct pkg_key *key, const struct iovec *iov, int niov)
 78  {
 79  
 80  	/* Malformed arguments; must come in pairs. */
 81  	if ((niov % 2) != 0)
 82  		return (EPKG_FATAL);
 83  
 84  	return (pkgsign_generate(key->ctx, iov, niov));
 85  }
 86  
 87  int
 88  pkg_key_sign_data(struct pkg_key *key, const unsigned char *msg, size_t msgsz,
 89      unsigned char **sig, size_t *siglen)
 90  {
 91  
 92  	return (pkgsign_sign_data(key->ctx, msg, msgsz, sig, siglen));
 93  }
 94  
 95  int
 96  pkg_key_info(struct pkg_key *key, struct iovec **iov, int *niov)
 97  {
 98  	int rc;
 99  	struct iovec *kiov;
100  	int nkiov;
101  
102  	kiov = NULL;
103  	rc = pkgsign_keyinfo(key->ctx, &kiov, &nkiov);
104  	if (rc != EPKG_OK)
105  		return (rc);
106  	if ((nkiov % 2) != 0) {
107  		free(kiov);
108  		return (EPKG_FATAL);
109  	}
110  
111  	*iov = kiov;
112  	*niov = nkiov;
113  
114  	return (EPKG_OK);
115  }
116  
117  int
118  pkg_key_pubkey(struct pkg_key *key, char **pubkey, size_t *len)
119  {
120  
121  	return (pkgsign_pubkey(key->ctx, pubkey, len));
122  }