I am trying to write a certificate managing application for an embedded system running on Linux using OpenSSL. I was able to implement certificate verification using my own certificate store. I am stuck at generating my own certificate revocation list and adding certificates to that certificate revoking list.
Here is how I verify certificates
do
{
store=X509_STORE_new();
if(NULL == store)
{
status = EOUTOFMEMORY;
break;
}
X509_STORE_set_default_paths(store);
vrfy_ctx = X509_STORE_CTX_new();
X509_STORE_CTX_init(vrfy_ctx, store, certificate, NULL);
*verifResult = X509_verify_cert(vrfy_ctx);
} while(0);
Can anyone please help me regarding creating a CRL file using C and adding certificates to it?
Related
With a windows desktop app, I am trying to access Exchange calendar resources using confidentialClientApplicationBuilder using the WithCertificate option. When we call AcquireTokenForClient, we get a Microsoft.Identity.Client.MsalException "The provided certificate has a key that is not accessable."
When we use WithClientSecret option it works fine.
On the client side, the certificate is obtained from one of our DLLs that is code signed with our code signing certificate. On the Azure side, our code signing cert (PFX) is converted to CER (using Windows Credential manager import/export) and then uploaded to our app registration on the "Certificates and Secrets" page. When I debug, the certificate thumbprint extracted from the DLL matches the thumbrpint of the cert loaded into Azure.
Here is the code:
assemblyPath = #"C:\Programs\MyProgramLibrary.dll";
var cert = X509Certificate.CreateFromSignedFile(assemblyPath);
var cert2 = new X509Certificate2(cert);
_Application = ConfidentialClientApplicationBuilder.Create(QuicklaunchAzureAppRegistration.ClientId())
.WithCertificate(cert2)
.WithAuthority(new Uri(string.Format(msalAuthFormat, TenantId)))
.Build();
result = await _Application.AcquireTokenForClient(_Scopes).ExecuteAsync();
I Is it complaining about the certificate on the client side or the server side or both? What Key is it looking for? Can a code signing certificate be used?
From what you're saying, it sounds like on the client side. it sounds like the client side needs access to the private key which it doesn't seem to be able to .
and yes a code signing certificate i believe must be used. here's an example of it working with a self signed cert: https://github.com/Azure-Samples/active-directory-dotnetcore-daemon-v2/tree/master/2-Call-OwnApi#optional-create-a-self-signed-certificate
I want to use SSl certificates in codename one.Currently I am using below code for connecting to server
ConnectionRequest req = new ConnectionRequest();
req.setUrl("http:/something");
But I want to use https instead of http.I want to import customize SSL certificates and want to use it in my app.
How to import and use SSL certificates ?
You should just change this to HTTPS but you can't use a custom (invalid) SSL certificate. Your certificate must be valid and must be from a valid certificate authority for it to work.
If this is just for debugging you can add your debugging certificate to the device in the device settings which usually allows you to customize the root certificates.
I would want my C/C++ client to authenticate the server via SSL.
I first downloaded the certificate file from the server with
openssl s_client -showcerts -connect www.openssl.org:443 </dev/null 2>/dev/null | openssl x509 -outform PEM > mycertfile.pem
Then in my application I do the following API invocations (pseudo code):
// Register the error strings for libcrypto & libssl
SSL_load_error_strings();
// Register the available ciphers and digests
SSL_library_init();
// New context saying we are a client, and using SSL 2 or 3
ctx = SSL_CTX_new(SSLv23_client_method());
// load the certificate
if(!SSL_CTX_load_verify_locations(ctx, "mycertfile.pem", 0))
...
// Create an SSL struct for the connection
ssl = SSL_new(ctx);
// Connect the SSL struct to our pre-existing TCP/IP socket connection
if (!SSL_set_fd(ssl, sd))
...
// Initiate SSL handshake
if(SSL_connect(ssl) != 1)
...
// form this point onwards the SSL connection is established and works
// perfectly, I would be able to send and receive encrypted data
// **Crucial point now**
// Get certificate (it works)
X509 *cert = SSL_get_peer_certificate(ssl);
if(cert) {
// the below API returns code 19
const long cert_res = SSL_get_verify_result(ssl);
if(cert_res == X509_V_OK) {
printf("Certificate verified!\n");
}
X509_free(cert);
}
Above code works fine if I don't mind checking the certificate and I'm just interested in an encrypted connection.
Problem with it is that when I try to verify the authenticity of the server, I do get the certificate from SSL_get_peer_certificate but then the verification of results doesn't work even if I've just downloaded the certificate 5 minutes before.
What am I doing wrong?
All this is on Ubuntu 12.04.03 x86-64 with gcc and openssl.
Thanks,
Ema
You should only call SSL_CTX_load_verify_locations() if you have a more complete set of CA certificates than what OpenSSL already provides, or if you are connecting to a server that has used a non-standard CA to sign its cert, and for which you have the CA certificate to verify the server cert. Otherwise, you should call SSL_CTX_set_default_verify_paths() instead.
// load the certificate^H^H^H^H^H^H^H^H^H^H^H^H CA trust-store
if(!SSL_CTX_set_default_verify_paths(ctx))
...
On a side note, your program had another error. You passed the wrong pointer to SSL_get_verify_result(). Instead of passing in a SSL_CTX *, you should pass in the SSL *. The compiler should have warned you about this error.
const long cert_res = SSL_get_verify_result(ssl);
The certificate you just downloaded should have been signed by a certificate authority (CA). You need to load the certificate of the CA (or the root CA) and not the certificate itself. Since you loaded the server's certificate directly into the SSL_CTX_load_verify_locations, the verification routine SSL_get_verify_result returned with a failure code. Most likely the verification code must have been 19 (X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN).
That said, OpenSSL comes with a built-in set of CAs (and root CAs) that you can use in your client application. The path to these certificates, on a Linux distribution, is typically /etc/ssl/certs. So, you can try changing your SSL_CTX_load_verify_locations as below:
if (!SSL_CTX_load_verify_locations(ctx, NULL, "/etc/ssl/certs"))
...
Of course, this assumes that /etc/ssl/certs exists and has the relevant certificates (one of which signed the server certificate). If you are authenticating a well known host, you will most likely find the CA in /etc/ssl/certs.
I have written a SOAP client using OpenSSL on Linux. I basically did some information gathering from OpenSSL website and other online resources and the following code summarises how I send the XML to the SOAP server.
SSL_library_init();
SSL_load_error_strings();
ERR_load_BIO_strings();
OpenSSL_add_all_algorithms();
SSL_CTX* ctx = SSL_CTX_new(SSLv23_client_method());
SSL* ssl;
BIO* bio = BIO_new_ssl_connect(ctx);
if (bio == NULL) {
SSL_CTX_free(ctx);
return false;
}
BIO_get_ssl(bio, &ssl);
SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
char target[] = "api.betfair.com:https";
BIO_set_conn_hostname(bio, target);
BIO_set_nbio(bio,1);
while (1) {
if (BIO_do_connect(bio) <= 0) {
if (!BIO_should_retry(bio)) {
cout << "Connect failed." << endl;
BIO_free_all(bio);
SSL_CTX_free(ctx);
return false;
}
} else {
break;
}
}
KeepAliveReq KeepAliveReq(sessionTok,0,iMode);
string strMessage = KeepAliveReq.GetXML(false);
BIO_puts(bio,strMessage.c_str());
This works well enough and has been reliable (if somewhat slow) for a number of weeks. I intentionally omitted the certificate checking phase of the SSL handshake process because at the time I did not really understand the details of it and the server I am sending to is of a well known company. My question is can I assume that my data is being encrypted by the SSL code or not? As far as I can make out from my code, I am not explicitly asking for encryption to occur, I am assuming that this simply occurs as part of the SSL communication process. Has my omission of certificate checking compromised the security of my application with regards to encryption?
Your data is still being encrypted—but the question is, to whom?
The certificate checking process is where we verify that the other party is who they claim to be. When someone orders an SSL certificate, the company who distributes the certificate will undertake measures to ensure they're giving the certificate and key to the rightful owner of the domain (or other entity) it's being ordered for. That company will then sign the certificate with their own details, which in turn are signed by a company your computer already trusts.
When you establish an connection, your computer checks the links to ensure that the certificate is legitimate, i.e. it's been signed by someone your computer trusts (perhaps indirectly through several layers of trust).
Skipping this process means anyone could generate a certificate on their own computer for any given website. Assuming they can then hijack connections you make, they can cause your system to believe it's the well-known company with ease.
You need to check the certificate to be secure.
I am using libcurl in my C application to communicate with an HTTPS server that I have set up. I generated a self-signed certificate on that server that I wish to use with curl.
I am aware of setting CURLOPT_SSL_VERIFYPEER to 0 to bypass the SSL verification, but I wish to add the generated certificate to curl's "valid" CA certificates.
I have tried setting CURLOPT_CAPATH and CURLOPT_SSLCERT to the location of the server SSL public key, but it fails to pass the verification.
How can I add my own CA/Self-signed certificate so that libcurl will successfully validate it?
To add a self-signed certificate, use CURLOPT_CAINFO
To retrieve the SSL public certificate of a site, use
openssl s_client -connect www.site.com:443 | tee logfile
The certificate is the portion marked by ----BEGIN CERTIFICATE---- and
---END CERTIFICATE----.
Save that certificate into a file, and use curl in a manner like so:
CURL* c = curl_easy_init();
curl_easy_setopt(c, CURLOPT_URL, "https://www.site.com");
curl_easy_setopt(c, CURLOPT_CAINFO, "/path/to/the/certificate.crt");
curl_easy_setopt(c, CURLOPT_SSL_VERIFYPEER, 1);
curl_easy_perform(c);
curl_easy_cleanup(c);
First, you kind of mix "Certificate Authority" files and "Certificate" files which confuses me.
How can I add my own CA/Self-signed certificate so that libcurl will
successfully validate it?
This might be seen as a complementary answer to the one above.
In the case you want to add a self-signed CA (every root-CA is self-signed) so that libcurl will successfully validate a website's certificate, which has been generated by the CA, then continue reading.
With CURLOPT_CAINFO you need to pass the "Certificate Authority" file (CA) that was used when generating the (non-CA) certificate of the site you want to verify.
(I do not know if this option works by passing it a non-CA certificate, the documentation is not really clear on this, and the previous answer has 2 up-votes, so if anyone has tested it please comment)
You can also pass a Certificate Authority chain file that contains the CA that was used, in case it was not a root-CA.
Here's a little tutorial I've found that can help you test your solution:
Creating a private root CA:
http://www.flatmtn.com/article/setting-openssl-create-certificates
Creating a site certificate:
http://www.flatmtn.com/article/setting-ssl-certificates-apache