blob: 056c87c4d1b464c52f2cf33ab7830fa06eb66342 [file] [log] [blame]
/**
*
* Copyright (c) 2023 Project CHIP Authors
*
* 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 "AttestationTrustStoreBridge.h"
#include <credentials/CHIPCert.h>
#include <lib/support/CHIPJNIError.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/JniReferences.h>
#include <lib/support/JniTypeWrappers.h>
#include <lib/support/logging/CHIPLogging.h>
using namespace chip;
AttestationTrustStoreBridge::~AttestationTrustStoreBridge()
{
if (mAttestationTrustStoreDelegate != nullptr)
{
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
VerifyOrReturn(env != nullptr, ChipLogError(Controller, "Could not get JNIEnv for current thread"));
env->DeleteGlobalRef(mAttestationTrustStoreDelegate);
mAttestationTrustStoreDelegate = nullptr;
}
}
CHIP_ERROR AttestationTrustStoreBridge::GetProductAttestationAuthorityCert(const chip::ByteSpan & skid,
chip::MutableByteSpan & outPaaDerBuffer) const
{
VerifyOrReturnError(skid.size() == chip::Crypto::kSubjectKeyIdentifierLength, CHIP_ERROR_INVALID_ARGUMENT);
constexpr size_t paaCertAllocatedLen = chip::Credentials::kMaxDERCertLength;
Platform::ScopedMemoryBuffer<uint8_t> paaCert;
VerifyOrReturnError(paaCert.Alloc(paaCertAllocatedLen), CHIP_ERROR_NO_MEMORY);
MutableByteSpan paaDerBuffer{ paaCert.Get(), paaCertAllocatedLen };
ReturnErrorOnFailure(GetPaaCertFromJava(skid, paaDerBuffer));
uint8_t skidBuf[chip::Crypto::kSubjectKeyIdentifierLength] = { 0 };
chip::MutableByteSpan candidateSkidSpan{ skidBuf };
VerifyOrReturnError(CHIP_NO_ERROR == chip::Crypto::ExtractSKIDFromX509Cert(paaDerBuffer, candidateSkidSpan),
CHIP_ERROR_INTERNAL);
// Make sure the skid of the paa cert is match.
if (skid.data_equal(candidateSkidSpan))
{
// Found a match
return CopySpanToMutableSpan(paaDerBuffer, outPaaDerBuffer);
}
return CHIP_ERROR_CA_CERT_NOT_FOUND;
}
CHIP_ERROR AttestationTrustStoreBridge::GetPaaCertFromJava(const chip::ByteSpan & skid,
chip::MutableByteSpan & outPaaDerBuffer) const
{
jclass attestationTrustStoreDelegateCls = nullptr;
jbyteArray javaSkid = nullptr;
jmethodID getProductAttestationAuthorityCertMethod = nullptr;
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
VerifyOrReturnError(env != nullptr, CHIP_ERROR_INCORRECT_STATE);
JniLocalReferenceScope scope(env);
JniReferences::GetInstance().GetLocalClassRef(env, "chip/devicecontroller/AttestationTrustStoreDelegate",
attestationTrustStoreDelegateCls);
VerifyOrReturnError(attestationTrustStoreDelegateCls != nullptr, CHIP_JNI_ERROR_TYPE_NOT_FOUND);
JniReferences::GetInstance().FindMethod(env, mAttestationTrustStoreDelegate, "getProductAttestationAuthorityCert", "([B)[B",
&getProductAttestationAuthorityCertMethod);
VerifyOrReturnError(getProductAttestationAuthorityCertMethod != nullptr, CHIP_JNI_ERROR_METHOD_NOT_FOUND);
JniReferences::GetInstance().N2J_ByteArray(env, skid.data(), static_cast<jsize>(skid.size()), javaSkid);
VerifyOrReturnError(javaSkid != nullptr, CHIP_ERROR_NO_MEMORY);
jbyteArray javaPaaCert =
(jbyteArray) env->CallObjectMethod(mAttestationTrustStoreDelegate, getProductAttestationAuthorityCertMethod, javaSkid);
VerifyOrReturnError(javaPaaCert != nullptr, CHIP_ERROR_CA_CERT_NOT_FOUND);
JniByteArray paaCertBytes(env, javaPaaCert);
CopySpanToMutableSpan(paaCertBytes.byteSpan(), outPaaDerBuffer);
return CHIP_NO_ERROR;
}