in java/remoteprovisioning/ProtectedDataPayload.java [281:353]
private void validateProtectedData(
CBORObject protectedDataPayload, byte[] challenge, byte[] deviceInfo, byte[] macedKeysMac)
throws CborException, CryptoException {
// Validate BCC chain, retrieve the device public key, and validate the MAC signature
CborUtil.checkArrayMinLength(
protectedDataPayload, PROTECTED_DATA_PAYLOAD_NUM_ENTRIES_MINIMUM, "ProtectedData");
Sign1Message signedMac;
try {
CBORObject signedMacObj =
protectedDataPayload.get(PROTECTED_DATA_SIGNED_MAC_INDEX);
byte[] signedMacEncoded = signedMacObj.EncodeToBytes();
signedMac = (Sign1Message) Message.DecodeFromBytes(signedMacEncoded, MessageTag.Sign1);
} catch (CoseException e) {
throw new CborException(
"Signed MAC decoding failure", e, CborException.DESERIALIZATION_ERROR);
}
// Build the Associated Authenticated Data
CBORObject arr = CBORObject.NewArray();
arr.Add(CBORObject.FromObject(challenge));
CBORObject deviceInfoObj = CBORObject.DecodeFromBytes(deviceInfo);
arr.Add(deviceInfoObj.get(DeviceInfo.DEVICE_INFO_VERIFIED));
arr.Add(CBORObject.FromObject(macedKeysMac));
signedMac.setExternal(arr.EncodeToBytes());
CBORObject bcc = protectedDataPayload.get(PROTECTED_DATA_BCC_INDEX);
OneKey devicePublicKey = verifyBccAndExtractDevicePublicKey(bcc);
try {
if (!signedMac.validate(devicePublicKey)) {
throw new CryptoException(
"Can't validate signature on MAC key",
CryptoException.MAC_WITH_AAD_SIGNATURE_VERIFICATION_FAILED);
}
} catch (CoseException e) {
throw new CryptoException(
"Can't validate signature on MAC key",
e,
CryptoException.MAC_WITH_AAD_SIGNATURE_VERIFICATION_FAILED);
}
// TODO: In future phases, the key signing the MAC is not going to be the device public key,
// it will be the leaf key in the BCC, which is owned by the KeyMint instance that
// generated the key pairs in the CSR. This should be renamed to be more generic, with
// supporting functionality.
try {
if (devicePublicKey.get(KeyKeys.KeyType.AsCBOR()).equals(KeyKeys.KeyType_OKP)) {
mDevicePublicKey = devicePublicKey.get(KeyKeys.OKP_X).ToObject(byte[].class);
} else if (devicePublicKey.get(KeyKeys.KeyType.AsCBOR()).equals(KeyKeys.KeyType_EC2)) {
mDevicePublicKey = new byte[64];
byte[] xCoord = CborUtil.getSafeBstr(
devicePublicKey.get(KeyKeys.EC2_X.AsCBOR()), 32, "Device public key X-coordinate");
byte[] yCoord = CborUtil.getSafeBstr(
devicePublicKey.get(KeyKeys.EC2_Y.AsCBOR()), 32, "Device public key Y-coordinate");
System.arraycopy(xCoord, 0, mDevicePublicKey, 0, 32);
System.arraycopy(yCoord, 0, mDevicePublicKey, 32, 32);
} else {
throw new CborException("Unsupported key type", CborException.INCORRECT_COSE_TYPE);
}
} catch (CoseException e) {
throw new CborException("Failed to decode the device public key", e,
CborException.DESERIALIZATION_ERROR);
}
mMacKey = signedMac.GetContent();
// Additional signatures are optional; they are only required in a solution where the
// signer cannot upload public keys from the factory floor due to various restrictions
// or obstacles they may deal with.
if (protectedDataPayload.size() == PROTECTED_DATA_PAYLOAD_NUM_ENTRIES_MINIMUM + 1) {
CBORObject additionalDkSignatures =
protectedDataPayload.get(PROTECTED_DATA_ADDITIONAL_DK_SIGNATURES);
extractAdditionalDkSignatures(additionalDkSignatures, devicePublicKey);
}
}