Skip to content

Commit 0218b0b

Browse files
author
Roland Hedberg
committed
Merge branch 'master' of github.com:rohe/pysaml2
2 parents 576317a + c6edeb3 commit 0218b0b

File tree

2 files changed

+109
-105
lines changed

2 files changed

+109
-105
lines changed

src/saml2/mdstore.py

Lines changed: 40 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,43 @@ def certs(self, entity_id, descriptor, use="signing"):
314314
'''
315315
Returns certificates for the given Entity
316316
'''
317-
raise NotImplementedError
317+
ent = self[entity_id]
318+
319+
def extract_certs(srvs):
320+
res = []
321+
for srv in srvs:
322+
if "key_descriptor" in srv:
323+
for key in srv["key_descriptor"]:
324+
if "use" in key and key["use"] == use:
325+
for dat in key["key_info"]["x509_data"]:
326+
cert = repack_cert(
327+
dat["x509_certificate"]["text"])
328+
if cert not in res:
329+
res.append(cert)
330+
elif not "use" in key:
331+
for dat in key["key_info"]["x509_data"]:
332+
cert = repack_cert(
333+
dat["x509_certificate"]["text"])
334+
if cert not in res:
335+
res.append(cert)
336+
337+
return res
338+
339+
if descriptor == "any":
340+
res = []
341+
for descr in ["spsso", "idpsso", "role", "authn_authority",
342+
"attribute_authority", "pdp"]:
343+
try:
344+
srvs = ent["%s_descriptor" % descr]
345+
except KeyError:
346+
continue
347+
348+
res.extend(extract_certs(srvs))
349+
else:
350+
srvs = ent["%s_descriptor" % descriptor]
351+
res = extract_certs(srvs)
352+
353+
return res
318354

319355

320356
class InMemoryMetaData(MetaData):
@@ -511,45 +547,6 @@ def construct_source_id(self):
511547

512548
return res
513549

514-
def certs(self, entity_id, descriptor, use="signing"):
515-
ent = self.__getitem__(entity_id)
516-
if descriptor == "any":
517-
res = []
518-
for descr in ["spsso", "idpsso", "role", "authn_authority",
519-
"attribute_authority", "pdp"]:
520-
try:
521-
srvs = ent["%s_descriptor" % descr]
522-
except KeyError:
523-
continue
524-
525-
for srv in srvs:
526-
for key in srv["key_descriptor"]:
527-
if "use" in key and key["use"] == use:
528-
for dat in key["key_info"]["x509_data"]:
529-
cert = repack_cert(
530-
dat["x509_certificate"]["text"])
531-
if cert not in res:
532-
res.append(cert)
533-
elif not "use" in key:
534-
for dat in key["key_info"]["x509_data"]:
535-
cert = repack_cert(
536-
dat["x509_certificate"]["text"])
537-
if cert not in res:
538-
res.append(cert)
539-
else:
540-
srvs = ent["%s_descriptor" % descriptor]
541-
542-
res = []
543-
for srv in srvs:
544-
for key in srv["key_descriptor"]:
545-
if "use" in key and key["use"] == use:
546-
for dat in key["key_info"]["x509_data"]:
547-
res.append(dat["x509_certificate"]["text"])
548-
elif not "use" in key:
549-
for dat in key["key_info"]["x509_data"]:
550-
res.append(dat["x509_certificate"]["text"])
551-
return res
552-
553550
def signed(self):
554551
if self.entities_descr and self.entities_descr.signature:
555552
return True
@@ -567,8 +564,8 @@ def parse_and_check_signature(self, txt):
567564
return True
568565

569566
node_name = self.node_name \
570-
or "%s:%s" % (md.EntitiesDescriptor.c_namespace,
571-
md.EntitiesDescriptor.c_tag)
567+
or "%s:%s" % (md.EntitiesDescriptor.c_namespace,
568+
md.EntitiesDescriptor.c_tag)
572569

573570
if self.security.verify_signature(
574571
txt, node_name=node_name, cert_file=self.cert):
@@ -752,7 +749,7 @@ def __getitem__(self, item):
752749
raise KeyError
753750

754751

755-
class MetadataStore(object):
752+
class MetadataStore(MetaData):
756753
def __init__(self, onts, attrc, config, ca_certs=None,
757754
check_validity=True,
758755
disable_ssl_certificate_validation=False,
@@ -1062,45 +1059,6 @@ def name(self, entity_id, langpref="en"):
10621059
return name(_md[entity_id], langpref)
10631060
return None
10641061

1065-
def certs(self, entity_id, descriptor, use="signing"):
1066-
ent = self.__getitem__(entity_id)
1067-
if descriptor == "any":
1068-
res = []
1069-
for descr in ["spsso", "idpsso", "role", "authn_authority",
1070-
"attribute_authority", "pdp"]:
1071-
try:
1072-
srvs = ent["%s_descriptor" % descr]
1073-
except KeyError:
1074-
continue
1075-
1076-
for srv in srvs:
1077-
for key in srv["key_descriptor"]:
1078-
if "use" in key and key["use"] == use:
1079-
for dat in key["key_info"]["x509_data"]:
1080-
cert = repack_cert(
1081-
dat["x509_certificate"]["text"])
1082-
if cert not in res:
1083-
res.append(cert)
1084-
elif not "use" in key:
1085-
for dat in key["key_info"]["x509_data"]:
1086-
cert = repack_cert(
1087-
dat["x509_certificate"]["text"])
1088-
if cert not in res:
1089-
res.append(cert)
1090-
else:
1091-
srvs = ent["%s_descriptor" % descriptor]
1092-
1093-
res = []
1094-
for srv in srvs:
1095-
for key in srv["key_descriptor"]:
1096-
if "use" in key and key["use"] == use:
1097-
for dat in key["key_info"]["x509_data"]:
1098-
res.append(dat["x509_certificate"]["text"])
1099-
elif not "use" in key:
1100-
for dat in key["key_info"]["x509_data"]:
1101-
res.append(dat["x509_certificate"]["text"])
1102-
return res
1103-
11041062
def vo_members(self, entity_id):
11051063
ad = self.__getitem__(entity_id)["affiliation_descriptor"]
11061064
return [m["text"] for m in ad["affiliate_member"]]

tests/test_30_mdstore.py

Lines changed: 69 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,9 @@
55
from six.moves.urllib.parse import quote_plus
66
from saml2.config import Config
77
from saml2.httpbase import HTTPBase
8-
98
from saml2.mdstore import MetadataStore, MetaDataMDX
109
from saml2.mdstore import destinations
1110
from saml2.mdstore import name
12-
1311
from saml2 import md
1412
from saml2 import sigver
1513
from saml2 import BINDING_SOAP
@@ -20,7 +18,6 @@
2018
from saml2 import config
2119
from saml2.attribute_converter import ac_factory
2220
from saml2.attribute_converter import d_to_local_name
23-
2421
from saml2.extension import mdui
2522
from saml2.extension import idpdisc
2623
from saml2.extension import dri
@@ -29,12 +26,27 @@
2926
from saml2.s_utils import UnknownPrincipal
3027
from saml2 import xmldsig
3128
from saml2 import xmlenc
32-
3329
from pathutils import full_path
3430

3531
sec_config = config.Config()
3632
# sec_config.xmlsec_binary = sigver.get_xmlsec_binary(["/opt/local/bin"])
3733

34+
TEST_CERT = """MIICsDCCAhmgAwIBAgIJAJrzqSSwmDY9MA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
35+
BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
36+
aWRnaXRzIFB0eSBMdGQwHhcNMDkxMDA2MTk0OTQxWhcNMDkxMTA1MTk0OTQxWjBF
37+
MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50
38+
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
39+
gQDJg2cms7MqjniT8Fi/XkNHZNPbNVQyMUMXE9tXOdqwYCA1cc8vQdzkihscQMXy
40+
3iPw2cMggBu6gjMTOSOxECkuvX5ZCclKr8pXAJM5cY6gVOaVO2PdTZcvDBKGbiaN
41+
efiEw5hnoZomqZGp8wHNLAUkwtH9vjqqvxyS/vclc6k2ewIDAQABo4GnMIGkMB0G
42+
A1UdDgQWBBRePsKHKYJsiojE78ZWXccK9K4aJTB1BgNVHSMEbjBsgBRePsKHKYJs
43+
iojE78ZWXccK9K4aJaFJpEcwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUt
44+
U3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJAJrzqSSw
45+
mDY9MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAJSrKOEzHO7TL5cy6
46+
h3qh+3+JAk8HbGBW+cbX6KBCAw/mzU8flK25vnWwXS3dv2FF3Aod0/S7AWNfKib5
47+
U/SA9nJaz/mWeF9S0farz9AQFc8/NSzAzaVq7YbM4F6f6N2FRl7GikdXRCed45j6
48+
mrPzGzk3ECbupFnqyREH3+ZPSdk="""
49+
3850
TEST_METADATA_STRING = """
3951
<EntitiesDescriptor
4052
xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
@@ -51,21 +63,8 @@
5163
<ds:KeyInfo>
5264
<ds:X509Data>
5365
<ds:X509Certificate>
54-
MIICsDCCAhmgAwIBAgIJAJrzqSSwmDY9MA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
55-
BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
56-
aWRnaXRzIFB0eSBMdGQwHhcNMDkxMDA2MTk0OTQxWhcNMDkxMTA1MTk0OTQxWjBF
57-
MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50
58-
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
59-
gQDJg2cms7MqjniT8Fi/XkNHZNPbNVQyMUMXE9tXOdqwYCA1cc8vQdzkihscQMXy
60-
3iPw2cMggBu6gjMTOSOxECkuvX5ZCclKr8pXAJM5cY6gVOaVO2PdTZcvDBKGbiaN
61-
efiEw5hnoZomqZGp8wHNLAUkwtH9vjqqvxyS/vclc6k2ewIDAQABo4GnMIGkMB0G
62-
A1UdDgQWBBRePsKHKYJsiojE78ZWXccK9K4aJTB1BgNVHSMEbjBsgBRePsKHKYJs
63-
iojE78ZWXccK9K4aJaFJpEcwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUt
64-
U3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJAJrzqSSw
65-
mDY9MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAJSrKOEzHO7TL5cy6
66-
h3qh+3+JAk8HbGBW+cbX6KBCAw/mzU8flK25vnWwXS3dv2FF3Aod0/S7AWNfKib5
67-
U/SA9nJaz/mWeF9S0farz9AQFc8/NSzAzaVq7YbM4F6f6N2FRl7GikdXRCed45j6
68-
mrPzGzk3ECbupFnqyREH3+ZPSdk=</ds:X509Certificate>
66+
{cert_data}
67+
</ds:X509Certificate>
6968
</ds:X509Data>
7069
</ds:KeyInfo>
7170
</KeyDescriptor>
@@ -85,7 +84,7 @@
8584
</ContactPerson>
8685
</EntityDescriptor>
8786
</EntitiesDescriptor>
88-
"""
87+
""".format(cert_data=TEST_CERT)
8988

9089
ONTS = {
9190
saml.NAMESPACE: saml,
@@ -149,7 +148,7 @@
149148
}],
150149
"11": [{
151150
"class": "saml2.mdstore.InMemoryMetaData",
152-
"metadata": [(TEST_METADATA_STRING, )]
151+
"metadata": [(TEST_METADATA_STRING,)]
153152
}],
154153
}
155154

@@ -372,7 +371,7 @@ def test_load_string():
372371
disable_ssl_certificate_validation=True)
373372

374373
mds.imp(METADATACONF["11"])
375-
#print(mds)
374+
# print(mds)
376375
assert len(mds.keys()) == 1
377376
idps = mds.with_descriptor("idpsso")
378377

@@ -384,5 +383,52 @@ def test_load_string():
384383
assert len(certs) == 1
385384

386385

386+
def test_get_certs_from_metadata():
387+
mds = MetadataStore(ONTS.values(), ATTRCONV, None)
388+
mds.imp(METADATACONF["11"])
389+
certs1 = mds.certs("http://xenosmilus.umdc.umu.se/simplesaml/saml2/idp/metadata.php", "any")
390+
certs2 = mds.certs("http://xenosmilus.umdc.umu.se/simplesaml/saml2/idp/metadata.php", "idpsso")
391+
392+
assert certs1[0] == certs2[0] == TEST_CERT
393+
394+
395+
def test_get_certs_from_metadata_without_keydescriptor():
396+
mds = MetadataStore(ONTS.values(), ATTRCONV, None)
397+
mds.imp([{
398+
"class": "saml2.mdstore.InMemoryMetaData",
399+
"metadata": [("""
400+
<EntitiesDescriptor
401+
xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
402+
xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
403+
xmlns:shibmeta="urn:mace:shibboleth:metadata:1.0"
404+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
405+
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
406+
Name="urn:mace:example.com:test-1.0">
407+
<EntityDescriptor
408+
entityID="http://xenosmilus.umdc.umu.se/simplesaml/saml2/idp/metadata.php"
409+
xml:base="swamid-1.0/idp.umu.se-saml2.xml">
410+
<IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
411+
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
412+
<SingleSignOnService
413+
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
414+
Location="http://xenosmilus.umdc.umu.se/simplesaml/saml2/idp/metadata.php"/>
415+
</IDPSSODescriptor>
416+
<Organization>
417+
<OrganizationName xml:lang="en">Catalogix</OrganizationName>
418+
<OrganizationDisplayName xml:lang="en">Catalogix</OrganizationDisplayName>
419+
<OrganizationURL xml:lang="en">http://www.catalogix.se</OrganizationURL>
420+
</Organization>
421+
<ContactPerson contactType="technical">
422+
<SurName>Hedberg</SurName>
423+
<EmailAddress>[email protected]</EmailAddress>
424+
</ContactPerson>
425+
</EntityDescriptor>
426+
</EntitiesDescriptor>""",)]
427+
}])
428+
certs = mds.certs("http://xenosmilus.umdc.umu.se/simplesaml/saml2/idp/metadata.php", "idpsso")
429+
430+
assert len(certs) == 0
431+
432+
387433
if __name__ == "__main__":
388-
test_load_local()
434+
test_get_certs_from_metadata()

0 commit comments

Comments
 (0)