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