diff --git a/openssl/src/asn1.rs b/openssl/src/asn1.rs index a50ec32f..b9f1df71 100644 --- a/openssl/src/asn1.rs +++ b/openssl/src/asn1.rs @@ -1,3 +1,29 @@ +#![deny(missing_docs)] + +//! Defines the format of certificiates +//! +//! This module is used by [`x509`] and other certificate building functions +//! to describe time, strings, and objects. +//! +//! Abstract Syntax Notation One is an interface description language. +//! The specification comes from [X.208] by OSI, and rewritten in X.680. +//! ASN.1 describes properties of an object with a type set. Those types +//! can be atomic, structured, choice, and other (CHOICE and ANY). These +//! types are expressed as a number and the assignment operator ::= gives +//! the type a name. +//! +//! The implementation here provides a subset of the ASN.1 types that OpenSSL +//! uses, especially in the properties of a certificate used in HTTPS. +//! +//! [X.208]: https://www.itu.int/rec/T-REC-X.208-198811-W/en +//! [`x509`]: ../x509/struct.X509Builder.html +//! +//! ## Examples +//! +//! ``` +//! use openssl::asn1::Asn1Time; +//! let tomorrow = Asn1Time::days_from_now(1); +//! ``` use ffi; use foreign_types::{ForeignType, ForeignTypeRef}; use libc::{c_long, c_char, c_int}; @@ -16,7 +42,21 @@ foreign_type! { type CType = ffi::ASN1_GENERALIZEDTIME; fn drop = ffi::ASN1_GENERALIZEDTIME_free; + /// Non-UTC representation of time + /// + /// If a time can be represented by UTCTime, UTCTime is used + /// otherwise, ASN1_GENERALIZEDTIME is used. This would be, for + /// example outside the year range of 1950-2049. + /// + /// [ASN1_GENERALIZEDTIME_set] documentation from OpenSSL provides + /// further details of implmentation. Note: these docs are from the master + /// branch as documentation on the 1.1.0 branch did not include this page. + /// + /// [ASN1_GENERALIZEDTIME_set]: https://www.openssl.org/docs/manmaster/man3/ASN1_GENERALIZEDTIME_set.html pub struct Asn1GeneralizedTime; + /// Reference to a [`Asn1GeneralizedTime`] + /// + /// [`Asn1GeneralizedTime`]: struct.Asn1GeneralizedTime.html pub struct Asn1GeneralizedTimeRef; } @@ -36,8 +76,20 @@ impl fmt::Display for Asn1GeneralizedTimeRef { foreign_type! { type CType = ffi::ASN1_TIME; fn drop = ffi::ASN1_TIME_free; - + /// Time storage and comparison + /// + /// Asn1Time should be used to store and share time information + /// using certificates. If Asn1Time is set using a string, it must + /// be in either YYMMDDHHMMSSZ, YYYYMMDDHHMMSSZ, or another ASN.1 format. + /// + /// [ASN_TIME_set] documentation at OpenSSL explains the ASN.1 implementaiton + /// used by OpenSSL. + /// + /// [ASN_TIME_set]: https://www.openssl.org/docs/man1.1.0/crypto/ASN1_TIME_set.html pub struct Asn1Time; + /// Reference to an [`Asn1Time`] + /// + /// [`Asn1Time`]: struct.Asn1Time.html pub struct Asn1TimeRef; } @@ -70,12 +122,26 @@ impl Asn1Time { foreign_type! { type CType = ffi::ASN1_STRING; fn drop = ffi::ASN1_STRING_free; - + /// Primary ASN.1 type used by OpenSSL + /// + /// Almost all ASN.1 types in OpenSSL are represented by ASN1_STRING + /// structures. This implementation uses [ASN1_STRING-to_UTF8] to preserve + /// compatibility with Rust's String. + /// + /// [ASN1_STRING-to_UTF8]: https://www.openssl.org/docs/man1.1.0/crypto/ASN1_STRING_to_UTF8.html pub struct Asn1String; + /// Reference to [`Asn1String`] + /// + /// [`Asn1String`]: struct.Asn1String.html pub struct Asn1StringRef; } impl Asn1StringRef { + /// Converts the ASN.1 underlying format to UTF8 + /// + /// ASN.1 strings may utilize UTF-16, ASCII, BMP, or UTF8. This is important to + /// consume the string in a meaningful way without knowing the underlying + /// format. pub fn as_utf8(&self) -> Result { unsafe { let mut ptr = ptr::null_mut(); @@ -88,10 +154,17 @@ impl Asn1StringRef { } } + /// Return the string as an array of bytes + /// + /// The bytes do not directly corespond to UTF-8 encoding. To interact with + /// strings in rust, it is preferable to use [`as_utf8`] + /// + /// [`as_utf8`]: struct.Asn1String.html#method.as_utf8 pub fn as_slice(&self) -> &[u8] { unsafe { slice::from_raw_parts(ASN1_STRING_data(self.as_ptr()), self.len()) } } + /// Return the length of the Asn1String (number of bytes) pub fn len(&self) -> usize { unsafe { ffi::ASN1_STRING_length(self.as_ptr()) as usize } } @@ -101,15 +174,38 @@ foreign_type! { type CType = ffi::ASN1_INTEGER; fn drop = ffi::ASN1_INTEGER_free; + /// Numeric representation + /// + /// Integers in ASN.1 may include BigNum, int64 or uint64. BigNum implementation + /// can be found within [`bn`] module. + /// + /// OpenSSL documentation includes [`ASN1_INTEGER_set`]. + /// + /// [`bn`]: ../bn/index.html + /// [`ASN1_INTEGER_set`]: https://www.openssl.org/docs/man1.1.0/crypto/ASN1_INTEGER_set.html pub struct Asn1Integer; + /// Reference to [`Asn1Integer`] + /// + /// [`Asn1Integer`]: struct.Asn1Integer.html pub struct Asn1IntegerRef; } impl Asn1IntegerRef { + /// Returns value of ASN.1 integer, or -1 if there is an error, and 0 if the integer is Null. + /// + /// OpenSSL documentation at [`ASN1_INTEGER_get`]. + /// + /// [`ASN1_INTEGER_get`]: https://www.openssl.org/docs/man1.1.0/crypto/ASN1_INTEGER_get.html pub fn get(&self) -> i64 { unsafe { ::ffi::ASN1_INTEGER_get(self.as_ptr()) as i64 } } - + /// Sets the ASN.1 value to the value of a signed 32-bit integer, for larger numbers + /// see [`bn`]. + /// + /// OpenSSL documentation at [`ASN1_INTEGER_set`] + /// + /// [`bn`]: ../bn/struct.BigNumRef.html#method.to_asn1_integer + /// [`ASN1_INTEGER_set`]: https://www.openssl.org/docs/man1.1.0/crypto/ASN1_INTEGER_set.html pub fn set(&mut self, value: i32) -> Result<(), ErrorStack> { unsafe { cvt(::ffi::ASN1_INTEGER_set(self.as_ptr(), value as c_long)).map(|_| ()) } } @@ -118,16 +214,25 @@ impl Asn1IntegerRef { foreign_type! { type CType = ffi::ASN1_BIT_STRING; fn drop = ffi::ASN1_BIT_STRING_free; - + /// Sequence of bytes + /// + /// Asn1BitString is used in [`x509`] certificates for the signature. + /// The bit string acts as a collection of bytes. + /// + /// [`x509`]: ../x509/struct.X509.html#method.signature pub struct Asn1BitString; + /// Reference to [`Asn1BitString`] + /// + /// [`Asn1BitString`]: struct.Asn1BitString.html pub struct Asn1BitStringRef; } impl Asn1BitStringRef { + /// Returns the Asn1BitString as a slice pub fn as_slice(&self) -> &[u8] { unsafe { slice::from_raw_parts(ASN1_STRING_data(self.as_ptr() as *mut _), self.len()) } } - + /// Length of Asn1BitString in number of bytes. pub fn len(&self) -> usize { unsafe { ffi::ASN1_STRING_length(self.as_ptr() as *mut _) as usize } } @@ -137,7 +242,23 @@ foreign_type! { type CType = ffi::ASN1_OBJECT; fn drop = ffi::ASN1_OBJECT_free; + /// Object Identifier + /// + /// Represents an ASN.1 Object. Typically, NIDs, or numeric identifiers + /// are stored as a table within the [`Nid`] module. These constants are + /// used to determine attributes of a certificate, such as mapping the + /// attribute "CommonName" to "CN" which is represented as the OID of 13. + /// This attribute is a constant in the [`nid::COMMONNAME`]. + /// + /// OpenSSL documentation at [`OBJ_nid2obj`] + /// + /// [`Nid`]: ../nid/index.html + /// [`nid::COMMONNAME`]: ../nid/constant.COMMONNAME.html + /// [`OBJ_nid2obj`]: https://www.openssl.org/docs/man1.1.0/crypto/OBJ_obj2nid.html pub struct Asn1Object; + /// Reference to [`Asn1Object`] + /// + /// [`Asn1Object`]: struct.Asn1Object.html pub struct Asn1ObjectRef; }