4 author: José Bollo <jose.bollo@iot.bzh>
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
10 http://www.apache.org/licenses/LICENSE-2.0
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
24 #include "wgtpkg-base64.h"
26 static char tob64(char x)
34 return x == 62 ? '+' : '/';
37 char *base64encw(const char *buffer, int length, int width)
42 if (width == 0 || width % 4) {
43 ERROR("bad width in base64enc");
46 result = malloc(2 + 4 * ((length + 2) / 3) + (length / width));
48 ERROR("malloc failed in base64enc");
54 if (out % (width + 1) == width)
56 result[out] = tob64((buffer[in] >> 2) & '\x3f');
57 result[out+1] = tob64(((buffer[in] << 4) & '\x30') | ((buffer[in+1] >> 4) & '\x0f'));
58 result[out+2] = tob64(((buffer[in+1] << 2) & '\x3c') | ((buffer[in+2] >> 6) & '\x03'));
59 result[out+3] = tob64(buffer[in+2] & '\x3f');
65 if (out % (width + 1) == width)
67 result[out] = tob64((buffer[in] >> 2) & '\x3f');
69 result[out+1] = tob64((buffer[in] << 4) & '\x30');
72 result[out+1] = tob64(((buffer[in] << 4) & '\x30') | ((buffer[in+1] >> 4) & '\x0f'));
73 result[out+2] = tob64((buffer[in+1] << 2) & '\x3c');
82 char *base64enc(const char *buffer, int length)
84 return base64encw(buffer, length, 76);
87 static char fromb64(char x)
89 if ('A' <= x && x <= 'Z')
91 if ('a' <= x && x <= 'z')
93 if ('0' <= x && x <= '9')
104 int base64dec(const char *buffer, char **output)
108 unsigned char x0, x1, x2, x3;
110 len = strlen(buffer);
111 result = malloc(3 * ((3 + len) / 4));
112 if (result == NULL) {
113 ERROR("malloc failed in base64dec");
117 while (buffer[in] == '\r' || buffer[in] == '\n')
121 ERROR("unexpected input size in base64dec");
125 x0 = (unsigned char)fromb64(buffer[in]);
126 x1 = (unsigned char)fromb64(buffer[in+1]);
127 x2 = (unsigned char)fromb64(buffer[in+2]);
128 x3 = (unsigned char)fromb64(buffer[in+3]);
130 if (x0 == 'E' || x1 == 'E' || x2 == 'E' || x3 == 'E') {
131 ERROR("unexpected input character in base64dec");
135 if (x0 == '@' || x1 == '@' || (x2 == '@' && x3 != '@')) {
136 ERROR("unexpected termination character in base64dec");
140 result[out] = (char)((x0 << 2) | (x1 >> 4));
141 result[out+1] = (char)((x1 << 4) | ((x2 >> 2) & 15));
142 result[out+2] = (char)((x2 << 6) | (x3 & 63));
143 while (buffer[in] == '\r' || buffer[in] == '\n')
147 else if (!buffer[in])
148 out += 1 + (x2 != '@');
150 ERROR("unexpected continuation in base64dec");
159 int base64eq(const char *buf1, const char *buf2)
162 while(*buf1 == '\n' || *buf1 == '\r')
164 while(*buf2 == '\n' || *buf2 == '\r')
179 int main(int ac, char **av)
186 fd = open(*av, O_RDONLY);
187 if (fd < 0) continue;
188 l0 = read(fd, buffer, sizeof buffer);
189 if (l0 <= 0) continue;
191 p1 = base64enc(buffer, l0);
194 l2 = base64dec(p1, &p2);
195 if (l2 <= 0) continue;
196 printf("[[[%.*s]]]\n",l2,p2);
197 if (l0 != l2) printf("length mismatch\n");
198 else if (memcmp(buffer, p2, l0)) printf("content mismatch\n");