Fix generate_pkcs12_bundle for FIPS

generate_pkcs12_bundle used the PKCS12 class of the pyOpenSSL module
which is not compliant with FIPS (uses SHA1).
Switch to the cryptography module for generating the PKCS bundles unless
for really old releases (<=3.0) that don't support it (stable/train is
still on 2.8).

Change-Id: Ibd50e9a6e406683b7faba093d716c83d2b994ad7
This commit is contained in:
Gregory Thiemonge 2022-07-21 12:21:40 +02:00
parent 2f975b31c9
commit a66952e962
1 changed files with 25 additions and 6 deletions

View File

@ -17,6 +17,8 @@ import datetime
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.serialization import NoEncryption
from cryptography.hazmat.primitives.serialization import pkcs12
from cryptography import x509
from cryptography.x509.oid import NameOID
import OpenSSL
@ -184,12 +186,29 @@ def generate_pkcs12_bundle(server_cert, server_key):
:param server_key: A cryptography key (x509) object.
:returns: A pkcs12 bundle.
"""
# TODO(johnsom) Replace with cryptography once it supports creating pkcs12
pkcs12 = OpenSSL.crypto.PKCS12()
pkcs12.set_privatekey(
OpenSSL.crypto.PKey.from_cryptography_key(server_key))
pkcs12.set_certificate(OpenSSL.crypto.X509.from_cryptography(server_cert))
return pkcs12.export()
# Use the PKCS12 serialization function from cryptography if it exists
# (>=3.0), otherwise use the pyOpenSSL module.
#
# The PKCS12 class of the pyOpenSSL module is not compliant with FIPS.
# It uses the SHA1 function [0] which is not allowed when generating
# digital signatures [1]
#
# [0] https://github.com/pyca/pyopenssl/blob/
# 65ca53a7a06a7c78c1749200a6b3a007e47d3214/src/OpenSSL/
# crypto.py#L2748-L2749
# [1] https://nvlpubs.nist.gov/nistpubs/SpecialPublications/
# NIST.SP.800-131Ar1.pdf
if hasattr(pkcs12, 'serialize_key_and_certificates'):
p12 = pkcs12.serialize_key_and_certificates(
b'', server_key, server_cert,
cas=None, encryption_algorithm=NoEncryption())
else:
p12 = OpenSSL.crypto.PKCS12()
p12.set_privatekey(
OpenSSL.crypto.PKey.from_cryptography_key(server_key))
p12.set_certificate(OpenSSL.crypto.X509.from_cryptography(server_cert))
p12 = p12.export()
return p12
def generate_certificate_revocation_list(ca_cert, ca_key, cert_to_revoke):