blob: 3faf757b150b5a157a672bce88b97012578b66ff [file] [log] [blame] [view]
David Benjamin65703b42015-09-02 16:51:42 -04001# Porting from OpenSSL to BoringSSL
2
3BoringSSL is an OpenSSL derivative and is mostly source-compatible, for the
4subset of OpenSSL retained. Libraries ideally need little to no changes for
5BoringSSL support, provided they do not use removed APIs. In general, see if the
6library compiles and, on failure, consult the documentation in the header files
7and see if problematic features can be removed.
8
David Benjamin81f030b2016-08-12 14:48:19 -04009BoringSSL's `OPENSSL_VERSION_NUMBER` matches the OpenSSL version it targets.
10Version checks for OpenSSL should ideally work as-is in BoringSSL. BoringSSL
11also defines upstream's `OPENSSL_NO_*` feature macros corresponding to removed
12features. If the preprocessor is needed, use these version checks or feature
13macros where possible, especially when patching third-party projects. Such
14patches are more generally useful to OpenSSL consumers and thus more
15appropriate to send upstream.
David Benjamin65703b42015-09-02 16:51:42 -040016
David Benjamin81f030b2016-08-12 14:48:19 -040017In some cases, BoringSSL-specific code may be necessary. Use the
18`OPENSSL_IS_BORINGSSL` preprocessor macro in `#ifdef`s. However, first contact
19the BoringSSL maintainers about the missing APIs. We will typically add
20compatibility functions for convenience. In particular, *contact BoringSSL
21maintainers before working around missing OpenSSL 1.1.0 accessors*. BoringSSL
22was originally derived from OpenSSL 1.0.2 but now targets OpenSSL 1.1.0. Some
23newer APIs may be missing but can be added on request. (Not all projects have
24been ported to OpenSSL 1.1.0, so BoringSSL also remains largely compatible with
25OpenSSL 1.0.2.)
26
27The `OPENSSL_IS_BORINGSSL` macro may also be used to distinguish OpenSSL from
28BoringSSL in configure scripts. Do not use the presence or absence of particular
29symbols to detect BoringSSL.
David Benjamin65703b42015-09-02 16:51:42 -040030
31Note: BoringSSL does *not* have a stable API or ABI. It must be updated with its
32consumers. It is not suitable for, say, a system library in a traditional Linux
33distribution. For instance, Chromium statically links the specific revision of
34BoringSSL it was built against. Likewise, Android's system-internal copy of
35BoringSSL is not exposed by the NDK and must not be used by third-party
36applications.
37
38
39## Major API changes
40
41### Integer types
42
43Some APIs have been converted to use `size_t` for consistency and to avoid
44integer overflows at the API boundary. (Existing logic uses a mismash of `int`,
45`long`, and `unsigned`.) For the most part, implicit casts mean that existing
46code continues to compile. In some cases, this may require BoringSSL-specific
47code, particularly to avoid compiler warnings.
48
49Most notably, the `STACK_OF(T)` types have all been converted to use `size_t`
50instead of `int` for indices and lengths.
51
David Benjamin81f030b2016-08-12 14:48:19 -040052### Reference counts and opaque types
David Benjamin65703b42015-09-02 16:51:42 -040053
54Some external consumers increment reference counts directly by calling
David Benjamin81f030b2016-08-12 14:48:19 -040055`CRYPTO_add` with the corresponding `CRYPTO_LOCK_*` value. These APIs no longer
56exist in BoringSSL. Instead, code which increments reference counts should call
57the corresponding `FOO_up_ref` function, such as `EVP_PKEY_up_ref`.
David Benjamin65703b42015-09-02 16:51:42 -040058
David Benjamin81f030b2016-08-12 14:48:19 -040059BoringSSL also hides some structs which were previously exposed in OpenSSL
601.0.2, particularly in libssl. Use the relevant accessors instead.
61
62Note that some of these APIs were added in OpenSSL 1.1.0, so projects which do
63not yet support 1.1.0 may need additional `#ifdef`s. Projects supporting OpenSSL
641.1.0 should not require modification.
David Benjamin65703b42015-09-02 16:51:42 -040065
66### Error codes
67
68OpenSSL's errors are extremely specific, leaking internals of the library,
69including even a function code for the function which emitted the error! As some
70logic in BoringSSL has been rewritten, code which conditions on the error may
71break (grep for `ERR_GET_REASON` and `ERR_GET_FUNC`). This danger also exists
72when upgrading OpenSSL versions.
73
74Where possible, avoid conditioning on the exact error reason. Otherwise, a
75BoringSSL `#ifdef` may be necessary. Exactly how best to resolve this issue is
76still being determined. It's possible some new APIs will be added in the future.
77
78Function codes have been completely removed. Remove code which conditions on
79these as it will break with the slightest change in the library, OpenSSL or
80BoringSSL.
81
82### `*_ctrl` functions
83
84Some OpenSSL APIs are implemented with `ioctl`-style functions such as
85`SSL_ctrl` and `EVP_PKEY_CTX_ctrl`, combined with convenience macros, such as
86
87 # define SSL_CTX_set_mode(ctx,op) \
88 SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,(op),NULL)
89
90In BoringSSL, these macros have been replaced with proper functions. The
91underlying `_ctrl` functions have been removed.
92
93For convenience, `SSL_CTRL_*` values are retained as macros to `doesnt_exist` so
94existing code which uses them (or the wrapper macros) in `#ifdef` expressions
95will continue to function. However, the macros themselves will not work.
96
97Switch any `*_ctrl` callers to the macro/function versions. This works in both
98OpenSSL and BoringSSL. Note that BoringSSL's function versions will be
David Benjamind8ba86d2016-07-16 00:29:27 +020099type-checked and may require more care with types. See the end of this
100document for a table of functions to use.
David Benjamin65703b42015-09-02 16:51:42 -0400101
102### HMAC `EVP_PKEY`s
103
104`EVP_PKEY_HMAC` is removed. Use the `HMAC_*` functions in `hmac.h` instead. This
105is compatible with OpenSSL.
106
107### DSA `EVP_PKEY`s
108
109`EVP_PKEY_DSA` is deprecated. It is currently still possible to parse DER into a
110DSA `EVP_PKEY`, but signing or verifying with those objects will not work.
111
112### DES
113
114The `DES_cblock` type has been switched from an array to a struct to avoid the
115pitfalls around array types in C. Where features which require DES cannot be
116disabled, BoringSSL-specific codepaths may be necessary.
117
118### TLS renegotiation
119
120OpenSSL enables TLS renegotiation by default and accepts renegotiation requests
121from the peer transparently. Renegotiation is an extremely problematic protocol
122feature, so BoringSSL rejects peer renegotiations by default.
123
David Benjamin471abb12015-10-18 23:09:17 -0400124To enable renegotiation, call `SSL_set_renegotiate_mode` and set it to
125`ssl_renegotiate_once` or `ssl_renegotiate_freely`. Renegotiation is only
David Benjamin0cc51a72018-06-29 13:17:10 -0400126supported as a client in TLS and the HelloRequest must be received at a
David Benjamin471abb12015-10-18 23:09:17 -0400127quiet point in the application protocol. This is sufficient to support the
128common use of requesting a new client certificate between an HTTP request and
129response in (unpipelined) HTTP/1.1.
David Benjamin65703b42015-09-02 16:51:42 -0400130
131Things which do not work:
132
Adam Langleya6b86892017-07-25 13:37:51 -0700133* There is no support for renegotiation as a server. (Attempts by clients will
134 result in a fatal alert so that ClientHello messages cannot be used to flood
135 a server and escape higher-level limits.)
David Benjamin65703b42015-09-02 16:51:42 -0400136
137* There is no support for renegotiation in DTLS.
138
David Benjamin809829e2015-09-03 11:48:12 -0400139* There is no support for initiating renegotiation; `SSL_renegotiate` always
140 fails and `SSL_set_state` does nothing.
141
David Benjamin65703b42015-09-02 16:51:42 -0400142* Interleaving application data with the new handshake is forbidden.
143
144* If a HelloRequest is received while `SSL_write` has unsent application data,
145 the renegotiation is rejected.
146
David Benjamin5ef40c62017-08-23 21:28:29 -0700147* Renegotiation does not participate in session resumption. The client will
148 not offer a session on renegotiation or resume any session established by a
149 renegotiation handshake.
150
David Benjamin5c4271f2017-08-23 22:09:41 -0700151* The server may not change its certificate in the renegotiation. This mitigates
152 the [triple handshake attack](https://mitls.org/pages/attacks/3SHAKE). Any new
153 stapled OCSP response and SCT list will be ignored. As no authentication state
154 may change, BoringSSL will not re-verify the certificate on a renegotiation.
155 Callbacks such as `SSL_CTX_set_custom_verify` will only run on the initial
156 handshake.
157
David Benjamin9a798ec2015-09-28 19:05:24 -0400158### Lowercase hexadecimal
159
160BoringSSL's `BN_bn2hex` function uses lowercase hexadecimal digits instead of
161uppercase. Some code may require changes to avoid being sensitive to this
162difference.
163
David Benjamin4aafe6a2016-01-23 11:53:33 -0500164### Legacy ASN.1 functions
165
166OpenSSL's ASN.1 stack uses `d2i` functions for parsing. They have the form:
167
168 RSA *d2i_RSAPrivateKey(RSA **out, const uint8_t **inp, long len);
169
170In addition to returning the result, OpenSSL places it in `*out` if `out` is
171not `NULL`. On input, if `*out` is not `NULL`, OpenSSL will usually (but not
172always) reuse that object rather than allocating a new one. In BoringSSL, these
David Benjamin19721cd2023-01-16 16:19:03 -0500173functions will always allocate a new object and free the previous one.
David Benjamin4aafe6a2016-01-23 11:53:33 -0500174
175Ensure that callers do not rely on this object reuse behavior. It is
176recommended to avoid the `out` parameter completely and always pass in `NULL`.
David Benjamin19721cd2023-01-16 16:19:03 -0500177In most cases, even in OpenSSL, relying on object reuse is not safe because, on
178parse error, OpenSSL will free the reused object. Note that less error-prone
179APIs are available for BoringSSL-specific code (see below).
David Benjamin65703b42015-09-02 16:51:42 -0400180
David Benjamin6881ec02017-09-07 18:38:32 -0400181### Memory allocation
182
183OpenSSL provides wrappers `OPENSSL_malloc` and `OPENSSL_free` over the standard
184`malloc` and `free`. Memory allocated by OpenSSL should be released with
185`OPENSSL_free`, not the standard `free`. However, by default, they are
186implemented directly using `malloc` and `free`, so code which mixes them up
187usually works.
188
189In BoringSSL, these functions maintain additional book-keeping to zero memory
190on `OPENSSL_free`, so any mixups must be fixed.
191
David Benjamin65703b42015-09-02 16:51:42 -0400192## Optional BoringSSL-specific simplifications
193
David Benjamin809829e2015-09-03 11:48:12 -0400194BoringSSL makes some changes to OpenSSL which simplify the API but remain
David Benjamin65703b42015-09-02 16:51:42 -0400195compatible with OpenSSL consumers. In general, consult the BoringSSL
196documentation for any functions in new BoringSSL-only code.
197
198### Return values
199
200Most OpenSSL APIs return 1 on success and either 0 or -1 on failure. BoringSSL
201has narrowed most of these to 1 on success and 0 on failure. BoringSSL-specific
202code may take advantage of the less error-prone APIs and use `!` to check for
203errors.
204
205### Initialization
206
207OpenSSL has a number of different initialization functions for setting up error
208strings and loading algorithms, etc. All of these functions still exist in
David Benjamin2fcdd112024-06-18 01:13:09 -0400209BoringSSL for convenience, but they do nothing and are not necessary. BoringSSL
210internally initializes itself as needed.
David Benjamin65703b42015-09-02 16:51:42 -0400211
212### Threading
213
214OpenSSL provides a number of APIs to configure threading callbacks and set up
215locks. Without initializing these, the library is not thread-safe. Configuring
216these does nothing in BoringSSL. Instead, BoringSSL calls pthreads and the
217corresponding Windows APIs internally and is always thread-safe where the API
218guarantees it.
David Benjamin4aafe6a2016-01-23 11:53:33 -0500219
220### ASN.1
221
222BoringSSL is in the process of deprecating OpenSSL's `d2i` and `i2d` in favor of
223new functions using the much less error-prone `CBS` and `CBB` types.
224BoringSSL-only code should use those functions where available.
David Benjamind8ba86d2016-07-16 00:29:27 +0200225
226
227## Replacements for `CTRL` values
228
229When porting code which uses `SSL_CTX_ctrl` or `SSL_ctrl`, use the replacement
230functions below. If a function has both `SSL_CTX` and `SSL` variants, only the
231`SSL_CTX` version is listed.
232
233Note some values correspond to multiple functions depending on the `larg`
234parameter.
235
236`CTRL` value | Replacement function(s)
237-------------|-------------------------
238`DTLS_CTRL_GET_TIMEOUT` | `DTLSv1_get_timeout`
239`DTLS_CTRL_HANDLE_TIMEOUT` | `DTLSv1_handle_timeout`
240`SSL_CTRL_CHAIN` | `SSL_CTX_set0_chain` or `SSL_CTX_set1_chain`
241`SSL_CTRL_CHAIN_CERT` | `SSL_add0_chain_cert` or `SSL_add1_chain_cert`
242`SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS` | `SSL_CTX_clear_extra_chain_certs`
243`SSL_CTRL_CLEAR_MODE` | `SSL_CTX_clear_mode`
244`SSL_CTRL_CLEAR_OPTIONS` | `SSL_CTX_clear_options`
245`SSL_CTRL_EXTRA_CHAIN_CERT` | `SSL_CTX_add_extra_chain_cert`
246`SSL_CTRL_GET_CHAIN_CERTS` | `SSL_CTX_get0_chain_certs`
247`SSL_CTRL_GET_CLIENT_CERT_TYPES` | `SSL_get0_certificate_types`
248`SSL_CTRL_GET_EXTRA_CHAIN_CERTS` | `SSL_CTX_get_extra_chain_certs` or `SSL_CTX_get_extra_chain_certs_only`
249`SSL_CTRL_GET_MAX_CERT_LIST` | `SSL_CTX_get_max_cert_list`
250`SSL_CTRL_GET_NUM_RENEGOTIATIONS` | `SSL_num_renegotiations`
251`SSL_CTRL_GET_READ_AHEAD` | `SSL_CTX_get_read_ahead`
252`SSL_CTRL_GET_RI_SUPPORT` | `SSL_get_secure_renegotiation_support`
253`SSL_CTRL_GET_SESSION_REUSED` | `SSL_session_reused`
254`SSL_CTRL_GET_SESS_CACHE_MODE` | `SSL_CTX_get_session_cache_mode`
255`SSL_CTRL_GET_SESS_CACHE_SIZE` | `SSL_CTX_sess_get_cache_size`
256`SSL_CTRL_GET_TLSEXT_TICKET_KEYS` | `SSL_CTX_get_tlsext_ticket_keys`
257`SSL_CTRL_GET_TOTAL_RENEGOTIATIONS` | `SSL_total_renegotiations`
258`SSL_CTRL_MODE` | `SSL_CTX_get_mode` or `SSL_CTX_set_mode`
259`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.)
260`SSL_CTRL_OPTIONS` | `SSL_CTX_get_options` or `SSL_CTX_set_options`
261`SSL_CTRL_SESS_NUMBER` | `SSL_CTX_sess_number`
262`SSL_CTRL_SET_CURVES` | `SSL_CTX_set1_curves`
David Benjamin48e1d182017-03-13 16:56:30 -0400263`SSL_CTRL_SET_ECDH_AUTO` | `SSL_CTX_set_ecdh_auto`
David Benjamind8ba86d2016-07-16 00:29:27 +0200264`SSL_CTRL_SET_MAX_CERT_LIST` | `SSL_CTX_set_max_cert_list`
265`SSL_CTRL_SET_MAX_SEND_FRAGMENT` | `SSL_CTX_set_max_send_fragment`
266`SSL_CTRL_SET_MSG_CALLBACK` | `SSL_set_msg_callback`
267`SSL_CTRL_SET_MSG_CALLBACK_ARG` | `SSL_set_msg_callback_arg`
268`SSL_CTRL_SET_MTU` | `SSL_set_mtu`
269`SSL_CTRL_SET_READ_AHEAD` | `SSL_CTX_set_read_ahead`
270`SSL_CTRL_SET_SESS_CACHE_MODE` | `SSL_CTX_set_session_cache_mode`
271`SSL_CTRL_SET_SESS_CACHE_SIZE` | `SSL_CTX_sess_set_cache_size`
272`SSL_CTRL_SET_TLSEXT_HOSTNAME` | `SSL_set_tlsext_host_name`
273`SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG` | `SSL_CTX_set_tlsext_servername_arg`
274`SSL_CTRL_SET_TLSEXT_SERVERNAME_CB` | `SSL_CTX_set_tlsext_servername_callback`
275`SSL_CTRL_SET_TLSEXT_TICKET_KEYS` | `SSL_CTX_set_tlsext_ticket_keys`
276`SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB` | `SSL_CTX_set_tlsext_ticket_key_cb`
277`SSL_CTRL_SET_TMP_DH` | `SSL_CTX_set_tmp_dh`
278`SSL_CTRL_SET_TMP_DH_CB` | `SSL_CTX_set_tmp_dh_callback`
279`SSL_CTRL_SET_TMP_ECDH` | `SSL_CTX_set_tmp_ecdh`
280`SSL_CTRL_SET_TMP_ECDH_CB` | `SSL_CTX_set_tmp_ecdh_callback`
281`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.)
282`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.)
Adam Langley61c98382017-07-28 12:20:58 -0700283
284## Significant API additions
285
286In some places, BoringSSL has added significant APIs. Use of these APIs goes beyound “porting” and means giving up on OpenSSL compatibility.
287
288One example of this has already been mentioned: the [CBS and CBB](https://commondatastorage.googleapis.com/chromium-boringssl-docs/bytestring.h.html) functions should be used whenever parsing or serialising data.
289
290### CRYPTO\_BUFFER
291
292With the standard OpenSSL APIs, when making many TLS connections, the certificate data for each connection is retained in memory in an expensive `X509` structure. Additionally, common certificates often appear in the chains for multiple connections and are needlessly duplicated in memory.
293
294A [`CRYPTO_BUFFER`](https://commondatastorage.googleapis.com/chromium-boringssl-docs/pool.h.html) is just an opaque byte string. A `CRYPTO_BUFFER_POOL` is an intern table for these buffers, i.e. it ensures that only a single copy of any given byte string is kept for each pool.
295
296The function `TLS_with_buffers_method` returns an `SSL_METHOD` that avoids creating `X509` objects for certificates. Additionally, `SSL_CTX_set0_buffer_pool` can be used to install a pool on an `SSL_CTX` so that certificates can be deduplicated across connections and across `SSL_CTX`s.
297
298When using these functions, the application also needs to ensure that it doesn't call other functions that deal with `X509` or `X509_NAME` objects. For example, `SSL_get_peer_certificate` or `SSL_get_peer_cert_chain`. Doing so will trigger an assert in debug mode and will result in NULLs in release mode. Instead, call the buffer-based alternatives such as `SSL_get0_peer_certificates`. (See [ssl.h](https://commondatastorage.googleapis.com/chromium-boringssl-docs/ssl.h.html) for functions taking or returning `CRYPTO_BUFFER`.) The buffer-based alternative functions will work even when not using `TLS_with_buffers_method`, thus application code can transition gradually.
299
300In order to use buffers, the application code also needs to implement its own certificate verification using `SSL_[CTX_]set_custom_verify`. Otherwise all connections will fail with a verification error. Auto-chaining is also disabled when using buffers.
301
302Once those changes have been completed, the whole of the OpenSSL X.509 and ASN.1 code should be eliminated by the linker if BoringSSL is linked statically.
Adam Langleyc90be3b2017-08-04 12:31:20 -0700303
304### Asynchronous and opaque private keys
305
306OpenSSL offers the ENGINE API for implementing opaque private keys (i.e. private keys where software only has oracle access because the secrets are held in special hardware or on another machine). While the ENGINE API has been mostly removed from BoringSSL, it is still possible to support opaque keys in this way. However, when using such keys with TLS and BoringSSL, you should strongly prefer using `SSL_PRIVATE_KEY_METHOD` via `SSL[_CTX]_set_private_key_method`. This allows a handshake to be suspended while the private operation is in progress. It also supports more forms of opaque key as it exposes higher-level information about the operation to be performed.