I have a client that calls an API that signs its response messages. The signature validation setup requires special binding that looks like this:
public class SignatureBinding : Binding
{
public override BindingElementCollection CreateBindingElements()
{
var signingElement = new AsymmetricSecurityBindingElement
{
AllowInsecureTransport = false,
RecipientTokenParameters = new X509SecurityTokenParameters(X509KeyIdentifierClauseType.IssuerSerial, SecurityTokenInclusionMode.Never),
InitiatorTokenParameters = new X509SecurityTokenParameters(X509KeyIdentifierClauseType.IssuerSerial, SecurityTokenInclusionMode.AlwaysToRecipient),
DefaultAlgorithmSuite = SecurityAlgorithmSuite.Basic256,
SecurityHeaderLayout = SecurityHeaderLayout.Strict,
MessageProtectionOrder = MessageProtectionOrder.SignBeforeEncrypt,
MessageSecurityVersion = MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10,
AllowSerializedSigningTokenOnReply = true
};
signingElement.SetKeyDerivation(false);
return new BindingElementCollection
{
signingElement,
new HttpsTransportBindingElement()
};
}
}
And in the ClientCredentials behavior:
public class CredentialsBehavior : ClientCredentials
{
public CredentialsBehavior()
{
base.ServiceCertificate.DefaultCertificate = store.FindBySerialNumber(signatureCertSN);
}
//Code omitted
}
I have confirmed that the above code works fine when run from an ordinary computer. The message is sent, the server crafts a response and signs it, it comes back, the client validates the signature, and all is well.
However, there is a failure when running from the intended server, which cannot access CRL services due to firewalls. The ServiceModel call returns an error when I send the message over the channel. The error pertains to the certificate that contains the public key for validating the signature. The error is:
The X.509 certificate CN=somecert.somedomain.com, OU=CE_Operations, O="MyCompany, Inc.", L=City, S=State, C=US chain building failed. The certificate that was used has a trust chain that cannot be verified. Replace the certificate or change the certificateValidationMode. The revocation function was unable to check revocation because the revocation server was offline.
The server exists in a domain that can't access CRLs so I disabled the check with help from this answer:
ServicePointManager.ServerCertificateValidationCallback += ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;
ServicePointManager.CheckCertificateRevocationList = false;
However, the error persists. I'm guessing that ServerCertificateValidationCallback
only fires for server certificates, and this certificate is different.
How do I convince the service model to allow the use of this certificate without checking the CRL or performing other validation procedures?