Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introducing Device Attestation Flow to CHIP. #8376

Closed

Conversation

mleisner
Copy link
Contributor

Added attestation callbacks to lighting-app example in order to test the flow

Problem

What is being fixed? Examples:

Change overview

What's in this PR

Testing

How was this tested? (at least one bullet point required)

  • If unit tests were added, how do they cover this issue?
  • If unit tests existed, how were they fixed/modified to prevent this in future?
  • If new unit tests are not added, why not?
  • If integration tests were added, how do they verify this change?
  • If new integration tests are not added, why not?
  • If manually tested, what platforms controller and device platforms were manually tested, and how?
  • If no testing is required, why not?

Added attestation callbacks to lighting-app example in order to test the flow
@todo
Copy link

todo bot commented Jul 14, 2021

(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.

// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
wasHandled = emberAfOperationalCredentialsClusterAttestationRequestCallback(apCommandObj, AttestationNonce);
}
break;
}
case Clusters::OperationalCredentials::Commands::Ids::CertChainRequest: {
expectArgumentCount = 1;
uint16_t CertChainType;
bool argExists[1];
memset(argExists, 0, sizeof argExists);


This comment was generated by todo based on a TODO comment in 4f34959 in #8376. cc @mleisner.

@CLAassistant
Copy link

CLAassistant commented Jul 14, 2021

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.


Marty Leisner seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

@todo
Copy link

todo bot commented Jul 14, 2021

(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.

// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
wasHandled = emberAfOperationalCredentialsClusterCertChainRequestCallback(apCommandObj, CertChainType);
}
break;
}
case Clusters::OperationalCredentials::Commands::Ids::OpCSRRequest: {
expectArgumentCount = 1;
chip::ByteSpan CSRNonce;


This comment was generated by todo based on a TODO comment in 4f34959 in #8376. cc @mleisner.

@todo
Copy link

todo bot commented Jul 14, 2021

Implement a mechanism to handle and secure DAC/PAI/PAA certificates and corresponding keypairs

// TODO: Implement a mechanism to handle and secure DAC/PAI/PAA certificates and corresponding keypairs
// Currently this is hard-coded to demonstrate Attestation Flow
const uint8_t pai_certificate[] = {
0x30, 0x82, 0x01, 0xac, 0x30, 0x82, 0x01, 0x52, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14, 0x66, 0xba, 0x49, 0xa8, 0xe3, 0xfb,
0x2e, 0xa3, 0xb4, 0xc6, 0x7b, 0x6a, 0x0c, 0x02, 0x39, 0x5c, 0x9f, 0x92, 0x38, 0xf1, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48,
0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x22, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0xa2, 0x7c,
0x01, 0x04, 0x0c, 0x10, 0x37, 0x32, 0x36, 0x38, 0x36, 0x35, 0x36, 0x43, 0x46, 0x44, 0x46, 0x33, 0x30, 0x41, 0x37, 0x41, 0x30,
0x1e, 0x17, 0x0d, 0x32, 0x31, 0x30, 0x34, 0x30, 0x36, 0x32, 0x32, 0x34, 0x37, 0x32, 0x37, 0x5a, 0x17, 0x0d, 0x34, 0x31, 0x30,
0x34, 0x30, 0x31, 0x32, 0x32, 0x34, 0x37, 0x32, 0x37, 0x5a, 0x30, 0x22, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x0a, 0x2b, 0x06, 0x01,
0x04, 0x01, 0x82, 0xa2, 0x7c, 0x01, 0x03, 0x0c, 0x10, 0x43, 0x33, 0x42, 0x39, 0x46, 0x36, 0x33, 0x30, 0x31, 0x36, 0x39, 0x34,


This comment was generated by todo based on a TODO comment in 4f34959 in #8376. cc @mleisner.

@todo
Copy link

todo bot commented Jul 14, 2021

add vendor_id

SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(0), certificationElement)); // TODO: add vendor_id
SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(1), certificationElement)); // TODO: add product_id
SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(2), certificationElement)); // TODO: add server_category_id
SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(3), certificationElement)); // TODO: add client_category_id
SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(4), certificationElement)); // TODO: add security_level
SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(5), certificationElement)); // TODO: add security_information
SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(6), certificationElement)); // TODO: add version_number
SuccessOrExit(err = tlvWriter.EndContainer(outerContainerType));
SuccessOrExit(err = tlvWriter.Finalize(&certDeclarationTbs));
SuccessOrExit(err = keypair.ECDSA_sign_msg(certDeclarationTbs->Start(), certDeclarationTbs->DataLength(), signature));


This comment was generated by todo based on a TODO comment in 4f34959 in #8376. cc @mleisner.

@todo
Copy link

todo bot commented Jul 14, 2021

add product_id

SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(1), certificationElement)); // TODO: add product_id
SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(2), certificationElement)); // TODO: add server_category_id
SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(3), certificationElement)); // TODO: add client_category_id
SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(4), certificationElement)); // TODO: add security_level
SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(5), certificationElement)); // TODO: add security_information
SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(6), certificationElement)); // TODO: add version_number
SuccessOrExit(err = tlvWriter.EndContainer(outerContainerType));
SuccessOrExit(err = tlvWriter.Finalize(&certDeclarationTbs));
SuccessOrExit(err = keypair.ECDSA_sign_msg(certDeclarationTbs->Start(), certDeclarationTbs->DataLength(), signature));


This comment was generated by todo based on a TODO comment in 4f34959 in #8376. cc @mleisner.

@todo
Copy link

todo bot commented Jul 14, 2021

add server_category_id

SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(2), certificationElement)); // TODO: add server_category_id
SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(3), certificationElement)); // TODO: add client_category_id
SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(4), certificationElement)); // TODO: add security_level
SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(5), certificationElement)); // TODO: add security_information
SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(6), certificationElement)); // TODO: add version_number
SuccessOrExit(err = tlvWriter.EndContainer(outerContainerType));
SuccessOrExit(err = tlvWriter.Finalize(&certDeclarationTbs));
SuccessOrExit(err = keypair.ECDSA_sign_msg(certDeclarationTbs->Start(), certDeclarationTbs->DataLength(), signature));
certDeclaration = System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize);


This comment was generated by todo based on a TODO comment in 4f34959 in #8376. cc @mleisner.

@todo
Copy link

todo bot commented Jul 14, 2021

add client_category_id

SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(3), certificationElement)); // TODO: add client_category_id
SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(4), certificationElement)); // TODO: add security_level
SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(5), certificationElement)); // TODO: add security_information
SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(6), certificationElement)); // TODO: add version_number
SuccessOrExit(err = tlvWriter.EndContainer(outerContainerType));
SuccessOrExit(err = tlvWriter.Finalize(&certDeclarationTbs));
SuccessOrExit(err = keypair.ECDSA_sign_msg(certDeclarationTbs->Start(), certDeclarationTbs->DataLength(), signature));
certDeclaration = System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize);
VerifyOrExit(!certDeclaration.IsNull(), err = CHIP_ERROR_NO_MEMORY);


This comment was generated by todo based on a TODO comment in 4f34959 in #8376. cc @mleisner.

@todo
Copy link

todo bot commented Jul 14, 2021

add security_level

SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(4), certificationElement)); // TODO: add security_level
SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(5), certificationElement)); // TODO: add security_information
SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(6), certificationElement)); // TODO: add version_number
SuccessOrExit(err = tlvWriter.EndContainer(outerContainerType));
SuccessOrExit(err = tlvWriter.Finalize(&certDeclarationTbs));
SuccessOrExit(err = keypair.ECDSA_sign_msg(certDeclarationTbs->Start(), certDeclarationTbs->DataLength(), signature));
certDeclaration = System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize);
VerifyOrExit(!certDeclaration.IsNull(), err = CHIP_ERROR_NO_MEMORY);


This comment was generated by todo based on a TODO comment in 4f34959 in #8376. cc @mleisner.

@todo
Copy link

todo bot commented Jul 14, 2021

add security_information

SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(5), certificationElement)); // TODO: add security_information
SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(6), certificationElement)); // TODO: add version_number
SuccessOrExit(err = tlvWriter.EndContainer(outerContainerType));
SuccessOrExit(err = tlvWriter.Finalize(&certDeclarationTbs));
SuccessOrExit(err = keypair.ECDSA_sign_msg(certDeclarationTbs->Start(), certDeclarationTbs->DataLength(), signature));
certDeclaration = System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize);
VerifyOrExit(!certDeclaration.IsNull(), err = CHIP_ERROR_NO_MEMORY);
tlvWriter.Init(std::move(certDeclaration));


This comment was generated by todo based on a TODO comment in 4f34959 in #8376. cc @mleisner.

@todo
Copy link

todo bot commented Jul 14, 2021

add version_number

SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(6), certificationElement)); // TODO: add version_number
SuccessOrExit(err = tlvWriter.EndContainer(outerContainerType));
SuccessOrExit(err = tlvWriter.Finalize(&certDeclarationTbs));
SuccessOrExit(err = keypair.ECDSA_sign_msg(certDeclarationTbs->Start(), certDeclarationTbs->DataLength(), signature));
certDeclaration = System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize);
VerifyOrExit(!certDeclaration.IsNull(), err = CHIP_ERROR_NO_MEMORY);
tlvWriter.Init(std::move(certDeclaration));
outerContainerType = TLV::kTLVType_NotSpecified;


This comment was generated by todo based on a TODO comment in 4f34959 in #8376. cc @mleisner.

@todo
Copy link

todo bot commented Jul 14, 2021

add firmware digest(s)

SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(1), ByteSpan(nullptr, 0))); // TODO: add firmware digest(s)
SuccessOrExit(err = tlvWriter.EndContainer(outerContainerType));
SuccessOrExit(err = tlvWriter.Finalize(&firmwareInfo));
attestationElements = System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize);
VerifyOrExit(!attestationElements.IsNull(), err = CHIP_ERROR_NO_MEMORY);
attestationElementsTbs = System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize);
VerifyOrExit(!attestationElementsTbs.IsNull(), err = CHIP_ERROR_NO_MEMORY);
tlvWriter.Init(std::move(attestationElements));


This comment was generated by todo based on a TODO comment in 4f34959 in #8376. cc @mleisner.

@todo
Copy link

todo bot commented Jul 14, 2021

add timestamp

SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(2), ByteSpan(nullptr, 0))); // TODO: add timestamp
SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(3), ByteSpan(firmwareInfo->Start(), firmwareInfo->DataLength())));
SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(4), ByteSpan(nullptr, 0))); // Vendor Reserved 5
SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(5), ByteSpan(nullptr, 0))); // Vendor Reserved 6
SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(6), ByteSpan(nullptr, 0))); // Vendor Reserved 7
SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(7), ByteSpan(nullptr, 0))); // Vendor Reserved 8
SuccessOrExit(err = tlvWriter.EndContainer(outerContainerType));
SuccessOrExit(err = tlvWriter.Finalize(&attestationElements));
// Retrieve attestation challenge
// TODO: Retrieve Peer Node Id / Remove hard-coded NodeId value


This comment was generated by todo based on a TODO comment in 4f34959 in #8376. cc @mleisner.

@todo
Copy link

todo bot commented Jul 14, 2021

Retrieve Peer Node Id / Remove hard-coded NodeId value

// TODO: Retrieve Peer Node Id / Remove hard-coded NodeId value
state = GetGlobalSecureSessionMgr().GetPeerConnectionState({ 112233, kAnyKeyId, kUndefinedAdminId });
VerifyOrExit(state != nullptr, err = CHIP_ERROR_NOT_CONNECTED);
attestationChallenge = state->GetSecureSession().GetAttestationChallenge();
tlvWriter.Init(std::move(attestationElementsTbs));
outerContainerType = TLV::kTLVType_NotSpecified;
SuccessOrExit(err = tlvWriter.StartContainer(TLV::AnonymousTag, TLV::kTLVType_Structure, outerContainerType));
SuccessOrExit(err =
tlvWriter.Put(TLV::ContextTag(0), ByteSpan(attestationElements->Start(), attestationElements->DataLength())));
SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(1), attestationChallenge));


This comment was generated by todo based on a TODO comment in 4f34959 in #8376. cc @mleisner.

@todo
Copy link

todo bot commented Jul 14, 2021

Map error status to correct error code

// TODO: Map error status to correct error code
commissioner->OnSessionEstablishmentError(CHIP_ERROR_INTERNAL);
}
void DeviceCommissioner::OnCertificateChainResponse(void * context, ByteSpan certificate)
{
ChipLogProgress(Controller, "Received certificate chain from the device");
DeviceCommissioner * commissioner = reinterpret_cast<DeviceCommissioner *>(context);
commissioner->mCertChainResponseCallback.Cancel();
commissioner->mOnCertChainFailureCallback.Cancel();


This comment was generated by todo based on a TODO comment in 4f34959 in #8376. cc @mleisner.

@todo
Copy link

todo bot commented Jul 14, 2021

Map error status to correct error code

// TODO: Map error status to correct error code
commissioner->OnSessionEstablishmentError(CHIP_ERROR_INTERNAL);
}
}
CHIP_ERROR DeviceCommissioner::ProcessCertificateChain(const ByteSpan & certificate)
{
Transport::AdminPairingInfo * admin = mAdmins.FindAdminWithId(mAdminId);
VerifyOrReturnError(admin != nullptr, CHIP_ERROR_INCORRECT_STATE);
switch (mCertificateChainBeingRequested)


This comment was generated by todo based on a TODO comment in 4f34959 in #8376. cc @mleisner.

@todo
Copy link

todo bot commented Jul 14, 2021

see if vid matches

// TODO: see if vid matches
// Step b/d
uint16_t paiLen;
const uint8_t * pai = admin->GetDevicePAI(paiLen);
uint16_t dacLen;
const uint8_t * dac = admin->GetDeviceDAC(dacLen);
ReturnErrorOnFailure(ValidateCertificateChain(paa_certificate, sizeof(paa_certificate), pai, paiLen, dac, dacLen));
// Extract Manufacturer Certificate Public Key


This comment was generated by todo based on a TODO comment in 4f34959 in #8376. cc @mleisner.

@todo
Copy link

todo bot commented Jul 14, 2021

Map error status to correct error code

// TODO: Map error status to correct error code
commissioner->OnSessionEstablishmentError(CHIP_ERROR_INTERNAL);
}
void DeviceCommissioner::OnAttestationResponse(void * context, chip::ByteSpan attestationElements, chip::ByteSpan signature)
{
ChipLogProgress(Controller, "Received Attestation Information from the device");
DeviceCommissioner * commissioner = reinterpret_cast<DeviceCommissioner *>(context);
commissioner->mAttestationResponseCallback.Cancel();
commissioner->mOnAttestationFailureCallback.Cancel();


This comment was generated by todo based on a TODO comment in 4f34959 in #8376. cc @mleisner.

@todo
Copy link

todo bot commented Jul 14, 2021

Map error status to correct error code

// TODO: Map error status to correct error code
commissioner->OnSessionEstablishmentError(CHIP_ERROR_INTERNAL);
}
}
CHIP_ERROR DeviceCommissioner::ValidateAttestationInfo(chip::ByteSpan attestationElements, chip::ByteSpan signature)
{
VerifyOrReturnError(mState == State::Initialized, CHIP_ERROR_INCORRECT_STATE);
VerifyOrReturnError(mDeviceBeingPaired < kNumMaxActiveDevices, CHIP_ERROR_INCORRECT_STATE);
Device * device = &mActiveDevices[mDeviceBeingPaired];


This comment was generated by todo based on a TODO comment in 4f34959 in #8376. cc @mleisner.

@todo
Copy link

todo bot commented Jul 14, 2021

Implement a mechanism to handle and secure DAC/PAI/PAA certificates and corresponding keypairs

// TODO: Implement a mechanism to handle and secure DAC/PAI/PAA certificates and corresponding keypairs
// Currently this is hard-coded to demonstrate Attestation Flow
const uint8_t paa_certificate[] = {
0x30, 0x82, 0x01, 0xac, 0x30, 0x82, 0x01, 0x52, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14, 0x3a, 0x34, 0x59, 0xee, 0xad, 0x55,
0x84, 0x4c, 0xe6, 0x57, 0x97, 0xd8, 0x69, 0x4a, 0x4b, 0xd3, 0x10, 0x35, 0xfa, 0x2a, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48,
0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x22, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0xa2, 0x7c,
0x01, 0x04, 0x0c, 0x10, 0x37, 0x32, 0x36, 0x38, 0x36, 0x35, 0x36, 0x43, 0x46, 0x44, 0x46, 0x33, 0x30, 0x41, 0x37, 0x41, 0x30,
0x1e, 0x17, 0x0d, 0x32, 0x31, 0x30, 0x34, 0x30, 0x36, 0x32, 0x32, 0x34, 0x31, 0x35, 0x36, 0x5a, 0x17, 0x0d, 0x34, 0x36, 0x30,
0x33, 0x33, 0x31, 0x32, 0x32, 0x34, 0x31, 0x35, 0x36, 0x5a, 0x30, 0x22, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x0a, 0x2b, 0x06, 0x01,
0x04, 0x01, 0x82, 0xa2, 0x7c, 0x01, 0x04, 0x0c, 0x10, 0x37, 0x32, 0x36, 0x38, 0x36, 0x35, 0x36, 0x43, 0x46, 0x44, 0x46, 0x33,


This comment was generated by todo based on a TODO comment in 4f34959 in #8376. cc @mleisner.

@todo
Copy link

todo bot commented Jul 14, 2021

(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.

// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
wasHandled =
emberAfOperationalCredentialsClusterAttestationResponseCallback(apCommandObj, AttestationElements, Signature);
}
break;
}
case Clusters::OperationalCredentials::Commands::Ids::CertChainResponse: {
expectArgumentCount = 1;
chip::ByteSpan Certificate;
bool argExists[1];


This comment was generated by todo based on a TODO comment in 4f34959 in #8376. cc @mleisner.

@todo
Copy link

todo bot commented Jul 14, 2021

(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.

// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
wasHandled = emberAfOperationalCredentialsClusterCertChainResponseCallback(apCommandObj, Certificate);
}
break;
}
case Clusters::OperationalCredentials::Commands::Ids::OpCSRResponse: {
expectArgumentCount = 6;
chip::ByteSpan CSR;


This comment was generated by todo based on a TODO comment in 4f34959 in #8376. cc @mleisner.

@mleisner mleisner closed this Jul 14, 2021
@mleisner
Copy link
Contributor Author

test run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants