From ddecd643be56256929ae1c45bebb8e39ae032225 Mon Sep 17 00:00:00 2001 From: simon Date: Mon, 16 Apr 2001 11:16:58 +0000 Subject: [PATCH] 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'. git-svn-id: svn://svn.tartarus.org/sgt/putty@1044 cda61777-01e9-0310-a592-d414129be87e --- Makefile | 2 +- pageant.c | 322 +++++++++++++++++++++++++++++++++++++++++++++++-------------- puttygen.c | 2 +- ssh.c | 4 +- ssh.h | 3 +- sshbn.c | 19 ++-- sshdh.c | 2 +- sshdss.c | 33 ++++--- sshpubk.c | 2 +- sshrsa.c | 62 +++++++++--- sshrsag.c | 2 +- 11 files changed, 336 insertions(+), 117 deletions(-) diff --git a/Makefile b/Makefile index b1261d25..9ff9aecc 100644 --- a/Makefile +++ b/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) diff --git a/pageant.c b/pageant.c index 370c099a..aad42263 100644 --- a/pageant.c +++ b/pageant.c @@ -9,6 +9,17 @@ #include #include #include +#include + +// 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; - - RegisterClass (&wndclass); - } + /* + * Find out if Pageant is already running. + */ + already_running = FALSE; + if (FindWindow("Pageant", "Pageant")) + already_running = TRUE; + else { + + 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; + + RegisterClass (&wndclass); + } - hwnd = keylist = NULL; + hwnd = keylist = NULL; - hwnd = CreateWindow (APPNAME, APPNAME, - WS_OVERLAPPEDWINDOW | WS_VSCROLL, - CW_USEDEFAULT, CW_USEDEFAULT, - 100, 100, NULL, NULL, inst, NULL); + 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; + /* 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)"); - - res = Shell_NotifyIcon(NIM_ADD, &tnid); - - 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"); - } + 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); + + 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); + ShowWindow (hwnd, SW_HIDE); - /* - * Initialise storage for RSA keys. - */ - rsakeys = newtree234(cmpkeys_rsa); - ssh2keys = newtree234(cmpkeys_ssh2); + /* + * 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. */ diff --git a/puttygen.c b/puttygen.c index 19245f80..ac5079e0 100644 --- a/puttygen.c +++ b/puttygen.c @@ -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); diff --git a/ssh.c b/ssh.c index e6b0bcc4..08ff8d97 100644 --- a/ssh.c +++ b/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); diff --git a/ssh.h b/ssh.h index cdb37800..3c4791fb 100644 --- a/ssh.h +++ b/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); diff --git a/sshbn.c b/sshbn.c index 1bd3f434..2fd98f91 100644 --- a/sshbn.c +++ b/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 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(); diff --git a/sshdss.c b/sshdss.c index d85d0007..672a2574 100644 --- a/sshdss.c +++ b/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, diff --git a/sshpubk.c b/sshpubk.c index 30be7d3d..ed16534d 100644 --- a/sshpubk.c +++ b/sshpubk.c @@ -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); diff --git a/sshrsa.c b/sshrsa.c index fa5bfa25..7f1d790e 100644 --- a/sshrsa.c +++ b/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, diff --git a/sshrsag.c b/sshrsag.c index 88a3d839..03f416ab 100644 --- a/sshrsag.c +++ b/sshrsag.c @@ -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