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;
}
}
