views:

2403

answers:

3

So I've got a ServiceReference added to a C# Console Application which calls a Web Service that is exposed from Oracle.

I've got everything setup and it works like peaches when it's not using SSL (http). I'm trying to set it up using SSL now, and I'm running into issues with adding it to the Service References (or even Web References). For example, the URL (https) that the service is being exposed on, isn't returning the appropriate web methods when I try to add it into Visual Studio.

The underlying connection was closed: An unexpected error occurred on a send. Received an unexpected EOF or 0 bytes from the transport stream. Metadata contains a reference that cannot be resolved: 'https://srs204.mywebsite.ca:7776/SomeDirectory/MyWebService?WSDL'

Another quandary I've got is in regards to certificate management and deployment. I've got about 1000 external client sites that will need to use this little utility and they'll need the certificate installed in the appropriate cert store in order to connect to the Web Service. Not sure on the best approach to handling this. Do they need to be in the root store?

I've spent quite a few hours on the web looking over various options but can't get a good clean answer anywhere.

To summarize, I've got a couple of questions here:

1) Anybody have some good links on setting up Web Services in Visual Studio that use SSL?

2) How should I register the certificate? Which store should it exist in? Can I just use something like CertMgr to register it?

There's gotta be a good book/tutorial/whatever that will show me common good practices on setting something like this up. I just can't seem to find it!

+4  A: 

It sounds like the web service is using a self signed certificate. Frankly this isn't the best approach.

Assuming you're a large organisation and it's internal you can setup your own trusted certificate authority, this is especially easy with Active Directory. From that CA the server hosting the Oracle service could request a certificate and you can use AD policy to trust your internal CA's root certificate by placing it in the trusted root of the machine store. This would remove the need to manually trust or accept the certificate on the web service.

If the client machines are external then you're going to have to get the folks exposing the service to either purchase a "real" certificate from one of the well known CAs like Verisign, Thawte, GeoTrust etc. or as part of your install bundle the public certificate and install it into Trusted Root certificate authorities at the machine level on every machine. This has problems, for example no way to revoke the certificate, but will remove the prompt.

blowdart
Thanks for the response! I've been provided with two certificates. One for the "development" server and another for the "production" server. Our client sites are external so I'll have to worry about registering the certs manually. Any good links on the best way to get them into the trusted root machine store? The production certificate is from GTE CyberTrust and is a Global Root certificate that covers all issuance policies and all application policies.
Mat Nadrofsky
So you won't need to worry about the live server then, it will work out of the box as GTE is a trusted root (I think you're a little confused - it's unlikely the live server has it's own root cert, it's probably just a normal cert). In order to check I'd add a reference to the live service and see what happens. If that's all good then for dev you only need to install the cert on your machine. Start up MMC and add the cerificates snapin, telling it to use the local machine. Then import the dev cert into trusted root.
blowdart
Gotcha. I've run MMC, used the certificates snap-in to make sure the developement cert authority has been added to "trusted root" for the local computer. Still can't connect to the development version of the service. I can't actually test against the production version since we aren't out of development yet. I might be able to get them to try to set something up for me though. Is there a chance something could be wrong on their end with the development certificate? If I've got the right cert installed on my system, I should be able to add the HTTPS service reference without an error right?
Mat Nadrofsky
And I should clarify by wrong on "their end" I mean that the cert I've got for the development server isn't the one that's actually being used on that server.
Mat Nadrofsky
Big time thanks for the help and suggestions by the way.
Mat Nadrofsky
Naw, it's doubtful there's anything wrong at their end ;) So, browse to their endpoint in IE. Get past the cert warnings, click the padlock icon and install it from there
blowdart
Ooo. Sneaky. I like that. Trying that now...
Mat Nadrofsky
Still no dice. That did install a different cert to the trust root on the local machine. Specifically one for srs204.mywebsite.ca. I was excited for a minute, then Visual Studio still failed to make a connection to the service to add in the reference. Consequently wsdl.exe fails as well. This thing is driving me bananas - Gwen style.
Mat Nadrofsky
weird. When you get the untrusted dialog you should be able to click View Certificate then add from that dialog and everything should work. You are running VS elevated though for this right?
blowdart
I'm actually not even getting an "untrusted" dialog. The error just shows up on the Add Service Reference dialog right below the Services and Operations tree-views. If I run wsdl.exe then the error of course spits out to the command line. I'll try running VS elevated, I am an admin on this PC but hey, stranger things have happened. This is uber-weird. I can hit the addy in IE using https and it's no probs. I get the end point, I have added the certs, everything is cool there. VS just doesn't want to play nice.
Mat Nadrofsky
I'm going to get them to check for any config differences on the Oracle side between the http version that works wonderfully and the https one that doesn't. Maybe there is something in there that won't let VS or .Net connect. But again if I can hit the end-point, that doesn't really make sense.
Mat Nadrofsky
+10  A: 

Well, I've figured this out. It took me far longer than I care to talk about, but I wanted to share my solution since it's a HUGE pet peeve of mine to see the standard. "Oh I fixed it! Thanks!" posts that leave everyone hanging on what actually happened.

So.

The root problem was that by default Visual Studio 2008 uses TLS for the SSL handshake and the Oracle/Java based Webservice that I was trying to connect too was using SSL3.

When you use the "Add Service Reference..." in Visual Studio 2008, you have no way to specify that the security protocol for the service point manager should be SSL3.

Unless.

You take a static WSDL document and use wsdl.exe to generate a proxy class.

wsdl /l:CS /protocol:SOAP /namespace:MyNamespace MyWebService.wsdl

Then you can use the C Sharp Compiler to turn that proxy class into a library (.dll) and add it to your .Net projects "References".

csc /t:library /r:System.Web.Services.dll /r:System.Xml.dll MyWebService.cs

At this point you also need to make sure that you've included System.Web.Services in your "References" as well.

Now you should be able to call your web service without an issue in the code. To make it work you're going to need one magic line of code added before you instantiate the service.

// We're using SSL here and not TLS. Without this line, nothing workie.
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;

Okay, so I was feeling pretty impressed with myself as testing was great on my dev box. Then I deployed to another client box and it wouldn't connect again due to a permissions/authority issue. This smelled like certificates to me (whatever they smell like). To resolve this, I used certmgr.exe to register the certificate for the site to the Trusted Root on the Local Machine.

certmgr -add -c "c:\someDir\yourCert.cer" -s -r localMachine root

This allows me to distribute the certificate to our client sites and install it automatically for the users. I'm still not sure on how "security friendly" the different versions of windows will be in regards to automated certificate registrations like this one, but it's worked great so far.

Hope this answer helps some folks. Thanks to blowdart too for all of your help on this one and providing some insight.

Mat Nadrofsky
+1  A: 

Mat,

I had such issues too and I have a way to avoid using certmgr.exe to add certificates to trusted root on a remote machine.

X509Store store; store = new X509Store("ROOT", StoreLocation.LocalMachine); store.Open(OpenFlags.ReadWrite); store.Add(certificate);

The 'certificate object' can be created like this:

X509Certificate2 certificate = new X509Certificate2("Give certificate location path here");

Hey thanks for the response! We've already deployed to our client sites with a custom script that's using certmgr.exe but I like this solution much better. We'll give it a shot when we dig back into that code next time there is a change.
Mat Nadrofsky