Skip to content

Comments

Use OSSL_STORE in apps, generalizing and simplifying load_key() etc.#11755

Closed
DDvO wants to merge 3 commits intoopenssl:masterfrom
siemens:use_OSSL_STORE_in_apps
Closed

Use OSSL_STORE in apps, generalizing and simplifying load_key() etc.#11755
DDvO wants to merge 3 commits intoopenssl:masterfrom
siemens:use_OSSL_STORE_in_apps

Conversation

@DDvO
Copy link
Contributor

@DDvO DDvO commented May 7, 2020

This is the continuation of #11745, a further spin-off of PR #11470 according to #11470 (comment).

This adds a flexible apps-internal function load_key_cert_crl() now used load_key(), load_pubkey(), and load_cert(), making use of OSSL_STORE.

This also adds the app-internal functions get_passwd(), cleanse(), and clear_free() to be used also in apps/cmp.c etc.

This PR also updates the help texts and the documentation of those apps using load-key() etc.

@levitte levitte mentioned this pull request May 7, 2020
@DDvO
Copy link
Contributor Author

DDvO commented May 7, 2020

Using OSSL_STORE for loading private keys in DER format gives a couple of strange failures of
make test TESTS=test_ec
at least for the following ED25519 Private-Key:

-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEINTuctv5E1hK1bbY8fdp+K06/nwoy/HU++CXqI9EdVhC
-----END PRIVATE KEY-----
ED25519 Private-Key:
priv:
    d4:ee:72:db:f9:13:58:4a:d5:b6:d8:f1:f7:69:f8:
    ad:3a:fe:7c:28:cb:f1:d4:fb:e0:97:a8:8f:44:75:
    58:42
pub:
    19:bf:44:09:69:84:cd:fe:85:41:ba:c1:67:dc:3b:
    96:c8:50:86:aa:30:b6:b6:cb:0c:5c:38:ad:70:31:
    66:e1

The loader reports on apps/openssl pkey -in pkey-f.d -inform der -text ambigous results with a matchcount of 10 and the following console output:

Unable to load key
C0:B7:87:51:D2:7F:00:00:error:rsa routines:(unknown function):RSA lib:crypto/rsa/rsa_ameth.c:142:
C0:B7:87:51:D2:7F:00:00:error:asn1 encoding routines:(unknown function):wrong tag:crypto/asn1/tasn_dec.c:1135:
C0:B7:87:51:D2:7F:00:00:error:asn1 encoding routines:(unknown function):nested asn1 error:crypto/asn1/tasn_dec.c:698:
C0:B7:87:51:D2:7F:00:00:error:asn1 encoding routines:(unknown function):nested asn1 error:crypto/asn1/tasn_dec.c:630:Field=params.p, Type=DSA
C0:B7:87:51:D2:7F:00:00:error:dsa routines:(unknown function):interrupted or cancelled:crypto/dsa/dsa_ameth.c:416:
C0:B7:87:51:D2:7F:00:00:error:asn1 encoding routines:(unknown function):wrong tag:crypto/asn1/tasn_dec.c:1135:
C0:B7:87:51:D2:7F:00:00:error:asn1 encoding routines:(unknown function):nested asn1 error:crypto/asn1/tasn_dec.c:698:
C0:B7:87:51:D2:7F:00:00:error:asn1 encoding routines:(unknown function):nested asn1 error:crypto/asn1/tasn_dec.c:630:Field=privateKey, Type=EC_PRIVATEKEY
C0:B7:87:51:D2:7F:00:00:error:elliptic curve routines:(unknown function):EC lib:crypto/ec/ec_asn1.c:991:
C0:B7:87:51:D2:7F:00:00:error:elliptic curve routines:(unknown function):decode error:crypto/ec/ec_ameth.c:455:
C0:B7:87:51:D2:7F:00:00:error:asn1 encoding routines:(unknown function):ASN1 lib:crypto/asn1/d2i_pr.c:62:
C0:B7:87:51:D2:7F:00:00:error:asn1 encoding routines:(unknown function):ASN1 lib:crypto/asn1/d2i_pr.c:62:
C0:B7:87:51:D2:7F:00:00:error:asn1 encoding routines:(unknown function):ASN1 lib:crypto/asn1/d2i_pr.c:62:
C0:B7:87:51:D2:7F:00:00:error:asn1 encoding routines:(unknown function):ASN1 lib:crypto/asn1/d2i_pr.c:62:
C0:B7:87:51:D2:7F:00:00:error:STORE routines:(unknown function):ambiguous content type:crypto/store/loader_file.c:1386:

How can this be fixed?

@levitte
Copy link
Member

levitte commented May 7, 2020

Oh, what a surprise! It turns out that d2i_PrivateKey (and thereby d2i_PrivateKey) doen't work as advertised for PKCS#8-wrapped keys! The manual says this (italics mine, for emphasis):

d2i_PrivateKey() decodes a private key using algorithm type. It
attempts to use any key specific format or PKCS#8 unencrypted
PrivateKeyInfo format. The type parameter should be a public key
algorithm constant such as EVP_PKEY_RSA. An error occurs if the decoded
key does not match type
. d2i_PublicKey() does the same for public
keys.

However, looking at actual code, you'll notice that when it has decoded a PKCS#8 structure, *it doesn't care about type at all!

if (!ret->ameth->old_priv_decode ||
!ret->ameth->old_priv_decode(ret, &p, length)) {
if (ret->ameth->priv_decode != NULL
|| ret->ameth->priv_decode_with_libctx != NULL) {
EVP_PKEY *tmp;
PKCS8_PRIV_KEY_INFO *p8 = NULL;
p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length);
if (p8 == NULL)
goto err;
tmp = evp_pkcs82pkey_int(p8, libctx, propq);
PKCS8_PRIV_KEY_INFO_free(p8);
if (tmp == NULL)
goto err;
EVP_PKEY_free(ret);
ret = tmp;
} else {
ASN1err(0, ERR_R_ASN1_LIB);
goto err;
}
}

Of course, the file loader is implemented according to documentation 😉

@levitte
Copy link
Member

levitte commented May 7, 2020

Try and see what happens if you add this patch:

diff --git a/crypto/asn1/d2i_pr.c b/crypto/asn1/d2i_pr.c
index c7346f5424..3ddc56d408 100644
--- a/crypto/asn1/d2i_pr.c
+++ b/crypto/asn1/d2i_pr.c
@@ -58,6 +58,8 @@ EVP_PKEY *d2i_PrivateKey_ex(int type, EVP_PKEY **a, const unsigned char **pp,
                 goto err;
             EVP_PKEY_free(ret);
             ret = tmp;
+            if (EVP_PKEY_type(type) != EVP_PKEY_base_id(ret))
+                goto err;
         } else {
             ASN1err(0, ERR_R_ASN1_LIB);
             goto err;

@DDvO
Copy link
Contributor Author

DDvO commented May 7, 2020

Try and see what happens if you add this patch:

Great, this fixes the test failures - thanks @levitte

@DDvO DDvO force-pushed the use_OSSL_STORE_in_apps branch from 477e358 to 2a16046 Compare May 7, 2020 20:08
@DDvO DDvO changed the title Use OSSL_STORE in apps, generalizing and simplifying load_key() etc. WIP: Use OSSL_STORE in apps, generalizing and simplifying load_key() etc. May 7, 2020
@DDvO DDvO added this to the 3.0.0 milestone May 7, 2020
@DDvO DDvO force-pushed the use_OSSL_STORE_in_apps branch 3 times, most recently from 8258354 to 16b6afa Compare May 8, 2020 10:34
@DDvO
Copy link
Contributor Author

DDvO commented May 8, 2020

@levitte, hope you can finish up #11756 providing OSSL_STORE_attach() soon
such that this PR can be finalized and merged also in #11470.

@DDvO DDvO force-pushed the use_OSSL_STORE_in_apps branch from 16b6afa to 50c3db5 Compare May 9, 2020 16:52
@DDvO
Copy link
Contributor Author

DDvO commented May 9, 2020

This PR meanwhile reflects also the extended load_key() and load_pubkey() features in the apps and their documentation.

@FdaSilvaYY, thanks for your yesterday's review. Maybe you wanna have a look also at this addendum.

@DDvO DDvO changed the title WIP: Use OSSL_STORE in apps, generalizing and simplifying load_key() etc. Use OSSL_STORE in apps, generalizing and simplifying load_key() etc. May 9, 2020
DDvO added a commit to mpeylo/cmpossl that referenced this pull request May 12, 2020
@DDvO
Copy link
Contributor Author

DDvO commented May 12, 2020

@levitte, if you can approve this today we should be able to get this along with #11756 into alpha2.
It would also simplify #11470.

@DDvO DDvO force-pushed the use_OSSL_STORE_in_apps branch from 43b7df1 to 9b0a075 Compare May 12, 2020 13:22
@DDvO
Copy link
Contributor Author

DDvO commented May 12, 2020

I've partly squashed the commits and
simplified the TODOs to be executed when rebasing on #11756.

@DDvO DDvO force-pushed the use_OSSL_STORE_in_apps branch from 9b0a075 to 0c672fe Compare May 12, 2020 14:55
@DDvO
Copy link
Contributor Author

DDvO commented May 12, 2020

I again caught the unrelated Travis failure "No space left on device",
which is annoying. Looks like the machine needs some disk cleanup.

@levitte
Copy link
Member

levitte commented May 13, 2020

Unfortunately, I was not well yesterday, and won't be able to look before this evening today. Considering that #11756 has only been approved today, time is running very short anyway.
I will look this evening.

@levitte
Copy link
Member

levitte commented May 13, 2020

That being said, we've internally decided to make fairly frequent alphas, with about three weeks' interval between them, so the wait for alpha3 isn't going to be huge. I think it's better to iron out whatever there is to iron out than to rush it in for alpha2. Do you agree?

@DDvO
Copy link
Contributor Author

DDvO commented May 13, 2020

Thanks @levitte for your comments on the timing of this PR.

I agree that it's not a problem if it does not make it into alpha2, mostly because it's not strictly needed anymore for #11470, which I'll be able to merge in about two hours.

@levitte
Copy link
Member

levitte commented May 14, 2020

I like your approach very much. Isn't it worth having this API not on the apps level but on the level of the libcrypto?

Please no.

@beldmit
Copy link
Member

beldmit commented May 14, 2020

I like your approach very much. Isn't it worth having this API not on the apps level but on the level of the libcrypto?

Please no.

It just causes the cut'n'pasting these functions when needed :(

@DDvO
Copy link
Contributor Author

DDvO commented May 14, 2020

I like your approach very much. Isn't it worth having this API not on the apps level but on the level of the libcrypto?

Please no.

What would make sense IHMO is a slight abstraction (without the stdin feature, and more general password input) of

int load_key_cert_crl(const char *uri, int maybe_stdin,
                      const char *pass, const char *desc,
                      EVP_PKEY **ppkey, X509 **pcert, X509_CRL **pcrl)

for convenient library-level use of the OSSL_STORE API, for instance:

int OSSL_STORE_load_key_cert_crl(const char *uri, BIO *bio,
                                 const UI_METHOD *ui_method, void *ui_data, const char *desc,
                                 EVP_PKEY **ppkey, X509 **pcert, X509_CRL **pcrl)

where either the uri or the bio would be used as input.

@DDvO
Copy link
Contributor Author

DDvO commented May 14, 2020

I like your approach very much. Isn't it worth having this API not on the apps level but on the level of the libcrypto?

Please no.

It just causes the cut'n'pasting these functions when needed :(

Indeed. Any why not even more directly usable

EVP_PKEY *OSSL_STORE_load_key(const char *uri, BIO *bio, const char *desc,
                              const UI_METHOD *ui_method, void *ui_data);
X509 *OSSL_STORE_load_cert(const char *uri, BIO *bio, const char *desc,
                           const UI_METHOD *ui_method, void *ui_data);
X509_CRL *OSSL_STORE_load_crl(const char *uri, BIO *bio, const char *desc);

@DDvO
Copy link
Contributor Author

DDvO commented May 14, 2020

Then we can also obsolete/replace/integrate

X509 *X509_load_http(const char *url, BIO *bio, BIO *rbio, int timeout);
X509_CRL *X509_CRL_load_http(const char *url, BIO *bio, BIO *rbio, int timeout);

@DDvO
Copy link
Contributor Author

DDvO commented May 14, 2020

BTW, is it possible with OSSL_STORE to set a timeout value in case HTTP-based fetching is used?

@levitte
Copy link
Member

levitte commented May 14, 2020

BTW, is it possible with OSSL_STORE to set a timeout value in case HTTP-based fetching is used?

There is a ctrl function, isn't there?

@levitte
Copy link
Member

levitte commented May 14, 2020

I really don't think that application specific routines belong in libcrypto. If you absolutely want to make them into a public library, it should be a separate one.

@beldmit
Copy link
Member

beldmit commented May 14, 2020

I really don't think that application specific routines belong in libcrypto. If you absolutely want to make them into a public library, it should be a separate one.

I agree with this position.

@levitte levitte added approval: done This pull request has the required number of approvals branch: master Applies to master branch labels May 14, 2020
@DDvO
Copy link
Contributor Author

DDvO commented May 15, 2020

I really don't think that application specific routines belong in libcrypto.
If you absolutely want to make them into a public library, it should be a separate one.

This brings us back to a discussion started pretty exactly four years back: #6986.

In my view also the OSSL_STORE would better be placed in such an application-level lib.
And of course various other rather high-level features that do not really belong to libcrypto,
such as S/MIME, TS, HTTP, OCSP, and CMP.

@openssl-machine
Copy link
Collaborator

24 hours has passed since 'approval: done' was set, but as this PR has been updated in that time the label 'approval: ready to merge' is not being automatically set. Please review the updates and set the label manually.

@levitte
Copy link
Member

levitte commented May 15, 2020

In my view also the OSSL_STORE would better be placed in such an application-level lib.

I disagree, especially in light if it being used internally in a few places in libcrypto, but also because it's a central ENGINE (and soon provider) interface.

And of course various other rather high-level features that do not really belong to libcrypto,
such as S/MIME, TS, HTTP, OCSP, and CMP.

I agree completely! There's a lot that's been shoved into libcrypto that's more like protocol libraries (interestingly, we have a separate libssl, go figure!) or application utility libraries.

@DDvO
Copy link
Contributor Author

DDvO commented May 15, 2020

In my view also the OSSL_STORE would better be placed in such an application-level lib.

I disagree, especially in light if it being used internally in a few places in libcrypto, but also because it's a central ENGINE (and soon provider) interface.

Given this insight I agree.

DDvO added 3 commits May 15, 2020 20:20
This also adds the more flexible and general load_key_cert_crl()
as well as helper functions get_passwd(), cleanse(), and clear_free()
to be used also in apps/cmp.c etc.
@DDvO DDvO force-pushed the use_OSSL_STORE_in_apps branch from cf2e871 to a2847b1 Compare May 15, 2020 18:20
openssl-machine pushed a commit that referenced this pull request May 15, 2020
…ib/apps.c

Reviewed-by: Richard Levitte <[email protected]>
Reviewed-by: David von Oheimb <[email protected]>
(Merged from #11755)
openssl-machine pushed a commit that referenced this pull request May 15, 2020
…warning

Reviewed-by: Richard Levitte <[email protected]>
Reviewed-by: David von Oheimb <[email protected]>
(Merged from #11755)
openssl-machine pushed a commit that referenced this pull request May 15, 2020
This also adds the more flexible and general load_key_cert_crl()
as well as helper functions get_passwd(), cleanse(), and clear_free()
to be used also in apps/cmp.c etc.

Reviewed-by: Richard Levitte <[email protected]>
Reviewed-by: David von Oheimb <[email protected]>
(Merged from #11755)
@DDvO
Copy link
Contributor Author

DDvO commented May 15, 2020

Pushed - thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approval: done This pull request has the required number of approvals branch: master Applies to master branch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants