Remove Patcher namespace
This commit is contained in:
parent
1dd88e11ff
commit
33a4e9a179
@ -3,152 +3,149 @@
|
||||
#include <openssl/err.h>
|
||||
#include <capstone/capstone.h>
|
||||
|
||||
namespace Patcher {
|
||||
class Exception {
|
||||
private:
|
||||
const char* const _FileName;
|
||||
const int _NumberOfLine;
|
||||
const char* _CustomMessage;
|
||||
public:
|
||||
|
||||
class Exception {
|
||||
private:
|
||||
const char* const _FileName;
|
||||
const int _NumberOfLine;
|
||||
const char* _CustomMessage;
|
||||
public:
|
||||
Exception(const char* FileName, int Line, const char* Message) noexcept :
|
||||
_FileName(FileName),
|
||||
_NumberOfLine(Line),
|
||||
_CustomMessage(Message) {}
|
||||
|
||||
Exception(const char* FileName, int Line, const char* Message) noexcept :
|
||||
_FileName(FileName),
|
||||
_NumberOfLine(Line),
|
||||
_CustomMessage(Message) {}
|
||||
const char* SourceFile() const noexcept {
|
||||
return _FileName;
|
||||
}
|
||||
|
||||
const char* SourceFile() const noexcept {
|
||||
return _FileName;
|
||||
}
|
||||
int SourceLine() const noexcept {
|
||||
return _NumberOfLine;
|
||||
}
|
||||
|
||||
int SourceLine() const noexcept {
|
||||
return _NumberOfLine;
|
||||
}
|
||||
const char* CustomMessage() const noexcept {
|
||||
return _CustomMessage;
|
||||
}
|
||||
|
||||
const char* CustomMessage() const noexcept {
|
||||
return _CustomMessage;
|
||||
}
|
||||
virtual bool HasErrorCode() const noexcept {
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool HasErrorCode() const noexcept {
|
||||
return false;
|
||||
}
|
||||
virtual unsigned long ErrorCode() const noexcept {
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual unsigned long ErrorCode() const noexcept {
|
||||
return 0;
|
||||
}
|
||||
virtual const char* ErrorString() const noexcept {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual const char* ErrorString() const noexcept {
|
||||
};
|
||||
|
||||
class SystemError : public Exception {
|
||||
private:
|
||||
const std::error_code _ErrorCode;
|
||||
public:
|
||||
SystemError(const char* FileName,
|
||||
int Line,
|
||||
unsigned long Code,
|
||||
const char* Message) noexcept :
|
||||
Exception(FileName, Line, Message),
|
||||
_ErrorCode(Code, std::system_category()) {}
|
||||
|
||||
virtual bool HasErrorCode() const noexcept override {
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual unsigned long ErrorCode() const noexcept override {
|
||||
return _ErrorCode.value();
|
||||
}
|
||||
|
||||
virtual const char* ErrorString() const noexcept override {
|
||||
return _ErrorCode.message().c_str();
|
||||
}
|
||||
};
|
||||
|
||||
class OpensslError : public Exception {
|
||||
private:
|
||||
const unsigned long _ErrorCode;
|
||||
public:
|
||||
|
||||
OpensslError(const char* FileName,
|
||||
int Line,
|
||||
unsigned long Code,
|
||||
const char* Message) noexcept :
|
||||
Exception(FileName, Line, Message),
|
||||
_ErrorCode(Code) {}
|
||||
|
||||
virtual bool HasErrorCode() const noexcept override {
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual unsigned long ErrorCode() const noexcept override {
|
||||
return _ErrorCode;
|
||||
}
|
||||
|
||||
virtual const char* ErrorString() const noexcept override {
|
||||
return ERR_error_string(_ErrorCode, nullptr);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class CapstoneError : public Exception {
|
||||
private:
|
||||
const cs_err _ErrorCode;
|
||||
public:
|
||||
CapstoneError(const char* FileName,
|
||||
int Line,
|
||||
cs_err Code,
|
||||
const char* Message) noexcept :
|
||||
Exception(FileName, Line, Message),
|
||||
_ErrorCode(Code) {}
|
||||
|
||||
virtual bool HasErrorCode() const noexcept override {
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual unsigned long ErrorCode() const noexcept override {
|
||||
return _ErrorCode;
|
||||
}
|
||||
|
||||
virtual const char* ErrorString() const noexcept override {
|
||||
switch (_ErrorCode) {
|
||||
case CS_ERR_MEM:
|
||||
return "Out-Of-Memory error.";
|
||||
case CS_ERR_ARCH:
|
||||
return "Unsupported architecture.";
|
||||
case CS_ERR_HANDLE:
|
||||
return "Invalid handle.";
|
||||
case CS_ERR_CSH:
|
||||
return "Invalid csh argument.";
|
||||
case CS_ERR_MODE:
|
||||
return "Invalid/unsupported mode.";
|
||||
case CS_ERR_OPTION:
|
||||
return "Invalid/unsupported option.";
|
||||
case CS_ERR_DETAIL:
|
||||
return "Information is unavailable because detail option is OFF";
|
||||
case CS_ERR_MEMSETUP:
|
||||
return "Dynamic memory management uninitialized.";
|
||||
case CS_ERR_VERSION:
|
||||
return "Unsupported version (bindings).";
|
||||
case CS_ERR_DIET:
|
||||
return "Access irrelevant data in \"diet\" engine.";
|
||||
case CS_ERR_SKIPDATA:
|
||||
return "Access irrelevant data for \"data\" instruction in SKIPDATA mode.";
|
||||
case CS_ERR_X86_ATT:
|
||||
return "X86 AT&T syntax is unsupported (opt-out at compile time).";
|
||||
case CS_ERR_X86_INTEL:
|
||||
return "X86 Intel syntax is unsupported (opt-out at compile time).";
|
||||
case CS_ERR_X86_MASM:
|
||||
return "X86 Intel syntax is unsupported (opt-out at compile time).";
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class SystemError : public Exception {
|
||||
private:
|
||||
const std::error_code _ErrorCode;
|
||||
public:
|
||||
SystemError(const char* FileName,
|
||||
int Line,
|
||||
unsigned long Code,
|
||||
const char* Message) noexcept :
|
||||
Exception(FileName, Line, Message),
|
||||
_ErrorCode(Code, std::system_category()) {}
|
||||
|
||||
virtual bool HasErrorCode() const noexcept override {
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual unsigned long ErrorCode() const noexcept override {
|
||||
return _ErrorCode.value();
|
||||
}
|
||||
|
||||
virtual const char* ErrorString() const noexcept override {
|
||||
return _ErrorCode.message().c_str();
|
||||
}
|
||||
};
|
||||
|
||||
class OpensslError : public Exception {
|
||||
private:
|
||||
const unsigned long _ErrorCode;
|
||||
public:
|
||||
|
||||
OpensslError(const char* FileName,
|
||||
int Line,
|
||||
unsigned long Code,
|
||||
const char* Message) noexcept :
|
||||
Exception(FileName, Line, Message),
|
||||
_ErrorCode(Code) {}
|
||||
|
||||
virtual bool HasErrorCode() const noexcept override {
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual unsigned long ErrorCode() const noexcept override {
|
||||
return _ErrorCode;
|
||||
}
|
||||
|
||||
virtual const char* ErrorString() const noexcept override {
|
||||
return ERR_error_string(_ErrorCode, nullptr);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class CapstoneError : public Exception {
|
||||
private:
|
||||
const cs_err _ErrorCode;
|
||||
public:
|
||||
CapstoneError(const char* FileName,
|
||||
int Line,
|
||||
cs_err Code,
|
||||
const char* Message) noexcept :
|
||||
Exception(FileName, Line, Message),
|
||||
_ErrorCode(Code) {}
|
||||
|
||||
virtual bool HasErrorCode() const noexcept override {
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual unsigned long ErrorCode() const noexcept override {
|
||||
return _ErrorCode;
|
||||
}
|
||||
|
||||
virtual const char* ErrorString() const noexcept override {
|
||||
switch (_ErrorCode) {
|
||||
case CS_ERR_MEM:
|
||||
return "Out-Of-Memory error.";
|
||||
case CS_ERR_ARCH:
|
||||
return "Unsupported architecture.";
|
||||
case CS_ERR_HANDLE:
|
||||
return "Invalid handle.";
|
||||
case CS_ERR_CSH:
|
||||
return "Invalid csh argument.";
|
||||
case CS_ERR_MODE:
|
||||
return "Invalid/unsupported mode.";
|
||||
case CS_ERR_OPTION:
|
||||
return "Invalid/unsupported option.";
|
||||
case CS_ERR_DETAIL:
|
||||
return "Information is unavailable because detail option is OFF";
|
||||
case CS_ERR_MEMSETUP:
|
||||
return "Dynamic memory management uninitialized.";
|
||||
case CS_ERR_VERSION:
|
||||
return "Unsupported version (bindings).";
|
||||
case CS_ERR_DIET:
|
||||
return "Access irrelevant data in \"diet\" engine.";
|
||||
case CS_ERR_SKIPDATA:
|
||||
return "Access irrelevant data for \"data\" instruction in SKIPDATA mode.";
|
||||
case CS_ERR_X86_ATT:
|
||||
return "X86 AT&T syntax is unsupported (opt-out at compile time).";
|
||||
case CS_ERR_X86_INTEL:
|
||||
return "X86 Intel syntax is unsupported (opt-out at compile time).";
|
||||
case CS_ERR_X86_MASM:
|
||||
return "X86 Intel syntax is unsupported (opt-out at compile time).";
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -9,88 +9,86 @@ using String = std::wstring;
|
||||
using String = std::string;
|
||||
#endif
|
||||
|
||||
namespace Patcher {
|
||||
|
||||
class FileMapper {
|
||||
private:
|
||||
ResourceGuard<FileHandleTraits> _FileHandle;
|
||||
ResourceGuard<GenericHandleTraits> _FileMapHandle;
|
||||
ResourceGuard<MapViewTraits> _FileView;
|
||||
public:
|
||||
class FileMapper {
|
||||
private:
|
||||
ResourceGuard<FileHandleTraits> _FileHandle;
|
||||
ResourceGuard<GenericHandleTraits> _FileMapHandle;
|
||||
ResourceGuard<MapViewTraits> _FileView;
|
||||
public:
|
||||
|
||||
static bool IsExist(const String&& FilePath) {
|
||||
DWORD dwAttr = GetFileAttributes(FilePath.c_str());
|
||||
if (dwAttr == INVALID_FILE_ATTRIBUTES) {
|
||||
if (GetLastError() == ERROR_FILE_NOT_FOUND)
|
||||
return false;
|
||||
else
|
||||
throw SystemError(__BASE_FILE__, __LINE__, GetLastError(),
|
||||
"GetFileAttributes fails.");
|
||||
} else {
|
||||
return (dwAttr & FILE_ATTRIBUTE_DIRECTORY) == 0;
|
||||
}
|
||||
static bool IsExist(const String&& FilePath) {
|
||||
DWORD dwAttr = GetFileAttributes(FilePath.c_str());
|
||||
if (dwAttr == INVALID_FILE_ATTRIBUTES) {
|
||||
if (GetLastError() == ERROR_FILE_NOT_FOUND)
|
||||
return false;
|
||||
else
|
||||
throw SystemError(__BASE_FILE__, __LINE__, GetLastError(),
|
||||
"GetFileAttributes fails.");
|
||||
} else {
|
||||
return (dwAttr & FILE_ATTRIBUTE_DIRECTORY) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename _Type>
|
||||
_Type* GetView() const noexcept {
|
||||
return reinterpret_cast<_Type*>(_FileView.GetHandle());
|
||||
}
|
||||
template<typename _Type>
|
||||
_Type* GetView() const noexcept {
|
||||
return reinterpret_cast<_Type*>(_FileView.GetHandle());
|
||||
}
|
||||
|
||||
void MapFile(const String& FileName) noexcept {
|
||||
ResourceGuard<FileHandleTraits> TempFileHandle;
|
||||
ResourceGuard<GenericHandleTraits> TempFileMapHandle;
|
||||
ResourceGuard<MapViewTraits> TempFileView;
|
||||
void MapFile(const String& FileName) noexcept {
|
||||
ResourceGuard<FileHandleTraits> TempFileHandle;
|
||||
ResourceGuard<GenericHandleTraits> TempFileMapHandle;
|
||||
ResourceGuard<MapViewTraits> TempFileView;
|
||||
|
||||
TempFileHandle.TakeHoldOf(
|
||||
CreateFile(FileName.c_str(),
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL)
|
||||
);
|
||||
if (TempFileHandle.IsValid() == false)
|
||||
throw SystemError(__BASE_FILE__, __LINE__, GetLastError(),
|
||||
"CreateFile fails.");
|
||||
TempFileHandle.TakeHoldOf(
|
||||
CreateFile(FileName.c_str(),
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL)
|
||||
);
|
||||
if (TempFileHandle.IsValid() == false)
|
||||
throw SystemError(__BASE_FILE__, __LINE__, GetLastError(),
|
||||
"CreateFile fails.");
|
||||
|
||||
TempFileMapHandle.TakeHoldOf(
|
||||
CreateFileMapping(TempFileHandle,
|
||||
NULL,
|
||||
PAGE_READWRITE,
|
||||
0,
|
||||
0,
|
||||
NULL)
|
||||
);
|
||||
if (TempFileMapHandle.IsValid() == false)
|
||||
throw SystemError(__BASE_FILE__, __LINE__, GetLastError(),
|
||||
"CreateFileMapping fails.");
|
||||
|
||||
TempFileView.TakeHoldOf(
|
||||
MapViewOfFile(TempFileMapHandle,
|
||||
FILE_MAP_READ | FILE_MAP_WRITE,
|
||||
TempFileMapHandle.TakeHoldOf(
|
||||
CreateFileMapping(TempFileHandle,
|
||||
NULL,
|
||||
PAGE_READWRITE,
|
||||
0,
|
||||
0,
|
||||
0)
|
||||
);
|
||||
if (TempFileView.IsValid() == false)
|
||||
throw SystemError(__BASE_FILE__, __LINE__, GetLastError(),
|
||||
"MapViewOfFile fails.");
|
||||
NULL)
|
||||
);
|
||||
if (TempFileMapHandle.IsValid() == false)
|
||||
throw SystemError(__BASE_FILE__, __LINE__, GetLastError(),
|
||||
"CreateFileMapping fails.");
|
||||
|
||||
_FileView.Release();
|
||||
_FileView = std::move(TempFileView);
|
||||
_FileMapHandle.Release();
|
||||
_FileMapHandle = std::move(TempFileMapHandle);
|
||||
_FileHandle.Release();
|
||||
_FileHandle = std::move(TempFileHandle);
|
||||
}
|
||||
TempFileView.TakeHoldOf(
|
||||
MapViewOfFile(TempFileMapHandle,
|
||||
FILE_MAP_READ | FILE_MAP_WRITE,
|
||||
0,
|
||||
0,
|
||||
0)
|
||||
);
|
||||
if (TempFileView.IsValid() == false)
|
||||
throw SystemError(__BASE_FILE__, __LINE__, GetLastError(),
|
||||
"MapViewOfFile fails.");
|
||||
|
||||
void Release() {
|
||||
_FileView.Release();
|
||||
_FileMapHandle.Release();
|
||||
_FileHandle.Release();
|
||||
}
|
||||
};
|
||||
_FileView.Release();
|
||||
_FileView = std::move(TempFileView);
|
||||
_FileMapHandle.Release();
|
||||
_FileMapHandle = std::move(TempFileMapHandle);
|
||||
_FileHandle.Release();
|
||||
_FileHandle = std::move(TempFileHandle);
|
||||
}
|
||||
|
||||
void Release() {
|
||||
_FileView.Release();
|
||||
_FileMapHandle.Release();
|
||||
_FileHandle.Release();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -13,233 +13,231 @@
|
||||
#pragma comment(lib, "WS2_32.lib") // some symbol are used in OpenSSL static lib
|
||||
#pragma comment(lib, "Crypt32.lib") // some symbol are used in OpenSSL static lib
|
||||
|
||||
namespace Patcher {
|
||||
|
||||
class RSACipher {
|
||||
public:
|
||||
enum class KeyType {
|
||||
PrivateKey,
|
||||
PublicKey
|
||||
};
|
||||
|
||||
enum class KeyFormat {
|
||||
NotSpecified,
|
||||
PEM,
|
||||
PKCS1
|
||||
};
|
||||
private:
|
||||
ResourceGuard<OpensslRSATraits> _RsaObj;
|
||||
|
||||
RSACipher(RSA* pRsa) : _RsaObj(pRsa) {}
|
||||
|
||||
// Copy constructor is not allowed
|
||||
RSACipher(const RSACipher&) = delete;
|
||||
|
||||
// Copy assignment is not allowed
|
||||
RSACipher& operator=(const RSACipher&) = delete;
|
||||
|
||||
template<KeyType _Type, KeyFormat _Format = KeyFormat::NotSpecified>
|
||||
static void _RSAToBIO(RSA* pRsaObject, BIO* pBioObject) {
|
||||
if constexpr (_Type == KeyType::PrivateKey) {
|
||||
if (!PEM_write_bio_RSAPrivateKey(bio_file, pRsaObject, nullptr, nullptr, 0, nullptr, nullptr))
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"PEM_write_bio_RSAPrivateKey fails.");
|
||||
} else {
|
||||
if constexpr (_Format == KeyFormat::PEM) {
|
||||
if (!PEM_write_bio_RSA_PUBKEY(bio_file, pRsaObject))
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"PEM_write_bio_RSA_PUBKEY fails.");
|
||||
} else if constexpr (_Format == KeyFormat::PKCS1) {
|
||||
if (!PEM_write_bio_RSAPublicKey(bio_file, pRsaObject))
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"PEM_write_bio_RSAPublicKey fails.");
|
||||
} else {
|
||||
static_assert(_Format == KeyFormat::PEM || _Format == KeyFormat::PKCS1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<KeyType _Type, KeyFormat _Format = KeyFormat::NotSpecified>
|
||||
static RSA* _BIOToRSA(BIO* pBioObject) {
|
||||
RSA* pNewRsaObject;
|
||||
|
||||
if constexpr (_Type == KeyType::PrivateKey) {
|
||||
pNewRsaObject = PEM_read_bio_RSAPrivateKey(bio_file, nullptr, nullptr, nullptr);
|
||||
if (pNewRsaObject == nullptr)
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"PEM_read_bio_RSAPrivateKey fails.");
|
||||
} else {
|
||||
if constexpr (_Format == KeyFormat::PEM) {
|
||||
pNewRsaObject = PEM_read_bio_RSA_PUBKEY(bio_file, nullptr, nullptr, nullptr);
|
||||
if (pNewRsaObject == nullptr)
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"PEM_read_bio_RSA_PUBKEY fails.");
|
||||
} else if constexpr (_Format == KeyFormat::PKCS1) {
|
||||
pNewRsaObject = PEM_read_bio_RSAPublicKey(bio_file, nullptr, nullptr, nullptr);
|
||||
if (pNewRsaObject == nullptr)
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"PEM_read_bio_RSAPublicKey fails.");
|
||||
} else {
|
||||
static_assert(_Format == KeyFormat::PEM || _Format == KeyFormat::PKCS1);
|
||||
}
|
||||
}
|
||||
|
||||
return pNewRsaObject;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
static RSACipher* Create() {
|
||||
RSACipher* aCipher = new RSACipher(RSA_new());
|
||||
if (aCipher->_RsaObj == nullptr) {
|
||||
delete aCipher;
|
||||
aCipher = nullptr;
|
||||
}
|
||||
return aCipher;
|
||||
}
|
||||
|
||||
RSACipher() : _RsaObj(RSA_new()) {}
|
||||
|
||||
void GenerateKey(int bits, unsigned int e = RSA_F4) {
|
||||
ResourceGuard<OpensslBNTraits> bn_e;
|
||||
|
||||
bn_e.TakeHoldOf(BN_new());
|
||||
if (bn_e.IsValid() == false)
|
||||
throw OpensslError(__BASE_FILE__, __LINE__, ERR_get_error(),
|
||||
"BN_new fails.");
|
||||
|
||||
if (!BN_set_word(bn_e, e))
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"BN_set_word fails.");
|
||||
|
||||
if (!RSA_generate_key_ex(_RsaObj, bits, bn_e, nullptr))
|
||||
throw OpensslError(__BASE_FILE__, __LINE__, ERR_get_error(),
|
||||
"RSA_generate_key_ex fails.");
|
||||
}
|
||||
|
||||
template<KeyType _Type, KeyFormat _Format = KeyFormat::NotSpecified>
|
||||
void ExportKeyToFile(const std::string& FileName) {
|
||||
ResourceGuard<OpensslBIOTraits> bio_file;
|
||||
|
||||
bio_file.TakeHoldOf(BIO_new_file(FileName.c_str(), "w"));
|
||||
if (bio_file.IsValid() == false)
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"BIO_new_file fails.");
|
||||
|
||||
_RSAToBIO<_Type, _Format>(_RsaObj, bio_file);
|
||||
}
|
||||
|
||||
template<KeyType _Type, KeyFormat _Format = KeyFormat::NotSpecified>
|
||||
std::string ExportKeyString() {
|
||||
std::string result;
|
||||
ResourceGuard<OpensslBIOTraits> bio_mem;
|
||||
int DataSize;
|
||||
const char* pData = nullptr;
|
||||
|
||||
bio_mem.TakeHoldOf(BIO_new(BIO_s_mem()));
|
||||
if (bio_mem.IsValid() == false)
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"BIO_new fails.");
|
||||
|
||||
_RSAToBIO<_Type, _Format>(_RsaObj, bio_mem);
|
||||
|
||||
DataSize = BIO_get_mem_data(bio_mem, &pData);
|
||||
result.resize(DataSize);
|
||||
memcpy(result.data(), pData, DataSize);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<KeyType _Type, KeyFormat _Format = KeyFormat::NotSpecified>
|
||||
void ImportKeyFromFile(const std::string& FileName) {
|
||||
bool bSuccess = false;
|
||||
ResourceGuard<OpensslBIOTraits> bio_file;
|
||||
RSA* NewRsaObj;
|
||||
|
||||
bio_file.TakeHoldOf(BIO_new_file(FileName.c_str(), "r"));
|
||||
if (bio_file.IsValid() == false)
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"BIO_new_file fails.");
|
||||
|
||||
NewRsaObj = _BIOToRSA<_Type, _Format>(bio_file);
|
||||
_RsaObj.Release();
|
||||
_RsaObj.TakeHoldOf(NewRsaObj);
|
||||
}
|
||||
|
||||
template<KeyType _Type, KeyFormat _Format = KeyFormat::NotSpecified>
|
||||
void ImportKeyString(const std::string& KeyString) {
|
||||
ResourceGuard<OpensslBIOTraits> bio_mem;
|
||||
RSA* NewRsaObj;
|
||||
|
||||
bio_mem = BIO_new(BIO_s_mem());
|
||||
if (bio_mem == nullptr)
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"BIO_new fails.");
|
||||
|
||||
if (BIO_puts(bio_mem, KeyString.c_str()) <= 0)
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"BIO_puts fails.");
|
||||
|
||||
NewRsaObj = _BIOToRSA<_Type, _Format>(bio_mem);
|
||||
_RsaObj.Release();
|
||||
_RsaObj.TakeHoldOf(NewRsaObj);
|
||||
}
|
||||
|
||||
template<KeyType _Type = KeyType::PublicKey>
|
||||
int Encrypt(const void* from, int len, void* to, int padding) {
|
||||
int write_bytes;
|
||||
|
||||
if constexpr (_Type == KeyType::PrivateKey) {
|
||||
write_bytes = RSA_private_encrypt(len,
|
||||
reinterpret_cast<const unsigned char*>(from),
|
||||
reinterpret_cast<unsigned char*>(to),
|
||||
_RsaObj,
|
||||
padding);
|
||||
if (write_bytes == -1)
|
||||
throw OpensslError(__BASE_FILE__, __LINE__, ERR_get_error(),
|
||||
"RSA_private_encrypt fails.");
|
||||
} else {
|
||||
write_bytes = RSA_public_encrypt(len,
|
||||
reinterpret_cast<const unsigned char*>(from),
|
||||
reinterpret_cast<unsigned char*>(to),
|
||||
_RsaObj,
|
||||
padding);
|
||||
if (write_bytes == -1)
|
||||
throw OpensslError(__BASE_FILE__, __LINE__, ERR_get_error(),
|
||||
"RSA_public_encrypt fails.");
|
||||
}
|
||||
|
||||
return write_bytes;
|
||||
}
|
||||
|
||||
template<KeyType _Type = KeyType::PrivateKey>
|
||||
int Decrypt(const void* from, int len, void* to, int padding) {
|
||||
int write_bytes;
|
||||
|
||||
if constexpr (_Type == KeyType::PrivateKey) {
|
||||
write_bytes = RSA_private_decrypt(len,
|
||||
reinterpret_cast<const unsigned char*>(from),
|
||||
reinterpret_cast<unsigned char*>(to),
|
||||
_RsaObj,
|
||||
padding);
|
||||
if (write_bytes == -1)
|
||||
throw OpensslError(__BASE_FILE__, __LINE__, ERR_get_error(),
|
||||
"RSA_private_decrypt fails.");
|
||||
} else {
|
||||
write_bytes = RSA_public_decrypt(len,
|
||||
reinterpret_cast<const unsigned char*>(from),
|
||||
reinterpret_cast<unsigned char*>(to),
|
||||
_RsaObj,
|
||||
padding);
|
||||
if (write_bytes == -1)
|
||||
throw OpensslError(__BASE_FILE__, __LINE__, ERR_get_error(),
|
||||
"RSA_public_decrypt fails.");
|
||||
}
|
||||
|
||||
return write_bytes;
|
||||
}
|
||||
|
||||
class RSACipher {
|
||||
public:
|
||||
enum class KeyType {
|
||||
PrivateKey,
|
||||
PublicKey
|
||||
};
|
||||
|
||||
}
|
||||
enum class KeyFormat {
|
||||
NotSpecified,
|
||||
PEM,
|
||||
PKCS1
|
||||
};
|
||||
private:
|
||||
ResourceGuard<OpensslRSATraits> _RsaObj;
|
||||
|
||||
RSACipher(RSA* pRsa) : _RsaObj(pRsa) {}
|
||||
|
||||
// Copy constructor is not allowed
|
||||
RSACipher(const RSACipher&) = delete;
|
||||
|
||||
// Copy assignment is not allowed
|
||||
RSACipher& operator=(const RSACipher&) = delete;
|
||||
|
||||
template<KeyType _Type, KeyFormat _Format = KeyFormat::NotSpecified>
|
||||
static void _RSAToBIO(RSA* pRsaObject, BIO* pBioObject) {
|
||||
if constexpr (_Type == KeyType::PrivateKey) {
|
||||
if (!PEM_write_bio_RSAPrivateKey(bio_file, pRsaObject, nullptr, nullptr, 0, nullptr, nullptr))
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"PEM_write_bio_RSAPrivateKey fails.");
|
||||
} else {
|
||||
if constexpr (_Format == KeyFormat::PEM) {
|
||||
if (!PEM_write_bio_RSA_PUBKEY(bio_file, pRsaObject))
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"PEM_write_bio_RSA_PUBKEY fails.");
|
||||
} else if constexpr (_Format == KeyFormat::PKCS1) {
|
||||
if (!PEM_write_bio_RSAPublicKey(bio_file, pRsaObject))
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"PEM_write_bio_RSAPublicKey fails.");
|
||||
} else {
|
||||
static_assert(_Format == KeyFormat::PEM || _Format == KeyFormat::PKCS1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<KeyType _Type, KeyFormat _Format = KeyFormat::NotSpecified>
|
||||
static RSA* _BIOToRSA(BIO* pBioObject) {
|
||||
RSA* pNewRsaObject;
|
||||
|
||||
if constexpr (_Type == KeyType::PrivateKey) {
|
||||
pNewRsaObject = PEM_read_bio_RSAPrivateKey(bio_file, nullptr, nullptr, nullptr);
|
||||
if (pNewRsaObject == nullptr)
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"PEM_read_bio_RSAPrivateKey fails.");
|
||||
} else {
|
||||
if constexpr (_Format == KeyFormat::PEM) {
|
||||
pNewRsaObject = PEM_read_bio_RSA_PUBKEY(bio_file, nullptr, nullptr, nullptr);
|
||||
if (pNewRsaObject == nullptr)
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"PEM_read_bio_RSA_PUBKEY fails.");
|
||||
} else if constexpr (_Format == KeyFormat::PKCS1) {
|
||||
pNewRsaObject = PEM_read_bio_RSAPublicKey(bio_file, nullptr, nullptr, nullptr);
|
||||
if (pNewRsaObject == nullptr)
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"PEM_read_bio_RSAPublicKey fails.");
|
||||
} else {
|
||||
static_assert(_Format == KeyFormat::PEM || _Format == KeyFormat::PKCS1);
|
||||
}
|
||||
}
|
||||
|
||||
return pNewRsaObject;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
static RSACipher* Create() {
|
||||
RSACipher* aCipher = new RSACipher(RSA_new());
|
||||
if (aCipher->_RsaObj == nullptr) {
|
||||
delete aCipher;
|
||||
aCipher = nullptr;
|
||||
}
|
||||
return aCipher;
|
||||
}
|
||||
|
||||
RSACipher() : _RsaObj(RSA_new()) {}
|
||||
|
||||
void GenerateKey(int bits, unsigned int e = RSA_F4) {
|
||||
ResourceGuard<OpensslBNTraits> bn_e;
|
||||
|
||||
bn_e.TakeHoldOf(BN_new());
|
||||
if (bn_e.IsValid() == false)
|
||||
throw OpensslError(__BASE_FILE__, __LINE__, ERR_get_error(),
|
||||
"BN_new fails.");
|
||||
|
||||
if (!BN_set_word(bn_e, e))
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"BN_set_word fails.");
|
||||
|
||||
if (!RSA_generate_key_ex(_RsaObj, bits, bn_e, nullptr))
|
||||
throw OpensslError(__BASE_FILE__, __LINE__, ERR_get_error(),
|
||||
"RSA_generate_key_ex fails.");
|
||||
}
|
||||
|
||||
template<KeyType _Type, KeyFormat _Format = KeyFormat::NotSpecified>
|
||||
void ExportKeyToFile(const std::string& FileName) {
|
||||
ResourceGuard<OpensslBIOTraits> bio_file;
|
||||
|
||||
bio_file.TakeHoldOf(BIO_new_file(FileName.c_str(), "w"));
|
||||
if (bio_file.IsValid() == false)
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"BIO_new_file fails.");
|
||||
|
||||
_RSAToBIO<_Type, _Format>(_RsaObj, bio_file);
|
||||
}
|
||||
|
||||
template<KeyType _Type, KeyFormat _Format = KeyFormat::NotSpecified>
|
||||
std::string ExportKeyString() {
|
||||
std::string result;
|
||||
ResourceGuard<OpensslBIOTraits> bio_mem;
|
||||
int DataSize;
|
||||
const char* pData = nullptr;
|
||||
|
||||
bio_mem.TakeHoldOf(BIO_new(BIO_s_mem()));
|
||||
if (bio_mem.IsValid() == false)
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"BIO_new fails.");
|
||||
|
||||
_RSAToBIO<_Type, _Format>(_RsaObj, bio_mem);
|
||||
|
||||
DataSize = BIO_get_mem_data(bio_mem, &pData);
|
||||
result.resize(DataSize);
|
||||
memcpy(result.data(), pData, DataSize);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<KeyType _Type, KeyFormat _Format = KeyFormat::NotSpecified>
|
||||
void ImportKeyFromFile(const std::string& FileName) {
|
||||
bool bSuccess = false;
|
||||
ResourceGuard<OpensslBIOTraits> bio_file;
|
||||
RSA* NewRsaObj;
|
||||
|
||||
bio_file.TakeHoldOf(BIO_new_file(FileName.c_str(), "r"));
|
||||
if (bio_file.IsValid() == false)
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"BIO_new_file fails.");
|
||||
|
||||
NewRsaObj = _BIOToRSA<_Type, _Format>(bio_file);
|
||||
_RsaObj.Release();
|
||||
_RsaObj.TakeHoldOf(NewRsaObj);
|
||||
}
|
||||
|
||||
template<KeyType _Type, KeyFormat _Format = KeyFormat::NotSpecified>
|
||||
void ImportKeyString(const std::string& KeyString) {
|
||||
ResourceGuard<OpensslBIOTraits> bio_mem;
|
||||
RSA* NewRsaObj;
|
||||
|
||||
bio_mem = BIO_new(BIO_s_mem());
|
||||
if (bio_mem == nullptr)
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"BIO_new fails.");
|
||||
|
||||
if (BIO_puts(bio_mem, KeyString.c_str()) <= 0)
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"BIO_puts fails.");
|
||||
|
||||
NewRsaObj = _BIOToRSA<_Type, _Format>(bio_mem);
|
||||
_RsaObj.Release();
|
||||
_RsaObj.TakeHoldOf(NewRsaObj);
|
||||
}
|
||||
|
||||
template<KeyType _Type = KeyType::PublicKey>
|
||||
int Encrypt(const void* from, int len, void* to, int padding) {
|
||||
int write_bytes;
|
||||
|
||||
if constexpr (_Type == KeyType::PrivateKey) {
|
||||
write_bytes = RSA_private_encrypt(len,
|
||||
reinterpret_cast<const unsigned char*>(from),
|
||||
reinterpret_cast<unsigned char*>(to),
|
||||
_RsaObj,
|
||||
padding);
|
||||
if (write_bytes == -1)
|
||||
throw OpensslError(__BASE_FILE__, __LINE__, ERR_get_error(),
|
||||
"RSA_private_encrypt fails.");
|
||||
} else {
|
||||
write_bytes = RSA_public_encrypt(len,
|
||||
reinterpret_cast<const unsigned char*>(from),
|
||||
reinterpret_cast<unsigned char*>(to),
|
||||
_RsaObj,
|
||||
padding);
|
||||
if (write_bytes == -1)
|
||||
throw OpensslError(__BASE_FILE__, __LINE__, ERR_get_error(),
|
||||
"RSA_public_encrypt fails.");
|
||||
}
|
||||
|
||||
return write_bytes;
|
||||
}
|
||||
|
||||
template<KeyType _Type = KeyType::PrivateKey>
|
||||
int Decrypt(const void* from, int len, void* to, int padding) {
|
||||
int write_bytes;
|
||||
|
||||
if constexpr (_Type == KeyType::PrivateKey) {
|
||||
write_bytes = RSA_private_decrypt(len,
|
||||
reinterpret_cast<const unsigned char*>(from),
|
||||
reinterpret_cast<unsigned char*>(to),
|
||||
_RsaObj,
|
||||
padding);
|
||||
if (write_bytes == -1)
|
||||
throw OpensslError(__BASE_FILE__, __LINE__, ERR_get_error(),
|
||||
"RSA_private_decrypt fails.");
|
||||
} else {
|
||||
write_bytes = RSA_public_decrypt(len,
|
||||
reinterpret_cast<const unsigned char*>(from),
|
||||
reinterpret_cast<unsigned char*>(to),
|
||||
_RsaObj,
|
||||
padding);
|
||||
if (write_bytes == -1)
|
||||
throw OpensslError(__BASE_FILE__, __LINE__, ERR_get_error(),
|
||||
"RSA_public_decrypt fails.");
|
||||
}
|
||||
|
||||
return write_bytes;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user