Skip to content

Comments

Introducing an application-level library for the CLI and OpenSSL-based applications#4992

Closed
DDvO wants to merge 11 commits intoopenssl:masterfrom
siemens:secapp
Closed

Introducing an application-level library for the CLI and OpenSSL-based applications#4992
DDvO wants to merge 11 commits intoopenssl:masterfrom
siemens:secapp

Conversation

@DDvO
Copy link
Contributor

@DDvO DDvO commented Dec 28, 2017

So far, the OpenSSL code has essentially a three-level structure with a stack of two libraries and a command-line application at the top:

apps/openssl
libssl
libcrypto

The apps/ directory contains various generally useful code like handling crypto-related files and messages, general TLS client/server and CA functionality, support for higher-level protocols like S/MIME, CRL fetching, OCSP, and certainly more to come.
While this code serves as a model for using the crypto and ssl libraries and can be used in a limited way by invoking the openssl application binary (CLI), it cannot be re-used directly. Other applications that need similar functionality need to copy or re-implement portions of that code and then maintain it.
On the other hand, the two libraries contain some code that is actually too high-level for them, for instance the minimal HTTP client as part of the crypto library (crypto/ocsp/ocsp_ht.c). It would be very helpful to introduce a further level in the hierarchy containing a more application-oriented library:

apps/openssl and external OpenSSL-based applications
libsecapp <-- new (with tentative name)
libssl
libcrypto

Then all more high-level and application support functionality can go there. This would make much of the generally useful code that so far resides in the apps/ folder directly accessible to other applications at the programming level, i.e., in the form of a library/API, with all the re-usability advantages that this brings. It would also relieve libcrypto from more high-level topics like HTTP.
This library would also form an ideal condensation point for further higher-level uses of crypto and TLS that may in the future get integrated with OpenSSL.

This pull request contains a fully functional proof-of-concept implementation for the above proposal. It introduces a library with the preliminary name 'secapp'.

For now, the library consists of essentially the code that so far as been in apps/apps.c and apps/app_rand.c, moved to the secapp/ directory. (I had to move and partly rename some functions between these two source files and apps/opt.c because the cut between these sources was not entirely clean. Of course, when this PR is accepted, some further cleanup would make sense.) I moved most of apps/apps.h to include/openssl/apps.h, while the strictly internal declarations in it went in a new file apps/apps_locl.h and the ones related to the command-line option functionality went in a new file apps/opt.h.

The high-level build.info mechanism proved very useful for adding the new library, stating its dependencies etc. Yet it turned out that its implementation in Configure and util/mkdef.pl is not complete - I added respective TODOs there.

I made sure that all this (including tests) builds and runs both in a Linux-like environment (Cygwin) and native Windows (Visual C).

Checklist
  • tests are added or updated

@DDvO
Copy link
Contributor Author

DDvO commented Dec 28, 2017

This pull request is related to suggestions I made in May 2016 and Sep 2017:
https://mta.openssl.org/pipermail/openssl-dev/2017-September/009712.html

@DDvO
Copy link
Contributor Author

DDvO commented Dec 28, 2017

This pull request contains in its first five commits various small corrections for shortcomings in the build machinery of OpenSSL I came across while building the addition of the new library, namely:

  • a bug fixed in util/mkdef.pl, which caused a loop handling declarations like void fn()
  • a more practically useful trace option for util/mkdef.pl
  • a new option for mkdef.pl for warning about incomplete handling of #if expressions
  • a POSIX/ANSI compatibility warning issue with crypto/mem.c and Visual C fixed in e_os.h
  • a correction of OPENSSL_EXPORT and OPENSSL_EXTERN in e_os2.h for native Windows builds
  • a bug fixed in a file open error message in apps/progs.pl

}
foreach (@{$ordinals{$dest}}) {
my %known_ordinals =
my %known_ordinals = # TODO this should be configurable in build.info using ORDINALS
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, everything about ORDINALS can be removed, both here and anywhere in Configurations.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean that also util/lib*.num are not needed anymore, not even for building Windows DLLs?
The better if so, because these often cause(d) extra work.
Hope that someone who is very familiar with this topic takes care of removing the unncessary pieces.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, no, not quite so unnecessary, sorry. What's not needed any more is the build.info keyword ORDINALS. It serves no purpose any more, as we've made the generation of corresponding .map / .def / .opt file explicit.

I will, however, clean out the stuff around ORDINAL, thanks.


foreach my $filename (@openssl_source) {
open F, $filename or die "Couldn't open $_: $!\n";
open F, $filename or die "Couldn't open $filename: $!\n";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops

LIBS=libcrypto libssl libsecapp
ORDINALS[libcrypto]=crypto
ORDINALS[libssl]=ssl
ORDINALS[libsecapp]=secapp
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The three ORDINALS lines aren't necessary at all

@levitte
Copy link
Member

levitte commented Dec 28, 2017

Ok... so here's a few thoughts:

  1. The code that you have put in that new library is internal, i.e. we have not at all designed it for public consumption. It's very likely that the names we use clash with something else if combined with "the wrong library".
  2. the API isn't necessarely stable, i.e. we may introduce changes at any time, and that just doesn't roll well with the idea of making this a public library. We don't promise that it will be stable across minor OpenSSL versions or even releases.

It's true that people do copy that code (hey, I've done the same in previous work), but it's entirely at their own risk.

So in the end, while this might seem like a good idea, this places a maintenance burden on @openssl that I'm unsure we're willing to take.

I'm sorry to deliver such a message, 'cause you have obviously put time and effort into this.
I do take a specific interest into the faults that you have found, however. Would you be willing to move those to a separate PR?

@DDvO
Copy link
Contributor Author

DDvO commented Dec 28, 2017

@levitte thanks for your swift comments.

I already anticipated the points you made about internal and unstable API components - that's why I wrote above: "Of course, when this PR is accepted, some further cleanup would make sense."

My main points of this PR are that an application-level library would be of great benefit for several reasons and that it is not too hard to implement.

Of course, the actual contents of the library are debatable - putting essentially all of apps.c and app_rand.c is just an example. Yet at least functions like load_cert, load_key, load_crl, ... and all the code supporting CRL loading and OCSP would fit there perfectly.
As mentioned, further more high-level code possibly added in the future, e.g., on certificate management using CMP, would likely better not go into the core crypto lib, but into the new library.

Sure I'll put the various commits with small general improvements in a separate PR.

@DDvO
Copy link
Contributor Author

DDvO commented Dec 28, 2017

How if I reduce the initial (API) contents of the new library to:

X509 *load_cert(const char *file, int format, const char *cert_descrip);
X509_CRL *load_crl(const char *infile, int format);
EVP_PKEY *load_key(const char *file, int format, int maybe_stdin,
                   const char *pass, ENGINE *e, const char *key_descrip);
EVP_PKEY *load_pubkey(const char *file, int format, int maybe_stdin,
                      const char *pass, ENGINE *e, const char *key_descrip);
int load_certs(const char *file, STACK_OF(X509) **certs, int format,
               const char *pass, const char *cert_descrip);
int load_crls(const char *file, STACK_OF(X509_CRL) **crls, int format,
              const char *pass, const char *cert_descrip);
int load_pkcs12(BIO *in, const char *desc, pem_password_cb *pem_cb, void *cb_data,
                EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca);

int load_cert_crl_http(const char *url, X509 **pcert, X509_CRL **pcrl);
X509_CRL *load_crl_crldp(STACK_OF(DIST_POINT) *crldp);
STACK_OF(X509_CRL) *crls_http_cb(X509_STORE_CTX *ctx, X509_NAME *nm);

ENGINE *setup_engine(const char *engine, int debug);
void release_engine(ENGINE *e);

Hope this addresses (all) the concerns mentioned above.

@mattcaswell
Copy link
Member

I am sceptical about the need for a new library (for this purpose). If we think there is code in the apps that is generally useful, I'm not sure why we wouldn't push that code down into libcrypto or libssl as appropriate. If we were to introduce a new library then I think it should be part of a broader review of the structure of all our codebase. There are other things that have been proposed for splitting out into separate libraries, e.g. we could make all algorithms dynamically loadable at runtime. There is also code in libcrypto which isn't really crypto related at all and probably doesn't belong there at all. Such a wholesale review probably shouldn't happen until 1.2.0

@tmshort
Copy link
Contributor

tmshort commented Jan 2, 2018

What about libtls from LibreSSL?

@mattcaswell mattcaswell added this to the 1.2.0 milestone Jan 24, 2018
@levitte
Copy link
Member

levitte commented Jan 31, 2018

So @DDvO, I just wanted to let you know that, which I'm sceptical about making a public library, I've recently come to think that a private apps library (that's made out of all the apps modules that aren't directly CLI stuff) wouldn't be such a bad thing, for practical purposes. So I want to thank you for the inspiration.

@DDvO
Copy link
Contributor Author

DDvO commented Feb 3, 2018

@mattcaswell and @levitte, very pleased that you confirmed that having such a lib would have practical advantages. and that you put this as a 1.2.0 milestone.

OpenSSL itself will benefit from this even without the need to sanitize and document the interface of such a library. Yet if this extra effort on the API is spent, also external users of OpenSSL would benefit. This would bring a considerable usability boost because OpenSSL-based developments would not need to deal with various awkward and error-prone details, for instance, on file handling, key management, certificate checking using CRLs and OCSP, and management of TLS connections.

@FdaSilvaYY
Copy link
Contributor

This PR needs a rebase.
A smart move would be to split out the opt.h refactoring as as 1st step to this PR.

@mattcaswell
Copy link
Member

This PR needs a rebase.

This PR is very unlikely to be merged as is, so a rebase would be pointless.

@DDvO
Copy link
Contributor Author

DDvO commented Feb 9, 2018

Indeed, no need to rebase since this was essentially a proof-of-concept.

@levitte
Copy link
Member

levitte commented Feb 9, 2018

I suggest it get closed, even.

@DDvO
Copy link
Contributor Author

DDvO commented Feb 10, 2018

If it gets closed I suspect that the milestone tag for 1.2.0 will get neglected.
So in order to keep this PR as a reminder, I'd suggest keeping it open, or maybe it can be transformed into an issue?

@richsalz richsalz modified the milestones: 1.2.0, Post 1.1.0 May 6, 2018
@richsalz richsalz modified the milestones: Post 1.1.0, Assessed May 6, 2018
@DDvO
Copy link
Contributor Author

DDvO commented Jun 25, 2019

Shall we convert this into an issue?

@DDvO
Copy link
Contributor Author

DDvO commented Nov 18, 2020

Closing this in favor of the new issue #13440,
which updates the suggestions made and discussed in this (heavily outdated) PR.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants