summaryrefslogtreecommitdiff
path: root/main.c
blob: 782e33766eaa9470a1f778b8885b6c61be29b3a6 (plain)
  1. #include <gnutls/gnutls.h>
  2. #include <gnutls/openpgp.h>
  3. #include <gnutls/x509.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <sys/types.h>
  8. #include <sys/stat.h>
  9. #include <unistd.h>
  10. #include <stdarg.h>
  11. void err(const char* fmt, ...) {
  12. static FILE* STDERR = NULL;
  13. va_list ap;
  14. if (NULL == STDERR)
  15. STDERR = fdopen(STDERR_FILENO, "a");
  16. va_start(ap, fmt);
  17. vfprintf(STDERR, fmt, ap);
  18. va_end(ap);
  19. }
  20. void init_datum(gnutls_datum_t* d) {
  21. d->data = NULL;
  22. d->size = 0;
  23. }
  24. void free_datum(gnutls_datum_t* d) {
  25. gnutls_free(d->data);
  26. d->data = NULL;
  27. d->size = 0;
  28. }
  29. /* read the passed-in string, store in a single datum */
  30. int set_datum_string(gnutls_datum_t* d, const char* s) {
  31. unsigned int x = strlen(s)+1;
  32. unsigned char* c = NULL;
  33. c = gnutls_realloc(d->data, x);
  34. if (NULL == c)
  35. return -1;
  36. d->data = c;
  37. d->size = x;
  38. memcpy(d->data, s, x);
  39. return 0;
  40. }
  41. /* read the passed-in file descriptor until EOF, store in a single
  42. datum */
  43. int set_datum_fd(gnutls_datum_t* d, int fd) {
  44. unsigned int bufsize = 1024;
  45. unsigned int len = 0;
  46. FILE* f = NULL;
  47. if (bufsize > d->size) {
  48. bufsize = 1024;
  49. if (gnutls_realloc(d->data, bufsize) == NULL) {
  50. err("out of memory!\n");
  51. return -1;
  52. }
  53. d->size = bufsize;
  54. } else {
  55. bufsize = d->size;
  56. }
  57. f = fdopen(fd, "r");
  58. while (!feof(f) && !ferror(f)) {
  59. if (len == bufsize) {
  60. /* allocate more space by doubling: */
  61. bufsize *= 2;
  62. if (gnutls_realloc(d->data, bufsize) == NULL) {
  63. err("out of memory!\n");
  64. return -1;
  65. };
  66. d->size = bufsize;
  67. }
  68. len += fread(d->data + len, 1, bufsize - len, f);
  69. }
  70. if (ferror(f)) {
  71. err("Error reading from fd %d\n", fd);
  72. return -1;
  73. }
  74. /* touch up buffer size to match reality: */
  75. gnutls_realloc(d->data, len);
  76. d->size = len;
  77. return 0;
  78. }
  79. /* read the file indicated (by na1me) in the fname parameter. store
  80. its entire contents in a single datum. */
  81. int set_datum_file(gnutls_datum_t* d, const char* fname) {
  82. struct stat sbuf;
  83. unsigned char* c = NULL;
  84. FILE* file = NULL;
  85. size_t x = 0;
  86. if (0 != stat(fname, &sbuf)) {
  87. err("failed to stat '%s'\n", fname);
  88. return -1;
  89. }
  90. c = gnutls_realloc(d->data, sbuf.st_size);
  91. if (NULL == c) {
  92. err("failed to allocate %d bytes for '%s'\n", sbuf.st_size, fname);
  93. return -1;
  94. }
  95. d->data = c;
  96. d->size = sbuf.st_size;
  97. file = fopen(fname, "r");
  98. if (NULL == file) {
  99. err("failed to open '%s' for reading\n", fname);
  100. return -1;
  101. }
  102. x = fread(d->data, d->size, 1, file);
  103. if (x != 1) {
  104. err("tried to read %d bytes, read %d instead from '%s'\n", d->size, x, fname);
  105. fclose(file);
  106. return -1;
  107. }
  108. fclose(file);
  109. return 0;
  110. }
  111. int main(int argc, char* argv[]) {
  112. const char* version = NULL;
  113. gnutls_x509_privkey_t x509_privkey;
  114. gnutls_datum_t data;
  115. int ret;
  116. /*
  117. const char *certfile, *keyfile;
  118. gnutls_certificate_credentials_t pgp_creds;
  119. */
  120. gnutls_datum_t m, e, d, p, q, u;
  121. gnutls_x509_crt_t crt;
  122. gnutls_openpgp_privkey_t pgp_privkey;
  123. gnutls_openpgp_crt_fmt_t pgp_format;
  124. gnutls_pk_algorithm_t pgp_algo;
  125. unsigned int pgp_bits;
  126. char output_data[10240];
  127. size_t ods = sizeof(output_data);
  128. init_datum(&data);
  129. if (ret = gnutls_global_init(), ret) {
  130. err("Failed to do gnutls_global_init() (error: %d)\n", ret);
  131. return 1;
  132. }
  133. version = gnutls_check_version(NULL);
  134. if (version)
  135. printf("gnutls version: %s\n", version);
  136. else {
  137. printf("no version found!\n");
  138. return 1;
  139. }
  140. if (ret = gnutls_x509_privkey_init(&x509_privkey), ret) {
  141. err("Failed to initialize X.509 private key (error: %d)\n", ret);
  142. return 1;
  143. }
  144. if (ret = gnutls_openpgp_privkey_init(&pgp_privkey), ret) {
  145. err("Failed to initialized OpenPGP private key (error: %d)\n", ret);
  146. return 1;
  147. }
  148. /* how do we initialize data? */
  149. /* reading from the file descriptor doesn't work right yet:
  150. if (ret = set_datum_fd(&data, 0), ret) {
  151. err("didn't read file descriptor 0\n");
  152. return 1;
  153. }
  154. */
  155. if (ret = set_datum_file(&data, argv[1]), ret) {
  156. err("didn't read file '%s'\n", argv[1]);
  157. return 1;
  158. }
  159. /* treat the passed file as an X.509 private key, and extract its
  160. component values: */
  161. /* if (ret = gnutls_x509_privkey_import(x509_privkey, &data, GNUTLS_X509_FMT_PEM), ret) { */
  162. /* err("Failed to import the X.509 key (error: %d)\n", ret); */
  163. /* return 1; */
  164. /* } */
  165. /* gnutls_x509_privkey_export_rsa_raw(x509_privkey, &m, &e, &d, &p, &q, &u); */
  166. /* try to print the PEM-encoded private key: */
  167. /* ret = gnutls_x509_privkey_export (x509_privkey, */
  168. /* GNUTLS_X509_FMT_PEM, */
  169. /* output_data, */
  170. /* &ods); */
  171. /* printf("ret: %u; ods: %u;\n", ret, ods); */
  172. /* if (ret == 0) { */
  173. /* write(0, output_data, ods); */
  174. /* } */
  175. /* format could be either: GNUTLS_OPENPGP_FMT_RAW,
  176. GNUTLS_OPENPGP_FMT_BASE64 */
  177. pgp_format = GNUTLS_OPENPGP_FMT_RAW;
  178. if (ret = gnutls_openpgp_privkey_import (pgp_privkey, &data, pgp_format, NULL, 0), ret) {
  179. err("failed to import the OpenPGP private key (error: %d)\n", ret);
  180. return 1;
  181. }
  182. pgp_algo = gnutls_openpgp_privkey_get_pk_algorithm(pgp_privkey, &pgp_bits);
  183. if (pgp_algo < 0) {
  184. err("failed to get OpenPGP key algorithm (error: %d)\n", pgp_algo);
  185. return 1;
  186. }
  187. if (pgp_algo != GNUTLS_PK_RSA) {
  188. err("OpenPGP Key was not RSA (actual algorithm was: %d)\n", pgp_algo);
  189. return 1;
  190. }
  191. printf("OpenPGP RSA Key, with %d bits\n", pgp_bits);
  192. ret = gnutls_x509_privkey_export (pgp_privkey,
  193. GNUTLS_X509_FMT_PEM,
  194. output_data,
  195. &ods);
  196. printf("ret: %u; ods: %u;\n", ret, ods);
  197. if (ret == 0) {
  198. write(0, output_data, ods);
  199. }
  200. gnutls_x509_privkey_deinit(x509_privkey);
  201. gnutls_openpgp_privkey_deinit(pgp_privkey);
  202. gnutls_global_deinit();
  203. return 0;
  204. }