Not all of them, but the ones that don't get a 'void *key' parameter.
This means I can share methods between multiple ssh_signkey
structures, and still give those methods an easy way to find out which
public key method they're dealing with, by loading parameters from a
larger structure in which the ssh_signkey is the first element.
(In OO terms, I'm arranging that all static methods of my public key
classes get a pointer to the class vtable, to make up for not having a
pointer to the class instance.)
I haven't actually done anything with the new facility in this commit,
but it will shortly allow me to clean up the constant lookups by curve
name in the ECDSA code.
if (ssh2blob) {
ssh2algf = find_pubkey_alg(ssh2alg);
if (ssh2algf)
- bits = ssh2algf->pubkey_bits(ssh2blob, ssh2bloblen);
+ bits = ssh2algf->pubkey_bits(ssh2algf,
+ ssh2blob, ssh2bloblen);
else
bits = -1;
}
memcpy(blob+4+19+4+8+4, p, len);
PUT_32BIT(blob+4+19+4+8+4+len, privlen);
memcpy(blob+4+19+4+8+4+len+4, priv, privlen);
- retkey->data = retkey->alg->createkey(blob, 4+19+4+8+4+len,
+ retkey->data = retkey->alg->createkey(retkey->alg,
+ blob, 4+19+4+8+4+len,
blob+4+19+4+8+4+len,
4+privlen);
if (!retkey->data) {
assert(privptr > 0); /* should have bombed by now if not */
retkey = snew(struct ssh2_userkey);
retkey->alg = (key->keytype == OP_RSA ? &ssh_rsa : &ssh_dss);
- retkey->data = retkey->alg->createkey(blob, privptr,
+ retkey->data = retkey->alg->createkey(retkey->alg, blob, privptr,
blob+privptr,
blobptr-privptr);
if (!retkey->data) {
if (key_index == key->key_wanted) {
retkey = snew(struct ssh2_userkey);
retkey->alg = alg;
- retkey->data = alg->openssh_createkey(&thiskey, &thiskeylen);
+ retkey->data = alg->openssh_createkey(alg, &thiskey, &thiskeylen);
if (!retkey->data) {
sfree(retkey);
errmsg = "unable to create key data structure";
retkey = snew(struct ssh2_userkey);
retkey->alg = alg;
- retkey->data = alg->createkey(blob, publen, blob+publen, privlen);
+ retkey->data = alg->createkey(alg, blob, publen, blob+publen, privlen);
if (!retkey->data) {
sfree(retkey);
errmsg = "unable to create key data structure";
}
bloblen = msgend - p;
- key->data = key->alg->openssh_createkey(&p, &bloblen);
+ key->data = key->alg->openssh_createkey(key->alg, &p, &bloblen);
if (!key->data) {
sfree(key);
fail_reason = "key setup failed";
}
set_busy_status(ssh->frontend, BUSY_CPU); /* cogitate */
ssh_pkt_getstring(pktin, &s->hostkeydata, &s->hostkeylen);
- s->hkey = ssh->hostkey->newkey(s->hostkeydata, s->hostkeylen);
+ s->hkey = ssh->hostkey->newkey(ssh->hostkey,
+ s->hostkeydata, s->hostkeylen);
s->f = ssh2_pkt_getmp(pktin);
if (!s->f) {
bombout(("unable to parse key exchange reply packet"));
ssh_pkt_getstring(pktin, &s->hostkeydata, &s->hostkeylen);
hash_string(ssh->kex->hash, ssh->exhash, s->hostkeydata, s->hostkeylen);
- s->hkey = ssh->hostkey->newkey(s->hostkeydata, s->hostkeylen);
+ s->hkey = ssh->hostkey->newkey(ssh->hostkey,
+ s->hostkeydata, s->hostkeylen);
{
char *publicPoint;
ssh_pkt_getstring(pktin, &s->hostkeydata, &s->hostkeylen);
hash_string(ssh->kex->hash, ssh->exhash,
s->hostkeydata, s->hostkeylen);
- s->hkey = ssh->hostkey->newkey(s->hostkeydata, s->hostkeylen);
+ s->hkey = ssh->hostkey->newkey(ssh->hostkey,
+ s->hostkeydata, s->hostkeylen);
{
char *keydata;
};
struct ssh_signkey {
- void *(*newkey) (const char *data, int len);
+ void *(*newkey) (const struct ssh_signkey *self,
+ const char *data, int len);
void (*freekey) (void *key);
char *(*fmtkey) (void *key);
unsigned char *(*public_blob) (void *key, int *len);
unsigned char *(*private_blob) (void *key, int *len);
- void *(*createkey) (const unsigned char *pub_blob, int pub_len,
+ void *(*createkey) (const struct ssh_signkey *self,
+ const unsigned char *pub_blob, int pub_len,
const unsigned char *priv_blob, int priv_len);
- void *(*openssh_createkey) (const unsigned char **blob, int *len);
+ void *(*openssh_createkey) (const struct ssh_signkey *self,
+ const unsigned char **blob, int *len);
int (*openssh_fmtkey) (void *key, unsigned char *blob, int len);
/* OpenSSH private key blobs, as created by openssh_fmtkey and
* consumed by openssh_createkey, always (at least so far...) take
* skip over the right number to find the next key in the file.
* openssh_private_npieces gives that information. */
int openssh_private_npieces;
- int (*pubkey_bits) (const void *blob, int len);
+ int (*pubkey_bits) (const struct ssh_signkey *self,
+ const void *blob, int len);
int (*verifysig) (void *key, const char *sig, int siglen,
const char *data, int datalen);
unsigned char *(*sign) (void *key, const char *data, int datalen,
static void dss_freekey(void *key); /* forward reference */
-static void *dss_newkey(const char *data, int len)
+static void *dss_newkey(const struct ssh_signkey *self,
+ const char *data, int len)
{
const char *p;
int slen;
return blob;
}
-static void *dss_createkey(const unsigned char *pub_blob, int pub_len,
+static void *dss_createkey(const struct ssh_signkey *self,
+ const unsigned char *pub_blob, int pub_len,
const unsigned char *priv_blob, int priv_len)
{
struct dss_key *dss;
unsigned char digest[20];
Bignum ytest;
- dss = dss_newkey((char *) pub_blob, pub_len);
+ dss = dss_newkey(self, (char *) pub_blob, pub_len);
if (!dss)
return NULL;
dss->x = getmp(&pb, &priv_len);
return dss;
}
-static void *dss_openssh_createkey(const unsigned char **blob, int *len)
+static void *dss_openssh_createkey(const struct ssh_signkey *self,
+ const unsigned char **blob, int *len)
{
const char **b = (const char **) blob;
struct dss_key *dss;
return bloblen;
}
-static int dss_pubkey_bits(const void *blob, int len)
+static int dss_pubkey_bits(const struct ssh_signkey *self,
+ const void *blob, int len)
{
struct dss_key *dss;
int ret;
- dss = dss_newkey((const char *) blob, len);
+ dss = dss_newkey(self, (const char *) blob, len);
if (!dss)
return -1;
ret = bignum_bitcount(dss->p);
sfree(ec);
}
-static void *ecdsa_newkey(const char *data, int len)
+static void *ecdsa_newkey(const struct ssh_signkey *self,
+ const char *data, int len)
{
const char *p;
int slen;
return blob;
}
-static void *ecdsa_createkey(const unsigned char *pub_blob, int pub_len,
+static void *ecdsa_createkey(const struct ssh_signkey *self,
+ const unsigned char *pub_blob, int pub_len,
const unsigned char *priv_blob, int priv_len)
{
struct ec_key *ec;
struct ec_point *publicKey;
const char *pb = (const char *) priv_blob;
- ec = (struct ec_key*)ecdsa_newkey((const char *) pub_blob, pub_len);
+ ec = (struct ec_key*)ecdsa_newkey(self, (const char *) pub_blob, pub_len);
if (!ec) {
return NULL;
}
return ec;
}
-static void *ed25519_openssh_createkey(const unsigned char **blob, int *len)
+static void *ed25519_openssh_createkey(const struct ssh_signkey *self,
+ const unsigned char **blob, int *len)
{
struct ec_key *ec;
struct ec_point *publicKey;
return bloblen;
}
-static void *ecdsa_openssh_createkey(const unsigned char **blob, int *len)
+static void *ecdsa_openssh_createkey(const struct ssh_signkey *self,
+ const unsigned char **blob, int *len)
{
const char **b = (const char **) blob;
const char *p;
return bloblen;
}
-static int ecdsa_pubkey_bits(const void *blob, int len)
+static int ecdsa_pubkey_bits(const struct ssh_signkey *self,
+ const void *blob, int len)
{
struct ec_key *ec;
int ret;
- ec = (struct ec_key*)ecdsa_newkey((const char *) blob, len);
+ ec = (struct ec_key*)ecdsa_newkey(self, (const char *) blob, len);
if (!ec)
return -1;
ret = ec->publicKey.curve->fieldBits;
ret = snew(struct ssh2_userkey);
ret->alg = alg;
ret->comment = comment;
- ret->data = alg->createkey(public_blob, public_blob_len,
+ ret->data = alg->createkey(alg, public_blob, public_blob_len,
private_blob, private_blob_len);
if (!ret->data) {
sfree(ret);
*/
alg = find_pubkey_alg_len(alglen, algstr);
if (alg) {
- int bits = alg->pubkey_bits(blob, bloblen);
+ int bits = alg->pubkey_bits(alg, blob, bloblen);
return dupprintf("%.*s %d %s", alglen, algstr,
bits, fingerprint_str);
} else {
static void rsa2_freekey(void *key); /* forward reference */
-static void *rsa2_newkey(const char *data, int len)
+static void *rsa2_newkey(const struct ssh_signkey *self,
+ const char *data, int len)
{
const char *p;
int slen;
return blob;
}
-static void *rsa2_createkey(const unsigned char *pub_blob, int pub_len,
+static void *rsa2_createkey(const struct ssh_signkey *self,
+ const unsigned char *pub_blob, int pub_len,
const unsigned char *priv_blob, int priv_len)
{
struct RSAKey *rsa;
const char *pb = (const char *) priv_blob;
- rsa = rsa2_newkey((char *) pub_blob, pub_len);
+ rsa = rsa2_newkey(self, (char *) pub_blob, pub_len);
rsa->private_exponent = getmp(&pb, &priv_len);
rsa->p = getmp(&pb, &priv_len);
rsa->q = getmp(&pb, &priv_len);
return rsa;
}
-static void *rsa2_openssh_createkey(const unsigned char **blob, int *len)
+static void *rsa2_openssh_createkey(const struct ssh_signkey *self,
+ const unsigned char **blob, int *len)
{
const char **b = (const char **) blob;
struct RSAKey *rsa;
return bloblen;
}
-static int rsa2_pubkey_bits(const void *blob, int len)
+static int rsa2_pubkey_bits(const struct ssh_signkey *self,
+ const void *blob, int len)
{
struct RSAKey *rsa;
int ret;
- rsa = rsa2_newkey((const char *) blob, len);
+ rsa = rsa2_newkey(self, (const char *) blob, len);
ret = bignum_bitcount(rsa->modulus);
rsa2_freekey(rsa);
void *ssh_rsakex_newkey(char *data, int len)
{
- return rsa2_newkey(data, len);
+ return rsa2_newkey(&ssh_rsa, data, len);
}
void ssh_rsakex_freekey(void *key)