Skip to content

Commit 2580961

Browse files
chrisdecenzorestyled-io[bot]restyled-commits
authored andcommitted
Add parsed attestation and csr info for Android apps (#21648)
* Draft: Add parsed attestation and csr info for Android apps * Restyle Draft: Add parsed attestation and csr info for Android apps (#21649) * Restyled by google-java-format * Restyled by gn Co-authored-by: Restyled.io <commits@restyled.io> * Restyled by google-java-format (#21694) Co-authored-by: Restyled.io <commits@restyled.io> Co-authored-by: restyled-io[bot] <32688539+restyled-io[bot]@users.noreply.github.com> Co-authored-by: Restyled.io <commits@restyled.io>
1 parent faf354e commit 2580961

File tree

5 files changed

+235
-55
lines changed

5 files changed

+235
-55
lines changed

src/controller/java/AndroidOperationalCredentialsIssuer.cpp

+132-25
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "AndroidOperationalCredentialsIssuer.h"
2020
#include <algorithm>
2121
#include <credentials/CHIPCert.h>
22+
#include <credentials/DeviceAttestationConstructor.h>
2223
#include <lib/core/CASEAuthTag.h>
2324
#include <lib/core/CHIPTLV.h>
2425
#include <lib/support/CHIPMem.h>
@@ -30,6 +31,7 @@
3031

3132
#include <lib/support/CHIPJNIError.h>
3233
#include <lib/support/JniReferences.h>
34+
#include <lib/support/JniTypeWrappers.h>
3335

3436
namespace chip {
3537
namespace Controller {
@@ -40,6 +42,13 @@ using namespace Credentials;
4042
using namespace Crypto;
4143
using namespace TLV;
4244

45+
static CHIP_ERROR N2J_CSRInfo(JNIEnv * env, jbyteArray nonce, jbyteArray elements, jbyteArray elementsSignature, jbyteArray csr,
46+
jobject & outCSRInfo);
47+
48+
static CHIP_ERROR N2J_AttestationInfo(JNIEnv * env, jbyteArray challenge, jbyteArray nonce, jbyteArray elements,
49+
jbyteArray elementsSignature, jbyteArray dac, jbyteArray pai, jbyteArray cd,
50+
jbyteArray firmwareInfo, jobject & outAttestationInfo);
51+
4352
CHIP_ERROR AndroidOperationalCredentialsIssuer::Initialize(PersistentStorageDelegate & storage, AutoCommissioner * autoCommissioner,
4453
jobject javaObjectRef)
4554
{
@@ -149,8 +158,9 @@ CHIP_ERROR AndroidOperationalCredentialsIssuer::CallbackGenerateNOCChain(const B
149158
{
150159
jmethodID method;
151160
CHIP_ERROR err = CHIP_NO_ERROR;
152-
err = JniReferences::GetInstance().FindMethod(JniReferences::GetInstance().GetEnvForCurrentThread(), mJavaObjectRef,
153-
"onNOCChainGenerationNeeded", "([B[B[B[B[B[B[B[B[B)V", &method);
161+
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
162+
err = JniReferences::GetInstance().FindMethod(env, mJavaObjectRef, "onNOCChainGenerationNeeded", "([B[B[B[B[B[B[B[B[B)V",
163+
&method);
154164
if (err != CHIP_NO_ERROR)
155165
{
156166
ChipLogError(Controller, "Error invoking onNOCChainGenerationNeeded: %" CHIP_ERROR_FORMAT, err.Format());
@@ -159,52 +169,103 @@ CHIP_ERROR AndroidOperationalCredentialsIssuer::CallbackGenerateNOCChain(const B
159169

160170
mOnNOCCompletionCallback = onCompletion;
161171

162-
JniReferences::GetInstance().GetEnvForCurrentThread()->ExceptionClear();
172+
env->ExceptionClear();
163173

164-
jbyteArray javaCsr;
165-
JniReferences::GetInstance().N2J_ByteArray(JniReferences::GetInstance().GetEnvForCurrentThread(), csrElements.data(),
166-
csrElements.size(), javaCsr);
174+
jbyteArray javaCsrElements;
175+
JniReferences::GetInstance().N2J_ByteArray(env, csrElements.data(), csrElements.size(), javaCsrElements);
167176

168177
jbyteArray javaCsrNonce;
169-
JniReferences::GetInstance().N2J_ByteArray(JniReferences::GetInstance().GetEnvForCurrentThread(), csrNonce.data(),
170-
csrNonce.size(), javaCsrNonce);
178+
JniReferences::GetInstance().N2J_ByteArray(env, csrNonce.data(), csrNonce.size(), javaCsrNonce);
171179

172180
jbyteArray javaCsrSignature;
173-
JniReferences::GetInstance().N2J_ByteArray(JniReferences::GetInstance().GetEnvForCurrentThread(), csrSignature.data(),
174-
csrSignature.size(), javaCsrSignature);
181+
JniReferences::GetInstance().N2J_ByteArray(env, csrSignature.data(), csrSignature.size(), javaCsrSignature);
182+
183+
ChipLogProgress(Controller, "Parsing Certificate Signing Request");
184+
TLVReader reader;
185+
reader.Init(csrElements);
186+
187+
if (reader.GetType() == kTLVType_NotSpecified)
188+
{
189+
ReturnErrorOnFailure(reader.Next());
190+
}
191+
192+
VerifyOrReturnError(reader.GetType() == kTLVType_Structure, CHIP_ERROR_WRONG_TLV_TYPE);
193+
VerifyOrReturnError(reader.GetTag() == AnonymousTag(), CHIP_ERROR_UNEXPECTED_TLV_ELEMENT);
194+
195+
TLVType containerType;
196+
ReturnErrorOnFailure(reader.EnterContainer(containerType));
197+
ReturnErrorOnFailure(reader.Next(kTLVType_ByteString, TLV::ContextTag(1)));
198+
199+
ByteSpan csr(reader.GetReadPoint(), reader.GetLength());
200+
reader.ExitContainer(containerType);
201+
202+
jbyteArray javaCsr;
203+
JniReferences::GetInstance().N2J_ByteArray(env, csr.data(), csr.size(), javaCsr);
204+
205+
jobject csrInfo;
206+
err = N2J_CSRInfo(env, javaCsrNonce, javaCsrElements, javaCsrSignature, javaCsr, csrInfo);
207+
if (err != CHIP_NO_ERROR)
208+
{
209+
ChipLogError(Controller, "Failed to create CSRInfo");
210+
return err;
211+
}
175212

176213
jbyteArray javaAttestationChallenge;
177-
JniReferences::GetInstance().N2J_ByteArray(JniReferences::GetInstance().GetEnvForCurrentThread(), attestationChallenge.data(),
178-
attestationChallenge.size(), javaAttestationChallenge);
214+
JniReferences::GetInstance().N2J_ByteArray(env, attestationChallenge.data(), attestationChallenge.size(),
215+
javaAttestationChallenge);
179216

180217
const ByteSpan & attestationElements = mAutoCommissioner->GetCommissioningParameters().GetAttestationElements().Value();
181218
jbyteArray javaAttestationElements;
182-
JniReferences::GetInstance().N2J_ByteArray(JniReferences::GetInstance().GetEnvForCurrentThread(), attestationElements.data(),
183-
attestationElements.size(), javaAttestationElements);
219+
JniReferences::GetInstance().N2J_ByteArray(env, attestationElements.data(), attestationElements.size(),
220+
javaAttestationElements);
184221

185222
const ByteSpan & attestationNonce = mAutoCommissioner->GetCommissioningParameters().GetAttestationNonce().Value();
186223
jbyteArray javaAttestationNonce;
187-
JniReferences::GetInstance().N2J_ByteArray(JniReferences::GetInstance().GetEnvForCurrentThread(), attestationNonce.data(),
188-
attestationNonce.size(), javaAttestationNonce);
224+
JniReferences::GetInstance().N2J_ByteArray(env, attestationNonce.data(), attestationNonce.size(), javaAttestationNonce);
189225

190226
const ByteSpan & attestationElementsSignature =
191227
mAutoCommissioner->GetCommissioningParameters().GetAttestationSignature().Value();
192228
jbyteArray javaAttestationElementsSignature;
193-
JniReferences::GetInstance().N2J_ByteArray(JniReferences::GetInstance().GetEnvForCurrentThread(),
194-
attestationElementsSignature.data(), attestationElementsSignature.size(),
229+
JniReferences::GetInstance().N2J_ByteArray(env, attestationElementsSignature.data(), attestationElementsSignature.size(),
195230
javaAttestationElementsSignature);
196231

197232
jbyteArray javaDAC;
198-
JniReferences::GetInstance().N2J_ByteArray(JniReferences::GetInstance().GetEnvForCurrentThread(), DAC.data(), DAC.size(),
199-
javaDAC);
233+
JniReferences::GetInstance().N2J_ByteArray(env, DAC.data(), DAC.size(), javaDAC);
200234

201235
jbyteArray javaPAI;
202-
JniReferences::GetInstance().N2J_ByteArray(JniReferences::GetInstance().GetEnvForCurrentThread(), PAI.data(), PAI.size(),
203-
javaPAI);
236+
JniReferences::GetInstance().N2J_ByteArray(env, PAI.data(), PAI.size(), javaPAI);
237+
238+
ByteSpan certificationDeclarationSpan;
239+
ByteSpan attestationNonceSpan;
240+
uint32_t timestampDeconstructed;
241+
ByteSpan firmwareInfoSpan;
242+
DeviceAttestationVendorReservedDeconstructor vendorReserved;
243+
244+
err = DeconstructAttestationElements(attestationElements, certificationDeclarationSpan, attestationNonceSpan,
245+
timestampDeconstructed, firmwareInfoSpan, vendorReserved);
246+
if (err != CHIP_NO_ERROR)
247+
{
248+
ChipLogError(Controller, "Failed to create parse attestation elements");
249+
return err;
250+
}
251+
252+
jbyteArray javaCD;
253+
JniReferences::GetInstance().N2J_ByteArray(env, certificationDeclarationSpan.data(), certificationDeclarationSpan.size(),
254+
javaCD);
204255

205-
JniReferences::GetInstance().GetEnvForCurrentThread()->CallVoidMethod(
206-
mJavaObjectRef, method, javaCsr, javaCsrNonce, javaCsrSignature, javaAttestationChallenge, javaAttestationElements,
207-
javaAttestationNonce, javaAttestationElementsSignature, javaDAC, javaPAI);
256+
jbyteArray javaFirmwareInfo;
257+
JniReferences::GetInstance().N2J_ByteArray(env, firmwareInfoSpan.data(), firmwareInfoSpan.size(), javaFirmwareInfo);
258+
259+
jobject attestationInfo;
260+
err = N2J_AttestationInfo(env, javaAttestationChallenge, javaAttestationNonce, javaAttestationElements,
261+
javaAttestationElementsSignature, javaDAC, javaPAI, javaCD, javaFirmwareInfo, attestationInfo);
262+
if (err != CHIP_NO_ERROR)
263+
{
264+
ChipLogError(Controller, "Failed to create AttestationInfo");
265+
return err;
266+
}
267+
268+
env->CallVoidMethod(mJavaObjectRef, method, csrInfo, attestationInfo);
208269
return CHIP_NO_ERROR;
209270
}
210271

@@ -312,5 +373,51 @@ CHIP_ERROR AndroidOperationalCredentialsIssuer::LocalGenerateNOCChain(const Byte
312373
return CHIP_NO_ERROR;
313374
}
314375

376+
CHIP_ERROR N2J_CSRInfo(JNIEnv * env, jbyteArray nonce, jbyteArray elements, jbyteArray elementsSignature, jbyteArray csr,
377+
jobject & outCSRInfo)
378+
{
379+
CHIP_ERROR err = CHIP_NO_ERROR;
380+
jmethodID constructor;
381+
jclass infoClass;
382+
383+
err = JniReferences::GetInstance().GetClassRef(env, "chip/devicecontroller/CSRInfo", infoClass);
384+
JniClass attestationInfoClass(infoClass);
385+
SuccessOrExit(err);
386+
387+
env->ExceptionClear();
388+
constructor = env->GetMethodID(infoClass, "<init>", "([B[B[B[B)V");
389+
VerifyOrExit(constructor != nullptr, err = CHIP_JNI_ERROR_METHOD_NOT_FOUND);
390+
391+
outCSRInfo = (jobject) env->NewObject(infoClass, constructor, nonce, elements, elementsSignature, csr);
392+
393+
VerifyOrExit(!env->ExceptionCheck(), err = CHIP_JNI_ERROR_EXCEPTION_THROWN);
394+
exit:
395+
return err;
396+
}
397+
398+
CHIP_ERROR N2J_AttestationInfo(JNIEnv * env, jbyteArray challenge, jbyteArray nonce, jbyteArray elements,
399+
jbyteArray elementsSignature, jbyteArray dac, jbyteArray pai, jbyteArray cd, jbyteArray firmwareInfo,
400+
jobject & outAttestationInfo)
401+
{
402+
CHIP_ERROR err = CHIP_NO_ERROR;
403+
jmethodID constructor;
404+
jclass infoClass;
405+
406+
err = JniReferences::GetInstance().GetClassRef(env, "chip/devicecontroller/AttestationInfo", infoClass);
407+
JniClass attestationInfoClass(infoClass);
408+
SuccessOrExit(err);
409+
410+
env->ExceptionClear();
411+
constructor = env->GetMethodID(infoClass, "<init>", "([B[B[B[B[B[B[B[B)V");
412+
VerifyOrExit(constructor != nullptr, err = CHIP_JNI_ERROR_METHOD_NOT_FOUND);
413+
414+
outAttestationInfo =
415+
(jobject) env->NewObject(infoClass, constructor, challenge, nonce, elements, elementsSignature, dac, pai, cd, firmwareInfo);
416+
417+
VerifyOrExit(!env->ExceptionCheck(), err = CHIP_JNI_ERROR_EXCEPTION_THROWN);
418+
exit:
419+
return err;
420+
}
421+
315422
} // namespace Controller
316423
} // namespace chip

src/controller/java/BUILD.gn

+2
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ android_library("java") {
8484
"src/chip/clusterinfo/CommandResponseInfo.java",
8585
"src/chip/clusterinfo/DelegatedClusterCallback.java",
8686
"src/chip/clusterinfo/InteractionInfo.java",
87+
"src/chip/devicecontroller/AttestationInfo.java",
88+
"src/chip/devicecontroller/CSRInfo.java",
8789
"src/chip/devicecontroller/ChipClusterException.java",
8890
"src/chip/devicecontroller/ChipCommandType.java",
8991
"src/chip/devicecontroller/ChipDeviceController.java",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package chip.devicecontroller;
2+
3+
/** Represents information relating to product attestation. */
4+
public final class AttestationInfo {
5+
6+
private byte[] challenge;
7+
private byte[] nonce;
8+
private byte[] elements;
9+
private byte[] elementsSignature;
10+
private byte[] dac;
11+
private byte[] pai;
12+
private byte[] certificationDeclaration;
13+
private byte[] firmwareInfo;
14+
15+
public AttestationInfo(
16+
byte[] challenge,
17+
byte[] nonce,
18+
byte[] elements,
19+
byte[] elementsSignature,
20+
byte[] dac,
21+
byte[] pai,
22+
byte[] certificationDeclaration,
23+
byte[] firmwareInfo) {
24+
this.challenge = challenge;
25+
this.nonce = nonce;
26+
this.elements = elements;
27+
this.elementsSignature = elementsSignature;
28+
this.dac = dac;
29+
this.pai = pai;
30+
this.certificationDeclaration = certificationDeclaration;
31+
this.firmwareInfo = firmwareInfo;
32+
}
33+
34+
public byte[] getChallenge() {
35+
return challenge;
36+
}
37+
38+
public byte[] getNonce() {
39+
return nonce;
40+
}
41+
42+
public byte[] getElements() {
43+
return elements;
44+
}
45+
46+
public byte[] getElementsSignature() {
47+
return elementsSignature;
48+
}
49+
50+
public byte[] getDAC() {
51+
return dac;
52+
}
53+
54+
public byte[] getPAI() {
55+
return pai;
56+
}
57+
58+
public byte[] getCertificationDeclaration() {
59+
return certificationDeclaration;
60+
}
61+
62+
public byte[] getFirmwareInfo() {
63+
return firmwareInfo;
64+
}
65+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package chip.devicecontroller;
2+
3+
/** Represents information relating to NOC CSR. */
4+
public final class CSRInfo {
5+
6+
private byte[] nonce;
7+
private byte[] elements;
8+
private byte[] elementsSignature;
9+
private byte[] csr;
10+
11+
public CSRInfo(byte[] nonce, byte[] elements, byte[] elementsSignature, byte[] csr) {
12+
this.nonce = nonce;
13+
this.elements = elements;
14+
this.elementsSignature = elementsSignature;
15+
this.csr = csr;
16+
}
17+
18+
public byte[] getNonce() {
19+
return nonce;
20+
}
21+
22+
public byte[] getElements() {
23+
return elements;
24+
}
25+
26+
public byte[] getElementsSignature() {
27+
return elementsSignature;
28+
}
29+
30+
public byte[] getCSR() {
31+
return csr;
32+
}
33+
}

src/controller/java/src/chip/devicecontroller/ChipDeviceController.java

+3-30
Original file line numberDiff line numberDiff line change
@@ -349,27 +349,9 @@ public void onError(Throwable error) {
349349
completionListener.onError(error);
350350
}
351351

352-
public void onNOCChainGenerationNeeded(
353-
byte[] csrElements,
354-
byte[] csrNonce,
355-
byte[] csrElementsSignature,
356-
byte[] attestationChallenge,
357-
byte[] attestationElements,
358-
byte[] attestationNonce,
359-
byte[] attestationElementsSignature,
360-
byte[] dac,
361-
byte[] pai) {
352+
public void onNOCChainGenerationNeeded(CSRInfo csrInfo, AttestationInfo attestationInfo) {
362353
if (nocChainIssuer != null) {
363-
nocChainIssuer.onNOCChainGenerationNeeded(
364-
csrElements,
365-
csrNonce,
366-
csrElementsSignature,
367-
attestationChallenge,
368-
attestationElements,
369-
attestationNonce,
370-
attestationElementsSignature,
371-
dac,
372-
pai);
354+
nocChainIssuer.onNOCChainGenerationNeeded(csrInfo, attestationInfo);
373355
}
374356
}
375357

@@ -739,16 +721,7 @@ public interface NOCChainIssuer {
739721
*
740722
* <p>All csr and attestation fields are provided to allow for custom attestestation checks.
741723
*/
742-
void onNOCChainGenerationNeeded(
743-
byte[] csrElements,
744-
byte[] csrNonce,
745-
byte[] csrElementsSignature,
746-
byte[] attestationChallenge,
747-
byte[] attestationElements,
748-
byte[] attestationNonce,
749-
byte[] attestationElementsSignature,
750-
byte[] dac,
751-
byte[] pai);
724+
void onNOCChainGenerationNeeded(CSRInfo csrInfo, AttestationInfo attestationInfo);
752725
}
753726

754727
/**

0 commit comments

Comments
 (0)