Sorry, I send this before finishing the Aside. I ended up calling these APIs:

DECODER_ctx = OSSL_DECODER_CTX_new_for_pkey(EVP_PKEY **pkey,
                               const char *input_type,
                               const char *input_struct,
                               const char *keytype, int selection,
                               OSSL_LIB_CTX *libctx, const char *propquery);

OSSL_DECODER_from_fp(dctx, fp);

SSL_CTX_set0_tmp_dh_pkey(ctx, dh_pkey);

To get the DH set up. I can't test this until I get past the intial problem, 
but I tried using the above functions for getting the public key from the 
certificate file, and the problem is still the same.

An example of a certificate I'm using that is failing is below:

# openssl x509 -noout -text -in /etc/ssl/certs/servercert.pem
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 286 (0x11e)
        Signature Algorithm: ecdsa-with-SHA256
        Issuer: C = US, ST = PA, L = City, O = Example, OU = Networking, CN = 
JCS-EC-CA, emailAddress = joe....@example.com
        Validity
            Not Before: Mar  3 18:15:13 2021 GMT
            Not After : Nov 28 18:15:13 2023 GMT
        Subject: C = US, ST = PA, L = City, O = Example, OU = Networking, CN = 
JCS-EC-server, emailAddress = joe1....@example.com
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:c2:1a:0c:76:dc:d9:b9:3d:49:f6:60:72:fa:18:
                    c2:e9:31:bc:64:42:24:02:61:06:80:e0:69:2c:5a:
                    c3:0e:e4:09:ce:79:64:f8:fd:b0:65:63:e1:e9:35:
                    34:ff:48:58:aa:72:21:20:c1:ce:f2:7a:90:2b:c7:
                    e7:b7:76:ad:88
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            Netscape Comment:
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier:
                EF:1E:DA:81:3A:43:AA:12:E4:53:B6:4B:E5:A0:3D:AB:CD:30:6B:2F
            X509v3 Authority Key Identifier:
                60:A2:DC:A3:7A:FB:78:A9:92:5F:88:B5:1A:03:65:9C:F4:10:CD:38
    Signature Algorithm: ecdsa-with-SHA256
    Signature Value:
        30:46:02:21:00:dc:fc:69:9c:a6:54:e1:fa:3c:e7:65:9f:cc:
        d5:a4:a2:3a:a7:b1:37:79:60:d0:61:9e:87:15:79:09:0f:34:
        14:02:21:00:fd:29:34:bf:bb:c5:02:0d:9a:04:44:6e:94:22:
        52:b4:0e:ab:1f:3d:15:5c:07:47:eb:76:68:80:f9:72:96:f6


________________________________
From: openssl-users <openssl-users-boun...@openssl.org> on behalf of Jason 
Schultz <jetso...@hotmail.com>
Sent: Tuesday, November 2, 2021 7:42 PM
To: openssl-users@openssl.org <openssl-users@openssl.org>
Subject: X509_get_pubkey() in OpenSSL 3.0?

I thought I should start a new thread since this question was buried in my 
"FIPS" thread and I dont' think it has anything to do with FIPS and OpenSSL 
providers. I'm hitting another problem that I think is related to the migration 
to OpenSSL 3.0, as this code works with OpenSSL 1.1.1 (and 1.0.2 before it). 
When looking at the documentation pages for 1.1.1 vs 3.0, I'm not seeing any 
differences between the OpenSSL APIs I'm calling in the 2 different release 
levels.

Here is the sequence, I'm basically setting up my certificate and private key, 
both in PEM format, for the server, then I need to extract some information 
from them:

    ctx = SSL_CTX_new_ex(non_fips_libctx, NULL, TLS_method());
    SSL_CTX_use_PrivateKey_file(ctx,<keyfile>,SSL_FILETYPE_PEM);
    SSL_CTX_use_certificate_file(ctx,<certfile>,SSL_FILETYPE_PEM);
    SSL_CTX_check_private_key(ctx);
    fp = fopen(<certfile>, "r");
    mycert = PEM_read_X509(fp, NULL, 0, NULL);
    pkey = X509_get_pubkey(mycert);

All functions return good statuses or non-NULL pointers until the last one, 
X509_get_pubkey() returns NULL. I have tried this with RSA and Elliptic Curve 
cert/key pairs. I have tried with pairs created with OpenSSL 1.1.1 as well as 
3.0 via the command line.

This seems like a pretty straightforward operation, but it appears that 
key->pkey is NULL in the code below:

EVP_PKEY *X509_PUBKEY_get0(const X509_PUBKEY *key)
{
    if (key == NULL) {
        ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER);
        return NULL;
    }

    if (key->pkey == NULL) {
        /* We failed to decode the key when we loaded it, or it was never set */
        ERR_raise(ERR_LIB_EVP, EVP_R_DECODE_ERROR);
        return NULL;
    }

    return key->pkey;
}

I got to this code from the error information I dumped from OpenSSL:

00079FF8647F0000:error:03000072:digital envelope routines:(unknown 
function):decode error:crypto/x509/x_pubkey.c:444:

I can paste certificates if anyone thinks it will help, but I've tried several 
types of cert/key pairs, and using the command line to do "openssl x509 
-pubkey..." displays the public key just fine with the certificate file in 
question.

Here is an example of the openssl command line to create one of the cert/key 
pairs that hits this error:

openssl req -new -x509 -nodes -newkey ec:<(openssl ecparam -name secp384r1) 
-keyout threecert.key -out threecert.crt -days 365

Aside: While I was waiting for an answer on this, I started working on removing 
some of the deprecated functions in my code, for example, PEM_read_DHparams(). 
I ended up finding the DECODER functions and plan on doing something like:


Thanks,

Jason

Reply via email to