/*** Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: RSAPublic.cpp Date: 2021-6-12 Author: Reece ***/ #include #include "../Crypto.hpp" #include "RSA.hpp" #include "RSAPublic.hpp" namespace Aurora::Crypto::RSA { PublicRSA::PublicRSA(rsa_key &key) : key_(key) { } PublicRSA::~PublicRSA() { } bool PublicRSA::Verify(const void *buffer, AuUInt length, const void *sigBuffer, AuUInt sigLength, EHashType method, EPaddingType type) { 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 hashVec; if (!TryResize(hashVec, 128)) { SysPushErrorMem(); return false; } unsigned long hashSize = hashVec.size(); auto ret = hash_memory(hash, reinterpret_cast(buffer), length, reinterpret_cast(hashVec.data()), &hashSize); if (ret != CRYPT_OK) { SysPushErrorCrypt("{}", ret); return false; } int ok = 0; ret = rsa_verify_hash_ex(reinterpret_cast(sigBuffer), sigLength, reinterpret_cast(hashVec.data()), hashSize, padding, hash, 0, &ok, &key_); if (ret != CRYPT_OK) { SysPushErrorCrypt("{}", ret); return false; } return ok == 1; } bool PublicRSA::Verify(const AuList &buffer, const AuList &sig, EHashType method, EPaddingType type) { return Verify(buffer.data(), buffer.size(), sig.data(), sig.size(), method, type); } bool PublicRSA::Encrypt(const void *buffer, AuUInt length, EPaddingType type, AuList &out) { prng_state yarrow_prng; 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 (!TryResize(out, length + 1024)) { SysPushErrorMem(); return false; } unsigned long len = out.size(); auto ret = rsa_encrypt_key_ex(reinterpret_cast(buffer), 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::Encrypt(const AuList &in, EPaddingType type, AuList &out) { return Encrypt(in.data(), in.size(), type, out); } bool PublicRSA::ToKey(ERSAKeyType type, AuList &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); if (!ret) { rsa_free(&in); return nullptr; } return ret; } AUKN_SYM void OpenRSAPublicRelease(IRSAPublic *re) { SafeDelete(re); } }