Skip to content

Commit

Permalink
Merge pull request #15 from tmilos/signing_options
Browse files Browse the repository at this point in the history
SignatureWriter and SigningOptions #13
  • Loading branch information
tmilos committed Dec 21, 2015
2 parents 20146f9 + c473504 commit 97cf511
Show file tree
Hide file tree
Showing 9 changed files with 751 additions and 62 deletions.
2 changes: 1 addition & 1 deletion .php_cs
Expand Up @@ -16,7 +16,7 @@ EOT;
Symfony\CS\Fixer\Contrib\HeaderCommentFixer::setHeader($header);

return Symfony\CS\Config\Config::create()
->setUsingCache(true)
->setUsingCache(false)
->level(Symfony\CS\FixerInterface::SYMFONY_LEVEL)
->fixers(array('-empty_return', '-phpdoc_no_empty_return', 'header_comment'))
->finder($finder)
Expand Down
132 changes: 132 additions & 0 deletions src/LightSaml/Meta/ParameterBag.php
@@ -0,0 +1,132 @@
<?php

/*
* This file is part of the LightSAML-Core package.
*
* (c) Milos Tomic <tmilos@lightsaml.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

namespace LightSaml\Meta;

class ParameterBag implements \IteratorAggregate, \Countable
{
/**
* Parameter storage.
*
* @var array
*/
protected $parameters;

/**
* @param array $parameters An array of parameters
*/
public function __construct(array $parameters = array())
{
$this->parameters = $parameters;
}

/**
* Returns the parameters.
*
* @return array An array of parameters
*/
public function all()
{
return $this->parameters;
}

/**
* Returns the parameter keys.
*
* @return array An array of parameter keys
*/
public function keys()
{
return array_keys($this->parameters);
}

/**
* Replaces the current parameters by a new set.
*
* @param array $parameters An array of parameters
*/
public function replace(array $parameters = array())
{
$this->parameters = $parameters;
}

/**
* Adds parameters.
*
* @param array $parameters
*/
public function add(array $parameters = array())
{
$this->parameters = array_replace($this->parameters, $parameters);
}

/**
* Returns a parameter by name.
*
* @param string $key
* @param mixed $default
*
* @return mixed
*/
public function get($key, $default = null)
{
return array_key_exists($key, $this->parameters) ? $this->parameters[$key] : $default;
}

/**
* Sets a parameter by name.
*
* @param string $key
* @param mixed $value
*/
public function set($key, $value)
{
$this->parameters[$key] = $value;
}

/**
* Returns true if the parameter is defined.
*
* @param string $key
*
* @return bool true if the parameter exists, false otherwise
*/
public function has($key)
{
return array_key_exists($key, $this->parameters);
}

/**
* Removes a parameter.
*
* @param string $key
*/
public function remove($key)
{
unset($this->parameters[$key]);
}

/**
* @return \ArrayIterator
*/
public function getIterator()
{
return new \ArrayIterator($this->parameters);
}

/**
* @return int
*/
public function count()
{
return count($this->parameters);
}
}
113 changes: 113 additions & 0 deletions src/LightSaml/Meta/SigningOptions.php
@@ -0,0 +1,113 @@
<?php

/*
* This file is part of the LightSAML-Core package.
*
* (c) Milos Tomic <tmilos@lightsaml.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

namespace LightSaml\Meta;

use LightSaml\Credential\X509Certificate;
use RobRichards\XMLSecLibs\XMLSecurityKey;

class SigningOptions
{
const CERTIFICATE_SUBJECT_NAME = 'subjectName';
const CERTIFICATE_ISSUER_SERIAL = 'issuerSerial';

/** @var bool */
private $enabled = true;

/** @var XMLSecurityKey */
private $privateKey;

/** @var X509Certificate */
private $certificate;

/** @var ParameterBag */
private $certificateOptions;

/**
* @param XMLSecurityKey $privateKey
* @param X509Certificate $certificate
*/
public function __construct(XMLSecurityKey $privateKey = null, X509Certificate $certificate = null)
{
$this->enabled = true;
$this->privateKey = $privateKey;
$this->certificate = $certificate;
$this->certificateOptions = new ParameterBag();
}

/**
* @return X509Certificate
*/
public function getCertificate()
{
return $this->certificate;
}

/**
* @param X509Certificate $certificate
*
* @return SigningOptions
*/
public function setCertificate(X509Certificate $certificate = null)
{
$this->certificate = $certificate;

return $this;
}

/**
* @return XMLSecurityKey
*/
public function getPrivateKey()
{
return $this->privateKey;
}

/**
* @param XMLSecurityKey $privateKey
*
* @return SigningOptions
*/
public function setPrivateKey(XMLSecurityKey $privateKey = null)
{
$this->privateKey = $privateKey;

return $this;
}

/**
* @return ParameterBag
*/
public function getCertificateOptions()
{
return $this->certificateOptions;
}

/**
* @return bool
*/
public function isEnabled()
{
return $this->enabled;
}

/**
* @param bool $enabled
*
* @return SigningOptions
*/
public function setEnabled($enabled)
{
$this->enabled = (bool) $enabled;

return $this;
}
}
69 changes: 63 additions & 6 deletions src/LightSaml/Model/XmlDSig/SignatureWriter.php
Expand Up @@ -11,6 +11,7 @@

namespace LightSaml\Model\XmlDSig;

use LightSaml\Meta\SigningOptions;
use LightSaml\Model\Context\DeserializationContext;
use LightSaml\Model\Context\SerializationContext;
use LightSaml\SamlConstants;
Expand All @@ -29,6 +30,35 @@ class SignatureWriter extends Signature
/** @var X509Certificate */
protected $certificate;

/** @var SigningOptions */
protected $signingOptions;

/**
* @param SigningOptions $options
*
* @return SignatureWriter
*/
public static function create(SigningOptions $options)
{
$writer = new self($options->getCertificate(), $options->getPrivateKey());
$writer->signingOptions = $options;

return $writer;
}

/**
* @param X509Certificate $certificate
* @param XMLSecurityKey $xmlSecurityKey
*
* @return SignatureWriter
*/
public static function createByKeyAndCertificate(X509Certificate $certificate, XMLSecurityKey $xmlSecurityKey)
{
$signingOptions = new SigningOptions($xmlSecurityKey, $certificate);

return self::create($signingOptions);
}

/**
* @param X509Certificate|null $certificate
* @param XMLSecurityKey|null $xmlSecurityKey
Expand All @@ -39,6 +69,26 @@ public function __construct(X509Certificate $certificate = null, XMLSecurityKey
$this->xmlSecurityKey = $xmlSecurityKey;
}

/**
* @return SigningOptions
*/
public function getSigningOptions()
{
return $this->signingOptions;
}

/**
* @param SigningOptions $signingOptions
*
* @return SignatureWriter
*/
public function setSigningOptions(SigningOptions $signingOptions)
{
$this->signingOptions = $signingOptions;

return $this;
}

/**
* @return string
*/
Expand Down Expand Up @@ -102,11 +152,13 @@ public function getCertificate()
/**
* @param \DOMNode $parent
* @param SerializationContext $context
*
* @return void
*/
public function serialize(\DOMNode $parent, SerializationContext $context)
{
if ($this->signingOptions && false === $this->signingOptions->isEnabled()) {
return;
}

$objXMLSecDSig = new XMLSecurityDSig();
$objXMLSecDSig->setCanonicalMethod($this->getCanonicalMethod());
$key = $this->getXmlSecurityKey();
Expand All @@ -132,7 +184,14 @@ public function serialize(\DOMNode $parent, SerializationContext $context)
);

$objXMLSecDSig->sign($key);
$objXMLSecDSig->add509Cert($this->getCertificate()->getData(), false, false, array('subjectName' => false));

$objXMLSecDSig->add509Cert(
$this->getCertificate()->getData(),
false,
false,
$this->signingOptions ? $this->signingOptions->getCertificateOptions()->all() : null
);

$firstChild = $parent->hasChildNodes() ? $parent->firstChild : null;
if ($firstChild && $firstChild->localName == 'Issuer') {
// The signature node should come after the issuer node
Expand All @@ -146,11 +205,9 @@ public function serialize(\DOMNode $parent, SerializationContext $context)
* @param DeserializationContext $context
*
* @throws \LogicException
*
* @return void
*/
public function deserialize(\DOMElement $node, DeserializationContext $context)
{
throw new \LogicException('SignatureWriter can not be deserialize');
throw new \LogicException('SignatureWriter can not be deserialized');
}
}

0 comments on commit 97cf511

Please sign in to comment.