You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ssl_privkey.cc 26 KiB

Simplify ssl_private_key_* state machine points. The original motivation behind the sign/complete split was to avoid needlessly hashing the input on each pass through the state machine, but we're payload-based now and, in all cases, the payload is either cheap to compute or readily available. (Even the hashing worry was probably unnecessary.) Tweak ssl_private_key_{sign,decrypt} to automatically call ssl_private_key_complete as needed and take advantage of this in the handshake state machines: - TLS 1.3 signing now computes the payload each pass. The payload is small and we're already allocating a comparable-sized buffer each iteration to hold the signature. This shouldn't be a big deal. - TLS 1.2 decryption code still needs two states due to reading the message (fixed in new state machine style), but otherwise it just performs cheap idempotent tasks again. The PSK code is reshuffled to guarantee the callback is not called twice (though this was impossible anyway because we don't support RSA_PSK). - TLS 1.2 CertificateVerify signing is easy as the transcript is readily available. The buffer is released very slightly later, but it shouldn't matter. - TLS 1.2 ServerKeyExchange signing required some reshuffling. Assembling the ServerKeyExchange parameters is moved to the previous state. The signing payload has some randoms prepended. This is cheap enough, but a nuisance in C. Pre-prepend the randoms in hs->server_params. With this change, we are *nearly* rid of the A/B => same function pattern. BUG=128 Change-Id: Iec4fe0be7cfc88a6de027ba2760fae70794ea810 Reviewed-on: https://boringssl-review.googlesource.com/17265 Commit-Queue: David Benjamin <davidben@google.com> Commit-Queue: Steven Valdez <svaldez@google.com> Reviewed-by: Steven Valdez <svaldez@google.com>
7 年之前
Move libssl's internals into the bssl namespace. This is horrible, but everything else I tried was worse. The goal with this CL is to take the extern "C" out of ssl/internal.h and move most symbols to namespace bssl, so we can start using C++ helpers and destructors without worry. Complications: - Public API functions must be extern "C" and match their declaration in ssl.h, which is unnamespaced. C++ really does not want you to interleave namespaced and unnamespaced things. One can actually write a namespaced extern "C" function, but this means, from C++'s perspective, the function is namespaced. Trying to namespace the public header would worked but ended up too deep a rabbithole. - Our STACK_OF macros do not work right in namespaces. - The typedefs for our exposed but opaque types are visible in the header files and copied into consuming projects as forward declarations. We ultimately want to give SSL a destructor, but clobbering an unnamespaced ssl_st::~ssl_st seems bad manners. - MSVC complains about ambiguous names if one typedefs SSL to bssl::SSL. This CL opts for: - ssl/*.cc must begin with #define BORINGSSL_INTERNAL_CXX_TYPES. This informs the public headers to create forward declarations which are compatible with our namespaces. - For now, C++-defined type FOO ends up at bssl::FOO with a typedef outside. Later I imagine we'll rename many of them. - Internal functions get namespace bssl, so we stop worrying about stomping the tls1_prf symbol. Exported C functions are stuck as they are. Rather than try anything weird, bite the bullet and reorder files which have a mix of public and private functions. I expect that over time, the public functions will become fairly small as we move logic to more idiomatic C++. Files without any public C functions can just be written normally. - To avoid MSVC troubles, some bssl types are renamed to CPlusPlusStyle in advance of them being made idiomatic C++. Bug: 132 Change-Id: Ic931895e117c38b14ff8d6e5a273e868796c7581 Reviewed-on: https://boringssl-review.googlesource.com/18124 Reviewed-by: David Benjamin <davidben@google.com>
7 年之前
Simplify ssl_private_key_* state machine points. The original motivation behind the sign/complete split was to avoid needlessly hashing the input on each pass through the state machine, but we're payload-based now and, in all cases, the payload is either cheap to compute or readily available. (Even the hashing worry was probably unnecessary.) Tweak ssl_private_key_{sign,decrypt} to automatically call ssl_private_key_complete as needed and take advantage of this in the handshake state machines: - TLS 1.3 signing now computes the payload each pass. The payload is small and we're already allocating a comparable-sized buffer each iteration to hold the signature. This shouldn't be a big deal. - TLS 1.2 decryption code still needs two states due to reading the message (fixed in new state machine style), but otherwise it just performs cheap idempotent tasks again. The PSK code is reshuffled to guarantee the callback is not called twice (though this was impossible anyway because we don't support RSA_PSK). - TLS 1.2 CertificateVerify signing is easy as the transcript is readily available. The buffer is released very slightly later, but it shouldn't matter. - TLS 1.2 ServerKeyExchange signing required some reshuffling. Assembling the ServerKeyExchange parameters is moved to the previous state. The signing payload has some randoms prepended. This is cheap enough, but a nuisance in C. Pre-prepend the randoms in hs->server_params. With this change, we are *nearly* rid of the A/B => same function pattern. BUG=128 Change-Id: Iec4fe0be7cfc88a6de027ba2760fae70794ea810 Reviewed-on: https://boringssl-review.googlesource.com/17265 Commit-Queue: David Benjamin <davidben@google.com> Commit-Queue: Steven Valdez <svaldez@google.com> Reviewed-by: Steven Valdez <svaldez@google.com>
7 年之前
Simplify ssl_private_key_* state machine points. The original motivation behind the sign/complete split was to avoid needlessly hashing the input on each pass through the state machine, but we're payload-based now and, in all cases, the payload is either cheap to compute or readily available. (Even the hashing worry was probably unnecessary.) Tweak ssl_private_key_{sign,decrypt} to automatically call ssl_private_key_complete as needed and take advantage of this in the handshake state machines: - TLS 1.3 signing now computes the payload each pass. The payload is small and we're already allocating a comparable-sized buffer each iteration to hold the signature. This shouldn't be a big deal. - TLS 1.2 decryption code still needs two states due to reading the message (fixed in new state machine style), but otherwise it just performs cheap idempotent tasks again. The PSK code is reshuffled to guarantee the callback is not called twice (though this was impossible anyway because we don't support RSA_PSK). - TLS 1.2 CertificateVerify signing is easy as the transcript is readily available. The buffer is released very slightly later, but it shouldn't matter. - TLS 1.2 ServerKeyExchange signing required some reshuffling. Assembling the ServerKeyExchange parameters is moved to the previous state. The signing payload has some randoms prepended. This is cheap enough, but a nuisance in C. Pre-prepend the randoms in hs->server_params. With this change, we are *nearly* rid of the A/B => same function pattern. BUG=128 Change-Id: Iec4fe0be7cfc88a6de027ba2760fae70794ea810 Reviewed-on: https://boringssl-review.googlesource.com/17265 Commit-Queue: David Benjamin <davidben@google.com> Commit-Queue: Steven Valdez <svaldez@google.com> Reviewed-by: Steven Valdez <svaldez@google.com>
7 年之前
Simplify ssl_private_key_* state machine points. The original motivation behind the sign/complete split was to avoid needlessly hashing the input on each pass through the state machine, but we're payload-based now and, in all cases, the payload is either cheap to compute or readily available. (Even the hashing worry was probably unnecessary.) Tweak ssl_private_key_{sign,decrypt} to automatically call ssl_private_key_complete as needed and take advantage of this in the handshake state machines: - TLS 1.3 signing now computes the payload each pass. The payload is small and we're already allocating a comparable-sized buffer each iteration to hold the signature. This shouldn't be a big deal. - TLS 1.2 decryption code still needs two states due to reading the message (fixed in new state machine style), but otherwise it just performs cheap idempotent tasks again. The PSK code is reshuffled to guarantee the callback is not called twice (though this was impossible anyway because we don't support RSA_PSK). - TLS 1.2 CertificateVerify signing is easy as the transcript is readily available. The buffer is released very slightly later, but it shouldn't matter. - TLS 1.2 ServerKeyExchange signing required some reshuffling. Assembling the ServerKeyExchange parameters is moved to the previous state. The signing payload has some randoms prepended. This is cheap enough, but a nuisance in C. Pre-prepend the randoms in hs->server_params. With this change, we are *nearly* rid of the A/B => same function pattern. BUG=128 Change-Id: Iec4fe0be7cfc88a6de027ba2760fae70794ea810 Reviewed-on: https://boringssl-review.googlesource.com/17265 Commit-Queue: David Benjamin <davidben@google.com> Commit-Queue: Steven Valdez <svaldez@google.com> Reviewed-by: Steven Valdez <svaldez@google.com>
7 年之前
Simplify ssl_private_key_* state machine points. The original motivation behind the sign/complete split was to avoid needlessly hashing the input on each pass through the state machine, but we're payload-based now and, in all cases, the payload is either cheap to compute or readily available. (Even the hashing worry was probably unnecessary.) Tweak ssl_private_key_{sign,decrypt} to automatically call ssl_private_key_complete as needed and take advantage of this in the handshake state machines: - TLS 1.3 signing now computes the payload each pass. The payload is small and we're already allocating a comparable-sized buffer each iteration to hold the signature. This shouldn't be a big deal. - TLS 1.2 decryption code still needs two states due to reading the message (fixed in new state machine style), but otherwise it just performs cheap idempotent tasks again. The PSK code is reshuffled to guarantee the callback is not called twice (though this was impossible anyway because we don't support RSA_PSK). - TLS 1.2 CertificateVerify signing is easy as the transcript is readily available. The buffer is released very slightly later, but it shouldn't matter. - TLS 1.2 ServerKeyExchange signing required some reshuffling. Assembling the ServerKeyExchange parameters is moved to the previous state. The signing payload has some randoms prepended. This is cheap enough, but a nuisance in C. Pre-prepend the randoms in hs->server_params. With this change, we are *nearly* rid of the A/B => same function pattern. BUG=128 Change-Id: Iec4fe0be7cfc88a6de027ba2760fae70794ea810 Reviewed-on: https://boringssl-review.googlesource.com/17265 Commit-Queue: David Benjamin <davidben@google.com> Commit-Queue: Steven Valdez <svaldez@google.com> Reviewed-by: Steven Valdez <svaldez@google.com>
7 年之前
Simplify ssl_private_key_* state machine points. The original motivation behind the sign/complete split was to avoid needlessly hashing the input on each pass through the state machine, but we're payload-based now and, in all cases, the payload is either cheap to compute or readily available. (Even the hashing worry was probably unnecessary.) Tweak ssl_private_key_{sign,decrypt} to automatically call ssl_private_key_complete as needed and take advantage of this in the handshake state machines: - TLS 1.3 signing now computes the payload each pass. The payload is small and we're already allocating a comparable-sized buffer each iteration to hold the signature. This shouldn't be a big deal. - TLS 1.2 decryption code still needs two states due to reading the message (fixed in new state machine style), but otherwise it just performs cheap idempotent tasks again. The PSK code is reshuffled to guarantee the callback is not called twice (though this was impossible anyway because we don't support RSA_PSK). - TLS 1.2 CertificateVerify signing is easy as the transcript is readily available. The buffer is released very slightly later, but it shouldn't matter. - TLS 1.2 ServerKeyExchange signing required some reshuffling. Assembling the ServerKeyExchange parameters is moved to the previous state. The signing payload has some randoms prepended. This is cheap enough, but a nuisance in C. Pre-prepend the randoms in hs->server_params. With this change, we are *nearly* rid of the A/B => same function pattern. BUG=128 Change-Id: Iec4fe0be7cfc88a6de027ba2760fae70794ea810 Reviewed-on: https://boringssl-review.googlesource.com/17265 Commit-Queue: David Benjamin <davidben@google.com> Commit-Queue: Steven Valdez <svaldez@google.com> Reviewed-by: Steven Valdez <svaldez@google.com>
7 年之前
Simplify ssl_private_key_* state machine points. The original motivation behind the sign/complete split was to avoid needlessly hashing the input on each pass through the state machine, but we're payload-based now and, in all cases, the payload is either cheap to compute or readily available. (Even the hashing worry was probably unnecessary.) Tweak ssl_private_key_{sign,decrypt} to automatically call ssl_private_key_complete as needed and take advantage of this in the handshake state machines: - TLS 1.3 signing now computes the payload each pass. The payload is small and we're already allocating a comparable-sized buffer each iteration to hold the signature. This shouldn't be a big deal. - TLS 1.2 decryption code still needs two states due to reading the message (fixed in new state machine style), but otherwise it just performs cheap idempotent tasks again. The PSK code is reshuffled to guarantee the callback is not called twice (though this was impossible anyway because we don't support RSA_PSK). - TLS 1.2 CertificateVerify signing is easy as the transcript is readily available. The buffer is released very slightly later, but it shouldn't matter. - TLS 1.2 ServerKeyExchange signing required some reshuffling. Assembling the ServerKeyExchange parameters is moved to the previous state. The signing payload has some randoms prepended. This is cheap enough, but a nuisance in C. Pre-prepend the randoms in hs->server_params. With this change, we are *nearly* rid of the A/B => same function pattern. BUG=128 Change-Id: Iec4fe0be7cfc88a6de027ba2760fae70794ea810 Reviewed-on: https://boringssl-review.googlesource.com/17265 Commit-Queue: David Benjamin <davidben@google.com> Commit-Queue: Steven Valdez <svaldez@google.com> Reviewed-by: Steven Valdez <svaldez@google.com>
7 年之前
SSL_CONFIG: new struct for sheddable handshake configuration. |SSL_CONFIG| is a container for bits of configuration that are unneeded after the handshake completes. By default it is retained for the life of the |SSL|, but it may be shed at the caller's option by calling SSL_set_shed_handshake_config(). This is incompatible with renegotiation, and with SSL_clear(). |SSL_CONFIG| is reachable by |ssl->config| and by |hs->config|. The latter is always non-NULL. To avoid null checks, I've changed the signature of a number of functions from |SSL*| arguments to |SSL_HANDSHAKE*| arguments. When configuration has been shed, setters that touch |SSL_CONFIG| return an error value if that is possible. Setters that return |void| do nothing. Getters that request |SSL_CONFIG| values will fail with an |assert| if the configuration has been shed. When asserts are compiled out, they will return an error value. The aim of this commit is to simplify analysis of split-handshakes by making it obvious that some bits of state have no effects beyond the handshake. It also cuts down on memory usage. Of note: |SSL_CTX| is still reachable after the configuration has been shed, and a couple things need to be retained only for the sake of post-handshake hooks. Perhaps these can be fixed in time. Change-Id: Idf09642e0518945b81a1e9fcd7331cc9cf7cc2d6 Bug: 123 Reviewed-on: https://boringssl-review.googlesource.com/27644 Commit-Queue: David Benjamin <davidben@google.com> CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org> Reviewed-by: David Benjamin <davidben@google.com>
6 年之前
Simplify ssl_private_key_* state machine points. The original motivation behind the sign/complete split was to avoid needlessly hashing the input on each pass through the state machine, but we're payload-based now and, in all cases, the payload is either cheap to compute or readily available. (Even the hashing worry was probably unnecessary.) Tweak ssl_private_key_{sign,decrypt} to automatically call ssl_private_key_complete as needed and take advantage of this in the handshake state machines: - TLS 1.3 signing now computes the payload each pass. The payload is small and we're already allocating a comparable-sized buffer each iteration to hold the signature. This shouldn't be a big deal. - TLS 1.2 decryption code still needs two states due to reading the message (fixed in new state machine style), but otherwise it just performs cheap idempotent tasks again. The PSK code is reshuffled to guarantee the callback is not called twice (though this was impossible anyway because we don't support RSA_PSK). - TLS 1.2 CertificateVerify signing is easy as the transcript is readily available. The buffer is released very slightly later, but it shouldn't matter. - TLS 1.2 ServerKeyExchange signing required some reshuffling. Assembling the ServerKeyExchange parameters is moved to the previous state. The signing payload has some randoms prepended. This is cheap enough, but a nuisance in C. Pre-prepend the randoms in hs->server_params. With this change, we are *nearly* rid of the A/B => same function pattern. BUG=128 Change-Id: Iec4fe0be7cfc88a6de027ba2760fae70794ea810 Reviewed-on: https://boringssl-review.googlesource.com/17265 Commit-Queue: David Benjamin <davidben@google.com> Commit-Queue: Steven Valdez <svaldez@google.com> Reviewed-by: Steven Valdez <svaldez@google.com>
7 年之前
SSL_CONFIG: new struct for sheddable handshake configuration. |SSL_CONFIG| is a container for bits of configuration that are unneeded after the handshake completes. By default it is retained for the life of the |SSL|, but it may be shed at the caller's option by calling SSL_set_shed_handshake_config(). This is incompatible with renegotiation, and with SSL_clear(). |SSL_CONFIG| is reachable by |ssl->config| and by |hs->config|. The latter is always non-NULL. To avoid null checks, I've changed the signature of a number of functions from |SSL*| arguments to |SSL_HANDSHAKE*| arguments. When configuration has been shed, setters that touch |SSL_CONFIG| return an error value if that is possible. Setters that return |void| do nothing. Getters that request |SSL_CONFIG| values will fail with an |assert| if the configuration has been shed. When asserts are compiled out, they will return an error value. The aim of this commit is to simplify analysis of split-handshakes by making it obvious that some bits of state have no effects beyond the handshake. It also cuts down on memory usage. Of note: |SSL_CTX| is still reachable after the configuration has been shed, and a couple things need to be retained only for the sake of post-handshake hooks. Perhaps these can be fixed in time. Change-Id: Idf09642e0518945b81a1e9fcd7331cc9cf7cc2d6 Bug: 123 Reviewed-on: https://boringssl-review.googlesource.com/27644 Commit-Queue: David Benjamin <davidben@google.com> CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org> Reviewed-by: David Benjamin <davidben@google.com>
6 年之前
Simplify ssl_private_key_* state machine points. The original motivation behind the sign/complete split was to avoid needlessly hashing the input on each pass through the state machine, but we're payload-based now and, in all cases, the payload is either cheap to compute or readily available. (Even the hashing worry was probably unnecessary.) Tweak ssl_private_key_{sign,decrypt} to automatically call ssl_private_key_complete as needed and take advantage of this in the handshake state machines: - TLS 1.3 signing now computes the payload each pass. The payload is small and we're already allocating a comparable-sized buffer each iteration to hold the signature. This shouldn't be a big deal. - TLS 1.2 decryption code still needs two states due to reading the message (fixed in new state machine style), but otherwise it just performs cheap idempotent tasks again. The PSK code is reshuffled to guarantee the callback is not called twice (though this was impossible anyway because we don't support RSA_PSK). - TLS 1.2 CertificateVerify signing is easy as the transcript is readily available. The buffer is released very slightly later, but it shouldn't matter. - TLS 1.2 ServerKeyExchange signing required some reshuffling. Assembling the ServerKeyExchange parameters is moved to the previous state. The signing payload has some randoms prepended. This is cheap enough, but a nuisance in C. Pre-prepend the randoms in hs->server_params. With this change, we are *nearly* rid of the A/B => same function pattern. BUG=128 Change-Id: Iec4fe0be7cfc88a6de027ba2760fae70794ea810 Reviewed-on: https://boringssl-review.googlesource.com/17265 Commit-Queue: David Benjamin <davidben@google.com> Commit-Queue: Steven Valdez <svaldez@google.com> Reviewed-by: Steven Valdez <svaldez@google.com>
7 年之前
SSL_CONFIG: new struct for sheddable handshake configuration. |SSL_CONFIG| is a container for bits of configuration that are unneeded after the handshake completes. By default it is retained for the life of the |SSL|, but it may be shed at the caller's option by calling SSL_set_shed_handshake_config(). This is incompatible with renegotiation, and with SSL_clear(). |SSL_CONFIG| is reachable by |ssl->config| and by |hs->config|. The latter is always non-NULL. To avoid null checks, I've changed the signature of a number of functions from |SSL*| arguments to |SSL_HANDSHAKE*| arguments. When configuration has been shed, setters that touch |SSL_CONFIG| return an error value if that is possible. Setters that return |void| do nothing. Getters that request |SSL_CONFIG| values will fail with an |assert| if the configuration has been shed. When asserts are compiled out, they will return an error value. The aim of this commit is to simplify analysis of split-handshakes by making it obvious that some bits of state have no effects beyond the handshake. It also cuts down on memory usage. Of note: |SSL_CTX| is still reachable after the configuration has been shed, and a couple things need to be retained only for the sake of post-handshake hooks. Perhaps these can be fixed in time. Change-Id: Idf09642e0518945b81a1e9fcd7331cc9cf7cc2d6 Bug: 123 Reviewed-on: https://boringssl-review.googlesource.com/27644 Commit-Queue: David Benjamin <davidben@google.com> CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org> Reviewed-by: David Benjamin <davidben@google.com>
6 年之前
Simplify ssl_private_key_* state machine points. The original motivation behind the sign/complete split was to avoid needlessly hashing the input on each pass through the state machine, but we're payload-based now and, in all cases, the payload is either cheap to compute or readily available. (Even the hashing worry was probably unnecessary.) Tweak ssl_private_key_{sign,decrypt} to automatically call ssl_private_key_complete as needed and take advantage of this in the handshake state machines: - TLS 1.3 signing now computes the payload each pass. The payload is small and we're already allocating a comparable-sized buffer each iteration to hold the signature. This shouldn't be a big deal. - TLS 1.2 decryption code still needs two states due to reading the message (fixed in new state machine style), but otherwise it just performs cheap idempotent tasks again. The PSK code is reshuffled to guarantee the callback is not called twice (though this was impossible anyway because we don't support RSA_PSK). - TLS 1.2 CertificateVerify signing is easy as the transcript is readily available. The buffer is released very slightly later, but it shouldn't matter. - TLS 1.2 ServerKeyExchange signing required some reshuffling. Assembling the ServerKeyExchange parameters is moved to the previous state. The signing payload has some randoms prepended. This is cheap enough, but a nuisance in C. Pre-prepend the randoms in hs->server_params. With this change, we are *nearly* rid of the A/B => same function pattern. BUG=128 Change-Id: Iec4fe0be7cfc88a6de027ba2760fae70794ea810 Reviewed-on: https://boringssl-review.googlesource.com/17265 Commit-Queue: David Benjamin <davidben@google.com> Commit-Queue: Steven Valdez <svaldez@google.com> Reviewed-by: Steven Valdez <svaldez@google.com>
7 年之前
Simplify ssl_private_key_* state machine points. The original motivation behind the sign/complete split was to avoid needlessly hashing the input on each pass through the state machine, but we're payload-based now and, in all cases, the payload is either cheap to compute or readily available. (Even the hashing worry was probably unnecessary.) Tweak ssl_private_key_{sign,decrypt} to automatically call ssl_private_key_complete as needed and take advantage of this in the handshake state machines: - TLS 1.3 signing now computes the payload each pass. The payload is small and we're already allocating a comparable-sized buffer each iteration to hold the signature. This shouldn't be a big deal. - TLS 1.2 decryption code still needs two states due to reading the message (fixed in new state machine style), but otherwise it just performs cheap idempotent tasks again. The PSK code is reshuffled to guarantee the callback is not called twice (though this was impossible anyway because we don't support RSA_PSK). - TLS 1.2 CertificateVerify signing is easy as the transcript is readily available. The buffer is released very slightly later, but it shouldn't matter. - TLS 1.2 ServerKeyExchange signing required some reshuffling. Assembling the ServerKeyExchange parameters is moved to the previous state. The signing payload has some randoms prepended. This is cheap enough, but a nuisance in C. Pre-prepend the randoms in hs->server_params. With this change, we are *nearly* rid of the A/B => same function pattern. BUG=128 Change-Id: Iec4fe0be7cfc88a6de027ba2760fae70794ea810 Reviewed-on: https://boringssl-review.googlesource.com/17265 Commit-Queue: David Benjamin <davidben@google.com> Commit-Queue: Steven Valdez <svaldez@google.com> Reviewed-by: Steven Valdez <svaldez@google.com>
7 年之前
SSL_CONFIG: new struct for sheddable handshake configuration. |SSL_CONFIG| is a container for bits of configuration that are unneeded after the handshake completes. By default it is retained for the life of the |SSL|, but it may be shed at the caller's option by calling SSL_set_shed_handshake_config(). This is incompatible with renegotiation, and with SSL_clear(). |SSL_CONFIG| is reachable by |ssl->config| and by |hs->config|. The latter is always non-NULL. To avoid null checks, I've changed the signature of a number of functions from |SSL*| arguments to |SSL_HANDSHAKE*| arguments. When configuration has been shed, setters that touch |SSL_CONFIG| return an error value if that is possible. Setters that return |void| do nothing. Getters that request |SSL_CONFIG| values will fail with an |assert| if the configuration has been shed. When asserts are compiled out, they will return an error value. The aim of this commit is to simplify analysis of split-handshakes by making it obvious that some bits of state have no effects beyond the handshake. It also cuts down on memory usage. Of note: |SSL_CTX| is still reachable after the configuration has been shed, and a couple things need to be retained only for the sake of post-handshake hooks. Perhaps these can be fixed in time. Change-Id: Idf09642e0518945b81a1e9fcd7331cc9cf7cc2d6 Bug: 123 Reviewed-on: https://boringssl-review.googlesource.com/27644 Commit-Queue: David Benjamin <davidben@google.com> CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org> Reviewed-by: David Benjamin <davidben@google.com>
6 年之前
Move libssl's internals into the bssl namespace. This is horrible, but everything else I tried was worse. The goal with this CL is to take the extern "C" out of ssl/internal.h and move most symbols to namespace bssl, so we can start using C++ helpers and destructors without worry. Complications: - Public API functions must be extern "C" and match their declaration in ssl.h, which is unnamespaced. C++ really does not want you to interleave namespaced and unnamespaced things. One can actually write a namespaced extern "C" function, but this means, from C++'s perspective, the function is namespaced. Trying to namespace the public header would worked but ended up too deep a rabbithole. - Our STACK_OF macros do not work right in namespaces. - The typedefs for our exposed but opaque types are visible in the header files and copied into consuming projects as forward declarations. We ultimately want to give SSL a destructor, but clobbering an unnamespaced ssl_st::~ssl_st seems bad manners. - MSVC complains about ambiguous names if one typedefs SSL to bssl::SSL. This CL opts for: - ssl/*.cc must begin with #define BORINGSSL_INTERNAL_CXX_TYPES. This informs the public headers to create forward declarations which are compatible with our namespaces. - For now, C++-defined type FOO ends up at bssl::FOO with a typedef outside. Later I imagine we'll rename many of them. - Internal functions get namespace bssl, so we stop worrying about stomping the tls1_prf symbol. Exported C functions are stuck as they are. Rather than try anything weird, bite the bullet and reorder files which have a mix of public and private functions. I expect that over time, the public functions will become fairly small as we move logic to more idiomatic C++. Files without any public C functions can just be written normally. - To avoid MSVC troubles, some bssl types are renamed to CPlusPlusStyle in advance of them being made idiomatic C++. Bug: 132 Change-Id: Ic931895e117c38b14ff8d6e5a273e868796c7581 Reviewed-on: https://boringssl-review.googlesource.com/18124 Reviewed-by: David Benjamin <davidben@google.com>
7 年之前
Move libssl's internals into the bssl namespace. This is horrible, but everything else I tried was worse. The goal with this CL is to take the extern "C" out of ssl/internal.h and move most symbols to namespace bssl, so we can start using C++ helpers and destructors without worry. Complications: - Public API functions must be extern "C" and match their declaration in ssl.h, which is unnamespaced. C++ really does not want you to interleave namespaced and unnamespaced things. One can actually write a namespaced extern "C" function, but this means, from C++'s perspective, the function is namespaced. Trying to namespace the public header would worked but ended up too deep a rabbithole. - Our STACK_OF macros do not work right in namespaces. - The typedefs for our exposed but opaque types are visible in the header files and copied into consuming projects as forward declarations. We ultimately want to give SSL a destructor, but clobbering an unnamespaced ssl_st::~ssl_st seems bad manners. - MSVC complains about ambiguous names if one typedefs SSL to bssl::SSL. This CL opts for: - ssl/*.cc must begin with #define BORINGSSL_INTERNAL_CXX_TYPES. This informs the public headers to create forward declarations which are compatible with our namespaces. - For now, C++-defined type FOO ends up at bssl::FOO with a typedef outside. Later I imagine we'll rename many of them. - Internal functions get namespace bssl, so we stop worrying about stomping the tls1_prf symbol. Exported C functions are stuck as they are. Rather than try anything weird, bite the bullet and reorder files which have a mix of public and private functions. I expect that over time, the public functions will become fairly small as we move logic to more idiomatic C++. Files without any public C functions can just be written normally. - To avoid MSVC troubles, some bssl types are renamed to CPlusPlusStyle in advance of them being made idiomatic C++. Bug: 132 Change-Id: Ic931895e117c38b14ff8d6e5a273e868796c7581 Reviewed-on: https://boringssl-review.googlesource.com/18124 Reviewed-by: David Benjamin <davidben@google.com>
7 年之前
SSL_CONFIG: new struct for sheddable handshake configuration. |SSL_CONFIG| is a container for bits of configuration that are unneeded after the handshake completes. By default it is retained for the life of the |SSL|, but it may be shed at the caller's option by calling SSL_set_shed_handshake_config(). This is incompatible with renegotiation, and with SSL_clear(). |SSL_CONFIG| is reachable by |ssl->config| and by |hs->config|. The latter is always non-NULL. To avoid null checks, I've changed the signature of a number of functions from |SSL*| arguments to |SSL_HANDSHAKE*| arguments. When configuration has been shed, setters that touch |SSL_CONFIG| return an error value if that is possible. Setters that return |void| do nothing. Getters that request |SSL_CONFIG| values will fail with an |assert| if the configuration has been shed. When asserts are compiled out, they will return an error value. The aim of this commit is to simplify analysis of split-handshakes by making it obvious that some bits of state have no effects beyond the handshake. It also cuts down on memory usage. Of note: |SSL_CTX| is still reachable after the configuration has been shed, and a couple things need to be retained only for the sake of post-handshake hooks. Perhaps these can be fixed in time. Change-Id: Idf09642e0518945b81a1e9fcd7331cc9cf7cc2d6 Bug: 123 Reviewed-on: https://boringssl-review.googlesource.com/27644 Commit-Queue: David Benjamin <davidben@google.com> CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org> Reviewed-by: David Benjamin <davidben@google.com>
6 年之前
Move libssl's internals into the bssl namespace. This is horrible, but everything else I tried was worse. The goal with this CL is to take the extern "C" out of ssl/internal.h and move most symbols to namespace bssl, so we can start using C++ helpers and destructors without worry. Complications: - Public API functions must be extern "C" and match their declaration in ssl.h, which is unnamespaced. C++ really does not want you to interleave namespaced and unnamespaced things. One can actually write a namespaced extern "C" function, but this means, from C++'s perspective, the function is namespaced. Trying to namespace the public header would worked but ended up too deep a rabbithole. - Our STACK_OF macros do not work right in namespaces. - The typedefs for our exposed but opaque types are visible in the header files and copied into consuming projects as forward declarations. We ultimately want to give SSL a destructor, but clobbering an unnamespaced ssl_st::~ssl_st seems bad manners. - MSVC complains about ambiguous names if one typedefs SSL to bssl::SSL. This CL opts for: - ssl/*.cc must begin with #define BORINGSSL_INTERNAL_CXX_TYPES. This informs the public headers to create forward declarations which are compatible with our namespaces. - For now, C++-defined type FOO ends up at bssl::FOO with a typedef outside. Later I imagine we'll rename many of them. - Internal functions get namespace bssl, so we stop worrying about stomping the tls1_prf symbol. Exported C functions are stuck as they are. Rather than try anything weird, bite the bullet and reorder files which have a mix of public and private functions. I expect that over time, the public functions will become fairly small as we move logic to more idiomatic C++. Files without any public C functions can just be written normally. - To avoid MSVC troubles, some bssl types are renamed to CPlusPlusStyle in advance of them being made idiomatic C++. Bug: 132 Change-Id: Ic931895e117c38b14ff8d6e5a273e868796c7581 Reviewed-on: https://boringssl-review.googlesource.com/18124 Reviewed-by: David Benjamin <davidben@google.com>
7 年之前
Move libssl's internals into the bssl namespace. This is horrible, but everything else I tried was worse. The goal with this CL is to take the extern "C" out of ssl/internal.h and move most symbols to namespace bssl, so we can start using C++ helpers and destructors without worry. Complications: - Public API functions must be extern "C" and match their declaration in ssl.h, which is unnamespaced. C++ really does not want you to interleave namespaced and unnamespaced things. One can actually write a namespaced extern "C" function, but this means, from C++'s perspective, the function is namespaced. Trying to namespace the public header would worked but ended up too deep a rabbithole. - Our STACK_OF macros do not work right in namespaces. - The typedefs for our exposed but opaque types are visible in the header files and copied into consuming projects as forward declarations. We ultimately want to give SSL a destructor, but clobbering an unnamespaced ssl_st::~ssl_st seems bad manners. - MSVC complains about ambiguous names if one typedefs SSL to bssl::SSL. This CL opts for: - ssl/*.cc must begin with #define BORINGSSL_INTERNAL_CXX_TYPES. This informs the public headers to create forward declarations which are compatible with our namespaces. - For now, C++-defined type FOO ends up at bssl::FOO with a typedef outside. Later I imagine we'll rename many of them. - Internal functions get namespace bssl, so we stop worrying about stomping the tls1_prf symbol. Exported C functions are stuck as they are. Rather than try anything weird, bite the bullet and reorder files which have a mix of public and private functions. I expect that over time, the public functions will become fairly small as we move logic to more idiomatic C++. Files without any public C functions can just be written normally. - To avoid MSVC troubles, some bssl types are renamed to CPlusPlusStyle in advance of them being made idiomatic C++. Bug: 132 Change-Id: Ic931895e117c38b14ff8d6e5a273e868796c7581 Reviewed-on: https://boringssl-review.googlesource.com/18124 Reviewed-by: David Benjamin <davidben@google.com>
7 年之前
Move libssl's internals into the bssl namespace. This is horrible, but everything else I tried was worse. The goal with this CL is to take the extern "C" out of ssl/internal.h and move most symbols to namespace bssl, so we can start using C++ helpers and destructors without worry. Complications: - Public API functions must be extern "C" and match their declaration in ssl.h, which is unnamespaced. C++ really does not want you to interleave namespaced and unnamespaced things. One can actually write a namespaced extern "C" function, but this means, from C++'s perspective, the function is namespaced. Trying to namespace the public header would worked but ended up too deep a rabbithole. - Our STACK_OF macros do not work right in namespaces. - The typedefs for our exposed but opaque types are visible in the header files and copied into consuming projects as forward declarations. We ultimately want to give SSL a destructor, but clobbering an unnamespaced ssl_st::~ssl_st seems bad manners. - MSVC complains about ambiguous names if one typedefs SSL to bssl::SSL. This CL opts for: - ssl/*.cc must begin with #define BORINGSSL_INTERNAL_CXX_TYPES. This informs the public headers to create forward declarations which are compatible with our namespaces. - For now, C++-defined type FOO ends up at bssl::FOO with a typedef outside. Later I imagine we'll rename many of them. - Internal functions get namespace bssl, so we stop worrying about stomping the tls1_prf symbol. Exported C functions are stuck as they are. Rather than try anything weird, bite the bullet and reorder files which have a mix of public and private functions. I expect that over time, the public functions will become fairly small as we move logic to more idiomatic C++. Files without any public C functions can just be written normally. - To avoid MSVC troubles, some bssl types are renamed to CPlusPlusStyle in advance of them being made idiomatic C++. Bug: 132 Change-Id: Ic931895e117c38b14ff8d6e5a273e868796c7581 Reviewed-on: https://boringssl-review.googlesource.com/18124 Reviewed-by: David Benjamin <davidben@google.com>
7 年之前
SSL_CONFIG: new struct for sheddable handshake configuration. |SSL_CONFIG| is a container for bits of configuration that are unneeded after the handshake completes. By default it is retained for the life of the |SSL|, but it may be shed at the caller's option by calling SSL_set_shed_handshake_config(). This is incompatible with renegotiation, and with SSL_clear(). |SSL_CONFIG| is reachable by |ssl->config| and by |hs->config|. The latter is always non-NULL. To avoid null checks, I've changed the signature of a number of functions from |SSL*| arguments to |SSL_HANDSHAKE*| arguments. When configuration has been shed, setters that touch |SSL_CONFIG| return an error value if that is possible. Setters that return |void| do nothing. Getters that request |SSL_CONFIG| values will fail with an |assert| if the configuration has been shed. When asserts are compiled out, they will return an error value. The aim of this commit is to simplify analysis of split-handshakes by making it obvious that some bits of state have no effects beyond the handshake. It also cuts down on memory usage. Of note: |SSL_CTX| is still reachable after the configuration has been shed, and a couple things need to be retained only for the sake of post-handshake hooks. Perhaps these can be fixed in time. Change-Id: Idf09642e0518945b81a1e9fcd7331cc9cf7cc2d6 Bug: 123 Reviewed-on: https://boringssl-review.googlesource.com/27644 Commit-Queue: David Benjamin <davidben@google.com> CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org> Reviewed-by: David Benjamin <davidben@google.com>
6 年之前
Move libssl's internals into the bssl namespace. This is horrible, but everything else I tried was worse. The goal with this CL is to take the extern "C" out of ssl/internal.h and move most symbols to namespace bssl, so we can start using C++ helpers and destructors without worry. Complications: - Public API functions must be extern "C" and match their declaration in ssl.h, which is unnamespaced. C++ really does not want you to interleave namespaced and unnamespaced things. One can actually write a namespaced extern "C" function, but this means, from C++'s perspective, the function is namespaced. Trying to namespace the public header would worked but ended up too deep a rabbithole. - Our STACK_OF macros do not work right in namespaces. - The typedefs for our exposed but opaque types are visible in the header files and copied into consuming projects as forward declarations. We ultimately want to give SSL a destructor, but clobbering an unnamespaced ssl_st::~ssl_st seems bad manners. - MSVC complains about ambiguous names if one typedefs SSL to bssl::SSL. This CL opts for: - ssl/*.cc must begin with #define BORINGSSL_INTERNAL_CXX_TYPES. This informs the public headers to create forward declarations which are compatible with our namespaces. - For now, C++-defined type FOO ends up at bssl::FOO with a typedef outside. Later I imagine we'll rename many of them. - Internal functions get namespace bssl, so we stop worrying about stomping the tls1_prf symbol. Exported C functions are stuck as they are. Rather than try anything weird, bite the bullet and reorder files which have a mix of public and private functions. I expect that over time, the public functions will become fairly small as we move logic to more idiomatic C++. Files without any public C functions can just be written normally. - To avoid MSVC troubles, some bssl types are renamed to CPlusPlusStyle in advance of them being made idiomatic C++. Bug: 132 Change-Id: Ic931895e117c38b14ff8d6e5a273e868796c7581 Reviewed-on: https://boringssl-review.googlesource.com/18124 Reviewed-by: David Benjamin <davidben@google.com>
7 年之前
Move libssl's internals into the bssl namespace. This is horrible, but everything else I tried was worse. The goal with this CL is to take the extern "C" out of ssl/internal.h and move most symbols to namespace bssl, so we can start using C++ helpers and destructors without worry. Complications: - Public API functions must be extern "C" and match their declaration in ssl.h, which is unnamespaced. C++ really does not want you to interleave namespaced and unnamespaced things. One can actually write a namespaced extern "C" function, but this means, from C++'s perspective, the function is namespaced. Trying to namespace the public header would worked but ended up too deep a rabbithole. - Our STACK_OF macros do not work right in namespaces. - The typedefs for our exposed but opaque types are visible in the header files and copied into consuming projects as forward declarations. We ultimately want to give SSL a destructor, but clobbering an unnamespaced ssl_st::~ssl_st seems bad manners. - MSVC complains about ambiguous names if one typedefs SSL to bssl::SSL. This CL opts for: - ssl/*.cc must begin with #define BORINGSSL_INTERNAL_CXX_TYPES. This informs the public headers to create forward declarations which are compatible with our namespaces. - For now, C++-defined type FOO ends up at bssl::FOO with a typedef outside. Later I imagine we'll rename many of them. - Internal functions get namespace bssl, so we stop worrying about stomping the tls1_prf symbol. Exported C functions are stuck as they are. Rather than try anything weird, bite the bullet and reorder files which have a mix of public and private functions. I expect that over time, the public functions will become fairly small as we move logic to more idiomatic C++. Files without any public C functions can just be written normally. - To avoid MSVC troubles, some bssl types are renamed to CPlusPlusStyle in advance of them being made idiomatic C++. Bug: 132 Change-Id: Ic931895e117c38b14ff8d6e5a273e868796c7581 Reviewed-on: https://boringssl-review.googlesource.com/18124 Reviewed-by: David Benjamin <davidben@google.com>
7 年之前
Move libssl's internals into the bssl namespace. This is horrible, but everything else I tried was worse. The goal with this CL is to take the extern "C" out of ssl/internal.h and move most symbols to namespace bssl, so we can start using C++ helpers and destructors without worry. Complications: - Public API functions must be extern "C" and match their declaration in ssl.h, which is unnamespaced. C++ really does not want you to interleave namespaced and unnamespaced things. One can actually write a namespaced extern "C" function, but this means, from C++'s perspective, the function is namespaced. Trying to namespace the public header would worked but ended up too deep a rabbithole. - Our STACK_OF macros do not work right in namespaces. - The typedefs for our exposed but opaque types are visible in the header files and copied into consuming projects as forward declarations. We ultimately want to give SSL a destructor, but clobbering an unnamespaced ssl_st::~ssl_st seems bad manners. - MSVC complains about ambiguous names if one typedefs SSL to bssl::SSL. This CL opts for: - ssl/*.cc must begin with #define BORINGSSL_INTERNAL_CXX_TYPES. This informs the public headers to create forward declarations which are compatible with our namespaces. - For now, C++-defined type FOO ends up at bssl::FOO with a typedef outside. Later I imagine we'll rename many of them. - Internal functions get namespace bssl, so we stop worrying about stomping the tls1_prf symbol. Exported C functions are stuck as they are. Rather than try anything weird, bite the bullet and reorder files which have a mix of public and private functions. I expect that over time, the public functions will become fairly small as we move logic to more idiomatic C++. Files without any public C functions can just be written normally. - To avoid MSVC troubles, some bssl types are renamed to CPlusPlusStyle in advance of them being made idiomatic C++. Bug: 132 Change-Id: Ic931895e117c38b14ff8d6e5a273e868796c7581 Reviewed-on: https://boringssl-review.googlesource.com/18124 Reviewed-by: David Benjamin <davidben@google.com>
7 年之前
Move libssl's internals into the bssl namespace. This is horrible, but everything else I tried was worse. The goal with this CL is to take the extern "C" out of ssl/internal.h and move most symbols to namespace bssl, so we can start using C++ helpers and destructors without worry. Complications: - Public API functions must be extern "C" and match their declaration in ssl.h, which is unnamespaced. C++ really does not want you to interleave namespaced and unnamespaced things. One can actually write a namespaced extern "C" function, but this means, from C++'s perspective, the function is namespaced. Trying to namespace the public header would worked but ended up too deep a rabbithole. - Our STACK_OF macros do not work right in namespaces. - The typedefs for our exposed but opaque types are visible in the header files and copied into consuming projects as forward declarations. We ultimately want to give SSL a destructor, but clobbering an unnamespaced ssl_st::~ssl_st seems bad manners. - MSVC complains about ambiguous names if one typedefs SSL to bssl::SSL. This CL opts for: - ssl/*.cc must begin with #define BORINGSSL_INTERNAL_CXX_TYPES. This informs the public headers to create forward declarations which are compatible with our namespaces. - For now, C++-defined type FOO ends up at bssl::FOO with a typedef outside. Later I imagine we'll rename many of them. - Internal functions get namespace bssl, so we stop worrying about stomping the tls1_prf symbol. Exported C functions are stuck as they are. Rather than try anything weird, bite the bullet and reorder files which have a mix of public and private functions. I expect that over time, the public functions will become fairly small as we move logic to more idiomatic C++. Files without any public C functions can just be written normally. - To avoid MSVC troubles, some bssl types are renamed to CPlusPlusStyle in advance of them being made idiomatic C++. Bug: 132 Change-Id: Ic931895e117c38b14ff8d6e5a273e868796c7581 Reviewed-on: https://boringssl-review.googlesource.com/18124 Reviewed-by: David Benjamin <davidben@google.com>
7 年之前
Move libssl's internals into the bssl namespace. This is horrible, but everything else I tried was worse. The goal with this CL is to take the extern "C" out of ssl/internal.h and move most symbols to namespace bssl, so we can start using C++ helpers and destructors without worry. Complications: - Public API functions must be extern "C" and match their declaration in ssl.h, which is unnamespaced. C++ really does not want you to interleave namespaced and unnamespaced things. One can actually write a namespaced extern "C" function, but this means, from C++'s perspective, the function is namespaced. Trying to namespace the public header would worked but ended up too deep a rabbithole. - Our STACK_OF macros do not work right in namespaces. - The typedefs for our exposed but opaque types are visible in the header files and copied into consuming projects as forward declarations. We ultimately want to give SSL a destructor, but clobbering an unnamespaced ssl_st::~ssl_st seems bad manners. - MSVC complains about ambiguous names if one typedefs SSL to bssl::SSL. This CL opts for: - ssl/*.cc must begin with #define BORINGSSL_INTERNAL_CXX_TYPES. This informs the public headers to create forward declarations which are compatible with our namespaces. - For now, C++-defined type FOO ends up at bssl::FOO with a typedef outside. Later I imagine we'll rename many of them. - Internal functions get namespace bssl, so we stop worrying about stomping the tls1_prf symbol. Exported C functions are stuck as they are. Rather than try anything weird, bite the bullet and reorder files which have a mix of public and private functions. I expect that over time, the public functions will become fairly small as we move logic to more idiomatic C++. Files without any public C functions can just be written normally. - To avoid MSVC troubles, some bssl types are renamed to CPlusPlusStyle in advance of them being made idiomatic C++. Bug: 132 Change-Id: Ic931895e117c38b14ff8d6e5a273e868796c7581 Reviewed-on: https://boringssl-review.googlesource.com/18124 Reviewed-by: David Benjamin <davidben@google.com>
7 年之前
Move libssl's internals into the bssl namespace. This is horrible, but everything else I tried was worse. The goal with this CL is to take the extern "C" out of ssl/internal.h and move most symbols to namespace bssl, so we can start using C++ helpers and destructors without worry. Complications: - Public API functions must be extern "C" and match their declaration in ssl.h, which is unnamespaced. C++ really does not want you to interleave namespaced and unnamespaced things. One can actually write a namespaced extern "C" function, but this means, from C++'s perspective, the function is namespaced. Trying to namespace the public header would worked but ended up too deep a rabbithole. - Our STACK_OF macros do not work right in namespaces. - The typedefs for our exposed but opaque types are visible in the header files and copied into consuming projects as forward declarations. We ultimately want to give SSL a destructor, but clobbering an unnamespaced ssl_st::~ssl_st seems bad manners. - MSVC complains about ambiguous names if one typedefs SSL to bssl::SSL. This CL opts for: - ssl/*.cc must begin with #define BORINGSSL_INTERNAL_CXX_TYPES. This informs the public headers to create forward declarations which are compatible with our namespaces. - For now, C++-defined type FOO ends up at bssl::FOO with a typedef outside. Later I imagine we'll rename many of them. - Internal functions get namespace bssl, so we stop worrying about stomping the tls1_prf symbol. Exported C functions are stuck as they are. Rather than try anything weird, bite the bullet and reorder files which have a mix of public and private functions. I expect that over time, the public functions will become fairly small as we move logic to more idiomatic C++. Files without any public C functions can just be written normally. - To avoid MSVC troubles, some bssl types are renamed to CPlusPlusStyle in advance of them being made idiomatic C++. Bug: 132 Change-Id: Ic931895e117c38b14ff8d6e5a273e868796c7581 Reviewed-on: https://boringssl-review.googlesource.com/18124 Reviewed-by: David Benjamin <davidben@google.com>
7 年之前
Move libssl's internals into the bssl namespace. This is horrible, but everything else I tried was worse. The goal with this CL is to take the extern "C" out of ssl/internal.h and move most symbols to namespace bssl, so we can start using C++ helpers and destructors without worry. Complications: - Public API functions must be extern "C" and match their declaration in ssl.h, which is unnamespaced. C++ really does not want you to interleave namespaced and unnamespaced things. One can actually write a namespaced extern "C" function, but this means, from C++'s perspective, the function is namespaced. Trying to namespace the public header would worked but ended up too deep a rabbithole. - Our STACK_OF macros do not work right in namespaces. - The typedefs for our exposed but opaque types are visible in the header files and copied into consuming projects as forward declarations. We ultimately want to give SSL a destructor, but clobbering an unnamespaced ssl_st::~ssl_st seems bad manners. - MSVC complains about ambiguous names if one typedefs SSL to bssl::SSL. This CL opts for: - ssl/*.cc must begin with #define BORINGSSL_INTERNAL_CXX_TYPES. This informs the public headers to create forward declarations which are compatible with our namespaces. - For now, C++-defined type FOO ends up at bssl::FOO with a typedef outside. Later I imagine we'll rename many of them. - Internal functions get namespace bssl, so we stop worrying about stomping the tls1_prf symbol. Exported C functions are stuck as they are. Rather than try anything weird, bite the bullet and reorder files which have a mix of public and private functions. I expect that over time, the public functions will become fairly small as we move logic to more idiomatic C++. Files without any public C functions can just be written normally. - To avoid MSVC troubles, some bssl types are renamed to CPlusPlusStyle in advance of them being made idiomatic C++. Bug: 132 Change-Id: Ic931895e117c38b14ff8d6e5a273e868796c7581 Reviewed-on: https://boringssl-review.googlesource.com/18124 Reviewed-by: David Benjamin <davidben@google.com>
7 年之前
Move libssl's internals into the bssl namespace. This is horrible, but everything else I tried was worse. The goal with this CL is to take the extern "C" out of ssl/internal.h and move most symbols to namespace bssl, so we can start using C++ helpers and destructors without worry. Complications: - Public API functions must be extern "C" and match their declaration in ssl.h, which is unnamespaced. C++ really does not want you to interleave namespaced and unnamespaced things. One can actually write a namespaced extern "C" function, but this means, from C++'s perspective, the function is namespaced. Trying to namespace the public header would worked but ended up too deep a rabbithole. - Our STACK_OF macros do not work right in namespaces. - The typedefs for our exposed but opaque types are visible in the header files and copied into consuming projects as forward declarations. We ultimately want to give SSL a destructor, but clobbering an unnamespaced ssl_st::~ssl_st seems bad manners. - MSVC complains about ambiguous names if one typedefs SSL to bssl::SSL. This CL opts for: - ssl/*.cc must begin with #define BORINGSSL_INTERNAL_CXX_TYPES. This informs the public headers to create forward declarations which are compatible with our namespaces. - For now, C++-defined type FOO ends up at bssl::FOO with a typedef outside. Later I imagine we'll rename many of them. - Internal functions get namespace bssl, so we stop worrying about stomping the tls1_prf symbol. Exported C functions are stuck as they are. Rather than try anything weird, bite the bullet and reorder files which have a mix of public and private functions. I expect that over time, the public functions will become fairly small as we move logic to more idiomatic C++. Files without any public C functions can just be written normally. - To avoid MSVC troubles, some bssl types are renamed to CPlusPlusStyle in advance of them being made idiomatic C++. Bug: 132 Change-Id: Ic931895e117c38b14ff8d6e5a273e868796c7581 Reviewed-on: https://boringssl-review.googlesource.com/18124 Reviewed-by: David Benjamin <davidben@google.com>
7 年之前
Move libssl's internals into the bssl namespace. This is horrible, but everything else I tried was worse. The goal with this CL is to take the extern "C" out of ssl/internal.h and move most symbols to namespace bssl, so we can start using C++ helpers and destructors without worry. Complications: - Public API functions must be extern "C" and match their declaration in ssl.h, which is unnamespaced. C++ really does not want you to interleave namespaced and unnamespaced things. One can actually write a namespaced extern "C" function, but this means, from C++'s perspective, the function is namespaced. Trying to namespace the public header would worked but ended up too deep a rabbithole. - Our STACK_OF macros do not work right in namespaces. - The typedefs for our exposed but opaque types are visible in the header files and copied into consuming projects as forward declarations. We ultimately want to give SSL a destructor, but clobbering an unnamespaced ssl_st::~ssl_st seems bad manners. - MSVC complains about ambiguous names if one typedefs SSL to bssl::SSL. This CL opts for: - ssl/*.cc must begin with #define BORINGSSL_INTERNAL_CXX_TYPES. This informs the public headers to create forward declarations which are compatible with our namespaces. - For now, C++-defined type FOO ends up at bssl::FOO with a typedef outside. Later I imagine we'll rename many of them. - Internal functions get namespace bssl, so we stop worrying about stomping the tls1_prf symbol. Exported C functions are stuck as they are. Rather than try anything weird, bite the bullet and reorder files which have a mix of public and private functions. I expect that over time, the public functions will become fairly small as we move logic to more idiomatic C++. Files without any public C functions can just be written normally. - To avoid MSVC troubles, some bssl types are renamed to CPlusPlusStyle in advance of them being made idiomatic C++. Bug: 132 Change-Id: Ic931895e117c38b14ff8d6e5a273e868796c7581 Reviewed-on: https://boringssl-review.googlesource.com/18124 Reviewed-by: David Benjamin <davidben@google.com>
7 年之前
Move libssl's internals into the bssl namespace. This is horrible, but everything else I tried was worse. The goal with this CL is to take the extern "C" out of ssl/internal.h and move most symbols to namespace bssl, so we can start using C++ helpers and destructors without worry. Complications: - Public API functions must be extern "C" and match their declaration in ssl.h, which is unnamespaced. C++ really does not want you to interleave namespaced and unnamespaced things. One can actually write a namespaced extern "C" function, but this means, from C++'s perspective, the function is namespaced. Trying to namespace the public header would worked but ended up too deep a rabbithole. - Our STACK_OF macros do not work right in namespaces. - The typedefs for our exposed but opaque types are visible in the header files and copied into consuming projects as forward declarations. We ultimately want to give SSL a destructor, but clobbering an unnamespaced ssl_st::~ssl_st seems bad manners. - MSVC complains about ambiguous names if one typedefs SSL to bssl::SSL. This CL opts for: - ssl/*.cc must begin with #define BORINGSSL_INTERNAL_CXX_TYPES. This informs the public headers to create forward declarations which are compatible with our namespaces. - For now, C++-defined type FOO ends up at bssl::FOO with a typedef outside. Later I imagine we'll rename many of them. - Internal functions get namespace bssl, so we stop worrying about stomping the tls1_prf symbol. Exported C functions are stuck as they are. Rather than try anything weird, bite the bullet and reorder files which have a mix of public and private functions. I expect that over time, the public functions will become fairly small as we move logic to more idiomatic C++. Files without any public C functions can just be written normally. - To avoid MSVC troubles, some bssl types are renamed to CPlusPlusStyle in advance of them being made idiomatic C++. Bug: 132 Change-Id: Ic931895e117c38b14ff8d6e5a273e868796c7581 Reviewed-on: https://boringssl-review.googlesource.com/18124 Reviewed-by: David Benjamin <davidben@google.com>
7 年之前
Move libssl's internals into the bssl namespace. This is horrible, but everything else I tried was worse. The goal with this CL is to take the extern "C" out of ssl/internal.h and move most symbols to namespace bssl, so we can start using C++ helpers and destructors without worry. Complications: - Public API functions must be extern "C" and match their declaration in ssl.h, which is unnamespaced. C++ really does not want you to interleave namespaced and unnamespaced things. One can actually write a namespaced extern "C" function, but this means, from C++'s perspective, the function is namespaced. Trying to namespace the public header would worked but ended up too deep a rabbithole. - Our STACK_OF macros do not work right in namespaces. - The typedefs for our exposed but opaque types are visible in the header files and copied into consuming projects as forward declarations. We ultimately want to give SSL a destructor, but clobbering an unnamespaced ssl_st::~ssl_st seems bad manners. - MSVC complains about ambiguous names if one typedefs SSL to bssl::SSL. This CL opts for: - ssl/*.cc must begin with #define BORINGSSL_INTERNAL_CXX_TYPES. This informs the public headers to create forward declarations which are compatible with our namespaces. - For now, C++-defined type FOO ends up at bssl::FOO with a typedef outside. Later I imagine we'll rename many of them. - Internal functions get namespace bssl, so we stop worrying about stomping the tls1_prf symbol. Exported C functions are stuck as they are. Rather than try anything weird, bite the bullet and reorder files which have a mix of public and private functions. I expect that over time, the public functions will become fairly small as we move logic to more idiomatic C++. Files without any public C functions can just be written normally. - To avoid MSVC troubles, some bssl types are renamed to CPlusPlusStyle in advance of them being made idiomatic C++. Bug: 132 Change-Id: Ic931895e117c38b14ff8d6e5a273e868796c7581 Reviewed-on: https://boringssl-review.googlesource.com/18124 Reviewed-by: David Benjamin <davidben@google.com>
7 年之前
SSL_CONFIG: new struct for sheddable handshake configuration. |SSL_CONFIG| is a container for bits of configuration that are unneeded after the handshake completes. By default it is retained for the life of the |SSL|, but it may be shed at the caller's option by calling SSL_set_shed_handshake_config(). This is incompatible with renegotiation, and with SSL_clear(). |SSL_CONFIG| is reachable by |ssl->config| and by |hs->config|. The latter is always non-NULL. To avoid null checks, I've changed the signature of a number of functions from |SSL*| arguments to |SSL_HANDSHAKE*| arguments. When configuration has been shed, setters that touch |SSL_CONFIG| return an error value if that is possible. Setters that return |void| do nothing. Getters that request |SSL_CONFIG| values will fail with an |assert| if the configuration has been shed. When asserts are compiled out, they will return an error value. The aim of this commit is to simplify analysis of split-handshakes by making it obvious that some bits of state have no effects beyond the handshake. It also cuts down on memory usage. Of note: |SSL_CTX| is still reachable after the configuration has been shed, and a couple things need to be retained only for the sake of post-handshake hooks. Perhaps these can be fixed in time. Change-Id: Idf09642e0518945b81a1e9fcd7331cc9cf7cc2d6 Bug: 123 Reviewed-on: https://boringssl-review.googlesource.com/27644 Commit-Queue: David Benjamin <davidben@google.com> CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org> Reviewed-by: David Benjamin <davidben@google.com>
6 年之前
Move libssl's internals into the bssl namespace. This is horrible, but everything else I tried was worse. The goal with this CL is to take the extern "C" out of ssl/internal.h and move most symbols to namespace bssl, so we can start using C++ helpers and destructors without worry. Complications: - Public API functions must be extern "C" and match their declaration in ssl.h, which is unnamespaced. C++ really does not want you to interleave namespaced and unnamespaced things. One can actually write a namespaced extern "C" function, but this means, from C++'s perspective, the function is namespaced. Trying to namespace the public header would worked but ended up too deep a rabbithole. - Our STACK_OF macros do not work right in namespaces. - The typedefs for our exposed but opaque types are visible in the header files and copied into consuming projects as forward declarations. We ultimately want to give SSL a destructor, but clobbering an unnamespaced ssl_st::~ssl_st seems bad manners. - MSVC complains about ambiguous names if one typedefs SSL to bssl::SSL. This CL opts for: - ssl/*.cc must begin with #define BORINGSSL_INTERNAL_CXX_TYPES. This informs the public headers to create forward declarations which are compatible with our namespaces. - For now, C++-defined type FOO ends up at bssl::FOO with a typedef outside. Later I imagine we'll rename many of them. - Internal functions get namespace bssl, so we stop worrying about stomping the tls1_prf symbol. Exported C functions are stuck as they are. Rather than try anything weird, bite the bullet and reorder files which have a mix of public and private functions. I expect that over time, the public functions will become fairly small as we move logic to more idiomatic C++. Files without any public C functions can just be written normally. - To avoid MSVC troubles, some bssl types are renamed to CPlusPlusStyle in advance of them being made idiomatic C++. Bug: 132 Change-Id: Ic931895e117c38b14ff8d6e5a273e868796c7581 Reviewed-on: https://boringssl-review.googlesource.com/18124 Reviewed-by: David Benjamin <davidben@google.com>
7 年之前
Move libssl's internals into the bssl namespace. This is horrible, but everything else I tried was worse. The goal with this CL is to take the extern "C" out of ssl/internal.h and move most symbols to namespace bssl, so we can start using C++ helpers and destructors without worry. Complications: - Public API functions must be extern "C" and match their declaration in ssl.h, which is unnamespaced. C++ really does not want you to interleave namespaced and unnamespaced things. One can actually write a namespaced extern "C" function, but this means, from C++'s perspective, the function is namespaced. Trying to namespace the public header would worked but ended up too deep a rabbithole. - Our STACK_OF macros do not work right in namespaces. - The typedefs for our exposed but opaque types are visible in the header files and copied into consuming projects as forward declarations. We ultimately want to give SSL a destructor, but clobbering an unnamespaced ssl_st::~ssl_st seems bad manners. - MSVC complains about ambiguous names if one typedefs SSL to bssl::SSL. This CL opts for: - ssl/*.cc must begin with #define BORINGSSL_INTERNAL_CXX_TYPES. This informs the public headers to create forward declarations which are compatible with our namespaces. - For now, C++-defined type FOO ends up at bssl::FOO with a typedef outside. Later I imagine we'll rename many of them. - Internal functions get namespace bssl, so we stop worrying about stomping the tls1_prf symbol. Exported C functions are stuck as they are. Rather than try anything weird, bite the bullet and reorder files which have a mix of public and private functions. I expect that over time, the public functions will become fairly small as we move logic to more idiomatic C++. Files without any public C functions can just be written normally. - To avoid MSVC troubles, some bssl types are renamed to CPlusPlusStyle in advance of them being made idiomatic C++. Bug: 132 Change-Id: Ic931895e117c38b14ff8d6e5a273e868796c7581 Reviewed-on: https://boringssl-review.googlesource.com/18124 Reviewed-by: David Benjamin <davidben@google.com>
7 年之前
Move libssl's internals into the bssl namespace. This is horrible, but everything else I tried was worse. The goal with this CL is to take the extern "C" out of ssl/internal.h and move most symbols to namespace bssl, so we can start using C++ helpers and destructors without worry. Complications: - Public API functions must be extern "C" and match their declaration in ssl.h, which is unnamespaced. C++ really does not want you to interleave namespaced and unnamespaced things. One can actually write a namespaced extern "C" function, but this means, from C++'s perspective, the function is namespaced. Trying to namespace the public header would worked but ended up too deep a rabbithole. - Our STACK_OF macros do not work right in namespaces. - The typedefs for our exposed but opaque types are visible in the header files and copied into consuming projects as forward declarations. We ultimately want to give SSL a destructor, but clobbering an unnamespaced ssl_st::~ssl_st seems bad manners. - MSVC complains about ambiguous names if one typedefs SSL to bssl::SSL. This CL opts for: - ssl/*.cc must begin with #define BORINGSSL_INTERNAL_CXX_TYPES. This informs the public headers to create forward declarations which are compatible with our namespaces. - For now, C++-defined type FOO ends up at bssl::FOO with a typedef outside. Later I imagine we'll rename many of them. - Internal functions get namespace bssl, so we stop worrying about stomping the tls1_prf symbol. Exported C functions are stuck as they are. Rather than try anything weird, bite the bullet and reorder files which have a mix of public and private functions. I expect that over time, the public functions will become fairly small as we move logic to more idiomatic C++. Files without any public C functions can just be written normally. - To avoid MSVC troubles, some bssl types are renamed to CPlusPlusStyle in advance of them being made idiomatic C++. Bug: 132 Change-Id: Ic931895e117c38b14ff8d6e5a273e868796c7581 Reviewed-on: https://boringssl-review.googlesource.com/18124 Reviewed-by: David Benjamin <davidben@google.com>
7 年之前
SSL_CONFIG: new struct for sheddable handshake configuration. |SSL_CONFIG| is a container for bits of configuration that are unneeded after the handshake completes. By default it is retained for the life of the |SSL|, but it may be shed at the caller's option by calling SSL_set_shed_handshake_config(). This is incompatible with renegotiation, and with SSL_clear(). |SSL_CONFIG| is reachable by |ssl->config| and by |hs->config|. The latter is always non-NULL. To avoid null checks, I've changed the signature of a number of functions from |SSL*| arguments to |SSL_HANDSHAKE*| arguments. When configuration has been shed, setters that touch |SSL_CONFIG| return an error value if that is possible. Setters that return |void| do nothing. Getters that request |SSL_CONFIG| values will fail with an |assert| if the configuration has been shed. When asserts are compiled out, they will return an error value. The aim of this commit is to simplify analysis of split-handshakes by making it obvious that some bits of state have no effects beyond the handshake. It also cuts down on memory usage. Of note: |SSL_CTX| is still reachable after the configuration has been shed, and a couple things need to be retained only for the sake of post-handshake hooks. Perhaps these can be fixed in time. Change-Id: Idf09642e0518945b81a1e9fcd7331cc9cf7cc2d6 Bug: 123 Reviewed-on: https://boringssl-review.googlesource.com/27644 Commit-Queue: David Benjamin <davidben@google.com> CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org> Reviewed-by: David Benjamin <davidben@google.com>
6 年之前
Move libssl's internals into the bssl namespace. This is horrible, but everything else I tried was worse. The goal with this CL is to take the extern "C" out of ssl/internal.h and move most symbols to namespace bssl, so we can start using C++ helpers and destructors without worry. Complications: - Public API functions must be extern "C" and match their declaration in ssl.h, which is unnamespaced. C++ really does not want you to interleave namespaced and unnamespaced things. One can actually write a namespaced extern "C" function, but this means, from C++'s perspective, the function is namespaced. Trying to namespace the public header would worked but ended up too deep a rabbithole. - Our STACK_OF macros do not work right in namespaces. - The typedefs for our exposed but opaque types are visible in the header files and copied into consuming projects as forward declarations. We ultimately want to give SSL a destructor, but clobbering an unnamespaced ssl_st::~ssl_st seems bad manners. - MSVC complains about ambiguous names if one typedefs SSL to bssl::SSL. This CL opts for: - ssl/*.cc must begin with #define BORINGSSL_INTERNAL_CXX_TYPES. This informs the public headers to create forward declarations which are compatible with our namespaces. - For now, C++-defined type FOO ends up at bssl::FOO with a typedef outside. Later I imagine we'll rename many of them. - Internal functions get namespace bssl, so we stop worrying about stomping the tls1_prf symbol. Exported C functions are stuck as they are. Rather than try anything weird, bite the bullet and reorder files which have a mix of public and private functions. I expect that over time, the public functions will become fairly small as we move logic to more idiomatic C++. Files without any public C functions can just be written normally. - To avoid MSVC troubles, some bssl types are renamed to CPlusPlusStyle in advance of them being made idiomatic C++. Bug: 132 Change-Id: Ic931895e117c38b14ff8d6e5a273e868796c7581 Reviewed-on: https://boringssl-review.googlesource.com/18124 Reviewed-by: David Benjamin <davidben@google.com>
7 年之前
Move libssl's internals into the bssl namespace. This is horrible, but everything else I tried was worse. The goal with this CL is to take the extern "C" out of ssl/internal.h and move most symbols to namespace bssl, so we can start using C++ helpers and destructors without worry. Complications: - Public API functions must be extern "C" and match their declaration in ssl.h, which is unnamespaced. C++ really does not want you to interleave namespaced and unnamespaced things. One can actually write a namespaced extern "C" function, but this means, from C++'s perspective, the function is namespaced. Trying to namespace the public header would worked but ended up too deep a rabbithole. - Our STACK_OF macros do not work right in namespaces. - The typedefs for our exposed but opaque types are visible in the header files and copied into consuming projects as forward declarations. We ultimately want to give SSL a destructor, but clobbering an unnamespaced ssl_st::~ssl_st seems bad manners. - MSVC complains about ambiguous names if one typedefs SSL to bssl::SSL. This CL opts for: - ssl/*.cc must begin with #define BORINGSSL_INTERNAL_CXX_TYPES. This informs the public headers to create forward declarations which are compatible with our namespaces. - For now, C++-defined type FOO ends up at bssl::FOO with a typedef outside. Later I imagine we'll rename many of them. - Internal functions get namespace bssl, so we stop worrying about stomping the tls1_prf symbol. Exported C functions are stuck as they are. Rather than try anything weird, bite the bullet and reorder files which have a mix of public and private functions. I expect that over time, the public functions will become fairly small as we move logic to more idiomatic C++. Files without any public C functions can just be written normally. - To avoid MSVC troubles, some bssl types are renamed to CPlusPlusStyle in advance of them being made idiomatic C++. Bug: 132 Change-Id: Ic931895e117c38b14ff8d6e5a273e868796c7581 Reviewed-on: https://boringssl-review.googlesource.com/18124 Reviewed-by: David Benjamin <davidben@google.com>
7 年之前
Move libssl's internals into the bssl namespace. This is horrible, but everything else I tried was worse. The goal with this CL is to take the extern "C" out of ssl/internal.h and move most symbols to namespace bssl, so we can start using C++ helpers and destructors without worry. Complications: - Public API functions must be extern "C" and match their declaration in ssl.h, which is unnamespaced. C++ really does not want you to interleave namespaced and unnamespaced things. One can actually write a namespaced extern "C" function, but this means, from C++'s perspective, the function is namespaced. Trying to namespace the public header would worked but ended up too deep a rabbithole. - Our STACK_OF macros do not work right in namespaces. - The typedefs for our exposed but opaque types are visible in the header files and copied into consuming projects as forward declarations. We ultimately want to give SSL a destructor, but clobbering an unnamespaced ssl_st::~ssl_st seems bad manners. - MSVC complains about ambiguous names if one typedefs SSL to bssl::SSL. This CL opts for: - ssl/*.cc must begin with #define BORINGSSL_INTERNAL_CXX_TYPES. This informs the public headers to create forward declarations which are compatible with our namespaces. - For now, C++-defined type FOO ends up at bssl::FOO with a typedef outside. Later I imagine we'll rename many of them. - Internal functions get namespace bssl, so we stop worrying about stomping the tls1_prf symbol. Exported C functions are stuck as they are. Rather than try anything weird, bite the bullet and reorder files which have a mix of public and private functions. I expect that over time, the public functions will become fairly small as we move logic to more idiomatic C++. Files without any public C functions can just be written normally. - To avoid MSVC troubles, some bssl types are renamed to CPlusPlusStyle in advance of them being made idiomatic C++. Bug: 132 Change-Id: Ic931895e117c38b14ff8d6e5a273e868796c7581 Reviewed-on: https://boringssl-review.googlesource.com/18124 Reviewed-by: David Benjamin <davidben@google.com>
7 年之前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817
  1. /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  2. * All rights reserved.
  3. *
  4. * This package is an SSL implementation written
  5. * by Eric Young (eay@cryptsoft.com).
  6. * The implementation was written so as to conform with Netscapes SSL.
  7. *
  8. * This library is free for commercial and non-commercial use as long as
  9. * the following conditions are aheared to. The following conditions
  10. * apply to all code found in this distribution, be it the RC4, RSA,
  11. * lhash, DES, etc., code; not just the SSL code. The SSL documentation
  12. * included with this distribution is covered by the same copyright terms
  13. * except that the holder is Tim Hudson (tjh@cryptsoft.com).
  14. *
  15. * Copyright remains Eric Young's, and as such any Copyright notices in
  16. * the code are not to be removed.
  17. * If this package is used in a product, Eric Young should be given attribution
  18. * as the author of the parts of the library used.
  19. * This can be in the form of a textual message at program startup or
  20. * in documentation (online or textual) provided with the package.
  21. *
  22. * Redistribution and use in source and binary forms, with or without
  23. * modification, are permitted provided that the following conditions
  24. * are met:
  25. * 1. Redistributions of source code must retain the copyright
  26. * notice, this list of conditions and the following disclaimer.
  27. * 2. Redistributions in binary form must reproduce the above copyright
  28. * notice, this list of conditions and the following disclaimer in the
  29. * documentation and/or other materials provided with the distribution.
  30. * 3. All advertising materials mentioning features or use of this software
  31. * must display the following acknowledgement:
  32. * "This product includes cryptographic software written by
  33. * Eric Young (eay@cryptsoft.com)"
  34. * The word 'cryptographic' can be left out if the rouines from the library
  35. * being used are not cryptographic related :-).
  36. * 4. If you include any Windows specific code (or a derivative thereof) from
  37. * the apps directory (application code) you must include an acknowledgement:
  38. * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
  39. *
  40. * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
  41. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  42. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  43. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  44. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  45. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  46. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  47. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  48. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  49. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  50. * SUCH DAMAGE.
  51. *
  52. * The licence and distribution terms for any publically available version or
  53. * derivative of this code cannot be changed. i.e. this code cannot simply be
  54. * copied and put under another distribution licence
  55. * [including the GNU Public Licence.] */
  56. #include <openssl/ssl.h>
  57. #include <assert.h>
  58. #include <limits.h>
  59. #include <openssl/ec.h>
  60. #include <openssl/ec_key.h>
  61. #include <openssl/err.h>
  62. #include <openssl/evp.h>
  63. #include <openssl/mem.h>
  64. #include "internal.h"
  65. #include "../crypto/internal.h"
  66. BSSL_NAMESPACE_BEGIN
  67. bool ssl_is_key_type_supported(int key_type) {
  68. return key_type == EVP_PKEY_RSA || key_type == EVP_PKEY_EC ||
  69. key_type == EVP_PKEY_ED25519;
  70. }
  71. static bool ssl_set_pkey(CERT *cert, EVP_PKEY *pkey) {
  72. if (!ssl_is_key_type_supported(pkey->type)) {
  73. OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
  74. return false;
  75. }
  76. if (cert->chain != nullptr &&
  77. sk_CRYPTO_BUFFER_value(cert->chain.get(), 0) != nullptr &&
  78. // Sanity-check that the private key and the certificate match.
  79. !ssl_cert_check_private_key(cert, pkey)) {
  80. return false;
  81. }
  82. cert->privatekey = UpRef(pkey);
  83. return true;
  84. }
  85. typedef struct {
  86. uint16_t sigalg;
  87. int pkey_type;
  88. int curve;
  89. const EVP_MD *(*digest_func)(void);
  90. bool is_rsa_pss;
  91. } SSL_SIGNATURE_ALGORITHM;
  92. static const SSL_SIGNATURE_ALGORITHM kSignatureAlgorithms[] = {
  93. {SSL_SIGN_RSA_PKCS1_MD5_SHA1, EVP_PKEY_RSA, NID_undef, &EVP_md5_sha1,
  94. false},
  95. {SSL_SIGN_RSA_PKCS1_SHA1, EVP_PKEY_RSA, NID_undef, &EVP_sha1, false},
  96. {SSL_SIGN_RSA_PKCS1_SHA256, EVP_PKEY_RSA, NID_undef, &EVP_sha256, false},
  97. {SSL_SIGN_RSA_PKCS1_SHA384, EVP_PKEY_RSA, NID_undef, &EVP_sha384, false},
  98. {SSL_SIGN_RSA_PKCS1_SHA512, EVP_PKEY_RSA, NID_undef, &EVP_sha512, false},
  99. {SSL_SIGN_RSA_PSS_RSAE_SHA256, EVP_PKEY_RSA, NID_undef, &EVP_sha256, true},
  100. {SSL_SIGN_RSA_PSS_RSAE_SHA384, EVP_PKEY_RSA, NID_undef, &EVP_sha384, true},
  101. {SSL_SIGN_RSA_PSS_RSAE_SHA512, EVP_PKEY_RSA, NID_undef, &EVP_sha512, true},
  102. {SSL_SIGN_ECDSA_SHA1, EVP_PKEY_EC, NID_undef, &EVP_sha1, false},
  103. {SSL_SIGN_ECDSA_SECP256R1_SHA256, EVP_PKEY_EC, NID_X9_62_prime256v1,
  104. &EVP_sha256, false},
  105. {SSL_SIGN_ECDSA_SECP384R1_SHA384, EVP_PKEY_EC, NID_secp384r1, &EVP_sha384,
  106. false},
  107. {SSL_SIGN_ECDSA_SECP521R1_SHA512, EVP_PKEY_EC, NID_secp521r1, &EVP_sha512,
  108. false},
  109. {SSL_SIGN_ED25519, EVP_PKEY_ED25519, NID_undef, nullptr, false},
  110. };
  111. static const SSL_SIGNATURE_ALGORITHM *get_signature_algorithm(uint16_t sigalg) {
  112. for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kSignatureAlgorithms); i++) {
  113. if (kSignatureAlgorithms[i].sigalg == sigalg) {
  114. return &kSignatureAlgorithms[i];
  115. }
  116. }
  117. return NULL;
  118. }
  119. bool ssl_has_private_key(const SSL_HANDSHAKE *hs) {
  120. if (hs->config->cert->privatekey != nullptr ||
  121. hs->config->cert->key_method != nullptr ||
  122. ssl_signing_with_dc(hs)) {
  123. return true;
  124. }
  125. return false;
  126. }
  127. static bool pkey_supports_algorithm(const SSL *ssl, EVP_PKEY *pkey,
  128. uint16_t sigalg) {
  129. const SSL_SIGNATURE_ALGORITHM *alg = get_signature_algorithm(sigalg);
  130. if (alg == NULL ||
  131. EVP_PKEY_id(pkey) != alg->pkey_type) {
  132. return false;
  133. }
  134. if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
  135. // RSA keys may only be used with RSA-PSS.
  136. if (alg->pkey_type == EVP_PKEY_RSA && !alg->is_rsa_pss) {
  137. return false;
  138. }
  139. // EC keys have a curve requirement.
  140. if (alg->pkey_type == EVP_PKEY_EC &&
  141. (alg->curve == NID_undef ||
  142. EC_GROUP_get_curve_name(
  143. EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(pkey))) != alg->curve)) {
  144. return false;
  145. }
  146. }
  147. return true;
  148. }
  149. static bool setup_ctx(SSL *ssl, EVP_MD_CTX *ctx, EVP_PKEY *pkey,
  150. uint16_t sigalg, bool is_verify) {
  151. if (!pkey_supports_algorithm(ssl, pkey, sigalg)) {
  152. OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
  153. return false;
  154. }
  155. const SSL_SIGNATURE_ALGORITHM *alg = get_signature_algorithm(sigalg);
  156. const EVP_MD *digest = alg->digest_func != NULL ? alg->digest_func() : NULL;
  157. EVP_PKEY_CTX *pctx;
  158. if (is_verify) {
  159. if (!EVP_DigestVerifyInit(ctx, &pctx, digest, NULL, pkey)) {
  160. return false;
  161. }
  162. } else if (!EVP_DigestSignInit(ctx, &pctx, digest, NULL, pkey)) {
  163. return false;
  164. }
  165. if (alg->is_rsa_pss) {
  166. if (!EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) ||
  167. !EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1 /* salt len = hash len */)) {
  168. return false;
  169. }
  170. }
  171. return true;
  172. }
  173. enum ssl_private_key_result_t ssl_private_key_sign(
  174. SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len, size_t max_out,
  175. uint16_t sigalg, Span<const uint8_t> in) {
  176. SSL *const ssl = hs->ssl;
  177. const SSL_PRIVATE_KEY_METHOD *key_method = hs->config->cert->key_method;
  178. EVP_PKEY *privatekey = hs->config->cert->privatekey.get();
  179. if (ssl_signing_with_dc(hs)) {
  180. key_method = hs->config->cert->dc_key_method;
  181. privatekey = hs->config->cert->dc_privatekey.get();
  182. }
  183. if (key_method != NULL) {
  184. enum ssl_private_key_result_t ret;
  185. if (hs->pending_private_key_op) {
  186. ret = key_method->complete(ssl, out, out_len, max_out);
  187. } else {
  188. ret = key_method->sign(ssl, out, out_len, max_out,
  189. sigalg, in.data(), in.size());
  190. }
  191. if (ret == ssl_private_key_failure) {
  192. OPENSSL_PUT_ERROR(SSL, SSL_R_PRIVATE_KEY_OPERATION_FAILED);
  193. }
  194. hs->pending_private_key_op = ret == ssl_private_key_retry;
  195. return ret;
  196. }
  197. *out_len = max_out;
  198. ScopedEVP_MD_CTX ctx;
  199. if (!setup_ctx(ssl, ctx.get(), privatekey, sigalg, false /* sign */) ||
  200. !EVP_DigestSign(ctx.get(), out, out_len, in.data(), in.size())) {
  201. return ssl_private_key_failure;
  202. }
  203. return ssl_private_key_success;
  204. }
  205. bool ssl_public_key_verify(SSL *ssl, Span<const uint8_t> signature,
  206. uint16_t sigalg, EVP_PKEY *pkey,
  207. Span<const uint8_t> in) {
  208. ScopedEVP_MD_CTX ctx;
  209. return setup_ctx(ssl, ctx.get(), pkey, sigalg, true /* verify */) &&
  210. EVP_DigestVerify(ctx.get(), signature.data(), signature.size(),
  211. in.data(), in.size());
  212. }
  213. enum ssl_private_key_result_t ssl_private_key_decrypt(SSL_HANDSHAKE *hs,
  214. uint8_t *out,
  215. size_t *out_len,
  216. size_t max_out,
  217. Span<const uint8_t> in) {
  218. SSL *const ssl = hs->ssl;
  219. if (hs->config->cert->key_method != NULL) {
  220. enum ssl_private_key_result_t ret;
  221. if (hs->pending_private_key_op) {
  222. ret = hs->config->cert->key_method->complete(ssl, out, out_len, max_out);
  223. } else {
  224. ret = hs->config->cert->key_method->decrypt(ssl, out, out_len, max_out,
  225. in.data(), in.size());
  226. }
  227. if (ret == ssl_private_key_failure) {
  228. OPENSSL_PUT_ERROR(SSL, SSL_R_PRIVATE_KEY_OPERATION_FAILED);
  229. }
  230. hs->pending_private_key_op = ret == ssl_private_key_retry;
  231. return ret;
  232. }
  233. RSA *rsa = EVP_PKEY_get0_RSA(hs->config->cert->privatekey.get());
  234. if (rsa == NULL) {
  235. // Decrypt operations are only supported for RSA keys.
  236. OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
  237. return ssl_private_key_failure;
  238. }
  239. // Decrypt with no padding. PKCS#1 padding will be removed as part of the
  240. // timing-sensitive code by the caller.
  241. if (!RSA_decrypt(rsa, out_len, out, max_out, in.data(), in.size(),
  242. RSA_NO_PADDING)) {
  243. return ssl_private_key_failure;
  244. }
  245. return ssl_private_key_success;
  246. }
  247. bool ssl_private_key_supports_signature_algorithm(SSL_HANDSHAKE *hs,
  248. uint16_t sigalg) {
  249. SSL *const ssl = hs->ssl;
  250. if (!pkey_supports_algorithm(ssl, hs->local_pubkey.get(), sigalg)) {
  251. return false;
  252. }
  253. // Ensure the RSA key is large enough for the hash. RSASSA-PSS requires that
  254. // emLen be at least hLen + sLen + 2. Both hLen and sLen are the size of the
  255. // hash in TLS. Reasonable RSA key sizes are large enough for the largest
  256. // defined RSASSA-PSS algorithm, but 1024-bit RSA is slightly too small for
  257. // SHA-512. 1024-bit RSA is sometimes used for test credentials, so check the
  258. // size so that we can fall back to another algorithm in that case.
  259. const SSL_SIGNATURE_ALGORITHM *alg = get_signature_algorithm(sigalg);
  260. if (alg->is_rsa_pss && (size_t)EVP_PKEY_size(hs->local_pubkey.get()) <
  261. 2 * EVP_MD_size(alg->digest_func()) + 2) {
  262. return false;
  263. }
  264. return true;
  265. }
  266. BSSL_NAMESPACE_END
  267. using namespace bssl;
  268. int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa) {
  269. if (rsa == NULL || ssl->config == NULL) {
  270. OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
  271. return 0;
  272. }
  273. UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
  274. if (!pkey ||
  275. !EVP_PKEY_set1_RSA(pkey.get(), rsa)) {
  276. OPENSSL_PUT_ERROR(SSL, ERR_R_EVP_LIB);
  277. return 0;
  278. }
  279. return ssl_set_pkey(ssl->config->cert.get(), pkey.get());
  280. }
  281. int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const uint8_t *der, size_t der_len) {
  282. UniquePtr<RSA> rsa(RSA_private_key_from_bytes(der, der_len));
  283. if (!rsa) {
  284. OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
  285. return 0;
  286. }
  287. return SSL_use_RSAPrivateKey(ssl, rsa.get());
  288. }
  289. int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) {
  290. if (pkey == NULL || ssl->config == NULL) {
  291. OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
  292. return 0;
  293. }
  294. return ssl_set_pkey(ssl->config->cert.get(), pkey);
  295. }
  296. int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const uint8_t *der,
  297. size_t der_len) {
  298. if (der_len > LONG_MAX) {
  299. OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
  300. return 0;
  301. }
  302. const uint8_t *p = der;
  303. UniquePtr<EVP_PKEY> pkey(d2i_PrivateKey(type, NULL, &p, (long)der_len));
  304. if (!pkey || p != der + der_len) {
  305. OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
  306. return 0;
  307. }
  308. return SSL_use_PrivateKey(ssl, pkey.get());
  309. }
  310. int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa) {
  311. if (rsa == NULL) {
  312. OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
  313. return 0;
  314. }
  315. UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
  316. if (!pkey ||
  317. !EVP_PKEY_set1_RSA(pkey.get(), rsa)) {
  318. OPENSSL_PUT_ERROR(SSL, ERR_R_EVP_LIB);
  319. return 0;
  320. }
  321. return ssl_set_pkey(ctx->cert.get(), pkey.get());
  322. }
  323. int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const uint8_t *der,
  324. size_t der_len) {
  325. UniquePtr<RSA> rsa(RSA_private_key_from_bytes(der, der_len));
  326. if (!rsa) {
  327. OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
  328. return 0;
  329. }
  330. return SSL_CTX_use_RSAPrivateKey(ctx, rsa.get());
  331. }
  332. int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) {
  333. if (pkey == NULL) {
  334. OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
  335. return 0;
  336. }
  337. return ssl_set_pkey(ctx->cert.get(), pkey);
  338. }
  339. int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const uint8_t *der,
  340. size_t der_len) {
  341. if (der_len > LONG_MAX) {
  342. OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
  343. return 0;
  344. }
  345. const uint8_t *p = der;
  346. UniquePtr<EVP_PKEY> pkey(d2i_PrivateKey(type, NULL, &p, (long)der_len));
  347. if (!pkey || p != der + der_len) {
  348. OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
  349. return 0;
  350. }
  351. return SSL_CTX_use_PrivateKey(ctx, pkey.get());
  352. }
  353. void SSL_set_private_key_method(SSL *ssl,
  354. const SSL_PRIVATE_KEY_METHOD *key_method) {
  355. if (!ssl->config) {
  356. return;
  357. }
  358. ssl->config->cert->key_method = key_method;
  359. }
  360. void SSL_CTX_set_private_key_method(SSL_CTX *ctx,
  361. const SSL_PRIVATE_KEY_METHOD *key_method) {
  362. ctx->cert->key_method = key_method;
  363. }
  364. static constexpr size_t kMaxSignatureAlgorithmNameLen = 23;
  365. // This was "constexpr" rather than "const", but that triggered a bug in MSVC
  366. // where it didn't pad the strings to the correct length.
  367. static const struct {
  368. uint16_t signature_algorithm;
  369. const char name[kMaxSignatureAlgorithmNameLen];
  370. } kSignatureAlgorithmNames[] = {
  371. {SSL_SIGN_RSA_PKCS1_MD5_SHA1, "rsa_pkcs1_md5_sha1"},
  372. {SSL_SIGN_RSA_PKCS1_SHA1, "rsa_pkcs1_sha1"},
  373. {SSL_SIGN_RSA_PKCS1_SHA256, "rsa_pkcs1_sha256"},
  374. {SSL_SIGN_RSA_PKCS1_SHA384, "rsa_pkcs1_sha384"},
  375. {SSL_SIGN_RSA_PKCS1_SHA512, "rsa_pkcs1_sha512"},
  376. {SSL_SIGN_ECDSA_SHA1, "ecdsa_sha1"},
  377. {SSL_SIGN_ECDSA_SECP256R1_SHA256, "ecdsa_secp256r1_sha256"},
  378. {SSL_SIGN_ECDSA_SECP384R1_SHA384, "ecdsa_secp384r1_sha384"},
  379. {SSL_SIGN_ECDSA_SECP521R1_SHA512, "ecdsa_secp521r1_sha512"},
  380. {SSL_SIGN_RSA_PSS_RSAE_SHA256, "rsa_pss_rsae_sha256"},
  381. {SSL_SIGN_RSA_PSS_RSAE_SHA384, "rsa_pss_rsae_sha384"},
  382. {SSL_SIGN_RSA_PSS_RSAE_SHA512, "rsa_pss_rsae_sha512"},
  383. {SSL_SIGN_ED25519, "ed25519"},
  384. };
  385. const char *SSL_get_signature_algorithm_name(uint16_t sigalg,
  386. int include_curve) {
  387. if (!include_curve) {
  388. switch (sigalg) {
  389. case SSL_SIGN_ECDSA_SECP256R1_SHA256:
  390. return "ecdsa_sha256";
  391. case SSL_SIGN_ECDSA_SECP384R1_SHA384:
  392. return "ecdsa_sha384";
  393. case SSL_SIGN_ECDSA_SECP521R1_SHA512:
  394. return "ecdsa_sha512";
  395. }
  396. }
  397. for (const auto &candidate : kSignatureAlgorithmNames) {
  398. if (candidate.signature_algorithm == sigalg) {
  399. return candidate.name;
  400. }
  401. }
  402. return NULL;
  403. }
  404. int SSL_get_signature_algorithm_key_type(uint16_t sigalg) {
  405. const SSL_SIGNATURE_ALGORITHM *alg = get_signature_algorithm(sigalg);
  406. return alg != nullptr ? alg->pkey_type : EVP_PKEY_NONE;
  407. }
  408. const EVP_MD *SSL_get_signature_algorithm_digest(uint16_t sigalg) {
  409. const SSL_SIGNATURE_ALGORITHM *alg = get_signature_algorithm(sigalg);
  410. if (alg == nullptr || alg->digest_func == nullptr) {
  411. return nullptr;
  412. }
  413. return alg->digest_func();
  414. }
  415. int SSL_is_signature_algorithm_rsa_pss(uint16_t sigalg) {
  416. const SSL_SIGNATURE_ALGORITHM *alg = get_signature_algorithm(sigalg);
  417. return alg != nullptr && alg->is_rsa_pss;
  418. }
  419. int SSL_CTX_set_signing_algorithm_prefs(SSL_CTX *ctx, const uint16_t *prefs,
  420. size_t num_prefs) {
  421. return ctx->cert->sigalgs.CopyFrom(MakeConstSpan(prefs, num_prefs));
  422. }
  423. int SSL_set_signing_algorithm_prefs(SSL *ssl, const uint16_t *prefs,
  424. size_t num_prefs) {
  425. if (!ssl->config) {
  426. return 0;
  427. }
  428. return ssl->config->cert->sigalgs.CopyFrom(MakeConstSpan(prefs, num_prefs));
  429. }
  430. static constexpr struct {
  431. int pkey_type;
  432. int hash_nid;
  433. uint16_t signature_algorithm;
  434. } kSignatureAlgorithmsMapping[] = {
  435. {EVP_PKEY_RSA, NID_sha1, SSL_SIGN_RSA_PKCS1_SHA1},
  436. {EVP_PKEY_RSA, NID_sha256, SSL_SIGN_RSA_PKCS1_SHA256},
  437. {EVP_PKEY_RSA, NID_sha384, SSL_SIGN_RSA_PKCS1_SHA384},
  438. {EVP_PKEY_RSA, NID_sha512, SSL_SIGN_RSA_PKCS1_SHA512},
  439. {EVP_PKEY_RSA_PSS, NID_sha256, SSL_SIGN_RSA_PSS_RSAE_SHA256},
  440. {EVP_PKEY_RSA_PSS, NID_sha384, SSL_SIGN_RSA_PSS_RSAE_SHA384},
  441. {EVP_PKEY_RSA_PSS, NID_sha512, SSL_SIGN_RSA_PSS_RSAE_SHA512},
  442. {EVP_PKEY_EC, NID_sha1, SSL_SIGN_ECDSA_SHA1},
  443. {EVP_PKEY_EC, NID_sha256, SSL_SIGN_ECDSA_SECP256R1_SHA256},
  444. {EVP_PKEY_EC, NID_sha384, SSL_SIGN_ECDSA_SECP384R1_SHA384},
  445. {EVP_PKEY_EC, NID_sha512, SSL_SIGN_ECDSA_SECP521R1_SHA512},
  446. {EVP_PKEY_ED25519, NID_undef, SSL_SIGN_ED25519},
  447. };
  448. static bool parse_sigalg_pairs(Array<uint16_t> *out, const int *values,
  449. size_t num_values) {
  450. if ((num_values & 1) == 1) {
  451. return false;
  452. }
  453. const size_t num_pairs = num_values / 2;
  454. if (!out->Init(num_pairs)) {
  455. return false;
  456. }
  457. for (size_t i = 0; i < num_values; i += 2) {
  458. const int hash_nid = values[i];
  459. const int pkey_type = values[i+1];
  460. bool found = false;
  461. for (const auto &candidate : kSignatureAlgorithmsMapping) {
  462. if (candidate.pkey_type == pkey_type && candidate.hash_nid == hash_nid) {
  463. (*out)[i / 2] = candidate.signature_algorithm;
  464. found = true;
  465. break;
  466. }
  467. }
  468. if (!found) {
  469. OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SIGNATURE_ALGORITHM);
  470. ERR_add_error_dataf("unknown hash:%d pkey:%d", hash_nid, pkey_type);
  471. return false;
  472. }
  473. }
  474. return true;
  475. }
  476. static int compare_uint16_t(const void *p1, const void *p2) {
  477. uint16_t u1 = *((const uint16_t *)p1);
  478. uint16_t u2 = *((const uint16_t *)p2);
  479. if (u1 < u2) {
  480. return -1;
  481. } else if (u1 > u2) {
  482. return 1;
  483. } else {
  484. return 0;
  485. }
  486. }
  487. static bool sigalgs_unique(Span<const uint16_t> in_sigalgs) {
  488. if (in_sigalgs.size() < 2) {
  489. return true;
  490. }
  491. Array<uint16_t> sigalgs;
  492. if (!sigalgs.CopyFrom(in_sigalgs)) {
  493. return false;
  494. }
  495. qsort(sigalgs.data(), sigalgs.size(), sizeof(uint16_t), compare_uint16_t);
  496. for (size_t i = 1; i < sigalgs.size(); i++) {
  497. if (sigalgs[i - 1] == sigalgs[i]) {
  498. OPENSSL_PUT_ERROR(SSL, SSL_R_DUPLICATE_SIGNATURE_ALGORITHM);
  499. return false;
  500. }
  501. }
  502. return true;
  503. }
  504. int SSL_CTX_set1_sigalgs(SSL_CTX *ctx, const int *values, size_t num_values) {
  505. Array<uint16_t> sigalgs;
  506. if (!parse_sigalg_pairs(&sigalgs, values, num_values) ||
  507. !sigalgs_unique(sigalgs)) {
  508. return 0;
  509. }
  510. if (!SSL_CTX_set_signing_algorithm_prefs(ctx, sigalgs.data(),
  511. sigalgs.size()) ||
  512. !ctx->verify_sigalgs.CopyFrom(sigalgs)) {
  513. return 0;
  514. }
  515. return 1;
  516. }
  517. int SSL_set1_sigalgs(SSL *ssl, const int *values, size_t num_values) {
  518. if (!ssl->config) {
  519. OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  520. return 0;
  521. }
  522. Array<uint16_t> sigalgs;
  523. if (!parse_sigalg_pairs(&sigalgs, values, num_values) ||
  524. !sigalgs_unique(sigalgs)) {
  525. return 0;
  526. }
  527. if (!SSL_set_signing_algorithm_prefs(ssl, sigalgs.data(), sigalgs.size()) ||
  528. !ssl->config->verify_sigalgs.CopyFrom(sigalgs)) {
  529. return 0;
  530. }
  531. return 1;
  532. }
  533. static bool parse_sigalgs_list(Array<uint16_t> *out, const char *str) {
  534. // str looks like "RSA+SHA1:ECDSA+SHA256:ecdsa_secp256r1_sha256".
  535. // Count colons to give the number of output elements from any successful
  536. // parse.
  537. size_t num_elements = 1;
  538. size_t len = 0;
  539. for (const char *p = str; *p; p++) {
  540. len++;
  541. if (*p == ':') {
  542. num_elements++;
  543. }
  544. }
  545. if (!out->Init(num_elements)) {
  546. return false;
  547. }
  548. size_t out_i = 0;
  549. enum {
  550. pkey_or_name,
  551. hash_name,
  552. } state = pkey_or_name;
  553. char buf[kMaxSignatureAlgorithmNameLen];
  554. // buf_used is always < sizeof(buf). I.e. it's always safe to write
  555. // buf[buf_used] = 0.
  556. size_t buf_used = 0;
  557. int pkey_type = 0, hash_nid = 0;
  558. // Note that the loop runs to len+1, i.e. it'll process the terminating NUL.
  559. for (size_t offset = 0; offset < len+1; offset++) {
  560. const char c = str[offset];
  561. switch (c) {
  562. case '+':
  563. if (state == hash_name) {
  564. OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SIGNATURE_ALGORITHM);
  565. ERR_add_error_dataf("+ found in hash name at offset %zu", offset);
  566. return false;
  567. }
  568. if (buf_used == 0) {
  569. OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SIGNATURE_ALGORITHM);
  570. ERR_add_error_dataf("empty public key type at offset %zu", offset);
  571. return false;
  572. }
  573. buf[buf_used] = 0;
  574. if (strcmp(buf, "RSA") == 0) {
  575. pkey_type = EVP_PKEY_RSA;
  576. } else if (strcmp(buf, "RSA-PSS") == 0 ||
  577. strcmp(buf, "PSS") == 0) {
  578. pkey_type = EVP_PKEY_RSA_PSS;
  579. } else if (strcmp(buf, "ECDSA") == 0) {
  580. pkey_type = EVP_PKEY_EC;
  581. } else {
  582. OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SIGNATURE_ALGORITHM);
  583. ERR_add_error_dataf("unknown public key type '%s'", buf);
  584. return false;
  585. }
  586. state = hash_name;
  587. buf_used = 0;
  588. break;
  589. case ':':
  590. OPENSSL_FALLTHROUGH;
  591. case 0:
  592. if (buf_used == 0) {
  593. OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SIGNATURE_ALGORITHM);
  594. ERR_add_error_dataf("empty element at offset %zu", offset);
  595. return false;
  596. }
  597. buf[buf_used] = 0;
  598. if (state == pkey_or_name) {
  599. // No '+' was seen thus this is a TLS 1.3-style name.
  600. bool found = false;
  601. for (const auto &candidate : kSignatureAlgorithmNames) {
  602. if (strcmp(candidate.name, buf) == 0) {
  603. assert(out_i < num_elements);
  604. (*out)[out_i++] = candidate.signature_algorithm;
  605. found = true;
  606. break;
  607. }
  608. }
  609. if (!found) {
  610. OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SIGNATURE_ALGORITHM);
  611. ERR_add_error_dataf("unknown signature algorithm '%s'", buf);
  612. return false;
  613. }
  614. } else {
  615. if (strcmp(buf, "SHA1") == 0) {
  616. hash_nid = NID_sha1;
  617. } else if (strcmp(buf, "SHA256") == 0) {
  618. hash_nid = NID_sha256;
  619. } else if (strcmp(buf, "SHA384") == 0) {
  620. hash_nid = NID_sha384;
  621. } else if (strcmp(buf, "SHA512") == 0) {
  622. hash_nid = NID_sha512;
  623. } else {
  624. OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SIGNATURE_ALGORITHM);
  625. ERR_add_error_dataf("unknown hash function '%s'", buf);
  626. return false;
  627. }
  628. bool found = false;
  629. for (const auto &candidate : kSignatureAlgorithmsMapping) {
  630. if (candidate.pkey_type == pkey_type &&
  631. candidate.hash_nid == hash_nid) {
  632. assert(out_i < num_elements);
  633. (*out)[out_i++] = candidate.signature_algorithm;
  634. found = true;
  635. break;
  636. }
  637. }
  638. if (!found) {
  639. OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SIGNATURE_ALGORITHM);
  640. ERR_add_error_dataf("unknown pkey:%d hash:%s", pkey_type, buf);
  641. return false;
  642. }
  643. }
  644. state = pkey_or_name;
  645. buf_used = 0;
  646. break;
  647. default:
  648. if (buf_used == sizeof(buf) - 1) {
  649. OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SIGNATURE_ALGORITHM);
  650. ERR_add_error_dataf("substring too long at offset %zu", offset);
  651. return false;
  652. }
  653. if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') ||
  654. (c >= 'A' && c <= 'Z') || c == '-' || c == '_') {
  655. buf[buf_used++] = c;
  656. } else {
  657. OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SIGNATURE_ALGORITHM);
  658. ERR_add_error_dataf("invalid character 0x%02x at offest %zu", c,
  659. offset);
  660. return false;
  661. }
  662. }
  663. }
  664. assert(out_i == out->size());
  665. return true;
  666. }
  667. int SSL_CTX_set1_sigalgs_list(SSL_CTX *ctx, const char *str) {
  668. Array<uint16_t> sigalgs;
  669. if (!parse_sigalgs_list(&sigalgs, str) ||
  670. !sigalgs_unique(sigalgs)) {
  671. return 0;
  672. }
  673. if (!SSL_CTX_set_signing_algorithm_prefs(ctx, sigalgs.data(),
  674. sigalgs.size()) ||
  675. !ctx->verify_sigalgs.CopyFrom(sigalgs)) {
  676. return 0;
  677. }
  678. return 1;
  679. }
  680. int SSL_set1_sigalgs_list(SSL *ssl, const char *str) {
  681. if (!ssl->config) {
  682. OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  683. return 0;
  684. }
  685. Array<uint16_t> sigalgs;
  686. if (!parse_sigalgs_list(&sigalgs, str) ||
  687. !sigalgs_unique(sigalgs)) {
  688. return 0;
  689. }
  690. if (!SSL_set_signing_algorithm_prefs(ssl, sigalgs.data(), sigalgs.size()) ||
  691. !ssl->config->verify_sigalgs.CopyFrom(sigalgs)) {
  692. return 0;
  693. }
  694. return 1;
  695. }
  696. int SSL_CTX_set_verify_algorithm_prefs(SSL_CTX *ctx, const uint16_t *prefs,
  697. size_t num_prefs) {
  698. return ctx->verify_sigalgs.CopyFrom(MakeConstSpan(prefs, num_prefs));
  699. }