Matter SDK Coverage Report
Current view: top level - credentials/attestation_verifier - DacOnlyPartialAttestationVerifier.cpp (source / functions) Coverage Total Hit
Test: SHA:209dc18e4021e7d0dff8120ccc585909391dd862 Lines: 95.9 % 49 47
Test Date: 2026-06-16 07:34:53 Functions: 100.0 % 1 1

            Line data    Source code
       1              : /*
       2              :  *
       3              :  *    Copyright (c) 2021-2022 Project CHIP Authors
       4              :  *
       5              :  *    Licensed under the Apache License, Version 2.0 (the "License");
       6              :  *    you may not use this file except in compliance with the License.
       7              :  *    You may obtain a copy of the License at
       8              :  *
       9              :  *        http://www.apache.org/licenses/LICENSE-2.0
      10              :  *
      11              :  *    Unless required by applicable law or agreed to in writing, software
      12              :  *    distributed under the License is distributed on an "AS IS" BASIS,
      13              :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      14              :  *    See the License for the specific language governing permissions and
      15              :  *    limitations under the License.
      16              :  */
      17              : #include "DacOnlyPartialAttestationVerifier.h"
      18              : 
      19              : #include <controller/OperationalCredentialsDelegate.h>
      20              : #include <credentials/CHIPCert.h>
      21              : #include <credentials/CertificationDeclaration.h>
      22              : #include <credentials/DeviceAttestationConstructor.h>
      23              : #include <credentials/DeviceAttestationVendorReserved.h>
      24              : #include <crypto/CHIPCryptoPAL.h>
      25              : 
      26              : #include <lib/core/CHIPError.h>
      27              : #include <lib/support/CodeUtils.h>
      28              : #include <lib/support/ScopedMemoryBuffer.h>
      29              : #include <lib/support/Span.h>
      30              : 
      31              : using namespace chip::Crypto;
      32              : 
      33              : namespace chip {
      34              : namespace Credentials {
      35              : 
      36              : // As per specifications section 11.22.5.1. Constant RESP_MAX
      37              : constexpr size_t kMaxResponseLength = 900;
      38              : 
      39              : /**
      40              :  * The implementation should track DefaultDACVerifier::VerifyAttestationInformation but with the checks
      41              :  * disabled that are outlined at the top of DacOnlyPartialAttestationVerifier.h.
      42              :  */
      43           15 : void PartialDACVerifier::VerifyAttestationInformation(const DeviceAttestationVerifier::AttestationInfo & info,
      44              :                                                       Callback::Callback<OnAttestationInformationVerification> * onCompletion)
      45              : {
      46              :     // The exit handler below dereferences onCompletion unconditionally; reject null here.
      47           15 :     VerifyOrReturn(onCompletion != nullptr);
      48              : 
      49           14 :     AttestationVerificationResult attestationError = AttestationVerificationResult::kSuccess;
      50              : 
      51           14 :     AttestationCertVidPid dacVidPid;
      52           14 :     AttestationCertVidPid paiVidPid;
      53           14 :     AttestationCertVidPid paaVidPid;
      54              : 
      55           14 :     DeviceInfoForAttestation deviceInfo{
      56           14 :         .vendorId  = info.vendorId,
      57           14 :         .productId = info.productId,
      58           14 :     };
      59              : 
      60           14 :     VerifyOrExit(!info.attestationElementsBuffer.empty() && !info.attestationChallengeBuffer.empty() &&
      61              :                      !info.attestationSignatureBuffer.empty() && !info.paiDerBuffer.empty() && !info.dacDerBuffer.empty() &&
      62              :                      !info.attestationNonceBuffer.empty(),
      63              :                  attestationError = AttestationVerificationResult::kInvalidArgument);
      64              : 
      65           13 :     VerifyOrExit(info.attestationElementsBuffer.size() <= kMaxResponseLength,
      66              :                  attestationError = AttestationVerificationResult::kInvalidArgument);
      67              : 
      68              :     // match DAC and PAI VIDs
      69              :     {
      70           24 :         VerifyOrExit(ExtractVIDPIDFromX509Cert(info.dacDerBuffer, dacVidPid) == CHIP_NO_ERROR,
      71              :                      attestationError = AttestationVerificationResult::kDacFormatInvalid);
      72           20 :         VerifyOrExit(ExtractVIDPIDFromX509Cert(info.paiDerBuffer, paiVidPid) == CHIP_NO_ERROR,
      73              :                      attestationError = AttestationVerificationResult::kPaiFormatInvalid);
      74            9 :         VerifyOrExit(paiVidPid.mVendorId.HasValue() && paiVidPid.mVendorId == dacVidPid.mVendorId,
      75              :                      attestationError = AttestationVerificationResult::kDacVendorIdMismatch);
      76            8 :         VerifyOrExit(dacVidPid.mProductId.HasValue(), attestationError = AttestationVerificationResult::kDacProductIdMismatch);
      77            8 :         if (paiVidPid.mProductId.HasValue())
      78              :         {
      79            8 :             VerifyOrExit(paiVidPid.mProductId == dacVidPid.mProductId,
      80              :                          attestationError = AttestationVerificationResult::kDacProductIdMismatch);
      81              :         }
      82              :     }
      83              : 
      84              :     {
      85            7 :         P256PublicKey remoteManufacturerPubkey;
      86            7 :         P256ECDSASignature deviceSignature;
      87              : 
      88           14 :         VerifyOrExit(ExtractPubkeyFromX509Cert(info.dacDerBuffer, remoteManufacturerPubkey) == CHIP_NO_ERROR,
      89              :                      attestationError = AttestationVerificationResult::kDacFormatInvalid);
      90              : 
      91              :         // Validate overall attestation signature on attestation information
      92              :         // SetLength will fail if signature doesn't fit
      93           14 :         VerifyOrExit(deviceSignature.SetLength(info.attestationSignatureBuffer.size()) == CHIP_NO_ERROR,
      94              :                      attestationError = AttestationVerificationResult::kAttestationSignatureInvalidFormat);
      95            6 :         memcpy(deviceSignature.Bytes(), info.attestationSignatureBuffer.data(), info.attestationSignatureBuffer.size());
      96           12 :         VerifyOrExit(ValidateAttestationSignature(remoteManufacturerPubkey, info.attestationElementsBuffer,
      97              :                                                   info.attestationChallengeBuffer, deviceSignature) == CHIP_NO_ERROR,
      98              :                      attestationError = AttestationVerificationResult::kAttestationSignatureInvalid);
      99            9 :     }
     100              : 
     101              :     {
     102            5 :         MutableByteSpan akid(deviceInfo.paaSKID);
     103              : 
     104           10 :         VerifyOrExit(ExtractAKIDFromX509Cert(info.paiDerBuffer, akid) == CHIP_NO_ERROR,
     105              :                      attestationError = AttestationVerificationResult::kPaiFormatInvalid);
     106              : 
     107            5 :         ChipLogProgress(Support, "PartialDACVerifier::CheckPAA skipping vid-scoped PAA check - PAARootStore disabled");
     108              :     }
     109              : 
     110              : #if !defined(CURRENT_TIME_NOT_IMPLEMENTED)
     111           10 :     VerifyOrExit(IsCertificateValidAtCurrentTime(info.dacDerBuffer) == CHIP_NO_ERROR,
     112              :                  attestationError = AttestationVerificationResult::kDacExpired);
     113              : #endif
     114              : 
     115            3 :     ChipLogProgress(Support, "PartialDACVerifier::CheckCertChain skipping cert chain check - PAARootStore disabled");
     116              : 
     117              :     {
     118            3 :         ByteSpan certificationDeclarationSpan;
     119            3 :         ByteSpan attestationNonceSpan;
     120              :         uint32_t timestampDeconstructed;
     121            3 :         ByteSpan firmwareInfoSpan;
     122            3 :         DeviceAttestationVendorReservedDeconstructor vendorReserved;
     123            3 :         ByteSpan certificationDeclarationPayload;
     124              : 
     125            3 :         deviceInfo.dacVendorId  = dacVidPid.mVendorId.Value();
     126            3 :         deviceInfo.dacProductId = dacVidPid.mProductId.Value();
     127            3 :         deviceInfo.paiVendorId  = paiVidPid.mVendorId.Value();
     128            3 :         deviceInfo.paiProductId = paiVidPid.mProductId.ValueOr(0);
     129            3 :         deviceInfo.paaVendorId  = paaVidPid.mVendorId.ValueOr(VendorId::NotSpecified);
     130              : 
     131            3 :         ChipLogProgress(
     132              :             Support,
     133              :             "PartialDACVerifier::VerifyAttestationInformation skipping PAA subject key id extraction - PAARootStore disabled");
     134              : 
     135            8 :         VerifyOrExit(DeconstructAttestationElements(info.attestationElementsBuffer, certificationDeclarationSpan,
     136              :                                                     attestationNonceSpan, timestampDeconstructed, firmwareInfoSpan,
     137              :                                                     vendorReserved) == CHIP_NO_ERROR,
     138              :                      attestationError = AttestationVerificationResult::kAttestationElementsMalformed);
     139              : 
     140              :         // Verify that Nonce matches with what we sent
     141            2 :         VerifyOrExit(attestationNonceSpan.data_equal(info.attestationNonceBuffer),
     142              :                      attestationError = AttestationVerificationResult::kAttestationNonceMismatch);
     143              : 
     144            1 :         ChipLogProgress(Support,
     145              :                         "PartialDACVerifier::VerifyAttestationInformation skipping CD signature check - LocalCSAStore disabled");
     146            2 :         VerifyOrExit(CMS_ExtractCDContent(certificationDeclarationSpan, certificationDeclarationPayload) == CHIP_NO_ERROR,
     147              :                      attestationError = AttestationVerificationResult::kPaaFormatInvalid);
     148              : 
     149            0 :         attestationError = ValidateCertificateDeclarationPayload(certificationDeclarationPayload, firmwareInfoSpan, deviceInfo);
     150            0 :         VerifyOrExit(attestationError == AttestationVerificationResult::kSuccess, attestationError = attestationError);
     151              :     }
     152              : 
     153           14 : exit:
     154           14 :     onCompletion->mCall(onCompletion->mContext, info, attestationError);
     155              : }
     156              : 
     157              : } // namespace Credentials
     158              : } // namespace chip
        

Generated by: LCOV version 2.0-1