abhishek-ram / pyas2-lib

AS2 Library for building and parsing Messages and MDNs
GNU General Public License v3.0
43 stars 28 forks source link

Support rsaes_oaep for KeyEncryptionAlgorithm #62

Closed chadgates closed 5 months ago

chadgates commented 1 year ago

Seems that MS BizTalk is using OAEP instead PKCS#1 v1.5, and therefore decryption fails with in cms.py -> decrypt_message with ""Unsupported Encryption Algorithm".

As a test, I did make simple changes to the decrypt function and see if in that case it would work:

`

    if cms.KeyEncryptionAlgorithmId(key_enc_alg) in (cms.KeyEncryptionAlgorithmId(
        "rsa"), cms.KeyEncryptionAlgorithmId("rsaes_oaep")):

        try:
            if key_enc_alg == 'rsa': 
                key = asymmetric.rsa_pkcs1v15_decrypt(decryption_key[0], encrypted_key)
            elif key_enc_alg == 'rsaes_oaep':
                key = asymmetric.rsa_oaep_decrypt(decryption_key[0], encrypted_key)

`

However, not sure if such an implementation is proper - I would assume we would want to also add something in the sending, and make it a partner element to select on outgoing message. But I don't feel comfortable doing that yet, as I simply don't know enough about the consequences of such a change, and if that is actually proper or not.

Any thoughts on this?

abhishek-ram commented 1 year ago

I think this works, maybe we want to rearrange the code. Do the key decrytion first and then do content decryption

        if cms.KeyEncryptionAlgorithmId(key_enc_alg) == cms.KeyEncryptionAlgorithmId(
            "rsa"
        ):
            try:
                key = asymmetric.rsa_pkcs1v15_decrypt(decryption_key[0], encrypted_key)
            except Exception as e:
                raise DecryptionError(
                    "Failed to decrypt the payload: Could not extract decryption key."
                ) from e
        elif  cms.KeyEncryptionAlgorithmId(key_enc_alg) == cms.KeyEncryptionAlgorithmId(
            "rsaes_oaep"
        ):
            try:
                key = asymmetric.rsa_oaep_decrypt(decryption_key[0], encrypted_key)
            except Exception as e:
                raise DecryptionError(
                    "Failed to decrypt the payload: Could not extract decryption key."
            ) from e
        else:
            raise AS2Exception(f"Unsupported Key Encryption Algorithm {key_enc_alg}")

        alg = cms_content["content"]["encrypted_content_info"][
            "content_encryption_algorithm"
        ]
        encapsulated_data = cms_content["content"]["encrypted_content_info"][
            "encrypted_content"
        ].native

        try:
            if alg["algorithm"].native == "rc4":
                decrypted_content = symmetric.rc4_decrypt(key, encapsulated_data)
            elif alg.encryption_cipher == "tripledes":
                cipher = "tripledes_192_cbc"
                decrypted_content = symmetric.tripledes_cbc_pkcs5_decrypt(
                    key, encapsulated_data, alg.encryption_iv
                )
            elif alg.encryption_cipher == "aes":
                decrypted_content = symmetric.aes_cbc_pkcs7_decrypt(
                    key, encapsulated_data, alg.encryption_iv
                )
            elif alg.encryption_cipher == "rc2":
                decrypted_content = symmetric.rc2_cbc_pkcs5_decrypt(
                    key, encapsulated_data, alg["parameters"]["iv"].native
                )
            else:
                raise AS2Exception(f"Unsupported Content Encryption Algorithm {alg}")
        except Exception as e:
            raise DecryptionError(
                "Failed to decrypt the payload: {}".format(e)
            ) from e