1
0
mirror of https://github.com/SoftEtherVPN/SoftEtherVPN.git synced 2024-11-23 01:49:53 +03:00

Merge pull request #1404 from davidebeatrici/base64-revamp

Refactor Base64 functions, encode/decode using OpenSSL's EVP interface
This commit is contained in:
Ilya Shipitsin 2021-07-02 13:23:10 +05:00 committed by GitHub
commit 08905e57a6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 224 additions and 369 deletions

View File

@ -939,30 +939,26 @@ bool HttpParseBasicAuthHeader(HTTP_HEADER *h, char *username, UINT username_size
{ {
if (StrCmpi(key, "Basic") == 0 && IsEmptyStr(value) == false) if (StrCmpi(key, "Basic") == 0 && IsEmptyStr(value) == false)
{ {
UINT b64_dest_size = StrSize(value) * 2 + 256; char *str = Base64ToBin(NULL, value, StrLen(value));
char *b64_dest = ZeroMalloc(b64_dest_size); if (str != NULL)
Decode64(b64_dest, value);
if (IsEmptyStr(b64_dest) == false)
{ {
if (b64_dest[0] == ':') if (str[0] == ':')
{ {
// Empty username // Empty username
StrCpy(username, username_size, ""); StrCpy(username, username_size, "");
StrCpy(password, password_size, b64_dest + 1); StrCpy(password, password_size, str + 1);
ret = true; ret = true;
} }
else else
{ {
if (GetKeyAndValue(b64_dest, username, username_size, password, password_size, ":")) if (GetKeyAndValue(str, username, username_size, password, password_size, ":"))
{ {
ret = true; ret = true;
} }
} }
}
Free(b64_dest); Free(str);
}
} }
} }
} }

View File

@ -806,9 +806,6 @@ static UINT SmDdnsGetKey(char *key, SM_DDNS *d){
void SmDDnsDlgInit(HWND hWnd, SM_DDNS *d) void SmDDnsDlgInit(HWND hWnd, SM_DDNS *d)
{ {
char key[20];
char encodedkey[20 * 4 + 32];
// Validate arguments // Validate arguments
if (hWnd == NULL || d == NULL) if (hWnd == NULL || d == NULL)
{ {
@ -845,10 +842,15 @@ void SmDDnsDlgInit(HWND hWnd, SM_DDNS *d)
Hide(hWnd, B_PROXY); Hide(hWnd, B_PROXY);
if(SmDdnsGetKey(key, d) == ERR_NO_ERROR){ char key[20];
encodedkey[ B64_Encode(encodedkey, key, 20) ] = 0; if (SmDdnsGetKey(key, d) == ERR_NO_ERROR)
SetTextA(hWnd, E_KEY, encodedkey); {
}else{ char *encoded_key = Base64FromBin(NULL, key, sizeof(key));
SetTextA(hWnd, E_KEY, encoded_key);
Free(encoded_key);
}
else
{
SetText(hWnd, E_KEY, _UU("SM_DDNS_KEY_ERR")); SetText(hWnd, E_KEY, _UU("SM_DDNS_KEY_ERR"));
} }

View File

@ -15,6 +15,7 @@
#include "Radius.h" #include "Radius.h"
#include "Server.h" #include "Server.h"
#include "Mayaqua/Encoding.h"
#include "Mayaqua/Internat.h" #include "Mayaqua/Internat.h"
#include "Mayaqua/Memory.h" #include "Mayaqua/Memory.h"
#include "Mayaqua/Microsoft.h" #include "Mayaqua/Microsoft.h"
@ -31,11 +32,6 @@
#include <unistd.h> #include <unistd.h>
#endif #endif
int base64_enc_len(unsigned int plainLen) {
unsigned int n = plainLen;
return (n + 2 - ((n + 2) % 3)) / 3 * 4;
}
PID OpenChildProcess(const char* path, char* const parameter[], int fd[] ) PID OpenChildProcess(const char* path, char* const parameter[], int fd[] )
{ {
#ifdef OS_WIN32 #ifdef OS_WIN32
@ -134,7 +130,6 @@ bool SmbAuthenticate(char* name, char* password, char* domainname, char* groupna
int fds[2]; int fds[2];
FILE* out, *in; FILE* out, *in;
PID pid; PID pid;
char buffer[255];
char ntlm_timeout[32]; char ntlm_timeout[32];
char* proc_parameter[6]; char* proc_parameter[6];
@ -153,8 +148,6 @@ bool SmbAuthenticate(char* name, char* password, char* domainname, char* groupna
return false; return false;
} }
Zero(buffer, sizeof(buffer));
// Truncate string if unsafe char // Truncate string if unsafe char
EnSafeStr(domainname, '\0'); EnSafeStr(domainname, '\0');
@ -218,64 +211,48 @@ bool SmbAuthenticate(char* name, char* password, char* domainname, char* groupna
return false; return false;
} }
if (base64_enc_len((unsigned int)strlen(name)) < sizeof(buffer)-1 &&
base64_enc_len((unsigned int)strlen(password)) < sizeof(buffer)-1 &&
base64_enc_len((unsigned int)strlen(domainname)) < sizeof(buffer)-1)
{ {
char answer[300]; char *base64 = Base64FromBin(NULL, name, StrLen(name));
unsigned int end = B64_Encode(buffer, name, (int)strlen(name));
buffer[end] = '\0';
fputs("Username:: ", out); fputs("Username:: ", out);
fputs(buffer, out); fputs(base64, out);
fputs("\n", out); fputs("\n", out);
Debug("Username: %s\n", buffer); Free(base64);
buffer[0] = 0;
end = B64_Encode(buffer, domainname, (int)strlen(domainname)); base64 = Base64FromBin(NULL, domainname, StrLen(domainname));
buffer[end] = '\0';
fputs("NT-Domain:: ", out); fputs("NT-Domain:: ", out);
fputs(buffer, out); fputs(base64, out);
fputs("\n", out); fputs("\n", out);
Debug("NT-Domain: %s\n", buffer); Free(base64);
buffer[0] = 0;
if (password[0] != '\0') if (IsEmptyStr(password) == false)
{ {
Debug("Password authentication\n"); Debug("SmbAuthenticate(): Using password authentication...\n");
end = B64_Encode(buffer, password, (int)strlen(password));
buffer[end] = '\0'; base64 = Base64FromBin(NULL, password, StrLen(password));
fputs("Password:: ", out); fputs("Password:: ", out);
fputs(buffer, out); fputs(base64, out);
fputs("\n", out); fputs("\n", out);
Debug("Password: %s\n", buffer); Free(base64);
buffer[0] = 0;
} }
else else
{ {
char* mschapv2_client_response; Debug("SmbAuthenticate(): Using MsChapV2 authentication...\n");
char* base64_challenge8;
Debug("MsChapV2 authentication\n"); char *mschapv2_client_response = CopyBinToStr(MsChapV2_ClientResponse, 24);
mschapv2_client_response = CopyBinToStr(MsChapV2_ClientResponse, 24); base64 = Base64FromBin(NULL, mschapv2_client_response, 48);
end = B64_Encode(buffer, mschapv2_client_response, 48);
buffer[end] = '\0';
fputs("NT-Response:: ", out);
fputs(buffer, out);
fputs("\n", out);
Debug("NT-Response:: %s\n", buffer);
buffer[0] = 0;
Free(mschapv2_client_response); Free(mschapv2_client_response);
fputs("NT-Response:: ", out);
base64_challenge8 = CopyBinToStr(challenge8, 8); fputs(base64, out);
end = B64_Encode(buffer, base64_challenge8 , 16);
buffer[end] = '\0';
fputs("LANMAN-Challenge:: ", out);
fputs(buffer, out);
fputs("\n", out); fputs("\n", out);
Debug("LANMAN-Challenge:: %s\n", buffer); Free(base64);
buffer[0] = 0;
char *base64_challenge8 = CopyBinToStr(challenge8, 8);
base64 = Base64FromBin(NULL, base64_challenge8, 16);
Free(base64_challenge8); Free(base64_challenge8);
fputs("LANMAN-Challenge:: ", out);
fputs(base64, out);
fputs("\n", out);
Free(base64);
fputs("Request-User-Session-Key: Yes\n", out); fputs("Request-User-Session-Key: Yes\n", out);
} }
@ -285,6 +262,7 @@ bool SmbAuthenticate(char* name, char* password, char* domainname, char* groupna
fflush (out); fflush (out);
// Request send! // Request send!
char answer[300];
Zero(answer, sizeof(answer)); Zero(answer, sizeof(answer));
while (fgets(answer, sizeof(answer)-1, in)) while (fgets(answer, sizeof(answer)-1, in))
@ -323,7 +301,7 @@ bool SmbAuthenticate(char* name, char* password, char* domainname, char* groupna
response_parameter[0] ='\0'; response_parameter[0] ='\0';
response_parameter++; response_parameter++;
end = Decode64(response_parameter, response_parameter); const UINT end = Base64Decode(response_parameter, response_parameter, StrLen(response_parameter));
response_parameter[end] = '\0'; response_parameter[end] = '\0';
} }

View File

@ -11,6 +11,7 @@
#include "Protocol.h" #include "Protocol.h"
#include "Mayaqua/DNS.h" #include "Mayaqua/DNS.h"
#include "Mayaqua/Encoding.h"
#include "Mayaqua/Memory.h" #include "Mayaqua/Memory.h"
#include "Mayaqua/Microsoft.h" #include "Mayaqua/Microsoft.h"
#include "Mayaqua/Pack.h" #include "Mayaqua/Pack.h"
@ -807,19 +808,14 @@ BUF *HttpRequestEx3(URL_DATA *data, INTERNET_SETTING *setting,
if (IsEmptyStr(setting->ProxyUsername) == false || IsEmptyStr(setting->ProxyPassword) == false) if (IsEmptyStr(setting->ProxyUsername) == false || IsEmptyStr(setting->ProxyPassword) == false)
{ {
char auth_tmp_str[MAX_SIZE], auth_b64_str[MAX_SIZE * 2]; char auth_str[MAX_SIZE * 2];
char basic_str[MAX_SIZE * 2]; Format(auth_str, sizeof(auth_str), "%s:%s", setting->ProxyUsername, setting->ProxyPassword);
// Generate the authentication string char *base64 = Base64FromBin(NULL, auth_str, StrLen(auth_str));
Format(auth_tmp_str, sizeof(auth_tmp_str), "%s:%s", Format(auth_str, sizeof(auth_str), "Basic %s", base64);
setting->ProxyUsername, setting->ProxyPassword); Free(base64);
// Base64 encode AddHttpValue(h, NewHttpValue("Proxy-Authorization", auth_str));
Zero(auth_b64_str, sizeof(auth_b64_str));
Encode64(auth_b64_str, auth_tmp_str);
Format(basic_str, sizeof(basic_str), "Basic %s", auth_b64_str);
AddHttpValue(h, NewHttpValue("Proxy-Authorization", basic_str));
} }
} }
@ -1229,18 +1225,14 @@ bool ParseUrl(URL_DATA *data, char *str, bool is_post, char *referrer)
} }
// String replacement // String replacement
void Base64ToSafe64(char *str) void Base64ToSafe64(char *str, const UINT size)
{ {
UINT i, len; if (str == NULL || size == 0)
// Validate arguments
if (str == NULL)
{ {
return; return;
} }
len = StrLen(str); for (UINT i = 0; i < size; ++i)
for (i = 0;i < len;i++)
{ {
switch (str[i]) switch (str[i])
{ {
@ -1258,18 +1250,14 @@ void Base64ToSafe64(char *str)
} }
} }
} }
void Safe64ToBase64(char *str) void Safe64ToBase64(char *str, const UINT size)
{ {
UINT i, len; if (str == NULL || size == 0)
// Validate arguments
if (str == NULL)
{ {
return; return;
} }
len = StrLen(str); for (UINT i = 0; i < size; ++i)
for (i = 0;i < len;i++)
{ {
switch (str[i]) switch (str[i])
{ {
@ -1288,44 +1276,39 @@ void Safe64ToBase64(char *str)
} }
} }
// Decode from Safe64 // Decode from escaped Base64
UINT DecodeSafe64(void *dst, char *src, UINT src_strlen) UINT DecodeSafe64(void *dst, const char *src, UINT size)
{ {
char *tmp;
UINT ret;
if (dst == NULL || src == NULL) if (dst == NULL || src == NULL)
{ {
return 0; return 0;
} }
if (src_strlen == 0) if (size == 0)
{ {
src_strlen = StrLen(src); size = StrLen(src);
} }
tmp = Malloc(src_strlen + 1); char *tmp = Malloc(size + 1);
Copy(tmp, src, src_strlen); Copy(tmp, src, size);
tmp[src_strlen] = 0; tmp[size] = '\0';
Safe64ToBase64(tmp);
ret = B64_Decode(dst, tmp, src_strlen); Safe64ToBase64(tmp, size);
const UINT ret = Base64Decode(dst, tmp, size);
Free(tmp); Free(tmp);
return ret; return ret;
} }
// Encode to Safe64 // Encode to escaped Base64
void EncodeSafe64(char *dst, void *src, UINT src_size) void EncodeSafe64(char *dst, const void *src, const UINT size)
{ {
UINT size;
if (dst == NULL || src == NULL) if (dst == NULL || src == NULL)
{ {
return; return;
} }
size = B64_Encode(dst, src, src_size); const UINT ret = Base64Encode(dst, src, size);
dst[size] = 0;
Base64ToSafe64(dst); Base64ToSafe64(dst, ret);
} }

View File

@ -84,10 +84,10 @@ struct WPC_PACKET
typedef bool (WPC_RECV_CALLBACK)(void *param, UINT total_size, UINT current_size, BUF *recv_buf); typedef bool (WPC_RECV_CALLBACK)(void *param, UINT total_size, UINT current_size, BUF *recv_buf);
// Function prototype // Function prototype
void EncodeSafe64(char *dst, void *src, UINT src_size); void Base64ToSafe64(char *str, const UINT size);
UINT DecodeSafe64(void *dst, char *src, UINT src_strlen); void Safe64ToBase64(char *str, const UINT size);
void Base64ToSafe64(char *str); UINT DecodeSafe64(void *dst, const char *src, UINT size);
void Safe64ToBase64(char *str); void EncodeSafe64(char *dst, const void *src, const UINT size);
bool ParseUrl(URL_DATA *data, char *str, bool is_post, char *referrer); bool ParseUrl(URL_DATA *data, char *str, bool is_post, char *referrer);
void CreateUrl(char *url, UINT url_size, URL_DATA *data); void CreateUrl(char *url, UINT url_size, URL_DATA *data);
void GetSystemInternetSetting(INTERNET_SETTING *setting); void GetSystemInternetSetting(INTERNET_SETTING *setting);

View File

@ -57,9 +57,16 @@ if(UNIX)
# In some cases libiconv is not included in libc # In some cases libiconv is not included in libc
find_library(LIB_ICONV iconv) find_library(LIB_ICONV iconv)
find_library(LIB_M m)
find_library(LIB_RT rt) find_library(LIB_RT rt)
target_link_libraries(mayaqua PRIVATE Threads::Threads) target_link_libraries(mayaqua
PRIVATE
Threads::Threads
$<$<BOOL:${LIB_ICONV}>:${LIB_ICONV}>
$<$<BOOL:${LIB_M}>:${LIB_M}>
$<$<BOOL:${LIB_RT}>:${LIB_RT}>
)
if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(armv7l|aarch64|s390x)$" OR NOT HAVE_SYS_AUXV OR SKIP_CPU_FEATURES) if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(armv7l|aarch64|s390x)$" OR NOT HAVE_SYS_AUXV OR SKIP_CPU_FEATURES)
add_definitions(-DSKIP_CPU_FEATURES) add_definitions(-DSKIP_CPU_FEATURES)
@ -69,14 +76,6 @@ if(UNIX)
target_link_libraries(mayaqua PRIVATE cpu_features) target_link_libraries(mayaqua PRIVATE cpu_features)
endif() endif()
if(LIB_RT)
target_link_libraries(mayaqua PRIVATE rt)
endif()
if(LIB_ICONV)
target_link_libraries(mayaqua PRIVATE ${LIB_ICONV})
endif()
if(${CMAKE_SYSTEM_NAME} STREQUAL "SunOS") if(${CMAKE_SYSTEM_NAME} STREQUAL "SunOS")
target_link_libraries(mayaqua PRIVATE nsl socket) target_link_libraries(mayaqua PRIVATE nsl socket)
endif() endif()

View File

@ -7,6 +7,7 @@
#include "Cfg.h" #include "Cfg.h"
#include "Encoding.h"
#include "FileIO.h" #include "FileIO.h"
#include "Internat.h" #include "Internat.h"
#include "Memory.h" #include "Memory.h"
@ -746,12 +747,18 @@ bool CfgReadNextTextBUF(BUF *b, FOLDER *current)
if (!StrCmpi(token->Token[0], TAG_BYTE)) if (!StrCmpi(token->Token[0], TAG_BYTE))
{ {
// byte // byte
char *unescaped_b64 = CfgUnescape(data); char *base64 = CfgUnescape(data);
void *tmp = Malloc(StrLen(unescaped_b64) * 4 + 64); const UINT base64_size = StrLen(base64);
int size = B64_Decode(tmp, unescaped_b64, StrLen(unescaped_b64));
CfgAddByte(current, name, tmp, size); UINT bin_size;
Free(tmp); void *bin = Base64ToBin(&bin_size, base64, base64_size);
Free(unescaped_b64); if (bin != NULL)
{
CfgAddByte(current, name, bin, bin_size);
Free(bin);
}
Free(base64);
} }
Free(name); Free(name);
@ -1162,9 +1169,7 @@ void CfgAddItemText(BUF *b, ITEM *t, UINT depth)
break; break;
case ITEM_TYPE_BYTE: case ITEM_TYPE_BYTE:
data = ZeroMalloc(t->size * 4 + 32); data = Base64FromBin(NULL, t->Buf, t->size);
len = B64_Encode(data, t->Buf, t->size);
data[len] = 0;
break; break;
case ITEM_TYPE_STRING: case ITEM_TYPE_STRING:

64
src/Mayaqua/Encoding.c Normal file
View File

@ -0,0 +1,64 @@
#include "Encoding.h"
#include <math.h>
#include <openssl/evp.h>
UINT Base64Decode(void *dst, const void *src, const UINT size)
{
if (dst == NULL)
{
// 4 input bytes = max. 3 output bytes.
//
// EVP_DecodeUpdate() ignores:
// - Leading/trailing whitespace.
// - Trailing newlines, carriage returns or EOF characters.
//
// EVP_DecodeFinal() fails if the input is not divisible by 4.
return size / 4 * 3;
}
// We don't use EVP_DecodeBlock() because it adds padding if the output is not divisible by 3.
EVP_ENCODE_CTX *ctx = EVP_ENCODE_CTX_new();
if (ctx == NULL)
{
return 0;
}
int ret = 0;
if (EVP_DecodeUpdate(ctx, dst, &ret, src, size) < 0)
{
goto FINAL;
}
int dummy;
if (EVP_DecodeFinal(ctx, dst, &dummy) < 0)
{
ret = 0;
}
FINAL:
EVP_ENCODE_CTX_free(ctx);
return ret;
}
UINT Base64Encode(void *dst, const void *src, const UINT size)
{
if (dst == NULL)
{
// 3 input bytes = 4 output bytes.
// +1 for the NUL terminator.
//
// EVP_EncodeBlock() adds padding when the input is not divisible by 3.
return ceilf((float)size / 3) * 4 + 1;
}
const int ret = EVP_EncodeBlock(dst, src, size);
if (ret > 0)
{
// EVP_EncodeBlock() returns the length of the string without the NUL terminator.
// We, instead, want to return the amount of bytes written into the output buffer.
return ret + 1;
}
return 0;
}

9
src/Mayaqua/Encoding.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef ENCODING_H
#define ENCODING_H
#include "MayaType.h"
UINT Base64Decode(void *dst, const void *src, const UINT size);
UINT Base64Encode(void *dst, const void *src, const UINT size);
#endif

View File

@ -7,6 +7,7 @@
#include "Memory.h" #include "Memory.h"
#include "Encoding.h"
#include "Encrypt.h" #include "Encrypt.h"
#include "FileIO.h" #include "FileIO.h"
#include "Internat.h" #include "Internat.h"
@ -3407,232 +3408,62 @@ UINT64 Swap64(UINT64 value)
return r; return r;
} }
// Base64 encode void *Base64ToBin(UINT *out_size, const void *src, const UINT size)
UINT Encode64(char *dst, char *src)
{ {
// Validate arguments if (src == NULL || size == 0)
if (dst == NULL || src == NULL)
{ {
return 0; return NULL;
} }
return B64_Encode(dst, src, StrLen(src)); UINT bin_size = Base64Decode(NULL, src, size);
if (bin_size == 0)
{
return NULL;
}
void *bin = Malloc(bin_size);
bin_size = Base64Decode(bin, src, size);
if (bin_size == 0)
{
Free(bin);
return NULL;
}
if (out_size != NULL)
{
*out_size = bin_size;
}
return bin;
} }
// Base64 decoding void *Base64FromBin(UINT *out_size, const void *src, const UINT size)
UINT Decode64(char *dst, char *src)
{ {
// Validate arguments if (src == NULL || size == 0)
if (dst == NULL || src == NULL)
{ {
return 0; return NULL;
} }
return B64_Decode(dst, src, StrLen(src)); UINT base64_size = Base64Encode(NULL, src, size);
} if (base64_size == 0)
{
return NULL;
}
// Base64 encode void *base64 = Malloc(base64_size);
int B64_Encode(char *set, char *source, int len) base64_size = Base64Encode(base64, src, size);
{ if (base64_size == 0)
BYTE *src;
int i,j;
src = (BYTE *)source;
j = 0;
i = 0;
if (!len)
{ {
return 0; Free(base64);
return NULL;
} }
while (true)
{
if (i >= len)
{
return j;
}
if (set)
{
set[j] = B64_CodeToChar((src[i]) >> 2);
}
if (i + 1 >= len)
{
if (set)
{
set[j + 1] = B64_CodeToChar((src[i] & 0x03) << 4);
set[j + 2] = '=';
set[j + 3] = '=';
}
return j + 4;
}
if (set)
{
set[j + 1] = B64_CodeToChar(((src[i] & 0x03) << 4) + ((src[i + 1] >> 4)));
}
if (i + 2 >= len)
{
if (set)
{
set[j + 2] = B64_CodeToChar((src[i + 1] & 0x0f) << 2);
set[j + 3] = '=';
}
return j + 4;
}
if (set)
{
set[j + 2] = B64_CodeToChar(((src[i + 1] & 0x0f) << 2) + ((src[i + 2] >> 6)));
set[j + 3] = B64_CodeToChar(src[i + 2] & 0x3f);
}
i += 3;
j += 4;
}
}
// Base64 decode if (out_size != NULL)
int B64_Decode(char *set, char *source, int len)
{
int i,j;
char a1,a2,a3,a4;
char *src;
int f1,f2,f3,f4;
src = source;
i = 0;
j = 0;
while (true)
{ {
f1 = f2 = f3 = f4 = 0; *out_size = base64_size;
if (i >= len)
{
break;
} }
f1 = 1;
a1 = B64_CharToCode(src[i]);
if (a1 == -1)
{
f1 = 0;
}
if (i >= len + 1)
{
a2 = 0;
}
else
{
a2 = B64_CharToCode(src[i + 1]);
f2 = 1;
if (a2 == -1)
{
f2 = 0;
}
}
if (i >= len + 2)
{
a3 = 0;
}
else
{
a3 = B64_CharToCode(src[i + 2]);
f3 = 1;
if (a3 == -1)
{
f3 = 0;
}
}
if (i >= len + 3)
{
a4 = 0;
}
else
{
a4 = B64_CharToCode(src[i + 3]);
f4 = 1;
if (a4 == -1)
{
f4 = 0;
}
}
if (f1 && f2)
{
if (set)
{
set[j] = (a1 << 2) + (a2 >> 4);
}
j++;
}
if (f2 && f3)
{
if (set)
{
set[j] = (a2 << 4) + (a3 >> 2);
}
j++;
}
if (f3 && f4)
{
if (set)
{
set[j] = (a3 << 6) + a4;
}
j++;
}
i += 4;
}
return j;
}
// Base64 : Convert a code to a character return base64;
char B64_CodeToChar(BYTE c)
{
BYTE r;
r = '=';
if (c <= 0x19)
{
r = c + 'A';
}
if (c >= 0x1a && c <= 0x33)
{
r = c - 0x1a + 'a';
}
if (c >= 0x34 && c <= 0x3d)
{
r = c - 0x34 + '0';
}
if (c == 0x3e)
{
r = '+';
}
if (c == 0x3f)
{
r = '/';
}
return r;
}
// Base64 : Convert a character to a code
char B64_CharToCode(char c)
{
if (c >= 'A' && c <= 'Z')
{
return c - 'A';
}
if (c >= 'a' && c <= 'z')
{
return c - 'a' + 0x1a;
}
if (c >= '0' && c <= '9')
{
return c - '0' + 0x34;
}
if (c == '+')
{
return 0x3e;
}
if (c == '/')
{
return 0x3f;
}
if (c == '=')
{
return -1;
}
return 0;
} }
// Malloc // Malloc

View File

@ -190,12 +190,8 @@ void Zero(void *addr, UINT size);
void *Clone(void *addr, UINT size); void *Clone(void *addr, UINT size);
void *AddHead(void *src, UINT src_size, void *head, UINT head_size); void *AddHead(void *src, UINT src_size, void *head, UINT head_size);
char B64_CodeToChar(BYTE c); void *Base64FromBin(UINT *out_size, const void *src, const UINT size);
char B64_CharToCode(char c); void *Base64ToBin(UINT *out_size, const void *src, const UINT size);
int B64_Encode(char *set, char *source, int len);
int B64_Decode(char *set, char *source, int len);
UINT Encode64(char *dst, char *src);
UINT Decode64(char *dst, char *src);
USHORT Swap16(USHORT value); USHORT Swap16(USHORT value);
UINT Swap32(UINT value); UINT Swap32(UINT value);

View File

@ -2239,10 +2239,9 @@ bool JsonTryParseValueAddToPack(PACK *p, JSON_VALUE *v, char *v_name, UINT index
{ {
if (v->type == JSON_TYPE_STRING) if (v->type == JSON_TYPE_STRING)
{ {
UINT len = StrLen(v->value.string); UINT data_size;
UCHAR *data = ZeroMalloc(len * 4 + 64); void *data = Base64ToBin(&data_size, v->value.string, StrLen(v->value.string));
UINT size = B64_Decode(data, v->value.string, len); ElementNullSafe(PackAddDataEx(p, name, data, data_size, index, total))->JsonHint_IsArray = !is_single;
ElementNullSafe(PackAddDataEx(p, name, data, size, index, total))->JsonHint_IsArray = !is_single;
Free(data); Free(data);
ok = true; ok = true;
} }

View File

@ -129,17 +129,12 @@ UINT ProxyHttpConnect(PROXY_PARAM_OUT *out, PROXY_PARAM_IN *in, volatile bool *c
if (use_auth && GetHttpValue(h, "Proxy-Authorization") == NULL) if (use_auth && GetHttpValue(h, "Proxy-Authorization") == NULL)
{ {
char auth_str[MAX_SIZE * 2], auth_b64_str[MAX_SIZE * 2]; char auth_str[MAX_SIZE * 2];
// Generate the authentication string
Format(auth_str, sizeof(auth_str), "%s:%s", in->Username, in->Password); Format(auth_str, sizeof(auth_str), "%s:%s", in->Username, in->Password);
// Base64 encode char *base64 = Base64FromBin(NULL, auth_str, StrLen(auth_str));
Zero(auth_b64_str, sizeof(auth_b64_str)); Format(auth_str, sizeof(auth_str), "Basic %s", base64);
Encode64(auth_b64_str, auth_str); Free(base64);
// Generate final string
Format(auth_str, sizeof(auth_str), "Basic %s", auth_b64_str);
AddHttpValue(h, NewHttpValue("Proxy-Authorization", auth_str)); AddHttpValue(h, NewHttpValue("Proxy-Authorization", auth_str));
} }

View File

@ -4667,12 +4667,11 @@ UINT JsonArrayAddNumber(JSON_ARRAY *array, UINT64 number) {
UINT JsonArrayAddData(JSON_ARRAY *array, void *data, UINT size) UINT JsonArrayAddData(JSON_ARRAY *array, void *data, UINT size)
{ {
UINT ret; UINT ret;
char *b64 = ZeroMalloc(size * 4 + 32); char *base64 = Base64FromBin(NULL, data, size);
B64_Encode(b64, data, size);
ret = JsonArrayAddStr(array, b64); ret = JsonArrayAddStr(array, base64);
Free(b64); Free(base64);
return ret; return ret;
} }
@ -4724,12 +4723,11 @@ UINT JsonSet(JSON_OBJECT *object, char *name, JSON_VALUE *value) {
UINT JsonSetData(JSON_OBJECT *object, char *name, void *data, UINT size) UINT JsonSetData(JSON_OBJECT *object, char *name, void *data, UINT size)
{ {
UINT ret; UINT ret;
char *b64 = ZeroMalloc(size * 4 + 32); char *base64 = Base64FromBin(NULL, data, size);
B64_Encode(b64, data, size);
ret = JsonSetStr(object, name, b64); ret = JsonSetStr(object, name, base64);
Free(b64); Free(base64);
return ret; return ret;
} }