From 760cfda0b1468d502700793c124955130b13af83 Mon Sep 17 00:00:00 2001 From: Chris Lalancette Date: Tue, 6 Feb 2024 08:04:24 -0500 Subject: [PATCH] Use modern PKCS7 to sign the certificate bytes. (#290) * Use modern PKCS7 to sign the certificate bytes. Using the SSLBinding leads to a warning in newer versions of pycryptography. Luckily, there is a supported API called pkcs7 that allows us to do the same thing. Even better, this API is supported since pycryptography 3.2, so this should work on both Ubuntu 22.04 and Ubuntu 24.04 without warnings. * Keep fallback path for using SSLBinding. Windows is still using pycryptography 2.9, which doesn't support the new pkcs7 API. Signed-off-by: Chris Lalancette --- sros2/sros2/_utilities.py | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/sros2/sros2/_utilities.py b/sros2/sros2/_utilities.py index 6291be0f..f35442f4 100644 --- a/sros2/sros2/_utilities.py +++ b/sros2/sros2/_utilities.py @@ -19,7 +19,6 @@ from cryptography import x509 from cryptography.hazmat.backends import default_backend as cryptography_backend -from cryptography.hazmat.bindings.openssl.binding import Binding as SSLBinding from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.asymmetric import ec @@ -133,7 +132,21 @@ def load_cert(cert_path: pathlib.Path): cert_file.read(), cryptography_backend()) -def _sign_bytes(cert, key, byte_string): +def _sign_bytes_pkcs7(cert, key, byte_string): + from cryptography.hazmat.primitives.serialization import pkcs7 + + builder = ( + pkcs7.PKCS7SignatureBuilder() + .set_data(byte_string) + .add_signer(cert, key, hashes.SHA256()) + ) + options = [pkcs7.PKCS7Options.Text, pkcs7.PKCS7Options.DetachedSignature] + return builder.sign(serialization.Encoding.SMIME, options) + + +def _sign_bytes_ssl_binding(cert, key, byte_string): + from cryptography.hazmat.bindings.openssl.binding import Binding as SSLBinding + # Using two flags here to get the output required: # - PKCS7_DETACHED: Use cleartext signing # - PKCS7_TEXT: Set the MIME headers for text/plain @@ -170,3 +183,12 @@ def _sign_bytes(cert, key, byte_string): SSLBinding.lib.BIO_free(bio_in) return output + + +def _sign_bytes(cert, key, byte_string): + try: + return _sign_bytes_pkcs7(cert, key, byte_string) + except ImportError: + pass + + return _sign_bytes_ssl_binding(cert, key, byte_string)