Victor- Thanks for the info. I think I'm going to use:
X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx) EVP_PKEY pkey = X509_get_pubkey(cert); (also suggested by Selva) The reason is, and to answer some of your questions, all of this is taking place well before any handshakes, so the SSL object doesn't come into play at this point. We do allow users to specify both an RSA and EC cert/key pair, but the order in which we set them up will work since these functions operate on the last one to load. If the certificate loads, that's great, but we also tell our users if they specified an RSA cert if it's really a EC cert, etc. We also do some checks on the certificate, like if it's expired, or not valid yet; that's why I chose SSL_CTX_get0_certificate() above, so I have the X509 certificate object to make those checks, with X509_get0_notBefore(), etc. In any case, things appear to be working now, but I'm hitting an issue later on when calling SSL_CTX_build_cert_chain(). I working on debugging that, I may have to start yet another thread later. Thanks, Jason ________________________________ From: openssl-users <openssl-users-boun...@openssl.org> on behalf of Viktor Dukhovni <openssl-us...@dukhovni.org> Sent: Tuesday, November 2, 2021 9:01 PM To: openssl-users@openssl.org <openssl-users@openssl.org> Subject: Re: X509_get_pubkey() in OpenSSL 3.0? On Tue, Nov 02, 2021 at 08:28:01PM +0000, Jason Schultz wrote: > Victor- > > I can't seem to find any documentation on SSL_CTX_get0_privatekey(), > but by the name of it, it sounds like it's getting the private key; > I'm trying to get the public key. It does appear to be "under-documented" (i.e. not at all), perhaps that could be addressed. Note that you can get a public key from the private key. > That said, I should probably explain more of why I'm doing what I'm > doing, because there may be an easier way all together. Basically, we > allow configuring RSA or EC certificates/keys, and I want to get the > public key so I can check the type of key with a call to: > > EVP_PKEY_base_id(pubkey); Which you can equally get from the private key, but there's also: SSL_CTX_get0_certificate (sadly also "under-documented") which means that you certainly don't need to read the PEM file again. > So maybe there's a better way? After I call: > > SSL_CTX_use_certificate_file(ctx,<certfile>,SSL_FILETYPE_PEM); > > Is there an API I can call passing the ctx that will tell me what type > of certificate is in use for that ctx? Or something else along those > lines? Also once you have an (SSL *) handle you can call SSL_get_certificate(3) which is documented, and proceed from there. > It's very possible I'm overcomplicating things with the fopen(), > PEM_read_X509(), X509_get_pubkey() sequence, so any suggestions on how > to better accomplish this verification are welcome. Yes. Query the data you already have in memory. Note that a context can be configured with *both* an RSA certificate chain *and* an EC certificate chain. The above functions return the one most recently loaded, but a handshake with a peer may select one of the other chains. Most applications only load keys for just one algorithm, but in general more may be present. It is surprising that you care which algorithm is in cert/keys. So long as it loads, why does it matter? If you want to log data for each handshake, at that point you can use SSL_get_certificate(3) for the cert actually selected by this handshake on the local end: https://github.com/vdukhovni/postfix/blob/master/postfix/src/tls/tls_misc.c#L950-L953 -- Viktor.