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:
parent
fb8745a7d7
commit
522f130391
2
Makefile
2
Makefile
@ -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
316
pageant.c
@ -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.
|
||||
*/
|
||||
|
@ -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
4
ssh.c
@ -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
3
ssh.h
@ -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
19
sshbn.c
@ -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);
|
||||
|
2
sshdh.c
2
sshdh.c
@ -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();
|
||||
|
33
sshdss.c
33
sshdss.c
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
|
62
sshrsa.c
62
sshrsa.c
@ -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,
|
||||
|
@ -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-- ;)
|
||||
|
Loading…
Reference in New Issue
Block a user