Andrey Popov

Hello!

I have following security header in soap message:

<oTongue Tiedecurity s:mustUnderstand="1" xmlnsSurprise="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlnsTongue Tied="http://schemas.xmlsoap.org/soap/envelope/">

- <u:Timestamp u:Id="_0" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<u:Created>2007-10-04T11:09:07.541Z</u:Created>
<u:Expires>2007-10-04T11:14:07.541Z</u:Expires>
</u:Timestamp>
<o:BinarySecurityToken u:Id="uuid-fcbe59e7-29b0-478d-9f49-d7a9f6db0c62-1" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">MIIGnTCCBIWgAwIBAgIKHWJrrwABAAAADjANBgkqhkiG9w0BAQUFADCBoDEnMCUGCSqGSIb3DQEJARYYY2VydGFkbWluQGFyY2FkaWEuc3BiLnJ1MQswCQYDVQQGEwJSVTEWMBQGA1UECBMNU3QuUGV0ZXJzYnVyZzEWMBQGA1UEBxMNU3QuUGV0ZXJzYnVyZzEVMBMGA1UEChMMQXJjYWRpYSwgSW5jMQwwCgYDVQQLEwNJVFMxEzARBgNVBAMTCkFyY2FkaWEgQ045k.......</o:BinarySecurityToken>
- <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
- <SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
- <Reference URI="#_0">
- <Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>cMvS06oVXCFY02ba3wa7LNEbX/w=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>bDbuV3ZQx2IB+PMCgXq4kJ8NVBMfTW8JATBuAdq/vG/WZRfY16rCXmTa8RbSR00fT6DOw0sURbaxNtpSaG/gV2LMIJcXa3Bbr6sqrd3WF7xNEhid6jDZBAjzaHspzAGnmQcLV5lwOJd6xCVSsoI3TtqwPdocTs9HyqsW/J6CwZB2IYFaDKAHR5/44einIcy7vXhKf5aoPUMpPz03u8c3Z+9L4kRQSqzSVKPaPDapYfZsULSSuenf0xnoZ5FxseuyfopWfkpBQVDJ81zWhbVPGD6RMsWlj/5pn07ZgLDYiWtdqr3EvyMu4Ituz9cti07w+lM9HVTHLQS30LtHHDMe9g==</SignatureValue>
- <KeyInfo>
- <oTongue TiedecurityTokenReference>
<o:Reference ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" URI="#uuid-fcbe59e7-29b0-478d-9f49-d7a9f6db0c62-1" />
</oTongue TiedecurityTokenReference>
</KeyInfo>
</Signature>
</oTongue Tiedecurity>

I use basicHttp Binding, security mode="TransportWithMessageCredential", message clientCredentialType="Certificate".

Can I get Client Certificate Information (Public Key or Thumbprint or certificate serial number) from this header

How can I do this




Re: Windows Communication Foundation (Indigo) BinarySecurityToken header

Allan-Nielsen

Hi I would look in the OperationContext.ServiceSecurityContext.AuthorizationContext.ClaimSets and then look for ClaimTypes.ThumbPrint

what are you trying todo here validate the cert , there are lots of knobs you can turn on here, like a setting up a custom x509CertificateValidator or use the ServiceAuthorizationManager which would check the ClaimSet mentioned...

/Allan





Re: Windows Communication Foundation (Indigo) BinarySecurityToken header

Andrey Popov

Thank you for reply!

I use MS BizTalk Server as WCF server, I have not access to OperationContext. I only can read Security Header. I need to authorize users with Client Certificate. Can I get information about Client Certifate (public key) from Security Header

Is BinarySecurityToken value contain Public Key in base64 encoding






Re: Windows Communication Foundation (Indigo) BinarySecurityToken header

Allan-Nielsen

BTS , didn't see that.

for the glory details ws-security 1.0 you should read up on the spec..

not sure but I think that o:Reference ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" URI="#uuid-fcbe59e7-29b0-478d-9f49-d7a9f6db0c62-1" />

the URI points to elements with the issuer and serial number can be found.

sorry perhaps someone else can chip in here.

/Allan





Re: Windows Communication Foundation (Indigo) BinarySecurityToken header

Andrey Popov

I solve this problem!

I use:

SignedXml class from System.Security.Cryptography.Xml

X509Store, X509CertificateCollection classes from System.Security.Cryptography, System.Security.Cryptography.X509Certificates

classes from System.Security.Cryptography.X509Certificates

1) Fisrt step, prepare class SignedXml for work with SOAP header:

public class SignedXmlEx : SignedXml

{

public SignedXmlEx(): base()

{}

public SignedXmlEx(XmlDocument document): base(document)

{}

public override XmlElement GetIdElement(XmlDocument document, string idValue)

{

XmlNode node = document.SelectSingleNode("//*[local-name()='Timestamp' and namespace-uri()='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd']");

return (XmlElement)node;

//return base.GetIdElement(document, idValue);

}

}

2) Second step, create function for validating Sognature in SOPA Header:

public static Boolean ValidateSOAPSignature(XmlDocument securitySOAPHeader, X509Certificate2 certificate, Boolean verifySignatureOnly)

{

SignedXmlEx signedXml = new SignedXmlEx(securitySOAPHeader);

XmlNodeList nodeList = securitySOAPHeader.GetElementsByTagName("Signature");

if ((nodeList != null) && (nodeList.Count > 0))

{

XmlElement signature = (XmlElement)nodeList[0];

signedXml.LoadXml((XmlElement)nodeList[0]);

return signedXml.CheckSignature(certificate, verifySignatureOnly);

}

return false;

}

//securitySOAPHeader - header, wich need to varify or get client certtificate information;

//certificate - X509 certificate, wich uses for verify signature;

3) Third step, look over all certificate from Windows store and varify it:

public static X509CertificateCollection CertificateCollection(StoreName storeName, StoreLocation storeLocation)

{

X509Store store = new X509Store(storeName, storeLocation);

store.Open(OpenFlags.ReadOnly);

return store.Certificates;

}

public static X509Certificate2 FindCertificateBySignature(XmlDocument securitySOAPHeader)

{

List<X509CertificateCollection> certCollections = new List<X509CertificateCollection>();

certCollections.Add( CertificateCollection(StoreName.TrustedPeople, StoreLocation.LocalMachine) );

certCollections.Add( CertificateCollection(StoreName.My, StoreLocation.LocalMachine) );

certCollections.Add( CertificateCollection(StoreName.TrustedPeople, StoreLocation.CurrentUser) );

certCollections.Add( CertificateCollection(StoreName.My, StoreLocation.CurrentUser) );

certCollections.Add( CertificateCollection(StoreName.Root, StoreLocation.LocalMachine) );

certCollections.Add( CertificateCollection(StoreName.Root, StoreLocation.CurrentUser) );

foreach (X509CertificateCollection certs in certCollections)

{

foreach (X509Certificate2 cert in certs)

{

if (ValidateSOAPSignature(securitySOAPHeader, cert, true))

{

return cert;

}

}

}

return null;

}

//Returned cert contains information about Client Certificate, if cert==null, certificate not found on local machine!!!