/ libpkg / pkgsign_ecc.c
pkgsign_ecc.c
   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  ecc_pkgkey_params(const uint8_t *curve, size_t curvesz)
 100  {
 101  	const struct pkgkey_map_entry *entry;
 102  
 103  	for (size_t i = 0; i < NELEM(pkgkey_map); i++) {
 104  		entry = &pkgkey_map[i];
 105  		if (curvesz != entry->namesz)
 106  			continue;
 107  		if (memcmp(curve, entry->name, curvesz) == 0)
 108  			return (entry->params);
 109  	}
 110  
 111  	return (NULL);
 112  }
 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  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  	if (keysz > sizeof(keybuf) - 2)
 139  		return (EPKG_FATAL);
 140  
 141  	ctx = libder_open();
 142  	if (ctx == NULL)
 143  		return (EPKG_FATAL);
 144  
 145  	rc = EPKG_FATAL;
 146  	root = libder_obj_alloc_simple(ctx, BT_SEQUENCE, NULL, 0);
 147  	if (root == NULL)
 148  		goto out;
 149  
 150  	params = libder_obj_alloc_simple(ctx, BT_SEQUENCE, NULL, 0);
 151  	if (params == NULL)
 152  		goto out;
 153  
 154  	ok = libder_obj_append(root, params);
 155  	assert(ok);
 156  
 157  	/* id-ecPublicKey */
 158  	oid = libder_obj_alloc_simple(ctx, BT_OID, oid_ecpubkey,
 159  	    sizeof(oid_ecpubkey));
 160  	if (oid == NULL)
 161  		goto out;
 162  	ok = libder_obj_append(params, oid);
 163  	assert(ok);
 164  
 165  	/*
 166  	 * secp256k1, we should eventually allow other curves and actually
 167  	 * construct the OID.
 168  	 */
 169  	oid = libder_obj_alloc_simple(ctx, BT_OID, oid_secp256k1,
 170  	    sizeof(oid_secp256k1));
 171  	if (oid == NULL)
 172  		goto out;
 173  	ok = libder_obj_append(params, oid);
 174  	assert(ok);
 175  
 176  	memset(keybuf, 0, sizeof(keybuf));
 177  	keybuf[0] = 0;	/* No unused bits */
 178  	keybuf[1] = PUBKEY_UNCOMPRESSED;
 179  	memcpy(&keybuf[2], keydata, keysz);
 180  
 181  	keybits = libder_obj_alloc_simple(ctx, BT_BITSTRING, &keybuf[0],
 182  	    keysz + 2);
 183  	if (keybits == NULL)
 184  		goto out;
 185  	ok = libder_obj_append(root, keybits);
 186  	assert(ok);
 187  
 188  	/* Finally, write it out. */
 189  	*buflen = 0;
 190  	outbuf = libder_write(ctx, root, NULL, buflen);
 191  	if (outbuf != NULL) {
 192  		*buf = outbuf;
 193  		rc = EPKG_OK;
 194  	}
 195  
 196  out:
 197  	libder_obj_free(root);
 198  	libder_close(ctx);
 199  	return (rc);
 200  }
 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  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  	uint8_t version = 1;
 231  	bool ok;
 232  
 233  	if (keysz > sizeof(keybuf) - 2)
 234  		return (EPKG_FATAL);
 235  
 236  	ctx = libder_open();
 237  	if (ctx == NULL)
 238  		return (EPKG_FATAL);
 239  
 240  	rc = EPKG_FATAL;
 241  	root = libder_obj_alloc_simple(ctx, BT_SEQUENCE, NULL, 0);
 242  	if (root == NULL)
 243  		goto out;
 244  
 245  	/* Application */
 246  	obj = libder_obj_alloc_simple(ctx, BT_UTF8STRING, pkgkey_app,
 247  	    sizeof(pkgkey_app) - 1);
 248  	if (obj == NULL)
 249  		goto out;
 250  	ok = libder_obj_append(root, obj);
 251  	assert(ok);
 252  
 253  	/* Version */
 254  	obj = libder_obj_alloc_simple(ctx, BT_INTEGER, &version, sizeof(version));
 255  	if (obj == NULL)
 256  		goto out;
 257  	ok = libder_obj_append(root, obj);
 258  	assert(ok);
 259  
 260  	/* Signer */
 261  	obj = libder_obj_alloc_simple(ctx, BT_UTF8STRING, pkgkey_signer,
 262  	    sizeof(pkgkey_signer) - 1);
 263  	if (obj == NULL)
 264  		goto out;
 265  	ok = libder_obj_append(root, obj);
 266  	assert(ok);
 267  
 268  	/* KeyType */
 269  	obj = libder_obj_alloc_simple(ctx, BT_UTF8STRING, params->curve_name,
 270  	    strlen(params->curve_name));
 271  	if (obj == NULL)
 272  		goto out;
 273  	ok = libder_obj_append(root, obj);
 274  	assert(ok);
 275  
 276  	/* Public */
 277  	obj = libder_obj_alloc_simple(ctx, BT_BOOLEAN, &public, sizeof(public));
 278  	if (obj == NULL)
 279  		goto out;
 280  	ok = libder_obj_append(root, obj);
 281  	assert(ok);
 282  
 283  	memset(keybuf, 0, sizeof(keybuf));
 284  	keybuf[0] = 0;	/* No unused bits */
 285  	keybuf[1] = PUBKEY_UNCOMPRESSED;
 286  	memcpy(&keybuf[2], keydata, keysz);
 287  
 288  	keybits = libder_obj_alloc_simple(ctx, BT_BITSTRING, &keybuf[0],
 289  	    keysz + 2);
 290  	if (keybits == NULL)
 291  		goto out;
 292  	ok = libder_obj_append(root, keybits);
 293  	assert(ok);
 294  
 295  	/* Finally, write it out. */
 296  	*buflen = 0;
 297  	outbuf = libder_write(ctx, root, NULL, buflen);
 298  	if (outbuf != NULL) {
 299  		*buf = outbuf;
 300  		rc = EPKG_OK;
 301  	}
 302  
 303  out:
 304  	libder_obj_free(root);
 305  	libder_close(ctx);
 306  	return (rc);
 307  }
 308  
 309  static int
 310  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  	if (libder_obj_type_simple(root) != BT_SEQUENCE)
 320  		return (EPKG_FATAL);
 321  
 322  	/* Application */
 323  	obj = libder_obj_child(root, 0);
 324  	if (obj == NULL || libder_obj_type_simple(obj) != BT_UTF8STRING)
 325  		return (EPKG_FATAL);
 326  	data = libder_obj_data(obj, &datasz);
 327  	if (datasz != sizeof(pkgkey_app) - 1 ||
 328  	    memcmp(data, pkgkey_app, datasz) != 0)
 329  		return (EPKG_FATAL);
 330  
 331  	/* Version */
 332  	obj = libder_obj_child(root, 1);
 333  	if (obj == NULL || libder_obj_type_simple(obj) != BT_INTEGER)
 334  		return (EPKG_FATAL);
 335  	data = libder_obj_data(obj, &datasz);
 336  	if (datasz != 1 || *data != 1 /* XXX */)
 337  		return (EPKG_FATAL);
 338  
 339  	/* Signer */
 340  	obj = libder_obj_child(root, 2);
 341  	if (obj == NULL || libder_obj_type_simple(obj) != BT_UTF8STRING)
 342  		return (EPKG_FATAL);
 343  	data = libder_obj_data(obj, &datasz);
 344  	if (datasz != sizeof(pkgkey_signer) - 1 ||
 345  	    memcmp(data, pkgkey_signer, datasz) != 0)
 346  		return (EPKG_FATAL);
 347  
 348  	/* KeyType (curve) */
 349  	obj = libder_obj_child(root, 3);
 350  	if (obj == NULL || libder_obj_type_simple(obj) != BT_UTF8STRING)
 351  		return (EPKG_FATAL);
 352  	data = libder_obj_data(obj, &datasz);
 353  	sparams = ecc_pkgkey_params(data, datasz);
 354  	if (sparams == NULL)
 355  		return (EPKG_FATAL);
 356  
 357  	ret = import_params(params, sparams);
 358  	if (ret != 0)
 359  		return (EPKG_FATAL);
 360  
 361  	/* Public? */
 362  	obj = libder_obj_child(root, 4);
 363  	if (obj == NULL || libder_obj_type_simple(obj) != BT_BOOLEAN)
 364  		return (EPKG_FATAL);
 365  	data = libder_obj_data(obj, &datasz);
 366  	if (datasz != 1 || !data[0] != !public)
 367  		return (EPKG_FATAL);
 368  
 369  	/* Key */
 370  	obj = libder_obj_child(root, 5);
 371  	if (obj == NULL || libder_obj_type_simple(obj) != BT_BITSTRING)
 372  		return (EPKG_FATAL);
 373  	data = libder_obj_data(obj, &datasz);
 374  	if (datasz <= 2 || data[0] != 0 || data[1] != PUBKEY_UNCOMPRESSED)
 375  		return (EPKG_FATAL);
 376  
 377  	data += 2;
 378  	datasz -= 2;
 379  
 380  	if (datasz > *rawlen)
 381  		return (EPKG_FATAL);
 382  
 383  
 384  	memcpy(rawkey, data, datasz);
 385  	*rawlen = datasz;
 386  
 387  	return (EPKG_OK);
 388  }
 389  
 390  static int
 391  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  	curlen = partlen;
 405  	while (curlen > 0 && sigpart[0] == 0) {
 406  		curlen--;
 407  		sigpart++;
 408  	}
 409  
 410  	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  		sigbounce[0] = 0;
 416  		memcpy(&sigbounce[1], sigpart, curlen);
 417  
 418  		obj = libder_obj_alloc_simple(ctx, BT_INTEGER, sigbounce,
 419  		    curlen + 1);
 420  	} else {
 421  		/*
 422  		 * Otherwise, we can just leave it be.
 423  		 */
 424  
 425  		obj = libder_obj_alloc_simple(ctx, BT_INTEGER, sigpart, curlen);
 426  	}
 427  
 428  	if (obj == NULL)
 429  		return (EPKG_FATAL);
 430  
 431  	ok = libder_obj_append(root, obj);
 432  	assert(ok);
 433  	return (EPKG_OK);
 434  }
 435  
 436  /*
 437   *       Ecdsa-Sig-Value  ::=  SEQUENCE  {
 438   *            r     INTEGER,
 439   *            s     INTEGER  }
 440   */
 441  static int
 442  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  	ctx = libder_open();
 452  	if (ctx == NULL)
 453  		return (EPKG_FATAL);
 454  
 455  	rc = EPKG_FATAL;
 456  	obj = NULL;
 457  	root = libder_obj_alloc_simple(ctx, BT_SEQUENCE, NULL, 0);
 458  	if (root == NULL)
 459  		goto out;
 460  
 461  	complen = siglen / 2;
 462  	rc = ecc_write_signature_component(ctx, root, sig, complen);
 463  	if (rc != EPKG_OK)
 464  		goto out;
 465  
 466  	sig += complen;
 467  	siglen -= complen;
 468  	rc = ecc_write_signature_component(ctx, root, sig, complen);
 469  	if (rc != EPKG_OK)
 470  		goto out;
 471  
 472  	*sigretlen = 0;
 473  	outbuf = libder_write(ctx, root, NULL, sigretlen);
 474  	if (outbuf != NULL) {
 475  		*sigret = outbuf;
 476  		rc = EPKG_OK;
 477  	}
 478  out:
 479  	libder_obj_free(obj);
 480  	libder_close(ctx);
 481  	return (rc);
 482  }
 483  
 484  static int
 485  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  	ctx = libder_open();
 495  	if (ctx == NULL)
 496  		return (EPKG_FATAL);
 497  
 498  	rc = EPKG_FATAL;
 499  	root = libder_read(ctx, sig, &siglen);
 500  	if (root == NULL || libder_obj_type_simple(root) != BT_SEQUENCE)
 501  		goto out;
 502  
 503  	/* Descend into the sequence's payload, extract both numbers. */
 504  	compsz = rawlen / 2;
 505  	sigoff = 0;
 506  	for (int i = 0; i < 2; i++) {
 507  		obj = libder_obj_child(root, i);
 508  		if (libder_obj_type_simple(obj) != BT_INTEGER)
 509  			goto out;
 510  
 511  		sigdata = libder_obj_data(obj, &datasz);
 512  		if (datasz < 2 || datasz > compsz + 1)
 513  			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  		if (sigdata[0] == 0 && (sigdata[1] & 0x80) != 0) {
 520  			sigdata++;
 521  			datasz--;
 522  		}
 523  
 524  		/* Sanity check: don't overflow the output. */
 525  		if (sigoff + datasz > rawlen)
 526  			goto out;
 527  
 528  		/* Padding to the significant end if we're too small. */
 529  		if (datasz < compsz) {
 530  			memset(&rawsig[sigoff], 0, compsz - datasz);
 531  			sigoff += compsz - datasz;
 532  		}
 533  
 534  		memcpy(&rawsig[sigoff], sigdata, datasz);
 535  		sigoff += datasz;
 536  	}
 537  
 538  	/* Sanity check: must have exactly the required # of signature bits. */
 539  	rc = (sigoff == rawlen) ? EPKG_OK : EPKG_FATAL;
 540  
 541  out:
 542  	libder_obj_free(root);
 543  	libder_close(ctx);
 544  	return (rc);
 545  }
 546  
 547  static int
 548  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  	if (datalen <= 2)
 554  		return (EPKG_FATAL);
 555  
 556  	usebit = *data++;
 557  	datalen--;
 558  
 559  	if (usebit != 0)
 560  		return (EPKG_FATAL);
 561  
 562  	prefix = *data++;
 563  	datalen--;
 564  
 565  	if (prefix != PUBKEY_UNCOMPRESSED)
 566  		return (EPKG_FATAL);
 567  
 568  	if (datalen > *rawlen)
 569  		return (EPKG_FATAL);
 570  
 571  	memcpy(rawkey, data, datalen);
 572  	*rawlen = datalen;
 573  
 574  	return (EPKG_OK);
 575  }
 576  
 577  static int
 578  ecc_extract_key_params(const uint8_t *oid, size_t oidlen,
 579      ec_params *rawparams)
 580  {
 581  	int ret;
 582  
 583  	if (oidlen >= sizeof(oid_secp) &&
 584  	    memcmp(oid, oid_secp, sizeof(oid_secp)) >= 0) {
 585  		oid += sizeof(oid_secp);
 586  		oidlen -= sizeof(oid_secp);
 587  
 588  		if (oidlen != 1)
 589  			return (EPKG_FATAL);
 590  
 591  		ret = -1;
 592  		switch (*oid) {
 593  		case 0x0a:	/* secp256k1 */
 594  			ret = import_params(rawparams, &secp256k1_str_params);
 595  			break;
 596  		case 0x22:	/* secp384r1 */
 597  			ret = import_params(rawparams, &secp384r1_str_params);
 598  			break;
 599  		case 0x23:	/* secp521r1 */
 600  			ret = import_params(rawparams, &secp521r1_str_params);
 601  			break;
 602  		default:
 603  			return (EPKG_FATAL);
 604  		}
 605  
 606  		if (ret == 0)
 607  			return (EPKG_OK);
 608  		return (EPKG_FATAL);
 609  	}
 610  
 611  	if (oidlen >= sizeof(oid_brainpoolP) &&
 612  	    memcmp(oid, oid_brainpoolP, sizeof(oid_brainpoolP)) >= 0) {
 613  		oid += sizeof(oid_brainpoolP);
 614  		oidlen -= sizeof(oid_brainpoolP);
 615  
 616  		if (oidlen != 1)
 617  			return (EPKG_FATAL);
 618  
 619  		ret = -1;
 620  		switch (*oid) {
 621  		case 0x07:	/* brainpoolP256r1 */
 622  			ret = import_params(rawparams, &brainpoolp256r1_str_params);
 623  			break;
 624  		case 0x08:	/* brainpoolP256t1 */
 625  			ret = import_params(rawparams, &brainpoolp256t1_str_params);
 626  			break;
 627  		case 0x09:	/* brainpoolP320r1 */
 628  			ret = import_params(rawparams, &brainpoolp320r1_str_params);
 629  			break;
 630  		case 0x0a:	/* brainpoolP320t1 */
 631  			ret = import_params(rawparams, &brainpoolp320t1_str_params);
 632  			break;
 633  		case 0x0b:	/* brainpoolP384r1 */
 634  			ret = import_params(rawparams, &brainpoolp384r1_str_params);
 635  			break;
 636  		case 0x0c:	/* brainpoolP384t1 */
 637  			ret = import_params(rawparams, &brainpoolp384t1_str_params);
 638  			break;
 639  		case 0x0d:	/* brainpoolP512r1 */
 640  			ret = import_params(rawparams, &brainpoolp512r1_str_params);
 641  			break;
 642  		case 0x0e:	/* brainpoolP512t1 */
 643  			ret = import_params(rawparams, &brainpoolp512t1_str_params);
 644  			break;
 645  		default:
 646  			return (EPKG_FATAL);
 647  		}
 648  
 649  		if (ret == 0)
 650  			return (EPKG_OK);
 651  		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  	return (EPKG_FATAL);
 663  }
 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  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  	ctx = libder_open();
 681  	if (ctx == NULL)
 682  		return (EPKG_FATAL);
 683  
 684  	rc = EPKG_FATAL;
 685  	root = libder_read(ctx, key, &keylen);
 686  	if (root == NULL || libder_obj_type_simple(root) != BT_SEQUENCE)
 687  		goto out;
 688  
 689  	params = libder_obj_child(root, 0);
 690  
 691  	if (params == NULL) {
 692  		goto out;
 693  	} else if (libder_obj_type_simple(params) != BT_SEQUENCE) {
 694  		rc = ecc_read_pkgkey(root, rawparams, 1, rawkey, rawlen);
 695  		goto out;
 696  	}
 697  
 698  	/* Is a sequence */
 699  	keydata = libder_obj_child(root, 1);
 700  	if (keydata == NULL || libder_obj_type_simple(keydata) != BT_BITSTRING)
 701  		goto out;
 702  
 703  	/* Key type */
 704  	oid = libder_obj_child(params, 0);
 705  	if (oid == NULL || libder_obj_type_simple(oid) != BT_OID)
 706  		goto out;
 707  
 708  	oidp = libder_obj_data(oid, &oidsz);
 709  	if (oidsz != sizeof(oid_ecpubkey) ||
 710  	    memcmp(oidp, oid_ecpubkey, oidsz) != 0)
 711  		return (EPKG_FATAL);
 712  
 713  	/* Curve */
 714  	oid = libder_obj_child(params, 1);
 715  	if (oid == NULL || libder_obj_type_simple(oid) != BT_OID)
 716  		goto out;
 717  
 718  	oidp = libder_obj_data(oid, &oidsz);
 719  	if (ecc_extract_key_params(oidp, oidsz, rawparams) != EPKG_OK)
 720  		goto out;
 721  
 722  	/* Finally, peel off the key material */
 723  	key = libder_obj_data(keydata, &keylen);
 724  	if (ecc_extract_pubkey_string(key, keylen, rawkey, rawlen) != EPKG_OK)
 725  		goto out;
 726  
 727  	rc = EPKG_OK;
 728  out:
 729  	libder_obj_free(root);
 730  	libder_close(ctx);
 731  	return (rc);
 732  }
 733  
 734  static int
 735  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  	ctx = libder_open();
 745  	if (ctx == NULL)
 746  		return (EPKG_FATAL);
 747  
 748  	rc = EPKG_FATAL;
 749  	root = libder_read(ctx, key, &keylen);
 750  	if (root == NULL || libder_obj_type_simple(root) != BT_SEQUENCE)
 751  		goto out;
 752  
 753  	/* Sanity check the version, we're expecting version 1. */
 754  	obj = libder_obj_child(root, 0);
 755  	if (obj == NULL)
 756  		goto out;
 757  	if (libder_obj_type_simple(obj) != BT_INTEGER) {
 758  		rc = ecc_read_pkgkey(root, rawparams, 0, rawkey, rawlen);
 759  		goto out;
 760  	}
 761  
 762  	data = libder_obj_data(obj, &datasz);
 763  	if (datasz != 1 || *data != 1)
 764  		goto out;
 765  
 766  	/* Grab the key data itself. */
 767  	obj = libder_obj_child(root, 1);
 768  	if (obj == NULL || libder_obj_type_simple(obj) != BT_OCTETSTRING)
 769  		goto out;
 770  
 771  	data = libder_obj_data(obj, &datasz);
 772  	if (datasz == 0 || datasz > *rawlen)
 773  		goto out;
 774  
 775  	memcpy(rawkey, data, datasz);
 776  	*rawlen = datasz;
 777  
 778  	/* Next, extract the OID describing the key type. */
 779  	obj = libder_obj_child(root, 2);
 780  	if (obj == NULL || libder_obj_type_simple(obj) !=
 781  	    ((BC_CONTEXT << 6) | BER_TYPE_CONSTRUCTED_MASK))
 782  		goto out;
 783  
 784  	obj = libder_obj_child(obj, 0);
 785  	if (obj == NULL || libder_obj_type_simple(obj) != BT_OID)
 786  		goto out;
 787  
 788  	data = libder_obj_data(obj, &datasz);
 789  	if (ecc_extract_key_params(data, datasz, rawparams) != EPKG_OK)
 790  		goto out;
 791  
 792  	rc = EPKG_OK;
 793  out:
 794  	libder_obj_free(root);
 795  	libder_close(ctx);
 796  	return (rc);
 797  }
 798  
 799  static int
 800  _generate_private_key(struct ecc_sign_ctx *keyinfo)
 801  {
 802  	int ret;
 803  
 804  	ret = ec_key_pair_gen(&keyinfo->keypair, &keyinfo->params,
 805  	    keyinfo->sig_alg);
 806  
 807  	if (ret != 0) {
 808  		pkg_emit_error("failed to generate ecc keypair");
 809  		return (EPKG_FATAL);
 810  	}
 811  
 812  	keyinfo->loaded = true;
 813  	return (EPKG_OK);
 814  }
 815  
 816  static inline void
 817  _specific_explicit_bzero(void *buf, size_t bufsz)
 818  {
 819  
 820  #ifdef __APPLE__
 821  	memset_s(buf, bufsz, 0, bufsz);
 822  #else
 823  	explicit_bzero(buf, bufsz);
 824  #endif
 825  }
 826  
 827  
 828  static int
 829  _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  	filedata = NULL;
 840  	fd = -1;
 841  	rc = EPKG_FATAL;
 842  
 843  	keyinfo->loaded = false;
 844  	if ((fd = open(keyinfo->sctx.path, O_RDONLY)) == -1)
 845  		return (EPKG_FATAL);
 846  
 847  	if (fstat(fd, &st) == -1)
 848  		goto out;
 849  
 850  	filedata = xmalloc(st.st_size);
 851  	resid = st.st_size;
 852  	offset = 0;
 853  	while (resid != 0) {
 854  		readsz = read(fd, &filedata[offset], resid);
 855  		if (readsz <= 0)
 856  			break;
 857  		resid -= readsz;
 858  		offset += readsz;
 859  	}
 860  
 861  	if (readsz < 0) {
 862  		pkg_emit_errno("read", keyinfo->sctx.path);
 863  		goto out;
 864  	} else if (resid != 0) {
 865  		pkg_emit_error("%s: failed to read key",
 866  		    keyinfo->sctx.path);
 867  		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  	keysz = sizeof(keybuf);
 876  	if (ecc_extract_privkey(filedata, offset, keybuf, &keysz,
 877  	    &keyinfo->params) != EPKG_OK) {
 878  		pkg_emit_error("failed to decode private key");
 879  		goto out;
 880  	}
 881  
 882  	ret = ec_priv_key_import_from_buf(&keyinfo->keypair.priv_key,
 883  	    &keyinfo->params, keybuf, keysz, keyinfo->sig_alg);
 884  	if (ret == 0) {
 885  		ret = init_pubkey_from_privkey(&keyinfo->keypair.pub_key,
 886  			&keyinfo->keypair.priv_key);
 887  		if (ret == 0) {
 888  			keyinfo->loaded = true;
 889  			rc = EPKG_OK;
 890  		} else {
 891  			pkg_emit_error("%s: failed to derive public key",
 892  			    keyinfo->sctx.path);
 893  			rc = EPKG_FATAL;
 894  		}
 895  	} else {
 896  		pkg_emit_error("%s: failed to import private key",
 897  		    keyinfo->sctx.path);
 898  		rc = EPKG_FATAL;
 899  	}
 900  
 901  out:
 902  	_specific_explicit_bzero(keybuf, sizeof(keybuf));
 903  	free(filedata);
 904  	if (fd != -1)
 905  		close(fd);
 906  	return (rc);
 907  }
 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  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  	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  	keysz = MIN(sizeof(keybuf), cbdata->keylen / 2);
 931  
 932  	keysz = sizeof(keybuf);
 933  	if (ecc_extract_pubkey(cbdata->key, cbdata->keylen, keybuf,
 934  	    &keysz, &derparams) != EPKG_OK) {
 935  		pkg_emit_error("failed to parse key");
 936  		return (EPKG_FATAL);
 937  	}
 938  
 939  	ret = ec_get_sig_len(&derparams, keyinfo->sig_alg, keyinfo->sig_hash,
 940  	    &ecsiglen);
 941  	if (ret != 0)
 942  		return (EPKG_FATAL);
 943  
 944  	/*
 945  	 * Signatures are DER-encoded, whether by OpenSSL or pkg.
 946  	 */
 947  	if (ecc_extract_signature(cbdata->sig, cbdata->siglen,
 948  	    rawsig, ecsiglen) != EPKG_OK) {
 949  		pkg_emit_error("failed to decode signature");
 950  		return (EPKG_FATAL);
 951  	}
 952  
 953  	ret = ec_pub_key_import_from_aff_buf(&pubkey, &derparams,
 954  	    keybuf, keysz, keyinfo->sig_alg);
 955  	if (ret != 0) {
 956  		pkg_emit_error("failed to import key");
 957  		return (EPKG_FATAL);
 958  	}
 959  
 960  	ret = ec_verify(rawsig, ecsiglen, &pubkey, hash, hashsz, keyinfo->sig_alg,
 961  	    keyinfo->sig_hash, NULL, 0);
 962  	if (ret != 0) {
 963  		pkg_emit_error("failed to verify signature");
 964  		return (EPKG_FATAL);
 965  	}
 966  
 967  	return (EPKG_OK);
 968  }
 969  
 970  
 971  static int
 972  ecc_verify_cert_cb(int fd, void *ud)
 973  {
 974  	struct ecc_verify_cbdata *cbdata = ud;
 975  	char *sha256;
 976  	int ret;
 977  
 978  	sha256 = pkg_checksum_fd(fd, PKG_HASH_TYPE_SHA256_HEX);
 979  	if (sha256 == NULL)
 980  		return (EPKG_FATAL);
 981  
 982  	ret = ecc_verify_internal(cbdata, sha256, strlen(sha256));
 983  	if (ret != 0) {
 984  		pkg_emit_error("ecc signature verification failure");
 985  		return (EPKG_FATAL);
 986  	}
 987  
 988  	return (EPKG_OK);
 989  }
 990  
 991  static int
 992  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  	(void)lseek(fd, 0, SEEK_SET);
 999  
1000  	cbdata.sctx = sctx;
1001  	cbdata.key = key;
1002  	cbdata.keylen = keylen;
1003  	cbdata.sig = sig;
1004  	cbdata.siglen = siglen;
1005  
1006  	ret = pkg_emit_sandbox_call(ecc_verify_cert_cb, fd, &cbdata);
1007  
1008  	return (ret);
1009  }
1010  
1011  static int
1012  ecc_verify_cb(int fd, void *ud)
1013  {
1014  	struct ecc_verify_cbdata *cbdata = ud;
1015  	uint8_t *blake2;
1016  	int ret;
1017  
1018  	blake2 = pkg_checksum_fd(fd, PKG_HASH_TYPE_BLAKE2_RAW);
1019  	if (blake2 == NULL)
1020  		return (EPKG_FATAL);
1021  
1022  	ret = ecc_verify_internal(cbdata, blake2,
1023  	    pkg_checksum_type_size(PKG_HASH_TYPE_BLAKE2_RAW));
1024  
1025  	free(blake2);
1026  	if (ret != 0) {
1027  		pkg_emit_error("ecc signature verification failure");
1028  		return (EPKG_FATAL);
1029  	}
1030  
1031  	return (EPKG_OK);
1032  }
1033  
1034  static int
1035  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  	if (file_to_buffer(keypath, (char**)&key_buf, &key_len) != EPKG_OK) {
1044  		pkg_emit_errno("ecc_verify", "cannot read key");
1045  		return (EPKG_FATAL);
1046  	}
1047  
1048  	(void)lseek(fd, 0, SEEK_SET);
1049  
1050  	cbdata.sctx = sctx;
1051  	cbdata.key = key_buf;
1052  	cbdata.keylen = key_len;
1053  	cbdata.sig = sig;
1054  	cbdata.siglen = sig_len;
1055  
1056  	ret = pkg_emit_sandbox_call(ecc_verify_cb, fd, &cbdata);
1057  
1058  	free(key_buf);
1059  
1060  	return (ret);
1061  }
1062  
1063  static int
1064  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  	struct ecc_sign_ctx *keyinfo = ECC_CTX(sctx);
1069  	int ret;
1070  	uint8_t rawlen;
1071  
1072  	if (!keyinfo->loaded && _load_private_key(keyinfo) != EPKG_OK) {
1073  		pkg_emit_error("%s: failed to load key", keyinfo->sctx.path);
1074  		return (EPKG_FATAL);
1075  	}
1076  
1077  	ret = ec_get_sig_len(&keyinfo->params, keyinfo->sig_alg, keyinfo->sig_hash,
1078  		&rawlen);
1079  	if (ret != 0)
1080  		return (EPKG_FATAL);
1081  
1082  	assert(rawlen <= sizeof(rawsig));
1083  
1084  	assert(priv_key_check_initialized_and_type(&keyinfo->keypair.priv_key,
1085  	    keyinfo->sig_alg) == 0);
1086  	assert(pub_key_check_initialized_and_type(&keyinfo->keypair.pub_key,
1087  	    keyinfo->sig_alg) == 0);
1088  
1089  	ret = ec_sign(rawsig, rawlen, &keyinfo->keypair, msg, msgsz,
1090  	    keyinfo->sig_alg, keyinfo->sig_hash, NULL, 0);
1091  
1092  	if (ret != 0) {
1093  		pkg_emit_error("%s: ecc signing failure", keyinfo->sctx.path);
1094  		return (EPKG_FATAL);
1095  	}
1096  
1097  	if (ecc_write_signature(rawsig, rawlen, sigret, siglen) != EPKG_OK) {
1098  		pkg_emit_error("failed to encode signature");
1099  		return (EPKG_FATAL);
1100  	}
1101  
1102  	return (EPKG_OK);
1103  }
1104  
1105  static int
1106  ecc_sign(struct pkgsign_ctx *sctx, const char *path, unsigned char **sigret,
1107      size_t *siglen)
1108  {
1109  	uint8_t *blake2;
1110  	struct ecc_sign_ctx *keyinfo = ECC_CTX(sctx);
1111  	int ret;
1112  
1113  	if (access(keyinfo->sctx.path, R_OK) == -1) {
1114  		pkg_emit_errno("access", keyinfo->sctx.path);
1115  		return (EPKG_FATAL);
1116  	}
1117  
1118  	blake2 = pkg_checksum_file(path, PKG_HASH_TYPE_BLAKE2_RAW);
1119  	if (blake2 == NULL)
1120  		return (EPKG_FATAL);
1121  
1122  	ret = ecc_sign_data(sctx, blake2,
1123  	    pkg_checksum_type_size(PKG_HASH_TYPE_BLAKE2_RAW), sigret, siglen);
1124  	free(blake2);
1125  
1126  	return (ret);
1127  }
1128  
1129  static int
1130  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  	struct ecc_sign_ctx *keyinfo = ECC_CTX(sctx);
1135  	const char *path = sctx->path;
1136  	FILE *fp;
1137  	size_t keysz, outsz;
1138  
1139  	if (niov != 0)
1140  		return (EPKG_FATAL);
1141  
1142  	if (_generate_private_key(keyinfo) != 0)
1143  		return (EPKG_FATAL);
1144  
1145  	assert(priv_key_check_initialized_and_type(&keyinfo->keypair.priv_key,
1146  	    keyinfo->sig_alg) == 0);
1147  	assert(pub_key_check_initialized_and_type(&keyinfo->keypair.pub_key,
1148  	    keyinfo->sig_alg) == 0);
1149  
1150  	keysz = EC_PRIV_KEY_EXPORT_SIZE(&keyinfo->keypair.priv_key);
1151  	if (ec_priv_key_export_to_buf(&keyinfo->keypair.priv_key,
1152  	    keybuf, keysz) != 0) {
1153  		pkg_emit_error("failed to export ecc key");
1154  		return (EPKG_FATAL);
1155  	}
1156  
1157  	outbuf = NULL;
1158  	outsz = 0;
1159  	if (ecc_write_pkgkey(&keyinfo->params, 0, keybuf, keysz, &outbuf,
1160  	    &outsz) != EPKG_OK) {
1161  		pkg_emit_error("%s: failed to write DER-encoded key",
1162  		    sctx->path);
1163  		return (EPKG_FATAL);
1164  	}
1165  
1166  	fp = fopen(path, "wb");
1167  	if (fp == NULL) {
1168  		pkg_emit_errno("fopen write", path);
1169  		free(outbuf);
1170  		return (EPKG_FATAL);
1171  	}
1172  
1173  	if (fchmod(fileno(fp), 0400) != 0) {
1174  		pkg_emit_errno("fchmod", path);
1175  		free(outbuf);
1176  		fclose(fp);
1177  		return (EPKG_FATAL);
1178  	}
1179  
1180  	fwrite(outbuf, outsz, 1, fp);
1181  	free(outbuf);
1182  	outbuf = NULL;
1183  	if (ferror(fp) != 0 || fflush(fp) != 0) {
1184  		pkg_emit_errno("fwrite", path);
1185  		fclose(fp);
1186  		return (EPKG_FATAL);
1187  	}
1188  
1189  	fclose(fp);
1190  	return (EPKG_OK);
1191  }
1192  
1193  static int
1194  ecc_pubkey(struct pkgsign_ctx *sctx, char **pubkey, size_t *pubkeylen)
1195  {
1196  	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  	if (!keyinfo->loaded && _load_private_key(keyinfo) != EPKG_OK) {
1202  		pkg_emit_error("%s: failed to load key", sctx->path);
1203  		return (EPKG_FATAL);
1204  	}
1205  
1206  	assert(keyinfo->loaded);
1207  	assert(pub_key_check_initialized_and_type(&keyinfo->keypair.pub_key,
1208  	    keyinfo->sig_alg) == 0);
1209  
1210  	keylen = 2 * BYTECEIL(keyinfo->params.ec_fp.p_bitlen);
1211  	ret = ec_pub_key_export_to_aff_buf(&keyinfo->keypair.pub_key, keybuf, keylen);
1212  	if (ret != 0) {
1213  		pkg_emit_error("%s: failed to export key", sctx->path);
1214  		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  	if (keyinfo->sig_alg != ECDSA) {
1224  		if (ecc_write_pkgkey(&keyinfo->params, 1, keybuf, keylen,
1225  		    (uint8_t **)pubkey, pubkeylen) != EPKG_OK) {
1226  			pkg_emit_error("%s: failed to write DER-encoded key",
1227  
1228  			    sctx->path);
1229  			return (EPKG_FATAL);
1230  		}
1231  	} else if (ecc_pubkey_write_pkcs8(keybuf, keylen,
1232  	    (uint8_t **)pubkey, pubkeylen) != EPKG_OK) {
1233  		pkg_emit_error("%s: failed to write DER-encoded key", sctx->path);
1234  		return (EPKG_FATAL);
1235  	}
1236  
1237  	return (EPKG_OK);
1238  }
1239  
1240  static int
1241  ecc_new(const char *name __unused, struct pkgsign_ctx *sctx)
1242  {
1243  	struct ecc_sign_ctx *keyinfo = ECC_CTX(sctx);
1244  	int ret;
1245  
1246  	ret = EPKG_FATAL;
1247  	if (STREQ(name, "ecc") || STREQ(name, "eddsa")) {
1248  			keyinfo->sig_alg = EDDSA25519;
1249  			keyinfo->sig_hash = SHA512;
1250  			ret = import_params(&keyinfo->params, &wei25519_str_params);
1251  	} else if (STREQ(name, "ecdsa")) {
1252  			keyinfo->sig_alg = ECDSA;
1253  			keyinfo->sig_hash = SHA256;
1254  			ret = import_params(&keyinfo->params, &secp256k1_str_params);
1255  	}
1256  
1257  	if (ret != 0)
1258  		return (EPKG_FATAL);
1259  
1260  	return (0);
1261  }
1262  
1263  static void
1264  ecc_free(struct pkgsign_ctx *sctx)
1265  {
1266  	struct ecc_sign_ctx *keyinfo = ECC_CTX(sctx);
1267  
1268  	_specific_explicit_bzero(&keyinfo->keypair, sizeof(keyinfo->keypair));
1269  }
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  };