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