New metadata configuration for encryption.

This commit is contained in:
Hans Hörberg
2015-06-02 15:34:01 +02:00
parent 9c2b951be6
commit cddf80f4c0
16 changed files with 289 additions and 134 deletions

View File

@@ -3,7 +3,9 @@ from __future__ import print_function
import logging
import re
import argparse
import os
from saml2.extension.pefim import SPCertEnc
from saml2.metadata import create_metadata_string
import service_conf
from Cookie import SimpleCookie
@@ -753,6 +755,21 @@ def add_urls():
# ----------------------------------------------------------------------------
def metadata(environ, start_response):
try:
path = _args.path
if path is None or len(path) == 0:
path = os.path.dirname(os.path.abspath( __file__ ))
if path[-1] != "/":
path += "/"
metadata = create_metadata_string(path+"sp_conf.py", None,
_args.valid, _args.cert, _args.keyfile,
_args.id, _args.name, _args.sign)
start_response('200 OK', [('Content-Type', "text/xml")])
return metadata
except Exception as ex:
logger.error("An error occured while creating metadata:" + ex.message)
return not_found(environ, start_response)
def application(environ, start_response):
"""
@@ -769,6 +786,8 @@ def application(environ, start_response):
path = environ.get('PATH_INFO', '').lstrip('/')
logger.debug("<application> PATH: '%s'" % path)
if path == "metadata":
return metadata(environ, start_response)
logger.debug("Finding callback to run")
try:
@@ -822,6 +841,18 @@ if __name__ == '__main__':
_parser.add_argument('-W', dest='wayf', action='store_true',
help="Which WAYF url to use")
_parser.add_argument("config", help="SAML client config")
_parser.add_argument('-p', dest='path', help='Path to configuration file.')
_parser.add_argument('-v', dest='valid', default="4",
help="How long, in days, the metadata is valid from the time of creation")
_parser.add_argument('-c', dest='cert', help='certificate')
_parser.add_argument('-i', dest='id',
help="The ID of the entities descriptor in the metadata")
_parser.add_argument('-k', dest='keyfile',
help="A file with a key to sign the metadata with")
_parser.add_argument('-n', dest='name')
_parser.add_argument('-S', dest='sign', action='store_true',
help="sign the metadata")
ARGS = {}
_args = _parser.parse_args()

View File

@@ -1,34 +0,0 @@
<?xml version='1.0' encoding='UTF-8'?>
<ns0:EntityDescriptor xmlns:ns0="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ns1="urn:oasis:names:tc:SAML:metadata:attribute" xmlns:ns2="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:ns4="http://www.w3.org/2000/09/xmldsig#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" entityID="http://localhost:8087/sp.xml"><ns0:Extensions><ns1:EntityAttributes><ns2:Attribute Name="http://macedir.org/entity-category" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"><ns2:AttributeValue xsi:type="xs:string">http://www.geant.net/uri/dataprotection-code-of-conduct/v1</ns2:AttributeValue></ns2:Attribute></ns1:EntityAttributes></ns0:Extensions><ns0:SPSSODescriptor AuthnRequestsSigned="false" WantAssertionsSigned="true" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"><ns0:KeyDescriptor use="encryption"><ns4:KeyInfo><ns4:X509Data><ns4:X509Certificate>MIIC8jCCAlugAwIBAgIJAJHg2V5J31I8MA0GCSqGSIb3DQEBBQUAMFoxCzAJBgNV
BAYTAlNFMQ0wCwYDVQQHEwRVbWVhMRgwFgYDVQQKEw9VbWVhIFVuaXZlcnNpdHkx
EDAOBgNVBAsTB0lUIFVuaXQxEDAOBgNVBAMTB1Rlc3QgU1AwHhcNMDkxMDI2MTMz
MTE1WhcNMTAxMDI2MTMzMTE1WjBaMQswCQYDVQQGEwJTRTENMAsGA1UEBxMEVW1l
YTEYMBYGA1UEChMPVW1lYSBVbml2ZXJzaXR5MRAwDgYDVQQLEwdJVCBVbml0MRAw
DgYDVQQDEwdUZXN0IFNQMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDkJWP7
bwOxtH+E15VTaulNzVQ/0cSbM5G7abqeqSNSs0l0veHr6/ROgW96ZeQ57fzVy2MC
FiQRw2fzBs0n7leEmDJyVVtBTavYlhAVXDNa3stgvh43qCfLx+clUlOvtnsoMiiR
mo7qf0BoPKTj7c0uLKpDpEbAHQT4OF1HRYVxMwIDAQABo4G/MIG8MB0GA1UdDgQW
BBQ7RgbMJFDGRBu9o3tDQDuSoBy7JjCBjAYDVR0jBIGEMIGBgBQ7RgbMJFDGRBu9
o3tDQDuSoBy7JqFepFwwWjELMAkGA1UEBhMCU0UxDTALBgNVBAcTBFVtZWExGDAW
BgNVBAoTD1VtZWEgVW5pdmVyc2l0eTEQMA4GA1UECxMHSVQgVW5pdDEQMA4GA1UE
AxMHVGVzdCBTUIIJAJHg2V5J31I8MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEF
BQADgYEAMuRwwXRnsiyWzmRikpwinnhTmbooKm5TINPE7A7gSQ710RxioQePPhZO
zkM27NnHTrCe2rBVg0EGz7QTd1JIwLPvgoj4VTi/fSha/tXrYUaqc9AqU1kWI4WN
+vffBGQ09mo+6CffuFTZYeOhzP/2stAPwCTU4kxEoiy0KpZMANI=
</ns4:X509Certificate></ns4:X509Data></ns4:KeyInfo></ns0:KeyDescriptor><ns0:KeyDescriptor use="signing"><ns4:KeyInfo><ns4:X509Data><ns4:X509Certificate>MIIC8jCCAlugAwIBAgIJAJHg2V5J31I8MA0GCSqGSIb3DQEBBQUAMFoxCzAJBgNV
BAYTAlNFMQ0wCwYDVQQHEwRVbWVhMRgwFgYDVQQKEw9VbWVhIFVuaXZlcnNpdHkx
EDAOBgNVBAsTB0lUIFVuaXQxEDAOBgNVBAMTB1Rlc3QgU1AwHhcNMDkxMDI2MTMz
MTE1WhcNMTAxMDI2MTMzMTE1WjBaMQswCQYDVQQGEwJTRTENMAsGA1UEBxMEVW1l
YTEYMBYGA1UEChMPVW1lYSBVbml2ZXJzaXR5MRAwDgYDVQQLEwdJVCBVbml0MRAw
DgYDVQQDEwdUZXN0IFNQMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDkJWP7
bwOxtH+E15VTaulNzVQ/0cSbM5G7abqeqSNSs0l0veHr6/ROgW96ZeQ57fzVy2MC
FiQRw2fzBs0n7leEmDJyVVtBTavYlhAVXDNa3stgvh43qCfLx+clUlOvtnsoMiiR
mo7qf0BoPKTj7c0uLKpDpEbAHQT4OF1HRYVxMwIDAQABo4G/MIG8MB0GA1UdDgQW
BBQ7RgbMJFDGRBu9o3tDQDuSoBy7JjCBjAYDVR0jBIGEMIGBgBQ7RgbMJFDGRBu9
o3tDQDuSoBy7JqFepFwwWjELMAkGA1UEBhMCU0UxDTALBgNVBAcTBFVtZWExGDAW
BgNVBAoTD1VtZWEgVW5pdmVyc2l0eTEQMA4GA1UECxMHSVQgVW5pdDEQMA4GA1UE
AxMHVGVzdCBTUIIJAJHg2V5J31I8MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEF
BQADgYEAMuRwwXRnsiyWzmRikpwinnhTmbooKm5TINPE7A7gSQ710RxioQePPhZO
zkM27NnHTrCe2rBVg0EGz7QTd1JIwLPvgoj4VTi/fSha/tXrYUaqc9AqU1kWI4WN
+vffBGQ09mo+6CffuFTZYeOhzP/2stAPwCTU4kxEoiy0KpZMANI=
</ns4:X509Certificate></ns4:X509Data></ns4:KeyInfo></ns0:KeyDescriptor><ns0:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://localhost:8087/acs/post" index="1" /><ns0:AttributeConsumingService index="1"><ns0:ServiceName xml:lang="en">My SP service</ns0:ServiceName><ns0:ServiceDescription xml:lang="en">Example SP</ns0:ServiceDescription><ns0:RequestedAttribute FriendlyName="sn" Name="urn:oid:2.5.4.4" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true" /><ns0:RequestedAttribute FriendlyName="givenname" Name="urn:oid:2.5.4.42" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true" /><ns0:RequestedAttribute FriendlyName="uid" Name="urn:oid:0.9.2342.19200300.100.1.1" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true" /><ns0:RequestedAttribute FriendlyName="edupersonaffiliation" Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.1" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true" /><ns0:RequestedAttribute FriendlyName="title" Name="urn:oid:2.5.4.12" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="false" /></ns0:AttributeConsumingService></ns0:SPSSODescriptor></ns0:EntityDescriptor>

View File

@@ -49,8 +49,8 @@ ONTS = {
}
COMMON_ARGS = [
"entityid", "xmlsec_binary", "debug", "key_file", "cert_file",
"encryption_type", "secret", "accepted_time_diff", "name", "ca_certs",
"entityid", "xmlsec_binary", "debug", "key_file", "cert_file", "encryption_keypairs", "additional_cert_files",
"metadata_key_usage", "secret", "accepted_time_diff", "name", "ca_certs",
"description", "valid_for", "verify_ssl_cert",
"organization",
"contact_person",
@@ -190,7 +190,9 @@ class Config(object):
self.debug = False
self.key_file = None
self.cert_file = None
self.encryption_type = 'both'
self.encryption_keypairs = None
self.additional_cert_files = None
self.metadata_key_usage = 'both'
self.secret = None
self.accepted_time_diff = None
self.name = None

View File

@@ -191,36 +191,37 @@ def do_contact_person_info(lava):
return cps
def do_key_descriptor(cert, use="both"):
if use == "both":
return [
def do_key_descriptor(cert=None, enc_cert=None, use="both"):
kd_list = []
if use in ["signing", "both"] and cert is not None:
if not isinstance(cert, list):
cert = [cert]
for _cert in cert:
kd_list.append(
md.KeyDescriptor(
key_info=ds.KeyInfo(
x509_data=ds.X509Data(
x509_certificate=ds.X509Certificate(text=cert)
)
),
use="encryption"
),
md.KeyDescriptor(
key_info=ds.KeyInfo(
x509_data=ds.X509Data(
x509_certificate=ds.X509Certificate(text=cert)
x509_certificate=ds.X509Certificate(text=_cert)
)
),
use="signing"
)
]
elif use in ["signing", "encryption"]:
return md.KeyDescriptor(
)
if use in ["both", "encryption"] and enc_cert is not None:
if not isinstance(enc_cert, list):
enc_cert = [enc_cert]
for _enc_cert in enc_cert:
kd_list.append(
md.KeyDescriptor(
key_info=ds.KeyInfo(
x509_data=ds.X509Data(
x509_certificate=ds.X509Certificate(text=cert)
x509_certificate=ds.X509Certificate(text=_enc_cert)
)
),
use=use
use="encryption"
)
else:
)
if len(kd_list) == 0 and cert is not None:
return md.KeyDescriptor(
key_info=ds.KeyInfo(
x509_data=ds.X509Data(
@@ -228,6 +229,7 @@ def do_key_descriptor(cert, use="both"):
)
)
)
return kd_list
def do_requested_attribute(attributes, acs, is_required="false"):
@@ -502,7 +504,7 @@ def do_attribute_consuming_service(conf, spsso):
spsso.attribute_consuming_service = [ac_serv]
def do_spsso_descriptor(conf, cert=None):
def do_spsso_descriptor(conf, cert=None, enc_cert=None):
spsso = md.SPSSODescriptor()
spsso.protocol_support_enumeration = samlp.NAMESPACE
@@ -537,9 +539,9 @@ def do_spsso_descriptor(conf, cert=None):
spsso.extensions = md.Extensions()
spsso.extensions.add_extension_element(do_uiinfo(ui_info))
if cert:
encryption_type = conf.encryption_type
spsso.key_descriptor = do_key_descriptor(cert, encryption_type)
if cert or enc_cert:
metadata_key_usage = conf.metadata_key_usage
spsso.key_descriptor = do_key_descriptor(cert=cert, enc_cert=enc_cert, use=metadata_key_usage)
for key in ["want_assertions_signed", "authn_requests_signed"]:
try:
@@ -557,7 +559,7 @@ def do_spsso_descriptor(conf, cert=None):
return spsso
def do_idpsso_descriptor(conf, cert=None):
def do_idpsso_descriptor(conf, cert=None, enc_cert=None):
idpsso = md.IDPSSODescriptor()
idpsso.protocol_support_enumeration = samlp.NAMESPACE
@@ -586,8 +588,8 @@ def do_idpsso_descriptor(conf, cert=None):
idpsso.extensions = md.Extensions()
idpsso.extensions.add_extension_element(do_uiinfo(ui_info))
if cert:
idpsso.key_descriptor = do_key_descriptor(cert)
if cert or enc_cert:
idpsso.key_descriptor = do_key_descriptor(cert, enc_cert, use=conf.metadata_key_usage)
for key in ["want_authn_requests_signed"]:
#"want_authn_requests_only_with_valid_cert"]:
@@ -603,7 +605,7 @@ def do_idpsso_descriptor(conf, cert=None):
return idpsso
def do_aa_descriptor(conf, cert):
def do_aa_descriptor(conf, cert=None, enc_cert=None):
aad = md.AttributeAuthorityDescriptor()
aad.protocol_support_enumeration = samlp.NAMESPACE
@@ -616,8 +618,8 @@ def do_aa_descriptor(conf, cert):
_do_nameid_format(aad, conf, "aa")
if cert:
aad.key_descriptor = do_key_descriptor(cert)
if cert or enc_cert:
aad.key_descriptor = do_key_descriptor(cert, enc_cert, use=conf.metadata_key_usage)
attributes = conf.getattr("attribute", "aa")
if attributes:
@@ -632,7 +634,7 @@ def do_aa_descriptor(conf, cert):
return aad
def do_aq_descriptor(conf, cert):
def do_aq_descriptor(conf, cert=None, enc_cert=None):
aqs = md.AuthnAuthorityDescriptor()
aqs.protocol_support_enumeration = samlp.NAMESPACE
@@ -645,13 +647,13 @@ def do_aq_descriptor(conf, cert):
_do_nameid_format(aqs, conf, "aq")
if cert:
aqs.key_descriptor = do_key_descriptor(cert)
if cert or enc_cert:
aqs.key_descriptor = do_key_descriptor(cert, enc_cert, use=conf.metadata_key_usage)
return aqs
def do_pdp_descriptor(conf, cert):
def do_pdp_descriptor(conf, cert=None, enc_cert=None):
""" Create a Policy Decision Point descriptor """
pdp = md.PDPDescriptor()
@@ -667,13 +669,24 @@ def do_pdp_descriptor(conf, cert):
_do_nameid_format(pdp, conf, "pdp")
if cert:
pdp.key_descriptor = do_key_descriptor(cert)
pdp.key_descriptor = do_key_descriptor(cert, enc_cert, use=conf.metadata_key_usage)
return pdp
def entity_descriptor(confd):
mycert = "".join(open(confd.cert_file).readlines()[1:-1])
mycert = None
enc_cert = None
if confd.cert_file is not None:
mycert = []
mycert.append("".join(open(confd.cert_file).readlines()[1:-1]))
if confd.additional_cert_files is not None:
for _cert_file in confd.additional_cert_files:
mycert.append("".join(open(_cert_file).readlines()[1:-1]))
if confd.encryption_keypairs is not None:
enc_cert = []
for _encryption in confd.encryption_keypairs:
enc_cert.append("".join(open(_encryption["cert_file"]).readlines()[1:-1]))
entd = md.EntityDescriptor()
entd.entity_id = confd.entityid
@@ -701,19 +714,19 @@ def entity_descriptor(confd):
if "sp" in serves:
confd.context = "sp"
entd.spsso_descriptor = do_spsso_descriptor(confd, mycert)
entd.spsso_descriptor = do_spsso_descriptor(confd, mycert, enc_cert)
if "idp" in serves:
confd.context = "idp"
entd.idpsso_descriptor = do_idpsso_descriptor(confd, mycert)
entd.idpsso_descriptor = do_idpsso_descriptor(confd, mycert, enc_cert)
if "aa" in serves:
confd.context = "aa"
entd.attribute_authority_descriptor = do_aa_descriptor(confd, mycert)
entd.attribute_authority_descriptor = do_aa_descriptor(confd, mycert, enc_cert)
if "pdp" in serves:
confd.context = "pdp"
entd.pdp_descriptor = do_pdp_descriptor(confd, mycert)
entd.pdp_descriptor = do_pdp_descriptor(confd, mycert, enc_cert)
if "aq" in serves:
confd.context = "aq"
entd.authn_authority_descriptor = do_aq_descriptor(confd, mycert)
entd.authn_authority_descriptor = do_aq_descriptor(confd, mycert, enc_cert)
return entd

View File

@@ -1055,6 +1055,12 @@ def security_context(conf, debug=None):
raise SigverError('Unknown crypto_backend %s' % (
repr(conf.crypto_backend)))
enc_key_files = []
if conf.encryption_keypairs is not None:
for _encryption_keypair in conf.encryption_keypairs:
if "key_file" in _encryption_keypair:
enc_key_files.append(_encryption_keypair["key_file"])
return SecurityContext(
crypto, conf.key_file, cert_file=conf.cert_file, metadata=metadata,
debug=debug, only_use_keys_in_metadata=_only_md,
@@ -1062,7 +1068,8 @@ def security_context(conf, debug=None):
generate_cert_info=conf.generate_cert_info,
tmp_cert_file=conf.tmp_cert_file,
tmp_key_file=conf.tmp_key_file,
validate_certificate=conf.validate_certificate)
validate_certificate=conf.validate_certificate,
enc_key_files=enc_key_files, encryption_keypairs=conf.encryption_keypairs)
def encrypt_cert_from_item(item):
@@ -1239,19 +1246,30 @@ class SecurityContext(object):
debug=False, template="", encrypt_key_type="des-192",
only_use_keys_in_metadata=False, cert_handler_extra_class=None,
generate_cert_info=None, tmp_cert_file=None,
tmp_key_file=None, validate_certificate=None):
tmp_key_file=None, validate_certificate=None, enc_key_files=None, enc_key_type="pem",
encryption_keypairs=None, enc_cert_type="pem"):
self.crypto = crypto
assert (isinstance(self.crypto, CryptoBackend))
# Your private key
# Your private key for signing
self.key_file = key_file
self.key_type = key_type
# Your public key
# Your public key for signing
self.cert_file = cert_file
self.cert_type = cert_type
# Your private key for encryption
self.enc_key_files = enc_key_files
self.enc_key_type = enc_key_type
# Your public key for encryption
self.encryption_keypairs = encryption_keypairs
self.enc_cert_type = enc_cert_type
self.my_cert = read_cert_from_file(cert_file, cert_type)
self.cert_handler = CertHandler(self, cert_file, cert_type, key_file,
@@ -1320,9 +1338,12 @@ class SecurityContext(object):
:param enctext: The encrypted text as a string
:return: The decrypted text
"""
_enctext = None
if not isinstance(keys, list):
keys = [keys]
_enctext = self.crypto.decrypt(enctext, self.key_file)
if self.enc_key_files is not None:
for _enc_key_file in self.enc_key_files:
_enctext = self.crypto.decrypt(enctext, _enc_key_file)
if _enctext is not None and len(_enctext) > 0:
return _enctext
for _key in keys:
@@ -1339,7 +1360,10 @@ class SecurityContext(object):
:param enctext: The encrypted text as a string
:return: The decrypted text
"""
_enctext = self.crypto.decrypt(enctext, self.key_file)
_enctext = None
if self.enc_key_files is not None:
for _enc_key_file in self.enc_key_files:
_enctext = self.crypto.decrypt(enctext, _enc_key_file)
if _enctext is not None and len(_enctext) > 0:
return _enctext
if key_file is not None and len(key_file.strip()) > 0:

View File

@@ -32,21 +32,38 @@
<ns1:KeyInfo>
<ns1:X509Data>
<ns1:X509Certificate>
MIICsDCCAhmgAwIBAgIJAJrzqSSwmDY9MA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
aWRnaXRzIFB0eSBMdGQwHhcNMDkxMDA2MTk0OTQxWhcNMDkxMTA1MTk0OTQxWjBF
MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
gQDJg2cms7MqjniT8Fi/XkNHZNPbNVQyMUMXE9tXOdqwYCA1cc8vQdzkihscQMXy
3iPw2cMggBu6gjMTOSOxECkuvX5ZCclKr8pXAJM5cY6gVOaVO2PdTZcvDBKGbiaN
efiEw5hnoZomqZGp8wHNLAUkwtH9vjqqvxyS/vclc6k2ewIDAQABo4GnMIGkMB0G
A1UdDgQWBBRePsKHKYJsiojE78ZWXccK9K4aJTB1BgNVHSMEbjBsgBRePsKHKYJs
iojE78ZWXccK9K4aJaFJpEcwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUt
U3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJAJrzqSSw
mDY9MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAJSrKOEzHO7TL5cy6
h3qh+3+JAk8HbGBW+cbX6KBCAw/mzU8flK25vnWwXS3dv2FF3Aod0/S7AWNfKib5
U/SA9nJaz/mWeF9S0farz9AQFc8/NSzAzaVq7YbM4F6f6N2FRl7GikdXRCed45j6
mrPzGzk3ECbupFnqyREH3+ZPSdk=
MIICHzCCAYgCAQEwDQYJKoZIhvcNAQELBQAwWDELMAkGA1UEBhMCenoxCzAJBgNV
BAgMAnp6MQ0wCwYDVQQHDAR6enp6MQ4wDAYDVQQKDAVaenp6ejEOMAwGA1UECwwF
Wnp6enoxDTALBgNVBAMMBHRlc3QwHhcNMTUwNjAyMDc0MzAxWhcNMjUwNTMwMDc0
MzAxWjBYMQswCQYDVQQGEwJ6ejELMAkGA1UECAwCenoxDTALBgNVBAcMBHp6enox
DjAMBgNVBAoMBVp6enp6MQ4wDAYDVQQLDAVaenp6ejENMAsGA1UEAwwEdGVzdDCB
nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA41tJCTPuG2lirbztuGbBlzbzSipM
EzM+zluWegUaoUjqtlgNHOTQqTJOqw/GdjkxRKJT6IxI3/HVcnfw7P4a4xSkL/ME
IG3VyzedWEyLIHeofoQSTvr84ZdD0+Gk+zNCSqOQC7UuqpOLbMKK1tgZ8Mr7BkgI
p8H3lreLf29Sd5MCAwEAATANBgkqhkiG9w0BAQsFAAOBgQB0EXxy5+hsB7Rid7Gy
CZrAObpaC4nbyPPW/vccFKmEkYtlygEPgky7D9AGsVSaTc/YxPZcanY+vKoRIsiR
6ZitIUU5b+NnHcdj6289tUQ0iHj5jgVyv8wYHvPntTnqH2S7he0talLER8ITYToh
2wz3u7waz/GypMeA/suhoEfxew==
</ns1:X509Certificate>
</ns1:X509Data>
</ns1:KeyInfo>
</ns0:KeyDescriptor>
<ns0:KeyDescriptor use="encryption">
<ns1:KeyInfo>
<ns1:X509Data>
<ns1:X509Certificate>
MIICHzCCAYgCAQEwDQYJKoZIhvcNAQELBQAwWDELMAkGA1UEBhMCenoxCzAJBgNV
BAgMAnp6MQ0wCwYDVQQHDAR6enp6MQ4wDAYDVQQKDAVaenp6ejEOMAwGA1UECwwF
Wnp6enoxDTALBgNVBAMMBHRlc3QwHhcNMTUwNjAyMDc0MjI2WhcNMjUwNTMwMDc0
MjI2WjBYMQswCQYDVQQGEwJ6ejELMAkGA1UECAwCenoxDTALBgNVBAcMBHp6enox
DjAMBgNVBAoMBVp6enp6MQ4wDAYDVQQLDAVaenp6ejENMAsGA1UEAwwEdGVzdDCB
nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAx3I/NFlP1wbHfRZckJn4z1HX5nnY
QhQ3ekxEJmTTaj/1BvlZBmvgV40SBzH4nP1sT02xoQo7+vHItFAzaJlF2oBXsSxj
aZMGu/gkVbaHP9cYKvskhOjOJ4XArrUnKMTb1jZ+XkkOuot1NLE7/dTILF8ahHU2
omYNASLnxHN3bnkCAwEAATANBgkqhkiG9w0BAQsFAAOBgQCQam1Oz7iQcD9+OurB
M5a+Hth53m5hbAFuguSvERPCuJ/CfP1+g7CIZN/GnsIsg9QW77NvdOyxjXxzoJJm
okl1qz/qy3FY3mJ0gIUxDyPD9DL3c9/03MDv5YmWsoP+HNqK8QtNJ/JDEOhBr/Eo
/MokRo4gtMNeLF/soveWNoNiUg==
</ns1:X509Certificate>
</ns1:X509Data>
</ns1:KeyInfo>

14
tests/pki/test_1.crt Normal file
View File

@@ -0,0 +1,14 @@
-----BEGIN CERTIFICATE-----
MIICHzCCAYgCAQEwDQYJKoZIhvcNAQELBQAwWDELMAkGA1UEBhMCenoxCzAJBgNV
BAgMAnp6MQ0wCwYDVQQHDAR6enp6MQ4wDAYDVQQKDAVaenp6ejEOMAwGA1UECwwF
Wnp6enoxDTALBgNVBAMMBHRlc3QwHhcNMTUwNjAyMDc0MjI2WhcNMjUwNTMwMDc0
MjI2WjBYMQswCQYDVQQGEwJ6ejELMAkGA1UECAwCenoxDTALBgNVBAcMBHp6enox
DjAMBgNVBAoMBVp6enp6MQ4wDAYDVQQLDAVaenp6ejENMAsGA1UEAwwEdGVzdDCB
nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAx3I/NFlP1wbHfRZckJn4z1HX5nnY
QhQ3ekxEJmTTaj/1BvlZBmvgV40SBzH4nP1sT02xoQo7+vHItFAzaJlF2oBXsSxj
aZMGu/gkVbaHP9cYKvskhOjOJ4XArrUnKMTb1jZ+XkkOuot1NLE7/dTILF8ahHU2
omYNASLnxHN3bnkCAwEAATANBgkqhkiG9w0BAQsFAAOBgQCQam1Oz7iQcD9+OurB
M5a+Hth53m5hbAFuguSvERPCuJ/CfP1+g7CIZN/GnsIsg9QW77NvdOyxjXxzoJJm
okl1qz/qy3FY3mJ0gIUxDyPD9DL3c9/03MDv5YmWsoP+HNqK8QtNJ/JDEOhBr/Eo
/MokRo4gtMNeLF/soveWNoNiUg==
-----END CERTIFICATE-----

15
tests/pki/test_1.key Normal file
View File

@@ -0,0 +1,15 @@
-----BEGIN RSA PRIVATE KEY-----
MIICXgIBAAKBgQDHcj80WU/XBsd9FlyQmfjPUdfmedhCFDd6TEQmZNNqP/UG+VkG
a+BXjRIHMfic/WxPTbGhCjv68ci0UDNomUXagFexLGNpkwa7+CRVtoc/1xgq+ySE
6M4nhcCutScoxNvWNn5eSQ66i3U0sTv91MgsXxqEdTaiZg0BIufEc3dueQIDAQAB
AoGBAIhWkN44L1vORpA7uQsgNfWC/ROQN0T0jPgNKokUY3E+R0F9Ml4xYCp5RNmm
T00B8AhGFCcB1/6zSX/5Uystm5GNO/V8pNnM7qTrTtnwX/umyceIVxq03z4RCVYb
Gdv67opQAy/Mjy+cHBdYBcIg4ihDbr9CX5qedf9buG4140wBAkEA4nKWZX7DEnEh
sbLnU9KhxwEjadzeZb0JKxoWUjfTTrBlIkHbm6toabV6TVqNENWMSCe0fcjJ7tr7
xPBdOGIlTwJBAOF5ka0khatTH5zSUMRiz8LkqXmy+F0RMXYJeuvNvTSlj3EM9/tK
eWGunHgxv4n1IhGybmfkiXt9MA3sAmUKTbcCQG7nUfM5Zw6EK81c4mCyOxs82nxB
eQZ406GxcBcqUioqyA1EFesiwstq3xA9dfM1szOvhn1INmXuB/qHAhDYOI8CQQCT
zc56ErPxMCdL9O5vHlsVZjHWjkSTNZ8XwnUquI6sQU97i0XQG+zf5Me7XtkxhVjV
AwOu5ThelBz5M1oKhCuXAkEAjDqWQQAiMR2JOFiG/PIHSnPzpmALmf4+A+bjIzbg
VIDhB0LMS5PZikLUWvXPFzdY5e3UKyNTKCxqxqLEYpLWGQ==
-----END RSA PRIVATE KEY-----

14
tests/pki/test_2.crt Normal file
View File

@@ -0,0 +1,14 @@
-----BEGIN CERTIFICATE-----
MIICHzCCAYgCAQEwDQYJKoZIhvcNAQELBQAwWDELMAkGA1UEBhMCenoxCzAJBgNV
BAgMAnp6MQ0wCwYDVQQHDAR6enp6MQ4wDAYDVQQKDAVaenp6ejEOMAwGA1UECwwF
Wnp6enoxDTALBgNVBAMMBHRlc3QwHhcNMTUwNjAyMDc0MzAxWhcNMjUwNTMwMDc0
MzAxWjBYMQswCQYDVQQGEwJ6ejELMAkGA1UECAwCenoxDTALBgNVBAcMBHp6enox
DjAMBgNVBAoMBVp6enp6MQ4wDAYDVQQLDAVaenp6ejENMAsGA1UEAwwEdGVzdDCB
nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA41tJCTPuG2lirbztuGbBlzbzSipM
EzM+zluWegUaoUjqtlgNHOTQqTJOqw/GdjkxRKJT6IxI3/HVcnfw7P4a4xSkL/ME
IG3VyzedWEyLIHeofoQSTvr84ZdD0+Gk+zNCSqOQC7UuqpOLbMKK1tgZ8Mr7BkgI
p8H3lreLf29Sd5MCAwEAATANBgkqhkiG9w0BAQsFAAOBgQB0EXxy5+hsB7Rid7Gy
CZrAObpaC4nbyPPW/vccFKmEkYtlygEPgky7D9AGsVSaTc/YxPZcanY+vKoRIsiR
6ZitIUU5b+NnHcdj6289tUQ0iHj5jgVyv8wYHvPntTnqH2S7he0talLER8ITYToh
2wz3u7waz/GypMeA/suhoEfxew==
-----END CERTIFICATE-----

15
tests/pki/test_2.key Normal file
View File

@@ -0,0 +1,15 @@
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQDjW0kJM+4baWKtvO24ZsGXNvNKKkwTMz7OW5Z6BRqhSOq2WA0c
5NCpMk6rD8Z2OTFEolPojEjf8dVyd/Ds/hrjFKQv8wQgbdXLN51YTIsgd6h+hBJO
+vzhl0PT4aT7M0JKo5ALtS6qk4tsworW2BnwyvsGSAinwfeWt4t/b1J3kwIDAQAB
AoGAGsVz+y5vOjEVmomloFIRN6IT0cbbQGOHYLsuI94X/afdY21I1f8nhtTSqJfp
8Z/YalGG+doS9rO+Q4VWDEH7nkrD32kX7GVHDArixjYNYtO4iOk+XW0lzGr1+ghJ
p9+zguQRwAiUFJE6/pqKvFlwhoKppJGtfUsniQpy7ANfyNkCQQD6arntqjlJsYml
cKgpgbA9rhZl7ebVKf1edd15kp411NH/FDWhIlxvg9c3HcAH3jQgnc4Gf4bdvZ6Z
UVDSa63HAkEA6Gzww5cXgGHqQrJoQW/qVaqBAVakeS5uf0CCyb6xvIcHRPS3lLlu
1upuHeA87IjVeRis8yULgaPzvVyiT/IX1QJBAJvhq/PCLv8swR53TnboACmlINQ6
j6LKDKqsfD2dg1bHMCG1Ft1DYn8YdvQcVNmQ/KoBEasB35ZQ31VZRRJ3bSkCQEXg
UrYK27buORaaOnvJ4MKmgyha2xHPosrBI1Dx8s+CLO5PQE4HPcqBKl/zBX37WWqR
v5VOAtqT5vh8PBQa7Y0CQGXFzSKBBp+Zmxab2t85qaZ2VNiQLvqsNA9v8YgNTT2j
jYHRzwnAZymfO4JCfKnsT3KiVy1xbcYsNEO9+DYpqBA=
-----END RSA PRIVATE KEY-----

14
tests/pki/test_3.crt Normal file
View File

@@ -0,0 +1,14 @@
-----BEGIN CERTIFICATE-----
MIICHzCCAYgCAQEwDQYJKoZIhvcNAQELBQAwWDELMAkGA1UEBhMCenoxCzAJBgNV
BAgMAnp6MQ0wCwYDVQQHDAR6enp6MQ4wDAYDVQQKDAVaenp6ejEOMAwGA1UECwwF
Wnp6enoxDTALBgNVBAMMBHRlc3QwHhcNMTUwNjAyMTEyMzQ2WhcNMjUwNTMwMTEy
MzQ2WjBYMQswCQYDVQQGEwJ6ejELMAkGA1UECAwCenoxDTALBgNVBAcMBHp6enox
DjAMBgNVBAoMBVp6enp6MQ4wDAYDVQQLDAVaenp6ejENMAsGA1UEAwwEdGVzdDCB
nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArxklvHr3cJJEHImPJCfsdId/yfhg
kZsbKzhoLTYX10gC9Qz1SbGxUJ4GKQn+IlaMWY4WTle5JUPibDIN5sYtF3GC5JPW
pI/sKeba7ni7JWBOCeAgcgQMGYvuX4VkR2HYuMkKOs/O3d1tAfQdEh8e0I1rXzyS
2TEiV2GECUec1JUCAwEAATANBgkqhkiG9w0BAQsFAAOBgQCbgMfVhmLWasoguB43
UtIc77T+AZwnxhPKpd8WNx6C03KFK+WoKViZuLR+8i6K/jwJhjiJ8nZzPDIomb4r
hnA/jvOVQKzzgZCr6FBWIVQjDFdIR6MCkGW+JKUVeTQTtsQ7DgL3QjnVDQLL96B7
ZYA44pe1CSmcdFPmZJyRwFQm/g==
-----END CERTIFICATE-----

15
tests/pki/test_3.key Normal file
View File

@@ -0,0 +1,15 @@
-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQCvGSW8evdwkkQciY8kJ+x0h3/J+GCRmxsrOGgtNhfXSAL1DPVJ
sbFQngYpCf4iVoxZjhZOV7klQ+JsMg3mxi0XcYLkk9akj+wp5trueLslYE4J4CBy
BAwZi+5fhWRHYdi4yQo6z87d3W0B9B0SHx7QjWtfPJLZMSJXYYQJR5zUlQIDAQAB
AoGACRxT3FTBnzfdF2cI7aauJPoP6iBkVe8uILeUpBWWc/spPDrqYGVAhqNSSrxc
XskGEHrWKkliNtArbdnE42cYXXPbwxHOwzoXxaHlLYIORDH0b90ukv1Pp6DhzQaW
guFb3yrxRO7tILhfA9V+nvYU4EcPLwRxRzLUipT7eNfIhYECQQDcTMWr3bvgLpD2
KD8Pn6iihskBiAsvvz1uVOjfSS1bKGzsyYjtKdq/bO0AM0e8uUdSWHXH2yeEkG/f
IMz9CXQlAkEAy3kqpl7uU+0Qe19mC+Icx/DbjJUV6Kv7dLozze3yjBzQFBMPQwi8
b4zA+4lcuX5u9b8f1kpqC8hNMcE9jGM7sQJAClwp550z2qUV+B2IaamueoYwKbxG
Gma58thXYzjDw0exZ6lKoSyYtuvecWX3964W5o52a4Go6BkKycl3Gmc5aQJAAsT3
a6RHIiVL4CIARZEiSyZgFp3A2pXcqk4OfnMKphWOT3ei8Yqg5fPIfKP1+yBZakbb
rBL/NoHXayHyMIL5QQJATnVslSzO10RzxBI+k1F+Mr1VRj1KnP4rjYP1gHQ9KqVP
CveP1Cqnu7+tZ9HezUMZSlFZ60A+D6uB8AGB/Z8EHg==
-----END RSA PRIVATE KEY-----

View File

@@ -19,6 +19,8 @@ CONFIG = {
"debug": 1,
"key_file": full_path("test.key"),
"cert_file": full_path("test.pem"),
"encryption_keypairs": [{"key_file": "pki/test_1.key", "cert_file": "pki/test_1.crt"},
{"key_file": "pki/test_2.key", "cert_file": "pki/test_2.crt"}],
"ca_certs": full_path("cacerts.txt"),
"xmlsec_binary": xmlsec_path,
"metadata": [{

View File

@@ -25,6 +25,8 @@ SIMPLE_SAML_PHP_RESPONSE = full_path("simplesamlphp_authnresponse.xml")
PUB_KEY = full_path("test.pem")
PRIV_KEY = full_path("test.key")
ENC_PUB_KEY = full_path("pki/test_1.crt")
ENC_PRIV_KEY = full_path("pki/test.key")
def _eq(l1, l2):
return set(l1) == set(l2)
@@ -96,6 +98,8 @@ class FakeConfig():
metadata = None
cert_file = PUB_KEY
key_file = PRIV_KEY
encryption_keypairs = [{"key_file": ENC_PRIV_KEY, "cert_file": ENC_PUB_KEY}]
enc_key_files = [ENC_PRIV_KEY]
debug = False
cert_handler_extra_class = None
generate_cert_func = None
@@ -503,8 +507,8 @@ def test_xmlsec_err():
if __name__ == "__main__":
# t = TestSecurity()
# t.setup_class()
# t.test_non_verify_2()
t = TestSecurity()
t.setup_class()
t.test_verify_1()
test_xmlsec_err()
#test_xmlsec_err()

View File

@@ -1,6 +1,7 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import base64
import copy
import os
from contextlib import closing
from urlparse import parse_qs
@@ -609,7 +610,15 @@ class TestServer1():
id_attr="")
assert valid
decr_text = self.server.sec.decrypt(signed_resp, self.client.config.key_file)
decr_text_old = copy.deepcopy("%s" % signed_resp)
decr_text = self.server.sec.decrypt(signed_resp, self.client.config.encryption_keypairs[0]["key_file"])
assert decr_text == decr_text_old
decr_text = self.server.sec.decrypt(signed_resp, self.client.config.encryption_keypairs[1]["key_file"])
assert decr_text != decr_text_old
resp = samlp.response_from_string(decr_text)
@@ -694,7 +703,7 @@ class TestServer1():
id_attr="")
assert valid
decr_text = self.server.sec.decrypt(signed_resp, self.client.config.key_file)
decr_text = self.server.sec.decrypt(signed_resp, self.client.config.encryption_keypairs[1]["key_file"])
resp = samlp.response_from_string(decr_text)
@@ -783,7 +792,7 @@ class TestServer1():
assert sresponse.signature is None
decr_text_1 = self.server.sec.decrypt(_resp, self.client.config.key_file)
decr_text_1 = self.server.sec.decrypt(_resp, self.client.config.encryption_keypairs[1]["key_file"])
_, key_file = make_temp("%s" % cert_key_str_advice, decode=False)
@@ -846,7 +855,7 @@ class TestServer1():
assert sresponse.signature is None
decr_text = self.server.sec.decrypt(_resp, self.client.config.key_file)
decr_text = self.server.sec.decrypt(_resp, self.client.config.encryption_keypairs[1]["key_file"])
resp = samlp.response_from_string(decr_text)
@@ -877,7 +886,7 @@ class TestServer1():
assert sresponse.signature is None
decr_text = self.server.sec.decrypt(_resp, self.client.config.key_file)
decr_text = self.server.sec.decrypt(_resp, self.client.config.encryption_keypairs[1]["key_file"])
resp = samlp.response_from_string(decr_text)
@@ -943,9 +952,9 @@ class TestServer1():
assert sresponse.signature is None
decr_text_1 = self.server.sec.decrypt(_resp, self.client.config.key_file)
decr_text_1 = self.server.sec.decrypt(_resp, self.client.config.encryption_keypairs[1]["key_file"])
decr_text_2 = self.server.sec.decrypt(decr_text_1, self.client.config.key_file)
decr_text_2 = self.server.sec.decrypt(decr_text_1, self.client.config.encryption_keypairs[1]["key_file"])
resp = samlp.response_from_string(decr_text_2)
@@ -1270,4 +1279,4 @@ class TestServerLogout():
if __name__ == "__main__":
ts = TestServer1()
ts.setup_class()
ts.test_encrypted_signed_response_1()
ts.test_encrypted_signed_response_4()

View File

@@ -767,7 +767,7 @@ class TestClient:
assertion=_ass
)
enctext = _sec.crypto.encrypt_assertion(response, _sec.cert_file,
enctext = _sec.crypto.encrypt_assertion(response, self.client.sec.encryption_keypairs[0]["cert_file"],
pre_encryption_part())
seresp = samlp.response_from_string(enctext)
@@ -837,7 +837,7 @@ class TestClient:
# or as part of a bunch of tests.
xmldoc = add_subelement(xmldoc, "EncryptedAssertion", sigass)
enctext = _sec.crypto.encrypt_assertion(xmldoc, _sec.cert_file,
enctext = _sec.crypto.encrypt_assertion(xmldoc, self.client.sec.encryption_keypairs[1]["cert_file"],
pre_encryption_part())
#seresp = samlp.response_from_string(enctext)
@@ -912,7 +912,7 @@ class TestClient:
node_xpath = ''.join(["/*[local-name()=\"%s\"]" % v for v in
["Response", "Assertion", "Advice", "EncryptedAssertion", "Assertion"]])
enctext = _sec.crypto.encrypt_assertion(response, _sec.cert_file,
enctext = _sec.crypto.encrypt_assertion(response, self.client.sec.encryption_keypairs[0]["cert_file"],
pre_encryption_part(), node_xpath=node_xpath)
#seresp = samlp.response_from_string(enctext)
@@ -1048,7 +1048,7 @@ class TestClient:
node_xpath = ''.join(["/*[local-name()=\"%s\"]" % v for v in
["Response", "Assertion", "Advice", "EncryptedAssertion", "Assertion"]])
enctext = _sec.crypto.encrypt_assertion(response, self.client.sec.cert_file,
enctext = _sec.crypto.encrypt_assertion(response, self.client.sec.encryption_keypairs[1]["cert_file"],
pre_encryption_part(), node_xpath=node_xpath)
response = samlp.response_from_string(enctext)
@@ -1071,7 +1071,7 @@ class TestClient:
node_xpath = ''.join(["/*[local-name()=\"%s\"]" % v for v in
["Response", "Assertion", "Advice", "EncryptedAssertion", "Assertion"]])
enctext = _sec.crypto.encrypt_assertion(response, self.client.sec.cert_file,
enctext = _sec.crypto.encrypt_assertion(response, self.client.sec.encryption_keypairs[0]["cert_file"],
pre_encryption_part(), node_xpath=node_xpath)
response = samlp.response_from_string(enctext)
@@ -1087,7 +1087,8 @@ class TestClient:
key_file=self.server.sec.key_file,
node_id=assertion_1.id)
enctext = _sec.crypto.encrypt_assertion(response, self.client.sec.cert_file, pre_encryption_part())
enctext = _sec.crypto.encrypt_assertion(response, self.client.sec.encryption_keypairs[1]["cert_file"],
pre_encryption_part())
response = samlp.response_from_string(enctext)
@@ -1098,7 +1099,6 @@ class TestClient:
response.assertion.advice.encrypted_assertion = []
response.assertion.advice.encrypted_assertion.append(EncryptedAssertion())
response.assertion.advice.encrypted_assertion[0].add_extension_element(a_assertion_3)
advice_tag = response.assertion.advice._to_element_tree().tag
@@ -1114,7 +1114,7 @@ class TestClient:
node_xpath = ''.join(["/*[local-name()=\"%s\"]" % v for v in
["Response", "Assertion", "Advice", "EncryptedAssertion", "Assertion"]])
enctext = _sec.crypto.encrypt_assertion(response, self.client.sec.cert_file,
enctext = _sec.crypto.encrypt_assertion(response, self.client.sec.encryption_keypairs[0]["cert_file"],
pre_encryption_part(), node_xpath=node_xpath)
response = samlp.response_from_string(enctext)
@@ -1138,7 +1138,7 @@ class TestClient:
node_xpath = ''.join(["/*[local-name()=\"%s\"]" % v for v in
["Response", "Assertion", "Advice", "EncryptedAssertion", "Assertion"]])
enctext = _sec.crypto.encrypt_assertion(response, self.client.sec.cert_file,
enctext = _sec.crypto.encrypt_assertion(response, self.client.sec.encryption_keypairs[1]["cert_file"],
pre_encryption_part(), node_xpath=node_xpath)
response = samlp.response_from_string(enctext)
@@ -1349,4 +1349,4 @@ class TestClientWithDummy():
if __name__ == "__main__":
tc = TestClient()
tc.setup_class()
tc.test_response_8()
tc.test_sign_then_encrypt_assertion()