generateSessionKey() public method

public generateSessionKey ( )
 /**
  * Set the assertion.
  *
  * @param SAML2_Assertion $assertion The assertion.
  * @param XMLSecurityKey  $key       The key we should use to encrypt the assertion.
  * @throws Exception
  */
 public function setAssertion(SAML2_Assertion $assertion, XMLSecurityKey $key)
 {
     $xml = $assertion->toXML();
     SAML2_Utils::getContainer()->debugMessage($xml, 'encrypt');
     $enc = new XMLSecEnc();
     $enc->setNode($xml);
     $enc->type = XMLSecEnc::Element;
     switch ($key->type) {
         case XMLSecurityKey::TRIPLEDES_CBC:
         case XMLSecurityKey::AES128_CBC:
         case XMLSecurityKey::AES192_CBC:
         case XMLSecurityKey::AES256_CBC:
             $symmetricKey = $key;
             break;
         case XMLSecurityKey::RSA_1_5:
         case XMLSecurityKey::RSA_OAEP_MGF1P:
             $symmetricKey = new XMLSecurityKey(XMLSecurityKey::AES128_CBC);
             $symmetricKey->generateSessionKey();
             $enc->encryptKey($key, $symmetricKey);
             break;
         default:
             throw new Exception('Unknown key type for encryption: ' . $key->type);
     }
     $this->encryptedData = $enc->encryptNode($symmetricKey);
 }
Example #2
0
 public function addUserToken($userName, $password = NULL, $passwordDigest = FALSE)
 {
     if ($passwordDigest && empty($password)) {
         throw new Exception("Cannot calculate the digest without a password");
     }
     $security = $this->locateSecurityHeader();
     $token = $this->SOAPDoc->createElementNS(WSSESoap::WSUNS, WSSESoap::WSUPFX . ':UsernameToken');
     $security->insertBefore($token, $security->firstChild);
     $username = $this->SOAPDoc->createElementNS(WSSESoap::WSUNS, WSSESoap::WSUPFX . ':Username', $userName);
     $token->appendChild($username);
     /* Generate nonce - create a 256 bit session key to be used */
     $objKey = new XMLSecurityKey(XMLSecurityKey::AES256_CBC);
     $nonce = $objKey->generateSessionKey();
     unset($objKey);
     $createdate = gmdate("Y-m-d\\TH:i:s") . 'Z';
     if ($password) {
         $passType = '#PasswordText';
         if ($passwordDigest) {
             $password = base64_encode(sha1($nonce . $createdate . $password, true));
             $passType = '#PasswordDigest';
         }
         $passwordNode = $this->SOAPDoc->createElementNS(WSSESoap::WSUNS, WSSESoap::WSUPFX . ':Password', $userName);
         $token->appendChild($passwordNode);
         $passwordNode->setAttribute('Type', $passType);
     }
     $nonceNode = $this->SOAPDoc->createElementNS(WSSESoap::WSUNS, WSSESoap::WSUPFX . ':Nonce', base64_encode($nonce));
     $token->appendChild($nonceNode);
     $created = $this->SOAPDoc->createElementNS(WSSESoap::WSUNS, WSSESoap::WSUPFX . ':Created', $createdate);
     $token->appendChild($created);
     return $token;
 }
Example #3
0
 public function __doRequest($request, $location, $saction, $version)
 {
     $doc = new DOMDocument('1.0');
     $doc->loadXML($request);
     $objWSSE = new WSSESoap($doc);
     /* add Timestamp with no expiration timestamp */
     $objWSSE->addTimestamp();
     /* create new XMLSec Key using AES256_CBC and type is private key */
     $objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'private'));
     /* load the private key from file - last arg is bool if key in file (true) or is string (false) */
     $objKey->loadKey(PRIVATE_KEY, true);
     /* Sign the message - also signs appropiate WS-Security items */
     $options = array("insertBefore" => false);
     $objWSSE->signSoapDoc($objKey, $options);
     /* Add certificate (BinarySecurityToken) to the message */
     $token = $objWSSE->addBinaryToken(file_get_contents(CERT_FILE));
     /* Attach pointer to Signature */
     $objWSSE->attachTokentoSig($token);
     $objKey = new XMLSecurityKey(XMLSecurityKey::AES256_CBC);
     $objKey->generateSessionKey();
     $siteKey = new XMLSecurityKey(XMLSecurityKey::RSA_OAEP_MGF1P, array('type' => 'public'));
     $siteKey->loadKey(SERVICE_CERT, true, true);
     $options = array("KeyInfo" => array("X509SubjectKeyIdentifier" => true));
     $objWSSE->encryptSoapDoc($siteKey, $objKey, $options);
     $retVal = parent::__doRequest($objWSSE->saveXML(), $location, $saction, $version);
     $doc = new DOMDocument();
     $doc->loadXML($retVal);
     $options = array("keys" => array("private" => array("key" => PRIVATE_KEY, "isFile" => true, "isCert" => false)));
     $objWSSE->decryptSoapDoc($doc, $options);
     return $doc->saveXML();
 }
 function __doRequest($request, $location, $saction, $version)
 {
     $doc = new DOMDocument('1.0');
     $doc->loadXML($request);
     $objWSSE = new WSSESoap($doc);
     $objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'private'));
     $objKey->loadKey(PRIVATE_KEY, TRUE);
     $options = array("insertBefore" => TRUE);
     $objWSSE->signSoapDoc($objKey, $options);
     $objWSSE->addIssuerSerial(CERT_FILE);
     $objKey = new XMLSecurityKey(XMLSecurityKey::AES256_CBC);
     $objKey->generateSessionKey();
     #está wea está rara, no pasa el wsdl y cambía el puerto o.O
     $location = "https://201.238.207.130:7200/WSWebpayTransaction/cxf/WSWebpayService?wsdl";
     #die($location);
     #die(CERT_FILE." ".PRIVATE_KEY);
     $retVal = parent::__doRequest($objWSSE->saveXML(), $location, $saction, $version);
     $doc = new DOMDocument();
     $doc->loadXML($retVal);
     return $doc->saveXML();
     /*
     if ($this->useSSL){ 
             $locationparts = parse_url($location); 
             $location = 'https://'; 
             if(isset($locationparts['host']))  $location .= $locationparts['host']; 
             if(isset($locationparts['port']))  $location .= ':'.$locationparts['port']; 
             if(isset($locationparts['path']))  $location .= $locationparts['path']; 
             if(isset($locationparts['query'])) $location .= '?'.$locationparts['query']; 
     }
     
     $doc = new DOMDocument('1.0'); 
     $doc->loadXML($request); 
     
     $objWSSE = new WSSESoap($doc); 
     $objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1,array('type' => 'private')); 
     $objKey->loadKey(PRIVATE_KEY, TRUE);
     
     $options = array("insertBefore" => TRUE); 
     
     $objWSSE->signSoapDoc($objKey, $options); 
     $objWSSE->addIssuerSerial(CERT_FILE);
     
     $objKey = new XMLSecurityKey(XMLSecurityKey::AES256_CBC); 
     $objKey->generateSessionKey(); 
     
     $retVal = parent::__doRequest($objWSSE->saveXML(), $location, $saction, $version); 
     
     $doc = new DOMDocument(); 
     $doc->loadXML($retVal); 
     return $doc->saveXML(); 
     */
 }
 public function testGenerateSessionKeyParity()
 {
     /* Run the test several times, to increase the chance of detecting an error. */
     for ($t = 0; $t < 16; $t++) {
         $key = new XMLSecurityKey(XMLSecurityKey::TRIPLEDES_CBC);
         $k = $key->generateSessionKey();
         for ($i = 0; $i < strlen($k); $i++) {
             $byte = ord($k[$i]);
             $parity = 0;
             while ($byte !== 0) {
                 $parity ^= $byte & 1;
                 $byte >>= 1;
             }
             $this->assertEquals(1, $parity);
         }
     }
 }
Example #6
0
 /**
  * Add an EncryptedAttribute Statement-node to the assertion.
  *
  * @param DOMElement $root  The assertion element we should add the Encrypted Attribute Statement to.
  */
 private function addEncryptedAttributeStatement(DOMElement $root)
 {
     if ($this->requiredEncAttributes == FALSE) {
         return;
     }
     $document = $root->ownerDocument;
     $attributeStatement = $document->createElementNS(SAML2_Const::NS_SAML, 'saml:AttributeStatement');
     $root->appendChild($attributeStatement);
     foreach ($this->attributes as $name => $values) {
         $document2 = new DOMDocument();
         $attribute = $document2->createElementNS(SAML2_Const::NS_SAML, 'saml:Attribute');
         $attribute->setAttribute('Name', $name);
         $document2->appendChild($attribute);
         if ($this->nameFormat !== SAML2_Const::NAMEFORMAT_UNSPECIFIED) {
             $attribute->setAttribute('NameFormat', $this->nameFormat);
         }
         foreach ($values as $value) {
             if (is_string($value)) {
                 $type = 'xs:string';
             } elseif (is_int($value)) {
                 $type = 'xs:integer';
             } else {
                 $type = NULL;
             }
             $attributeValue = $document2->createElementNS(SAML2_Const::NS_SAML, 'saml:AttributeValue');
             $attribute->appendChild($attributeValue);
             if ($type !== NULL) {
                 $attributeValue->setAttributeNS(SAML2_Const::NS_XSI, 'xsi:type', $type);
             }
             if ($value instanceof DOMNodeList) {
                 for ($i = 0; $i < $value->length; $i++) {
                     $node = $document2->importNode($value->item($i), TRUE);
                     $attributeValue->appendChild($node);
                 }
             } else {
                 $attributeValue->appendChild($document2->createTextNode($value));
             }
         }
         /*Once the attribute nodes are built, the are encrypted*/
         $EncAssert = new XMLSecEnc();
         $EncAssert->setNode($document2->documentElement);
         $EncAssert->type = 'http://www.w3.org/2001/04/xmlenc#Element';
         /*
          * Attributes are encrypted with a session key and this one with
          * $EncryptionKey
          */
         $symmetricKey = new XMLSecurityKey(XMLSecurityKey::AES256_CBC);
         $symmetricKey->generateSessionKey();
         $EncAssert->encryptKey($this->encryptionKey, $symmetricKey);
         $EncrNode = $EncAssert->encryptNode($symmetricKey);
         $EncAttribute = $document->createElementNS(SAML2_Const::NS_SAML, 'saml:EncryptedAttribute');
         $attributeStatement->appendChild($EncAttribute);
         $n = $document->importNode($EncrNode, true);
         $EncAttribute->appendChild($n);
     }
 }
Example #7
0
 /**
  * Generates a nameID.
  *
  * @param string $value  fingerprint
  * @param string $spnq   SP Name Qualifier
  * @param string $format SP Format
  * @param string $cert   IdP Public cert to encrypt the nameID
  *
  * @return string $nameIDElement DOMElement | XMLSec nameID
  */
 public static function generateNameId($value, $spnq, $format, $cert = null)
 {
     $doc = new DOMDocument();
     $nameId = $doc->createElement('saml:NameID');
     $nameId->setAttribute('SPNameQualifier', $spnq);
     $nameId->setAttribute('Format', $format);
     $nameId->appendChild($doc->createTextNode($value));
     $doc->appendChild($nameId);
     if (!empty($cert)) {
         $seckey = new XMLSecurityKey(XMLSecurityKey::RSA_1_5, array('type' => 'public'));
         $seckey->loadKey($cert);
         $enc = new XMLSecEnc();
         $enc->setNode($nameId);
         $enc->type = XMLSecEnc::Element;
         $symmetricKey = new XMLSecurityKey(XMLSecurityKey::AES128_CBC);
         $symmetricKey->generateSessionKey();
         $enc->encryptKey($seckey, $symmetricKey);
         $encryptedData = $enc->encryptNode($symmetricKey);
         $newdoc = new DOMDocument();
         $encryptedID = $newdoc->createElement('saml:EncryptedID');
         $newdoc->appendChild($encryptedID);
         $encryptedID->appendChild($encryptedID->ownerDocument->importNode($encryptedData, true));
         return $newdoc->saveXML($encryptedID);
     } else {
         return $doc->saveXML($nameId);
     }
 }
Example #8
0
 /**
  * Encrypt the NameID in the LogoutRequest.
  *
  * @param XMLSecurityKey $key The encryption key.
  */
 public function encryptNameId(XMLSecurityKey $key)
 {
     /* First create a XML representation of the NameID. */
     $doc = new DOMDocument();
     $root = $doc->createElement('root');
     $doc->appendChild($root);
     SAML2_Utils::addNameId($root, $this->nameId);
     $nameId = $root->firstChild;
     SAML2_Utils::getContainer()->debugMessage($nameId, 'encrypt');
     /* Encrypt the NameID. */
     $enc = new XMLSecEnc();
     $enc->setNode($nameId);
     $enc->type = XMLSecEnc::Element;
     $symmetricKey = new XMLSecurityKey(XMLSecurityKey::AES128_CBC);
     $symmetricKey->generateSessionKey();
     $enc->encryptKey($key, $symmetricKey);
     $this->encryptedNameId = $enc->encryptNode($symmetricKey);
     $this->nameId = NULL;
 }
Example #9
0
 /**
  * @throws \Exception
  */
 public function testEncryptNoReplace()
 {
     $dom = new \DOMDocument();
     $dom->load(dirname(__FILE__) . '/../basic-doc.xml');
     $origData = $dom->saveXML();
     $objKey = new XMLSecurityKey(XMLSecurityKey::AES256_CBC);
     $objKey->generateSessionKey();
     $siteKey = new XMLSecurityKey(XMLSecurityKey::RSA_OAEP_MGF1P, array('type' => 'public'));
     $siteKey->loadKey(dirname(__FILE__) . '/../mycert.pem', true, true);
     $enc = new XMLSecEnc();
     $enc->setNode($dom->documentElement);
     $enc->encryptKey($siteKey, $objKey);
     $enc->type = XMLSecEnc::Element;
     $encNode = $enc->encryptNode($objKey, false);
     $newData = $dom->saveXML();
     $this->assertEquals($origData, $newData, "Original data was modified");
     $this->assertFalse($encNode->namespaceURI !== XMLSecEnc::XMLENCNS || $encNode->localName !== 'EncryptedData', "Encrypted node wasn't a <xenc:EncryptedData>-element");
 }
Example #10
0
 public function addUserToken($userName, $password = NULL, $passwordDigest = FALSE)
 {
     if ($passwordDigest && empty($password)) {
         throw new Exception("Cannot calculate the digest without a password");
     }
     $security = $this->locateSecurityHeader();
     $token = $this->soapDoc->createElementNS(WSSESoap::WSSENS, WSSESoap::WSSEPFX . ':UsernameToken');
     //$token->setAttributeNS(WSSESoap::WSUNS, WSSESoap::WSUPFX.':Id', XMLSecurityDSig::generate_GUID());
     $token->setAttribute(WSSESoap::XMLNS . ":" . WSSESoap::WSSEPFX, WSSESoap::WSSENS);
     $token->setAttribute("xmlns:wsu", WSSESoap::WSUNS);
     $security->insertBefore($token, $security->firstChild);
     $username = $this->soapDoc->createElementNS(WSSESoap::WSSENS, WSSESoap::WSSEPFX . ':Username', $userName);
     $username->setAttribute(WSSESoap::XMLNS . ":" . WSSESoap::WSSEPFX, WSSESoap::WSSENS);
     $token->appendChild($username);
     /* Generate nonce - create a 256 bit session key to be used */
     $objKey = new XMLSecurityKey(XMLSecurityKey::AES256_CBC);
     $nonce = $objKey->generateSessionKey();
     unset($objKey);
     $createdate = gmdate("Y-m-d\\TH:i:s") . 'Z';
     if ($password) {
         $passType = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText';
         if ($passwordDigest) {
             $password = base64_encode(sha1($nonce . $createdate . $password, true));
             $passType = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest';
         }
         $passwordNode = $this->soapDoc->createElementNS(WSSESoap::WSSENS, WSSESoap::WSSEPFX . ':Password', $password);
         $token->appendChild($passwordNode);
         $passwordNode->setAttribute('xmlns:wsse', WSSESoap::WSSENS);
         $passwordNode->setAttribute('Type', $passType);
     }
     $nonceNode = $this->soapDoc->createElementNS(WSSESoap::WSSENS, WSSESoap::WSSEPFX . ':Nonce', base64_encode($nonce));
     $token->appendChild($nonceNode);
     $created = $this->soapDoc->createElementNS(WSSESoap::WSUNS, WSSESoap::WSUPFX . ':Created', $createdate);
     $token->appendChild($created);
 }
 public function sendResponse($response, $idmetaindex, $spentityid, $relayState = null)
 {
     $idpmd = $this->metadata->getMetaData($idmetaindex, 'saml20-idp-hosted');
     $spmd = $this->metadata->getMetaData($spentityid, 'saml20-sp-remote');
     $destination = $spmd['AssertionConsumerService'];
     if (empty($idpmd['privatekey'])) {
         throw new Exception('SAML: RSA private key not configured. This is required to sign the authentication response.');
     }
     if (empty($idpmd['certificate'])) {
         throw new Exception('SAML: X.509 certificate not configured. This is required to attach to the authentication response.');
     }
     // XMLDSig. Sign the complete request with the key stored in cert/server.pem
     $objXMLSecDSig = new XMLSecurityDSig();
     $objXMLSecDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N);
     try {
         $responsedom = new DOMDocument();
         $responsedom->loadXML(str_replace("\n", "", str_replace("\r", "", $response)));
     } catch (Exception $e) {
         throw new Exception("foo");
     }
     $responseroot = $responsedom->getElementsByTagName('Response')->item(0);
     $firstassertionroot = $responsedom->getElementsByTagName('Assertion')->item(0);
     /* Determine what we should sign - either the Response element or the Assertion. The default
      * is to sign the Assertion, but that can be overridden by the 'signresponse' option in the
      * SP metadata or 'saml20.signresponse' in the global configuration.
      */
     $signResponse = FALSE;
     if (array_key_exists('signresponse', $spmd) && $spmd['signresponse'] !== NULL) {
         $signResponse = $spmd['signresponse'];
         if (!is_bool($signResponse)) {
             throw new Exception('Expected the \'signresponse\' option in the metadata of the' . ' SP \'' . $spmd['entityid'] . '\' to be a boolean value.');
         }
     } else {
         $signResponse = $this->configuration->getBoolean('saml20.signresponse', FALSE);
     }
     if ($signResponse) {
         // Sign the response.
         $objXMLSecDSig->addReferenceList(array($responseroot), XMLSecurityDSig::SHA1, array('http://www.w3.org/2000/09/xmldsig#enveloped-signature', XMLSecurityDSig::EXC_C14N), array('id_name' => 'ID'));
     } else {
         // Sign the assertion.
         $objXMLSecDSig->addReferenceList(array($firstassertionroot), XMLSecurityDSig::SHA1, array('http://www.w3.org/2000/09/xmldsig#enveloped-signature', XMLSecurityDSig::EXC_C14N), array('id_name' => 'ID'));
     }
     $objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'private'));
     if (array_key_exists('privatekey_pass', $idpmd)) {
         $objKey->passphrase = $idpmd['privatekey_pass'];
     }
     $objKey->loadKey($idpmd['privatekey']);
     $objXMLSecDSig->sign($objKey);
     $objXMLSecDSig->add509Cert($idpmd['certificate'], true);
     if ($signResponse) {
         $objXMLSecDSig->appendSignature($responseroot, true, false);
     } else {
         $objXMLSecDSig->appendSignature($firstassertionroot, true, true);
     }
     if (isset($spmd['assertion.encryption']) && $spmd['assertion.encryption']) {
         $encryptedassertion = $responsedom->createElement("saml:EncryptedAssertion");
         $encryptedassertion->setAttribute("xmlns:saml", "urn:oasis:names:tc:SAML:2.0:assertion");
         $firstassertionroot->parentNode->replaceChild($encryptedassertion, $firstassertionroot);
         $encryptedassertion->appendChild($firstassertionroot);
         $enc = new XMLSecEnc();
         $enc->setNode($firstassertionroot);
         $enc->type = XMLSecEnc::Element;
         $objKey = new XMLSecurityKey(XMLSecurityKey::AES128_CBC);
         if (isset($spmd['sharedkey'])) {
             $objKey->loadkey($spmd['sharedkey']);
         } else {
             $key = $objKey->generateSessionKey();
             $objKey->loadKey($key);
             if (empty($spmd['certificate'])) {
                 throw new Exception("Public key for encrypting assertion needed, but not specified for saml20-sp-remote id: " . $spentityid);
             }
             $keyKey = new XMLSecurityKey(XMLSecurityKey::RSA_1_5, array('type' => 'public'));
             $keyKey->loadKey($spmd['certificate']);
             $enc->encryptKey($keyKey, $objKey);
         }
         $encNode = $enc->encryptNode($objKey);
         # replacing the unencrypted node
     }
     $response = $responsedom->saveXML();
     SimpleSAML_Utilities::validateXMLDocument($response, 'saml20');
     # openssl genrsa -des3 -out server.key 1024
     # openssl rsa -in server.key -out server.pem
     # openssl req -new -key server.key -out server.csr
     # openssl x509 -req -days 60 -in server.csr -signkey server.key -out server.crt
     if ($this->configuration->getValue('debug')) {
         $p = new SimpleSAML_XHTML_Template($this->configuration, 'post-debug.php');
         $p->data['header'] = 'SAML Response Debug-mode';
         $p->data['RelayStateName'] = 'RelayState';
         $p->data['RelayState'] = $relayState;
         $p->data['destination'] = $destination;
         $p->data['response'] = str_replace("\n", "", base64_encode($response));
         $p->data['responseHTML'] = htmlentities($responsedom->saveHTML());
         $p->show();
     } else {
         $p = new SimpleSAML_XHTML_Template($this->configuration, 'post.php');
         $p->data['RelayStateName'] = 'RelayState';
         $p->data['RelayState'] = $relayState;
         $p->data['destination'] = $destination;
         $p->data['response'] = base64_encode($response);
         $p->show();
     }
 }