From bfee6397247f9c44268c999643d307f8de274aab Mon Sep 17 00:00:00 2001
From: Olav Morken <olav.morken@uninett.no>
Date: Mon, 20 Oct 2008 08:28:54 +0000
Subject: [PATCH] SAMLParser: Extract raw certificate data from metadata

git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@927 44740490-163a-0410-bde0-09ae8108e29a
---
 lib/SimpleSAML/Metadata/SAMLParser.php | 54 +++++++++++++++++++++-----
 1 file changed, 44 insertions(+), 10 deletions(-)

diff --git a/lib/SimpleSAML/Metadata/SAMLParser.php b/lib/SimpleSAML/Metadata/SAMLParser.php
index 502f1f530..5c1ce47a2 100644
--- a/lib/SimpleSAML/Metadata/SAMLParser.php
+++ b/lib/SimpleSAML/Metadata/SAMLParser.php
@@ -408,6 +408,7 @@ class SimpleSAML_Metadata_SAMLParser {
 	 * - 'entityid': The entity id of the entity described in the metadata.
 	 * - 'AssertionConsumerService': String with the url of the assertion consumer service which supports
 	 *   the browser-post binding.
+	 * - 'certData': X509Certificate for entity (if present).
 	 *
 	 * Metadata must be loaded with one of the parse functions before this function can be called.
 	 *
@@ -444,6 +445,21 @@ class SimpleSAML_Metadata_SAMLParser {
 
 		$ret['AssertionConsumerService'] = $acs['location'];
 
+		/* Add certificate data. Only the first valid certificate will be added. */
+		foreach($spd['keys'] as $key) {
+			if($key['type'] !== 'X509Certificate') {
+				continue;
+			}
+
+			$certData = base64_decode($key['X509Certificate']);
+			if($certData === FALSE) {
+				/* Empty/invalid certificate. */
+				continue;
+			}
+
+			$ret['certData'] = str_replace(array("\r", "\n"), '', $key['X509Certificate']);
+			break;
+		}
 
 		/* Add organization info. */
 		$this->addOrganizationInfo($ret);
@@ -459,6 +475,7 @@ class SimpleSAML_Metadata_SAMLParser {
 	 * - 'name': Autogenerated name for this entity. Currently set to the entity id.
 	 * - 'SingleSignOnService': String with the url of the SSO service which supports the redirect binding.
 	 * - 'SingleLogoutService': String with the url where we should send logout requests/responses.
+	 * - 'certData': X509Certificate for entity (if present).
 	 * - 'certFingerprint': Fingerprint of the X509Certificate from the metadata.
 	 *
 	 * Metadata must be loaded with one of the parse functions before this function can be called.
@@ -495,7 +512,7 @@ class SimpleSAML_Metadata_SAMLParser {
 		}
 		$ret['SingleSignOnService'] = $sso['location'];
 
-		/* Find the certificate fingerprints. */
+		/* Add certificate to metadata. Only the first valid certificate will be added. */
 		$ret['certFingerprint'] = array();
 		foreach($idp['keys'] as $key) {
 			if($key['type'] !== 'X509Certificate') {
@@ -504,16 +521,12 @@ class SimpleSAML_Metadata_SAMLParser {
 
 			$certData = base64_decode($key['X509Certificate']);
 			if($certData === FALSE) {
+				/* Empty/invalid certificate. */
 				continue;
-				/*
-				 * At 2008-06-18 we removed the requirement for certificate to be emedded in metadata. Instead
-				 * of throwing an exception which caused the whole parsing to crash, we just skip adding the
-				 * certificate fingerprint for this entity. 
-				 *
-				 * throw new Exception('Unable to parse base64 encoded certificate data.');
-				 */
 			}
 
+			/* Add the certificate data to the metadata. Only the first certificate will be added. */
+			$ret['certData'] = str_replace(array("\r", "\n"), '', $key['X509Certificate']);
 			$ret['certFingerprint'][] = sha1($certData);
 			break;
 		}
@@ -534,6 +547,7 @@ class SimpleSAML_Metadata_SAMLParser {
 	 *   the browser-post binding.
 	 * - 'SingleLogoutService': String with the url where we should send logout requests/responses.
 	 * - 'NameIDFormat': The name ID format this SP expects. This may be unset.
+	 * - 'certData': X509Certificate for entity (if present).
 	 *
 	 * Metadata must be loaded with one of the parse functions before this function can be called.
 	 *
@@ -584,6 +598,22 @@ class SimpleSAML_Metadata_SAMLParser {
 			$ret['NameIDFormat'] = $spd['nameIDFormats'][0];
 		}
 
+		/* Add certificate data. Only the first valid certificate will be added. */
+		foreach($idp['keys'] as $key) {
+			if($key['type'] !== 'X509Certificate') {
+				continue;
+			}
+
+			$certData = base64_decode($key['X509Certificate']);
+			if($certData === FALSE) {
+				/* Empty/invalid certificate. */
+				continue;
+			}
+
+			$ret['certData'] = str_replace(array("\r", "\n"), '', $key['X509Certificate']);
+			break;
+		}
+
 
 		/* Add organization info. */
 		$this->addOrganizationInfo($ret);
@@ -601,6 +631,7 @@ class SimpleSAML_Metadata_SAMLParser {
 	 * - 'SingleLogoutService': String with the url where we should send logout requests(/responses).
 	 * - 'SingleLogoutServiceResponse': String where we should send logout responses (if this is different from
 	 *   the 'SingleLogoutService' endpoint.
+	 * - 'certData': X509Certificate for entity (if present).
 	 * - 'certFingerprint': Fingerprint of the X509Certificate from the metadata.
 	 *
 	 * Metadata must be loaded with one of the parse functions before this function can be called.
@@ -650,7 +681,7 @@ class SimpleSAML_Metadata_SAMLParser {
 		}
 
 
-		/* Find the certificate fingerprint. */
+		/* Add certificate to metadata. Only the first valid certificate will be added. */
 		$ret['certFingerprint'] = array();
 		foreach($idp['keys'] as $key) {
 			if($key['type'] !== 'X509Certificate') {
@@ -659,9 +690,12 @@ class SimpleSAML_Metadata_SAMLParser {
 
 			$certData = base64_decode($key['X509Certificate']);
 			if($certData === FALSE) {
-				throw new Exception('Unable to parse base64 encoded certificate data.');
+				/* Empty/invalid certificate. */
+				continue;
 			}
 
+			/* Add the certificate data to the metadata. Only the first certificate will be added. */
+			$ret['certData'] = str_replace(array("\r", "\n"), '', $key['X509Certificate']);
 			$ret['certFingerprint'][] = sha1($certData);
 			break;
 		}
-- 
GitLab