David Benjamin | 65703b4 | 2015-09-02 16:51:42 -0400 | [diff] [blame] | 1 | # Porting from OpenSSL to BoringSSL |
| 2 | |
| 3 | BoringSSL is an OpenSSL derivative and is mostly source-compatible, for the |
| 4 | subset of OpenSSL retained. Libraries ideally need little to no changes for |
| 5 | BoringSSL support, provided they do not use removed APIs. In general, see if the |
| 6 | library compiles and, on failure, consult the documentation in the header files |
| 7 | and see if problematic features can be removed. |
| 8 | |
| 9 | In some cases, BoringSSL-specific code may be necessary. In that case, the |
| 10 | `OPENSSL_IS_BORINGSSL` preprocessor macro may be used in `#ifdef`s. This macro |
| 11 | should also be used in lieu of the presence of any particular function to detect |
| 12 | OpenSSL vs BoringSSL in configure scripts, etc., where those are necessary. |
| 13 | |
| 14 | For convenience, BoringSSL defines upstream's `OPENSSL_NO_*` feature macros |
| 15 | corresponding to removed features. These may also be used to disable code which |
| 16 | uses a removed feature. |
| 17 | |
| 18 | Note: BoringSSL does *not* have a stable API or ABI. It must be updated with its |
| 19 | consumers. It is not suitable for, say, a system library in a traditional Linux |
| 20 | distribution. For instance, Chromium statically links the specific revision of |
| 21 | BoringSSL it was built against. Likewise, Android's system-internal copy of |
| 22 | BoringSSL is not exposed by the NDK and must not be used by third-party |
| 23 | applications. |
| 24 | |
| 25 | |
| 26 | ## Major API changes |
| 27 | |
| 28 | ### Integer types |
| 29 | |
| 30 | Some APIs have been converted to use `size_t` for consistency and to avoid |
| 31 | integer overflows at the API boundary. (Existing logic uses a mismash of `int`, |
| 32 | `long`, and `unsigned`.) For the most part, implicit casts mean that existing |
| 33 | code continues to compile. In some cases, this may require BoringSSL-specific |
| 34 | code, particularly to avoid compiler warnings. |
| 35 | |
| 36 | Most notably, the `STACK_OF(T)` types have all been converted to use `size_t` |
| 37 | instead of `int` for indices and lengths. |
| 38 | |
| 39 | ### Reference counts |
| 40 | |
| 41 | Some external consumers increment reference counts directly by calling |
| 42 | `CRYPTO_add` with the corresponding `CRYPTO_LOCK_*` value. |
| 43 | |
| 44 | These APIs no longer exist in BoringSSL. Instead, code which increments |
| 45 | reference counts should call the corresponding `FOO_up_ref` function, such as |
| 46 | `EVP_PKEY_up_ref`. Note that not all of these APIs are present in OpenSSL and |
| 47 | may require `#ifdef`s. |
| 48 | |
| 49 | ### Error codes |
| 50 | |
| 51 | OpenSSL's errors are extremely specific, leaking internals of the library, |
| 52 | including even a function code for the function which emitted the error! As some |
| 53 | logic in BoringSSL has been rewritten, code which conditions on the error may |
| 54 | break (grep for `ERR_GET_REASON` and `ERR_GET_FUNC`). This danger also exists |
| 55 | when upgrading OpenSSL versions. |
| 56 | |
| 57 | Where possible, avoid conditioning on the exact error reason. Otherwise, a |
| 58 | BoringSSL `#ifdef` may be necessary. Exactly how best to resolve this issue is |
| 59 | still being determined. It's possible some new APIs will be added in the future. |
| 60 | |
| 61 | Function codes have been completely removed. Remove code which conditions on |
| 62 | these as it will break with the slightest change in the library, OpenSSL or |
| 63 | BoringSSL. |
| 64 | |
| 65 | ### `*_ctrl` functions |
| 66 | |
| 67 | Some OpenSSL APIs are implemented with `ioctl`-style functions such as |
| 68 | `SSL_ctrl` and `EVP_PKEY_CTX_ctrl`, combined with convenience macros, such as |
| 69 | |
| 70 | # define SSL_CTX_set_mode(ctx,op) \ |
| 71 | SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,(op),NULL) |
| 72 | |
| 73 | In BoringSSL, these macros have been replaced with proper functions. The |
| 74 | underlying `_ctrl` functions have been removed. |
| 75 | |
| 76 | For convenience, `SSL_CTRL_*` values are retained as macros to `doesnt_exist` so |
| 77 | existing code which uses them (or the wrapper macros) in `#ifdef` expressions |
| 78 | will continue to function. However, the macros themselves will not work. |
| 79 | |
| 80 | Switch any `*_ctrl` callers to the macro/function versions. This works in both |
| 81 | OpenSSL and BoringSSL. Note that BoringSSL's function versions will be |
David Benjamin | d8ba86d | 2016-07-16 00:29:27 +0200 | [diff] [blame^] | 82 | type-checked and may require more care with types. See the end of this |
| 83 | document for a table of functions to use. |
David Benjamin | 65703b4 | 2015-09-02 16:51:42 -0400 | [diff] [blame] | 84 | |
| 85 | ### HMAC `EVP_PKEY`s |
| 86 | |
| 87 | `EVP_PKEY_HMAC` is removed. Use the `HMAC_*` functions in `hmac.h` instead. This |
| 88 | is compatible with OpenSSL. |
| 89 | |
| 90 | ### DSA `EVP_PKEY`s |
| 91 | |
| 92 | `EVP_PKEY_DSA` is deprecated. It is currently still possible to parse DER into a |
| 93 | DSA `EVP_PKEY`, but signing or verifying with those objects will not work. |
| 94 | |
| 95 | ### DES |
| 96 | |
| 97 | The `DES_cblock` type has been switched from an array to a struct to avoid the |
| 98 | pitfalls around array types in C. Where features which require DES cannot be |
| 99 | disabled, BoringSSL-specific codepaths may be necessary. |
| 100 | |
| 101 | ### TLS renegotiation |
| 102 | |
| 103 | OpenSSL enables TLS renegotiation by default and accepts renegotiation requests |
| 104 | from the peer transparently. Renegotiation is an extremely problematic protocol |
| 105 | feature, so BoringSSL rejects peer renegotiations by default. |
| 106 | |
David Benjamin | 471abb1 | 2015-10-18 23:09:17 -0400 | [diff] [blame] | 107 | To enable renegotiation, call `SSL_set_renegotiate_mode` and set it to |
| 108 | `ssl_renegotiate_once` or `ssl_renegotiate_freely`. Renegotiation is only |
| 109 | supported as a client in SSL3/TLS and the HelloRequest must be received at a |
| 110 | quiet point in the application protocol. This is sufficient to support the |
| 111 | common use of requesting a new client certificate between an HTTP request and |
| 112 | response in (unpipelined) HTTP/1.1. |
David Benjamin | 65703b4 | 2015-09-02 16:51:42 -0400 | [diff] [blame] | 113 | |
| 114 | Things which do not work: |
| 115 | |
| 116 | * There is no support for renegotiation as a server. |
| 117 | |
| 118 | * There is no support for renegotiation in DTLS. |
| 119 | |
David Benjamin | 809829e | 2015-09-03 11:48:12 -0400 | [diff] [blame] | 120 | * There is no support for initiating renegotiation; `SSL_renegotiate` always |
| 121 | fails and `SSL_set_state` does nothing. |
| 122 | |
David Benjamin | 65703b4 | 2015-09-02 16:51:42 -0400 | [diff] [blame] | 123 | * Interleaving application data with the new handshake is forbidden. |
| 124 | |
| 125 | * If a HelloRequest is received while `SSL_write` has unsent application data, |
| 126 | the renegotiation is rejected. |
| 127 | |
David Benjamin | 9a798ec | 2015-09-28 19:05:24 -0400 | [diff] [blame] | 128 | ### Lowercase hexadecimal |
| 129 | |
| 130 | BoringSSL's `BN_bn2hex` function uses lowercase hexadecimal digits instead of |
| 131 | uppercase. Some code may require changes to avoid being sensitive to this |
| 132 | difference. |
| 133 | |
David Benjamin | 4aafe6a | 2016-01-23 11:53:33 -0500 | [diff] [blame] | 134 | ### Legacy ASN.1 functions |
| 135 | |
| 136 | OpenSSL's ASN.1 stack uses `d2i` functions for parsing. They have the form: |
| 137 | |
| 138 | RSA *d2i_RSAPrivateKey(RSA **out, const uint8_t **inp, long len); |
| 139 | |
| 140 | In addition to returning the result, OpenSSL places it in `*out` if `out` is |
| 141 | not `NULL`. On input, if `*out` is not `NULL`, OpenSSL will usually (but not |
| 142 | always) reuse that object rather than allocating a new one. In BoringSSL, these |
| 143 | functions are compatibility wrappers over a newer ASN.1 stack. Even if `*out` |
| 144 | is not `NULL`, these wrappers will always allocate a new object and free the |
| 145 | previous one. |
| 146 | |
| 147 | Ensure that callers do not rely on this object reuse behavior. It is |
| 148 | recommended to avoid the `out` parameter completely and always pass in `NULL`. |
| 149 | Note that less error-prone APIs are available for BoringSSL-specific code (see |
| 150 | below). |
David Benjamin | 65703b4 | 2015-09-02 16:51:42 -0400 | [diff] [blame] | 151 | |
| 152 | ## Optional BoringSSL-specific simplifications |
| 153 | |
David Benjamin | 809829e | 2015-09-03 11:48:12 -0400 | [diff] [blame] | 154 | BoringSSL makes some changes to OpenSSL which simplify the API but remain |
David Benjamin | 65703b4 | 2015-09-02 16:51:42 -0400 | [diff] [blame] | 155 | compatible with OpenSSL consumers. In general, consult the BoringSSL |
| 156 | documentation for any functions in new BoringSSL-only code. |
| 157 | |
| 158 | ### Return values |
| 159 | |
| 160 | Most OpenSSL APIs return 1 on success and either 0 or -1 on failure. BoringSSL |
| 161 | has narrowed most of these to 1 on success and 0 on failure. BoringSSL-specific |
| 162 | code may take advantage of the less error-prone APIs and use `!` to check for |
| 163 | errors. |
| 164 | |
| 165 | ### Initialization |
| 166 | |
| 167 | OpenSSL has a number of different initialization functions for setting up error |
| 168 | strings and loading algorithms, etc. All of these functions still exist in |
| 169 | BoringSSL for convenience, but they do nothing and are not necessary. |
| 170 | |
David Benjamin | 7a1eefd | 2015-10-17 23:39:22 -0400 | [diff] [blame] | 171 | The one exception is `CRYPTO_library_init`. In `BORINGSSL_NO_STATIC_INITIALIZER` |
| 172 | builds, it must be called to query CPU capabitilies before the rest of the |
| 173 | library. In the default configuration, this is done with a static initializer |
| 174 | and is also unnecessary. |
David Benjamin | 65703b4 | 2015-09-02 16:51:42 -0400 | [diff] [blame] | 175 | |
| 176 | ### Threading |
| 177 | |
| 178 | OpenSSL provides a number of APIs to configure threading callbacks and set up |
| 179 | locks. Without initializing these, the library is not thread-safe. Configuring |
| 180 | these does nothing in BoringSSL. Instead, BoringSSL calls pthreads and the |
| 181 | corresponding Windows APIs internally and is always thread-safe where the API |
| 182 | guarantees it. |
David Benjamin | 4aafe6a | 2016-01-23 11:53:33 -0500 | [diff] [blame] | 183 | |
| 184 | ### ASN.1 |
| 185 | |
| 186 | BoringSSL is in the process of deprecating OpenSSL's `d2i` and `i2d` in favor of |
| 187 | new functions using the much less error-prone `CBS` and `CBB` types. |
| 188 | BoringSSL-only code should use those functions where available. |
David Benjamin | d8ba86d | 2016-07-16 00:29:27 +0200 | [diff] [blame^] | 189 | |
| 190 | |
| 191 | ## Replacements for `CTRL` values |
| 192 | |
| 193 | When porting code which uses `SSL_CTX_ctrl` or `SSL_ctrl`, use the replacement |
| 194 | functions below. If a function has both `SSL_CTX` and `SSL` variants, only the |
| 195 | `SSL_CTX` version is listed. |
| 196 | |
| 197 | Note some values correspond to multiple functions depending on the `larg` |
| 198 | parameter. |
| 199 | |
| 200 | `CTRL` value | Replacement function(s) |
| 201 | -------------|------------------------- |
| 202 | `DTLS_CTRL_GET_TIMEOUT` | `DTLSv1_get_timeout` |
| 203 | `DTLS_CTRL_HANDLE_TIMEOUT` | `DTLSv1_handle_timeout` |
| 204 | `SSL_CTRL_CHAIN` | `SSL_CTX_set0_chain` or `SSL_CTX_set1_chain` |
| 205 | `SSL_CTRL_CHAIN_CERT` | `SSL_add0_chain_cert` or `SSL_add1_chain_cert` |
| 206 | `SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS` | `SSL_CTX_clear_extra_chain_certs` |
| 207 | `SSL_CTRL_CLEAR_MODE` | `SSL_CTX_clear_mode` |
| 208 | `SSL_CTRL_CLEAR_OPTIONS` | `SSL_CTX_clear_options` |
| 209 | `SSL_CTRL_EXTRA_CHAIN_CERT` | `SSL_CTX_add_extra_chain_cert` |
| 210 | `SSL_CTRL_GET_CHAIN_CERTS` | `SSL_CTX_get0_chain_certs` |
| 211 | `SSL_CTRL_GET_CLIENT_CERT_TYPES` | `SSL_get0_certificate_types` |
| 212 | `SSL_CTRL_GET_EXTRA_CHAIN_CERTS` | `SSL_CTX_get_extra_chain_certs` or `SSL_CTX_get_extra_chain_certs_only` |
| 213 | `SSL_CTRL_GET_MAX_CERT_LIST` | `SSL_CTX_get_max_cert_list` |
| 214 | `SSL_CTRL_GET_NUM_RENEGOTIATIONS` | `SSL_num_renegotiations` |
| 215 | `SSL_CTRL_GET_READ_AHEAD` | `SSL_CTX_get_read_ahead` |
| 216 | `SSL_CTRL_GET_RI_SUPPORT` | `SSL_get_secure_renegotiation_support` |
| 217 | `SSL_CTRL_GET_SESSION_REUSED` | `SSL_session_reused` |
| 218 | `SSL_CTRL_GET_SESS_CACHE_MODE` | `SSL_CTX_get_session_cache_mode` |
| 219 | `SSL_CTRL_GET_SESS_CACHE_SIZE` | `SSL_CTX_sess_get_cache_size` |
| 220 | `SSL_CTRL_GET_TLSEXT_TICKET_KEYS` | `SSL_CTX_get_tlsext_ticket_keys` |
| 221 | `SSL_CTRL_GET_TOTAL_RENEGOTIATIONS` | `SSL_total_renegotiations` |
| 222 | `SSL_CTRL_MODE` | `SSL_CTX_get_mode` or `SSL_CTX_set_mode` |
| 223 | `SSL_CTRL_NEED_TMP_RSA` | `SSL_CTX_need_tmp_RSA` is equivalent, but [*do not use this function*](https://freakattack.com/). (It is a no-op in BoringSSL.) |
| 224 | `SSL_CTRL_OPTIONS` | `SSL_CTX_get_options` or `SSL_CTX_set_options` |
| 225 | `SSL_CTRL_SESS_NUMBER` | `SSL_CTX_sess_number` |
| 226 | `SSL_CTRL_SET_CURVES` | `SSL_CTX_set1_curves` |
| 227 | `SSL_CTRL_SET_MAX_CERT_LIST` | `SSL_CTX_set_max_cert_list` |
| 228 | `SSL_CTRL_SET_MAX_SEND_FRAGMENT` | `SSL_CTX_set_max_send_fragment` |
| 229 | `SSL_CTRL_SET_MSG_CALLBACK` | `SSL_set_msg_callback` |
| 230 | `SSL_CTRL_SET_MSG_CALLBACK_ARG` | `SSL_set_msg_callback_arg` |
| 231 | `SSL_CTRL_SET_MTU` | `SSL_set_mtu` |
| 232 | `SSL_CTRL_SET_READ_AHEAD` | `SSL_CTX_set_read_ahead` |
| 233 | `SSL_CTRL_SET_SESS_CACHE_MODE` | `SSL_CTX_set_session_cache_mode` |
| 234 | `SSL_CTRL_SET_SESS_CACHE_SIZE` | `SSL_CTX_sess_set_cache_size` |
| 235 | `SSL_CTRL_SET_TLSEXT_HOSTNAME` | `SSL_set_tlsext_host_name` |
| 236 | `SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG` | `SSL_CTX_set_tlsext_servername_arg` |
| 237 | `SSL_CTRL_SET_TLSEXT_SERVERNAME_CB` | `SSL_CTX_set_tlsext_servername_callback` |
| 238 | `SSL_CTRL_SET_TLSEXT_TICKET_KEYS` | `SSL_CTX_set_tlsext_ticket_keys` |
| 239 | `SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB` | `SSL_CTX_set_tlsext_ticket_key_cb` |
| 240 | `SSL_CTRL_SET_TMP_DH` | `SSL_CTX_set_tmp_dh` |
| 241 | `SSL_CTRL_SET_TMP_DH_CB` | `SSL_CTX_set_tmp_dh_callback` |
| 242 | `SSL_CTRL_SET_TMP_ECDH` | `SSL_CTX_set_tmp_ecdh` |
| 243 | `SSL_CTRL_SET_TMP_ECDH_CB` | `SSL_CTX_set_tmp_ecdh_callback` |
| 244 | `SSL_CTRL_SET_TMP_RSA` | `SSL_CTX_set_tmp_rsa` is equivalent, but [*do not use this function*](https://freakattack.com/). (It is a no-op in BoringSSL.) |
| 245 | `SSL_CTRL_SET_TMP_RSA_CB` | `SSL_CTX_set_tmp_rsa_callback` is equivalent, but [*do not use this function*](https://freakattack.com/). (It is a no-op in BoringSSL.) |