Skip to content

Commit

Permalink
Feature: Add support for XML-encryption 1.1 elements (#59)
Browse files Browse the repository at this point in the history
* Add xenc-11 schema + namespace const

* Add namespace-abstract

* Add xenc11:KeyDerivationMethod element

* Add xenc11:ConcatKDFParams element

* Add xenc11:DerivedKeyName element

* Add xenc11:MasterKeyName element

* Add xenc11:Specified element

* Add xenc11:Parameters element

* Add xenc11:OtherSource element

* Add xenc11:PRF element

* Add xenc11:KeyLength element

* Add xenc11:IterationCount element

* Exclude empty parameters

* Add xenc11:MGF element

* Add xenc11:Salt element

* Add xenc11:PBKDF2-params element

* Add xenc11:DerivedKey element
  • Loading branch information
tvdijen authored Dec 8, 2024
1 parent 2d37815 commit f489162
Show file tree
Hide file tree
Showing 53 changed files with 2,519 additions and 2 deletions.
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@
"ext-pcre": "*",
"ext-spl": "*",

"simplesamlphp/assert": "^1.5",
"simplesamlphp/xml-common": "^1.20.0"
"simplesamlphp/assert": "^1.6",
"simplesamlphp/xml-common": "^1.21.0"
},
"require-dev": {
"simplesamlphp/simplesamlphp-test-framework": "^1.7"
Expand Down
119 changes: 119 additions & 0 deletions resources/schemas/xenc-schema-11.xsd
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
<?xml version="1.0" encoding="utf-8"?>

<!--
#
# Copyright ©[2011] World Wide Web Consortium
# (Massachusetts Institute of Technology,
# European Research Consortium for Informatics and Mathematics,
# Keio University). All Rights Reserved.
# This work is distributed under the W3C® Software License [1] in the
# hope that it will be useful, but WITHOUT ANY WARRANTY; without even
# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE.
# [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231
#
-->

<!DOCTYPE schema PUBLIC "-//W3C//DTD XMLSchema 200102//EN"
"http://www.w3.org/2001/XMLSchema.dtd"
[
<!ATTLIST schema
xmlns:xenc CDATA #FIXED 'http://www.w3.org/2001/04/xmlenc#'
xmlns:ds CDATA #FIXED 'http://www.w3.org/2000/09/xmldsig#'
xmlns:xenc11 CDATA #FIXED 'http://www.w3.org/2009/xmlenc11#'>
<!ENTITY xenc 'http://www.w3.org/2001/04/xmlenc#'>
<!ENTITY % p ''>
<!ENTITY % s ''>
]>

<schema xmlns='http://www.w3.org/2001/XMLSchema' version='1.0'
xmlns:xenc='http://www.w3.org/2001/04/xmlenc#'
xmlns:xenc11='http://www.w3.org/2009/xmlenc11#'
xmlns:ds='http://www.w3.org/2000/09/xmldsig#'
targetNamespace='http://www.w3.org/2009/xmlenc11#'
elementFormDefault='qualified'>

<import namespace='http://www.w3.org/2000/09/xmldsig#'
schemaLocation='xmldsig-core-schema.xsd'/>

<import namespace='http://www.w3.org/2001/04/xmlenc#'
schemaLocation='xenc-schema.xsd'/>

<element name="ConcatKDFParams" type="xenc11:ConcatKDFParamsType"/>
<complexType name="ConcatKDFParamsType">
<sequence>
<element ref="ds:DigestMethod"/>
</sequence>
<attribute name="AlgorithmID" type="hexBinary"/>
<attribute name="PartyUInfo" type="hexBinary"/>
<attribute name="PartyVInfo" type="hexBinary"/>
<attribute name="SuppPubInfo" type="hexBinary"/>
<attribute name="SuppPrivInfo" type="hexBinary"/>
</complexType>

<element name="DerivedKey" type="xenc11:DerivedKeyType"/>
<complexType name="DerivedKeyType">
<sequence>
<element ref="xenc11:KeyDerivationMethod" minOccurs="0"/>
<element ref="xenc:ReferenceList" minOccurs="0"/>
<element name="DerivedKeyName" type="string" minOccurs="0"/>
<element name="MasterKeyName" type="string" minOccurs="0"/>
</sequence>
<attribute name="Recipient" type="string" use="optional"/>
<attribute name="Id" type="ID" use="optional"/>
<attribute name="Type" type="anyURI" use="optional"/>
</complexType>

<element name="KeyDerivationMethod" type="xenc11:KeyDerivationMethodType"/>
<complexType name="KeyDerivationMethodType">
<sequence>
<any namespace="##any" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
<attribute name="Algorithm" type="anyURI" use="required"/>
</complexType>

<element name="PBKDF2-params" type="xenc11:PBKDF2ParameterType"/>

<complexType name="AlgorithmIdentifierType">
<sequence>
<element name="Parameters" type="anyType" minOccurs="0"/>
</sequence>
<attribute name="Algorithm" type="anyURI" use="required" />
</complexType>

<complexType name="PRFAlgorithmIdentifierType">
<complexContent>
<restriction base="xenc11:AlgorithmIdentifierType">
<attribute name="Algorithm" type="anyURI" use="required" />
</restriction>
</complexContent>
</complexType>

<complexType name="PBKDF2ParameterType">
<sequence>
<element name="Salt">
<complexType>
<choice>
<element name="Specified" type="base64Binary"/>
<element name="OtherSource" type="xenc11:AlgorithmIdentifierType"/>
</choice>
</complexType>
</element>
<element name="IterationCount" type="positiveInteger"/>
<element name="KeyLength" type="positiveInteger"/>
<element name="PRF" type="xenc11:PRFAlgorithmIdentifierType"/>
</sequence>
</complexType>

<element name="MGF" type="xenc11:MGFType"/>
<complexType name="MGFType">
<complexContent>
<restriction base="xenc11:AlgorithmIdentifierType">
<attribute name="Algorithm" type="anyURI" use="required" />
</restriction>
</complexContent>
</complexType>

</schema>


1 change: 1 addition & 0 deletions src/Constants.php
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ class Constants extends \SimpleSAML\XML\Constants
public const XMLDSIG_MANIFEST = 'http://www.w3.org/2000/09/xmldsig#Manifest';

public const NS_XENC = 'http://www.w3.org/2001/04/xmlenc#';
public const NS_XENC11 = 'http://www.w3.org/2009/xmlenc11#';
public const XMLENC_CONTENT = 'http://www.w3.org/2001/04/xmlenc#Content';
public const XMLENC_ELEMENT = 'http://www.w3.org/2001/04/xmlenc#Element';
public const XMLENC_ENCRYPTEDKEY = 'http://www.w3.org/2001/04/xmlenc#EncryptedKey';
Expand Down
70 changes: 70 additions & 0 deletions src/XML/xenc11/AbstractAlgorithmIdentifierType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\XMLSecurity\XML\xenc11;

use DOMElement;
use SimpleSAML\Assert\Assert;
use SimpleSAML\XML\Exception\SchemaViolationException;

/**
* Class representing <xenc11:AlgorithmIdentifierType>.
*
* @package simplesamlphp/xml-security
*/
abstract class AbstractAlgorithmIdentifierType extends AbstractXenc11Element
{
/**
* AlgorithmIdentifierType constructor.
*
* @param string $Algorithm
* @param \SimpleSAML\XMLSecurity\XML\xenc11\Parameters|null $parameters
*/
public function __construct(
protected string $Algorithm,
protected ?Parameters $parameters = null,
) {
Assert::validURI($Algorithm, SchemaViolationException::class);
}


/**
* Get the value of the $Algorithm property.
*
* @return string
*/
public function getAlgorithm(): string
{
return $this->Algorithm;
}


/**
* Get the value of the $parameters property.
*
* @return \SimpleSAML\XMLSecurity\XML\xenc11\Parameters|null
*/
public function getParameters(): ?Parameters
{
return $this->parameters;
}


/**
* @inheritDoc
*/
public function toXML(?DOMElement $parent = null): DOMElement
{
$e = $this->instantiateParentElement($parent);
$e->setAttribute('Algorithm', $this->getAlgorithm());

if ($this->getParameters() !== null) {
if (!$this->getParameters()->isEmptyElement()) {
$this->getParameters()->toXML($e);
}
}

return $e;
}
}
173 changes: 173 additions & 0 deletions src/XML/xenc11/AbstractConcatKDFParamsType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\XMLSecurity\XML\xenc11;

use DOMElement;
use SimpleSAML\Assert\Assert;
use SimpleSAML\XML\Exception\InvalidDOMElementException;
use SimpleSAML\XML\Exception\MissingElementException;
use SimpleSAML\XML\Exception\SchemaViolationException;
use SimpleSAML\XML\Exception\TooManyElementsException;
use SimpleSAML\XMLSecurity\XML\ds\DigestMethod;

use function array_pop;

/**
* Class representing <xenc11:ConcatKDFParamsType>.
*
* @package simplesamlphp/xml-security
*/
abstract class AbstractConcatKDFParamsType extends AbstractXenc11Element
{
/**
* ConcatKDFParams constructor.
*
* @param \SimpleSAML\XMLSecurity\XML\ds\DigestMethod $digestMethod
* @param string|null $AlgorithmID
* @param string|null $PartyUInfo
* @param string|null $PartyVInfo
* @param string|null $SuppPubInfo
* @param string|null $SuppPrivInfo
*/
final public function __construct(
protected DigestMethod $digestMethod,
protected ?string $AlgorithmID = null,
protected ?string $PartyUInfo = null,
protected ?string $PartyVInfo = null,
protected ?string $SuppPubInfo = null,
protected ?string $SuppPrivInfo = null,
) {
Assert::validHexBinary($AlgorithmID, SchemaViolationException::class);
Assert::validHexBinary($PartyUInfo, SchemaViolationException::class);
Assert::validHexBinary($PartyVInfo, SchemaViolationException::class);
Assert::validHexBinary($SuppPubInfo, SchemaViolationException::class);
Assert::validHexBinary($SuppPrivInfo, SchemaViolationException::class);
}


/**
* Get the value of the $digestMethod property.
*
* @return \SimpleSAML\XMLSecurity\XML\ds\DigestMethod
*/
public function getDigestMethod(): DigestMethod
{
return $this->digestMethod;
}


/**
* Get the value of the $AlgorithmID property.
*
* @return string|null
*/
public function getAlgorithmID(): ?string
{
return $this->AlgorithmID;
}


/**
* Get the value of the $PartyUInfo property.
*
* @return string|null
*/
public function getPartyUInfo(): ?string
{
return $this->PartyUInfo;
}


/**
* Get the value of the $PartyVInfo property.
*
* @return string|null
*/
public function getPartyVInfo(): ?string
{
return $this->PartyVInfo;
}


/**
* Get the value of the $SuppPubInfo property.
*
* @return string|null
*/
public function getSuppPubInfo(): ?string
{
return $this->SuppPubInfo;
}


/**
* Get the value of the $SuppPrivInfo property.
*
* @return string|null
*/
public function getSuppPrivInfo(): ?string
{
return $this->SuppPrivInfo;
}


/**
* @inheritDoc
*
* @throws \SimpleSAML\XML\Exception\InvalidDOMElementException
* If the qualified name of the supplied element is wrong
*/
public static function fromXML(DOMElement $xml): static
{
Assert::same($xml->localName, static::getLocalName(), InvalidDOMElementException::class);
Assert::same($xml->namespaceURI, static::getNamespaceURI(), InvalidDOMElementException::class);

$digestMethod = DigestMethod::getChildrenOfClass($xml);
Assert::minCount($digestMethod, 1, MissingElementException::class);
Assert::maxCount($digestMethod, 1, TooManyElementsException::class);

return new static(
array_pop($digestMethod),
self::getOptionalAttribute($xml, 'AlgorithmID', null),
self::getOptionalAttribute($xml, 'PartyUInfo', null),
self::getOptionalAttribute($xml, 'PartyVInfo', null),
self::getOptionalAttribute($xml, 'SuppPubInfo', null),
self::getOptionalAttribute($xml, 'SuppPrivInfo', null),
);
}


/**
* @inheritDoc
*/
public function toXML(?DOMElement $parent = null): DOMElement
{
$e = $this->instantiateParentElement($parent);

if ($this->getAlgorithmID() !== null) {
$e->setAttribute('AlgorithmID', $this->getAlgorithmID());
}

if ($this->getPartyUInfo() !== null) {
$e->setAttribute('PartyUInfo', $this->getPartyUInfo());
}

if ($this->getPartyVInfo() !== null) {
$e->setAttribute('PartyVInfo', $this->getPartyVInfo());
}

if ($this->getSuppPubInfo() !== null) {
$e->setAttribute('SuppPubInfo', $this->getSuppPubInfo());
}

if ($this->getSuppPrivInfo() !== null) {
$e->setAttribute('SuppPrivInfo', $this->getSuppPrivInfo());
}

$this->getDigestMethod()->toXML($e);

return $e;
}
}
Loading

0 comments on commit f489162

Please sign in to comment.