Tweak verify_cert's signature
The call can fail either due to an invalid cert or an internal error, and we should distinguish between the two.
This commit is contained in:
parent
00359a1a55
commit
4ee7e0d3a9
|
|
@ -122,22 +122,33 @@ impl X509StoreContextRef {
|
||||||
///
|
///
|
||||||
/// [`X509_STORE_CTX_init`]: https://www.openssl.org/docs/man1.0.2/crypto/X509_STORE_CTX_init.html
|
/// [`X509_STORE_CTX_init`]: https://www.openssl.org/docs/man1.0.2/crypto/X509_STORE_CTX_init.html
|
||||||
/// [`X509_STORE_CTX_cleanup`]: https://www.openssl.org/docs/man1.0.2/crypto/X509_STORE_CTX_cleanup.html
|
/// [`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,
|
pub fn init<F, T>(
|
||||||
cert_chain: &StackRef<X509>, with_context: F) -> Result<T, ErrorStack>
|
&mut self,
|
||||||
|
trust: &store::X509StoreRef,
|
||||||
|
cert: &X509Ref,
|
||||||
|
cert_chain: &StackRef<X509>,
|
||||||
|
with_context: F,
|
||||||
|
) -> Result<T, ErrorStack>
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut X509StoreContextRef) -> Result<T, ErrorStack>
|
F: FnOnce(&mut X509StoreContextRef) -> Result<T, ErrorStack>,
|
||||||
{
|
{
|
||||||
struct Cleanup<'a>(&'a mut X509StoreContextRef);
|
struct Cleanup<'a>(&'a mut X509StoreContextRef);
|
||||||
|
|
||||||
impl<'a> Drop for Cleanup<'a> {
|
impl<'a> Drop for Cleanup<'a> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.0.cleanup();
|
unsafe {
|
||||||
|
ffi::X509_STORE_CTX_cleanup(self.0.as_ptr());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
cvt(ffi::X509_STORE_CTX_init(self.as_ptr(), trust.as_ptr(),
|
cvt(ffi::X509_STORE_CTX_init(
|
||||||
cert.as_ptr(), cert_chain.as_ptr()))?;
|
self.as_ptr(),
|
||||||
|
trust.as_ptr(),
|
||||||
|
cert.as_ptr(),
|
||||||
|
cert_chain.as_ptr(),
|
||||||
|
))?;
|
||||||
|
|
||||||
let cleanup = Cleanup(self);
|
let cleanup = Cleanup(self);
|
||||||
with_context(cleanup.0)
|
with_context(cleanup.0)
|
||||||
|
|
@ -145,30 +156,17 @@ impl X509StoreContextRef {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Verifies the stored certificate.
|
/// Verifies the stored certificate.
|
||||||
/// It is required to call `init` in beforehand, to initialize the required values.
|
///
|
||||||
|
/// Returns `true` if verification succeeds. The `error` method will return the specific
|
||||||
|
/// validation error if the certificate was not valid.
|
||||||
|
///
|
||||||
|
/// This will only work inside of a call to `init`.
|
||||||
///
|
///
|
||||||
/// This corresponds to [`X509_verify_cert`].
|
/// This corresponds to [`X509_verify_cert`].
|
||||||
///
|
///
|
||||||
/// [`X509_verify_cert`]: https://www.openssl.org/docs/man1.0.2/crypto/X509_verify_cert.html
|
/// [`X509_verify_cert`]: https://www.openssl.org/docs/man1.0.2/crypto/X509_verify_cert.html
|
||||||
///
|
pub fn verify_cert(&mut self) -> Result<bool, ErrorStack> {
|
||||||
/// # Result
|
unsafe { cvt_n(ffi::X509_verify_cert(self.as_ptr())).map(|n| n != 0) }
|
||||||
///
|
|
||||||
/// The Result must be `Ok(())` to be a valid certificate, otherwise the cert is not valid.
|
|
||||||
pub fn verify_cert(&mut self) -> Result<(), ErrorStack> {
|
|
||||||
unsafe {
|
|
||||||
cvt(ffi::X509_verify_cert(self.as_ptr())).map(|_| ())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Cleans-up the context.
|
|
||||||
///
|
|
||||||
/// 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
|
|
||||||
fn cleanup(&mut self) {
|
|
||||||
unsafe {
|
|
||||||
ffi::X509_STORE_CTX_cleanup(self.as_ptr());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the error code of the context.
|
/// Set the error code of the context.
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ use nid::Nid;
|
||||||
use pkey::{PKey, Private};
|
use pkey::{PKey, Private};
|
||||||
use rsa::Rsa;
|
use rsa::Rsa;
|
||||||
use stack::Stack;
|
use stack::Stack;
|
||||||
use x509::{X509, X509Name, X509Req, X509VerifyResult, X509StoreContext};
|
use x509::{X509, X509Name, X509Req, X509StoreContext, X509VerifyResult};
|
||||||
use x509::extension::{AuthorityKeyIdentifier, BasicConstraints, ExtendedKeyUsage, KeyUsage,
|
use x509::extension::{AuthorityKeyIdentifier, BasicConstraints, ExtendedKeyUsage, KeyUsage,
|
||||||
SubjectAlternativeName, SubjectKeyIdentifier};
|
SubjectAlternativeName, SubjectKeyIdentifier};
|
||||||
use x509::store::X509StoreBuilder;
|
use x509::store::X509StoreBuilder;
|
||||||
|
|
@ -242,15 +242,11 @@ fn test_stack_from_pem() {
|
||||||
|
|
||||||
assert_eq!(certs.len(), 2);
|
assert_eq!(certs.len(), 2);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
hex::encode(certs[0]
|
hex::encode(certs[0].fingerprint(MessageDigest::sha1()).unwrap()),
|
||||||
.fingerprint(MessageDigest::sha1())
|
|
||||||
.unwrap()),
|
|
||||||
"59172d9313e84459bcff27f967e79e6e9217e584"
|
"59172d9313e84459bcff27f967e79e6e9217e584"
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
hex::encode(certs[1]
|
hex::encode(certs[1].fingerprint(MessageDigest::sha1()).unwrap()),
|
||||||
.fingerprint(MessageDigest::sha1())
|
|
||||||
.unwrap()),
|
|
||||||
"c0cbdf7cdd03c9773e5468e1f6d2da7d5cbb1875"
|
"c0cbdf7cdd03c9773e5468e1f6d2da7d5cbb1875"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -306,8 +302,16 @@ fn test_verify_cert() {
|
||||||
let store = store_bldr.build();
|
let store = store_bldr.build();
|
||||||
|
|
||||||
let mut context = X509StoreContext::new().unwrap();
|
let mut context = X509StoreContext::new().unwrap();
|
||||||
assert!(context.init(&store, &cert, &chain, |c| c.verify_cert()).is_ok());
|
assert!(
|
||||||
assert!(context.init(&store, &cert, &chain, |c| c.verify_cert()).is_ok());
|
context
|
||||||
|
.init(&store, &cert, &chain, |c| c.verify_cert())
|
||||||
|
.unwrap()
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
context
|
||||||
|
.init(&store, &cert, &chain, |c| c.verify_cert())
|
||||||
|
.unwrap()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -323,5 +327,7 @@ fn test_verify_fails() {
|
||||||
let store = store_bldr.build();
|
let store = store_bldr.build();
|
||||||
|
|
||||||
let mut context = X509StoreContext::new().unwrap();
|
let mut context = X509StoreContext::new().unwrap();
|
||||||
assert!(context.init(&store, &cert, &chain, |c| c.verify_cert()).is_err());
|
assert!(!context
|
||||||
|
.init(&store, &cert, &chain, |c| c.verify_cert())
|
||||||
|
.unwrap());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue