EldoS | Feel safer!

Software components for data protection, secure storage and transfer

Sign Soap Message with Smart Card / WS-Security

Also by EldoS: CallbackRegistry
A component to monitor and control Windows registry access and create virtual registry keys.
#32046
Posted: 02/02/2015 05:35:48
by Engin K. (Basic support level)
Joined: 02/02/2015
Posts: 6

I need to call Web service with WS-Security using C#. I need to sign soap message by using smart card and HSM.

You can see my example soap message on attachment that i have to generate just like this.
Is it possible to generate this by using XMLBlackbox? I looked your sample XMLBlackbox -> SecureSOAP but it doesn't generate exactly what i want. I also need to add TimeStamp on SoapHeader and add <ec:InclusiveNamespaces PrefixList="web... to transforms.

So am i looking right sample (SecureSOAP)? Or is there any other codes taht can generate my sample soap message?

Any help would be much appreciated. Thanks...


[ Download ]
#32048
Posted: 02/02/2015 06:07:45
by Dmytro Bogatskyy (EldoS Corp.)

Thank you for contacting us.

Quote

Is it possible to generate this by using XMLBlackbox? I looked your sample XMLBlackbox -> SecureSOAP but it doesn't generate exactly what i want.

Yes, it is possible, everything could be customized.
Quote
I also need to add TimeStamp on SoapHeader

Please use the following code to add a timestamp:
Code
int k = SOAPMessage.AddSecurityHeader();
TElXMLWSUTimestamp Timestamp = new TElXMLWSUTimestamp();
SOAPMessage.get_SecurityHeaders(k).AddToken(Timestamp);
Timestamp.CreatedUTC =...
Timestamp.Expires =...
Timestamp.ID = ...

Then, to place a signature in the newly created security header, you would need to set SecurityHeader property before signing:
Code
handler.SecurityHeader = SOAPMessage.get_SecurityHeaders(k);

Quote

add <ec:InclusiveNamespaces PrefixList="web... to transforms

By default AddReference() method of TElXMLWSSSignatureHandler class creates a reference with exclusive canonicalization transform. To modify existent transform you would need to use a following code:
Code
TElXMLC14NTransform C14N = handler.get_References(index).TransformChain.get_Transforms(0) as TElXMLC14NTransform;
C14N.InclusiveNamespacesPrefixList = "web";


Add the code above before a following line in SecureSOAP sample:
Code
((TElXMLWSSSignatureHandler)handler).Sign(...);


Quote

I need to call Web service with WS-Security using C#.
So am i looking right sample (SecureSOAP)?

You can also check SOAPClient sample, it allows to create a SOAP message (body contents) from scratch, then you can sign the SOAP message (to sign a message you can reuse a code from SecureSOAP sample) and then send it.
#32053
Posted: 02/03/2015 01:39:15
by Engin K. (Basic support level)
Joined: 02/02/2015
Posts: 6

Thank you for an answer.
I did what you told and also i add reference for Timestamp. Then I set reference's DigestMethod to SHA-256 as
Code
handler.References.get_Reference(0).DigestMethod = SBXMLSec.Unit.xdmSHA256;
TElXMLC14NTransform C14N_Body = handler.References.get_Reference(0).TransformChain.get_Transforms(0) as TElXMLC14NTransform;
C14N_Body.InclusiveNamespacesPrefixList = "web";

handler.References.get_Reference(1).DigestMethod = SBXMLSec.Unit.xdmSHA256;
TElXMLC14NTransform C14N_Ts = handler.References.get_Reference(1).TransformChain.get_Transforms(0) as TElXMLC14NTransform;
C14N_Ts.InclusiveNamespacesPrefixList = "wsse soap web";

Also now SignatureMethod algorithm is "http://www.w3.org/2000/09/xmldsig#rsa-sha1" i want to change this to "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" . I did this as following:
Code
private void handler_OnBeforeSign(object Sender, TElXMLSigner Signer)
{
  Signer.Signature.ID = "SIG-1";
  Signer.Signature.KeyInfo.ID = "KI-2B1CE5D5CD4A26CDE514228880100312";
  TElXMLSignatureMethodType signatureMethod = new TElXMLSignatureMethodType();
  signatureMethod.Algorithm = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
  Signer.Signature.SignedInfo.SignatureMethod = signatureMethod;
}

But after changing SignatureMethod Algorithm I got "Hash algorithm mismatch (28929)" error on Verifying signature.
What am I doing wrong?
#32056
Posted: 02/03/2015 03:46:42
by Engin K. (Basic support level)
Joined: 02/02/2015
Posts: 6

OK, I found my mistake. I also need to set Signer.SignatureMethod too.
This code worked to change SignatureMethod algorithm.
Code
private void handler_OnBeforeSign(object Sender, TElXMLSigner Signer)
{
    Signer.Signature.ID = "SIG-1";
    Signer.Signature.KeyInfo.ID = "KI-2B1CE5D5CD4A26CDE514228880100312";
    Signer.SignatureMethod = SBXMLSec.Unit.xsmRSA_SHA256;
    TElXMLSignatureMethodType signatureMethod = new TElXMLSignatureMethodType();
    signatureMethod.Algorithm = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
    Signer.Signature.SignedInfo.SignatureMethod = signatureMethod;            
}
#32057
Posted: 02/03/2015 03:55:00
by Dmytro Bogatskyy (EldoS Corp.)

Hello,

Quote

Code
private void handler_OnBeforeSign(object Sender, TElXMLSigner Signer)
{
  TElXMLSignatureMethodType signatureMethod = new TElXMLSignatureMethodType();
  signatureMethod.Algorithm = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
  Signer.Signature.SignedInfo.SignatureMethod = signatureMethod;
}


This is incorrect, you should set TElXMLSigner.SignatureMethod in OnPrepareSignature event handler (you don't need to modify SignedInfo.SignatureMethod property), for example:
Code
handler.OnPrepareSignature += new TSBXMLSOAPSignEvent(handler_OnPrepareSignature);
private void handler_OnPrepareSignature(object Sender, TElXMLSigner Signer)
{
    Signer.SignatureMethod = SBXMLSec.Unit.xsmRSA_SHA256;
}

The OnPrepareSignature event handler used to set TElXMLSigner properties, it is fired before OnBeforeSign. The OnBeforeSign event handler used to set TElXMLSigner.Signature properties.
#32081
Posted: 02/03/2015 09:25:23
by Engin K. (Basic support level)
Joined: 02/02/2015
Posts: 6

OnPrepareSignature event handler did what i want.

Thank you.
#32101
Posted: 02/05/2015 01:36:58
by Engin K. (Basic support level)
Joined: 02/02/2015
Posts: 6

I have created and signed SOAP message successfully by using smart card.Also i need to sign by using HSM, and i did it sucessfully.

I have nearly 20 certificates stored in HSM and they have KeyName / LabelName. When i loop certificates and get with this code then I don't see any field/property about KeyName or LabelName.
Code
for (int i = 0; i < PKCS11CertStorage.Count; i++)
{
  TElX509Certificate Cert = PKCS11CertStorage.get_Certificates(i);
  ...

I also looked to objects (only certificate objects) with this code PKCS11CertStorage.get_Objects(i) and I see that object has ObjectLabel property. Maybe this field is what i need to have.

So what is the best way to get certificate by KeyName / LabelName?
#32106
Posted: 02/05/2015 04:53:16
by Ken Ivanov (EldoS Corp.)

Hi Scarlet,

Quote
So what is the best way to get certificate by KeyName / LabelName?

I'm afraid there is no best way here, as different tokens and drivers store that information in different places. In practice, the token may store textual and/or user-friendly identifiers of the certificates and keys in the following PKCS#11 properties:

- Key ID. This can be extracted through the TElX509Certificate.KeyMaterial.KeyID property.

- Subject: TElX509Certificate.KeyMaterial.KeySubject property.

- ObjectLabel: can be recovered from a TElPKCS11Object object that corresponds to the certificate's key material. The proper object can be obtained from the TElPKCS11CertStorage.get_Objects() list by comparing the value of the TElPKCS11Object.Handle property to that of the TElX509Certificate.KeyMaterial.KeyHandle property.

Ken
Also by EldoS: MsgConnect
Cross-platform protocol-independent communication framework for building peer-to-peer and client-server applications and middleware components.

Reply

Statistics

Topic viewed 1313 times

Number of guests: 1, registered members: 0, in total hidden: 0




|

Back to top

As of July 15, 2016 EldoS Corporation will operate as a division of /n software inc. For more information, please read the announcement.

Got it!