4 // Base64 decoding table
6 static const uint8_t b64dec[128] = {
7 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
8 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
9 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
10 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
11 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
12 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
13 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
14 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f,
15 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
16 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff,
17 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
18 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
19 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
20 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12,
21 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
22 0x19, 0xff, 0xff, 0xff, 0xff, 0xff,
23 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e,
24 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24,
25 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a,
26 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
27 0x31, 0x32, 0x33, 0xff, 0xff, 0xff,
31 static const char b64enc[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
32 "abcdefghijklmnopqrstuvwxyz"
35 // Heavily based on code by Jouni Malinen <j@w1.fi>
36 // https://web.mit.edu/freebsd/head/contrib/wpa/src/utils/base64.c
37 static size_t b64encode(char *dst, const void *src, const size_t length) {
38 const uint8_t *end = src + length;
39 const uint8_t *in = src;
42 while(end - in >= 3) {
43 *pos++ = b64enc[in[0] >> 2];
44 *pos++ = b64enc[((in[0] & 0x03) << 4) | (in[1] >> 4)];
45 *pos++ = b64enc[((in[1] & 0x0f) << 2) | (in[2] >> 6)];
46 *pos++ = b64enc[in[2] & 0x3f];
51 *pos++ = b64enc[in[0] >> 2];
54 *pos++ = b64enc[(in[0] & 0x03) << 4];
57 *pos++ = b64enc[((in[0] & 0x03) << 4) | (in[1] >> 4)];
58 *pos++ = b64enc[(in[1] & 0x0f) << 2];
70 bool pem_encode(FILE *fp, const char *header, uint8_t *buf, size_t size) {
71 if(fprintf(fp, "-----BEGIN %s-----\n", header) <= 0) {
75 char b64[B64_SIZE(size)];
76 const size_t b64len = b64encode(b64, buf, size);
78 for(char *p = b64; p < b64 + b64len; p += 64) {
79 if(fprintf(fp, "%.64s\n", p) <= 0) {
84 return fprintf(fp, "-----END %s-----\n", header) > 0;
87 bool pem_decode(FILE *fp, const char *header, uint8_t *buf, size_t size, size_t *outsize) {
95 if(!fgets(line, sizeof(line), fp)) {
99 if(!decode && !strncmp(line, "-----BEGIN ", 11)) {
100 if(!strncmp(line + 11, header, strlen(header))) {
107 if(decode && !strncmp(line, "-----END", 8)) {
115 for(i = 0; line[i] >= ' '; i++) {
116 if((signed char)line[i] < 0 || b64dec[(int)line[i]] == 0xff) {
120 word |= b64dec[(int)line[i]] << shift;
129 buf[j++] = word >> 8;
130 word = (uint16_t)(word << 8);