LCOV - code coverage report
Current view: top level - credentials/attestation_verifier - DefaultDeviceAttestationVerifier.cpp (source / functions) Hit Total Coverage
Test: lcov_final.info Lines: 160 180 88.9 %
Date: 2024-02-15 08:20:41 Functions: 12 12 100.0 %

          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 "DefaultDeviceAttestationVerifier.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 <credentials/attestation_verifier/TestPAAStore.h>
      25             : #include <crypto/CHIPCryptoPAL.h>
      26             : 
      27             : #include <lib/core/CHIPError.h>
      28             : #include <lib/core/Global.h>
      29             : #include <lib/support/CodeUtils.h>
      30             : #include <lib/support/ScopedBuffer.h>
      31             : #include <lib/support/Span.h>
      32             : 
      33             : using namespace chip::Crypto;
      34             : using chip::TestCerts::GetTestPaaRootStore;
      35             : 
      36             : namespace chip {
      37             : namespace Credentials {
      38             : 
      39             : namespace {
      40             : 
      41             : // As per specifications section 11.22.5.1. Constant RESP_MAX
      42             : constexpr size_t kMaxResponseLength = 900;
      43             : 
      44             : // Test CD Signing Key from `credentials/test/certification-declaration/Chip-Test-CD-Signing-Cert.pem`
      45             : // used to verify any in-SDK development CDs. The associated keypair to do actual signing is in
      46             : // `credentials/test/certification-declaration/Chip-Test-CD-Signing-Key.pem`.
      47             : //
      48             : // Note that this certificate is a self signed certificate and doesn't chain up to the CSA trusted root.
      49             : // This CD Signing certificate can only be used to sign CDs for testing/development purposes
      50             : // and should never be used in production devices.
      51             : //
      52             : // -----BEGIN CERTIFICATE-----
      53             : // MIIBszCCAVqgAwIBAgIIRdrzneR6oI8wCgYIKoZIzj0EAwIwKzEpMCcGA1UEAwwg
      54             : // TWF0dGVyIFRlc3QgQ0QgU2lnbmluZyBBdXRob3JpdHkwIBcNMjEwNjI4MTQyMzQz
      55             : // WhgPOTk5OTEyMzEyMzU5NTlaMCsxKTAnBgNVBAMMIE1hdHRlciBUZXN0IENEIFNp
      56             : // Z25pbmcgQXV0aG9yaXR5MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEPDmJIkUr
      57             : // VcrzicJb0bykZWlSzLkOiGkkmthHRlMBTL+V1oeWXgNrUhxRA35rjO3vyh60QEZp
      58             : // T6CIgu7WUZ3suqNmMGQwEgYDVR0TAQH/BAgwBgEB/wIBATAOBgNVHQ8BAf8EBAMC
      59             : // AQYwHQYDVR0OBBYEFGL6gjNZrPqplj4c+hQK3fUE83FgMB8GA1UdIwQYMBaAFGL6
      60             : // gjNZrPqplj4c+hQK3fUE83FgMAoGCCqGSM49BAMCA0cAMEQCICxUXOTkV9im8NnZ
      61             : // u+vW7OHd/n+MbZps83UyH8b6xxOEAiBUB3jodDlyUn7t669YaGIgtUB48s1OYqdq
      62             : // 58u5L/VMiw==
      63             : // -----END CERTIFICATE-----
      64             : //
      65             : constexpr uint8_t gTestCdPubkeyBytes[] = {
      66             :     0x04, 0x3c, 0x39, 0x89, 0x22, 0x45, 0x2b, 0x55, 0xca, 0xf3, 0x89, 0xc2, 0x5b, 0xd1, 0xbc, 0xa4, 0x65,
      67             :     0x69, 0x52, 0xcc, 0xb9, 0x0e, 0x88, 0x69, 0x24, 0x9a, 0xd8, 0x47, 0x46, 0x53, 0x01, 0x4c, 0xbf, 0x95,
      68             :     0xd6, 0x87, 0x96, 0x5e, 0x03, 0x6b, 0x52, 0x1c, 0x51, 0x03, 0x7e, 0x6b, 0x8c, 0xed, 0xef, 0xca, 0x1e,
      69             :     0xb4, 0x40, 0x46, 0x69, 0x4f, 0xa0, 0x88, 0x82, 0xee, 0xd6, 0x51, 0x9d, 0xec, 0xba,
      70             : };
      71             : 
      72             : constexpr uint8_t gTestCdPubkeyKid[] = {
      73             :     0x62, 0xfa, 0x82, 0x33, 0x59, 0xac, 0xfa, 0xa9, 0x96, 0x3e, 0x1c, 0xfa, 0x14, 0x0a, 0xdd, 0xf5, 0x04, 0xf3, 0x71, 0x60,
      74             : };
      75             : 
      76             : // Official CSA "Matter Certification and Testing CA"
      77             : //
      78             : // -----BEGIN CERTIFICATE-----
      79             : // MIICATCCAaegAwIBAgIHY3Nhcm9vdDAKBggqhkjOPQQDAjBSMQwwCgYDVQQKDAND
      80             : // U0ExLDAqBgNVBAMMI01hdHRlciBDZXJ0aWZpY2F0aW9uIGFuZCBUZXN0aW5nIENB
      81             : // MRQwEgYKKwYBBAGConwCAQwEQzVBMDAgFw0yMjA3MDcxOTI4MDRaGA8yMTIyMDYx
      82             : // MzE5MjgwNFowUjEMMAoGA1UECgwDQ1NBMSwwKgYDVQQDDCNNYXR0ZXIgQ2VydGlm
      83             : // aWNhdGlvbiBhbmQgVGVzdGluZyBDQTEUMBIGCisGAQQBgqJ8AgEMBEM1QTAwWTAT
      84             : // BgcqhkjOPQIBBggqhkjOPQMBBwNCAAQ4SjrDql2+y3IP5iEdPK1IYm/3EaCkkp+t
      85             : // 2GD44nf/wN4fPrYzejSEe1o6BW6ocQ6Td+7t7iUXA/3ZNQEly45Io2YwZDASBgNV
      86             : // HRMBAf8ECDAGAQH/AgEBMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUl+Rp0MUE
      87             : // FMJvxwH3fpR3OQmN9qUwHwYDVR0jBBgwFoAUl+Rp0MUEFMJvxwH3fpR3OQmN9qUw
      88             : // CgYIKoZIzj0EAwIDSAAwRQIgearlB0fCJ49UoJ6xwKPdlPEopCOL9jVCviODEleI
      89             : // +mQCIQDvvDCKi7kvj4R4BoFS4BVZGCk4zJ84W4tfTTfu89lRbQ==
      90             : // -----END CERTIFICATE-----
      91             : //
      92             : constexpr uint8_t gCdRootCert[] = {
      93             :     0x30, 0x82, 0x02, 0x01, 0x30, 0x82, 0x01, 0xa7, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x07, 0x63, 0x73, 0x61, 0x72, 0x6f, 0x6f,
      94             :     0x74, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x52, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03,
      95             :     0x55, 0x04, 0x0a, 0x0c, 0x03, 0x43, 0x53, 0x41, 0x31, 0x2c, 0x30, 0x2a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x23, 0x4d, 0x61,
      96             :     0x74, 0x74, 0x65, 0x72, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x6e,
      97             :     0x64, 0x20, 0x54, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x43, 0x41, 0x31, 0x14, 0x30, 0x12, 0x06, 0x0a, 0x2b, 0x06, 0x01,
      98             :     0x04, 0x01, 0x82, 0xa2, 0x7c, 0x02, 0x01, 0x0c, 0x04, 0x43, 0x35, 0x41, 0x30, 0x30, 0x20, 0x17, 0x0d, 0x32, 0x32, 0x30, 0x37,
      99             :     0x30, 0x37, 0x31, 0x39, 0x32, 0x38, 0x30, 0x34, 0x5a, 0x18, 0x0f, 0x32, 0x31, 0x32, 0x32, 0x30, 0x36, 0x31, 0x33, 0x31, 0x39,
     100             :     0x32, 0x38, 0x30, 0x34, 0x5a, 0x30, 0x52, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x03, 0x43, 0x53, 0x41,
     101             :     0x31, 0x2c, 0x30, 0x2a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x23, 0x4d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x20, 0x43, 0x65, 0x72,
     102             :     0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x54, 0x65, 0x73, 0x74, 0x69, 0x6e,
     103             :     0x67, 0x20, 0x43, 0x41, 0x31, 0x14, 0x30, 0x12, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0xa2, 0x7c, 0x02, 0x01, 0x0c,
     104             :     0x04, 0x43, 0x35, 0x41, 0x30, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a,
     105             :     0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x38, 0x4a, 0x3a, 0xc3, 0xaa, 0x5d, 0xbe, 0xcb, 0x72, 0x0f,
     106             :     0xe6, 0x21, 0x1d, 0x3c, 0xad, 0x48, 0x62, 0x6f, 0xf7, 0x11, 0xa0, 0xa4, 0x92, 0x9f, 0xad, 0xd8, 0x60, 0xf8, 0xe2, 0x77, 0xff,
     107             :     0xc0, 0xde, 0x1f, 0x3e, 0xb6, 0x33, 0x7a, 0x34, 0x84, 0x7b, 0x5a, 0x3a, 0x05, 0x6e, 0xa8, 0x71, 0x0e, 0x93, 0x77, 0xee, 0xed,
     108             :     0xee, 0x25, 0x17, 0x03, 0xfd, 0xd9, 0x35, 0x01, 0x25, 0xcb, 0x8e, 0x48, 0xa3, 0x66, 0x30, 0x64, 0x30, 0x12, 0x06, 0x03, 0x55,
     109             :     0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
     110             :     0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
     111             :     0x97, 0xe4, 0x69, 0xd0, 0xc5, 0x04, 0x14, 0xc2, 0x6f, 0xc7, 0x01, 0xf7, 0x7e, 0x94, 0x77, 0x39, 0x09, 0x8d, 0xf6, 0xa5, 0x30,
     112             :     0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x97, 0xe4, 0x69, 0xd0, 0xc5, 0x04, 0x14, 0xc2, 0x6f,
     113             :     0xc7, 0x01, 0xf7, 0x7e, 0x94, 0x77, 0x39, 0x09, 0x8d, 0xf6, 0xa5, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04,
     114             :     0x03, 0x02, 0x03, 0x48, 0x00, 0x30, 0x45, 0x02, 0x20, 0x79, 0xaa, 0xe5, 0x07, 0x47, 0xc2, 0x27, 0x8f, 0x54, 0xa0, 0x9e, 0xb1,
     115             :     0xc0, 0xa3, 0xdd, 0x94, 0xf1, 0x28, 0xa4, 0x23, 0x8b, 0xf6, 0x35, 0x42, 0xbe, 0x23, 0x83, 0x12, 0x57, 0x88, 0xfa, 0x64, 0x02,
     116             :     0x21, 0x00, 0xef, 0xbc, 0x30, 0x8a, 0x8b, 0xb9, 0x2f, 0x8f, 0x84, 0x78, 0x06, 0x81, 0x52, 0xe0, 0x15, 0x59, 0x18, 0x29, 0x38,
     117             :     0xcc, 0x9f, 0x38, 0x5b, 0x8b, 0x5f, 0x4d, 0x37, 0xee, 0xf3, 0xd9, 0x51, 0x6d
     118             : };
     119             : 
     120             : // Official CD "Signing Key 001"
     121             : //
     122             : // -----BEGIN CERTIFICATE-----
     123             : // MIICBzCCAa2gAwIBAgIHY3NhY2RrMTAKBggqhkjOPQQDAjBSMQwwCgYDVQQKDAND
     124             : // U0ExLDAqBgNVBAMMI01hdHRlciBDZXJ0aWZpY2F0aW9uIGFuZCBUZXN0aW5nIENB
     125             : // MRQwEgYKKwYBBAGConwCAQwEQzVBMDAgFw0yMjEwMDMxOTI4NTVaGA8yMDcyMDky
     126             : // MDE5Mjg1NVowWDEMMAoGA1UECgwDQ1NBMTIwMAYDVQQDDClDZXJ0aWZpY2F0aW9u
     127             : // IERlY2xhcmF0aW9uIFNpZ25pbmcgS2V5IDAwMTEUMBIGCisGAQQBgqJ8AgEMBEM1
     128             : // QTAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATN7uk+RPi3K+PRqcB+IZaLmv/z
     129             : // tAPwXhZp17Hlyu5vx3FLQufiNpXpLNdjVHOigK5ojze7lInhFim5uU/3sJkpo2Yw
     130             : // ZDASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQU
     131             : // /jQ/lZlHdjth7kU5ExM4SU/mfY4wHwYDVR0jBBgwFoAUl+Rp0MUEFMJvxwH3fpR3
     132             : // OQmN9qUwCgYIKoZIzj0EAwIDSAAwRQIgEDWOcdKsVGtUh3evHbBd1lq4aS7yQtOp
     133             : // 6GrOQ3/zXBsCIQDxorh2RXSaI8m2RCcoWaiWa0nLzQepNm3C2jrQVJmC2Q==
     134             : // -----END CERTIFICATE-----
     135             : //
     136             : constexpr uint8_t gCdSigningKey001PubkeyBytes[] = {
     137             :     0x04, 0xcd, 0xee, 0xe9, 0x3e, 0x44, 0xf8, 0xb7, 0x2b, 0xe3, 0xd1, 0xa9, 0xc0, 0x7e, 0x21, 0x96, 0x8b,
     138             :     0x9a, 0xff, 0xf3, 0xb4, 0x03, 0xf0, 0x5e, 0x16, 0x69, 0xd7, 0xb1, 0xe5, 0xca, 0xee, 0x6f, 0xc7, 0x71,
     139             :     0x4b, 0x42, 0xe7, 0xe2, 0x36, 0x95, 0xe9, 0x2c, 0xd7, 0x63, 0x54, 0x73, 0xa2, 0x80, 0xae, 0x68, 0x8f,
     140             :     0x37, 0xbb, 0x94, 0x89, 0xe1, 0x16, 0x29, 0xb9, 0xb9, 0x4f, 0xf7, 0xb0, 0x99, 0x29,
     141             : };
     142             : 
     143             : constexpr uint8_t gCdSigningKey001Kid[] = {
     144             :     0xFE, 0x34, 0x3F, 0x95, 0x99, 0x47, 0x76, 0x3B, 0x61, 0xEE, 0x45, 0x39, 0x13, 0x13, 0x38, 0x49, 0x4F, 0xE6, 0x7D, 0x8E,
     145             : };
     146             : 
     147             : // Official CD "Signing Key 002"
     148             : //
     149             : // -----BEGIN CERTIFICATE-----
     150             : // MIICCDCCAa2gAwIBAgIHY3NhY2RrMjAKBggqhkjOPQQDAjBSMQwwCgYDVQQKDAND
     151             : // U0ExLDAqBgNVBAMMI01hdHRlciBDZXJ0aWZpY2F0aW9uIGFuZCBUZXN0aW5nIENB
     152             : // MRQwEgYKKwYBBAGConwCAQwEQzVBMDAgFw0yMjEwMDMxOTM2NDZaGA8yMDcyMDky
     153             : // MDE5MzY0NlowWDEMMAoGA1UECgwDQ1NBMTIwMAYDVQQDDClDZXJ0aWZpY2F0aW9u
     154             : // IERlY2xhcmF0aW9uIFNpZ25pbmcgS2V5IDAwMjEUMBIGCisGAQQBgqJ8AgEMBEM1
     155             : // QTAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQDGTfo+UJRBF3ydFe7RiU+43VO
     156             : // jBKuKFV9gCe51MNW2RtAjP8yJ1AXsl+Mi6IFFtXIOvK3JBKAE9/Mj5XSAKkLo2Yw
     157             : // ZDASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQU
     158             : // 3QTbWFshTBxYFYfmVo30h7bdxwEwHwYDVR0jBBgwFoAUl+Rp0MUEFMJvxwH3fpR3
     159             : // OQmN9qUwCgYIKoZIzj0EAwIDSQAwRgIhAJruzxZ806cP/LoQ07PN9xAbjLdwUalV
     160             : // h0Qfx304Tb92AiEAk+jnf2qtyfKyTEHpT3Xf3bfekqUOA+8ikB1yjL5oTsI=
     161             : // -----END CERTIFICATE-----
     162             : //
     163             : constexpr uint8_t gCdSigningKey002PubkeyBytes[] = {
     164             :     0x04, 0x03, 0x19, 0x37, 0xe8, 0xf9, 0x42, 0x51, 0x04, 0x5d, 0xf2, 0x74, 0x57, 0xbb, 0x46, 0x25, 0x3e,
     165             :     0xe3, 0x75, 0x4e, 0x8c, 0x12, 0xae, 0x28, 0x55, 0x7d, 0x80, 0x27, 0xb9, 0xd4, 0xc3, 0x56, 0xd9, 0x1b,
     166             :     0x40, 0x8c, 0xff, 0x32, 0x27, 0x50, 0x17, 0xb2, 0x5f, 0x8c, 0x8b, 0xa2, 0x05, 0x16, 0xd5, 0xc8, 0x3a,
     167             :     0xf2, 0xb7, 0x24, 0x12, 0x80, 0x13, 0xdf, 0xcc, 0x8f, 0x95, 0xd2, 0x00, 0xa9, 0x0b,
     168             : };
     169             : 
     170             : constexpr uint8_t gCdSigningKey002Kid[] = {
     171             :     0xDD, 0x04, 0xDB, 0x58, 0x5B, 0x21, 0x4C, 0x1C, 0x58, 0x15, 0x87, 0xE6, 0x56, 0x8D, 0xF4, 0x87, 0xB6, 0xDD, 0xC7, 0x01,
     172             : };
     173             : 
     174             : // Official CD "Signing Key 003"
     175             : //
     176             : // -----BEGIN CERTIFICATE-----
     177             : // MIICBjCCAa2gAwIBAgIHY3NhY2RrMzAKBggqhkjOPQQDAjBSMQwwCgYDVQQKDAND
     178             : // U0ExLDAqBgNVBAMMI01hdHRlciBDZXJ0aWZpY2F0aW9uIGFuZCBUZXN0aW5nIENB
     179             : // MRQwEgYKKwYBBAGConwCAQwEQzVBMDAgFw0yMjEwMDMxOTQxMDFaGA8yMDcyMDky
     180             : // MDE5NDEwMVowWDEMMAoGA1UECgwDQ1NBMTIwMAYDVQQDDClDZXJ0aWZpY2F0aW9u
     181             : // IERlY2xhcmF0aW9uIFNpZ25pbmcgS2V5IDAwMzEUMBIGCisGAQQBgqJ8AgEMBEM1
     182             : // QTAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASfV1zV/bdSHxCk3zHwc5ErYUco
     183             : // 8tN/W2uWvCy/fAsRlpBXfVVdIaCWYKiwgqM56lMPeoEthpO1b9dkGF+rzTL1o2Yw
     184             : // ZDASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQU
     185             : // RxA158BOqqi+fE1ME+PkwgmVqEswHwYDVR0jBBgwFoAUl+Rp0MUEFMJvxwH3fpR3
     186             : // OQmN9qUwCgYIKoZIzj0EAwIDRwAwRAIgIFecbY+1mVVNqxH9+8IMB8+safdyIJU2
     187             : // AqqtZ/w7AkQCIHiVlYTaCnJsnW5/cvj9GfIv7Eb0cjdmcAkrYGbnPQzX
     188             : // -----END CERTIFICATE-----
     189             : //
     190             : constexpr uint8_t gCdSigningKey003PubkeyBytes[] = {
     191             :     0x04, 0x9f, 0x57, 0x5c, 0xd5, 0xfd, 0xb7, 0x52, 0x1f, 0x10, 0xa4, 0xdf, 0x31, 0xf0, 0x73, 0x91, 0x2b,
     192             :     0x61, 0x47, 0x28, 0xf2, 0xd3, 0x7f, 0x5b, 0x6b, 0x96, 0xbc, 0x2c, 0xbf, 0x7c, 0x0b, 0x11, 0x96, 0x90,
     193             :     0x57, 0x7d, 0x55, 0x5d, 0x21, 0xa0, 0x96, 0x60, 0xa8, 0xb0, 0x82, 0xa3, 0x39, 0xea, 0x53, 0x0f, 0x7a,
     194             :     0x81, 0x2d, 0x86, 0x93, 0xb5, 0x6f, 0xd7, 0x64, 0x18, 0x5f, 0xab, 0xcd, 0x32, 0xf5,
     195             : };
     196             : 
     197             : constexpr uint8_t gCdSigningKey003Kid[] = {
     198             :     0x47, 0x10, 0x35, 0xE7, 0xC0, 0x4E, 0xAA, 0xA8, 0xBE, 0x7C, 0x4D, 0x4C, 0x13, 0xE3, 0xE4, 0xC2, 0x09, 0x95, 0xA8, 0x4B,
     199             : };
     200             : 
     201             : // Official CD "Signing Key 004"
     202             : //
     203             : // -----BEGIN CERTIFICATE-----
     204             : // MIICBjCCAa2gAwIBAgIHY3NhY2RrNDAKBggqhkjOPQQDAjBSMQwwCgYDVQQKDAND
     205             : // U0ExLDAqBgNVBAMMI01hdHRlciBDZXJ0aWZpY2F0aW9uIGFuZCBUZXN0aW5nIENB
     206             : // MRQwEgYKKwYBBAGConwCAQwEQzVBMDAgFw0yMjEwMDMxOTQzMjFaGA8yMDcyMDky
     207             : // MDE5NDMyMVowWDEMMAoGA1UECgwDQ1NBMTIwMAYDVQQDDClDZXJ0aWZpY2F0aW9u
     208             : // IERlY2xhcmF0aW9uIFNpZ25pbmcgS2V5IDAwNDEUMBIGCisGAQQBgqJ8AgEMBEM1
     209             : // QTAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAR8/I2IEKic9PoZF3jyr+x4+FF6
     210             : // l6Plf8ITutiI42EedP+2hL3rqKaLJSNKXDWPNzurm20wThMG3XYgpSjRFhwLo2Yw
     211             : // ZDASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQU
     212             : // 9oYDo2kumBByQZ6h4as4VL13ldMwHwYDVR0jBBgwFoAUl+Rp0MUEFMJvxwH3fpR3
     213             : // OQmN9qUwCgYIKoZIzj0EAwIDRwAwRAIgLqAfkbtLYYdmQsnbn0CWv3G1/lbE36nz
     214             : // HbLbW5t6PY4CIE8oyIHsVhNSTPcb3mwRp+Vxhs8tKhbAdwv5BGgDaAHj
     215             : // -----END CERTIFICATE-----
     216             : //
     217             : constexpr uint8_t gCdSigningKey004PubkeyBytes[] = {
     218             :     0x04, 0x7c, 0xfc, 0x8d, 0x88, 0x10, 0xa8, 0x9c, 0xf4, 0xfa, 0x19, 0x17, 0x78, 0xf2, 0xaf, 0xec, 0x78,
     219             :     0xf8, 0x51, 0x7a, 0x97, 0xa3, 0xe5, 0x7f, 0xc2, 0x13, 0xba, 0xd8, 0x88, 0xe3, 0x61, 0x1e, 0x74, 0xff,
     220             :     0xb6, 0x84, 0xbd, 0xeb, 0xa8, 0xa6, 0x8b, 0x25, 0x23, 0x4a, 0x5c, 0x35, 0x8f, 0x37, 0x3b, 0xab, 0x9b,
     221             :     0x6d, 0x30, 0x4e, 0x13, 0x06, 0xdd, 0x76, 0x20, 0xa5, 0x28, 0xd1, 0x16, 0x1c, 0x0b,
     222             : };
     223             : 
     224             : constexpr uint8_t gCdSigningKey004Kid[] = {
     225             :     0xF6, 0x86, 0x03, 0xA3, 0x69, 0x2E, 0x98, 0x10, 0x72, 0x41, 0x9E, 0xA1, 0xE1, 0xAB, 0x38, 0x54, 0xBD, 0x77, 0x95, 0xD3,
     226             : };
     227             : 
     228             : // Official CD "Signing Key 005"
     229             : //
     230             : // -----BEGIN CERTIFICATE-----
     231             : // MIICBzCCAa2gAwIBAgIHY3NhY2RrNTAKBggqhkjOPQQDAjBSMQwwCgYDVQQKDAND
     232             : // U0ExLDAqBgNVBAMMI01hdHRlciBDZXJ0aWZpY2F0aW9uIGFuZCBUZXN0aW5nIENB
     233             : // MRQwEgYKKwYBBAGConwCAQwEQzVBMDAgFw0yMjEwMDMxOTQ3MTVaGA8yMDcyMDky
     234             : // MDE5NDcxNVowWDEMMAoGA1UECgwDQ1NBMTIwMAYDVQQDDClDZXJ0aWZpY2F0aW9u
     235             : // IERlY2xhcmF0aW9uIFNpZ25pbmcgS2V5IDAwNTEUMBIGCisGAQQBgqJ8AgEMBEM1
     236             : // QTAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARDilLGYqKm1yZH+V63UxNu5K4P
     237             : // 2zqpwWkxQms9CGf5EDrn16G4h+n4E6byb3a7zak1k3h8EneMqPKXXcRaIEL5o2Yw
     238             : // ZDASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQU
     239             : // Y38mNK1i6v5q9mLvuW9v0vy//C8wHwYDVR0jBBgwFoAUl+Rp0MUEFMJvxwH3fpR3
     240             : // OQmN9qUwCgYIKoZIzj0EAwIDSAAwRQIhAM1HQpvkHKxLJByWaSYAPRZgh3Bis18W
     241             : // AViq7c/mtzEAAiBZO0lVe6Qo9iQPIBWZaVx/S/YSNO9uKNa/pvFu3V+nIg==
     242             : // -----END CERTIFICATE-----
     243             : //
     244             : constexpr uint8_t gCdSigningKey005PubkeyBytes[] = {
     245             :     0x04, 0x43, 0x8a, 0x52, 0xc6, 0x62, 0xa2, 0xa6, 0xd7, 0x26, 0x47, 0xf9, 0x5e, 0xb7, 0x53, 0x13, 0x6e,
     246             :     0xe4, 0xae, 0x0f, 0xdb, 0x3a, 0xa9, 0xc1, 0x69, 0x31, 0x42, 0x6b, 0x3d, 0x08, 0x67, 0xf9, 0x10, 0x3a,
     247             :     0xe7, 0xd7, 0xa1, 0xb8, 0x87, 0xe9, 0xf8, 0x13, 0xa6, 0xf2, 0x6f, 0x76, 0xbb, 0xcd, 0xa9, 0x35, 0x93,
     248             :     0x78, 0x7c, 0x12, 0x77, 0x8c, 0xa8, 0xf2, 0x97, 0x5d, 0xc4, 0x5a, 0x20, 0x42, 0xf9,
     249             : };
     250             : 
     251             : constexpr uint8_t gCdSigningKey005Kid[] = {
     252             :     0x63, 0x7F, 0x26, 0x34, 0xAD, 0x62, 0xEA, 0xFE, 0x6A, 0xF6, 0x62, 0xEF, 0xB9, 0x6F, 0x6F, 0xD2, 0xFC, 0xBF, 0xFC, 0x2F,
     253             : };
     254             : 
     255             : struct MatterCDSigningKey
     256             : {
     257             :     const CertificateKeyId mKid;
     258             :     const P256PublicKeySpan mPubkey;
     259             : };
     260             : 
     261             : constexpr std::array<MatterCDSigningKey, 6> gCdSigningKeys = { {
     262             :     { FixedByteSpan<20>{ gTestCdPubkeyKid }, FixedByteSpan<65>{ gTestCdPubkeyBytes } },
     263             :     { FixedByteSpan<20>{ gCdSigningKey001Kid }, FixedByteSpan<65>{ gCdSigningKey001PubkeyBytes } },
     264             :     { FixedByteSpan<20>{ gCdSigningKey002Kid }, FixedByteSpan<65>{ gCdSigningKey002PubkeyBytes } },
     265             :     { FixedByteSpan<20>{ gCdSigningKey003Kid }, FixedByteSpan<65>{ gCdSigningKey003PubkeyBytes } },
     266             :     { FixedByteSpan<20>{ gCdSigningKey004Kid }, FixedByteSpan<65>{ gCdSigningKey004PubkeyBytes } },
     267             :     { FixedByteSpan<20>{ gCdSigningKey005Kid }, FixedByteSpan<65>{ gCdSigningKey005PubkeyBytes } },
     268             : } };
     269             : 
     270             : struct TestAttestationTrustStore final : public ArrayAttestationTrustStore
     271             : {
     272           3 :     TestAttestationTrustStore() : ArrayAttestationTrustStore(GetTestPaaRootStore().data(), GetTestPaaRootStore().size()) {}
     273             : };
     274             : Global<TestAttestationTrustStore> gTestAttestationTrustStore;
     275             : 
     276           2 : AttestationVerificationResult MapError(CertificateChainValidationResult certificateChainValidationResult)
     277             : {
     278           2 :     switch (certificateChainValidationResult)
     279             :     {
     280           0 :     case CertificateChainValidationResult::kRootFormatInvalid:
     281           0 :         return AttestationVerificationResult::kPaaFormatInvalid;
     282             : 
     283           0 :     case CertificateChainValidationResult::kRootArgumentInvalid:
     284           0 :         return AttestationVerificationResult::kPaaArgumentInvalid;
     285             : 
     286           0 :     case CertificateChainValidationResult::kICAFormatInvalid:
     287           0 :         return AttestationVerificationResult::kPaiFormatInvalid;
     288             : 
     289           0 :     case CertificateChainValidationResult::kICAArgumentInvalid:
     290           0 :         return AttestationVerificationResult::kPaiArgumentInvalid;
     291             : 
     292           0 :     case CertificateChainValidationResult::kLeafFormatInvalid:
     293           0 :         return AttestationVerificationResult::kDacFormatInvalid;
     294             : 
     295           0 :     case CertificateChainValidationResult::kLeafArgumentInvalid:
     296           0 :         return AttestationVerificationResult::kDacArgumentInvalid;
     297             : 
     298           2 :     case CertificateChainValidationResult::kChainInvalid:
     299           2 :         return AttestationVerificationResult::kDacSignatureInvalid;
     300             : 
     301           0 :     case CertificateChainValidationResult::kNoMemory:
     302           0 :         return AttestationVerificationResult::kNoMemory;
     303             : 
     304           0 :     case CertificateChainValidationResult::kInternalFrameworkError:
     305           0 :         return AttestationVerificationResult::kInternalError;
     306             : 
     307           0 :     default:
     308           0 :         return AttestationVerificationResult::kInternalError;
     309             :     }
     310             : }
     311             : } // namespace
     312             : 
     313         149 : void DefaultDACVerifier::VerifyAttestationInformation(const DeviceAttestationVerifier::AttestationInfo & info,
     314             :                                                       Callback::Callback<OnAttestationInformationVerification> * onCompletion)
     315             : {
     316         149 :     AttestationVerificationResult attestationError = AttestationVerificationResult::kSuccess;
     317             : 
     318         149 :     Platform::ScopedMemoryBuffer<uint8_t> paaCert;
     319         149 :     MutableByteSpan paaDerBuffer;
     320         149 :     AttestationCertVidPid dacVidPid;
     321         149 :     AttestationCertVidPid paiVidPid;
     322         149 :     AttestationCertVidPid paaVidPid;
     323             : 
     324         149 :     VerifyOrExit(!info.attestationElementsBuffer.empty() && !info.attestationChallengeBuffer.empty() &&
     325             :                      !info.attestationSignatureBuffer.empty() && !info.dacDerBuffer.empty() &&
     326             :                      !info.attestationNonceBuffer.empty() && onCompletion != nullptr,
     327             :                  attestationError = AttestationVerificationResult::kInvalidArgument);
     328             : 
     329         149 :     VerifyOrExit(info.attestationElementsBuffer.size() <= kMaxResponseLength,
     330             :                  attestationError = AttestationVerificationResult::kInvalidArgument);
     331             : 
     332             :     // Ensure PAI is present
     333         149 :     VerifyOrExit(!info.paiDerBuffer.empty(), attestationError = AttestationVerificationResult::kPaiMissing);
     334             : 
     335             :     // Validate Proper Certificate Format
     336             :     {
     337         149 :         VerifyOrExit(VerifyAttestationCertificateFormat(info.paiDerBuffer, AttestationCertType::kPAI) == CHIP_NO_ERROR,
     338             :                      attestationError = AttestationVerificationResult::kPaiFormatInvalid);
     339         131 :         VerifyOrExit(VerifyAttestationCertificateFormat(info.dacDerBuffer, AttestationCertType::kDAC) == CHIP_NO_ERROR,
     340             :                      attestationError = AttestationVerificationResult::kDacFormatInvalid);
     341             :     }
     342             : 
     343             :     // match DAC and PAI VIDs
     344             :     {
     345         112 :         VerifyOrExit(ExtractVIDPIDFromX509Cert(info.dacDerBuffer, dacVidPid) == CHIP_NO_ERROR,
     346             :                      attestationError = AttestationVerificationResult::kDacFormatInvalid);
     347         106 :         VerifyOrExit(ExtractVIDPIDFromX509Cert(info.paiDerBuffer, paiVidPid) == CHIP_NO_ERROR,
     348             :                      attestationError = AttestationVerificationResult::kPaiFormatInvalid);
     349         100 :         VerifyOrExit(paiVidPid.mVendorId.HasValue() && paiVidPid.mVendorId == dacVidPid.mVendorId,
     350             :                      attestationError = AttestationVerificationResult::kDacVendorIdMismatch);
     351          91 :         VerifyOrExit(dacVidPid.mProductId.HasValue(), attestationError = AttestationVerificationResult::kDacProductIdMismatch);
     352          91 :         if (paiVidPid.mProductId.HasValue())
     353             :         {
     354          69 :             VerifyOrExit(paiVidPid.mProductId == dacVidPid.mProductId,
     355             :                          attestationError = AttestationVerificationResult::kDacProductIdMismatch);
     356             :         }
     357             :     }
     358             : 
     359             :     {
     360          91 :         P256PublicKey remoteManufacturerPubkey;
     361          91 :         P256ECDSASignature deviceSignature;
     362             : 
     363          91 :         VerifyOrExit(ExtractPubkeyFromX509Cert(info.dacDerBuffer, remoteManufacturerPubkey) == CHIP_NO_ERROR,
     364             :                      attestationError = AttestationVerificationResult::kDacFormatInvalid);
     365             : 
     366             :         // Validate overall attestation signature on attestation information
     367             :         // SetLength will fail if signature doesn't fit
     368          91 :         VerifyOrExit(deviceSignature.SetLength(info.attestationSignatureBuffer.size()) == CHIP_NO_ERROR,
     369             :                      attestationError = AttestationVerificationResult::kAttestationSignatureInvalidFormat);
     370          91 :         memcpy(deviceSignature.Bytes(), info.attestationSignatureBuffer.data(), info.attestationSignatureBuffer.size());
     371          91 :         VerifyOrExit(ValidateAttestationSignature(remoteManufacturerPubkey, info.attestationElementsBuffer,
     372             :                                                   info.attestationChallengeBuffer, deviceSignature) == CHIP_NO_ERROR,
     373             :                      attestationError = AttestationVerificationResult::kAttestationSignatureInvalid);
     374          91 :     }
     375             : 
     376             :     {
     377             :         uint8_t akidBuf[Crypto::kAuthorityKeyIdentifierLength];
     378          91 :         MutableByteSpan akid(akidBuf);
     379          91 :         constexpr size_t paaCertAllocatedLen = kMaxDERCertLength;
     380          91 :         CHIP_ERROR err                       = CHIP_NO_ERROR;
     381             : 
     382          93 :         VerifyOrExit(ExtractAKIDFromX509Cert(info.paiDerBuffer, akid) == CHIP_NO_ERROR,
     383             :                      attestationError = AttestationVerificationResult::kPaiFormatInvalid);
     384             : 
     385          91 :         VerifyOrExit(paaCert.Alloc(paaCertAllocatedLen), attestationError = AttestationVerificationResult::kNoMemory);
     386             : 
     387          91 :         paaDerBuffer = MutableByteSpan(paaCert.Get(), paaCertAllocatedLen);
     388          91 :         err          = mAttestationTrustStore->GetProductAttestationAuthorityCert(akid, paaDerBuffer);
     389          91 :         VerifyOrExit(err == CHIP_NO_ERROR || err == CHIP_ERROR_NOT_IMPLEMENTED,
     390             :                      attestationError = AttestationVerificationResult::kPaaNotFound);
     391             : 
     392          90 :         if (err == CHIP_ERROR_NOT_IMPLEMENTED)
     393             :         {
     394           0 :             VerifyOrExit(gTestAttestationTrustStore->GetProductAttestationAuthorityCert(akid, paaDerBuffer) == CHIP_NO_ERROR,
     395             :                          attestationError = AttestationVerificationResult::kPaaNotFound);
     396             :         }
     397             : 
     398          90 :         VerifyOrExit(ExtractVIDPIDFromX509Cert(paaDerBuffer, paaVidPid) == CHIP_NO_ERROR,
     399             :                      attestationError = AttestationVerificationResult::kPaaFormatInvalid);
     400             : 
     401          90 :         if (paaVidPid.mVendorId.HasValue())
     402             :         {
     403          89 :             VerifyOrExit(paaVidPid.mVendorId == paiVidPid.mVendorId,
     404             :                          attestationError = AttestationVerificationResult::kPaiVendorIdMismatch);
     405             :         }
     406             : 
     407          89 :         VerifyOrExit(!paaVidPid.mProductId.HasValue(), attestationError = AttestationVerificationResult::kPaaFormatInvalid);
     408             :     }
     409             : 
     410             : #if !defined(CURRENT_TIME_NOT_IMPLEMENTED)
     411          89 :     VerifyOrExit(IsCertificateValidAtCurrentTime(info.dacDerBuffer) == CHIP_NO_ERROR,
     412             :                  attestationError = AttestationVerificationResult::kDacExpired);
     413             : #endif
     414             : 
     415             :     CertificateChainValidationResult chainValidationResult;
     416          87 :     VerifyOrExit(ValidateCertificateChain(paaDerBuffer.data(), paaDerBuffer.size(), info.paiDerBuffer.data(),
     417             :                                           info.paiDerBuffer.size(), info.dacDerBuffer.data(), info.dacDerBuffer.size(),
     418             :                                           chainValidationResult) == CHIP_NO_ERROR,
     419             :                  attestationError = MapError(chainValidationResult));
     420             : 
     421             :     {
     422          85 :         ByteSpan certificationDeclarationSpan;
     423          85 :         ByteSpan attestationNonceSpan;
     424             :         uint32_t timestampDeconstructed;
     425          85 :         ByteSpan firmwareInfoSpan;
     426          85 :         DeviceAttestationVendorReservedDeconstructor vendorReserved;
     427          85 :         ByteSpan certificationDeclarationPayload;
     428             : 
     429          85 :         DeviceInfoForAttestation deviceInfo{
     430          85 :             .vendorId     = info.vendorId,
     431          85 :             .productId    = info.productId,
     432         170 :             .dacVendorId  = dacVidPid.mVendorId.Value(),
     433         170 :             .dacProductId = dacVidPid.mProductId.Value(),
     434         170 :             .paiVendorId  = paiVidPid.mVendorId.Value(),
     435         170 :             .paiProductId = paiVidPid.mProductId.ValueOr(0),
     436         170 :             .paaVendorId  = paaVidPid.mVendorId.ValueOr(VendorId::NotSpecified),
     437          85 :         };
     438             : 
     439          85 :         MutableByteSpan paaSKID(deviceInfo.paaSKID);
     440         119 :         VerifyOrExit(ExtractSKIDFromX509Cert(paaDerBuffer, paaSKID) == CHIP_NO_ERROR,
     441             :                      attestationError = AttestationVerificationResult::kPaaFormatInvalid);
     442          85 :         VerifyOrExit(paaSKID.size() == sizeof(deviceInfo.paaSKID),
     443             :                      attestationError = AttestationVerificationResult::kPaaFormatInvalid);
     444             : 
     445          85 :         VerifyOrExit(DeconstructAttestationElements(info.attestationElementsBuffer, certificationDeclarationSpan,
     446             :                                                     attestationNonceSpan, timestampDeconstructed, firmwareInfoSpan,
     447             :                                                     vendorReserved) == CHIP_NO_ERROR,
     448             :                      attestationError = AttestationVerificationResult::kAttestationElementsMalformed);
     449             : 
     450             :         // Verify that Nonce matches with what we sent
     451          85 :         VerifyOrExit(attestationNonceSpan.data_equal(info.attestationNonceBuffer),
     452             :                      attestationError = AttestationVerificationResult::kAttestationNonceMismatch);
     453             : 
     454          85 :         attestationError = ValidateCertificationDeclarationSignature(certificationDeclarationSpan, certificationDeclarationPayload);
     455          85 :         VerifyOrExit(attestationError == AttestationVerificationResult::kSuccess, attestationError = attestationError);
     456             : 
     457          77 :         attestationError = ValidateCertificateDeclarationPayload(certificationDeclarationPayload, firmwareInfoSpan, deviceInfo);
     458          77 :         VerifyOrExit(attestationError == AttestationVerificationResult::kSuccess, attestationError = attestationError);
     459             :     }
     460             : 
     461         149 : exit:
     462         149 :     onCompletion->mCall(onCompletion->mContext, info, attestationError);
     463         149 : }
     464             : 
     465          86 : AttestationVerificationResult DefaultDACVerifier::ValidateCertificationDeclarationSignature(const ByteSpan & cmsEnvelopeBuffer,
     466             :                                                                                             ByteSpan & certDeclBuffer)
     467             : {
     468          86 :     ByteSpan kid;
     469          86 :     VerifyOrReturnError(CMS_ExtractKeyId(cmsEnvelopeBuffer, kid) == CHIP_NO_ERROR,
     470             :                         AttestationVerificationResult::kCertificationDeclarationNoKeyId);
     471             : 
     472          83 :     Crypto::P256PublicKey verifyingKey;
     473          83 :     CHIP_ERROR err = mCdKeysTrustStore.LookupVerifyingKey(kid, verifyingKey);
     474          83 :     VerifyOrReturnError(err == CHIP_NO_ERROR, AttestationVerificationResult::kCertificationDeclarationNoCertificateFound);
     475             : 
     476             :     // Disallow test key if support not enabled
     477          82 :     if (mCdKeysTrustStore.IsCdTestKey(kid) && !IsCdTestKeySupported())
     478             :     {
     479           0 :         return AttestationVerificationResult::kCertificationDeclarationNoCertificateFound;
     480             :     }
     481             : 
     482          82 :     VerifyOrReturnError(CMS_Verify(cmsEnvelopeBuffer, verifyingKey, certDeclBuffer) == CHIP_NO_ERROR,
     483             :                         AttestationVerificationResult::kCertificationDeclarationInvalidSignature);
     484             : 
     485          78 :     return AttestationVerificationResult::kSuccess;
     486          83 : }
     487             : 
     488          78 : AttestationVerificationResult DefaultDACVerifier::ValidateCertificateDeclarationPayload(const ByteSpan & certDeclBuffer,
     489             :                                                                                         const ByteSpan & firmwareInfo,
     490             :                                                                                         const DeviceInfoForAttestation & deviceInfo)
     491             : {
     492          78 :     CertificationElementsWithoutPIDs cdContent;
     493             :     CertificationElementsDecoder cdElementsDecoder;
     494          78 :     VerifyOrReturnError(DecodeCertificationElements(certDeclBuffer, cdContent) == CHIP_NO_ERROR,
     495             :                         AttestationVerificationResult::kCertificationDeclarationInvalidFormat);
     496             : 
     497          66 :     if (!firmwareInfo.empty())
     498             :     {
     499             :         // TODO: validate contents based on DCL
     500             :     }
     501             : 
     502             :     // Verify the cd elements are as required by the spec
     503             :     // security_level, security_information are meant to be ignored. version_number is not meant to be interpreted by the
     504             :     // commissioners.
     505          66 :     if (cdContent.formatVersion != 1 || cdContent.certificationType >= chip::to_underlying(CertificationType::kReserved))
     506             :     {
     507           2 :         return AttestationVerificationResult::kAttestationElementsMalformed;
     508             :     }
     509             : 
     510             :     // The vendor_id field in the Certification Declaration SHALL match the VendorID attribute found in the Basic Information
     511             :     // cluster
     512          64 :     VerifyOrReturnError(cdContent.vendorId == deviceInfo.vendorId,
     513             :                         AttestationVerificationResult::kCertificationDeclarationInvalidVendorId);
     514             : 
     515             :     //  The product_id_array field in the Certification Declaration SHALL contain the value of the ProductID attribute found in
     516             :     //  the Basic Information cluster.
     517          63 :     VerifyOrReturnError(cdElementsDecoder.IsProductIdIn(certDeclBuffer, deviceInfo.productId),
     518             :                         AttestationVerificationResult::kCertificationDeclarationInvalidProductId);
     519             : 
     520          58 :     if (cdContent.dacOriginVIDandPIDPresent)
     521             :     {
     522             :         // The Vendor ID (VID) subject DN in the DAC SHALL match the dac_origin_vendor_id field in the Certification
     523             :         // Declaration.
     524           4 :         VerifyOrReturnError(deviceInfo.dacVendorId == cdContent.dacOriginVendorId,
     525             :                             AttestationVerificationResult::kCertificationDeclarationInvalidVendorId);
     526             :         // The Vendor ID (VID) subject DN in the PAI SHALL match the dac_origin_vendor_id field in the Certification
     527             :         // Declaration.
     528           2 :         VerifyOrReturnError(deviceInfo.paiVendorId == cdContent.dacOriginVendorId,
     529             :                             AttestationVerificationResult::kCertificationDeclarationInvalidVendorId);
     530             :         // The Product ID (PID) subject DN in the DAC SHALL match the dac_origin_product_id field in the Certification
     531             :         // Declaration.
     532           2 :         VerifyOrReturnError(deviceInfo.dacProductId == cdContent.dacOriginProductId,
     533             :                             AttestationVerificationResult::kCertificationDeclarationInvalidProductId);
     534             :         // The Product ID (PID) subject DN in the PAI, if such a Product ID is present, SHALL match the dac_origin_product_id
     535             :         // field in the Certification Declaration.
     536           2 :         if (deviceInfo.paiProductId != 0) // if PAI PID is present
     537             :         {
     538           2 :             VerifyOrReturnError(deviceInfo.paiProductId == cdContent.dacOriginProductId,
     539             :                                 AttestationVerificationResult::kCertificationDeclarationInvalidProductId);
     540             :         }
     541             :     }
     542             :     else
     543             :     {
     544             :         //  The Vendor ID (VID) subject DN in the DAC SHALL match the vendor_id field in the Certification Declaration
     545          54 :         VerifyOrReturnError(deviceInfo.dacVendorId == cdContent.vendorId,
     546             :                             AttestationVerificationResult::kCertificationDeclarationInvalidVendorId);
     547             :         // The Vendor ID (VID) subject DN in the PAI SHALL match the vendor_id field in the Certification Declaration.
     548          54 :         VerifyOrReturnError(deviceInfo.paiVendorId == cdContent.vendorId,
     549             :                             AttestationVerificationResult::kCertificationDeclarationInvalidVendorId);
     550             :         // The Product ID (PID) subject DN in the DAC SHALL be present in the product_id_array field in the Certification
     551             :         // Declaration.
     552          54 :         VerifyOrReturnError(cdElementsDecoder.IsProductIdIn(certDeclBuffer, deviceInfo.dacProductId),
     553             :                             AttestationVerificationResult::kCertificationDeclarationInvalidProductId);
     554             :         // The Product ID (PID) subject DN in the PAI, if such a Product ID is present, SHALL match one of the values present in
     555             :         // the product_id_array field in the Certification Declaration.
     556          53 :         if (deviceInfo.paiProductId != 0) // if PAI PID is present
     557             :         {
     558          39 :             VerifyOrReturnError(cdElementsDecoder.IsProductIdIn(certDeclBuffer, deviceInfo.paiProductId),
     559             :                                 AttestationVerificationResult::kCertificationDeclarationInvalidProductId);
     560             :         }
     561             :     }
     562             : 
     563          55 :     if (cdContent.authorizedPAAListPresent)
     564             :     {
     565             :         // The Subject Key Id of the PAA SHALL match one of the values present in the authorized_paa_list
     566             :         // in the Certification Declaration.
     567           6 :         VerifyOrReturnError(cdElementsDecoder.HasAuthorizedPAA(certDeclBuffer, ByteSpan(deviceInfo.paaSKID)),
     568             :                             AttestationVerificationResult::kCertificationDeclarationInvalidPAA);
     569             :     }
     570             : 
     571          52 :     return AttestationVerificationResult::kSuccess;
     572             : }
     573             : 
     574           2 : CHIP_ERROR DefaultDACVerifier::VerifyNodeOperationalCSRInformation(const ByteSpan & nocsrElementsBuffer,
     575             :                                                                    const ByteSpan & attestationChallengeBuffer,
     576             :                                                                    const ByteSpan & attestationSignatureBuffer,
     577             :                                                                    const P256PublicKey & dacPublicKey, const ByteSpan & csrNonce)
     578             : {
     579           2 :     VerifyOrReturnError(!nocsrElementsBuffer.empty() && !attestationChallengeBuffer.empty() &&
     580             :                             !attestationSignatureBuffer.empty() && !csrNonce.empty(),
     581             :                         CHIP_ERROR_INVALID_ARGUMENT);
     582             : 
     583           2 :     VerifyOrReturnError(nocsrElementsBuffer.size() <= kMaxResponseLength, CHIP_ERROR_INVALID_ARGUMENT);
     584           2 :     VerifyOrReturnError(csrNonce.size() == Controller::kCSRNonceLength, CHIP_ERROR_INVALID_ARGUMENT);
     585             : 
     586           2 :     ByteSpan csrSpan;
     587           2 :     ByteSpan csrNonceSpan;
     588           2 :     ByteSpan vendorReserved1Span;
     589           2 :     ByteSpan vendorReserved2Span;
     590           2 :     ByteSpan vendorReserved3Span;
     591           2 :     ReturnErrorOnFailure(DeconstructNOCSRElements(nocsrElementsBuffer, csrSpan, csrNonceSpan, vendorReserved1Span,
     592             :                                                   vendorReserved2Span, vendorReserved3Span));
     593             : 
     594           2 :     VerifyOrReturnError(csrNonceSpan.size() == Controller::kCSRNonceLength, CHIP_ERROR_INVALID_ARGUMENT);
     595             : 
     596             :     // Verify that Nonce matches with what we sent
     597           2 :     VerifyOrReturnError(csrNonceSpan.data_equal(csrNonce), CHIP_ERROR_INVALID_ARGUMENT);
     598             : 
     599             :     // Validate overall attestation signature on attestation information
     600           2 :     P256ECDSASignature signature;
     601             :     // SetLength will fail if signature doesn't fit
     602           2 :     ReturnErrorOnFailure(signature.SetLength(attestationSignatureBuffer.size()));
     603           2 :     memcpy(signature.Bytes(), attestationSignatureBuffer.data(), attestationSignatureBuffer.size());
     604             : 
     605           2 :     ReturnErrorOnFailure(ValidateAttestationSignature(dacPublicKey, nocsrElementsBuffer, attestationChallengeBuffer, signature));
     606             : 
     607           1 :     return CHIP_NO_ERROR;
     608           2 : }
     609             : 
     610          86 : bool CsaCdKeysTrustStore::IsCdTestKey(const ByteSpan & kid) const
     611             : {
     612          86 :     return kid.data_equal(ByteSpan{ gTestCdPubkeyKid });
     613             : }
     614             : 
     615           2 : CHIP_ERROR CsaCdKeysTrustStore::AddTrustedKey(const ByteSpan & kid, const Crypto::P256PublicKey & pubKey)
     616             : {
     617           2 :     ReturnErrorCodeIf(kid.size() > SingleKeyEntry::kMaxKidSize, CHIP_ERROR_INVALID_ARGUMENT);
     618           2 :     ReturnErrorCodeIf(kid.empty(), CHIP_ERROR_INVALID_ARGUMENT);
     619           2 :     ReturnErrorCodeIf(mNumTrustedKeys == kMaxNumTrustedKeys, CHIP_ERROR_NO_MEMORY);
     620             : 
     621           2 :     auto & entry = mTrustedKeys[mNumTrustedKeys];
     622             : 
     623           2 :     entry.kidSize = kid.size();
     624           2 :     memcpy(&entry.kidBuffer[0], kid.data(), kid.size());
     625           2 :     entry.publicKey = pubKey;
     626             : 
     627           2 :     ++mNumTrustedKeys;
     628           2 :     return CHIP_NO_ERROR;
     629             : }
     630             : 
     631           2 : CHIP_ERROR CsaCdKeysTrustStore::AddTrustedKey(const ByteSpan & derCertBytes)
     632             : {
     633           2 :     uint8_t kidBuf[Crypto::kSubjectKeyIdentifierLength] = { 0 };
     634           2 :     MutableByteSpan kidSpan{ kidBuf };
     635           2 :     P256PublicKey pubKey;
     636             : 
     637           2 :     VerifyOrReturnError(CHIP_NO_ERROR == Crypto::ExtractSKIDFromX509Cert(derCertBytes, kidSpan), CHIP_ERROR_INVALID_ARGUMENT);
     638           2 :     VerifyOrReturnError(CHIP_NO_ERROR == Crypto::ExtractPubkeyFromX509Cert(derCertBytes, pubKey), CHIP_ERROR_INVALID_ARGUMENT);
     639             : 
     640           2 :     if (!IsCdTestKey(kidSpan))
     641             :     {
     642             :         // Verify cert against CSA CD root of trust.
     643             :         CertificateChainValidationResult chainValidationResult;
     644           2 :         VerifyOrReturnError(CHIP_NO_ERROR ==
     645             :                                 ValidateCertificateChain(gCdRootCert, sizeof(gCdRootCert), nullptr, 0, derCertBytes.data(),
     646             :                                                          derCertBytes.size(), chainValidationResult),
     647             :                             CHIP_ERROR_INVALID_ARGUMENT);
     648           1 :         VerifyOrReturnError(chainValidationResult == CertificateChainValidationResult::kSuccess, CHIP_ERROR_INVALID_ARGUMENT);
     649             :     }
     650             : 
     651           1 :     return AddTrustedKey(kidSpan, pubKey);
     652           2 : }
     653             : 
     654          86 : CHIP_ERROR CsaCdKeysTrustStore::LookupVerifyingKey(const ByteSpan & kid, Crypto::P256PublicKey & outPubKey) const
     655             : {
     656             :     // First, search for the well known keys
     657         104 :     for (auto & cdSigningKey : gCdSigningKeys)
     658             :     {
     659         101 :         if (kid.data_equal(cdSigningKey.mKid))
     660             :         {
     661          83 :             outPubKey = cdSigningKey.mPubkey;
     662          83 :             return CHIP_NO_ERROR;
     663             :         }
     664             :     }
     665             : 
     666             :     // Seconds, search externally added keys
     667           3 :     for (size_t keyIdx = 0; keyIdx < mNumTrustedKeys; keyIdx++)
     668             :     {
     669           1 :         auto & entry = mTrustedKeys[keyIdx];
     670           1 :         if (kid.data_equal(entry.GetKid()))
     671             :         {
     672           1 :             outPubKey = entry.publicKey;
     673           1 :             return CHIP_NO_ERROR;
     674             :         }
     675             :     }
     676             : 
     677             :     // If we get here, the desired key was not found
     678           2 :     return CHIP_ERROR_KEY_NOT_FOUND;
     679             : }
     680             : 
     681           5 : const AttestationTrustStore * GetTestAttestationTrustStore()
     682             : {
     683           5 :     return &gTestAttestationTrustStore.get();
     684             : }
     685             : 
     686           4 : DeviceAttestationVerifier * GetDefaultDACVerifier(const AttestationTrustStore * paaRootStore)
     687             : {
     688           4 :     static DefaultDACVerifier defaultDACVerifier{ paaRootStore };
     689             : 
     690           4 :     return &defaultDACVerifier;
     691             : }
     692             : 
     693             : } // namespace Credentials
     694             : } // namespace chip

Generated by: LCOV version 1.14