a2f8446c614653509c0c0e3c1db91356ab5d9fca
[monkeysphere.git] / gnutls-helpers.c
1 /* Author: Daniel Kahn Gillmor <dkg@fifthhorseman.net> */
2 /* Date: Fri, 04 Apr 2008 19:31:16 -0400 */
3 /* License: GPL v3 or later */
4
5 #include "gnutls-helpers.h"
6
7 int loglevel = 0;
8
9
10 void err(const char* fmt, ...) {
11   va_list ap;
12   va_start(ap, fmt);
13   vfprintf(stderr, fmt, ap);
14   va_end(ap);
15 }
16
17 void logfunc(int level, const char* string) {
18   fprintf(stderr, "GnuTLS Logging (%d): %s\n", level, string);
19 }
20
21 void init_keyid(gnutls_openpgp_keyid_t keyid) {
22   memset(keyid, 'x', sizeof(gnutls_openpgp_keyid_t));
23 }
24
25
26
27 void make_keyid_printable(printable_keyid out, gnutls_openpgp_keyid_t keyid)
28 {
29   static const char hex[16] = "0123456789ABCDEF";
30   unsigned int kix = 0, outix = 0;
31   
32   while (kix < sizeof(gnutls_openpgp_keyid_t)) {
33     out[outix] = hex[(keyid[kix] >> 4) & 0x0f];
34     out[outix + 1] = hex[keyid[kix] & 0x0f];
35     kix++;
36     outix += 2;
37   }
38 }
39
40
41 int init_gnutls() {
42   const char* version = NULL;
43   const char* debug_string = NULL;
44   int ret;
45
46   if (ret = gnutls_global_init(), ret) {
47     err("Failed to do gnutls_global_init() (error: %d)\n", ret);
48     return 1;
49   }
50
51   version = gnutls_check_version(NULL);
52
53   if (version) 
54     err("gnutls version: %s\n", version);
55   else {
56     err("no version found!\n");
57     return 1;
58   }
59
60   if (debug_string = getenv("MONKEYSPHERE_DEBUG"), debug_string) {
61     loglevel = atoi(debug_string);
62     gnutls_global_set_log_function(logfunc);
63     
64     gnutls_global_set_log_level(loglevel);
65     err("set log level to %d\n", loglevel);
66   }
67   return 0;
68 }
69
70 void init_datum(gnutls_datum_t* d) {
71   d->data = NULL;
72   d->size = 0;
73 }
74 void copy_datum(gnutls_datum_t* dest, const gnutls_datum_t* src) {
75   dest->data = gnutls_realloc(dest->data, src->size);
76   dest->size = src->size;
77   memcpy(dest->data, src->data, src->size);
78 }
79 int compare_data(const gnutls_datum_t* a, const gnutls_datum_t* b) {
80   if (a->size > b->size) {
81     err("a is larger\n");
82     return 1;
83   }
84   if (a->size < b->size) {
85     err("b is larger\n");
86     return -1;
87   }
88   return memcmp(a->data, b->data, a->size);
89 }
90 void free_datum(gnutls_datum_t* d) {
91   gnutls_free(d->data);
92   d->data = NULL;
93   d->size = 0;
94 }
95
96 /* read the passed-in string, store in a single datum */
97 int set_datum_string(gnutls_datum_t* d, const char* s) {
98   unsigned int x = strlen(s)+1;
99   unsigned char* c = NULL;
100
101   c = gnutls_realloc(d->data, x);
102   if (NULL == c)
103     return -1;
104   d->data = c;
105   d->size = x;
106   memcpy(d->data, s, x);
107   return 0;
108 }
109
110 /* read the passed-in file descriptor until EOF, store in a single
111    datum */
112 int set_datum_fd(gnutls_datum_t* d, int fd) {
113   unsigned int bufsize = 1024;
114   unsigned int len = 0;
115
116   FILE* f = fdopen(fd, "r");
117   if (bufsize > d->size) {
118     bufsize = 1024;
119     d->data = gnutls_realloc(d->data, bufsize);
120     if (d->data == NULL) {
121       err("out of memory!\n");
122       return -1;
123     }
124     d->size = bufsize;
125   } else {
126     bufsize = d->size;
127   }
128   f = fdopen(fd, "r");
129   if (NULL == f) {
130     err("could not fdopen FD %d\n", fd);
131   }
132   clearerr(f);
133   while (!feof(f) && !ferror(f)) { 
134     if (len == bufsize) {
135       /* allocate more space by doubling: */
136       bufsize *= 2;
137       d->data = gnutls_realloc(d->data, bufsize);
138       if (d->data == NULL) {
139         err("out of memory!\n"); 
140         return -1;
141       };
142       d->size = bufsize;
143     }
144     len += fread(d->data + len, 1, bufsize - len, f);
145     /*     err("read %d bytes\n", len); */
146   }
147   if (ferror(f)) {
148     err("Error reading from fd %d (error: %d) (error: %d '%s')\n", fd, ferror(f), errno, strerror(errno));
149     return -1;
150   }
151     
152   /* touch up buffer size to match reality: */
153   d->data = gnutls_realloc(d->data, len);
154   d->size = len;
155   return 0;
156 }
157
158 /* read the file indicated (by na1me) in the fname parameter.  store
159    its entire contents in a single datum. */
160 int set_datum_file(gnutls_datum_t* d, const char* fname) {
161   struct stat sbuf;
162   unsigned char* c = NULL;
163   FILE* file = NULL;
164   size_t x = 0;
165
166   if (0 != stat(fname, &sbuf)) {
167     err("failed to stat '%s'\n", fname);
168     return -1;
169   }
170   
171   c = gnutls_realloc(d->data, sbuf.st_size);
172   if (NULL == c) {
173     err("failed to allocate %d bytes for '%s'\n", sbuf.st_size, fname);
174     return -1;
175   }
176
177   d->data = c;
178   d->size = sbuf.st_size;
179   file = fopen(fname, "r");
180   if (NULL == file) {
181     err("failed to open '%s' for reading\n",  fname);
182     return -1;
183   }
184
185   x = fread(d->data, d->size, 1, file);
186   if (x != 1) {
187     err("tried to read %d bytes, read %d instead from '%s'\n", d->size, x, fname);
188     fclose(file);
189     return -1;
190   }
191   fclose(file);
192   return 0;
193 }