AuroraRuntime/Source/IO/TLS/TLSCertificateChain.cpp
Reece Wilson d9dd1182b9 [+] TLS pinning
[*] ISocket::Shutdown(*bool bNow*), allowing for flush of the send channel when false
[*] Fix StartRead and StartWrite after shutdown (NT)
[*] Amended dead-lock
2022-11-18 04:44:47 +00:00

209 lines
5.1 KiB
C++

/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: TLSCertificateChain.cpp
Date: 2022-8-27
Author: Reece
***/
#include "TLS.hpp"
#include "TLSCertificateChain.hpp"
#include <Source/Crypto/X509/x509.hpp>
namespace Aurora::IO::TLS
{
CertificateChain::CertificateChain()
{
}
CertificateChain::~CertificateChain()
{
::mbedtls_x509_crt_free(&this->ownCertificate);
}
AuUInt32 CertificateChain::GetCertificateCount()
{
AuUInt32 ret {};
auto pCert = this->pCertificate;
if (!pCert)
{
return {};
}
do
{
auto index = ret++;
}
while (pCert = pCert->next);
return ret;
}
AuSPtr<AuMemoryViewRead> CertificateChain::GetCertificate(AuUInt32 idx)
{
AuUInt32 ret {};
auto pCert = this->pCertificate;
if (!pCert)
{
return {};
}
do
{
auto index = ret++;
if (index == idx)
{
struct View : AuMemoryViewRead
{
View(const AuMemoryViewRead &in, AuSPtr<void> pin) :
AuMemoryViewRead(in),
pin(pin)
{ }
AuSPtr<void> pin;
};
return AuMakeSharedThrow<View>(AuMemoryViewRead { pCert->raw.p, pCert->raw.len}, AuSharedFromThis());
}
}
while (pCert = pCert->next);
return {};
}
Crypto::X509::DecodedCertificate CertificateChain::GetCertificateDetails(AuUInt32 idx)
{
AuUInt32 ret {};
auto pCert = this->pCertificate;
if (!pCert)
{
return {};
}
do
{
auto index = ret++;
if (index == idx)
{
Crypto::X509::DecodedCertificate cert;
AuCrypto::X509::DecodeInternal(*pCert, cert);
return cert;
}
}
while (pCert = pCert->next);
return {};
}
bool CertificateChain::Init(const AuList<AuByteBuffer> &certs)
{
int iRet {};
this->pCertificate = &this->ownCertificate;
::mbedtls_x509_crt_init(&this->ownCertificate);
for (const auto &cert : certs)
{
iRet = ::mbedtls_x509_crt_parse(&this->ownCertificate,
(const unsigned char *)cert.base,
cert.length);
if (iRet != 0)
{
this->pCertificate = nullptr;
SysPushErrorCrypto("Failed to parse certificate chain: {}", iRet);
return false;
}
}
return this->Precache();
}
bool CertificateChain::Init(const AuList<AuMemoryViewRead> &certs)
{
int iRet {};
this->pCertificate = &this->ownCertificate;
::mbedtls_x509_crt_init(&this->ownCertificate);
for (const auto &cert : certs)
{
iRet = ::mbedtls_x509_crt_parse(&this->ownCertificate,
(const unsigned char *)cert.ToPointer(),
cert.length);
if (iRet != 0)
{
this->pCertificate = nullptr;
SysPushErrorCrypto("Failed to parse certificate chain: {}", iRet);
return false;
}
}
return this->Precache();
}
bool CertificateChain::Init(const AuMemoryViewRead &cert)
{
int iRet {};
this->pCertificate = &this->ownCertificate;
::mbedtls_x509_crt_init(&this->ownCertificate);
iRet = ::mbedtls_x509_crt_parse(&this->ownCertificate,
(const unsigned char *)cert.ToPointer(),
cert.length);
if (iRet != 0)
{
SysPushErrorCrypto("Failed to parse certificate chain: {}", iRet);
return false;
}
return this->Precache();
}
bool CertificateChain::Init(const mbedtls_x509_crt *pCert)
{
this->pCertificate = (mbedtls_x509_crt *)pCert;
return this->Precache();
}
bool CertificateChain::Precache()
{
return true;
}
AUKN_SYM AuSPtr<ICertificateChain> ChainFromOne(const AuMemoryViewRead &read)
{
auto pCertificateChain = AuMakeShared<CertificateChain>();
if (!pCertificateChain)
{
SysPushErrorMemory();
return {};
}
if (!pCertificateChain->Init(read))
{
return {};
}
return pCertificateChain;
}
AUKN_SYM AuSPtr<ICertificateChain> ChainFromMany(const AuList<AuMemoryViewRead> &read)
{
auto pCertificateChain = AuMakeShared<CertificateChain>();
if (!pCertificateChain)
{
SysPushErrorMemory();
return {};
}
if (!pCertificateChain->Init(read))
{
return {};
}
return pCertificateChain;
}
}