Trying to get a public info for a certificate

Daniel Pedraza juanamichi at gmail.com
Mon Jun 3 17:03:38 UTC 2019


Thanks a lot, Matt and Viktor! You guys are absolutely right,
X509_get0_pubkey_bitstr gives me the same struct that was once inside of
cert_info->key->public_key.

@Viktor I had also tried your second approach (didn't know about the first
one!) and for some reason it doesn't have the "correct" data. My guess is
you're right and the application has been hashing the wrong thing all
along. I will look into it.

Anyway, thanks a lot you guys, you are the best!

On Mon, Jun 3, 2019 at 11:31 AM Viktor Dukhovni <openssl-users at dukhovni.org>
wrote:

> 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.
>
> --
>         Viktor.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mta.openssl.org/pipermail/openssl-users/attachments/20190603/07b62bc0/attachment.html>


More information about the openssl-users mailing list