> From:
owner-ope...@openssl.org On Behalf Of Jeffrey Walton
> Sent: Monday, 11 February, 2013 23:04
Some minor points:
> >> On Mon, Feb 11, 2013 at 12:01:49AM -0500, Jeffrey Walton wrote:
<snip: extract subjectPublicKeyInfo from X509 cert>
> > To "write out" to a file, don't need to manage a buffer explicitly,
> > can just i2d_X509_PUBKEY_{fp,bio} in one step.
> Unfortunately, it appears many of those functions (macros?) are
> undocumented. But I kind of know they exist, and have come across them
> in s_client.c and x509.c.
>
All i2d_$thing{,_fp,_bio}, and d2i_, work the same ways. Some do
processing on the internal data before it is encoded or after it
is decoded, but not $thing's that are just ASN.1 structures like
X509_PUBKEY. Similarly all of the PEM_{write,read}[_bio]_$thing.
i2d_ and d2i_ are real functions, mostly implemented by one call
to a generic routine with a compiled-in description of the ASN.1.
Similarly PEM_{write,read} are real functions declared by macros
mostly implemented by macros which call a generic routine.
> > Also i2d_$alg?PUBKEY (and PEM_write_$alg?PUBKEY) write pubkeyinfo
> > from several OpenSSL internal structs including EVP_PKEY. But to
> > just take existing info from a cert, your approach is more direct.
> It also has the benefit of direct memory comparison without
> the need for BIOs.
>
I took your "write out" to mean to a file. As noted below you can
use a mem-BIO for memory, but you don't need it the way you need
a FILE* or file-BIO for a file.
> Since I was pinning, I needed a standard presentation format to
> compare the public key offered by the server with the public key I
> expect (embedded within the application). I had that with PKCS#1
> format and ASN.1 notation.
>
Not needed; you could get both keys in EVP_PKEY form and use
EVP_PKEY_cmp. But DER works too. (Not ASN.1 by itself; there
are other ASN.1 encodings that you can't just memcmp.)
I assume you understand that PKCS#1 format is only part of
SubjectPublicKeyInfo though a big part, so not memcmpable as is.
> I could write the server's public key to a memory BIO; but I could not
> load the expected key in memory from a file BIO; and there was no
> BIO_cmp_data(server, file) to tell me if there was a difference in
> bits (in constant time of the larger, FTW!).
>
Yes, not quite, and yes.
> In the end, it was most expedient to simply use (1)
> i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert)) on the server's
> certificate, (2) fopen/fseek/ftell/fread on the embedded public key,
> and then (3) memcmp.
>
For (1) you can write to a mem-BIO and then read the contents with
BIO_get_mem_data (which despite the name actually gets a pointer and
length) or BIO_get_mem_ptr (which gets a "fat" pointer). For the file
you could explicitly copy from a file-read-BIO to a mem-BIO and then
use those contents, but that's reaching the point of silliness. As
above, for memory (and not PEM) there is no real need for BIOs.
> Sorry about not mentioning pinning sooner. I did not want to distract
> folks from the task at hand.
>