[openssl-users] Certificate gets verified OK over SSL-CLI, but not when using SSL-API

Manuel Wagesreither ManWag at FastMail.FM
Thu Dec 21 11:42:52 UTC 2017


Dear all,

I'm struggling with programatically verifying a certificate which is solely stored in memory, i. e. not on the file system. The certificate and the CA seem to be fine though, because when I extract them from memory and store them as a file, and use the `openssl verify`, verification is successful. Hence I suspect my code is faulty.

Unfortunately, I'm under the impression that validating certificates which exist solely in memory is a niche application. I was yet not able to find a comprehensive tutorial or even a code sample on the internet. Hence, I hope you can help me.

Below I'm posting my sample code. (I have stripped the certificate and CA raw data, tough.) It can be compiled an run under a GNU/Linux system.
When this code is run, OpenSSL emits a "certificate signature failure" with an error depth of 0.

Thanks a lot!
Manuel

============

#include <openssl/x509.h>
#include <stdexcept>
#include <iostream>

unsigned char g_authority[] = {	0x30, 0x82, 0x03, 0x00 /* and so on */ };
unsigned char g_cert[] = { 0x30, 0x82, 0x02, 0x9b /* and so on */ };

int main(int, char**)
{
	// This holds the return codes and gets reused for most function calls
	int rc = 0;

	// Make a new store
	X509_STORE *x509_store = X509_STORE_new();
	if (x509_store == NULL) {
		throw std::runtime_error("X509_STORE_new() failed");
	}

	// Load and convert the authoritys certificate to a compatible form
	X509 *auth_cert = NULL;
	{
		const unsigned char* auth_cert_ptr = g_authority;
		auth_cert = d2i_X509(NULL, &auth_cert_ptr, sizeof(g_authority));
		if (auth_cert == nullptr) {
			throw std::runtime_error("d2i_X509() failed for authoritys certificate");
		}
	}

	// Add the authoritys certificate to the store
	rc = X509_STORE_add_cert(x509_store, auth_cert);
	if (rc != 1) {
		throw std::runtime_error("X509_STORE_add_cert() failed");
	}

	// Make a new store context
	X509_STORE_CTX *x509_store_ctx = X509_STORE_CTX_new();
	if (x509_store_ctx == NULL) {
		throw std::runtime_error("X509_STORE_CTX_new() failed");
	}

	// Load and convert the certificate to be verified to a compatible form
	X509 *myself = NULL;
	{
		const unsigned char *my_cert_ptr = g_cert;
		myself = d2i_X509(NULL, &my_cert_ptr, sizeof(g_cert));
		if (myself == NULL) {
			throw std::runtime_error("d2i_X509() failed for own certificate");
		}
	}

	rc = X509_STORE_CTX_init(x509_store_ctx, x509_store, myself, NULL);
	if (rc != 1) {
		throw std::runtime_error("X509_STORE_CTX_init() failed");
	}

	rc = X509_verify_cert(x509_store_ctx);

	X509_STORE_free(x509_store);
	X509_STORE_CTX_free(x509_store_ctx);

	if (rc > 0) {
		std::cout << X509_verify_cert_error_string(X509_STORE_CTX_get_error(x509_store_ctx)) << std::endl;
		return 0;
	} else {
		std::cerr << X509_verify_cert_error_string(X509_STORE_CTX_get_error(x509_store_ctx)) << std::endl;
		std::cerr << "Error depth: " << X509_STORE_CTX_get_error_depth(x509_store_ctx) << std::endl;
		return 1;
	}
}


More information about the openssl-users mailing list