Skip to content

Commit 4124e4e

Browse files
committed
Use a local copy of Message:addSign that uses the xmlsecurity-library for signing
1 parent 21daf7e commit 4124e4e

File tree

1 file changed

+63
-7
lines changed

1 file changed

+63
-7
lines changed

src/Controller/AttributeServer.php

Lines changed: 63 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,10 @@
99
use SimpleSAML\{Configuration, Error, Logger};
1010
use SimpleSAML\HTTP\RunnableResponse;
1111
use SimpleSAML\Metadata\MetaDataStorageHandler;
12-
use SimpleSAML\Module\saml\Message;;
1312
use SimpleSAML\SAML2\Binding;
1413
use SimpleSAML\SAML2\Binding\HTTPPost;
1514
use SimpleSAML\SAML2\Constants as C;
16-
use SimpleSAML\SAML2\Utils;
15+
use SimpleSAML\SAML2\Utils as SAML2_Utils;
1716
use SimpleSAML\SAML2\XML\saml\{
1817
Assertion,
1918
Attribute,
@@ -30,7 +29,13 @@
3029
SubjectConfirmationData,
3130
};
3231
use SimpleSAML\SAML2\XML\samlp\{AttributeQuery, Response};
32+
use SimpleSAML\Utils;
3333
use SimpleSAML\XML\Utils\Random;
34+
use SimpleSAML\XMLSecurity\Alg\Signature\SignatureAlgorithmFactory;
35+
use SimpleSAML\XMLSecurity\CryptoEncoding\PEM;
36+
use SimpleSAML\XMLSecurity\Key\PrivateKey;
37+
use SimpleSAML\XMLSecurity\XML\ds\{KeyInfo, X509Certificate, X509Data};
38+
use SimpleSAML\XMLSecurity\XML\SignableElementInterface;
3439
use Symfony\Bridge\PsrHttpMessage\Factory\{HttpFoundationFactory, PsrHttpFactory};
3540
use Symfony\Component\HttpFoundation\Request;
3641

@@ -159,7 +164,7 @@ public function main(/** @scrutinizer ignore-unused */ Request $request): Runnab
159164
}
160165

161166
// $returnAttributes contains the attributes we should return. Send them
162-
$clock = Utils::getContainer()->getClock();
167+
$clock = SAML2_Utils::getContainer()->getClock();
163168

164169
$assertion = new Assertion(
165170
issuer: new Issuer($idpEntityId),
@@ -192,8 +197,7 @@ public function main(/** @scrutinizer ignore-unused */ Request $request): Runnab
192197
],
193198
);
194199

195-
// TODO: Fix signing; should use xml-security lib
196-
Message::addSign($idpMetadata, $spMetadata, $assertion);
200+
self::addSign($idpMetadata, $spMetadata, $assertion);
197201

198202
$response = new Response(
199203
status: new Status(
@@ -208,8 +212,7 @@ public function main(/** @scrutinizer ignore-unused */ Request $request): Runnab
208212
assertions: [$assertion],
209213
);
210214

211-
// TODO: Fix signing; should use xml-security lib
212-
Message::addSign($idpMetadata, $spMetadata, $response);
215+
self::addSign($idpMetadata, $spMetadata, $response);
213216

214217
$httpPost = new HTTPPost();
215218
$httpPost->setRelayState($binding->getRelayState());
@@ -238,4 +241,57 @@ private function filterAttributeValues(array $reqValues, array $values): array
238241

239242
return $result;
240243
}
244+
245+
246+
/**
247+
* Add signature key and sender certificate to an element (Message or Assertion).
248+
*
249+
* @param \SimpleSAML\Configuration $srcMetadata The metadata of the sender.
250+
* @param \SimpleSAML\Configuration $dstMetadata The metadata of the recipient.
251+
* @param \SimpleSAML\XMLSecurity\XML\SignableElementInterface $element The element we should add the data to.
252+
*/
253+
private static function addSign(
254+
Configuration $srcMetadata,
255+
Configuration $dstMetadata,
256+
SignableElementInterface &$element,
257+
): void {
258+
$dstPrivateKey = $dstMetadata->getOptionalString('signature.privatekey', null);
259+
$cryptoUtils = new Utils\Crypto();
260+
261+
if ($dstPrivateKey !== null) {
262+
/** @var array $keyArray */
263+
$keyArray = $cryptoUtils->loadPrivateKey($dstMetadata, true, 'signature.');
264+
$certArray = $cryptoUtils->loadPublicKey($dstMetadata, false, 'signature.');
265+
} else {
266+
/** @var array $keyArray */
267+
$keyArray = $cryptoUtils->loadPrivateKey($srcMetadata, true);
268+
$certArray = $cryptoUtils->loadPublicKey($srcMetadata, false);
269+
}
270+
271+
$algo = $dstMetadata->getOptionalString('signature.algorithm', null);
272+
if ($algo === null) {
273+
$algo = $srcMetadata->getOptionalString('signature.algorithm', C::SIG_RSA_SHA256);
274+
}
275+
276+
$privateKey = new PrivateKey(PEM::fromString($keyArray['PEM']));
277+
278+
$keyInfo = null;
279+
if ($certArray !== null) {
280+
$certificate = new X509Certificate(PEM::fromString($keyArray['PEM']));
281+
$keyInfo = new KeyInfo([
282+
new X509Data(
283+
[
284+
new X509Certificate($certArray['PEM']),
285+
],
286+
),
287+
]);
288+
}
289+
290+
$signer = (new SignatureAlgorithmFactory())->getAlgorithm(
291+
$algo,
292+
$privateKey,
293+
);
294+
295+
$element->sign($signer, C::C14N_EXCLUSIVE_WITHOUT_COMMENTS, $keyInfo);
296+
}
241297
}

0 commit comments

Comments
 (0)