2 use foreign_types
::ForeignTypeRef
;
3 use libc
::{c_int, c_long, c_ulong}
;
8 use asn1
::Asn1GeneralizedTimeRef
;
10 use hash
::MessageDigest
;
12 use x509
::store
::X509StoreRef
;
13 use x509
::{X509, X509Ref}
;
16 pub struct Flag
: c_ulong
{
17 const FLAG_NO_CERTS
= ffi
::OCSP_NOCERTS
;
18 const FLAG_NO_INTERN
= ffi
::OCSP_NOINTERN
;
19 const FLAG_NO_CHAIN
= ffi
::OCSP_NOCHAIN
;
20 const FLAG_NO_VERIFY
= ffi
::OCSP_NOVERIFY
;
21 const FLAG_NO_EXPLICIT
= ffi
::OCSP_NOEXPLICIT
;
22 const FLAG_NO_CA_SIGN
= ffi
::OCSP_NOCASIGN
;
23 const FLAG_NO_DELEGATED
= ffi
::OCSP_NODELEGATED
;
24 const FLAG_NO_CHECKS
= ffi
::OCSP_NOCHECKS
;
25 const FLAG_TRUST_OTHER
= ffi
::OCSP_TRUSTOTHER
;
26 const FLAG_RESPID_KEY
= ffi
::OCSP_RESPID_KEY
;
27 const FLAG_NO_TIME
= ffi
::OCSP_NOTIME
;
31 pub const RESPONSE_STATUS_SUCCESSFUL
: OcspResponseStatus
=
32 OcspResponseStatus(ffi
::OCSP_RESPONSE_STATUS_SUCCESSFUL
);
33 pub const RESPONSE_STATUS_MALFORMED_REQUEST
: OcspResponseStatus
=
34 OcspResponseStatus(ffi
::OCSP_RESPONSE_STATUS_MALFORMEDREQUEST
);
35 pub const RESPONSE_STATUS_INTERNAL_ERROR
: OcspResponseStatus
=
36 OcspResponseStatus(ffi
::OCSP_RESPONSE_STATUS_INTERNALERROR
);
37 pub const RESPONSE_STATUS_TRY_LATER
: OcspResponseStatus
=
38 OcspResponseStatus(ffi
::OCSP_RESPONSE_STATUS_TRYLATER
);
39 pub const RESPONSE_STATUS_SIG_REQUIRED
: OcspResponseStatus
=
40 OcspResponseStatus(ffi
::OCSP_RESPONSE_STATUS_SIGREQUIRED
);
41 pub const RESPONSE_STATUS_UNAUTHORIZED
: OcspResponseStatus
=
42 OcspResponseStatus(ffi
::OCSP_RESPONSE_STATUS_UNAUTHORIZED
);
44 pub const CERT_STATUS_GOOD
: OcspCertStatus
= OcspCertStatus(ffi
::V_OCSP_CERTSTATUS_GOOD
);
45 pub const CERT_STATUS_REVOKED
: OcspCertStatus
= OcspCertStatus(ffi
::V_OCSP_CERTSTATUS_REVOKED
);
46 pub const CERT_STATUS_UNKNOWN
: OcspCertStatus
= OcspCertStatus(ffi
::V_OCSP_CERTSTATUS_UNKNOWN
);
48 pub const REVOKED_STATUS_NO_STATUS
: OcspRevokedStatus
=
49 OcspRevokedStatus(ffi
::OCSP_REVOKED_STATUS_NOSTATUS
);
50 pub const REVOKED_STATUS_UNSPECIFIED
: OcspRevokedStatus
=
51 OcspRevokedStatus(ffi
::OCSP_REVOKED_STATUS_UNSPECIFIED
);
52 pub const REVOKED_STATUS_KEY_COMPROMISE
: OcspRevokedStatus
=
53 OcspRevokedStatus(ffi
::OCSP_REVOKED_STATUS_KEYCOMPROMISE
);
54 pub const REVOKED_STATUS_CA_COMPROMISE
: OcspRevokedStatus
=
55 OcspRevokedStatus(ffi
::OCSP_REVOKED_STATUS_CACOMPROMISE
);
56 pub const REVOKED_STATUS_AFFILIATION_CHANGED
: OcspRevokedStatus
=
57 OcspRevokedStatus(ffi
::OCSP_REVOKED_STATUS_AFFILIATIONCHANGED
);
58 pub const REVOKED_STATUS_SUPERSEDED
: OcspRevokedStatus
=
59 OcspRevokedStatus(ffi
::OCSP_REVOKED_STATUS_SUPERSEDED
);
60 pub const REVOKED_STATUS_CESSATION_OF_OPERATION
: OcspRevokedStatus
=
61 OcspRevokedStatus(ffi
::OCSP_REVOKED_STATUS_CESSATIONOFOPERATION
);
62 pub const REVOKED_STATUS_CERTIFICATE_HOLD
: OcspRevokedStatus
=
63 OcspRevokedStatus(ffi
::OCSP_REVOKED_STATUS_CERTIFICATEHOLD
);
64 pub const REVOKED_STATUS_REMOVE_FROM_CRL
: OcspRevokedStatus
=
65 OcspRevokedStatus(ffi
::OCSP_REVOKED_STATUS_REMOVEFROMCRL
);
67 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
68 pub struct OcspResponseStatus(c_int
);
70 impl OcspResponseStatus
{
71 pub fn from_raw(raw
: c_int
) -> OcspResponseStatus
{
72 OcspResponseStatus(raw
)
75 pub fn as_raw(&self) -> c_int
{
80 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
81 pub struct OcspCertStatus(c_int
);
84 pub fn from_raw(raw
: c_int
) -> OcspCertStatus
{
88 pub fn as_raw(&self) -> c_int
{
93 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
94 pub struct OcspRevokedStatus(c_int
);
96 impl OcspRevokedStatus
{
97 pub fn from_raw(raw
: c_int
) -> OcspRevokedStatus
{
98 OcspRevokedStatus(raw
)
101 pub fn as_raw(&self) -> c_int
{
106 pub struct Status
<'a
> {
107 /// The overall status of the response.
108 pub status
: OcspCertStatus
,
109 /// If `status` is `CERT_STATUS_REVOKED`, the reason for the revocation.
110 pub reason
: OcspRevokedStatus
,
111 /// If `status` is `CERT_STATUS_REVOKED`, the time at which the certificate was revoked.
112 pub revocation_time
: Option
<&'a Asn1GeneralizedTimeRef
>,
113 /// The time that this revocation check was performed.
114 pub this_update
: &'a Asn1GeneralizedTimeRef
,
115 /// The time at which this revocation check expires.
116 pub next_update
: &'a Asn1GeneralizedTimeRef
,
119 impl<'a
> Status
<'a
> {
120 /// Checks validity of the `this_update` and `next_update` fields.
122 /// The `nsec` parameter specifies an amount of slack time that will be used when comparing
123 /// those times with the current time to account for delays and clock skew.
125 /// The `maxsec` parameter limits the maximum age of the `this_update` parameter to prohibit
126 /// very old responses.
127 pub fn check_validity(&self, nsec
: u32, maxsec
: Option
<u32>) -> Result
<(), ErrorStack
> {
129 cvt(ffi
::OCSP_check_validity(
130 self.this_update
.as_ptr(),
131 self.next_update
.as_ptr(),
133 maxsec
.map(|n
| n
as c_long
).unwrap_or(-1),
139 foreign_type_and_impl_send_sync
! {
140 type CType
= ffi
::OCSP_BASICRESP
;
141 fn drop
= ffi
::OCSP_BASICRESP_free
;
143 pub struct OcspBasicResponse
;
144 pub struct OcspBasicResponseRef
;
147 impl OcspBasicResponseRef
{
148 /// Verifies the validity of the response.
150 /// The `certs` parameter contains a set of certificates that will be searched when locating the
151 /// OCSP response signing certificate. Some responders do not include this in the response.
154 certs
: &StackRef
<X509
>,
155 store
: &X509StoreRef
,
157 ) -> Result
<(), ErrorStack
> {
159 cvt(ffi
::OCSP_basic_verify(
168 /// Looks up the status for the specified certificate ID.
169 pub fn find_status
<'a
>(&'a
self, id
: &OcspCertIdRef
) -> Option
<Status
<'a
>> {
171 let mut status
= ffi
::V_OCSP_CERTSTATUS_UNKNOWN
;
172 let mut reason
= ffi
::OCSP_REVOKED_STATUS_NOSTATUS
;
173 let mut revocation_time
= ptr
::null_mut();
174 let mut this_update
= ptr
::null_mut();
175 let mut next_update
= ptr
::null_mut();
177 let r
= ffi
::OCSP_resp_find_status(
182 &mut revocation_time
,
187 let revocation_time
= if revocation_time
.is_null() {
190 Some(Asn1GeneralizedTimeRef
::from_ptr(revocation_time
))
193 status
: OcspCertStatus(status
),
194 reason
: OcspRevokedStatus(status
),
195 revocation_time
: revocation_time
,
196 this_update
: Asn1GeneralizedTimeRef
::from_ptr(this_update
),
197 next_update
: Asn1GeneralizedTimeRef
::from_ptr(next_update
),
206 foreign_type_and_impl_send_sync
! {
207 type CType
= ffi
::OCSP_CERTID
;
208 fn drop
= ffi
::OCSP_CERTID_free
;
210 pub struct OcspCertId
;
211 pub struct OcspCertIdRef
;
215 /// Constructs a certificate ID for certificate `subject`.
217 digest
: MessageDigest
,
220 ) -> Result
<OcspCertId
, ErrorStack
> {
222 cvt_p(ffi
::OCSP_cert_to_id(
231 foreign_type_and_impl_send_sync
! {
232 type CType
= ffi
::OCSP_RESPONSE
;
233 fn drop
= ffi
::OCSP_RESPONSE_free
;
235 pub struct OcspResponse
;
236 pub struct OcspResponseRef
;
240 /// Creates an OCSP response from the status and optional body.
242 /// A body should only be provided if `status` is `RESPONSE_STATUS_SUCCESSFUL`.
244 status
: OcspResponseStatus
,
245 body
: Option
<&OcspBasicResponseRef
>,
246 ) -> Result
<OcspResponse
, ErrorStack
> {
250 cvt_p(ffi
::OCSP_response_create(
252 body
.map(|r
| r
.as_ptr()).unwrap_or(ptr
::null_mut()),
257 from_der
!(OcspResponse
, ffi
::d2i_OCSP_RESPONSE
);
260 impl OcspResponseRef
{
261 to_der
!(ffi
::i2d_OCSP_RESPONSE
);
263 /// Returns the status of the response.
264 pub fn status(&self) -> OcspResponseStatus
{
265 unsafe { OcspResponseStatus(ffi::OCSP_response_status(self.as_ptr())) }
268 /// Returns the basic response.
270 /// This will only succeed if `status()` returns `RESPONSE_STATUS_SUCCESSFUL`.
271 pub fn basic(&self) -> Result
<OcspBasicResponse
, ErrorStack
> {
272 unsafe { cvt_p(ffi::OCSP_response_get1_basic(self.as_ptr())).map(OcspBasicResponse) }
276 foreign_type_and_impl_send_sync
! {
277 type CType
= ffi
::OCSP_REQUEST
;
278 fn drop
= ffi
::OCSP_REQUEST_free
;
280 pub struct OcspRequest
;
281 pub struct OcspRequestRef
;
285 pub fn new() -> Result
<OcspRequest
, ErrorStack
> {
289 cvt_p(ffi
::OCSP_REQUEST_new()).map(OcspRequest
)
293 from_der
!(OcspRequest
, ffi
::d2i_OCSP_REQUEST
);
296 impl OcspRequestRef
{
297 to_der
!(ffi
::i2d_OCSP_REQUEST
);
299 pub fn add_id(&mut self, id
: OcspCertId
) -> Result
<&mut OcspOneReqRef
, ErrorStack
> {
301 let ptr
= cvt_p(ffi
::OCSP_request_add0_id(self.as_ptr(), id
.as_ptr()))?
;
303 Ok(OcspOneReqRef
::from_ptr_mut(ptr
))
308 foreign_type_and_impl_send_sync
! {
309 type CType
= ffi
::OCSP_ONEREQ
;
310 fn drop
= ffi
::OCSP_ONEREQ_free
;
312 pub struct OcspOneReq
;
313 pub struct OcspOneReqRef
;