-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[all-clusters-app] Add some command line options to modify what is re…
…turned by the CSRResponse (#19461) * [examples/platform/linux - Testing] Add some command line options to modify what is returned by the CSRResponse * Add additional checks related to RESP_MAX into the DefaultDeviceAttestationVerifier
- Loading branch information
1 parent
cdfb941
commit 1755250
Showing
7 changed files
with
287 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
/* | ||
* | ||
* Copyright (c) 2022 Project CHIP Authors | ||
* All rights reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#include "Options.h" | ||
|
||
#include <algorithm> | ||
#include <app-common/zap-generated/cluster-objects.h> | ||
#include <app/data-model/Encode.h> | ||
#include <credentials/DeviceAttestationConstructor.h> | ||
#include <crypto/CHIPCryptoPAL.h> | ||
|
||
using namespace chip; | ||
using namespace chip::app; | ||
using namespace chip::app::Clusters::OperationalCredentials::Commands; | ||
|
||
constexpr size_t kMaxResponseLength = 900; | ||
constexpr size_t kCSRNonceLength = 32; | ||
|
||
namespace { | ||
|
||
CHIP_ERROR ConstructCustomNOCSRElements(TLV::TLVWriter & writer, TLV::Tag tag, const ByteSpan & nocsrElements, | ||
CSRResponseOptions & options) | ||
{ | ||
ByteSpan csr; | ||
ByteSpan csrNonce; | ||
ByteSpan vendorReserved1; | ||
ByteSpan vendorReserved2; | ||
ByteSpan vendorReserved3; | ||
ReturnErrorOnFailure( | ||
Credentials::DeconstructNOCSRElements(nocsrElements, csr, csrNonce, vendorReserved1, vendorReserved2, vendorReserved3)); | ||
|
||
// Add 10 bytes of possible overhead to allow the generation of content longer than the allowed maximum of RESP_MAX. | ||
// 10 has been choosen to leave enough space for the possible TLV overhead when adding the additional data. | ||
uint8_t nocsrElementsData[kMaxResponseLength + 10]; | ||
MutableByteSpan nocsrElementsSpan(nocsrElementsData); | ||
|
||
TLV::TLVType outerContainerType = TLV::kTLVType_NotSpecified; | ||
TLV::TLVWriter tlvWriter; | ||
tlvWriter.Init(nocsrElementsSpan); | ||
|
||
ReturnErrorOnFailure(tlvWriter.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, outerContainerType)); | ||
|
||
// Update CSR | ||
if (options.csrIncorrectType) | ||
{ | ||
ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(1), true)); | ||
} | ||
else | ||
{ | ||
ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(1), csr)); | ||
} | ||
|
||
// Update CSRNonce | ||
if (options.csrNonceIncorrectType) | ||
{ | ||
ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(2), true)); | ||
} | ||
else if (options.csrNonceInvalid) | ||
{ | ||
uint8_t csrNonceInvalid[kCSRNonceLength] = {}; | ||
memcpy(csrNonceInvalid, csrNonce.data(), csrNonce.size()); | ||
std::reverse(csrNonceInvalid, csrNonceInvalid + sizeof(csrNonceInvalid)); | ||
ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(2), ByteSpan(csrNonceInvalid))); | ||
} | ||
else if (options.csrNonceTooLong) | ||
{ | ||
uint8_t csrNonceTooLong[kCSRNonceLength + 1] = {}; | ||
memcpy(csrNonceTooLong, csrNonce.data(), csrNonce.size()); | ||
ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(2), ByteSpan(csrNonceTooLong))); | ||
} | ||
else | ||
{ | ||
ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(2), csrNonce)); | ||
} | ||
|
||
// Add vendorReserved1 if present | ||
if (!vendorReserved1.empty()) | ||
{ | ||
ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(3), vendorReserved1)); | ||
} | ||
|
||
// Add vendorReserved2 if present | ||
if (!vendorReserved2.empty()) | ||
{ | ||
ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(4), vendorReserved2)); | ||
} | ||
|
||
// Add vendorReserved3 if present | ||
if (!vendorReserved3.empty()) | ||
{ | ||
ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(5), vendorReserved3)); | ||
} | ||
|
||
// Add additional data | ||
if (options.nocsrElementsTooLong) | ||
{ | ||
size_t len = kMaxResponseLength - tlvWriter.GetLengthWritten(); | ||
ReturnLogErrorOnFailure(tlvWriter.Put(TLV::ContextTag(6), ByteSpan(nocsrElementsData, len))); | ||
} | ||
|
||
ReturnErrorOnFailure(tlvWriter.EndContainer(outerContainerType)); | ||
ReturnErrorOnFailure(tlvWriter.Finalize()); | ||
|
||
return DataModel::Encode(writer, tag, nocsrElementsSpan.SubSpan(0, tlvWriter.GetLengthWritten())); | ||
} | ||
|
||
CHIP_ERROR ConstructCustomAttestationSignature(TLV::TLVWriter & writer, TLV::Tag tag, const ByteSpan & attestationSignature, | ||
CSRResponseOptions & options) | ||
{ | ||
if (options.attestationSignatureIncorrectType) | ||
{ | ||
return DataModel::Encode(writer, tag, true); | ||
} | ||
|
||
if (options.attestationSignatureInvalid) | ||
{ | ||
uint8_t invalidAttestationSignature[Crypto::kP256_ECDSA_Signature_Length_Raw] = {}; | ||
memcpy(invalidAttestationSignature, attestationSignature.data(), attestationSignature.size()); | ||
std::reverse(invalidAttestationSignature, invalidAttestationSignature + sizeof(invalidAttestationSignature)); | ||
return DataModel::Encode(writer, tag, ByteSpan(invalidAttestationSignature)); | ||
} | ||
|
||
return DataModel::Encode(writer, tag, attestationSignature); | ||
} | ||
|
||
} // namespace | ||
|
||
namespace chip { | ||
namespace app { | ||
namespace DataModel { | ||
|
||
template <> | ||
CHIP_ERROR Encode(TLV::TLVWriter & writer, TLV::Tag tag, const CSRResponse::Type & responseData) | ||
{ | ||
auto tag1 = TLV::ContextTag(to_underlying(CSRResponse::Fields::kNOCSRElements)); | ||
auto tag2 = TLV::ContextTag(to_underlying(CSRResponse::Fields::kAttestationSignature)); | ||
auto options = LinuxDeviceOptions::GetInstance().mCSRResponseOptions; | ||
|
||
TLV::TLVType outer; | ||
ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer)); | ||
ReturnErrorOnFailure(ConstructCustomNOCSRElements(writer, tag1, responseData.NOCSRElements, options)); | ||
ReturnErrorOnFailure(ConstructCustomAttestationSignature(writer, tag2, responseData.attestationSignature, options)); | ||
ReturnErrorOnFailure(writer.EndContainer(outer)); | ||
|
||
return CHIP_NO_ERROR; | ||
} | ||
|
||
} // namespace DataModel | ||
} // namespace app | ||
} // namespace chip |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/* | ||
* | ||
* Copyright (c) 2022 Project CHIP Authors | ||
* All rights reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
namespace chip { | ||
|
||
struct CSRResponseOptions | ||
{ | ||
bool csrIncorrectType = false; | ||
bool csrNonceIncorrectType = false; | ||
bool csrNonceTooLong = false; | ||
bool csrNonceInvalid = false; | ||
bool nocsrElementsTooLong = false; | ||
bool attestationSignatureIncorrectType = false; | ||
bool attestationSignatureInvalid = false; | ||
}; | ||
|
||
} // namespace chip |
Oops, something went wrong.