Add checks for dns name in certificate

This commit adds validation of https certificate for openstack
to ensure the provisioned endpoint domain matches the dns names
or the common name in the certificate.

If the domain is example.com, then the CN or SAN value must be
*.example.com.
SAN values, such as *.*.example.com, bad.*.example.com would not be
accepted.

Closes-Bug: 1826227

Change-Id: Ib50491282e8bf15b42f008d4eb55a7db9d64999b
Signed-off-by: Teresa Ho <teresa.ho@windriver.com>
This commit is contained in:
Teresa Ho 2019-07-17 23:43:25 -04:00
parent 8b52334cb0
commit 6ac774799e
7 changed files with 456 additions and 0 deletions

View File

@ -23,6 +23,7 @@ import datetime
import os
import pecan
import ssl
import wsme
import wsmeext.pecan as wsme_pecan
from cryptography import x509
@ -328,6 +329,15 @@ class CertificateController(rest.RestController):
if msg is not True:
return dict(success="", error=msg)
if mode == constants.CERT_MODE_OPENSTACK:
domain, msg = _check_endpoint_domain_exists()
if domain:
msg = _check_cert_dns_name(cert, domain)
if msg is not True:
return dict(success="", error=msg.message)
elif msg:
return dict(success="", error=msg)
if mode == constants.CERT_MODE_TPM:
try:
tpm = pecan.request.dbapi.tpmconfig_get_one()
@ -410,3 +420,62 @@ class CertificateController(rest.RestController):
return dict(success="", error="", body="",
certificates=sp_certificates_dict)
def _check_endpoint_domain_exists():
# Check that public endpoint FQDN is configured
endpoint_domain = None
msg = None
try:
endpoint_domain = pecan.request.dbapi.service_parameter_get_one(
constants.SERVICE_TYPE_OPENSTACK,
constants.SERVICE_PARAM_SECTION_OPENSTACK_HELM,
constants.SERVICE_PARAM_NAME_ENDPOINT_DOMAIN).value
except exception.NotFound:
msg = _("Service parameter for %s, %s, %s is not provisioned" % (
constants.SERVICE_TYPE_OPENSTACK,
constants.SERVICE_PARAM_SECTION_OPENSTACK_HELM,
constants.SERVICE_PARAM_NAME_ENDPOINT_DOMAIN
))
LOG.info(msg)
return endpoint_domain, msg
def _check_cert_dns_name(cert, endpoint_domain):
# Prepend the domain with any service name
service_endpoint_domain = 'keystone.' + endpoint_domain
# Check that the endpoint FQDN matches common name or
# the dns names in the subject alternative name section of the certificate
try:
alt_names = cert.extensions.get_extension_for_oid(
x509.oid.ExtensionOID.SUBJECT_ALTERNATIVE_NAME)
except x509.extensions.ExtensionNotFound:
alt_names = None
pass
if alt_names:
dns_names = alt_names.value.get_values_for_type(x509.DNSName)
if not alt_names or not dns_names:
cn = cert.subject.get_attributes_for_oid(
x509.oid.NameOID.COMMON_NAME)[0].value
LOG.debug("certificate has common name %s" % cn)
cert_cn = {'subject': ((('commonName', cn),),)}
try:
ssl.match_hostname(cert_cn, service_endpoint_domain)
except Exception as e:
LOG.info("Failed to match CN: %s" % e)
return e
else:
LOG.debug("Certificate contains subject alternative name %s" % dns_names)
dns_list = []
for name in dns_names:
dns_list.append(('DNS', name))
cert_san = {'subjectAltName': dns_list}
try:
ssl.match_hostname(cert_san, service_endpoint_domain)
except Exception as e:
LOG.info("Failed to match SAN: %s" % e)
return e
return True

View File

@ -0,0 +1,50 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAo1dfl2cF/7WRWrrz15coz280mEhjEjwUvUiefsnkoNk8h1K/
Pi00eoBUM/7RcI7xfS0Kayv9ABkhbxoJZdWe27DjU+JYt5vTGUj5B0qU6Z1uN342
kJsTJRy6Pfqj4ZMj3a6xFolcPxjGK6YmNtrqAT1XUH9RVcZvJTyRYX3pzUUKiLNy
+9arItM+QJS7j1jEEi2OkurCFLQQU914BArutInGkgHjOSj7qTUexGl1KnPFx3dy
TUYaPlOdNjN3FAymfCN9+vNhDI3NQukxL6nUNGFQmwNPj7rHk0GRg/j9NdiWqIhz
CkndXOeuFvmCCSsV151jKHc97TSj0awA+0Z11wIDAQABAoIBAAoESq1rOPf0d4R7
4IZBE9Scujn4fnLY0mDFOksGMIoYqFiYH3g9p3E3u3Iw10Ey0uZdQ71MxkgiQmWg
0CC5l/NbBqXXRJ+F480yJ2tmDHnDGMY4bDoz+FmXSGiSnUgxEMsAcoWySMDp0QVO
PBuzExSeYWNjW2aKM7ix3SyAXz0iPK1UuhQbunPeAv5ljv+b3NDXiDr5vk+FULUV
ueMvpnJciAa6aP5Yjz2m1PjaLmTA8h6gAnyrfIzsqDHFkBZxQU4tf/l/irifpJ/F
keWjtNxvBjYOXsTpKOb04yAZ++QgrbCaUJ9WVSVRxDFSMaZd6C9Xb2ptzGxwfutU
GTrzkukCgYEAzh0i8bEixgflO9Nup8OQHnTZ33cAh4Kkn0l+wOwRjT8HeUF31N3m
X8o7KFJ7Bdq/Y+aLF1H1cOygxz7lhYofGjnfRmtH2ltjwIitBhYYg5GXg+p3Bdy4
lj0OLGTbpqx9Kw2eGpx5zagVCG2d8XXxUlvPOu57/2QtI/kYB8Yyen0CgYEAyuAK
lkI+RhQVo10gINflKAWkIRhZfW+fs6R9e5sXyarTPJv+MbleqX0h7Mh8hzO4RqS4
j+9HKA0E/3guCkDIC9E3RtlFeAf17e9o+ABOFRHiSDGgLDB/PiHrKCnvqt1mxSVU
Yyb76wntn0lG/gkHyifwogZPJKixKqFJmlvRjeMCgYB8QXpwhF43Tkk20Nbz0mTO
x5kVK7Oo/exqjq8YdPh701SZGAu6y293rf4N5/N8awxYmIKfs2wpAK5Ij7Vk1Qi9
Ech1tnUhwViYmIzej3GF176k6zOH2DF7eSFTSBZXG8N1sgbvegfAIKVVaGgASh8K
jIiYuW8NXwILnr6K6URDLQKBgQCaXtgvdcCE+otsf1QPKbiJN6GoPSr7M5DF1QhW
obD8FywdFmXZ2D+boEfMMNHw3v39YyG9BEmUxDNlYUFHM/wEYfI5yuH9b7FGl8G7
1B+WEMGqRXinp09rK8wQB7kCvu2QXdNUjzlpo2hYqB2I974hqTqFT1+xeVs2IPws
pGlUGQKBgDyV6R4NZy9LW4ZuDB1i3aeQO65t88nB4FJe1lu3FZ1GzEyIpTrZol3t
cHt7DEY2PUKy3DHVtsEYS3gvB0a8IxnhMHxFnifgnvQMz4uSv6I6/YAc3uMjm57P
kzhEqcr/qj86gLuPFOjLFdnGQ2MgFfXg61TTXrIyVW423Gbidm2n
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIID1jCCAr6gAwIBAgIJANAQSpOMHLHWMA0GCSqGSIb3DQEBCwUAMIGSMQswCQYD
VQQGEwJDTjEQMA4GA1UECAwHT250YXJpbzEPMA0GA1UEBwwGT3R0YXdhMRgwFgYD
VQQKDA9XaW5kIFJpdmVyIEluYy4xFzAVBgNVBAsMDlRpdGFuaXVtIENsb3VkMS0w
KwYDVQQDDCRodHRwc19UaXRhbnVtX0Nsb3VkX0ludGVybmFsX1Rlc3RpbmcwHhcN
MTkwNzIyMjAxOTAxWhcNMjkwNzE5MjAxOTAxWjB6MQswCQYDVQQGEwJDTjEQMA4G
A1UECAwHT250YXJpbzEPMA0GA1UEBwwGT3R0YXdhMRgwFgYDVQQKDA9XaW5kIFJp
dmVyIEluYy4xFzAVBgNVBAsMDlRpdGFuaXVtIENsb3VkMRUwEwYDVQQDDAwqLnZi
b3gubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCjV1+XZwX/
tZFauvPXlyjPbzSYSGMSPBS9SJ5+yeSg2TyHUr8+LTR6gFQz/tFwjvF9LQprK/0A
GSFvGgll1Z7bsONT4li3m9MZSPkHSpTpnW43fjaQmxMlHLo9+qPhkyPdrrEWiVw/
GMYrpiY22uoBPVdQf1FVxm8lPJFhfenNRQqIs3L71qsi0z5AlLuPWMQSLY6S6sIU
tBBT3XgECu60icaSAeM5KPupNR7EaXUqc8XHd3JNRho+U502M3cUDKZ8I33682EM
jc1C6TEvqdQ0YVCbA0+PuseTQZGD+P012JaoiHMKSd1c564W+YIJKxXXnWModz3t
NKPRrAD7RnXXAgMBAAGjRjBEMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgXgMCoGA1Ud
EQQjMCGCEGJhZC4qLnZib3gubG9jYWyCDSouZXhhbXBsZS5jb20wDQYJKoZIhvcN
AQELBQADggEBAJks/7ZmAtc5z69dVQ9XrIcZhdLClz/L5fZsCK4xRXRxZ+zcgNDJ
SGIThjOi2pFpojYSVz9EDk5XyaOUtIcGkcBFK2k+BhceXueVcMgxYInICYTaXXvM
g5BMjBbDvx4CynFI/Vha3melaJ+zf6UWOxLl/UhqF5pEEm62WYypTblMmQcH2E1J
vwghQH/WmNetABwfJJ0yYepWBhHVEcyVoNEeKa6VR4TovpI+0h9ilnh/MR+tcRtq
Bjg22Q3+PyAcP6sVI+REElchFnL7iWGYIq3IUEhXItT/aHaOUuhcsuLuj2zKs4hr
burdyy1H7hGnJnfYyuqNQhxPfpsHxgOOHo4=
-----END CERTIFICATE-----

View File

@ -0,0 +1,48 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAo1dfl2cF/7WRWrrz15coz280mEhjEjwUvUiefsnkoNk8h1K/
Pi00eoBUM/7RcI7xfS0Kayv9ABkhbxoJZdWe27DjU+JYt5vTGUj5B0qU6Z1uN342
kJsTJRy6Pfqj4ZMj3a6xFolcPxjGK6YmNtrqAT1XUH9RVcZvJTyRYX3pzUUKiLNy
+9arItM+QJS7j1jEEi2OkurCFLQQU914BArutInGkgHjOSj7qTUexGl1KnPFx3dy
TUYaPlOdNjN3FAymfCN9+vNhDI3NQukxL6nUNGFQmwNPj7rHk0GRg/j9NdiWqIhz
CkndXOeuFvmCCSsV151jKHc97TSj0awA+0Z11wIDAQABAoIBAAoESq1rOPf0d4R7
4IZBE9Scujn4fnLY0mDFOksGMIoYqFiYH3g9p3E3u3Iw10Ey0uZdQ71MxkgiQmWg
0CC5l/NbBqXXRJ+F480yJ2tmDHnDGMY4bDoz+FmXSGiSnUgxEMsAcoWySMDp0QVO
PBuzExSeYWNjW2aKM7ix3SyAXz0iPK1UuhQbunPeAv5ljv+b3NDXiDr5vk+FULUV
ueMvpnJciAa6aP5Yjz2m1PjaLmTA8h6gAnyrfIzsqDHFkBZxQU4tf/l/irifpJ/F
keWjtNxvBjYOXsTpKOb04yAZ++QgrbCaUJ9WVSVRxDFSMaZd6C9Xb2ptzGxwfutU
GTrzkukCgYEAzh0i8bEixgflO9Nup8OQHnTZ33cAh4Kkn0l+wOwRjT8HeUF31N3m
X8o7KFJ7Bdq/Y+aLF1H1cOygxz7lhYofGjnfRmtH2ltjwIitBhYYg5GXg+p3Bdy4
lj0OLGTbpqx9Kw2eGpx5zagVCG2d8XXxUlvPOu57/2QtI/kYB8Yyen0CgYEAyuAK
lkI+RhQVo10gINflKAWkIRhZfW+fs6R9e5sXyarTPJv+MbleqX0h7Mh8hzO4RqS4
j+9HKA0E/3guCkDIC9E3RtlFeAf17e9o+ABOFRHiSDGgLDB/PiHrKCnvqt1mxSVU
Yyb76wntn0lG/gkHyifwogZPJKixKqFJmlvRjeMCgYB8QXpwhF43Tkk20Nbz0mTO
x5kVK7Oo/exqjq8YdPh701SZGAu6y293rf4N5/N8awxYmIKfs2wpAK5Ij7Vk1Qi9
Ech1tnUhwViYmIzej3GF176k6zOH2DF7eSFTSBZXG8N1sgbvegfAIKVVaGgASh8K
jIiYuW8NXwILnr6K6URDLQKBgQCaXtgvdcCE+otsf1QPKbiJN6GoPSr7M5DF1QhW
obD8FywdFmXZ2D+boEfMMNHw3v39YyG9BEmUxDNlYUFHM/wEYfI5yuH9b7FGl8G7
1B+WEMGqRXinp09rK8wQB7kCvu2QXdNUjzlpo2hYqB2I974hqTqFT1+xeVs2IPws
pGlUGQKBgDyV6R4NZy9LW4ZuDB1i3aeQO65t88nB4FJe1lu3FZ1GzEyIpTrZol3t
cHt7DEY2PUKy3DHVtsEYS3gvB0a8IxnhMHxFnifgnvQMz4uSv6I6/YAc3uMjm57P
kzhEqcr/qj86gLuPFOjLFdnGQ2MgFfXg61TTXrIyVW423Gbidm2n
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIIDiTCCAnECCQDQEEqTjByx2DANBgkqhkiG9w0BAQsFADCBkjELMAkGA1UEBhMC
Q04xEDAOBgNVBAgMB09udGFyaW8xDzANBgNVBAcMBk90dGF3YTEYMBYGA1UECgwP
V2luZCBSaXZlciBJbmMuMRcwFQYDVQQLDA5UaXRhbml1bSBDbG91ZDEtMCsGA1UE
AwwkaHR0cHNfVGl0YW51bV9DbG91ZF9JbnRlcm5hbF9UZXN0aW5nMB4XDTE5MDcz
MDE2NDQ0MFoXDTI5MDcyNzE2NDQ0MFowejELMAkGA1UEBhMCQ04xEDAOBgNVBAgM
B09udGFyaW8xDzANBgNVBAcMBk90dGF3YTEYMBYGA1UECgwPV2luZCBSaXZlciBJ
bmMuMRcwFQYDVQQLDA5UaXRhbml1bSBDbG91ZDEVMBMGA1UEAwwMKi52Ym94Lmxv
Y2FsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo1dfl2cF/7WRWrrz
15coz280mEhjEjwUvUiefsnkoNk8h1K/Pi00eoBUM/7RcI7xfS0Kayv9ABkhbxoJ
ZdWe27DjU+JYt5vTGUj5B0qU6Z1uN342kJsTJRy6Pfqj4ZMj3a6xFolcPxjGK6Ym
NtrqAT1XUH9RVcZvJTyRYX3pzUUKiLNy+9arItM+QJS7j1jEEi2OkurCFLQQU914
BArutInGkgHjOSj7qTUexGl1KnPFx3dyTUYaPlOdNjN3FAymfCN9+vNhDI3NQukx
L6nUNGFQmwNPj7rHk0GRg/j9NdiWqIhzCkndXOeuFvmCCSsV151jKHc97TSj0awA
+0Z11wIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQBy12kPVSfYuOKV8qMVDKQW9Hbp
Vm+FmHV6h2LpsMHKdNtLMeMhoaiHqFuHgOIIMYqVNDK7olJPHzMDx11ijeHSEVHk
lAgEyUE7wLblUm4NCtIAT2o5afr7FLVta6KdKv8BbDktczu6ffNTXPup3/3HTVJu
jS5ZaQMPkS/8f4InPbkhWvj162N5bsbwMYyGMyAFmi7J5WPvtgrMeiFfSsFHEZzW
MytI8uXa2lYrP0WADg3d0rVgCGXemBK0vsD0RmzxHIBsJNa3uGkWKUmv0+ogn39r
61DG1rVrGzBBvfjGca0Jri1B0HeCPXH+hjb+BRUst8MDO8bNM7FrFhX2yq3K
-----END CERTIFICATE-----

View File

@ -0,0 +1,50 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAo1dfl2cF/7WRWrrz15coz280mEhjEjwUvUiefsnkoNk8h1K/
Pi00eoBUM/7RcI7xfS0Kayv9ABkhbxoJZdWe27DjU+JYt5vTGUj5B0qU6Z1uN342
kJsTJRy6Pfqj4ZMj3a6xFolcPxjGK6YmNtrqAT1XUH9RVcZvJTyRYX3pzUUKiLNy
+9arItM+QJS7j1jEEi2OkurCFLQQU914BArutInGkgHjOSj7qTUexGl1KnPFx3dy
TUYaPlOdNjN3FAymfCN9+vNhDI3NQukxL6nUNGFQmwNPj7rHk0GRg/j9NdiWqIhz
CkndXOeuFvmCCSsV151jKHc97TSj0awA+0Z11wIDAQABAoIBAAoESq1rOPf0d4R7
4IZBE9Scujn4fnLY0mDFOksGMIoYqFiYH3g9p3E3u3Iw10Ey0uZdQ71MxkgiQmWg
0CC5l/NbBqXXRJ+F480yJ2tmDHnDGMY4bDoz+FmXSGiSnUgxEMsAcoWySMDp0QVO
PBuzExSeYWNjW2aKM7ix3SyAXz0iPK1UuhQbunPeAv5ljv+b3NDXiDr5vk+FULUV
ueMvpnJciAa6aP5Yjz2m1PjaLmTA8h6gAnyrfIzsqDHFkBZxQU4tf/l/irifpJ/F
keWjtNxvBjYOXsTpKOb04yAZ++QgrbCaUJ9WVSVRxDFSMaZd6C9Xb2ptzGxwfutU
GTrzkukCgYEAzh0i8bEixgflO9Nup8OQHnTZ33cAh4Kkn0l+wOwRjT8HeUF31N3m
X8o7KFJ7Bdq/Y+aLF1H1cOygxz7lhYofGjnfRmtH2ltjwIitBhYYg5GXg+p3Bdy4
lj0OLGTbpqx9Kw2eGpx5zagVCG2d8XXxUlvPOu57/2QtI/kYB8Yyen0CgYEAyuAK
lkI+RhQVo10gINflKAWkIRhZfW+fs6R9e5sXyarTPJv+MbleqX0h7Mh8hzO4RqS4
j+9HKA0E/3guCkDIC9E3RtlFeAf17e9o+ABOFRHiSDGgLDB/PiHrKCnvqt1mxSVU
Yyb76wntn0lG/gkHyifwogZPJKixKqFJmlvRjeMCgYB8QXpwhF43Tkk20Nbz0mTO
x5kVK7Oo/exqjq8YdPh701SZGAu6y293rf4N5/N8awxYmIKfs2wpAK5Ij7Vk1Qi9
Ech1tnUhwViYmIzej3GF176k6zOH2DF7eSFTSBZXG8N1sgbvegfAIKVVaGgASh8K
jIiYuW8NXwILnr6K6URDLQKBgQCaXtgvdcCE+otsf1QPKbiJN6GoPSr7M5DF1QhW
obD8FywdFmXZ2D+boEfMMNHw3v39YyG9BEmUxDNlYUFHM/wEYfI5yuH9b7FGl8G7
1B+WEMGqRXinp09rK8wQB7kCvu2QXdNUjzlpo2hYqB2I974hqTqFT1+xeVs2IPws
pGlUGQKBgDyV6R4NZy9LW4ZuDB1i3aeQO65t88nB4FJe1lu3FZ1GzEyIpTrZol3t
cHt7DEY2PUKy3DHVtsEYS3gvB0a8IxnhMHxFnifgnvQMz4uSv6I6/YAc3uMjm57P
kzhEqcr/qj86gLuPFOjLFdnGQ2MgFfXg61TTXrIyVW423Gbidm2n
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIIDxDCCAqygAwIBAgIJANAQSpOMHLHEMA0GCSqGSIb3DQEBCwUAMIGSMQswCQYD
VQQGEwJDTjEQMA4GA1UECAwHT250YXJpbzEPMA0GA1UEBwwGT3R0YXdhMRgwFgYD
VQQKDA9XaW5kIFJpdmVyIEluYy4xFzAVBgNVBAsMDlRpdGFuaXVtIENsb3VkMS0w
KwYDVQQDDCRodHRwc19UaXRhbnVtX0Nsb3VkX0ludGVybmFsX1Rlc3RpbmcwHhcN
MTkwMzE5MTU0NDE0WhcNMjkwMzE2MTU0NDE0WjB7MQswCQYDVQQGEwJDTjEQMA4G
A1UECAwHT250YXJpbzEPMA0GA1UEBwwGT3R0YXdhMRgwFgYDVQQKDA9XaW5kIFJp
dmVyIEluYy4xFzAVBgNVBAsMDlRpdGFuaXVtIENsb3VkMRYwFAYDVQQDDA0qLnZi
b3gubG9jYWwgMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo1dfl2cF
/7WRWrrz15coz280mEhjEjwUvUiefsnkoNk8h1K/Pi00eoBUM/7RcI7xfS0Kayv9
ABkhbxoJZdWe27DjU+JYt5vTGUj5B0qU6Z1uN342kJsTJRy6Pfqj4ZMj3a6xFolc
PxjGK6YmNtrqAT1XUH9RVcZvJTyRYX3pzUUKiLNy+9arItM+QJS7j1jEEi2OkurC
FLQQU914BArutInGkgHjOSj7qTUexGl1KnPFx3dyTUYaPlOdNjN3FAymfCN9+vNh
DI3NQukxL6nUNGFQmwNPj7rHk0GRg/j9NdiWqIhzCkndXOeuFvmCCSsV151jKHc9
7TSj0awA+0Z11wIDAQABozMwMTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIF4DAXBgNV
HREEEDAOggwqLnZib3gubG9jYWwwDQYJKoZIhvcNAQELBQADggEBACjGrHk9NBTP
RyD5BTd2LW3otn9849N3Pk0/EebX4bpv/KUfGodOGMrpfa8v+D560ASvQWPyQXG8
Jgy+lIhudHxPuSeLVWzwoBtA9G8dJrMhVOynmyQnc30FcQrC43Mr/fzFlz7yD+xc
RsDKGxPlZoNiXJ69N5cT9jDuqmkozlzsmtVK8wXua7JZF2AieD5Ak3aOA7lQjhz5
BmxnIpClBC3jsOT1c+9p1oiSe9Ox0yfqRGZX2ur5ItTqcQb37gQ2xlTDNOiSI8zH
gsTnBb5Oc7pH2TNZygV00u0flBTxCv2N86Gdm7v0FiXZiI7yNRejPWT6KKPl3rhR
BuXvEE7bj3k=
-----END CERTIFICATE-----

View File

@ -0,0 +1,50 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAo1dfl2cF/7WRWrrz15coz280mEhjEjwUvUiefsnkoNk8h1K/
Pi00eoBUM/7RcI7xfS0Kayv9ABkhbxoJZdWe27DjU+JYt5vTGUj5B0qU6Z1uN342
kJsTJRy6Pfqj4ZMj3a6xFolcPxjGK6YmNtrqAT1XUH9RVcZvJTyRYX3pzUUKiLNy
+9arItM+QJS7j1jEEi2OkurCFLQQU914BArutInGkgHjOSj7qTUexGl1KnPFx3dy
TUYaPlOdNjN3FAymfCN9+vNhDI3NQukxL6nUNGFQmwNPj7rHk0GRg/j9NdiWqIhz
CkndXOeuFvmCCSsV151jKHc97TSj0awA+0Z11wIDAQABAoIBAAoESq1rOPf0d4R7
4IZBE9Scujn4fnLY0mDFOksGMIoYqFiYH3g9p3E3u3Iw10Ey0uZdQ71MxkgiQmWg
0CC5l/NbBqXXRJ+F480yJ2tmDHnDGMY4bDoz+FmXSGiSnUgxEMsAcoWySMDp0QVO
PBuzExSeYWNjW2aKM7ix3SyAXz0iPK1UuhQbunPeAv5ljv+b3NDXiDr5vk+FULUV
ueMvpnJciAa6aP5Yjz2m1PjaLmTA8h6gAnyrfIzsqDHFkBZxQU4tf/l/irifpJ/F
keWjtNxvBjYOXsTpKOb04yAZ++QgrbCaUJ9WVSVRxDFSMaZd6C9Xb2ptzGxwfutU
GTrzkukCgYEAzh0i8bEixgflO9Nup8OQHnTZ33cAh4Kkn0l+wOwRjT8HeUF31N3m
X8o7KFJ7Bdq/Y+aLF1H1cOygxz7lhYofGjnfRmtH2ltjwIitBhYYg5GXg+p3Bdy4
lj0OLGTbpqx9Kw2eGpx5zagVCG2d8XXxUlvPOu57/2QtI/kYB8Yyen0CgYEAyuAK
lkI+RhQVo10gINflKAWkIRhZfW+fs6R9e5sXyarTPJv+MbleqX0h7Mh8hzO4RqS4
j+9HKA0E/3guCkDIC9E3RtlFeAf17e9o+ABOFRHiSDGgLDB/PiHrKCnvqt1mxSVU
Yyb76wntn0lG/gkHyifwogZPJKixKqFJmlvRjeMCgYB8QXpwhF43Tkk20Nbz0mTO
x5kVK7Oo/exqjq8YdPh701SZGAu6y293rf4N5/N8awxYmIKfs2wpAK5Ij7Vk1Qi9
Ech1tnUhwViYmIzej3GF176k6zOH2DF7eSFTSBZXG8N1sgbvegfAIKVVaGgASh8K
jIiYuW8NXwILnr6K6URDLQKBgQCaXtgvdcCE+otsf1QPKbiJN6GoPSr7M5DF1QhW
obD8FywdFmXZ2D+boEfMMNHw3v39YyG9BEmUxDNlYUFHM/wEYfI5yuH9b7FGl8G7
1B+WEMGqRXinp09rK8wQB7kCvu2QXdNUjzlpo2hYqB2I974hqTqFT1+xeVs2IPws
pGlUGQKBgDyV6R4NZy9LW4ZuDB1i3aeQO65t88nB4FJe1lu3FZ1GzEyIpTrZol3t
cHt7DEY2PUKy3DHVtsEYS3gvB0a8IxnhMHxFnifgnvQMz4uSv6I6/YAc3uMjm57P
kzhEqcr/qj86gLuPFOjLFdnGQ2MgFfXg61TTXrIyVW423Gbidm2n
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIID2DCCAsCgAwIBAgIJANAQSpOMHLHQMA0GCSqGSIb3DQEBCwUAMIGSMQswCQYD
VQQGEwJDTjEQMA4GA1UECAwHT250YXJpbzEPMA0GA1UEBwwGT3R0YXdhMRgwFgYD
VQQKDA9XaW5kIFJpdmVyIEluYy4xFzAVBgNVBAsMDlRpdGFuaXVtIENsb3VkMS0w
KwYDVQQDDCRodHRwc19UaXRhbnVtX0Nsb3VkX0ludGVybmFsX1Rlc3RpbmcwHhcN
MTkwNzIyMTYyNDM1WhcNMjkwNzE5MTYyNDM1WjB7MQswCQYDVQQGEwJDTjEQMA4G
A1UECAwHT250YXJpbzEPMA0GA1UEBwwGT3R0YXdhMRgwFgYDVQQKDA9XaW5kIFJp
dmVyIEluYy4xFzAVBgNVBAsMDlRpdGFuaXVtIENsb3VkMRYwFAYDVQQDDA0qLnZi
b3gubG9jYWwgMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo1dfl2cF
/7WRWrrz15coz280mEhjEjwUvUiefsnkoNk8h1K/Pi00eoBUM/7RcI7xfS0Kayv9
ABkhbxoJZdWe27DjU+JYt5vTGUj5B0qU6Z1uN342kJsTJRy6Pfqj4ZMj3a6xFolc
PxjGK6YmNtrqAT1XUH9RVcZvJTyRYX3pzUUKiLNy+9arItM+QJS7j1jEEi2OkurC
FLQQU914BArutInGkgHjOSj7qTUexGl1KnPFx3dyTUYaPlOdNjN3FAymfCN9+vNh
DI3NQukxL6nUNGFQmwNPj7rHk0GRg/j9NdiWqIhzCkndXOeuFvmCCSsV151jKHc9
7TSj0awA+0Z11wIDAQABo0cwRTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIF4DArBgNV
HREEJDAigg4qLioudmJveC5sb2NhbIIQYmFkLioudmJveC5sb2NhbDANBgkqhkiG
9w0BAQsFAAOCAQEAhawkjoc1WJz/kf3EiS3VuToQad048NTrN6dBOuvFrmSfI6Tr
cw+nW2UXmOYjOn0pWC1R1Otkp2F32UeHKtrfYFLT+kxQuJWNN3Sf3AWcSf2Y0RbS
BvGvnp4D+HSxs2fn8nf7ssmT50KBosPw7Q1HnH+fzmCNeayqceB9hl8DsiaYNN6w
JUHdEuoRSxQTSYJR1GDSdAvRhx6pYFZV+1ryDuXxqOqP74M+y0SP7DwNXqX3vA22
dZEvuWnbWIcKDc+1Ah/HgzoqoF/brTxE2RcxXtAp0uSEdP4HmqE+7t0pYD5AYXjV
FX9zl8kJXeDhbUfXEM018Hm9sejLQndpHG1khA==
-----END CERTIFICATE-----

View File

@ -0,0 +1,50 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAo1dfl2cF/7WRWrrz15coz280mEhjEjwUvUiefsnkoNk8h1K/
Pi00eoBUM/7RcI7xfS0Kayv9ABkhbxoJZdWe27DjU+JYt5vTGUj5B0qU6Z1uN342
kJsTJRy6Pfqj4ZMj3a6xFolcPxjGK6YmNtrqAT1XUH9RVcZvJTyRYX3pzUUKiLNy
+9arItM+QJS7j1jEEi2OkurCFLQQU914BArutInGkgHjOSj7qTUexGl1KnPFx3dy
TUYaPlOdNjN3FAymfCN9+vNhDI3NQukxL6nUNGFQmwNPj7rHk0GRg/j9NdiWqIhz
CkndXOeuFvmCCSsV151jKHc97TSj0awA+0Z11wIDAQABAoIBAAoESq1rOPf0d4R7
4IZBE9Scujn4fnLY0mDFOksGMIoYqFiYH3g9p3E3u3Iw10Ey0uZdQ71MxkgiQmWg
0CC5l/NbBqXXRJ+F480yJ2tmDHnDGMY4bDoz+FmXSGiSnUgxEMsAcoWySMDp0QVO
PBuzExSeYWNjW2aKM7ix3SyAXz0iPK1UuhQbunPeAv5ljv+b3NDXiDr5vk+FULUV
ueMvpnJciAa6aP5Yjz2m1PjaLmTA8h6gAnyrfIzsqDHFkBZxQU4tf/l/irifpJ/F
keWjtNxvBjYOXsTpKOb04yAZ++QgrbCaUJ9WVSVRxDFSMaZd6C9Xb2ptzGxwfutU
GTrzkukCgYEAzh0i8bEixgflO9Nup8OQHnTZ33cAh4Kkn0l+wOwRjT8HeUF31N3m
X8o7KFJ7Bdq/Y+aLF1H1cOygxz7lhYofGjnfRmtH2ltjwIitBhYYg5GXg+p3Bdy4
lj0OLGTbpqx9Kw2eGpx5zagVCG2d8XXxUlvPOu57/2QtI/kYB8Yyen0CgYEAyuAK
lkI+RhQVo10gINflKAWkIRhZfW+fs6R9e5sXyarTPJv+MbleqX0h7Mh8hzO4RqS4
j+9HKA0E/3guCkDIC9E3RtlFeAf17e9o+ABOFRHiSDGgLDB/PiHrKCnvqt1mxSVU
Yyb76wntn0lG/gkHyifwogZPJKixKqFJmlvRjeMCgYB8QXpwhF43Tkk20Nbz0mTO
x5kVK7Oo/exqjq8YdPh701SZGAu6y293rf4N5/N8awxYmIKfs2wpAK5Ij7Vk1Qi9
Ech1tnUhwViYmIzej3GF176k6zOH2DF7eSFTSBZXG8N1sgbvegfAIKVVaGgASh8K
jIiYuW8NXwILnr6K6URDLQKBgQCaXtgvdcCE+otsf1QPKbiJN6GoPSr7M5DF1QhW
obD8FywdFmXZ2D+boEfMMNHw3v39YyG9BEmUxDNlYUFHM/wEYfI5yuH9b7FGl8G7
1B+WEMGqRXinp09rK8wQB7kCvu2QXdNUjzlpo2hYqB2I974hqTqFT1+xeVs2IPws
pGlUGQKBgDyV6R4NZy9LW4ZuDB1i3aeQO65t88nB4FJe1lu3FZ1GzEyIpTrZol3t
cHt7DEY2PUKy3DHVtsEYS3gvB0a8IxnhMHxFnifgnvQMz4uSv6I6/YAc3uMjm57P
kzhEqcr/qj86gLuPFOjLFdnGQ2MgFfXg61TTXrIyVW423Gbidm2n
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIID5DCCAsygAwIBAgIJANAQSpOMHLHUMA0GCSqGSIb3DQEBCwUAMIGSMQswCQYD
VQQGEwJDTjEQMA4GA1UECAwHT250YXJpbzEPMA0GA1UEBwwGT3R0YXdhMRgwFgYD
VQQKDA9XaW5kIFJpdmVyIEluYy4xFzAVBgNVBAsMDlRpdGFuaXVtIENsb3VkMS0w
KwYDVQQDDCRodHRwc19UaXRhbnVtX0Nsb3VkX0ludGVybmFsX1Rlc3RpbmcwHhcN
MTkwNzIyMTkyNjQzWhcNMjkwNzE5MTkyNjQzWjB6MQswCQYDVQQGEwJDTjEQMA4G
A1UECAwHT250YXJpbzEPMA0GA1UEBwwGT3R0YXdhMRgwFgYDVQQKDA9XaW5kIFJp
dmVyIEluYy4xFzAVBgNVBAsMDlRpdGFuaXVtIENsb3VkMRUwEwYDVQQDDAwqLnZi
b3gubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCjV1+XZwX/
tZFauvPXlyjPbzSYSGMSPBS9SJ5+yeSg2TyHUr8+LTR6gFQz/tFwjvF9LQprK/0A
GSFvGgll1Z7bsONT4li3m9MZSPkHSpTpnW43fjaQmxMlHLo9+qPhkyPdrrEWiVw/
GMYrpiY22uoBPVdQf1FVxm8lPJFhfenNRQqIs3L71qsi0z5AlLuPWMQSLY6S6sIU
tBBT3XgECu60icaSAeM5KPupNR7EaXUqc8XHd3JNRho+U502M3cUDKZ8I33682EM
jc1C6TEvqdQ0YVCbA0+PuseTQZGD+P012JaoiHMKSd1c564W+YIJKxXXnWModz3t
NKPRrAD7RnXXAgMBAAGjVDBSMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgXgMDgGA1Ud
EQQxMC+CDCoudmJveC5sb2NhbIIQYmFkLioudmJveC5sb2NhbIINKi5leGFtcGxl
LmNvbTANBgkqhkiG9w0BAQsFAAOCAQEAk0HgwlWUmKBBOlE7EmyuZQ5XUtxd+5Gx
iMfQ13iiciCHDmcKKiC2zspdIqNhRrUxLA1ht/lbs6KTVxRYA+j44dasU+fG3vOR
Fe/HovWyoDi+NYZcGWnselQ7cyJ/L/CRItWmVGkpDxBb9n2lCnI0mZ0POqrZC2EI
CSuaSJij6W4H9XWjyP8vXANYGrP3dUkKTrsFzTdDiqDi/7/hYgwIHuVZYCmnb5Id
HRlmODxRW+JIt6Yyej0dFI/fepgA7CJjWcK1cmbRU6LTmK19Z1Y0pBeoiRVpQaYu
usixcBMJ5kVk3D4B67TMyQX6cRbBRdh+v9EyyJ+utQnMik+C5LN4ng==
-----END CERTIFICATE-----

View File

@ -0,0 +1,139 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# -*- encoding: utf-8 -*-
#
#
# Copyright (c) 2017-2019 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
"""
Tests for the API /certificate_install/ methods.
"""
import os
from cryptography import x509
from cryptography.hazmat.backends import default_backend
from sysinv.api.controllers.v1 import certificate as cert_api
from sysinv.tests.api import base
class CertificateTestCase(base.FunctionalTest):
def setUp(self):
super(CertificateTestCase, self).setUp()
def test_check_cert_dns_name_valid_SAN(self):
# This certificate contains
# CN: *.vbox.local
# DNS: *.vbox.local
certfile = os.path.join(os.path.dirname(__file__), "data",
'cert-with-key-SAN.pem')
with open(certfile, 'rb') as f:
pem_contents = f.read()
cert = x509.load_pem_x509_certificate(pem_contents,
default_backend())
result = cert_api._check_cert_dns_name(cert, 'vbox.local')
self.assertTrue(result)
result = cert_api._check_cert_dns_name(cert, 'domain.org')
self.assertIn("doesn't match", str(result))
result = cert_api._check_cert_dns_name(cert, 'lab.vbox.local')
self.assertIn("doesn't match", str(result))
def test_check_cert_dns_name_invalid_SAN(self):
# This certificate contains
# CN: *.vbox.local
# DNS:*.*.vbox.local, DNS:bad.*.vbox.local
certfile = os.path.join(os.path.dirname(__file__), "data",
'cert-with-key-invalidDNS.pem')
with open(certfile, 'rb') as f:
pem_contents = f.read()
cert = x509.load_pem_x509_certificate(pem_contents,
default_backend())
result = cert_api._check_cert_dns_name(cert, 'vbox.local')
self.assertIn("doesn't match", str(result))
result = cert_api._check_cert_dns_name(cert, 'a.vbox.local')
self.assertIn("doesn't match", str(result))
result = cert_api._check_cert_dns_name(cert, 'a.b.vbox.local')
self.assertIn("doesn't match", str(result))
result = cert_api._check_cert_dns_name(cert, 'bad.b.vbox.local')
self.assertIn("doesn't match", str(result))
def test_check_cert_dns_name_CN_only(self):
# This certificate contains CN:*.vbox.local
certfile = os.path.join(os.path.dirname(__file__), "data",
'cert-with-key-CNnoSAN.pem')
with open(certfile, 'rb') as f:
pem_contents = f.read()
cert = x509.load_pem_x509_certificate(pem_contents,
default_backend())
result = cert_api._check_cert_dns_name(cert, 'vbox.local')
self.assertTrue(result)
result = cert_api._check_cert_dns_name(cert, 'a.vbox.local')
self.assertIn("doesn't match", str(result))
result = cert_api._check_cert_dns_name(cert, 'a.b.vbox.local')
self.assertIn("doesn't match", str(result))
result = cert_api._check_cert_dns_name(cert, 'bad.b.vbox.local')
self.assertIn("doesn't match", str(result))
def test_check_cert_dns_name_multi_SAN(self):
# This certificate contains
# CN: *.vbox.local
# DNS: *.vbox.local, bad.*.vbox.local, *.example.com
certfile = os.path.join(os.path.dirname(__file__), "data",
'cert-with-key-multiSAN.pem')
with open(certfile, 'rb') as f:
pem_contents = f.read()
cert = x509.load_pem_x509_certificate(pem_contents,
default_backend())
result = cert_api._check_cert_dns_name(cert, 'vbox.local')
self.assertTrue(result)
# domain matches one of the DNS names, but not the CN
result = cert_api._check_cert_dns_name(cert, 'example.com')
self.assertTrue(result)
result = cert_api._check_cert_dns_name(cert, 'a.vbox.local')
self.assertIn("doesn't match", str(result))
result = cert_api._check_cert_dns_name(cert, 'x.example.com')
self.assertIn("doesn't match", str(result))
def test_check_cert_dns_name_CN_differ_SAN(self):
# This certificate contains
# CN: *.vbox.local
# DNS: bad.*.vbox.local, *.example.com
certfile = os.path.join(os.path.dirname(__file__), "data",
'cert-with-key-CNdifferSAN.pem')
with open(certfile, 'rb') as f:
pem_contents = f.read()
cert = x509.load_pem_x509_certificate(pem_contents,
default_backend())
# domain matches CN, but does not match any of the DNS names
result = cert_api._check_cert_dns_name(cert, 'vbox.local')
self.assertIn("doesn't match", str(result))
# domain matches one of the DNS names, but not the CN
result = cert_api._check_cert_dns_name(cert, 'example.com')
self.assertTrue(result)
result = cert_api._check_cert_dns_name(cert, 'a.vbox.local')
self.assertIn("doesn't match", str(result))
result = cert_api._check_cert_dns_name(cert, 'x.example.com')
self.assertIn("doesn't match", str(result))