mess822x 1.23
mess822x
Loading...
Searching...
No Matches
mess822_base64.c
Go to the documentation of this file.
1#include "mess822.h"
2#include "str.h"
3#include "stralloc.h"
4#include "logmsg.h"
5
6#define WHO "mess822_base64"
7
8static uint8 *b64alpha =
9 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
10
11static const unsigned char *b64alphaurl =
12 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
13
14static unsigned int base64_dec(int c)
15{
16 if ('A' <= c && c <= 'Z') return c - 'A';
17 if ('a' <= c && c <= 'z') return 26 + c - 'a';
18 if ('0' <= c && c <= '9') return 52 + c - '0';
19 if (c == '+') return 62;
20 if (c == '/') return 63;
21 return 64;
22}
23
24/* returns number of bytes written; -1 problem
25 stralloc *out => null terminated
26 Some code borrowed from Bert Bos @ w3c.org
27 RFC 4648 is considered.
28*/
29
30int mess822_b64decode(stralloc *out,const char *in,int len,int flag)
31{
32 int i = 0; // FIXME: can't be done in for loop
33 int r = 0;
34 uint8 b;
35 unsigned int c, v;
36
37 if (!stralloc_copys(out,"")) return -1;
38 if (len == 0) return 0;
39
40 if (!stralloc_ready(out,len)) return -1;
41
42 for (int remaining = 0; i < len; i++) {
43 if (in[i] == '\0') break;
44 if (in[i] == '=') continue;
45 if (in[i] == '\n') continue;
46 if (flag == 4648) {
47 if (in[i] == '_') { if (!stralloc_append(out,"/")) return -1; r++; continue; }
48 if (in[i] == '-') { if (!stralloc_append(out,"+")) return -1; r++; continue; }
49 }
50 if ((v = base64_dec(in[i])) < 64) {
51 switch (remaining) {
52 case 0: c = v; remaining = 6; break;
53 case 6: b = (c << 2) | (v >> 4);
54 if (!stralloc_append(out,&b)) return -1;
55 c = (v & 0x0f); remaining = 4; r++; break;
56 case 4: b = (c << 4) | (v >> 2);
57 if (!stralloc_append(out,&b)) return -1;
58 c = (v & 0x03); remaining = 2; r++; break;
59 case 2: b = (c << 6) | v;
60 if (!stralloc_append(out,&b)) return -1;
61 c = 0; remaining = 0; r++; break;
62 }
63 } else if (flag == 1) {
64 char ch[] = { '\0', '\0' };
65 ch[0] = in[i];
66 logmsg(WHO,0,INFO,B("Erroneous character on input: >",ch,"<")); /* be quiet */
67 return 0;
68 }
69 }
70
71 return r;
72}
73
74int mess822_b64encode(stralloc *out,stralloc *in)
75{
76 uint8 a, b ,c;
77 uint8 b64[4];
78 int i, r = 0; // number of base64 chars written
79
80 if (in->len == 0) {
81 if (!stralloc_cats(out,"")) return -1;
82 return 1;
83 }
84
85 // Compute size, mod(3) remaining bytes, #loops; allocate memory
86
87 int len = in->len % 3;
88 int blen = in->len - len;
89 int lines = (4 * in->len / 3) / 76 + 1;
90 if (!stralloc_ready(out,4*in->len/3 + 2 + lines)) return -1;
91
92 for (i = 0; i < blen; i += 3) {
93 a = in->s[i];
94 b = in->s[i + 1];
95 c = in->s[i + 2];
96
97 b64[0] = b64alpha[a >> 2];
98 b64[1] = b64alpha[((a & 0x03) << 4) | (b >> 4)];
99 b64[2] = b64alpha[((b & 0x0f) << 2) | (c >> 6)];
100 b64[3] = b64alpha[c & 0x3f];
101 if (!stralloc_catb(out,b64,4)) return -1;
102 r += 4;
103 if (r % 76 == 0) if (!stralloc_append(out,"\n")) return -1;
104 }
105
106 if (len == 2) { // last two input bytes - padding
107 a = in->s[i];
108 b = in->s[i + 1];
109
110 b64[0] = b64alpha[a >> 2];
111 b64[1] = b64alpha[((a & 0x03) << 4) | (b >> 4)];
112 b64[2] = b64alpha[b & 0x0f << 2];
113 b64[3] = '=';
114 if (!stralloc_catb(out,b64,4)) return -1;
115 r += 4;
116 } else if (len == 1) { // last input byte - padding
117 a = in->s[i];
118
119 b64[0] = b64alpha[a >> 2];
120 b64[1] = b64alpha[(a & 0x03) << 4];
121 b64[2] = '=';
122 b64[3] = '=';
123 if (!stralloc_catb(out,b64,4)) return -1;
124 r += 4;
125 }
126
127 return r;
128}
129
130int mess822_b64urlencode(stralloc *out,stralloc *in)
131{
132 uint8 a, b ,c;
133 uint8 b64[4];
134 int i, r = 0; // number of base64 chars written
135
136 if (in->len == 0) {
137 if (!stralloc_cats(out,"")) return -1;
138 return 1;
139 }
140
141 // Compute size, mod(3) remaining bytes, #loops; allocate memory
142
143 int len = in->len % 3;
144 int blen = in->len - len;
145 int lines = (4 * in->len / 3) / 76 + 1;
146 if (!stralloc_ready(out,4*in->len/3 + 2 + lines)) return -1;
147
148 for (i = 0; i < blen; i += 3) {
149 a = in->s[i];
150 b = in->s[i + 1];
151 c = in->s[i + 2];
152
153 b64[0] = b64alphaurl[a >> 2];
154 b64[1] = b64alphaurl[((a & 0x03) << 4) | (b >> 4)];
155 b64[2] = b64alphaurl[((b & 0x0f) << 2) | (c >> 6)];
156 b64[3] = b64alphaurl[c & 0x3f];
157 if (!stralloc_catb(out,b64,4)) return -1;
158 r += 4;
159 if (r % 76 == 0) if (!stralloc_append(out,"\n")) return -1;
160 }
161
162 if (len == 2) { // last two input bytes - padding
163 a = in->s[i];
164 b = in->s[i + 1];
165
166 b64[0] = b64alphaurl[a >> 2];
167 b64[1] = b64alphaurl[((a & 0x03) << 4) | (b >> 4)];
168 b64[2] = b64alphaurl[b & 0x0f << 2];
169 b64[3] = '=';
170 if (!stralloc_catb(out,b64,4)) return -1;
171 r += 4;
172 } else if (len == 1) { // last input byte - padding
173 a = in->s[i];
174
175 b64[0] = b64alphaurl[a >> 2];
176 b64[1] = b64alphaurl[(a & 0x03) << 4];
177 b64[2] = '=';
178 b64[3] = '=';
179 if (!stralloc_catb(out,b64,4)) return -1;
180 r += 4;
181 }
182
183 return r;
184}
mess822_action a[]
Definition: 822date.c:25
stralloc out
Definition: b64decode.c:12
void c(char *, char *, char *, int, int, int)
Definition: install.c:46
int mess822_b64decode(stralloc *out, const char *in, int len, int flag)
int mess822_b64urlencode(stralloc *out, stralloc *in)
#define WHO
Definition: mess822_base64.c:6
int mess822_b64encode(stralloc *out, stralloc *in)
int flag
Definition: 822field.c:16