adding initial support for ECDSA (19) to netpgp. tested using p256/sha256, p384/sha384, and p521/sha512
This commit is contained in:
parent
5c869fd70e
commit
0294a66b69
|
@ -57,7 +57,7 @@
|
|||
|
||||
#if defined(__NetBSD__)
|
||||
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
|
||||
__RCSID("$NetBSD: create.c,v 1.38 2010/11/15 08:03:39 agc Exp $");
|
||||
__RCSID("$NetBSD: create.c,v 1.39 2022/08/26 19:18:38 jhigh Exp $");
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
@ -250,6 +250,11 @@ write_pubkey_body(const pgp_pubkey_t *key, pgp_output_t *output)
|
|||
pgp_write_mpi(output, key->key.dsa.g) &&
|
||||
pgp_write_mpi(output, key->key.dsa.y);
|
||||
|
||||
case PGP_PKA_ECDSA:
|
||||
return pgp_write(output, &key->key.ecdsa.len, 1) &&
|
||||
pgp_write(output, key->key.ecdsa.oid, key->key.ecdsa.len) &&
|
||||
pgp_write_mpi(output, key->key.ecdsa.p);
|
||||
|
||||
case PGP_PKA_RSA:
|
||||
case PGP_PKA_RSA_ENCRYPT_ONLY:
|
||||
case PGP_PKA_RSA_SIGN_ONLY:
|
||||
|
|
|
@ -58,7 +58,9 @@
|
|||
#include "memory.h"
|
||||
#include "packet-parse.h"
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/dsa.h>
|
||||
#include <openssl/ecdsa.h>
|
||||
|
||||
#define PGP_MIN_HASH_SIZE 16
|
||||
|
||||
|
@ -119,6 +121,10 @@ unsigned pgp_dsa_verify(const uint8_t *, size_t,
|
|||
const pgp_dsa_sig_t *,
|
||||
const pgp_dsa_pubkey_t *);
|
||||
|
||||
unsigned pgp_ecdsa_verify(const uint8_t *, size_t,
|
||||
const pgp_ecdsa_sig_t *,
|
||||
const pgp_ecdsa_pubkey_t *);
|
||||
|
||||
int pgp_rsa_public_decrypt(uint8_t *, const uint8_t *, size_t,
|
||||
const pgp_rsa_pubkey_t *);
|
||||
int pgp_rsa_public_encrypt(uint8_t *, const uint8_t *, size_t,
|
||||
|
@ -214,6 +220,10 @@ DSA_SIG *pgp_dsa_sign(uint8_t *, unsigned,
|
|||
const pgp_dsa_seckey_t *,
|
||||
const pgp_dsa_pubkey_t *);
|
||||
|
||||
ECDSA_SIG *pgp_ecdsa_sign(uint8_t *, unsigned,
|
||||
const pgp_ecdsa_seckey_t *,
|
||||
const pgp_ecdsa_pubkey_t *);
|
||||
|
||||
int openssl_read_pem_seckey(const char *, pgp_key_t *, const char *, int);
|
||||
|
||||
/** pgp_reader_t */
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
|
||||
#if defined(__NetBSD__)
|
||||
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
|
||||
__RCSID("$NetBSD: misc.c,v 1.43 2020/04/18 19:27:48 jhigh Exp $");
|
||||
__RCSID("$NetBSD: misc.c,v 1.44 2022/08/26 19:18:38 jhigh Exp $");
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
@ -96,6 +96,18 @@ __RCSID("$NetBSD: misc.c,v 1.43 2020/04/18 19:27:48 jhigh Exp $");
|
|||
#define vsnprintf _vsnprintf
|
||||
#endif
|
||||
|
||||
struct ecdsa_map {
|
||||
char *sname;
|
||||
int nid;
|
||||
int bits;
|
||||
int len;
|
||||
uint8_t oid[8];
|
||||
} ecdsa_map[] = {
|
||||
{ "P-256", NID_X9_62_prime256v1, 256, 8, {0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07} },
|
||||
{ "P-384", NID_secp384r1, 384, 5, {0x2B, 0x81, 0x04, 0x00, 0x22} },
|
||||
{ "P-521", NID_secp521r1, 521, 5, {0x2B, 0x81, 0x04, 0x00, 0x23} },
|
||||
{ NULL, 0, 0, 0, {0} }
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
pgp_keyring_t *keyring;
|
||||
|
@ -1364,3 +1376,75 @@ netpgp_strcasecmp(const char *s1, const char *s2)
|
|||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
int
|
||||
ecdsa_nid(const pgp_ecdsa_pubkey_t * pub)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; ecdsa_map[i].sname; i++ ) {
|
||||
if (pub->len == ecdsa_map[i].len) {
|
||||
if (memcmp(pub->oid, ecdsa_map[i].oid, pub->len) == 0) {
|
||||
return ecdsa_map[i].nid;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
ecdsa_numbits(const pgp_ecdsa_pubkey_t * pub)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; ecdsa_map[i].sname; i++ ) {
|
||||
if (pub->len == ecdsa_map[i].len) {
|
||||
if (memcmp(pub->oid, ecdsa_map[i].oid, pub->len) == 0) {
|
||||
return ecdsa_map[i].bits;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
ecdsa_hashsize(const pgp_ecdsa_pubkey_t * pub)
|
||||
{
|
||||
int bits;
|
||||
|
||||
bits = ecdsa_numbits(pub);
|
||||
|
||||
if (bits == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (bits/8) - (bits%8);
|
||||
}
|
||||
|
||||
pgp_hash_alg_t
|
||||
ecdsa_hashalg(const pgp_ecdsa_pubkey_t * pub)
|
||||
{
|
||||
int nid;
|
||||
|
||||
if (pub == NULL) {
|
||||
return PGP_HASH_UNKNOWN;
|
||||
}
|
||||
|
||||
nid = ecdsa_nid(pub);
|
||||
|
||||
switch (nid) {
|
||||
case NID_X9_62_prime256v1:
|
||||
return PGP_HASH_SHA256;
|
||||
|
||||
case NID_secp384r1:
|
||||
return PGP_HASH_SHA384;
|
||||
|
||||
case NID_secp521r1:
|
||||
return PGP_HASH_SHA512;
|
||||
|
||||
default:
|
||||
(void) fprintf(stderr, "ecdsa_hashalg: unknown NID\n");
|
||||
}
|
||||
|
||||
return PGP_HASH_UNKNOWN;
|
||||
}
|
||||
|
|
|
@ -74,5 +74,9 @@ void netpgp_log(const char *, ...) __printflike(1, 2);
|
|||
int netpgp_strcasecmp(const char *, const char *);
|
||||
char *netpgp_strdup(const char *);
|
||||
|
||||
int ecdsa_numbits(const pgp_ecdsa_pubkey_t *);
|
||||
int ecdsa_nid(const pgp_ecdsa_pubkey_t *);
|
||||
pgp_hash_alg_t ecdsa_hashalg(const pgp_ecdsa_pubkey_t *);
|
||||
int ecdsa_hashsize(const pgp_ecdsa_pubkey_t *);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
|
||||
#if defined(__NetBSD__)
|
||||
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
|
||||
__RCSID("$NetBSD: openssl_crypto.c,v 1.34 2018/02/05 23:56:01 christos Exp $");
|
||||
__RCSID("$NetBSD: openssl_crypto.c,v 1.35 2022/08/26 19:18:38 jhigh Exp $");
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENSSL_DSA_H
|
||||
|
@ -87,6 +87,7 @@ __RCSID("$NetBSD: openssl_crypto.c,v 1.34 2018/02/05 23:56:01 christos Exp $");
|
|||
#include "readerwriter.h"
|
||||
#include "netpgpdefs.h"
|
||||
#include "netpgpdigest.h"
|
||||
#include "netpgpsdk.h"
|
||||
#include "packet.h"
|
||||
|
||||
static void
|
||||
|
@ -223,6 +224,103 @@ takeDSA(const DSA *odsa, pgp_dsa_seckey_t *sk)
|
|||
sk->x = BN_dup(x);
|
||||
}
|
||||
|
||||
static ECDSA_SIG *
|
||||
makeECDSADSA_SIG(const pgp_ecdsa_sig_t *sig)
|
||||
{
|
||||
ECDSA_SIG *osig;
|
||||
BIGNUM *r, *s;
|
||||
|
||||
osig = ECDSA_SIG_new();
|
||||
r = BN_dup(sig->r);
|
||||
s = BN_dup(sig->s);
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
|
||||
ECDSA_SIG_set0(osig, r, s);
|
||||
#else
|
||||
BN_free(osig->r);
|
||||
BN_free(osig->s);
|
||||
osig->r = r;
|
||||
osig->s = s;
|
||||
#endif
|
||||
|
||||
return osig;
|
||||
}
|
||||
|
||||
static EC_KEY *
|
||||
makeECDSA(const pgp_ecdsa_pubkey_t *ecdsa, const pgp_ecdsa_seckey_t *sececdsa)
|
||||
{
|
||||
EC_KEY *key;
|
||||
BIGNUM *x;
|
||||
BIGNUM *y;
|
||||
EC_GROUP *group;
|
||||
EC_POINT *pub_key;
|
||||
EC_POINT *point;
|
||||
int nid;
|
||||
|
||||
key = EC_KEY_new();
|
||||
x = BN_new();
|
||||
y = BN_new();
|
||||
|
||||
nid = ecdsa_nid(ecdsa);
|
||||
if (nid == -1) {
|
||||
(void) fprintf(stderr,"makeECDSA: failed to determine NID\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
group = EC_GROUP_new_by_curve_name(nid);
|
||||
if (group == NULL) {
|
||||
(void) fprintf(stderr,"makeECDSA: failed to get group for specified NID\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
pub_key = EC_POINT_new(group);
|
||||
if (pub_key == NULL) {
|
||||
(void) fprintf(stderr,"makeECDSA: failed to alloc point\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
point = EC_POINT_bn2point(group, ecdsa->p, NULL, NULL);
|
||||
if (point == NULL) {
|
||||
(void) fprintf(stderr,"makeECDSA: failed to conv BN to point\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if ((EC_POINT_get_affine_coordinates(group, point, x, y, NULL)) == 0) {
|
||||
(void) fprintf(stderr,"makeECDSA: failed to get coordinates from point\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((EC_POINT_set_affine_coordinates(group, pub_key, x, y, NULL)) == 0) {
|
||||
(void) fprintf(stderr,"makeECDSA: failed to set coordinates from point\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((EC_KEY_set_group(key, group)) == 0) {
|
||||
(void) fprintf(stderr,"makeECDSA: failed to set group for key\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((EC_KEY_set_public_key(key, pub_key)) == 0) {
|
||||
(void) fprintf(stderr,"makeECDSA: failed to set pubkey for key\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sececdsa) {
|
||||
if ((EC_KEY_set_private_key(key, sececdsa->x)) == 0) {
|
||||
(void) fprintf(stderr,"makeECDSA: failed to set seckey for key\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((EC_POINT_mul(group, pub_key, sececdsa->x, NULL, NULL, NULL)) == 0) {
|
||||
(void) fprintf(stderr,"makeECDSA: failed to calculate generator\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
static void
|
||||
test_seckey(const pgp_seckey_t *seckey)
|
||||
{
|
||||
|
@ -587,6 +685,36 @@ pgp_dsa_verify(const uint8_t *hash, size_t hash_length,
|
|||
return (unsigned)ret;
|
||||
}
|
||||
|
||||
unsigned
|
||||
pgp_ecdsa_verify(const uint8_t *hash, size_t hash_length,
|
||||
const pgp_ecdsa_sig_t *sig,
|
||||
const pgp_ecdsa_pubkey_t *ecdsa)
|
||||
{
|
||||
unsigned qlen;
|
||||
ECDSA_SIG *osig = makeECDSADSA_SIG(sig);
|
||||
EC_KEY *oecdsa = makeECDSA(ecdsa, NULL);
|
||||
int ret;
|
||||
|
||||
if (pgp_get_debug_level(__FILE__)) {
|
||||
hexdump(stderr, "input hash", hash, hash_length);
|
||||
}
|
||||
|
||||
ret = ECDSA_do_verify(hash, (int)hash_length, osig, oecdsa);
|
||||
|
||||
if (pgp_get_debug_level(__FILE__)) {
|
||||
(void) fprintf(stderr, "ret=%d\n", ret);
|
||||
}
|
||||
|
||||
if (ret <= 0) {
|
||||
(void) fprintf(stderr, "pgp_ecdsa_verify: ECDSA verification failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ECDSA_SIG_free(osig);
|
||||
|
||||
return (unsigned)ret;
|
||||
}
|
||||
|
||||
/**
|
||||
\ingroup Core_Crypto
|
||||
\brief Recovers message digest from the signature
|
||||
|
@ -916,6 +1044,27 @@ pgp_dsa_sign(uint8_t *hashbuf,
|
|||
return dsasig;
|
||||
}
|
||||
|
||||
ECDSA_SIG *
|
||||
pgp_ecdsa_sign(uint8_t *hashbuf,
|
||||
unsigned hashsize,
|
||||
const pgp_ecdsa_seckey_t *sececdsa,
|
||||
const pgp_ecdsa_pubkey_t *pubecdsa)
|
||||
{
|
||||
ECDSA_SIG * ecdsasig;
|
||||
EC_KEY * eckey = makeECDSA(pubecdsa, sececdsa);
|
||||
|
||||
ecdsasig = ECDSA_do_sign(hashbuf, (int)hashsize, eckey);
|
||||
|
||||
if (ecdsasig == NULL) {
|
||||
printf("do_sign returned null\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
EC_KEY_free(eckey);
|
||||
|
||||
return ecdsasig;
|
||||
}
|
||||
|
||||
int
|
||||
openssl_read_pem_seckey(const char *f, pgp_key_t *key, const char *type, int verbose)
|
||||
{
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
|
||||
#if defined(__NetBSD__)
|
||||
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
|
||||
__RCSID("$NetBSD: packet-parse.c,v 1.53 2020/10/14 05:19:41 jhigh Exp $");
|
||||
__RCSID("$NetBSD: packet-parse.c,v 1.54 2022/08/26 19:18:38 jhigh Exp $");
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
@ -940,6 +940,11 @@ sig_free(pgp_sig_t *sig)
|
|||
free_BN(&sig->info.sig.dsa.s);
|
||||
break;
|
||||
|
||||
case PGP_PKA_ECDSA:
|
||||
free_BN(&sig->info.sig.ecdsa.r);
|
||||
free_BN(&sig->info.sig.ecdsa.s);
|
||||
break;
|
||||
|
||||
case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
|
||||
free_BN(&sig->info.sig.elgamal.r);
|
||||
free_BN(&sig->info.sig.elgamal.s);
|
||||
|
@ -1176,6 +1181,10 @@ pgp_pubkey_free(pgp_pubkey_t *p)
|
|||
free_BN(&p->key.dsa.y);
|
||||
break;
|
||||
|
||||
case PGP_PKA_ECDSA:
|
||||
free_BN(&p->key.ecdsa.p);
|
||||
break;
|
||||
|
||||
case PGP_PKA_ELGAMAL:
|
||||
case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
|
||||
free_BN(&p->key.elgamal.p);
|
||||
|
@ -1245,6 +1254,14 @@ parse_pubkey_data(pgp_pubkey_t *key, pgp_region_t *region,
|
|||
}
|
||||
break;
|
||||
|
||||
case PGP_PKA_ECDSA:
|
||||
if (!limread(&key->key.ecdsa.len, 1, region, stream) ||
|
||||
!limread(key->key.ecdsa.oid, key->key.ecdsa.len, region, stream) ||
|
||||
!limread_mpi(&key->key.ecdsa.p, region, stream)) {
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case PGP_PKA_RSA:
|
||||
case PGP_PKA_RSA_ENCRYPT_ONLY:
|
||||
case PGP_PKA_RSA_SIGN_ONLY:
|
||||
|
@ -1496,6 +1513,13 @@ parse_v3_sig(pgp_region_t *region,
|
|||
}
|
||||
break;
|
||||
|
||||
case PGP_PKA_ECDSA:
|
||||
if (!limread_mpi(&pkt.u.sig.info.sig.ecdsa.r, region, stream) ||
|
||||
!limread_mpi(&pkt.u.sig.info.sig.ecdsa.s, region, stream)) {
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
|
||||
if (!limread_mpi(&pkt.u.sig.info.sig.elgamal.r, region,
|
||||
stream) ||
|
||||
|
@ -2035,6 +2059,13 @@ parse_v4_sig(pgp_region_t *region, pgp_stream_t *stream)
|
|||
}
|
||||
break;
|
||||
|
||||
case PGP_PKA_ECDSA:
|
||||
if (!limread_mpi(&pkt.u.sig.info.sig.ecdsa.r, region, stream) ||
|
||||
!limread_mpi(&pkt.u.sig.info.sig.ecdsa.s, region, stream)) {
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
|
||||
if (!limread_mpi(&pkt.u.sig.info.sig.elgamal.r, region,
|
||||
stream) ||
|
||||
|
@ -2322,6 +2353,10 @@ pgp_seckey_free(pgp_seckey_t *key)
|
|||
free_BN(&key->key.dsa.x);
|
||||
break;
|
||||
|
||||
case PGP_PKA_ECDSA:
|
||||
free_BN(&key->key.ecdsa.x);
|
||||
break;
|
||||
|
||||
default:
|
||||
(void) fprintf(stderr,
|
||||
"pgp_seckey_free: Unknown algorithm: %d (%s)\n",
|
||||
|
@ -2632,6 +2667,12 @@ parse_seckey(pgp_region_t *region, pgp_stream_t *stream)
|
|||
}
|
||||
break;
|
||||
|
||||
case PGP_PKA_ECDSA:
|
||||
if (!limread_mpi(&pkt.u.seckey.key.ecdsa.x, region, stream)) {
|
||||
ret = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case PGP_PKA_ELGAMAL:
|
||||
if (!limread_mpi(&pkt.u.seckey.key.elgamal.x, region, stream)) {
|
||||
ret = 0;
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
|
||||
#if defined(__NetBSD__)
|
||||
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
|
||||
__RCSID("$NetBSD: packet-print.c,v 1.43 2021/07/28 22:31:45 jhigh Exp $");
|
||||
__RCSID("$NetBSD: packet-print.c,v 1.44 2022/08/26 19:18:38 jhigh Exp $");
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
@ -325,6 +325,8 @@ numkeybits(const pgp_pubkey_t *pubkey)
|
|||
default:
|
||||
return 0;
|
||||
}
|
||||
case PGP_PKA_ECDSA:
|
||||
return ecdsa_numbits(&pubkey->key.ecdsa);
|
||||
case PGP_PKA_ELGAMAL:
|
||||
return BN_num_bytes(pubkey->key.elgamal.y) * 8;
|
||||
default:
|
||||
|
@ -659,7 +661,9 @@ pgp_print_pubkey(const pgp_pubkey_t *pubkey)
|
|||
print_bn(0, "g", pubkey->key.dsa.g);
|
||||
print_bn(0, "y", pubkey->key.dsa.y);
|
||||
break;
|
||||
|
||||
case PGP_PKA_ECDSA:
|
||||
print_bn(0, "p", pubkey->key.ecdsa.p);
|
||||
break;
|
||||
case PGP_PKA_RSA:
|
||||
case PGP_PKA_RSA_ENCRYPT_ONLY:
|
||||
case PGP_PKA_RSA_SIGN_ONLY:
|
||||
|
@ -974,6 +978,11 @@ pgp_print_packet(pgp_printstate_t *print, const pgp_packet_t *pkt)
|
|||
print_bn(print->indent, "s", content->sig.info.sig.dsa.s);
|
||||
break;
|
||||
|
||||
case PGP_PKA_ECDSA:
|
||||
print_bn(print->indent, "r", content->sig.info.sig.ecdsa.r);
|
||||
print_bn(print->indent, "s", content->sig.info.sig.ecdsa.s);
|
||||
break;
|
||||
|
||||
case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
|
||||
print_bn(print->indent, "r", content->sig.info.sig.elgamal.r);
|
||||
print_bn(print->indent, "s", content->sig.info.sig.elgamal.s);
|
||||
|
|
|
@ -60,7 +60,7 @@
|
|||
|
||||
#if defined(__NetBSD__)
|
||||
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
|
||||
__RCSID("$NetBSD: packet-show.c,v 1.22 2021/07/28 22:31:45 jhigh Exp $");
|
||||
__RCSID("$NetBSD: packet-show.c,v 1.23 2022/08/26 19:18:38 jhigh Exp $");
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
@ -218,7 +218,7 @@ static pgp_map_t pubkey_alg_map[] =
|
|||
{PGP_PKA_ELGAMAL, "Elgamal (Encrypt-Only)"},
|
||||
{PGP_PKA_DSA, "DSA"},
|
||||
{PGP_PKA_RESERVED_ELLIPTIC_CURVE, "Reserved for Elliptic Curve"},
|
||||
{PGP_PKA_RESERVED_ECDSA, "Reserved for ECDSA"},
|
||||
{PGP_PKA_ECDSA, "ECDSA"},
|
||||
{PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN, "Reserved (formerly Elgamal Encrypt or Sign"},
|
||||
{PGP_PKA_RESERVED_DH, "Reserved for Diffie-Hellman (X9.42)"},
|
||||
{PGP_PKA_PRIVATE00, "Private/Experimental"},
|
||||
|
|
|
@ -348,7 +348,7 @@ typedef enum {
|
|||
PGP_PKA_DSA = 17, /* DSA (Digital Signature Algorithm) */
|
||||
PGP_PKA_RESERVED_ELLIPTIC_CURVE = 18, /* Reserved for Elliptic
|
||||
* Curve */
|
||||
PGP_PKA_RESERVED_ECDSA = 19, /* Reserved for ECDSA */
|
||||
PGP_PKA_ECDSA = 19, /* ECDSA */
|
||||
PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN = 20, /* Deprecated. */
|
||||
PGP_PKA_RESERVED_DH = 21, /* Reserved for Diffie-Hellman
|
||||
* (X9.42, as defined for
|
||||
|
@ -378,6 +378,16 @@ typedef struct {
|
|||
* with x being the secret) */
|
||||
} pgp_dsa_pubkey_t;
|
||||
|
||||
/** Structure to hold one ECDSA public key params.
|
||||
*
|
||||
* \see RFC6637 9
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t len;
|
||||
uint8_t oid[8];
|
||||
BIGNUM *p;
|
||||
} pgp_ecdsa_pubkey_t;
|
||||
|
||||
/** Structure to hold an RSA public key.
|
||||
*
|
||||
* \see RFC4880 5.5.2
|
||||
|
@ -422,6 +432,7 @@ typedef struct {
|
|||
pgp_pubkey_alg_t alg; /* Public Key Algorithm type */
|
||||
union {
|
||||
pgp_dsa_pubkey_t dsa; /* A DSA public key */
|
||||
pgp_ecdsa_pubkey_t ecdsa; /* An ECDSA public key */
|
||||
pgp_rsa_pubkey_t rsa; /* An RSA public key */
|
||||
pgp_elgamal_pubkey_t elgamal; /* An ElGamal public key */
|
||||
} key; /* Public Key Parameters */
|
||||
|
@ -441,6 +452,11 @@ typedef struct {
|
|||
BIGNUM *x;
|
||||
} pgp_dsa_seckey_t;
|
||||
|
||||
/** pgp_ecdsa_seckey_t */
|
||||
typedef struct {
|
||||
BIGNUM *x;
|
||||
} pgp_ecdsa_seckey_t;
|
||||
|
||||
/** pgp_elgamal_seckey_t */
|
||||
typedef struct {
|
||||
BIGNUM *x;
|
||||
|
@ -542,6 +558,7 @@ typedef struct pgp_seckey_t {
|
|||
union {
|
||||
pgp_rsa_seckey_t rsa;
|
||||
pgp_dsa_seckey_t dsa;
|
||||
pgp_ecdsa_seckey_t ecdsa;
|
||||
pgp_elgamal_seckey_t elgamal;
|
||||
} key;
|
||||
unsigned checksum;
|
||||
|
@ -599,6 +616,12 @@ typedef struct pgp_dsa_sig_t {
|
|||
BIGNUM *s; /* DSA value s */
|
||||
} pgp_dsa_sig_t;
|
||||
|
||||
/** Struct to hold params of an ECDSA signature */
|
||||
typedef struct pgp_ecdsa_sig_t {
|
||||
BIGNUM *r; /* ECDSA value r */
|
||||
BIGNUM *s; /* ECDSA value s */
|
||||
} pgp_ecdsa_sig_t;
|
||||
|
||||
/** pgp_elgamal_signature_t */
|
||||
typedef struct pgp_elgamal_sig_t {
|
||||
BIGNUM *r;
|
||||
|
@ -625,6 +648,7 @@ typedef struct pgp_sig_info_t {
|
|||
union {
|
||||
pgp_rsa_sig_t rsa; /* An RSA Signature */
|
||||
pgp_dsa_sig_t dsa; /* A DSA Signature */
|
||||
pgp_ecdsa_sig_t ecdsa; /* An ECDSA Signature */
|
||||
pgp_elgamal_sig_t elgamal; /* deprecated */
|
||||
pgp_data_t unknown; /* private or experimental */
|
||||
} sig; /* signature params */
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
|
||||
#if defined(__NetBSD__)
|
||||
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
|
||||
__RCSID("$NetBSD: signature.c,v 1.38 2018/02/05 23:56:01 christos Exp $");
|
||||
__RCSID("$NetBSD: signature.c,v 1.39 2022/08/26 19:18:38 jhigh Exp $");
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
@ -265,6 +265,56 @@ dsa_sign(pgp_hash_t *hash,
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
ecdsa_sign(pgp_hash_t *hash,
|
||||
const pgp_ecdsa_pubkey_t *ecdsa,
|
||||
const pgp_ecdsa_seckey_t *secdsa,
|
||||
pgp_output_t *output)
|
||||
{
|
||||
unsigned hashsize;
|
||||
unsigned t;
|
||||
uint8_t hashbuf[NETPGP_BUFSIZ];
|
||||
ECDSA_SIG *ecdsasig;
|
||||
const BIGNUM *r, *s;
|
||||
|
||||
hashsize = ecdsa_hashsize(ecdsa);
|
||||
|
||||
if (hashsize == -1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
t = hash->finish(hash, &hashbuf[0]);
|
||||
|
||||
if (t != hashsize) {
|
||||
(void) fprintf(stderr, "ecdsa_sign: hashfinish %d not %d\n", t, hashsize);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pgp_write(output, &hashbuf[0], 2);
|
||||
|
||||
/* write signature to buf */
|
||||
ecdsasig = pgp_ecdsa_sign(hashbuf, hashsize, secdsa, ecdsa);
|
||||
|
||||
if (ecdsasig == NULL) {
|
||||
(void) fprintf(stderr, "ecdsa_sign: invalid ecdsa sig\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* convert and write the sig out to memory */
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000
|
||||
ECDSA_SIG_get0(ecdsasig, &r, &s);
|
||||
#else
|
||||
r = ecdsasig->r;
|
||||
s = ecdsasig->s;
|
||||
#endif
|
||||
pgp_write_mpi(output, r);
|
||||
pgp_write_mpi(output, s);
|
||||
|
||||
ECDSA_SIG_free(ecdsasig);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static unsigned
|
||||
rsa_verify(pgp_hash_alg_t type,
|
||||
const uint8_t *hash,
|
||||
|
@ -430,6 +480,12 @@ pgp_check_sig(const uint8_t *hash, unsigned length,
|
|||
&signer->key.dsa);
|
||||
break;
|
||||
|
||||
case PGP_PKA_ECDSA:
|
||||
ret = pgp_ecdsa_verify(hash, length,
|
||||
&sig->info.sig.ecdsa,
|
||||
&signer->key.ecdsa);
|
||||
break;
|
||||
|
||||
case PGP_PKA_RSA:
|
||||
ret = rsa_verify(sig->info.hash_alg, hash, length,
|
||||
&sig->info.sig.rsa,
|
||||
|
@ -764,6 +820,14 @@ pgp_write_sig(pgp_output_t *output,
|
|||
}
|
||||
break;
|
||||
|
||||
case PGP_PKA_ECDSA:
|
||||
if (seckey->key.ecdsa.x == NULL) {
|
||||
(void) fprintf(stderr, "pgp_write_sig: null ecdsa.x\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
(void) fprintf(stderr, "Unsupported algorithm %d\n",
|
||||
seckey->pubkey.alg);
|
||||
|
@ -817,6 +881,15 @@ pgp_write_sig(pgp_output_t *output,
|
|||
}
|
||||
break;
|
||||
|
||||
case PGP_PKA_ECDSA:
|
||||
if (!ecdsa_sign(&sig->hash, &key->key.ecdsa, &seckey->key.ecdsa,
|
||||
sig->output)) {
|
||||
(void) fprintf(stderr,
|
||||
"pgp_write_sig: ecdsa_sign failure\n");
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
(void) fprintf(stderr, "Unsupported algorithm %d\n",
|
||||
seckey->pubkey.alg);
|
||||
|
@ -972,7 +1045,14 @@ pgp_sign_file(pgp_io_t *io,
|
|||
fd_out = 0;
|
||||
|
||||
/* find the hash algorithm */
|
||||
hash_alg = pgp_str_to_hash_alg(hashname);
|
||||
switch (seckey->pubkey.alg) {
|
||||
case PGP_PKA_ECDSA:
|
||||
hash_alg = ecdsa_hashalg(&seckey->pubkey.key.ecdsa);
|
||||
break;
|
||||
default:
|
||||
hash_alg = pgp_str_to_hash_alg(hashname);
|
||||
}
|
||||
|
||||
if (hash_alg == PGP_HASH_UNKNOWN) {
|
||||
(void) fprintf(io->errs,
|
||||
"pgp_sign_file: unknown hash algorithm: \"%s\"\n",
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
#endif
|
||||
|
||||
/* development versions have .99 suffix */
|
||||
#define NETPGP_BASE_VERSION "3.99.17"
|
||||
#define NETPGP_BASE_VERSION "3.99.18"
|
||||
|
||||
#define NETPGP_VERSION_CAT(a, b) "NetPGP portable " a "/[" b "]"
|
||||
#define NETPGP_VERSION_STRING \
|
||||
|
|
Loading…
Reference in New Issue