Get certificate fingerprint

This commit is contained in:
Valerii Hiora 2014-09-17 20:40:40 +03:00
parent efa1a719f5
commit f508b7f067
2 changed files with 28 additions and 2 deletions

View File

@ -1,6 +1,7 @@
#![allow(non_camel_case_types)] #![allow(non_camel_case_types)]
use libc::{c_int, c_void, c_long, c_ulong, c_char}; use libc::{c_int, c_void, c_long, c_ulong, c_char, c_uint};
use crypto::hash::{EVP_MD};
pub type SSL_CTX = c_void; pub type SSL_CTX = c_void;
pub type SSL_METHOD = c_void; pub type SSL_METHOD = c_void;
@ -145,6 +146,7 @@ extern "C" {
pub fn X509_STORE_CTX_get_error(ctx: *mut X509_STORE_CTX) -> c_int; pub fn X509_STORE_CTX_get_error(ctx: *mut X509_STORE_CTX) -> c_int;
pub fn X509_get_subject_name(x: *mut X509) -> *mut X509_NAME; pub fn X509_get_subject_name(x: *mut X509) -> *mut X509_NAME;
pub fn X509_digest(x: *mut X509, digest: *const EVP_MD, buf: *mut c_char, len: *mut c_uint) -> c_int;
pub fn SSL_new(ctx: *mut SSL_CTX) -> *mut SSL; pub fn SSL_new(ctx: *mut SSL_CTX) -> *mut SSL;
pub fn SSL_free(ssl: *mut SSL); pub fn SSL_free(ssl: *mut SSL);

View File

@ -1,4 +1,4 @@
use libc::{c_int, c_void, c_char}; use libc::{c_int, c_uint, c_void, c_char};
use std::io::{IoResult, IoError, EndOfFile, Stream, Reader, Writer}; use std::io::{IoResult, IoError, EndOfFile, Stream, Reader, Writer};
use std::mem; use std::mem;
use std::ptr; use std::ptr;
@ -6,6 +6,7 @@ use std::rt::mutex::NativeMutex;
use std::string; use std::string;
use sync::one::{Once, ONCE_INIT}; use sync::one::{Once, ONCE_INIT};
use crypto::hash::{HashType, evpmd};
use ssl::error::{SslError, SslSessionClosed, StreamError}; use ssl::error::{SslError, SslSessionClosed, StreamError};
pub mod error; pub mod error;
@ -230,6 +231,29 @@ impl<'ctx> X509<'ctx> {
let name = unsafe { ffi::X509_get_subject_name(self.x509) }; let name = unsafe { ffi::X509_get_subject_name(self.x509) };
X509Name { x509: self, name: name } X509Name { x509: self, name: name }
} }
/// Returns certificate fingerprint calculated using provided hash
pub fn fingerprint(&self, hash_type: HashType) -> Option<Vec<u8>> {
let (evp, len) = evpmd(hash_type);
let v: Vec<u8> = Vec::from_elem(len, 0);
let act_len: c_uint = 0;
let res = unsafe {
ffi::X509_digest(self.x509, evp, mem::transmute(v.as_ptr()),
mem::transmute(&act_len))
};
match res {
0 => None,
_ => {
let act_len = act_len as uint;
match len.cmp(&act_len) {
Greater => None,
Equal => Some(v),
Less => fail!("Fingerprint buffer was corrupted!")
}
}
}
}
} }
#[allow(dead_code)] #[allow(dead_code)]