Trying to get a public info for a certificate

Viktor Dukhovni openssl-users at
Mon Jun 3 16:31:11 UTC 2019

On Mon, Jun 03, 2019 at 10:40:02AM -0500, Daniel Pedraza wrote:

> There's a part of the code where we're doing a sha256 hash of the public
> key of our certificate. On the older OpenSSL, we were able to get the
> public key by doing cert->cert_info->key->public_key->data. On the newer
> version, we no longer have access to the cert_info struct.
> I tried doing:
> EVP_PKEY * public_key = X509_get0_pubkey(cert);
> this gives me an EVP_PKEY value, which I tried to convert to a char** by
> doing this:
> unsigned char *buf, *p;
> int len = i2d_PublicKey(public_key, NULL);
> buf = OPENSSL_malloc(len);
> p = buf;
> i2d_PublicKey(public_key, &p);

To obtain the serialized buffer 'buf' of length 'len' that you
can then checksum, there are two essentially equivalent approaches:

   1.   X509 *cert = ...;
        X509_PUBKEY *xpk = X509_get_X509_PUBKEY(cert);
	int len = i2d_X509_PUBKEY(xpk, NULL);
        unsigned char *buf = malloc(len);	/* error check */
	unsigned char *buf2 = buf;

	i2d_X509_PUBKEY(xpk, &buf2);
	OPENSSL_assert(buf2 - buf == len);

   2.   X509 *cert = ...;
	EVP_PKEY *pkey = X509_get0_pubkey(cert);
	int len = i2d_PUBKEY(pkey, NULL);
	unsigned char *buf = malloc(len);	/* error check */
	unsigned char *buf2 = buf;

	i2d_PUBKEY(pkey, &buf2);
	OPENSSL_assert(buf2 - buf == len);

The first approach avoids having to reconstruct (allocate, use and
free) the X509_PUBKEY (SPKI) from the underlying EVP_PKEY, so will
be slightly more efficient.

> This gives me a buffer with the correct length, but it seems like it has
> different data from what the public_key->data used to give me.

I don't recall what public_key->data contains, but if different it
was probably not the right thing to use, since you should be capturing
the complete SPKI structure (public key algorithm OID, any parameters
and the key data).  If it contains just the key bits, without the
algorithm and parameters, it is unwise to use that.

If needed for backwards-compatibility, you should be able to recover
the key bitstring with X509_get0_pubkey_bitstr(3), but you really
should not.  The SPKI is the right object to fingerprint.


More information about the openssl-users mailing list