[+] Aurora::Crypto::X509::CertRequest

[+] Aurora::Crypto::X509::GenerateCertificate
[*] Fix lazily copied gen1 RSA code
[+] Aurora::Crypto::ECC::EECCCurve::eCurveSECP256R1
[+] Aurora::Crypto::ECC::EECCCurve::eCurveSECP256K1
[+] Aurora::Crypto::ECC::EECCCurve::eCurveSECP384R1
[+] Aurora::Crypto::ECC::EECCCurve::eCurveSECP521R1
[*] Unfuck ECC interop
[*] Tls pinning: use mbedtls_ssl_conf_verify for tls1.3 (when mbedtls is in a better state)
This commit is contained in:
Reece Wilson 2022-11-18 21:03:11 +00:00
parent d9dd1182b9
commit 033f7e2453
22 changed files with 609 additions and 86 deletions

View File

@ -36,11 +36,11 @@ namespace Aurora::Crypto
#include "TDES/TDES.hpp"
#include "PBKDF2/PBKDF2.hpp"
#include "AES/AES.hpp"
#include "X509/X509.hpp"
#include "CA/CA.hpp"
#include "ECC/ECC.hpp"
#include "PEM/PEM.hpp"
#include "RSA/RSA.hpp"
#include "X509/X509.hpp"
#include "BCrypt/BCrypt.hpp"
#include "HMAC/HMAC.hpp"
#include "HashCash/HashCash.hpp"

View File

@ -15,6 +15,10 @@ namespace Aurora::Crypto::ECC
eCurve384,
eCurve521,
eCurveX25519,
eCurveEd25519
eCurveEd25519,
eCurveSECP256R1,
eCurveSECP256K1,
eCurveSECP384R1,
eCurveSECP521R1
));
}

View File

@ -0,0 +1,20 @@
/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: EExtendedUsage.hpp
Date: 2022-11-18
Author: Reece
***/
#pragma once
namespace Aurora::Crypto::X509
{
AUE_DEFINE(EExtendedUsage,
(
eClientAuth,
eCodeSigning,
eEmailProtection,
eTimeStamping,
eOCSPSigning
));
}

View File

@ -0,0 +1,49 @@
/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: GenerateCertificate.hpp
Date: 2022-11-18
Author: Reece
***/
#pragma once
namespace Aurora::IO::TLS
{
struct ITLSPrivateKeyPair;
}
namespace Aurora::Crypto::X509
{
struct CertRequest
{
// subject --
CertName name;
// metadata --
Hashing::EHashType digest;
AuUInt8 uVersion { 3 };
bool bIsCA {};
bool bSubjectKeyId {};
AuList<EExtendedUsage> usage;
AuUInt8 uSerialRadix { 10 };
AuString sSerial { "69420" };
// validity --
AuSInt iIssuedDateMs {};
AuSInt iExpirationDateMs {};
// public key ---
AuSPtr<RSA::IRSAPublic> pRSAKey;
AuSPtr<ECC::IECCPublic> pECCKey;
// private key ---
AuSPtr<RSA::IRSAPrivate> pSelfSigningRSAKey;
AuSPtr<ECC::IECCPrivate> pSelfSigningECCKey;
// or
AuSPtr<Aurora::IO::TLS::ITLSPrivateKeyPair> pSigningChain;
};
AUKN_SYM AuResult<Memory::ByteBuffer> GenerateCertificate(const CertRequest &request);
}

View File

@ -8,6 +8,7 @@
#pragma once
#include "ESignatureAlgorithm.hpp"
#include "EExtendedUsage.hpp"
namespace Aurora::Crypto::X509
{
@ -60,8 +61,12 @@ namespace Aurora::Crypto::X509
AuList<AuString> AIAs;
// TODO: AuString CRL;
// TODO: AuList<String> subjectNames;
Hashing::EHashType digest;
AuList<EExtendedUsage> usage;
};
AUKN_SYM bool Decode(const Certificate &der, DecodedCertificate &out);
AUKN_SYM bool Validate(const Certificate &der, const Certificate &parentDer);
}
#include "GenerateCertificate.hpp"

View File

@ -8,6 +8,7 @@
#include <Source/RuntimeInternal.hpp>
#include "AuCrypto.hpp"
#include <tomcrypt.h>
#include <mbedtls/psa_util.h>
namespace Crypto
{
@ -42,7 +43,7 @@ namespace Crypto
static void MBedTlsInit()
{
psa_crypto_init();
}
void InitCrypto()
@ -108,4 +109,25 @@ namespace Crypto
return 0xFF;
}
}
mbedtls_md_type_t TypeToMbed(Aurora::Hashing::EHashType type)
{
switch (type)
{
case AuHashing::EHashType::eMD5:
return mbedtls_md_type_t::MBEDTLS_MD_MD5;
case AuHashing::EHashType::eRMD160:
return mbedtls_md_type_t::MBEDTLS_MD_RIPEMD160;
case AuHashing::EHashType::eSHA1:
return mbedtls_md_type_t::MBEDTLS_MD_SHA1;
case AuHashing::EHashType::eSHA2_32:
return mbedtls_md_type_t::MBEDTLS_MD_SHA256;
case AuHashing::EHashType::eSHA2_64:
return mbedtls_md_type_t::MBEDTLS_MD_SHA512;
case AuHashing::EHashType::eSHA2_48:
return mbedtls_md_type_t::MBEDTLS_MD_SHA384;
default:
return mbedtls_md_type_t::MBEDTLS_MD_NONE;
}
}
}

View File

@ -7,6 +7,8 @@
***/
#pragma once
#include <mbedtls/md.h>
namespace Crypto
{
inline int gAesCipher;
@ -33,4 +35,6 @@ namespace Crypto
int PaddingToType(Aurora::Crypto::EPaddingType type);
int HashMethodToId(Aurora::Hashing::EHashType type);
mbedtls_md_type_t TypeToMbed(Aurora::Hashing::EHashType type);
}

View File

@ -28,9 +28,24 @@ namespace Aurora::Crypto::ECC
0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
oidLen = 16;
return x509_decode_subject_public_key_info_2((const unsigned char *)ptr, length, oid, curveOidm.data(), &oidLen) == CRYPT_OK;
}
#define LTC_SET_ASN12(list, index, Type, Data, Size) \
do { \
int LTC_MACRO_temp = (index); \
ltc_asn1_list *LTC_MACRO_list = (list); \
LTC_MACRO_list[LTC_MACRO_temp].type = (Type); \
LTC_MACRO_list[LTC_MACRO_temp].data = (void*)(Data); \
LTC_MACRO_list[LTC_MACRO_temp].size = (Size); \
LTC_MACRO_list[LTC_MACRO_temp].used = 0; \
LTC_MACRO_list[LTC_MACRO_temp].optional = 0; \
LTC_MACRO_list[LTC_MACRO_temp].klass = {}; \
LTC_MACRO_list[LTC_MACRO_temp].pc = {}; \
LTC_MACRO_list[LTC_MACRO_temp].tag = 0; \
} while (0)
static EECCCurve GetEdECCCurveType(const void *ptr, AuUInt length)
{
AuArray<unsigned long, 16> ec;
@ -84,13 +99,20 @@ namespace Aurora::Crypto::ECC
}
else
{
constexpr auto type = IsPublic ? PK_PUBLIC : PK_PRIVATE;
ret = isX25519 ? x25519_import_raw(pk.Begin<const unsigned char>(), pk.length, type, &in) : ed25519_import_raw(pk.Begin<const unsigned char>(), pk.length, type, &in);
if (IsPublic)
{
ret = isX25519 ? x25519_import(pk.Begin<const unsigned char>(), pk.length, &in) :
ed25519_import(pk.Begin<const unsigned char>(), pk.length, &in);
}
else
{
ret = isX25519 ? x25519_import_pkcs8(pk.Begin<const unsigned char>(), pk.length, nullptr, 0, &in ) :
ed25519_import_pkcs8(pk.Begin<const unsigned char>(), pk.length, nullptr, 0, &in);
}
}
if (ret != CRYPT_OK)
{
SysPushErrorCrypto("{}", ret);
return nullptr;
}
@ -109,8 +131,9 @@ namespace Aurora::Crypto::ECC
curve25519_key in {};
int ret;
const int prng_idx = register_prng(&sprng_desc);
prng_state yarrow_prng {};
ret = isX25519 ? x25519_make_key(NULL, prng_idx, &in) : ed25519_make_key(NULL, prng_idx, &in);
ret = isX25519 ? x25519_make_key(&yarrow_prng, prng_idx, &in) : ed25519_make_key(&yarrow_prng, prng_idx, &in);
if (ret != CRYPT_OK)
{
SysPushErrorCrypto("{}", ret);
@ -164,7 +187,7 @@ namespace Aurora::Crypto::ECC
AUKN_SYM IECCPrivate *OpenPrivateECCNew(const AuMemoryViewRead &pk)
{
auto type = GetEdECCCurveType(pk.ptr, pk.length);
if (type != EECCCurve::eEnumInvalid)
//if (type != EECCCurve::eEnumInvalid)
{
if (auto ret = NewStdECC<PrivateECCImpl>(type, pk, false))
{
@ -172,14 +195,15 @@ namespace Aurora::Crypto::ECC
}
}
if (IsBlobCurveX25519(pk.ptr, pk.length))
if (auto pTemp = New25519ECC<false, IECCPrivate *>(true, pk, false))
{
return New25519ECC<false, IECCPrivate*>(true, pk, false);
return pTemp;
}
if (IsBlobCurveEd25519(pk.ptr, pk.length))
if (auto pTemp = New25519ECC<false, IECCPrivate *>(false, pk, false))
{
return New25519ECC<false, IECCPrivate *>(false, pk, false);
return pTemp;
}
return {};
@ -188,7 +212,7 @@ namespace Aurora::Crypto::ECC
AUKN_SYM IECCPublic *OpenPublicECCNew(const AuMemoryViewRead &pk)
{
auto type = GetEdECCCurveType(pk.ptr, pk.length);
if (type != EECCCurve::eEnumInvalid)
//if (type != EECCCurve::eEnumInvalid)
{
if (auto ret = NewStdECC<PublicECCImpl>(type, pk, false))
{
@ -196,14 +220,14 @@ namespace Aurora::Crypto::ECC
}
}
if (IsBlobCurveX25519(pk.ptr, pk.length))
if (auto pTemp = New25519ECC<true, IECCPublic *>(true, pk, false))
{
return New25519ECC<true, IECCPublic *>(true, pk, false);
return pTemp;
}
if (IsBlobCurveEd25519(pk.ptr, pk.length))
if (auto pTemp = New25519ECC<true, IECCPublic *>(false, pk, false))
{
return New25519ECC<true, IECCPublic *>(false, pk, false);
return pTemp;
}
return {};
@ -220,14 +244,14 @@ namespace Aurora::Crypto::ECC
}
}
if (IsBlobCurveX25519(certificate.ptr, certificate.length))
if (auto pTemp = New25519ECC<true, IECCPublic *>(true, certificate, true))
{
return New25519ECC<true, IECCPublic *>(true, certificate, true);
return pTemp;
}
if (IsBlobCurveEd25519(certificate.ptr, certificate.length))
if (auto pTemp = New25519ECC<true, IECCPublic *>(false, certificate, true))
{
return New25519ECC<true, IECCPublic *>(false, certificate, true);
return pTemp;
}
return {};

View File

@ -49,8 +49,65 @@ namespace Aurora::Crypto::ECC
/* OID */ "1.3.132.0.35"
};
static const EECCCurve kEccTypes[] = {EECCCurve::eCurve256, EECCCurve::eCurve384, EECCCurve::eCurve521};
static const ltc_ecc_curve *kEccCurves[] = {&kNistp256, &kNistp384, &kNistp521};
static const ltc_ecc_curve kSECP256R1 =
{
/* prime */ "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
/* A */ "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
/* B */ "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
/* order */ "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",
/* Gx */ "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
/* Gy */ "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
/* cofactor */ 1,
/* OID */ "1.2.840.10045.3.1.7"
};
static const ltc_ecc_curve kSECP256K1 =
{
/* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F",
/* A */ "0000000000000000000000000000000000000000000000000000000000000000",
/* B */ "0000000000000000000000000000000000000000000000000000000000000007",
/* order */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141",
/* Gx */ "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798",
/* Gy */ "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8",
/* cofactor */ 1,
/* OID */ "1.3.132.0.10"
};
static const ltc_ecc_curve kSECP384R1 =
{
/* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF",
/* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC",
/* B */ "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF",
/* order */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973",
/* Gx */ "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7",
/* Gy */ "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F",
/* cofactor */ 1,
/* OID */ "1.3.132.0.34"
};
static const ltc_ecc_curve kSECP521R1 =
{
/* prime */ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
/* A */ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC",
/* B */ "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",
/* order */ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409",
/* Gx */ "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",
/* Gy */ "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650",
/* cofactor */ 1,
/* OID */ "1.3.132.0.35"
};
static const EECCCurve kEccTypes[] = {
EECCCurve::eCurve256, EECCCurve::eCurve384, EECCCurve::eCurve521,
EECCCurve::eCurveSECP256K1, EECCCurve::eCurveSECP256R1, EECCCurve::eCurveSECP384R1,
EECCCurve::eCurveSECP521R1
};
static const ltc_ecc_curve *kEccCurves[] = {
&kNistp256, &kNistp384, &kNistp521,
&kSECP256K1, &kSECP256R1, &kSECP384R1,
&kSECP521R1
};
EECCCurve OIDToCurve(unsigned long *oid, unsigned long oidlen)
{
@ -115,6 +172,14 @@ namespace Aurora::Crypto::ECC
return &kNistp384;
case EECCCurve::eCurve521:
return &kNistp521;
case EECCCurve::eCurveSECP256K1:
return &kSECP256K1;
case EECCCurve::eCurveSECP256R1:
return &kSECP256R1;
case EECCCurve::eCurveSECP384R1:
return &kSECP384R1;
case EECCCurve::eCurveSECP521R1:
return &kSECP521R1;
default:
return {};
}

View File

@ -112,7 +112,7 @@ namespace Aurora::Crypto::ECC
unsigned long actualSize = 4096;
auto iRet = ::ecc_export_openssl(out.writePtr,
&actualSize, pub ? PK_PUBLIC : PK_PRIVATE,
&actualSize, PK_CURVEOID | (pub ? PK_PUBLIC : PK_PRIVATE),
&key);
if (iRet != CRYPT_OK)
@ -130,6 +130,7 @@ namespace Aurora::Crypto::ECC
{
ecc_key key = {};
const int prng_idx = register_prng(&sprng_desc);
prng_state yarrow_prng;
auto tc = GetECCCurve(curve);
if (!tc)
@ -138,7 +139,7 @@ namespace Aurora::Crypto::ECC
return {};
}
auto error = ecc_make_key_ex(NULL, prng_idx, &key, *tc);
auto error = ecc_make_key_ex(&yarrow_prng, prng_idx, &key, *tc);
if (error != CRYPT_OK)
{
SysPushErrorCrypt("{}", error);

View File

@ -26,16 +26,16 @@ namespace Aurora::Crypto::ECC
int ret {};
AuOptional<const ltc_ecc_curve *> ref;
if (EECCCurveIsValid(curve))
{
ref = GetECCCurve(curve);
if (!ref)
{
SysPushErrorParam("This curve isn't supported here");
// wrong function, bucko
return nullptr;
}
}
//if (EECCCurveIsValid(curve))
//{
// ref = GetECCCurve(curve);
// if (!ref)
// {
// SysPushErrorParam("This curve isn't supported here");
// // wrong function, bucko
// return nullptr;
// }
//}
if (cert)
{
@ -48,7 +48,7 @@ namespace Aurora::Crypto::ECC
if (ret != CRYPT_OK)
{
SysPushErrorCrypto("{}", ret);
//SysPushErrorCrypto("{}", ret);
return nullptr;
}
@ -72,11 +72,11 @@ namespace Aurora::Crypto::ECC
curve = OIDToCurve(in.dp.oid, in.dp.oidlen);
}
if (!EECCCurveIsValid(curve))
{
SysPushErrorCrypt("Couldn't find curve");
return {};
}
//if (!EECCCurveIsValid(curve))
//{
// SysPushErrorCrypt("Couldn't find curve");
// return {};
//}
Type_t *out = _new Type_t(curve, in);
if (!out)

View File

@ -155,11 +155,11 @@ namespace Aurora::Crypto::ECC
if (this->bIsX25519_)
{
ret = x25519_export(out.writePtr, &actualSize, PK_PUBLIC, &this->key_);
ret = x25519_export(out.writePtr, &actualSize, PK_PUBLIC | PK_STD, &this->key_);
}
else
{
ret = ed25519_export(out.writePtr, &actualSize, PK_PUBLIC, &this->key_);
ret = ed25519_export(out.writePtr, &actualSize, PK_PUBLIC | PK_STD, &this->key_);
}
if (ret != CRYPT_OK)
@ -189,11 +189,11 @@ namespace Aurora::Crypto::ECC
if (this->bIsX25519_)
{
ret = x25519_export(out.writePtr, &actualSize, PK_PRIVATE, &this->key_);
ret = x25519_export(out.writePtr, &actualSize, PK_PRIVATE | PK_STD, &this->key_);
}
else
{
ret = ed25519_export(out.writePtr, &actualSize, PK_PRIVATE, &this->key_);
ret = ed25519_export(out.writePtr, &actualSize, PK_PRIVATE | PK_STD, &this->key_);
}
if (ret != CRYPT_OK)

View File

@ -118,11 +118,11 @@ namespace Aurora::Crypto::ECC
if (this->bIsX25519_)
{
ret = ::x25519_export(out.writePtr, &actualSize, PK_PUBLIC, &this->key_);
ret = ::x25519_export(out.writePtr, &actualSize, PK_PUBLIC | PK_STD, &this->key_);
}
else
{
ret = ::ed25519_export(out.writePtr, &actualSize, PK_PUBLIC, &this->key_);
ret = ::ed25519_export(out.writePtr, &actualSize, PK_PUBLIC | PK_STD, &this->key_);
}
if (ret != CRYPT_OK)

View File

@ -30,7 +30,7 @@ namespace Aurora::Crypto::RSA
}
unsigned long actualSize = out.size();
auto ret = rsa_pkcs8_export(out.data(), &actualSize, &key, flags);
auto ret = rsa_pkcs8_export(out.writePtr, &actualSize, &key, flags);
if (ret != CRYPT_OK)
{
@ -38,7 +38,7 @@ namespace Aurora::Crypto::RSA
return false;
}
out.resize(actualSize);
out.writePtr += actualSize;
return true;
}

View File

@ -157,21 +157,16 @@ namespace Aurora::Crypto::RSA
AuSPtr<IRSAPublic> PrivateRSA::ToPublic()
{
rsa_key key {};
key.type = this->key_.type;
key.type = PK_PUBLIC;
#define COPY_KEY_PART(x) \
if (ltc_mp.copy(&this->key_.x, &key.x) != CRYPT_OK) \
if (ltc_mp.init_copy(&key.x, this->key_.x) != CRYPT_OK) \
{ \
return {}; \
}
COPY_KEY_PART(N)
COPY_KEY_PART(e)
COPY_KEY_PART(d)
COPY_KEY_PART(p)
COPY_KEY_PART(qP)
COPY_KEY_PART(dP)
COPY_KEY_PART(dQ)
return AuMakeShared<PublicRSA>(key);
}
@ -215,8 +210,9 @@ namespace Aurora::Crypto::RSA
{
rsa_key key {};
const int prng_idx = register_prng(&sprng_desc);
prng_state yarrow_prng;
auto iRet = ::rsa_make_key(NULL, prng_idx, keySize / 8, 65537, &key);
auto iRet = ::rsa_make_key(&yarrow_prng, prng_idx, keySize / 8, 65537, &key);
if (iRet != CRYPT_OK)
{
SysPushErrorCrypt("{}", iRet);

View File

@ -0,0 +1,314 @@
/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: GenerateCertificate.cpp
Date: 2022-11-18
Author: Reece
***/
#include <Source/RuntimeInternal.hpp>
#include "../Crypto.hpp"
#include "x509.hpp"
#include <Source/IO/TLS/TLS.hpp>
#include <Source/IO/TLS/TLSPrivateKeyPair.hpp>
#include <mbedtls/asn1write.h>
#include <mbedtls/oid.h>
namespace Aurora::Crypto::X509
{
AUKN_SYM AuResult<Memory::ByteBuffer> GenerateCertificate(const CertRequest &request)
{
int iRet {};
mbedtls_x509write_cert crt;
mbedtls_mpi serial;
AuByteBuffer bufPb;
mbedtls_pk_context ctxPb {};
mbedtls_md_type_t hash {};
AuByteBuffer bufPv;
mbedtls_pk_context ctxPv {};
Memory::ByteBuffer buffer;
if (request.pRSAKey && request.pECCKey)
{
SysPushErrorArg("A certificate may only contain one key");
return {};
}
if (!request.pSigningChain)
{
if (!(bool(request.pRSAKey) == bool(request.pSelfSigningRSAKey) &&
bool(request.pECCKey) == bool(request.pSelfSigningECCKey)))
{
SysPushErrorArg("Missing or conflicting private/public key types");
return {};
}
}
else
{
if (request.pSelfSigningRSAKey || request.pSelfSigningECCKey)
{
SysPushErrorArg("Missing or conflicting private/public key types");
return {};
}
}
if (request.uVersion > 3)
{
SysPushErrorArg("Invalid version");
return {};
}
::mbedtls_x509write_crt_init(&crt);
::mbedtls_mpi_init(&serial);
::mbedtls_x509write_crt_set_version(&crt, request.uVersion - 1);
{
if (request.pRSAKey)
{
if (!request.pRSAKey->ToKey(RSA::ERSAKeyType::eRsaKey, bufPb))
{
SysPushErrorNested();
goto out;
}
}
if (request.pECCKey)
{
if (!request.pECCKey->AsPublicECC(bufPb))
{
SysPushErrorNested();
goto out;
}
}
if ((iRet = ::mbedtls_pk_parse_public_key(&ctxPb, bufPb.readPtr, bufPb.RemainingBytes())) != 0)
{
SysPushErrorCrypto("Couldn't import public key: {}", iRet);
goto out;
}
::mbedtls_x509write_crt_set_subject_key(&crt, &ctxPb);
}
{
if (request.pSigningChain)
{
ctxPv = AuStaticCast<IO::TLS::TLSPrivateKeyPairImpl>(request.pSigningChain)->GetInternal();
}
else
{
if (request.pSelfSigningRSAKey)
{
RSA::RSAMeta meta;
meta.encoding = RSA::ERSAKeyType::eKey;
meta.type = AuCrypto::EKeyType::eKeyPrivate;
if (!request.pSelfSigningRSAKey->ToKey(meta, bufPv))
{
SysPushErrorNested();
goto out;
}
}
if (request.pSelfSigningECCKey)
{
if (!request.pSelfSigningECCKey->AsPrivateECC(bufPv))
{
SysPushErrorNested();
goto out;
}
}
if ((iRet = ::mbedtls_pk_parse_key(&ctxPv,
bufPv.base, bufPv.RemainingBytes(),
nullptr, 0,
mbedtls_ctr_drbg_random,
&IO::TLS::gCtrDrbg)) != 0)
{
SysPushErrorCrypt("Couldn't parse private issuer key: {}", iRet);
goto out;
}
::mbedtls_x509write_crt_set_issuer_key(&crt, &ctxPv);
}
}
#define _WRITE_ISSUER(oid, expression) \
if (expression.size()) \
{ \
mbedtls_asn1_named_data* pCur; \
if (!(pCur =::mbedtls_asn1_store_named_data(&crt.private_subject, \
oid, \
strlen(oid), \
(const unsigned char *)expression.c_str(),\
expression.size()))) \
{ \
goto out; \
} \
pCur->val.tag = MBEDTLS_ASN1_UTF8_STRING; \
}
_WRITE_ISSUER(MBEDTLS_OID_AT_CN, request.name.commonName);
_WRITE_ISSUER(MBEDTLS_OID_AT_COUNTRY, request.name.countryCode);
_WRITE_ISSUER(MBEDTLS_OID_AT_ORGANIZATION, request.name.organization);
_WRITE_ISSUER(MBEDTLS_OID_AT_ORG_UNIT, request.name.department);
_WRITE_ISSUER(MBEDTLS_OID_AT_STATE, request.name.state);
_WRITE_ISSUER(MBEDTLS_OID_PKCS9_EMAIL, request.name.email);
_WRITE_ISSUER(MBEDTLS_OID_AT_TITLE, request.name.title);
_WRITE_ISSUER(MBEDTLS_OID_AT_GIVEN_NAME, request.name.name);
#undef _WRITE_ISSUER
if (request.pSigningChain)
{
crt.private_issuer = &AuStaticCast<IO::TLS::CertificateChain>(request.pSigningChain->GetChain())->pCertificate->issuer;
}
else
{
crt.private_issuer = crt.private_subject;
}
{
auto issueNorm = AuTime::ToCivilTime(request.iIssuedDateMs, true);
auto issue = fmt::format("{:04}{:02}{:02}{:02}{:02}{:02}",
issueNorm.tm_year + 1900, issueNorm.tm_mon + 1, issueNorm.tm_mday,
issueNorm.tm_hour, issueNorm.tm_min, issueNorm.tm_sec);
auto expireNorm = AuTime::ToCivilTime(request.iExpirationDateMs, true);
auto expire = fmt::format("{:04}{:02}{:02}{:02}{:02}{:02}",
expireNorm.tm_year + 1900, expireNorm.tm_mon + 1, expireNorm.tm_mday,
expireNorm.tm_hour, expireNorm.tm_min, expireNorm.tm_sec);
if (mbedtls_x509write_crt_set_validity(&crt, issue.c_str(), expire.c_str()) != 0)
{
SysPushErrorCrypto("Couldn't update certificate validity");
goto out;
}
}
hash = ::Crypto::TypeToMbed(request.digest);
if (hash == mbedtls_md_type_t::MBEDTLS_MD_NONE)
{
SysPushErrorCrypto("Unsupported digest: {}", AuHashing::EHashTypeToString(request.digest));
goto out;
}
::mbedtls_x509write_crt_set_md_alg(&crt, hash);
if (::mbedtls_mpi_read_string(&serial, request.uSerialRadix, request.sSerial.c_str()) != 0)
{
SysPushErrorCrypto("Couldn't parse serial");
goto out;
}
if (::mbedtls_x509write_crt_set_serial(&crt, &serial) != 0)
{
SysPushErrorCrypto("Couldn't set serial");
goto out;
}
if (request.bSubjectKeyId && request.uVersion == 3)
{
if (::mbedtls_x509write_crt_set_subject_key_identifier(&crt) != 0)
{
SysPushErrorCrypto("Couldn't set subject key identifier");
goto out;
}
}
if (request.bIsCA && request.uVersion == 3)
{
if (::mbedtls_x509write_crt_set_authority_key_identifier(&crt) != 0)
{
SysPushErrorCrypto("Couldn't set authority key identifier");
goto out;
}
}
if (request.usage.size())
{
mbedtls_asn1_sequence *tail {};
for (const auto A : request.usage)
{
#define SET_OID(x, oid) \
do { x.len = MBEDTLS_OID_SIZE(oid); x.p = (unsigned char*)oid; x.tag = MBEDTLS_ASN1_OID; } while( 0 )
auto ext_key_usage = (mbedtls_asn1_sequence *)::Aurora::Memory::_ZAlloc(sizeof(mbedtls_asn1_sequence));
if (tail)
{
ext_key_usage->next = tail;
}
tail = ext_key_usage;
switch (A)
{
//case EExtendedUsage::eClientAuth:
// SET_OID(ext_key_usage->buf, MBEDTLS_OID_SERVER_AUTH);
// break;
case EExtendedUsage::eClientAuth:
SET_OID(ext_key_usage->buf, MBEDTLS_OID_CLIENT_AUTH);
break;
case EExtendedUsage::eCodeSigning:
SET_OID(ext_key_usage->buf, MBEDTLS_OID_CODE_SIGNING);
break;
case EExtendedUsage::eEmailProtection:
SET_OID(ext_key_usage->buf, MBEDTLS_OID_EMAIL_PROTECTION);
break;
case EExtendedUsage::eTimeStamping:
SET_OID(ext_key_usage->buf, MBEDTLS_OID_TIME_STAMPING);
break;
case EExtendedUsage::eOCSPSigning:
SET_OID(ext_key_usage->buf, MBEDTLS_OID_OCSP_SIGNING);
break;
default:
{
tail = nullptr;
break;
}
}
}
if (tail)
{
iRet = ::mbedtls_x509write_crt_set_ext_key_usage(&crt, tail);
if (iRet != 0)
{
SysPushErrorCrypto("Couldn't write usage {}", iRet);
goto out;
}
}
}
if (!AuTryResize(buffer, 10 * 1024))
{
goto out;
}
iRet = ::mbedtls_x509write_crt_der(&crt,
buffer.base,
buffer.length,
::mbedtls_ctr_drbg_random,
&IO::TLS::gCtrDrbg);
if (iRet < 0)
{
SysPushErrorCrypto("Couldn't write x509 cert: {}", iRet);
goto out;
}
AuMemmove(buffer.base, buffer.base + buffer.length - iRet, iRet);
buffer.writePtr += iRet;
crt.private_issuer = nullptr;
mbedtls_x509write_crt_free(&crt);
mbedtls_pk_free(&ctxPv);
mbedtls_pk_free(&ctxPb);
return buffer;
out:
crt.private_issuer = nullptr;
mbedtls_x509write_crt_free(&crt);
mbedtls_pk_free(&ctxPv);
mbedtls_pk_free(&ctxPb);
return {};
}
}

View File

@ -0,0 +1,13 @@
/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: GenerateCertificate.hpp
Date: 2022-11-18
Author: Reece
***/
#pragma once
namespace Aurora::Crypto::X509
{
}

View File

@ -467,12 +467,12 @@ namespace Aurora::Crypto::X509
[&](mbedtls_x509_crt &ca)
{
if (failed = IsHighRiskStateIssuer(ca))
if (failed |= IsHighRiskStateIssuer(ca))
{
return;
}
failed = 0 > mbedtls_x509_crt_verify_restartable(&crt, &ca, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
failed |= 0 > mbedtls_x509_crt_verify_restartable(&crt, &ca, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
});
}) && !failed;
}

View File

@ -44,11 +44,6 @@ int rsa_basic_export(unsigned char *out, unsigned long *outlen, const rsa_key *k
{
/* public key */
if (key->type != PK_PUBLIC)
{
return CRYPT_INVALID_ARG;
}
return der_encode_sequence_multi(out, outlen,
LTC_ASN1_INTEGER, 1UL, key->N,
LTC_ASN1_INTEGER, 1UL, key->e,
@ -56,7 +51,7 @@ int rsa_basic_export(unsigned char *out, unsigned long *outlen, const rsa_key *k
}
}
int rsa_pkcs8_export(unsigned char *out, unsigned long *outlen, const rsa_key *key, int flags)
int rsa_pkcs8_export(unsigned char *out, unsigned long *outlen, const rsa_key * key, int flags)
{
int ret;
char temp[4096];
@ -69,14 +64,13 @@ int rsa_pkcs8_export(unsigned char *out, unsigned long *outlen, const rsa_key *k
if ((flags & kRsaFlagPKCS1) != 0)
{
*outlen = length;
if (*outlen < length)
{
*outlen = length;
return CRYPT_BUFFER_OVERFLOW;
}
memcpy(out, temp, length);
return CRYPT_OK;
}
else
@ -124,11 +118,7 @@ int rsa_pkcs8_export(unsigned char *out, unsigned long *outlen, const rsa_key *k
}
else
{
if (key->type != PK_PUBLIC)
{
return CRYPT_INVALID_ARG;
}
// TODO: return false?
ret = der_encode_sequence_multi(out, outlen,
LTC_ASN1_SEQUENCE, 1, alg_seq,
LTC_ASN1_BIT_STRING, length, temp,

View File

@ -213,7 +213,7 @@ namespace Aurora::IO::FS
goto out;
}
if (written != blockSize)
if (!written)
{
SysPushErrorIO();
goto out;

View File

@ -13,6 +13,14 @@ namespace Aurora::IO::TLS
AUKN_SYM const AuList<AuUInt16> &GetDefaultCipherSuites()
{
static AuList<AuUInt16> gDefaultSuites {
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
MBEDTLS_TLS1_3_AES_128_GCM_SHA256,
MBEDTLS_TLS1_3_AES_256_GCM_SHA384,
MBEDTLS_TLS1_3_CHACHA20_POLY1305_SHA256,
MBEDTLS_TLS1_3_AES_128_CCM_SHA256,
MBEDTLS_TLS1_3_AES_128_CCM_8_SHA256,
#endif
MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256,

View File

@ -17,6 +17,7 @@ namespace Aurora::IO::TLS
{
mbedtls_entropy_context gEntropy;
mbedtls_ctr_drbg_context gCtrDrbg;
static bool gTlsReady {};
AuString TLSErrorToString(int iError)
@ -136,11 +137,6 @@ namespace Aurora::IO::TLS
return true;
}
if (this->bPinLock_)
{
return true;
}
auto pCertChain = AuMakeShared<CertificateChain>();
if (!pCertChain)
{
@ -151,7 +147,6 @@ namespace Aurora::IO::TLS
pCertChain->Init(child);
auto bRet = this->meta_.pCertPin->CheckCertificate(pCertChain, read);
this->bPinLock_ = true;
pCertChain->pCertificate = nullptr;
return bRet;
}
@ -204,7 +199,7 @@ namespace Aurora::IO::TLS
if (this->meta_.bIsClient)
{
::mbedtls_ssl_conf_authmode(&this->conf, MBEDTLS_SSL_VERIFY_OPTIONAL);
::mbedtls_ssl_conf_authmode(&this->conf, MBEDTLS_SSL_VERIFY_REQUIRED);
}
else
{
@ -218,12 +213,25 @@ namespace Aurora::IO::TLS
}
}
::mbedtls_ssl_conf_verify(&this->conf, [](void *p_ctx, mbedtls_x509_crt *crt,
int depth, uint32_t *flags)
{
*flags &= ~MBEDTLS_X509_BADCERT_NOT_TRUSTED;
if (depth != 0)
{
return 0;
}
((TLSContext *)p_ctx)->CheckCertificate(crt, { crt->raw.p, crt->raw.len }) ? 0 : -1;
return 0;
}, this);
//
::mbedtls_ssl_conf_ca_cb(&this->conf, [](void *p_ctx,
mbedtls_x509_crt const *child,
mbedtls_x509_crt **candidate_cas) -> int
{
return ((TLSContext *)p_ctx)->CheckCertificate(child, { child->raw.p, child->raw.len }) ? 0 : -1;
return 0;// ((TLSContext *)p_ctx)->CheckCertificate(child, { child->raw.p, child->raw.len }) ? 0 : -1;
}, this);
::mbedtls_ssl_conf_rng(&this->conf, mbedtls_ctr_drbg_random, &gCtrDrbg);