private void validateProtectedData()

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);
    }
  }