[+] ICertificateStore::RemoveCertificate
[+] ICertificateStore::RemoveCertificatesFromChain [+] ICertificateStore::Size
This commit is contained in:
parent
e63903d0f4
commit
5abfb0eee0
@ -16,10 +16,15 @@ namespace Aurora::Crypto::CA
|
|||||||
{
|
{
|
||||||
struct ICertificateStore : IPinCertificate
|
struct ICertificateStore : IPinCertificate
|
||||||
{
|
{
|
||||||
|
virtual void Serialize(Memory::ByteBuffer &buffer) = 0;
|
||||||
|
virtual bool Deserialize(Memory::ByteBuffer &buffer) = 0;
|
||||||
|
|
||||||
virtual bool AddCertificate(const AuMemoryViewRead &x509Certificate) = 0;
|
virtual bool AddCertificate(const AuMemoryViewRead &x509Certificate) = 0;
|
||||||
virtual bool AddCertificateChain(X509::ICertificateChain *pChain) = 0;
|
virtual bool AddCertificateChain(X509::ICertificateChain *pChain) = 0;
|
||||||
|
|
||||||
virtual void Serialize(Memory::ByteBuffer &buffer) = 0;
|
virtual bool RemoveCertificate(const AuMemoryViewRead &x509Certificate) = 0;
|
||||||
virtual bool Deserialize(Memory::ByteBuffer &buffer) = 0;
|
virtual AuUInt32 RemoveCertificatesFromChain(X509::ICertificateChain *pChain) = 0;
|
||||||
|
|
||||||
|
virtual AuUInt32 Size() = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -18,9 +18,37 @@ namespace Aurora::Crypto::X509
|
|||||||
|
|
||||||
namespace Aurora::Crypto::CA
|
namespace Aurora::Crypto::CA
|
||||||
{
|
{
|
||||||
|
// ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
|
||||||
// Digicerts "high assurance" and other special roots trusted by payment insitutions use 2048... FUCKING WHY?
|
// Digicerts "high assurance" and other special roots trusted by payment insitutions use 2048... FUCKING WHY?
|
||||||
// These certs should be expiring in early 2030. Hopefully PayPal, Stripe, and others will get their act
|
// These certs should be expiring in early 2030. Hopefully PayPal, Stripe, and others will get their act
|
||||||
// together soon. Oh, and guess what, Amazon and tons of AWS customers use Amazon Root CA 1 with a 2048-bit PK as well.
|
// together soon. Oh, and guess what, Amazon and tons of AWS customers use Amazon Root CA 1 with a 2048-bit PK as well.
|
||||||
|
// ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
|
||||||
|
//
|
||||||
|
// ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
|
||||||
|
// Please also note that this profile is only used to verify certificate *chains*
|
||||||
|
//
|
||||||
|
// When chain[0].publicKey is trusted by your client, and you've performed a key exchanged based upon that keypair, we don't care.
|
||||||
|
// Certificate parameter validation is your issue - the clients' implementation side with your expected profile parameters and state container
|
||||||
|
// of the peers connection and hostname,common-name pair. Such validation is not an issue for this relatively stateless * certificate store *.
|
||||||
|
//
|
||||||
|
// However, when *we* recurse a *chain*, we need to verify that the previous certificate the signator to the next, at this point it is our
|
||||||
|
// responsibility to ensure some unsound certificates weren't injected into the middle of the chain to violate the "is trusted by a known root
|
||||||
|
// via a series of unknown middle-man certificates" test. Noting we dont care for testing CN and SANs; we only care about testing the PK infra
|
||||||
|
// which just to happens to include a signature test of the serialized ASN.1 properties from the anonymous root down to the chain[0] common name.
|
||||||
|
// These certificate chains, we have to assume they're arbitrary remote user data, and therefore could be severely malformed or manipulated.
|
||||||
|
// Any provided TLS stack will verify the chain[0] common name and profile parameters of the peer, however as the root-store validator, we need
|
||||||
|
// to vertify cert[1...n] eventually references a good known anon root authority without a breakage the chains of signatures.
|
||||||
|
//
|
||||||
|
// PS: Emphasis on anonymous. I've seen some certificate roots, *ahem google*, change their x509 container without changing their key.
|
||||||
|
// If we're hard-coding a series of CAs to trust, or even storing long term keychains, we're saying "we trust the owner of this key" to not
|
||||||
|
// be a dipshit, therefore we shouldn't need to worry about every minute detail of the CA - we only care about: 1) the binary public key,
|
||||||
|
// and 2) expiration time. It is therefore the case we only serialized these two properties. Do we really care that somebody we trust changed
|
||||||
|
// their their expiration time by an hour after reserializing their root cert? No, not really. Do we care that they added some SANs? Again,
|
||||||
|
// no. What about extended key uses? What are those? The extension RFC specifies use cases we couldn't care less about.
|
||||||
|
// Any certificate revocation or further tests must come from another validator, perhaps connected to us via a "PinCheckTwoAnd" object.
|
||||||
|
//
|
||||||
|
// kAssumeRootIsSmart is used to satisfy this relationship test.
|
||||||
|
// ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
|
||||||
static const mbedtls_x509_crt_profile kAssumeRootIsSmart =
|
static const mbedtls_x509_crt_profile kAssumeRootIsSmart =
|
||||||
{
|
{
|
||||||
MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA1) | // TODO(by 2030): delete me
|
MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA1) | // TODO(by 2030): delete me
|
||||||
@ -42,17 +70,37 @@ namespace Aurora::Crypto::CA
|
|||||||
2048, // TODO(by 2030): Raise to 4k
|
2048, // TODO(by 2030): Raise to 4k
|
||||||
};
|
};
|
||||||
|
|
||||||
bool CertificateStore::CheckCertificate(const AuSPtr<X509::ICertificateChain> &pChain,
|
bool CertificateStore::CheckCertificate(const AuSPtr<X509::ICertificateChain> &pChain2,
|
||||||
const AuMemoryViewRead &derCertificate)
|
const AuMemoryViewRead &derCertificate)
|
||||||
{
|
{
|
||||||
AU_LOCK_GUARD(this->rwLock->AsReadable());
|
AuUPtr<X509::ICertificateChain> pTempChain;
|
||||||
|
X509::ICertificateChain *pChain;
|
||||||
bool bFoundTrustedCA {};
|
bool bFoundTrustedCA {};
|
||||||
|
|
||||||
if (!pChain)
|
AU_LOCK_GUARD(this->rwLock->AsReadable());
|
||||||
|
|
||||||
|
if (!pChain2)
|
||||||
|
{
|
||||||
|
if (derCertificate)
|
||||||
|
{
|
||||||
|
pTempChain = X509::NewChainFromOneDerGenericUnique(derCertificate);
|
||||||
|
if (!pTempChain)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pChain = pTempChain.get();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pChain = pChain2.get();
|
||||||
|
}
|
||||||
|
|
||||||
auto uCount = pChain->GetCertificateCount();
|
auto uCount = pChain->GetCertificateCount();
|
||||||
for (AU_ITERATE_N(i, uCount))
|
for (AU_ITERATE_N(i, uCount))
|
||||||
{
|
{
|
||||||
@ -199,8 +247,104 @@ namespace Aurora::Crypto::CA
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CertificateStore::RemoveCertificate(const AuMemoryViewRead &x509Certificate)
|
||||||
|
{
|
||||||
|
bool bRet {};
|
||||||
|
mbedtls_x509_crt crt;
|
||||||
|
|
||||||
|
if (!x509Certificate)
|
||||||
|
{
|
||||||
|
SysPushErrorArg();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mbedtls_x509_crt_init(&crt);
|
||||||
|
|
||||||
|
if (mbedtls_x509_crt_parse(&crt,
|
||||||
|
x509Certificate.Begin<unsigned char>(),
|
||||||
|
x509Certificate.Size()) < 0)
|
||||||
|
{
|
||||||
|
SysPushErrorGeneric();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
AuUInt32 uCode { AuFnv1a32Runtime(crt.pk_raw.p, crt.pk_raw.len) };
|
||||||
|
|
||||||
|
{
|
||||||
|
AU_LOCK_GUARD(this->rwLock->AsWritable());
|
||||||
|
|
||||||
|
auto itr = this->storage.find(uCode);
|
||||||
|
if (itr != this->storage.end())
|
||||||
|
{
|
||||||
|
if (AuTryRemoveByTupleN<0>(itr->second, AuMemoryViewRead { crt.pk_raw.p, crt.pk_raw.len }))
|
||||||
|
{
|
||||||
|
bRet = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mbedtls_x509_crt_free(&crt);
|
||||||
|
return bRet;
|
||||||
|
}
|
||||||
|
|
||||||
|
AuUInt32 CertificateStore::RemoveCertificatesFromChain(X509::ICertificateChain *pChain)
|
||||||
|
{
|
||||||
|
AuUInt32 uRet {};
|
||||||
|
|
||||||
|
if (!pChain)
|
||||||
|
{
|
||||||
|
SysPushErrorArg();
|
||||||
|
return uRet;
|
||||||
|
}
|
||||||
|
|
||||||
|
AU_LOCK_GUARD(this->rwLock->AsWritable());
|
||||||
|
|
||||||
|
auto uCount = pChain->GetCertificateCount();
|
||||||
|
for (AU_ITERATE_N(i, uCount))
|
||||||
|
{
|
||||||
|
auto pCert = AuStaticCast<AuCrypto::X509::CertificateChain>(pChain)->GetCertificateInternal(i);
|
||||||
|
if (!pCert)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
AuUInt32 uCode { AuFnv1a32Runtime(pCert->pk_raw.p, pCert->pk_raw.len) };
|
||||||
|
|
||||||
|
auto itr = this->storage.find(uCode);
|
||||||
|
if (itr == this->storage.end())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!AuTryRemoveByTupleN<0>(itr->second, AuMemoryViewRead { pCert->pk_raw.p, pCert->pk_raw.len }))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
uRet++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return uRet;
|
||||||
|
}
|
||||||
|
|
||||||
|
AuUInt32 CertificateStore::Size()
|
||||||
|
{
|
||||||
|
AuUInt32 uRet {};
|
||||||
|
|
||||||
|
AU_LOCK_GUARD(this->rwLock->AsReadable());
|
||||||
|
|
||||||
|
for (auto &[uID, storageList] : this->storage)
|
||||||
|
{
|
||||||
|
uRet += storageList.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
return uRet;
|
||||||
|
}
|
||||||
|
|
||||||
void CertificateStore::Serialize(Memory::ByteBuffer &buffer)
|
void CertificateStore::Serialize(Memory::ByteBuffer &buffer)
|
||||||
{
|
{
|
||||||
|
AU_LOCK_GUARD(this->rwLock->AsReadable());
|
||||||
|
|
||||||
for (auto &[uID, storageList] : this->storage)
|
for (auto &[uID, storageList] : this->storage)
|
||||||
{
|
{
|
||||||
for (auto &[cert, uValidTo] : storageList)
|
for (auto &[cert, uValidTo] : storageList)
|
||||||
|
@ -17,6 +17,10 @@ namespace Aurora::Crypto::CA
|
|||||||
bool AddCertificate(const AuMemoryViewRead &x509Certificate) override;
|
bool AddCertificate(const AuMemoryViewRead &x509Certificate) override;
|
||||||
bool AddCertificateChain(X509::ICertificateChain *pChain) override;
|
bool AddCertificateChain(X509::ICertificateChain *pChain) override;
|
||||||
|
|
||||||
|
bool RemoveCertificate(const AuMemoryViewRead &x509Certificate) override;
|
||||||
|
AuUInt32 RemoveCertificatesFromChain(X509::ICertificateChain *pChain) override;
|
||||||
|
|
||||||
|
AuUInt32 Size() override;
|
||||||
|
|
||||||
void Serialize(Memory::ByteBuffer &buffer) override;
|
void Serialize(Memory::ByteBuffer &buffer) override;
|
||||||
bool Deserialize(Memory::ByteBuffer &buffer) override;
|
bool Deserialize(Memory::ByteBuffer &buffer) override;
|
||||||
|
Loading…
Reference in New Issue
Block a user