Install certificates on client when consuming a WCF service with WSHttpBinding, Certificate Authentication and Message Security? - security

i've created a WCF service that should be consumed outside my domain, so i decided to use WSHttpBinding with Certificate authentification and message Security.
I created a self signed certificate named "Test And Dev Root Authority" using makecert and with it I signed other two certificates using mthe same tool like this
makecert -pe -n "CN=WcfServiceServer" -ss my -sr LocalMachine -a sha1 -sky exchange -eku 1.3.6.1.5.5.7.3.1 -in "Test And Dev Root Authority" -is my -ir LocalMachine -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12 WcfServiceServer.cer
makecert -pe -n "CN=WcfServiceClient" -ss my -sr LocalMachine -a sha1 -sky exchange -eku 1.3.6.1.5.5.7.3.1 -in "Test And Dev Root Authority" -is my -ir LocalMachine -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12 WcfServiceClient.cer
on my pc with mmc i added the 3 certificates to trusted people and trusted root certification authorities on the local machine account.
i called up the wcf service in IE and it was displayed correctly.
i created a test app on another computer and added the service as a reference to it. I exported WcfServiceClient with the secret key and imported it on the current account on the second machine and added it to the trusted folders mentioned above.
my app.config section for the wcf section in the client app looks like this:
<client>
<endpoint address="http://otherpc/WcfTest/Service.svc"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IServices"
contract="WcfTest.IServices" name="WSHttpBinding_IServices" behaviorConfiguration="CustomBehavior">
<identity>
<dns value="WcfServiceServer" />
</identity>
</endpoint>
</client>
<behaviors>
<endpointBehaviors>
<behavior name="CustomBehavior">
<clientCredentials>
<clientCertificate findValue="WcfServiceClient" x509FindType="FindBySubjectName" storeLocation="CurrentUser" storeName="My" />
<serviceCertificate>
<authentication certificateValidationMode="PeerTrust"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
when i wanted to test the app on the second computer it failed because it said that the certificate WcfServiceServer was not in the trusted peoples folder. I didn't expect that error. The only solution i found, in order to consume the service from the test app, was to export the WcfServiceServer certificate also and install it on the second machine and add it for the current user acoount in the trusted people zone.
Is it possible to avoid giving to the client the WCFServiceServer certificate, just the WcfServiceClient certificate and make the app acces the service correctly?
My second question is: in a production enviroment i should buy a SSL certificate and with it generate the other two certificate(one for service and one for client) like above and pass them to client/server side fallowing the steps described above?
thank you in advance. i'm a total noob in WCF

Related

Azure Linux web app: change OpenSSL default security level?

In my Azure Linux web app, I'm trying to perform an API call to an external provider, with a certificate. That call fails, while it's working fine when deploying the same code on a Windows app service plan. The equivalent cURL command line is:
curl --cert-type p12 --cert /var/ssl/private/THUMBPRINT.p12 -X POST https://www.example.com
The call fails with the following error:
curl: (58) could not load PKCS12 client certificate, OpenSSL error error:140AB18E:SSL routines:SSL_CTX_use_certificate:ca md too weak
The issue is caused by OpenSSL 1.1.1d, which by defaults requires a security level of 2, and my certificate is signed with SHA1 with RSA encryption:
openssl pkcs12 -in THUMBPRINT.p12 -nodes | openssl x509 -noout -text | grep 'Signature Algorithm'
Signature Algorithm: sha1WithRSAEncryption
Signature Algorithm: sha1WithRSAEncryption
On a normal Linux VM, I could edit /etc/ssl/openssl/cnf to change
CipherString = DEFAULT#SECLEVEL=2
to security level 1, but on an Azure Linux web app, the changes I make to that file are not persisted..
So my question is: how do I change the OpenSSL security level on an Azure web app? Or is there a better way to allow the use of my weak certificate?
Note: I'm not the issuer of the certificate, so I can't regenerate it myself. I'll check with the issuer if they can regenerate it, but in the meantime I'd like to proceed if possible :)
A call with Microsoft support led me to a solution. It's possible to run a script whenever the web app container starts, which means it's possible to edit the openssl.cnf file before the dotnet app in launched.
To do this, navigate to the Configuration blade of your Linux web app, then General settings, then Startup command:
The Startup command is a command that's ran when the container starts. You can do what you want, but it HAS to launch your app, because it's no longer done automatically.
You can SSH to your Linux web app, and edit that custom_startup.sh file:
#!/usr/sh
# allow weak certificates (certificate signed with SHA1)
# by downgrading OpenSSL security level from 2 to 1
sed -i 's/SECLEVEL=2/SECLEVEL=1/g' /etc/ssl/openssl.cnf
# run the dotnet website
cd /home/site/wwwroot
dotnet APPLICATION_DLL_NAME.dll
The relevant doc can be found here: https://learn.microsoft.com/en-us/azure/app-service/containers/app-service-linux-faq#built-in-images
Note however that the Startup command is not working for Azure Functions (at the time of writing May 19th, 2020). I've opened an issue on Github.
To work around this, I ended up creating custom Docker images:
Dockerfile for a webapp:
FROM mcr.microsoft.com/appsvc/dotnetcore:3.1-latest_20200502.1
# allow weak certificates (certificate signed with SHA1)
# by downgrading OpenSSL security level from 2 to 1
RUN sed -i 's/SECLEVEL=2/SECLEVEL=1/g' /etc/ssl/openssl.cnf
Dockerfile for an Azure function:
FROM mcr.microsoft.com/azure-functions/dotnet:3.0.13614-appservice
# allow weak certificates (certificate signed with SHA1)
# by downgrading OpenSSL security level from 2 to 1
RUN sed -i 's/SECLEVEL=2/SECLEVEL=1/g' /etc/ssl/openssl.cnf

Error connecting to Azure Virtual Network - Point to Site

I followed this tutorial to create a point-to-site connection:
https://learn.microsoft.com/en-us/azure/vpn-gateway/vpn-gateway-howto-point-to-site-resource-manager-portal
Now, when i try to connect the VPN I get this error:
A certificate could not be found that can be used with this Extensible Authentication Protocol. (Error 798)
It doesn't even work in the computer that I generated the self-signed cert. Neither it works in another client that I installed the pfx private key and fails in both with the same error.
Any ideas?
Ok turns out the document to create the certs are not complete here and not mentioning anything about the client cert and it just says how to create a root cert:
https://learn.microsoft.com/en-us/azure/vpn-gateway/vpn-gateway-certificates-point-to-site
Here is what I had to do to make it work:
Create root cert:
makecert -sky exchange -r -n "CN=AzureRootCert" -pe -a sha1 -len 2048 -ss My "AzureRootCert.cer"
Create client cert:
makecert.exe -n "CN=AzureClientCert" -pe -sky exchange -m 96 -ss My -in "AzureRootCert" -is my -a sha1
Then the rest is documented. so have to export the root cert and upload to Azure and then download the VPN tool.

Azure management certificate is not working

we create azure management certiicate both using "makecert" and using IIS7..And uploaded it in the azure site also.But noting seems to be working .Is there any other reason behind this?
API throws 403 errors.Powershell cmdlets throws Authentication failed error.
Working with different certificate file types and the various parameters to makecert can be a bit confusing. Ultimately, you need to upload a CER file (does not contain private key) to the management portal for management API authentication, and use a PFX (contains private key) for signing requests.
When you need to use SSL, you need to upload a PFX file to your hosted service via the management portal, the management API, or you can use a tool like one of Cerebrata's.
We use the following batch file to create our certificate files (replace CAPS_HERE text):
makecert -r -pe -a sha1 -n "CN=CERTIFICATE_NAME_HERE" -ss My -len 2048 -sp "Microsoft Enhanced RSA and AES Cryptographic Provider" -sy 24 CER_FILE_NAME_HERE.cer
makecert -r -pe -n "CN=CERTIFICATE_NAME_HERE" -sky exchange "CER_FILE_NAME_HERE.cer" -sv "PVK_FILE_NAME_HERE.pvk"
pvk2pfx -pvk "PVK_FILE_NAME_HERE.pvk" -spc "CER_FILE_NAME_HERE.cer" -pfx "PVK_FILE_NAME_HERE.pfx" -pi PASSWORD_HERE
Additionally, some links:
http://blogs.msdn.com/b/kaushal/archive/2010/11/05/ssl-certificates.aspx
http://www.lombard.me/2008/03/summary-of-x509-certificate-file-types.html
http://technet.microsoft.com/en-us/library/cc770735.aspx
Another alternative is to download a publishsettings file - this automatically configures a certificate public key in your azure subscription and downloads the cert to your machine.
You can use Get-AzurePublishSettingsFile to download a publishsettings file, or log in at:
https://manage.windowsazure.com/publishsettings/index?client=powershell

TeamCity build agent becomes disconnected after adding self-signed https certificate to teamcity

I added a self-signed certificate to my Teamcity BuildServer to introduce https support so that it can now be accessed at
https://ServerUrl:8443
(More details about how here )
The result was that I was able access the server via https, but my build agent was now disconnected. How to fix this?
The build agent works as a client to the build server and communicates with it using http/https, and it turns out that when you add a self-signed certificate the build agent does not accept it.
I needed to
Let the build agent know the new path for communicating with the server
Let the build agent know that it could trust the self-signed certificate
To change the path I did the following (see this post for more details )
Locate the file:
$TEAMCITY_HOME/buildAgent/conf/buildAgent.properties
Change the property
serverUrl=http:\://localhost\:8080 to your new url
To let the build agent know that it could trust the new certificate I had to import it into the build agent's key store.This was done using keytool:
keytool -importcert -file <cert file>
-keystore <agent installation path>/jre/lib/security/cacerts
( unless you've changed it, the keystore is protected by password: changeit)
The TeamCity team describes this process in slightly more details here
NOTE
If you need to retrieve your certificate from the TeamCity buildserver keystore, you can also use keytool to do this :
keytool -export -alias <alias name>
-file <certificate file name>
-keystore <Teamcity keystore path>
Here is a link to the TeamCity v8 documentation on the keytool.
I was doing this on a Windows Build Agent and had a self-signed SSL cert on my Amazon Linux Build Server. Here were the steps I took:
Went to build server in browser on Build Agent i.e. https://teamcity.example.com
Clicked on the certificate error in the URL and downloaded the cert to the local machine
Exported the certificate from the certificate explorer in windows into a cer file.
Used the keytool exactly as specified in the documentation
> keytool -importcert -file <cert file where it was exported to>
-keystore <path to JRE installation>/lib/security/cacerts
password: changeit
Restarted the build agent and viola!

Using makecert for Development SSL

Here's my situation:
I'm trying to create a SSL certificate that will be installed on all developer's machine's, along with two internal servers (everything is non-production).
What do I need to do to create a certificate that can be installed in all of these places?
Right now I've got something along these lines, using the makecert application in Microsoft Visual Studio 8\SDK\v2.0\Bin:
makecert -r -pe -n "CN=MySite.com Dev" -b 01/01/2000 -e 01/01/2033 -eku 1.3.6.1.5.5.7.3.1 -ss Root -sr localMachine -sky exchange -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12 mycert.cer
However, I'm not sure as to how to place this .cer file on the other computers, and when I install it on my local machine IIS, everytime I visit a page via https:, I get the security prompt (even after I've installed the certificate). Has anyone done this before?
Here are my scripts for doing this:
Create Certificate Authority
Create a self-signed certificate (-r), with an exportable private key (-pe), using SHA1 (-r), for signing (-sky signature).
The private key is written to a file (-sv).
makecert -r -pe -n "CN=My Root Authority" -ss CA -sr CurrentUser ^
-a sha1 -sky signature -cy authority -sv CA.pvk CA.cer
(^= allow batch command-line to wrap line)
Create Server Certificate
Create a server certificate, with an exportable private key (-pe), using SHA1 (-a) for key exchange (-sky exchange).
It can be used as an SSL server certificate (-eku 1.3.6.1.5.5.7.3.1).
The issuing certificate is in a file (-ic), as is the key (-iv).
Use a particular crypto provider (-sp, -sy).
makecert -pe -n "CN=fqdn.of.server" -a sha1 -sky Exchange ^
-eku 1.3.6.1.5.5.7.3.1 -ic CA.cer -iv CA.pvk ^
-sp "Microsoft RSA SChannel Cryptographic Provider" ^
-sy 12 -sv server.pvk server.cer
pvk2pfx -pvk server.pvk -spc server.cer -pfx server.pfx
You then use the .PFX file in your server app (or install it in IIS). Note that, by default, pvk2pfx doesn't apply a password to the output PFX file. You need to use the -po switch for that.
To make all of your client machines trust it, install CA.cer in their certificate stores (in the Trusted Root Authorities store). If you're on a domain, you can use Windows Group Policy to do this globally. If not, you can use the certmgr.msc MMC snapin, or the certutil command-line utility:
certutil -user -addstore Root CA.cer
To programmatically install the certificate in IIS 6.0, look at this Microsoft KB article. For IIS 7.0, I don't know.
You should add -cy authority to the switches when creating the cert authority, otherwise some cert stores won't see it as a proper CA.

Resources