diff --git a/DesktopEditor/xmlsec/src/wasm/openssl/main.cpp b/DesktopEditor/xmlsec/src/wasm/openssl/main.cpp index 5ba7689d25..496b15a99e 100644 --- a/DesktopEditor/xmlsec/src/wasm/openssl/main.cpp +++ b/DesktopEditor/xmlsec/src/wasm/openssl/main.cpp @@ -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 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;