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 /openssl/src | |
| 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.
Diffstat (limited to 'openssl/src')
| -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()); } |