views:

165

answers:

1

So I'm using the PayPal API. They require bigger companies to send an X509Certificate along with each SOAP API request. I've never heard of using a cert, it's always been just send the API signature along with an API request.

So I first created a class called Cerficate that implements the .NET ICerfiticatePolicy. One of the member methods, really the only one you have to implement is:

System.Net.ICertificatePolicy.CheckValidationResult(System.Net.ServicePoint, System.Security.Cryptography.X509Certificates.X509Certificate, System.Net.WebRequest, int)

So far I'm having trouble really understanding what to pass to this method. I guess the method simply validates that the Cerfiticate is valid. So I'm not sure what ServicePoint is and what to pass into it. I assumed it was my web service reference and a proxy class within such as the PayPalAPIAAInterfaceClient

I also see a very old example using ServicePointManager.S for something but I don't understand it, even after looking at MSDN. So I guess you are to use ServicePointManager.ServerCertificateValidationCallback and I suppose set the callback to the CheckValidationResult? If so, when do you do this? It's just very confusing to me.

Also, So I guess I create an instance of my Certificate class and set the certificate properties by reading the P12 certificate from my disk and then pass in that to this method to check if it's valid? I guess that's right.

I'm still trying to figure out this whole thing and I'm really stuck on the ServicePoint as well as WebRequest because really I'm using a proxy class in PayPal which does the under the hood sending of the request. So I don't see how I can even pass in type WebRequest because I'm using a proxy method for that anyway. So what would I even pass for the WebRequest param? I'm using a SOAP API WSDL, not NVP here so I'm not for example creating an HttpWebRequest variable like you do with REST services in order to send the API request over Http.

so far here's what I've tried:

    PayPalAPIAAInterfaceClient client = new PayPalAPIAAInterfaceClient();
    Certificate x509Certificate = new Certificate();
    ServicePointManager.ServerCertificateValidationCallback = x509Certificate.CheckValidationResult();
    client.ClientCredentials.ClientCertificate.Certificate = x509Certificate;

the problem is, what do I pass in for the ServicePiont and the rest of the params for CheckValidationResult?? I don't even know if I'm calling this right.

+2  A: 

It's certainly not unheard of and in fact fairly common to secure SOAP services with X.509 certificates using the WS-Security spec - in fact, we do this for all of our internal and external web services. All web service frameworks including WCF are specifically designed to make this as easy as possible.

You should never have to use the ServicePointManager or ICertificatePolicy with a SOAP service using WS-Security. Unless there's something truly bizarre about PayPal's API, I think you're on the wrong track with that. All you have to do in WCF is this:

var client = new PayPalAPIInterfaceClient();
X509Certificate2 certificate = (...);
client.ClientCredentials.ClientCertificate.Certificate = certificate;
client.AddressVerify(...);  // or whatever method you want to call

You don't even really need to write this code; if you have the certificate installed in the server's certificate store then you just edit the binding and behavior elements of the app.config - or use the WCF Service Configuration Editor, which is a lot easier.

Of course, in order to do this you have to have an X.509 certificate, and PayPal has to know about it. You can't just write new X509Certificate2(). You need to have a .pfx or .p12 file somewhere or, as mentioned above, have the certificate physically installed (this is the easiest way and the most secure because you're not hard-coding a password). And you need to upload the public key to PayPal.

You might be able to use OpenSSL to create a cert. PayPal's EWP page suggests that they'll accept these and gives instructions on how to create them, although it's not entirely clear whether or not the same process can be used for their SOAP API. It could be that they require a "real" certificate from Verisign, Thawte, etc. - I would try OpenSSL first and see, or just ask them.

There's a pretty comprehensive guide to the whole process here - you'll probably want to skip the sections on generating the certificate unless you have a Microsoft CA somewhere. Again, for that part, you'll probably want to try using the OpenSSL utility instead and follow PayPal's instructions, then install the cert on your server and skip to step 7 of that guide.

Aaronaught