Spaces:
No application file
No application file
File size: 4,141 Bytes
d2897cd |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
<?php
namespace Mautic\UserBundle\Security\SAML\Store;
use LightSaml\Credential\KeyHelper;
use LightSaml\Credential\X509Certificate;
use LightSaml\Credential\X509Credential;
use LightSaml\Store\Credential\CredentialStoreInterface;
use Mautic\CoreBundle\Helper\CoreParametersHelper;
use RobRichards\XMLSecLibs\XMLSecurityKey;
class CredentialsStore implements CredentialStoreInterface
{
private ?X509Credential $credentials = null;
public function __construct(
private CoreParametersHelper $coreParametersHelper,
private string $entityId
) {
}
public function getByEntityId($entityId): array
{
// EntityIds do not match
if ($entityId !== $this->entityId) {
return [];
}
if (!$this->credentials) {
$this->delegateAndCreateCredentials();
}
return [$this->credentials];
}
private function delegateAndCreateCredentials(): void
{
// Credentials are required or SP will cause a never ending login loop as it throws an exception
$samlEnabled = (bool) $this->coreParametersHelper->get('saml_idp_metadata');
if (!$samlEnabled || !$certificateContent = $this->coreParametersHelper->get('saml_idp_own_certificate')) {
$this->credentials = $this->createDefaultCredentials();
return;
}
$this->credentials = $this->createOwnCredentials();
}
private function createOwnCredentials(): X509Credential
{
$certificateContent = base64_decode($this->coreParametersHelper->get('saml_idp_own_certificate'));
$privateKeyContent = base64_decode($this->coreParametersHelper->get('saml_idp_own_private_key'));
$keyPassword = (string) $this->coreParametersHelper->get('saml_idp_own_password');
return $this->createCredentials($certificateContent, $privateKeyContent, $keyPassword);
}
private function createDefaultCredentials(): X509Credential
{
$cache_dir = $this->coreParametersHelper->get('cache_path');
$keyPassword = '';
if (!file_exists($cache_dir.'/saml_default.key') || !file_exists($cache_dir.'/saml_default.crt')) {
$dn = ['commonName' => 'Mautic dummy cert'];
// Generate a new private (and public) key pair
$privkey = openssl_pkey_new([
'private_key_bits' => 2048,
'private_key_type' => OPENSSL_KEYTYPE_RSA,
]);
// Generate a certificate signing request
$csr = openssl_csr_new($dn, $privkey, ['digest_alg' => 'sha256']);
// Generate a self-signed cert, valid for 365 days
$x509 = openssl_csr_sign($csr, null, $privkey, $days=365, ['digest_alg' => 'sha256']);
openssl_x509_export_to_file($x509, $cache_dir.'/saml_default.crt');
openssl_pkey_export_to_file($privkey, $cache_dir.'/saml_default.key', $keyPassword);
}
$cert = file_get_contents($cache_dir.'/saml_default.crt');
$privateKey = file_get_contents($cache_dir.'/saml_default.key');
return $this->createCredentials($cert, $privateKey, $keyPassword);
}
private function createCertificate(string $certificateContent): X509Certificate
{
$certificate = new X509Certificate();
$certificate->loadPem($certificateContent);
return $certificate;
}
private function createPrivateKey(string $privateKeyContent, string $keyPassword, X509Certificate $certificate): XMLSecurityKey
{
return KeyHelper::createPrivateKey($privateKeyContent, $keyPassword, false, $certificate->getSignatureAlgorithm());
}
private function createCredentials(string $certificateContent, string $privateKeyContent, string $keyPassword): X509Credential
{
$certificate = $this->createCertificate($certificateContent);
$privateKey = $this->createPrivateKey($privateKeyContent, $keyPassword, $certificate);
$credentials = new X509Credential($certificate, $privateKey);
$credentials->setEntityId($this->entityId);
return $credentials;
}
}
|