From c7598e8c83de574816c8198b9f99d6435bd62359 Mon Sep 17 00:00:00 2001 From: Scott Baker Date: Wed, 12 Nov 2008 22:09:16 +0000 Subject: [PATCH] check in keyconvert tool --- keyconvert/Makefile | 5 ++ keyconvert/b64decode.c | 62 ++++++++++++++++++ keyconvert/b64decode.h | 7 ++ keyconvert/keyconvert.c | 126 ++++++++++++++++++++++++++++++++++++ keyconvert/keyconvert.h | 6 ++ keyconvert/keyconvertext.c | 34 ++++++++++ keyconvert/keyconvertmain.c | 65 +++++++++++++++++++ 7 files changed, 305 insertions(+) create mode 100644 keyconvert/Makefile create mode 100644 keyconvert/b64decode.c create mode 100644 keyconvert/b64decode.h create mode 100644 keyconvert/keyconvert.c create mode 100644 keyconvert/keyconvert.h create mode 100644 keyconvert/keyconvertext.c create mode 100644 keyconvert/keyconvertmain.c diff --git a/keyconvert/Makefile b/keyconvert/Makefile new file mode 100644 index 00000000..eda3f9b7 --- /dev/null +++ b/keyconvert/Makefile @@ -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 index 00000000..07dc4520 --- /dev/null +++ b/keyconvert/b64decode.c @@ -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) +{ + int k,k2,i; + + i=0; + while (*s!='\0') { + /* byte #1 */ + if ((*s=='=') || ((k=pcharmap[(unsigned char) (*(s++))])<0)) + return -1; + + /* byte #2 */ + if ((*s=='=') || ((k2=pcharmap[(unsigned char) (*(s++))])<0)) + return -1; + else + dest[i++] = (k<<2) + (k2>>4); + + /* byte #3 */ + if (*s=='=') + s++; + else + if ((k=pcharmap[(unsigned char) (*(s++))])<0) + return -1; + else + dest[i++] = (k2<<4) + (k>>2); + + /* byte #4 */ + if (*s=='=') + s++; + else + if ((k2=pcharmap[(unsigned char) (*(s++))])<0) + -1; + else + dest[i++] = (k<<6) + (k2); + } + + return i; +} diff --git a/keyconvert/b64decode.h b/keyconvert/b64decode.h new file mode 100644 index 00000000..b93a2521 --- /dev/null +++ b/keyconvert/b64decode.h @@ -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 index 00000000..b2fdfd1b --- /dev/null +++ b/keyconvert/keyconvert.c @@ -0,0 +1,126 @@ +#include +#include +#include +#include + +#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 index 00000000..eb942cba --- /dev/null +++ b/keyconvert/keyconvert.h @@ -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 index 00000000..d2c9e13a --- /dev/null +++ b/keyconvert/keyconvertext.c @@ -0,0 +1,34 @@ +#include + +#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 index 00000000..d59dba8b --- /dev/null +++ b/keyconvert/keyconvertmain.c @@ -0,0 +1,65 @@ +#include +#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 \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; +} -- 2.43.0