diff --git a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimApplet.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimApplet.java index fc9db86e..8f5c8ba0 100644 --- a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimApplet.java +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimApplet.java @@ -153,7 +153,7 @@ public void process(APDU apdu) { case INS_PROVISION_SECURE_BOOT_MODE_CMD: processSecureBootCmd(apdu); break; - + default: super.process(apdu); break; @@ -239,7 +239,8 @@ private boolean isSeFactoryProvisioningLocked() { private boolean isSeFactoryProvisioningComplete() { short pStatus = kmDataStore.getProvisionStatus(); - short seCompleteStatus = PROVISION_STATUS_DEVICE_UNIQUE_KEYPAIR | PROVISION_STATUS_ADDITIONAL_CERT_CHAIN; + short seCompleteStatus = (PROVISION_STATUS_DEVICE_UNIQUE_KEYPAIR | + PROVISION_STATUS_ADDITIONAL_CERT_CHAIN); if (seCompleteStatus == (pStatus & seCompleteStatus)) { return true; } @@ -380,18 +381,28 @@ private static void processProvisionRkpDeviceUniqueKeyPair(APDU apdu) { sendResponse(apdu, KMError.OK); } - private static void processProvisionRkpAdditionalCertChain(APDU apdu) { - // Prepare the expression to decode - short headers = KMCoseHeaders.exp(); - short arrInst = KMArray.instance((short) 4); - KMArray.cast(arrInst).add((short) 0, KMByteBlob.exp()); - KMArray.cast(arrInst).add((short) 1, headers); - KMArray.cast(arrInst).add((short) 2, KMByteBlob.exp()); - KMArray.cast(arrInst).add((short) 3, KMByteBlob.exp()); - short coseSignArr = KMArray.exp(arrInst); - short map = KMMap.instance((short) 1); - KMMap.cast(map).add((short) 0, KMTextString.exp(), coseSignArr); - // receive incoming data and decode it. + private void processProvisionRkpAdditionalCertChain(APDU apdu) { + // X509 certificate chain is received as shown below: + /** + * x509CertChain = bstr .cbor UdsCerts + * + * UdsCerts = { + * * SignerName => UdsCertChain + * } + * ; SignerName is a string identifier that indicates both the signing authority as + * ; well as the format of the UdsCertChain + * SignerName = tstr + * + * UdsCertChain = [ + * 2* X509Certificate ; Root -> ... -> Leaf. "Root" is the vendor self-signed + * ; cert, "Leaf" contains UDS_Public. There may also be + * ; intermediate certificates between Root and Leaf. + * ] + * ; A bstr containing a DER-encoded X.509 certificate (RSA, NIST P-curve, or edDSA) + * X509Certificate = bstr + */ + // Store the cbor encoded UdsCerts as it is in the persistent memory so cbor decoding is + // required here. byte[] srcBuffer = apdu.getBuffer(); short recvLen = apdu.setIncomingAndReceive(); short srcOffset = apdu.getOffsetCdata(); @@ -404,27 +415,12 @@ private static void processProvisionRkpAdditionalCertChain(APDU apdu) { index += recvLen; recvLen = apdu.receiveBytes(srcOffset); } - // decode - map = decoder.decode(map, buffer, bufferStartOffset, bufferLength); - arrInst = KMMap.cast(map).getKeyValue((short) 0); - // Validate Additional certificate chain. - short leafCoseKey = - validateCertChain(false, KMCose.COSE_ALG_ES256, KMCose.COSE_ALG_ES256, arrInst, - srcBuffer, null); - // Compare the DK_Pub. - short pubKeyLen = KMCoseKey.cast(leafCoseKey).getEcdsa256PublicKey(srcBuffer, (short) 0); - KMDeviceUniqueKeyPair uniqueKey = kmDataStore.getRkpDeviceUniqueKeyPair(false); - if (uniqueKey == null) { - KMException.throwIt(KMError.STATUS_FAILED); - } - short uniqueKeyLen = uniqueKey.getPublicKey(srcBuffer, pubKeyLen); - if ((pubKeyLen != uniqueKeyLen) || - (0 != Util.arrayCompare(srcBuffer, (short) 0, srcBuffer, pubKeyLen, pubKeyLen))) { - KMException.throwIt(KMError.STATUS_FAILED); - } - kmDataStore.persistAdditionalCertChain(buffer, bufferStartOffset, bufferLength); + short byteHeaderLen = decoder.readCertificateChainHeaderLen(buffer, bufferStartOffset, + bufferLength); + kmDataStore.persistAdditionalCertChain(buffer, (short) (bufferStartOffset + byteHeaderLen), + (short) (bufferLength - byteHeaderLen)); kmDataStore.setProvisionStatus(PROVISION_STATUS_ADDITIONAL_CERT_CHAIN); - //reclaim memory + // reclaim memory repository.reclaimMemory(bufferLength); sendResponse(apdu, KMError.OK); } diff --git a/Applet/JCardSimProvider/test/com/android/javacard/test/KMFunctionalTest.java b/Applet/JCardSimProvider/test/com/android/javacard/test/KMFunctionalTest.java index bcc02018..d68c6a4f 100644 --- a/Applet/JCardSimProvider/test/com/android/javacard/test/KMFunctionalTest.java +++ b/Applet/JCardSimProvider/test/com/android/javacard/test/KMFunctionalTest.java @@ -1482,7 +1482,7 @@ public void testVerifyOemLockWithOutSeLockFailure() { Assert.assertEquals(KMError.OK, KMTestUtils.decodeError(decoder, KMProvision.provisionDeviceUniqueKeyPair(simulator, cryptoProvider, encoder, decoder))); Assert.assertEquals(KMError.OK, KMTestUtils.decodeError(decoder, - KMProvision.provisionAdditionalCertChain(simulator, cryptoProvider, encoder, decoder))); + KMProvision.provisionAdditionalCertChain(simulator, encoder, decoder))); Assert.assertEquals(KMError.OK, KMTestUtils.decodeError(decoder, KMProvision.provisionSharedSecret(simulator, encoder, decoder))); Assert.assertEquals(KMError.OK, KMTestUtils.decodeError(decoder, @@ -1505,7 +1505,7 @@ public void testVerifyOemUnLockAfterOemLockSuccess() { Assert.assertEquals(KMError.OK, KMTestUtils.decodeError(decoder, KMProvision.provisionDeviceUniqueKeyPair(simulator, cryptoProvider, encoder, decoder))); Assert.assertEquals(KMError.OK, KMTestUtils.decodeError(decoder, - KMProvision.provisionAdditionalCertChain(simulator, cryptoProvider, encoder, decoder))); + KMProvision.provisionAdditionalCertChain(simulator, encoder, decoder))); Assert.assertEquals(KMError.OK, KMTestUtils.decodeError(decoder, KMProvision.provisionSeLocked(simulator, decoder))); Assert.assertEquals(KMError.OK, KMTestUtils.decodeError(decoder, @@ -1552,7 +1552,7 @@ public void testVerifyOemLockWithOutOemRootKeyFailure() { Assert.assertEquals(KMError.OK, KMTestUtils.decodeError(decoder, KMProvision.provisionDeviceUniqueKeyPair(simulator, cryptoProvider, encoder, decoder))); Assert.assertEquals(KMError.OK, KMTestUtils.decodeError(decoder, - KMProvision.provisionAdditionalCertChain(simulator, cryptoProvider, encoder, decoder))); + KMProvision.provisionAdditionalCertChain(simulator, encoder, decoder))); Assert.assertEquals(KMError.OK, KMTestUtils.decodeError(decoder, KMProvision.provisionSeLocked(simulator, decoder))); Assert.assertEquals(KMError.OK, KMTestUtils.decodeError(decoder, @@ -1588,13 +1588,13 @@ public void testVerifyProvisionSeDataAfterSeLockFailure() { Assert.assertEquals(KMError.OK, KMTestUtils.decodeError(decoder, KMProvision.provisionDeviceUniqueKeyPair(simulator, cryptoProvider, encoder, decoder))); Assert.assertEquals(KMError.OK, KMTestUtils.decodeError(decoder, - KMProvision.provisionAdditionalCertChain(simulator, cryptoProvider, encoder, decoder))); + KMProvision.provisionAdditionalCertChain(simulator, encoder, decoder))); Assert.assertEquals(KMError.OK, KMTestUtils.decodeError(decoder, KMProvision.provisionSeLocked(simulator, decoder))); Assert.assertEquals(KMError.UNKNOWN_ERROR, KMTestUtils.decodeError(decoder, KMProvision.provisionDeviceUniqueKeyPair(simulator, cryptoProvider, encoder, decoder))); Assert.assertEquals(KMError.UNKNOWN_ERROR, KMTestUtils.decodeError(decoder, - KMProvision.provisionAdditionalCertChain(simulator, cryptoProvider, encoder, decoder))); + KMProvision.provisionAdditionalCertChain(simulator, encoder, decoder))); cleanUp(); } @@ -1608,7 +1608,7 @@ public void testVerifyOemProvisionAfterOemLockFailure() { Assert.assertEquals(KMError.OK, KMTestUtils.decodeError(decoder, KMProvision.provisionDeviceUniqueKeyPair(simulator, cryptoProvider, encoder, decoder))); Assert.assertEquals(KMError.OK, KMTestUtils.decodeError(decoder, - KMProvision.provisionAdditionalCertChain(simulator, cryptoProvider, encoder, decoder))); + KMProvision.provisionAdditionalCertChain(simulator, encoder, decoder))); Assert.assertEquals(KMError.OK, KMTestUtils.decodeError(decoder, KMProvision.provisionSeLocked(simulator, decoder))); Assert.assertEquals(KMError.OK, KMTestUtils.decodeError(decoder, diff --git a/Applet/JCardSimProvider/test/com/android/javacard/test/KMProvision.java b/Applet/JCardSimProvider/test/com/android/javacard/test/KMProvision.java index c86bb23f..7d60b1f1 100644 --- a/Applet/JCardSimProvider/test/com/android/javacard/test/KMProvision.java +++ b/Applet/JCardSimProvider/test/com/android/javacard/test/KMProvision.java @@ -13,9 +13,7 @@ import com.android.javacard.keymaster.KMError; import com.android.javacard.keymaster.KMHmacSharingParameters; import com.android.javacard.keymaster.KMInteger; -import com.android.javacard.keymaster.KMIntegerTag; import com.android.javacard.keymaster.KMKeyParameters; -import com.android.javacard.keymaster.KMKeymasterApplet; import com.android.javacard.keymaster.KMKeymintDataStore; import com.android.javacard.keymaster.KMMap; import com.android.javacard.keymaster.KMNInteger; @@ -23,15 +21,12 @@ import com.android.javacard.keymaster.KMSimpleValue; import com.android.javacard.keymaster.KMTextString; import com.android.javacard.keymaster.KMType; -import com.android.javacard.seprovider.KMECDeviceUniqueKey; import com.android.javacard.seprovider.KMSEProvider; import com.licel.jcardsim.smartcardio.CardSimulator; import javacard.framework.Util; import javacard.security.ECPrivateKey; import javacard.security.KeyBuilder; -import javacard.security.KeyPair; import javacard.security.Signature; -import javax.smartcardio.Card; import javax.smartcardio.CommandAPDU; import javax.smartcardio.ResponseAPDU; import org.junit.Assert; @@ -93,6 +88,294 @@ public class KMProvision { (byte) 0xa6, (byte) 0x71, (byte) 0x58, (byte) 0x3e, (byte) 0xdb, (byte) 0x3e, (byte) 0x11, (byte) 0xae, (byte) 0x10, (byte) 0x14}; + private static final byte[] kEcAttestCert = { + 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x78, (byte) 0x30, (byte) 0x82, + (byte) 0x02, (byte) 0x1e, (byte) 0xa0, (byte) 0x03, (byte) 0x02, + (byte) 0x01, (byte) 0x02, (byte) 0x02, (byte) 0x02, (byte) 0x10, 0x01, + (byte) 0x30, (byte) 0x0a, (byte) 0x06, (byte) 0x08, (byte) 0x2a, + (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x04, + (byte) 0x03, (byte) 0x02, (byte) 0x30, (byte) 0x81, (byte) 0x98, 0x31, + (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, + (byte) 0x55, (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, + (byte) 0x55, (byte) 0x53, (byte) 0x31, (byte) 0x13, (byte) 0x30, 0x11, + (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x08, + (byte) 0x0c, (byte) 0x0a, (byte) 0x43, (byte) 0x61, (byte) 0x6c, + (byte) 0x69, (byte) 0x66, (byte) 0x6f, (byte) 0x72, (byte) 0x6e, 0x69, + (byte) 0x61, (byte) 0x31, (byte) 0x16, (byte) 0x30, (byte) 0x14, + (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x07, + (byte) 0x0c, (byte) 0x0d, (byte) 0x4d, (byte) 0x6f, (byte) 0x75, 0x6e, + (byte) 0x74, (byte) 0x61, (byte) 0x69, (byte) 0x6e, (byte) 0x20, + (byte) 0x56, (byte) 0x69, (byte) 0x65, (byte) 0x77, (byte) 0x31, + (byte) 0x15, (byte) 0x30, (byte) 0x13, (byte) 0x06, (byte) 0x03, 0x55, + (byte) 0x04, (byte) 0x0a, (byte) 0x0c, (byte) 0x0c, (byte) 0x47, + (byte) 0x6f, (byte) 0x6f, (byte) 0x67, (byte) 0x6c, (byte) 0x65, + (byte) 0x2c, (byte) 0x20, (byte) 0x49, (byte) 0x6e, (byte) 0x63, 0x2e, + (byte) 0x31, (byte) 0x10, (byte) 0x30, (byte) 0x0e, (byte) 0x06, + (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0b, (byte) 0x0c, + (byte) 0x07, (byte) 0x41, (byte) 0x6e, (byte) 0x64, (byte) 0x72, 0x6f, + (byte) 0x69, (byte) 0x64, (byte) 0x31, (byte) 0x33, (byte) 0x30, + (byte) 0x31, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, + (byte) 0x03, (byte) 0x0c, (byte) 0x2a, (byte) 0x41, (byte) 0x6e, 0x64, + (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x20, + (byte) 0x4b, (byte) 0x65, (byte) 0x79, (byte) 0x73, (byte) 0x74, + (byte) 0x6f, (byte) 0x72, (byte) 0x65, (byte) 0x20, (byte) 0x53, 0x6f, + (byte) 0x66, (byte) 0x74, (byte) 0x77, (byte) 0x61, (byte) 0x72, + (byte) 0x65, (byte) 0x20, (byte) 0x41, (byte) 0x74, (byte) 0x74, + (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x61, (byte) 0x74, 0x69, + (byte) 0x6f, (byte) 0x6e, (byte) 0x20, (byte) 0x52, (byte) 0x6f, + (byte) 0x6f, (byte) 0x74, (byte) 0x30, (byte) 0x1e, (byte) 0x17, + (byte) 0x0d, (byte) 0x31, (byte) 0x36, (byte) 0x30, (byte) 0x31, 0x31, + (byte) 0x31, (byte) 0x30, (byte) 0x30, (byte) 0x34, (byte) 0x36, + (byte) 0x30, (byte) 0x39, (byte) 0x5a, (byte) 0x17, (byte) 0x0d, + (byte) 0x32, (byte) 0x36, (byte) 0x30, (byte) 0x31, (byte) 0x30, 0x38, + (byte) 0x30, (byte) 0x30, (byte) 0x34, (byte) 0x36, (byte) 0x30, + (byte) 0x39, (byte) 0x5a, (byte) 0x30, (byte) 0x81, (byte) 0x88, + (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, 0x03, + (byte) 0x55, (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, + (byte) 0x55, (byte) 0x53, (byte) 0x31, (byte) 0x13, (byte) 0x30, + (byte) 0x11, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, 0x08, + (byte) 0x0c, (byte) 0x0a, (byte) 0x43, (byte) 0x61, (byte) 0x6c, + (byte) 0x69, (byte) 0x66, (byte) 0x6f, (byte) 0x72, (byte) 0x6e, + (byte) 0x69, (byte) 0x61, (byte) 0x31, (byte) 0x15, (byte) 0x30, 0x13, + (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a, + (byte) 0x0c, (byte) 0x0c, (byte) 0x47, (byte) 0x6f, (byte) 0x6f, + (byte) 0x67, (byte) 0x6c, (byte) 0x65, (byte) 0x2c, (byte) 0x20, 0x49, + (byte) 0x6e, (byte) 0x63, (byte) 0x2e, (byte) 0x31, (byte) 0x10, + (byte) 0x30, (byte) 0x0e, (byte) 0x06, (byte) 0x03, (byte) 0x55, + (byte) 0x04, (byte) 0x0b, (byte) 0x0c, (byte) 0x07, (byte) 0x41, 0x6e, + (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64, + (byte) 0x31, (byte) 0x3b, (byte) 0x30, (byte) 0x39, (byte) 0x06, + (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x03, (byte) 0x0c, 0x32, + (byte) 0x41, (byte) 0x6e, (byte) 0x64, (byte) 0x72, (byte) 0x6f, + (byte) 0x69, (byte) 0x64, (byte) 0x20, (byte) 0x4b, (byte) 0x65, + (byte) 0x79, (byte) 0x73, (byte) 0x74, (byte) 0x6f, (byte) 0x72, 0x65, + (byte) 0x20, (byte) 0x53, (byte) 0x6f, (byte) 0x66, (byte) 0x74, + (byte) 0x77, (byte) 0x61, (byte) 0x72, (byte) 0x65, (byte) 0x20, + (byte) 0x41, (byte) 0x74, (byte) 0x74, (byte) 0x65, (byte) 0x73, 0x74, + (byte) 0x61, (byte) 0x74, (byte) 0x69, (byte) 0x6f, (byte) 0x6e, + (byte) 0x20, (byte) 0x49, (byte) 0x6e, (byte) 0x74, (byte) 0x65, + (byte) 0x72, (byte) 0x6d, (byte) 0x65, (byte) 0x64, (byte) 0x69, 0x61, + (byte) 0x74, (byte) 0x65, (byte) 0x30, (byte) 0x59, (byte) 0x30, + (byte) 0x13, (byte) 0x06, (byte) 0x07, (byte) 0x2a, (byte) 0x86, + (byte) 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x02, (byte) 0x01, 0x06, + (byte) 0x08, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0xce, + (byte) 0x3d, (byte) 0x03, (byte) 0x01, (byte) 0x07, (byte) 0x03, + (byte) 0x42, (byte) 0x00, (byte) 0x04, (byte) 0xeb, (byte) 0x9e, 0x79, + (byte) 0xf8, (byte) 0x42, (byte) 0x63, (byte) 0x59, (byte) 0xac, + (byte) 0xcb, (byte) 0x2a, (byte) 0x91, (byte) 0x4c, (byte) 0x89, + (byte) 0x86, (byte) 0xcc, (byte) 0x70, (byte) 0xad, (byte) 0x90, 0x66, + (byte) 0x93, (byte) 0x82, (byte) 0xa9, (byte) 0x73, (byte) 0x26, + (byte) 0x13, (byte) 0xfe, (byte) 0xac, (byte) 0xcb, (byte) 0xf8, + (byte) 0x21, (byte) 0x27, (byte) 0x4c, (byte) 0x21, (byte) 0x74, + (byte) 0x97, (byte) 0x4a, (byte) 0x2a, (byte) 0xfe, (byte) 0xa5, + (byte) 0xb9, (byte) 0x4d, (byte) 0x7f, (byte) 0x66, (byte) 0xd4, + (byte) 0xe0, (byte) 0x65, (byte) 0x10, (byte) 0x66, (byte) 0x35, + (byte) 0xbc, 0x53, (byte) 0xb7, (byte) 0xa0, (byte) 0xa3, (byte) 0xa6, + (byte) 0x71, (byte) 0x58, (byte) 0x3e, (byte) 0xdb, (byte) 0x3e, + (byte) 0x11, (byte) 0xae, (byte) 0x10, (byte) 0x14, (byte) 0xa3, + (byte) 0x66, 0x30, (byte) 0x64, (byte) 0x30, (byte) 0x1d, (byte) 0x06, + (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x0e, (byte) 0x04, + (byte) 0x16, (byte) 0x04, (byte) 0x14, (byte) 0x3f, (byte) 0xfc, + (byte) 0xac, (byte) 0xd6, (byte) 0x1a, (byte) 0xb1, (byte) 0x3a, + (byte) 0x9e, (byte) 0x81, (byte) 0x20, (byte) 0xb8, (byte) 0xd5, + (byte) 0x25, (byte) 0x1c, (byte) 0xc5, (byte) 0x65, (byte) 0xbb, + (byte) 0x1e, (byte) 0x91, (byte) 0xa9, (byte) 0x30, (byte) 0x1f, + (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x23, + (byte) 0x04, (byte) 0x18, (byte) 0x30, (byte) 0x16, (byte) 0x80, + (byte) 0x14, (byte) 0xc8, (byte) 0xad, (byte) 0xe9, (byte) 0x77, + (byte) 0x4c, (byte) 0x45, (byte) 0xc3, (byte) 0xa3, (byte) 0xcf, + (byte) 0x0d, (byte) 0x16, (byte) 0x10, (byte) 0xe4, (byte) 0x79, + (byte) 0x43, (byte) 0x3a, (byte) 0x21, (byte) 0x5a, 0x30, (byte) 0xcf, + (byte) 0x30, (byte) 0x12, (byte) 0x06, (byte) 0x03, (byte) 0x55, + (byte) 0x1d, (byte) 0x13, (byte) 0x01, (byte) 0x01, (byte) 0xff, + (byte) 0x04, (byte) 0x08, (byte) 0x30, (byte) 0x06, 0x01, (byte) 0x01, + (byte) 0xff, (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x30, + (byte) 0x0e, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, + (byte) 0x0f, (byte) 0x01, (byte) 0x01, (byte) 0xff, 0x04, (byte) 0x04, + (byte) 0x03, (byte) 0x02, (byte) 0x02, (byte) 0x84, (byte) 0x30, + (byte) 0x0a, (byte) 0x06, (byte) 0x08, (byte) 0x2a, (byte) 0x86, + (byte) 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x04, 0x03, (byte) 0x02, + (byte) 0x03, (byte) 0x48, (byte) 0x00, (byte) 0x30, (byte) 0x45, + (byte) 0x02, (byte) 0x20, (byte) 0x4b, (byte) 0x8a, (byte) 0x9b, + (byte) 0x7b, (byte) 0xee, (byte) 0x82, (byte) 0xbc, (byte) 0xc0, + (byte) 0x33, (byte) 0x87, (byte) 0xae, (byte) 0x2f, (byte) 0xc0, + (byte) 0x89, (byte) 0x98, (byte) 0xb4, (byte) 0xdd, (byte) 0xc3, + (byte) 0x8d, (byte) 0xab, (byte) 0x27, (byte) 0x2a, (byte) 0x45, + (byte) 0x9f, (byte) 0x69, (byte) 0x0c, (byte) 0xc7, (byte) 0xc3, + (byte) 0x92, (byte) 0xd4, (byte) 0x0f, (byte) 0x8e, (byte) 0x02, + (byte) 0x21, (byte) 0x00, (byte) 0xee, (byte) 0xda, (byte) 0x01, + (byte) 0x5d, (byte) 0xb6, (byte) 0xf4, (byte) 0x32, (byte) 0xe9, + (byte) 0xd4, (byte) 0x84, (byte) 0x3b, (byte) 0x62, (byte) 0x4c, + (byte) 0x94, (byte) 0x04, (byte) 0xef, (byte) 0x3a, (byte) 0x7c, + (byte) 0xcc, (byte) 0xbd, 0x5e, (byte) 0xfb, (byte) 0x22, (byte) 0xbb, + (byte) 0xe7, (byte) 0xfe, (byte) 0xb9, (byte) 0x77, (byte) 0x3f, + (byte) 0x59, (byte) 0x3f, (byte) 0xfb,}; + + private static final byte[] kEcAttestRootCert = { + 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x8b, (byte) 0x30, + (byte) 0x82, (byte) 0x02, (byte) 0x32, (byte) 0xa0, (byte) 0x03, + (byte) 0x02, (byte) 0x01, (byte) 0x02, (byte) 0x02, (byte) 0x09, + (byte) 0x00, (byte) 0xa2, (byte) 0x05, (byte) 0x9e, (byte) 0xd1, + (byte) 0x0e, (byte) 0x43, (byte) 0x5b, (byte) 0x57, (byte) 0x30, + (byte) 0x0a, (byte) 0x06, (byte) 0x08, (byte) 0x2a, (byte) 0x86, + (byte) 0x48, (byte) 0xce, 0x3d, (byte) 0x04, (byte) 0x03, + (byte) 0x02, (byte) 0x30, (byte) 0x81, (byte) 0x98, (byte) 0x31, + (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, + (byte) 0x55, (byte) 0x04, (byte) 0x06, 0x13, (byte) 0x02, + (byte) 0x55, (byte) 0x53, (byte) 0x31, (byte) 0x13, (byte) 0x30, + (byte) 0x11, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, + (byte) 0x08, (byte) 0x0c, (byte) 0x0a, (byte) 0x43, 0x61, + (byte) 0x6c, (byte) 0x69, (byte) 0x66, (byte) 0x6f, (byte) 0x72, + (byte) 0x6e, (byte) 0x69, (byte) 0x61, (byte) 0x31, (byte) 0x16, + (byte) 0x30, (byte) 0x14, (byte) 0x06, (byte) 0x03, (byte) 0x55, + 0x04, (byte) 0x07, (byte) 0x0c, (byte) 0x0d, (byte) 0x4d, + (byte) 0x6f, (byte) 0x75, (byte) 0x6e, (byte) 0x74, (byte) 0x61, + (byte) 0x69, (byte) 0x6e, (byte) 0x20, (byte) 0x56, (byte) 0x69, + (byte) 0x65, 0x77, (byte) 0x31, (byte) 0x15, (byte) 0x30, + (byte) 0x13, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, + (byte) 0x0a, (byte) 0x0c, (byte) 0x0c, (byte) 0x47, (byte) 0x6f, + (byte) 0x6f, (byte) 0x67, 0x6c, (byte) 0x65, (byte) 0x2c, + (byte) 0x20, (byte) 0x49, (byte) 0x6e, (byte) 0x63, (byte) 0x2e, + (byte) 0x31, (byte) 0x10, (byte) 0x30, (byte) 0x0e, (byte) 0x06, + (byte) 0x03, (byte) 0x55, (byte) 0x04, 0x0b, (byte) 0x0c, + (byte) 0x07, (byte) 0x41, (byte) 0x6e, (byte) 0x64, (byte) 0x72, + (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x31, (byte) 0x33, + (byte) 0x30, (byte) 0x31, (byte) 0x06, (byte) 0x03, 0x55, + (byte) 0x04, (byte) 0x03, (byte) 0x0c, (byte) 0x2a, (byte) 0x41, + (byte) 0x6e, (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, + (byte) 0x64, (byte) 0x20, (byte) 0x4b, (byte) 0x65, (byte) 0x79, + 0x73, (byte) 0x74, (byte) 0x6f, (byte) 0x72, (byte) 0x65, + (byte) 0x20, (byte) 0x53, (byte) 0x6f, (byte) 0x66, (byte) 0x74, + (byte) 0x77, (byte) 0x61, (byte) 0x72, (byte) 0x65, (byte) 0x20, + (byte) 0x41, 0x74, (byte) 0x74, (byte) 0x65, (byte) 0x73, + (byte) 0x74, (byte) 0x61, (byte) 0x74, (byte) 0x69, (byte) 0x6f, + (byte) 0x6e, (byte) 0x20, (byte) 0x52, (byte) 0x6f, (byte) 0x6f, + (byte) 0x74, (byte) 0x30, 0x1e, (byte) 0x17, (byte) 0x0d, + (byte) 0x31, (byte) 0x36, (byte) 0x30, (byte) 0x31, (byte) 0x31, + (byte) 0x31, (byte) 0x30, (byte) 0x30, (byte) 0x34, (byte) 0x33, + (byte) 0x35, (byte) 0x30, (byte) 0x5a, 0x17, (byte) 0x0d, + (byte) 0x33, (byte) 0x36, (byte) 0x30, (byte) 0x31, (byte) 0x30, + (byte) 0x36, (byte) 0x30, (byte) 0x30, (byte) 0x34, (byte) 0x33, + (byte) 0x35, (byte) 0x30, (byte) 0x5a, (byte) 0x30, (byte) 0x81, + (byte) 0x98, (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09, + (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06, + (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53, (byte) 0x31, + 0x13, (byte) 0x30, (byte) 0x11, (byte) 0x06, (byte) 0x03, + (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x0c, (byte) 0x0a, + (byte) 0x43, (byte) 0x61, (byte) 0x6c, (byte) 0x69, (byte) 0x66, + (byte) 0x6f, 0x72, (byte) 0x6e, (byte) 0x69, (byte) 0x61, + (byte) 0x31, (byte) 0x16, (byte) 0x30, (byte) 0x14, (byte) 0x06, + (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x07, (byte) 0x0c, + (byte) 0x0d, (byte) 0x4d, 0x6f, (byte) 0x75, (byte) 0x6e, + (byte) 0x74, (byte) 0x61, (byte) 0x69, (byte) 0x6e, (byte) 0x20, + (byte) 0x56, (byte) 0x69, (byte) 0x65, (byte) 0x77, (byte) 0x31, + (byte) 0x15, (byte) 0x30, (byte) 0x13, 0x06, (byte) 0x03, + (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x0c, (byte) 0x0c, + (byte) 0x47, (byte) 0x6f, (byte) 0x6f, (byte) 0x67, (byte) 0x6c, + (byte) 0x65, (byte) 0x2c, (byte) 0x20, (byte) 0x49, 0x6e, + (byte) 0x63, (byte) 0x2e, (byte) 0x31, (byte) 0x10, (byte) 0x30, + (byte) 0x0e, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, + (byte) 0x0b, (byte) 0x0c, (byte) 0x07, (byte) 0x41, (byte) 0x6e, + 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64, + (byte) 0x31, (byte) 0x33, (byte) 0x30, (byte) 0x31, (byte) 0x06, + (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x03, (byte) 0x0c, + (byte) 0x2a, 0x41, (byte) 0x6e, (byte) 0x64, (byte) 0x72, + (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x20, (byte) 0x4b, + (byte) 0x65, (byte) 0x79, (byte) 0x73, (byte) 0x74, (byte) 0x6f, + (byte) 0x72, (byte) 0x65, 0x20, (byte) 0x53, (byte) 0x6f, + (byte) 0x66, (byte) 0x74, (byte) 0x77, (byte) 0x61, (byte) 0x72, + (byte) 0x65, (byte) 0x20, (byte) 0x41, (byte) 0x74, (byte) 0x74, + (byte) 0x65, (byte) 0x73, (byte) 0x74, 0x61, (byte) 0x74, + (byte) 0x69, (byte) 0x6f, (byte) 0x6e, 0x77, (byte) 0x1f, + (byte) 0x44, (byte) 0x22, (byte) 0x6d, (byte) 0xbd, (byte) 0xb1, + (byte) 0xaf, (byte) 0xfa, (byte) 0x16, (byte) 0xcb, (byte) 0xc7, + (byte) 0xad, (byte) 0xc5, (byte) 0x77, (byte) 0xd2, (byte) 0x20, + (byte) 0x52, (byte) 0x6f, (byte) 0x6f, (byte) 0x74, (byte) 0x30, + (byte) 0x59, (byte) 0x30, (byte) 0x13, (byte) 0x06, (byte) 0x07, + 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x3d, + (byte) 0x02, (byte) 0x01, (byte) 0x06, (byte) 0x08, (byte) 0x2a, + (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x03, + (byte) 0x01, 0x07, (byte) 0x03, (byte) 0x42, (byte) 0x00, + (byte) 0x04, (byte) 0xee, (byte) 0x5d, (byte) 0x5e, (byte) 0xc7, + (byte) 0xe1, (byte) 0xc0, (byte) 0xdb, (byte) 0x6d, (byte) 0x03, + (byte) 0xa6, (byte) 0x7e, (byte) 0xe6, (byte) 0xb6, (byte) 0x1b, + (byte) 0xec, (byte) 0x4d, (byte) 0x6a, (byte) 0x5d, (byte) 0x6a, + (byte) 0x68, (byte) 0x2e, (byte) 0x0f, (byte) 0xff, (byte) 0x7f, + (byte) 0x49, (byte) 0x0e, (byte) 0x7d, 0x56, (byte) 0x9c, + (byte) 0xaa, (byte) 0xb7, (byte) 0xb0, (byte) 0x2d, (byte) 0x54, + (byte) 0x01, (byte) 0x5d, (byte) 0x3e, (byte) 0x43, (byte) 0x2b, + (byte) 0x2a, (byte) 0x8e, (byte) 0xd7, (byte) 0x4e, (byte) 0xec, + (byte) 0x48, (byte) 0x75, (byte) 0x41, (byte) 0xa4, (byte) 0xa3, + (byte) 0x63, (byte) 0x30, (byte) 0x61, (byte) 0x30, (byte) 0x1d, + (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x0e, + 0x04, (byte) 0x16, (byte) 0x04, (byte) 0x14, (byte) 0xc8, + (byte) 0xad, (byte) 0xe9, (byte) 0x77, (byte) 0x4c, (byte) 0x45, + (byte) 0xc3, (byte) 0xa3, (byte) 0xcf, (byte) 0x0d, (byte) 0x16, + (byte) 0x10, (byte) 0xe4, (byte) 0x79, (byte) 0x43, (byte) 0x3a, + (byte) 0x21, (byte) 0x5a, (byte) 0x30, (byte) 0xcf, (byte) 0x30, + (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, + (byte) 0x23, (byte) 0x04, 0x18, (byte) 0x30, (byte) 0x16, + (byte) 0x80, (byte) 0x14, (byte) 0xc8, (byte) 0xad, (byte) 0xe9, + (byte) 0x77, (byte) 0x4c, (byte) 0x45, (byte) 0xc3, (byte) 0xa3, + (byte) 0xcf, (byte) 0x0d, (byte) 0x16, 0x10, (byte) 0xe4, + (byte) 0x79, (byte) 0x43, (byte) 0x3a, (byte) 0x21, (byte) 0x5a, + (byte) 0x30, (byte) 0xcf, (byte) 0x30, (byte) 0x0f, (byte) 0x06, + (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x13, 0x01, + (byte) 0x01, (byte) 0xff, (byte) 0x04, (byte) 0x05, (byte) 0x30, + (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0xff, (byte) 0x30, + (byte) 0x0e, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, + 0x0f, (byte) 0x01, (byte) 0x01, (byte) 0xff, (byte) 0x04, + (byte) 0x04, (byte) 0x03, (byte) 0x02, (byte) 0x02, (byte) 0x84, + (byte) 0x30, (byte) 0x0a, (byte) 0x06, (byte) 0x08, (byte) 0x2a, + (byte) 0x86, 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x04, + (byte) 0x03, (byte) 0x02, (byte) 0x03, (byte) 0x47, (byte) 0x00, + (byte) 0x30, (byte) 0x44, (byte) 0x02, (byte) 0x20, (byte) 0x35, + (byte) 0x21, (byte) 0xa3, (byte) 0xef, (byte) 0x8b, (byte) 0x34, + (byte) 0x46, (byte) 0x1e, (byte) 0x9c, (byte) 0xd5, (byte) 0x60, + (byte) 0xf3, (byte) 0x1d, (byte) 0x58, (byte) 0x89, (byte) 0x20, + (byte) 0x6a, (byte) 0xdc, (byte) 0xa3, 0x65, (byte) 0x41, + (byte) 0xf6, (byte) 0x0d, (byte) 0x9e, (byte) 0xce, (byte) 0x8a, + (byte) 0x19, (byte) 0x8c, (byte) 0x66, (byte) 0x48, (byte) 0x60, + (byte) 0x7b, (byte) 0x02, (byte) 0x20, (byte) 0x4d, 0x0b, + (byte) 0xf3, (byte) 0x51, (byte) 0xd9, (byte) 0x30, (byte) 0x7c, + (byte) 0x7d, (byte) 0x5b, (byte) 0xda, (byte) 0x35, (byte) 0x34, + (byte) 0x1d, (byte) 0xa8, (byte) 0x47, (byte) 0x1b, (byte) 0x63, + (byte) 0xa5, (byte) 0x85, (byte) 0x65, (byte) 0x3c, (byte) 0xad, + (byte) 0x4f, (byte) 0x24, (byte) 0xa7, (byte) 0xe7, (byte) 0x4d, + (byte) 0xaf, (byte) 0x41, (byte) 0x7d, (byte) 0xf1, + (byte) 0xbf,}; + private static final byte[] X509Issuer = { + (byte) 0x30, (byte) 0x81, (byte) 0x88, (byte) 0x31, (byte) 0x0b, + (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, + (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x55, + (byte) 0x53, (byte) 0x31, (byte) 0x13, (byte) 0x30, (byte) 0x11, + (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x08, + (byte) 0x0c, (byte) 0x0a, (byte) 0x43, (byte) 0x61, (byte) 0x6c, + (byte) 0x69, (byte) 0x66, (byte) 0x6f, (byte) 0x72, (byte) 0x6e, + (byte) 0x69, (byte) 0x61, (byte) 0x31, (byte) 0x15, (byte) 0x30, + (byte) 0x13, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, + (byte) 0x0a, (byte) 0x0c, (byte) 0x0c, (byte) 0x47, (byte) 0x6f, + (byte) 0x6f, (byte) 0x67, (byte) 0x6c, (byte) 0x65, (byte) 0x2c, + (byte) 0x20, (byte) 0x49, (byte) 0x6e, (byte) 0x63, (byte) 0x2e, + (byte) 0x31, (byte) 0x10, (byte) 0x30, (byte) 0x0e, (byte) 0x06, + (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0b, (byte) 0x0c, + (byte) 0x07, (byte) 0x41, (byte) 0x6e, (byte) 0x64, (byte) 0x72, + (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x31, (byte) 0x3b, + (byte) 0x30, (byte) 0x39, (byte) 0x06, (byte) 0x03, (byte) 0x55, + (byte) 0x04, (byte) 0x03, (byte) 0x0c, (byte) 0x32, (byte) 0x41, + (byte) 0x6e, (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, + (byte) 0x64, (byte) 0x20, (byte) 0x4b, (byte) 0x65, (byte) 0x79, + (byte) 0x73, (byte) 0x74, (byte) 0x6f, (byte) 0x72, (byte) 0x65, + (byte) 0x20, (byte) 0x53, (byte) 0x6f, (byte) 0x66, (byte) 0x74, + (byte) 0x77, (byte) 0x61, (byte) 0x72, (byte) 0x65, (byte) 0x20, + (byte) 0x41, (byte) 0x74, (byte) 0x74, (byte) 0x65, (byte) 0x73, + (byte) 0x74, (byte) 0x61, (byte) 0x74, (byte) 0x69, (byte) 0x6f, + (byte) 0x6e, (byte) 0x20, (byte) 0x49, (byte) 0x6e, (byte) 0x74, + (byte) 0x65, (byte) 0x72, (byte) 0x6d, (byte) 0x65, (byte) 0x64, + (byte) 0x69, (byte) 0x61, (byte) 0x74, (byte) 0x65}; + private static final byte[] expiryTime = {(byte) 0x32, (byte) 0x36, (byte) 0x30, (byte) 0x31, + (byte) 0x30, (byte) 0x38, (byte) 0x30, (byte) 0x30, (byte) 0x34, (byte) 0x36, (byte) 0x30, + (byte) 0x39, (byte) 0x5a}; // OEM lock / unlock verification constants. private static final byte[] OEM_LOCK_PROVISION_VERIFICATION_LABEL = { // "OEM Provisioning Lock" 0x4f, 0x45, 0x4d, 0x20, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x69, 0x6e, @@ -166,78 +449,6 @@ public static ResponseAPDU setBootParams(CardSimulator simulator, KMEncoder enco return simulator.transmitCommand(apdu); } - public static ResponseAPDU provisionAdditionalCertChain(CardSimulator simulator, - KMSEProvider cryptoProvider, KMEncoder encoder, KMDecoder decoder) { - short[] lengths = new short[2]; - byte[] rootPriv = new byte[128]; - byte[] rootPub = new byte[128]; - byte[] scratchpad = new byte[500]; - short[] coseScratchpad = new short[20]; - cryptoProvider.createAsymmetricKey(KMType.EC, rootPriv, (short) 0, (short) 128, - rootPub, (short) 0, (short) 128, lengths); - short coseKey = - KMTestUtils.constructCoseKey( - KMInteger.uint_8(KMCose.COSE_KEY_TYPE_EC2), - KMType.INVALID_VALUE, - KMNInteger.uint_8(KMCose.COSE_ALG_ES256), - KMInteger.uint_8(KMCose.COSE_KEY_OP_SIGN), - KMInteger.uint_8(KMCose.COSE_ECCURVE_256), - rootPub, (short) 0, lengths[1], - rootPriv, (short) 0, lengths[0], - false - ); - short payload = encoder.encode(coseKey, scratchpad, (short) 0, (short) 500); - payload = KMByteBlob.instance(scratchpad, (short) 0, payload); - // Protected Header - short protectedHeaderPtr = KMCose.constructHeaders(coseScratchpad, - KMNInteger.uint_8(KMCose.COSE_ALG_ES256), - KMType.INVALID_VALUE, - KMType.INVALID_VALUE, - KMType.INVALID_VALUE); - protectedHeaderPtr = encoder.encode(protectedHeaderPtr, scratchpad, (short) 0, (short) 500); - protectedHeaderPtr = KMByteBlob.instance(scratchpad, (short) 0, protectedHeaderPtr); - - // Unprotected Headers. - short emptyArr = KMArray.instance((short) 0); - short unprotectedHeader = KMCoseHeaders.instance(emptyArr); - - short aad = KMByteBlob.instance((short) 0); - KeyPair ecKeyPair = new KeyPair(KeyPair.ALG_EC_FP, KeyBuilder.LENGTH_EC_FP_256); - KMECDeviceUniqueKey ecUniqueKey = new KMECDeviceUniqueKey(ecKeyPair); - ecUniqueKey.setS(rootPriv, (short) 0, lengths[0]); - ecUniqueKey.setW(rootPub, (short) 0, lengths[1]); - short root = KMTestUtils.constructCoseSign1(cryptoProvider, encoder, - protectedHeaderPtr, unprotectedHeader, payload, aad, - ecUniqueKey); - coseKey = - KMTestUtils.constructCoseKey( - KMInteger.uint_8(KMCose.COSE_KEY_TYPE_EC2), - KMType.INVALID_VALUE, - KMNInteger.uint_8(KMCose.COSE_ALG_ES256), - KMInteger.uint_8(KMCose.COSE_KEY_OP_SIGN), - KMInteger.uint_8(KMCose.COSE_ECCURVE_256), - RKP_DK_PUB, (short) 0, (short) RKP_DK_PUB.length, - RKP_DK_PRIV, (short) 0, (short) RKP_DK_PRIV.length, - false - ); - payload = encoder.encode(coseKey, scratchpad, (short) 0, (short) 500); - payload = KMByteBlob.instance(scratchpad, (short) 0, payload); - short leaf = KMTestUtils.constructCoseSign1(cryptoProvider, encoder, protectedHeaderPtr, - unprotectedHeader, payload, aad, - ecUniqueKey); - short additionalCertChain = KMArray.instance((short) 2); - KMArray.cast(additionalCertChain).add((short) 0, root); - KMArray.cast(additionalCertChain).add((short) 1, leaf); - short map = KMMap.instance((short) 1); - byte[] signerName = "TestSigner".getBytes(); - KMMap.cast(map) - .add((short) 0, KMTextString.instance(signerName, (short) 0, (short) signerName.length), - additionalCertChain); - CommandAPDU apdu = KMTestUtils.encodeApdu(encoder, - (byte) INS_PROVISION_RKP_ADDITIONAL_CERT_CHAIN_CMD, map); - return simulator.transmitCommand(apdu); - } - public static ResponseAPDU provisionDeviceUniqueKeyPair(CardSimulator simulator, KMSEProvider cryptoProvider, KMEncoder encoder, KMDecoder decoder) { @@ -476,7 +687,7 @@ public static void provisionCmd(CardSimulator simulator, Assert.assertEquals(KMError.OK, KMTestUtils.decodeError(decoder, provisionDeviceUniqueKeyPair(simulator, cryptoProvider, encoder, decoder))); Assert.assertEquals(KMError.OK, KMTestUtils.decodeError(decoder, - provisionAdditionalCertChain(simulator, cryptoProvider, encoder, decoder))); + provisionAdditionalCertChain(simulator, encoder, decoder))); Assert.assertEquals(KMError.OK, KMTestUtils.decodeError(decoder, provisionSeLocked(simulator, decoder))); Assert.assertEquals(KMError.OK, KMTestUtils.decodeError(decoder, @@ -528,6 +739,48 @@ public static short getHmacSharingParams(CardSimulator simulator, KMDecoder deco ret = decoder.decode(ret, respBuf, (short) 0, len); return ret; } + public static ResponseAPDU provisionAdditionalCertChain(CardSimulator simulator, KMEncoder encoder, + KMDecoder decoder) { + short arrPtr = KMArray.instance((short) 3); + short innerArrPtr = KMArray.instance((short) 2); + + short byteBlobPtr1 = KMByteBlob.instance( + (short) (kEcAttestCert.length)); + Util.arrayCopyNonAtomic(kEcAttestCert, (short) 0, + KMByteBlob.cast(byteBlobPtr1).getBuffer(), + KMByteBlob.cast(byteBlobPtr1).getStartOff(), + (short) kEcAttestCert.length); + + short byteBlobPtr2 = KMByteBlob.instance( + (short) (kEcAttestRootCert.length)); + Util.arrayCopyNonAtomic(kEcAttestRootCert, (short) 0, + KMByteBlob.cast(byteBlobPtr2).getBuffer(), + KMByteBlob.cast(byteBlobPtr2).getStartOff(), + (short) kEcAttestRootCert.length); + KMArray.cast(innerArrPtr).add((short) 0, byteBlobPtr1); + KMArray.cast(innerArrPtr).add((short) 1, byteBlobPtr2); + short map = KMMap.instance((short) 1); + byte[] signerName = "TestSigner".getBytes(); + KMMap.cast(map) + .add((short) 0, KMTextString.instance(signerName, (short) 0, (short) signerName.length), + innerArrPtr); + byte[] output = new byte[2048]; + short encodedLen = encoder.encode(map, output, (short) 0, (short) 2048); + short encodedData = KMByteBlob.instance(output, (short) 0, encodedLen); + + CommandAPDU apdu = KMTestUtils.encodeApdu(encoder, + (byte) INS_PROVISION_RKP_ADDITIONAL_CERT_CHAIN_CMD, encodedData); + // print(commandAPDU.getBytes()); + ResponseAPDU response = simulator.transmitCommand(apdu); + + Assert.assertEquals(0x9000, response.getSW()); + byte[] resp = response.getBytes(); + short arr = KMArray.instance((short) 1); + KMArray.cast(arr).add((short) 0, KMInteger.exp()); + short ptr = decoder.decode(arr, resp, (short) 0, (short) resp.length); + Assert.assertEquals(KMError.OK, KMInteger.cast(KMArray.cast(ptr).get((short) 0)).getShort()); + return response; + } public static void sendRootOfTrust(CardSimulator simulator, KMSEProvider cryptoProvider, KMEncoder encoder, diff --git a/Applet/JCardSimProvider/test/com/android/javacard/test/KMRKPFunctionalTest.java b/Applet/JCardSimProvider/test/com/android/javacard/test/KMRKPFunctionalTest.java index 00134ad1..d1e74702 100644 --- a/Applet/JCardSimProvider/test/com/android/javacard/test/KMRKPFunctionalTest.java +++ b/Applet/JCardSimProvider/test/com/android/javacard/test/KMRKPFunctionalTest.java @@ -501,6 +501,8 @@ public void testGenerateCsr(short no_keys) { encodedSignBuf, (short) 0, encodedSignLen)); byte moreData; + byte[] udsCerts = new byte[2500]; + short offset = 0; do { apdu = new CommandAPDU(0x80, INS_GET_UDS_CERTS_CMD, 0x50, 0x00, (byte[]) null, 65536); //Acc response = simulator.transmitCommand(apdu); @@ -513,9 +515,15 @@ public void testGenerateCsr(short no_keys) { ret = decoder.decode(arr, resp, (short) 0, (short) resp.length); //TODO accumlate acc data Assert.assertEquals(KMTestUtils.getErrorCode(ret), KMError.OK); + short partialData = KMArray.cast(ret).get((short) 1); + Util.arrayCopyNonAtomic(KMByteBlob.cast(partialData).getBuffer(), KMByteBlob.cast(partialData).getStartOff(), + udsCerts, offset, KMByteBlob.cast(partialData).length()); + offset += KMByteBlob.cast(partialData).length(); moreData = KMInteger.cast(KMArray.cast(ret).get((short) 2)).getByte(); }while (moreData != 0); + System.out.println("Certificate Chain===============>"); + KMTestUtils.print(udsCerts, (short) 0, offset); } } diff --git a/Applet/JCardSimProvider/test/com/android/javacard/test/KMTestUtils.java b/Applet/JCardSimProvider/test/com/android/javacard/test/KMTestUtils.java index e9d5be04..e2ccd254 100644 --- a/Applet/JCardSimProvider/test/com/android/javacard/test/KMTestUtils.java +++ b/Applet/JCardSimProvider/test/com/android/javacard/test/KMTestUtils.java @@ -462,16 +462,9 @@ public static void validateProtectedData(KMSEProvider cryptoProvider, KMEncoder KMArray.cast(bccArr).add((short) 1, signedMacArr); //if (!testMode) { short headers = KMCoseHeaders.exp(); - short arrInst = KMArray.instance((short) 4); - KMArray.cast(arrInst).add((short) 0, KMByteBlob.exp()); - KMArray.cast(arrInst).add((short) 1, headers); - KMArray.cast(arrInst).add((short) 2, KMByteBlob.exp()); - KMArray.cast(arrInst).add((short) 3, KMByteBlob.exp()); - short coseSignArr = KMArray.exp(arrInst); - if (!testMode) { - additionalCertChain = KMMap.instance((short) 1); - KMMap.cast(additionalCertChain).add((short) 0, KMTextString.exp(), coseSignArr); - } + short x509Arr = KMArray.exp(KMByteBlob.exp()); + additionalCertChain = KMMap.instance((short) 1); + KMMap.cast(additionalCertChain).add((short) 0, KMTextString.exp(), x509Arr); // protected payload exp short payload = KMArray.instance(payloadLength); KMArray.cast(payload).add((short) 0, signedMacArr); @@ -496,12 +489,20 @@ public static void validateProtectedData(KMSEProvider cryptoProvider, KMEncoder //-------------------------------------------- // Validate Additional certificate chain. //-------------------------------------------- - if (!testMode) { + //if (!testMode) { + { short addCertChain = KMArray.cast(payloadPtr).get((short) 2); addCertChain = KMMap.cast(addCertChain).getKeyValue((short) 0); - Assert.assertTrue( - validateCertChain(cryptoProvider, encoder, decoder, KMCose.COSE_ALG_ES256, - KMCose.COSE_ALG_ES256, addCertChain)); + short len = KMArray.cast(addCertChain).length(); + System.out.println("AdditionalCertificateChain RKP UNiTest Certs ::===>"); + for(short i = 0; i < len; i++) { + short blob = KMArray.cast(addCertChain).get(i); + print(KMByteBlob.cast(blob).getBuffer(), KMByteBlob.cast(blob).getStartOff(), + KMByteBlob.cast(blob).length()); + } + // Assert.assertTrue( + // validateCertChain(cryptoProvider, encoder, decoder, KMCose.COSE_ALG_ES256, + // KMCose.COSE_ALG_ES256, addCertChain)); } } diff --git a/Applet/JCardSimProviderLib/src/com/android/javacard/seprovider/KMSEProvider.java b/Applet/JCardSimProviderLib/src/com/android/javacard/seprovider/KMSEProvider.java index 4669feb2..50f014cd 100644 --- a/Applet/JCardSimProviderLib/src/com/android/javacard/seprovider/KMSEProvider.java +++ b/Applet/JCardSimProviderLib/src/com/android/javacard/seprovider/KMSEProvider.java @@ -46,7 +46,7 @@ public interface KMSEProvider { * @param resetBootFlag is false if event has been handled */ void clearDeviceBooted(boolean resetBootFlag); - + /** * Create a symmetric key instance. If the algorithm and/or keysize are not supported then it * should throw a CryptoException. @@ -94,7 +94,7 @@ void createAsymmetricKey( * @return instance of KMOperation. */ KMOperation initTrustedConfirmationSymmetricOperation(KMComputedHmacKey computedHmacKey); - + /** * Verify that the imported key is valid. If the algorithm and/or keysize are not supported then * it should throw a CryptoException. @@ -297,7 +297,7 @@ short hmacSign( short dataLength, byte[] signature, short signatureStart); - + /** * This is a oneshot operation that signs the data using hmac algorithm. * @@ -310,7 +310,7 @@ short hmacSign( * @return length of the signature buffer in bytes. */ short hmacSign( - Object hmacKey, + Object hmacKey, byte[] data, short dataStart, short dataLength, @@ -340,9 +340,7 @@ short hmacKDF( /** * This is a oneshot operation that verifies the signature using hmac algorithm. * - * @param keyBuf is the buffer with hmac key. - * @param keyStart is the start of the buffer. - * @param keyLength is the length of the buffer which will be in bytes from 8 to 64. + * @param hmacKey is the Hmac key. * @param data is the buffer containing data. * @param dataStart is the start of the data. * @param dataLength is the length of the data. @@ -600,7 +598,7 @@ KMOperation initSymmetricOperation( boolean oneShot); /** - * This function creates an Operation instance only for RKP module. + * This function creates an Operation instance only for RKP module. * * @param purpose is KMType.ENCRYPT or KMType.DECRYPT for AES and DES algorithm. It will be * KMType.SIGN and KMType.VERIFY for HMAC algorithm @@ -691,7 +689,8 @@ KMOperation initAsymmetricOperation( * @param length length of the buffer. * @return An instance of the KMComputedHmacKey. */ - KMComputedHmacKey createComputedHmacKey(KMComputedHmacKey computedHmacKey, byte[] keyData, short offset, short length); + KMComputedHmacKey createComputedHmacKey(KMComputedHmacKey computedHmacKey, byte[] keyData, + short offset, short length); /** * Returns true if factory provisioned attestation key is supported. @@ -719,7 +718,7 @@ KMOperation initAsymmetricOperation( KMDeviceUniqueKeyPair createRkpDeviceUniqueKeyPair(KMDeviceUniqueKeyPair key, byte[] pubKey, short pubKeyOff, short pubKeyLen, byte[] privKey, short privKeyOff, short privKeyLen); - + /** * This is a one-shot operation the does digest of the input mesage. * @@ -732,7 +731,7 @@ KMDeviceUniqueKeyPair createRkpDeviceUniqueKeyPair(KMDeviceUniqueKeyPair key, */ short messageDigest256(byte[] inBuff, short inOffset, short inLength, byte[] outBuff, short outOffset); - + /** * This function generates a HMAC key from the provided key buffers. * @@ -744,7 +743,7 @@ short messageDigest256(byte[] inBuff, short inOffset, short inLength, byte[] out */ KMPreSharedKey createPreSharedKey(KMPreSharedKey presharedKey, byte[] key, short offset, short length); - + /** * This function saves the key objects while upgrade. * @@ -753,18 +752,18 @@ KMPreSharedKey createPreSharedKey(KMPreSharedKey presharedKey, byte[] key, short * @param object instance of the object to be saved. */ void onSave(Element element, byte interfaceType, Object object); - + /** * This function restores the the object from element instance. - * + * * @param element instance of the Element class. * @return restored object. */ Object onRestore(Element element); - + /** - * This function returns the count of the primitive bytes required to - * be stored by the implementation of the interface type. + * This function returns the count of the primitive bytes required to be stored by the + * implementation of the interface type. * * @param interfaceType type interface of the parent object. * @return count of the primitive bytes. @@ -772,14 +771,14 @@ KMPreSharedKey createPreSharedKey(KMPreSharedKey presharedKey, byte[] key, short short getBackupPrimitiveByteCount(byte interfaceType); /** - * This function returns the object count required to be stored by the - * implementation of the interface type. + * This function returns the object count required to be stored by the implementation of the + * interface type. * * @param interfaceType type interface of the parent object. * @return count of the objects. */ short getBackupObjectCount(byte interfaceType); - + /** * This function creates an HMACKey and initializes the key with the provided input key data. * diff --git a/Applet/src/com/android/javacard/keymaster/KMDecoder.java b/Applet/src/com/android/javacard/keymaster/KMDecoder.java index 51395bb9..04eabe54 100644 --- a/Applet/src/com/android/javacard/keymaster/KMDecoder.java +++ b/Applet/src/com/android/javacard/keymaster/KMDecoder.java @@ -753,13 +753,12 @@ public short readKeyblobVersion(byte[] buf, short bufOffset, short bufLen) { return version; } - public short readCertificateChainLengthAndHeaderLen(byte[] buf, short bufOffset, - short bufLen) { + public short readCertificateChainHeaderLen(byte[] buf, short bufOffset, + short bufLen) { bufferRef[0] = buf; scratchBuf[START_OFFSET] = bufOffset; scratchBuf[LEN_OFFSET] = (short) (bufOffset + bufLen); - short totalLen = readMajorTypeWithPayloadLength(BYTES_TYPE); - totalLen += (short) (scratchBuf[START_OFFSET] - bufOffset); - return totalLen; + readMajorTypeWithPayloadLength(BYTES_TYPE); + return (short) (scratchBuf[START_OFFSET] - bufOffset); } } diff --git a/Applet/src/com/android/javacard/keymaster/KMKeymintDataStore.java b/Applet/src/com/android/javacard/keymaster/KMKeymintDataStore.java index 1fc34dd7..b4a2ac1d 100644 --- a/Applet/src/com/android/javacard/keymaster/KMKeymintDataStore.java +++ b/Applet/src/com/android/javacard/keymaster/KMKeymintDataStore.java @@ -74,7 +74,7 @@ public class KMKeymintDataStore implements KMUpgradable { private static final short SHARED_SECRET_KEY_SIZE = 32; private static final byte DEVICE_STATUS_FLAG_SIZE = 1; - private static final short ADDITIONAL_CERT_CHAIN_MAX_SIZE = 512;//First 2 bytes for length. + private static final short ADDITIONAL_CERT_CHAIN_MAX_SIZE = 2500;//First 2 bytes for length. private static final short BCC_MAX_SIZE = 512; //Device boot states. Applet starts executing the diff --git a/HAL/SocketTransport.cpp b/HAL/SocketTransport.cpp index 76b50c34..663b9edf 100644 --- a/HAL/SocketTransport.cpp +++ b/HAL/SocketTransport.cpp @@ -79,9 +79,9 @@ keymaster_error_t SocketTransport::sendData(const vector& inData, vecto inDataPrependedLength.push_back(static_cast(inData.size() & 0xFF)); inDataPrependedLength.insert(inDataPrependedLength.end(), inData.begin(), inData.end()); - if (0 > send(mSocket, inDataPrependedLength.data(), inDataPrependedLength.size(), 0)) { + if (0 > send(mSocket, inDataPrependedLength.data(), inDataPrependedLength.size(), MSG_NOSIGNAL)) { static int connectionResetCnt = 0; /* To avoid loop */ - if (ECONNRESET == errno && connectionResetCnt == 0) { + if ((ECONNRESET == errno || EPIPE == errno) && connectionResetCnt == 0) { // Connection reset. Try open socket and then sendData. socketStatus = false; connectionResetCnt++; diff --git a/ProvisioningTool/include/cppbor/cppbor.h b/ProvisioningTool/include/cppbor/cppbor.h index 45ae67cf..5761bca0 100644 --- a/ProvisioningTool/include/cppbor/cppbor.h +++ b/ProvisioningTool/include/cppbor/cppbor.h @@ -700,12 +700,12 @@ class Map : public Item { * * If the searched-for `key` is not present, returns `nullptr`. * - * Note that if the map is canonicalized (sorted), Map::get() peforms a binary search. If your + * Note that if the map is canonicalized (sorted), Map::get() performs a binary search. If your * map is large and you're searching in it many times, it may be worthwhile to canonicalize it * to make Map::get() faster. Any use of a method that might modify the map disables the * speedup. */ - template + template const std::unique_ptr& get(Key key) const; // Note that use of non-const operator[] marks the map as not canonicalized. diff --git a/ProvisioningTool/sample_json_keymint_cf.txt b/ProvisioningTool/sample_json_keymint_cf.txt index f0de686c..a046baef 100644 --- a/ProvisioningTool/sample_json_keymint_cf.txt +++ b/ProvisioningTool/sample_json_keymint_cf.txt @@ -21,8 +21,9 @@ "signer_info": { "signer_name": "Google", "signing_keys": [ - "test_resources/ca_key.der", - "test_resources/intermediate_key.der" + "test_resources/ca_cert.der", + "test_resources/intermediate_cert.der", + "test_resources/batch_cert.der" ] }, "oem_root_key": "test_resources/oem_root_key.der", diff --git a/ProvisioningTool/sample_json_keymint_gf.txt b/ProvisioningTool/sample_json_keymint_gf.txt index 50b10011..94b2a1e9 100644 --- a/ProvisioningTool/sample_json_keymint_gf.txt +++ b/ProvisioningTool/sample_json_keymint_gf.txt @@ -1,13 +1,13 @@ { "attest_ids": { "brand": "Android", - "device": "generic_x86_64", - "product": "aosp_x86_64", + "device": "emulator_x86_64", + "product": "sdk_phone_x86_64", "serial": "", "imei": "000000000000000", "meid": "000000000000000", "manufacturer": "unknown", - "model": "AOSP on x86_64" + "model": "Android SDK built for x86_64" }, "shared_secret": "0000000000000000000000000000000000000000000000000000000000000000", "set_boot_params": { diff --git a/ProvisioningTool/src/construct_apdus.cpp b/ProvisioningTool/src/construct_apdus.cpp index 2c101a93..fb1b93d0 100644 --- a/ProvisioningTool/src/construct_apdus.cpp +++ b/ProvisioningTool/src/construct_apdus.cpp @@ -92,7 +92,6 @@ void usage() { printf("-o, --output jsonFile \t Output json file \n"); } - int ecRawKeyFromPKCS8(const std::vector& pkcs8Blob, std::vector& secret, std::vector& pub_x, std::vector& pub_y) { const uint8_t *data = pkcs8Blob.data(); @@ -317,9 +316,8 @@ int processInputFile() { int processAdditionalCertificateChain() { Json::Value signerInfo = root.get(kSignerInfo, Json::Value::nullRef); if (!signerInfo.isNull()) { + std::vector certData; std::string signerName; - std::string signingKeyFile; - std::vector previousKey; Array array; if (SUCCESS != getStringValue(signerInfo, "signer_name", signerName)) { @@ -327,89 +325,44 @@ int processAdditionalCertificateChain() { return FAILURE; } - Json::Value keys = signerInfo.get("signing_keys", Json::Value::nullRef); - if (!keys.isNull()) { - if (!keys.isArray()) { + Json::Value certChainFiles = signerInfo.get("signing_keys", Json::Value::nullRef); + if (!certChainFiles.isNull()) { + if (!certChainFiles.isArray()) { printf("\n Improper value for signing_keys in json file \n"); return FAILURE; } - for(uint32_t i = 0; i < keys.size(); i++) { - std::vector data; - std::vector privateKey; - std::vector x_coord; - std::vector y_coord; - - if (!keys[i].isString()) { - printf("\n Improper value for signing_keys in json file \n"); - return FAILURE; - } - - if(SUCCESS != readDataFromFile(keys[i].asString().data(), data)) { - printf("\n Failed to read the attestation key from the file.\n"); - return FAILURE; - } - if (SUCCESS != ecRawKeyFromPKCS8(data, privateKey, x_coord, y_coord)) { - return FAILURE; - } - - if (i == 0) { - // self-signed. - previousKey = privateKey; - } - - auto rootCoseSign = - cppcose::constructCoseSign1(previousKey, /* Signing key */ - cppbor::Map() /* Payload CoseKey */ - .add(CoseKey::KEY_TYPE, EC2) - .add(CoseKey::ALGORITHM, ES256) - .add(CoseKey::CURVE, P256) - .add(CoseKey::KEY_OPS, SIGN) - .add(CoseKey::PUBKEY_X, x_coord) - .add(CoseKey::PUBKEY_Y, y_coord) - .canonicalize() - .encode(), - {} /* AAD */); - if (!rootCoseSign) { - printf("\n Failed to construct CoseSign1 %s\n", rootCoseSign.moveMessage().c_str()); + for (uint32_t i = 0; i < certChainFiles.size(); i++) { + if(certChainFiles[i].isString()) { + /* Read the certificates. */ + if(SUCCESS != readDataFromFile(certChainFiles[i].asString().data(), certData)) { + printf("\n Failed to read the Root certificate\n"); + return FAILURE; + } + array.add(certData); + certData.clear(); + + } else { + printf("\n Fail: Only proper certificate paths as a " + "string is allowed inside the json file. \n"); return FAILURE; } - - // Add to cbor array - array.add(rootCoseSign.moveValue()); - previousKey = privateKey; } + } else { + printf("\n Fail: cert chain value should be an array inside the json file. \n"); + return FAILURE; } - std::vector dk_priv; - std::vector dk_pub_x; - std::vector dk_pub_y; - if (SUCCESS == getDeviceUniqueKey(dk_priv, dk_pub_x, dk_pub_y)) { - auto dkCoseSign = - cppcose::constructCoseSign1(previousKey, /* Signing key */ - cppbor::Map() /* Payload CoseKey */ - .add(CoseKey::KEY_TYPE, EC2) - .add(CoseKey::ALGORITHM, ES256) - .add(CoseKey::CURVE, P256) - .add(CoseKey::KEY_OPS, SIGN) - .add(CoseKey::PUBKEY_X, dk_pub_x) - .add(CoseKey::PUBKEY_Y, dk_pub_y) - .canonicalize() - .encode(), - {} /* AAD */); - if (!dkCoseSign) { - printf("\n Failed to construct CoseSign1 %s\n", dkCoseSign.moveMessage().c_str()); - return FAILURE; - } - array.add(dkCoseSign.moveValue()); - std::vector cborData = Map().add(signerName, std::move(array)).encode(); - if(SUCCESS != addApduHeader(kAdditionalCertChainCmd, cborData)) { - return FAILURE; - } - // Write to json. - writerRoot[kAdditionalCertChain] = getHexString(cborData); - } else { + // Prepare cbor input + cppbor::Map map; + map.add(signerName, std::move(array)); + cppbor::Bstr bstr(map.encode()); + std::vector cborData = bstr.encode(); + + if(SUCCESS != addApduHeader(kAdditionalCertChainCmd, cborData)) { return FAILURE; } + // Write to json. + writerRoot[kAdditionalCertChain] = getHexString(cborData); } else { printf("\n Improper value for signer_info in json file \n");