--- /dev/null
+#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;
+ }
+}
+
--- /dev/null
+#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);
+}
+
--- /dev/null
+#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;
+}