Skip to content

Commit 24a1700

Browse files
author
Christopher Perrin
committed
Fixed bug with formated cert fingerprints
- Added Test - Fixed typo in README.md
1 parent a99b869 commit 24a1700

File tree

4 files changed

+109
-2
lines changed

4 files changed

+109
-2
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -289,8 +289,8 @@ This is the settings.json file:
289289
* Notice that if you want to validate any SAML Message sent by the HTTP-Redirect binding, you
290290
* will need to provide the whole x509cert.
291291
*/
292-
// "certFingerprint" => "",
293-
// "certFingerprintAlgorithm" => "sha1",
292+
// "certFingerprint": "",
293+
// "certFingerprintAlgorithm": "sha1",
294294
}
295295
}
296296
```

src/onelogin/saml2/response.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,8 @@ def is_valid(self, request_data, request_id=None, raise_exceptions=False):
274274
else:
275275
cert = idp_data.get('x509cert', None)
276276
fingerprint = idp_data.get('certFingerprint', None)
277+
if fingerprint:
278+
fingerprint = OneLogin_Saml2_Utils.format_finger_print(fingerprint)
277279
fingerprintalg = idp_data.get('certFingerprintAlgorithm', None)
278280

279281
# If find a Signature on the Response, validates it checking the original response

tests/settings/settings6.json

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
{
2+
"strict": false,
3+
"debug": false,
4+
"custom_base_path": "../../../tests/data/customPath/",
5+
"sp": {
6+
"entityId": "http://stuff.com/endpoints/metadata.php",
7+
"assertionConsumerService": {
8+
"url": "http://stuff.com/endpoints/endpoints/acs.php"
9+
},
10+
"singleLogoutService": {
11+
"url": "http://stuff.com/endpoints/endpoints/sls.php"
12+
},
13+
"NameIDFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
14+
},
15+
"idp": {
16+
"entityId": "http://idp.example.com/",
17+
"singleSignOnService": {
18+
"url": "http://idp.example.com/SSOService.php"
19+
},
20+
"singleLogoutService": {
21+
"url": "http://idp.example.com/SingleLogoutService.php"
22+
},
23+
"certFingerprint": "AF:E7:1C:28:EF:74:0B:C8:74:25:BE:13:A2:26:3D:37:97:1D:A1:F9",
24+
"certFingerprintAlgorithm": "sha1"
25+
},
26+
"security": {
27+
"authnRequestsSigned": true,
28+
"wantAssertionsSigned": false,
29+
"signMetadata": false
30+
},
31+
"contactPerson": {
32+
"technical": {
33+
"givenName": "technical_name",
34+
"emailAddress": "technical@example.com"
35+
},
36+
"support": {
37+
"givenName": "support_name",
38+
"emailAddress": "support@example.com"
39+
}
40+
},
41+
"organization": {
42+
"en-US": {
43+
"name": "sp_test",
44+
"displayname": "SP test",
45+
"url": "http://sp.example.com"
46+
}
47+
}
48+
}

tests/src/OneLogin/saml2_tests/response_test.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1238,6 +1238,63 @@ def testIsValidSign(self):
12381238
# Modified message
12391239
self.assertFalse(response_9.is_valid(self.get_request_data()))
12401240

1241+
def testIsValidSignFingerprint(self):
1242+
"""
1243+
Tests the is_valid method of the OneLogin_Saml2_Response
1244+
Case valid sign response / sign assertion / both signed
1245+
1246+
Strict mode will always fail due destination problem, if we manipulate
1247+
it the sign will fail.
1248+
"""
1249+
settings = OneLogin_Saml2_Settings(self.loadSettingsJSON("settings6.json"))
1250+
1251+
# expired cert
1252+
xml = self.file_contents(join(self.data_path, 'responses', 'signed_message_response.xml.base64'))
1253+
response = OneLogin_Saml2_Response(settings, xml)
1254+
self.assertTrue(response.is_valid(self.get_request_data()))
1255+
1256+
xml_2 = self.file_contents(join(self.data_path, 'responses', 'signed_assertion_response.xml.base64'))
1257+
response_2 = OneLogin_Saml2_Response(settings, xml_2)
1258+
self.assertTrue(response_2.is_valid(self.get_request_data()))
1259+
1260+
xml_3 = self.file_contents(join(self.data_path, 'responses', 'double_signed_response.xml.base64'))
1261+
response_3 = OneLogin_Saml2_Response(settings, xml_3)
1262+
self.assertTrue(response_3.is_valid(self.get_request_data()))
1263+
1264+
settings_2 = OneLogin_Saml2_Settings(self.loadSettingsJSON('settings2.json'))
1265+
xml_4 = self.file_contents(join(self.data_path, 'responses', 'signed_message_response2.xml.base64'))
1266+
response_4 = OneLogin_Saml2_Response(settings_2, xml_4)
1267+
self.assertTrue(response_4.is_valid(self.get_request_data()))
1268+
1269+
xml_5 = self.file_contents(join(self.data_path, 'responses', 'signed_assertion_response2.xml.base64'))
1270+
response_5 = OneLogin_Saml2_Response(settings_2, xml_5)
1271+
self.assertTrue(response_5.is_valid(self.get_request_data()))
1272+
1273+
xml_6 = self.file_contents(join(self.data_path, 'responses', 'double_signed_response2.xml.base64'))
1274+
response_6 = OneLogin_Saml2_Response(settings_2, xml_6)
1275+
self.assertTrue(response_6.is_valid(self.get_request_data()))
1276+
1277+
dom = parseString(b64decode(xml_4))
1278+
dom.firstChild.firstChild.firstChild.nodeValue = 'https://example.com/other-idp'
1279+
xml_7 = OneLogin_Saml2_Utils.b64encode(dom.toxml())
1280+
response_7 = OneLogin_Saml2_Response(settings, xml_7)
1281+
# Modified message
1282+
self.assertFalse(response_7.is_valid(self.get_request_data()))
1283+
1284+
dom_2 = parseString(OneLogin_Saml2_Utils.b64decode(xml_5))
1285+
dom_2.firstChild.firstChild.firstChild.nodeValue = 'https://example.com/other-idp'
1286+
xml_8 = OneLogin_Saml2_Utils.b64encode(dom_2.toxml())
1287+
response_8 = OneLogin_Saml2_Response(settings, xml_8)
1288+
# Modified message
1289+
self.assertFalse(response_8.is_valid(self.get_request_data()))
1290+
1291+
dom_3 = parseString(OneLogin_Saml2_Utils.b64decode(xml_6))
1292+
dom_3.firstChild.firstChild.firstChild.nodeValue = 'https://example.com/other-idp'
1293+
xml_9 = OneLogin_Saml2_Utils.b64encode(dom_3.toxml())
1294+
response_9 = OneLogin_Saml2_Response(settings, xml_9)
1295+
# Modified message
1296+
self.assertFalse(response_9.is_valid(self.get_request_data()))
1297+
12411298
def testIsValidSignWithEmptyReferenceURI(self):
12421299
settings_info = self.loadSettingsJSON()
12431300
del settings_info['idp']['x509cert']

0 commit comments

Comments
 (0)