Merge pull request #811 from apeduru/x509-docs
Add documentation for x509 module
This commit is contained in:
commit
753a7d07b1
|
|
@ -7,6 +7,7 @@ use cvt;
|
|||
use error::ErrorStack;
|
||||
|
||||
bitflags! {
|
||||
/// Flags used to check an `X509` certificate.
|
||||
pub struct X509CheckFlags: c_uint {
|
||||
const ALWAYS_CHECK_SUBJECT = ffi::X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT;
|
||||
const FLAG_NO_WILDCARDS = ffi::X509_CHECK_FLAG_NO_WILDCARDS;
|
||||
|
|
@ -24,17 +25,29 @@ foreign_type_and_impl_send_sync! {
|
|||
type CType = ffi::X509_VERIFY_PARAM;
|
||||
fn drop = ffi::X509_VERIFY_PARAM_free;
|
||||
|
||||
/// Adjust parameters associated with certificate verification.
|
||||
pub struct X509VerifyParam;
|
||||
/// Reference to `X509VerifyParam`.
|
||||
pub struct X509VerifyParamRef;
|
||||
}
|
||||
|
||||
impl X509VerifyParamRef {
|
||||
/// Set the host flags.
|
||||
///
|
||||
/// This corresponds to [`X509_VERIFY_PARAM_set_hostflags`].
|
||||
///
|
||||
/// [`X509_VERIFY_PARAM_set_hostflags`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_VERIFY_PARAM_set_hostflags.html
|
||||
pub fn set_hostflags(&mut self, hostflags: X509CheckFlags) {
|
||||
unsafe {
|
||||
ffi::X509_VERIFY_PARAM_set_hostflags(self.as_ptr(), hostflags.bits);
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the expected DNS hostname.
|
||||
///
|
||||
/// This corresponds to [`X509_VERIFY_PARAM_set1_host`].
|
||||
///
|
||||
/// [`X509_VERIFY_PARAM_set1_host`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_VERIFY_PARAM_set1_host.html
|
||||
pub fn set_host(&mut self, host: &str) -> Result<(), ErrorStack> {
|
||||
unsafe {
|
||||
cvt(ffi::X509_VERIFY_PARAM_set1_host(
|
||||
|
|
@ -45,6 +58,11 @@ impl X509VerifyParamRef {
|
|||
}
|
||||
}
|
||||
|
||||
/// Set the expected IPv4 or IPv6 address.
|
||||
///
|
||||
/// This corresponds to [`X509_VERIFY_PARAM_set1_ip`].
|
||||
///
|
||||
/// [`X509_VERIFY_PARAM_set1_ip`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_VERIFY_PARAM_set1_ip.html
|
||||
pub fn set_ip(&mut self, ip: IpAddr) -> Result<(), ErrorStack> {
|
||||
unsafe {
|
||||
let mut buf = [0; 16];
|
||||
|
|
|
|||
|
|
@ -1,9 +1,32 @@
|
|||
//! Add extensions to an `X509` certificate or certificate request.
|
||||
//!
|
||||
//! The extensions defined for X.509 v3 certificates provide methods for
|
||||
//! associating additional attributes with users or public keys and for
|
||||
//! managing relationships between CAs. The extensions created using this
|
||||
//! module can be used with `X509v3Context` objects.
|
||||
//!
|
||||
//! # Example
|
||||
//!
|
||||
//! ```rust
|
||||
//! extern crate openssl;
|
||||
//!
|
||||
//! use openssl::x509::extension::BasicConstraints;
|
||||
//! use openssl::x509::X509Extension;
|
||||
//!
|
||||
//! fn main() {
|
||||
//! let mut bc = BasicConstraints::new();
|
||||
//! let bc = bc.critical().ca().pathlen(1);
|
||||
//!
|
||||
//! let extension: X509Extension = bc.build().unwrap();
|
||||
//! }
|
||||
//! ```
|
||||
use std::fmt::Write;
|
||||
|
||||
use error::ErrorStack;
|
||||
use nid::Nid;
|
||||
use x509::{X509Extension, X509v3Context};
|
||||
|
||||
/// An extension which indicates whether a certificate is a CA certificate.
|
||||
pub struct BasicConstraints {
|
||||
critical: bool,
|
||||
ca: bool,
|
||||
|
|
@ -11,6 +34,7 @@ pub struct BasicConstraints {
|
|||
}
|
||||
|
||||
impl BasicConstraints {
|
||||
/// Construct a new `BasicConstraints` extension.
|
||||
pub fn new() -> BasicConstraints {
|
||||
BasicConstraints {
|
||||
critical: false,
|
||||
|
|
@ -19,21 +43,26 @@ impl BasicConstraints {
|
|||
}
|
||||
}
|
||||
|
||||
/// Sets the `critical` flag to `true`. The extension will be critical.
|
||||
pub fn critical(&mut self) -> &mut BasicConstraints {
|
||||
self.critical = true;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the `ca` flag to `true`.
|
||||
pub fn ca(&mut self) -> &mut BasicConstraints {
|
||||
self.ca = true;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the pathlen to an optional non-negative value. The pathlen is the
|
||||
/// maximum number of CAs that can appear below this one in a chain.
|
||||
pub fn pathlen(&mut self, pathlen: u32) -> &mut BasicConstraints {
|
||||
self.pathlen = Some(pathlen);
|
||||
self
|
||||
}
|
||||
|
||||
/// Return the `BasicConstraints` extension as an `X509Extension`.
|
||||
pub fn build(&self) -> Result<X509Extension, ErrorStack> {
|
||||
let mut value = String::new();
|
||||
if self.critical {
|
||||
|
|
@ -52,6 +81,7 @@ impl BasicConstraints {
|
|||
}
|
||||
}
|
||||
|
||||
/// An extension consisting of a list of names of the permitted key usages.
|
||||
pub struct KeyUsage {
|
||||
critical: bool,
|
||||
digital_signature: bool,
|
||||
|
|
@ -66,6 +96,7 @@ pub struct KeyUsage {
|
|||
}
|
||||
|
||||
impl KeyUsage {
|
||||
/// Construct a new `KeyUsage` extension.
|
||||
pub fn new() -> KeyUsage {
|
||||
KeyUsage {
|
||||
critical: false,
|
||||
|
|
@ -81,56 +112,67 @@ impl KeyUsage {
|
|||
}
|
||||
}
|
||||
|
||||
/// Sets the `critical` flag to `true`. The extension will be critical.
|
||||
pub fn critical(&mut self) -> &mut KeyUsage {
|
||||
self.critical = true;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the `digitalSignature` flag to `true`.
|
||||
pub fn digital_signature(&mut self) -> &mut KeyUsage {
|
||||
self.digital_signature = true;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the `nonRepudiation` flag to `true`.
|
||||
pub fn non_repudiation(&mut self) -> &mut KeyUsage {
|
||||
self.non_repudiation = true;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the `keyEncipherment` flag to `true`.
|
||||
pub fn key_encipherment(&mut self) -> &mut KeyUsage {
|
||||
self.key_encipherment = true;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the `dataEncipherment` flag to `true`.
|
||||
pub fn data_encipherment(&mut self) -> &mut KeyUsage {
|
||||
self.data_encipherment = true;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the `keyAgreement` flag to `true`.
|
||||
pub fn key_agreement(&mut self) -> &mut KeyUsage {
|
||||
self.key_agreement = true;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the `keyCertSign` flag to `true`.
|
||||
pub fn key_cert_sign(&mut self) -> &mut KeyUsage {
|
||||
self.key_cert_sign = true;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the `cRLSign` flag to `true`.
|
||||
pub fn crl_sign(&mut self) -> &mut KeyUsage {
|
||||
self.crl_sign = true;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the `encipherOnly` flag to `true`.
|
||||
pub fn encipher_only(&mut self) -> &mut KeyUsage {
|
||||
self.encipher_only = true;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the `decipherOnly` flag to `true`.
|
||||
pub fn decipher_only(&mut self) -> &mut KeyUsage {
|
||||
self.decipher_only = true;
|
||||
self
|
||||
}
|
||||
|
||||
/// Return the `KeyUsage` extension as an `X509Extension`.
|
||||
pub fn build(&self) -> Result<X509Extension, ErrorStack> {
|
||||
let mut value = String::new();
|
||||
let mut first = true;
|
||||
|
|
@ -168,6 +210,8 @@ impl KeyUsage {
|
|||
}
|
||||
}
|
||||
|
||||
/// An extension consisting of a list of usages indicating purposes
|
||||
/// for which the certificate public key can be used for.
|
||||
pub struct ExtendedKeyUsage {
|
||||
critical: bool,
|
||||
server_auth: bool,
|
||||
|
|
@ -185,6 +229,7 @@ pub struct ExtendedKeyUsage {
|
|||
}
|
||||
|
||||
impl ExtendedKeyUsage {
|
||||
/// Construct a new `ExtendedKeyUsage` extension.
|
||||
pub fn new() -> ExtendedKeyUsage {
|
||||
ExtendedKeyUsage {
|
||||
critical: false,
|
||||
|
|
@ -203,66 +248,79 @@ impl ExtendedKeyUsage {
|
|||
}
|
||||
}
|
||||
|
||||
/// Sets the `critical` flag to `true`. The extension will be critical.
|
||||
pub fn critical(&mut self) -> &mut ExtendedKeyUsage {
|
||||
self.critical = true;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the `serverAuth` flag to `true`.
|
||||
pub fn server_auth(&mut self) -> &mut ExtendedKeyUsage {
|
||||
self.server_auth = true;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the `clientAuth` flag to `true`.
|
||||
pub fn client_auth(&mut self) -> &mut ExtendedKeyUsage {
|
||||
self.client_auth = true;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the `codeSigning` flag to `true`.
|
||||
pub fn code_signing(&mut self) -> &mut ExtendedKeyUsage {
|
||||
self.code_signing = true;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the `timeStamping` flag to `true`.
|
||||
pub fn time_stamping(&mut self) -> &mut ExtendedKeyUsage {
|
||||
self.time_stamping = true;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the `msCodeInd` flag to `true`.
|
||||
pub fn ms_code_ind(&mut self) -> &mut ExtendedKeyUsage {
|
||||
self.ms_code_ind = true;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the `msCodeCom` flag to `true`.
|
||||
pub fn ms_code_com(&mut self) -> &mut ExtendedKeyUsage {
|
||||
self.ms_code_com = true;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the `msCTLSign` flag to `true`.
|
||||
pub fn ms_ctl_sign(&mut self) -> &mut ExtendedKeyUsage {
|
||||
self.ms_ctl_sign = true;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the `msSGC` flag to `true`.
|
||||
pub fn ms_sgc(&mut self) -> &mut ExtendedKeyUsage {
|
||||
self.ms_sgc = true;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the `msEFS` flag to `true`.
|
||||
pub fn ms_efs(&mut self) -> &mut ExtendedKeyUsage {
|
||||
self.ms_efs = true;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the `nsSGC` flag to `true`.
|
||||
pub fn ns_sgc(&mut self) -> &mut ExtendedKeyUsage {
|
||||
self.ns_sgc = true;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets a flag not already defined.
|
||||
pub fn other(&mut self, other: &str) -> &mut ExtendedKeyUsage {
|
||||
self.other.push(other.to_owned());
|
||||
self
|
||||
}
|
||||
|
||||
/// Return the `ExtendedKeyUsage` extension as an `X509Extension`.
|
||||
pub fn build(&self) -> Result<X509Extension, ErrorStack> {
|
||||
let mut value = String::new();
|
||||
let mut first = true;
|
||||
|
|
@ -290,20 +348,25 @@ impl ExtendedKeyUsage {
|
|||
}
|
||||
}
|
||||
|
||||
/// An extension that provides a means of identifying certificates that contain a
|
||||
/// particular public key.
|
||||
pub struct SubjectKeyIdentifier {
|
||||
critical: bool,
|
||||
}
|
||||
|
||||
impl SubjectKeyIdentifier {
|
||||
/// Construct a new `SubjectKeyIdentifier` extension.
|
||||
pub fn new() -> SubjectKeyIdentifier {
|
||||
SubjectKeyIdentifier { critical: false }
|
||||
}
|
||||
|
||||
/// Sets the `critical` flag to `true`. The extension will be critical.
|
||||
pub fn critical(&mut self) -> &mut SubjectKeyIdentifier {
|
||||
self.critical = true;
|
||||
self
|
||||
}
|
||||
|
||||
/// Return a `SubjectKeyIdentifier` extension as an `X509Extension`.
|
||||
pub fn build(&self, ctx: &X509v3Context) -> Result<X509Extension, ErrorStack> {
|
||||
let mut value = String::new();
|
||||
let mut first = true;
|
||||
|
|
@ -313,6 +376,8 @@ impl SubjectKeyIdentifier {
|
|||
}
|
||||
}
|
||||
|
||||
/// An extension that provides a means of identifying the public key corresponding
|
||||
/// to the private key used to sign a CRL.
|
||||
pub struct AuthorityKeyIdentifier {
|
||||
critical: bool,
|
||||
keyid: Option<bool>,
|
||||
|
|
@ -320,6 +385,7 @@ pub struct AuthorityKeyIdentifier {
|
|||
}
|
||||
|
||||
impl AuthorityKeyIdentifier {
|
||||
/// Construct a new `AuthorityKeyIdentifier` extension.
|
||||
pub fn new() -> AuthorityKeyIdentifier {
|
||||
AuthorityKeyIdentifier {
|
||||
critical: false,
|
||||
|
|
@ -328,21 +394,25 @@ impl AuthorityKeyIdentifier {
|
|||
}
|
||||
}
|
||||
|
||||
/// Sets the `critical` flag to `true`. The extension will be critical.
|
||||
pub fn critical(&mut self) -> &mut AuthorityKeyIdentifier {
|
||||
self.critical = true;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the `keyid` flag.
|
||||
pub fn keyid(&mut self, always: bool) -> &mut AuthorityKeyIdentifier {
|
||||
self.keyid = Some(always);
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the `issuer` flag.
|
||||
pub fn issuer(&mut self, always: bool) -> &mut AuthorityKeyIdentifier {
|
||||
self.issuer = Some(always);
|
||||
self
|
||||
}
|
||||
|
||||
/// Return a `AuthorityKeyIdentifier` extension as an `X509Extension`.
|
||||
pub fn build(&self, ctx: &X509v3Context) -> Result<X509Extension, ErrorStack> {
|
||||
let mut value = String::new();
|
||||
let mut first = true;
|
||||
|
|
@ -361,12 +431,15 @@ impl AuthorityKeyIdentifier {
|
|||
}
|
||||
}
|
||||
|
||||
/// An extension that allows additional identities to be bound to the subject
|
||||
/// of the certificate.
|
||||
pub struct SubjectAlternativeName {
|
||||
critical: bool,
|
||||
names: Vec<String>,
|
||||
}
|
||||
|
||||
impl SubjectAlternativeName {
|
||||
/// Construct a new `SubjectAlternativeName` extension.
|
||||
pub fn new() -> SubjectAlternativeName {
|
||||
SubjectAlternativeName {
|
||||
critical: false,
|
||||
|
|
@ -374,46 +447,55 @@ impl SubjectAlternativeName {
|
|||
}
|
||||
}
|
||||
|
||||
/// Sets the `critical` flag to `true`. The extension will be critical.
|
||||
pub fn critical(&mut self) -> &mut SubjectAlternativeName {
|
||||
self.critical = true;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the `email` flag.
|
||||
pub fn email(&mut self, email: &str) -> &mut SubjectAlternativeName {
|
||||
self.names.push(format!("email:{}", email));
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the `uri` flag.
|
||||
pub fn uri(&mut self, uri: &str) -> &mut SubjectAlternativeName {
|
||||
self.names.push(format!("URI:{}", uri));
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the `dns` flag.
|
||||
pub fn dns(&mut self, dns: &str) -> &mut SubjectAlternativeName {
|
||||
self.names.push(format!("DNS:{}", dns));
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the `rid` flag.
|
||||
pub fn rid(&mut self, rid: &str) -> &mut SubjectAlternativeName {
|
||||
self.names.push(format!("RID:{}", rid));
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the `ip` flag.
|
||||
pub fn ip(&mut self, ip: &str) -> &mut SubjectAlternativeName {
|
||||
self.names.push(format!("IP:{}", ip));
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the `dirName` flag.
|
||||
pub fn dir_name(&mut self, dir_name: &str) -> &mut SubjectAlternativeName {
|
||||
self.names.push(format!("dirName:{}", dir_name));
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the `otherName` flag.
|
||||
pub fn other_name(&mut self, other_name: &str) -> &mut SubjectAlternativeName {
|
||||
self.names.push(format!("otherName:{}", other_name));
|
||||
self
|
||||
}
|
||||
|
||||
/// Return a `SubjectAlternativeName` extension as an `X509Extension`.
|
||||
pub fn build(&self, ctx: &X509v3Context) -> Result<X509Extension, ErrorStack> {
|
||||
let mut value = String::new();
|
||||
let mut first = true;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,45 @@
|
|||
//! The standard defining the format of public key certificates.
|
||||
//!
|
||||
//! An `X509` certificate binds an identity to a public key, and is either
|
||||
//! signed by a certificate authority (CA) or self-signed. An entity that gets
|
||||
//! a hold of a certificate can both verify your identity (via a CA) and encrypt
|
||||
//! data with the included public key. `X509` certificates are used in many
|
||||
//! Internet protocols, including SSL/TLS, which is the basis for HTTPS,
|
||||
//! the secure protocol for browsing the web.
|
||||
//!
|
||||
//! # Example
|
||||
//!
|
||||
//! Build an `X509` certificate and use a generated RSA key to sign it.
|
||||
//!
|
||||
//! ```rust
|
||||
//!
|
||||
//! extern crate openssl;
|
||||
//!
|
||||
//! use openssl::x509::{X509, X509Name};
|
||||
//! use openssl::pkey::PKey;
|
||||
//! use openssl::hash::MessageDigest;
|
||||
//! use openssl::rsa::Rsa;
|
||||
//! use openssl::nid::Nid;
|
||||
//!
|
||||
//! fn main() {
|
||||
//! let rsa = Rsa::generate(2048).unwrap();
|
||||
//! let pkey = PKey::from_rsa(rsa).unwrap();
|
||||
//!
|
||||
//! let mut name = X509Name::builder().unwrap();
|
||||
//! name.append_entry_by_nid(Nid::COMMONNAME, "foobar.com").unwrap();
|
||||
//! let name = name.build();
|
||||
//!
|
||||
//! let mut builder = X509::builder().unwrap();
|
||||
//! builder.set_version(2).unwrap();
|
||||
//! builder.set_subject_name(&name).unwrap();
|
||||
//! builder.set_issuer_name(&name).unwrap();
|
||||
//! builder.set_pubkey(&pkey).unwrap();
|
||||
//! builder.sign(&pkey, MessageDigest::sha256()).unwrap();
|
||||
//!
|
||||
//! let certificate: X509 = builder.build();
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
use libc::{c_int, c_long};
|
||||
use ffi;
|
||||
use foreign_types::{ForeignType, ForeignTypeRef};
|
||||
|
|
@ -44,7 +86,10 @@ foreign_type_and_impl_send_sync! {
|
|||
type CType = ffi::X509_STORE_CTX;
|
||||
fn drop = ffi::X509_STORE_CTX_free;
|
||||
|
||||
/// An `X509` certificate store context.
|
||||
pub struct X509StoreContext;
|
||||
|
||||
/// Reference to `X509StoreContext`.
|
||||
pub struct X509StoreContextRef;
|
||||
}
|
||||
|
||||
|
|
@ -57,6 +102,11 @@ impl X509StoreContext {
|
|||
}
|
||||
|
||||
impl X509StoreContextRef {
|
||||
/// Returns application data pertaining to an `X509` store context.
|
||||
///
|
||||
/// This corresponds to [`X509_STORE_CTX_get_ex_data`].
|
||||
///
|
||||
/// [`X509_STORE_CTX_get_ex_data`]: https://www.openssl.org/docs/man1.0.2/crypto/X509_STORE_CTX_get_ex_data.html
|
||||
pub fn ex_data<T>(&self, index: Index<X509StoreContext, T>) -> Option<&T> {
|
||||
unsafe {
|
||||
let data = ffi::X509_STORE_CTX_get_ex_data(self.as_ptr(), index.as_raw());
|
||||
|
|
@ -68,16 +118,32 @@ impl X509StoreContextRef {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the error code of the context.
|
||||
///
|
||||
/// This corresponds to [`X509_STORE_CTX_get_error`].
|
||||
///
|
||||
/// [`X509_STORE_CTX_get_error`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_STORE_CTX_get_error.html
|
||||
pub fn error(&self) -> X509VerifyResult {
|
||||
unsafe { X509VerifyResult::from_raw(ffi::X509_STORE_CTX_get_error(self.as_ptr())) }
|
||||
}
|
||||
|
||||
/// Set the error code of the context.
|
||||
///
|
||||
/// This corresponds to [`X509_STORE_CTX_set_error`].
|
||||
///
|
||||
/// [`X509_STORE_CTX_set_error`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_STORE_CTX_set_error.html
|
||||
pub fn set_error(&mut self, result: X509VerifyResult) {
|
||||
unsafe {
|
||||
ffi::X509_STORE_CTX_set_error(self.as_ptr(), result.as_raw());
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a reference to the certificate which caused the error or None if
|
||||
/// no certificate is relevant to the error.
|
||||
///
|
||||
/// This corresponds to [`X509_STORE_CTX_get_current_cert`].
|
||||
///
|
||||
/// [`X509_STORE_CTX_get_current_cert`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_STORE_CTX_get_current_cert.html
|
||||
pub fn current_cert(&self) -> Option<&X509Ref> {
|
||||
unsafe {
|
||||
let ptr = ffi::X509_STORE_CTX_get_current_cert(self.as_ptr());
|
||||
|
|
@ -89,10 +155,23 @@ impl X509StoreContextRef {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns a non-negative integer representing the depth in the certificate
|
||||
/// chain where the error occurred. If it is zero it occurred in the end
|
||||
/// entity certificate, one if it is the certificate which signed the end
|
||||
/// entity certificate and so on.
|
||||
///
|
||||
/// This corresponds to [`X509_STORE_CTX_get_error_depth`].
|
||||
///
|
||||
/// [`X509_STORE_CTX_get_error_depth`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_STORE_CTX_get_error_depth.html
|
||||
pub fn error_depth(&self) -> u32 {
|
||||
unsafe { ffi::X509_STORE_CTX_get_error_depth(self.as_ptr()) as u32 }
|
||||
}
|
||||
|
||||
/// Returns a reference to a complete valid `X509` certificate chain.
|
||||
///
|
||||
/// This corresponds to [`X509_STORE_CTX_get0_chain`].
|
||||
///
|
||||
/// [`X509_STORE_CTX_get0_chain`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_STORE_CTX_get0_chain.html
|
||||
pub fn chain(&self) -> Option<&StackRef<X509>> {
|
||||
unsafe {
|
||||
let chain = X509_STORE_CTX_get_chain(self.as_ptr());
|
||||
|
|
@ -106,7 +185,7 @@ impl X509StoreContextRef {
|
|||
}
|
||||
}
|
||||
|
||||
/// A builder type which can create `X509` objects.
|
||||
/// A builder used to construct an `X509`.
|
||||
pub struct X509Builder(X509);
|
||||
|
||||
impl X509Builder {
|
||||
|
|
@ -252,7 +331,9 @@ foreign_type_and_impl_send_sync! {
|
|||
type CType = ffi::X509;
|
||||
fn drop = ffi::X509_free;
|
||||
|
||||
/// An `X509` public key certificate.
|
||||
pub struct X509;
|
||||
/// Reference to `X509`.
|
||||
pub struct X509Ref;
|
||||
}
|
||||
|
||||
|
|
@ -471,7 +552,7 @@ impl Stackable for X509 {
|
|||
type StackType = ffi::stack_st_X509;
|
||||
}
|
||||
|
||||
/// A context object required to construct certain X509 extension values.
|
||||
/// A context object required to construct certain `X509` extension values.
|
||||
pub struct X509v3Context<'a>(ffi::X509V3_CTX, PhantomData<(&'a X509Ref, &'a ConfRef)>);
|
||||
|
||||
impl<'a> X509v3Context<'a> {
|
||||
|
|
@ -484,7 +565,9 @@ foreign_type_and_impl_send_sync! {
|
|||
type CType = ffi::X509_EXTENSION;
|
||||
fn drop = ffi::X509_EXTENSION_free;
|
||||
|
||||
/// Permit additional fields to be added to an `X509` v3 certificate.
|
||||
pub struct X509Extension;
|
||||
/// Reference to `X509Extension`.
|
||||
pub struct X509ExtensionRef;
|
||||
}
|
||||
|
||||
|
|
@ -545,9 +628,11 @@ impl X509Extension {
|
|||
}
|
||||
}
|
||||
|
||||
/// A builder used to construct an `X509Name`.
|
||||
pub struct X509NameBuilder(X509Name);
|
||||
|
||||
impl X509NameBuilder {
|
||||
/// Creates a new builder.
|
||||
pub fn new() -> Result<X509NameBuilder, ErrorStack> {
|
||||
unsafe {
|
||||
ffi::init();
|
||||
|
|
@ -555,6 +640,11 @@ impl X509NameBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
/// Add a field entry by str.
|
||||
///
|
||||
/// This corresponds to [`X509_NAME_add_entry_by_txt`].
|
||||
///
|
||||
/// [`X509_NAME_add_entry_by_txt`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_NAME_add_entry_by_txt.html
|
||||
pub fn append_entry_by_text(&mut self, field: &str, value: &str) -> Result<(), ErrorStack> {
|
||||
unsafe {
|
||||
let field = CString::new(field).unwrap();
|
||||
|
|
@ -571,6 +661,11 @@ impl X509NameBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
/// Add a field entry by NID.
|
||||
///
|
||||
/// This corresponds to [`X509_NAME_add_entry_by_NID`].
|
||||
///
|
||||
/// [`X509_NAME_add_entry_by_NID`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_NAME_add_entry_by_NID.html
|
||||
pub fn append_entry_by_nid(&mut self, field: Nid, value: &str) -> Result<(), ErrorStack> {
|
||||
unsafe {
|
||||
assert!(value.len() <= c_int::max_value() as usize);
|
||||
|
|
@ -586,6 +681,7 @@ impl X509NameBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
/// Return an `X509Name`.
|
||||
pub fn build(self) -> X509Name {
|
||||
self.0
|
||||
}
|
||||
|
|
@ -595,7 +691,9 @@ foreign_type_and_impl_send_sync! {
|
|||
type CType = ffi::X509_NAME;
|
||||
fn drop = ffi::X509_NAME_free;
|
||||
|
||||
/// The names of an `X509` certificate.
|
||||
pub struct X509Name;
|
||||
/// Reference to `X509Name`.
|
||||
pub struct X509NameRef;
|
||||
}
|
||||
|
||||
|
|
@ -619,6 +717,7 @@ impl Stackable for X509Name {
|
|||
}
|
||||
|
||||
impl X509NameRef {
|
||||
/// Returns the name entries by the nid.
|
||||
pub fn entries_by_nid<'a>(&'a self, nid: Nid) -> X509NameEntries<'a> {
|
||||
X509NameEntries {
|
||||
name: self,
|
||||
|
|
@ -628,6 +727,7 @@ impl X509NameRef {
|
|||
}
|
||||
}
|
||||
|
||||
/// A type to destructure and examine an `X509Name`.
|
||||
pub struct X509NameEntries<'a> {
|
||||
name: &'a X509NameRef,
|
||||
nid: Nid,
|
||||
|
|
@ -658,11 +758,18 @@ foreign_type_and_impl_send_sync! {
|
|||
type CType = ffi::X509_NAME_ENTRY;
|
||||
fn drop = ffi::X509_NAME_ENTRY_free;
|
||||
|
||||
/// A name entry associated with a `X509Name`.
|
||||
pub struct X509NameEntry;
|
||||
/// Reference to `X509NameEntry`.
|
||||
pub struct X509NameEntryRef;
|
||||
}
|
||||
|
||||
impl X509NameEntryRef {
|
||||
/// Returns the field value of an `X509NameEntry`.
|
||||
///
|
||||
/// This corresponds to [`X509_NAME_ENTRY_get_data`].
|
||||
///
|
||||
/// [`X509_NAME_ENTRY_get_data`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_NAME_ENTRY_get_data.html
|
||||
pub fn data(&self) -> &Asn1StringRef {
|
||||
unsafe {
|
||||
let data = ffi::X509_NAME_ENTRY_get_data(self.as_ptr());
|
||||
|
|
@ -671,9 +778,15 @@ impl X509NameEntryRef {
|
|||
}
|
||||
}
|
||||
|
||||
/// A builder used to construct an `X509Req`.
|
||||
pub struct X509ReqBuilder(X509Req);
|
||||
|
||||
impl X509ReqBuilder {
|
||||
/// Returns a builder for a certificate request.
|
||||
///
|
||||
/// This corresponds to [`X509_REQ_new`].
|
||||
///
|
||||
///[`X509_REQ_new`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_REQ_new.html
|
||||
pub fn new() -> Result<X509ReqBuilder, ErrorStack> {
|
||||
unsafe {
|
||||
ffi::init();
|
||||
|
|
@ -681,10 +794,20 @@ impl X509ReqBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
/// Set the numerical value of the version field.
|
||||
///
|
||||
/// This corresponds to [`X509_REQ_set_version`].
|
||||
///
|
||||
///[`X509_REQ_set_version`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_REQ_set_version.html
|
||||
pub fn set_version(&mut self, version: i32) -> Result<(), ErrorStack> {
|
||||
unsafe { cvt(ffi::X509_REQ_set_version(self.0.as_ptr(), version.into())).map(|_| ()) }
|
||||
}
|
||||
|
||||
/// Set the issuer name.
|
||||
///
|
||||
/// This corresponds to [`X509_REQ_set_subject_name`].
|
||||
///
|
||||
/// [`X509_REQ_set_subject_name`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_REQ_set_subject_name.html
|
||||
pub fn set_subject_name(&mut self, subject_name: &X509NameRef) -> Result<(), ErrorStack> {
|
||||
unsafe {
|
||||
cvt(ffi::X509_REQ_set_subject_name(
|
||||
|
|
@ -694,6 +817,11 @@ impl X509ReqBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
/// Set the public key.
|
||||
///
|
||||
/// This corresponds to [`X509_REQ_set_pubkey`].
|
||||
///
|
||||
/// [`X509_REQ_set_pubkey`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_REQ_set_pubkey.html
|
||||
pub fn set_pubkey<T>(&mut self, key: &PKeyRef<T>) -> Result<(), ErrorStack>
|
||||
where
|
||||
T: HasPublic,
|
||||
|
|
@ -701,6 +829,8 @@ impl X509ReqBuilder {
|
|||
unsafe { cvt(ffi::X509_REQ_set_pubkey(self.0.as_ptr(), key.as_ptr())).map(|_| ()) }
|
||||
}
|
||||
|
||||
/// Return an `X509v3Context`. This context object can be used to construct
|
||||
/// certain `X509` extensions.
|
||||
pub fn x509v3_context<'a>(&'a self, conf: Option<&'a ConfRef>) -> X509v3Context<'a> {
|
||||
unsafe {
|
||||
let mut ctx = mem::zeroed();
|
||||
|
|
@ -723,6 +853,7 @@ impl X509ReqBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
/// Permits any number of extension fields to be added to the certificate.
|
||||
pub fn add_extensions(
|
||||
&mut self,
|
||||
extensions: &StackRef<X509Extension>,
|
||||
|
|
@ -735,6 +866,11 @@ impl X509ReqBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
/// Sign the request using a private key.
|
||||
///
|
||||
/// This corresponds to [`X509_REQ_sign`].
|
||||
///
|
||||
/// [`X509_REQ_sign`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_REQ_sign.html
|
||||
pub fn sign<T>(&mut self, key: &PKeyRef<T>, hash: MessageDigest) -> Result<(), ErrorStack>
|
||||
where
|
||||
T: HasPrivate,
|
||||
|
|
@ -748,6 +884,7 @@ impl X509ReqBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the `X509Req`.
|
||||
pub fn build(self) -> X509Req {
|
||||
self.0
|
||||
}
|
||||
|
|
@ -757,16 +894,19 @@ foreign_type_and_impl_send_sync! {
|
|||
type CType = ffi::X509_REQ;
|
||||
fn drop = ffi::X509_REQ_free;
|
||||
|
||||
/// An `X509` certificate request.
|
||||
pub struct X509Req;
|
||||
/// Reference to `X509Req`.
|
||||
pub struct X509ReqRef;
|
||||
}
|
||||
|
||||
impl X509Req {
|
||||
/// A builder for `X509Req`.
|
||||
pub fn builder() -> Result<X509ReqBuilder, ErrorStack> {
|
||||
X509ReqBuilder::new()
|
||||
}
|
||||
|
||||
/// Reads CSR from PEM
|
||||
/// Reads Certifcate Signing Request (CSR) from PEM.
|
||||
pub fn from_pem(buf: &[u8]) -> Result<X509Req, ErrorStack> {
|
||||
let mem_bio = MemBioSlice::new(buf)?;
|
||||
unsafe {
|
||||
|
|
@ -787,10 +927,20 @@ impl X509ReqRef {
|
|||
to_pem!(ffi::PEM_write_bio_X509_REQ);
|
||||
to_der!(ffi::i2d_X509_REQ);
|
||||
|
||||
/// Returns the numerical value of the version field of the certificate request.
|
||||
///
|
||||
/// This corresponds to [`X509_REQ_get_version`]
|
||||
///
|
||||
/// [`X509_REQ_get_version`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_REQ_get_version.html
|
||||
pub fn version(&self) -> i32 {
|
||||
unsafe { compat::X509_REQ_get_version(self.as_ptr()) as i32 }
|
||||
}
|
||||
|
||||
/// Returns the subject name of the certificate request.
|
||||
///
|
||||
/// This corresponds to [`X509_REQ_get_subject_name`]
|
||||
///
|
||||
/// [`X509_REQ_get_subject_name`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_REQ_get_subject_name.html
|
||||
pub fn subject_name(&self) -> &X509NameRef {
|
||||
unsafe {
|
||||
let name = compat::X509_REQ_get_subject_name(self.as_ptr());
|
||||
|
|
@ -800,6 +950,7 @@ impl X509ReqRef {
|
|||
}
|
||||
}
|
||||
|
||||
/// The result of peer certificate verification.
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub struct X509VerifyResult(c_int);
|
||||
|
||||
|
|
@ -835,10 +986,16 @@ impl X509VerifyResult {
|
|||
X509VerifyResult(err)
|
||||
}
|
||||
|
||||
/// Return the integer representation of an `X509VerifyResult`.
|
||||
pub fn as_raw(&self) -> c_int {
|
||||
self.0
|
||||
}
|
||||
|
||||
/// Return a human readable error string from the verification error.
|
||||
///
|
||||
/// This corresponds to [`X509_verify_cert_error_string`].
|
||||
///
|
||||
/// [`X509_verify_cert_error_string`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_verify_cert_error_string.html
|
||||
pub fn error_string(&self) -> &'static str {
|
||||
ffi::init();
|
||||
|
||||
|
|
@ -848,7 +1005,9 @@ impl X509VerifyResult {
|
|||
}
|
||||
}
|
||||
|
||||
/// Successful peer certifiate verification.
|
||||
pub const OK: X509VerifyResult = X509VerifyResult(ffi::X509_V_OK);
|
||||
/// Application verification failure.
|
||||
pub const APPLICATION_VERIFICATION: X509VerifyResult =
|
||||
X509VerifyResult(ffi::X509_V_ERR_APPLICATION_VERIFICATION);
|
||||
}
|
||||
|
|
@ -857,7 +1016,9 @@ foreign_type_and_impl_send_sync! {
|
|||
type CType = ffi::GENERAL_NAME;
|
||||
fn drop = ffi::GENERAL_NAME_free;
|
||||
|
||||
/// An `X509` certificate alternative names.
|
||||
pub struct GeneralName;
|
||||
/// Reference to `GeneralName`.
|
||||
pub struct GeneralNameRef;
|
||||
}
|
||||
|
||||
|
|
@ -903,7 +1064,9 @@ foreign_type_and_impl_send_sync! {
|
|||
type CType = ffi::X509_ALGOR;
|
||||
fn drop = ffi::X509_ALGOR_free;
|
||||
|
||||
/// An `X509` certificate signature algorithm.
|
||||
pub struct X509Algorithm;
|
||||
/// Reference to `X509Algorithm`.
|
||||
pub struct X509AlgorithmRef;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,45 @@
|
|||
//! Describe a context in which to verify an `X509` certificate.
|
||||
//!
|
||||
//! The `X509` certificate store holds trusted CA certificates used to verify
|
||||
//! peer certificates.
|
||||
//!
|
||||
//! # Example
|
||||
//!
|
||||
//! ```rust
|
||||
//!
|
||||
//! extern crate openssl;
|
||||
//!
|
||||
//! use openssl::x509::store::{X509StoreBuilder, X509Store};
|
||||
//! use openssl::x509::{X509, X509Name};
|
||||
//! use openssl::pkey::PKey;
|
||||
//! use openssl::hash::MessageDigest;
|
||||
//! use openssl::rsa::Rsa;
|
||||
//! use openssl::nid::Nid;
|
||||
//!
|
||||
//! fn main() {
|
||||
//! let rsa = Rsa::generate(2048).unwrap();
|
||||
//! let pkey = PKey::from_rsa(rsa).unwrap();
|
||||
//!
|
||||
//! let mut name = X509Name::builder().unwrap();
|
||||
//! name.append_entry_by_nid(Nid::COMMONNAME, "foobar.com").unwrap();
|
||||
//! let name = name.build();
|
||||
//!
|
||||
//! let mut builder = X509::builder().unwrap();
|
||||
//! builder.set_version(2).unwrap();
|
||||
//! builder.set_subject_name(&name).unwrap();
|
||||
//! builder.set_issuer_name(&name).unwrap();
|
||||
//! builder.set_pubkey(&pkey).unwrap();
|
||||
//! builder.sign(&pkey, MessageDigest::sha256()).unwrap();
|
||||
//!
|
||||
//! let certificate: X509 = builder.build();
|
||||
//!
|
||||
//! let mut builder = X509StoreBuilder::new().unwrap();
|
||||
//! let _ = builder.add_cert(certificate);
|
||||
//!
|
||||
//! let store: X509Store = builder.build();
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
use ffi;
|
||||
use foreign_types::ForeignTypeRef;
|
||||
use std::mem;
|
||||
|
|
@ -10,7 +52,9 @@ foreign_type! {
|
|||
type CType = ffi::X509_STORE;
|
||||
fn drop = ffi::X509_STORE_free;
|
||||
|
||||
/// A builder type used to construct an `X509Store`.
|
||||
pub struct X509StoreBuilder;
|
||||
/// Reference to an `X509StoreBuilder`.
|
||||
pub struct X509StoreBuilderRef;
|
||||
}
|
||||
|
||||
|
|
@ -58,6 +102,8 @@ foreign_type! {
|
|||
type CType = ffi::X509_STORE;
|
||||
fn drop = ffi::X509_STORE_free;
|
||||
|
||||
/// A certificate store to hold trusted `X509` certificates.
|
||||
pub struct X509Store;
|
||||
/// Reference to an `X509Store`.
|
||||
pub struct X509StoreRef;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue