Skip to content

Add OCSP nonce functionality #1046

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions openssl-sys/src/ocsp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ cfg_if! {

extern "C" {
pub fn OCSP_request_add0_id(r: *mut OCSP_REQUEST, id: *mut OCSP_CERTID) -> *mut OCSP_ONEREQ;
pub fn OCSP_request_add1_nonce(req: *mut OCSP_REQUEST, val: *mut c_uchar, len: c_int) -> c_int;

pub fn OCSP_resp_find_status(
bs: *mut OCSP_BASICRESP,
Expand All @@ -85,6 +86,9 @@ extern "C" {

pub fn OCSP_response_status(resp: *mut OCSP_RESPONSE) -> c_int;
pub fn OCSP_response_get1_basic(resp: *mut OCSP_RESPONSE) -> *mut OCSP_BASICRESP;
pub fn OCSP_basic_add1_nonce(resp: *mut OCSP_BASICRESP, val: *mut c_uchar, len: c_int)
-> c_int;
pub fn OCSP_copy_nonce(resp: *mut OCSP_BASICRESP, req: *mut OCSP_REQUEST) -> c_int;

pub fn OCSP_response_create(status: c_int, bs: *mut OCSP_BASICRESP) -> *mut OCSP_RESPONSE;

Expand Down Expand Up @@ -115,4 +119,6 @@ extern "C" {
st: *mut X509_STORE,
flags: c_ulong,
) -> c_int;

pub fn OCSP_check_nonce(req: *mut OCSP_REQUEST, bs: *mut OCSP_BASICRESP) -> c_int;
}
74 changes: 74 additions & 0 deletions openssl/src/ocsp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,24 @@ impl OcspBasicResponseRef {
}
}
}

pub fn add_nonce(&mut self, val: Option<&[u8]>) -> Result<(), ErrorStack> {
unsafe {
let (ptr, len) = match val {
Some(slice) => (slice.as_ptr() as *mut _, slice.len() as c_int),
None => (ptr::null_mut(), 0),
};
cvt(ffi::OCSP_basic_add1_nonce(self.as_ptr(), ptr, len))?;
Ok(())
}
}

pub fn copy_nonce(&mut self, req: OcspRequestRef) -> Result<(), ErrorStack> {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should take &OcspRequestRef, not OcspRequestRef.

unsafe {
cvt(ffi::OCSP_copy_nonce(self.as_ptr(), req.as_ptr()))?;
Ok(())
}
}
}

foreign_type_and_impl_send_sync! {
Expand Down Expand Up @@ -336,6 +354,17 @@ impl OcspRequestRef {
Ok(OcspOneReqRef::from_ptr_mut(ptr))
}
}

pub fn add_nonce(&mut self, val: Option<&[u8]>) -> Result<(), ErrorStack> {
unsafe {
let (ptr, len) = match val {
Some(slice) => (slice.as_ptr() as *mut _, slice.len() as c_int),
None => (ptr::null_mut(), 0),
};
cvt(ffi::OCSP_request_add1_nonce(self.as_ptr(), ptr, len))?;
Ok(())
}
}
}

foreign_type_and_impl_send_sync! {
Expand All @@ -345,3 +374,48 @@ foreign_type_and_impl_send_sync! {
pub struct OcspOneReq;
pub struct OcspOneReqRef;
}

pub fn check_nonce(req: &OcspRequestRef, bs: &OcspBasicResponseRef) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::OCSP_check_nonce(req.as_ptr(), bs.as_ptr()))?;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function will need a custom return type, looking at the documentation.

Copy link
Author

@scolby33 scolby33 Jan 27, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've implemented this custom return. I don't love what I've done, especially how for the _ case I had to bury the ErrorStack down in my new enum. Please let me know what you think.

Ok(())
}
}

#[cfg(test)]
mod tests {
use hex::FromHex;

use super::*;
use hash::MessageDigest;
use x509::X509;

#[test]
fn test_create_ocsp_request() {
let subject = include_bytes!("../test/cert.pem");
let subject = X509::from_pem(subject).unwrap();
let issuer = include_bytes!("../test/root-ca.pem");
let issuer = X509::from_pem(issuer).unwrap();

let req_der = include_bytes!("../test/ocsp-req.der");
let req_nonce_der = include_bytes!("../test/ocsp-req-nonce.der");

let cert_id = OcspCertId::from_cert(
MessageDigest::sha1(),
&subject,
&issuer
).unwrap();

let mut req = OcspRequest::new().unwrap();
req.add_id(cert_id).unwrap();

assert_eq!(&*req.to_der().unwrap(), req_der.as_ref());


let nonce = Vec::from_hex("4413A2C5019A7C3A384CDD8AB30E3816").unwrap();
req.add_nonce(Some(&nonce)).unwrap();

assert_eq!(&*req.to_der().unwrap(), req_nonce_der.as_ref());
}

}
Binary file added openssl/test/ocsp-req-nonce.der
Binary file not shown.
Binary file added openssl/test/ocsp-req.der
Binary file not shown.