what is the use of "https://expired.badssl.com" ? Can someone explain it to me - ssl-certificate

I am using it in my code as follow. but can't understand what is the use of it.
URL url = new URL("https://expired.badssl.com/");//https://revoked.grc.com/
HttpsURLConnection urlConnection = (HttpsURLConnection)url.openConnection();
urlConnection.setHostnameVerifier(connection.getHostnameVerifier());
urlConnection.setSSLSocketFactory(connection.getSSLContext().getSocketFactory();
LineNumberReader lnr =
new LineNumberReader(new InputStreamReader(urlConnection.getInputStream()));
String line;
while (null != (line = lnr.readLine()))
System.out.println(line);

https://expired.badssl.com/
has expired SSL certificate, used to test edge cases where you may encounter expired certificate while connecting to some website.
You can find more # https://github.com/chromium/badssl.com
It provides other sub-domains as
self-signed.badssl.com to test self signed certificate related edge cases
mixed.badssl.com etc.

Related

Verify user identity on my site, using SSL Certificates

I need to register companies on my site for an electronic procurement system. Up to now these were local companies I could meet physically and give credentials to, but now they can be companies based anywhere in the world.
The solution is to have an online registration process whereby they submit a third party certificate. So say Verisign says they are 'Company X' so I register them as Company X and issue them credentials.
How can I implement this on my site? Do I simply give them a field in the registration form where they upload their certificate file? Do I then manually check these certificates in my back office? How does one check this manually? Is there a way to automate this process?
Once they have an account, should I simply request the credentials I issue them with to log in, or can all future logins request the same certificate file? In these a particular format for certificates I can request or should I allow a number of common formats that different certificate vendors provide?
Thanks in advance.
Being able to provide a certificate does unfortunately not prove anything. A certificate is completely public, and anyone can get a hold of the SSL certificate for any website. The certificate contains a public key. Proving ownership of the corresponding private key is what's required.
This is possible to do, but it requires that your users are technical enough to know how to run scripts and/or OpenSSL terminal commands so that they can sign something with their private key. Having the users upload their private key is of course a big no-no, as it means you can now act as the user, and that would require an enormous amount of trust in you to discard the private key after you've verified it.
From a technical perspective, you can do the verification by creating some kind of challenge, for example a random string, and have the user encrypt this string with their private key. If you decrypt this string with the public key in the certificate, and get the original string back, then you know that they have possession of the corresponding private key.
Here's a self-contained Ruby script that demonstrates this, with comments indicating which part of it is run on your side, and which part is run on their side.
require "openssl"
## This happens on the client side. They generate a private key and a certificate.
## This particular certificate is not signed by a CA - it is assumed that a CA
## signature check is already done elsewhere on the user cert.
user_keypair = OpenSSL::PKey::RSA.new(2048)
user_cert = OpenSSL::X509::Certificate.new
user_cert.not_before = Time.now
user_cert.subject = OpenSSL::X509::Name.new([
["C", "NO"],
["ST", "Oslo"],
["L", "Oslo"],
["CN", "August Lilleaas"]
])
user_cert.issuer = user_cert.subject
user_cert.not_after = Time.now + 1000000000 # 40 or so years
user_cert.public_key = user_keypair.public_key
user_cert.sign(user_keypair, OpenSSL::Digest::SHA256.new)
File.open("/tmp/user-cert.crt", "w+") do |f|
f.write user_cert.to_pem
end
## This happens on your side - generate a random phrase, and agree on a digest algorithm
random_phrase = "A small brown fox"
digest = OpenSSL::Digest::SHA256.new
## The client signs (encrypts a cheksum) the random phrase
signature = user_keypair.sign(digest, random_phrase)
## On your side, verify the signature using the user's certificate.
your_user_cert = OpenSSL::X509::Certificate.new(File.new("/tmp/user-cert.crt"))
puts your_user_cert.public_key.verify(digest, signature, random_phrase + "altered")
# => falase
puts your_user_cert.public_key.verify(digest, signature, random_phrase)
# => true
## On your side - attempting to verify with another public key/keypair fails
malicious_keypair = OpenSSL::PKey::RSA.new(2048)
puts malicious_keypair.public_key.verify(digest, signature, random_phrase)
Note that this script does not take into account the CA verification step - you also obviously want to verify that the user's certificate is verified by a CA, such as Verisign that you mentioned, because anyone can issue a certificate and hold a private key for foo.com - it's the CA signature of the certificate that provides authenticity guarantees.

How to use personal certificate for WCF communication?

When inserting a smart card to a reader the certificates will be read in to the personal store, my question is simple how I then explain for WCF that it should use a specific (of these) certificate in runtime?
My WCF service is selfhosted and are communicating with the client over TCP.
I do already have a communication that uses certificate but these certificates is stated in the config files(one for service and one for client).
Now I need to switch the certificate on the client side before communicating.
You should try to find a specific set of attributes that is unique to the certificate you would like to use.
For example we use filtering like this:
/// <summary>
/// Get the certificate we need for authentication
/// </summary>
/// <returns>the certificate</returns>
/// <exception cref="InvalidOperationException">when no certificate is available</exception>
public static X509Certificate2 GetCertificate()
{
// open private certificate store of the user
X509Store store = new X509Store(StoreName.My);
store.Open(OpenFlags.ReadOnly);
// get the collection of certificates which we need
X509Certificate2Collection certColl = store.Certificates
.Find(X509FindType.FindByExtension, new X509KeyUsageExtension().Oid.Value, false)
.Find(X509FindType.FindByKeyUsage, X509KeyUsageFlags.NonRepudiation, false);
store.Close();
// if more certificates match the criteria, let the user choose one
if (certColl.Count > 1)
{
certColl = X509Certificate2UI.SelectFromCollection(
certColl, "Choose certificate", "We were unable to find the correct certificate. Please choose one from the list.",
X509SelectionFlag.SingleSelection);
}
// if no certificate is available, fail
if (certColl.Count < 1)
{
throw new InvalidOperationException("No certificates selected");
}
else
{
return certColl[0];
}
}
Check the attributes of the certificates you need and try to create your own Find criteria. Of course the use could have additional certificates in his store which match the criteria, this case a dialog window pops up and asks the user to do this himself.
Of course once the user chooses the correct certificate you can store the CN of the certificate in the application configuration file so next time he won't have to do these steps again.

X.509 certificate can't find with "FindBySubjectName"

After a brutal struggle with WCF Security, I think I'm at the final stage now and can see the light.
I've got a Client certificate installed on my server, and is now, as advised, in the Trusted People folder of the certificate store.
However, when I try and read the certificate application -> service, I get this error:
Cannot find the X.509 certificate using the following search criteria: StoreName 'My', StoreLocation 'CurrentUser', FindType
'FindBySubjectName', FindValue 'Forename Surname'.
With the "Forename Surname" being the "Issued to" part of my certificate. In all tutorials I have seen, this is just one word; is this the problem? I received my certificate from my CA with these two words, with a space.
Anyone ever come across this, is there something I'm blatantly doing wrong?
Update, cert can be seen here:
Update:
It gets even more strange:
I installed Visual Studio on my web server, and used the following code to pick up the cert by Thumbprint:
var store = new X509Store(StoreName.TrustedPeople, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
var certs = store.Certificates.Find(X509FindType.FindByThumbprint, "71995159BFF803D25BFB691DEF7AF625D4EE6DFB", false);
This actually RETURNS a valid result. When I put this information into the web.config of my service/client though, I still get the error.
I think..You installed certificate at location Trusted People and searching at store name my
var store = new X509Store(StoreName.TrustedPeople, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
var certs = store.Certificates.Find(X509FindType.FindBySubjectDistinguishedName, certificateSubject, false);
Also there are two search terms FindBySubjectName or FindBySubjectDistinguishedName, the later is more relevant with keywords and first one will find anything with search keywords.
So basically you need to look for Subject and if you use above code then your search string would be .."CN=urs.microsoft.com, O=DO_NOT_TRUST, OU=Created by http://fiddler2.com"
https://i.stack.imgur.com/QtYvV.png
private X509Certificate2 GetCertificateFromStore()
{
var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
var certCollection = store.Certificates;
var currentCerts = certCollection.Find(X509FindType.FindBySubjectDistinguishedName, "CN=sf.sandbox.mapshc.com", false);
return currentCerts.Count == 0 ? null : currentCerts[0];
}

cxf failover recovery

I have a cxf JAX-WS client. I added the failover strategy. The question is how the client can recovery from the backup solution and use again the primary URL? Because now after the client will switch to secondary URL remains there, will not use the primary URL even if this become available again.
The code for the client part is:
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setServiceClass(GatewayPort.class);
factory.setAddress(this.configFile.getPrimaryURL());
FailoverFeature feature = new FailoverFeature();
SequentialStrategy strategy = new SequentialStrategy();
List<String> addList = new ArrayList<String>();
addList.add(this.configFile.getSecondaryURL());
strategy.setAlternateAddresses(addList);
feature.setStrategy(strategy);
List<AbstractFeature> features = new ArrayList<AbstractFeature>();
features.add(feature);
factory.setFeatures(features);
this.serviceSoap = (GatewayPort)factory.create();
Client client = ClientProxy.getClient(this.serviceSoap);
if (client != null)
{
HTTPConduit conduit = (HTTPConduit)client.getConduit();
HTTPClientPolicy policy = new HTTPClientPolicy();
policy.setConnectionTimeout(this.configFile.getTimeout());
policy.setReceiveTimeout(this.configFile.getTimeout());
conduit.setClient(policy);
}
You may add the primary URL to the alternate addresses list instead of setting that to JaxWsProxyFactoryBean. This way, since you are using SequentialStrategy, the primary URL will be checked first for every service call, if it fails then secodary URL will be tried.
You might as well try an alternative CXF failover feture with failback.
https://github.com/jaceko/cxf-circuit-switcher

Error getting twitter request token using OAuth and PEAR Services_Twitter

I am moving from the basic authentication method using username
and password to the OAuth based authentication.
I was using an old version of the pear package Services_Twitter, that
did not support OAuth.
The latest version of this package supports OAuth authentications, it
has a few dependencies (HTTP_Request2, HTTP_OAuth).
It was very simple to install them and upgrade the package. I did all
this my local machine and had no trouble getting the authentication up
and running.
I committed this code to the test site, but every time the code
request a "request token" I get the following error message "Unable to
connect to ssl://api.twitter.com:443. Error #0"
I have spend 6 hours making sure that all the pear packages where up
to date, checking the customer token and token secret, making sure
port 443 is not closed... in addition to various other test.
I have exhausted my resources and I come to you in hope to find some
answers.
Thank you
PD: One of the things I do not understand is why does the message says
that the url is ssl://api.twitter.com:443 rather than
https://api.twitter.com/request_token? the former one is the one I am
using to get the request token.
"Unable to connect to ssl://_______:443. Error #0" generally means that there is a ssl_verify_peer or certificate match issue - and the twitter API doesn't require you to provide a certificate!
HTTP_Request2 sets the ssl_verify_peer option to true by default - which is fine if you are specifying a certificate for establishing a connection so perhaps you need to check that setting is switched off?
This is checked for you in Services_Twitter if the use_ssl config setting is enabled so at a guess you may need to check that is set?
e.g.:
$twitter = Services_Twitter_factory('statuses/update', true, array('use_ssl' => true));
Here is the implementation of the code for kguest answer.
$httpRequest = new HTTP_Request2( null,
HTTP_Request2::METHOD_GET ,
array ('ssl_verify_peer' => false,
'ssl_verify_host' => false)
);
$httpRequest->setHeader('Accept-Encoding', '.*');
$request = new HTTP_OAuth_Consumer_Request;
$request->accept($httpRequest);
$oauth = new HTTP_OAuth_Consumer('twitterConsumerKey','twitterConsumerSecret');
$oauth->accept($request);
$oauth->getRequestToken('https://api.twitter.com/oauth/request_token',
"path/to/call/back/file.php");
$_SESSION['token'] = $oauth->getToken();
$_SESSION['token_secret'] = $oauth->getTokenSecret();
$authorize_link_twitter = $oauth->getAuthorizeUrl('https://api.twitter.com/oauth/authorize');
and something very similar was done to get the access token once you get back from twitter.
$httpRequest = new HTTP_Request2( null,
HTTP_Request2::METHOD_GET ,
array ('ssl_verify_peer' => false,
'ssl_verify_host' => false)
);
$httpRequest->setHeader('Accept-Encoding', '.*');
$request = new HTTP_OAuth_Consumer_Request;
$request->accept($httpRequest);
$oauth = new HTTP_OAuth_Consumer('twitterConsumerKey',
'twitterConsumerSecret',
$_SESSION['token'],
$_SESSION['token_secret']);
$oauth->accept($request);
$oauth->getAccessToken('https://api.twitter.com/oauth/access_token',
$_GET['oauth_verifier']);
// you can get the final tokens like this.
$oauth->getToken());
$oauth->getTokenSecret();
All the credit goes to kguest for the idea that lead to the solution of this problem. this is just the code.
Checkout this bug report http://pear.php.net/bugs/bug.php?id=18061 I have added resources to solve the issues of SSL and the Services_Twitter package.
But basically you should follow the instructions at http://curl.haxx.se/docs/sslcerts.html
Disabling ssl_verify_peer and ssl_verify_host makes you vulnerable to the security attacks that SSL tries to solve ( Verifying peer in SSL using python ). So don't ;)