Skip to content

Commit 2924481

Browse files
ksperling-applepull[bot]
authored andcommitted
Move VerifySignature out of ChipCertificateSet as VerifyCertSignature() (#30012)
It just operates on ChipCertificateData structs directly and is useful outside of ChipCertificateSet. Also move the check for kTBSHashPresent and the signature algorithm into the function.
1 parent b209abc commit 2924481

File tree

3 files changed

+34
-21
lines changed

3 files changed

+34
-21
lines changed

src/credentials/CHIPCert.cpp

+18-13
Original file line numberDiff line numberDiff line change
@@ -284,20 +284,29 @@ CHIP_ERROR ChipCertificateSet::FindValidCert(const ChipDN & subjectDN, const Cer
284284

285285
CHIP_ERROR ChipCertificateSet::VerifySignature(const ChipCertificateData * cert, const ChipCertificateData * caCert)
286286
{
287+
VerifyOrReturnError((cert != nullptr) && (caCert != nullptr), CHIP_ERROR_INVALID_ARGUMENT);
288+
return VerifyCertSignature(*cert, *caCert);
289+
}
290+
291+
CHIP_ERROR VerifyCertSignature(const ChipCertificateData & cert, const ChipCertificateData & signer)
292+
{
293+
VerifyOrReturnError(cert.mCertFlags.Has(CertFlags::kTBSHashPresent), CHIP_ERROR_INVALID_ARGUMENT);
294+
VerifyOrReturnError(cert.mSigAlgoOID == kOID_SigAlgo_ECDSAWithSHA256, CHIP_ERROR_UNSUPPORTED_SIGNATURE_TYPE);
295+
287296
#ifdef ENABLE_HSM_ECDSA_VERIFY
288-
P256PublicKeyHSM caPublicKey;
297+
P256PublicKeyHSM signerPublicKey;
289298
#else
290-
P256PublicKey caPublicKey;
299+
P256PublicKey signerPublicKey;
291300
#endif
292301
P256ECDSASignature signature;
293302

294-
VerifyOrReturnError((cert != nullptr) && (caCert != nullptr), CHIP_ERROR_INVALID_ARGUMENT);
295-
ReturnErrorOnFailure(signature.SetLength(cert->mSignature.size()));
296-
memcpy(signature.Bytes(), cert->mSignature.data(), cert->mSignature.size());
303+
ReturnErrorOnFailure(signature.SetLength(cert.mSignature.size()));
304+
memcpy(signature.Bytes(), cert.mSignature.data(), cert.mSignature.size());
297305

298-
memcpy(caPublicKey, caCert->mPublicKey.data(), caCert->mPublicKey.size());
306+
memcpy(signerPublicKey, signer.mPublicKey.data(), signer.mPublicKey.size());
299307

300-
ReturnErrorOnFailure(caPublicKey.ECDSA_validate_hash_signature(cert->mTBSHash, chip::Crypto::kSHA256_Hash_Length, signature));
308+
ReturnErrorOnFailure(
309+
signerPublicKey.ECDSA_validate_hash_signature(cert.mTBSHash, chip::Crypto::kSHA256_Hash_Length, signature));
301310

302311
return CHIP_NO_ERROR;
303312
}
@@ -454,10 +463,6 @@ CHIP_ERROR ChipCertificateSet::ValidateCert(const ChipCertificateData * cert, Va
454463
// recursion in such a case.
455464
VerifyOrExit(depth < mCertCount, err = CHIP_ERROR_CERT_PATH_TOO_LONG);
456465

457-
// Verify that a hash of the 'to-be-signed' portion of the certificate has been computed. We will need this to
458-
// verify the cert's signature below.
459-
VerifyOrExit(cert->mCertFlags.Has(CertFlags::kTBSHashPresent), err = CHIP_ERROR_INVALID_ARGUMENT);
460-
461466
// Search for a valid CA certificate that matches the Issuer DN and Authority Key Id of the current certificate.
462467
// Fail if no acceptable certificate is found.
463468
err = FindValidCert(cert->mIssuerDN, cert->mAuthKeyId, context, static_cast<uint8_t>(depth + 1), &caCert);
@@ -468,7 +473,7 @@ CHIP_ERROR ChipCertificateSet::ValidateCert(const ChipCertificateData * cert, Va
468473

469474
// Verify signature of the current certificate against public key of the CA certificate. If signature verification
470475
// succeeds, the current certificate is valid.
471-
err = VerifySignature(cert, caCert);
476+
err = VerifyCertSignature(*cert, *caCert);
472477
SuccessOrExit(err);
473478

474479
exit:
@@ -1166,7 +1171,7 @@ CHIP_ERROR ValidateChipRCAC(const ByteSpan & rcac)
11661171

11671172
VerifyOrReturnError(certData.mKeyUsageFlags.Has(KeyUsageFlags::kKeyCertSign), CHIP_ERROR_CERT_USAGE_NOT_ALLOWED);
11681173

1169-
return ChipCertificateSet::VerifySignature(&certData, &certData);
1174+
return VerifyCertSignature(certData, certData);
11701175
}
11711176

11721177
CHIP_ERROR ConvertIntegerDERToRaw(ByteSpan derInt, uint8_t * rawInt, const uint16_t rawIntLen)

src/credentials/CHIPCert.h

+15
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,21 @@ CHIP_ERROR ConvertX509CertToChipCert(const ByteSpan x509Cert, MutableByteSpan &
504504
**/
505505
CHIP_ERROR ConvertChipCertToX509Cert(const ByteSpan chipCert, MutableByteSpan & x509Cert);
506506

507+
/**
508+
* @brief Verifies the signature of a certificate.
509+
*
510+
* @param cert The certificate to be verified.
511+
* @param signer The certificate containing the public key used to verify the signature.
512+
*
513+
* @return Returns a CHIP_ERROR on validation or other error, CHIP_NO_ERROR otherwise
514+
*
515+
* The certificate to be verified must have been decoded with TBS hash calculation enabled.
516+
*
517+
* Note that this function performs ONLY signature verification. No Subject and Issuer DN
518+
* comparison, Key Usage extension checks or similar validation is performed.
519+
**/
520+
CHIP_ERROR VerifyCertSignature(const ChipCertificateData & cert, const ChipCertificateData & signer);
521+
507522
/**
508523
* Validate CHIP Root CA Certificate (RCAC) in ByteSpan TLV-encoded form.
509524
* This function performs RCAC parsing, checks SubjectDN validity, verifies that SubjectDN

src/credentials/CHIPCertificateSet.h

+1-8
Original file line numberDiff line numberDiff line change
@@ -246,14 +246,7 @@ class DLL_EXPORT ChipCertificateSet
246246
CHIP_ERROR FindValidCert(const ChipDN & subjectDN, const CertificateKeyId & subjectKeyId, ValidationContext & context,
247247
const ChipCertificateData ** certData);
248248

249-
/**
250-
* @brief Verify CHIP certificate signature.
251-
*
252-
* @param cert Pointer to the CHIP certificate which signature should be validated.
253-
* @param caCert Pointer to the CA certificate of the verified certificate.
254-
*
255-
* @return Returns a CHIP_ERROR on validation or other error, CHIP_NO_ERROR otherwise
256-
**/
249+
// Deprecated, use the equivalent free function VerifyCertSignature()
257250
static CHIP_ERROR VerifySignature(const ChipCertificateData * cert, const ChipCertificateData * caCert);
258251

259252
private:

0 commit comments

Comments
 (0)