Add /pks/hashquery
[onak.git] / marshal.c
1 /*
2  * marshal.c - SKS compatible marshalling routines
3  *
4  * Copyright 2011 Jonathan McDowell <noodles@earth.li>
5  */
6
7 #include <arpa/inet.h>
8 #include <stdint.h>
9 #include <stdlib.h>
10 #include <string.h>
11
12 #include "charfuncs.h"
13 #include "keyid.h"
14 #include "keystructs.h"
15 #include "mem.h"
16 #include "parsekey.h"
17
18 void marshal_publickey(int (*putchar_func)(void *ctx, size_t count,
19                                 void *c),
20                                 void *ctx,
21                                 const struct openpgp_publickey *key)
22 {
23         uint32_t len;
24         struct openpgp_packet_list *packets = NULL, *list_end = NULL;
25         struct buffer_ctx buf;
26
27         buf.buffer = calloc(1, 1024);
28         buf.size = 1024;
29         buf.offset = 0;
30
31         flatten_publickey((struct openpgp_publickey *) key, &packets,
32                         &list_end);
33         write_openpgp_stream(buffer_putchar, &buf, packets);
34
35         len = htonl(buf.offset);
36
37         putchar_func(ctx, sizeof(len), &len);
38         putchar_func(ctx, buf.offset, buf.buffer);
39
40         free_packet_list(packets);
41 }
42
43 void marshal_skshash(int (*putchar_func)(void *ctx, size_t count,
44                                 void *c),
45                                 void *ctx,
46                                 const struct skshash *hash)
47 {
48         uint32_t len;
49
50         len = htonl(sizeof(hash->hash));
51
52         putchar_func(ctx, sizeof(len), &len);
53         putchar_func(ctx, sizeof(hash->hash), (void *) hash->hash);
54 }
55
56 struct skshash *unmarshal_skshash(int (*getchar_func)(void *ctx, size_t count,
57                                 void *c),
58                                 void *ctx)
59 {
60         uint32_t len;
61         struct skshash *hash;
62
63         if (getchar_func(ctx, sizeof(len), &len)) {
64                 return NULL;
65         }
66         len = ntohl(len);
67         if (len > sizeof(struct skshash)) {
68                 return NULL;
69         }
70         hash = calloc(sizeof(struct skshash), 1);
71         if (getchar_func(ctx, len, hash->hash)) {
72                 free(hash);
73                 return NULL;
74         }
75
76         return hash;
77 }
78
79 void marshal_string(int (*putchar_func)(void *ctx, size_t count,
80                                 void *c),
81                                 void *ctx,
82                                 const char *string)
83 {
84         uint32_t len, nlen;
85
86         len = strlen(string);
87         nlen = htonl(len);
88
89         putchar_func(ctx, sizeof(nlen), &nlen);
90         putchar_func(ctx, len, &string);
91 }
92
93 char *unmarshal_string(int (*getchar_func)(void *ctx, size_t count,
94                                 void *c),
95                                 void *ctx)
96 {
97         uint32_t len;
98         char *string;
99
100         if (getchar_func(ctx, sizeof(len), &len)) {
101                 return NULL;
102         }
103         len = ntohl(len);
104         string = malloc(len + 1);
105         if (getchar_func(ctx, len, string)) {
106                 free(string);
107                 return NULL;
108         }
109
110         string[len] = 0;
111         return string;
112 }
113
114 void marshal_array(int (*putchar_func)(void *ctx, size_t count,
115                                 void *c),
116                                 void *ctx,
117                                 void (*marshal_func)(int
118                                         (*putchar_func)(void *ctx,
119                                                 size_t count, void *c),
120                                         void *ctx, const void *item),
121                                 void **array,
122                                 int size)
123 {
124         uint32_t len;
125         int i;
126
127         len = htonl(size);
128
129         putchar_func(ctx, sizeof(len), &len);
130
131         for (i = 0; i < size; i++) {
132                 marshal_func(putchar_func, ctx, array[i]);
133         }
134 }
135
136 void **unmarshal_array(int (*getchar_func)(void *ctx, size_t count,
137                                 void *c),
138                                 void *ctx,
139                                 void *(*unmarshal_func)(int
140                                         (*getchar_func)(void *ctx,
141                                                 size_t count, void *c),
142                                         void *ctx),
143                                 int *size)
144 {
145         uint32_t len;
146         void **array;
147         int i;
148
149         if (getchar_func(ctx, sizeof(len), &len)) {
150                 return NULL;
151         }
152         *size = ntohl(len);
153         array = malloc(*size * sizeof(void *));
154         for (i = 0; i < *size; i++) {
155                 array[i] = unmarshal_func(getchar_func, ctx);
156         }
157
158         return array;
159 }