diff options
Diffstat (limited to 'keystone/common/utils.py')
-rw-r--r-- | keystone/common/utils.py | 66 |
1 files changed, 65 insertions, 1 deletions
diff --git a/keystone/common/utils.py b/keystone/common/utils.py index 70d277e52..792c17951 100644 --- a/keystone/common/utils.py +++ b/keystone/common/utils.py @@ -15,7 +15,7 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. - +import base64 import collections.abc import contextlib import grp @@ -25,6 +25,7 @@ import os import pwd import uuid +from cryptography import x509 from oslo_log import log from oslo_serialization import jsonutils from oslo_utils import reflection @@ -60,6 +61,14 @@ hash_user_password = password_hashing.hash_user_password check_password = password_hashing.check_password +# NOTE(hiromu): This dict defines alternative DN string for X.509. When +# retriving DN from X.509, converting attributes types that are not listed +# in the RFC4514 to a corresponding alternative DN string. +ATTR_NAME_OVERRIDES = { + x509.NameOID.EMAIL_ADDRESS: "emailAddress", +} + + def resource_uuid(value): """Convert input to valid UUID hex digits.""" try: @@ -458,6 +467,61 @@ def check_endpoint_url(url): raise exception.URLValidationError(url=url) +def get_certificate_subject_dn(cert_pem): + """Get subject DN from the PEM certificate content. + + :param str cert_pem: the PEM certificate content + :rtype: JSON data for subject DN + :raises keystone.exception.ValidationError: if the PEM certificate content + is invalid + """ + dn_dict = {} + try: + cert = x509.load_pem_x509_certificate(cert_pem.encode('utf-8')) + for item in cert.subject: + name, value = item.rfc4514_string( + attr_name_overrides=ATTR_NAME_OVERRIDES).split('=') + dn_dict[name] = value + except Exception as error: + LOG.exception(error) + message = _('The certificate content is not PEM format.') + raise exception.ValidationError(message=message) + return dn_dict + + +def get_certificate_issuer_dn(cert_pem): + """Get issuer DN from the PEM certificate content. + + :param str cert_pem: the PEM certificate content + :rtype: JSON data for issuer DN + :raises keystone.exception.ValidationError: if the PEM certificate content + is invalid + """ + dn_dict = {} + try: + cert = x509.load_pem_x509_certificate(cert_pem.encode('utf-8')) + for item in cert.issuer: + name, value = item.rfc4514_string( + attr_name_overrides=ATTR_NAME_OVERRIDES).split('=') + dn_dict[name] = value + except Exception as error: + LOG.exception(error) + message = _('The certificate content is not PEM format.') + raise exception.ValidationError(message=message) + return dn_dict + + +def get_certificate_thumbprint(cert_pem): + """Get certificate thumbprint from the PEM certificate content. + + :param str cert_pem: the PEM certificate content + :rtype: certificate thumbprint + """ + thumb_sha256 = hashlib.sha256(cert_pem.encode('ascii')).digest() + thumbprint = base64.urlsafe_b64encode(thumb_sha256).decode('ascii') + return thumbprint + + def create_directory(directory, keystone_user_id=None, keystone_group_id=None): """Attempt to create a directory if it doesn't exist. |