Azure : Point to Site, from the Certificate Authority, what kind of certificates should be requested? - ssl

As a part of the POC, I followed the article https://www.ais.com/how-to-configure-point-to-site-vpn-connection-using-azure-certificate-authentication/ and configured Point-to-Site.
In summary: I have created the Root & Client Certificate and configured the Virtual Gateway
Here we are generating the root certificate
$cert = New-SelfSignedCertificate -Type Custom -KeySpec Signature -Subject "CN=VPNRoot" -KeyExportPolicy Exportable -HashAlgorithm sha256 -KeyLength 2048 -CertStoreLocation "Cert:\CurrentUser\My" -KeyUsageProperty Sign -KeyUsage CertSign
Here we are generating the client certificate from the root certificate
New-SelfSignedCertificate -Type Custom -DnsName VPNCert -KeySpec Signature -Subject "CN=VPNCert" -KeyExportPolicy Exportable -HashAlgorithm sha256 -KeyLength 2048 -CertStoreLocation "Cert:\CurrentUser\My" -Signer $cert -TextExtension #("2.5.29.37={text}1.3.6.1.5.5.7.3.2")
Now that it works, my goal is to replace the certificates ("Root" and "Client") with production ready certificates.
From the Certificate Authority, what kind of certificates should be requested?
Note: Our Azure Tenant is something like xyznp.onmicrosoft.com

Note that In Azure Point to Site, you can use a root certificate that was generated using an Enterprise solution, or you can generate a self-signed certificate.
Refer : About Azure Point-to-Site VPN connections - Azure VPN Gateway
When you are using the enterprise solution certificate chain in the root certificate, you should acquire the .cer file for the root certificate that want to use.
And generate a client certificate with the common name value format name#yourdomain.com. In your case it should be in the format xyznp#onmicrosoft.com
Refer : Connect to a VNet using P2S VPN & certificate authentication: portal - Azure VPN Gateway
NOTE : Verify the authentication order on the client certificate if you used a certificate that was issued by an Enterprise CA solution and but having trouble for authenticating.
By double-clicking the client certificate, choosing the Details tab, and then selecting Enhanced Key Usage, you can verify the authentication list order like below.
Make sure Client Authentication is listed first. If it isn't, create a client certificate based on the user template with Client Authentication listed as the first item.
Refer: Connect to a VNet using P2S VPN & certificate authentication: portal - Azure VPN Gateway

Related

Setting up client side certificate for mutual authentication

I am trying to set up 2 way ssl mutual authentication for my web application. I currently haven't set up my client and am testing my web service through my browser.
I created a client certificate using the keychain tool on my mac and import the certificate.p12 file in Firefox. I also have a certificate.cert file. From my understanding I need to add this cert file in my servers truststore.
For that I need to using the following command:
keytool -import -trustcacerts -alias <hostname of DP> -file <your file.crt> -keystore <truststorefile>
However what do I add as the hostname of my system? What will the browser show the hostname as to my webserver?
First if you have client cert(s) issued by either a well-known CA (like Verisign, GoDaddy, etc) or a locally-trusted one (like your employer), you don't have to do anything. The client will simply present the cert with a chain that leads to the already-trusted CA.
If you have issued client certs from your own CA, you should add the CA (root) cert only to the server truststore. Then all client certs issued by that CA will be validated without further effort. If you make the CA cert long-lived, as is the usual practice, you can even renew and/or replace client certs with no effort on the server. And you can automatically revoke them if you set up CRL distribution and/or OCSP, although DIY CAs don't always want to go to that effort.
If you have created a self-signed client cert, then and only then you need to add that specific cert to the server truststore. Although SSL/TLS server certs must be identified by the hostname(s) of the server, client certs are not required to, and CA certs (which are the certs usually in your truststore by default) never have a hostname as the Subject (although some extensions usually contain URLs that contain hostnames). Codesigning certs also don't need to use a hostname.
The alias of a cert entry in a Java truststore does not need to be the hostname; it only needs to be unique, although it should be mnemonic of the subject of the cert. If for example your client certs are for users named Alice and Bob (or more likely their PCs or whatever devices) you can just use alice and bob as the aliases.

CA certificate to connect to MQTT server over TLS - iot.eclipse.org

I want to connect to ssl://iot.eclipse.org:8883 using Client certficate authentication.
How I can obtain CA certificate?
Do I require to generate my own client certificate with provided CA certificate.
Or client certificate is also bundled along with CA certificate.
Using openssl to check it appears that the certificate for iot.eclipse.org is from the Let's Encrypt project.
$ openssl s_client -showcerts -connect iot.eclipse.org:8883CONNECTED(00000003)
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
0 s:/CN=iot.eclipse.org
i:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
-----BEGIN CERTIFICATE-----
So you should be able to check this certificate is valid with the standard CA set in most modern OS/Applications.
You will not be able to get hold of the CA cert/private key to generate your own client certs for obvious reasons and they do not issue client certificates ( and that is assuming that the eclipse.org broker is set up to authenticate clients with the same CA, it doesn't have to).
Also it doesn't make sense to authenticate against this broker as you have no way to set an ACL to control which users can subscribe/publish to specific topics as it's a public demonstration broker. If you want to secure access then you will have to run your own public broker
EDIT: You don't want to do client certificate authentication, you just want to verify the server cert, this is very different.
To do this with mosquitto_pub or mosquitto_sub you have to specify a CA cert or a path to a directory of multiple certificates in order to enable ssl/tls for the connection. You would specify an individual CA cert if you were using a private CA, but since the iot.eclipse.org broker is using a well known public CA you need to specify the path to the system collection of CA certs.
On Linux that is /etc/ssl/certs so you would publish as follows:
mosquitto_pub -h iot.eclipse.org -p 8883 --capath /etc/ssl/certs/ -t testing/ben -m foo
If a certificate is like a passport which proves your identity, then CA is just like a passport office(1). You could consider Verisign, Entrust etc as passport offices. CA certficate is analogous to passport office providing a way to check if a passport is valid or not.
To prove their identity any two parties,( read server and client ), could use certificates. To verify the authenticity of a party( read server ), you need CA certificate. Linux system(Ubuntu) holds commonly used CA certificates at /etc/ssl/certs.
A client certificate is needed only if you need to authenticate yourself to the server. Here server is iot.eclipse.org which doesn't ask for client authentication and so you don't need client certificate.
So, to communicate securely with server ( read TLS ), you can use the CA store present in your system(Ubuntu) as below.
mosquitto_pub -h iot.eclipse.org -p 8883 -t my_topic -m my_message --capath /etc/ssl/certs/

SSL client verification failure

I have a backend server with SSL only as defaut public interface. This server listens on 443 with cert, key and ca files on, ssl verify client is set to true.
On client side, I have client cert, key and a ca file made of 2 CA files catted together (intermediate CA, root CA) in a single ca.pem file. When I do curl request on my backend server, it works fine. I also tested the server / client cert and key with gnutls-serv and openssl s_server to ensure all was valid.
But when I create a keystore on Apigee (client cert and key file [pem format]) and a trustore (ca.pem file), there is an error:
- target.name fsbca-test
- Properties
- Expression ("fsbca-test" equals target.name)
- ExpressionResult true
- Tree TARGET_fsbca-test
- error The Service is temporarily unavailable
- error.cause General SSLEngine problem
- error.cause.cause General SSLEngine problem
- error.class com.apigee.messaging.adaptors.http.HttpAdaptorException
- state TARGET_REQ_FLOW
- type ErrorPoint
If I put SSL verify client to false on my backend, then the request is correctly diverted by Apigee and I get the response.
If I put IgnoreValidationErrors to true in the target endpoints property, then the request is diverted to my backend server but I can see an error in the server's log: "client sent no required SSL certificate while reading c...".
Any ideas about what could be wrong in what I am doing?
Additional track: could it be an issue on Apigee side with the CA file made of 2 certs (it may ignore trailing certificates found in a .pem). If wanted to test pkcs12 and jks but I failed to upload them to Apigee (the API doc page only describes .pem, JAR and cert action). I wrote a small Java client with pkcs12 keystore and jks trustore and it worked fine from my local workstation.
Thank you in advance for any piece of information that could help me.
Regards
Fr
You should upload your certificates separately (one per cert), and you need the entire trust chain of certificates to be stored in your truststore.
Here is the page about SSL to your backend.
EDIT:
Here is a method I know works:
1) Separate certs into separate PEM files. Do not put more than once cert in a file.
2) Validate each cert using openssl:
openssl x509 -noout -text -in <cert file name>
Validate that no certs are expired, and that the Subject and Issuer fields create a chain of all the certs, with identical names.
The server's certificate, the root certificate, and all certificates in between need to be in the truststore.

WCF error "The X.509 certificate chain building failed" despite trusted root CA

I'm getting the error mentioned in this question:
The X.509 certificate CN=Farm chain building failed. The certificate that was used has a trust chain that cannot be verified. Replace the certificate or change the certificateValidationMode. A certificate chain processed, but terminated in a root certificate which is not trusted by the trust.
What I don't understand why I'm getting this error as the certificate I use for my request to the WCF service is added as shown below:
client.ClientCredentials.Peer.PeerAuthentication.CertificateValidationMode =
X509CertificateValidationMode.ChainTrust;
client.ClientCredentials.ClientCertificate.SetCertificate(
StoreLocation.CurrentUser,
StoreName.My,
X509FindType.FindBySerialNumber,
"MyCertificatesSerialNumber" );
The certificate itself is a self-signed certificate in the store shown above. When I click on it to show the certification path, no errors are shown (the root certificate is also a self-signed certificate). The root certificate was manually imported into the trusted root certification authorities.
From the error message I would have expected that there was an error in the certification chain with one of my certificates, but there isn't. Any ideas?
Update
I'm using Internet Explorer 9 as my browser to access the webservice. Programmatically I'm using a C# console application.
I had exactly the same problem - my own trusted root CA which signed another certificate. No errors were shown in the certificate store.
It turned out that having a trusted root CA and a certificate is not sufficient! You also need a certificate revocation list! Take a look at this MSDN Link.
So simply create such a .crl and add it also to the trusted root certificate authorities and everything works fine!
makecert -crl -n "CN=CARoot" -r -sv CARoot.pvk CARoot.crl
or simply turn of the revocation list check:
...RevocationMode = X509RevocationMode.NoCheck;
I had this problem - this is what I'd suggest:
On the server, make sure that the root cert is located on the "local computer" side of the computer, not "Current User". The other thing is that the SSL cert needs to be derived from the root cert. I eventually got it all to work using a script that included these lines:
rem creates root authority file and cert in localmachine\root and gives it the right to sign certs
makecert.exe -a sha1 -n CN=RootCert RootCertName -sr LocalMachine -ss Root -sky signature -pe -r -sk MyNewKey -cy authority
rem creates ssl cert, puts it in the currentuser\Personal store, signing it based on the root cert
makecert.exe -n cn=HostURL SSLCertName -is root -ic RootCertName -sky exchange -pe -sv SSLCertPrivateKeyName -eku 1.3.6.1.5.5.7.3.1
It's complicated, tedious stuff. You just have to keep at it.
I faced a similar issue while trying to connect to a self hosted WCF service using net.tcp binding. I already had the self signed root CA certificate installed in the CurrentUser certificate store, client was using a certificate signed by the root CA cert.
Installing the root CA certificate in LocalComputer certificate store fixed the error "A certificate chain could not be built to a trusted root authority". My WCF Server process runs using current user account hence this step was not obvious.
The next error was "The revocation function was unable to check revocation for the certificate"
To fix this, I created an empty Certificate Revocation List for the root CA cert and then installed the CRL in the LocalComputer certificate store. (Please check this link for details : https://msdn.microsoft.com/en-us/library/ff648732.aspx)
I also set the revocation check mode to Offline for both server and client certificates.
defaultCredentials.ServiceCertificate.Authentication.RevocationMode = X509RevocationMode.Offline;
defaultCredentials.ServiceCertificate.Authentication.CertificateValidationMode =
X509CertificateValidationMode.ChainTrust;
Now I don't have to turn off certificate validation or use different validation mode for development (In my case production code will also use self signed certificates for the time being)

Is it possible to force the WCF test client to accept a self-signed certificate?

I have a WCF web service running in IIS 7 using a self-signed certificate (it's a proof of concept to make sure this is the route I want to go). It's required to use SSL.
Is it possible to use the WCF Test Client to debug this service without needing a non-self-signed certificate?
When I try I get this error:
Error: Cannot obtain Metadata from
https:///Service1.svc
If this is a Windows (R) Communication
Foundation service to which you have
access, please check that you have
enabled metadata publishing at the
specified address. For help enabling
metadata publishing, please refer to
the MSDN documentation at
http://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata
Exchange Error URI:
https:///Service1.svc
Metadata contains a reference that
cannot be resolved:
'https:///Service1.svc'.
Could not establish trust relationship
for the SSL/TLS secure channel with
authority ''. The
underlying connection was closed:
Could not establish trust relationship
for the SSL/TLS secure channel. The
remote certificate is invalid
according to the validation
procedure.HTTP GET Error URI:
https:///Service1.svc
There was an error downloading
'https:///Service1.svc'.
The underlying connection was closed:
Could not establish trust relationship
for the SSL/TLS secure channel. The
remote certificate is invalid
according to the validation procedure.
EDIT: This question is specifically about using the WCF Test Client to test a web service already secured via SSL using a self-signed certificate. The server is already set up to accept any certificate provided, it's the WCF Test Client I don't see a way to do this for.
You can create a non self-signed certificate in development area and then use this certificate in IIS for applying the SSL. The steps are:
Create self-signed certificate
makecert -r -pe -n "CN=My Root Authority" -a sha1 -sky signature
-ss CA -sr CurrentUser
-cy authority
-sv CA.pvk CA.cer
Create a non self-signed certificate for SSL which signed by this root certificate and then create pfx-file from that
makecert -pe -n "CN=servername" -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
now you just need to import the server.pfx into the IIS and setup the web site binding to use this certificate and also install the CA.cer in Local Computer \ Trusted Root Certification Authorities store in both server and client by doing this WCF client would work with the service through HTTPS without any problem.
you should be able to do this if you replace the WCF Test Client with WCFStorm Lite Edition. It's free and is quite a bit more flexible than MS's test client... for example, it'll let you specify a user name & password if you're doing username authentication.
The answer from this question helped in my case. Be sure to use exact machine name as certificate expects. For exampe machine/service.svc may not work, while machine.domain/service.svc - works.
To answer your question... here is how you force your WCF test client to accept a self-signed certificate...
using (ServiceReference1.Service1Client proxy = new ServiceReference1.Service1Client())
{
System.Net.Security.RemoteCertificateValidationCallback callBack = (sender, certificate, chain, sslPolicyErrors) => true;
ServicePointManager.ServerCertificateValidationCallback += callBack;
Console.WriteLine(proxy.GetData(35));
ServicePointManager.ServerCertificateValidationCallback -= callBack;
}
Yes it is possible.
Just download the generated WSDL from the service (https://localhost/Service1.svc?singleWsdl) and supply the path to this file when adding a service in the WCF Test Client.
You can supply your own method to validate the certificate.
Try this:
ServicePointManager.ServerCertificateValidationCallback +=
new System.Net.Security.RemoteCertificateValidationCallback(EasyCertCheck);
The call back:
bool EasyCertCheck(object sender, X509Certificate cert,
X509Chain chain, System.Net.Security.SslPolicyErrors error)
{
return true;
}