check in keyconvert tool
Scott Baker [Wed, 12 Nov 2008 22:09:16 +0000 (22:09 +0000)]
keyconvert/Makefile [new file with mode: 0644]
keyconvert/b64decode.c [new file with mode: 0644]
keyconvert/b64decode.h [new file with mode: 0644]
keyconvert/keyconvert.c [new file with mode: 0644]
keyconvert/keyconvert.h [new file with mode: 0644]
keyconvert/keyconvertext.c [new file with mode: 0644]
keyconvert/keyconvertmain.c [new file with mode: 0644]

diff --git a/keyconvert/Makefile b/keyconvert/Makefile
new file mode 100644 (file)
index 0000000..eda3f9b
--- /dev/null
@@ -0,0 +1,5 @@
+keyconvert:
+       gcc -o keyconvert keyconvert.c keyconvertmain.c b64decode.c /usr/lib/libcrypto.a
+
+clean:
+       rm -rf keyconvert
diff --git a/keyconvert/b64decode.c b/keyconvert/b64decode.c
new file mode 100644 (file)
index 0000000..07dc452
--- /dev/null
@@ -0,0 +1,62 @@
+#include "b64decode.h"
+
+#define UNDEF_CH -2
+
+char s64table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+int     charmap[257];
+int     *pcharmap;
+
+void b64decodeinit()
+{
+   int i;
+   char ch;
+
+   pcharmap= charmap + 1;
+
+  for (i = 0; i <= 255; i++)
+    pcharmap[i] = UNDEF_CH;
+
+  for (i = 0; i < 64; i++) {
+    ch = s64table[i];
+    if (pcharmap[ch] == UNDEF_CH)
+      pcharmap[ch] = i;
+  }
+}
+
+int b64decode(char *s, char *dest)
+{\r
+  int k,k2,i;\r
+\r
+  i=0;\r
+  while (*s!='\0') {\r
+    /* byte #1 */\r
+    if ((*s=='=') || ((k=pcharmap[(unsigned char) (*(s++))])<0))\r
+      return -1;\r
+\r
+    /* byte #2 */\r
+    if ((*s=='=') || ((k2=pcharmap[(unsigned char) (*(s++))])<0))\r
+      return -1;\r
+    else\r
+      dest[i++] = (k<<2) + (k2>>4);\r
+\r
+    /* byte #3 */\r
+    if (*s=='=')\r
+      s++;\r
+    else\r
+      if ((k=pcharmap[(unsigned char) (*(s++))])<0)\r
+       return -1;\r
+      else\r
+       dest[i++] = (k2<<4) + (k>>2);\r
+\r
+    /* byte #4 */\r
+    if (*s=='=')\r
+      s++;\r
+    else\r
+      if ((k2=pcharmap[(unsigned char) (*(s++))])<0)\r
+       -1;\r
+      else\r
+       dest[i++] = (k<<6) + (k2);\r
+  }\r
+\r
+  return i;\r
+}
diff --git a/keyconvert/b64decode.h b/keyconvert/b64decode.h
new file mode 100644 (file)
index 0000000..b93a252
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef __B64DECODE_H
+#define __B64DECODE_H
+
+void b64decodeinit();
+int b64decode(char *s, char *dest);
+
+#endif
diff --git a/keyconvert/keyconvert.c b/keyconvert/keyconvert.c
new file mode 100644 (file)
index 0000000..b2fdfd1
--- /dev/null
@@ -0,0 +1,126 @@
+#include <stdlib.h>
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+
+#ifndef TRUE
+#define TRUE 1
+#define FALSE (!TRUE)
+#endif
+
+void write_rsa(FILE *fout, char *estr, int elen, char *nstr, int nlen)
+{
+    RSA *rsa;
+    BIGNUM *r1, *r2;
+
+    rsa = RSA_new();
+    rsa->e = BN_new();
+    rsa->n = BN_new();
+
+    r1 = BN_bin2bn(estr, elen, rsa->e);
+    r2 = BN_bin2bn(nstr, nlen, rsa->n);
+
+    PEM_write_RSA_PUBKEY(fout, rsa);
+
+    // free rsa ?
+}
+
+void write_dsa(FILE *fout, char *pstr, int plen, char *qstr, int qlen, char *gstr, int glen, char *pkstr, int pklen)
+{
+    DSA *dsa;
+
+    dsa = DSA_new();
+    dsa->p = BN_new();
+    dsa->q = BN_new();
+    dsa->g = BN_new();
+    dsa->pub_key = BN_new();
+
+    BN_bin2bn(pstr, plen, dsa->p);
+    BN_bin2bn(qstr, qlen, dsa->q);
+    BN_bin2bn(gstr, glen, dsa->g);
+    BN_bin2bn(pkstr, pklen, dsa->pub_key);
+
+    PEM_write_DSA_PUBKEY(fout, dsa);
+
+    // free dsa ?
+}
+
+int get_str(char **src, int *len, char *dest)
+{
+   int *iptr = (int*) (*src);
+   int thislen = ntohl(*iptr);
+
+   // eat 4 bytes
+   (*len) -= 4;
+   (*src) = (*src) + 4;
+
+//   fprintf(stdout, "thislen = %d\n", thislen);
+
+   if (thislen > *len) {
+       fprintf(stdout, "thislen(%d) > *len(%d)\n", thislen, *len);
+       return -1;
+   }
+
+   memcpy(dest, *src, thislen);
+
+   (*len) = (*len) - thislen;
+   (*src) = (*src) + thislen;
+
+   // null terminate it
+   *(dest + thislen) = '\0';
+
+   return thislen;
+}
+
+int openssh_binary_to_openssl(char *s, int len, FILE *fout)
+{
+    char keytype[1024], estr[1024], nstr[1024], pstr[1024], qstr[1024], gstr[1024], pkstr[1024];
+    int elen, nlen, plen, qlen, glen, pklen;
+    int result;
+
+    result = get_str(&s, &len, keytype);
+    if (result <= 0) {
+        return FALSE;
+    }
+
+    fprintf(stdout, "keytype = %s\n", keytype);
+
+    if (strcmp(keytype, "ssh-rsa") == 0) {
+        elen = get_str(&s, &len, estr);
+//        fprintf(stdout, "elen = %d\n", elen);
+        if (elen <= 0) {
+            return FALSE;
+        }
+        nlen = get_str(&s, &len, nstr);
+//        fprintf(stdout, "nlen = %d\n", nlen);
+        if (nlen <= 0) {
+            return FALSE;
+        }
+        write_rsa(fout, estr, elen, nstr, nlen);
+    } else if (strcmp(keytype, "ssh-dss") == 0) {
+        plen = get_str(&s, &len, pstr);
+//        fprintf(stdout, "plen = %d\n", plen);
+        if (plen <= 0) {
+            return FALSE;
+        }
+        qlen = get_str(&s, &len, qstr);
+//        fprintf(stdout, "qlen = %d\n", qlen);
+        if (qlen <= 0) {
+            return FALSE;
+        }
+        glen = get_str(&s, &len, gstr);
+//        fprintf(stdout, "glen = %d\n", glen);
+        if (glen <= 0) {
+            return FALSE;
+        }
+        pklen = get_str(&s, &len, pkstr);
+//        fprintf(stdout, "pklen = %d\n", pklen);
+        if (pklen <= 0) {
+            return FALSE;
+        }
+        write_dsa(fout, pstr, plen, qstr, qlen, gstr, glen, pkstr, pklen);
+    } else {
+        return FALSE;
+    }
+}
+
diff --git a/keyconvert/keyconvert.h b/keyconvert/keyconvert.h
new file mode 100644 (file)
index 0000000..eb942cb
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef _KEYCONVERT_H
+#define _KEYCONVERT_H
+
+int openssh_binary_to_openssl(char *s, int len, FILE *fout);
+
+#endif
diff --git a/keyconvert/keyconvertext.c b/keyconvert/keyconvertext.c
new file mode 100644 (file)
index 0000000..d2c9e13
--- /dev/null
@@ -0,0 +1,34 @@
+#include <python2.3/Python.h>
+
+#include "keyconvert.h"
+
+static PyObject *keyconvert_opensshtoopenssl(PyObject *self, PyObject *args)
+{
+    const char *fn;
+    const char *s;
+    int len;
+    FILE *fout;
+
+    PyArg_ParseTuple(args, "ss#", &fn, &s, &len);
+
+    fout = fopen(fn, "wt");
+    if (fout == NULL) {
+        return Py_BuildValue("i", 0);
+    } else {
+        fprintf(stdout, "len = %d\n", len);
+        openssh_binary_to_openssl(s, len, fout);
+        fclose(fout);
+    }
+
+    return Py_BuildValue("i", 1);
+}
+
+static PyMethodDef KeyConvertMethods[] = {
+    {"opensshtoopenssl", keyconvert_opensshtoopenssl, METH_VARARGS, "convert an openssh key to an openssl key"},
+    {NULL, NULL, 0, NULL}};
+
+PyMODINIT_FUNC initkeyconvert(void)
+{
+    (void) Py_InitModule("keyconvert", KeyConvertMethods);
+}
+
diff --git a/keyconvert/keyconvertmain.c b/keyconvert/keyconvertmain.c
new file mode 100644 (file)
index 0000000..d59dba8
--- /dev/null
@@ -0,0 +1,65 @@
+#include <stdio.h>
+#include "keyconvert.h"
+#include "b64decode.h"
+
+int main(int argc, char **argv)
+{
+    FILE *fin, *fout;
+    char inbytes[16384], *inptr;
+    char decodedKey[16384];
+    int len;
+
+    b64decodeinit();
+
+    if (argc != 3) {
+        fprintf(stderr, "syntax: keyconvert <infile> <outfile>\n");
+        exit(1);
+    }
+
+    fin = fopen(argv[1], "rt");
+    if (fin == NULL) {
+        fprintf(stderr, "failed to open %s\n", argv[1]);
+        exit(1);
+    }
+
+    memset(inbytes, 0, sizeof(inbytes));
+    len = fread(inbytes, 1, sizeof(inbytes), fin);
+    fclose(fin);
+
+ //   fprintf(stdout, "read %d bytes from openssh file\n", len);
+
+    inptr = inbytes;
+
+    // skip leading space
+    while (isspace(*inptr)) inptr++;
+
+    // skip the ssh-rsa or ssh-dsa part
+    while (*inptr && !isspace(*inptr)) inptr++;
+
+    // skip spaces between ssh-rsa/ssh-dsa and key
+    while (isspace(*inptr)) inptr++;
+
+    // if there is any part after the key, terminate it
+    if (strchr(inptr, ' ') != NULL) {
+        *strchr(inptr, ' ') = '\0';
+    }
+
+    // at this point, inptr contains the b64 encoded openssh key
+
+    len = b64decode(inptr, decodedKey);
+
+//    fprintf(stdout, "decoded openssh file length is %d\n", len);
+
+    fout = fopen(argv[2], "wt");
+    if (fout == NULL) {
+        fprintf(stderr, "failed to open output file %s\n", argv[2]);
+        exit(1);
+    }
+
+    openssh_binary_to_openssl(decodedKey, len, fout);
+
+    fclose(fout);
+
+    fprintf(stdout, "completed\n");
+    return 0;
+}