aboutsummaryrefslogtreecommitdiff
path: root/openssl/src
diff options
context:
space:
mode:
authorBastian Köcher <[email protected]>2018-03-11 11:29:45 +0100
committerBastian Köcher <[email protected]>2018-03-11 11:34:36 +0100
commitd7a7c379a85965fa2a49849d9e424c2c11035d89 (patch)
tree9228a3b494a30210dad0fdd12348a83e0fe07fa2 /openssl/src
parentMoves store context init into its own function (diff)
downloadrust-openssl-d7a7c379a85965fa2a49849d9e424c2c11035d89.tar.xz
rust-openssl-d7a7c379a85965fa2a49849d9e424c2c11035d89.zip
Changes `init` to take a closure which is called with the initialized context
After calling the closure, we automatically cleanup the context. This is required, because otherwise we could have dangling references in the context.
Diffstat (limited to 'openssl/src')
-rw-r--r--openssl/src/x509/mod.rs32
-rw-r--r--openssl/src/x509/tests.rs10
2 files changed, 28 insertions, 14 deletions
diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs
index 55e5c75d..146a77b0 100644
--- a/openssl/src/x509/mod.rs
+++ b/openssl/src/x509/mod.rs
@@ -108,21 +108,39 @@ impl X509StoreContextRef {
}
/// Initializes this context with the given certificate, certificates chain and certificate
- /// store.
- /// For successive calls to this function, it is required to call `cleanup` in beforehand.
+ /// store. After initializing the context, the `with_context` closure is called with the prepared
+ /// context. As long as the closure is running, the context stays initialized and can be used
+ /// to e.g. verify a certificate. The context will be cleaned up, after the closure finished.
///
/// * `trust` - The certificate store with the trusted certificates.
/// * `cert` - The certificate that should be verified.
/// * `cert_chain` - The certificates chain.
+ /// * `with_context` - The closure that is called with the initialized context.
///
- /// This corresponds to [`X509_STORE_CTX_init`].
+ /// This corresponds to [`X509_STORE_CTX_init`] before calling `with_context` and to
+ /// [`X509_STORE_CTX_cleanup`] after calling `with_context`.
///
/// [`X509_STORE_CTX_init`]: https://www.openssl.org/docs/man1.0.2/crypto/X509_STORE_CTX_init.html
- pub fn init(&mut self, trust: &store::X509StoreRef, cert: &X509Ref,
- cert_chain: &StackRef<X509>) -> Result<(), ErrorStack> {
+ /// [`X509_STORE_CTX_cleanup`]: https://www.openssl.org/docs/man1.0.2/crypto/X509_STORE_CTX_cleanup.html
+ pub fn init<F, T>(&mut self, trust: &store::X509StoreRef, cert: &X509Ref,
+ cert_chain: &StackRef<X509>, with_context: F) -> Result<T, ErrorStack>
+ where
+ F: FnOnce(&mut X509StoreContextRef) -> Result<T, ErrorStack>
+ {
+ struct Cleanup<'a>(&'a mut X509StoreContextRef);
+
+ impl<'a> Drop for Cleanup<'a> {
+ fn drop(&mut self) {
+ self.0.cleanup();
+ }
+ }
+
unsafe {
cvt(ffi::X509_STORE_CTX_init(self.as_ptr(), trust.as_ptr(),
- cert.as_ptr(), cert_chain.as_ptr())).map(|_| ())
+ cert.as_ptr(), cert_chain.as_ptr()))?;
+
+ let cleanup = Cleanup(self);
+ with_context(cleanup.0)
}
}
@@ -147,7 +165,7 @@ impl X509StoreContextRef {
/// This corresponds to [`X509_STORE_CTX_cleanup`].
///
/// [`X509_STORE_CTX_cleanup`]: https://www.openssl.org/docs/man1.0.2/crypto/X509_STORE_CTX_cleanup.html
- pub fn cleanup(&mut self) {
+ fn cleanup(&mut self) {
unsafe {
ffi::X509_STORE_CTX_cleanup(self.as_ptr());
}
diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs
index 9b630d0e..e3c726ae 100644
--- a/openssl/src/x509/tests.rs
+++ b/openssl/src/x509/tests.rs
@@ -306,11 +306,8 @@ fn test_verify_cert() {
let store = store_bldr.build();
let mut context = X509StoreContext::new().unwrap();
- assert!(context.init(&store, &cert, &chain).is_ok());
- assert!(context.verify_cert().is_ok());
- context.cleanup();
- assert!(context.init(&store, &cert, &chain).is_ok());
- assert!(context.verify_cert().is_ok());
+ assert!(context.init(&store, &cert, &chain, |c| c.verify_cert()).is_ok());
+ assert!(context.init(&store, &cert, &chain, |c| c.verify_cert()).is_ok());
}
#[test]
@@ -326,6 +323,5 @@ fn test_verify_fails() {
let store = store_bldr.build();
let mut context = X509StoreContext::new().unwrap();
- assert!(context.init(&store, &cert, &chain).is_ok());
- assert!(context.verify_cert().is_err());
+ assert!(context.init(&store, &cert, &chain, |c| c.verify_cert()).is_err());
}