From ed35ebcffe50c5ef8c76a5bb090a12ffc67e826b Mon Sep 17 00:00:00 2001 From: Joonhaeng Heo Date: Wed, 21 Feb 2024 19:40:17 +0900 Subject: [PATCH 1/9] Implement Android validate Device attestation --- .../AndroidOperationalCredentialsIssuer.cpp | 13 +- .../java/CHIPDeviceController-JNI.cpp | 138 ++++++++++++++++++ .../java/DeviceAttestationDelegateBridge.cpp | 6 +- .../devicecontroller/AttestationInfo.java | 41 ++++++ .../ChipDeviceController.java | 4 + 5 files changed, 195 insertions(+), 7 deletions(-) diff --git a/src/controller/java/AndroidOperationalCredentialsIssuer.cpp b/src/controller/java/AndroidOperationalCredentialsIssuer.cpp index af9e8adc8621a0..be980339586a76 100644 --- a/src/controller/java/AndroidOperationalCredentialsIssuer.cpp +++ b/src/controller/java/AndroidOperationalCredentialsIssuer.cpp @@ -47,7 +47,7 @@ static CHIP_ERROR N2J_CSRInfo(JNIEnv * env, jbyteArray nonce, jbyteArray element static CHIP_ERROR N2J_AttestationInfo(JNIEnv * env, jbyteArray challenge, jbyteArray nonce, jbyteArray elements, jbyteArray elementsSignature, jbyteArray dac, jbyteArray pai, jbyteArray cd, - jbyteArray firmwareInfo, jobject & outAttestationInfo); + jbyteArray firmwareInfo, chip::VendorId vendorId, uint16_t productId, jobject & outAttestationInfo); CHIP_ERROR AndroidOperationalCredentialsIssuer::Initialize(PersistentStorageDelegate & storage, AutoCommissioner * autoCommissioner, jobject javaObjectRef) @@ -271,9 +271,12 @@ CHIP_ERROR AndroidOperationalCredentialsIssuer::CallbackGenerateNOCChain(const B JniReferences::GetInstance().N2J_ByteArray(env, firmwareInfoSpan.data(), static_cast(firmwareInfoSpan.size()), javaFirmwareInfo); + chip::VendorId vendorId = mAutoCommissioner->GetCommissioningParameters().GetRemoteVendorId().ValueOr(chip::VendorId::Unspecified); + uint16_t productId = mAutoCommissioner->GetCommissioningParameters().GetRemoteProductId().ValueOr(0x0000); // 0x0000 is invalid product ID value. + jobject attestationInfo; err = N2J_AttestationInfo(env, javaAttestationChallenge, javaAttestationNonce, javaAttestationElements, - javaAttestationElementsSignature, javaDAC, javaPAI, javaCD, javaFirmwareInfo, attestationInfo); + javaAttestationElementsSignature, javaDAC, javaPAI, javaCD, javaFirmwareInfo, vendorId, productId, attestationInfo); if (err != CHIP_NO_ERROR) { ChipLogError(Controller, "Failed to create AttestationInfo"); @@ -482,7 +485,7 @@ CHIP_ERROR N2J_CSRInfo(JNIEnv * env, jbyteArray nonce, jbyteArray elements, jbyt CHIP_ERROR N2J_AttestationInfo(JNIEnv * env, jbyteArray challenge, jbyteArray nonce, jbyteArray elements, jbyteArray elementsSignature, jbyteArray dac, jbyteArray pai, jbyteArray cd, jbyteArray firmwareInfo, - jobject & outAttestationInfo) + chip::VendorId vendorId, uint16_t productId, jobject & outAttestationInfo) { CHIP_ERROR err = CHIP_NO_ERROR; jmethodID constructor; @@ -492,11 +495,11 @@ CHIP_ERROR N2J_AttestationInfo(JNIEnv * env, jbyteArray challenge, jbyteArray no SuccessOrExit(err); env->ExceptionClear(); - constructor = env->GetMethodID(infoClass, "", "([B[B[B[B[B[B[B[B)V"); + constructor = env->GetMethodID(infoClass, "", "([B[B[B[B[B[B[B[BII)V"); VerifyOrExit(constructor != nullptr, err = CHIP_JNI_ERROR_METHOD_NOT_FOUND); outAttestationInfo = - (jobject) env->NewObject(infoClass, constructor, challenge, nonce, elements, elementsSignature, dac, pai, cd, firmwareInfo); + (jobject) env->NewObject(infoClass, constructor, challenge, nonce, elements, elementsSignature, dac, pai, cd, firmwareInfo, static_cast(vendorId), static_cast(productId)); VerifyOrExit(!env->ExceptionCheck(), err = CHIP_JNI_ERROR_EXCEPTION_THROWN); exit: diff --git a/src/controller/java/CHIPDeviceController-JNI.cpp b/src/controller/java/CHIPDeviceController-JNI.cpp index 206103ca82a311..4105e3a0388242 100644 --- a/src/controller/java/CHIPDeviceController-JNI.cpp +++ b/src/controller/java/CHIPDeviceController-JNI.cpp @@ -1270,6 +1270,144 @@ JNI_METHOD(jbyteArray, extractSkidFromPaaCert) return outJbytes; } +JNI_METHOD(jbyteArray, extractAkidFromPaiCert) +(JNIEnv * env, jclass clazz, jbyteArray paiCert) +{ + uint32_t allocatedCertLength = chip::Credentials::kMaxCHIPCertLength; + chip::Platform::ScopedMemoryBuffer outBuf; + jbyteArray outJbytes = nullptr; + JniByteArray paiCertBytes(env, paiCert); + + CHIP_ERROR err = CHIP_NO_ERROR; + VerifyOrExit(outBuf.Alloc(allocatedCertLength), err = CHIP_ERROR_NO_MEMORY); + { + MutableByteSpan outBytes(outBuf.Get(), allocatedCertLength); + + err = chip::Crypto::ExtractAKIDFromX509Cert(paiCertBytes.byteSpan(), outBytes); + SuccessOrExit(err); + + VerifyOrExit(chip::CanCastTo(outBytes.size()), err = CHIP_ERROR_INTERNAL); + + err = JniReferences::GetInstance().N2J_ByteArray(env, outBytes.data(), static_cast(outBytes.size()), outJbytes); + SuccessOrExit(err); + } + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(Controller, "Failed to extract akid frome X509 cert. Err = %" CHIP_ERROR_FORMAT, err.Format()); + JniReferences::GetInstance().ThrowError(env, sChipDeviceControllerExceptionCls, err); + } + + return outJbytes; +} + +JNI_METHOD(void, validateAttestationInfo) +(JNIEnv * env, jclass clazz, jint vendorId, jint productId, jbyteArray paaCert, jbyteArray paiCert, jbyteArray dacCert, jbyteArray attestationElementsBuffer) +{ + AttestationVerificationResult attestationError = AttestationVerificationResult::kSuccess; + CHIP_ERROR err = CHIP_NO_ERROR; + + DeviceInfoForAttestation deviceInfo{ + .vendorId = static_cast(vendorId), + .productId = static_cast(productId), + }; + + VerifyOrExit(paaCert != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrExit(paiCert != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrExit(dacCert != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); + + { + JniByteArray paaCertBytes(env, paaCert); + JniByteArray paiCertBytes(env, paiCert); + JniByteArray dacCertBytes(env, dacCert); + + AttestationCertVidPid paaVidPid; + AttestationCertVidPid paiVidPid; + AttestationCertVidPid dacVidPid; + + uint8_t skidBuf[chip::Crypto::kAuthorityKeyIdentifierLength]; + MutableByteSpan paaSKID(skidBuf); + + CertificateChainValidationResult chainValidationResult; + + err = chip::Crypto::VerifyAttestationCertificateFormat(paiCertBytes.byteSpan(), AttestationCertType::kPAI); + VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Verify PAI Attestation Cert format Error! : %" CHIP_ERROR_FORMAT, err.Format())); + + err = chip::Crypto::VerifyAttestationCertificateFormat(dacCertBytes.byteSpan(), AttestationCertType::kDAC); + VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Verify DAC Attestation Cert format Error! : %" CHIP_ERROR_FORMAT, err.Format())); + + err = chip::Crypto::ExtractVIDPIDFromX509Cert(paaCertBytes.byteSpan(), paaVidPid); + VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Extract VID, PID from PAA Error! : %" CHIP_ERROR_FORMAT, err.Format())); + + err = chip::Crypto::ExtractVIDPIDFromX509Cert(paiCertBytes.byteSpan(), paiVidPid); + VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Extract VID, PID from PAI Error! : %" CHIP_ERROR_FORMAT, err.Format())); + + err = chip::Crypto::ExtractVIDPIDFromX509Cert(dacCertBytes.byteSpan(), dacVidPid); + VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Extract VID, PID from DAC Error! : %" CHIP_ERROR_FORMAT, err.Format())); + + if (paaVidPid.mVendorId.HasValue()) + { + VerifyOrExit(paaVidPid.mVendorId == paiVidPid.mVendorId, + attestationError = AttestationVerificationResult::kPaiVendorIdMismatch); + } + + VerifyOrExit(!paaVidPid.mProductId.HasValue(), attestationError = AttestationVerificationResult::kPaaFormatInvalid); + + err = chip::Crypto::ValidateCertificateChain(paaCertBytes.byteSpan().data(), paaCertBytes.byteSpan().size(), paiCertBytes.byteSpan().data(), + paiCertBytes.byteSpan().size(), dacCertBytes.byteSpan().data(), dacCertBytes.byteSpan().size(), + chainValidationResult); + VerifyOrExit(err == CHIP_NO_ERROR, attestationError = static_cast(chainValidationResult)); + + err = ExtractSKIDFromX509Cert(paaCertBytes.byteSpan(), paaSKID); + VerifyOrExit(err == CHIP_NO_ERROR, attestationError = AttestationVerificationResult::kPaaFormatInvalid); + VerifyOrExit(paaSKID.size() == chip::Crypto::kAuthorityKeyIdentifierLength, attestationError = AttestationVerificationResult::kPaaFormatInvalid); + + deviceInfo.dacVendorId = dacVidPid.mVendorId.Value(); + deviceInfo.dacProductId = dacVidPid.mProductId.Value(); + deviceInfo.paiVendorId = paiVidPid.mVendorId.Value(); + deviceInfo.paiProductId = paiVidPid.mProductId.ValueOr(0); + deviceInfo.paaVendorId = paaVidPid.mVendorId.ValueOr(VendorId::NotSpecified); + } + + { + VerifyOrExit(attestationElementsBuffer != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); + + JniByteArray attestationElementsBytes(env, attestationElementsBuffer); + + ByteSpan certificationDeclarationSpan; + ByteSpan attestationNonceSpan; + uint32_t timestampDeconstructed; + ByteSpan firmwareInfoSpan; + DeviceAttestationVendorReservedDeconstructor vendorReserved; + ByteSpan certificationDeclarationPayload; + + const chip::Credentials::AttestationTrustStore * testingRootStore = chip::Credentials::GetTestAttestationTrustStore(); + chip::Credentials::DeviceAttestationVerifier * dacVertifier = chip::Credentials::GetDefaultDACVerifier(testingRootStore); + + err = chip::Credentials::DeconstructAttestationElements(attestationElementsBytes.byteSpan(), certificationDeclarationSpan, + attestationNonceSpan, timestampDeconstructed, firmwareInfoSpan, + vendorReserved); + + VerifyOrExit(err == CHIP_NO_ERROR, attestationError = AttestationVerificationResult::kAttestationElementsMalformed); + + attestationError = dacVertifier->ValidateCertificationDeclarationSignature(certificationDeclarationSpan, certificationDeclarationPayload); + VerifyOrExit(attestationError == AttestationVerificationResult::kSuccess, err = CHIP_ERROR_INTERNAL); + } + +exit: + if (err == CHIP_NO_ERROR && attestationError != AttestationVerificationResult::kSuccess) + { + err = CHIP_ERROR_INTERNAL; + } + + if (err != CHIP_NO_ERROR) + { + ChipLogError(Controller, "Failed to validate Attestation Info. Err = %u, %" CHIP_ERROR_FORMAT , static_cast(attestationError), err.Format()); + JniReferences::GetInstance().ThrowError(env, sChipDeviceControllerExceptionCls, err); + } +} + JNI_METHOD(void, unpairDevice)(JNIEnv * env, jobject self, jlong handle, jlong deviceId) { chip::DeviceLayer::StackLock lock; diff --git a/src/controller/java/DeviceAttestationDelegateBridge.cpp b/src/controller/java/DeviceAttestationDelegateBridge.cpp index b57654d18a0415..a297b89e97560a 100644 --- a/src/controller/java/DeviceAttestationDelegateBridge.cpp +++ b/src/controller/java/DeviceAttestationDelegateBridge.cpp @@ -36,12 +36,14 @@ CHIP_ERROR N2J_AttestationInfo(JNIEnv * env, const chip::Credentials::DeviceAtte const ByteSpan DAC = info.dacDerBuffer(); const ByteSpan PAI = info.paiDerBuffer(); const Optional certificationDeclarationSpan = info.cdBuffer(); + uint16_t vendorId = info.BasicInformationVendorId(); + uint16_t productId = info.BasicInformationProductId(); err = JniReferences::GetInstance().GetLocalClassRef(env, "chip/devicecontroller/AttestationInfo", infoClass); SuccessOrExit(err); env->ExceptionClear(); - constructor = env->GetMethodID(infoClass, "", "([B[B[B)V"); + constructor = env->GetMethodID(infoClass, "", "([B[B[BII)V"); VerifyOrExit(constructor != nullptr, err = CHIP_JNI_ERROR_METHOD_NOT_FOUND); err = JniReferences::GetInstance().N2J_ByteArray(env, DAC.data(), static_cast(DAC.size()), javaDAC); @@ -54,7 +56,7 @@ CHIP_ERROR N2J_AttestationInfo(JNIEnv * env, const chip::Credentials::DeviceAtte static_cast(certificationDeclarationSpan.Value().size()), javaCD); SuccessOrExit(err); } - outAttestationInfo = (jobject) env->NewObject(infoClass, constructor, javaDAC, javaPAI, javaCD); + outAttestationInfo = (jobject) env->NewObject(infoClass, constructor, javaDAC, javaPAI, javaCD, static_cast(vendorId), static_cast(productId)); VerifyOrExit(!env->ExceptionCheck(), err = CHIP_JNI_ERROR_EXCEPTION_THROWN); exit: return err; diff --git a/src/controller/java/src/chip/devicecontroller/AttestationInfo.java b/src/controller/java/src/chip/devicecontroller/AttestationInfo.java index 097d6b8ecaf369..47f98583d4bdc3 100644 --- a/src/controller/java/src/chip/devicecontroller/AttestationInfo.java +++ b/src/controller/java/src/chip/devicecontroller/AttestationInfo.java @@ -11,6 +11,8 @@ public final class AttestationInfo { private byte[] pai; private byte[] certificationDeclaration; private byte[] firmwareInfo; + private int vendorId; + private int productId; public AttestationInfo(byte[] dac, byte[] pai, byte[] certificationDeclaration) { this.dac = dac; @@ -18,6 +20,14 @@ public AttestationInfo(byte[] dac, byte[] pai, byte[] certificationDeclaration) this.certificationDeclaration = certificationDeclaration; } + public AttestationInfo(byte[] dac, byte[] pai, byte[] certificationDeclaration, int vendorId, int productId) { + this.dac = dac; + this.pai = pai; + this.certificationDeclaration = certificationDeclaration; + this.vendorId = vendorId; + this.productId = productId; + } + public AttestationInfo( byte[] challenge, byte[] nonce, @@ -37,6 +47,29 @@ public AttestationInfo( this.firmwareInfo = firmwareInfo; } + public AttestationInfo( + byte[] challenge, + byte[] nonce, + byte[] elements, + byte[] elementsSignature, + byte[] dac, + byte[] pai, + byte[] certificationDeclaration, + byte[] firmwareInfo, + int vendorId, + int productId) { + this.challenge = challenge; + this.nonce = nonce; + this.elements = elements; + this.elementsSignature = elementsSignature; + this.dac = dac; + this.pai = pai; + this.certificationDeclaration = certificationDeclaration; + this.firmwareInfo = firmwareInfo; + this.vendorId = vendorId; + this.productId = productId; + } + public byte[] getChallenge() { return challenge; } @@ -68,4 +101,12 @@ public byte[] getCertificationDeclaration() { public byte[] getFirmwareInfo() { return firmwareInfo; } + + public int getVendorId() { + return vendorId; + } + + public int getProductId() { + return productId; + } } diff --git a/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java b/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java index 9e5c6e12f42520..ba6b8163341b7c 100644 --- a/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java +++ b/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java @@ -1314,6 +1314,10 @@ public static native byte[] createOperationalCertificate( */ public native byte[] extractSkidFromPaaCert(byte[] paaCert); + public static native byte[] extractAkidFromPaiCert(byte[] paiCert); + + public static native void validateAttestationInfo(int vendorId, int productId, byte[] paaCert, byte[] paiCert, byte[] dacCert, byte[] attestationElementsBuffer); + /** * Generates a new PASE verifier for the given setup PIN code. * From d1af721246cad9e9ea7852edf188a492ca154ee0 Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Wed, 21 Feb 2024 10:56:53 +0000 Subject: [PATCH 2/9] Restyled by google-java-format --- .../java/src/chip/devicecontroller/AttestationInfo.java | 3 ++- .../src/chip/devicecontroller/ChipDeviceController.java | 8 +++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/controller/java/src/chip/devicecontroller/AttestationInfo.java b/src/controller/java/src/chip/devicecontroller/AttestationInfo.java index 47f98583d4bdc3..a2e15f4d971605 100644 --- a/src/controller/java/src/chip/devicecontroller/AttestationInfo.java +++ b/src/controller/java/src/chip/devicecontroller/AttestationInfo.java @@ -20,7 +20,8 @@ public AttestationInfo(byte[] dac, byte[] pai, byte[] certificationDeclaration) this.certificationDeclaration = certificationDeclaration; } - public AttestationInfo(byte[] dac, byte[] pai, byte[] certificationDeclaration, int vendorId, int productId) { + public AttestationInfo( + byte[] dac, byte[] pai, byte[] certificationDeclaration, int vendorId, int productId) { this.dac = dac; this.pai = pai; this.certificationDeclaration = certificationDeclaration; diff --git a/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java b/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java index ba6b8163341b7c..e26213e55cacf9 100644 --- a/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java +++ b/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java @@ -1316,7 +1316,13 @@ public static native byte[] createOperationalCertificate( public static native byte[] extractAkidFromPaiCert(byte[] paiCert); - public static native void validateAttestationInfo(int vendorId, int productId, byte[] paaCert, byte[] paiCert, byte[] dacCert, byte[] attestationElementsBuffer); + public static native void validateAttestationInfo( + int vendorId, + int productId, + byte[] paaCert, + byte[] paiCert, + byte[] dacCert, + byte[] attestationElementsBuffer); /** * Generates a new PASE verifier for the given setup PIN code. From 4a4d67e313012d3f6583179fb8a5f4462459fb94 Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Wed, 21 Feb 2024 10:56:55 +0000 Subject: [PATCH 3/9] Restyled by clang-format --- .../AndroidOperationalCredentialsIssuer.cpp | 16 +++++--- .../java/CHIPDeviceController-JNI.cpp | 41 +++++++++++-------- .../java/DeviceAttestationDelegateBridge.cpp | 3 +- 3 files changed, 37 insertions(+), 23 deletions(-) diff --git a/src/controller/java/AndroidOperationalCredentialsIssuer.cpp b/src/controller/java/AndroidOperationalCredentialsIssuer.cpp index be980339586a76..7657ca230ecd73 100644 --- a/src/controller/java/AndroidOperationalCredentialsIssuer.cpp +++ b/src/controller/java/AndroidOperationalCredentialsIssuer.cpp @@ -47,7 +47,8 @@ static CHIP_ERROR N2J_CSRInfo(JNIEnv * env, jbyteArray nonce, jbyteArray element static CHIP_ERROR N2J_AttestationInfo(JNIEnv * env, jbyteArray challenge, jbyteArray nonce, jbyteArray elements, jbyteArray elementsSignature, jbyteArray dac, jbyteArray pai, jbyteArray cd, - jbyteArray firmwareInfo, chip::VendorId vendorId, uint16_t productId, jobject & outAttestationInfo); + jbyteArray firmwareInfo, chip::VendorId vendorId, uint16_t productId, + jobject & outAttestationInfo); CHIP_ERROR AndroidOperationalCredentialsIssuer::Initialize(PersistentStorageDelegate & storage, AutoCommissioner * autoCommissioner, jobject javaObjectRef) @@ -271,12 +272,15 @@ CHIP_ERROR AndroidOperationalCredentialsIssuer::CallbackGenerateNOCChain(const B JniReferences::GetInstance().N2J_ByteArray(env, firmwareInfoSpan.data(), static_cast(firmwareInfoSpan.size()), javaFirmwareInfo); - chip::VendorId vendorId = mAutoCommissioner->GetCommissioningParameters().GetRemoteVendorId().ValueOr(chip::VendorId::Unspecified); - uint16_t productId = mAutoCommissioner->GetCommissioningParameters().GetRemoteProductId().ValueOr(0x0000); // 0x0000 is invalid product ID value. + chip::VendorId vendorId = + mAutoCommissioner->GetCommissioningParameters().GetRemoteVendorId().ValueOr(chip::VendorId::Unspecified); + uint16_t productId = + mAutoCommissioner->GetCommissioningParameters().GetRemoteProductId().ValueOr(0x0000); // 0x0000 is invalid product ID value. jobject attestationInfo; err = N2J_AttestationInfo(env, javaAttestationChallenge, javaAttestationNonce, javaAttestationElements, - javaAttestationElementsSignature, javaDAC, javaPAI, javaCD, javaFirmwareInfo, vendorId, productId, attestationInfo); + javaAttestationElementsSignature, javaDAC, javaPAI, javaCD, javaFirmwareInfo, vendorId, productId, + attestationInfo); if (err != CHIP_NO_ERROR) { ChipLogError(Controller, "Failed to create AttestationInfo"); @@ -498,8 +502,8 @@ CHIP_ERROR N2J_AttestationInfo(JNIEnv * env, jbyteArray challenge, jbyteArray no constructor = env->GetMethodID(infoClass, "", "([B[B[B[B[B[B[B[BII)V"); VerifyOrExit(constructor != nullptr, err = CHIP_JNI_ERROR_METHOD_NOT_FOUND); - outAttestationInfo = - (jobject) env->NewObject(infoClass, constructor, challenge, nonce, elements, elementsSignature, dac, pai, cd, firmwareInfo, static_cast(vendorId), static_cast(productId)); + outAttestationInfo = (jobject) env->NewObject(infoClass, constructor, challenge, nonce, elements, elementsSignature, dac, pai, + cd, firmwareInfo, static_cast(vendorId), static_cast(productId)); VerifyOrExit(!env->ExceptionCheck(), err = CHIP_JNI_ERROR_EXCEPTION_THROWN); exit: diff --git a/src/controller/java/CHIPDeviceController-JNI.cpp b/src/controller/java/CHIPDeviceController-JNI.cpp index 4105e3a0388242..b7c4bce4804164 100644 --- a/src/controller/java/CHIPDeviceController-JNI.cpp +++ b/src/controller/java/CHIPDeviceController-JNI.cpp @@ -1303,10 +1303,11 @@ JNI_METHOD(jbyteArray, extractAkidFromPaiCert) } JNI_METHOD(void, validateAttestationInfo) -(JNIEnv * env, jclass clazz, jint vendorId, jint productId, jbyteArray paaCert, jbyteArray paiCert, jbyteArray dacCert, jbyteArray attestationElementsBuffer) +(JNIEnv * env, jclass clazz, jint vendorId, jint productId, jbyteArray paaCert, jbyteArray paiCert, jbyteArray dacCert, + jbyteArray attestationElementsBuffer) { AttestationVerificationResult attestationError = AttestationVerificationResult::kSuccess; - CHIP_ERROR err = CHIP_NO_ERROR; + CHIP_ERROR err = CHIP_NO_ERROR; DeviceInfoForAttestation deviceInfo{ .vendorId = static_cast(vendorId), @@ -1332,36 +1333,42 @@ JNI_METHOD(void, validateAttestationInfo) CertificateChainValidationResult chainValidationResult; err = chip::Crypto::VerifyAttestationCertificateFormat(paiCertBytes.byteSpan(), AttestationCertType::kPAI); - VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Verify PAI Attestation Cert format Error! : %" CHIP_ERROR_FORMAT, err.Format())); + VerifyOrExit(err == CHIP_NO_ERROR, + ChipLogError(Controller, "Verify PAI Attestation Cert format Error! : %" CHIP_ERROR_FORMAT, err.Format())); err = chip::Crypto::VerifyAttestationCertificateFormat(dacCertBytes.byteSpan(), AttestationCertType::kDAC); - VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Verify DAC Attestation Cert format Error! : %" CHIP_ERROR_FORMAT, err.Format())); + VerifyOrExit(err == CHIP_NO_ERROR, + ChipLogError(Controller, "Verify DAC Attestation Cert format Error! : %" CHIP_ERROR_FORMAT, err.Format())); err = chip::Crypto::ExtractVIDPIDFromX509Cert(paaCertBytes.byteSpan(), paaVidPid); - VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Extract VID, PID from PAA Error! : %" CHIP_ERROR_FORMAT, err.Format())); + VerifyOrExit(err == CHIP_NO_ERROR, + ChipLogError(Controller, "Extract VID, PID from PAA Error! : %" CHIP_ERROR_FORMAT, err.Format())); err = chip::Crypto::ExtractVIDPIDFromX509Cert(paiCertBytes.byteSpan(), paiVidPid); - VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Extract VID, PID from PAI Error! : %" CHIP_ERROR_FORMAT, err.Format())); + VerifyOrExit(err == CHIP_NO_ERROR, + ChipLogError(Controller, "Extract VID, PID from PAI Error! : %" CHIP_ERROR_FORMAT, err.Format())); err = chip::Crypto::ExtractVIDPIDFromX509Cert(dacCertBytes.byteSpan(), dacVidPid); - VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Extract VID, PID from DAC Error! : %" CHIP_ERROR_FORMAT, err.Format())); + VerifyOrExit(err == CHIP_NO_ERROR, + ChipLogError(Controller, "Extract VID, PID from DAC Error! : %" CHIP_ERROR_FORMAT, err.Format())); if (paaVidPid.mVendorId.HasValue()) { VerifyOrExit(paaVidPid.mVendorId == paiVidPid.mVendorId, - attestationError = AttestationVerificationResult::kPaiVendorIdMismatch); + attestationError = AttestationVerificationResult::kPaiVendorIdMismatch); } VerifyOrExit(!paaVidPid.mProductId.HasValue(), attestationError = AttestationVerificationResult::kPaaFormatInvalid); - err = chip::Crypto::ValidateCertificateChain(paaCertBytes.byteSpan().data(), paaCertBytes.byteSpan().size(), paiCertBytes.byteSpan().data(), - paiCertBytes.byteSpan().size(), dacCertBytes.byteSpan().data(), dacCertBytes.byteSpan().size(), - chainValidationResult); + err = chip::Crypto::ValidateCertificateChain( + paaCertBytes.byteSpan().data(), paaCertBytes.byteSpan().size(), paiCertBytes.byteSpan().data(), + paiCertBytes.byteSpan().size(), dacCertBytes.byteSpan().data(), dacCertBytes.byteSpan().size(), chainValidationResult); VerifyOrExit(err == CHIP_NO_ERROR, attestationError = static_cast(chainValidationResult)); err = ExtractSKIDFromX509Cert(paaCertBytes.byteSpan(), paaSKID); VerifyOrExit(err == CHIP_NO_ERROR, attestationError = AttestationVerificationResult::kPaaFormatInvalid); - VerifyOrExit(paaSKID.size() == chip::Crypto::kAuthorityKeyIdentifierLength, attestationError = AttestationVerificationResult::kPaaFormatInvalid); + VerifyOrExit(paaSKID.size() == chip::Crypto::kAuthorityKeyIdentifierLength, + attestationError = AttestationVerificationResult::kPaaFormatInvalid); deviceInfo.dacVendorId = dacVidPid.mVendorId.Value(); deviceInfo.dacProductId = dacVidPid.mProductId.Value(); @@ -1386,12 +1393,13 @@ JNI_METHOD(void, validateAttestationInfo) chip::Credentials::DeviceAttestationVerifier * dacVertifier = chip::Credentials::GetDefaultDACVerifier(testingRootStore); err = chip::Credentials::DeconstructAttestationElements(attestationElementsBytes.byteSpan(), certificationDeclarationSpan, - attestationNonceSpan, timestampDeconstructed, firmwareInfoSpan, - vendorReserved); + attestationNonceSpan, timestampDeconstructed, firmwareInfoSpan, + vendorReserved); VerifyOrExit(err == CHIP_NO_ERROR, attestationError = AttestationVerificationResult::kAttestationElementsMalformed); - attestationError = dacVertifier->ValidateCertificationDeclarationSignature(certificationDeclarationSpan, certificationDeclarationPayload); + attestationError = + dacVertifier->ValidateCertificationDeclarationSignature(certificationDeclarationSpan, certificationDeclarationPayload); VerifyOrExit(attestationError == AttestationVerificationResult::kSuccess, err = CHIP_ERROR_INTERNAL); } @@ -1403,7 +1411,8 @@ JNI_METHOD(void, validateAttestationInfo) if (err != CHIP_NO_ERROR) { - ChipLogError(Controller, "Failed to validate Attestation Info. Err = %u, %" CHIP_ERROR_FORMAT , static_cast(attestationError), err.Format()); + ChipLogError(Controller, "Failed to validate Attestation Info. Err = %u, %" CHIP_ERROR_FORMAT, + static_cast(attestationError), err.Format()); JniReferences::GetInstance().ThrowError(env, sChipDeviceControllerExceptionCls, err); } } diff --git a/src/controller/java/DeviceAttestationDelegateBridge.cpp b/src/controller/java/DeviceAttestationDelegateBridge.cpp index a297b89e97560a..4541b5d1ce06ac 100644 --- a/src/controller/java/DeviceAttestationDelegateBridge.cpp +++ b/src/controller/java/DeviceAttestationDelegateBridge.cpp @@ -56,7 +56,8 @@ CHIP_ERROR N2J_AttestationInfo(JNIEnv * env, const chip::Credentials::DeviceAtte static_cast(certificationDeclarationSpan.Value().size()), javaCD); SuccessOrExit(err); } - outAttestationInfo = (jobject) env->NewObject(infoClass, constructor, javaDAC, javaPAI, javaCD, static_cast(vendorId), static_cast(productId)); + outAttestationInfo = (jobject) env->NewObject(infoClass, constructor, javaDAC, javaPAI, javaCD, static_cast(vendorId), + static_cast(productId)); VerifyOrExit(!env->ExceptionCheck(), err = CHIP_JNI_ERROR_EXCEPTION_THROWN); exit: return err; From f64c44f5fa5d48583ced93f65ffb3d2ebe009c67 Mon Sep 17 00:00:00 2001 From: Joonhaeng Heo Date: Thu, 22 Feb 2024 13:32:22 +0900 Subject: [PATCH 4/9] Update VendorId to uint16_t --- .../java/AndroidOperationalCredentialsIssuer.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/controller/java/AndroidOperationalCredentialsIssuer.cpp b/src/controller/java/AndroidOperationalCredentialsIssuer.cpp index 7657ca230ecd73..601073473e6b99 100644 --- a/src/controller/java/AndroidOperationalCredentialsIssuer.cpp +++ b/src/controller/java/AndroidOperationalCredentialsIssuer.cpp @@ -47,7 +47,7 @@ static CHIP_ERROR N2J_CSRInfo(JNIEnv * env, jbyteArray nonce, jbyteArray element static CHIP_ERROR N2J_AttestationInfo(JNIEnv * env, jbyteArray challenge, jbyteArray nonce, jbyteArray elements, jbyteArray elementsSignature, jbyteArray dac, jbyteArray pai, jbyteArray cd, - jbyteArray firmwareInfo, chip::VendorId vendorId, uint16_t productId, + jbyteArray firmwareInfo, uint16_t vendorId, uint16_t productId, jobject & outAttestationInfo); CHIP_ERROR AndroidOperationalCredentialsIssuer::Initialize(PersistentStorageDelegate & storage, AutoCommissioner * autoCommissioner, @@ -272,8 +272,8 @@ CHIP_ERROR AndroidOperationalCredentialsIssuer::CallbackGenerateNOCChain(const B JniReferences::GetInstance().N2J_ByteArray(env, firmwareInfoSpan.data(), static_cast(firmwareInfoSpan.size()), javaFirmwareInfo); - chip::VendorId vendorId = - mAutoCommissioner->GetCommissioningParameters().GetRemoteVendorId().ValueOr(chip::VendorId::Unspecified); + uint16_t vendorId = + mAutoCommissioner->GetCommissioningParameters().GetRemoteVendorId().ValueOr(0x0000); // 0x0000 is Unspecified vendor ID value. uint16_t productId = mAutoCommissioner->GetCommissioningParameters().GetRemoteProductId().ValueOr(0x0000); // 0x0000 is invalid product ID value. @@ -489,7 +489,7 @@ CHIP_ERROR N2J_CSRInfo(JNIEnv * env, jbyteArray nonce, jbyteArray elements, jbyt CHIP_ERROR N2J_AttestationInfo(JNIEnv * env, jbyteArray challenge, jbyteArray nonce, jbyteArray elements, jbyteArray elementsSignature, jbyteArray dac, jbyteArray pai, jbyteArray cd, jbyteArray firmwareInfo, - chip::VendorId vendorId, uint16_t productId, jobject & outAttestationInfo) + uint16_t vendorId, uint16_t productId, jobject & outAttestationInfo) { CHIP_ERROR err = CHIP_NO_ERROR; jmethodID constructor; From a38c3f3b43984160f16fb65e5d8e1190cab0cc86 Mon Sep 17 00:00:00 2001 From: Joonhaeng Heo Date: Fri, 23 Feb 2024 12:02:58 +0900 Subject: [PATCH 5/9] Update from comment --- .../ExampleAttestationTrustStoreDelegate.kt | 3 +- .../AndroidOperationalCredentialsIssuer.cpp | 6 +- src/controller/java/BUILD.gn | 2 + .../java/CHIPDeviceController-JNI.cpp | 179 -------------- src/controller/java/DeviceAttestation-JNI.cpp | 219 ++++++++++++++++++ .../ChipDeviceController.java | 18 +- .../devicecontroller/DeviceAttestation.java | 56 +++++ 7 files changed, 287 insertions(+), 196 deletions(-) create mode 100644 src/controller/java/DeviceAttestation-JNI.cpp create mode 100644 src/controller/java/src/chip/devicecontroller/DeviceAttestation.java diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/attestation/ExampleAttestationTrustStoreDelegate.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/attestation/ExampleAttestationTrustStoreDelegate.kt index f62be2ce7dbbc6..da8e71ea40a624 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/attestation/ExampleAttestationTrustStoreDelegate.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/attestation/ExampleAttestationTrustStoreDelegate.kt @@ -3,6 +3,7 @@ package com.google.chip.chiptool.attestation import android.util.Base64 import chip.devicecontroller.AttestationTrustStoreDelegate import chip.devicecontroller.ChipDeviceController +import chip.devicecontroller.DeviceAttestation import java.util.* class ExampleAttestationTrustStoreDelegate(val chipDeviceController: ChipDeviceController) : @@ -14,7 +15,7 @@ class ExampleAttestationTrustStoreDelegate(val chipDeviceController: ChipDeviceC return paaCerts .map { Base64.decode(it, Base64.DEFAULT) } .firstOrNull { cert -> - Arrays.equals(chipDeviceController.extractSkidFromPaaCert(cert), skid) + Arrays.equals(DeviceAttestation.extractSkidFromPaaCert(cert), skid) } } diff --git a/src/controller/java/AndroidOperationalCredentialsIssuer.cpp b/src/controller/java/AndroidOperationalCredentialsIssuer.cpp index 601073473e6b99..cb1993de31fd46 100644 --- a/src/controller/java/AndroidOperationalCredentialsIssuer.cpp +++ b/src/controller/java/AndroidOperationalCredentialsIssuer.cpp @@ -272,14 +272,14 @@ CHIP_ERROR AndroidOperationalCredentialsIssuer::CallbackGenerateNOCChain(const B JniReferences::GetInstance().N2J_ByteArray(env, firmwareInfoSpan.data(), static_cast(firmwareInfoSpan.size()), javaFirmwareInfo); - uint16_t vendorId = - mAutoCommissioner->GetCommissioningParameters().GetRemoteVendorId().ValueOr(0x0000); // 0x0000 is Unspecified vendor ID value. + chip::VendorId vendorId = + mAutoCommissioner->GetCommissioningParameters().GetRemoteVendorId().ValueOr(chip::VendorId::Unspecified); uint16_t productId = mAutoCommissioner->GetCommissioningParameters().GetRemoteProductId().ValueOr(0x0000); // 0x0000 is invalid product ID value. jobject attestationInfo; err = N2J_AttestationInfo(env, javaAttestationChallenge, javaAttestationNonce, javaAttestationElements, - javaAttestationElementsSignature, javaDAC, javaPAI, javaCD, javaFirmwareInfo, vendorId, productId, + javaAttestationElementsSignature, javaDAC, javaPAI, javaCD, javaFirmwareInfo, static_cast(vendorId), productId, attestationInfo); if (err != CHIP_NO_ERROR) { diff --git a/src/controller/java/BUILD.gn b/src/controller/java/BUILD.gn index 678a03a6bf63bc..e13dc20548b00c 100644 --- a/src/controller/java/BUILD.gn +++ b/src/controller/java/BUILD.gn @@ -63,6 +63,7 @@ shared_library("jni") { "CHIPAttributeTLVValueDecoder.h", "CHIPDeviceController-JNI.cpp", "CHIPEventTLVValueDecoder.h", + "DeviceAttestation-JNI.cpp", "DeviceAttestationDelegateBridge.cpp", "DeviceAttestationDelegateBridge.h", "GroupDeviceProxy.h", @@ -459,6 +460,7 @@ android_library("java") { "src/chip/devicecontroller/ChipDeviceControllerException.java", "src/chip/devicecontroller/ConnectionFailureException.java", "src/chip/devicecontroller/ControllerParams.java", + "src/chip/devicecontroller/DeviceAttestation.java", "src/chip/devicecontroller/DeviceAttestationDelegate.java", "src/chip/devicecontroller/DiscoveredDevice.java", "src/chip/devicecontroller/GetConnectedDeviceCallbackJni.java", diff --git a/src/controller/java/CHIPDeviceController-JNI.cpp b/src/controller/java/CHIPDeviceController-JNI.cpp index b7c4bce4804164..2c352b7f539394 100644 --- a/src/controller/java/CHIPDeviceController-JNI.cpp +++ b/src/controller/java/CHIPDeviceController-JNI.cpp @@ -1238,185 +1238,6 @@ JNI_METHOD(jbyteArray, convertX509CertToMatterCert) return outJbytes; } -JNI_METHOD(jbyteArray, extractSkidFromPaaCert) -(JNIEnv * env, jobject self, jbyteArray paaCert) -{ - uint32_t allocatedCertLength = chip::Credentials::kMaxCHIPCertLength; - chip::Platform::ScopedMemoryBuffer outBuf; - jbyteArray outJbytes = nullptr; - JniByteArray paaCertBytes(env, paaCert); - - CHIP_ERROR err = CHIP_NO_ERROR; - VerifyOrExit(outBuf.Alloc(allocatedCertLength), err = CHIP_ERROR_NO_MEMORY); - { - MutableByteSpan outBytes(outBuf.Get(), allocatedCertLength); - - err = chip::Crypto::ExtractSKIDFromX509Cert(paaCertBytes.byteSpan(), outBytes); - SuccessOrExit(err); - - VerifyOrExit(chip::CanCastTo(outBytes.size()), err = CHIP_ERROR_INTERNAL); - - err = JniReferences::GetInstance().N2J_ByteArray(env, outBytes.data(), static_cast(outBytes.size()), outJbytes); - SuccessOrExit(err); - } - -exit: - if (err != CHIP_NO_ERROR) - { - ChipLogError(Controller, "Failed to extract skid frome X509 cert. Err = %" CHIP_ERROR_FORMAT, err.Format()); - JniReferences::GetInstance().ThrowError(env, sChipDeviceControllerExceptionCls, err); - } - - return outJbytes; -} - -JNI_METHOD(jbyteArray, extractAkidFromPaiCert) -(JNIEnv * env, jclass clazz, jbyteArray paiCert) -{ - uint32_t allocatedCertLength = chip::Credentials::kMaxCHIPCertLength; - chip::Platform::ScopedMemoryBuffer outBuf; - jbyteArray outJbytes = nullptr; - JniByteArray paiCertBytes(env, paiCert); - - CHIP_ERROR err = CHIP_NO_ERROR; - VerifyOrExit(outBuf.Alloc(allocatedCertLength), err = CHIP_ERROR_NO_MEMORY); - { - MutableByteSpan outBytes(outBuf.Get(), allocatedCertLength); - - err = chip::Crypto::ExtractAKIDFromX509Cert(paiCertBytes.byteSpan(), outBytes); - SuccessOrExit(err); - - VerifyOrExit(chip::CanCastTo(outBytes.size()), err = CHIP_ERROR_INTERNAL); - - err = JniReferences::GetInstance().N2J_ByteArray(env, outBytes.data(), static_cast(outBytes.size()), outJbytes); - SuccessOrExit(err); - } - -exit: - if (err != CHIP_NO_ERROR) - { - ChipLogError(Controller, "Failed to extract akid frome X509 cert. Err = %" CHIP_ERROR_FORMAT, err.Format()); - JniReferences::GetInstance().ThrowError(env, sChipDeviceControllerExceptionCls, err); - } - - return outJbytes; -} - -JNI_METHOD(void, validateAttestationInfo) -(JNIEnv * env, jclass clazz, jint vendorId, jint productId, jbyteArray paaCert, jbyteArray paiCert, jbyteArray dacCert, - jbyteArray attestationElementsBuffer) -{ - AttestationVerificationResult attestationError = AttestationVerificationResult::kSuccess; - CHIP_ERROR err = CHIP_NO_ERROR; - - DeviceInfoForAttestation deviceInfo{ - .vendorId = static_cast(vendorId), - .productId = static_cast(productId), - }; - - VerifyOrExit(paaCert != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); - VerifyOrExit(paiCert != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); - VerifyOrExit(dacCert != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); - - { - JniByteArray paaCertBytes(env, paaCert); - JniByteArray paiCertBytes(env, paiCert); - JniByteArray dacCertBytes(env, dacCert); - - AttestationCertVidPid paaVidPid; - AttestationCertVidPid paiVidPid; - AttestationCertVidPid dacVidPid; - - uint8_t skidBuf[chip::Crypto::kAuthorityKeyIdentifierLength]; - MutableByteSpan paaSKID(skidBuf); - - CertificateChainValidationResult chainValidationResult; - - err = chip::Crypto::VerifyAttestationCertificateFormat(paiCertBytes.byteSpan(), AttestationCertType::kPAI); - VerifyOrExit(err == CHIP_NO_ERROR, - ChipLogError(Controller, "Verify PAI Attestation Cert format Error! : %" CHIP_ERROR_FORMAT, err.Format())); - - err = chip::Crypto::VerifyAttestationCertificateFormat(dacCertBytes.byteSpan(), AttestationCertType::kDAC); - VerifyOrExit(err == CHIP_NO_ERROR, - ChipLogError(Controller, "Verify DAC Attestation Cert format Error! : %" CHIP_ERROR_FORMAT, err.Format())); - - err = chip::Crypto::ExtractVIDPIDFromX509Cert(paaCertBytes.byteSpan(), paaVidPid); - VerifyOrExit(err == CHIP_NO_ERROR, - ChipLogError(Controller, "Extract VID, PID from PAA Error! : %" CHIP_ERROR_FORMAT, err.Format())); - - err = chip::Crypto::ExtractVIDPIDFromX509Cert(paiCertBytes.byteSpan(), paiVidPid); - VerifyOrExit(err == CHIP_NO_ERROR, - ChipLogError(Controller, "Extract VID, PID from PAI Error! : %" CHIP_ERROR_FORMAT, err.Format())); - - err = chip::Crypto::ExtractVIDPIDFromX509Cert(dacCertBytes.byteSpan(), dacVidPid); - VerifyOrExit(err == CHIP_NO_ERROR, - ChipLogError(Controller, "Extract VID, PID from DAC Error! : %" CHIP_ERROR_FORMAT, err.Format())); - - if (paaVidPid.mVendorId.HasValue()) - { - VerifyOrExit(paaVidPid.mVendorId == paiVidPid.mVendorId, - attestationError = AttestationVerificationResult::kPaiVendorIdMismatch); - } - - VerifyOrExit(!paaVidPid.mProductId.HasValue(), attestationError = AttestationVerificationResult::kPaaFormatInvalid); - - err = chip::Crypto::ValidateCertificateChain( - paaCertBytes.byteSpan().data(), paaCertBytes.byteSpan().size(), paiCertBytes.byteSpan().data(), - paiCertBytes.byteSpan().size(), dacCertBytes.byteSpan().data(), dacCertBytes.byteSpan().size(), chainValidationResult); - VerifyOrExit(err == CHIP_NO_ERROR, attestationError = static_cast(chainValidationResult)); - - err = ExtractSKIDFromX509Cert(paaCertBytes.byteSpan(), paaSKID); - VerifyOrExit(err == CHIP_NO_ERROR, attestationError = AttestationVerificationResult::kPaaFormatInvalid); - VerifyOrExit(paaSKID.size() == chip::Crypto::kAuthorityKeyIdentifierLength, - attestationError = AttestationVerificationResult::kPaaFormatInvalid); - - deviceInfo.dacVendorId = dacVidPid.mVendorId.Value(); - deviceInfo.dacProductId = dacVidPid.mProductId.Value(); - deviceInfo.paiVendorId = paiVidPid.mVendorId.Value(); - deviceInfo.paiProductId = paiVidPid.mProductId.ValueOr(0); - deviceInfo.paaVendorId = paaVidPid.mVendorId.ValueOr(VendorId::NotSpecified); - } - - { - VerifyOrExit(attestationElementsBuffer != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); - - JniByteArray attestationElementsBytes(env, attestationElementsBuffer); - - ByteSpan certificationDeclarationSpan; - ByteSpan attestationNonceSpan; - uint32_t timestampDeconstructed; - ByteSpan firmwareInfoSpan; - DeviceAttestationVendorReservedDeconstructor vendorReserved; - ByteSpan certificationDeclarationPayload; - - const chip::Credentials::AttestationTrustStore * testingRootStore = chip::Credentials::GetTestAttestationTrustStore(); - chip::Credentials::DeviceAttestationVerifier * dacVertifier = chip::Credentials::GetDefaultDACVerifier(testingRootStore); - - err = chip::Credentials::DeconstructAttestationElements(attestationElementsBytes.byteSpan(), certificationDeclarationSpan, - attestationNonceSpan, timestampDeconstructed, firmwareInfoSpan, - vendorReserved); - - VerifyOrExit(err == CHIP_NO_ERROR, attestationError = AttestationVerificationResult::kAttestationElementsMalformed); - - attestationError = - dacVertifier->ValidateCertificationDeclarationSignature(certificationDeclarationSpan, certificationDeclarationPayload); - VerifyOrExit(attestationError == AttestationVerificationResult::kSuccess, err = CHIP_ERROR_INTERNAL); - } - -exit: - if (err == CHIP_NO_ERROR && attestationError != AttestationVerificationResult::kSuccess) - { - err = CHIP_ERROR_INTERNAL; - } - - if (err != CHIP_NO_ERROR) - { - ChipLogError(Controller, "Failed to validate Attestation Info. Err = %u, %" CHIP_ERROR_FORMAT, - static_cast(attestationError), err.Format()); - JniReferences::GetInstance().ThrowError(env, sChipDeviceControllerExceptionCls, err); - } -} - JNI_METHOD(void, unpairDevice)(JNIEnv * env, jobject self, jlong handle, jlong deviceId) { chip::DeviceLayer::StackLock lock; diff --git a/src/controller/java/DeviceAttestation-JNI.cpp b/src/controller/java/DeviceAttestation-JNI.cpp new file mode 100644 index 00000000000000..4e659d950ca393 --- /dev/null +++ b/src/controller/java/DeviceAttestation-JNI.cpp @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2024 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. + * + */ + +/** + * @file + * Implementation of JNI bridge for Device Attestation + * + */ +#include +#include +#include +#include + +#include +#include +#include +#include + +#define JNI_METHOD(RETURN, METHOD_NAME) \ + extern "C" JNIEXPORT RETURN JNICALL Java_chip_devicecontroller_DeviceAttestation_##METHOD_NAME + +void ThrowException(JNIEnv * env, CHIP_ERROR err); + +JNI_METHOD(jbyteArray, extractSkidFromPaaCert) +(JNIEnv * env, jclass clazz, jbyteArray paaCert) +{ + uint32_t allocatedCertLength = chip::Credentials::kMaxCHIPCertLength; + chip::Platform::ScopedMemoryBuffer outBuf; + jbyteArray outJbytes = nullptr; + chip::JniByteArray paaCertBytes(env, paaCert); + + CHIP_ERROR err = CHIP_NO_ERROR; + VerifyOrExit(outBuf.Alloc(allocatedCertLength), err = CHIP_ERROR_NO_MEMORY); + { + chip::MutableByteSpan outBytes(outBuf.Get(), allocatedCertLength); + + err = chip::Crypto::ExtractSKIDFromX509Cert(paaCertBytes.byteSpan(), outBytes); + SuccessOrExit(err); + + VerifyOrExit(chip::CanCastTo(outBytes.size()), err = CHIP_ERROR_INTERNAL); + + err = chip::JniReferences::GetInstance().N2J_ByteArray(env, outBytes.data(), static_cast(outBytes.size()), outJbytes); + SuccessOrExit(err); + } + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(Controller, "Failed to extract skid frome X509 cert. Err = %" CHIP_ERROR_FORMAT, err.Format()); + ThrowException(env, err); + } + + return outJbytes; +} + +JNI_METHOD(jbyteArray, extractAkidFromPaiCert) +(JNIEnv * env, jclass clazz, jbyteArray paiCert) +{ + uint32_t allocatedCertLength = chip::Credentials::kMaxCHIPCertLength; + chip::Platform::ScopedMemoryBuffer outBuf; + jbyteArray outJbytes = nullptr; + chip::JniByteArray paiCertBytes(env, paiCert); + + CHIP_ERROR err = CHIP_NO_ERROR; + VerifyOrExit(outBuf.Alloc(allocatedCertLength), err = CHIP_ERROR_NO_MEMORY); + { + chip::MutableByteSpan outBytes(outBuf.Get(), allocatedCertLength); + + err = chip::Crypto::ExtractAKIDFromX509Cert(paiCertBytes.byteSpan(), outBytes); + SuccessOrExit(err); + + VerifyOrExit(chip::CanCastTo(outBytes.size()), err = CHIP_ERROR_INTERNAL); + + err = chip::JniReferences::GetInstance().N2J_ByteArray(env, outBytes.data(), static_cast(outBytes.size()), outJbytes); + SuccessOrExit(err); + } + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(Controller, "Failed to extract akid frome X509 cert. Err = %" CHIP_ERROR_FORMAT, err.Format()); + ThrowException(env, err); + } + + return outJbytes; +} + +JNI_METHOD(void, validateAttestationInfo) +(JNIEnv * env, jclass clazz, jint vendorId, jint productId, jbyteArray paaCert, jbyteArray paiCert, jbyteArray dacCert, + jbyteArray attestationElements) +{ + chip::Credentials::AttestationVerificationResult attestationError = chip::Credentials::AttestationVerificationResult::kSuccess; + CHIP_ERROR err = CHIP_NO_ERROR; + + VerifyOrExit(paaCert != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrExit(paiCert != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrExit(dacCert != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); + + { + chip::JniByteArray paaCertBytes(env, paaCert); + chip::JniByteArray paiCertBytes(env, paiCert); + chip::JniByteArray dacCertBytes(env, dacCert); + + chip::Crypto::AttestationCertVidPid paaVidPid; + chip::Crypto::AttestationCertVidPid paiVidPid; + chip::Crypto::AttestationCertVidPid dacVidPid; + + uint8_t skidBuf[chip::Crypto::kAuthorityKeyIdentifierLength]; + chip::MutableByteSpan paaSKID(skidBuf); + + chip::Crypto::CertificateChainValidationResult chainValidationResult; + + err = chip::Crypto::VerifyAttestationCertificateFormat(paiCertBytes.byteSpan(), chip::Crypto::AttestationCertType::kPAI); + VerifyOrExit(err == CHIP_NO_ERROR, + ChipLogError(Controller, "Verify PAI Attestation Cert format Error! : %" CHIP_ERROR_FORMAT, err.Format())); + + err = chip::Crypto::VerifyAttestationCertificateFormat(dacCertBytes.byteSpan(), chip::Crypto::AttestationCertType::kDAC); + VerifyOrExit(err == CHIP_NO_ERROR, + ChipLogError(Controller, "Verify DAC Attestation Cert format Error! : %" CHIP_ERROR_FORMAT, err.Format())); + + err = chip::Crypto::ExtractVIDPIDFromX509Cert(paaCertBytes.byteSpan(), paaVidPid); + VerifyOrExit(err == CHIP_NO_ERROR, + ChipLogError(Controller, "Extract VID, PID from PAA Error! : %" CHIP_ERROR_FORMAT, err.Format())); + + err = chip::Crypto::ExtractVIDPIDFromX509Cert(paiCertBytes.byteSpan(), paiVidPid); + VerifyOrExit(err == CHIP_NO_ERROR, + ChipLogError(Controller, "Extract VID, PID from PAI Error! : %" CHIP_ERROR_FORMAT, err.Format())); + + err = chip::Crypto::ExtractVIDPIDFromX509Cert(dacCertBytes.byteSpan(), dacVidPid); + VerifyOrExit(err == CHIP_NO_ERROR, + ChipLogError(Controller, "Extract VID, PID from DAC Error! : %" CHIP_ERROR_FORMAT, err.Format())); + + if (paaVidPid.mVendorId.HasValue()) + { + VerifyOrExit(paaVidPid.mVendorId == paiVidPid.mVendorId, + attestationError = chip::Credentials::AttestationVerificationResult::kPaiVendorIdMismatch); + } + + VerifyOrExit(!paaVidPid.mProductId.HasValue(), attestationError = chip::Credentials::AttestationVerificationResult::kPaaFormatInvalid); + + err = chip::Crypto::ValidateCertificateChain( + paaCertBytes.byteSpan().data(), paaCertBytes.byteSpan().size(), paiCertBytes.byteSpan().data(), + paiCertBytes.byteSpan().size(), dacCertBytes.byteSpan().data(), dacCertBytes.byteSpan().size(), chainValidationResult); + VerifyOrExit(err == CHIP_NO_ERROR, attestationError = static_cast(chainValidationResult)); + + err = chip::Crypto::ExtractSKIDFromX509Cert(paaCertBytes.byteSpan(), paaSKID); + VerifyOrExit(err == CHIP_NO_ERROR, attestationError = chip::Credentials::AttestationVerificationResult::kPaaFormatInvalid); + VerifyOrExit(paaSKID.size() == chip::Crypto::kAuthorityKeyIdentifierLength, + attestationError = chip::Credentials::AttestationVerificationResult::kPaaFormatInvalid); + } + + { + VerifyOrExit(attestationElements != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); + + chip::JniByteArray attestationElementsBytes(env, attestationElements); + + chip::ByteSpan certificationDeclarationSpan; + chip::ByteSpan attestationNonceSpan; + uint32_t timestampDeconstructed; + chip::ByteSpan firmwareInfoSpan; + chip::Credentials::DeviceAttestationVendorReservedDeconstructor vendorReserved; + chip::ByteSpan certificationDeclarationPayload; + + const chip::Credentials::AttestationTrustStore * testingRootStore = chip::Credentials::GetTestAttestationTrustStore(); + chip::Credentials::DeviceAttestationVerifier * dacVertifier = chip::Credentials::GetDefaultDACVerifier(testingRootStore); + + err = chip::Credentials::DeconstructAttestationElements(attestationElementsBytes.byteSpan(), certificationDeclarationSpan, + attestationNonceSpan, timestampDeconstructed, firmwareInfoSpan, + vendorReserved); + + VerifyOrExit(err == CHIP_NO_ERROR, attestationError = chip::Credentials::AttestationVerificationResult::kAttestationElementsMalformed); + + attestationError = + dacVertifier->ValidateCertificationDeclarationSignature(certificationDeclarationSpan, certificationDeclarationPayload); + VerifyOrExit(attestationError == chip::Credentials::AttestationVerificationResult::kSuccess, err = CHIP_ERROR_INTERNAL); + } + +exit: + if (err == CHIP_NO_ERROR && attestationError != chip::Credentials::AttestationVerificationResult::kSuccess) + { + err = CHIP_ERROR_INTERNAL; + } + + if (err != CHIP_NO_ERROR) + { + ChipLogError(Controller, "Failed to validate Attestation Info. Err = %u, %" CHIP_ERROR_FORMAT, + static_cast(attestationError), err.Format()); + ThrowException(env, err); + } +} + +void ThrowException(JNIEnv * env, CHIP_ERROR err) +{ + jclass controllerExceptionCls; + CHIP_ERROR classRefErr = chip::JniReferences::GetInstance().GetLocalClassRef(env, "chip/devicecontroller/ChipDeviceControllerException", controllerExceptionCls); + + if (classRefErr != CHIP_NO_ERROR) + { + ChipLogError(Controller, "Failed to GetLocalClassRef: %" CHIP_ERROR_FORMAT, classRefErr.Format()); + return; + } + + chip::JniReferences::GetInstance().ThrowError(env, controllerExceptionCls, err); +} diff --git a/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java b/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java index e26213e55cacf9..c9510c2d77d8b6 100644 --- a/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java +++ b/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java @@ -1309,20 +1309,12 @@ public static native byte[] createOperationalCertificate( /** * Extract skid from paa cert. * - * @param paaCert The product attestation authority (PAA) cert - * @return The subject key identifier (SKID) + * This method was deprecated. Please use {@link DeviceAttestation.extractSkidFromPaaCert}. */ - public native byte[] extractSkidFromPaaCert(byte[] paaCert); - - public static native byte[] extractAkidFromPaiCert(byte[] paiCert); - - public static native void validateAttestationInfo( - int vendorId, - int productId, - byte[] paaCert, - byte[] paiCert, - byte[] dacCert, - byte[] attestationElementsBuffer); + @Deprecated + public byte[] extractSkidFromPaaCert(byte[] paaCert) { + return DeviceAttestation.extractSkidFromPaaCert(paaCert); + } /** * Generates a new PASE verifier for the given setup PIN code. diff --git a/src/controller/java/src/chip/devicecontroller/DeviceAttestation.java b/src/controller/java/src/chip/devicecontroller/DeviceAttestation.java new file mode 100644 index 00000000000000..b980e89b32356e --- /dev/null +++ b/src/controller/java/src/chip/devicecontroller/DeviceAttestation.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2024 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. + * + */ + + package chip.devicecontroller; + + public class DeviceAttestation { + /** + * Extract skid from paa cert. + * + * @param paaCert The product attestation authority (PAA) cert + * @return The subject key identifier (SKID) + */ + public static native byte[] extractSkidFromPaaCert(byte[] paaCert); + + /** + * Extract akid from pai cert. + * + * @param paiCert The product attestation intermediate (PAI) cert + * @return The authority key identifier (AKID) + */ + public static native byte[] extractAkidFromPaiCert(byte[] paiCert); + + /** + * Validate device Attestation. If device attestation fails, {@link ChipDeviceControllerException} exception occurs. + * + * @param vendorId Vendor ID from the node + * @param productId Product ID from the node + * @param paaCert The product attestation authority (PAA) cert + * @param paiCert The product attestation intermediate (PAI) cert + * @param dacCert The device attestation certificate (DAC) cert + * @param attestationElements Attestation elements from the node + */ + public static native void validateAttestationInfo( + int vendorId, + int productId, + byte[] paaCert, + byte[] paiCert, + byte[] dacCert, + byte[] attestationElements) throws ChipDeviceControllerException; + } + \ No newline at end of file From 7fd2d02d3a2264d5b9712ce754eb0979c2ac2247 Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Fri, 23 Feb 2024 03:03:28 +0000 Subject: [PATCH 6/9] Restyled by whitespace --- src/controller/java/DeviceAttestation-JNI.cpp | 2 +- .../java/src/chip/devicecontroller/DeviceAttestation.java | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/controller/java/DeviceAttestation-JNI.cpp b/src/controller/java/DeviceAttestation-JNI.cpp index 4e659d950ca393..803d97ed5d46b8 100644 --- a/src/controller/java/DeviceAttestation-JNI.cpp +++ b/src/controller/java/DeviceAttestation-JNI.cpp @@ -208,7 +208,7 @@ void ThrowException(JNIEnv * env, CHIP_ERROR err) { jclass controllerExceptionCls; CHIP_ERROR classRefErr = chip::JniReferences::GetInstance().GetLocalClassRef(env, "chip/devicecontroller/ChipDeviceControllerException", controllerExceptionCls); - + if (classRefErr != CHIP_NO_ERROR) { ChipLogError(Controller, "Failed to GetLocalClassRef: %" CHIP_ERROR_FORMAT, classRefErr.Format()); diff --git a/src/controller/java/src/chip/devicecontroller/DeviceAttestation.java b/src/controller/java/src/chip/devicecontroller/DeviceAttestation.java index b980e89b32356e..59acfe5d9ca3e6 100644 --- a/src/controller/java/src/chip/devicecontroller/DeviceAttestation.java +++ b/src/controller/java/src/chip/devicecontroller/DeviceAttestation.java @@ -17,7 +17,7 @@ */ package chip.devicecontroller; - + public class DeviceAttestation { /** * Extract skid from paa cert. @@ -36,7 +36,7 @@ public class DeviceAttestation { public static native byte[] extractAkidFromPaiCert(byte[] paiCert); /** - * Validate device Attestation. If device attestation fails, {@link ChipDeviceControllerException} exception occurs. + * Validate device Attestation. If device attestation fails, {@link ChipDeviceControllerException} exception occurs. * * @param vendorId Vendor ID from the node * @param productId Product ID from the node @@ -53,4 +53,3 @@ public static native void validateAttestationInfo( byte[] dacCert, byte[] attestationElements) throws ChipDeviceControllerException; } - \ No newline at end of file From 7a6b7890c932d47449ea27838eda7e923094fae7 Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Fri, 23 Feb 2024 03:03:52 +0000 Subject: [PATCH 7/9] Restyled by google-java-format --- .../chip/devicecontroller/ChipDeviceController.java | 2 +- .../src/chip/devicecontroller/DeviceAttestation.java | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java b/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java index c9510c2d77d8b6..341d85d673b1e3 100644 --- a/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java +++ b/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java @@ -1309,7 +1309,7 @@ public static native byte[] createOperationalCertificate( /** * Extract skid from paa cert. * - * This method was deprecated. Please use {@link DeviceAttestation.extractSkidFromPaaCert}. + *

This method was deprecated. Please use {@link DeviceAttestation.extractSkidFromPaaCert}. */ @Deprecated public byte[] extractSkidFromPaaCert(byte[] paaCert) { diff --git a/src/controller/java/src/chip/devicecontroller/DeviceAttestation.java b/src/controller/java/src/chip/devicecontroller/DeviceAttestation.java index 59acfe5d9ca3e6..694635950795f4 100644 --- a/src/controller/java/src/chip/devicecontroller/DeviceAttestation.java +++ b/src/controller/java/src/chip/devicecontroller/DeviceAttestation.java @@ -16,9 +16,9 @@ * */ - package chip.devicecontroller; +package chip.devicecontroller; - public class DeviceAttestation { +public class DeviceAttestation { /** * Extract skid from paa cert. * @@ -36,7 +36,8 @@ public class DeviceAttestation { public static native byte[] extractAkidFromPaiCert(byte[] paiCert); /** - * Validate device Attestation. If device attestation fails, {@link ChipDeviceControllerException} exception occurs. + * Validate device Attestation. If device attestation fails, {@link ChipDeviceControllerException} + * exception occurs. * * @param vendorId Vendor ID from the node * @param productId Product ID from the node @@ -51,5 +52,6 @@ public static native void validateAttestationInfo( byte[] paaCert, byte[] paiCert, byte[] dacCert, - byte[] attestationElements) throws ChipDeviceControllerException; - } + byte[] attestationElements) + throws ChipDeviceControllerException; +} From 474a091940a24727c5fcf19d455c07a94a034212 Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Fri, 23 Feb 2024 03:03:54 +0000 Subject: [PATCH 8/9] Restyled by clang-format --- .../AndroidOperationalCredentialsIssuer.cpp | 7 +++---- src/controller/java/DeviceAttestation-JNI.cpp | 20 ++++++++++++------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/controller/java/AndroidOperationalCredentialsIssuer.cpp b/src/controller/java/AndroidOperationalCredentialsIssuer.cpp index cb1993de31fd46..f4b57e4ebb2ecd 100644 --- a/src/controller/java/AndroidOperationalCredentialsIssuer.cpp +++ b/src/controller/java/AndroidOperationalCredentialsIssuer.cpp @@ -47,8 +47,7 @@ static CHIP_ERROR N2J_CSRInfo(JNIEnv * env, jbyteArray nonce, jbyteArray element static CHIP_ERROR N2J_AttestationInfo(JNIEnv * env, jbyteArray challenge, jbyteArray nonce, jbyteArray elements, jbyteArray elementsSignature, jbyteArray dac, jbyteArray pai, jbyteArray cd, - jbyteArray firmwareInfo, uint16_t vendorId, uint16_t productId, - jobject & outAttestationInfo); + jbyteArray firmwareInfo, uint16_t vendorId, uint16_t productId, jobject & outAttestationInfo); CHIP_ERROR AndroidOperationalCredentialsIssuer::Initialize(PersistentStorageDelegate & storage, AutoCommissioner * autoCommissioner, jobject javaObjectRef) @@ -279,8 +278,8 @@ CHIP_ERROR AndroidOperationalCredentialsIssuer::CallbackGenerateNOCChain(const B jobject attestationInfo; err = N2J_AttestationInfo(env, javaAttestationChallenge, javaAttestationNonce, javaAttestationElements, - javaAttestationElementsSignature, javaDAC, javaPAI, javaCD, javaFirmwareInfo, static_cast(vendorId), productId, - attestationInfo); + javaAttestationElementsSignature, javaDAC, javaPAI, javaCD, javaFirmwareInfo, + static_cast(vendorId), productId, attestationInfo); if (err != CHIP_NO_ERROR) { ChipLogError(Controller, "Failed to create AttestationInfo"); diff --git a/src/controller/java/DeviceAttestation-JNI.cpp b/src/controller/java/DeviceAttestation-JNI.cpp index 803d97ed5d46b8..e41184de774edb 100644 --- a/src/controller/java/DeviceAttestation-JNI.cpp +++ b/src/controller/java/DeviceAttestation-JNI.cpp @@ -54,7 +54,8 @@ JNI_METHOD(jbyteArray, extractSkidFromPaaCert) VerifyOrExit(chip::CanCastTo(outBytes.size()), err = CHIP_ERROR_INTERNAL); - err = chip::JniReferences::GetInstance().N2J_ByteArray(env, outBytes.data(), static_cast(outBytes.size()), outJbytes); + err = + chip::JniReferences::GetInstance().N2J_ByteArray(env, outBytes.data(), static_cast(outBytes.size()), outJbytes); SuccessOrExit(err); } @@ -86,7 +87,8 @@ JNI_METHOD(jbyteArray, extractAkidFromPaiCert) VerifyOrExit(chip::CanCastTo(outBytes.size()), err = CHIP_ERROR_INTERNAL); - err = chip::JniReferences::GetInstance().N2J_ByteArray(env, outBytes.data(), static_cast(outBytes.size()), outJbytes); + err = + chip::JniReferences::GetInstance().N2J_ByteArray(env, outBytes.data(), static_cast(outBytes.size()), outJbytes); SuccessOrExit(err); } @@ -105,7 +107,7 @@ JNI_METHOD(void, validateAttestationInfo) jbyteArray attestationElements) { chip::Credentials::AttestationVerificationResult attestationError = chip::Credentials::AttestationVerificationResult::kSuccess; - CHIP_ERROR err = CHIP_NO_ERROR; + CHIP_ERROR err = CHIP_NO_ERROR; VerifyOrExit(paaCert != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); VerifyOrExit(paiCert != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); @@ -151,12 +153,14 @@ JNI_METHOD(void, validateAttestationInfo) attestationError = chip::Credentials::AttestationVerificationResult::kPaiVendorIdMismatch); } - VerifyOrExit(!paaVidPid.mProductId.HasValue(), attestationError = chip::Credentials::AttestationVerificationResult::kPaaFormatInvalid); + VerifyOrExit(!paaVidPid.mProductId.HasValue(), + attestationError = chip::Credentials::AttestationVerificationResult::kPaaFormatInvalid); err = chip::Crypto::ValidateCertificateChain( paaCertBytes.byteSpan().data(), paaCertBytes.byteSpan().size(), paiCertBytes.byteSpan().data(), paiCertBytes.byteSpan().size(), dacCertBytes.byteSpan().data(), dacCertBytes.byteSpan().size(), chainValidationResult); - VerifyOrExit(err == CHIP_NO_ERROR, attestationError = static_cast(chainValidationResult)); + VerifyOrExit(err == CHIP_NO_ERROR, + attestationError = static_cast(chainValidationResult)); err = chip::Crypto::ExtractSKIDFromX509Cert(paaCertBytes.byteSpan(), paaSKID); VerifyOrExit(err == CHIP_NO_ERROR, attestationError = chip::Credentials::AttestationVerificationResult::kPaaFormatInvalid); @@ -183,7 +187,8 @@ JNI_METHOD(void, validateAttestationInfo) attestationNonceSpan, timestampDeconstructed, firmwareInfoSpan, vendorReserved); - VerifyOrExit(err == CHIP_NO_ERROR, attestationError = chip::Credentials::AttestationVerificationResult::kAttestationElementsMalformed); + VerifyOrExit(err == CHIP_NO_ERROR, + attestationError = chip::Credentials::AttestationVerificationResult::kAttestationElementsMalformed); attestationError = dacVertifier->ValidateCertificationDeclarationSignature(certificationDeclarationSpan, certificationDeclarationPayload); @@ -207,7 +212,8 @@ JNI_METHOD(void, validateAttestationInfo) void ThrowException(JNIEnv * env, CHIP_ERROR err) { jclass controllerExceptionCls; - CHIP_ERROR classRefErr = chip::JniReferences::GetInstance().GetLocalClassRef(env, "chip/devicecontroller/ChipDeviceControllerException", controllerExceptionCls); + CHIP_ERROR classRefErr = chip::JniReferences::GetInstance().GetLocalClassRef( + env, "chip/devicecontroller/ChipDeviceControllerException", controllerExceptionCls); if (classRefErr != CHIP_NO_ERROR) { From 6fdb040e4998d1293f3482514d32909784ffd96d Mon Sep 17 00:00:00 2001 From: Joonhaeng Heo Date: Fri, 23 Feb 2024 12:26:01 +0900 Subject: [PATCH 9/9] Update kotlin codestyle --- .../attestation/ExampleAttestationTrustStoreDelegate.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/attestation/ExampleAttestationTrustStoreDelegate.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/attestation/ExampleAttestationTrustStoreDelegate.kt index da8e71ea40a624..33ad938f144fb9 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/attestation/ExampleAttestationTrustStoreDelegate.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/attestation/ExampleAttestationTrustStoreDelegate.kt @@ -14,9 +14,7 @@ class ExampleAttestationTrustStoreDelegate(val chipDeviceController: ChipDeviceC override fun getProductAttestationAuthorityCert(skid: ByteArray): ByteArray? { return paaCerts .map { Base64.decode(it, Base64.DEFAULT) } - .firstOrNull { cert -> - Arrays.equals(DeviceAttestation.extractSkidFromPaaCert(cert), skid) - } + .firstOrNull { cert -> Arrays.equals(DeviceAttestation.extractSkidFromPaaCert(cert), skid) } } companion object {