Table of Contents

Class SamlSigningKeys

Namespace
Fdyay.IdentityServer.Saml.Xml
Assembly
Fdyay.IdentityServer.Saml.dll

The one place in this assembly that asks what kind of key a certificate holds.

public static class SamlSigningKeys
Inheritance
SamlSigningKeys
Inherited Members

Remarks

Until 0.62.0 there was no such place, and that is the whole shape of the defect it closes: six call sites each wrote certificate.GetRSAPublicKey() and treated null as a failed verification. An EC certificate is not a weaker signature under that code — it is no signature, refused by a verifier that never looked at it, and the refusal is indistinguishable from a forgery.

Centralised rather than fixed six times for the reason this programme keeps re-learning: a rule applied at each site individually is a rule that gets applied to some of them. A seventh call site added later asks this type and inherits both families; one that reached for a key directly would inherit neither.

Encryption is deliberately not here. SamlEncryption stays RSA-only, because the algorithm it implements is RSA-OAEP key transport and elliptic curve has no key transport — the EC equivalent is ECDH key agreement, which is a different EncryptedKey shape, a different algorithm identifier and a different thing to get wrong. Signing and encryption are separate capabilities that happen to both take a certificate, and widening one does not widen the other.

Methods

HashFor(string)

The hash a signature method names, or null when this server does not accept that method.

public static HashAlgorithmName? HashFor(string signatureMethod)

Parameters

signatureMethod string

Returns

HashAlgorithmName?

Remarks

Null is the refusal, and it is the same refusal for "SHA-1" as for a URI nobody recognises: an algorithm this server cannot name is never downgraded to a default, which is how a pinned allow-list differs from a lookup with a fallback.

Matches(string, AsymmetricAlgorithm)

Whether key is the family signatureMethod names.

public static bool Matches(string signatureMethod, AsymmetricAlgorithm key)

Parameters

signatureMethod string
key AsymmetricAlgorithm

Returns

bool

Remarks

The check an allow-list invites somebody to skip, and the reason it is here rather than left to the crypto layer: with one accepted algorithm, "the method is the one we pinned" and "the key is the kind we expect" were the same sentence. With six they are not, and a verifier that checks only the first asks a key to answer for a signature made by the other family — which is an exception at best and an algorithm-confusion bug at worst. A signature is verified by exactly the pair its sender named.

MethodsFor(AsymmetricAlgorithm)

The signature method and digest method this server signs with, given the key it holds.

public static (string SignatureMethod, string DigestMethod) MethodsFor(AsymmetricAlgorithm key)

Parameters

key AsymmetricAlgorithm

Returns

(string SignatureMethod, string DigestMethod)

Remarks

RSA keeps SHA-256 whatever its modulus, because that is what every partner of this server is already configured to verify and a key size is not a reason to change what goes on the wire.

EC takes its hash from the curve — P-256 with SHA-256, P-384 with SHA-384, P-521 with SHA-512 — which is the conventional pairing and the only one where the hash is not the weak link. A curve is chosen by whoever issued the certificate, so this has to answer for all three rather than pick a favourite.

MethodsFor(AsymmetricAlgorithm, string?)

The signature method and digest method to sign with: signatureMethod when a host chose one, else the one the key implies.

public static (string SignatureMethod, string DigestMethod) MethodsFor(AsymmetricAlgorithm key, string? signatureMethod)

Parameters

key AsymmetricAlgorithm
signatureMethod string

Returns

(string SignatureMethod, string DigestMethod)

Remarks

A chosen method has to be one this server accepts and one the key can produce — RSA for an rsa-sha*, EC for an ecdsa-sha* — and is refused otherwise rather than replaced with the default. Its digest is the same strength. Since 0.109.0, for the service provider's OutboundSigningAlgorithm.

PrivateKey(X509Certificate2)

The certificate's private signing key, whichever family it is, or null if it has neither.

public static AsymmetricAlgorithm? PrivateKey(X509Certificate2 certificate)

Parameters

certificate X509Certificate2

Returns

AsymmetricAlgorithm

PublicKey(X509Certificate2)

The certificate's public signing key, whichever family it is, or null if it has neither.

public static AsymmetricAlgorithm? PublicKey(X509Certificate2 certificate)

Parameters

certificate X509Certificate2

Returns

AsymmetricAlgorithm

Remarks

The caller owns the returned key and must dispose it, exactly as the platform accessors require.