initial import
authorDaniel Kahn Gillmor <dkg@fifthhorseman.net>
Sun, 10 Feb 2008 03:57:55 +0000 (22:57 -0500)
committermike castleman <m@mlcastle.net>
Sun, 10 Feb 2008 03:57:55 +0000 (22:57 -0500)
.gitignore [new file with mode: 0644]
Makefile [new file with mode: 0644]
main.c [new file with mode: 0644]
test.key [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..d2cf588
--- /dev/null
@@ -0,0 +1,3 @@
+*~
+*.[ao]
+monkeysphere
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
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 (file)
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 (file)
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-----