mirror of
https://github.com/SoftEtherVPN/SoftEtherVPN.git
synced 2024-12-27 02:29:52 +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:
commit
08905e57a6
@ -939,30 +939,26 @@ bool HttpParseBasicAuthHeader(HTTP_HEADER *h, char *username, UINT username_size
|
||||
{
|
||||
if (StrCmpi(key, "Basic") == 0 && IsEmptyStr(value) == false)
|
||||
{
|
||||
UINT b64_dest_size = StrSize(value) * 2 + 256;
|
||||
char *b64_dest = ZeroMalloc(b64_dest_size);
|
||||
|
||||
Decode64(b64_dest, value);
|
||||
|
||||
if (IsEmptyStr(b64_dest) == false)
|
||||
char *str = Base64ToBin(NULL, value, StrLen(value));
|
||||
if (str != NULL)
|
||||
{
|
||||
if (b64_dest[0] == ':')
|
||||
if (str[0] == ':')
|
||||
{
|
||||
// Empty username
|
||||
StrCpy(username, username_size, "");
|
||||
StrCpy(password, password_size, b64_dest + 1);
|
||||
StrCpy(password, password_size, str + 1);
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GetKeyAndValue(b64_dest, username, username_size, password, password_size, ":"))
|
||||
if (GetKeyAndValue(str, username, username_size, password, password_size, ":"))
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Free(b64_dest);
|
||||
Free(str);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -806,9 +806,6 @@ static UINT SmDdnsGetKey(char *key, SM_DDNS *d){
|
||||
|
||||
void SmDDnsDlgInit(HWND hWnd, SM_DDNS *d)
|
||||
{
|
||||
char key[20];
|
||||
char encodedkey[20 * 4 + 32];
|
||||
|
||||
// Validate arguments
|
||||
if (hWnd == NULL || d == NULL)
|
||||
{
|
||||
@ -845,10 +842,15 @@ void SmDDnsDlgInit(HWND hWnd, SM_DDNS *d)
|
||||
|
||||
Hide(hWnd, B_PROXY);
|
||||
|
||||
if(SmDdnsGetKey(key, d) == ERR_NO_ERROR){
|
||||
encodedkey[ B64_Encode(encodedkey, key, 20) ] = 0;
|
||||
SetTextA(hWnd, E_KEY, encodedkey);
|
||||
}else{
|
||||
char key[20];
|
||||
if (SmDdnsGetKey(key, d) == ERR_NO_ERROR)
|
||||
{
|
||||
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"));
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "Radius.h"
|
||||
#include "Server.h"
|
||||
|
||||
#include "Mayaqua/Encoding.h"
|
||||
#include "Mayaqua/Internat.h"
|
||||
#include "Mayaqua/Memory.h"
|
||||
#include "Mayaqua/Microsoft.h"
|
||||
@ -31,11 +32,6 @@
|
||||
#include <unistd.h>
|
||||
#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[] )
|
||||
{
|
||||
#ifdef OS_WIN32
|
||||
@ -134,7 +130,6 @@ bool SmbAuthenticate(char* name, char* password, char* domainname, char* groupna
|
||||
int fds[2];
|
||||
FILE* out, *in;
|
||||
PID pid;
|
||||
char buffer[255];
|
||||
char ntlm_timeout[32];
|
||||
char* proc_parameter[6];
|
||||
|
||||
@ -153,8 +148,6 @@ bool SmbAuthenticate(char* name, char* password, char* domainname, char* groupna
|
||||
return false;
|
||||
}
|
||||
|
||||
Zero(buffer, sizeof(buffer));
|
||||
|
||||
// Truncate string if unsafe char
|
||||
EnSafeStr(domainname, '\0');
|
||||
|
||||
@ -218,64 +211,48 @@ bool SmbAuthenticate(char* name, char* password, char* domainname, char* groupna
|
||||
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];
|
||||
|
||||
unsigned int end = B64_Encode(buffer, name, (int)strlen(name));
|
||||
buffer[end] = '\0';
|
||||
char *base64 = Base64FromBin(NULL, name, StrLen(name));
|
||||
fputs("Username:: ", out);
|
||||
fputs(buffer, out);
|
||||
fputs(base64, out);
|
||||
fputs("\n", out);
|
||||
Debug("Username: %s\n", buffer);
|
||||
buffer[0] = 0;
|
||||
Free(base64);
|
||||
|
||||
end = B64_Encode(buffer, domainname, (int)strlen(domainname));
|
||||
buffer[end] = '\0';
|
||||
base64 = Base64FromBin(NULL, domainname, StrLen(domainname));
|
||||
fputs("NT-Domain:: ", out);
|
||||
fputs(buffer, out);
|
||||
fputs(base64, out);
|
||||
fputs("\n", out);
|
||||
Debug("NT-Domain: %s\n", buffer);
|
||||
buffer[0] = 0;
|
||||
Free(base64);
|
||||
|
||||
if (password[0] != '\0')
|
||||
if (IsEmptyStr(password) == false)
|
||||
{
|
||||
Debug("Password authentication\n");
|
||||
end = B64_Encode(buffer, password, (int)strlen(password));
|
||||
buffer[end] = '\0';
|
||||
Debug("SmbAuthenticate(): Using password authentication...\n");
|
||||
|
||||
base64 = Base64FromBin(NULL, password, StrLen(password));
|
||||
fputs("Password:: ", out);
|
||||
fputs(buffer, out);
|
||||
fputs(base64, out);
|
||||
fputs("\n", out);
|
||||
Debug("Password: %s\n", buffer);
|
||||
buffer[0] = 0;
|
||||
Free(base64);
|
||||
}
|
||||
else
|
||||
{
|
||||
char* mschapv2_client_response;
|
||||
char* base64_challenge8;
|
||||
Debug("SmbAuthenticate(): Using MsChapV2 authentication...\n");
|
||||
|
||||
Debug("MsChapV2 authentication\n");
|
||||
mschapv2_client_response = CopyBinToStr(MsChapV2_ClientResponse, 24);
|
||||
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;
|
||||
char *mschapv2_client_response = CopyBinToStr(MsChapV2_ClientResponse, 24);
|
||||
base64 = Base64FromBin(NULL, mschapv2_client_response, 48);
|
||||
Free(mschapv2_client_response);
|
||||
|
||||
base64_challenge8 = CopyBinToStr(challenge8, 8);
|
||||
end = B64_Encode(buffer, base64_challenge8 , 16);
|
||||
buffer[end] = '\0';
|
||||
fputs("LANMAN-Challenge:: ", out);
|
||||
fputs(buffer, out);
|
||||
fputs("NT-Response:: ", out);
|
||||
fputs(base64, out);
|
||||
fputs("\n", out);
|
||||
Debug("LANMAN-Challenge:: %s\n", buffer);
|
||||
buffer[0] = 0;
|
||||
Free(base64);
|
||||
|
||||
char *base64_challenge8 = CopyBinToStr(challenge8, 8);
|
||||
base64 = Base64FromBin(NULL, base64_challenge8, 16);
|
||||
Free(base64_challenge8);
|
||||
fputs("LANMAN-Challenge:: ", out);
|
||||
fputs(base64, out);
|
||||
fputs("\n", out);
|
||||
Free(base64);
|
||||
|
||||
fputs("Request-User-Session-Key: Yes\n", out);
|
||||
}
|
||||
@ -285,6 +262,7 @@ bool SmbAuthenticate(char* name, char* password, char* domainname, char* groupna
|
||||
fflush (out);
|
||||
// Request send!
|
||||
|
||||
char answer[300];
|
||||
Zero(answer, sizeof(answer));
|
||||
|
||||
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++;
|
||||
|
||||
end = Decode64(response_parameter, response_parameter);
|
||||
const UINT end = Base64Decode(response_parameter, response_parameter, StrLen(response_parameter));
|
||||
response_parameter[end] = '\0';
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "Protocol.h"
|
||||
|
||||
#include "Mayaqua/DNS.h"
|
||||
#include "Mayaqua/Encoding.h"
|
||||
#include "Mayaqua/Memory.h"
|
||||
#include "Mayaqua/Microsoft.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)
|
||||
{
|
||||
char auth_tmp_str[MAX_SIZE], auth_b64_str[MAX_SIZE * 2];
|
||||
char basic_str[MAX_SIZE * 2];
|
||||
char auth_str[MAX_SIZE * 2];
|
||||
Format(auth_str, sizeof(auth_str), "%s:%s", setting->ProxyUsername, setting->ProxyPassword);
|
||||
|
||||
// Generate the authentication string
|
||||
Format(auth_tmp_str, sizeof(auth_tmp_str), "%s:%s",
|
||||
setting->ProxyUsername, setting->ProxyPassword);
|
||||
char *base64 = Base64FromBin(NULL, auth_str, StrLen(auth_str));
|
||||
Format(auth_str, sizeof(auth_str), "Basic %s", base64);
|
||||
Free(base64);
|
||||
|
||||
// Base64 encode
|
||||
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));
|
||||
AddHttpValue(h, NewHttpValue("Proxy-Authorization", auth_str));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1229,18 +1225,14 @@ bool ParseUrl(URL_DATA *data, char *str, bool is_post, char *referrer)
|
||||
}
|
||||
|
||||
// String replacement
|
||||
void Base64ToSafe64(char *str)
|
||||
void Base64ToSafe64(char *str, const UINT size)
|
||||
{
|
||||
UINT i, len;
|
||||
// Validate arguments
|
||||
if (str == NULL)
|
||||
if (str == NULL || size == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
len = StrLen(str);
|
||||
|
||||
for (i = 0;i < len;i++)
|
||||
for (UINT i = 0; i < size; ++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;
|
||||
// Validate arguments
|
||||
if (str == NULL)
|
||||
if (str == NULL || size == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
len = StrLen(str);
|
||||
|
||||
for (i = 0;i < len;i++)
|
||||
for (UINT i = 0; i < size; ++i)
|
||||
{
|
||||
switch (str[i])
|
||||
{
|
||||
@ -1288,44 +1276,39 @@ void Safe64ToBase64(char *str)
|
||||
}
|
||||
}
|
||||
|
||||
// Decode from Safe64
|
||||
UINT DecodeSafe64(void *dst, char *src, UINT src_strlen)
|
||||
// Decode from escaped Base64
|
||||
UINT DecodeSafe64(void *dst, const char *src, UINT size)
|
||||
{
|
||||
char *tmp;
|
||||
UINT ret;
|
||||
if (dst == NULL || src == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (src_strlen == 0)
|
||||
if (size == 0)
|
||||
{
|
||||
src_strlen = StrLen(src);
|
||||
size = StrLen(src);
|
||||
}
|
||||
|
||||
tmp = Malloc(src_strlen + 1);
|
||||
Copy(tmp, src, src_strlen);
|
||||
tmp[src_strlen] = 0;
|
||||
Safe64ToBase64(tmp);
|
||||
char *tmp = Malloc(size + 1);
|
||||
Copy(tmp, src, size);
|
||||
tmp[size] = '\0';
|
||||
|
||||
ret = B64_Decode(dst, tmp, src_strlen);
|
||||
Safe64ToBase64(tmp, size);
|
||||
const UINT ret = Base64Decode(dst, tmp, size);
|
||||
Free(tmp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Encode to Safe64
|
||||
void EncodeSafe64(char *dst, void *src, UINT src_size)
|
||||
// Encode to escaped Base64
|
||||
void EncodeSafe64(char *dst, const void *src, const UINT size)
|
||||
{
|
||||
UINT size;
|
||||
if (dst == NULL || src == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
size = B64_Encode(dst, src, src_size);
|
||||
dst[size] = 0;
|
||||
const UINT ret = Base64Encode(dst, src, size);
|
||||
|
||||
Base64ToSafe64(dst);
|
||||
Base64ToSafe64(dst, ret);
|
||||
}
|
||||
|
||||
|
@ -84,10 +84,10 @@ struct WPC_PACKET
|
||||
typedef bool (WPC_RECV_CALLBACK)(void *param, UINT total_size, UINT current_size, BUF *recv_buf);
|
||||
|
||||
// Function prototype
|
||||
void EncodeSafe64(char *dst, void *src, UINT src_size);
|
||||
UINT DecodeSafe64(void *dst, char *src, UINT src_strlen);
|
||||
void Base64ToSafe64(char *str);
|
||||
void Safe64ToBase64(char *str);
|
||||
void Base64ToSafe64(char *str, const UINT size);
|
||||
void Safe64ToBase64(char *str, const UINT size);
|
||||
UINT DecodeSafe64(void *dst, const char *src, UINT size);
|
||||
void EncodeSafe64(char *dst, const void *src, const UINT size);
|
||||
bool ParseUrl(URL_DATA *data, char *str, bool is_post, char *referrer);
|
||||
void CreateUrl(char *url, UINT url_size, URL_DATA *data);
|
||||
void GetSystemInternetSetting(INTERNET_SETTING *setting);
|
||||
|
@ -57,9 +57,16 @@ if(UNIX)
|
||||
# In some cases libiconv is not included in libc
|
||||
find_library(LIB_ICONV iconv)
|
||||
|
||||
find_library(LIB_M m)
|
||||
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)
|
||||
add_definitions(-DSKIP_CPU_FEATURES)
|
||||
@ -69,14 +76,6 @@ if(UNIX)
|
||||
target_link_libraries(mayaqua PRIVATE cpu_features)
|
||||
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")
|
||||
target_link_libraries(mayaqua PRIVATE nsl socket)
|
||||
endif()
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "Cfg.h"
|
||||
|
||||
#include "Encoding.h"
|
||||
#include "FileIO.h"
|
||||
#include "Internat.h"
|
||||
#include "Memory.h"
|
||||
@ -746,12 +747,18 @@ bool CfgReadNextTextBUF(BUF *b, FOLDER *current)
|
||||
if (!StrCmpi(token->Token[0], TAG_BYTE))
|
||||
{
|
||||
// byte
|
||||
char *unescaped_b64 = CfgUnescape(data);
|
||||
void *tmp = Malloc(StrLen(unescaped_b64) * 4 + 64);
|
||||
int size = B64_Decode(tmp, unescaped_b64, StrLen(unescaped_b64));
|
||||
CfgAddByte(current, name, tmp, size);
|
||||
Free(tmp);
|
||||
Free(unescaped_b64);
|
||||
char *base64 = CfgUnescape(data);
|
||||
const UINT base64_size = StrLen(base64);
|
||||
|
||||
UINT bin_size;
|
||||
void *bin = Base64ToBin(&bin_size, base64, base64_size);
|
||||
if (bin != NULL)
|
||||
{
|
||||
CfgAddByte(current, name, bin, bin_size);
|
||||
Free(bin);
|
||||
}
|
||||
|
||||
Free(base64);
|
||||
}
|
||||
|
||||
Free(name);
|
||||
@ -1162,9 +1169,7 @@ void CfgAddItemText(BUF *b, ITEM *t, UINT depth)
|
||||
break;
|
||||
|
||||
case ITEM_TYPE_BYTE:
|
||||
data = ZeroMalloc(t->size * 4 + 32);
|
||||
len = B64_Encode(data, t->Buf, t->size);
|
||||
data[len] = 0;
|
||||
data = Base64FromBin(NULL, t->Buf, t->size);
|
||||
break;
|
||||
|
||||
case ITEM_TYPE_STRING:
|
||||
|
64
src/Mayaqua/Encoding.c
Normal file
64
src/Mayaqua/Encoding.c
Normal 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
9
src/Mayaqua/Encoding.h
Normal 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
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "Memory.h"
|
||||
|
||||
#include "Encoding.h"
|
||||
#include "Encrypt.h"
|
||||
#include "FileIO.h"
|
||||
#include "Internat.h"
|
||||
@ -3407,232 +3408,62 @@ UINT64 Swap64(UINT64 value)
|
||||
return r;
|
||||
}
|
||||
|
||||
// Base64 encode
|
||||
UINT Encode64(char *dst, char *src)
|
||||
void *Base64ToBin(UINT *out_size, const void *src, const UINT size)
|
||||
{
|
||||
// Validate arguments
|
||||
if (dst == NULL || src == NULL)
|
||||
if (src == NULL || size == 0)
|
||||
{
|
||||
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
|
||||
UINT Decode64(char *dst, char *src)
|
||||
void *Base64FromBin(UINT *out_size, const void *src, const UINT size)
|
||||
{
|
||||
// Validate arguments
|
||||
if (dst == NULL || src == NULL)
|
||||
if (src == NULL || size == 0)
|
||||
{
|
||||
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
|
||||
int B64_Encode(char *set, char *source, int len)
|
||||
{
|
||||
BYTE *src;
|
||||
int i,j;
|
||||
src = (BYTE *)source;
|
||||
j = 0;
|
||||
i = 0;
|
||||
if (!len)
|
||||
void *base64 = Malloc(base64_size);
|
||||
base64_size = Base64Encode(base64, src, size);
|
||||
if (base64_size == 0)
|
||||
{
|
||||
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
|
||||
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)
|
||||
if (out_size != NULL)
|
||||
{
|
||||
f1 = f2 = f3 = f4 = 0;
|
||||
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;
|
||||
*out_size = base64_size;
|
||||
}
|
||||
return j;
|
||||
}
|
||||
|
||||
// Base64 : Convert a code to a character
|
||||
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;
|
||||
return base64;
|
||||
}
|
||||
|
||||
// Malloc
|
||||
|
@ -190,12 +190,8 @@ void Zero(void *addr, UINT size);
|
||||
void *Clone(void *addr, UINT size);
|
||||
void *AddHead(void *src, UINT src_size, void *head, UINT head_size);
|
||||
|
||||
char B64_CodeToChar(BYTE c);
|
||||
char B64_CharToCode(char c);
|
||||
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);
|
||||
void *Base64FromBin(UINT *out_size, const void *src, const UINT size);
|
||||
void *Base64ToBin(UINT *out_size, const void *src, const UINT size);
|
||||
|
||||
USHORT Swap16(USHORT value);
|
||||
UINT Swap32(UINT value);
|
||||
|
@ -2239,10 +2239,9 @@ bool JsonTryParseValueAddToPack(PACK *p, JSON_VALUE *v, char *v_name, UINT index
|
||||
{
|
||||
if (v->type == JSON_TYPE_STRING)
|
||||
{
|
||||
UINT len = StrLen(v->value.string);
|
||||
UCHAR *data = ZeroMalloc(len * 4 + 64);
|
||||
UINT size = B64_Decode(data, v->value.string, len);
|
||||
ElementNullSafe(PackAddDataEx(p, name, data, size, index, total))->JsonHint_IsArray = !is_single;
|
||||
UINT data_size;
|
||||
void *data = Base64ToBin(&data_size, v->value.string, StrLen(v->value.string));
|
||||
ElementNullSafe(PackAddDataEx(p, name, data, data_size, index, total))->JsonHint_IsArray = !is_single;
|
||||
Free(data);
|
||||
ok = true;
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
char auth_str[MAX_SIZE * 2], auth_b64_str[MAX_SIZE * 2];
|
||||
|
||||
// Generate the authentication string
|
||||
char auth_str[MAX_SIZE * 2];
|
||||
Format(auth_str, sizeof(auth_str), "%s:%s", in->Username, in->Password);
|
||||
|
||||
// Base64 encode
|
||||
Zero(auth_b64_str, sizeof(auth_b64_str));
|
||||
Encode64(auth_b64_str, auth_str);
|
||||
|
||||
// Generate final string
|
||||
Format(auth_str, sizeof(auth_str), "Basic %s", auth_b64_str);
|
||||
char *base64 = Base64FromBin(NULL, auth_str, StrLen(auth_str));
|
||||
Format(auth_str, sizeof(auth_str), "Basic %s", base64);
|
||||
Free(base64);
|
||||
|
||||
AddHttpValue(h, NewHttpValue("Proxy-Authorization", auth_str));
|
||||
}
|
||||
|
@ -4667,12 +4667,11 @@ UINT JsonArrayAddNumber(JSON_ARRAY *array, UINT64 number) {
|
||||
UINT JsonArrayAddData(JSON_ARRAY *array, void *data, UINT size)
|
||||
{
|
||||
UINT ret;
|
||||
char *b64 = ZeroMalloc(size * 4 + 32);
|
||||
B64_Encode(b64, data, size);
|
||||
char *base64 = Base64FromBin(NULL, data, size);
|
||||
|
||||
ret = JsonArrayAddStr(array, b64);
|
||||
ret = JsonArrayAddStr(array, base64);
|
||||
|
||||
Free(b64);
|
||||
Free(base64);
|
||||
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 ret;
|
||||
char *b64 = ZeroMalloc(size * 4 + 32);
|
||||
B64_Encode(b64, data, size);
|
||||
char *base64 = Base64FromBin(NULL, data, size);
|
||||
|
||||
ret = JsonSetStr(object, name, b64);
|
||||
ret = JsonSetStr(object, name, base64);
|
||||
|
||||
Free(b64);
|
||||
Free(base64);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user