/**
  * @param  string $publicKeyFile /full/path/to/the/public/key
  * @return SAML2_Certificate_X509
  */
 public function loadPublicKeyFromFile($publicKeyFile)
 {
     $this->publicKeyLoader->loadCertificateFile($publicKeyFile);
     $keyCollection = $this->publicKeyLoader->getKeys();
     $publicKey = $keyCollection->getOnlyElement();
     // remove it from the collection so we can reuse the publicKeyLoader for consecutive signing
     $keyCollection->remove($publicKey);
     return $publicKey;
 }
 /**
  * @group certificate
  *
  * @test
  */
 public function loading_a_certificate_from_file_creates_a_key()
 {
     $file = dirname(__FILE__) . '/File/example.org.crt';
     $this->keyLoader->loadCertificateFile($file);
     $loadedKeys = $this->keyLoader->getKeys();
     $loadedKey = $loadedKeys->get(0);
     $fileContents = file_get_contents($file);
     preg_match(SAML2_Utilities_Certificate::CERTIFICATE_PATTERN, $fileContents, $matches);
     $expected = preg_replace('~\\s+~', '', $matches[1]);
     $this->assertTrue($this->keyLoader->hasKeys());
     $this->assertCount(1, $loadedKeys);
     $this->assertEquals($expected, $loadedKey['X509Certificate']);
 }
 /**
  * @param Request $request
  * @return AuthnRequest
  * @throws \Exception
  *
  * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  * @SuppressWarnings(PHPMD.NPathComplexity)
  */
 public function processRequest(Request $request)
 {
     if (!$this->entityRepository) {
         throw new LogicException('RedirectBinding::processRequest requires a ServiceProviderRepository to be configured');
     }
     $rawSamlRequest = $request->get(AuthnRequest::PARAMETER_REQUEST);
     if (!$rawSamlRequest) {
         throw new BadRequestHttpException(sprintf('Required GET parameter "%s" is missing', AuthnRequest::PARAMETER_REQUEST));
     }
     if ($request->get(AuthnRequest::PARAMETER_SIGNATURE) && !$request->get(AuthnRequest::PARAMETER_SIGNATURE_ALGORITHM)) {
         throw new BadRequestHttpException(sprintf('The request includes a signature "%s", but does not include the signature algorithm (SigAlg) parameter', $request->get('Signature')));
     }
     $authnRequest = AuthnRequestFactory::createFromHttpRequest($request);
     $currentUri = $this->getFullRequestUri($request);
     if (!$authnRequest->getDestination() === $currentUri) {
         throw new BadRequestHttpException(sprintf('Actual Destination "%s" does no match the AuthnRequest Destination "%s"', $currentUri, $authnRequest->getDestination()));
     }
     if (!$this->entityRepository->hasServiceProvider($authnRequest->getServiceProvider())) {
         throw new UnknownServiceProviderException($authnRequest->getServiceProvider());
     }
     if (!$authnRequest->isSigned()) {
         return $authnRequest;
     }
     if (!$authnRequest->getSignatureAlgorithm()) {
         throw new BadRequestHttpException(sprintf('The SAMLRequest has to be signed with SHA256 algorithm: "%s"', XMLSecurityKey::RSA_SHA256));
     }
     $serviceProvider = $this->entityRepository->getServiceProvider($authnRequest->getServiceProvider());
     if (!$this->signatureVerifier->hasValidSignature($authnRequest, $serviceProvider)) {
         throw new BadRequestHttpException('The SAMLRequest has been signed, but the signature could not be validated');
     }
     return $authnRequest;
 }
 /**
  * @param AuthnRequest    $request
  * @param ServiceProvider $serviceProvider
  * @return bool
  */
 public function hasValidSignature(AuthnRequest $request, ServiceProvider $serviceProvider)
 {
     $this->logger->debug(sprintf('Extracting public keys for ServiceProvider "%s"', $serviceProvider->getEntityId()));
     $keys = $this->keyLoader->extractPublicKeys($serviceProvider);
     $this->logger->debug(sprintf('Found "%d" keys, filtering the keys to get X509 keys', $keys->count()));
     $x509Keys = $keys->filter(function (SAML2_Certificate_Key $key) {
         return $key instanceof SAML2_Certificate_X509;
     });
     $this->logger->debug(sprintf('Found "%d" X509 keys, attempting to use each for signature verification', $x509Keys->count()));
     foreach ($x509Keys as $key) {
         if ($this->isSignedWith($request, $key)) {
             return true;
         }
     }
     $this->logger->debug('Signature could not be verified with any of the found X509 keys.');
     return false;
 }
 /**
  * @param $authnRequest
  */
 private function verifySignature(AuthnRequest $authnRequest)
 {
     if (!$authnRequest->isSigned()) {
         throw new BadRequestHttpException('The SAMLRequest has to be signed');
     }
     if (!$authnRequest->getSignatureAlgorithm()) {
         throw new BadRequestHttpException(sprintf('The SAMLRequest has to be signed with SHA256 algorithm: "%s"', XMLSecurityKey::RSA_SHA256));
     }
     $serviceProvider = $this->entityRepository->getServiceProvider($authnRequest->getServiceProvider());
     if (!$this->signatureVerifier->hasValidSignature($authnRequest, $serviceProvider)) {
         throw new BadRequestHttpException('The SAMLRequest has been signed, but the signature could not be validated');
     }
 }
Beispiel #6
0
 /**
  * @param SAML2_SignedElement             $signedElement
  * @param SAML2_Configuration_CertificateProvider $configuration
  *
  * @return bool
  */
 public function canValidate(SAML2_SignedElement $signedElement, SAML2_Configuration_CertificateProvider $configuration)
 {
     $this->configuredKeys = $this->keyLoader->extractPublicKeys($configuration);
     return !!count($this->configuredKeys);
 }
Beispiel #7
0
 /**
  * @group certificate
  *
  * @test
  * @expectedException SAML2_Certificate_Exception_InvalidCertificateStructureException
  */
 public function loading_an_invalid_certificate_file_from_configuration_throws_exception()
 {
     $file = dirname(__FILE__) . '/File/not_a_key.crt';
     $this->configurationMock->shouldReceive('getKeys')->atMost()->once()->andReturnNull()->shouldReceive('getCertificateData')->atMost()->once()->andReturnNull()->shouldReceive('getCertificateFile')->once()->andReturn($file);
     $loadedKeys = $this->keyLoader->loadKeysFromConfiguration($this->configurationMock);
 }