171 lines
4.3 KiB
C++
171 lines
4.3 KiB
C++
/***
|
|
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
|
|
File: RSAPublic.cpp
|
|
Date: 2021-6-12
|
|
Author: Reece
|
|
***/
|
|
#include <Source/RuntimeInternal.hpp>
|
|
#include "../Crypto.hpp"
|
|
#include "RSA.hpp"
|
|
#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_);
|
|
}
|
|
}
|
|
|
|
bool PublicRSA::Verify(const Memory::MemoryViewRead &payload,
|
|
const Memory::MemoryViewRead &signature,
|
|
EHashType method,
|
|
EPaddingType type)
|
|
{
|
|
|
|
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;
|
|
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,
|
|
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,
|
|
reinterpret_cast<const unsigned char *>(hashVec.data()), hashSize,
|
|
padding, hash, 0, &ok, &key_);
|
|
if (ret != CRYPT_OK)
|
|
{
|
|
SysPushErrorCrypt("{}", ret);
|
|
return false;
|
|
}
|
|
|
|
return ok == 1;
|
|
}
|
|
|
|
bool PublicRSA::Encrypt(const Memory::MemoryViewRead &plainText,
|
|
EPaddingType type,
|
|
AuList<AuUInt8> &out)
|
|
{
|
|
prng_state yarrow_prng;
|
|
|
|
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,
|
|
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);
|
|
}
|
|
} |