1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 17:38:00 +00:00

Pageant interface changes. You can now do `pageant -c command' to

spawn another command after starting Pageant. Also, if Pageant is
already running, `pageant keyfile' and `pageant -c command' will do
the Right Thing, that is, add the key to the _first_ Pageant and/or
run a command and then exit. The only time you now get the `Pageant
is already running' error is if you try to start the second copy
with no arguments.
NB the affected files in this checkin are rather wide-ranging
because I renamed the not really SSH1-specific
`ssh1_bignum_bitcount' function to just `bignum_bitcount'.

[originally from svn r1044]
This commit is contained in:
Simon Tatham 2001-04-16 11:16:58 +00:00
parent fb8745a7d7
commit 522f130391
11 changed files with 333 additions and 114 deletions

View File

@ -87,7 +87,7 @@ OBJS4 = x11fwd.$(OBJ) sshaes.$(OBJ)
##-- objects pageant
PAGE1 = pageant.$(OBJ) sshrsa.$(OBJ) sshpubk.$(OBJ) sshdes.$(OBJ) sshbn.$(OBJ)
PAGE2 = sshmd5.$(OBJ) version.$(OBJ) tree234.$(OBJ) misc.$(OBJ) sshaes.$(OBJ)
PAGE3 = sshsha.$(OBJ)
PAGE3 = sshsha.$(OBJ) pageantc.$(OBJ)
##-- objects puttygen
GEN1 = puttygen.$(OBJ) sshrsag.$(OBJ) sshprime.$(OBJ) sshdes.$(OBJ)
GEN2 = sshbn.$(OBJ) sshmd5.$(OBJ) version.$(OBJ) sshrand.$(OBJ) noise.$(OBJ)

316
pageant.c
View File

@ -9,6 +9,17 @@
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <tchar.h>
// FIXME
#define DEBUG
#ifdef DEBUG
void dprintf(char *fmt, ...);
#define debug(x) (dprintf x)
#else
#define debug(x)
#endif
#include "ssh.h"
#include "tree234.h"
@ -41,6 +52,7 @@ static HWND hwnd;
static HWND keylist;
static HWND aboutbox;
static HMENU systray_menu;
static int already_running;
static tree234 *rsakeys, *ssh2keys;
@ -284,16 +296,22 @@ static void add_keyfile(char *filename) {
return;
}
debug(("ooh %d\n", __LINE__));
if (ver == 1)
needs_pass = rsakey_encrypted(filename, &comment);
else
needs_pass = ssh2_userkey_encrypted(filename, &comment);
debug(("ooh %d\n", __LINE__));
attempts = 0;
debug(("ooh %d\n", __LINE__));
if (ver == 1)
rkey = smalloc(sizeof(*rkey));
debug(("ooh %d\n", __LINE__));
pps.passphrase = passphrase;
pps.comment = comment;
debug(("ooh %d\n", __LINE__));
do {
debug(("ooh %d\n", __LINE__));
if (needs_pass) {
int dlgret;
dlgret = DialogBoxParam(instance, MAKEINTRESOURCE(210),
@ -307,10 +325,13 @@ static void add_keyfile(char *filename) {
}
} else
*passphrase = '\0';
debug(("ooh %d\n", __LINE__));
if (ver == 1)
ret = loadrsakey(filename, rkey, passphrase);
else {
debug(("ooh %d\n", __LINE__));
skey = ssh2_load_userkey(filename, passphrase);
debug(("ooh %d\n", __LINE__));
if (skey == SSH2_WRONG_PASSPHRASE)
ret = -1;
else if (!skey)
@ -320,7 +341,9 @@ static void add_keyfile(char *filename) {
}
attempts++;
} while (ret == -1);
debug(("ooh %d\n", __LINE__));
if (comment) sfree(comment);
debug(("ooh %d\n", __LINE__));
if (ret == 0) {
MessageBox(NULL, "Couldn't load private key.", APPNAME,
MB_OK | MB_ICONERROR);
@ -328,13 +351,120 @@ static void add_keyfile(char *filename) {
sfree(rkey);
return;
}
debug(("ooh %d\n", __LINE__));
if (ver == 1) {
if (add234(rsakeys, rkey) != rkey)
sfree(rkey); /* already present, don't waste RAM */
if (already_running) {
unsigned char *request, *response;
int reqlen, clen, resplen;
debug(("ooh %d\n", __LINE__));
clen = strlen(rkey->comment);
debug(("ooh %d\n", __LINE__));
reqlen = 4 + 1 + /* length, message type */
4 + /* bit count */
ssh1_bignum_length(rkey->modulus) +
ssh1_bignum_length(rkey->exponent) +
ssh1_bignum_length(rkey->private_exponent) +
ssh1_bignum_length(rkey->iqmp) +
ssh1_bignum_length(rkey->p) +
ssh1_bignum_length(rkey->q) +
4 + clen /* comment */
;
debug(("ooh %d %d\n", __LINE__, reqlen));
request = smalloc(reqlen);
debug(("ooh %d\n", __LINE__));
debug(("ooh %d\n", __LINE__));
request[4] = SSH1_AGENTC_ADD_RSA_IDENTITY;
debug(("ooh %d\n", __LINE__));
reqlen = 5;
PUT_32BIT(request+reqlen, bignum_bitcount(rkey->modulus));
reqlen += 4;
reqlen += ssh1_write_bignum(request+reqlen, rkey->modulus);
reqlen += ssh1_write_bignum(request+reqlen, rkey->exponent);
reqlen += ssh1_write_bignum(request+reqlen, rkey->private_exponent);
reqlen += ssh1_write_bignum(request+reqlen, rkey->iqmp);
reqlen += ssh1_write_bignum(request+reqlen, rkey->p);
reqlen += ssh1_write_bignum(request+reqlen, rkey->q);
PUT_32BIT(request+reqlen, clen);
memcpy(request+reqlen+4, rkey->comment, clen);
reqlen += 4+clen;
PUT_32BIT(request, reqlen-4);
debug(("ooh %d\n", __LINE__));
agent_query(request, reqlen, &response, &resplen);
debug(("ooh %d\n", __LINE__));
if (resplen < 5 || response[4] != SSH_AGENT_SUCCESS)
MessageBox(NULL, "The already running Pageant "
"refused to add the key.", APPNAME,
MB_OK | MB_ICONERROR);
} else {
if (add234(rsakeys, rkey) != rkey)
sfree(rkey); /* already present, don't waste RAM */
}
} else {
if (add234(ssh2keys, skey) != skey) {
skey->alg->freekey(skey->data);
sfree(skey); /* already present, don't waste RAM */
if (already_running) {
unsigned char *request, *response;
int reqlen, alglen, clen, keybloblen, resplen;
debug(("ooh %d\n", __LINE__));
alglen = strlen(skey->alg->name);
debug(("ooh %d\n", __LINE__));
clen = strlen(skey->comment);
debug(("ooh %d\n", __LINE__));
debug(("ooh %d\n", __LINE__));
keybloblen = skey->alg->openssh_fmtkey(skey->data, NULL, 0);
debug(("ooh %d\n", __LINE__));
debug(("ooh %d\n", __LINE__));
reqlen = 4 + 1 + /* length, message type */
4 + alglen + /* algorithm name */
keybloblen + /* key data */
4 + clen /* comment */
;
debug(("ooh %d\n", __LINE__));
debug(("ooh %d\n", __LINE__));
request = smalloc(reqlen);
debug(("ooh %d\n", __LINE__));
request[4] = SSH2_AGENTC_ADD_IDENTITY;
debug(("ooh %d\n", __LINE__));
reqlen = 5;
debug(("ooh %d\n", __LINE__));
PUT_32BIT(request+reqlen, alglen);
debug(("ooh %d\n", __LINE__));
reqlen += 4;
debug(("ooh %d\n", __LINE__));
memcpy(request+reqlen, skey->alg->name, alglen);
debug(("ooh %d\n", __LINE__));
reqlen += alglen;
debug(("ooh %d\n", __LINE__));
reqlen += skey->alg->openssh_fmtkey(skey->data,
request+reqlen, keybloblen);
debug(("ooh %d\n", __LINE__));
PUT_32BIT(request+reqlen, clen);
debug(("ooh %d\n", __LINE__));
memcpy(request+reqlen+4, skey->comment, clen);
debug(("ooh %d\n", __LINE__));
PUT_32BIT(request, reqlen-4);
debug(("ooh %d\n", __LINE__));
reqlen += clen+4;
agent_query(request, reqlen, &response, &resplen);
debug(("ooh %d\n", __LINE__));
if (resplen < 5 || response[4] != SSH_AGENT_SUCCESS)
MessageBox(NULL, "The already running Pageant"
"refused to add the key.", APPNAME,
MB_OK | MB_ICONERROR);
debug(("ooh %d\n", __LINE__));
} else {
if (add234(ssh2keys, skey) != skey) {
skey->alg->freekey(skey->data);
sfree(skey); /* already present, don't waste RAM */
}
}
}
}
@ -387,7 +517,7 @@ static void answer_msg(void *msg) {
PUT_32BIT(ret+5, nkeys);
p = ret + 5 + 4;
for (key = first234(rsakeys, &e); key; key = next234(&e)) {
PUT_32BIT(p, ssh1_bignum_bitcount(key->modulus));
PUT_32BIT(p, bignum_bitcount(key->modulus));
p += 4;
p += ssh1_write_bignum(p, key->exponent);
p += ssh1_write_bignum(p, key->modulus);
@ -721,8 +851,8 @@ static int cmpkeys_rsa(void *av, void *bv) {
/*
* Compare by length of moduli.
*/
alen = ssh1_bignum_bitcount(am);
blen = ssh1_bignum_bitcount(bm);
alen = bignum_bitcount(am);
blen = bignum_bitcount(bm);
if (alen > blen) return +1; else if (alen < blen) return -1;
/*
* Now compare by moduli themselves.
@ -1081,11 +1211,26 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
return DefWindowProc (hwnd, message, wParam, lParam);
}
/*
* Fork and Exec the command in cmdline. [DBW]
*/
void spawn_cmd(char *cmdline, int show) {
if (ShellExecute(NULL, _T("open"), cmdline,
NULL, NULL, show) <= (HINSTANCE) 32) {
TCHAR sMsg[140];
sprintf(sMsg, _T("Failed to run \"%.100s\", Error: %d"), cmdline,
GetLastError());
MessageBox(NULL, sMsg, APPNAME, MB_OK | MB_ICONEXCLAMATION);
}
}
int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
WNDCLASS wndclass;
MSG msg;
OSVERSIONINFO osi;
HMODULE advapi;
char *command = NULL;
int added_keys = 0;
/*
* Determine whether we're an NT system (should have security
@ -1101,7 +1246,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
if (has_security) {
#ifndef NO_SECURITY
/*
* Attempt to ge the security API we need.
* Attempt to get the security API we need.
*/
advapi = LoadLibrary("ADVAPI32.DLL");
getsecurityinfo = (gsi_fn_t)GetProcAddress(advapi, "GetSecurityInfo");
@ -1122,87 +1267,90 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
} else
advapi = NULL;
/*
* First bomb out totally if we are already running.
*/
if (FindWindow("Pageant", "Pageant")) {
MessageBox(NULL, "Pageant is already running", "Pageant Error",
MB_ICONERROR | MB_OK);
if (advapi) FreeLibrary(advapi);
return 0;
}
instance = inst;
if (!prev) {
wndclass.style = 0;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = inst;
wndclass.hIcon = LoadIcon (inst,
MAKEINTRESOURCE(IDI_MAINICON));
wndclass.hCursor = LoadCursor (NULL, IDC_IBEAM);
wndclass.hbrBackground = GetStockObject (BLACK_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = APPNAME;
/*
* Find out if Pageant is already running.
*/
already_running = FALSE;
if (FindWindow("Pageant", "Pageant"))
already_running = TRUE;
else {
RegisterClass (&wndclass);
}
if (!prev) {
wndclass.style = 0;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = inst;
wndclass.hIcon = LoadIcon (inst,
MAKEINTRESOURCE(IDI_MAINICON));
wndclass.hCursor = LoadCursor (NULL, IDC_IBEAM);
wndclass.hbrBackground = GetStockObject (BLACK_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = APPNAME;
hwnd = keylist = NULL;
RegisterClass (&wndclass);
}
hwnd = CreateWindow (APPNAME, APPNAME,
WS_OVERLAPPEDWINDOW | WS_VSCROLL,
CW_USEDEFAULT, CW_USEDEFAULT,
100, 100, NULL, NULL, inst, NULL);
hwnd = keylist = NULL;
/* Set up a system tray icon */
{
BOOL res;
NOTIFYICONDATA tnid;
HICON hicon;
hwnd = CreateWindow (APPNAME, APPNAME,
WS_OVERLAPPEDWINDOW | WS_VSCROLL,
CW_USEDEFAULT, CW_USEDEFAULT,
100, 100, NULL, NULL, inst, NULL);
/* Set up a system tray icon */
{
BOOL res;
NOTIFYICONDATA tnid;
HICON hicon;
#ifdef NIM_SETVERSION
tnid.uVersion = 0;
res = Shell_NotifyIcon(NIM_SETVERSION, &tnid);
tnid.uVersion = 0;
res = Shell_NotifyIcon(NIM_SETVERSION, &tnid);
#endif
tnid.cbSize = sizeof(NOTIFYICONDATA);
tnid.hWnd = hwnd;
tnid.uID = 1; /* unique within this systray use */
tnid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
tnid.uCallbackMessage = WM_SYSTRAY;
tnid.hIcon = hicon = LoadIcon (instance, MAKEINTRESOURCE(201));
strcpy(tnid.szTip, "Pageant (PuTTY authentication agent)");
tnid.cbSize = sizeof(NOTIFYICONDATA);
tnid.hWnd = hwnd;
tnid.uID = 1; /* unique within this systray use */
tnid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
tnid.uCallbackMessage = WM_SYSTRAY;
tnid.hIcon = hicon = LoadIcon (instance, MAKEINTRESOURCE(201));
strcpy(tnid.szTip, "Pageant (PuTTY authentication agent)");
res = Shell_NotifyIcon(NIM_ADD, &tnid);
res = Shell_NotifyIcon(NIM_ADD, &tnid);
if (hicon)
DestroyIcon(hicon);
if (hicon)
DestroyIcon(hicon);
systray_menu = CreatePopupMenu();
/* accelerators used: vkxa */
AppendMenu (systray_menu, MF_ENABLED, IDM_VIEWKEYS, "&View Keys");
AppendMenu (systray_menu, MF_ENABLED, IDM_ADDKEY, "Add &Key");
AppendMenu (systray_menu, MF_ENABLED, IDM_ABOUT, "&About");
AppendMenu (systray_menu, MF_ENABLED, IDM_CLOSE, "E&xit");
}
ShowWindow (hwnd, SW_HIDE);
/*
* Initialise storage for RSA keys.
*/
rsakeys = newtree234(cmpkeys_rsa);
ssh2keys = newtree234(cmpkeys_ssh2);
systray_menu = CreatePopupMenu();
/* accelerators used: vkxa */
AppendMenu (systray_menu, MF_ENABLED, IDM_VIEWKEYS, "&View Keys");
AppendMenu (systray_menu, MF_ENABLED, IDM_ADDKEY, "Add &Key");
AppendMenu (systray_menu, MF_ENABLED, IDM_ABOUT, "&About");
AppendMenu (systray_menu, MF_ENABLED, IDM_CLOSE, "E&xit");
}
ShowWindow (hwnd, SW_HIDE);
/*
* Initialise storage for RSA keys.
*/
rsakeys = newtree234(cmpkeys_rsa);
ssh2keys = newtree234(cmpkeys_ssh2);
/*
* Process the command line and add keys as listed on it.
* If we already determined that we need to spawn a program from above we
* need to ignore the first two arguments. [DBW]
*/
{
char *p;
int inquotes = 0;
int ignorearg = 0;
p = cmdline;
while (*p) {
while (*p && isspace(*p)) p++;
@ -1221,11 +1369,39 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
if (*p) p++;
*pp++ = '\0';
}
add_keyfile(q);
if (!strcmp(q, "-c")) {
/*
* If we see `-c', then the rest of the
* command line should be treated as a
* command to be spawned.
*/
while (*p && isspace(*p)) p++;
command = p;
break;
} else {
add_keyfile(q);
added_keys = TRUE;
}
}
}
}
if (command) spawn_cmd (command, show);
/*
* If Pageant was already running, we leave now. If we haven't
* even taken any auxiliary action (spawned a command or added
* keys), complain.
*/
if (already_running) {
if (!command && !added_keys) {
MessageBox(NULL, "Pageant is already running", "Pageant Error",
MB_ICONERROR | MB_OK);
}
if (advapi) FreeLibrary(advapi);
return 0;
}
/*
* Main message loop.
*/

View File

@ -314,7 +314,7 @@ static void setupbigedit1(HWND hwnd, int id, struct RSAKey *key) {
buffer = smalloc(strlen(dec1)+strlen(dec2)+
strlen(key->comment)+30);
sprintf(buffer, "%d %s %s %s",
ssh1_bignum_bitcount(key->modulus),
bignum_bitcount(key->modulus),
dec1, dec2, key->comment);
SetDlgItemText(hwnd, id, buffer);
sfree(dec1);

4
ssh.c
View File

@ -987,7 +987,7 @@ static void ssh2_pkt_addstring(char *data) {
}
static char *ssh2_mpint_fmt(Bignum b, int *len) {
unsigned char *p;
int i, n = (ssh1_bignum_bitcount(b)+7)/8;
int i, n = (bignum_bitcount(b)+7)/8;
p = smalloc(n + 1);
if (!p)
fatalbox("out of memory");
@ -1753,7 +1753,7 @@ static int do_ssh1_login(unsigned char *in, int inlen, int ispkt)
PUT_32BIT(agentreq, len);
q = agentreq + 4;
*q++ = SSH1_AGENTC_RSA_CHALLENGE;
PUT_32BIT(q, ssh1_bignum_bitcount(key.modulus));
PUT_32BIT(q, bignum_bitcount(key.modulus));
q += 4;
q += ssh1_write_bignum(q, key.exponent);
q += ssh1_write_bignum(q, key.modulus);

3
ssh.h
View File

@ -144,6 +144,7 @@ struct ssh_signkey {
void *(*createkey)(unsigned char *pub_blob, int pub_len,
unsigned char *priv_blob, int priv_len);
void *(*openssh_createkey)(unsigned char **blob, int *len);
int (*openssh_fmtkey)(void *key, unsigned char *blob, int len);
char *(*fingerprint)(void *key);
int (*verifysig)(void *key, char *sig, int siglen,
char *data, int datalen);
@ -209,7 +210,7 @@ void decbn(Bignum n);
extern Bignum Zero, One;
Bignum bignum_from_bytes(unsigned char *data, int nbytes);
int ssh1_read_bignum(unsigned char *data, Bignum *result);
int ssh1_bignum_bitcount(Bignum bn);
int bignum_bitcount(Bignum bn);
int ssh1_bignum_length(Bignum bn);
int bignum_byte(Bignum bn, int i);
int bignum_bit(Bignum bn, int i);

19
sshbn.c
View File

@ -478,7 +478,7 @@ int ssh1_read_bignum(unsigned char *data, Bignum *result) {
/*
* Return the bit count of a bignum, for ssh1 encoding.
*/
int ssh1_bignum_bitcount(Bignum bn) {
int bignum_bitcount(Bignum bn) {
int bitcount = bn[0] * 16 - 1;
while (bitcount >= 0 && (bn[bitcount/16+1] >> (bitcount % 16)) == 0)
bitcount--;
@ -489,7 +489,14 @@ int ssh1_bignum_bitcount(Bignum bn) {
* Return the byte length of a bignum when ssh1 encoded.
*/
int ssh1_bignum_length(Bignum bn) {
return 2 + (ssh1_bignum_bitcount(bn)+7)/8;
return 2 + (bignum_bitcount(bn)+7)/8;
}
/*
* Return the byte length of a bignum when ssh2 encoded.
*/
int ssh2_bignum_length(Bignum bn) {
return 4 + (bignum_bitcount(bn)+8)/8;
}
/*
@ -538,7 +545,7 @@ int ssh1_write_bignum(void *data, Bignum bn) {
unsigned char *p = data;
int len = ssh1_bignum_length(bn);
int i;
int bitc = ssh1_bignum_bitcount(bn);
int bitc = bignum_bitcount(bn);
*p++ = (bitc >> 8) & 0xFF;
*p++ = (bitc ) & 0xFF;
@ -571,7 +578,7 @@ Bignum bignum_rshift(Bignum a, int shift) {
int i, shiftw, shiftb, shiftbb, bits;
unsigned short ai, ai1;
bits = ssh1_bignum_bitcount(a) - shift;
bits = bignum_bitcount(a) - shift;
ret = newbn((bits+15)/16);
if (ret) {
@ -724,7 +731,7 @@ void diagbn(char *prefix, Bignum md) {
debugprint(("%s0x", prefix ? prefix : ""));
nibbles = (3 + ssh1_bignum_bitcount(md))/4; if (nibbles<1) nibbles=1;
nibbles = (3 + bignum_bitcount(md))/4; if (nibbles<1) nibbles=1;
morenibbles = 4*md[0] - nibbles;
for (i=0; i<morenibbles; i++) debugprint(("-"));
for (i=nibbles; i-- ;)
@ -835,7 +842,7 @@ char *bignum_decimal(Bignum x) {
* Therefore if we multiply the bit count by 28/93, rounding
* up, we will have enough digits.
*/
i = ssh1_bignum_bitcount(x);
i = bignum_bitcount(x);
ndigits = (28*i + 92)/93; /* multiply by 28/93 and round up */
ndigits++; /* allow for trailing \0 */
ret = smalloc(ndigits);

View File

@ -102,7 +102,7 @@ Bignum dh_create_e(int nbits) {
* with qmask.
*/
if (x) freebn(x);
if (nbits == 0 || nbits > ssh1_bignum_bitcount(qmask)) {
if (nbits == 0 || nbits > bignum_bitcount(qmask)) {
ssh1_write_bignum(buf, qmask);
for (i = 2; i < nbytes; i++)
buf[i] &= random_byte();

View File

@ -108,28 +108,28 @@ static char *dss_fmtkey(void *key) {
if (!dss->p)
return NULL;
len = 8 + 4 + 1; /* 4 x "0x", punctuation, \0 */
len += 4 * (ssh1_bignum_bitcount(dss->p)+15)/16;
len += 4 * (ssh1_bignum_bitcount(dss->q)+15)/16;
len += 4 * (ssh1_bignum_bitcount(dss->g)+15)/16;
len += 4 * (ssh1_bignum_bitcount(dss->y)+15)/16;
len += 4 * (bignum_bitcount(dss->p)+15)/16;
len += 4 * (bignum_bitcount(dss->q)+15)/16;
len += 4 * (bignum_bitcount(dss->g)+15)/16;
len += 4 * (bignum_bitcount(dss->y)+15)/16;
p = smalloc(len);
if (!p) return NULL;
pos = 0;
pos += sprintf(p+pos, "0x");
nibbles = (3 + ssh1_bignum_bitcount(dss->p))/4; if (nibbles<1) nibbles=1;
nibbles = (3 + bignum_bitcount(dss->p))/4; if (nibbles<1) nibbles=1;
for (i=nibbles; i-- ;)
p[pos++] = hex[(bignum_byte(dss->p, i/2) >> (4*(i%2))) & 0xF];
pos += sprintf(p+pos, ",0x");
nibbles = (3 + ssh1_bignum_bitcount(dss->q))/4; if (nibbles<1) nibbles=1;
nibbles = (3 + bignum_bitcount(dss->q))/4; if (nibbles<1) nibbles=1;
for (i=nibbles; i-- ;)
p[pos++] = hex[(bignum_byte(dss->q, i/2) >> (4*(i%2))) & 0xF];
pos += sprintf(p+pos, ",0x");
nibbles = (3 + ssh1_bignum_bitcount(dss->g))/4; if (nibbles<1) nibbles=1;
nibbles = (3 + bignum_bitcount(dss->g))/4; if (nibbles<1) nibbles=1;
for (i=nibbles; i-- ;)
p[pos++] = hex[(bignum_byte(dss->g, i/2) >> (4*(i%2))) & 0xF];
pos += sprintf(p+pos, ",0x");
nibbles = (3 + ssh1_bignum_bitcount(dss->y))/4; if (nibbles<1) nibbles=1;
nibbles = (3 + bignum_bitcount(dss->y))/4; if (nibbles<1) nibbles=1;
for (i=nibbles; i-- ;)
p[pos++] = hex[(bignum_byte(dss->y, i/2) >> (4*(i%2))) & 0xF];
p[pos] = '\0';
@ -148,7 +148,7 @@ static char *dss_fingerprint(void *key) {
MD5Update(&md5c, "\0\0\0\7ssh-dss", 11);
#define ADD_BIGNUM(bignum) \
numlen = (ssh1_bignum_bitcount(bignum)+8)/8; \
numlen = (bignum_bitcount(bignum)+8)/8; \
PUT_32BIT(lenbuf, numlen); MD5Update(&md5c, lenbuf, 4); \
for (i = numlen; i-- ;) { \
unsigned char c = bignum_byte(bignum, i); \
@ -162,7 +162,7 @@ static char *dss_fingerprint(void *key) {
MD5Final(digest, &md5c);
sprintf(buffer, "ssh-dss %d ", ssh1_bignum_bitcount(dss->p));
sprintf(buffer, "ssh-dss %d ", bignum_bitcount(dss->p));
for (i = 0; i < 16; i++)
sprintf(buffer+strlen(buffer), "%s%02x", i?":":"", digest[i]);
ret = smalloc(strlen(buffer)+1);
@ -279,10 +279,10 @@ static unsigned char *dss_public_blob(void *key, int *len) {
int i;
unsigned char *blob, *p;
plen = (ssh1_bignum_bitcount(dss->p)+8)/8;
qlen = (ssh1_bignum_bitcount(dss->q)+8)/8;
glen = (ssh1_bignum_bitcount(dss->g)+8)/8;
ylen = (ssh1_bignum_bitcount(dss->y)+8)/8;
plen = (bignum_bitcount(dss->p)+8)/8;
qlen = (bignum_bitcount(dss->q)+8)/8;
glen = (bignum_bitcount(dss->g)+8)/8;
ylen = (bignum_bitcount(dss->y)+8)/8;
/*
* string "ssh-dss", mpint p, mpint q, mpint g, mpint y. Total
@ -319,6 +319,10 @@ static void *dss_openssh_createkey(unsigned char **blob, int *len) {
return NULL; /* can't handle DSS private keys */
}
static int dss_openssh_fmtkey(void *key, unsigned char *blob, int len) {
return -1; /* can't handle DSS private keys */
}
unsigned char *dss_sign(void *key, char *data, int datalen, int *siglen) {
return NULL; /* can't handle DSS private keys */
}
@ -331,6 +335,7 @@ const struct ssh_signkey ssh_dss = {
dss_private_blob,
dss_createkey,
dss_openssh_createkey,
dss_openssh_fmtkey,
dss_fingerprint,
dss_verifysig,
dss_sign,

View File

@ -213,7 +213,7 @@ int saversakey(char *filename, struct RSAKey *key, char *passphrase) {
* containing the bit count, then two bignums containing the
* modulus and exponent respectively.
*/
PUT_32BIT(p, ssh1_bignum_bitcount(key->modulus)); p += 4;
PUT_32BIT(p, bignum_bitcount(key->modulus)); p += 4;
p += ssh1_write_bignum(p, key->modulus);
p += ssh1_write_bignum(p, key->exponent);

View File

@ -88,8 +88,8 @@ int rsastr_len(struct RSAKey *key) {
md = key->modulus;
ex = key->exponent;
mdlen = (ssh1_bignum_bitcount(md)+15) / 16;
exlen = (ssh1_bignum_bitcount(ex)+15) / 16;
mdlen = (bignum_bitcount(md)+15) / 16;
exlen = (bignum_bitcount(ex)+15) / 16;
return 4 * (mdlen+exlen) + 20;
}
@ -103,13 +103,13 @@ void rsastr_fmt(char *str, struct RSAKey *key) {
len += sprintf(str+len, "0x");
nibbles = (3 + ssh1_bignum_bitcount(ex))/4; if (nibbles<1) nibbles=1;
nibbles = (3 + bignum_bitcount(ex))/4; if (nibbles<1) nibbles=1;
for (i=nibbles; i-- ;)
str[len++] = hex[(bignum_byte(ex, i/2) >> (4*(i%2))) & 0xF];
len += sprintf(str+len, ",0x");
nibbles = (3 + ssh1_bignum_bitcount(md))/4; if (nibbles<1) nibbles=1;
nibbles = (3 + bignum_bitcount(md))/4; if (nibbles<1) nibbles=1;
for (i=nibbles; i-- ;)
str[len++] = hex[(bignum_byte(md, i/2) >> (4*(i%2))) & 0xF];
@ -139,7 +139,7 @@ void rsa_fingerprint(char *str, int len, struct RSAKey *key) {
}
MD5Final(digest, &md5c);
sprintf(buffer, "%d ", ssh1_bignum_bitcount(key->modulus));
sprintf(buffer, "%d ", bignum_bitcount(key->modulus));
for (i = 0; i < 16; i++)
sprintf(buffer+strlen(buffer), "%s%02x", i?":":"", digest[i]);
strncpy(str, buffer, len); str[len-1] = '\0';
@ -292,8 +292,8 @@ static unsigned char *rsa2_public_blob(void *key, int *len) {
int i;
unsigned char *blob, *p;
elen = (ssh1_bignum_bitcount(rsa->exponent)+8)/8;
mlen = (ssh1_bignum_bitcount(rsa->modulus)+8)/8;
elen = (bignum_bitcount(rsa->exponent)+8)/8;
mlen = (bignum_bitcount(rsa->modulus)+8)/8;
/*
* string "ssh-rsa", mpint exp, mpint mod. Total 19+elen+mlen.
@ -319,10 +319,10 @@ static unsigned char *rsa2_private_blob(void *key, int *len) {
int i;
unsigned char *blob, *p;
dlen = (ssh1_bignum_bitcount(rsa->private_exponent)+8)/8;
plen = (ssh1_bignum_bitcount(rsa->p)+8)/8;
qlen = (ssh1_bignum_bitcount(rsa->q)+8)/8;
ulen = (ssh1_bignum_bitcount(rsa->iqmp)+8)/8;
dlen = (bignum_bitcount(rsa->private_exponent)+8)/8;
plen = (bignum_bitcount(rsa->p)+8)/8;
qlen = (bignum_bitcount(rsa->q)+8)/8;
ulen = (bignum_bitcount(rsa->iqmp)+8)/8;
/*
* mpint private_exp, mpint p, mpint q, mpint iqmp. Total 16 +
@ -393,6 +393,35 @@ static void *rsa2_openssh_createkey(unsigned char **blob, int *len) {
return rsa;
}
static int *rsa2_openssh_fmtkey(void *key, unsigned char *blob, int len) {
struct RSAKey *rsa = (struct RSAKey *)key;
int bloblen, i;
bloblen =
ssh2_bignum_length(rsa->modulus) +
ssh2_bignum_length(rsa->exponent) +
ssh2_bignum_length(rsa->private_exponent) +
ssh2_bignum_length(rsa->iqmp) +
ssh2_bignum_length(rsa->p) +
ssh2_bignum_length(rsa->q);
if (bloblen > len)
return bloblen;
bloblen = 0;
#define ENC(x) \
PUT_32BIT(blob+bloblen, ssh2_bignum_length((x))-4); bloblen += 4; \
for (i = ssh2_bignum_length((x))-4; i-- ;) blob[bloblen++]=bignum_byte((x),i);
ENC(rsa->modulus);
ENC(rsa->exponent);
ENC(rsa->private_exponent);
ENC(rsa->iqmp);
ENC(rsa->p);
ENC(rsa->q);
return bloblen;
}
static char *rsa2_fingerprint(void *key) {
struct RSAKey *rsa = (struct RSAKey *)key;
struct MD5Context md5c;
@ -405,7 +434,7 @@ static char *rsa2_fingerprint(void *key) {
MD5Update(&md5c, "\0\0\0\7ssh-rsa", 11);
#define ADD_BIGNUM(bignum) \
numlen = (ssh1_bignum_bitcount(bignum)+8)/8; \
numlen = (bignum_bitcount(bignum)+8)/8; \
PUT_32BIT(lenbuf, numlen); MD5Update(&md5c, lenbuf, 4); \
for (i = numlen; i-- ;) { \
unsigned char c = bignum_byte(bignum, i); \
@ -417,7 +446,7 @@ static char *rsa2_fingerprint(void *key) {
MD5Final(digest, &md5c);
sprintf(buffer, "ssh-rsa %d ", ssh1_bignum_bitcount(rsa->modulus));
sprintf(buffer, "ssh-rsa %d ", bignum_bitcount(rsa->modulus));
for (i = 0; i < 16; i++)
sprintf(buffer+strlen(buffer), "%s%02x", i?":":"", digest[i]);
ret = smalloc(strlen(buffer)+1);
@ -476,7 +505,7 @@ static int rsa2_verifysig(void *key, char *sig, int siglen,
ret = 1;
bytes = ssh1_bignum_bitcount(rsa->modulus) / 8;
bytes = bignum_bitcount(rsa->modulus) / 8;
/* Top (partial) byte should be zero. */
if (bignum_byte(out, bytes-1) != 0)
ret = 0;
@ -513,7 +542,7 @@ unsigned char *rsa2_sign(void *key, char *data, int datalen, int *siglen) {
SHA_Simple(data, datalen, hash);
nbytes = (ssh1_bignum_bitcount(rsa->modulus)-1) / 8;
nbytes = (bignum_bitcount(rsa->modulus)-1) / 8;
bytes = smalloc(nbytes);
bytes[0] = 1;
@ -530,7 +559,7 @@ unsigned char *rsa2_sign(void *key, char *data, int datalen, int *siglen) {
out = modpow(in, rsa->private_exponent, rsa->modulus);
freebn(in);
nbytes = (ssh1_bignum_bitcount(out)+7)/8;
nbytes = (bignum_bitcount(out)+7)/8;
bytes = smalloc(4+7+4+nbytes);
PUT_32BIT(bytes, 7);
memcpy(bytes+4, "ssh-rsa", 7);
@ -551,6 +580,7 @@ const struct ssh_signkey ssh_rsa = {
rsa2_private_blob,
rsa2_createkey,
rsa2_openssh_createkey,
rsa2_openssh_fmtkey,
rsa2_fingerprint,
rsa2_verifysig,
rsa2_sign,

View File

@ -13,7 +13,7 @@ static void diagbn(char *prefix, Bignum md) {
printf("%s0x", prefix ? prefix : "");
nibbles = (3 + ssh1_bignum_bitcount(md))/4; if (nibbles<1) nibbles=1;
nibbles = (3 + bignum_bitcount(md))/4; if (nibbles<1) nibbles=1;
morenibbles = 4*md[0] - nibbles;
for (i=0; i<morenibbles; i++) putchar('-');
for (i=nibbles; i-- ;)