From 679af3e313f7045de4475d21bf782d9e3053c569 Mon Sep 17 00:00:00 2001 From: Emi Tatsuo Date: Wed, 16 Dec 2020 09:24:34 -0500 Subject: [PATCH] Add the Request::fingerprint associated function --- examples/certificates.rs | 12 +++++------- src/types/request.rs | 38 +++++++++++++++++++++++++++++++++++++- 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/examples/certificates.rs b/examples/certificates.rs index 5076f4c..8bd785b 100644 --- a/examples/certificates.rs +++ b/examples/certificates.rs @@ -1,8 +1,6 @@ use anyhow::Result; use log::LevelFilter; -use std::fmt::Write; - use kochab::{Request, Response, Server}; #[tokio::main] @@ -18,12 +16,12 @@ async fn main() -> Result<()> { } async fn handle_request(request: Request) -> Result { - if let Some(fingerprint) = request.certificate() { - let mut message = String::from("You connected with a certificate with a fingerprint of:\n"); - for byte in fingerprint { - write!(&mut message, "{:x}", byte).unwrap(); - } + if let Some(fingerprint) = request.fingerprint() { + let message = format!( + "You connected with a certificate with a fingerprint of:\n{}", + fingerprint, + ); Ok(Response::success_plain(message)) } else { diff --git a/src/types/request.rs b/src/types/request.rs index bb0cd11..0f9825d 100644 --- a/src/types/request.rs +++ b/src/types/request.rs @@ -1,4 +1,7 @@ -use std::ops; +use std::{ + fmt::Write, + ops, +}; #[cfg(feature = "gemini_srv")] use std::convert::TryInto; #[cfg(feature = "scgi_srv")] @@ -247,10 +250,43 @@ impl Request { #[allow(clippy::missing_const_for_fn)] /// Get the fingerprint of the certificate the user is connecting with + /// + /// Please not that this is **not** the full certificate, just it's fingerprint + /// represented as bytes. The full certificate is not currently exposed, since some + /// SCGI servers may not receive it. + /// + /// If you are planning on displaying the certificate to the user, you may want to + /// consider using [`fingerprint()`], which stringifies the output of this method. + /// + /// [`fingerprint()`]: Request::fingerprint pub fn certificate(&self) -> Option<&[u8; 32]> { self.certificate.as_ref() } + /// Get the user's certificate as a [`String`] contain the hex fingerprint + /// + /// This is a convenience method for stringiying the certificate fingerprint from the + /// [`certificate()`] method. If you're using this fingerprint as a key for some user + /// data, you may want to perfer the former method. This method should be used when + /// the fingerprint is being displayed to the user. + /// + /// The returned fingerprint will always be a 64 character string containing lowercase + /// hex digits, such as + /// `5e7097dc25dc62867ee4e0d3214a74b83156e613fdf92ca05e08c79efb14b90e` + /// + /// [`certificate()`]: Request::certificate + pub fn fingerprint(&self) -> Option { + self.certificate.as_ref().map(|c| { + let mut message = String::with_capacity(64); + + for byte in c { + write!(&mut message, "{:x}", byte).unwrap(); + } + + message + }) + } + #[cfg(feature="user_management")] /// Attempt to determine the user who sent this request ///