aboutsummaryrefslogtreecommitdiff
path: root/models/openid-php-openid-782224d/contrib/signed_assertions/SAML.php
diff options
context:
space:
mode:
Diffstat (limited to 'models/openid-php-openid-782224d/contrib/signed_assertions/SAML.php')
-rw-r--r--models/openid-php-openid-782224d/contrib/signed_assertions/SAML.php220
1 files changed, 220 insertions, 0 deletions
diff --git a/models/openid-php-openid-782224d/contrib/signed_assertions/SAML.php b/models/openid-php-openid-782224d/contrib/signed_assertions/SAML.php
new file mode 100644
index 000000000..fa6df51f6
--- /dev/null
+++ b/models/openid-php-openid-782224d/contrib/signed_assertions/SAML.php
@@ -0,0 +1,220 @@
+<?php
+/**
+ ** PHP versions 4 and 5
+ **
+ ** LICENSE: See the COPYING file included in this distribution.
+ **
+ ** @package OpenID
+ ** @author Santosh Subramanian <subrasan@cs.sunysb.edu>
+ ** @author Shishir Randive <srandive@cs.sunysb.edu>
+ ** Stony Brook University.
+ ** largely derived from
+ **
+ * Copyright (C) 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ **/
+
+class SAML{
+ private $assertionTemplate=null;
+ /**
+ * Returns a SAML response with various elements filled in.
+ * @param string $authenticatedUser The OpenId of the user
+ * @param string $notBefore The ISO 8601 formatted date before which the
+ response is invalid
+ * @param string $notOnOrAfter The ISO 8601 formatted data after which the
+ response is invalid
+ * @param string $rsadsa 'rsa' if the response will be signed with RSA keys,
+ 'dsa' for DSA keys
+ * @param string $requestID The ID of the request we're responding to
+ * @param string $destination The ACS URL that the response is submitted to
+ * @return string XML SAML response.
+ */
+ function createSamlAssertion($authenticatedUser, $notBefore, $notOnOrAfter, $rsadsa, $acsURI,$attribute,$value,$assertionTemplate)
+ {
+ $samlResponse = $assertionTemplate;
+ $samlResponse = str_replace('USERNAME_STRING', $authenticatedUser, $samlResponse);
+ $samlResponse = str_replace('RESPONSE_ID', $this->samlCreateId(), $samlResponse);
+ $samlResponse = str_replace('ISSUE_INSTANT', $this->samlGetDateTime(time()), $samlResponse);
+ $samlResponse = str_replace('NOT_BEFORE', $this->samlGetDateTime(strtotime($notBefore)), $samlResponse);
+ $samlResponse = str_replace('NOT_ON_OR_AFTER', $this->samlGetDateTime(strtotime($notOnOrAfter)),$samlResponse);
+ $samlResponse = str_replace('ASSERTION_ID',$this->samlCreateId(), $samlResponse);
+ $samlResponse = str_replace('RSADSA', strtolower($rsadsa), $samlResponse);
+ $samlResponse = str_replace('ISSUER_DOMAIN', $acsURI, $samlResponse);
+ $samlResponse = str_replace('ATTRIBUTE_NAME', $attribute, $samlResponse);
+ $samlResponse = str_replace('ATTRIBUTE_VALUE', $value, $samlResponse);
+ return $samlResponse;
+ }
+
+ /**
+ * Signs a SAML response with the given private key, and embeds the public key.
+ * @param string $responseXmlString The unsigned Assertion which will be signed
+ * @param string $priKey Private key to sign the certificate
+ * @param string $cert Public key certificate of signee
+ * @return string Signed Assertion
+ */
+ function signAssertion($responseXmlString,$privKey,$cert)
+ {
+ if (file_exists("/tmp/xml")) {
+ $tempFileDir="/tmp/xml/";
+
+ } else {
+ mkdir("/tmp/xml",0777);
+ $tempFileDir="/tmp/xml/";
+ }
+ $tempName = 'saml-response-' . $this->samlCreateId() . '.xml';
+ $tempFileName=$tempFileDir.$tempName;
+ while (file_exists($tempFileName))
+ $tempFileName = 'saml-response-' . $this->samlCreateId() . '.xml';
+
+ if (!$handle = fopen($tempFileName, 'w')) {
+ return null;
+ }
+ if (fwrite($handle, $responseXmlString) === false) {
+ return null;
+ }
+ fclose($handle);
+ $cmd = 'xmlsec1 --sign --privkey-pem ' . $privKey .
+ ',' . $cert . ' --output ' . $tempFileName .
+ '.out ' . $tempFileName;
+ exec($cmd, $resp);
+ unlink($tempFileName);
+
+ $xmlResult = @file_get_contents($tempFileName . '.out');
+ if (!$xmlResult) {
+ return null;
+ } else {
+ unlink($tempFileName . '.out');
+ return $xmlResult;
+ }
+ }
+
+
+ /**
+ * Verify a saml response with the given public key.
+ * @param string $responseXmlString Response to sign
+ * @param string $rootcert trusted public key certificate
+ * @return string Signed SAML response
+ */
+ function verifyAssertion($responseXmlString,$rootcert)
+ {
+ date_default_timezone_set("UTC");
+ if (file_exists("/tmp/xml")) {
+ $tempFileDir="/tmp/xml/";
+
+ } else {
+ mkdir("/tmp/xml",0777);
+ $tempFileDir="/tmp/xml/";
+ }
+
+ $tempName = 'saml-response-' . $this->samlCreateId() . '.xml';
+ $tempFileName=$tempFileDir.$tempName;
+ while (file_exists($tempFileName))
+ $tempFileName = 'saml-response-' . $this->samlCreateId() . '.xml';
+
+ if (!$handle = fopen($tempFileName, 'w')) {
+ return false;
+ }
+
+ if (fwrite($handle, $responseXmlString) === false) {
+ return false;
+ }
+
+ $p=xml_parser_create();
+ $result=xml_parse_into_struct($p,$responseXmlString,$vals,$index);
+ xml_parser_free($p);
+ $cert_info=$index["X509CERTIFICATE"];
+ $conditions=$index["CONDITIONS"];
+ foreach($cert_info as $key=>$value){
+ file_put_contents($tempFileName.'.cert',$vals[$value]['value']);
+ }
+ $cert=$tempFileName.'.cert';
+ $before=0;
+ $after=0;
+ foreach($conditions as $key=>$value){
+ $before=$vals[$value]['attributes']['NOTBEFORE'];
+ $after=$vals[$value]['attributes']['NOTONORAFTER'];
+ }
+ $before=$this->validSamlDateFormat($before);
+ $after=$this->validSamlDateFormat($after);
+ if(strtotime("now") < $before || strtotime("now") >= $after){
+ unlink($tempFileName);
+ unlink($cert);
+ return false;
+ }
+ fclose($handle);
+ $cmd = 'xmlsec1 --verify --pubkey-cert ' . $cert .'--trusted '.$rootcert. ' '.$tempFileName.'* 2>&1 1>/dev/null';
+ exec($cmd,$resp);
+ if(strcmp($resp[0],"FAIL") == 0){
+ $value = false;
+ }elseif(strcmp($resp[0],"ERROR") == 0){
+ $value = false;
+ }elseif(strcmp($resp[0],"OK") == 0){
+ $value = TRUE;
+ }
+ unlink($tempFileName);
+ unlink($cert);
+ return $value;
+ }
+
+ /**
+ * Creates a 40-character string containing 160-bits of pseudorandomness.
+ * @return string Containing pseudorandomness of 160 bits
+ */
+
+ function samlCreateId()
+ {
+ $rndChars = 'abcdefghijklmnop';
+ $rndId = '';
+ for ($i = 0; $i < 40; $i++ ) {
+ $rndId .= $rndChars[rand(0,strlen($rndChars)-1)];
+ }
+ return $rndId;
+ }
+
+ /**
+ * Returns a unix timestamp in xsd:dateTime format.
+ * @param timestamp int UNIX Timestamp to convert to xsd:dateTime
+ * ISO 8601 format.
+ * @return string
+ */
+ function samlGetDateTime($timestamp)
+ {
+ return gmdate('Y-m-d\TH:i:s\Z', $timestamp);
+ }
+ /**
+ * Attempts to check whether a SAML date is valid. Returns true or false.
+ * @param string $samlDate
+ * @return bool
+ */
+
+ function validSamlDateFormat($samlDate)
+ {
+ if ($samlDate == "") return false;
+ $indexT = strpos($samlDate, 'T');
+ $indexZ = strpos($samlDate, 'Z');
+ if (($indexT != 10) || ($indexZ != 19)) {
+ return false;
+ }
+ $dateString = substr($samlDate, 0, 10);
+ $timeString = substr($samlDate, $indexT + 1, 8);
+ list($year, $month, $day) = explode('-', $dateString);
+ list($hour, $minute, $second) = explode(':', $timeString);
+ $parsedDate = gmmktime($hour, $minute, $second, $month, $day, $year);
+ if (($parsedDate === false) || ($parsedDate == -1)) return false;
+ if (!checkdate($month, $day, $year)) return false;
+ return $parsedDate;
+ }
+
+}
+?>