From 033f7e245303a8acaaf7a46d5612c75847a05e55 Mon Sep 17 00:00:00 2001 From: Reece Wilson Date: Fri, 18 Nov 2022 21:03:11 +0000 Subject: [PATCH] [+] 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) --- Include/Aurora/Crypto/Crypto.hpp | 2 +- Include/Aurora/Crypto/ECC/EECCCurve.hpp | 6 +- Include/Aurora/Crypto/X509/EExtendedUsage.hpp | 20 ++ .../Crypto/X509/GenerateCertificate.hpp | 49 +++ Include/Aurora/Crypto/X509/X509.hpp | 5 + Source/AuCrypto.cpp | 24 +- Source/AuCrypto.hpp | 4 + Source/Crypto/ECC/ECC.cpp | 62 ++-- Source/Crypto/ECC/ECCCurves.cpp | 69 +++- Source/Crypto/ECC/ECCGeneric.cpp | 5 +- Source/Crypto/ECC/ECCGeneric.hpp | 32 +- Source/Crypto/ECC/ECCX25519Private.cpp | 8 +- Source/Crypto/ECC/ECCX25519Public.cpp | 4 +- Source/Crypto/RSA/RSA.hpp | 4 +- Source/Crypto/RSA/RSAPrivate.cpp | 18 +- Source/Crypto/X509/GenerateCertificate.cpp | 314 ++++++++++++++++++ Source/Crypto/X509/GenerateCertificate.hpp | 13 + Source/Crypto/X509/x509.cpp | 4 +- Source/Extensions/LTC/LTCExport.c | 16 +- Source/IO/FS/FS.NT.cpp | 2 +- Source/IO/TLS/TLSCipherSuites.cpp | 8 + Source/IO/TLS/TLSContext.cpp | 26 +- 22 files changed, 609 insertions(+), 86 deletions(-) create mode 100644 Include/Aurora/Crypto/X509/EExtendedUsage.hpp create mode 100644 Include/Aurora/Crypto/X509/GenerateCertificate.hpp create mode 100644 Source/Crypto/X509/GenerateCertificate.cpp create mode 100644 Source/Crypto/X509/GenerateCertificate.hpp diff --git a/Include/Aurora/Crypto/Crypto.hpp b/Include/Aurora/Crypto/Crypto.hpp index 33ef4786..7c9520d4 100644 --- a/Include/Aurora/Crypto/Crypto.hpp +++ b/Include/Aurora/Crypto/Crypto.hpp @@ -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" \ No newline at end of file diff --git a/Include/Aurora/Crypto/ECC/EECCCurve.hpp b/Include/Aurora/Crypto/ECC/EECCCurve.hpp index 1b930b56..f6213589 100644 --- a/Include/Aurora/Crypto/ECC/EECCCurve.hpp +++ b/Include/Aurora/Crypto/ECC/EECCCurve.hpp @@ -15,6 +15,10 @@ namespace Aurora::Crypto::ECC eCurve384, eCurve521, eCurveX25519, - eCurveEd25519 + eCurveEd25519, + eCurveSECP256R1, + eCurveSECP256K1, + eCurveSECP384R1, + eCurveSECP521R1 )); } \ No newline at end of file diff --git a/Include/Aurora/Crypto/X509/EExtendedUsage.hpp b/Include/Aurora/Crypto/X509/EExtendedUsage.hpp new file mode 100644 index 00000000..437f61ca --- /dev/null +++ b/Include/Aurora/Crypto/X509/EExtendedUsage.hpp @@ -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 + )); +} \ No newline at end of file diff --git a/Include/Aurora/Crypto/X509/GenerateCertificate.hpp b/Include/Aurora/Crypto/X509/GenerateCertificate.hpp new file mode 100644 index 00000000..b5a7413c --- /dev/null +++ b/Include/Aurora/Crypto/X509/GenerateCertificate.hpp @@ -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 usage; + AuUInt8 uSerialRadix { 10 }; + AuString sSerial { "69420" }; + + // validity -- + AuSInt iIssuedDateMs {}; + AuSInt iExpirationDateMs {}; + + // public key --- + AuSPtr pRSAKey; + AuSPtr pECCKey; + + // private key --- + AuSPtr pSelfSigningRSAKey; + AuSPtr pSelfSigningECCKey; + + // or + + AuSPtr pSigningChain; + }; + + AUKN_SYM AuResult GenerateCertificate(const CertRequest &request); +} \ No newline at end of file diff --git a/Include/Aurora/Crypto/X509/X509.hpp b/Include/Aurora/Crypto/X509/X509.hpp index 313746de..8ee3686e 100644 --- a/Include/Aurora/Crypto/X509/X509.hpp +++ b/Include/Aurora/Crypto/X509/X509.hpp @@ -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 AIAs; // TODO: AuString CRL; // TODO: AuList subjectNames; + Hashing::EHashType digest; + AuList usage; }; AUKN_SYM bool Decode(const Certificate &der, DecodedCertificate &out); AUKN_SYM bool Validate(const Certificate &der, const Certificate &parentDer); } + +#include "GenerateCertificate.hpp" \ No newline at end of file diff --git a/Source/AuCrypto.cpp b/Source/AuCrypto.cpp index 354b9da9..ad5659fa 100644 --- a/Source/AuCrypto.cpp +++ b/Source/AuCrypto.cpp @@ -8,6 +8,7 @@ #include #include "AuCrypto.hpp" #include +#include 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; + } + } } \ No newline at end of file diff --git a/Source/AuCrypto.hpp b/Source/AuCrypto.hpp index 4fc9ea27..a71c3f90 100644 --- a/Source/AuCrypto.hpp +++ b/Source/AuCrypto.hpp @@ -7,6 +7,8 @@ ***/ #pragma once +#include + 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); } \ No newline at end of file diff --git a/Source/Crypto/ECC/ECC.cpp b/Source/Crypto/ECC/ECC.cpp index 7f73d3f1..70c14d64 100644 --- a/Source/Crypto/ECC/ECC.cpp +++ b/Source/Crypto/ECC/ECC.cpp @@ -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 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(), pk.length, type, &in) : ed25519_import_raw(pk.Begin(), pk.length, type, &in); + if (IsPublic) + { + ret = isX25519 ? x25519_import(pk.Begin(), pk.length, &in) : + ed25519_import(pk.Begin(), pk.length, &in); + } + else + { + ret = isX25519 ? x25519_import_pkcs8(pk.Begin(), pk.length, nullptr, 0, &in ) : + ed25519_import_pkcs8(pk.Begin(), 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(type, pk, false)) { @@ -172,14 +195,15 @@ namespace Aurora::Crypto::ECC } } - if (IsBlobCurveX25519(pk.ptr, pk.length)) + if (auto pTemp = New25519ECC(true, pk, false)) { - return New25519ECC(true, pk, false); + return pTemp; } - if (IsBlobCurveEd25519(pk.ptr, pk.length)) + if (auto pTemp = New25519ECC(false, pk, false)) { - return New25519ECC(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(type, pk, false)) { @@ -196,14 +220,14 @@ namespace Aurora::Crypto::ECC } } - if (IsBlobCurveX25519(pk.ptr, pk.length)) + if (auto pTemp = New25519ECC(true, pk, false)) { - return New25519ECC(true, pk, false); + return pTemp; } - if (IsBlobCurveEd25519(pk.ptr, pk.length)) + if (auto pTemp = New25519ECC(false, pk, false)) { - return New25519ECC(false, pk, false); + return pTemp; } return {}; @@ -220,16 +244,16 @@ namespace Aurora::Crypto::ECC } } - if (IsBlobCurveX25519(certificate.ptr, certificate.length)) + if (auto pTemp = New25519ECC(true, certificate, true)) { - return New25519ECC(true, certificate, true); + return pTemp; } - if (IsBlobCurveEd25519(certificate.ptr, certificate.length)) + if (auto pTemp = New25519ECC(false, certificate, true)) { - return New25519ECC(false, certificate, true); + return pTemp; } - + return {}; } diff --git a/Source/Crypto/ECC/ECCCurves.cpp b/Source/Crypto/ECC/ECCCurves.cpp index 7ae6bdce..2adc48a5 100644 --- a/Source/Crypto/ECC/ECCCurves.cpp +++ b/Source/Crypto/ECC/ECCCurves.cpp @@ -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 {}; } diff --git a/Source/Crypto/ECC/ECCGeneric.cpp b/Source/Crypto/ECC/ECCGeneric.cpp index 8995bdde..de2d7cc3 100644 --- a/Source/Crypto/ECC/ECCGeneric.cpp +++ b/Source/Crypto/ECC/ECCGeneric.cpp @@ -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); diff --git a/Source/Crypto/ECC/ECCGeneric.hpp b/Source/Crypto/ECC/ECCGeneric.hpp index c864f7b6..3b1dc0e7 100644 --- a/Source/Crypto/ECC/ECCGeneric.hpp +++ b/Source/Crypto/ECC/ECCGeneric.hpp @@ -26,16 +26,16 @@ namespace Aurora::Crypto::ECC int ret {}; AuOptional 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) diff --git a/Source/Crypto/ECC/ECCX25519Private.cpp b/Source/Crypto/ECC/ECCX25519Private.cpp index 9bfcd3ff..b4e79c36 100644 --- a/Source/Crypto/ECC/ECCX25519Private.cpp +++ b/Source/Crypto/ECC/ECCX25519Private.cpp @@ -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) diff --git a/Source/Crypto/ECC/ECCX25519Public.cpp b/Source/Crypto/ECC/ECCX25519Public.cpp index 41679ca9..0d76a410 100644 --- a/Source/Crypto/ECC/ECCX25519Public.cpp +++ b/Source/Crypto/ECC/ECCX25519Public.cpp @@ -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) diff --git a/Source/Crypto/RSA/RSA.hpp b/Source/Crypto/RSA/RSA.hpp index a7b7289d..e1191b1f 100644 --- a/Source/Crypto/RSA/RSA.hpp +++ b/Source/Crypto/RSA/RSA.hpp @@ -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; } diff --git a/Source/Crypto/RSA/RSAPrivate.cpp b/Source/Crypto/RSA/RSAPrivate.cpp index 7b1b4dcf..79b7e74f 100644 --- a/Source/Crypto/RSA/RSAPrivate.cpp +++ b/Source/Crypto/RSA/RSAPrivate.cpp @@ -157,21 +157,16 @@ namespace Aurora::Crypto::RSA AuSPtr 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) \ - { \ - return {}; \ + #define COPY_KEY_PART(x) \ + 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(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); diff --git a/Source/Crypto/X509/GenerateCertificate.cpp b/Source/Crypto/X509/GenerateCertificate.cpp new file mode 100644 index 00000000..b2de6cec --- /dev/null +++ b/Source/Crypto/X509/GenerateCertificate.cpp @@ -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 +#include "../Crypto.hpp" +#include "x509.hpp" +#include +#include +#include +#include + +namespace Aurora::Crypto::X509 +{ + AUKN_SYM AuResult 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(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(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 {}; + } +} \ No newline at end of file diff --git a/Source/Crypto/X509/GenerateCertificate.hpp b/Source/Crypto/X509/GenerateCertificate.hpp new file mode 100644 index 00000000..14bd3877 --- /dev/null +++ b/Source/Crypto/X509/GenerateCertificate.hpp @@ -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 +{ + +} \ No newline at end of file diff --git a/Source/Crypto/X509/x509.cpp b/Source/Crypto/X509/x509.cpp index 70965076..f14639da 100644 --- a/Source/Crypto/X509/x509.cpp +++ b/Source/Crypto/X509/x509.cpp @@ -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; } diff --git a/Source/Extensions/LTC/LTCExport.c b/Source/Extensions/LTC/LTCExport.c index 59c3f2f8..615867af 100644 --- a/Source/Extensions/LTC/LTCExport.c +++ b/Source/Extensions/LTC/LTCExport.c @@ -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, diff --git a/Source/IO/FS/FS.NT.cpp b/Source/IO/FS/FS.NT.cpp index 5d33f352..c93071cb 100644 --- a/Source/IO/FS/FS.NT.cpp +++ b/Source/IO/FS/FS.NT.cpp @@ -213,7 +213,7 @@ namespace Aurora::IO::FS goto out; } - if (written != blockSize) + if (!written) { SysPushErrorIO(); goto out; diff --git a/Source/IO/TLS/TLSCipherSuites.cpp b/Source/IO/TLS/TLSCipherSuites.cpp index 42c437e7..c80ae473 100644 --- a/Source/IO/TLS/TLSCipherSuites.cpp +++ b/Source/IO/TLS/TLSCipherSuites.cpp @@ -13,6 +13,14 @@ namespace Aurora::IO::TLS AUKN_SYM const AuList &GetDefaultCipherSuites() { static AuList 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, diff --git a/Source/IO/TLS/TLSContext.cpp b/Source/IO/TLS/TLSContext.cpp index 03dbdc2d..3d82be53 100644 --- a/Source/IO/TLS/TLSContext.cpp +++ b/Source/IO/TLS/TLSContext.cpp @@ -17,6 +17,7 @@ namespace Aurora::IO::TLS { mbedtls_entropy_context gEntropy; mbedtls_ctr_drbg_context gCtrDrbg; + static bool gTlsReady {}; AuString TLSErrorToString(int iError) @@ -135,11 +136,6 @@ namespace Aurora::IO::TLS { return true; } - - if (this->bPinLock_) - { - return true; - } auto pCertChain = AuMakeShared(); 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);