Skip to content

Commit 550b207

Browse files
1. Updated the SignedData payload as per the specification changes.
2. Removed the certType from DeviceInfo.
1 parent 96b742f commit 550b207

10 files changed

+218
-373
lines changed

Applet/JCardSimProvider/test/com/android/javacard/test/KMFunctionalTest.java

+14-3
Original file line numberDiff line numberDiff line change
@@ -2350,16 +2350,27 @@ public ResponseAPDU importWrappedKey() {
23502350
Util.arrayCopyNonAtomic(output, (short) 0, encTransportKey, (short) 0,
23512351
outlen);
23522352
// Begn Import wrapped key.
2353-
short nullParams = KMArray.instance((short) 0);
2354-
nullParams = KMKeyParameters.instance(nullParams);
2353+
// Unwrapping params should have Digest: SHA256 and padding as RSA_OAEP
2354+
short unwrappingParamsArr = KMArray.instance((short) 2);
2355+
// RSA OAEP Padding
2356+
short paddingBlob = KMByteBlob.instance((short) 1);
2357+
KMByteBlob.cast(paddingBlob).add((short) 0, KMType.RSA_OAEP);
2358+
short padding = KMEnumArrayTag.instance(KMType.PADDING, paddingBlob);
2359+
// SHA256 digest
2360+
short digestBlob = KMByteBlob.instance((short) 1);
2361+
KMByteBlob.cast(digestBlob).add((short) 0, KMType.SHA2_256);
2362+
short digest = KMEnumArrayTag.instance(KMType.DIGEST, digestBlob);
2363+
KMArray.cast(unwrappingParamsArr).add((short) 0, padding);
2364+
KMArray.cast(unwrappingParamsArr).add((short) 1, digest);
2365+
short unwrappingParams = KMKeyParameters.instance(unwrappingParamsArr);
23552366
short arr = KMArray.instance((short) 4);
23562367
KMArray.cast(arr).add((short) 0, KMByteBlob.instance(encTransportKey, (short) 0,
23572368
(short) encTransportKey.length)); // Encrypted Transport Key
23582369
KMArray.cast(arr).add((short) 1, KMByteBlob.instance(wrappingKeyBlob, (short) 0,
23592370
(short) wrappingKeyBlob.length)); // Wrapping Key KeyBlob
23602371
KMArray.cast(arr).add((short) 2, KMByteBlob.instance(maskingKey, (short) 0,
23612372
(short) maskingKey.length)); // Masking Key
2362-
KMArray.cast(arr).add((short) 3, nullParams); // unwrapping params
2373+
KMArray.cast(arr).add((short) 3, unwrappingParams); // unwrapping params
23632374
CommandAPDU apdu = KMTestUtils.encodeApdu(encoder, (byte) INS_BEGIN_IMPORT_WRAPPED_KEY_CMD,
23642375
arr);
23652376
ResponseAPDU response = simulator.transmitCommand(apdu);

Applet/JCardSimProvider/test/com/android/javacard/test/KMRKPFunctionalTest.java

+139-114
Original file line numberDiff line numberDiff line change
@@ -17,34 +17,30 @@
1717
package com.android.javacard.test;
1818

1919
import com.android.javacard.keymaster.KMArray;
20-
import com.android.javacard.keymaster.KMAsn1Parser;
2120
import com.android.javacard.keymaster.KMByteBlob;
2221
import com.android.javacard.keymaster.KMCose;
2322
import com.android.javacard.keymaster.KMCoseHeaders;
2423
import com.android.javacard.keymaster.KMCoseKey;
24+
import com.android.javacard.keymaster.KMDecoder;
25+
import com.android.javacard.keymaster.KMEncoder;
26+
import com.android.javacard.keymaster.KMError;
27+
import com.android.javacard.keymaster.KMInteger;
28+
import com.android.javacard.keymaster.KMJCardSimApplet;
29+
import com.android.javacard.keymaster.KMKeymasterApplet;
2530
import com.android.javacard.keymaster.KMMap;
2631
import com.android.javacard.keymaster.KMNInteger;
2732
import com.android.javacard.keymaster.KMRepository;
2833
import com.android.javacard.keymaster.KMSimpleValue;
29-
import com.android.javacard.keymaster.KMJCardSimApplet;
30-
import com.android.javacard.keymaster.KMKeymasterApplet;
3134
import com.android.javacard.keymaster.KMTextString;
35+
import com.android.javacard.keymaster.KMType;
3236
import com.android.javacard.seprovider.KMJCardSimulator;
3337
import com.android.javacard.seprovider.KMSEProvider;
34-
import com.android.javacard.keymaster.KMDecoder;
35-
import com.android.javacard.keymaster.KMEncoder;
36-
import com.android.javacard.keymaster.KMError;
37-
import com.android.javacard.keymaster.KMInteger;
38-
import com.android.javacard.keymaster.KMType;
3938
import com.licel.jcardsim.smartcardio.CardSimulator;
4039
import com.licel.jcardsim.utils.AIDUtil;
41-
4240
import javacard.framework.AID;
4341
import javacard.framework.Util;
44-
4542
import javax.smartcardio.CommandAPDU;
4643
import javax.smartcardio.ResponseAPDU;
47-
4844
import org.junit.Assert;
4945
import org.junit.Test;
5046

@@ -298,24 +294,26 @@ public void testGenerateCsr(short no_keys) {
298294

299295
// challenge
300296
short challenge = KMByteBlob.instance(CSR_CHALLENGE, (short) 0, (short) CSR_CHALLENGE.length);
301-
297+
302298
// begin send data
303299
short arr = KMArray.instance((short) 3);
304300
KMArray.cast(arr).add((short) 0, KMInteger.uint_8((byte) no_keys));
305301
KMArray.cast(arr).add((short) 1, KMInteger.uint_16(totalEncodedCoseKeysLen));
306302
KMArray.cast(arr).add((short) 2, challenge);
307-
303+
308304
CommandAPDU apdu = KMTestUtils.encodeApdu(encoder, (byte) INS_BEGIN_SEND_DATA_CMD, arr);
309305
ResponseAPDU response = simulator.transmitCommand(apdu);
310306
byte[] resp = response.getBytes();
311-
arr = KMArray.instance((short) 2);
307+
arr = KMArray.instance((short) 4);
312308
KMArray.cast(arr).add((short) 0, KMInteger.exp()); // OK
313309
KMArray.cast(arr).add((short) 1, KMByteBlob.exp()); // deviceInfo
310+
KMArray.cast(arr).add((short) 2, KMInteger.exp()); // version
311+
KMArray.cast(arr).add((short) 3, KMTextString.exp()); // certType
314312
ret = decoder.decode(arr, resp, (short) 0, (short) resp.length);
315313
Assert.assertEquals(KMTestUtils.getErrorCode(ret), KMError.OK);
316-
314+
317315
// get device info
318-
short deviceInfo = KMArray.cast(ret).get((short) 1);
316+
short deviceInfo = KMArray.cast(ret).get((short) 1);
319317
byte[] deviceInfoBytes = new byte[512];
320318
Util.arrayCopyNonAtomic(KMByteBlob.cast(deviceInfo).getBuffer(),
321319
KMByteBlob.cast(deviceInfo).getStartOff(),
@@ -324,12 +322,22 @@ public void testGenerateCsr(short no_keys) {
324322
KMByteBlob.cast(deviceInfo).length());
325323
short deviceInfoBytesLen = KMByteBlob.cast(deviceInfo).length();
326324

325+
short schemaVersion = KMArray.cast(ret).get((short) 2);
326+
schemaVersion = KMInteger.cast(schemaVersion).getShort();
327+
328+
short certType = KMArray.cast(ret).get((short) 3);
329+
short certTypeLen = KMTextString.cast(certType).length();
330+
byte[] cerTypeBytes = new byte[certTypeLen];
331+
Util.arrayCopyNonAtomic(KMTextString.cast(certType).getBuffer(),
332+
KMTextString.cast(certType).getStartOff(), cerTypeBytes, (short) 0,
333+
KMTextString.cast(certType).length());
334+
327335
// update data.
328336
short cKey;
329-
byte[]cosyKeyArrayBytes = new byte[2048];
337+
byte[] cosyKeyArrayBytes = new byte[2048];
330338
short coseKeyBytesLen = 0;
331339
coseKeyBytesLen +=
332-
encoder.encodeArrayHeader(no_keys, cosyKeyArrayBytes, coseKeyBytesLen, (short) 3);
340+
encoder.encodeArrayHeader(no_keys, cosyKeyArrayBytes, coseKeyBytesLen, (short) 3);
333341
for (short i = 0; i < no_keys; i++) {
334342
coseMacPtr = KMTestUtils.decodeCoseMac(decoder, mackedKeys[i], (short) 0,
335343
(short) mackedKeys[i].length);
@@ -343,25 +351,25 @@ public void testGenerateCsr(short no_keys) {
343351
KMArray.cast(arr).add((short) 1, KMByteBlob.exp()); // cosekey
344352
ret = decoder.decode(arr, resp, (short) 0, (short) resp.length);
345353
Assert.assertEquals(KMTestUtils.getErrorCode(ret), KMError.OK);
346-
354+
347355
// get cose keys in cosyKeyArrayBytes byte array
348356
cKey = KMArray.cast(ret).get((short) 1);
349357
Util.arrayCopyNonAtomic(KMByteBlob.cast(cKey).getBuffer(),
350-
KMByteBlob.cast(cKey).getStartOff(),
351-
cosyKeyArrayBytes,
352-
coseKeyBytesLen,
353-
KMByteBlob.cast(cKey).length());
358+
KMByteBlob.cast(cKey).getStartOff(),
359+
cosyKeyArrayBytes,
360+
coseKeyBytesLen,
361+
KMByteBlob.cast(cKey).length());
354362
coseKeyBytesLen += KMByteBlob.cast(cKey).length();
355363
}
356364

357365
//Clean the heap.
358366
KMRepository.instance().clean();
359-
367+
360368
// finish
361369
// Extended length.
362370
apdu = new CommandAPDU(0x80, INS_FINISH_SEND_DATA_CMD, 0x50, 0x00, (byte[]) null, 65536);
363371
response = simulator.transmitCommand(apdu);
364-
372+
365373
short coseHeadersExp = KMCoseHeaders.exp();
366374
arr = KMArray.instance((short) 5);
367375
KMArray.cast(arr).add((short) 0, KMInteger.exp()); // OK
@@ -376,58 +384,72 @@ public void testGenerateCsr(short no_keys) {
376384
short protectedHeaders = KMArray.cast(ret).get((short) 1);
377385
short signatureData = KMArray.cast(ret).get((short) 2);
378386
short version = KMArray.cast(ret).get((short) 3);
379-
387+
380388
byte[] signature = new byte[512];
381389
Util.arrayCopyNonAtomic(KMByteBlob.cast(signatureData).getBuffer(),
382-
KMByteBlob.cast(signatureData).getStartOff(),
383-
signature,
384-
(short)0,
385-
KMByteBlob.cast(signatureData).length());
390+
KMByteBlob.cast(signatureData).getStartOff(),
391+
signature,
392+
(short) 0,
393+
KMByteBlob.cast(signatureData).length());
386394
short signatureLen = KMByteBlob.cast(signatureData).length();
387-
388-
byte[] tmp = new byte[10];
395+
396+
byte[] tmp = new byte[10];
389397
byte[] payload = new byte[2048];
390398
short payloadLen = 0;
391-
392-
short aad = KMByteBlob.instance(tmp, (short) 0, (short) 0);
393-
// construct cose sign structure
399+
400+
short aad = KMByteBlob.instance(tmp, (short) 0, (short) 0);
401+
// construct cose sign structure
394402
short signStructure =
395-
KMCose.constructCoseSignStructure(protectedHeaders, aad, KMType.INVALID_VALUE);
403+
KMCose.constructCoseSignStructure(protectedHeaders, aad, KMType.INVALID_VALUE);
396404
//encode sign structure to paload byte array
397-
payloadLen = KMKeymasterApplet.encodeToApduBuffer(signStructure, payload,
398-
(short) 0, KMKeymasterApplet.MAX_COSE_BUF_SIZE);
399-
400-
short payloadByteLen = (short)((short)1 /*Array of 3 elements occupies 1 byte */+
401-
deviceInfoBytesLen +
402-
encoder.getEncodedBytesLength((short)CSR_CHALLENGE.length) +
403-
(short)CSR_CHALLENGE.length +
404-
coseKeyBytesLen);
405-
405+
payloadLen = KMKeymasterApplet.encodeToApduBuffer(signStructure, payload,
406+
(short) 0, KMKeymasterApplet.MAX_COSE_BUF_SIZE);
407+
408+
short payloadByteLen = (short) ((short) 1 /*Array of 5 elements occupies 1 byte */ +
409+
(short) 1 + // Version occupies 1 byte
410+
encoder.getEncodedBytesLength(certTypeLen) +
411+
certTypeLen +
412+
deviceInfoBytesLen +
413+
encoder.getEncodedBytesLength((short) CSR_CHALLENGE.length) +
414+
(short) CSR_CHALLENGE.length +
415+
coseKeyBytesLen);
416+
406417
payloadLen += encoder.encodeByteBlobHeader(payloadByteLen, payload, payloadLen, (short) 3);
407-
payloadLen += encoder.encodeArrayHeader((short)3, payload, payloadLen, (short) 3);
418+
payloadLen += encoder.encodeArrayHeader((short) 5, payload, payloadLen, (short) 3);
419+
420+
short payloadSchemaVersion = KMInteger.uint_16(schemaVersion);
421+
payloadLen +=
422+
encoder.encode(payloadSchemaVersion, payload, payloadLen,
423+
KMKeymasterApplet.MAX_COSE_BUF_SIZE);
424+
425+
short certTypeTstr = KMTextString.instance(cerTypeBytes, (short) 0, certTypeLen);
426+
payloadLen +=
427+
encoder.encode(certTypeTstr, payload, payloadLen, KMKeymasterApplet.MAX_COSE_BUF_SIZE);
428+
408429
Util.arrayCopyNonAtomic(deviceInfoBytes,
409-
(short)0,
410-
payload,
411-
payloadLen,
412-
deviceInfoBytesLen);
430+
(short) 0,
431+
payload,
432+
payloadLen,
433+
deviceInfoBytesLen);
413434
payloadLen += deviceInfoBytesLen;
414-
415-
payloadLen += encoder.encodeByteBlobHeader((short)CSR_CHALLENGE.length, payload, payloadLen, (short) 3);
416-
435+
436+
payloadLen += encoder.encodeByteBlobHeader((short) CSR_CHALLENGE.length, payload, payloadLen,
437+
(short) 3);
438+
417439
Util.arrayCopyNonAtomic(CSR_CHALLENGE,
418-
(short)0,
419-
payload,
420-
payloadLen,
421-
(short)CSR_CHALLENGE.length);
422-
payloadLen += (short)CSR_CHALLENGE.length;
423-
440+
(short) 0,
441+
payload,
442+
payloadLen,
443+
(short) CSR_CHALLENGE.length);
444+
payloadLen += (short) CSR_CHALLENGE.length;
445+
424446
Util.arrayCopyNonAtomic(cosyKeyArrayBytes,
425-
(short)0,
426-
payload,
427-
payloadLen,
428-
coseKeyBytesLen);
447+
(short) 0,
448+
payload,
449+
payloadLen,
450+
coseKeyBytesLen);
429451
payloadLen += coseKeyBytesLen;
430-
452+
431453
byte moreData;
432454
byte[] udsCerts = new byte[2500];
433455
short offset = 0;
@@ -443,10 +465,11 @@ public void testGenerateCsr(short no_keys) {
443465
ret = decoder.decode(arr, resp, (short) 0, (short) resp.length);
444466
Assert.assertEquals(KMTestUtils.getErrorCode(ret), KMError.OK);
445467
short partialData = KMArray.cast(ret).get((short) 1);
446-
Util.arrayCopyNonAtomic(KMByteBlob.cast(partialData).getBuffer(), KMByteBlob.cast(partialData).getStartOff(),
468+
Util.arrayCopyNonAtomic(KMByteBlob.cast(partialData).getBuffer(),
469+
KMByteBlob.cast(partialData).getStartOff(),
447470
udsCerts, offset, KMByteBlob.cast(partialData).length());
448471
offset += KMByteBlob.cast(partialData).length();
449-
472+
450473
moreData = KMInteger.cast(KMArray.cast(ret).get((short) 2)).getByte();
451474
} while (moreData != 0);
452475
short x509Arr = KMArray.exp(KMByteBlob.exp());
@@ -460,54 +483,56 @@ public void testGenerateCsr(short no_keys) {
460483
byte[] diceCerts = new byte[2500];
461484
offset = 0;
462485
do {
463-
apdu = new CommandAPDU(0x80, INS_GET_DICE_CERT_CHAIN_CMD, 0x50, 0x00, (byte[]) null, 65536);// BCC
464-
response = simulator.transmitCommand(apdu);
465-
arr = KMArray.instance((short) 3);
466-
KMArray.cast(arr).add((short) 0, KMInteger.exp()); // OK
467-
KMArray.cast(arr).add((short) 1, KMByteBlob.exp()); // data
468-
KMArray.cast(arr).add((short) 2, KMInteger.exp()); // more data
469-
resp = response.getBytes();
470-
ret = decoder.decode(arr, resp, (short) 0, (short) resp.length);
471-
Assert.assertEquals(KMTestUtils.getErrorCode(ret), KMError.OK);
472-
short partialData = KMArray.cast(ret).get((short) 1);
473-
Util.arrayCopyNonAtomic(KMByteBlob.cast(partialData).getBuffer(), KMByteBlob.cast(partialData).getStartOff(),
474-
diceCerts, offset, KMByteBlob.cast(partialData).length());
475-
offset += KMByteBlob.cast(partialData).length();
476-
477-
moreData = KMInteger.cast(KMArray.cast(ret).get((short) 2)).getByte();
478-
} while (moreData != 0);
479-
480-
short coseKeyExp = KMCoseKey.exp();
481-
short signedMacArr = KMArray.instance((short) 4);
482-
short headersExp = KMCoseHeaders.exp();
483-
KMArray.cast(signedMacArr).add((short) 0, KMByteBlob.exp());
484-
KMArray.cast(signedMacArr).add((short) 1, headersExp);
485-
KMArray.cast(signedMacArr).add((short) 2, KMByteBlob.exp());
486-
KMArray.cast(signedMacArr).add((short) 3, KMByteBlob.exp());
487-
short dccArr = KMArray.instance((short) 2);
488-
KMArray.cast(dccArr).add((short) 0, coseKeyExp);
489-
KMArray.cast(dccArr).add((short) 1, signedMacArr);
490-
491-
short dccPtr = decoder.decode(dccArr, diceCerts, (short)0, offset);
492-
493-
byte[] pubKey = new byte[100];
494-
short pubLen = KMTestUtils.getDccPublicKey(cryptoProvider, encoder, decoder,
495-
dccPtr, pubKey, (short) 0);
496-
497-
byte[] encodedSignBuf = new byte[512];
498-
short encodedSignLen =
499-
KMTestUtils.encodeES256CoseSignSignature(
500-
signature,
501-
(short)0,
502-
signatureLen,
503-
encodedSignBuf,
504-
(short) 0);
505-
// Verify the signature of cose sign1.
506-
KMTestUtils.print(payload, (short) 0, payloadLen);
507-
Assert.assertTrue(
508-
cryptoProvider.ecVerify256(pubKey, (short)0, pubLen, payload, (short) 0, payloadLen,
509-
encodedSignBuf, (short) 0, encodedSignLen));
510-
486+
apdu = new CommandAPDU(0x80, INS_GET_DICE_CERT_CHAIN_CMD, 0x50, 0x00, (byte[]) null,
487+
65536);// BCC
488+
response = simulator.transmitCommand(apdu);
489+
arr = KMArray.instance((short) 3);
490+
KMArray.cast(arr).add((short) 0, KMInteger.exp()); // OK
491+
KMArray.cast(arr).add((short) 1, KMByteBlob.exp()); // data
492+
KMArray.cast(arr).add((short) 2, KMInteger.exp()); // more data
493+
resp = response.getBytes();
494+
ret = decoder.decode(arr, resp, (short) 0, (short) resp.length);
495+
Assert.assertEquals(KMTestUtils.getErrorCode(ret), KMError.OK);
496+
short partialData = KMArray.cast(ret).get((short) 1);
497+
Util.arrayCopyNonAtomic(KMByteBlob.cast(partialData).getBuffer(),
498+
KMByteBlob.cast(partialData).getStartOff(),
499+
diceCerts, offset, KMByteBlob.cast(partialData).length());
500+
offset += KMByteBlob.cast(partialData).length();
501+
502+
moreData = KMInteger.cast(KMArray.cast(ret).get((short) 2)).getByte();
503+
} while (moreData != 0);
504+
505+
short coseKeyExp = KMCoseKey.exp();
506+
short signedMacArr = KMArray.instance((short) 4);
507+
short headersExp = KMCoseHeaders.exp();
508+
KMArray.cast(signedMacArr).add((short) 0, KMByteBlob.exp());
509+
KMArray.cast(signedMacArr).add((short) 1, headersExp);
510+
KMArray.cast(signedMacArr).add((short) 2, KMByteBlob.exp());
511+
KMArray.cast(signedMacArr).add((short) 3, KMByteBlob.exp());
512+
short dccArr = KMArray.instance((short) 2);
513+
KMArray.cast(dccArr).add((short) 0, coseKeyExp);
514+
KMArray.cast(dccArr).add((short) 1, signedMacArr);
515+
516+
short dccPtr = decoder.decode(dccArr, diceCerts, (short) 0, offset);
517+
518+
byte[] pubKey = new byte[100];
519+
short pubLen = KMTestUtils.getDccPublicKey(cryptoProvider, encoder, decoder,
520+
dccPtr, pubKey, (short) 0);
521+
522+
byte[] encodedSignBuf = new byte[512];
523+
short encodedSignLen =
524+
KMTestUtils.encodeES256CoseSignSignature(
525+
signature,
526+
(short) 0,
527+
signatureLen,
528+
encodedSignBuf,
529+
(short) 0);
530+
// Verify the signature of cose sign1.
531+
KMTestUtils.print(payload, (short) 0, payloadLen);
532+
Assert.assertTrue(
533+
cryptoProvider.ecVerify256(pubKey, (short) 0, pubLen, payload, (short) 0, payloadLen,
534+
encodedSignBuf, (short) 0, encodedSignLen));
535+
511536
}
512537

513538
}

0 commit comments

Comments
 (0)