Skip to content

Commit 86dae8b

Browse files
authored
Fix documented lifetime on connection getters (#194)
And change rustls_connection_get_peer_certificate to take a `*const rustls_connection`. Fixes #178.
1 parent f4e370b commit 86dae8b

File tree

3 files changed

+30
-8
lines changed

3 files changed

+30
-8
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ If you are importing this as a library from other Rust code, you should import `
5555
rustls_server_config_builder_set_client_verifier and
5656
rustls_server_config_builder_set_client_verifier_optional, which are setters
5757
rather than constructors.
58+
- The documented lifetime for pointers returned by rustls_connection_get_peer_certificate
59+
and rustls_connection_get_alpn_protocol has been fixed - the pointers those
60+
functions provide are valid until the next mutating function call on that
61+
connection.
5862

5963
## Removed
6064

src/connection.rs

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -307,15 +307,18 @@ impl rustls_connection {
307307
/// Index 0 is the end entity certificate. Higher indexes are certificates
308308
/// in the chain. Requesting an index higher than what is available returns
309309
/// NULL.
310-
/// The returned pointer lives as long as the rustls_connection does.
310+
/// The returned pointer is valid until the next mutating function call
311+
/// affecting the connection. A mutating function call is one where the
312+
/// first argument has type `struct rustls_connection *` (as opposed to
313+
/// `const struct rustls_connection *`).
311314
/// <https://docs.rs/rustls/0.20.0/rustls/enum.Connection.html#method.peer_certificates>
312315
#[no_mangle]
313316
pub extern "C" fn rustls_connection_get_peer_certificate(
314-
conn: *mut rustls_connection,
317+
conn: *const rustls_connection,
315318
i: size_t,
316319
) -> *const rustls_certificate {
317320
ffi_panic_boundary! {
318-
let conn: &mut Connection = try_mut_from_ptr!(conn);
321+
let conn: &Connection = try_ref_from_ptr!(conn);
319322
match conn.peer_certificates().and_then(|c| c.get(i)) {
320323
Some(cert) => cert as *const Certificate as *const _,
321324
None => null()
@@ -328,6 +331,10 @@ impl rustls_connection {
328331
/// The borrow lives as long as the connection.
329332
/// If the connection is still handshaking, or no ALPN protocol was negotiated,
330333
/// stores NULL and 0 in the output parameters.
334+
/// The provided pointer is valid until the next mutating function call
335+
/// affecting the connection. A mutating function call is one where the
336+
/// first argument has type `struct rustls_connection *` (as opposed to
337+
/// `const struct rustls_connection *`).
331338
/// <https://www.iana.org/assignments/tls-parameters/>
332339
/// <https://docs.rs/rustls/0.20.0/rustls/enum.Connection.html#method.alpn_protocol>
333340
#[no_mangle]
@@ -385,9 +392,13 @@ impl rustls_connection {
385392
Some(cs) => cs,
386393
None => return null(),
387394
};
388-
for &cs in ALL_CIPHER_SUITES {
389-
if negotiated == cs {
390-
return &cs as *const SupportedCipherSuite as *const _;
395+
for cs in ALL_CIPHER_SUITES {
396+
// This type annotation is here to enforce the lifetime stated
397+
// in the doccomment - that the returned pointer lives as long
398+
// as the program.
399+
let cs: &'static SupportedCipherSuite = cs;
400+
if negotiated == *cs {
401+
return cs as *const SupportedCipherSuite as *const _;
391402
}
392403
}
393404
null()

src/rustls.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -904,10 +904,13 @@ void rustls_connection_send_close_notify(struct rustls_connection *conn);
904904
* Index 0 is the end entity certificate. Higher indexes are certificates
905905
* in the chain. Requesting an index higher than what is available returns
906906
* NULL.
907-
* The returned pointer lives as long as the rustls_connection does.
907+
* The returned pointer is valid until the next mutating function call
908+
* affecting the connection. A mutating function call is one where the
909+
* first argument has type `struct rustls_connection *` (as opposed to
910+
* `const struct rustls_connection *`).
908911
* <https://docs.rs/rustls/0.20.0/rustls/enum.Connection.html#method.peer_certificates>
909912
*/
910-
const struct rustls_certificate *rustls_connection_get_peer_certificate(struct rustls_connection *conn,
913+
const struct rustls_certificate *rustls_connection_get_peer_certificate(const struct rustls_connection *conn,
911914
size_t i);
912915

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

0 commit comments

Comments
 (0)