Update Debian Vcs-* fields to point to git repository
[onak.git] / marshal.c
1 /*
2  * marshal.c - SKS compatible marshalling routines
3  *
4  * Copyright 2011 Jonathan McDowell <noodles@earth.li>
5  *
6  * This program is free software: you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the Free
8  * Software Foundation; version 2 of the License.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License along with
16  * this program; if not, write to the Free Software Foundation, Inc., 51
17  * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  */
19
20 #include <arpa/inet.h>
21 #include <stdint.h>
22 #include <stdlib.h>
23 #include <string.h>
24
25 #include "charfuncs.h"
26 #include "keyid.h"
27 #include "keystructs.h"
28 #include "mem.h"
29 #include "parsekey.h"
30
31 void marshal_publickey(int (*putchar_func)(void *ctx, size_t count,
32                                 void *c),
33                                 void *ctx,
34                                 const struct openpgp_publickey *key)
35 {
36         uint32_t len;
37         struct openpgp_packet_list *packets = NULL, *list_end = NULL;
38         struct buffer_ctx buf;
39
40         buf.buffer = calloc(1, 1024);
41         buf.size = 1024;
42         buf.offset = 0;
43
44         flatten_publickey((struct openpgp_publickey *) key, &packets,
45                         &list_end);
46         write_openpgp_stream(buffer_putchar, &buf, packets);
47
48         len = htonl(buf.offset);
49
50         putchar_func(ctx, sizeof(len), &len);
51         putchar_func(ctx, buf.offset, buf.buffer);
52
53         free_packet_list(packets);
54 }
55
56 void marshal_skshash(int (*putchar_func)(void *ctx, size_t count,
57                                 void *c),
58                                 void *ctx,
59                                 const struct skshash *hash)
60 {
61         uint32_t len;
62
63         len = htonl(sizeof(hash->hash));
64
65         putchar_func(ctx, sizeof(len), &len);
66         putchar_func(ctx, sizeof(hash->hash), (void *) hash->hash);
67 }
68
69 struct skshash *unmarshal_skshash(int (*getchar_func)(void *ctx, size_t count,
70                                 void *c),
71                                 void *ctx)
72 {
73         uint32_t len;
74         struct skshash *hash;
75
76         if (getchar_func(ctx, sizeof(len), &len)) {
77                 return NULL;
78         }
79         len = ntohl(len);
80         if (len > sizeof(struct skshash)) {
81                 return NULL;
82         }
83         hash = calloc(sizeof(struct skshash), 1);
84         if (getchar_func(ctx, len, hash->hash)) {
85                 free(hash);
86                 return NULL;
87         }
88
89         return hash;
90 }
91
92 void marshal_string(int (*putchar_func)(void *ctx, size_t count,
93                                 void *c),
94                                 void *ctx,
95                                 const char *string)
96 {
97         uint32_t len, nlen;
98
99         len = strlen(string);
100         nlen = htonl(len);
101
102         putchar_func(ctx, sizeof(nlen), &nlen);
103         putchar_func(ctx, len, &string);
104 }
105
106 char *unmarshal_string(int (*getchar_func)(void *ctx, size_t count,
107                                 void *c),
108                                 void *ctx)
109 {
110         uint32_t len;
111         char *string;
112
113         if (getchar_func(ctx, sizeof(len), &len)) {
114                 return NULL;
115         }
116         len = ntohl(len);
117         string = malloc(len + 1);
118         if (getchar_func(ctx, len, string)) {
119                 free(string);
120                 return NULL;
121         }
122
123         string[len] = 0;
124         return string;
125 }
126
127 void marshal_array(int (*putchar_func)(void *ctx, size_t count,
128                                 void *c),
129                                 void *ctx,
130                                 void (*marshal_func)(int
131                                         (*putchar_func)(void *ctx,
132                                                 size_t count, void *c),
133                                         void *ctx, const void *item),
134                                 void **array,
135                                 int size)
136 {
137         uint32_t len;
138         int i;
139
140         len = htonl(size);
141
142         putchar_func(ctx, sizeof(len), &len);
143
144         for (i = 0; i < size; i++) {
145                 marshal_func(putchar_func, ctx, array[i]);
146         }
147 }
148
149 void **unmarshal_array(int (*getchar_func)(void *ctx, size_t count,
150                                 void *c),
151                                 void *ctx,
152                                 void *(*unmarshal_func)(int
153                                         (*getchar_func)(void *ctx,
154                                                 size_t count, void *c),
155                                         void *ctx),
156                                 int *size)
157 {
158         uint32_t len;
159         void **array;
160         int i;
161
162         if (getchar_func(ctx, sizeof(len), &len)) {
163                 return NULL;
164         }
165         *size = ntohl(len);
166         array = malloc(*size * sizeof(void *));
167         for (i = 0; i < *size; i++) {
168                 array[i] = unmarshal_func(getchar_func, ctx);
169         }
170
171         return array;
172 }