AuroraRuntime/Source/Crypto/RSA/RSAPublic.cpp

171 lines
4.3 KiB
C++
Raw Normal View History

2021-06-27 21:25:29 +00:00
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: RSAPublic.cpp
Date: 2021-6-12
Author: Reece
***/
#include <RuntimeInternal.hpp>
#include "../Crypto.hpp"
#include "RSA.hpp"
2021-06-27 21:25:29 +00:00
#include "RSAPublic.hpp"
namespace Aurora::Crypto::RSA
{
PublicRSA::PublicRSA(rsa_key &key, bool owned) : key_(key), owned_(owned)
{
}
PublicRSA::~PublicRSA()
{
if (owned_)
{
rsa_free(&key_);
}
}
2021-09-18 20:10:25 +00:00
bool PublicRSA::Verify(const Memory::MemoryViewRead &payload,
const Memory::MemoryViewRead &signature,
EHashType method,
EPaddingType type)
{
2021-09-18 20:10:25 +00:00
if (!payload.HasMemory())
{
SysPushErrorParam();
return {};
}
if (!signature.HasMemory())
{
SysPushErrorParam();
return {};
}
int padding = PaddingToType(type);
if (padding == 0xFF)
{
SysPushErrorCrypt("invalid pad {}", type);
return false;
}
int hash = HashMethodToId(method);
if (hash == 0xFF)
{
SysPushErrorCrypt("invalid hash {}", method);
return false;
}
AuList<AuUInt8> hashVec;
2021-09-06 10:58:08 +00:00
if (!AuTryResize(hashVec, 128))
{
SysPushErrorMem();
return false;
}
unsigned long hashSize = hashVec.size();
auto ret = hash_memory(hash,
reinterpret_cast<const unsigned char *>(payload.ptr), payload.length,
2021-07-12 12:17:16 +00:00
reinterpret_cast<unsigned char *>(hashVec.data()), &hashSize);
if (ret != CRYPT_OK)
{
SysPushErrorCrypt("{}", ret);
return false;
}
int ok = 0;
ret = rsa_verify_hash_ex(reinterpret_cast<const unsigned char *>(signature.ptr), signature.length,
2021-07-12 12:17:16 +00:00
reinterpret_cast<const unsigned char *>(hashVec.data()), hashSize,
padding, hash, 0, &ok, &key_);
if (ret != CRYPT_OK)
{
SysPushErrorCrypt("{}", ret);
return false;
}
return ok == 1;
}
2021-09-18 20:10:25 +00:00
bool PublicRSA::Encrypt(const Memory::MemoryViewRead &plainText,
EPaddingType type,
AuList<AuUInt8> &out)
{
prng_state yarrow_prng;
2021-09-18 20:10:25 +00:00
if (!plainText.HasMemory())
{
SysPushErrorParam();
return {};
}
int padding = PaddingToType(type);
if (padding == 0xFF)
{
SysPushErrorCrypt("invalid pad {}", type);
return false;
}
const int prng_idx = padding == LTC_PKCS_1_PSS ? ::Crypto::gPrngYarrow : 0;
if (prng_idx < 0)
{
SysPushErrorCrypt("{}", prng_idx);
return false;
}
if (!AuTryResize(out, plainText.length + 1024))
{
SysPushErrorMem();
return false;
}
unsigned long len = out.size();
auto ret = rsa_encrypt_key_ex(reinterpret_cast<const unsigned char *>(plainText.ptr),
plainText.length,
2021-07-12 12:17:16 +00:00
out.data(), &len,
NULL, 0,
&yarrow_prng, prng_idx,
0,
padding,
&key_);
if (ret != CRYPT_OK)
{
SysPushErrorCrypt("{}", ret);
return false;
}
out.resize(len);
return true;
}
bool PublicRSA::ToKey(ERSAKeyType type, AuList<AuUInt8> &out)
{
return ExportRSAKey(key_, EKeyType::eKeyPublic, type, out);
}
AUKN_SYM IRSAPublic *OpenRSAPublicNew(const RSAKey &key)
{
rsa_key in {};
if (!ImportRSAKey(in, key))
{
return nullptr;
}
auto ret = _new PublicRSA(in, true);
if (!ret)
{
rsa_free(&in);
return nullptr;
}
return ret;
}
AUKN_SYM void OpenRSAPublicRelease(IRSAPublic *re)
{
SafeDelete<PublicRSA *>(re);
}
}