OpenBSD Journal

LibreSSL documentation status update

Contributed by schwarze on from the little-strokes-to-great-oaks dept.

More than six years ago, LibreSSL was forked from OpenSSL, and almost two years ago, i explained the status of LibreSSL documentation during EuroBSDCon 2018 in Bucuresti. So it seems providing an update might be in order.

Note that this is not an update regarding LibreSSL status in general because i'm not the right person to talk about the big picture of working on the LibreSSL code, my work has been quite focussed on documentation. All the same, it is fair to say that even though the number of developers working on it is somewhat limited, the LibreSSL project is quite alive, typically having a release every few months. Progress continues being made with respect to porting and adding new functionality (for example regarding TLSv1.3, CMS, RSA-PSS, RSA-OAEP, GOST, SM3, SM4, XChaCha20 during the last two years), OpenSSL compatibility improvements (including providing additional OpenSSL-1.1 APIs), and lots of bug fixes and code cleanup.

Maintaining LibreSSL is a challenge not only due to the many questionable design choices and the dubious code quality inherited from OpenSSL, but also due to its sheer size. With roughly half a million lines of code and documentation, it accounts for more than a third of the lines below /usr/src/lib/ and it is about half the size of the complete /usr/src/usr.bin/ tree — see Appendix 1 for an overview of sizes. Its almost 500 manual pages, documenting just over 3000 functions, account for almost half the manual pages in /usr/share/man/man3/, and for more than half of the functions documented there, even though probably about a third of the LibreSSL API is still completely undocumented.

Currently, there are

  • about 355 pages in librcypto documenting about 2580 functions,
  • about 115 pages in libssl documenting about 390 functions,
  • and 12 pages in libtls documenting 90 functions.

Since 2015, of the above,

Merges of improvements from OpenSSL clustered around 2018 in particular. Before that, i was still quite busy with more fundamental tasks, and lately, OpenSSL development has shifted to the OpenSSL-3 branch, so the number of improvements in the OpenSSL-1.1 branch has somewhat dwindled.

While almost all existing pages have received at least some local improvements that did not come from OpenSSL, these local improvements vary considerably in character and size, from the simplest typo and wording fixes to complete rewrites. The majority of improvements were committed by me, but several other developers also contributed, most prominently Jason McIntyre (jmc@) with almost a hundred commits since 2015.

The above overview implies that even after these six years, of the required LibreSSL documentation,

  • about half is still largely based on OpenSSL manual pages,
  • about one third still does not exist at all,
  • and only about one sixth has been newly written or completely rewritten.

Consequently, it is good to remember that this is still predominantly a large body of inherited text, suffering from a number of systematic deficiencies.

Stages of progress

During the last half decade, improvement of LibreSSL documentation proceeded in several phases.

  1. Markup conversion

    To get started, the markup format was converted from perlpod(1) to mdoc(7).

    This conversion was partially automated using the pod2mdoc(1) program, but no automated check of the correctness is possible, so every single page needed manual review. The tool was already in good shape by February 2015, but the conversion was only finished in a dedicated effort during the l2k16 hackathon in Toulouse more than a year later. A first round of review was already done during the conversion: add some completely missing markup, resolve cases where the automatic presentational to semantic markup conversion went wrong, resolve cases where markup was already bad in the original, and so on. Also, some content improvements were already applied: delete inapplicable or useless text, improve various wordings, improve SEE ALSO sections. The end of this phase was marked by linting and semi-automated checks: for example, cases of functions documented in more than one page were resolved.

    Anthony Bentley (bentley@) committed the libssl part on Oct 12, 2014, and i covered libcrypto with about 20 commits from Feb 14, 2015 to Nov 5, 2016.

  2. MLINKS removal

    The MLINKS — which used to be over 2000 additional file names created with ln(1) below /usr/share/man/ — were removed by Jason McIntyre (jmc@) on Mar 30, 2016 because our mandoc-based man(1) implementation no longer needs them.

  3. Copyright and license audit

    Copyright statements and license headers were missing throughout and were systematically added with about 115 commits in libcrypto and about 45 commits in libssl from Nov 10 to Dec 10, 2016.

    In that phase, many bug fixes were merged from OpenSSL and about 40 missing pages were imported from OpenSSL. Near the end of this phase, the overview pages for BIO, BN, DH, DSA, EC, RSA, and ssl were reorganized to satisfy the principle "every page is named after a function."

  4. ASN.1 object type documentation

    The numerous objects and functions that OpenSSL lumps together in X509_dup.pod were properly documented with about a dozen commits plus about 25 completely new pages from Dec 12 to Dec 24, 2016.

  5. ASN.1 decoding documentation

    Systematic fixes were applied to the d2i_*(3) pages with about 15-20 commits and about 20 completely new pages from Dec 24, 2016 to Jan 7, 2017. OpenSSL still has nothing better than d2i_X509.pod.

  6. Libtls documentation split

    The tls_init(3) manual page was split into more readable parts on Jan 25, 2017.

  7. First attempt to start working towards completeness

    A first attempt was made to systematically start documenting undocumented functions, by starting with one of the most fundamental sub-libraries, BN. However, after a handful of commits from Jan 25 to 31, 2017, this attempt was abandonend because deciding which functions should be documented and which are better left undocumented is a very tedious job.

    This short episode is notable because it illustrates that achieving completeness is a serious challenge, not just due to the size of the API, but also because of serious doubts which parts might better not be public in the first place.

  8. Partial compatibility with the OpenSSL-1.1 API

    Documentation for many newly exposed 1.1 API functions was merged from OpenSSL with about 40 commits in libcrypto and a dozen in libssl from Feb 11 to Mar 20, 2018.

    New text was written for many newly exposed 1.1 API functions with about 20 commits from Feb 22 to Apr 2, 2018, and with about 15 more commits scattered over the years since then.

  9. HISTORY audit

    Proper HISTORY sections were added with about 55 commits in libcrypto and about 20 in libssl from Mar 20 to 27, 2018.

  10. The openssl(1) command line testing tool

    Systematic checks of the openssl(1) manual page started on March 30, 2018 and were finished by INOGUCHI Kinichiro (inoguchi@) with 10 commits from June 7 to July 12, 2019. Later, inoguchi@ added cms (Nov 28, 2019) and certhash (July 14, 2020) entries to this manual page.

  11. Const qualifier additions

    The addition of const qualifiers to many function prototypes was merged from OpenSSL and documented with about 40 commits from Apr 25 to Aug 24, 2018, with a significant fraction of these documentation commits done by Theo Buehler (tb@).

  12. Manual page tree structure

    A systematic tree structure of manual pages was established on Jun 6, 2019 in libcryptro and on Jun 12, 2019 in libssl, making sure that every page can by reached from the crypto(3) and ssl(3) starting points by following at most two .Xr links.

  13. First Genua working phase

    Revisiting the question how to come closer to completeness, a first working phase was funded by genua GmbH, leading to about a dozen commits documenting additional functions in existing pages plus half a dozen completely new pages from Aug 16 to Sep 1, 2019. This phase included work in the AES, ASN1, EC, EVP, OCSP, RSA, and X509 sub-libraries.

  14. Second Genua working phase

    A second working phase was funded by genua GmbH this summer, leading to about another dozen commits documenting additional functions in existing pages plus another dozen completely new pages from May 24, 2020 to Jul 23, 2020. This phase included work in the ChaCha, CMAC, PEM, PKCS7, and again X509 sub-libraries.

Writing documentation finds bugs in the code

In Bucuresti, i already mentioned very briefly that work on documentation revealed bugs in the code in a number of cases. To show that such events are not isolated incidents but happen regularly, here is a complete list of commits fixing bugs that were found while writing LibreSSL documentation:

Open tasks

In Bucuresti, i listed the following open tasks. Even though there has been significant progress since that time, the outline still applies.

  • Completeness on the level of functions

    Many public functions lack manual pages. They need to be written from scratch, or comments should be added saying why they are intentionally undocumented. Before EuroBSDCon 2018, about 70 new pages had been written and about 20 fully rewritten, and i estimated the remaining effort to be at least many months of full-time work.

    Since EuroBSDCon 2018, about 20 additional new pages have been written.

    For one important sublibrary, <openssl/x509.h>, all undocumented public functions have been systematically identified, and it turned out there are almost 200 of them, in X509 alone. Work to get them documented might be attempted in the future, but that is not finally decided yet and there is no estimate so far when that work might be finished. Given that with my current level of experience, i tend to need two hours on average to document one additional function, it is not a trivial task and X509 alone will likely take more than two months of full-time work. I'm not going to work full-time on that task, though.

    Giving an accurate count of the total number of undocumented public functions in LibreSSL, even without documenting any of them, would already cause several days of work, and i believe drafting such a TODO list that cannot be worked through in the near future would be a waste of time. However, my very rough estimate is that the number of undocumented public functions may be on the order of about 1500, with significant uncertainties, see Appendix 6 for an approximate breakdown by sub-libraries.

    For comparison, when i talked to Matt Caswell <matt at openssl dot org> recently (in June 2020), he told me that he believes in OpenSSL, 1530 functions in libcrypto, 40 in libssl, and 160 macros are still undocumented. I can't judge the accuracy of that claim, but the order of magnitude seems consistent with my estimate in LibreSSL; it is plausible that the number of undocumented public functions in OpenSSL is slightly higher given that we wrote significant numbers of new pages.

    In any case, there can be no doubt that writing new documentation for undocumented public functions is by far the most important open task with respect to LibreSSL documentation. This is not only my personal impression. Both documentation professionals and certfication specialists at genua GmbH agree with that assessment, and it seems that the OpenSSL development team agrees, too.

    Either way, the 2018 estimate of "at least many months" was clearly not pessimistic. About one and a half years of full-time work now seem likely to be required, with large uncertainties in the estimation. If you don't want to end up in a similarly unenviable position, think twice before adding additional functions to the library you maintain yourself. Often enough, quantity is not an advantage.

  • Precision, clarity, and internal completeness

    Almost all existing pages need basic copy-editing, they are in general wordy, imprecise, and incomplete. Fixing them usually requires comparing the text to the code, but the code is often contorted, so reading it is time-consuming.

    In 2018, i estimated that this will require at least many months of full-time work, and that estimation is clearly not pessimistic. No such work has been started or planned, and such work probably won't be started or planned while very large numbers of functions are still completely undocumented.

  • The openssl(1) command line testing tool

    At EuroBSDCon 2018, i hoped for a completion of the first pass through the openssl(1) manual page, which i estimated to require about one week of full.time work. INOGUCHI Kinichiro (inoguchi@) completed that pass from June 7 to July 12, 2019. As far as i'm aware, all subcommands and options are now documented.

  • Routine syncs with OpenSSL

    In 2018, i feared that these might cause serious problems in the near future due to the OpenSSL license change to the not-quite-free Apache 2 license. Fortunately, the expected problems did not yet occur in practice because LibreSSL still aims for OpenSSL-1.1 compatility, which is still free, not yet for OpenSSL-3.0 compatibility, which is no longer fully free.

    In this area, about 70 commits to existing pages and about 60 merges of additional pages had already been done before EuroBSDCon 2018, and about 25 commits to existing pages and about 30 merges of additional pages have been added since then.

  • Ongoing maintenance

    Ongoing maintenance of the documentation is required when code is added, deleted, or changed. This aspect is the same as for other software. Some examples are mentioned in the list of stages above.

Error handling and diagnostics

I'd like to discuss one additional aspect here that i did not yet discuss in 2018. Ideally, the documentation of a function should not just describe the input, processing, and output of the function, but also list the errors that can occur and describe how exactly the calling code can distinguish between different types of errors.

For example, in our libc documentation, such information is mostly provided in the form of ERRORS sections, and many section 4 manual pages contain DIAGNOSTICS sections. Compiling these sections is tricky because, well, errors tend to occur in odd situations, and enumerating all possible oddities often isn't a straightforward task. Consequently, many of these sections are not strictly complete. On the other hand, being over-zealous in this respect can easily result in over-documentation, exposing implementation details to the user that the user really should not take into consideration when using the functions because such details might change.

In LibreSSL, the situation is much worse. On the one hand, just like in libc, function return values usually imply a statement about success or failure, and sometimes, just like in libc, the errno(2) might provide a clue what kind of failure occurred. But then, OpenSSL introduced its own system of error codes, which has lots of problems:

  • It is vastly over-engineered, which is a frequent problem with custom-built error reporting frameworks in the real world. I'm not sure why exactly that often tends to happen, but once people start writing their own error reporting framework, it usually quickly gets out of hand. The same happened to me in the past in more than one of my projects. In mandoc, it took many years and many steps to simplify the error reporting framework to a state that i now consider adequate. In OpenSSL, this widespread disease has become particularly bad, with large numbers of functions, many of them quite arcane. The error handling module alone has well over a hundred functions.
  • Even though the framework is overengineered to an unusual degree, it is used in a particularly sloppy way. Many messages, though often long and cryptic, provide almost no useful information to the user, many even consist of text that is not just unspecific, but outright misleading.
  • After failure, OpenSSL does not just provide one error message, but an error stack, in many cases containing several messages. One can argue that alone is already a misdesign. Situations where code can reasonably continue after a first error and try to identify additional, unrelated errors are the exception rather than the norm. And if further errors arise as a consequence of the first one, only the root cause really matters for the user. So, a single, clear error message is almost always better than a bunch of different messages. In OpenSSL, the consequences of this misdesign are even more dire than usual. Sometimes, the most useful message is at the bottom of the stack, sometimes at the top, and sometimes in the middle. It often happens that there are many messages on the stack, but all of them are non-specific and none of them are helpful. And in addition, how to use these stacks isn't even properly documented, neither for developers changing the library nor for application programmers using the library.
  • Even worse, in many cases, OpenSSL functions return failure without reporting the reason to the official framework. This even happens frequently in functions that do report reasons for failure at other places. Consequently, the majority of functions can fail both with and without providing reasons.
  • In many cases, functions that are not documented to use the error handling framework and that indeed don't use it themselves call functions internally that do use it, which may cause erratic messages to end up on the error stack, no matter whether the function the user called failed or succeeded. This can cause confusion when these messages persist until another, later error occurs.
  • Some functions conditionally or unconditionally clear the error stack. That is comparable to reckless "errno = 0;" statements in libc, and it can hide earlier errors. I did not search specifically, but i don't remember ever seeing proper idioms that save the state of the stack immediately before an internal operation that may fail, do the operation, check success, then accordingly restore the stack immediately afterwards, similar to the widespread idiom "int save_errno = errno; if (do_something() == -1) return -1; errno = save_errno;" in libc.
  • Whether or not a given function uses the error reporting framework at all is only occasionally mentioned in the manual pages; most are completely silent about the question. Even when it is mentioned, it usually remains unclear whether the reason is reported for all or only for some errors, and manual pages that document specific error codes as resulting from specific error conditions hardly exist at all.
  • On top of all that, not only error reporting is highly erratic in OpenSSL, but even mere error detection is often defective. Many functions may silently return success even when essential operations they attempted failed, simply because they neglect to check for some failure conditions.

So, the obvious task of documenting how error reporting works is practically impossible to disentangle from auditing the code and improving the error handling throughout, probably at least at hundreds of places. This is clearly a large project, but i believe it might be a relevant one. It cannot be disentangled from documentation work, but it can be started in parallel to writing new documentation for undocumented public functions. So far, it was not started, and no plans for starting it have been made yet.

Conclusions

While the LibreSSL project is alive and constantly improving, and while LibreSSL documentation has been significantly better than OpenSSL documentation for more than two years now, the quality of LibreSSL documentation is still notably below OpenBSD quality standards regarding completeness and precision. Some of the defects in the documentation are linked to defects in the code, and besides, inspecting code in order to document it tends to find bugs even when not specifically searching for them, so working on the documentation also helps the code.

During the last half decade, significant progress has been made by converting to a better markup format, adding about 200 manual pages that were missing and replacing about 20 that were of particularly bad quality, merging improvements from OpenSSL to about 100 existing pages, and committing local improvements to almost all pages. Like in other parts of OpenBSD, most of this work has been done on a voluntary basis, but it is greatly appreciated that genua GmbH helps to speed up progress by providing some funding for specific subtasks.

The most important open task remains that roughly one out of three public interface functions is still completely undocumented, with almost all sub-libraries affected and with an estimated grand total of about 1500 undocumented public functions. That problem will not be solved in the short term, but some progress keeps being made.

Additionally, auditing existing pages for completeness and precision and auditing, documenting, and possibly simplifying error handling and error reporting would be desirable. So, much still remains to be done regarding LibreSSL documentation.


Providing this update was suggested by Moritz Buhl, who kindly sponsors my Free Software work on Patreon. Please also remember that the normal way of supporting OpenBSD, LibreSSL, and mandoc development is through the OpenBSD foundation.


Appendices

  1. Lines of code and documentation

    The following are very rough estimates of lines of code and documentation in various parts of the src tree. I'm not counting /usr/src/gnu/ — which is a backronym for "Gigantic and Nasty but Unfortunately Unavoidable" — because some parts of that are of outright appalling size. GNU is about double the size of the grand total of everything listed below.

    sys:           8000 files, 5000k lines
    lib:           6000 files, 1300k lines
      LibreSSL:    1500 files,  500k lines
        libcrypto: 1200 files,  420k lines
        libssl:     245 files,   70k lines
        libtls:      30 files,    7k lines
    usr.bin:       2800 files,  900k lines
    usr.sbin:      2400 files, 1000k lines
    sbin:           700 files,  330k lines
    bin:            450 files,  100k lines
    libexec:        260 files,   50k lines
    games:          580 files,  200k lines
    include:        110 files,   15k lines
    share:         1500 files,  600k lines
    distrib:        400 files,   65k lines
    etc:            320 files,   20k lines
    regress:      19000 files,  900k lines
    
  2. List of new pages written from scratch

    EVP_AEAD_CTX_init(3) Oct 14 07:41:28 2015 +0000 reyk@
    ASN1_time_parse(3) Nov 4 18:07:23 2016 +0000 beck@
    BN_set_negative(3) Nov 5 20:36:11 2016 +0000 schwarze@
    OPENSSL_malloc(3) Nov 28 16:33:48 2016 +0000 schwarze@
    SSL_SESSION_new(3) Dec 6 18:40:31 2016 +0000 schwarze@
    SSL_SESSION_print(3) Dec 6 23:45:34 2016 +0000 schwarze@
    SSL_dup_CA_list(3) Dec 7 15:14:34 2016 +0000 schwarze@
    SSL_dup(3) Dec 7 17:09:07 2016 +0000 schwarze@
    SSL_copy_session_id(3) Dec 7 18:09:31 2016 +0000 schwarze@
    SSL_renegotiate(3) Dec 7 20:11:55 2016 +0000 schwarze@
    SSL_get_certificate(3) Dec 10 13:54:32 2016 +0000 schwarze@
    SSL_get_state(3) Dec 10 13:54:32 2016 +0000 schwarze@
    SSL_num_renegotiations(3) Dec 10 13:54:32 2016 +0000 schwarze@
    SSL_get_shared_ciphers(3) Dec 10 14:56:56 2016 +0000 schwarze@
    OCSP_CRLID_new(3) Dec 12 22:48:02 2016 +0000 schwarze@
    OCSP_SERVICELOC_new(3) Dec 12 22:48:02 2016 +0000 schwarze@
    PKCS7_new(3) Dec 13 14:31:55 2016 +0000 schwarze@
    RSA_PSS_PARAMS_new(3) Dec 13 20:41:35 2016 +0000 schwarze@
    ESS_SIGNING_CERT_new(3) Dec 14 02:03:50 2016 +0000 schwarze@
    TS_REQ_new(3) Dec 14 02:03:50 2016 +0000 schwarze@
    X509_NAME_new(3) Dec 14 15:04:13 2016 +0000 schwarze@
    X509_CINF_new(3) Dec 16 09:17:59 2016 +0000 schwarze@
    X509_CRL_new(3) Dec 16 09:56:33 2016 +0000 schwarze@
    X509_REQ_new(3) Dec 17 01:08:14 2016 +0000 schwarze@
    X509_ATTRIBUTE_new(3) Dec 17 14:51:09 2016 +0000 schwarze@
    PKCS8_PRIV_KEY_INFO_new(3) Dec 22 12:10:06 2016 +0000 schwarze@
    X509_SIG_new(3) Dec 22 14:06:51 2016 +0000 schwarze@
    PKCS12_new(3) Dec 22 16:05:22 2016 +0000 schwarze@
    PKCS12_SAFEBAG_new(3) Dec 22 16:05:22 2016 +0000 schwarze@
    GENERAL_NAME_new(3) Dec 23 00:40:16 2016 +0000 schwarze@
    AUTHORITY_KEYID_new(3) Dec 23 14:37:08 2016 +0000 schwarze@
    DIST_POINT_new(3) Dec 23 15:25:19 2016 +0000 schwarze@
    BASIC_CONSTRAINTS_new(3) Dec 23 17:02:41 2016 +0000 schwarze@
    NAME_CONSTRAINTS_new(3) Dec 23 17:41:29 2016 +0000 schwarze@
    POLICYINFO_new(3) Dec 23 18:50:23 2016 +0000 schwarze@
    EXTENDED_KEY_USAGE_new(3) Dec 23 20:43:02 2016 +0000 schwarze@
    ACCESS_DESCRIPTION_new(3) Dec 23 22:21:40 2016 +0000 schwarze@
    PROXY_POLICY_new(3) Dec 23 23:19:57 2016 +0000 schwarze@
    PKEY_USAGE_PERIOD_new(3) Dec 23 23:50:04 2016 +0000 schwarze@
    SXNET_new(3) Dec 24 01:00:48 2016 +0000 schwarze@
    d2i_PKCS12(3) Dec 26 18:04:45 2016 +0000 schwarze@
    d2i_PKCS7(3) Dec 26 18:52:51 2016 +0000 schwarze@
    d2i_ESS_SIGNING_CERT(3) Dec 27 20:56:18 2016 +0000 schwarze@
    d2i_TS_REQ(3) Dec 27 20:56:18 2016 +0000 schwarze@
    d2i_OCSP_REQUEST(3) Dec 27 22:06:55 2016 +0000 schwarze@
    d2i_OCSP_RESPONSE(3) Dec 27 22:06:55 2016 +0000 schwarze@
    d2i_PKCS8_PRIV_KEY_INFO(3) Dec 28 00:55:05 2016 +0000 schwarze@
    d2i_X509_ATTRIBUTE(3) Dec 28 13:45:30 2016 +0000 schwarze@
    d2i_X509_EXTENSION(3) Dec 28 20:36:33 2016 +0000 schwarze@
    d2i_AUTHORITY_KEYID(3) Dec 28 20:36:33 2016 +0000 schwarze@
    d2i_BASIC_CONSTRAINTS(3) Dec 28 20:36:33 2016 +0000 schwarze@
    d2i_DIST_POINT(3) Dec 28 20:36:33 2016 +0000 schwarze@
    d2i_GENERAL_NAME(3) Dec 28 20:36:33 2016 +0000 schwarze@
    d2i_PKEY_USAGE_PERIOD(3) Dec 28 20:36:33 2016 +0000 schwarze@
    d2i_POLICYINFO(3) Dec 28 20:36:33 2016 +0000 schwarze@
    d2i_PROXY_POLICY(3) Dec 28 20:36:33 2016 +0000 schwarze@
    d2i_ASN1_NULL(3) Dec 29 17:42:54 2016 +0000 schwarze@
    d2i_ASN1_SEQUENCE_ANY(3) Jan 4 21:14:26 2017 +0000 schwarze@
    d2i_ASN1_OCTET_STRING(3) Jan 5 22:38:04 2017 +0000 schwarze@
    X509_STORE_load_locations(3) Jan 7 00:45:04 2017 +0000 schwarze@
    get_rfc3526_prime_8192(3) Jan 31 05:40:26 2017 +0000 schwarze@
    ERR_asprintf_error_data(3) Feb 20 23:21:19 2017 +0000 beck@
    BIO_printf(3) Mar 25 17:15:59 2017 +0000 schwarze@
    SSL_set_tmp_ecdh(3) Aug 12 12:31:30 2017 +0000 schwarze@
    ASN1_STRING_TABLE_add(3) Aug 20 15:01:20 2017 +0000 schwarze@
    X509_check_private_key(3) Aug 20 23:18:53 2017 +0000 schwarze@
    X509_get0_notBefore(3) Feb 15 10:01:33 2018 +0000 schwarze@
    SSL_CTX_get0_certificate(3) Feb 18 22:18:59 2018 +0000 schwarze@
    X509_OBJECT_get0_X509(3) Feb 25 20:26:51 2018 +0000 schwarze@
    OPENSSL_sk_new(3) Mar 1 19:20:09 2018 +0000 schwarze@
    STACK_OF(3) Mar 1 19:20:09 2018 +0000 schwarze@
    OPENSSL_init_ssl(3) Mar 17 18:52:42 2018 +0000 schwarze@
    CMS_ContentInfo_new(3) Aug 12 14:24:38 2019 +0000 schwarze@
    EC_KEY_METHOD_new(3) Aug 16 16:15:50 2019 +0000 schwarze@
    ECDH_compute_key(3) Aug 19 13:08:26 2019 +0000 schwarze@
    X509_INFO_new(3) Aug 19 13:52:53 2019 +0000 schwarze@
    X509_check_purpose(3) Aug 22 15:15:35 2019 +0000 schwarze@
    X509_get1_email(3) Aug 23 12:23:39 2019 +0000 schwarze@
    ASN1_put_object(3) Aug 26 11:41:31 2019 +0000 schwarze@
    AES_encrypt(3) Aug 28 10:37:42 2019 +0000 schwarze@
    PKCS7_set_type(3) May 16 00:11:55 2020 +0000 schwarze@
    PKCS7_set_content(3) May 20 11:40:26 2020 +0000 schwarze@
    PKCS7_dataInit(3) May 24 12:37:30 2020 +0000 schwarze@
    PKCS7_dataFinal(3) May 27 12:00:44 2020 +0000 schwarze@
    PKCS7_final(3) Jun 3 13:41:27 2020 +0000 schwarze@
    PKCS7_add_attribute(3) Jun 4 10:24:27 2020 +0000 schwarze@
    PKCS7_get_signer_info(3) Jun 10 11:43:07 2020 +0000 schwarze@
    PEM_ASN1_read(3) Jun 12 11:37:42 2020 +0000 schwarze@
    CMAC_Init(3) Jun 24 16:06:26 2020 +0000 schwarze@
    ChaCha(3) Jun 24 17:00:38 2020 +0000 schwarze@
    PEM_X509_INFO_read(3) Jul 23 17:34:53 2020 +0000 schwarze@
  3. List of complete rewrites

    SSL_COMP_add_compression_method(3) Nov 29 19:52:17 2016 +0000 schwarze@
    d2i_X509_NAME(3) Dec 14 16:18:31 2016 +0000 schwarze@
    d2i_X509_SIG(3) Dec 28 02:48:59 2016 +0000 schwarze@
    d2i_X509_ALGOR(3) Dec 28 14:17:47 2016 +0000 schwarze@
    d2i_X509_CRL(3) Dec 28 14:59:39 2016 +0000 schwarze@
    d2i_X509_REQ(3) Dec 28 15:18:05 2016 +0000 schwarze@
    d2i_ASN1_OBJECT(3) Jan 4 09:04:45 2017 +0000 schwarze@
    ASN1_STRING_new(3) Jan 5 06:08:31 2017 +0000 schwarze@
    ENGINE_add(3) Apr 15 01:43:45 2018 +0000 schwarze@
    ENGINE_ctrl(3) Apr 15 01:43:45 2018 +0000 schwarze@
    ENGINE_get_default_RSA(3) Apr 15 01:43:45 2018 +0000 schwarze@
    ENGINE_init(3) Apr 15 01:43:45 2018 +0000 schwarze@
    ENGINE_register_RSA(3) Apr 15 01:43:45 2018 +0000 schwarze@
    ENGINE_register_all_RSA(3) Apr 15 01:43:45 2018 +0000 schwarze@
    ENGINE_set_default(3) Apr 15 01:43:45 2018 +0000 schwarze@
    ENGINE_unregister_RSA(3) Apr 15 01:43:45 2018 +0000 schwarze@
    ENGINE_new(3) Apr 15 17:02:03 2018 +0000 schwarze@
    ENGINE_set_RSA(3) Apr 15 17:02:03 2018 +0000 schwarze@
    ENGINE_set_flags(3) Apr 15 17:02:03 2018 +0000 schwarze@
  4. List of pages imported from OpenSSL

    ASN1_TIME_set(3) Nov 10 14:42:21 2016 +0000 schwarze@
    ASN1_TYPE_get(3) Nov 11 01:18:19 2016 +0000 schwarze@
    BIO_get_ex_new_index(3) Nov 18 18:54:43 2016 +0000 schwarze@
    BN_get0_nist_prime_521(3) Nov 21 11:38:54 2016 +0000 schwarze@
    DTLSv1_listen(3) Nov 21 13:52:28 2016 +0000 schwarze@
    EVP_EncodeInit(3) Nov 26 18:09:35 2016 +0000 schwarze@
    OCSP_REQUEST_new(3) Nov 27 20:40:07 2016 +0000 schwarze@
    OCSP_cert_to_id(3) Nov 27 20:40:07 2016 +0000 schwarze@
    OCSP_request_add1_nonce(3) Nov 27 20:40:07 2016 +0000 schwarze@
    OCSP_resp_find_status(3) Nov 27 20:40:07 2016 +0000 schwarze@
    OCSP_response_status(3) Nov 27 20:40:07 2016 +0000 schwarze@
    OCSP_sendreq_new(3) Nov 27 20:40:07 2016 +0000 schwarze@
    PEM_read(3) Nov 28 17:55:26 2016 +0000 schwarze@
    PEM_read_SSL_SESSION(3) Nov 28 21:05:21 2016 +0000 schwarze@
    PKCS12_newpass(3) Nov 28 23:02:16 2016 +0000 schwarze@
    SSL_set1_param(3) Nov 30 13:39:38 2016 +0000 schwarze@
    SSL_CTX_set_alpn_select_cb(3) Nov 30 16:46:56 2016 +0000 schwarze@
    SSL_CTX_set_read_ahead(3) Dec 1 16:48:36 2016 +0000 schwarze@
    SSL_set_max_send_fragment(3) Dec 1 19:40:05 2016 +0000 schwarze@
    SSL_CTX_set_tlsext_status_cb(3) Dec 1 21:12:49 2016 +0000 schwarze@
    SSL_CTX_set_tlsext_ticket_key_cb(3) Dec 1 21:12:49 2016 +0000 schwarze@
    X509V3_get_d2i(3) Dec 4 20:51:47 2016 +0000 schwarze@
    X509_ALGOR_dup(3) Dec 4 20:51:47 2016 +0000 schwarze@
    X509_CRL_get0_by_serial(3) Dec 4 20:51:47 2016 +0000 schwarze@
    X509_EXTENSION_set_object(3) Dec 4 20:51:47 2016 +0000 schwarze@
    X509_LOOKUP_hash_dir(3) Dec 4 20:51:47 2016 +0000 schwarze@
    X509_PUBKEY_new(3) Dec 5 12:50:07 2016 +0000 schwarze@
    X509_check_ca(3) Dec 5 15:56:46 2016 +0000 schwarze@
    X509_check_host(3) Dec 5 15:56:46 2016 +0000 schwarze@
    X509_check_issued(3) Dec 5 15:56:46 2016 +0000 schwarze@
    X509_STORE_set1_param(3) Dec 5 16:13:19 2016 +0000 schwarze@
    X509_get_pubkey(3) Dec 5 18:24:08 2016 +0000 schwarze@
    X509_get_serialNumber(3) Dec 5 18:24:08 2016 +0000 schwarze@
    X509_get_subject_name(3) Dec 5 18:24:08 2016 +0000 schwarze@
    X509_get_version(3) Dec 5 18:24:08 2016 +0000 schwarze@
    X509_sign(3) Dec 5 18:24:08 2016 +0000 schwarze@
    X509v3_get_ext_by_NID(3) Dec 5 18:24:08 2016 +0000 schwarze@
    d2i_PrivateKey(3) Dec 5 20:30:12 2016 +0000 schwarze@
    openssl.cnf(5) Dec 11 18:06:09 2016 +0000 schwarze@
    x509v3.cnf(5) Dec 11 18:06:09 2016 +0000 schwarze@
    UI_UTIL_read_pw(3) Mar 26 00:06:10 2017 +0000 schwarze@
    UI_create_method(3) Mar 26 00:06:10 2017 +0000 schwarze@
    UI_get_string_type(3) Mar 26 00:06:10 2017 +0000 schwarze@
    SSL_CTX_set_tlsext_servername_callback(3) Apr 10 13:05:06 2017 +0000 schwarze@
    SSL_get_server_tmp_key(3) Apr 10 15:54:46 2017 +0000 schwarze@
    X25519(3) Apr 10 17:45:06 2017 +0000 schwarze@
    SSL_CTX_set1_groups(3) Aug 12 14:09:34 2017 +0000 schwarze@
    SSL_CTX_set_min_proto_version(3) Aug 19 23:45:10 2017 +0000 schwarze@
    EVP_PKEY_meth_get0_info(3) Aug 20 19:21:20 2017 +0000 schwarze@
    PEM_bytes_read_bio(3) Sun Aug 20 20:15:13 2017 +0000 schwarze@
    SSL_export_keying_material(3) Aug 21 10:10:25 2017 +0000 schwarze@
    EVP_PKEY_asn1_new(3) Feb 14 02:15:46 2018 +0000 schwarze@
    X509_get_signature_nid(3) Feb 14 18:50:47 2018 +0000 schwarze@
    EVP_PKEY_asn1_get_count(3) Feb 15 12:09:55 2018 +0000 schwarze@
    EVP_PKEY_meth_new(3) Feb 15 14:52:16 2018 +0000 schwarze@
    SSL_get_client_random(3) Feb 18 23:34:01 2018 +0000 schwarze@
    BIO_get_data(3) Feb 19 14:08:52 2018 +0000 schwarze@
    SSL_SESSION_get_protocol_version(3) Feb 24 19:24:09 2018 +0000 schwarze@
    SSL_CTX_set_tlsext_use_srtp(3) Feb 27 18:30:30 2018 +0000 schwarze@
    SSL_SESSION_has_ticket(3) Mar 17 18:19:49 2018 +0000 schwarze@
    ASN1_INTEGER_get(3) Jul 8 23:00:17 2018 +0000 schwarze@
    EVP_sm4_cbc(3) Mar 18 05:56:24 2019 +0000 schwarze@
    EVP_camellia_128_cbc(3) Mar 21 14:15:13 2019 +0000 schwarze@
    SSL_CTX_add1_chain_cert(3) Apr 5 18:29:43 2019 +0000 schwarze@
    BIO_new_CMS(3) Aug 10 23:41:22 2019 +0000 and Nov 2 15:12:31 2019 +0000 schwarze@
    CMS_add0_cert(3) Aug 10 23:41:22 2019 +0000 and Nov 2 15:12:31 2019 +0000 schwarze@
    CMS_add1_recipient_cert(3) Aug 10 23:41:22 2019 +0000 and Nov 2 15:12:31 2019 +0000 schwarze@
    CMS_add1_signer(3) Aug 10 23:41:22 2019 +0000 and Nov 2 15:12:31 2019 +0000 schwarze@
    CMS_compress(3) Aug 10 23:41:22 2019 +0000 and Nov 2 15:12:31 2019 +0000 schwarze@
    CMS_decrypt(3) Aug 10 23:41:22 2019 +0000 and Nov 2 15:12:31 2019 +0000 schwarze@
    CMS_encrypt(3) Aug 10 23:41:22 2019 +0000 and Nov 2 15:12:31 2019 +0000 schwarze@
    CMS_final(3) Aug 10 23:41:22 2019 +0000 and Nov 2 15:12:31 2019 +0000 schwarze@
    CMS_get0_RecipientInfos(3) Aug 10 23:41:22 2019 +0000 and Nov 2 15:12:31 2019 +0000 schwarze@
    CMS_get0_SignerInfos(3) Aug 10 23:41:22 2019 +0000 and Nov 2 15:12:31 2019 +0000 schwarze@
    CMS_get0_type(3) Aug 10 23:41:22 2019 +0000 and Nov 2 15:12:31 2019 +0000 schwarze@
    CMS_get1_ReceiptRequest(3) Aug 10 23:41:22 2019 +0000 and Nov 2 15:12:31 2019 +0000 schwarze@
    CMS_sign(3) Aug 10 23:41:22 2019 +0000 and Nov 2 15:12:31 2019 +0000 schwarze@
    CMS_sign_receipt(3) Aug 10 23:41:22 2019 +0000 and Nov 2 15:12:31 2019 +0000 schwarze@
    CMS_uncompress(3) Aug 10 23:41:22 2019 +0000 and Nov 2 15:12:31 2019 +0000 schwarze@
    CMS_verify(3) Aug 10 23:41:22 2019 +0000 and Nov 2 15:12:31 2019 +0000 schwarze@
    CMS_verify_receipt(3) Aug 10 23:41:22 2019 +0000 and Nov 2 15:12:31 2019 +0000 schwarze@
    PEM_write_bio_CMS_stream(3) Aug 10 23:41:22 2019 +0000 and Nov 2 15:12:31 2019 +0000 schwarze@
    SMIME_read_CMS(3) Aug 10 23:41:22 2019 +0000 and Nov 2 15:12:31 2019 +0000 schwarze@
    SMIME_write_CMS(3) Aug 10 23:41:22 2019 +0000 and Nov 2 15:12:31 2019 +0000 schwarze@
    i2d_CMS_bio_stream(3) Aug 10 23:41:22 2019 +0000 and Nov 2 15:12:31 2019 +0000 schwarze@
    X509_cmp(3) Aug 20 13:27:19 2019 +0000 schwarze@
    CRYPTO_memcmp(3) Aug 25 06:20:22 2019 +0000 schwarze@
    EVP_sm3(3) Aug 25 17:08:20 2019 +0000 schwarze@
    EVP_whirlpool(3) Aug 25 17:08:20 2019 +0000 schwarze@
  5. Merges of improvements to existing pages from OpenSSL

    • Dec 2016: 4 commits
    • spring 2017: 14 commits
    • summer 2017: 14 commits
    • spring 2018: 37 commits
    • Dec 2018: 10 commits
    • spring 2019: 6 commits
    • summer 2019: 5 commits
    • autumn 2019: 3 commits
  6. Estimating the number of undocumented public functions

    sublib   tot  doc  undoc
    AES       15    5   10
    ASN1     200  100  100
    BF         8    8       complete?
    BIO      240  150   90
    BN       190  140   50
    BUF       10    5    5
    Camellia  10        10
    CAST      10        10
    ChaCha     6    6       complete
    CMAC       9    9       complete
    CMS      120   50   70
    COMP      10        10
    CONF      55    5   50  incl. NCONF
    CRYPTO   145   35  110  incl. poly1305.h
    DES       40   30   10
    DH        40   30   10
    DSA       60   40   20
    DSO       25        25
    EC       190  155   35
    ENGINE   145  110   35
    ERR      110   35   75
    EVP      425  395   30
    GOST      40        40  incl. STREEBOG
    HKDF       3
    HMAC      15   15       complete?
    idea      10        10
    MD4        5    4
    MD5        5    4
    OBJ       30   15   15
    OCSP     165   65  100
    OPENSSL   20   17       scattered around *.h
    PEM      120  105   15
    PKCS12    70   15   55  incl. PKCS8
    PKCS7    110   45   65
    RAND      15   15       complete?
    RC2        7
    RC4        4    2
    RIPEMD     5    4
    RSA      130   85   45
    SHA       20   20       complete?
    SM3        3
    SM4        3
    TS       180   20  160
    TXT_DB     7
    UI        60   55    5
    WHIRLPOOL  5
    X25519     2    2       complete?
    X509     510  310  200
    SSL      470  385   85
    

    So the sum may be about 1450 undocumented functions in libcrypto and about 85 in libssl.

(Comments are closed)


Comments
  1. By Billy Larlad (billylarlad) on

    Thanks a lot for the update, Ingo! Like all your work on the project, this is very meticulous.

Credits

Copyright © - Daniel Hartmeier. All rights reserved. Articles and comments are copyright their respective authors, submission implies license to publish on this web site. Contents of the archive prior to as well as images and HTML templates were copied from the fabulous original deadly.org with Jose's and Jim's kind permission. This journal runs as CGI with httpd(8) on OpenBSD, the source code is BSD licensed. undeadly \Un*dead"ly\, a. Not subject to death; immortal. [Obs.]