v2.6.5 release
[git-osx-installer.git] / src / cevpb64.c
blobeeb26db07168859e380bf2a839841ea2fcf312bd
1 /*
3 cevpb64.c -- compatibility implemenation of EVP base 64 functions
4 Copyright (c) 2014 Kyle J. McKay. All rights reserved.
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 #include <stddef.h>
24 static const signed char b64tab[256] = {
25 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
26 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
27 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0x3E,-1,-1,-1,0x3F,
28 0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,-1,-1,-1,0x40,-1,-1,
29 -1,0,1,2,3,4,5,6,7,8,9,0x0A,0x0B,0x0C,0x0D,0x0E,
30 0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,-1,-1,-1,-1,-1,
31 -1,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,
32 0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,-1,-1,-1,-1,-1,
33 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
34 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
35 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
36 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
37 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
38 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
39 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
40 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
43 static void decode24(const unsigned char *input, unsigned char *output)
45 output[0] = ((b64tab[input[0]]&0x3F)<<2)|((b64tab[input[1]]&0x3F)>>4);
46 output[1] = (((b64tab[input[1]]&0x3F)&0x0F)<<4)|((b64tab[input[2]]&0x3F)>>2);
47 output[2] = (((b64tab[input[2]]&0x3F)&0x03)<<6)|(b64tab[input[3]]&0x3F);
50 static int DecodeBase64Block(const void *_in, size_t inl, void *_out, size_t *outl)
52 const unsigned char *in = (unsigned char *)_in;
53 unsigned char *out = (unsigned char *)_out;
54 unsigned char inb[4];
55 unsigned char outb[3];
56 size_t count;
57 int i;
59 if (inl && !in)
60 return -1;
61 if (!inl) {
62 *outl = 0;
63 return 0;
65 count = 0;
66 for (i=0; inl; ++in, --inl) {
67 unsigned char c = *in;
68 if (c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\f')
69 continue;
70 if (b64tab[c] < 0)
71 return -1;
72 inb[i++] = c;
73 if (i == 4) {
74 decode24(inb, outb);
75 i = 0;
76 if (inb[3] == '=') {
77 *out++ = outb[0];
78 ++count;
79 if (inb[2] != '=') {
80 *out++ = outb[1];
81 ++count;
83 break;
85 *out++ = outb[0];
86 *out++ = outb[1];
87 *out++ = outb[2];
88 count += 3;
91 if (i != 0)
92 return -1;
93 *outl = count;
94 return 0;
97 static const char tab64[64] = {
98 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
99 'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
100 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
101 'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'
104 static void encode24(const unsigned char *input, unsigned char *output)
107 output[0] = tab64[input[0]>>2];
108 output[1] = tab64[((input[0]&0x3)<<4)+(input[1]>>4)];
109 output[2] = tab64[((input[1]&0xF)<<2)+(input[2]>>6)];
110 output[3] = tab64[input[2]&0x3F];
113 static int EncodeBase64Block(const void *_in, size_t inl, void *_out, size_t *outl)
115 const unsigned char *in = (unsigned char *)_in;
116 unsigned char *out = (unsigned char *)_out;
117 size_t count;
118 int i;
120 if (inl && !in)
121 return -1;
122 if (!inl) {
123 *outl = 0;
124 return 0;
126 count = 0;
127 for (i=0; inl >= 3; in+=3, inl-=3) {
128 encode24(in, out);
129 out += 4;
130 count += 4;
132 if (inl) {
133 unsigned char inb[3];
134 inb[0] = *in;
135 inb[1] = inl == 2 ? in[1] : '\0';
136 inb[2] = '\0';
137 encode24(inb, out);
138 count += 4;
140 *outl = count;
141 return 0;
144 int cEVP_DecodeBlock(void *to, const void *from, int fromlen)
146 int err;
147 size_t ans;
149 if (fromlen < 0)
150 return -1;
151 err = DecodeBase64Block(from, (size_t)fromlen, to, &ans);
152 if (err)
153 return -1;
154 return (int)ans;
157 int cEVP_EncodeBlock(void *to, const void *from, int fromlen)
159 int err;
160 size_t ans;
162 if (fromlen < 0)
163 return -1;
164 err = EncodeBase64Block(from, (size_t)fromlen, to, &ans);
165 if (err)
166 return -1;
167 return (int)ans;