summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Kahn Gillmor <dkg@fifthhorseman.net>2008-02-09 22:57:55 -0500
committermike castleman <m@mlcastle.net>2008-02-09 22:57:55 -0500
commit0e9fcae8b7434972a6ae2d76a79136c24305d7c5 (patch)
tree1f89cafe28feb6cedde116eae686b91b2a22517a
initial import
-rw-r--r--.gitignore3
-rw-r--r--Makefile5
-rw-r--r--main.c244
-rw-r--r--test.key27
4 files changed, 279 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..d2cf588
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+*~
+*.[ao]
+monkeysphere
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..eb82821
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,5 @@
+monkeysphere: main.c
+ gcc -g -Wall --pedantic -o monkeysphere main.c `libgnutls-config --libs --cflags` -lgnutls-extra
+
+clean:
+ rm monkeysphere
diff --git a/main.c b/main.c
new file mode 100644
index 0000000..782e337
--- /dev/null
+++ b/main.c
@@ -0,0 +1,244 @@
+#include <gnutls/gnutls.h>
+#include <gnutls/openpgp.h>
+#include <gnutls/x509.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdarg.h>
+
+void err(const char* fmt, ...) {
+ static FILE* STDERR = NULL;
+ va_list ap;
+
+ if (NULL == STDERR)
+ STDERR = fdopen(STDERR_FILENO, "a");
+ va_start(ap, fmt);
+ vfprintf(STDERR, fmt, ap);
+ va_end(ap);
+}
+
+
+void init_datum(gnutls_datum_t* d) {
+ d->data = NULL;
+ d->size = 0;
+}
+void free_datum(gnutls_datum_t* d) {
+ gnutls_free(d->data);
+ d->data = NULL;
+ d->size = 0;
+}
+
+/* read the passed-in string, store in a single datum */
+int set_datum_string(gnutls_datum_t* d, const char* s) {
+ unsigned int x = strlen(s)+1;
+ unsigned char* c = NULL;
+
+ c = gnutls_realloc(d->data, x);
+ if (NULL == c)
+ return -1;
+ d->data = c;
+ d->size = x;
+ memcpy(d->data, s, x);
+ return 0;
+}
+
+/* read the passed-in file descriptor until EOF, store in a single
+ datum */
+int set_datum_fd(gnutls_datum_t* d, int fd) {
+ unsigned int bufsize = 1024;
+ unsigned int len = 0;
+
+ FILE* f = NULL;
+ if (bufsize > d->size) {
+ bufsize = 1024;
+ if (gnutls_realloc(d->data, bufsize) == NULL) {
+ err("out of memory!\n");
+ return -1;
+ }
+ d->size = bufsize;
+ } else {
+ bufsize = d->size;
+ }
+ f = fdopen(fd, "r");
+ while (!feof(f) && !ferror(f)) {
+ if (len == bufsize) {
+ /* allocate more space by doubling: */
+ bufsize *= 2;
+ if (gnutls_realloc(d->data, bufsize) == NULL) {
+ err("out of memory!\n");
+ return -1;
+ };
+ d->size = bufsize;
+ }
+ len += fread(d->data + len, 1, bufsize - len, f);
+ }
+ if (ferror(f)) {
+ err("Error reading from fd %d\n", fd);
+ return -1;
+ }
+ /* touch up buffer size to match reality: */
+ gnutls_realloc(d->data, len);
+ d->size = len;
+ return 0;
+}
+
+/* read the file indicated (by na1me) in the fname parameter. store
+ its entire contents in a single datum. */
+int set_datum_file(gnutls_datum_t* d, const char* fname) {
+ struct stat sbuf;
+ unsigned char* c = NULL;
+ FILE* file = NULL;
+ size_t x = 0;
+
+ if (0 != stat(fname, &sbuf)) {
+ err("failed to stat '%s'\n", fname);
+ return -1;
+ }
+
+ c = gnutls_realloc(d->data, sbuf.st_size);
+ if (NULL == c) {
+ err("failed to allocate %d bytes for '%s'\n", sbuf.st_size, fname);
+ return -1;
+ }
+
+ d->data = c;
+ d->size = sbuf.st_size;
+ file = fopen(fname, "r");
+ if (NULL == file) {
+ err("failed to open '%s' for reading\n", fname);
+ return -1;
+ }
+
+ x = fread(d->data, d->size, 1, file);
+ if (x != 1) {
+ err("tried to read %d bytes, read %d instead from '%s'\n", d->size, x, fname);
+ fclose(file);
+ return -1;
+ }
+ fclose(file);
+ return 0;
+}
+
+
+int main(int argc, char* argv[]) {
+ const char* version = NULL;
+
+ gnutls_x509_privkey_t x509_privkey;
+ gnutls_datum_t data;
+ int ret;
+
+ /*
+ const char *certfile, *keyfile;
+ gnutls_certificate_credentials_t pgp_creds;
+ */
+ gnutls_datum_t m, e, d, p, q, u;
+ gnutls_x509_crt_t crt;
+
+ gnutls_openpgp_privkey_t pgp_privkey;
+ gnutls_openpgp_crt_fmt_t pgp_format;
+ gnutls_pk_algorithm_t pgp_algo;
+ unsigned int pgp_bits;
+
+ char output_data[10240];
+ size_t ods = sizeof(output_data);
+
+ init_datum(&data);
+
+ if (ret = gnutls_global_init(), ret) {
+ err("Failed to do gnutls_global_init() (error: %d)\n", ret);
+ return 1;
+ }
+
+
+
+ version = gnutls_check_version(NULL);
+
+ if (version)
+ printf("gnutls version: %s\n", version);
+ else {
+ printf("no version found!\n");
+ return 1;
+ }
+
+ if (ret = gnutls_x509_privkey_init(&x509_privkey), ret) {
+ err("Failed to initialize X.509 private key (error: %d)\n", ret);
+ return 1;
+ }
+
+ if (ret = gnutls_openpgp_privkey_init(&pgp_privkey), ret) {
+ err("Failed to initialized OpenPGP private key (error: %d)\n", ret);
+ return 1;
+ }
+
+ /* how do we initialize data? */
+
+ /* reading from the file descriptor doesn't work right yet:
+ if (ret = set_datum_fd(&data, 0), ret) {
+ err("didn't read file descriptor 0\n");
+ return 1;
+ }
+ */
+
+ if (ret = set_datum_file(&data, argv[1]), ret) {
+ err("didn't read file '%s'\n", argv[1]);
+ return 1;
+ }
+
+ /* treat the passed file as an X.509 private key, and extract its
+ component values: */
+
+/* if (ret = gnutls_x509_privkey_import(x509_privkey, &data, GNUTLS_X509_FMT_PEM), ret) { */
+/* err("Failed to import the X.509 key (error: %d)\n", ret); */
+/* return 1; */
+/* } */
+/* gnutls_x509_privkey_export_rsa_raw(x509_privkey, &m, &e, &d, &p, &q, &u); */
+
+ /* try to print the PEM-encoded private key: */
+/* ret = gnutls_x509_privkey_export (x509_privkey, */
+/* GNUTLS_X509_FMT_PEM, */
+/* output_data, */
+/* &ods); */
+/* printf("ret: %u; ods: %u;\n", ret, ods); */
+/* if (ret == 0) { */
+/* write(0, output_data, ods); */
+/* } */
+
+
+ /* format could be either: GNUTLS_OPENPGP_FMT_RAW,
+ GNUTLS_OPENPGP_FMT_BASE64 */
+ pgp_format = GNUTLS_OPENPGP_FMT_RAW;
+ if (ret = gnutls_openpgp_privkey_import (pgp_privkey, &data, pgp_format, NULL, 0), ret) {
+ err("failed to import the OpenPGP private key (error: %d)\n", ret);
+ return 1;
+ }
+ pgp_algo = gnutls_openpgp_privkey_get_pk_algorithm(pgp_privkey, &pgp_bits);
+ if (pgp_algo < 0) {
+ err("failed to get OpenPGP key algorithm (error: %d)\n", pgp_algo);
+ return 1;
+ }
+ if (pgp_algo != GNUTLS_PK_RSA) {
+ err("OpenPGP Key was not RSA (actual algorithm was: %d)\n", pgp_algo);
+ return 1;
+ }
+
+ printf("OpenPGP RSA Key, with %d bits\n", pgp_bits);
+
+
+ ret = gnutls_x509_privkey_export (pgp_privkey,
+ GNUTLS_X509_FMT_PEM,
+ output_data,
+ &ods);
+ printf("ret: %u; ods: %u;\n", ret, ods);
+ if (ret == 0) {
+ write(0, output_data, ods);
+ }
+
+
+ gnutls_x509_privkey_deinit(x509_privkey);
+ gnutls_openpgp_privkey_deinit(pgp_privkey);
+ gnutls_global_deinit();
+ return 0;
+}
diff --git a/test.key b/test.key
new file mode 100644
index 0000000..4e05880
--- /dev/null
+++ b/test.key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEogIBAAKCAQEAxMv33LvWBZnKtahorHGYdBZqVxrNUQcVNrgxp4bf/FvgvSLG
+kBrw6wHFdVYvWWViD5efrJugqA4+pKp16LEWlc7JZICrou4vEJGkvoqBIJC/4cVN
+xcwV1a8jo9ZOYjt0JIyuHrEDGW/edQYWI41XO/H+QdMDsdI+oOmfPV/V4eMyjGKH
+vRJ+xDae5izhUb3Lb00YnxpP2n/zhvHpn7weu+bzvwb3pMMo9336Ft7m5ulGPJzN
++3l595LW+lUSDUlUJbACp4Nyn+i9ODPV6xzghzirsh7rnD8jD2kaqIVkcvEhusoB
+JN3daPXt9t6m5cfsCWu31BXdbpTWiLIZRUxDzQIBIwKCAQEAl9CMAg0+s90KFxuD
+8r4H5IZSCK5GnZe/6GI07vMEj3oTxRrTsP7XG7DoyDsr1z+UyjMjZ+XFE+27S9P0
+ju8Cy1Zg2ICEZ78OXT0nUSkEhtYQXbV2gqTAYwNzQ9/WEUPOn9o9LZ5+u9n0wKzs
+gdNvLj5WbUsC2aIwUD8xswDJkP5cA4RfKo8Mz40aXbK6b+S/bOKEkXRFvOor46pl
+A8GHxUVcUPUG7LAXCm1FWrDob6FTlv3yW8DeVTCYwt6HdrTmc9b+yOinwMR6ZvUz
+R6AESGG7czCvA6rpkCcprfCPx0gfntuzLiGRtl54GvbYWWtPDlxnPwcw1zcSALvM
+pJNpawKBgQD/zze04kYZBNDTxolBrZltpPXtPpOrG2Otp8CHreOKn0TifCFPDnCb
+ewUhxuDRA+L9KPLT311DtHfIzXJ8/RD6K/QE72ny39h2X2Pn2hWSgb9+iysHBDNc
+jb136QFoKQcpqUpLEfTvA71Yqvuk6gsYiuWnIN5KJwy/AhwFQnK/WQKBgQDE8X87
+C+0JSg2ybUopOQVSrvildJEa8CWbM1SAL1j3E24U2fPh+zVmIxqa2m4X/PxFBBTv
+WVGayzFkmJK2Dgt7F7hBqi5HelP0B38dXtkPlK6idTALNHoS/7HCDXISgHmDOhcQ
+LHGQUuQMkTq6H4cOMwTNO5aM2zc5E9uF/hptlQKBgEHHkftQIKdZAn+Zc8Bud+j+
+iGGTv5JmIPIj0mwIJJFcJ6f0CJCr8RIJsNzMvXeTSP9FCz3LuOWGLW4mM2H37mw3
+MB6GtNgNrLC5cXYiIs3m2XhPq/p9bEr/4ENnzSlposGR7ohVExjjtFig/uFDfzIy
+WE+MG+cunOCoxWBwLCKTAoGBALQP/0vtpYTV/eT2NS0A7uyCt3Kzt94dZDYgTUH/
+Z0hMR2OFcUOj2Qzs5R/dpnxVA+dUMGXOAXeVNHk7CcsFhtbxHX3dbCQYEj4yvVyu
+fVAS6M8MDqsoqh//uHbnuMB1dmlZrq+zmwecPjdgNbF76TGNuz9MbGOGmOO6Yk6f
+LhsLAoGAJoK+yRDaEFDwrjdvGazEy/d1CtknkGY2r4vb8giEodFJcQQhtVtjnYPl
+gDIpbcpeT0GDiZd0pxAxpibbKM63pYz8PKtlq0B/qXgArRgJnbku01Jc4iLVWPqK
+qitRgsz1HdN2tIqa8oQE0iuvyoq+r6+pqcQJd7sc6lKlk0gO0Mo=
+-----END RSA PRIVATE KEY-----