JNIDACProvider.cpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. /*
  2. *
  3. * Copyright (c) 2021 Project CHIP Authors
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. #include "JNIDACProvider.h"
  18. #include "lib/support/logging/CHIPLogging.h"
  19. #include <credentials/CHIPCert.h>
  20. #include <crypto/CHIPCryptoPAL.h>
  21. #include <cstdlib>
  22. #include <jni.h>
  23. #include <lib/core/CHIPError.h>
  24. #include <lib/support/CHIPJNIError.h>
  25. #include <lib/support/JniReferences.h>
  26. #include <lib/support/JniTypeWrappers.h>
  27. #include <lib/support/Span.h>
  28. using namespace chip;
  29. JNIDACProvider::JNIDACProvider(jobject provider)
  30. {
  31. JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
  32. VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Failed to GetEnvForCurrentThread for JNIDACProvider"));
  33. mJNIDACProviderObject = env->NewGlobalRef(provider);
  34. VerifyOrReturn(mJNIDACProviderObject != nullptr, ChipLogError(Zcl, "Failed to NewGlobalRef JNIDACProvider"));
  35. jclass JNIDACProviderClass = env->GetObjectClass(provider);
  36. VerifyOrReturn(JNIDACProviderClass != nullptr, ChipLogError(Zcl, "Failed to get JNIDACProvider Java class"));
  37. mGetCertificationDeclarationMethod = env->GetMethodID(JNIDACProviderClass, "GetCertificationDeclaration", "()[B");
  38. if (mGetCertificationDeclarationMethod == nullptr)
  39. {
  40. ChipLogError(Zcl, "Failed to access JNIDACProvider 'GetCertificationDeclaration' method");
  41. env->ExceptionClear();
  42. }
  43. mGetFirmwareInformationMethod = env->GetMethodID(JNIDACProviderClass, "GetFirmwareInformation", "()[B");
  44. if (mGetFirmwareInformationMethod == nullptr)
  45. {
  46. ChipLogError(Zcl, "Failed to access JNIDACProvider 'GetFirmwareInformation' method");
  47. env->ExceptionClear();
  48. }
  49. mGetDeviceAttestationCertMethod = env->GetMethodID(JNIDACProviderClass, "GetDeviceAttestationCert", "()[B");
  50. if (mGetDeviceAttestationCertMethod == nullptr)
  51. {
  52. ChipLogError(Zcl, "Failed to access JNIDACProvider 'GetDeviceAttestationCert' method");
  53. env->ExceptionClear();
  54. }
  55. mGetProductAttestationIntermediateCertMethod =
  56. env->GetMethodID(JNIDACProviderClass, "GetProductAttestationIntermediateCert", "()[B");
  57. if (mGetProductAttestationIntermediateCertMethod == nullptr)
  58. {
  59. ChipLogError(Zcl, "Failed to access JNIDACProvider 'GetProductAttestationIntermediateCert' method");
  60. env->ExceptionClear();
  61. }
  62. mSignWithDeviceAttestationKeyMethod = env->GetMethodID(JNIDACProviderClass, "SignWithDeviceAttestationKey", "([B)[B");
  63. if (mSignWithDeviceAttestationKeyMethod == nullptr)
  64. {
  65. ChipLogError(Zcl, "Failed to access JNIDACProvider 'SignWithDeviceAttestationKey' method");
  66. env->ExceptionClear();
  67. }
  68. }
  69. CHIP_ERROR JNIDACProvider::GetJavaByteByMethod(jmethodID method, MutableByteSpan & out_buffer)
  70. {
  71. JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
  72. VerifyOrReturnLogError(mJNIDACProviderObject != nullptr, CHIP_ERROR_INCORRECT_STATE);
  73. VerifyOrReturnLogError(method != nullptr, CHIP_ERROR_INCORRECT_STATE);
  74. VerifyOrReturnLogError(env != nullptr, CHIP_JNI_ERROR_NO_ENV);
  75. jbyteArray outArray = (jbyteArray) env->CallObjectMethod(mJNIDACProviderObject, method);
  76. if (env->ExceptionCheck())
  77. {
  78. ChipLogError(Zcl, "Java exception in get Method");
  79. env->ExceptionDescribe();
  80. env->ExceptionClear();
  81. return CHIP_ERROR_INCORRECT_STATE;
  82. }
  83. if (outArray == nullptr || env->GetArrayLength(outArray) <= 0)
  84. {
  85. out_buffer.reduce_size(0);
  86. return CHIP_NO_ERROR;
  87. }
  88. JniByteArray JniOutArray(env, outArray);
  89. return CopySpanToMutableSpan(JniOutArray.byteSpan(), out_buffer);
  90. }
  91. CHIP_ERROR JNIDACProvider::GetJavaByteByMethod(jmethodID method, const ByteSpan & in_buffer, MutableByteSpan & out_buffer)
  92. {
  93. JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
  94. VerifyOrReturnLogError(mJNIDACProviderObject != nullptr, CHIP_ERROR_INCORRECT_STATE);
  95. VerifyOrReturnLogError(method != nullptr, CHIP_ERROR_INCORRECT_STATE);
  96. VerifyOrReturnLogError(env != nullptr, CHIP_JNI_ERROR_NO_ENV);
  97. jbyteArray in_buffer_jbyteArray = env->NewByteArray((jsize)(in_buffer.size()));
  98. env->SetByteArrayRegion(in_buffer_jbyteArray, 0, (int) in_buffer.size(), reinterpret_cast<const jbyte *>(in_buffer.data()));
  99. jbyteArray outArray = (jbyteArray) env->CallObjectMethod(mJNIDACProviderObject, method, in_buffer_jbyteArray);
  100. if (env->ExceptionCheck())
  101. {
  102. ChipLogError(Zcl, "Java exception in get Method");
  103. env->ExceptionDescribe();
  104. env->ExceptionClear();
  105. return CHIP_ERROR_INCORRECT_STATE;
  106. }
  107. env->DeleteLocalRef(in_buffer_jbyteArray);
  108. if (outArray == nullptr || env->GetArrayLength(outArray) <= 0)
  109. {
  110. out_buffer.reduce_size(0);
  111. return CHIP_NO_ERROR;
  112. }
  113. JniByteArray JniOutArray(env, outArray);
  114. return CopySpanToMutableSpan(JniOutArray.byteSpan(), out_buffer);
  115. }
  116. CHIP_ERROR JNIDACProvider::GetCertificationDeclaration(MutableByteSpan & out_cd_buffer)
  117. {
  118. ChipLogProgress(Zcl, "Received GetCertificationDeclaration");
  119. return GetJavaByteByMethod(mGetCertificationDeclarationMethod, out_cd_buffer);
  120. }
  121. CHIP_ERROR JNIDACProvider::GetFirmwareInformation(MutableByteSpan & out_firmware_info_buffer)
  122. {
  123. ChipLogProgress(Zcl, "Received GetFirmwareInformation");
  124. return GetJavaByteByMethod(mGetFirmwareInformationMethod, out_firmware_info_buffer);
  125. }
  126. CHIP_ERROR JNIDACProvider::GetDeviceAttestationCert(MutableByteSpan & out_dac_buffer)
  127. {
  128. ChipLogProgress(Zcl, "Received GetDeviceAttestationCert");
  129. return GetJavaByteByMethod(mGetDeviceAttestationCertMethod, out_dac_buffer);
  130. }
  131. CHIP_ERROR JNIDACProvider::GetProductAttestationIntermediateCert(MutableByteSpan & out_pai_buffer)
  132. {
  133. ChipLogProgress(Zcl, "Received GetProductAttestationIntermediateCert");
  134. return GetJavaByteByMethod(mGetProductAttestationIntermediateCertMethod, out_pai_buffer);
  135. }
  136. CHIP_ERROR JNIDACProvider::SignWithDeviceAttestationKey(const ByteSpan & message_to_sign, MutableByteSpan & out_signature_buffer)
  137. {
  138. ChipLogProgress(Zcl, "Received SignWithDeviceAttestationKey");
  139. uint8_t mAsn1SignatureBytes[73];
  140. MutableByteSpan asn1_signature_buffer(mAsn1SignatureBytes, sizeof(mAsn1SignatureBytes));
  141. CHIP_ERROR error = GetJavaByteByMethod(mSignWithDeviceAttestationKeyMethod, message_to_sign, asn1_signature_buffer);
  142. if (error != CHIP_NO_ERROR)
  143. {
  144. ChipLogProgress(Zcl, "SignWithDeviceAttestationKey failed");
  145. return error;
  146. }
  147. return chip::Crypto::EcdsaAsn1SignatureToRaw(32, ByteSpan(asn1_signature_buffer.data(), asn1_signature_buffer.size()),
  148. out_signature_buffer);
  149. }