0

I need to add a BinarySecurityToken to the WS security header of a SOAP request. I followed https://stackoverflow.com/a/22560639 and the Samples of MicrosoftWSE where FindCertificateByKeyIdentifier is used, however I would like to use the thumbprint so I made this function:

    public static X509SecurityToken GetClientToken(string certThumbprint)
    {
        X509CertificateStore store = X509CertificateStore.CurrentUserStore(X509CertificateStore.MyStore);

        if (store == null)
            throw new ArgumentNullException("store");

        X509SecurityToken token = null;

        if (store.OpenRead())
        {
            Microsoft.Web.Services2.Security.X509.X509CertificateCollection certs =
                store.FindCertificateByHash(Convert.FromBase64String(certThumbprint));
            //store.FindCertificateByKeyIdentifier(Convert.FromBase64String(certThumbprint));

            if (certs.Count > 0)
                token = new X509SecurityToken(((Microsoft.Web.Services2.Security.X509.X509Certificate)certs[0]));
        }

        if (store != null)
            store.Close();

        return token;
    }

However when I try to FindCertificateByHash I don't get the certificate.

In debugging mode I see that after store.OpenRead() the store has my certificate inside, yet under Non-Public members, m_thumbprint=null so I think the store doesn't load the certificates properly, why?

Note that in another scenario I use a System.Security.Cryptography.X509Certificates.X509Certificate2 which is retrieved by doing:

            System.Security.Cryptography.X509Certificates.X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);

            store.Open(OpenFlags.ReadOnly);

            X509Certificate2Collection certCollection =
            store.Certificates.Find(X509FindType.FindByThumbprint, certThumbprint, false);

This works, so I assume the certificate is installed correcly on my machine, still the certificate is not shown when using the X.509 Certificate tool WseCertificate2, maybe this is the reason why visual studio cannot load all the info? Due to this I was not able to get the key identifier to try to use FindCertificateByKeyIdentifier

IAmUser
  • 78
  • 5

1 Answers1

0

You can try something like this.

public static X509Certificate2 TryGetCertificate(string thumbprint, StoreLocation location = StoreLocation.LocalMachine)
{
    using var store = new X509Store(StoreName.My, location);
    store.Open(OpenFlags.ReadOnly);
    thumbprint = Regex.Replace(thumbprint, @"[^\da-fA-F]", string.Empty).ToUpper();

    X509Certificate2Collection certificateCollection = store.Certificates.Find(X509FindType.FindByThumbprint, thumbprint, false);
    if (certificateCollection.Count == 0)
    {
        return null;
    }

    return certificateCollection[0];
}
bartonjs
  • 30,352
  • 2
  • 71
  • 111
Andrii
  • 21
  • 4
  • I have no problems when using a X509Store, in this case everything works fine. The problem is when I use a X509CertificateStore. I need that store to get a X509Certificate to then generate a X509SecurityToken, while a X509Store returns a X509Certificate2 that cannot be used to generate a X509SecurityToken. Also your approach gets the first certificate with empty thumbprint, which is not unique and may not be the one I need – IAmUser Apr 29 '22 at 07:41