[openweave] Expand WeaveCertificateSet API for cert replacement
Add the ability to replace a cert. This is done by splitting out the
load functionality and allowing a caller to overwrite an existing
WeaveCertificateData element.
Bug: b/284072303
Test: Verified dev cert is replaced.
Change-Id: I79992631243ae8bb42dd5a1b412541fc13a1a5fd
(cherry picked from commit 1d23f3d03fa93c7933767aad705624308c5424dc)
diff --git a/src/lib/profiles/security/WeaveCert.cpp b/src/lib/profiles/security/WeaveCert.cpp
index 26f84be..39d85e5 100644
--- a/src/lib/profiles/security/WeaveCert.cpp
+++ b/src/lib/profiles/security/WeaveCert.cpp
@@ -163,22 +163,37 @@
WEAVE_ERROR WeaveCertificateSet::LoadCert(TLVReader& reader, uint16_t decodeFlags, WeaveCertificateData *& cert)
{
WEAVE_ERROR err;
- ASN1Writer writer;
- uint8_t *decodeBuf = mDecodeBuf;
cert = NULL;
- // Must be positioned on the structure element representing the certificate.
- VerifyOrExit(reader.GetType() == kTLVType_Structure, err = WEAVE_ERROR_INVALID_ARGUMENT);
-
// Verify we have room for the new certificate.
VerifyOrExit(CertCount < MaxCerts, err = WEAVE_ERROR_NO_MEMORY);
+ cert = &Certs[CertCount];
+
+ err = LoadCertToElement(reader, decodeFlags, cert);
+ SuccessOrExit(err);
+
+ CertCount++;
+
+exit:
+ return err;
+}
+
+WEAVE_ERROR WeaveCertificateSet::LoadCertToElement(TLVReader& reader, uint16_t decodeFlags, WeaveCertificateData * cert)
+{
+ WEAVE_ERROR err;
+ ASN1Writer writer;
+ uint8_t *decodeBuf = mDecodeBuf;
+
+ // Must be positioned on the structure element representing the certificate.
+ VerifyOrExit(reader.GetType() == kTLVType_Structure, err = WEAVE_ERROR_INVALID_ARGUMENT);
+
if (decodeBuf == NULL && mAllocFunct != NULL)
decodeBuf = (uint8_t *)(mAllocFunct(mDecodeBufSize));
VerifyOrExit(decodeBuf != NULL, err = WEAVE_ERROR_NO_MEMORY);
- cert = &Certs[CertCount];
+ VerifyOrExit(cert != NULL, err = WEAVE_ERROR_INVALID_ARGUMENT);
memset(cert, 0, sizeof(*cert));
// Record the starting point of the certificate's elements.
@@ -272,8 +287,6 @@
// Record the overall size of the certificate.
cert->EncodedCertLen = reader.GetReadPoint() - cert->EncodedCert;
- CertCount++;
-
// If requested by the caller, mark the certificate as trusted.
if (decodeFlags & kDecodeFlag_IsTrusted)
{
@@ -287,6 +300,28 @@
exit:
if (decodeBuf != NULL && decodeBuf != mDecodeBuf && mFreeFunct != NULL)
mFreeFunct(decodeBuf);
+
+ return err;
+}
+
+WEAVE_ERROR WeaveCertificateSet::ReplaceCert(const uint8_t *weaveCert, uint32_t weaveCertLen,
+ uint16_t decodeFlags, WeaveCertificateData *& oldCert)
+{
+ WEAVE_ERROR err = WEAVE_ERROR_CERT_NOT_FOUND;
+ VerifyOrExit(oldCert != NULL, err = WEAVE_ERROR_INVALID_ARGUMENT);
+
+ TLVReader reader;
+
+ reader.Init(weaveCert, weaveCertLen);
+ reader.ImplicitProfileId = kWeaveProfile_Security;
+
+ err = reader.Next(kTLVType_Structure,
+ ProfileTag(kWeaveProfile_Security, kTag_WeaveCertificate));
+ SuccessOrExit(err);
+
+ err = LoadCertToElement(reader, decodeFlags, oldCert);
+
+exit:
return err;
}
diff --git a/src/lib/profiles/security/WeaveCert.h b/src/lib/profiles/security/WeaveCert.h
index 862b2fe..13de382 100644
--- a/src/lib/profiles/security/WeaveCert.h
+++ b/src/lib/profiles/security/WeaveCert.h
@@ -248,6 +248,16 @@
WeaveCertificateData *FindCert(const CertificateKeyId& subjectKeyId) const;
WeaveCertificateData *LastCert(void) const { return (CertCount > 0) ? &Certs[CertCount-1] : NULL; }
+ // Load a weave-encoded cert from a TLVReader to a WeaveCertificateData pointer.
+ WEAVE_ERROR LoadCertToElement(TLVReader& reader, uint16_t decodeFlags, WeaveCertificateData * cert);
+
+ // Replace a certificate in the set.
+ // This takes a pointer to the old cert to be replaced, which can be
+ // obtained by FindCert. The new cert is loaded to the pointer reference.
+ // The args are parallel with the LoadCert API.
+ WEAVE_ERROR ReplaceCert(const uint8_t *weaveCert, uint32_t weaveCertLen, uint16_t decodeFlags,
+ WeaveCertificateData *& oldCert);
+
WEAVE_ERROR ValidateCert(WeaveCertificateData& cert, ValidationContext& context);
WEAVE_ERROR FindValidCert(const WeaveDN& subjectDN, const CertificateKeyId& subjectKeyId,
ValidationContext& context, WeaveCertificateData *& cert);