Inheritance: implements saml2\SignedElement
Beispiel #1
0
 /**
  * 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(Assertion $assertion, XMLSecurityKey $key)
 {
     $xml = $assertion->toXML();
     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);
 }
Beispiel #2
0
 public function validate(Assertion $assertion, Result $result)
 {
     $notBeforeTimestamp = $assertion->getNotBefore();
     if ($notBeforeTimestamp && $notBeforeTimestamp > Temporal::getTime() + 60) {
         $result->addError('Received an assertion that is valid in the future. Check clock synchronization on IdP and SP.');
     }
 }
Beispiel #3
0
 public function validate(Assertion $assertion, Result $result)
 {
     $notValidOnOrAfterTimestamp = $assertion->getNotOnOrAfter();
     if ($notValidOnOrAfterTimestamp && $notValidOnOrAfterTimestamp <= Temporal::getTime() - 60) {
         $result->addError('Received an assertion that has expired. Check clock synchronization on IdP and SP.');
     }
 }
Beispiel #4
0
 public function validate(Assertion $assertion, Result $result)
 {
     $sessionNotOnOrAfterTimestamp = $assertion->getSessionNotOnOrAfter();
     $currentTime = Temporal::getTime();
     if ($sessionNotOnOrAfterTimestamp && $sessionNotOnOrAfterTimestamp <= $currentTime - 60) {
         $result->addError('Received an assertion with a session that has expired. Check clock synchronization on IdP and SP.');
     }
 }
Beispiel #5
0
 public function validate(Assertion $assertion, Result $result)
 {
     $intendedAudiences = $assertion->getValidAudiences();
     if ($intendedAudiences === null) {
         return;
     }
     $entityId = $this->serviceProvider->getEntityId();
     if (!in_array($entityId, $intendedAudiences)) {
         $result->addError(sprintf('The configured Service Provider [%s] is not a valid audience for the assertion. Audiences: [%s]', $entityId, implode('], [', $intendedAudiences)));
     }
 }
 public function transform(Assertion $assertion)
 {
     if (!$this->identityProvider->hasBase64EncodedAttributes()) {
         return $assertion;
     }
     $attributes = $assertion->getAttributes();
     $keys = array_keys($attributes);
     $decoded = array_map(array($this, 'decodeValue'), $attributes);
     $attributes = array_combine($keys, $decoded);
     $assertion->setAttributes($attributes);
 }
 public static function handleLoginRequest(IPerson $Person)
 {
     try {
         $binding = Binding::getCurrentBinding();
     } catch (Exception $e) {
         return static::throwUnauthorizedError('Cannot obtain SAML2 binding');
     }
     $request = $binding->receive();
     // build response
     $response = new Response();
     $response->setInResponseTo($request->getId());
     $response->setRelayState($request->getRelayState());
     $response->setDestination($request->getAssertionConsumerServiceURL());
     // build assertion
     $assertion = new Assertion();
     $assertion->setIssuer(static::$issuer);
     $assertion->setSessionIndex(ContainerSingleton::getInstance()->generateId());
     $assertion->setNotBefore(time() - 30);
     $assertion->setNotOnOrAfter(time() + 300);
     $assertion->setAuthnContext(SAML2_Constants::AC_PASSWORD);
     // build subject confirmation
     $sc = new SubjectConfirmation();
     $sc->Method = SAML2_Constants::CM_BEARER;
     $sc->SubjectConfirmationData = new SubjectConfirmationData();
     $sc->SubjectConfirmationData->NotOnOrAfter = $assertion->getNotOnOrAfter();
     $sc->SubjectConfirmationData->Recipient = $request->getAssertionConsumerServiceURL();
     $sc->SubjectConfirmationData->InResponseTo = $request->getId();
     $assertion->setSubjectConfirmation([$sc]);
     // set NameID
     $assertion->setNameId(['Format' => 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress', 'Value' => $Person->Username . '@' . static::$issuer]);
     // set additional attributes
     $assertion->setAttributes(['User.Email' => [$Person->Email], 'User.Username' => [$Person->Username]]);
     // attach assertion to response
     $response->setAssertions([$assertion]);
     // create signature
     $privateKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, ['type' => 'private']);
     $privateKey->loadKey(static::$privateKey);
     $response->setSignatureKey($privateKey);
     $response->setCertificates([static::$certificate]);
     // prepare response
     $responseXML = $response->toSignedXML();
     $responseString = $responseXML->ownerDocument->saveXML($responseXML);
     // dump response and quit
     #        header('Content-Type: text/xml');
     #        die($responseString);
     // send response
     $responseBinding = new HTTPPost();
     $responseBinding->send($response);
 }
 public function transform(Assertion $assertion)
 {
     if (!$assertion->isNameIdEncrypted()) {
         return $assertion;
     }
     $decryptionKeys = $this->privateKeyLoader->loadDecryptionKeys($this->identityProvider, $this->serviceProvider);
     $blacklistedKeys = $this->identityProvider->getBlacklistedAlgorithms();
     if (is_null($blacklistedKeys)) {
         $blacklistedKeys = $this->serviceProvider->getBlacklistedAlgorithms();
     }
     foreach ($decryptionKeys as $index => $key) {
         try {
             $assertion->decryptNameId($key, $blacklistedKeys);
             $this->logger->debug(sprintf('Decrypted assertion NameId with key "#%d"', $index));
         } catch (\Exception $e) {
             $this->logger->debug(sprintf('Decrypting assertion NameId with key "#%d" failed, "%s" thrown: "%s"', $index, get_class($e), $e->getMessage()));
         }
     }
     if ($assertion->isNameIdEncrypted()) {
         throw new NotDecryptedException('Could not decrypt the assertion NameId with the configured keys, see the debug log for information');
     }
     return $assertion;
 }
 /**
  * Decrypt an assertion.
  *
  * This function takes in a \SAML2\Assertion and decrypts it if it is encrypted.
  * If it is unencrypted, and encryption is enabled in the metadata, an exception
  * will be throws.
  *
  * @param SimpleSAML_Configuration $srcMetadata  The metadata of the sender (IdP).
  * @param SimpleSAML_Configuration $dstMetadata  The metadata of the recipient (SP).
  * @param \SAML2\Assertion|\SAML2\EncryptedAssertion $assertion  The assertion we are decrypting.
  * @return \SAML2\Assertion  The assertion.
  */
 private static function decryptAssertion(SimpleSAML_Configuration $srcMetadata, SimpleSAML_Configuration $dstMetadata, $assertion)
 {
     assert('$assertion instanceof \\SAML2\\Assertion || $assertion instanceof \\SAML2\\EncryptedAssertion');
     if ($assertion instanceof \SAML2\Assertion) {
         $encryptAssertion = $srcMetadata->getBoolean('assertion.encryption', NULL);
         if ($encryptAssertion === NULL) {
             $encryptAssertion = $dstMetadata->getBoolean('assertion.encryption', FALSE);
         }
         if ($encryptAssertion) {
             /* The assertion was unencrypted, but we have encryption enabled. */
             throw new Exception('Received unencrypted assertion, but encryption was enabled.');
         }
         return $assertion;
     }
     try {
         $keys = self::getDecryptionKeys($srcMetadata, $dstMetadata);
     } catch (Exception $e) {
         throw new SimpleSAML_Error_Exception('Error decrypting assertion: ' . $e->getMessage());
     }
     $blacklist = self::getBlacklistedAlgorithms($srcMetadata, $dstMetadata);
     $lastException = NULL;
     foreach ($keys as $i => $key) {
         try {
             $ret = $assertion->getAssertion($key, $blacklist);
             SimpleSAML\Logger::debug('Decryption with key #' . $i . ' succeeded.');
             return $ret;
         } catch (Exception $e) {
             SimpleSAML\Logger::debug('Decryption with key #' . $i . ' failed with exception: ' . $e->getMessage());
             $lastException = $e;
         }
     }
     throw $lastException;
 }
Beispiel #10
0
    public function testHasEncryptedAttributes()
    {
        $document = new \DOMDocument();
        $document->loadXML(<<<XML
    <saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
                    Version="2.0"
                    ID="_93af655219464fb403b34436cfb0c5cb1d9a5502"
                    IssueInstant="1970-01-01T01:33:31Z">
      <saml:Issuer>Provider</saml:Issuer>
      <saml:Subject>
        <saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent">s00000000:123456789</saml:NameID>
        <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
          <saml:SubjectConfirmationData NotOnOrAfter="2011-08-31T08:51:05Z" Recipient="https://sp.example.com/assertion_consumer" InResponseTo="_13603a6565a69297e9809175b052d115965121c8" />
        </saml:SubjectConfirmation>
      </saml:Subject>
      <saml:Conditions NotOnOrAfter="2011-08-31T08:51:05Z" NotBefore="2011-08-31T08:51:05Z">
        <saml:AudienceRestriction>
          <saml:Audience>ServiceProvider</saml:Audience>
        </saml:AudienceRestriction>
      </saml:Conditions>
      <saml:AuthnStatement AuthnInstant="2011-08-31T08:51:05Z" SessionIndex="_93af655219464fb403b34436cfb0c5cb1d9a5502">
        <saml:AuthnContext>
          <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef>
        </saml:AuthnContext>
        <saml:SubjectLocality Address="127.0.0.1"/>
      </saml:AuthnStatement>
      <saml:AttributeStatement>
        <saml:Attribute Name="urn:ServiceID">
          <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">1</saml:AttributeValue>
        </saml:Attribute>
        <saml:Attribute Name="urn:EntityConcernedID">
          <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">1</saml:AttributeValue>
        </saml:Attribute>
        <saml:Attribute Name="urn:EntityConcernedSubID">
          <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">1</saml:AttributeValue>
        </saml:Attribute>
        <saml:EncryptedAttribute xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
          <xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Type="http://www.w3.org/2001/04/xmlenc#Element" Id="_F39625AF68B4FC078CC7582D28D05D9C">
            <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/>
            <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
              <xenc:EncryptedKey>
                <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"/>
                <ds:KeyInfo>
                  <ds:KeyName>62355fbd1f624503c5c9677402ecca00ef1f6277</ds:KeyName>
                </ds:KeyInfo>
                <xenc:CipherData>
                  <xenc:CipherValue>K0mBLxfLziKVUKEAOYe7D6uVSCPy8vyWVh3RecnPES+8QkAhOuRSuE/LQpFr0huI/iCEy9pde1QgjYDLtjHcujKi2xGqW6jkXW/EuKomqWPPA2xYs1fpB1su4aXUOQB6OJ70/oDcOsy834ghFaBWilE8fqyDBUBvW+2IvaMUZabwN/s9mVkWzM3r30tlkhLK7iOrbGAldIHwFU5z7PPR6RO3Y3fIxjHU40OnLsJc3xIqdLH3fXpC0kgi5UspLdq14e5OoXjLoPG3BO3zwOAIJ8XNBWY5uQof6KrKbcvtZSY0fMvPYhYfNjtRFy8y49ovL9fwjCRTDlT5+aHqsCTBrw==</xenc:CipherValue>
                </xenc:CipherData>
              </xenc:EncryptedKey>
            </ds:KeyInfo>
            <xenc:CipherData>
              <xenc:CipherValue>ZzCu6axGgAYZHVf77NX8apZKB/GJDeuV6bFByBS0AIgiXkvDUAmLCpabTAWBM+yz19olA6rryuOfr82ev2bzPNURvm4SYxahvuL4Pibn5wJky0Bl54VqmcU+Aqj0dAvOgqG1y3X4wO9n9bRsTv6921m0eqRAFph8kK8L9hirK1BxYBYj2RyFCoFDPxVZ5wyra3q4qmE4/ELQpFP6mfU8LXb0uoWJUjGUelS2Aa7bZis8zEpwov4CwtlNjltQih4mv7ttCAfYqcQIFzBTB+DAa0+XggxCLcdB3+mQiRcECBfwHHJ7gRmnuBEgeWT3CGKa3Nb7GMXOfuxFKF5pIehWgo3kdNQLalor8RVW6I8P/I8fQ33Fe+NsHVnJ3zwSA//a</xenc:CipherValue>
            </xenc:CipherData>
          </xenc:EncryptedData>
        </saml:EncryptedAttribute>
      </saml:AttributeStatement>
    </saml:Assertion>
XML
);
        $assertion = new Assertion($document->firstChild);
        $this->assertTrue($assertion->hasEncryptedAttributes());
    }
Beispiel #11
0
    /**
     * @group Assertion
     */
    public function testCorrectSignatureMethodCanBeExtracted()
    {
        $document = new \DOMDocument();
        $document->loadXML(<<<XML
    <saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
                    Version="2.0"
                    ID="_93af655219464fb403b34436cfb0c5cb1d9a5502"
                    IssueInstant="1970-01-01T01:33:31Z">
      <saml:Issuer>Provider</saml:Issuer>
      <saml:Subject>
        <saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent">s00000000:123456789</saml:NameID>
        <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
          <saml:SubjectConfirmationData NotOnOrAfter="2011-08-31T08:51:05Z" Recipient="https://sp.example.com/assertion_consumer" InResponseTo="_13603a6565a69297e9809175b052d115965121c8" />
        </saml:SubjectConfirmation>
      </saml:Subject>
      <saml:Conditions NotOnOrAfter="2011-08-31T08:51:05Z" NotBefore="2011-08-31T08:51:05Z">
        <saml:AudienceRestriction>
          <saml:Audience>ServiceProvider</saml:Audience>
        </saml:AudienceRestriction>
      </saml:Conditions>
      <saml:AuthnStatement AuthnInstant="2011-08-31T08:51:05Z" SessionIndex="_93af655219464fb403b34436cfb0c5cb1d9a5502">
        <saml:AuthnContext>
          <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef>
        </saml:AuthnContext>
        <saml:SubjectLocality Address="127.0.0.1"/>
      </saml:AuthnStatement>
      <saml:AttributeStatement>
        <saml:Attribute Name="urn:ServiceID">
          <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">1</saml:AttributeValue>
        </saml:Attribute>
        <saml:Attribute Name="urn:EntityConcernedID">
          <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">1</saml:AttributeValue>
        </saml:Attribute>
        <saml:Attribute Name="urn:EntityConcernedSubID">
          <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">1</saml:AttributeValue>
        </saml:Attribute>
      </saml:AttributeStatement>
    </saml:Assertion>
XML
);
        $privateKey = CertificatesMock::getPrivateKey();
        $unsignedAssertion = new Assertion($document->firstChild);
        $unsignedAssertion->setSignatureKey($privateKey);
        $unsignedAssertion->setCertificates(array(CertificatesMock::PUBLIC_KEY_PEM));
        $signedAssertion = new Assertion($unsignedAssertion->toXML());
        $signatureMethod = $signedAssertion->getSignatureMethod();
        $this->assertEquals($privateKey->getAlgorith(), $signatureMethod);
    }
Beispiel #12
0
    public function testTypedEncryptedAttributeValuesAreParsedCorrectly()
    {
        $xml = <<<XML
            <saml:Assertion
                    xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
                    xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
                    xmlns:xs="http://www.w3.org/2001/XMLSchema"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    Version="2.0"
                    ID="_93af655219464fb403b34436cfb0c5cb1d9a5502"
                    IssueInstant="1970-01-01T01:33:31Z">
      <saml:Issuer>Provider</saml:Issuer>
      <saml:Conditions/>
      <saml:AttributeStatement>
        <saml:Attribute Name="urn:some:string">
            <saml:AttributeValue xsi:type="xs:string">string</saml:AttributeValue>
        </saml:Attribute>
        <saml:Attribute Name="urn:some:integer">
            <saml:AttributeValue xsi:type="xs:integer">42</saml:AttributeValue>
        </saml:Attribute>
      </saml:AttributeStatement>
    </saml:Assertion>
XML;
        $privateKey = CertificatesMock::getPublicKey();
        $assertion = new Assertion(DOMDocumentFactory::fromString($xml)->firstChild);
        $assertion->setEncryptionKey($privateKey);
        $assertion->setEncryptedAttributes(true);
        $encryptedAssertion = $assertion->toXML()->ownerDocument->saveXML();
        $assertionToVerify = new Assertion(DOMDocumentFactory::fromString($encryptedAssertion)->firstChild);
        $this->assertTrue($assertionToVerify->hasEncryptedAttributes());
        $assertionToVerify->decryptAttributes(CertificatesMock::getPrivateKey());
        $attributes = $assertionToVerify->getAttributes();
        $this->assertInternalType('int', $attributes['urn:some:integer'][0]);
        $this->assertInternalType('string', $attributes['urn:some:string'][0]);
        $this->assertXmlStringEqualsXmlString($xml, $assertionToVerify->toXML()->ownerDocument->saveXML());
    }
Beispiel #13
0
    /**
     * Test Exception when trying to get encrypted NameId without
     * decrypting it first.
     */
    public function testRetrieveEncryptedNameIdException()
    {
        $xml = <<<XML
<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
                xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
                ID="_593e33ddf86449ce4d4c22b60ac48e067d98a0b2bf"
                Version="2.0"
                IssueInstant="2010-03-05T13:34:28Z"
>
  <saml:Issuer>testIssuer</saml:Issuer>
  <saml:Subject>
  <saml:EncryptedID>
    <xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" Type="http://www.w3.org/2001/04/xmlenc#Element">
    <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
    <dsig:KeyInfo xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
      <xenc:EncryptedKey><xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
      <xenc:CipherData><xenc:CipherValue>Y78/DDeSkI4qECUPXJM1cWUTaYVglxnqDRpjcqd6zdIR6yWMwIzUCd+fa9KhKutN4kN1i/koSMNmk+c6uOXSi0Xuohth61eU9oIwLl6mKZwThXEQiuphAtMVPXtooKfU1l58+xWiiO2IidYmtb1vCcVD0hZwnVv28kxrMQdQmzw=</xenc:CipherValue></xenc:CipherData>
      </xenc:EncryptedKey>
   </dsig:KeyInfo>
   <xenc:CipherData>
     <xenc:CipherValue>cfQoRV0xf+D5bOQs+8icVEkWX4MRNxl1MhImqO/GwYxjCwj0AH/9O4kr2v4WZ4MC3zHhUjcq4HO70/xrkzQVMN9pBsF2yv9sUuN2rEPd8k/Oj/OA3X4xGNywxoJILioh56OyNkFK/q4WRptvvSQV1vPc0G5y65MZBiR2fy+L+ukBJ8mnzxL7aIIEKRxNa0beKdrrZ2twWH3Uwn3UW5LcSefaY+VHcM/9I4Xb7U5QWxRXzBOEa6v/a3cZ/TmlXYkj</xenc:CipherValue>
   </xenc:CipherData>
   </xenc:EncryptedData>
  </saml:EncryptedID>
  </saml:Subject>
</saml:Assertion>
XML;
        $document = DOMDocumentFactory::fromString($xml);
        $assertion = new Assertion($document->documentElement);
        $this->setExpectedException('Exception', "Attempted to retrieve encrypted NameID without decrypting it first");
        $assertion->getNameID();
    }