decryptAndVerifyMessage function

Future<Message> decryptAndVerifyMessage({
  1. required Message message,
  2. required String pgpPublicKey,
  3. required String pgpPrivateKey,
})

Decrypts and verifies a Push Chat Message

@param message encrypted chat message

@param pgpPublicKey pgp public key of signer of message - used for verification

@param pgpPrivateKey pgp private key of receiver - used for decryption

Implementation

Future<Message> decryptAndVerifyMessage({
  required Message message,
  required String pgpPublicKey,
  required String pgpPrivateKey,
}) async {
  /**
   * VERIFICATION
   * If verification proof is present then check that else check messageContent Signature
   */

  if (message.verificationProof != null &&
      message.verificationProof!.split(':')[0] == 'pgpv2') {
    Map<String, dynamic> bodyToBeHashed = {
      'fromDID': message.fromDID,
      'toDID': message.fromDID,
      'fromCAIP10': message.fromCAIP10,
      'toCAIP10': message.toCAIP10,
      'messageObj': message.messageObj,
      'messageType': message.messageType,
      'encType': message.encType,
      'encryptedSecret': message.encryptedSecret,
    };
    String hash = generateHash(bodyToBeHashed);
    String signature = message.verificationProof!.split(':')[1];
    await verifySignature(
      messageContent: hash,
      signatureArmored: signature,
      publicKeyArmored: pgpPublicKey,
    );
  } else if (message.verificationProof != null &&
      message.verificationProof!.split(':')[0] == 'pgpv3') {
    final bodyToBeHashed = {
      'fromDID': message.fromDID,
      'toDID': message.fromDID,
      'fromCAIP10': message.fromCAIP10,
      'toCAIP10': message.toCAIP10,
      'messageObj': message.messageObj,
      'messageType': message.messageType,
      'encType': message.encType,
      'sessionKey': message.sessionKey,
      'encryptedSecret': message.encryptedSecret,
    };
    String hash = generateHash(bodyToBeHashed);
    String signature = message.verificationProof!.split(':')[1];
    await verifySignature(
      messageContent: hash,
      signatureArmored: signature,
      publicKeyArmored: pgpPublicKey,
    );
  } else {
    if (message.link == null) {
      Map<String, dynamic> bodyToBeHashed = {
        'fromDID': message.fromDID,
        'toDID': message.toDID,
        'messageContent': message.messageContent,
        'messageType': message.messageType,
      };
      String hash = generateHash(bodyToBeHashed);
      try {
        await verifySignature(
          messageContent: hash,
          signatureArmored: message.signature,
          publicKeyArmored: pgpPublicKey,
        );
      } catch (e) {
        await verifySignature(
          messageContent: message.messageContent,
          signatureArmored: message.signature,
          publicKeyArmored: pgpPublicKey,
        );
      }
    } else {
      await verifySignature(
        messageContent: message.messageContent,
        signatureArmored: message.signature,
        publicKeyArmored: pgpPrivateKey,
      );
    }
  }

  /**
   * DECRYPTION
   * 1. Decrypt AES Key
   * 2. Decrypt messageObj.message, messageObj.meta , messageContent
   */
  try {
    /**
     * Get encryptedSecret from Backend using sessionKey for this encryption type
     */
    if (message.encType == 'pgpv1:group') {
      message.encryptedSecret = await getEncryptedSecret(
        sessionKey: message.sessionKey!,
      );
    }

    String secretKey = await pgpDecrypt(
      cipherText: message.encryptedSecret,
      privateKeyArmored: pgpPrivateKey,
    );

    if (message.messageObj != null) {
      message.messageObj = json.decode(
        aesDecrypt(
          // messageObj is a string as its encrypted
          cipherText: message.messageObj,
          secretKey: secretKey,
        ),
      );
    }

    message.messageContent =
        aesDecrypt(cipherText: message.messageContent, secretKey: secretKey);
  } catch (err) {
    message.messageContent = message.messageObj = 'Unable to Decrypt Message';
  }

  // log('decryptAndVerifyMessage - decrypted message - ${message.toJson()}');
  return message;
}