Add methods for sign/keys module

This commit is contained in:
Oleg Korshul
2022-12-12 14:52:33 +03:00
parent d79a6977dc
commit f69aab7562

View File

@ -14,6 +14,7 @@
extern "C" {
#endif
// Memory
WASM_EXPORT void* Crypto_Malloc(unsigned int size)
{
return ::malloc(size);
@ -111,6 +112,7 @@ public:
}
};
// X509/RSA
WASM_EXPORT void* Crypto_CreateCertificate()
{
return new CCertificate();
@ -144,17 +146,122 @@ WASM_EXPORT char* Crypto_CreateKeys(const char* alg, const char* password, const
std::string privateKeyEnc;
NSOpenSSL::AES_Encrypt_desktop_GCM(password, privateKey, privateKeyEnc, salt);
char* pDataPublicBase64 = NULL;
int nDataPublicBase64Len = 0;
NSFile::CBase64Converter::Encode((BYTE*)publicKey.c_str(), (int)publicKey.length(), pDataPublicBase64, nDataPublicBase64Len, NSBase64::B64_BASE64_FLAG_NOCRLF);
publicKey = std::string(pDataPublicBase64, (size_t)nDataPublicBase64Len);
RELEASEARRAYOBJECTS(pDataPublicBase64);
size_t public_len = publicKey.length();
size_t private_len = privateKeyEnc.length();
char* result = (char*)Crypto_Malloc(public_len + private_len + 2);
char* result = (char*)Crypto_Malloc((unsigned int)(public_len + private_len + 2));
memcpy(result, publicKey.c_str(), public_len);
result[public_len] = '\0';
memcpy(result + public_len, privateKeyEnc.c_str(), private_len);
memcpy(result + public_len + 1, privateKeyEnc.c_str(), private_len);
result[public_len + private_len + 1] = '\0';
return result;
}
int CheckEncryptedVersion(const std::string& input, int& offset)
{
offset = 0;
// VER%NUMBER%; version from 100 to 999
if (input.length() > 7)
{
const char* input_ptr = input.c_str();
if (input_ptr[0] == 'V' && input_ptr[1] == 'E' && input_ptr[2] == 'R')
{
input_ptr += 3;
int nVersion = 0;
for (int i = 0; i < 4; ++i)
{
if (*input_ptr == ';')
{
offset = 3 + i + 1;
return nVersion;
}
nVersion *= 10;
nVersion += (*input_ptr - '0');
++input_ptr;
}
return nVersion;
}
}
return 1;
}
WASM_EXPORT char* Crypto_Sign(const char* privateKeyEncPtr, const char* password, const char* salt, const char* data, int dataLen)
{
std::string sPrivateKeyEnc(privateKeyEncPtr);
if (0 == dataLen)
dataLen = (int)strlen(data);
int nHeaderLen = 0;
int nVersion = CheckEncryptedVersion(sPrivateKeyEnc, nHeaderLen);
std::string sSalt = std::string(salt);
std::string sPassword(password);
std::string sPrivateKey;
bool bIsSuccess = false;
if (nVersion == 2)
bIsSuccess = NSOpenSSL::AES_Decrypt_desktop_GCM(sPassword, sPrivateKeyEnc, sPrivateKey, sSalt, nHeaderLen);
else
bIsSuccess = NSOpenSSL::AES_Decrypt_desktop(sPassword, sPrivateKeyEnc, sPrivateKey, sSalt);
if (!bIsSuccess)
return NULL;
NSOpenSSL::CMemoryData dataSign = NSOpenSSL::Sign((const unsigned char*)data, dataLen, sPrivateKey);
int nDataSignBase64Len = NSBase64::Base64EncodeGetRequiredLength((int)dataSign.Size, NSBase64::B64_BASE64_FLAG_NOCRLF);
char* pDataSignBase64 = (char*)Crypto_Malloc(nDataSignBase64Len + 1);
memset(pDataSignBase64, 0, nDataSignBase64Len + 1);
if (FALSE == NSBase64::Base64Encode(dataSign.Data, (int)dataSign.Size, (BYTE*)pDataSignBase64, &nDataSignBase64Len, NSBase64::B64_BASE64_FLAG_NOCRLF))
{
Crypto_Free((void*)pDataSignBase64);
return NULL;
}
return pDataSignBase64;
}
WASM_EXPORT char* Crypto_ChangePassword(const char* privateKeyEnc, const char* passwordOld, const char* passwordNew, const char* salt)
{
std::string sPrivateKeyEnc(privateKeyEnc);
int nHeaderLen = 0;
int nVersion = CheckEncryptedVersion(sPrivateKeyEnc, nHeaderLen);
std::string sSalt = std::string(salt);
std::string sPasswordOld(passwordOld);
std::string sPasswordNew(passwordNew);
std::string sPrivateKey;
bool bIsSuccess = false;
if (nVersion == 2)
bIsSuccess = NSOpenSSL::AES_Decrypt_desktop_GCM(sPasswordOld, sPrivateKeyEnc, sPrivateKey, sSalt, nHeaderLen);
else
bIsSuccess = NSOpenSSL::AES_Decrypt_desktop(sPasswordOld, sPrivateKeyEnc, sPrivateKey, sSalt);
if (!bIsSuccess)
return NULL;
sPrivateKeyEnc = "";
NSOpenSSL::AES_Encrypt_desktop_GCM(sPasswordNew, sPrivateKey, sPrivateKeyEnc, sSalt);
size_t nEncLen = sPrivateKeyEnc.length();
char* result = (char*)Crypto_Malloc((unsigned int)(nEncLen + 1));
memcpy(result, sPrivateKeyEnc.c_str(), nEncLen);
result[nEncLen] = '\0';
return result;
}
#ifdef __cplusplus
}
#endif
@ -163,6 +270,51 @@ WASM_EXPORT char* Crypto_CreateKeys(const char* alg, const char* password, const
#include <iostream>
int main()
{
// oform module --------------------------------
if (true)
{
std::string sSalt = "123546789";
std::string sPassword = "qwerty";
std::string sPasswordNew = "qwerty2";
char* pGeneratedKeys = Crypto_CreateKeys("ed25519", sPassword.c_str(), sSalt.c_str());
if (NULL == pGeneratedKeys)
return 1;
size_t nLen = 0;
while (pGeneratedKeys[nLen] != 0)
nLen++;
std::string sPublicKey = std::string(pGeneratedKeys, nLen);
size_t nLen2 = nLen + 1;
while (pGeneratedKeys[nLen2] != 0)
nLen2++;
std::string sPrivateKeyEnc = std::string(pGeneratedKeys + nLen + 1, nLen2 - nLen - 1);
Crypto_Free(pGeneratedKeys);
std::string sSignData = "hello world!";
char* pSignData = Crypto_Sign(sPrivateKeyEnc.c_str(), sPassword.c_str(), sSalt.c_str(), sSignData.c_str(), (int)sSignData.length());
std::string sSignature(pSignData);
Crypto_Free(pSignData);
char* pNewPrivateKey = Crypto_ChangePassword(sPrivateKeyEnc.c_str(), sPassword.c_str(), sPasswordNew.c_str(), sSalt.c_str());
std::string sPrivateKeyEncNew(pNewPrivateKey);
Crypto_Free(pNewPrivateKey);
return 0;
}
// ---------------------------------------------
std::string publicKey;
std::string privateKey;