Pageant interface changes. You can now do `pageant -c command' to
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Mon, 16 Apr 2001 11:16:58 +0000 (11:16 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Mon, 16 Apr 2001 11:16:58 +0000 (11:16 +0000)
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
pageant.c
puttygen.c
ssh.c
ssh.h
sshbn.c
sshdh.c
sshdss.c
sshpubk.c
sshrsa.c
sshrsag.c

index b1261d2..9ff9aec 100644 (file)
--- 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)
index 370c099..aad4226 100644 (file)
--- a/pageant.c
+++ b/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;
-
-       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.
      */
index 19245f8..ac5079e 100644 (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);
diff --git a/ssh.c b/ssh.c
index e6b0bcc..08ff8d9 100644 (file)
--- 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 cdb3780..3c4791f 100644 (file)
--- 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 1bd3f43..2fd98f9 100644 (file)
--- 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<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);
diff --git a/sshdh.c b/sshdh.c
index 0beac6c..845a72b 100644 (file)
--- a/sshdh.c
+++ b/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();
index d85d000..672a257 100644 (file)
--- 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,
index 30be7d3..ed16534 100644 (file)
--- 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);
 
index fa5bfa2..7f1d790 100644 (file)
--- 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,
index 88a3d83..03f416a 100644 (file)
--- 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<morenibbles; i++) putchar('-');
     for (i=nibbles; i-- ;)