nisse@lysator.liu.se (Niels Möller) writes:
nisse@lysator.liu.se (Niels Möller) writes:
Nikos Mavrogiannopoulos nmav@gnutls.org writes:
In the master branch you break the ABI anyway, so it may be a good time to introduce that. Otherwise you may simply introduce new functions for the new structures and leave the old API intact.
I think I can do that *almost* without breaking source-level compatibility. API draft:
New structs:
struct dsa_params { /* Modulo */ mpz_t p;
/* Group order */ mpz_t q; /* Generator */ mpz_t g;
};
struct dsa_value { const struct dsa_params *params; /* For private keys, represents an exponent (0 < x < q). For public keys, represents a group element, 0 < x < p) */ mpz_t x; };
I have now implemented this and pushed it to the dsa-reorg branch in the repo. Comments appreciated.
It remains to convert the function that convert dsa keys to and from strings using sexp or asn.1 der formatting.
I've converted thse to the new api now (with no backwards compatibility). Looking at http://www.lysator.liu.se/~nisse/nettle/plan.html, the DSA interface is one of the last API changes I'd like to complete before the release.
The current code (on the dsa-reorg branch) uses a struct dsa_params to represent the group parameters p, q, and g. And a struct dsa_value which holds a pointer to the parameters (a bit like the ecc functions) and a single number, which can represent either a group element or an exponent, depending on the context.
This makes it a bit unwieldy to read a key pair, since one needs to initialize three different structs, for parameters, public key, and private key. I think the old interface which puts the parameters and the public key in the same struct is a bit easier in some common usecases.
Typical code, from pkcs1-conv.c
static int convert_dsa_private_key(struct nettle_buffer *buffer, size_t length, const uint8_t *data) { struct dsa_params params; struct dsa_value pub; struct dsa_value priv; int res;
dsa_params_init (¶ms); dsa_value_init (&pub, ¶ms); dsa_value_init (&priv, ¶ms);
if (dsa_openssl_private_key_from_der(¶ms, &pub, &priv, 0, length, data)) { /* Reuses the buffer */ nettle_buffer_reset(buffer); res = dsa_keypair_to_sexp(buffer, NULL, &pub, &priv); } else { werror("Invalid OpenSSL private key.\n"); res = 0; } dsa_value_clear (&pub); dsa_value_clear (&priv); dsa_params_clear (¶ms); return res; }
What do you think?
Is it possible to somehow provide a "all-in-one" interface for both parameters and a public or private key, and have a separate parameter struct (for the benefit of diffie-hellman use, or for keys using some fixed predefined group), without lots of duplication?
It differs a bit from the ecc case, in that a common case is that the dsa parameters are defined more or less dynamically at runtime, while ecc curves are compile time constants.
One possibility might be to have all dsa functions take the dsa group parameters and the actual key as separate function arguments. Then the application is free to choose if it wants an all-in-one key struct like
struct dsa_public_key { struct dsa_params params; mpz_t y; };
or something like the above dsa_value, or keep the params separately in some other way. It would call the same nettle functions in either case. Ant struct combining key and parameters would always be taken apart when calling nettle functions; it would not appear in any nettle function prototypes. At the moment, I think that is an attractive alternative.
A somewhat related question is that of backwards compatibility. The current code maintains struct dsa_public_key and struct dsa_private_key unchanged, and the sign and verify functions that use these types, for some source level compatibility with existing code. Is that important or not?
And to add tests using the new interface.
This still remains. In particular, the new key generation function.
Regards, /Niels