<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Thanks to everyone for the help so far. I think I have things set up correctly as far as FIPS, providers, and library contexts. 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. </div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
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:</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
    ctx = SSL_CTX_new_ex(non_fips_libctx, NULL, TLS_method());</div>
<div>
<div id="appendonsend"></div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
    SSL_CTX_use_PrivateKey_file(ctx,<keyfile>,SSL_FILETYPE_PEM);</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
    SSL_CTX_use_certificate_file(ctx,<certfile>,SSL_FILETYPE_PEM);</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
    SSL_CTX_check_private_key(ctx);<br>
</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
    fp = fopen(<certfile>, "r");</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
    mycert = PEM_read_X509(fp, NULL, 0, NULL);</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
    pkey = X509_get_pubkey(mycert);<br>
</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
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. </div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
This seems like a pretty straightforward operation, but it appears that key->pkey is NULL in the code below:</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
EVP_PKEY *X509_PUBKEY_get0(const X509_PUBKEY *key)
<div>{</div>
<div>    if (key == NULL) {</div>
<div>        ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER);</div>
<div>        return NULL;</div>
<div>    }</div>
<div><br>
</div>
<div>    if (key->pkey == NULL) {</div>
<div>        /* We failed to decode the key when we loaded it, or it was never set */</div>
<div>        ERR_raise(ERR_LIB_EVP, EVP_R_DECODE_ERROR);</div>
<div>        return NULL;</div>
<div>    }</div>
<div><br>
</div>
<div>    return key->pkey;</div>
}<br>
</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
I got to this code from the error information I dumped from OpenSSL:</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
00079FF8647F0000:error:03000072:digital envelope routines:(unknown function):decode error:crypto/x509/x_pubkey.c:444:<br>
</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
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.</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Here is an example of the openssl command line to create one of the cert/key pairs that hits this error:</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
openssl req -new -x509 -nodes -newkey ec:<(openssl ecparam -name secp384r1) -keyout threecert.key -out threecert.crt -days 365<br>
</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
I kept this on the same "FIPS OpenSSL 3.0" thread because I'm not 100% sure it's unrelated.</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
What am I missing here?</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Thanks,</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Jason</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<hr tabindex="-1" style="display:inline-block; width:98%">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" color="#000000" style="font-size:11pt"><b>From:</b> Matt Caswell <matt@openssl.org><br>
<b>Sent:</b> Thursday, October 28, 2021 6:03 PM<br>
<b>To:</b> Jason Schultz <jetson23@hotmail.com>; Dr Paul Dale <pauli@openssl.org>; openssl-users@openssl.org <openssl-users@openssl.org><br>
<b>Subject:</b> Re: OpenSSL 3.0 FIPS questions</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt">
<div class="PlainText"><br>
<br>
On 28/10/2021 18:33, Jason Schultz wrote:<br>
> Thanks Matt. I think I have what I need as far as loading providers. I <br>
> also did the test you suggested with EVP_MD_fetch() and things failed as <br>
> expected, the fetch did not work.<br>
> <br>
> One other question on providers, given how I load everything, it seems <br>
> like before application exit, the cleanup should be the following:<br>
> <br>
>      OSSL_LIB_CTX_free(fips_libctx);<br>
>      OSSL_LIB_CTX_free(non_fips_libctx);<br>
>      OSSL_PROVIDER_unload(defp);<br>
<br>
Yes, but I would recommend unloading the default provider before freeing <br>
the libctx it is associated with. Otherwise bad things might happen.<br>
<br>
> <br>
> Since I didn't "explicitly" load the fips and base providers with API <br>
> calls, I only need to unlead the default provider, as well as free both <br>
> library contexts.<br>
<br>
Correct.<br>
<br>
> <br>
> Also, when I did try to unload the fips and base providers, the call to <br>
> OSSL_PROVIDER_unload() hung, with the following backtrace:<br>
<br>
Yeah. Don't do that. :-)<br>
<br>
Matt<br>
<br>
> <br>
> #1  0x00007fb37f51d709 in CRYPTO_THREAD_read_lock () from <br>
> /lib64/libcrypto.so.3<br>
> #2  0x00007fb37f50c068 in ossl_lib_ctx_get_data () from <br>
> /lib64/libcrypto.so.3<br>
> #3  0x00007fb37f519482 in get_provider_store () from /lib64/libcrypto.so.3<br>
> #4  0x00007fb37f519af9 in provider_deactivate () from /lib64/libcrypto.so.3<br>
> #5  0x00007fb37f51b813 in ossl_provider_deactivate () from <br>
> /lib64/libcrypto.so.3<br>
> #6  0x00007fb37f518399 in OSSL_PROVIDER_unload () from /lib64/libcrypto.so.3<br>
> <br>
> Thanks,<br>
> <br>
> Jason<br>
> <br>
> <br>
> ------------------------------------------------------------------------<br>
> *From:* Matt Caswell <matt@openssl.org><br>
> *Sent:* Thursday, October 28, 2021 2:00 PM<br>
> *To:* Jason Schultz <jetson23@hotmail.com>; Dr Paul Dale <br>
> <pauli@openssl.org>; openssl-users@openssl.org <openssl-users@openssl.org><br>
> *Subject:* Re: OpenSSL 3.0 FIPS questions<br>
> <br>
> <br>
> On 28/10/2021 14:49, Jason Schultz wrote:<br>
>> A call to OSSL_PROVIDER_available() says the "default" provider is <br>
>> available;  however, I'm wondering if I should be loading the default <br>
>> provider via *load_config() as well? I would have to uncomment the <br>
>> "activate = 1" in the default section of my config though.<br>
> <br>
> This is entirely a matter of personal taste. It makes no difference<br>
> functionally whether you load a provider via OSSL_PROVIDER_load()<br>
> directly, or whether you do it via the config file. Obviously if you do<br>
> it via a config file it gives you the ability to modify what providers<br>
> get loaded later without having to recompile.<br>
> <br>
> If you decided to do it via config then you probably want *2* different<br>
> config files. One for the fips libctx and one for the non-fips libctx.<br>
> <br>
> <br>
>> <br>
>> I also still have this in my code:<br>
>> <br>
>>      /* Disallow falling back to the default library context */<br>
>>      nullp = OSSL_PROVIDER_load(NULL, "null");<br>
>> <br>
>> But not sure it's having any affect?<br>
> <br>
> You could attempt to test it by attempting to fetch an algorithm. We<br>
> would expect it to fail if it is working as expected. E.g.<br>
> <br>
> EVP_MD *md = EVP_MD_fetch(NULL, "SHA2-256", NULL);<br>
> if (md != NULL) {<br>
>       /* Should not happen! The null provider should prevent this */<br>
> }<br>
> <br>
> <br>
>> <br>
>> I do know that later in my application, both in "FIPS" or "non-FIPS" <br>
>> mode, I can  create an SSL_CTX with SSL_CTX_new_ex(). I also <br>
>> successfully call several APIs using both the fips_libctx or the <br>
>> non_fips_libctx, for example:<br>
>> <br>
>> status = SSL_CTX_use_PrivateKey_file(ctx,<file>,SSL_FILETYPE_PEM);<br>
>> <br>
>> status = SSL_CTX_use_certificate_file(ctx,<file>,SSL_FILETYPE_PEM);<br>
>> <br>
>> status = SSL_CTX_check_private_key(ctx);<br>
>> <br>
>> <br>
>> All return successfully. So I think what I have between configuration <br>
>> files and API calls accomplishes what I need to. Would anyone reading <br>
>> this agree?<br>
> <br>
> It sounds correct from what you have described.<br>
> <br>
> Matt<br>
> <br>
>> <br>
>> I'm running into another issue that I need to troubleshoot a bit more <br>
>> before I add too much information and too many questions to a single <br>
>> message.<br>
>> <br>
>> Thanks to everyone for their help with this, things are starting to make <br>
>> more sense now.<br>
>> <br>
>> <br>
>> <br>
>> ------------------------------------------------------------------------<br>
>> *From:* Matt Caswell <matt@openssl.org><br>
>> *Sent:* Thursday, October 28, 2021 7:39 AM<br>
>> *To:* Jason Schultz <jetson23@hotmail.com>; Dr Paul Dale <br>
>> <pauli@openssl.org>; openssl-users@openssl.org <openssl-users@openssl.org><br>
>> *Subject:* Re: OpenSSL 3.0 FIPS questions<br>
>> <br>
>> <br>
>> On 27/10/2021 17:28, Jason Schultz wrote:<br>
>>> With these config files and the code above, the <br>
>>> OSSL_PROVIDER_load(fips_libctx, "fips") call fails. Here are the <br>
>>> messages from the ERR_print_errors_fp() call:<br>
>>> <br>
>>> 2097C692B57F0000:error:1C8000D5:Provider routines:(unknown <br>
>>> function):missing config data:providers/fips/self_test.c:289:<br>
>>> 2097C692B57F0000:error:1C8000E0:Provider routines:(unknown <br>
>>> function):fips module entering error state:providers/fips/self_test.c:387:<br>
>>> 2097C692B57F0000:error:1C8000D8:Provider routines:(unknown <br>
>>> function):self test post failure:providers/fips/fipsprov.c:706:<br>
>>> 2097C692B57F0000:error:078C0105:common libcrypto routines:(unknown <br>
>>> function):init fail:crypto/provider_core.c:903:name=fips<br>
>> <br>
>> <br>
>> This tells us that the fips provider has successfully loaded, but then<br>
>> subsequently failed during its self-test because it cannot find its<br>
>> config data.<br>
>> <br>
>> I can see that you have created a separate libctx for fips. However<br>
>> automatic loading of the config file only works for the *default*<br>
>> libctx. If you create your own one then you need to explicitly load the<br>
>> config file:<br>
>> <br>
>> if (!OSSL_LIB_CTX_load_config(fips_libtx, "/usr/local/ssl/openssl.cnf")) {<br>
>>       /* error handling */<br>
>> }<br>
>> <br>
>> Actually if you do this then you should not need to call<br>
>> OSSL_PROVIDER_load() explicitly to load the fips provider since you<br>
>> already activated it in the config file. You can either drop the<br>
>> explicit call to OSSL_PROVIDER_load() for the fips provider, or remove<br>
>> the "activate = 1" line in "fips_sect" in fipsmodule.cnf. This is just a<br>
>> minor optimisation though. Doing both is redundant but harmless. You<br>
>> could also load the base provider via config if you wanted to.<br>
>> <br>
>> Matt<br>
>> <br>
>> <br>
</div>
</span></font></div>
</div>
</body>
</html>