Skip to content

Commit d1d7fe7

Browse files
committed
Use cryptography to load PKCS12 certificates
... because implementation in PyOpenSSL has been derprecated, according to the following warning. ``` DeprecationWarning: PKCS#12 support in pyOpenSSL is deprecated. You should use the APIs in cryptography. ``` Closes-Bug: #2042787 Change-Id: Ic81e98c54c4bce100e3f44ff1a2fe6ce7b7f4256
1 parent 51ae110 commit d1d7fe7

File tree

5 files changed

+44
-35
lines changed

5 files changed

+44
-35
lines changed

octavia/certificates/common/pkcs12.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"""
1919

2020
from cryptography.hazmat.primitives import serialization
21-
from OpenSSL import crypto
21+
from cryptography.hazmat.primitives.serialization import pkcs12
2222

2323
from octavia.certificates.common import cert
2424
from octavia.common import exceptions
@@ -28,29 +28,29 @@ class PKCS12Cert(cert.Cert):
2828
"""Representation of a Cert for local storage."""
2929
def __init__(self, certbag):
3030
try:
31-
p12 = crypto.load_pkcs12(certbag)
32-
except crypto.Error as e:
31+
p12 = pkcs12.load_pkcs12(certbag, None)
32+
except (TypeError, ValueError) as e:
3333
raise exceptions.UnreadablePKCS12(error=str(e))
34-
self.certificate = p12.get_certificate()
35-
self.intermediates = p12.get_ca_certificates()
36-
self.private_key = p12.get_privatekey()
34+
self.certificate = p12.cert
35+
self.intermediates = p12.additional_certs
36+
self.private_key = p12.key
3737

3838
def get_certificate(self):
39-
return self.certificate.to_cryptography().public_bytes(
39+
return self.certificate.certificate.public_bytes(
4040
encoding=serialization.Encoding.PEM).strip()
4141

4242
def get_intermediates(self):
4343
if self.intermediates:
4444
int_data = [
45-
ic.to_cryptography().public_bytes(
45+
ic.certificate.public_bytes(
4646
encoding=serialization.Encoding.PEM).strip()
4747
for ic in self.intermediates
4848
]
4949
return int_data
5050
return None
5151

5252
def get_private_key(self):
53-
return self.private_key.to_cryptography_key().private_bytes(
53+
return self.private_key.private_bytes(
5454
encoding=serialization.Encoding.PEM,
5555
format=serialization.PrivateFormat.TraditionalOpenSSL,
5656
encryption_algorithm=serialization.NoEncryption()).strip()

octavia/certificates/manager/barbican.py

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@
1717
"""
1818
Cert manager implementation for Barbican using a single PKCS12 secret
1919
"""
20-
from OpenSSL import crypto
21-
20+
from cryptography.hazmat.primitives import serialization
21+
from cryptography.hazmat.primitives.serialization import pkcs12 as c_pkcs12
22+
from cryptography import x509
2223
from oslo_config import cfg
2324
from oslo_log import log as logging
2425
from oslo_utils import encodeutils
@@ -64,25 +65,29 @@ def store_cert(self, context, certificate, private_key, intermediates=None,
6465
connection = self.auth.get_barbican_client(context.project_id)
6566

6667
LOG.info("Storing certificate secret '%s' in Barbican.", name)
67-
p12 = crypto.PKCS12()
68-
p12.set_friendlyname(encodeutils.to_utf8(name))
69-
x509_cert = crypto.load_certificate(crypto.FILETYPE_PEM, certificate)
70-
p12.set_certificate(x509_cert)
71-
x509_pk = crypto.load_privatekey(crypto.FILETYPE_PEM, private_key)
72-
p12.set_privatekey(x509_pk)
73-
if intermediates:
74-
cert_ints = list(cert_parser.get_intermediates_pems(intermediates))
75-
x509_ints = [
76-
crypto.load_certificate(crypto.FILETYPE_PEM, ci)
77-
for ci in cert_ints]
78-
p12.set_ca_certificates(x509_ints)
68+
7969
if private_key_passphrase:
8070
raise exceptions.CertificateStorageException(
8171
"Passphrase protected PKCS12 certificates are not supported.")
8272

73+
x509_cert = x509.load_pem_x509_certificate(certificate)
74+
x509_pk = serialization.load_pem_private_key(private_key, None)
75+
cas = None
76+
if intermediates:
77+
cert_ints = list(cert_parser.get_intermediates_pems(intermediates))
78+
cas = [
79+
x509.load_pem_x509_certificate(ci)
80+
for ci in cert_ints]
81+
8382
try:
8483
certificate_secret = connection.secrets.create(
85-
payload=p12.export(),
84+
payload=c_pkcs12.serialize_key_and_certificates(
85+
name=encodeutils.safe_encode(name),
86+
key=x509_pk,
87+
cert=x509_cert,
88+
cas=cas,
89+
encryption_algorithm=serialization.NoEncryption()
90+
),
8691
expiration=expiration,
8792
name=name
8893
)

octavia/certificates/manager/castellan_mgr.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
"""
1919
from castellan.common.objects import opaque_data
2020
from castellan import key_manager
21-
from OpenSSL import crypto
21+
from cryptography.hazmat.primitives import serialization
22+
from cryptography.hazmat.primitives.serialization import pkcs12 as c_pkcs12
2223
from oslo_config import cfg
2324
from oslo_log import log as logging
2425

@@ -41,16 +42,20 @@ def __init__(self):
4142
def store_cert(self, context, certificate, private_key, intermediates=None,
4243
private_key_passphrase=None, expiration=None,
4344
name="PKCS12 Certificate Bundle"):
44-
p12 = crypto.PKCS12()
45-
p12.set_certificate(certificate)
46-
p12.set_privatekey(private_key)
47-
if intermediates:
48-
p12.set_ca_certificates(intermediates)
4945
if private_key_passphrase:
5046
raise exceptions.CertificateStorageException(
5147
"Passphrases protected PKCS12 certificates are not supported.")
5248

53-
p12_data = opaque_data.OpaqueData(p12.export(), name=name)
49+
p12_data = opaque_data.OpaqueData(
50+
c_pkcs12.serialize_key_and_certificates(
51+
name=None,
52+
key=private_key,
53+
cert=certificate,
54+
cas=intermediates,
55+
encryption_algorithm=serialization.NoEncryption()
56+
),
57+
name=name
58+
)
5459
self.manager.store(context, p12_data)
5560

5661
def get_cert(self, context, cert_ref, resource_ref=None, check_only=False,

octavia/tests/unit/certificates/manager/test_barbican.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
import uuid
1616

1717
from barbicanclient.v1 import secrets
18-
from OpenSSL import crypto
1918

2019
import octavia.certificates.common.barbican as barbican_common
2120
import octavia.certificates.common.cert as cert
@@ -138,10 +137,11 @@ def test_get_cert(self):
138137
sorted(data.get_intermediates()))
139138
self.assertIsNone(data.get_private_key_passphrase())
140139

141-
@mock.patch('OpenSSL.crypto.load_pkcs12')
140+
@mock.patch('cryptography.hazmat.primitives.serialization.pkcs12.'
141+
'load_pkcs12')
142142
def test_get_cert_bad_pkcs12(self, mock_load_pkcs12):
143143

144-
mock_load_pkcs12.side_effect = [crypto.Error]
144+
mock_load_pkcs12.side_effect = [ValueError]
145145

146146
# Mock out the client
147147
self.bc.secrets.get.return_value = self.secret_pkcs12

requirements.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ python-barbicanclient>=4.5.2 # Apache-2.0
3838
python-glanceclient>=2.8.0 # Apache-2.0
3939
python-novaclient>=9.1.0 # Apache-2.0
4040
python-cinderclient>=3.3.0 # Apache-2.0
41-
pyOpenSSL>=19.1.0 # Apache-2.0
4241
WSME>=0.8.0 # MIT
4342
Jinja2>=2.10 # BSD License (3 clause)
4443
taskflow>=4.4.0 # Apache-2.0

0 commit comments

Comments
 (0)