Skip to content

Commit

Permalink
Merge pull request #24 from Web3Auth/feat/sapphire-and-open-logn-updates
Browse files Browse the repository at this point in the history
Feat/sapphire and open login updates
  • Loading branch information
metalurgical authored Dec 7, 2023
2 parents e005a34 + 310bef0 commit 7d22970
Show file tree
Hide file tree
Showing 14 changed files with 545 additions and 184 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,9 @@ DerivedDataCache/*
# MAC
**/*.DS_Store
package/*

# IntelliJ Specific Files
.idea/*

# VSCode Specific Files.
.vscode/*
19 changes: 0 additions & 19 deletions .vscode/c_cpp_properties.json

This file was deleted.

24 changes: 0 additions & 24 deletions .vscode/settings.json

This file was deleted.

10 changes: 8 additions & 2 deletions Config/DefaultEngine.ini
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,13 @@ AdditionalPlistData=<key>CFBundleURLTypes</key><array> <dict> <key>CFB
bCookOnTheFlyForLaunchOn=False

[/Web3AuthSDK/AuthInterface.AuthInterface_C]
Web3AuthOptionsClientId="BJRZ6qdDTbj6Vd5YXvV994TYCqY42-PxldCetmvGTUdoq6pkCqdpuC1DIehz76zuYdaq1RJkXGHuDraHRhCQHvA"
Web3AuthOptionsClientId="BPi5PB_UiIZ-cPz1GtV5i1I2iOSOHuimiXBI0e-Oe_u6X3oVAbCiAZOTEBtTXw4tsluTITPqA8zMsfxIKMjiqNQ"
Web3AuthOptionsRedirectUrl="torusapp://com.torus.web3authunity/auth"
Web3AuthOptionsSdkUrl="https://sdk.openlogin.com/"
Web3AuthOptionsNetwork=MAINNET
Web3AuthOptionsNetwork=SAPPHIRE_MAINNET
WhiteLabelAppName="Web3AuthUnrealDemo"
WhiteLabelDefaultLanguage=en
WhiteLabelTheme=dark
Web3AuthOptionsBuildEnv=PRODUCTION
LoginParamsMfaLevel=NONE

Binary file modified Plugins/Web3AuthSDK/Content/AuthInterface.uasset
Binary file not shown.
217 changes: 178 additions & 39 deletions Plugins/Web3AuthSDK/Source/Web3AuthSDK/Private/ECCrypto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,15 @@ char* FStringToCharArray(const FString& InString) {
UECCrypto::UECCrypto() {
}

FString UECCrypto::decrypt(FString data, FString privateKeyHex, FString ephemPublicKeyHex, FString encryptionIvHex)
FString UECCrypto::decrypt(FString data, FString privateKeyHex, FString ephemPublicKeyHex, FString encryptionIvHex, FString macKeyHex)
{
// Convert to bytes array
const char* priv_hex = FStringToCharArray(privateKeyHex);
const char* pub_hex = FStringToCharArray(ephemPublicKeyHex);

// Decode IV key
// Decode IV key to bytes
const unsigned char* iv = toByteArray(FStringToCharArray(encryptionIvHex));

// Decode cipher text
// Decode cipher text to bytes from hex
const unsigned char* src = toByteArray(FStringToCharArray(data));
int srclen = data.Len() / 2;

Expand Down Expand Up @@ -64,24 +63,41 @@ FString UECCrypto::decrypt(FString data, FString privateKeyHex, FString ephemPub
unsigned char key[32];
memcpy(key, hash, 32);

// Calculate mac_key
unsigned char mac_key[SHA512_DIGEST_LENGTH - 32];
memcpy(mac_key, hash + 32, SHA512_DIGEST_LENGTH - 32);
FString macHex;
for (int i = 0; i < sizeof(mac_key); ++i) {
macHex += FString::Printf(TEXT("%02x"), mac_key[i]);
}

// Verify mac
if (!hmacSha256Verify(macHex, getCombinedData(data, ephemPublicKeyHex, encryptionIvHex), macKeyHex))
{
return FString(TEXT("Bad MAC error during decrypt"));
}

// Create a new encryption context for AES-256 CBC mode with the key and IV
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv);
EVP_CIPHER_CTX_set_padding(ctx, 0);

// Allocate a string buffer for the decrypted data
std::string dst;
dst.resize(srclen + EVP_CIPHER_block_size(EVP_aes_256_cbc()));
dst.resize(srclen + (encryptionIvHex.Len()/2) + EVP_CIPHER_block_size(EVP_aes_256_cbc()));

// Decrypt the input data
int cipher_len;
int outlen;
EVP_DecryptUpdate(ctx, (unsigned char*)dst.data(), &outlen, src, srclen);

cipher_len = outlen;
// Finalize the decryption and retrieve any remaining data
int finaloutlen;
EVP_DecryptFinal_ex(ctx, (unsigned char*)dst.data() + outlen, &finaloutlen);
EVP_DecryptFinal_ex(ctx, (unsigned char*)dst.data() + outlen, &outlen);
cipher_len += outlen;

// Resize the buffer to the actual decrypted length
dst.resize(outlen + finaloutlen);
dst.resize(cipher_len);
// Put a null terminator at cipher_len
dst[cipher_len] = '\0';

// Free the encryption context
EVP_CIPHER_CTX_free(ctx);
Expand All @@ -96,18 +112,16 @@ FString UECCrypto::decrypt(FString data, FString privateKeyHex, FString ephemPub
return FString(dst.c_str());
}

FString UECCrypto::encrypt(FString data, FString privateKeyHex, FString ephemPublicKeyHex, FString encryptionIvHex)
FString UECCrypto::encrypt(FString data, FString privateKeyHex, FString ephemPublicKeyHex, FString encryptionIvHex, FString& mac_key)
{
// Convert to bytes array
const char* priv_hex = FStringToCharArray(privateKeyHex);
const char* pub_hex = FStringToCharArray(ephemPublicKeyHex);

// Decode IV key
// Convert IV key to bytes
const unsigned char* iv = toByteArray(FStringToCharArray(encryptionIvHex));

// Decode cipher text
const unsigned char* src = (unsigned char*)FStringToCharArray(data);
int srclen = data.Len() / 2;
int srclen = data.Len();

// Convert to BIGNUM
BIGNUM* priv_bn = BN_new();
Expand All @@ -133,41 +147,50 @@ FString UECCrypto::encrypt(FString data, FString privateKeyHex, FString ephemPub
unsigned char key[32];
memcpy(key, hash, 32);

// Calculate mac_key
unsigned char mc[SHA512_DIGEST_LENGTH - 32];
memcpy(mc, hash + 32, SHA512_DIGEST_LENGTH - 32);

for (int i = 0; i < sizeof(mc); ++i) {
mac_key += FString::Printf(TEXT("%02x"), mc[i]);
}


// Create a new encryption context for AES-256 CBC mode with the key and IV
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv);

// Allocate a string buffer for the decrypted data
std::string dst;
dst.resize(srclen + EVP_CIPHER_block_size(EVP_aes_256_cbc()));

// Decrypt the input data
// Allocate a buffer for the ciphertext, calculating at most how much space is needed.
// plaintext_length + iv_length + aes_block_size
unsigned char* dst = new unsigned char[srclen + (encryptionIvHex.Len()/2) + EVP_CIPHER_block_size(EVP_aes_256_cbc())];

// Ecrypt the input data
int cipher_len;
int outlen;
EVP_EncryptUpdate(ctx, (unsigned char*)dst.data(), &outlen, src, srclen);
EVP_EncryptUpdate(ctx, dst, &outlen, src, srclen);
cipher_len = outlen;
// Finalize the encryption
EVP_EncryptFinal_ex(ctx, dst + outlen, &outlen);
cipher_len += outlen;
// Free the encryption context
EVP_CIPHER_CTX_free(ctx);

// Finalize the decryption and retrieve any remaining data
int finaloutlen;
EVP_EncryptFinal_ex(ctx, (unsigned char*)dst.data() + outlen, &finaloutlen);

// Resize the buffer to the actual decrypted length
dst.resize(outlen + finaloutlen);

// Free the encryption context
EVP_CIPHER_CTX_free(ctx);
// Convert ciphertext to hex
FString hex;
for (int i = 0; i < cipher_len; ++i) {
hex += FString::Printf(TEXT("%02x"), dst[i]);
}

// Clean up resources
BN_free(priv_bn);
BN_free(pub_bn);
EC_KEY_free(priv_key);
EC_KEY_free(pub_key);
EVP_cleanup();
delete[] dst;

const char* buf = dst.c_str();

FString hex;
for (int i = 0; i < strlen(buf); ++i) {
hex += FString::Printf(TEXT("%02x"), buf[i]);
}
return hex;
}

Expand Down Expand Up @@ -230,11 +253,11 @@ FString UECCrypto::generateECDSASignature(const FString& privateKeyHex, const FS
BN_CTX_free(ctx);

int n = i2d_ECDSA_SIG(signature, &sig_buf);
//// Convert signature to hex string
FString signature_hex;
for (int i = 0; i < n; ++i) {
signature_hex += FString::Printf(TEXT("%02x"), sig_buf[i]);

//// Convert signature to hex string
FString signature_hex;
for (int i = 0; i < n; ++i) {
signature_hex += FString::Printf(TEXT("%02x"), sig_buf[i]);
}

EC_KEY_free(key);
Expand All @@ -244,6 +267,122 @@ FString UECCrypto::generateECDSASignature(const FString& privateKeyHex, const FS
return signature_hex;
}

// Generate session key (private key) for ECDH locally
FString UECCrypto::generateRandomSessionKey() {
EC_KEY* ecKeyPair = generateECKeyPair();

if (!ecKeyPair) {
return FString(); // handle error
}

const BIGNUM* privateKeyBN = EC_KEY_get0_private_key(ecKeyPair);

FString privateKeyStr = convertBigNumToHex(privateKeyBN);

EC_KEY_free(ecKeyPair);

return privateKeyStr;
}

// Generate a new EC key pair
EC_KEY* UECCrypto::generateECKeyPair() {
EC_KEY* ecKey = EC_KEY_new_by_curve_name(NID_secp256k1);

if (!ecKey) {
UE_LOG(LogTemp, Error, TEXT("Error creating EC_KEY structure."));
return nullptr;
}

if (EC_KEY_generate_key(ecKey) != 1) {
UE_LOG(LogTemp, Error, TEXT("Error generating EC key pair."));
EC_KEY_free(ecKey);
return nullptr;
}

return ecKey;
}

// Convert a BIGNUM to a hexadecimal FString
FString UECCrypto::convertBigNumToHex(const BIGNUM* bn) {
char* hex = BN_bn2hex(bn);
FString result(hex);
OPENSSL_free(hex);
return result;
}

FString UECCrypto::generateRandomBytes(int length) {
// Generate random bytes
const int32 numBytes = length;
unsigned char* buffer = new unsigned char[numBytes];
RAND_bytes(buffer, numBytes);

// Convert to hexadecimal FString
FString HexString;
for (int32 i = 0; i < numBytes; ++i) {
HexString += FString::Printf(TEXT("%02x"), buffer[i]);
}

delete[] buffer;
return HexString;
}

// getCombinedData combines the IV, ephemeral public key, and cipher text into a single byte array
FString UECCrypto::getCombinedData(FString cipherTextHex, FString ephemPublicKeyHex, FString encryptionIvHex)
{
return encryptionIvHex + ephemPublicKeyHex + cipherTextHex;
}

FString UECCrypto::getMac(FString cipherTextHex, FString ephemPublicKeyHex, FString encryptionIvHex, FString macKeyHex)
{
FString combinedData = getCombinedData(cipherTextHex, ephemPublicKeyHex, encryptionIvHex);
return hmacSha256Sign(macKeyHex, combinedData);
}

FString UECCrypto::hmacSha256Sign(FString key, FString data)
{
unsigned char* result = nullptr;
unsigned int resultLen = SHA256_DIGEST_LENGTH; // 256-bit hash

unsigned char* keyBytes = toByteArray(FStringToCharArray(key));
int keyLen = key.Len() / 2;
unsigned char* dataBytes = toByteArray(FStringToCharArray(data));
int dataLen = data.Len() / 2;
result = new unsigned char[resultLen];

HMAC_CTX* hmacCtx = HMAC_CTX_new();
if (!hmacCtx)
{
UE_LOG(LogTemp, Error, TEXT("Error creating HMAC context."));
return FString();
}

HMAC_Init_ex(hmacCtx, keyBytes, keyLen, EVP_sha256(), nullptr);
HMAC_Update(hmacCtx, dataBytes, dataLen);
HMAC_Final(hmacCtx, result, &resultLen);
HMAC_CTX_free(hmacCtx);

// Convert to hexadecimal FString
FString HexString;
for (int32 i = 0; i < (int)resultLen; ++i) {
HexString += FString::Printf(TEXT("%02x"), result[i]);
}

return HexString;
}

// hmacSha256Verify verifies that the calculated MAC matches the expected MAC
bool UECCrypto::hmacSha256Verify(FString key, FString data, FString expectedMac)
{
if (key.Len() == 0 || data.Len() == 0 || expectedMac.Len() == 0)
{
return false;
}

FString calculatedMac = hmacSha256Sign(key, data);
return calculatedMac.Compare(expectedMac) == 0;

}

UECCrypto::~UECCrypto()
{
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
*/

#include "Keccak256.h"
#include <cassert>

using std::uint8_t;
using std::uint64_t;
Expand Down
Loading

0 comments on commit 7d22970

Please sign in to comment.