mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-10 09:58:01 +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:
parent
1a02274272
commit
7e8ae41a3f
11
cmdgen.c
11
cmdgen.c
@ -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,8 +811,8 @@ 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;
|
||||||
|
|
||||||
n = 4; /* skip modulus bits */
|
n = 4; /* skip modulus bits */
|
||||||
@ -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;
|
||||||
|
30
pageant.c
30
pageant.c
@ -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);
|
||||||
|
31
ssh.c
31
ssh.c
@ -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++) {
|
||||||
|
39
ssh.h
39
ssh.h
@ -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);
|
char **commentptr, const char **errorstr);
|
||||||
int rsakey_pubblob(const Filename *filename, void **blob, int *bloblen,
|
int rsa_ssh1_loadkey(const Filename *filename, struct RSAKey *key,
|
||||||
char **commentptr, const char **errorstr);
|
const char *passphrase, const char **errorstr);
|
||||||
|
int rsa_ssh1_savekey(const Filename *filename, struct RSAKey *key,
|
||||||
int saversakey(const Filename *filename, struct RSAKey *key, char *passphrase);
|
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);
|
||||||
|
36
sshpubk.c
36
sshpubk.c
@ -23,9 +23,9 @@
|
|||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
unsigned char buf[16384];
|
unsigned char buf[16384];
|
||||||
unsigned char keybuf[16];
|
unsigned char keybuf[16];
|
||||||
@ -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,8 +157,8 @@ 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;
|
||||||
char buf[64];
|
char buf[64];
|
||||||
@ -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,8 +230,8 @@ 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;
|
||||||
char buf[64];
|
char buf[64];
|
||||||
@ -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];
|
||||||
|
34
sshrsa.c
34
sshrsa.c
@ -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;
|
||||||
pos += ssh1_write_bignum(ret + pos, key->exponent);
|
if (order == RSA_SSH1_EXPONENT_FIRST) {
|
||||||
pos += ssh1_write_bignum(ret + pos, key->modulus);
|
pos += ssh1_write_bignum(ret + pos, key->exponent);
|
||||||
|
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;
|
||||||
|
@ -556,8 +556,8 @@ 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",
|
||||||
string, error);
|
string, error);
|
||||||
@ -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 {
|
||||||
|
@ -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,8 +1280,9 @@ 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(
|
||||||
*passphrase ? passphrase : NULL);
|
fn, &state->key,
|
||||||
|
*passphrase ? passphrase : NULL);
|
||||||
filename_free(fn);
|
filename_free(fn);
|
||||||
}
|
}
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
|
Loading…
Reference in New Issue
Block a user