Skip to content

Commit

Permalink
Fix documented lifetime on connection getters (#194)
Browse files Browse the repository at this point in the history
And change rustls_connection_get_peer_certificate to take a `*const rustls_connection`.

Fixes #178.
  • Loading branch information
jsha authored Nov 9, 2021
1 parent f4e370b commit 86dae8b
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 8 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ If you are importing this as a library from other Rust code, you should import `
rustls_server_config_builder_set_client_verifier and
rustls_server_config_builder_set_client_verifier_optional, which are setters
rather than constructors.
- The documented lifetime for pointers returned by rustls_connection_get_peer_certificate
and rustls_connection_get_alpn_protocol has been fixed - the pointers those
functions provide are valid until the next mutating function call on that
connection.

## Removed

Expand Down
23 changes: 17 additions & 6 deletions src/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -307,15 +307,18 @@ impl rustls_connection {
/// Index 0 is the end entity certificate. Higher indexes are certificates
/// in the chain. Requesting an index higher than what is available returns
/// NULL.
/// The returned pointer lives as long as the rustls_connection does.
/// The returned pointer is valid until the next mutating function call
/// affecting the connection. A mutating function call is one where the
/// first argument has type `struct rustls_connection *` (as opposed to
/// `const struct rustls_connection *`).
/// <https://docs.rs/rustls/0.20.0/rustls/enum.Connection.html#method.peer_certificates>
#[no_mangle]
pub extern "C" fn rustls_connection_get_peer_certificate(
conn: *mut rustls_connection,
conn: *const rustls_connection,
i: size_t,
) -> *const rustls_certificate {
ffi_panic_boundary! {
let conn: &mut Connection = try_mut_from_ptr!(conn);
let conn: &Connection = try_ref_from_ptr!(conn);
match conn.peer_certificates().and_then(|c| c.get(i)) {
Some(cert) => cert as *const Certificate as *const _,
None => null()
Expand All @@ -328,6 +331,10 @@ impl rustls_connection {
/// The borrow lives as long as the connection.
/// If the connection is still handshaking, or no ALPN protocol was negotiated,
/// stores NULL and 0 in the output parameters.
/// The provided pointer is valid until the next mutating function call
/// affecting the connection. A mutating function call is one where the
/// first argument has type `struct rustls_connection *` (as opposed to
/// `const struct rustls_connection *`).
/// <https://www.iana.org/assignments/tls-parameters/>
/// <https://docs.rs/rustls/0.20.0/rustls/enum.Connection.html#method.alpn_protocol>
#[no_mangle]
Expand Down Expand Up @@ -385,9 +392,13 @@ impl rustls_connection {
Some(cs) => cs,
None => return null(),
};
for &cs in ALL_CIPHER_SUITES {
if negotiated == cs {
return &cs as *const SupportedCipherSuite as *const _;
for cs in ALL_CIPHER_SUITES {
// This type annotation is here to enforce the lifetime stated
// in the doccomment - that the returned pointer lives as long
// as the program.
let cs: &'static SupportedCipherSuite = cs;
if negotiated == *cs {
return cs as *const SupportedCipherSuite as *const _;
}
}
null()
Expand Down
11 changes: 9 additions & 2 deletions src/rustls.h
Original file line number Diff line number Diff line change
Expand Up @@ -904,10 +904,13 @@ void rustls_connection_send_close_notify(struct rustls_connection *conn);
* Index 0 is the end entity certificate. Higher indexes are certificates
* in the chain. Requesting an index higher than what is available returns
* NULL.
* The returned pointer lives as long as the rustls_connection does.
* The returned pointer is valid until the next mutating function call
* affecting the connection. A mutating function call is one where the
* first argument has type `struct rustls_connection *` (as opposed to
* `const struct rustls_connection *`).
* <https://docs.rs/rustls/0.20.0/rustls/enum.Connection.html#method.peer_certificates>
*/
const struct rustls_certificate *rustls_connection_get_peer_certificate(struct rustls_connection *conn,
const struct rustls_certificate *rustls_connection_get_peer_certificate(const struct rustls_connection *conn,
size_t i);

/**
Expand All @@ -916,6 +919,10 @@ const struct rustls_certificate *rustls_connection_get_peer_certificate(struct r
* The borrow lives as long as the connection.
* If the connection is still handshaking, or no ALPN protocol was negotiated,
* stores NULL and 0 in the output parameters.
* The provided pointer is valid until the next mutating function call
* affecting the connection. A mutating function call is one where the
* first argument has type `struct rustls_connection *` (as opposed to
* `const struct rustls_connection *`).
* <https://www.iana.org/assignments/tls-parameters/>
* <https://docs.rs/rustls/0.20.0/rustls/enum.Connection.html#method.alpn_protocol>
*/
Expand Down

0 comments on commit 86dae8b

Please sign in to comment.