Showing posts with label WS-*. Show all posts
Showing posts with label WS-*. Show all posts

Friday, September 10, 2010

Wcf on iPhone?

@YaronNaveh

Apple's announcement yesterday on relaxing the strict AppStore SDK policy is good news for web services interoperability. Why is that? We need to get some background first:

With the rising popularity of iPhone development, people seek for web services support.

One known Mac framework is wsdl2objc (wsdl to objective-C, the iPhone development language). It give the basic functionality of creating a proxy and calling the service.

If your web service is relatively simple and you can afford to build the soap payload by hand, you could also consider using the native Http library CFNetwork or a the ASIHTTPRequest wrapper.

The latter option also enables transport level security (ssl).

Message level security
This is a known pain point. I have yet to find a WS-Security implementation for the iPhone. If you are doing simple stuff (mainly username token) you can get away with manually pushing these headers. But more advanced scenarios (involving X.509) are harder and Apple does not seem to develop a ws-security implementation soon.

So why doesn't any third party develop one?
Until yesterday, apple banned the usage of code generators for AppStore applications. While a soap stack may be developed in pure objective-C, the realm of web services highly relies upon code generation and libraries.
Yesterday, Apple announced that it now allows any development tools to be used for AppStore applications. While the media mainly mentioned the implication on Adobe Flash, the announcment also positively affected the MonoTouch framework which enables C# development for iPhone. And while MonoTouch WCF support is still experiential and does not include advanced WS-*, there is now hope to have all the advanced stuff in a future version.

UPDATE 1: It seems MonoTouch does support the Wcf Silverlight stack. I assume username token is in but not sure about binary encoding and tcp transport. Looking at Mono WCF support page shows that Wcf is still not fully supported there, which may be an indication.

UPDATE 2: Carlos mentions that Silverlight is supported on Mac. After yesterday's announcement there is a reason to believe that SL will be officially supported in iPhone either which makes standalone SL applications a prospect too.

@YaronNaveh

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

Friday, June 18, 2010

Wcf Security Interoperability Series

@YaronNaveh

If you are a fan of Wcf security interoperability blogs - and if you read my blog you must admit you secretly are - you do not want to miss dhurba's series on WCF security interoperability.

As a side note, in the last weeks there is a bug with MSDN hosted blogs (as dhurba's) where I am sometimes prompted for a password when surfing there. This mostly happens with Chrome, but sometimes also in IE. This is usually solved by restarting the browser (better chances with IE) but is really annoying.

@YaronNaveh

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

Tuesday, April 20, 2010

Interoperability Gotcha: OAEP Parameterization is not supported

@YaronNaveh

WSE2 is already obsolete but I still see people trying to reach interoperability from WSE2 to WCF. Surprisingly there are a number of interesting ws-security scenarios where this is possible. Today I will discuss one scenario where it may be harder.

WSE configuration allows to configure the algorithms we use for encryption:


<microsoft.web.services2>
...
     <keyAlgorithm name="RSA15" />
...
</microsoft.web.services2>


Some scenarios work great with RSA15 but when we change it to RSAOAEP we may see this exception from the WSE party:


OAEP Parameterization is not supported


Let's see what in the message that WCF sent to WSE may cause this:


<e:EncryptedKey xmlns:e="http://www.w3.org/2001/04/xmlenc#">
  <e:EncryptionMethod   Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p">
      <DigestMethod       Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"       xmlns="http://www.w3.org/2000/09/xmldsig#" />
  </e:EncryptionMethod>
</EncryptedKey>


We can see that the encryptedKey is indeed encrypted with the RSAOAEP algorithm. Also the RSAOAEP RFC states that:


The RSAES-OAEP-ENCRYPT algorithm... takes three parameters. The two user specified parameters are [MANDATORY]... The message digest function is indicated by the Algorithm attribute of a child ds:DigestMethod element...


Hence the DigestMethod element.

So why WSE throws an exception when a mandatory parameter is specified? Let's look at a WSE generated message to see if it produces anything different:


<e:EncryptedKey xmlns:e="http://www.w3.org/2001/04/xmlenc#">
  <e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p">
    <ds:DigestMethod     xmlns:ds="http://www.w3.org/2000/09/xmldsig#"     Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
  </e:EncryptionMethod>
</EncryptedKey>


Looks the same to me. So let's drill down into the WSE stack to understand the root cause. The error seems to be thrown from within this method:


public override void set_Parameters(string value)
{
   if (((value != null) && (value.Length != 0)) && (value != this._parameters))
   {
     throw new NotSupportedException("OAEP Parameterization is not supported");
   }
}


Ok so we are comparing the current message parameters (value) to some default value (this._parameters). But what is this default? Let's look in the ctor:


public RSAOAEPKeyExchangeFormatter()
{
   this._parameters = "";
}


Oh boy. WSE2 compares xml fragments as strings! So it sees this:


<DigestMethod xmlns="http://www.w3.org/2000/09/xmldsig#" />


as different from this:


<ds:DigestMethod xmlns:ds="http://www.w3.org/2000/09/xmldsig#" />


While the above fragments have the same xml semantics.

Just in order to convince my self this is the issue, I have manually changed the soap so that it will have the WSE-style digest. This worked like a charm. This kind of gives us the general solution here which is to build a WSE filter that changes the soap format to the one WSe expects. Note that you can only change non-signed soap parts, which is usually the case with the encrypted key. The easier option of course is to revert to the RSA15 algorithm.

And let's not forget the main point which is to never compare xml as a string.

@YaronNaveh

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

Tuesday, February 9, 2010

An error was discovered processing the <Security> header

@YaronNaveh

This week's error can happen when Wse2 processes a secured message.

When Wse receives a message which has expired according to its producer policy we will see this exception:


Message Expired


Pretty much self explained. However in other cases we might see this error:


An error was discovered processing the header


This error means that the message timestamp is not valid according to the server policy (e.g. message was sent in the future).

The answer for these ills is to either sync the client & server clocks or to configure a larger skew.

@YaronNaveh

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

Friday, July 3, 2009

Security in SOA

@YaronNaveh

Prabath gave a great presentation on SOA & web services security in the WSO2 summer school. It is particularily interesting for everyone who wants to understand what stands behind security related WS-* standards such as WS-Security and WS-Trust.

@YaronNaveh

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

Tuesday, March 17, 2009

Which Binding to Use - WSHttpBinding or WS2007HttpBinding?

@YaronNaveh

The default binding in Wcf 3.0 is WSHttpBinding. Wcf 3.5 brings the new WS2007HttpBinding binding but WSHttpBinding is still the default. These bindings do not interoperate together well due to the fact that WS2007HttpBinding uses some newer standards.

When the client uses WS2007HttpBinding and the server employs WSHttpBinding we may get this exception in the client side:


Secure channel cannot be opened because security negotiation with the remote endpoint has failed. This may be due to absent or incorrectly specified EndpointIdentity in the EndpointAddress used to create the channel. Please verify the EndpointIdentity specified or implied by the EndpointAddress correctly identifies the remote endpoint.


And the inner exception is:


"The message could not be processed. This is most likely because the action 'http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue' is incorrect or because the message contains an invalid or expired security context token or because there is a mismatch between bindings. The security context token would be invalid if the service aborted the channel due to inactivity. To prevent the service from aborting idle sessions prematurely increase the Receive timeout on the service endpoint's binding."


On the server side trace we see


System.ServiceModel.EndpointNotFoundException, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089


And the inner exception:


There was no channel that could accept the message with action 'http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue'.


When the client uses WSHttpBinding and the server employs WS2007HttpBinding we would get the same exceptions with http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue being replaced by http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue.

The reason for the errors is the different WS-Trust versions between the bindings. WS-Trust is used when the negotiateServiceCredential or establishSecurityContext settings are set to true (which is the default). In these cases infrastructure messages are exchanged between the client and the server and these messages require the WS-Trust version to match.

We can see the different versions if we use the reflector to check the bindings static constructors.

In WSHttpBinding:


static WSHttpBinding()
{
  WSMessageSecurityVersion = MessageSecurityVersion.WSSecurity11WSTrustFebruary2005
      WSSecureConversationFebruary2005WSSecurityPolicy11
BasicSecurityProfile10;
}


In WS2007HttpBinding:


static WS2007HttpBinding()
{
...
  WS2007MessageSecurityVersion = MessageSecurityVersion.WSSecurity11WSTrust13WSSecureConversation13
      WSSecurityPolicy12
BasicSecurityProfile10;
}


So, which binding to use?
In many cases this does not matter since both bindings expose similar functionality.
You might want to consider the following:

  • WSHttpBinding is supported by .Net 3.0 clients.

  • WS2007HttpBinding uses WS-* standards while WSHttpBinding uses drafts. You might face a requirement to work with the standard.

  • Different soap stacks support different standards so if you need to interoperate with a specific framework verify the standards it supports.

  • In the long run WS2007HttpBinding should be used as it supports the actuall standard.


  • Nevertheless, for most services this decision will probably only have a very minor effect.

    @YaronNaveh

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