AuroraRuntime/Source/Crypto/ECC/ECCGeneric.hpp
2021-09-21 02:54:47 +01:00

94 lines
2.6 KiB
C++

/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: ECCGeneric.hpp
Date: 2021-9-17
Author: Reece
***/
#pragma once
#include "ECCCurves.hpp"
namespace Aurora::Crypto::ECC
{
template<typename Type_t>
Type_t *NewECC(EECCCurve curve, const AuList<AuUInt8> &pub);
bool ExportECCKey(const ecc_key &key, bool pub, DerBuffer &out);
int pk_oid_str_to_num(const char *OID, unsigned long *oid, unsigned long *oidlen);
int pk_oid_num_to_str(const unsigned long *oid, unsigned long oidlen, char *OID, unsigned long *outlen);
template<typename Type_t>
static Type_t *NewStdECC(AuOptional<EECCCurve> curve, const Memory::MemoryViewRead &pk, bool cert = false)
{
ecc_key in {};
AuOptional<const ltc_ecc_curve *> ref;
if (curve)
{
ref = GetECCCurve(curve.value());
if (!ref)
{
SysPushErrorParam("This curve isn't supported here");
// wrong function, bucko
return nullptr;
}
}
if (cert)
{
auto ret = ecc_import_x509(pk.Begin<const unsigned char>(), pk.length, &in);
if (ret != CRYPT_OK)
{
SysPushErrorCrypto("{}", ret);
return nullptr;
}
}
else
{
auto ret = ecc_import_openssl(pk.Begin<const unsigned char>(), pk.length, &in);
if (ret != CRYPT_OK)
{
SysPushErrorCrypto("{}", ret);
return nullptr;
}
}
if (ref)
{
unsigned long oid[16] {};
unsigned long oidLength = AuArraySize(oid);
pk_oid_str_to_num(ref.value()->OID, oid, &oidLength);
if (oidLength != in.dp.oidlen ||
std::memcmp(in.dp.oid, oid, in.dp.oidlen * sizeof(unsigned long)))
{
SysPushErrorParam("Improper curve type, expected {}, got {}, for ECCCurveType: {}", ref.value()->OID, AuList<unsigned long>(in.dp.oid, in.dp.oid + in.dp.oidlen), curve.value());
ecc_free(&in);
return nullptr;
}
}
else
{
curve = OIDToCurve(in.dp.oid, in.dp.oidlen);
}
if (!curve)
{
SysPushErrorCrypt("Couldn't find curve");
return {};
}
Type_t *out = _new Type_t(curve.value(), in);
if (!out)
{
ecc_free(&in);
}
return out;
}
std::optional<IECCPrivate *> GenerateNewGenericECC(EECCCurve curve);
}