Skip to content
Snippets Groups Projects
Commit e86e40f4 authored by Jaime Pérez's avatar Jaime Pérez
Browse files

metadata: Add support for SHA2 digests when signing self metadata.

The hash algorithm to use to calculate signature digests for self metadata was not configurable. Add the 'metadata.sign.algorithm' configuration option to fix that.

This resolves #411.
parent 4056af12
No related branches found
No related tags found
No related merge requests found
......@@ -93,6 +93,13 @@ SimpleSAMLphp supports signing of the metadata it generates. Metadata signing is
- `metadata.sign.privatekey`: Name of the file with the private key which should be used to sign the metadata. This file must exist in in the `cert` directory.
- `metadata.sign.privatekey_pass`: Passphrase which should be used to open the private key. This parameter is optional, and should be left out if the private key is unencrypted.
- `metadata.sign.certificate`: Name of the file with the certificate which matches the private key. This file must exist in in the `cert` directory.
- `metadata.sign.algorithm`: The algorithm to use when signing metadata for this entity. Defaults to RSA-SHA1. Possible values:
* `http://www.w3.org/2000/09/xmldsig#rsa-sha1`
*Note*: the use of SHA1 is **deprecated** and will be disallowed in the future.
* `http://www.w3.org/2001/04/xmldsig-more#rsa-sha256`
* `http://www.w3.org/2001/04/xmldsig-more#rsa-sha384`
* `http://www.w3.org/2001/04/xmldsig-more#rsa-sha512`
These options can be configured globally in the `config/config.php`-file, or per SP/IdP by adding them to the hosted metadata for the SP/IdP. The configuration in the metadata for the SP/IdP takes precedence over the global configuration.
......
......@@ -142,6 +142,70 @@ class SimpleSAML_Metadata_Signer
}
/**
* Determine the signature and digest algorithms to use when signing metadata.
*
* This method will look for the 'metadata.sign.algorithm' key in the $entityMetadata array, or look for such
* a configuration option in the $config object.
*
* @param SimpleSAML_Configuration $config The global configuration.
* @param array $entityMetadata An array containing the metadata related to this entity.
* @param string $type A string describing the type of entity. E.g. 'SAML 2 IdP' or 'Shib 1.3 SP'.
*
* @return array An array with two keys, 'algorithm' and 'digest', corresponding to the signature and digest
* algorithms to use, respectively.
*
* @throws \SimpleSAML\Error\CriticalConfigurationError
*
* @todo change to SHA256 by default.
*/
private static function getMetadataSigningAlgorithm($config, $entityMetadata, $type)
{
// configure the algorithm to use
if (array_key_exists('metadata.sign.algorithm', $entityMetadata)) {
if (!is_string($entityMetadata['metadata.sign.algorithm'])) {
throw new \SimpleSAML\Error\CriticalConfigurationError(
"Invalid value for the 'metadata.sign.algorithm' configuration option for the ".$type.
"'".$entityMetadata['entityid']."'. This option has restricted values"
);
}
$alg = $entityMetadata['metadata.sign.algorithm'];
} else {
$alg = $config->getString('metadata.sign.algorithm', XMLSecurityKey::RSA_SHA1);
}
$supported_algs = array(
XMLSecurityKey::RSA_SHA1,
XMLSecurityKey::RSA_SHA256,
XMLSecurityKey::RSA_SHA384,
XMLSecurityKey::RSA_SHA512,
);
if (!in_array($alg, $supported_algs)) {
throw new \SimpleSAML\Error\CriticalConfigurationError("Unknown signature algorithm '$alg'");
}
switch ($alg) {
case XMLSecurityKey::RSA_SHA256:
$digest = XMLSecurityDSig::SHA256;
break;
case XMLSecurityKey::RSA_SHA384:
$digest = XMLSecurityDSig::SHA384;
break;
case XMLSecurityKey::RSA_SHA512:
$digest = XMLSecurityDSig::SHA512;
break;
default:
$digest = XMLSecurityDSig::SHA1;
}
return array(
'algorithm' => $alg,
'digest' => $digest,
);
}
/**
* Signs the given metadata if metadata signing is enabled.
*
......@@ -186,8 +250,10 @@ class SimpleSAML_Metadata_Signer
throw new Exception('Error parsing self-generated metadata.');
}
$signature_cf = self::getMetadataSigningAlgorithm($config, $entityMetadata, $type);
// load the private key
$objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'private'));
$objKey = new XMLSecurityKey($signature_cf['algorithm'], array('type' => 'private'));
if (array_key_exists('privatekey_pass', $keyCertFiles)) {
$objKey->passphrase = $keyCertFiles['privatekey_pass'];
}
......@@ -207,7 +273,7 @@ class SimpleSAML_Metadata_Signer
$objXMLSecDSig->addReferenceList(
array($rootNode),
XMLSecurityDSig::SHA1,
$signature_cf['digest'],
array('http://www.w3.org/2000/09/xmldsig#enveloped-signature', XMLSecurityDSig::EXC_C14N),
array('id_name' => 'ID')
);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment