1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-10 01:48:00 +00:00

Clean up the crufty old SSH-1 RSA API.

Lots of functions had really generic names (like 'makekey'), or names
that missed out an important concept (like 'rsakey_pubblob', which
loads a public blob from a _file_ and doesn't generate it from an
in-memory representation at all). Also, the opaque 'int order' that
distinguishes the two formats of public key blob is now a mnemonic
enumeration, and while I'm at it, rsa_ssh1_public_blob takes one of
those as an extra argument.
This commit is contained in:
Simon Tatham 2018-05-24 08:22:44 +01:00
parent 1a02274272
commit 7e8ae41a3f
8 changed files with 109 additions and 89 deletions

View File

@ -769,7 +769,7 @@ int main(int argc, char **argv)
* Find out whether the input key is encrypted. * Find out whether the input key is encrypted.
*/ */
if (intype == SSH_KEYTYPE_SSH1) if (intype == SSH_KEYTYPE_SSH1)
encrypted = rsakey_encrypted(infilename, &origcomment); encrypted = rsa_ssh1_encrypted(infilename, &origcomment);
else if (intype == SSH_KEYTYPE_SSH2) else if (intype == SSH_KEYTYPE_SSH2)
encrypted = ssh2_userkey_encrypted(infilename, &origcomment); encrypted = ssh2_userkey_encrypted(infilename, &origcomment);
else else
@ -811,7 +811,7 @@ int main(int argc, char **argv)
unsigned char *blob; unsigned char *blob;
int n, l, bloblen; int n, l, bloblen;
ret = rsakey_pubblob(infilename, &vblob, &bloblen, ret = rsa_ssh1_loadpub(infilename, &vblob, &bloblen,
&origcomment, &error); &origcomment, &error);
blob = (unsigned char *)vblob; blob = (unsigned char *)vblob;
@ -836,7 +836,8 @@ int main(int argc, char **argv)
ssh1key->q = NULL; ssh1key->q = NULL;
ssh1key->iqmp = NULL; ssh1key->iqmp = NULL;
} else { } else {
ret = loadrsakey(infilename, ssh1key, old_passphrase, &error); ret = rsa_ssh1_loadkey(
infilename, ssh1key, old_passphrase, &error);
} }
if (ret > 0) if (ret > 0)
error = NULL; error = NULL;
@ -972,7 +973,7 @@ int main(int argc, char **argv)
case PRIVATE: case PRIVATE:
if (sshver == 1) { if (sshver == 1) {
assert(ssh1key); assert(ssh1key);
ret = saversakey(outfilename, ssh1key, new_passphrase); ret = rsa_ssh1_savekey(outfilename, ssh1key, new_passphrase);
if (!ret) { if (!ret) {
fprintf(stderr, "puttygen: unable to save SSH-1 private key\n"); fprintf(stderr, "puttygen: unable to save SSH-1 private key\n");
return 1; return 1;

View File

@ -11,8 +11,8 @@
#include "pageant.h" #include "pageant.h"
/* /*
* We need this to link with the RSA code, because rsaencrypt() * We need this to link with the RSA code, because rsa_ssh1_encrypt()
* pads its data with random bytes. Since we only use rsadecrypt() * pads its data with random bytes. Since we only use rsa_ssh1_decrypt()
* and the signing functions, which are deterministic, this should * and the signing functions, which are deterministic, this should
* never be called. * never be called.
* *
@ -182,7 +182,7 @@ void *pageant_make_keylist1(int *length)
nkeys = 0; nkeys = 0;
for (i = 0; NULL != (key = index234(rsakeys, i)); i++) { for (i = 0; NULL != (key = index234(rsakeys, i)); i++) {
nkeys++; nkeys++;
blob = rsa_public_blob(key, &bloblen); blob = rsa_ssh1_public_blob(key, &bloblen, RSA_SSH1_EXPONENT_FIRST);
len += bloblen; len += bloblen;
sfree(blob); sfree(blob);
len += 4 + strlen(key->comment); len += 4 + strlen(key->comment);
@ -195,7 +195,7 @@ void *pageant_make_keylist1(int *length)
PUT_32BIT(p, nkeys); PUT_32BIT(p, nkeys);
p += 4; p += 4;
for (i = 0; NULL != (key = index234(rsakeys, i)); i++) { for (i = 0; NULL != (key = index234(rsakeys, i)); i++) {
blob = rsa_public_blob(key, &bloblen); blob = rsa_ssh1_public_blob(key, &bloblen, RSA_SSH1_EXPONENT_FIRST);
memcpy(p, blob, bloblen); memcpy(p, blob, bloblen);
p += bloblen; p += bloblen;
sfree(blob); sfree(blob);
@ -447,7 +447,7 @@ void *pageant_handle_msg(const void *msg, int msglen, int *outlen,
fail_reason = "key not found"; fail_reason = "key not found";
goto failure; goto failure;
} }
response = rsadecrypt(challenge, key); response = rsa_ssh1_decrypt(challenge, key);
for (i = 0; i < 32; i++) for (i = 0; i < 32; i++)
response_source[i] = bignum_byte(response, 31 - i); response_source[i] = bignum_byte(response, 31 - i);
@ -547,7 +547,8 @@ void *pageant_handle_msg(const void *msg, int msglen, int *outlen,
key = snew(struct RSAKey); key = snew(struct RSAKey);
memset(key, 0, sizeof(struct RSAKey)); memset(key, 0, sizeof(struct RSAKey));
n = makekey(p, msgend - p, key, NULL, 1); n = rsa_ssh1_readpub(p, msgend - p, key, NULL,
RSA_SSH1_MODULUS_FIRST);
if (n < 0) { if (n < 0) {
freersakey(key); freersakey(key);
sfree(key); sfree(key);
@ -556,7 +557,7 @@ void *pageant_handle_msg(const void *msg, int msglen, int *outlen,
} }
p += n; p += n;
n = makeprivate(p, msgend - p, key); n = rsa_ssh1_readpriv(p, msgend - p, key);
if (n < 0) { if (n < 0) {
freersakey(key); freersakey(key);
sfree(key); sfree(key);
@ -745,7 +746,8 @@ void *pageant_handle_msg(const void *msg, int msglen, int *outlen,
plog(logctx, logfn, "request: SSH1_AGENTC_REMOVE_RSA_IDENTITY"); plog(logctx, logfn, "request: SSH1_AGENTC_REMOVE_RSA_IDENTITY");
n = makekey(p, msgend - p, &reqkey, NULL, 0); n = rsa_ssh1_readpub(p, msgend - p, &reqkey, NULL,
RSA_SSH1_EXPONENT_FIRST);
if (n < 0) { if (n < 0) {
fail_reason = "request truncated before public key"; fail_reason = "request truncated before public key";
goto failure; goto failure;
@ -1286,7 +1288,7 @@ int pageant_add_keyfile(Filename *filename, const char *passphrase,
int i, nkeys, bloblen, keylistlen; int i, nkeys, bloblen, keylistlen;
if (type == SSH_KEYTYPE_SSH1) { if (type == SSH_KEYTYPE_SSH1) {
if (!rsakey_pubblob(filename, &blob, &bloblen, NULL, &error)) { if (!rsa_ssh1_loadpub(filename, &blob, &bloblen, NULL, &error)) {
*retstr = dupprintf("Couldn't load private key (%s)", error); *retstr = dupprintf("Couldn't load private key (%s)", error);
return PAGEANT_ACTION_FAILURE; return PAGEANT_ACTION_FAILURE;
} }
@ -1396,7 +1398,7 @@ int pageant_add_keyfile(Filename *filename, const char *passphrase,
error = NULL; error = NULL;
if (type == SSH_KEYTYPE_SSH1) if (type == SSH_KEYTYPE_SSH1)
needs_pass = rsakey_encrypted(filename, &comment); needs_pass = rsa_ssh1_encrypted(filename, &comment);
else else
needs_pass = ssh2_userkey_encrypted(filename, &comment); needs_pass = ssh2_userkey_encrypted(filename, &comment);
attempts = 0; attempts = 0;
@ -1434,7 +1436,7 @@ int pageant_add_keyfile(Filename *filename, const char *passphrase,
this_passphrase = ""; this_passphrase = "";
if (type == SSH_KEYTYPE_SSH1) if (type == SSH_KEYTYPE_SSH1)
ret = loadrsakey(filename, rkey, this_passphrase, &error); ret = rsa_ssh1_loadkey(filename, rkey, this_passphrase, &error);
else { else {
skey = ssh2_load_userkey(filename, this_passphrase, &error); skey = ssh2_load_userkey(filename, this_passphrase, &error);
if (skey == SSH2_WRONG_PASSPHRASE) if (skey == SSH2_WRONG_PASSPHRASE)
@ -1629,7 +1631,8 @@ int pageant_enum_keys(pageant_key_enum_fn_t callback, void *callback_ctx,
/* public blob and fingerprint */ /* public blob and fingerprint */
memset(&rkey, 0, sizeof(rkey)); memset(&rkey, 0, sizeof(rkey));
n = makekey(p, keylistlen, &rkey, NULL, 0); n = rsa_ssh1_readpub(p, keylistlen, &rkey, NULL,
RSA_SSH1_EXPONENT_FIRST);
if (n < 0 || n > keylistlen) { if (n < 0 || n > keylistlen) {
freersakey(&rkey); freersakey(&rkey);
*retstr = dupstr("Received broken SSH-1 key list from agent"); *retstr = dupstr("Received broken SSH-1 key list from agent");
@ -1657,7 +1660,8 @@ int pageant_enum_keys(pageant_key_enum_fn_t callback, void *callback_ctx,
comment = dupprintf("%.*s", (int)n, (const char *)p); comment = dupprintf("%.*s", (int)n, (const char *)p);
p += n, keylistlen -= n; p += n, keylistlen -= n;
cbkey.blob = rsa_public_blob(&rkey, &cbkey.bloblen); cbkey.blob = rsa_ssh1_public_blob(&rkey, &cbkey.bloblen,
RSA_SSH1_EXPONENT_FIRST);
cbkey.comment = comment; cbkey.comment = comment;
cbkey.ssh_version = 1; cbkey.ssh_version = 1;
callback(callback_ctx, fingerprint, comment, &cbkey); callback(callback_ctx, fingerprint, comment, &cbkey);

25
ssh.c
View File

@ -2871,9 +2871,9 @@ static int ssh1_pkt_getrsakey(struct Packet *pkt, struct RSAKey *key,
{ {
int j; int j;
j = makekey(pkt->body + pkt->savedpos, j = rsa_ssh1_readpub(pkt->body + pkt->savedpos,
pkt->length - pkt->savedpos, pkt->length - pkt->savedpos,
key, keystr, 0); key, keystr, RSA_SSH1_EXPONENT_FIRST);
if (j < 0) if (j < 0)
return FALSE; return FALSE;
@ -4424,13 +4424,13 @@ static void do_ssh1_login(void *vctx)
} }
if (s->hostkey.bytes > s->servkey.bytes) { if (s->hostkey.bytes > s->servkey.bytes) {
ret = rsaencrypt(s->rsabuf, 32, &s->servkey); ret = rsa_ssh1_encrypt(s->rsabuf, 32, &s->servkey);
if (ret) if (ret)
ret = rsaencrypt(s->rsabuf, s->servkey.bytes, &s->hostkey); ret = rsa_ssh1_encrypt(s->rsabuf, s->servkey.bytes, &s->hostkey);
} else { } else {
ret = rsaencrypt(s->rsabuf, 32, &s->hostkey); ret = rsa_ssh1_encrypt(s->rsabuf, 32, &s->hostkey);
if (ret) if (ret)
ret = rsaencrypt(s->rsabuf, s->hostkey.bytes, &s->servkey); ret = rsa_ssh1_encrypt(s->rsabuf, s->hostkey.bytes, &s->servkey);
} }
if (!ret) { if (!ret) {
bombout(("SSH-1 public key encryptions failed due to bad formatting")); bombout(("SSH-1 public key encryptions failed due to bad formatting"));
@ -4617,14 +4617,13 @@ static void do_ssh1_login(void *vctx)
if (keytype == SSH_KEYTYPE_SSH1 || if (keytype == SSH_KEYTYPE_SSH1 ||
keytype == SSH_KEYTYPE_SSH1_PUBLIC) { keytype == SSH_KEYTYPE_SSH1_PUBLIC) {
const char *error; const char *error;
if (rsakey_pubblob(s->keyfile, if (rsa_ssh1_loadpub(s->keyfile,
&s->publickey_blob, &s->publickey_bloblen, &s->publickey_blob, &s->publickey_bloblen,
&s->publickey_comment, &error)) { &s->publickey_comment, &error)) {
s->privatekey_available = (keytype == SSH_KEYTYPE_SSH1); s->privatekey_available = (keytype == SSH_KEYTYPE_SSH1);
if (!s->privatekey_available) if (!s->privatekey_available)
logeventf(ssh, "Key file contains public key only"); logeventf(ssh, "Key file contains public key only");
s->privatekey_encrypted = rsakey_encrypted(s->keyfile, s->privatekey_encrypted = rsa_ssh1_encrypted(s->keyfile, NULL);
NULL);
} else { } else {
char *msgbuf; char *msgbuf;
logeventf(ssh, "Unable to load key (%s)", error); logeventf(ssh, "Unable to load key (%s)", error);
@ -4888,8 +4887,8 @@ static void do_ssh1_login(void *vctx)
* Try decrypting key with passphrase. * Try decrypting key with passphrase.
*/ */
s->keyfile = conf_get_filename(ssh->conf, CONF_keyfile); s->keyfile = conf_get_filename(ssh->conf, CONF_keyfile);
ret = loadrsakey(s->keyfile, &s->key, passphrase, ret = rsa_ssh1_loadkey(
&error); s->keyfile, &s->key, passphrase, &error);
if (passphrase) { if (passphrase) {
smemclr(passphrase, strlen(passphrase)); smemclr(passphrase, strlen(passphrase));
sfree(passphrase); sfree(passphrase);
@ -4910,7 +4909,7 @@ static void do_ssh1_login(void *vctx)
got_passphrase = FALSE; got_passphrase = FALSE;
/* and try again */ /* and try again */
} else { } else {
assert(0 && "unexpected return from loadrsakey()"); assert(0 && "unexpected return from rsa_ssh1_loadkey()");
got_passphrase = FALSE; /* placate optimisers */ got_passphrase = FALSE; /* placate optimisers */
} }
} }
@ -4943,7 +4942,7 @@ static void do_ssh1_login(void *vctx)
bombout(("Server's RSA challenge was badly formatted")); bombout(("Server's RSA challenge was badly formatted"));
crStopV; crStopV;
} }
response = rsadecrypt(challenge, &s->key); response = rsa_ssh1_decrypt(challenge, &s->key);
freebn(s->key.private_exponent);/* burn the evidence */ freebn(s->key.private_exponent);/* burn the evidence */
for (i = 0; i < 32; i++) { for (i = 0; i < 32; i++) {

37
ssh.h
View File

@ -173,18 +173,29 @@ struct ec_key {
struct ec_point *ec_public(const Bignum privateKey, const struct ec_curve *curve); struct ec_point *ec_public(const Bignum privateKey, const struct ec_curve *curve);
int makekey(const unsigned char *data, int len, struct RSAKey *result, /*
const unsigned char **keystr, int order); * SSH-1 never quite decided which order to store the two components
int makeprivate(const unsigned char *data, int len, struct RSAKey *result); * of an RSA key. During connection setup, the server sends its host
int rsaencrypt(unsigned char *data, int length, struct RSAKey *key); * and server keys with the exponent first; private key files store
Bignum rsadecrypt(Bignum input, struct RSAKey *key); * the modulus first. The agent protocol is even more confusing,
void rsasign(unsigned char *data, int length, struct RSAKey *key); * because the client specifies a key to the server in one order and
* the server lists the keys it knows about in the other order!
*/
typedef enum { RSA_SSH1_EXPONENT_FIRST, RSA_SSH1_MODULUS_FIRST } RsaSsh1Order;
int rsa_ssh1_readpub(const unsigned char *data, int len, struct RSAKey *result,
const unsigned char **keystr, RsaSsh1Order order);
int rsa_ssh1_readpriv(const unsigned char *data, int len,
struct RSAKey *result);
int rsa_ssh1_encrypt(unsigned char *data, int length, struct RSAKey *key);
Bignum rsa_ssh1_decrypt(Bignum input, struct RSAKey *key);
void rsasanitise(struct RSAKey *key); void rsasanitise(struct RSAKey *key);
int rsastr_len(struct RSAKey *key); int rsastr_len(struct RSAKey *key);
void rsastr_fmt(char *str, struct RSAKey *key); void rsastr_fmt(char *str, struct RSAKey *key);
void rsa_fingerprint(char *str, int len, struct RSAKey *key); void rsa_fingerprint(char *str, int len, struct RSAKey *key);
int rsa_verify(struct RSAKey *key); int rsa_verify(struct RSAKey *key);
unsigned char *rsa_public_blob(struct RSAKey *key, int *len); unsigned char *rsa_ssh1_public_blob(struct RSAKey *key, int *len,
RsaSsh1Order order);
int rsa_public_blob_len(void *data, int maxlen); int rsa_public_blob_len(void *data, int maxlen);
void freersakey(struct RSAKey *key); void freersakey(struct RSAKey *key);
@ -711,13 +722,13 @@ Bignum dh_create_e(void *, int nbits);
const char *dh_validate_f(void *handle, Bignum f); const char *dh_validate_f(void *handle, Bignum f);
Bignum dh_find_K(void *, Bignum f); Bignum dh_find_K(void *, Bignum f);
int loadrsakey(const Filename *filename, struct RSAKey *key, int rsa_ssh1_encrypted(const Filename *filename, char **comment);
const char *passphrase, const char **errorstr); int rsa_ssh1_loadpub(const Filename *filename, void **blob, int *bloblen,
int rsakey_encrypted(const Filename *filename, char **comment);
int rsakey_pubblob(const Filename *filename, void **blob, int *bloblen,
char **commentptr, const char **errorstr); char **commentptr, const char **errorstr);
int rsa_ssh1_loadkey(const Filename *filename, struct RSAKey *key,
int saversakey(const Filename *filename, struct RSAKey *key, char *passphrase); const char *passphrase, const char **errorstr);
int rsa_ssh1_savekey(const Filename *filename, struct RSAKey *key,
char *passphrase);
extern int base64_decode_atom(const char *atom, unsigned char *out); extern int base64_decode_atom(const char *atom, unsigned char *out);
extern int base64_lines(int datalen); extern int base64_lines(int datalen);

View File

@ -23,7 +23,7 @@
static int key_type_fp(FILE *fp); static int key_type_fp(FILE *fp);
static int loadrsakey_main(FILE * fp, struct RSAKey *key, int pub_only, static int rsa_ssh1_load_main(FILE * fp, struct RSAKey *key, int pub_only,
char **commentptr, const char *passphrase, char **commentptr, const char *passphrase,
const char **error) const char **error)
{ {
@ -69,7 +69,7 @@ static int loadrsakey_main(FILE * fp, struct RSAKey *key, int pub_only,
i += 4; i += 4;
/* Now the serious stuff. An ordinary SSH-1 public key. */ /* Now the serious stuff. An ordinary SSH-1 public key. */
j = makekey(buf + i, len - i, key, NULL, 1); j = rsa_ssh1_readpub(buf + i, len - i, key, NULL, RSA_SSH1_MODULUS_FIRST);
if (j < 0) if (j < 0)
goto end; /* overran */ goto end; /* overran */
i += j; i += j;
@ -132,7 +132,7 @@ static int loadrsakey_main(FILE * fp, struct RSAKey *key, int pub_only,
* decryption exponent, and then the three auxiliary values * decryption exponent, and then the three auxiliary values
* (iqmp, q, p). * (iqmp, q, p).
*/ */
j = makeprivate(buf + i, len - i, key); j = rsa_ssh1_readpriv(buf + i, len - i, key);
if (j < 0) goto end; if (j < 0) goto end;
i += j; i += j;
j = ssh1_read_bignum(buf + i, len - i, &key->iqmp); j = ssh1_read_bignum(buf + i, len - i, &key->iqmp);
@ -157,7 +157,7 @@ static int loadrsakey_main(FILE * fp, struct RSAKey *key, int pub_only,
return ret; return ret;
} }
int loadrsakey(const Filename *filename, struct RSAKey *key, int rsa_ssh1_loadkey(const Filename *filename, struct RSAKey *key,
const char *passphrase, const char **errorstr) const char *passphrase, const char **errorstr)
{ {
FILE *fp; FILE *fp;
@ -179,7 +179,7 @@ int loadrsakey(const Filename *filename, struct RSAKey *key,
/* /*
* This routine will take care of calling fclose() for us. * This routine will take care of calling fclose() for us.
*/ */
ret = loadrsakey_main(fp, key, FALSE, NULL, passphrase, &error); ret = rsa_ssh1_load_main(fp, key, FALSE, NULL, passphrase, &error);
fp = NULL; fp = NULL;
goto end; goto end;
} }
@ -201,7 +201,7 @@ int loadrsakey(const Filename *filename, struct RSAKey *key,
* See whether an RSA key is encrypted. Return its comment field as * See whether an RSA key is encrypted. Return its comment field as
* well. * well.
*/ */
int rsakey_encrypted(const Filename *filename, char **comment) int rsa_ssh1_encrypted(const Filename *filename, char **comment)
{ {
FILE *fp; FILE *fp;
char buf[64]; char buf[64];
@ -219,7 +219,7 @@ int rsakey_encrypted(const Filename *filename, char **comment)
/* /*
* This routine will take care of calling fclose() for us. * This routine will take care of calling fclose() for us.
*/ */
return loadrsakey_main(fp, NULL, FALSE, comment, NULL, &dummy); return rsa_ssh1_load_main(fp, NULL, FALSE, comment, NULL, &dummy);
} }
fclose(fp); fclose(fp);
return 0; /* wasn't the right kind of file */ return 0; /* wasn't the right kind of file */
@ -230,7 +230,7 @@ int rsakey_encrypted(const Filename *filename, char **comment)
* an RSA key, as given in the agent protocol (modulus bits, * an RSA key, as given in the agent protocol (modulus bits,
* exponent, modulus). * exponent, modulus).
*/ */
int rsakey_pubblob(const Filename *filename, void **blob, int *bloblen, int rsa_ssh1_loadpub(const Filename *filename, void **blob, int *bloblen,
char **commentptr, const char **errorstr) char **commentptr, const char **errorstr)
{ {
FILE *fp; FILE *fp;
@ -256,12 +256,13 @@ int rsakey_pubblob(const Filename *filename, void **blob, int *bloblen,
*/ */
if (fgets(buf, sizeof(buf), fp) && !strcmp(buf, rsa_signature)) { if (fgets(buf, sizeof(buf), fp) && !strcmp(buf, rsa_signature)) {
memset(&key, 0, sizeof(key)); memset(&key, 0, sizeof(key));
if (loadrsakey_main(fp, &key, TRUE, commentptr, NULL, &error)) { if (rsa_ssh1_load_main(fp, &key, TRUE, commentptr, NULL, &error)) {
*blob = rsa_public_blob(&key, bloblen); *blob = rsa_ssh1_public_blob(&key, bloblen,
RSA_SSH1_EXPONENT_FIRST);
freersakey(&key); freersakey(&key);
ret = 1; ret = 1;
} }
fp = NULL; /* loadrsakey_main unconditionally closes fp */ fp = NULL; /* rsa_ssh1_load_main unconditionally closes fp */
} else { } else {
/* /*
* Try interpreting the file as an SSH-1 public key. * Try interpreting the file as an SSH-1 public key.
@ -307,7 +308,7 @@ int rsakey_pubblob(const Filename *filename, void **blob, int *bloblen,
} }
if (commentptr) if (commentptr)
*commentptr = commentp ? dupstr(commentp) : NULL; *commentptr = commentp ? dupstr(commentp) : NULL;
*blob = rsa_public_blob(&key, bloblen); *blob = rsa_ssh1_public_blob(&key, bloblen, RSA_SSH1_EXPONENT_FIRST);
freersakey(&key); freersakey(&key);
sfree(line); sfree(line);
fclose(fp); fclose(fp);
@ -329,7 +330,8 @@ int rsakey_pubblob(const Filename *filename, void **blob, int *bloblen,
/* /*
* Save an RSA key file. Return nonzero on success. * Save an RSA key file. Return nonzero on success.
*/ */
int saversakey(const Filename *filename, struct RSAKey *key, char *passphrase) int rsa_ssh1_savekey(const Filename *filename, struct RSAKey *key,
char *passphrase)
{ {
unsigned char buf[16384]; unsigned char buf[16384];
unsigned char keybuf[16]; unsigned char keybuf[16];

View File

@ -10,8 +10,8 @@
#include "ssh.h" #include "ssh.h"
#include "misc.h" #include "misc.h"
int makekey(const unsigned char *data, int len, struct RSAKey *result, int rsa_ssh1_readpub(const unsigned char *data, int len, struct RSAKey *result,
const unsigned char **keystr, int order) const unsigned char **keystr, RsaSsh1Order order)
{ {
const unsigned char *p = data; const unsigned char *p = data;
int i, n; int i, n;
@ -28,13 +28,7 @@ int makekey(const unsigned char *data, int len, struct RSAKey *result,
len -= 4; len -= 4;
/* if (order == RSA_SSH1_EXPONENT_FIRST) {
* order=0 means exponent then modulus (the keys sent by the
* server). order=1 means modulus then exponent (the keys
* stored in a keyfile).
*/
if (order == 0) {
n = ssh1_read_bignum(p, len, result ? &result->exponent : NULL); n = ssh1_read_bignum(p, len, result ? &result->exponent : NULL);
if (n < 0) return -1; if (n < 0) return -1;
p += n; p += n;
@ -50,7 +44,7 @@ int makekey(const unsigned char *data, int len, struct RSAKey *result,
p += n; p += n;
len -= n; len -= n;
if (order == 1) { if (order == RSA_SSH1_MODULUS_FIRST) {
n = ssh1_read_bignum(p, len, result ? &result->exponent : NULL); n = ssh1_read_bignum(p, len, result ? &result->exponent : NULL);
if (n < 0) return -1; if (n < 0) return -1;
p += n; p += n;
@ -59,12 +53,13 @@ int makekey(const unsigned char *data, int len, struct RSAKey *result,
return p - data; return p - data;
} }
int makeprivate(const unsigned char *data, int len, struct RSAKey *result) int rsa_ssh1_readpriv(const unsigned char *data, int len,
struct RSAKey *result)
{ {
return ssh1_read_bignum(data, len, &result->private_exponent); return ssh1_read_bignum(data, len, &result->private_exponent);
} }
int rsaencrypt(unsigned char *data, int length, struct RSAKey *key) int rsa_ssh1_encrypt(unsigned char *data, int length, struct RSAKey *key)
{ {
Bignum b1, b2; Bignum b1, b2;
int i; int i;
@ -318,7 +313,7 @@ static Bignum rsa_privkey_op(Bignum input, struct RSAKey *key)
return ret; return ret;
} }
Bignum rsadecrypt(Bignum input, struct RSAKey *key) Bignum rsa_ssh1_decrypt(Bignum input, struct RSAKey *key)
{ {
return rsa_privkey_op(input, key); return rsa_privkey_op(input, key);
} }
@ -468,8 +463,8 @@ int rsa_verify(struct RSAKey *key)
return 1; return 1;
} }
/* Public key blob as used by Pageant: exponent before modulus. */ unsigned char *rsa_ssh1_public_blob(struct RSAKey *key, int *len,
unsigned char *rsa_public_blob(struct RSAKey *key, int *len) RsaSsh1Order order)
{ {
int length, pos; int length, pos;
unsigned char *ret; unsigned char *ret;
@ -480,8 +475,13 @@ unsigned char *rsa_public_blob(struct RSAKey *key, int *len)
PUT_32BIT(ret, bignum_bitcount(key->modulus)); PUT_32BIT(ret, bignum_bitcount(key->modulus));
pos = 4; pos = 4;
if (order == RSA_SSH1_EXPONENT_FIRST) {
pos += ssh1_write_bignum(ret + pos, key->exponent); pos += ssh1_write_bignum(ret + pos, key->exponent);
pos += ssh1_write_bignum(ret + pos, key->modulus); pos += ssh1_write_bignum(ret + pos, key->modulus);
} else {
pos += ssh1_write_bignum(ret + pos, key->modulus);
pos += ssh1_write_bignum(ret + pos, key->exponent);
}
*len = length; *len = length;
return ret; return ret;

View File

@ -556,7 +556,7 @@ struct pageant_pubkey *find_key(const char *string, char **retstr)
keytype == SSH_KEYTYPE_SSH1_PUBLIC) { keytype == SSH_KEYTYPE_SSH1_PUBLIC) {
const char *error; const char *error;
if (!rsakey_pubblob(fn, &key_in.blob, &key_in.bloblen, if (!rsa_ssh1_loadpub(fn, &key_in.blob, &key_in.bloblen,
NULL, &error)) { NULL, &error)) {
if (file_errors) { if (file_errors) {
*retstr = dupprintf("unable to load file '%s': %s", *retstr = dupprintf("unable to load file '%s': %s",
@ -696,7 +696,8 @@ void run_client(void)
struct RSAKey rkey; struct RSAKey rkey;
memset(&rkey, 0, sizeof(rkey)); memset(&rkey, 0, sizeof(rkey));
rkey.comment = dupstr(key->comment); rkey.comment = dupstr(key->comment);
makekey(key->blob, key->bloblen, &rkey, NULL, 0); rsa_ssh1_readpub(key->blob, key->bloblen, &rkey, NULL,
RSA_SSH1_EXPONENT_FIRST);
ssh1_write_pubkey(fp, &rkey); ssh1_write_pubkey(fp, &rkey);
freersakey(&rkey); freersakey(&rkey);
} else { } else {

View File

@ -671,7 +671,7 @@ void load_key_file(HWND hwnd, struct MainDlgState *state,
comment = NULL; comment = NULL;
passphrase = NULL; passphrase = NULL;
if (realtype == SSH_KEYTYPE_SSH1) if (realtype == SSH_KEYTYPE_SSH1)
needs_pass = rsakey_encrypted(filename, &comment); needs_pass = rsa_ssh1_encrypted(filename, &comment);
else if (realtype == SSH_KEYTYPE_SSH2) else if (realtype == SSH_KEYTYPE_SSH2)
needs_pass = ssh2_userkey_encrypted(filename, &comment); needs_pass = ssh2_userkey_encrypted(filename, &comment);
else else
@ -698,7 +698,8 @@ void load_key_file(HWND hwnd, struct MainDlgState *state,
passphrase = dupstr(""); passphrase = dupstr("");
if (type == SSH_KEYTYPE_SSH1) { if (type == SSH_KEYTYPE_SSH1) {
if (realtype == type) if (realtype == type)
ret = loadrsakey(filename, &newkey1, passphrase, &errmsg); ret = rsa_ssh1_loadkey(
filename, &newkey1, passphrase, &errmsg);
else else
ret = import_ssh1(filename, realtype, &newkey1, ret = import_ssh1(filename, realtype, &newkey1,
passphrase, &errmsg); passphrase, &errmsg);
@ -1279,7 +1280,8 @@ static INT_PTR CALLBACK MainDlgProc(HWND hwnd, UINT msg,
ret = export_ssh1(fn, type, &state->key, ret = export_ssh1(fn, type, &state->key,
*passphrase ? passphrase : NULL); *passphrase ? passphrase : NULL);
else else
ret = saversakey(fn, &state->key, ret = rsa_ssh1_savekey(
fn, &state->key,
*passphrase ? passphrase : NULL); *passphrase ? passphrase : NULL);
filename_free(fn); filename_free(fn);
} }