Merge lp:~roadmr/django-saml2-idp/custom-certificate-support into lp:~ubuntuone-pqm-team/django-saml2-idp/stable

Proposed by Daniel Manrique
Status: Merged
Merged at revision: 70
Proposed branch: lp:~roadmr/django-saml2-idp/custom-certificate-support
Merge into: lp:~ubuntuone-pqm-team/django-saml2-idp/stable
Diff against target: 415 lines (+193/-45)
5 files modified
idptest/saml2idp/base.py (+4/-3)
idptest/saml2idp/tests/signing.py (+148/-26)
idptest/saml2idp/xml_render.py (+14/-10)
idptest/saml2idp/xml_signing.py (+25/-4)
requirements.txt (+2/-2)
To merge this branch: bzr merge lp:~roadmr/django-saml2-idp/custom-certificate-support
Reviewer Review Type Date Requested Status
Ricardo Kirkner (community) Approve
Review via email: mp+334947@code.launchpad.net

Commit message

Add custom certificate support.

A "certificate" parameter was added to the get_signature_xml method and to methods that call this, all the way up to the ones called by Processor subclasses.

The parameter has a default of None in all methods that support it. If get_signature_xml ultimately doesn't get a certificate value, it will use the globally-configured certificate, as it always has.

If the certificate parameter has a string containing a PEM-formatted certificate (with ---BEGIN/END--- certificate delimiters), it will be included in the assertion instead of the globally-configured one.

The certificate is expected to be derived from the globally-configured private key; there's no custom private key support.

The validation behavior is (as with the global certificate) whatever M2Crypto.X509.load_cert_string() raises for an invalid certificate.

The test suite was expanded to account for custom certificates and also explicitly tests the google apps-compatible xml generators which were not previously tested.

Description of the change

Add custom certificate support.

A "certificate" parameter was added to the get_signature_xml method and to methods that call this, all the way up to the ones called by Processor subclasses.

The parameter has a default of None in all methods that support it. If get_signature_xml ultimately doesn't get a certificate value, it will use the globally-configured certificate, as it always has.

If the certificate parameter has a string containing a PEM-formatted certificate (with ---BEGIN/END--- certificate delimiters), it will be included in the assertion instead of the globally-configured one.

The certificate is expected to be derived from the globally-configured private key; there's no custom private key support.

The validation behavior is (as with the global certificate) whatever M2Crypto.X509.load_cert_string() raises for an invalid certificate.

The test suite was expanded to account for custom certificates and also explicitly tests the google apps-compatible xml generators which were not previously tested.

To post a comment you must log in.
Revision history for this message
Ricardo Kirkner (ricardokirkner) wrote :

LGTM

review: Approve
Revision history for this message
Daniel Manrique (roadmr) wrote :

FIxed review comments.

89. By Daniel Manrique

review fixes

Revision history for this message
Daniel Manrique (roadmr) wrote :

Merging manually.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'idptest/saml2idp/base.py'
2--- idptest/saml2idp/base.py 2012-08-20 18:41:37 +0000
3+++ idptest/saml2idp/base.py 2017-12-11 19:14:27 +0000
4@@ -131,12 +131,13 @@
5 """
6 raise NotImplemented()
7
8- def _format_response(self):
9+ def _format_response(self, certificate=None):
10 """
11 Formats _response_params as _response_xml.
12 """
13- sign_it=saml2idp_metadata.SAML2IDP_CONFIG['signing']
14- self._response_xml = xml_render.get_response_xml(self._response_params, signed=sign_it)
15+ sign_it = saml2idp_metadata.SAML2IDP_CONFIG['signing']
16+ self._response_xml = xml_render.get_response_xml(
17+ self._response_params, signed=sign_it, certificate=certificate)
18
19 def _get_django_response_params(self):
20 """
21
22=== modified file 'idptest/saml2idp/tests/signing.py'
23--- idptest/saml2idp/tests/signing.py 2012-06-27 20:26:38 +0000
24+++ idptest/saml2idp/tests/signing.py 2017-12-11 19:14:27 +0000
25@@ -2,7 +2,11 @@
26 import unittest
27 from saml2idp import xml_render
28 from saml2idp.xml_signing import get_signature_xml
29-from saml2idp.xml_templates import ASSERTION_SALESFORCE, RESPONSE
30+from saml2idp.xml_templates import (
31+ ASSERTION_GOOGLE_APPS,
32+ ASSERTION_SALESFORCE,
33+ RESPONSE,
34+)
35
36 IDP_PARAMS = {
37 'ISSUER': 'http://127.0.0.1:8000',
38@@ -15,7 +19,7 @@
39
40 ASSERTION_SALESFORCE_PARAMS = {
41 'ASSERTION_ID': '_7ccdda8bc6b328570c03b218d7521772998da45374',
42- 'ASSERTION_SIGNATURE': '', # it's unsigned
43+ 'ASSERTION_SIGNATURE': '', # it's unsigned
44 'AUDIENCE': 'example.net',
45 'AUTH_INSTANT': '2011-08-11T23:38:34Z',
46 'ISSUE_INSTANT': '2011-08-11T23:38:34Z',
47@@ -29,6 +33,26 @@
48
49 ASSERTION_SALESFORCE_XML = '<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_7ccdda8bc6b328570c03b218d7521772998da45374" IssueInstant="2011-08-11T23:38:34Z" Version="2.0"><saml:Issuer>http://127.0.0.1:8000</saml:Issuer><saml:Subject><saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:email" SPNameQualifier="example.net">randomuser@example.com</saml:NameID><saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"><saml:SubjectConfirmationData InResponseTo="mpjibjdppiodcpciaefmdahiipjpcghdcfjodkbi" NotOnOrAfter="2011-08-11T23:43:34Z" Recipient="https://www.example.net/a/example.com/acs"></saml:SubjectConfirmationData></saml:SubjectConfirmation></saml:Subject><saml:Conditions NotBefore="2011-08-11T23:38:04Z" NotOnOrAfter="2011-08-11T23:43:34Z"><saml:AudienceRestriction><saml:Audience>example.net</saml:Audience></saml:AudienceRestriction></saml:Conditions><saml:AuthnStatement AuthnInstant="2011-08-11T23:38:34Z"><saml:AuthnContext><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef></saml:AuthnContext></saml:AuthnStatement></saml:Assertion>'
50 SIGNED_ASSERTION_SALESFORCE_XML = '<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_7ccdda8bc6b328570c03b218d7521772998da45374" IssueInstant="2011-08-11T23:38:34Z" Version="2.0"><saml:Issuer>http://127.0.0.1:8000</saml:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationMethod><ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></ds:SignatureMethod><ds:Reference URI="#_7ccdda8bc6b328570c03b218d7521772998da45374"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod><ds:DigestValue>b7HwOJQgKYvhWcrUH17T8WXTY24=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>WP+9aFiuj52WLW6ebwSaQhF2nU/wtyP3E2dudTa6mVTSjItpqduUqWR3rp/q39Hsehde6i+4RlbGQkZUwZSPEw==</ds:SignatureValue><ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIICKzCCAdWgAwIBAgIJAM8DxRNtPj90MA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwHhcNMTEwODEyMjA1MTIzWhcNMTIwODExMjA1MTIzWjBFMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANcNmgm4YlSUAr2xdWei5aRU/DbWtsQ47gjkv28Ekje3ob+6q0M+D5phwYDcv9ygYmuJ5wOi1cPprsWdFWmvSusCAwEAAaOBpzCBpDAdBgNVHQ4EFgQUzyBR9+vE8bygqvD6CZ/w6aQPikMwdQYDVR0jBG4wbIAUzyBR9+vE8bygqvD6CZ/w6aQPikOhSaRHMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGSCCQDPA8UTbT4/dDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA0EAIQuPLA/mlMJAMF680kL7reX5WgyRwAtRzJK6FgNjE7kRaLZQ79UKYVYa0VAyrRdoNEyVhG4tJFEiQJzaLWsl/A==</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature><saml:Subject><saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:email" SPNameQualifier="example.net">randomuser@example.com</saml:NameID><saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"><saml:SubjectConfirmationData InResponseTo="mpjibjdppiodcpciaefmdahiipjpcghdcfjodkbi" NotOnOrAfter="2011-08-11T23:43:34Z" Recipient="https://www.example.net/a/example.com/acs"></saml:SubjectConfirmationData></saml:SubjectConfirmation></saml:Subject><saml:Conditions NotBefore="2011-08-11T23:38:04Z" NotOnOrAfter="2011-08-11T23:43:34Z"><saml:AudienceRestriction><saml:Audience>example.net</saml:Audience></saml:AudienceRestriction></saml:Conditions><saml:AuthnStatement AuthnInstant="2011-08-11T23:38:34Z"><saml:AuthnContext><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef></saml:AuthnContext></saml:AuthnStatement></saml:Assertion>'
51+SIGNED_ASSERTION_SALESFORCE_XML_CUSTOM = '<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_7ccdda8bc6b328570c03b218d7521772998da45374" IssueInstant="2011-08-11T23:38:34Z" Version="2.0"><saml:Issuer>http://127.0.0.1:8000</saml:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationMethod><ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></ds:SignatureMethod><ds:Reference URI="#_7ccdda8bc6b328570c03b218d7521772998da45374"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod><ds:DigestValue>b7HwOJQgKYvhWcrUH17T8WXTY24=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>WP+9aFiuj52WLW6ebwSaQhF2nU/wtyP3E2dudTa6mVTSjItpqduUqWR3rp/q39Hsehde6i+4RlbGQkZUwZSPEw==</ds:SignatureValue><ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIICMTCCAdugAwIBAgIJAIlHgvpeylz2MA0GCSqGSIb3DQEBCwUAMHQxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMQ0wCwYDVQQHDARIZXJlMRgwFgYDVQQKDA9kamFuZ28tc2FtbDJpZHAxJzAlBgNVBAMMHkNlcnRpZmljYXRlIGZvciBjdXN0b20gdGVzdGluZzAeFw0xNzEyMDYyMTU4NTBaFw0xODEyMDYyMTU4NTBaMHQxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMQ0wCwYDVQQHDARIZXJlMRgwFgYDVQQKDA9kamFuZ28tc2FtbDJpZHAxJzAlBgNVBAMMHkNlcnRpZmljYXRlIGZvciBjdXN0b20gdGVzdGluZzBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDXDZoJuGJUlAK9sXVnouWkVPw21rbEOO4I5L9vBJI3t6G/uqtDPg+aYcGA3L/coGJriecDotXD6a7FnRVpr0rrAgMBAAGjUDBOMB0GA1UdDgQWBBTPIFH368TxvKCq8PoJn/DppA+KQzAfBgNVHSMEGDAWgBTPIFH368TxvKCq8PoJn/DppA+KQzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA0EA1mV57y79x9QjFJO5iHgqhXKJuCVVaGx4TaVMcX1exWLLNp37CTvn0zsTdXhlc4MKsznXr3dLrZhVoTHVlkin8w==</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature><saml:Subject><saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:email" SPNameQualifier="example.net">randomuser@example.com</saml:NameID><saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"><saml:SubjectConfirmationData InResponseTo="mpjibjdppiodcpciaefmdahiipjpcghdcfjodkbi" NotOnOrAfter="2011-08-11T23:43:34Z" Recipient="https://www.example.net/a/example.com/acs"></saml:SubjectConfirmationData></saml:SubjectConfirmation></saml:Subject><saml:Conditions NotBefore="2011-08-11T23:38:04Z" NotOnOrAfter="2011-08-11T23:43:34Z"><saml:AudienceRestriction><saml:Audience>example.net</saml:Audience></saml:AudienceRestriction></saml:Conditions><saml:AuthnStatement AuthnInstant="2011-08-11T23:38:34Z"><saml:AuthnContext><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef></saml:AuthnContext></saml:AuthnStatement></saml:Assertion>'
52+
53+ASSERTION_GOOGLE_APPS_PARAMS = {
54+ 'ASSERTION_ID': '_7ccdda8bc6b328570c03b218d7521772998da45374',
55+ 'ASSERTION_SIGNATURE': '', # it's unsigned
56+ 'AUDIENCE': 'google.example.net',
57+ 'AUTH_INSTANT': '2011-08-11T23:38:34Z',
58+ 'ISSUE_INSTANT': '2011-08-11T23:38:34Z',
59+ 'NOT_BEFORE': '2011-08-11T23:38:04Z',
60+ 'NOT_ON_OR_AFTER': '2011-08-11T23:43:34Z',
61+ 'SESSION_NOT_ON_OR_AFTER': '2011-08-12T07:38:34Z',
62+ 'SP_NAME_QUALIFIER': 'google.example.net',
63+ 'SUBJECT': 'randomuser@example.com',
64+ 'SUBJECT_FORMAT': 'urn:oasis:names:tc:SAML:2.0:nameid-format:email',
65+}
66+
67+ASSERTION_GOOGLE_APPS_XML = '<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_7ccdda8bc6b328570c03b218d7521772998da45374" IssueInstant="2011-08-11T23:38:34Z" Version="2.0"><saml:Issuer>http://127.0.0.1:8000</saml:Issuer><saml:Subject><saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:email" SPNameQualifier="google.example.net">randomuser@example.com</saml:NameID><saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"><saml:SubjectConfirmationData InResponseTo="mpjibjdppiodcpciaefmdahiipjpcghdcfjodkbi" NotOnOrAfter="2011-08-11T23:43:34Z" Recipient="https://www.example.net/a/example.com/acs"></saml:SubjectConfirmationData></saml:SubjectConfirmation></saml:Subject><saml:Conditions NotBefore="2011-08-11T23:38:04Z" NotOnOrAfter="2011-08-11T23:43:34Z"></saml:Conditions><saml:AuthnStatement AuthnInstant="2011-08-11T23:38:34Z"><saml:AuthnContext><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef></saml:AuthnContext></saml:AuthnStatement></saml:Assertion>'
68+SIGNED_ASSERTION_GOOGLE_APPS_XML = '<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_7ccdda8bc6b328570c03b218d7521772998da45374" IssueInstant="2011-08-11T23:38:34Z" Version="2.0"><saml:Issuer>http://127.0.0.1:8000</saml:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationMethod><ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></ds:SignatureMethod><ds:Reference URI="#_7ccdda8bc6b328570c03b218d7521772998da45374"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod><ds:DigestValue>6CyR79BkYhTW72Sat2KiBxvgG38=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>Eyaqg5Vx1095Z+5OLIM2vSTFmSawRP4qzakMol/w/xIwjCLiu++OFzpv9TUeRELnA4F/WuEukUVV+59gUqz5RA==</ds:SignatureValue><ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIICKzCCAdWgAwIBAgIJAM8DxRNtPj90MA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwHhcNMTEwODEyMjA1MTIzWhcNMTIwODExMjA1MTIzWjBFMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANcNmgm4YlSUAr2xdWei5aRU/DbWtsQ47gjkv28Ekje3ob+6q0M+D5phwYDcv9ygYmuJ5wOi1cPprsWdFWmvSusCAwEAAaOBpzCBpDAdBgNVHQ4EFgQUzyBR9+vE8bygqvD6CZ/w6aQPikMwdQYDVR0jBG4wbIAUzyBR9+vE8bygqvD6CZ/w6aQPikOhSaRHMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGSCCQDPA8UTbT4/dDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA0EAIQuPLA/mlMJAMF680kL7reX5WgyRwAtRzJK6FgNjE7kRaLZQ79UKYVYa0VAyrRdoNEyVhG4tJFEiQJzaLWsl/A==</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature><saml:Subject><saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:email" SPNameQualifier="google.example.net">randomuser@example.com</saml:NameID><saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"><saml:SubjectConfirmationData InResponseTo="mpjibjdppiodcpciaefmdahiipjpcghdcfjodkbi" NotOnOrAfter="2011-08-11T23:43:34Z" Recipient="https://www.example.net/a/example.com/acs"></saml:SubjectConfirmationData></saml:SubjectConfirmation></saml:Subject><saml:Conditions NotBefore="2011-08-11T23:38:04Z" NotOnOrAfter="2011-08-11T23:43:34Z"></saml:Conditions><saml:AuthnStatement AuthnInstant="2011-08-11T23:38:34Z"><saml:AuthnContext><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef></saml:AuthnContext></saml:AuthnStatement></saml:Assertion>'
69+SIGNED_ASSERTION_GOOGLE_APPS_XML_CUSTOM = '<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_7ccdda8bc6b328570c03b218d7521772998da45374" IssueInstant="2011-08-11T23:38:34Z" Version="2.0"><saml:Issuer>http://127.0.0.1:8000</saml:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationMethod><ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></ds:SignatureMethod><ds:Reference URI="#_7ccdda8bc6b328570c03b218d7521772998da45374"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod><ds:DigestValue>6CyR79BkYhTW72Sat2KiBxvgG38=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>Eyaqg5Vx1095Z+5OLIM2vSTFmSawRP4qzakMol/w/xIwjCLiu++OFzpv9TUeRELnA4F/WuEukUVV+59gUqz5RA==</ds:SignatureValue><ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIICMTCCAdugAwIBAgIJAIlHgvpeylz2MA0GCSqGSIb3DQEBCwUAMHQxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMQ0wCwYDVQQHDARIZXJlMRgwFgYDVQQKDA9kamFuZ28tc2FtbDJpZHAxJzAlBgNVBAMMHkNlcnRpZmljYXRlIGZvciBjdXN0b20gdGVzdGluZzAeFw0xNzEyMDYyMTU4NTBaFw0xODEyMDYyMTU4NTBaMHQxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMQ0wCwYDVQQHDARIZXJlMRgwFgYDVQQKDA9kamFuZ28tc2FtbDJpZHAxJzAlBgNVBAMMHkNlcnRpZmljYXRlIGZvciBjdXN0b20gdGVzdGluZzBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDXDZoJuGJUlAK9sXVnouWkVPw21rbEOO4I5L9vBJI3t6G/uqtDPg+aYcGA3L/coGJriecDotXD6a7FnRVpr0rrAgMBAAGjUDBOMB0GA1UdDgQWBBTPIFH368TxvKCq8PoJn/DppA+KQzAfBgNVHSMEGDAWgBTPIFH368TxvKCq8PoJn/DppA+KQzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA0EA1mV57y79x9QjFJO5iHgqhXKJuCVVaGx4TaVMcX1exWLLNp37CTvn0zsTdXhlc4MKsznXr3dLrZhVoTHVlkin8w==</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature><saml:Subject><saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:email" SPNameQualifier="google.example.net">randomuser@example.com</saml:NameID><saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"><saml:SubjectConfirmationData InResponseTo="mpjibjdppiodcpciaefmdahiipjpcghdcfjodkbi" NotOnOrAfter="2011-08-11T23:43:34Z" Recipient="https://www.example.net/a/example.com/acs"></saml:SubjectConfirmationData></saml:SubjectConfirmation></saml:Subject><saml:Conditions NotBefore="2011-08-11T23:38:04Z" NotOnOrAfter="2011-08-11T23:43:34Z"></saml:Conditions><saml:AuthnStatement AuthnInstant="2011-08-11T23:38:34Z"><saml:AuthnContext><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef></saml:AuthnContext></saml:AuthnStatement></saml:Assertion>'
70+
71
72 RESPONSE_PARAMS = {
73 'ASSERTION': '',
74@@ -41,14 +65,36 @@
75 'SUBJECT_FORMAT': 'urn:oasis:names:tc:SAML:2.0:nameid-format:email',
76 }
77
78-RESPONSE_XML = '<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://www.example.net/a/example.com/acs" ID="_2972e82c07bb5453956cc11fb19cad97ed26ff8bb4" InResponseTo="mpjibjdppiodcpciaefmdahiipjpcghdcfjodkbi" IssueInstant="2011-08-11T23:38:34Z" Version="2.0"><saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">http://127.0.0.1:8000</saml:Issuer><samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"></samlp:StatusCode></samlp:Status><saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_7ccdda8bc6b328570c03b218d7521772998da45374" IssueInstant="2011-08-11T23:38:34Z" Version="2.0"><saml:Issuer>http://127.0.0.1:8000</saml:Issuer><saml:Subject><saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:email" SPNameQualifier="example.net">randomuser@example.com</saml:NameID><saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"><saml:SubjectConfirmationData InResponseTo="mpjibjdppiodcpciaefmdahiipjpcghdcfjodkbi" NotOnOrAfter="2011-08-11T23:43:34Z" Recipient="https://www.example.net/a/example.com/acs"></saml:SubjectConfirmationData></saml:SubjectConfirmation></saml:Subject><saml:Conditions NotBefore="2011-08-11T23:38:04Z" NotOnOrAfter="2011-08-11T23:43:34Z"><saml:AudienceRestriction><saml:Audience>example.net</saml:Audience></saml:AudienceRestriction></saml:Conditions><saml:AuthnStatement AuthnInstant="2011-08-11T23:38:34Z"><saml:AuthnContext><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef></saml:AuthnContext></saml:AuthnStatement></saml:Assertion></samlp:Response>'
79+RESPONSE_SALESFORCE_XML = '<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://www.example.net/a/example.com/acs" ID="_2972e82c07bb5453956cc11fb19cad97ed26ff8bb4" InResponseTo="mpjibjdppiodcpciaefmdahiipjpcghdcfjodkbi" IssueInstant="2011-08-11T23:38:34Z" Version="2.0"><saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">http://127.0.0.1:8000</saml:Issuer><samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"></samlp:StatusCode></samlp:Status><saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_7ccdda8bc6b328570c03b218d7521772998da45374" IssueInstant="2011-08-11T23:38:34Z" Version="2.0"><saml:Issuer>http://127.0.0.1:8000</saml:Issuer><saml:Subject><saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:email" SPNameQualifier="example.net">randomuser@example.com</saml:NameID><saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"><saml:SubjectConfirmationData InResponseTo="mpjibjdppiodcpciaefmdahiipjpcghdcfjodkbi" NotOnOrAfter="2011-08-11T23:43:34Z" Recipient="https://www.example.net/a/example.com/acs"></saml:SubjectConfirmationData></saml:SubjectConfirmation></saml:Subject><saml:Conditions NotBefore="2011-08-11T23:38:04Z" NotOnOrAfter="2011-08-11T23:43:34Z"><saml:AudienceRestriction><saml:Audience>example.net</saml:Audience></saml:AudienceRestriction></saml:Conditions><saml:AuthnStatement AuthnInstant="2011-08-11T23:38:34Z"><saml:AuthnContext><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef></saml:AuthnContext></saml:AuthnStatement></saml:Assertion></samlp:Response>'
80 RESPONSE_WITH_SIGNED_ASSERTION_SALESFORCE_XML = '<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://www.example.net/a/example.com/acs" ID="_2972e82c07bb5453956cc11fb19cad97ed26ff8bb4" InResponseTo="mpjibjdppiodcpciaefmdahiipjpcghdcfjodkbi" IssueInstant="2011-08-11T23:38:34Z" Version="2.0"><saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">http://127.0.0.1:8000</saml:Issuer><samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"></samlp:StatusCode></samlp:Status><saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_7ccdda8bc6b328570c03b218d7521772998da45374" IssueInstant="2011-08-11T23:38:34Z" Version="2.0"><saml:Issuer>http://127.0.0.1:8000</saml:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationMethod><ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></ds:SignatureMethod><ds:Reference URI="#_7ccdda8bc6b328570c03b218d7521772998da45374"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod><ds:DigestValue>b7HwOJQgKYvhWcrUH17T8WXTY24=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>WP+9aFiuj52WLW6ebwSaQhF2nU/wtyP3E2dudTa6mVTSjItpqduUqWR3rp/q39Hsehde6i+4RlbGQkZUwZSPEw==</ds:SignatureValue><ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIICKzCCAdWgAwIBAgIJAM8DxRNtPj90MA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwHhcNMTEwODEyMjA1MTIzWhcNMTIwODExMjA1MTIzWjBFMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANcNmgm4YlSUAr2xdWei5aRU/DbWtsQ47gjkv28Ekje3ob+6q0M+D5phwYDcv9ygYmuJ5wOi1cPprsWdFWmvSusCAwEAAaOBpzCBpDAdBgNVHQ4EFgQUzyBR9+vE8bygqvD6CZ/w6aQPikMwdQYDVR0jBG4wbIAUzyBR9+vE8bygqvD6CZ/w6aQPikOhSaRHMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGSCCQDPA8UTbT4/dDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA0EAIQuPLA/mlMJAMF680kL7reX5WgyRwAtRzJK6FgNjE7kRaLZQ79UKYVYa0VAyrRdoNEyVhG4tJFEiQJzaLWsl/A==</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature><saml:Subject><saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:email" SPNameQualifier="example.net">randomuser@example.com</saml:NameID><saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"><saml:SubjectConfirmationData InResponseTo="mpjibjdppiodcpciaefmdahiipjpcghdcfjodkbi" NotOnOrAfter="2011-08-11T23:43:34Z" Recipient="https://www.example.net/a/example.com/acs"></saml:SubjectConfirmationData></saml:SubjectConfirmation></saml:Subject><saml:Conditions NotBefore="2011-08-11T23:38:04Z" NotOnOrAfter="2011-08-11T23:43:34Z"><saml:AudienceRestriction><saml:Audience>example.net</saml:Audience></saml:AudienceRestriction></saml:Conditions><saml:AuthnStatement AuthnInstant="2011-08-11T23:38:34Z"><saml:AuthnContext><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef></saml:AuthnContext></saml:AuthnStatement></saml:Assertion></samlp:Response>'
81-
82 SIGNED_RESPONSE_WITH_SIGNED_ASSERTION_SALESFORCE_XML = '<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://www.example.net/a/example.com/acs" ID="_2972e82c07bb5453956cc11fb19cad97ed26ff8bb4" InResponseTo="mpjibjdppiodcpciaefmdahiipjpcghdcfjodkbi" IssueInstant="2011-08-11T23:38:34Z" Version="2.0"><saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">http://127.0.0.1:8000</saml:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationMethod><ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></ds:SignatureMethod><ds:Reference URI="#_2972e82c07bb5453956cc11fb19cad97ed26ff8bb4"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod><ds:DigestValue>sxi1OztMxi2taVoT3kxaVXQrVx4=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>tErJwi7CBpFWXQRKxEcpkoNZKDv2D1D1hBOlEWWYOyrU5eGaaLFrQ/dMA3D7S0lGjGEf7YkkgiZOAE4dKVHhUg==</ds:SignatureValue><ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIICKzCCAdWgAwIBAgIJAM8DxRNtPj90MA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwHhcNMTEwODEyMjA1MTIzWhcNMTIwODExMjA1MTIzWjBFMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANcNmgm4YlSUAr2xdWei5aRU/DbWtsQ47gjkv28Ekje3ob+6q0M+D5phwYDcv9ygYmuJ5wOi1cPprsWdFWmvSusCAwEAAaOBpzCBpDAdBgNVHQ4EFgQUzyBR9+vE8bygqvD6CZ/w6aQPikMwdQYDVR0jBG4wbIAUzyBR9+vE8bygqvD6CZ/w6aQPikOhSaRHMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGSCCQDPA8UTbT4/dDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA0EAIQuPLA/mlMJAMF680kL7reX5WgyRwAtRzJK6FgNjE7kRaLZQ79UKYVYa0VAyrRdoNEyVhG4tJFEiQJzaLWsl/A==</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature><samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"></samlp:StatusCode></samlp:Status><saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_7ccdda8bc6b328570c03b218d7521772998da45374" IssueInstant="2011-08-11T23:38:34Z" Version="2.0"><saml:Issuer>http://127.0.0.1:8000</saml:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationMethod><ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></ds:SignatureMethod><ds:Reference URI="#_7ccdda8bc6b328570c03b218d7521772998da45374"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod><ds:DigestValue>b7HwOJQgKYvhWcrUH17T8WXTY24=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>WP+9aFiuj52WLW6ebwSaQhF2nU/wtyP3E2dudTa6mVTSjItpqduUqWR3rp/q39Hsehde6i+4RlbGQkZUwZSPEw==</ds:SignatureValue><ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIICKzCCAdWgAwIBAgIJAM8DxRNtPj90MA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwHhcNMTEwODEyMjA1MTIzWhcNMTIwODExMjA1MTIzWjBFMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANcNmgm4YlSUAr2xdWei5aRU/DbWtsQ47gjkv28Ekje3ob+6q0M+D5phwYDcv9ygYmuJ5wOi1cPprsWdFWmvSusCAwEAAaOBpzCBpDAdBgNVHQ4EFgQUzyBR9+vE8bygqvD6CZ/w6aQPikMwdQYDVR0jBG4wbIAUzyBR9+vE8bygqvD6CZ/w6aQPikOhSaRHMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGSCCQDPA8UTbT4/dDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA0EAIQuPLA/mlMJAMF680kL7reX5WgyRwAtRzJK6FgNjE7kRaLZQ79UKYVYa0VAyrRdoNEyVhG4tJFEiQJzaLWsl/A==</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature><saml:Subject><saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:email" SPNameQualifier="example.net">randomuser@example.com</saml:NameID><saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"><saml:SubjectConfirmationData InResponseTo="mpjibjdppiodcpciaefmdahiipjpcghdcfjodkbi" NotOnOrAfter="2011-08-11T23:43:34Z" Recipient="https://www.example.net/a/example.com/acs"></saml:SubjectConfirmationData></saml:SubjectConfirmation></saml:Subject><saml:Conditions NotBefore="2011-08-11T23:38:04Z" NotOnOrAfter="2011-08-11T23:43:34Z"><saml:AudienceRestriction><saml:Audience>example.net</saml:Audience></saml:AudienceRestriction></saml:Conditions><saml:AuthnStatement AuthnInstant="2011-08-11T23:38:34Z"><saml:AuthnContext><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef></saml:AuthnContext></saml:AuthnStatement></saml:Assertion></samlp:Response>'
83+SIGNED_RESPONSE_WITH_SIGNED_ASSERTION_SALESFORCE_XML_CUSTOM = '<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://www.example.net/a/example.com/acs" ID="_2972e82c07bb5453956cc11fb19cad97ed26ff8bb4" InResponseTo="mpjibjdppiodcpciaefmdahiipjpcghdcfjodkbi" IssueInstant="2011-08-11T23:38:34Z" Version="2.0"><saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">http://127.0.0.1:8000</saml:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationMethod><ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></ds:SignatureMethod><ds:Reference URI="#_2972e82c07bb5453956cc11fb19cad97ed26ff8bb4"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod><ds:DigestValue>sxi1OztMxi2taVoT3kxaVXQrVx4=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>tErJwi7CBpFWXQRKxEcpkoNZKDv2D1D1hBOlEWWYOyrU5eGaaLFrQ/dMA3D7S0lGjGEf7YkkgiZOAE4dKVHhUg==</ds:SignatureValue><ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIICMTCCAdugAwIBAgIJAIlHgvpeylz2MA0GCSqGSIb3DQEBCwUAMHQxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMQ0wCwYDVQQHDARIZXJlMRgwFgYDVQQKDA9kamFuZ28tc2FtbDJpZHAxJzAlBgNVBAMMHkNlcnRpZmljYXRlIGZvciBjdXN0b20gdGVzdGluZzAeFw0xNzEyMDYyMTU4NTBaFw0xODEyMDYyMTU4NTBaMHQxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMQ0wCwYDVQQHDARIZXJlMRgwFgYDVQQKDA9kamFuZ28tc2FtbDJpZHAxJzAlBgNVBAMMHkNlcnRpZmljYXRlIGZvciBjdXN0b20gdGVzdGluZzBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDXDZoJuGJUlAK9sXVnouWkVPw21rbEOO4I5L9vBJI3t6G/uqtDPg+aYcGA3L/coGJriecDotXD6a7FnRVpr0rrAgMBAAGjUDBOMB0GA1UdDgQWBBTPIFH368TxvKCq8PoJn/DppA+KQzAfBgNVHSMEGDAWgBTPIFH368TxvKCq8PoJn/DppA+KQzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA0EA1mV57y79x9QjFJO5iHgqhXKJuCVVaGx4TaVMcX1exWLLNp37CTvn0zsTdXhlc4MKsznXr3dLrZhVoTHVlkin8w==</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature><samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"></samlp:StatusCode></samlp:Status><saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_7ccdda8bc6b328570c03b218d7521772998da45374" IssueInstant="2011-08-11T23:38:34Z" Version="2.0"><saml:Issuer>http://127.0.0.1:8000</saml:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationMethod><ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></ds:SignatureMethod><ds:Reference URI="#_7ccdda8bc6b328570c03b218d7521772998da45374"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod><ds:DigestValue>b7HwOJQgKYvhWcrUH17T8WXTY24=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>WP+9aFiuj52WLW6ebwSaQhF2nU/wtyP3E2dudTa6mVTSjItpqduUqWR3rp/q39Hsehde6i+4RlbGQkZUwZSPEw==</ds:SignatureValue><ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIICKzCCAdWgAwIBAgIJAM8DxRNtPj90MA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwHhcNMTEwODEyMjA1MTIzWhcNMTIwODExMjA1MTIzWjBFMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANcNmgm4YlSUAr2xdWei5aRU/DbWtsQ47gjkv28Ekje3ob+6q0M+D5phwYDcv9ygYmuJ5wOi1cPprsWdFWmvSusCAwEAAaOBpzCBpDAdBgNVHQ4EFgQUzyBR9+vE8bygqvD6CZ/w6aQPikMwdQYDVR0jBG4wbIAUzyBR9+vE8bygqvD6CZ/w6aQPikOhSaRHMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGSCCQDPA8UTbT4/dDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA0EAIQuPLA/mlMJAMF680kL7reX5WgyRwAtRzJK6FgNjE7kRaLZQ79UKYVYa0VAyrRdoNEyVhG4tJFEiQJzaLWsl/A==</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature><saml:Subject><saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:email" SPNameQualifier="example.net">randomuser@example.com</saml:NameID><saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"><saml:SubjectConfirmationData InResponseTo="mpjibjdppiodcpciaefmdahiipjpcghdcfjodkbi" NotOnOrAfter="2011-08-11T23:43:34Z" Recipient="https://www.example.net/a/example.com/acs"></saml:SubjectConfirmationData></saml:SubjectConfirmation></saml:Subject><saml:Conditions NotBefore="2011-08-11T23:38:04Z" NotOnOrAfter="2011-08-11T23:43:34Z"><saml:AudienceRestriction><saml:Audience>example.net</saml:Audience></saml:AudienceRestriction></saml:Conditions><saml:AuthnStatement AuthnInstant="2011-08-11T23:38:34Z"><saml:AuthnContext><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef></saml:AuthnContext></saml:AuthnStatement></saml:Assertion></samlp:Response>'
84+
85+RESPONSE_GOOGLE_APPS_XML = '<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://www.example.net/a/example.com/acs" ID="_2972e82c07bb5453956cc11fb19cad97ed26ff8bb4" InResponseTo="mpjibjdppiodcpciaefmdahiipjpcghdcfjodkbi" IssueInstant="2011-08-11T23:38:34Z" Version="2.0"><saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">http://127.0.0.1:8000</saml:Issuer><samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"></samlp:StatusCode></samlp:Status><saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_7ccdda8bc6b328570c03b218d7521772998da45374" IssueInstant="2011-08-11T23:38:34Z" Version="2.0"><saml:Issuer>http://127.0.0.1:8000</saml:Issuer><saml:Subject><saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:email" SPNameQualifier="google.example.net">randomuser@example.com</saml:NameID><saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"><saml:SubjectConfirmationData InResponseTo="mpjibjdppiodcpciaefmdahiipjpcghdcfjodkbi" NotOnOrAfter="2011-08-11T23:43:34Z" Recipient="https://www.example.net/a/example.com/acs"></saml:SubjectConfirmationData></saml:SubjectConfirmation></saml:Subject><saml:Conditions NotBefore="2011-08-11T23:38:04Z" NotOnOrAfter="2011-08-11T23:43:34Z"></saml:Conditions><saml:AuthnStatement AuthnInstant="2011-08-11T23:38:34Z"><saml:AuthnContext><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef></saml:AuthnContext></saml:AuthnStatement></saml:Assertion></samlp:Response>'
86+RESPONSE_WITH_SIGNED_ASSERTION_GOOGLE_APPS_XML = '<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://www.example.net/a/example.com/acs" ID="_2972e82c07bb5453956cc11fb19cad97ed26ff8bb4" InResponseTo="mpjibjdppiodcpciaefmdahiipjpcghdcfjodkbi" IssueInstant="2011-08-11T23:38:34Z" Version="2.0"><saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">http://127.0.0.1:8000</saml:Issuer><samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"></samlp:StatusCode></samlp:Status><saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_7ccdda8bc6b328570c03b218d7521772998da45374" IssueInstant="2011-08-11T23:38:34Z" Version="2.0"><saml:Issuer>http://127.0.0.1:8000</saml:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationMethod><ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></ds:SignatureMethod><ds:Reference URI="#_7ccdda8bc6b328570c03b218d7521772998da45374"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod><ds:DigestValue>6CyR79BkYhTW72Sat2KiBxvgG38=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>Eyaqg5Vx1095Z+5OLIM2vSTFmSawRP4qzakMol/w/xIwjCLiu++OFzpv9TUeRELnA4F/WuEukUVV+59gUqz5RA==</ds:SignatureValue><ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIICKzCCAdWgAwIBAgIJAM8DxRNtPj90MA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwHhcNMTEwODEyMjA1MTIzWhcNMTIwODExMjA1MTIzWjBFMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANcNmgm4YlSUAr2xdWei5aRU/DbWtsQ47gjkv28Ekje3ob+6q0M+D5phwYDcv9ygYmuJ5wOi1cPprsWdFWmvSusCAwEAAaOBpzCBpDAdBgNVHQ4EFgQUzyBR9+vE8bygqvD6CZ/w6aQPikMwdQYDVR0jBG4wbIAUzyBR9+vE8bygqvD6CZ/w6aQPikOhSaRHMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGSCCQDPA8UTbT4/dDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA0EAIQuPLA/mlMJAMF680kL7reX5WgyRwAtRzJK6FgNjE7kRaLZQ79UKYVYa0VAyrRdoNEyVhG4tJFEiQJzaLWsl/A==</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature><saml:Subject><saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:email" SPNameQualifier="google.example.net">randomuser@example.com</saml:NameID><saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"><saml:SubjectConfirmationData InResponseTo="mpjibjdppiodcpciaefmdahiipjpcghdcfjodkbi" NotOnOrAfter="2011-08-11T23:43:34Z" Recipient="https://www.example.net/a/example.com/acs"></saml:SubjectConfirmationData></saml:SubjectConfirmation></saml:Subject><saml:Conditions NotBefore="2011-08-11T23:38:04Z" NotOnOrAfter="2011-08-11T23:43:34Z"></saml:Conditions><saml:AuthnStatement AuthnInstant="2011-08-11T23:38:34Z"><saml:AuthnContext><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef></saml:AuthnContext></saml:AuthnStatement></saml:Assertion></samlp:Response>'
87+SIGNED_RESPONSE_WITH_SIGNED_ASSERTION_GOOGLE_APPS_XML = '<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://www.example.net/a/example.com/acs" ID="_2972e82c07bb5453956cc11fb19cad97ed26ff8bb4" InResponseTo="mpjibjdppiodcpciaefmdahiipjpcghdcfjodkbi" IssueInstant="2011-08-11T23:38:34Z" Version="2.0"><saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">http://127.0.0.1:8000</saml:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationMethod><ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></ds:SignatureMethod><ds:Reference URI="#_2972e82c07bb5453956cc11fb19cad97ed26ff8bb4"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod><ds:DigestValue>gKuvvIsDFU3vjLr1gEjbNK11Wh0=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>PNDqw6f8k55hrR9wlb0BqxebweV9oEzgjcPqQ2WVMD9Cf/DwHcvfNprIflY/u/hsiWaINoCWXZ9EVaVyO/NM9w==</ds:SignatureValue><ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIICKzCCAdWgAwIBAgIJAM8DxRNtPj90MA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwHhcNMTEwODEyMjA1MTIzWhcNMTIwODExMjA1MTIzWjBFMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANcNmgm4YlSUAr2xdWei5aRU/DbWtsQ47gjkv28Ekje3ob+6q0M+D5phwYDcv9ygYmuJ5wOi1cPprsWdFWmvSusCAwEAAaOBpzCBpDAdBgNVHQ4EFgQUzyBR9+vE8bygqvD6CZ/w6aQPikMwdQYDVR0jBG4wbIAUzyBR9+vE8bygqvD6CZ/w6aQPikOhSaRHMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGSCCQDPA8UTbT4/dDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA0EAIQuPLA/mlMJAMF680kL7reX5WgyRwAtRzJK6FgNjE7kRaLZQ79UKYVYa0VAyrRdoNEyVhG4tJFEiQJzaLWsl/A==</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature><samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"></samlp:StatusCode></samlp:Status><saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_7ccdda8bc6b328570c03b218d7521772998da45374" IssueInstant="2011-08-11T23:38:34Z" Version="2.0"><saml:Issuer>http://127.0.0.1:8000</saml:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationMethod><ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></ds:SignatureMethod><ds:Reference URI="#_7ccdda8bc6b328570c03b218d7521772998da45374"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod><ds:DigestValue>6CyR79BkYhTW72Sat2KiBxvgG38=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>Eyaqg5Vx1095Z+5OLIM2vSTFmSawRP4qzakMol/w/xIwjCLiu++OFzpv9TUeRELnA4F/WuEukUVV+59gUqz5RA==</ds:SignatureValue><ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIICKzCCAdWgAwIBAgIJAM8DxRNtPj90MA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwHhcNMTEwODEyMjA1MTIzWhcNMTIwODExMjA1MTIzWjBFMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANcNmgm4YlSUAr2xdWei5aRU/DbWtsQ47gjkv28Ekje3ob+6q0M+D5phwYDcv9ygYmuJ5wOi1cPprsWdFWmvSusCAwEAAaOBpzCBpDAdBgNVHQ4EFgQUzyBR9+vE8bygqvD6CZ/w6aQPikMwdQYDVR0jBG4wbIAUzyBR9+vE8bygqvD6CZ/w6aQPikOhSaRHMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGSCCQDPA8UTbT4/dDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA0EAIQuPLA/mlMJAMF680kL7reX5WgyRwAtRzJK6FgNjE7kRaLZQ79UKYVYa0VAyrRdoNEyVhG4tJFEiQJzaLWsl/A==</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature><saml:Subject><saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:email" SPNameQualifier="google.example.net">randomuser@example.com</saml:NameID><saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"><saml:SubjectConfirmationData InResponseTo="mpjibjdppiodcpciaefmdahiipjpcghdcfjodkbi" NotOnOrAfter="2011-08-11T23:43:34Z" Recipient="https://www.example.net/a/example.com/acs"></saml:SubjectConfirmationData></saml:SubjectConfirmation></saml:Subject><saml:Conditions NotBefore="2011-08-11T23:38:04Z" NotOnOrAfter="2011-08-11T23:43:34Z"></saml:Conditions><saml:AuthnStatement AuthnInstant="2011-08-11T23:38:34Z"><saml:AuthnContext><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef></saml:AuthnContext></saml:AuthnStatement></saml:Assertion></samlp:Response>'
88+SIGNED_RESPONSE_WITH_SIGNED_ASSERTION_GOOGLE_APPS_XML_CUSTOM = '<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://www.example.net/a/example.com/acs" ID="_2972e82c07bb5453956cc11fb19cad97ed26ff8bb4" InResponseTo="mpjibjdppiodcpciaefmdahiipjpcghdcfjodkbi" IssueInstant="2011-08-11T23:38:34Z" Version="2.0"><saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">http://127.0.0.1:8000</saml:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationMethod><ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></ds:SignatureMethod><ds:Reference URI="#_2972e82c07bb5453956cc11fb19cad97ed26ff8bb4"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod><ds:DigestValue>gKuvvIsDFU3vjLr1gEjbNK11Wh0=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>PNDqw6f8k55hrR9wlb0BqxebweV9oEzgjcPqQ2WVMD9Cf/DwHcvfNprIflY/u/hsiWaINoCWXZ9EVaVyO/NM9w==</ds:SignatureValue><ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIICMTCCAdugAwIBAgIJAIlHgvpeylz2MA0GCSqGSIb3DQEBCwUAMHQxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMQ0wCwYDVQQHDARIZXJlMRgwFgYDVQQKDA9kamFuZ28tc2FtbDJpZHAxJzAlBgNVBAMMHkNlcnRpZmljYXRlIGZvciBjdXN0b20gdGVzdGluZzAeFw0xNzEyMDYyMTU4NTBaFw0xODEyMDYyMTU4NTBaMHQxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMQ0wCwYDVQQHDARIZXJlMRgwFgYDVQQKDA9kamFuZ28tc2FtbDJpZHAxJzAlBgNVBAMMHkNlcnRpZmljYXRlIGZvciBjdXN0b20gdGVzdGluZzBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDXDZoJuGJUlAK9sXVnouWkVPw21rbEOO4I5L9vBJI3t6G/uqtDPg+aYcGA3L/coGJriecDotXD6a7FnRVpr0rrAgMBAAGjUDBOMB0GA1UdDgQWBBTPIFH368TxvKCq8PoJn/DppA+KQzAfBgNVHSMEGDAWgBTPIFH368TxvKCq8PoJn/DppA+KQzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA0EA1mV57y79x9QjFJO5iHgqhXKJuCVVaGx4TaVMcX1exWLLNp37CTvn0zsTdXhlc4MKsznXr3dLrZhVoTHVlkin8w==</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature><samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"></samlp:StatusCode></samlp:Status><saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_7ccdda8bc6b328570c03b218d7521772998da45374" IssueInstant="2011-08-11T23:38:34Z" Version="2.0"><saml:Issuer>http://127.0.0.1:8000</saml:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationMethod><ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></ds:SignatureMethod><ds:Reference URI="#_7ccdda8bc6b328570c03b218d7521772998da45374"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod><ds:DigestValue>6CyR79BkYhTW72Sat2KiBxvgG38=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>Eyaqg5Vx1095Z+5OLIM2vSTFmSawRP4qzakMol/w/xIwjCLiu++OFzpv9TUeRELnA4F/WuEukUVV+59gUqz5RA==</ds:SignatureValue><ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIICKzCCAdWgAwIBAgIJAM8DxRNtPj90MA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwHhcNMTEwODEyMjA1MTIzWhcNMTIwODExMjA1MTIzWjBFMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANcNmgm4YlSUAr2xdWei5aRU/DbWtsQ47gjkv28Ekje3ob+6q0M+D5phwYDcv9ygYmuJ5wOi1cPprsWdFWmvSusCAwEAAaOBpzCBpDAdBgNVHQ4EFgQUzyBR9+vE8bygqvD6CZ/w6aQPikMwdQYDVR0jBG4wbIAUzyBR9+vE8bygqvD6CZ/w6aQPikOhSaRHMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGSCCQDPA8UTbT4/dDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA0EAIQuPLA/mlMJAMF680kL7reX5WgyRwAtRzJK6FgNjE7kRaLZQ79UKYVYa0VAyrRdoNEyVhG4tJFEiQJzaLWsl/A==</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature><saml:Subject><saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:email" SPNameQualifier="google.example.net">randomuser@example.com</saml:NameID><saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"><saml:SubjectConfirmationData InResponseTo="mpjibjdppiodcpciaefmdahiipjpcghdcfjodkbi" NotOnOrAfter="2011-08-11T23:43:34Z" Recipient="https://www.example.net/a/example.com/acs"></saml:SubjectConfirmationData></saml:SubjectConfirmation></saml:Subject><saml:Conditions NotBefore="2011-08-11T23:38:04Z" NotOnOrAfter="2011-08-11T23:43:34Z"></saml:Conditions><saml:AuthnStatement AuthnInstant="2011-08-11T23:38:34Z"><saml:AuthnContext><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef></saml:AuthnContext></saml:AuthnStatement></saml:Assertion></samlp:Response>'
89+
90+CUSTOM_CERT_STRING = """-----BEGIN CERTIFICATE-----
91+MIICMTCCAdugAwIBAgIJAIlHgvpeylz2MA0GCSqGSIb3DQEBCwUAMHQxCzAJBgNV
92+BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMQ0wCwYDVQQHDARIZXJlMRgwFgYD
93+VQQKDA9kamFuZ28tc2FtbDJpZHAxJzAlBgNVBAMMHkNlcnRpZmljYXRlIGZvciBj
94+dXN0b20gdGVzdGluZzAeFw0xNzEyMDYyMTU4NTBaFw0xODEyMDYyMTU4NTBaMHQx
95+CzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMQ0wCwYDVQQHDARIZXJl
96+MRgwFgYDVQQKDA9kamFuZ28tc2FtbDJpZHAxJzAlBgNVBAMMHkNlcnRpZmljYXRl
97+IGZvciBjdXN0b20gdGVzdGluZzBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDXDZoJ
98+uGJUlAK9sXVnouWkVPw21rbEOO4I5L9vBJI3t6G/uqtDPg+aYcGA3L/coGJriecD
99+otXD6a7FnRVpr0rrAgMBAAGjUDBOMB0GA1UdDgQWBBTPIFH368TxvKCq8PoJn/Dp
100+pA+KQzAfBgNVHSMEGDAWgBTPIFH368TxvKCq8PoJn/DppA+KQzAMBgNVHRMEBTAD
101+AQH/MA0GCSqGSIb3DQEBCwUAA0EA1mV57y79x9QjFJO5iHgqhXKJuCVVaGx4TaVM
102+cX1exWLLNp37CTvn0zsTdXhlc4MKsznXr3dLrZhVoTHVlkin8w==
103+-----END CERTIFICATE-----
104+"""
105+
106
107 class XmlTest(unittest.TestCase):
108 def _test(self, got, exp):
109- #TODO: Maybe provide more meaningful output. YAGNI?
110+ # TODO: Maybe provide more meaningful output. YAGNI?
111 msg = 'Did not get expected XML.\nExp: %s\nGot: %s' % (exp, got)
112 self.assertEqual(exp, got, msg)
113
114@@ -59,49 +105,94 @@
115 got = string.Template(template_source).substitute(parameters)
116 self._test(got, exp)
117
118+
119 class TestSigning(XmlTest):
120- def test1(self):
121+ def test_signing_default_cert(self):
122 signature_xml = get_signature_xml("this is a test", 'abcd' * 10)
123 expected_xml = '<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationMethod><ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></ds:SignatureMethod><ds:Reference URI="#abcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod><ds:DigestValue>+ia+Gd5r/5P3C8IwhDTkpEC7rQI=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>t1IywxEzobY8ZyHL+iuB+E3zzVAWByUjRqFTdyNerGbGSRwo0oYWx6hcYX+ST1DTDaQ50gV2PJeibbykFsA3vQ==</ds:SignatureValue><ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIICKzCCAdWgAwIBAgIJAM8DxRNtPj90MA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwHhcNMTEwODEyMjA1MTIzWhcNMTIwODExMjA1MTIzWjBFMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANcNmgm4YlSUAr2xdWei5aRU/DbWtsQ47gjkv28Ekje3ob+6q0M+D5phwYDcv9ygYmuJ5wOi1cPprsWdFWmvSusCAwEAAaOBpzCBpDAdBgNVHQ4EFgQUzyBR9+vE8bygqvD6CZ/w6aQPikMwdQYDVR0jBG4wbIAUzyBR9+vE8bygqvD6CZ/w6aQPikOhSaRHMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGSCCQDPA8UTbT4/dDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA0EAIQuPLA/mlMJAMF680kL7reX5WgyRwAtRzJK6FgNjE7kRaLZQ79UKYVYa0VAyrRdoNEyVhG4tJFEiQJzaLWsl/A==</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature>'
124 self._test(signature_xml, expected_xml)
125
126-class TestAssertionSalesForce(XmlTest):
127+ def test_signing_custom_cert(self):
128+ signature_xml = get_signature_xml(
129+ "this is a test", 'abcd' * 10, certificate=CUSTOM_CERT_STRING)
130+ expected_xml = '<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationMethod><ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></ds:SignatureMethod><ds:Reference URI="#abcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod><ds:DigestValue>+ia+Gd5r/5P3C8IwhDTkpEC7rQI=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>t1IywxEzobY8ZyHL+iuB+E3zzVAWByUjRqFTdyNerGbGSRwo0oYWx6hcYX+ST1DTDaQ50gV2PJeibbykFsA3vQ==</ds:SignatureValue><ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIICMTCCAdugAwIBAgIJAIlHgvpeylz2MA0GCSqGSIb3DQEBCwUAMHQxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMQ0wCwYDVQQHDARIZXJlMRgwFgYDVQQKDA9kamFuZ28tc2FtbDJpZHAxJzAlBgNVBAMMHkNlcnRpZmljYXRlIGZvciBjdXN0b20gdGVzdGluZzAeFw0xNzEyMDYyMTU4NTBaFw0xODEyMDYyMTU4NTBaMHQxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMQ0wCwYDVQQHDARIZXJlMRgwFgYDVQQKDA9kamFuZ28tc2FtbDJpZHAxJzAlBgNVBAMMHkNlcnRpZmljYXRlIGZvciBjdXN0b20gdGVzdGluZzBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDXDZoJuGJUlAK9sXVnouWkVPw21rbEOO4I5L9vBJI3t6G/uqtDPg+aYcGA3L/coGJriecDotXD6a7FnRVpr0rrAgMBAAGjUDBOMB0GA1UdDgQWBBTPIFH368TxvKCq8PoJn/DppA+KQzAfBgNVHSMEGDAWgBTPIFH368TxvKCq8PoJn/DppA+KQzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA0EA1mV57y79x9QjFJO5iHgqhXKJuCVVaGx4TaVMcX1exWLLNp37CTvn0zsTdXhlc4MKsznXr3dLrZhVoTHVlkin8w==</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature>'
131+ self._test(signature_xml, expected_xml)
132+
133+
134+class TestAssertion(object):
135+ """Mixin of common assertion test methods using class parameters to customize."""
136 def test_assertion(self):
137 # This test simply verifies that the template isn't bad.
138 params = {}
139 params.update(IDP_PARAMS)
140 params.update(REQUEST_PARAMS)
141- params.update(ASSERTION_SALESFORCE_PARAMS)
142- self._test_template(ASSERTION_SALESFORCE, params, ASSERTION_SALESFORCE_XML)
143+ params.update(self.ASSERTION_PARAMS)
144+ self._test_template(self.ASSERTION, params, self.ASSERTION_XML)
145
146 def test_assertion_rendering(self):
147 # Verifies that the xml rendering is OK.
148 params = {}
149 params.update(IDP_PARAMS)
150 params.update(REQUEST_PARAMS)
151- params.update(ASSERTION_SALESFORCE_PARAMS)
152- got = xml_render.get_assertion_salesforce_xml(params, signed=False)
153- self._test(got, ASSERTION_SALESFORCE_XML)
154+ params.update(self.ASSERTION_PARAMS)
155+ got = self.render_method(params, signed=False)
156+ self._test(got, self.ASSERTION_XML)
157
158 def test_signed_assertion(self):
159 # This test verifies that the assertion got signed properly.
160 params = {}
161 params.update(IDP_PARAMS)
162 params.update(REQUEST_PARAMS)
163- params.update(ASSERTION_SALESFORCE_PARAMS)
164- got = xml_render.get_assertion_salesforce_xml(params, signed=True)
165- self._test(got, SIGNED_ASSERTION_SALESFORCE_XML)
166-
167-
168-class TestResponse(XmlTest):
169+ params.update(self.ASSERTION_PARAMS)
170+ got = self.render_method(params, signed=True)
171+ self._test(got, self.SIGNED_ASSERTION_XML)
172+
173+ def test_signed_assertion_custom_cert(self):
174+ # This test verifies that the assertion got signed properly with a
175+ # custom cert
176+ params = {}
177+ params.update(IDP_PARAMS)
178+ params.update(REQUEST_PARAMS)
179+ params.update(self.ASSERTION_PARAMS)
180+ got = self.render_method(
181+ params, signed=True, certificate=CUSTOM_CERT_STRING)
182+ self._test(got, self.SIGNED_ASSERTION_XML_CUSTOM)
183+
184+
185+class TestAssertionGoogleApps(XmlTest, TestAssertion):
186+ ASSERTION_PARAMS = ASSERTION_GOOGLE_APPS_PARAMS
187+ ASSERTION = ASSERTION_GOOGLE_APPS
188+ ASSERTION_XML = ASSERTION_GOOGLE_APPS_XML
189+ SIGNED_ASSERTION_XML = SIGNED_ASSERTION_GOOGLE_APPS_XML
190+ SIGNED_ASSERTION_XML_CUSTOM = SIGNED_ASSERTION_GOOGLE_APPS_XML_CUSTOM
191+
192+ # render_method should just call one of the get_assertion_*_xml methods.
193+ def render_method(self, *args, **kwargs):
194+ return xml_render.get_assertion_googleapps_xml(*args, **kwargs)
195+
196+
197+class TestAssertionSalesForce(XmlTest, TestAssertion):
198+ ASSERTION_PARAMS = ASSERTION_SALESFORCE_PARAMS
199+ ASSERTION = ASSERTION_SALESFORCE
200+ ASSERTION_XML = ASSERTION_SALESFORCE_XML
201+ SIGNED_ASSERTION_XML = SIGNED_ASSERTION_SALESFORCE_XML
202+ SIGNED_ASSERTION_XML_CUSTOM = SIGNED_ASSERTION_SALESFORCE_XML_CUSTOM
203+
204+ # render_method should just call one of the get_assertion_*_xml methods.
205+ def render_method(self, *args, **kwargs):
206+ return xml_render.get_assertion_salesforce_xml(*args, **kwargs)
207+
208+
209+class TestResponse(object):
210+ """Mixin of common response test methods,"""
211 def test_response(self):
212 # This test simply verifies that the template isn't bad.
213 params = {}
214 params.update(IDP_PARAMS)
215 params.update(REQUEST_PARAMS)
216 params.update(RESPONSE_PARAMS)
217- params['ASSERTION'] = ASSERTION_SALESFORCE_XML
218- self._test_template(RESPONSE, params, RESPONSE_XML)
219+ params['ASSERTION'] = self.ASSERTION_XML
220+ self._test_template(RESPONSE, params, self.RESPONSE_XML)
221
222 def test_response_rendering(self):
223 # Verifies that the rendering is OK.
224@@ -109,9 +200,9 @@
225 params.update(IDP_PARAMS)
226 params.update(REQUEST_PARAMS)
227 params.update(RESPONSE_PARAMS)
228- params['ASSERTION'] = ASSERTION_SALESFORCE_XML
229+ params['ASSERTION'] = self.ASSERTION_XML
230 got = xml_render.get_response_xml(params, signed=False)
231- self._test(got, RESPONSE_XML)
232+ self._test(got, self.RESPONSE_XML)
233
234 def test_response_with_signed_assertion(self):
235 # This test also verifies that the template isn't bad.
236@@ -119,9 +210,9 @@
237 params.update(IDP_PARAMS)
238 params.update(REQUEST_PARAMS)
239 params.update(RESPONSE_PARAMS)
240- params['ASSERTION'] = SIGNED_ASSERTION_SALESFORCE_XML
241+ params['ASSERTION'] = self.SIGNED_ASSERTION_XML
242 got = xml_render.get_response_xml(params, signed=False)
243- self._test(got, RESPONSE_WITH_SIGNED_ASSERTION_SALESFORCE_XML)
244+ self._test(got, self.RESPONSE_WITH_SIGNED_ASSERTION_XML)
245
246 def test_signed_response_with_signed_assertion(self):
247 # This test verifies that the response got signed properly.
248@@ -129,6 +220,37 @@
249 params.update(IDP_PARAMS)
250 params.update(REQUEST_PARAMS)
251 params.update(RESPONSE_PARAMS)
252- params['ASSERTION'] = SIGNED_ASSERTION_SALESFORCE_XML
253+ params['ASSERTION'] = self.SIGNED_ASSERTION_XML
254 got = xml_render.get_response_xml(params, signed=True)
255- self._test(got, SIGNED_RESPONSE_WITH_SIGNED_ASSERTION_SALESFORCE_XML)
256+ self._test(got, self.SIGNED_RESPONSE_WITH_SIGNED_ASSERTION_XML)
257+
258+ def test_signed_response_with_signed_assertion_custom_cert(self):
259+ # This test verifies that the response got signed properly with a
260+ # custom cert.
261+ params = {}
262+ params.update(IDP_PARAMS)
263+ params.update(REQUEST_PARAMS)
264+ params.update(RESPONSE_PARAMS)
265+ params['ASSERTION'] = self.SIGNED_ASSERTION_XML
266+ got = xml_render.get_response_xml(
267+ params, signed=True, certificate=CUSTOM_CERT_STRING)
268+ self._test(
269+ got, self.SIGNED_RESPONSE_WITH_SIGNED_ASSERTION_XML_CUSTOM)
270+
271+
272+class TestResponseSalesForce(TestResponse, XmlTest):
273+ ASSERTION_XML = ASSERTION_SALESFORCE_XML
274+ RESPONSE_XML = RESPONSE_SALESFORCE_XML
275+ RESPONSE_WITH_SIGNED_ASSERTION_XML = RESPONSE_WITH_SIGNED_ASSERTION_SALESFORCE_XML
276+ SIGNED_ASSERTION_XML = SIGNED_ASSERTION_SALESFORCE_XML
277+ SIGNED_RESPONSE_WITH_SIGNED_ASSERTION_XML = SIGNED_RESPONSE_WITH_SIGNED_ASSERTION_SALESFORCE_XML
278+ SIGNED_RESPONSE_WITH_SIGNED_ASSERTION_XML_CUSTOM = SIGNED_RESPONSE_WITH_SIGNED_ASSERTION_SALESFORCE_XML_CUSTOM
279+
280+
281+class TestResponseGoogleApps(TestResponse, XmlTest):
282+ ASSERTION_XML = ASSERTION_GOOGLE_APPS_XML
283+ RESPONSE_XML = RESPONSE_GOOGLE_APPS_XML
284+ RESPONSE_WITH_SIGNED_ASSERTION_XML = RESPONSE_WITH_SIGNED_ASSERTION_GOOGLE_APPS_XML
285+ SIGNED_ASSERTION_XML = SIGNED_ASSERTION_GOOGLE_APPS_XML
286+ SIGNED_RESPONSE_WITH_SIGNED_ASSERTION_XML = SIGNED_RESPONSE_WITH_SIGNED_ASSERTION_GOOGLE_APPS_XML
287+ SIGNED_RESPONSE_WITH_SIGNED_ASSERTION_XML_CUSTOM = SIGNED_RESPONSE_WITH_SIGNED_ASSERTION_GOOGLE_APPS_XML_CUSTOM
288
289=== modified file 'idptest/saml2idp/xml_render.py'
290--- idptest/saml2idp/xml_render.py 2012-06-27 20:26:38 +0000
291+++ idptest/saml2idp/xml_render.py 2017-12-11 19:14:27 +0000
292@@ -54,7 +54,7 @@
293 template = string.Template(SUBJECT)
294 params['SUBJECT_STATEMENT'] = template.substitute(params)
295
296-def _get_assertion_xml(template, parameters, signed=False):
297+def _get_assertion_xml(template, parameters, signed=False, certificate=None):
298 # Reset signature.
299 params = {}
300 params.update(parameters)
301@@ -72,7 +72,8 @@
302 return unsigned
303
304 # Sign it.
305- signature_xml = get_signature_xml(unsigned, params['ASSERTION_ID'])
306+ signature_xml = get_signature_xml(
307+ unsigned, params['ASSERTION_ID'], certificate=certificate)
308 params['ASSERTION_SIGNATURE'] = signature_xml
309 signed = template.substitute(params)
310
311@@ -80,13 +81,15 @@
312 logging.debug(signed)
313 return signed
314
315-def get_assertion_googleapps_xml(parameters, signed=False):
316- return _get_assertion_xml(ASSERTION_GOOGLE_APPS, parameters, signed)
317-
318-def get_assertion_salesforce_xml(parameters, signed=False):
319- return _get_assertion_xml(ASSERTION_SALESFORCE, parameters, signed)
320-
321-def get_response_xml(parameters, signed=False):
322+def get_assertion_googleapps_xml(parameters, signed=False, certificate=None):
323+ return _get_assertion_xml(
324+ ASSERTION_GOOGLE_APPS, parameters, signed, certificate=certificate)
325+
326+def get_assertion_salesforce_xml(parameters, signed=False, certificate=None):
327+ return _get_assertion_xml(
328+ ASSERTION_SALESFORCE, parameters, signed, certificate=certificate)
329+
330+def get_response_xml(parameters, signed=False, certificate=None):
331 """
332 Returns XML for response, with signatures, if signed is True.
333 """
334@@ -105,7 +108,8 @@
335 return unsigned
336
337 # Sign it.
338- signature_xml = get_signature_xml(unsigned, params['RESPONSE_ID'])
339+ signature_xml = get_signature_xml(
340+ unsigned, params['RESPONSE_ID'], certificate=certificate)
341 params['RESPONSE_SIGNATURE'] = signature_xml
342 signed = template.substitute(params)
343
344
345=== modified file 'idptest/saml2idp/xml_signing.py'
346--- idptest/saml2idp/xml_signing.py 2012-07-06 20:22:21 +0000
347+++ idptest/saml2idp/xml_signing.py 2017-12-11 19:14:27 +0000
348@@ -13,6 +13,10 @@
349 from xml_templates import SIGNED_INFO, SIGNATURE
350
351 def load_cert_data(certificate_file):
352+ """Backward-compatible alias for load_cert_data_from_file."""
353+ return load_cert_data_from_file(certificate_file)
354+
355+def load_cert_data_from_file(certificate_file):
356 """
357 Returns the certificate data out of the certificate_file.
358 """
359@@ -20,16 +24,31 @@
360 cert_data = ''.join(certificate.as_pem().split('\n')[1:-2])
361 return cert_data
362
363-def get_signature_xml(subject, reference_uri):
364+def load_cert_data_from_string(certificate):
365+ """
366+ Returns the certificate data out of the certificate string.
367+ """
368+ certificate = M2Crypto.X509.load_cert_string(certificate)
369+ cert_data = ''.join(certificate.as_pem().split('\n')[1:-2])
370+ return cert_data
371+
372+def get_signature_xml(subject, reference_uri, certificate=None):
373 """
374 Returns XML Signature for subject.
375+
376+ If certificate is a string, it will be included in the SAML assertion
377+ instead of the globally-defined certificate. This allows, for example,
378+ overriding the certificate on a per-SP basis.
379 """
380 config = saml2idp_metadata.SAML2IDP_CONFIG
381 private_key_file = config['private_key_file']
382 certificate_file = config['certificate_file']
383 logging.debug('get_signature_xml - Begin.')
384 logging.debug('Using private key file: ' + private_key_file)
385- logging.debug('Using certificate file: ' + certificate_file)
386+ if certificate:
387+ logging.debug('Using certificate data: ' + certificate)
388+ else:
389+ logging.debug('Using certificate file: ' + certificate_file)
390 logging.debug('Subject: ' + subject)
391
392 # Hash the subject.
393@@ -53,8 +72,10 @@
394 logging.debug('RSA Signature: ' + rsa_signature)
395
396 # Load the certificate.
397- cert_data = load_cert_data(certificate_file)
398-
399+ if certificate:
400+ cert_data = load_cert_data_from_string(certificate)
401+ else:
402+ cert_data = load_cert_data_from_file(certificate_file)
403 # Put the signed_info and rsa_signature into the XML signature.
404 signed_info_short = signed_info.replace(' xmlns:ds="http://www.w3.org/2000/09/xmldsig#"', '')
405 signature_xml = string.Template(SIGNATURE).substitute({
406
407=== modified file 'requirements.txt'
408--- requirements.txt 2012-05-18 15:55:11 +0000
409+++ requirements.txt 2017-12-11 19:14:27 +0000
410@@ -1,3 +1,3 @@
411-m2crypto>=0.20.1
412-Django>=1.1.1
413+m2crypto==0.25.1
414+Django>=1.1.1,<1.5.0
415 BeautifulSoup>=3.2.0

Subscribers

People subscribed via source and target branches