Saturday, January 9, 2010

Programmatically install an X.509 certificate with a private key

@YaronNaveh

This c# snippet will install an X.509 certificate with a private key into your windows certificates store:


public static void InstallCertificate(string path, string password)
{
   var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
   store.Open(OpenFlags.ReadWrite);

  try
  {
     X509Certificate2 cert;

     cert = new X509Certificate2(
           path,
           password,
           X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);

     store.Add(cert);
  }
  finally
  {
     store.Close();
  }
}

@YaronNaveh

What's next? get this blog rss updates or register for mail updates!

Friday, January 8, 2010

Replay attacks in Wcf

@YaronNaveh

One important attack against web services is a "replay attack": a malicious man-in-the-middle captures a valid message from a client to a server and resends it. This can cause duplicate transactions or denial of service (DOS).

Typically the way to protect here is to have a timestamp on the message and some expiration policy on the server. This is a very simplified description though, here are all the details.

The sending party attaches this timestamp to the SOAP message:


<wsu:Timestamp>
   <wsu:Created>2006-02-22T09:56:27Z</wsu:Created>
   <wsu:Expires>2006-02-22T10:01:27Z</wsu:Expires>
</wsu:Timestamp>


The receiving party can then decide based on some policy how much after the message was created it is suspected as a replay.

But what is this service policy? We can see an "expires" element in the client message itself, then why does the service need an additional policy?

The answer is that there is a duplicate protection against replay attacks. The client can decide its own policy and express it inside the message. The server should respect this policy and also adds its own policy. For example:


  • Client sends a message in 15:00

  • Client expiration policy is set to 15:05

  • Service gets the message in 15:06

  • Service expiration policy is set to 15:07



  • In this case the message is considered valid by the service, but the service is expected to respect the client policy and reject the message. the situation gets more interesting when we add real network latency and clocks synchronization into the picture.

    In Wcf there are two somehow confusing settings to control the expiration:


  • LocalServiceSecuritySettings.ReplayWindow - The service expiration policy.

  • LocalclientSecuritySettings.TimestampValidityDuration - The client expiration policy as expressed in the message itself.


  • There are various other settings which relate to tolerance for clock differences and I will write a separate post on them some other time.

    @YaronNaveh

    What's next? get this blog rss updates or register for mail updates!

    Wednesday, January 6, 2010

    WCF Binary-encoded Message Inspector for Fiddler

    @YaronNaveh

    We all love our Fiddler. It is a great Http proxy to use when debugging web services (and html). Fiddler now has a WCF binary encoding message inspector. It allows us to see in clear xml binary messages. This is very usefull especially since binary encoding is the default setting for Silverlight 3 applications.

    @YaronNaveh

    What's next? get this blog rss updates or register for mail updates!

    Axis2 & Wcf Interoperability

    @YaronNaveh

    Recently I had to consume an Axis2 web service using a Wcf client. Axis2 used the rampart module for message security where a mutual X.509 certificate was required. Since I had control over both client and server I was able to fine tune them to reach perfect interoperability.

    On the Axis side, I have found the WS-Policy flavor configuration better to work with (interoperability-wise) .

    This is the Axis configuration:



    and this is the Wcf configuration:



    Here is the full Axis2 service (which is based on the rampart SDK sample):



    and the wcf client:



    You will also need certificates.

    Client certificate:



    Server Certificate:



    If prompt for a password use "adminamdin".

    This is the Java key store:



    and the password is "adminadmin".

    If you want to use your own certificate just make sure the certificates have an SKI.

    @YaronNaveh

    What's next? get this blog rss updates or register for mail updates!

    Saturday, January 2, 2010

    Anti-Spam: Deleting multipe comments in blogger

    @YaronNaveh

    I always love to see comments to my posts:




    However when the comments are nothing but SPAM...




    I have recently needed to delete 100+ comments from my blogger account. Unfortunately blogger only allows to delete one comment at a time. This is really not helping when I need to delete 100+ comments.

    The trick is to use a browser that supports tabs (almost all of them today) and to middle click the basket icon near each comment we want to delete. It will now open in a new tab:



    We still need to approve the deletion in that tab, but at least we do not need the extra clicks of returning to the original post and finding the next comment.

    @YaronNaveh

    What's next? get this blog rss updates or register for mail updates!

    Cryptic WCF error messages (part 7 of N)

    @YaronNaveh

    Yet another post in the ongoing series.

    This one happens when you use 2-way ssl (e.g. client authenticates with an X.509 certificate in the HTTP level). You may get this error message:


    The HTTP request was forbidden with client authentication scheme 'Anonymous'.


    This simply means the client certificate failed validation on the server. So check you use the correct certificate and that it is valid on the server.

    @YaronNaveh

    What's next? get this blog rss updates or register for mail updates!

    Wednesday, December 30, 2009

    Security Gotcha: Nonrepudiation

    @YaronNaveh

    An important web services security requirement is nonrepudiation. This requirement prevents a party from denying it sent or received a message. The way to implement this is using Xml Digital Signatures. For example, if I sent a message which is signed with my private key, I cannot later deny that I sent it.

    A common mistake is to think that every web service that require an X.509 certificate ensures nonrepudiation. This goes without say for web services that only require server certificate - in these services clients are either anonymous or username/password identified, which is considered weak cryptographically material.

    However, also when a client X.509 is involved, nonrepudiation is not always guaranteed.
    For example, let's examine a Wcf service which uses WsHttpBinding with TransportWithMessageCredential and clientCredentialType="Certificate":


    <wsHttpBinding>
       <binding name="WSHttpBinding_IService" >
         <security mode="TransportWithMessageCredential">
           <transport clientCredentialType="None" proxyCredentialType="None"
            realm="" />
           <message clientCredentialType="Certificate" negotiateServiceCredential="true"
            algorithmSuite="Default" establishSecurityContext="false" />
         </security>
       </binding>
    </wsHttpBinding>


    This is how the client request looks like:


    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing">
      <soap:Header>
      ...
       <To soap:mustUnderstand="1" u:Id="_1" xmlns="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">https://www.someService.co.il/</To>
       ...
       <o:Security soap:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
        <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>2009-12-30T18:19:03.538Z</u:Created>
         <u:Expires>2009-12-30T18:24:03.538Z</u:Expires>
        </u:Timestamp>
        <o:BinarySecurityToken u:Id="uuid-b29856c4-1be8-4cf6-94ef-b3e2818b9924-1" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">...</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>ExzPg2kUjOQz2nFBMlhm+OT3GNY=</DigestValue>
          </Reference>
          <Reference URI="#_1">
           <Transforms>
            <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
           </Transforms>
           <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
           <DigestValue>mN+2rmNLmjSJxbO4x+n/V6gGAb4=</DigestValue>
          </Reference>
         </SignedInfo>
         <SignatureValue>...</SignatureValue>
         <KeyInfo>
          <o:SecurityTokenReference>
           <o:Reference URI="#uuid-b29856c4-1be8-4cf6-94ef-b3e2818b9924-1" />
          </o:SecurityTokenReference>
         </KeyInfo>
        </Signature>
       </o:Security>
      </soap:Header>
      <soap:Body>
       <EchoString xmlns="http://tempuri.org/">
        <s>abcde</s>
       </EchoString>
      </soap:Body>
    </soap:Envelope>


    The message body is not signed!
    This practically means anyone who has this message (for example the server) can extract the signed parts and resend them with a bogus body.

    @YaronNaveh

    What's next? get this blog rss updates or register for mail updates!