/*** 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 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 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 pin) : AuMemoryViewRead(in), pin(pin) { } AuSPtr pin; }; return AuMakeSharedThrow(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 &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 &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 ChainFromOne(const AuMemoryViewRead &read) { auto pCertificateChain = AuMakeShared(); if (!pCertificateChain) { SysPushErrorMemory(); return {}; } if (!pCertificateChain->Init(read)) { return {}; } return pCertificateChain; } AUKN_SYM AuSPtr ChainFromMany(const AuList &read) { auto pCertificateChain = AuMakeShared(); if (!pCertificateChain) { SysPushErrorMemory(); return {}; } if (!pCertificateChain->Init(read)) { return {}; } return pCertificateChain; } }