Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Add support for XML-encryption 1.1 elements #59

Merged
merged 17 commits into from
Dec 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading