When one or more vendor bills in Italian e-invoice format were sent to the registered PEC mailbox, if they are in the PKCS#7 format ('.xml.p7m'), nothing happened.
The e-invoice content should be automatically decoded and the invoice should be created as soon as the xml file is fetched from the PEC mailbox.
A new remove_signature function has been added in a tools/remove_signature.py file to handle this case.
The OpenSSL and pyOpenSSL libraries must be installed.
They are not in requirements.txt but they're probably available.
New tests has been provided for the signed email reading method.
opw-2460485
closes odoo/odoo#71164
X-original-commit: ed723be917637320fc4d2787bdf505e4a7a8216d
Signed-off-by: Josse Colpaert <jco@openerp.com>
Signed-off-by: Paolo Gatti <lordkrandel@users.noreply.github.com>
48 lines
1.7 KiB
Python
48 lines
1.7 KiB
Python
# -*- coding:utf-8 -*-
|
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
import logging
|
|
import warnings
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
try:
|
|
from OpenSSL import crypto as ssl_crypto
|
|
import OpenSSL._util as ssl_util
|
|
except ImportError:
|
|
ssl_crypto = None
|
|
_logger.warning("Cannot import library 'OpenSSL' for PKCS#7 envelope extraction.")
|
|
|
|
|
|
def remove_signature(content):
|
|
""" Remove the PKCS#7 envelope from given content, making a '.xml.p7m' file content readable as it was '.xml'.
|
|
As OpenSSL may not be installed, in that case a warning is issued and None is returned. """
|
|
|
|
# Prevent using the library if it had import errors
|
|
if not ssl_crypto:
|
|
_logger.warning("Error reading the content, check if the OpenSSL library is installed for for PKCS#7 envelope extraction.")
|
|
return None
|
|
|
|
# Load some tools from the library
|
|
null = ssl_util.ffi.NULL
|
|
verify = ssl_util.lib.PKCS7_verify
|
|
|
|
# By default ignore the validity of the certificates, just validate the structure
|
|
flags = ssl_util.lib.PKCS7_NOVERIFY | ssl_util.lib.PKCS7_NOSIGS
|
|
|
|
# Read the signed data fron the content
|
|
out_buffer = ssl_crypto._new_mem_buf()
|
|
|
|
# This method is deprecated, but there are actually no alternatives
|
|
with warnings.catch_warnings():
|
|
warnings.filterwarnings("ignore", category=DeprecationWarning)
|
|
loaded_data = ssl_crypto.load_pkcs7_data(ssl_crypto.FILETYPE_ASN1, content)
|
|
|
|
# Verify the signature
|
|
if verify(loaded_data._pkcs7, null, null, null, out_buffer, flags) != 1:
|
|
ssl_crypto._raise_current_error()
|
|
|
|
# Get the content as a byte-string
|
|
decoded_content = ssl_crypto._bio_to_string(out_buffer)
|
|
return decoded_content
|