diff options
| author | Bastian Köcher <[email protected]> | 2018-03-11 11:29:45 +0100 |
|---|---|---|
| committer | Bastian Köcher <[email protected]> | 2018-03-11 11:34:36 +0100 |
| commit | d7a7c379a85965fa2a49849d9e424c2c11035d89 (patch) | |
| tree | 9228a3b494a30210dad0fdd12348a83e0fe07fa2 | |
| parent | Moves store context init into its own function (diff) | |
| download | rust-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.
| -rw-r--r-- | openssl/src/x509/mod.rs | 32 | ||||
| -rw-r--r-- | openssl/src/x509/tests.rs | 10 |
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()); } |