3
votes

I have pointer to the X509 struct, and I want to convert it to the string, how can i do it? I need to get string like it printed in PEM_write_X509 function.

-----BEGIN CERTIFICATE-----
MIIIxjCCB66gAwIBAgIKah4k3wAAAAC/WTANBgkqhkiG9w0BAQUFADBbMRIwEAYK
CZImiZPyLGQBGRYCcnUxFjAUBgoJkiaJk/IsZAEZFgZ5YW5kZXgxEjAQBgoJkiaJ
k/IsZAEZFgJsZDEZMBcGA1UEAxMQWWFuZGV4RXh0ZXJuYWxDQTAeFw0xMjA5MDQx
NDEzMDhaFw0xNDAxMTcxNTE1NDZaMIGQMQswCQYDVQQGEwJSVTEPMA0GA1UECBMG
UnVzc2lhMQ8wDQYDVQQHEwZNb3Njb3cxDzANBgNVBAoTBllhbmRleDEMMAoGA1UE
CxMDSVRPMRQwEgYDVQQDEwtZYW5kZXggU2VycDEqMCgGCSqGSIb3DQEJARYbc2Vh
cmNoLWFkbWluQHlhbmRleC10ZWFtLnJ1MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
iQKBgQDBXfluaCox4R4D2Y/3mc6O9i3koHtGtHZmZjYm7XdsAA5xsOZAonLReJCL
J8BtgS6McmX9cGa9GF9ErxfWODC+1Wb3yayUNzOhr2ICu3T++ttf0aMVvMTeDF/Y
lfoZ+tgg1ITQ9yVtz7eteodjLNAy6AaC0z7ulSq4jvPbm1WuBQIDAQABo4IF2DCC
BdQwDAYDVR0TAQH/BAIwADALBgNVHQ8EBAMCBaAwggRbBgNVHREEggRSMIIEToIJ
eWFuZGV4LmJ5ggp5YW5kZXguY29tgg15YW5kZXguY29tLnRygg15YW5kZXguY29t
LnVhggl5YW5kZXgua3qCC3lhbmRleC5tb2Jpggp5YW5kZXgubmV0ggl5YW5kZXgu
cnWCCXlhbmRleC5zdIIJeWFuZGV4LnVhghBpbWFnZXMueWFuZGV4LmJ5ghFpbWFn
ZXMueWFuZGV4LmNvbYIUaW1hZ2VzLnlhbmRleC5jb20udHKCFGltYWdlcy55YW5k
ZXguY29tLnVhghBpbWFnZXMueWFuZGV4Lmt6ghJpbWFnZXMueWFuZGV4Lm1vYmmC
EWltYWdlcy55YW5kZXgubmV0ghBpbWFnZXMueWFuZGV4LnJ1ghBpbWFnZXMueWFu
ZGV4LnN0ghBpbWFnZXMueWFuZGV4LnVhghBwZW9wbGUueWFuZGV4LmJ5ghFwZW9w
bGUueWFuZGV4LmNvbYIUcGVvcGxlLnlhbmRleC5jb20udHKCFHBlb3BsZS55YW5k
ZXguY29tLnVhghBwZW9wbGUueWFuZGV4Lmt6ghJwZW9wbGUueWFuZGV4Lm1vYmmC
EXBlb3BsZS55YW5kZXgubmV0ghBwZW9wbGUueWFuZGV4LnJ1ghBwZW9wbGUueWFu
ZGV4LnN0ghBwZW9wbGUueWFuZGV4LnVhghZwZW9wbGVzZWFyY2gueWFuZGV4LmJ5
ghdwZW9wbGVzZWFyY2gueWFuZGV4LmNvbYIacGVvcGxlc2VhcmNoLnlhbmRleC5j
b20udHKCGnBlb3BsZXNlYXJjaC55YW5kZXguY29tLnVhghZwZW9wbGVzZWFyY2gu
eWFuZGV4Lmt6ghhwZW9wbGVzZWFyY2gueWFuZGV4Lm1vYmmCF3Blb3BsZXNlYXJj
aC55YW5kZXgubmV0ghZwZW9wbGVzZWFyY2gueWFuZGV4LnJ1ghZwZW9wbGVzZWFy
Y2gueWFuZGV4LnN0ghZwZW9wbGVzZWFyY2gueWFuZGV4LnVhgg92aWRlby55YW5k
ZXguYnmCEHZpZGVvLnlhbmRleC5jb22CE3ZpZGVvLnlhbmRleC5jb20udHKCE3Zp
ZGVvLnlhbmRleC5jb20udWGCD3ZpZGVvLnlhbmRleC5reoIRdmlkZW8ueWFuZGV4
Lm1vYmmCEHZpZGVvLnlhbmRleC5uZXSCD3ZpZGVvLnlhbmRleC5ydYIPdmlkZW8u
eWFuZGV4LnN0gg92aWRlby55YW5kZXgudWGCDXd3dy55YW5kZXguYnmCDnd3dy55
YW5kZXguY29tghF3d3cueWFuZGV4LmNvbS50coIRd3d3LnlhbmRleC5jb20udWGC
DXd3dy55YW5kZXgua3qCD3d3dy55YW5kZXgubW9iaYIOd3d3LnlhbmRleC5uZXSC
DXd3dy55YW5kZXgucnWCDXd3dy55YW5kZXguc3SCDXd3dy55YW5kZXgudWEwHQYD
VR0OBBYEFDjrNQM8dYCWIlusgG7EqlAZ5D9lMB8GA1UdIwQYMBaAFNtBJzBPGvVb
PoRWyOyFmLNRLC0nMEwGA1UdHwRFMEMwQaA/oD2GO2h0dHA6Ly9jcmxzLnlhbmRl
eC5ydS9ZYW5kZXhFeHRlcm5hbENBL1lhbmRleEV4dGVybmFsQ0EuY3JsMFcGCCsG
AQUFBwEBBEswSTBHBggrBgEFBQcwAoY7aHR0cDovL2NybHMueWFuZGV4LnJ1L1lh
bmRleEV4dGVybmFsQ0EvWWFuZGV4RXh0ZXJuYWxDQS5kZXIwPwYJKwYBBAGCNxUH
BDIwMAYoKwYBBAGCNxUIhtyhJoWT1VWH/YEtg/nnAoOV0gQci62jzDeH/MC/KAIB
ZAIBBjATBgNVHSUEDDAKBggrBgEFBQcDATAbBgkrBgEEAYI3FQoEDjAMMAoGCCsG
AQUFBwMBMA0GCSqGSIb3DQEBBQUAA4IBAQDNo4rLhEWgj72wbpYO6lSuM6YHn6Bj
BsXJfumtchTyRHsY8RJGGKGZ6joeOQweqChsQXULTnVzadCJ1VqVJ2lTaII5R8Ii
N9jcYgFl4WOv1ynFJ0Jf3V6/ePQd9cqFFJTfFSODHsyZR/Dhgez81/QExfsG/SzS
u+ACIvsDbyu7NFcAK6ZM5CKz3lcisddT/pSPbTOi7AtqtNTrvKlV2AT+5mfNTEa7
rNv6chVl1He7RW8r7uCkK6AfFb0Z4LDhv2zkvmcUtaojmDOO/2AZSXym8efCSmHr
CL2rhv6+ER3c0x5uJlhAUr1ZM76/XnfvT/2SKekPXbGlVAE3v7tfRnW9
-----END CERTIFICATE-----

I tried to look at the PEM_write_X509 function in sources of openssl, but I can't do it, so many macros and defines.

Also, how can i check the type of certificate? is it PEM or DER?

Update:

struct x509_st
    {
    X509_CINF *cert_info;
    X509_ALGOR *sig_alg;
    ASN1_BIT_STRING *signature;
    int valid;
    int references;
    char *name;
    CRYPTO_EX_DATA ex_data;
    /* These contain copies of various extension values */
    long ex_pathlen;
    long ex_pcpathlen;
    unsigned long ex_flags;
    unsigned long ex_kusage;
    unsigned long ex_xkusage;
    unsigned long ex_nscert;
    ASN1_OCTET_STRING *skid;
    AUTHORITY_KEYID *akid;
    X509_POLICY_CACHE *policy_cache;
    STACK_OF(DIST_POINT) *crldp;
    STACK_OF(GENERAL_NAME) *altname;
    NAME_CONSTRAINTS *nc;
#ifndef OPENSSL_NO_RFC3779
    STACK_OF(IPAddressFamily) *rfc3779_addr;
    struct ASIdentifiers_st *rfc3779_asid;
#endif
#ifndef OPENSSL_NO_SHA
    unsigned char sha1_hash[SHA_DIGEST_LENGTH];
#endif
    X509_CERT_AUX *aux;
    } /* X509 */;
2
Nobody can read X.509 certificates. That was a fundamental part of the security design :-)Kerrek SB
@KerrekSB he doesn't want to actually read it, but i'm assuming he wants the data in a string.Joseph Pla
yes @JosephPla, thanksBergP
Can you show some code?Joseph Pla
I just have X509 struct from openssl lib, and I want to get string from it. What code should I submit?BergP

2 Answers

8
votes

Use the following function to write in PEM format:

int PEM_write_bio_X509(BIO *bp, X509 *x);

Then you can read into a char* array with the following function:

int    BIO_read(BIO *b, void *buf, int len);

Just cast the void* to char*. Or just use this one, but it will be the same in the end:

int    BIO_gets(BIO *b,char *buf, int size);

if you pass -1 for len, the buffer is assumed to be null terminated.

If you need to find the length, you can do this:

BIO *b64;
PEM_write_bio_X509(b64, yourX509);
BUF_MEM *bptr;
BIO_get_mem_ptr(b64, &bptr);
int length = bptr->length;
1
votes
char *X509_to_PEM(X509 *cert) {

    BIO *bio = NULL;
    char *pem = NULL;

    if (NULL == cert) {
        return NULL;
    }

    bio = BIO_new(BIO_s_mem());
    if (NULL == bio) {
        return NULL;
    }

    if (0 == PEM_write_bio_X509(bio, cert)) {
        BIO_free(bio);
        return NULL;
    }

    pem = (char *) malloc(bio->num_write + 1);
    if (NULL == pem) {
        BIO_free(bio);
        return NULL;    
    }

    memset(pem, 0, bio->num_write + 1);
    BIO_read(bio, pem, bio->num_write);
    BIO_free(bio);
    return pem;
}