Skip to content

Commit

Permalink
Support 'x509cert' and 'privateKey' on signMetadata security settings
Browse files Browse the repository at this point in the history
  • Loading branch information
pitbulk committed Sep 10, 2019
1 parent 7a6f4ba commit dc97088
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 22 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,11 @@ $advancedSettings = array (
False || True (use sp certs) || array (
keyFileName => 'metadata.key',
certFileName => 'metadata.crt'
)
)
|| array (
'x509cert' => '',
'privateKey' => ''
)
*/
'signMetadata' => false,

Expand Down
8 changes: 6 additions & 2 deletions advanced_settings_example.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

$advancedSettings = array (

// Compression settings
// Compression settings
// Handle if the getRequest/getResponse methods will return the Request/Response deflated.
// But if we provide a $deflate boolean parameter to the getRequest or getResponse
// method it will have priority over the compression settings.
Expand Down Expand Up @@ -36,7 +36,11 @@
False || True (use sp certs) || array (
keyFileName => 'metadata.key',
certFileName => 'metadata.crt'
)
)
|| array (
'x509cert' => '',
'privateKey' => ''
)
*/
'signMetadata' => false,

Expand Down
51 changes: 32 additions & 19 deletions lib/Saml2/Settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -608,9 +608,14 @@ public function checkSPSettings($settings)
$errors[] = 'sp_sls_url_invalid';
}

if (isset($security['signMetadata']) && is_array($security['signMetadata']) &&
(!isset($security['signMetadata']['keyFileName']) || !isset($security['signMetadata']['certFileName']))) {
$errors[] = 'sp_signMetadata_invalid';
if (isset($security['signMetadata']) && is_array($security['signMetadata'])) {
if ((!isset($security['signMetadata']['keyFileName'])
|| !isset($security['signMetadata']['certFileName'])) &&
(!isset($security['signMetadata']['privateKey'])
|| !isset($security['signMetadata']['x509cert']))
) {
$errors[] = 'sp_signMetadata_invalid';
}
}

if (((isset($security['authnRequestsSigned']) && $security['authnRequestsSigned'] == true)
Expand Down Expand Up @@ -842,48 +847,35 @@ public function getSPMetadata($alwaysPublishEncryptionCert = false, $validUntil
}

//Sign Metadata
if (isset($this->_security['signMetadata']) && $this->_security['signMetadata'] != false) {
if (isset($this->_security['signMetadata']) && $this->_security['signMetadata'] !== false) {
if ($this->_security['signMetadata'] === true) {
$keyMetadata = $this->getSPkey();
$certMetadata = $cert;

if (!$keyMetadata) {
throw new OneLogin_Saml2_Error(
'SP Private key not found.',
OneLogin_Saml2_Error::PRIVATE_KEY_FILE_NOT_FOUND
);
}

if (!$certMetadata) {
throw new OneLogin_Saml2_Error(
'SP Public cert not found.',
OneLogin_Saml2_Error::PUBLIC_CERT_FILE_NOT_FOUND
);
}
} else {
if (!isset($this->_security['signMetadata']['keyFileName'])
|| !isset($this->_security['signMetadata']['certFileName'])
) {
throw new OneLogin_Saml2_Error(
'Invalid Setting: signMetadata value of the sp is not valid',
OneLogin_Saml2_Error::SETTINGS_INVALID_SYNTAX
);
}
} else if (isset($this->_security['signMetadata']['keyFileName']) &&
isset($this->_security['signMetadata']['certFileName'])) {
$keyFileName = $this->_security['signMetadata']['keyFileName'];
$certFileName = $this->_security['signMetadata']['certFileName'];

$keyMetadataFile = $this->_paths['cert'].$keyFileName;
$certMetadataFile = $this->_paths['cert'].$certFileName;


if (!file_exists($keyMetadataFile)) {
throw new OneLogin_Saml2_Error(
'SP Private key file not found: %s',
OneLogin_Saml2_Error::PRIVATE_KEY_FILE_NOT_FOUND,
array($keyMetadataFile)
);
}

if (!file_exists($certMetadataFile)) {
throw new OneLogin_Saml2_Error(
'SP Public cert file not found: %s',
Expand All @@ -893,6 +885,27 @@ public function getSPMetadata($alwaysPublishEncryptionCert = false, $validUntil
}
$keyMetadata = file_get_contents($keyMetadataFile);
$certMetadata = file_get_contents($certMetadataFile);
} else if (isset($this->_security['signMetadata']['privateKey']) &&
isset($this->_security['signMetadata']['x509cert'])) {
$keyMetadata = OneLogin_Saml2_Utils::formatPrivateKey($this->_security['signMetadata']['privateKey']);
$certMetadata = OneLogin_Saml2_Utils::formatCert($this->_security['signMetadata']['x509cert']);
if (!$keyMetadata) {
throw new OneLogin_Saml2_Error(
'Private key not found.',
OneLogin_Saml2_Error::PRIVATE_KEY_FILE_NOT_FOUND
);
}
if (!$certMetadata) {
throw new OneLogin_Saml2_Error(
'Public cert not found.',
OneLogin_Saml2_Error::PUBLIC_CERT_FILE_NOT_FOUND
);
}
} else {
throw new OneLogin_Saml2_Error(
'Invalid Setting: signMetadata value of the sp is not valid',
OneLogin_Saml2_Error::SETTINGS_INVALID_SYNTAX
);
}

$signatureAlgorithm = $this->_security['signatureAlgorithm'];
Expand Down
30 changes: 30 additions & 0 deletions tests/src/OneLogin/Saml2/SettingsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,16 @@ public function testCheckSettings()
$this->assertContains('organization_not_enought_data', $e->getMessage());
$this->assertContains('contact_type_invalid', $e->getMessage());
}

$settingsInfo['security']['signMetadata'] = ['privateKey' => file_get_contents(TEST_ROOT . '/data/customPath/certs/metadata.key')];
try {
$settings = new OneLogin_Saml2_Settings($settingsInfo);
$this->fail('Error was not raised');
} catch (OneLogin_Saml2_Error $e) {
$this->assertContains('sp_signMetadata_invalid', $e->getMessage());
$this->assertContains('organization_not_enought_data', $e->getMessage());
$this->assertContains('contact_type_invalid', $e->getMessage());
}
}

/**
Expand Down Expand Up @@ -588,6 +598,26 @@ public function testGetSPMetadataSigned()
$this->assertContains('<ds:Reference', $metadata2);
$this->assertContains('<ds:KeyInfo><ds:X509Data><ds:X509Certificate>', $metadata2);

$cert = file_get_contents(TEST_ROOT . '/data/customPath/certs/metadata.crt');
$settingsInfo['security']['signMetadata'] = [
'privateKey' => file_get_contents(TEST_ROOT . '/data/customPath/certs/metadata.key'),
'x509cert' => $cert,
];
$settings3 = new OneLogin_Saml2_Settings($settingsInfo);
$metadata3 = $settings3->getSPMetadata();
$this->assertNotEmpty($metadata3);
$this->assertContains('<md:SPSSODescriptor', $metadata3);
$this->assertContains('entityID="http://stuff.com/endpoints/metadata.php"', $metadata3);
$this->assertContains('AuthnRequestsSigned="false"', $metadata3);
$this->assertContains('WantAssertionsSigned="false"', $metadata3);
$this->assertContains('<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://stuff.com/endpoints/endpoints/acs.php" index="1"/>', $metadata3);
$this->assertContains('<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://stuff.com/endpoints/endpoints/sls.php"/>', $metadata3);
$this->assertContains('<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>', $metadata3);
$this->assertContains('<ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>', $metadata3);
$this->assertContains('<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>', $metadata3);
$this->assertContains('<ds:Reference', $metadata3);
$this->assertContains('<ds:KeyInfo><ds:X509Data><ds:X509Certificate>', $metadata3);
$this->assertContains(OneLogin_Saml2_Utils::formatCert($cert, false), $metadata3);
}

/**
Expand Down

0 comments on commit dc97088

Please sign in to comment.