From 8ebd88950d9d0a94037e4962daa6e80a464bea06 Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Tue, 6 Oct 2020 16:11:17 +0200 Subject: [PATCH] Document how deprecation should be done Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/13074) --- doc/internal/man7/deprecation.pod | 225 ++++++++++++++++++++++++++++ doc/man7/openssl_user_macros.pod.in | 3 +- util/missingmacro.txt | 11 ++ 3 files changed, 238 insertions(+), 1 deletion(-) create mode 100644 doc/internal/man7/deprecation.pod diff --git a/doc/internal/man7/deprecation.pod b/doc/internal/man7/deprecation.pod new file mode 100644 index 0000000000..e55da1ffe4 --- /dev/null +++ b/doc/internal/man7/deprecation.pod @@ -0,0 +1,225 @@ +=pod + +=head1 NAME + +deprecation - Macros used for deprecating symbols and simulate removal + +=head1 SYNOPSIS + + #include + + OSSL_DEPRECATED(since) + OSSL_DEPRECATED_FOR(since, msg) + + OPENSSL_NO_DEPRECATED_3_0 + OSSL_DEPRECATEDIN_3_0 + OSSL_DEPRECATEDIN_3_0_FOR(msg) + + OPENSSL_NO_DEPRECATED_1_1_1 + OSSL_DEPRECATEDIN_1_1_1 + OSSL_DEPRECATEDIN_1_1_1_FOR(msg) + + OPENSSL_NO_DEPRECATED_1_1_0 + OSSL_DEPRECATEDIN_1_1_0 + OSSL_DEPRECATEDIN_1_1_0_FOR(msg) + + OPENSSL_NO_DEPRECATED_1_0_2 + OSSL_DEPRECATEDIN_1_0_2 + OSSL_DEPRECATEDIN_1_0_2_FOR(msg) + + OPENSSL_NO_DEPRECATED_1_0_1 + OSSL_DEPRECATEDIN_1_0_1 + OSSL_DEPRECATEDIN_1_0_1_FOR(msg) + + OPENSSL_NO_DEPRECATED_1_0_0 + OSSL_DEPRECATEDIN_1_0_0 + OSSL_DEPRECATEDIN_1_0_0_FOR(msg) + + OPENSSL_NO_DEPRECATED_0_9_8 + OSSL_DEPRECATEDIN_0_9_8 + OSSL_DEPRECATEDIN_0_9_8_FOR(msg) + +=head1 DESCRIPTION + +Deprecation of a symbol is adding an attribute to the declaration of that +symbol (function, type, variable, but we currently only do that for +functions in our F<< >> header files). + +Removal of a symbol is not the same thing as deprecation, as it actually +removes the symbol from public view. + +OpenSSL configuration supports deprecation as well as simulating removal of +symbols from public view, and also supports doing this in terms of a +specified OpenSSL version. + +Deprecation is done using attribute macros having names starting with +B, used with any declaration it applies to. + +Simulating removal is done with guard macros having names starting with +L. + +The implementation of a deprecated symbol is kept for two reasons: + +=over 4 + +=item Kept as legacy for the deprecation period + +It's implemented only to have it available as long as the symbol isn't +removed entirely (be it by explicitly removing it when it's judged that it +has been deprecated long enough, or because the removal is simulated). +These need to be guarded appropriately, as shown in the L. + +=item Kept for internal purposes + +The implementation doesn't need to change or be guarded. However, it's +necessary to ensure that the declaration remains available for the +translation unit where the implementation is located, even when the symbol +is publicly unavailable through simulated removal. That's done by including +an internal header file very early in the translation unit. See +L. + +In a future cleanup, the declaration should be explicitly moved to an +internal header file, with the deprecation attribute removed, and the +translation unit should adjust its header inclusions accordingly. + +=back + +=head2 General macros + +I + +OSSL_DEPRECATED() implements the deprecated attribute if the compiler +supports it, otherwise it expands to nothing. It takes one argument +I that should be set to the OpenSSL version where the symbol was +deprecated, and will be displayed with the deprecation warning message, +for compilers that support user specified deprecation messages. + +OSSL_DEPRECATED_FOR() does the same as OSSL_DEPRECATED(), but also takes a +second argument I, which is an additional text messages to be displayed +with the deprecation warning along with the OpenSSL version number, for +compilers that support user specified deprecation messages. + +B is a macro that's generated by OpenSSL +configuration in response to the C configuration option. +This macro suppresses the definition of deprecated symbols. + +=head2 Version specific macros + +OSSL_DEPRECATEDIN_I_I() macros that are defined to +OSSL_DEPRECATED() with that version number as I, for any version up +to and including the one expressed with L. For any +known version above the version expressed with L, +The are defined to nothing. + +OSSL_DEPRECATEDIN_I_I_FOR() macros that are defined to +OSSL_DEPRECATED() with that version number as I, under the same +conditions as OSSL_DEPRECATEDIN_I_I(). + +B_I> macros should be used as +guards around declarations that will eventually disappear from the public +header files (F<< >>). + +Any set of symbols deprecated with a B_I> +attribute macro B be wrapped with a guard using the corresponding +B_I> macro, see L +example below. This not only affects what the user of the header file will +have available, it's also used to determine the conditions for exporting the +symbol in the shared libraries. + +=head1 EXAMPLES + +=head2 Header files + +In public header files (F<< >>), a deprecated symbol will +always be wrapped with a negative test of the guard: + + # ifndef OPENSSL_NO_DEPRECATED_1_1_0 + /* ... */ + OSSL_DEPRECATEDIN_1_1_0 __owur int + HMAC_Init(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md); + /* ... */ + # endif + +=head2 Implementations of deprecated symbols + +At least for the period of deprecation for any symbol, its implementation +needs to be kept, and for symbols that are kept internally, for longer than +that. There are two things to deal with: + +=over 4 + +=item Deprecation warnings + +To remedy deprecation warnings, simply define the macro +B at the beginning of the translation unit. + +=item Simulated removal + +=over 4 + +=item * + +For symbols that are kept as legacy, the simulated removal should be +enforced, by guarding the implementation the exact same way as the +declaration in the public header file. + +=item * + +For symbols that are planned to be kept internally beyond their deprecation +period, the translation units that implement them must ensure that the +public header files they include to that declare the symbols don't remove +the symbols, even when removal is otherwise simulated. + +=back + +=back + +=head3 Implementations kept as legacy + +For a deprecated function that we plan to simply remove, for example +RSA_new_method(), the following should be found very early (before including +any OpenSSL header file) in the translation unit: + + /* + * Suppress deprecation warnings for RSA low level implementations that are + * kept until removal. + */ + #define OPENSSL_SUPPRESS_DEPRECATED + +And RSA_new_method() implementation itself should be guarded like this: + + #ifndef OPENSSL_NO_DEPRECATED_3_0 + RSA *RSA_new_method(ENGINE *engine) + { + /* ... */ + } + #endif + +=head3 Implementations kept for internal purposes + +For a deprecated function that we plan to keep internally, for example +RSA_size(), the following should be found very early (before including any +other OpenSSL header file) in the translation unit: + + /* + * RSA low level APIs are deprecated for public use, but are kept for + * internal use. + */ + #include "internal/deprecated.h" + +=head1 SEE ALSO + +L + +=head1 COPYRIGHT + +Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man7/openssl_user_macros.pod.in b/doc/man7/openssl_user_macros.pod.in index 8e9d116e17..33969e2476 100644 --- a/doc/man7/openssl_user_macros.pod.in +++ b/doc/man7/openssl_user_macros.pod.in @@ -2,7 +2,8 @@ =head1 NAME -openssl_user_macros, OPENSSL_API_COMPAT - User defined macros +openssl_user_macros, OPENSSL_API_COMPAT, OPENSSL_NO_DEPRECATED +- User defined macros =head1 DESCRIPTION diff --git a/util/missingmacro.txt b/util/missingmacro.txt index 2b02fef5f5..109bb0870f 100644 --- a/util/missingmacro.txt +++ b/util/missingmacro.txt @@ -176,3 +176,14 @@ X509V3_set_ctx_test(3) X509V3_set_ctx_nodb(3) EXT_BITSTRING(3) EXT_IA5STRING(3) + +# These are documented internally, in doc/internal/man7/deprecation.pod +OSSL_DEPRECATED(3) +OSSL_DEPRECATED_FOR(3) +OSSL_DEPRECATEDIN_3_0_FOR(3) +OSSL_DEPRECATEDIN_1_1_1_FOR(3) +OSSL_DEPRECATEDIN_1_1_0_FOR(3) +OSSL_DEPRECATEDIN_1_0_2_FOR(3) +OSSL_DEPRECATEDIN_1_0_1_FOR(3) +OSSL_DEPRECATEDIN_1_0_0_FOR(3) +OSSL_DEPRECATEDIN_0_9_8_FOR(3) -- GitLab