Hi-

I'm having trouble with the d2i_X509() call. I've googled all the errors that I get and I can't figure out what's going on.
I'm using OpenSSL 0.9.7d.


Basically, I'm trying to read a cert off disk (PEM format). Then I convert it into a DER buffer using i2d_X509(). Sometime later, I need to convert the DER buffer back into an X509 structure using d2i_X509() and that's when the wheels come off the wagon.

I've attached a code snippet that shows the problem. Can anyone help me out?

Thanks,
Nick
all:    example.c
        gcc -o example -lcrypto example.c
-----BEGIN CERTIFICATE-----
MIIDdTCCAl2gAwIBAgIBADANBgkqhkiG9w0BAQUFADB1MQwwCgYDVQQDEwNTQ0Ex
CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3Vu
dGFpbiBWaWV3MRUwEwYDVQQKEwxFc3RpcHMsIEluYy4xFDASBgNVBAsTC0VuZ2lu
ZWVyaW5nMB4XDTA0MTAxMTIzMTU0M1oXDTA0MTExMDIzMTU0M1owdTEMMAoGA1UE
AxMDU0NBMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UE
BxMNTW91bnRhaW4gVmlldzEVMBMGA1UEChMMRXN0aXBzLCBJbmMuMRQwEgYDVQQL
EwtFbmdpbmVlcmluZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANHm
DVMGPubS11msKHvWxvI5NINCPx/fZuznUwkGJOZrlF0F2H3gALqJWTkPHJb1gZ1c
0+m6eLE8FfNyhy4quatWLQ2UYe2eve+HoiwJxiM5IYjBiAq09uePQI9lJK65qdT7
8pSjNZpH+yqIBk5DTMT1tVpiqUESkq5Rk6dH4IstX0nrw95HFTOm1fScnk8p5oGt
1jl8Yr6azTXt8mQb8ijqPERJ2CXLmdv+ygBAaZDBvWcSA7EHIXEgVaUBFuO649dK
QmXvUQOeWtgCWMtfs+ICIBTAO7pgqhdgIj0sdfi68Rg/Wgvu4ZTM0ESFxcJ1z5o7
77adKG+9gY9egHFXa+0CAwEAAaMQMA4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0B
AQUFAAOCAQEAf3dj+IZuAabWeXmq67N4AGUqMt2fZmba5V/sfRfVtqLmZUANoEhs
NohoPsMeeFcfrRlOp0rbuVRhukSXDso+PvB0nX9dz394PC9oiFxVngMORum6LEyV
kv2gZ7czDjp9a6oiLWLpvMdutmS1gOWJ78HTgOLHTNp+CP8EwfIZby594TnJab4S
r3Twg6apj+IXaPqL3WymKAyzMxefokUFa6YNBdnyc7XsEnOfo4llxEbW1EC0WHfM
zhvU6ww6sAec2cngoezDS48tfD9GAOYUh+ObHvy5g5E6ZSyNwKyi5n6fUVcNphn6
Hfpp/N4nh2UwHihvxn4g2yg+HbxuTJt4Aw==
-----END CERTIFICATE-----
#include <stdio.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
#include <openssl/err.h>

int main(int argc, char** argv)
{
	int buflen = 200;
	char buf[buflen];
	unsigned long opensslerr = 0;

	/* This OpenSSL incantation is absolutely necessary */
	OpenSSL_add_all_algorithms();
	ERR_load_crypto_strings();

	FILE *fp = fopen("cacert.pem", "r");

	/* Load a cert off disk */
	X509 *cert = PEM_read_X509(fp, NULL, NULL, NULL);
	opensslerr = ERR_get_error();
	if (opensslerr != 0) 
	{
		ERR_error_string_n(opensslerr, buf, buflen);
		printf("PEM READ ERROR %s\n", buf);
		return -1;
	}

	fclose(fp);
	fp = NULL;

	/* Print out the subject and issuer */
	X509_NAME *name = X509_get_subject_name(cert);
	char *nameStr = X509_NAME_oneline(name, buf, buflen);
	printf ("Subject: %s\n", nameStr);
	name = X509_get_issuer_name(cert);
	nameStr = X509_NAME_oneline(name, buf, buflen);
	printf ("Issuer: %s\n", nameStr);

	/* Find out how long the cert is when converted to DER */
	int certlen = i2d_X509(cert, NULL);
	opensslerr = ERR_get_error();
	if (opensslerr != 0) {
		ERR_error_string_n(opensslerr, buf, buflen);
		printf("CERT DER LEN ERROR %s\n", buf);
		return -1;
	}

	printf("CertLen: %d\n", certlen);

	/* Allocate some space for it */
	unsigned char* certbuf = (unsigned char*) malloc(certlen);
	if (certbuf == NULL) 
	{
		printf("Unable to allocate memory for DER buffer");
		return -1;
	}

	/* Convert the X509 structure to a DER encoding */
	if (i2d_X509(cert, &certbuf) < 0) 
	{
		opensslerr = ERR_get_error();
		ERR_error_string_n(opensslerr, buf, buflen);
		printf("i2d ERROR %s\n", buf);
		return -1;
	}

	/* Turn right around and try to recreate the X509 from the DER */
	X509 *decodedcert = d2i_X509(NULL, &certbuf, certlen);
	if (decodedcert == NULL) {
		while ((opensslerr = ERR_get_error()) != 0) {
			ERR_error_string_n(opensslerr, buf, buflen);
			printf("d2i ERROR %s\n", buf);
		}
		return -1;
	}
}

Reply via email to