f5d37e602eb40da9aad86d93d4f1473b067a19cb
[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
22
23 int init_gnutls() {
24   const char* version = NULL;
25   const char* debug_string = NULL;
26   int ret;
27
28   if (ret = gnutls_global_init(), ret) {
29     err("Failed to do gnutls_global_init() (error: %d)\n", ret);
30     return 1;
31   }
32
33   version = gnutls_check_version(NULL);
34
35   if (version) 
36     err("gnutls version: %s\n", version);
37   else {
38     err("no version found!\n");
39     return 1;
40   }
41
42   if (debug_string = getenv("MONKEYSPHERE_DEBUG"), debug_string) {
43     loglevel = atoi(debug_string);
44     gnutls_global_set_log_function(logfunc);
45     
46     gnutls_global_set_log_level(loglevel);
47     err("set log level to %d\n", loglevel);
48   }
49   return 0;
50 }
51
52 void init_datum(gnutls_datum_t* d) {
53   d->data = NULL;
54   d->size = 0;
55 }
56 void copy_datum(gnutls_datum_t* dest, const gnutls_datum_t* src) {
57   dest->data = gnutls_realloc(dest->data, src->size);
58   dest->size = src->size;
59   memcpy(dest->data, src->data, src->size);
60 }
61 int compare_data(const gnutls_datum_t* a, const gnutls_datum_t* b) {
62   if (a->size > b->size) {
63     err("a is larger\n");
64     return 1;
65   }
66   if (a->size < b->size) {
67     err("b is larger\n");
68     return -1;
69   }
70   return memcmp(a->data, b->data, a->size);
71 }
72 void free_datum(gnutls_datum_t* d) {
73   gnutls_free(d->data);
74   d->data = NULL;
75   d->size = 0;
76 }
77
78 /* read the passed-in string, store in a single datum */
79 int set_datum_string(gnutls_datum_t* d, const char* s) {
80   unsigned int x = strlen(s)+1;
81   unsigned char* c = NULL;
82
83   c = gnutls_realloc(d->data, x);
84   if (NULL == c)
85     return -1;
86   d->data = c;
87   d->size = x;
88   memcpy(d->data, s, x);
89   return 0;
90 }
91
92 /* read the passed-in file descriptor until EOF, store in a single
93    datum */
94 int set_datum_fd(gnutls_datum_t* d, int fd) {
95   unsigned int bufsize = 1024;
96   unsigned int len = 0;
97
98   FILE* f = fdopen(fd, "r");
99   if (bufsize > d->size) {
100     bufsize = 1024;
101     d->data = gnutls_realloc(d->data, bufsize);
102     if (d->data == NULL) {
103       err("out of memory!\n");
104       return -1;
105     }
106     d->size = bufsize;
107   } else {
108     bufsize = d->size;
109   }
110   f = fdopen(fd, "r");
111   if (NULL == f) {
112     err("could not fdopen FD %d\n", fd);
113   }
114   clearerr(f);
115   while (!feof(f) && !ferror(f)) { 
116     if (len == bufsize) {
117       /* allocate more space by doubling: */
118       bufsize *= 2;
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     }
126     len += fread(d->data + len, 1, bufsize - len, f);
127     /*     err("read %d bytes\n", len); */
128   }
129   if (ferror(f)) {
130     err("Error reading from fd %d (error: %d) (error: %d '%s')\n", fd, ferror(f), errno, strerror(errno));
131     return -1;
132   }
133     
134   /* touch up buffer size to match reality: */
135   d->data = gnutls_realloc(d->data, len);
136   d->size = len;
137   return 0;
138 }
139
140 /* read the file indicated (by na1me) in the fname parameter.  store
141    its entire contents in a single datum. */
142 int set_datum_file(gnutls_datum_t* d, const char* fname) {
143   struct stat sbuf;
144   unsigned char* c = NULL;
145   FILE* file = NULL;
146   size_t x = 0;
147
148   if (0 != stat(fname, &sbuf)) {
149     err("failed to stat '%s'\n", fname);
150     return -1;
151   }
152   
153   c = gnutls_realloc(d->data, sbuf.st_size);
154   if (NULL == c) {
155     err("failed to allocate %d bytes for '%s'\n", sbuf.st_size, fname);
156     return -1;
157   }
158
159   d->data = c;
160   d->size = sbuf.st_size;
161   file = fopen(fname, "r");
162   if (NULL == file) {
163     err("failed to open '%s' for reading\n",  fname);
164     return -1;
165   }
166
167   x = fread(d->data, d->size, 1, file);
168   if (x != 1) {
169     err("tried to read %d bytes, read %d instead from '%s'\n", d->size, x, fname);
170     fclose(file);
171     return -1;
172   }
173   fclose(file);
174   return 0;
175 }