Answered by:
Naming a SSL Certificate when installing with/for a WCF Service

Question
-
Hello,
I've got 3 WCF Services all self-hosted and they are all using SSL. I've created my root certificate, self signed and then created certificates from that. The securing on the bindings is transport.
I've got ssl working with the services right now but the CN of certificate (the one created from the root certficate) is the ip address of my development box. I've used httpcfg to assign the thumbnail of the certificate to the ip a/port. When I go to host the services up, I use
myLisServiceHost.AddServiceEndpoint(GetType(LIS_WorkflowInterface.ILISWorkflowInterface), _wsHttp, "https://" & ipaddress & ":" & httpport & "/LIS_WorkflowService/secure")
myLisServiceHost.Credentials.ServiceCertificate.SetCertificate( _
StoreLocation.LocalMachine, _
StoreName.My, _
X509FindType.FindByThumbprint, _
"5bdfd54555e6b2455f3454784b93de0f099564bc")
These services are going to be installed via a windows installer (WIX). The install is going to take place at many different customers/clients. From the samples I have seen, when I create the certificate (from my root authority self signed certificate), the CN="...." of the certificate has to be either the name of the ip address of the box its being installed on.
When these services get deployed for real, into production at various customer sites .. that CN needs to be more flexible. How do I approach this ?
I have thought about having a harcoded string i.e.
https://MYWCFSERVICES:8755/OneofThreeWCFServices
https://MYWCFSERVICES:8755/TwoofThreeWCFServices
https://MYWCFSERVICES:8755/ThreeofThreeWCFServices
Where the client would have to setup MYWCFSERVICES ahead of time (prior to the install) to be a hostname which resolves to the ip address of the box.
Does anyone have any suggestions ? Thanks for help in advance ! I appreciate it !
Thursday, June 10, 2010 3:00 AM
Answers
-
Hi,
In my opinion using pre-made certificate is reasonable. As the certificate issuer you need to know who you want to issue this certificate to. If anyone can get a working certificate just by getting the installer of your WCF application it involves a big security hole.
However if you persist to do so (with any reason that I cannot think of at this moment) you may have a look at custom actions. By using it you can call your code to execute command during installation:
http://msdn.microsoft.com/en-us/library/d9k65z2d(VS.80).aspx
Please remember to mark the replies as answers if they help and unmark them if they provide no help. Windows Azure Platform China Blog: http://blogs.msdn.com/azchina/default.aspx- Marked as answer by Allen Chen - MSFT Thursday, June 17, 2010 9:56 AM
Tuesday, June 15, 2010 9:29 AM
All replies
-
Hi,
You can specify different CN names when making certificate:
http://msdn.microsoft.com/en-us/library/bfsktky3(VS.80).aspx
In addition, after you've confirmed the certificate works you can use the following code to bypass validation of server certificate for new certificates to assume the certificate validation works (remember to remove the code for production version):
public static class Util
{
/// <summary>
/// Sets the cert policy.
/// </summary>
public static void SetCertificatePolicy()
{
ServicePointManager.ServerCertificateValidationCallback += RemoteCertificateValidate;
}/// <summary>
/// Remotes the certificate validate.
/// </summary>
private static bool RemoteCertificateValidate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error)
{
// trust any certificate
System.Console.WriteLine("Warning, trust any certificate");
return true;
}
}call Util.SetCertificatePolicy() before sending request to server.
Please remember to mark the replies as answers if they help and unmark them if they provide no help. Windows Azure Platform China Blog: http://blogs.msdn.com/azchina/default.aspxMonday, June 14, 2010 3:30 AM -
I realize I can specifiy different CN names when making the certificate however the install of the WCF is not going to make a certificate. To be clear, when these services get installed at the customer sites, on their servers, the installer won't be constructing a certficate. The installer will install a pre-made certificate. That is where my question comes from. What is the best way to handle the scenario where a premade certificate (using make cert or other means ?) is going to be installed at different customers .. thus the domain/ip is going to be different.
Can I use a generic namie ..i.e. MYWCFSERVICEHOST to name the certificate, reference this in when I go to host up the services and well when the client connects and authenicates the server. This software install does not have a certificate specifically for the client, only the root and certificate for the server. The customer would have to have this setup as a valid hostname on their system prior to the install.
Thanks in Advance ..
Monday, June 14, 2010 1:12 PM -
Hi,
In my opinion using pre-made certificate is reasonable. As the certificate issuer you need to know who you want to issue this certificate to. If anyone can get a working certificate just by getting the installer of your WCF application it involves a big security hole.
However if you persist to do so (with any reason that I cannot think of at this moment) you may have a look at custom actions. By using it you can call your code to execute command during installation:
http://msdn.microsoft.com/en-us/library/d9k65z2d(VS.80).aspx
Please remember to mark the replies as answers if they help and unmark them if they provide no help. Windows Azure Platform China Blog: http://blogs.msdn.com/azchina/default.aspx- Marked as answer by Allen Chen - MSFT Thursday, June 17, 2010 9:56 AM
Tuesday, June 15, 2010 9:29 AM -
You should get the customer to obtain a valid SSL cert for the machine they want to install on then get the installer to allow them to select the approriate cert at install time. Generally you don;t need to specify the SSL cert in your code - you tell http.sys about it via the netsh http add sslcert command and you bind the cert to a port. Then the service listens on the appropriate port and http.sys presents the cert to the caller
Richard Blewett, thinktecture - http://www.dotnetconsult.co.uk/weblog2
Twitter: richardblewett- Marked as answer by Allen Chen - MSFT Thursday, June 17, 2010 9:56 AM
- Unmarked as answer by TriathleteRob Friday, June 18, 2010 7:52 PM
Tuesday, June 15, 2010 1:07 PM -
I was away from this topic for a bit ...
So you can't create a certificate (from a trusted root) on one machine and then deploy it to another machine ?
I have not tried the MYWCFSERVICEHOST idea yet ...
I'm just reading alot of articles that say the CN .. name of the certificate has to match the computer name of the computer it gets installed.
When I installed my services on a differnet and try to connect to the services.. here is the communication exception I get ....
An error occurred while making the HTTP request to https://192.168.0.111:56223/TMS_WorkstationService/secure. This could be due to the fact that the server certificate is not configured properly with HTTP.SYS in the HTTPS case. This could also be caused by a mismatch of the security binding between the client and the server.System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a send. ---> System.IO.IOException: Authentication failed because the remote party has closed the transport stream.
at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
at System.Net.TlsStream.CallProcessAuthentication(Object state)
at System.Threading.ExecutionContext.runTryCode(Object userData)
at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result)
at System.Net.TlsStream.Write(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.PooledStream.Write(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.ConnectStream.WriteHeaders(Boolean async)
--- End of inner exception stack trace ---
at System.Net.HttpWebRequest.GetResponse()
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)Does this provide any more insight / help to you guys ...
Friday, June 18, 2010 8:24 PM -
I think you need to step back bit and understand certificates a bit ...
There is a fundematnal problem of how do you know you are talking to the right server.
So lets use Public/Private Key cryptography: here there are two keys that are mathematically related but not derivable from eachother. The crucial thing here is that anything I ancrypt with one key can only be decrypted with the other key. The idea is that I allow you to see the public key but the private key only I know
So what does this mean? A message encrypted with my public key only I can read: this gives me privacy; A message encrypted that you can decrypt with my public key must have come from me - therefore we have authentication
So when you send me a message that you are going to encrypt you need to send me your public key, but how do you know that its my public key - someone might have injected another into our conversation. Well I need someone to verify its your public key - lets take a trusted 3rd party like Verisign who check that I am who I say I am - their publicv key is well known therefore they encrypt my public key with their private key - only they can have done this and as long as I trust Verisign then it must be your public key. Basically, someones public key encrypted with a trusted 3rd party (the issuer) private key is a certificate
Now if verisign issue a cert named as your server then that is now verified. Generally WCF makes sure that the issuer of a cert is trusted - so if you are issuing certs as a server then the client must trust them which means the issuer must be trusted on the client
this article is great at showing you what you need to do to create and issue trusted certs
http://www.digitallycreated.net/Blog/38/using-makecert-to-create-certificates-for-development
Richard Blewett, thinktecture - http://www.dotnetconsult.co.uk/weblog2
Twitter: richardblewettFriday, June 18, 2010 11:35 PM -
My post that I tried to make friday after the post you see above this one (with all the trace it in) .. I guess did not make it to the forums.
I did step back for a bit and look to see if I was trying to fit a square block into a round hole type of thing. I was.
I got my WCF Services to work on another machine. What I did is to create a certificate using my root certificates on that -other- machine. I named CN=... of the certificate the ip address of the machine. I then did the httpcfg utility and I was able to talk to the services. Yes I understand when you do server authenication, there is authenication between what the client has in its url and what the services are hosted up to be... from what I have read anyways. You just can not deploy generic certificates. That makes sense.
Here is ultimately what I am trying to solve and perhaps the article that you issued above will answer this for me but just in case:
When my end users install these services (via a installer package), they do not want to be involved in the creation of the certificate. To be clear, they do not want to know anything about a 'make a certificate' utility and how to use it. All the command line certificate creation is to be done 100% behind the scenes. Makecert is not redistributable , correct ? What is a recommended utility to use that is redistributable and one that has command line options. I'll definitely read over the article and that may give me my answers to this scenario but just to let you guys know what I really need to accomplish.
thanks for your help.
Saturday, June 19, 2010 3:23 PM -
Makecert is redistributable so ... my problem is sovled.
- Proposed as answer by 10437NiceGuy Saturday, June 19, 2010 7:11 PM
Saturday, June 19, 2010 7:11 PM