blob: 373aed856091e12efdfb48ce34a7a98b1885b6a3 [file] [log] [blame]
ss412g1a79bdf2019-10-24 12:03:05 +03001/*
2 * Copyright 2019 AT&T Intellectual Property
3 * Copyright 2019 Nokia
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
ss412g3bac2da2020-01-05 11:52:19 +020017
18 /*
nm755n2e268142019-11-28 16:40:23 +000019 * This source code is part of the near-RT RIC (RAN Intelligent Controller)
20 * platform project (RICP).
21 */
22
ss412g1a79bdf2019-10-24 12:03:05 +030023//
24// Created by adi ENZEL on 9/26/19.
25//
26
27#include "base64.h"
28
ss412g3bac2da2020-01-05 11:52:19 +020029int base64::encode(const unsigned char *src, int srcLen, char unsigned *dst, long &dstLen) {
ss412g1a79bdf2019-10-24 12:03:05 +030030 unsigned char *pos;
31 const unsigned char *end, *in;
ss412g3bac2da2020-01-05 11:52:19 +020032
33 if (dstLen <= 0 || srcLen <= 0) {
34 mdclog_write(MDCLOG_ERR, "source or destination length are 0. dst =%ld source = %d",
ss412g1a79bdf2019-10-24 12:03:05 +030035 dstLen, srcLen);
ss412g3bac2da2020-01-05 11:52:19 +020036 return -1;
37 }
38 if (dstLen < (srcLen * 4 / 3)) {
39 mdclog_write(MDCLOG_ERR, "Destination size %ld must be at least 140 percent from source size %d",
40 dstLen, srcLen);
41 return -1;
ss412g1a79bdf2019-10-24 12:03:05 +030042 }
43 if (dst == nullptr) {
44 mdclog_write(MDCLOG_ERR, "Destination must be allocated and freed by caller the function not allocate the memory");
ss412g3bac2da2020-01-05 11:52:19 +020045 return -1;
46 }
47 if (src == nullptr) {
48 mdclog_write(MDCLOG_ERR, "source is null pointer");
49 return -1;
ss412g1a79bdf2019-10-24 12:03:05 +030050 }
51
52 end = src + srcLen;
53 in = src;
54 pos = dst;
55 while (end - in >= 3) {
56 *pos++ = base64_table[in[0] >> (unsigned int)2];
57 *pos++ = base64_table[((in[0] & 0x03) << (unsigned int)4) | (in[1] >> (unsigned int)4)];
58 *pos++ = base64_table[((in[1] & 0x0f) << (unsigned int)2) | (in[2] >> (unsigned int)6)];
59 *pos++ = base64_table[in[2] & (unsigned int)0x3f];
60 in += 3;
61 }
62
63 if (end - in) {
64 *pos++ = base64_table[in[0] >> (unsigned int)2];
65 if (end - in == 1) {
66 *pos++ = base64_table[(in[0] & 0x03) << (unsigned int)4];
67 *pos++ = '=';
68 } else {
69 *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> (unsigned int)4)];
70 *pos++ = base64_table[(in[1] & 0x0f) << 2];
71 }
72 *pos++ = '=';
73 }
74
75 *pos = '\0';
ss412g3bac2da2020-01-05 11:52:19 +020076 dstLen = pos - dst;return 0;
ss412g1a79bdf2019-10-24 12:03:05 +030077}
78
aa7133@att.com84bd3342020-03-16 18:04:57 +020079int base64::decode(const unsigned char *src, int srcLen, char unsigned *dst, long dstLen) {
ss412g3bac2da2020-01-05 11:52:19 +020080 unsigned char inv_table[INVERSE_TABLE_SIZE];
81 memset(inv_table, 0x80, INVERSE_TABLE_SIZE);
82 for (ulong i = 0; i < sizeof(base64_table) - 1; i++) {
83 inv_table[base64_table[i]] = (unsigned char) i;
84 }
85 inv_table['='] = 0;
86
87
88 if (dstLen == 0 || dstLen < (int)(srcLen / 4 * 3)) {
89 mdclog_write(MDCLOG_ERR, "Destination size %ld can be up to 40 smaller then source size %d",
90 dstLen, srcLen);
91 return -1;
92 }
93 if (dst == nullptr) {
94 mdclog_write(MDCLOG_ERR, "Destination must be allocated and freed by caller the function not allocate the memory");
95 return -1;
96 }
97
98 unsigned char *pos, block[4], tmp;
99 long i;
100 int pad = 0;
101
102 size_t count = 0;
103
104 for (i = 0; i < srcLen; i++) {
105 if (inv_table[src[i]] != 0x80) {
106 count++;
107 }
108 }
109
110 if (count == 0 || count % 4)
111 return -1;
112
113 pos = dst;
114 count = 0;
115 for (i = 0; i < srcLen; i++) {
116 tmp = inv_table[src[i]];
117 if (tmp == 0x80) {
118 continue;
119 }
120 block[count] = tmp;
121
122 if (src[i] == '=') {
123 pad++;
124 }
125
126 count++;
127 if (count == 4) {
128 *pos++ = (block[0] << 2) | ((unsigned char)block[1] >> (unsigned int)4);
129 *pos++ = (block[1] << 4) | ((unsigned char)block[2] >> (unsigned int)2);
130 *pos++ = (block[2] << 6) | block[3];
131 count = 0;
132 if (pad) {
133 if (pad == 1) {
134 pos--;
135 }
136 else if (pad == 2) {
137 pos -= 2;
138 }
139 else {
140 return -1;
141 }
142 break;
143 }
144 }
145 }
146
147 dstLen = pos - dst;
148 return 0;
149}