• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE-MIT)
2 //! [![Apache License 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](./LICENSE-APACHE)
3 //! [![docs.rs](https://docs.rs/x509-parser/badge.svg)](https://docs.rs/x509-parser)
4 //! [![crates.io](https://img.shields.io/crates/v/x509-parser.svg)](https://crates.io/crates/x509-parser)
5 //! [![Download numbers](https://img.shields.io/crates/d/x509-parser.svg)](https://crates.io/crates/x509-parser)
6 //! [![Github CI](https://github.com/rusticata/x509-parser/workflows/Continuous%20integration/badge.svg)](https://github.com/rusticata/x509-parser/actions)
7 //! [![Minimum rustc version](https://img.shields.io/badge/rustc-1.46.0+-lightgray.svg)](#rust-version-requirements)
8 //!
9 //! # X.509 Parser
10 //!
11 //! A X.509 v3 ([RFC5280]) parser, implemented with the [nom](https://github.com/Geal/nom)
12 //! parser combinator framework.
13 //!
14 //! It is written in pure Rust, fast, and makes extensive use of zero-copy. A lot of care is taken
15 //! to ensure security and safety of this crate, including design (recursion limit, defensive
16 //! programming), tests, and fuzzing. It also aims to be panic-free.
17 //!
18 //! The code is available on [Github](https://github.com/rusticata/x509-parser)
19 //! and is part of the [Rusticata](https://github.com/rusticata) project.
20 //!
21 //! Certificates are usually encoded in two main formats: PEM (usually the most common format) or
22 //! DER.  A PEM-encoded certificate is a container, storing a DER object. See the
23 //! [`pem`](pem/index.html) module for more documentation.
24 //!
25 //! To decode a DER-encoded certificate, the main parsing method is
26 //! [`X509Certificate::from_der`] (
27 //! part of the [`FromDer`](traits/trait.FromDer.html) trait
28 //! ), which builds a
29 //! [`X509Certificate`](certificate/struct.X509Certificate.html) object.
30 //!
31 //! An alternative method is to use [`X509CertificateParser`](certificate/struct.X509CertificateParser.html),
32 //! which allows specifying parsing options (for example, not automatically parsing option contents).
33 //!
34 //! The returned objects for parsers follow the definitions of the RFC. This means that accessing
35 //! fields is done by accessing struct members recursively. Some helper functions are provided, for
36 //! example [`X509Certificate::issuer()`](certificate/struct.X509Certificate.html#method.issuer) returns the
37 //! same as accessing `<object>.tbs_certificate.issuer`.
38 //!
39 //! For PEM-encoded certificates, use the [`pem`](pem/index.html) module.
40 //!
41 //! # Examples
42 //!
43 //! Parsing a certificate in DER format:
44 //!
45 //! ```rust
46 //! use x509_parser::prelude::*;
47 //!
48 //! static IGCA_DER: &[u8] = include_bytes!("../assets/IGC_A.der");
49 //!
50 //! # fn main() {
51 //! let res = X509Certificate::from_der(IGCA_DER);
52 //! match res {
53 //!     Ok((rem, cert)) => {
54 //!         assert!(rem.is_empty());
55 //!         //
56 //!         assert_eq!(cert.version(), X509Version::V3);
57 //!     },
58 //!     _ => panic!("x509 parsing failed: {:?}", res),
59 //! }
60 //! # }
61 //! ```
62 //!
63 //! To parse a CRL and print information about revoked certificates:
64 //!
65 //! ```rust
66 //! # use x509_parser::prelude::*;
67 //! #
68 //! # static DER: &[u8] = include_bytes!("../assets/example.crl");
69 //! #
70 //! # fn main() {
71 //! let res = CertificateRevocationList::from_der(DER);
72 //! match res {
73 //!     Ok((_rem, crl)) => {
74 //!         for revoked in crl.iter_revoked_certificates() {
75 //!             println!("Revoked certificate serial: {}", revoked.raw_serial_as_string());
76 //!             println!("  Reason: {}", revoked.reason_code().unwrap_or_default().1);
77 //!         }
78 //!     },
79 //!     _ => panic!("CRL parsing failed: {:?}", res),
80 //! }
81 //! # }
82 //! ```
83 //!
84 //! See also `examples/print-cert.rs`.
85 //!
86 //! # Features
87 //!
88 //! - The `verify` feature adds support for (cryptographic) signature verification, based on `ring`.
89 //!   It adds the
90 //!   [`X509Certificate::verify_signature()`](certificate/struct.X509Certificate.html#method.verify_signature)
91 //!   to `X509Certificate`.
92 //!
93 //! ```rust
94 //! # #[cfg(feature = "verify")]
95 //! # use x509_parser::certificate::X509Certificate;
96 //! /// Cryptographic signature verification: returns true if certificate was signed by issuer
97 //! #[cfg(feature = "verify")]
98 //! pub fn check_signature(cert: &X509Certificate<'_>, issuer: &X509Certificate<'_>) -> bool {
99 //!     let issuer_public_key = issuer.public_key();
100 //!     cert
101 //!         .verify_signature(Some(issuer_public_key))
102 //!         .is_ok()
103 //! }
104 //! ```
105 //!
106 //! - The `validate` features add methods to run more validation functions on the certificate structure
107 //!   and values using the [`Validate`](validate/trait.Validate.html) trait.
108 //!   It does not validate any cryptographic parameter (see `verify` above).
109 //!
110 //! ## Rust version requirements
111 //!
112 //! `x509-parser` requires **Rustc version 1.46 or greater**, based on nom 7
113 //! dependencies and for proc-macro attributes support.
114 //!
115 //! [RFC5280]: https://tools.ietf.org/html/rfc5280
116 
117 #![deny(/*missing_docs,*/
118         unstable_features,
119         unused_import_braces, unused_qualifications)]
120 #![warn(
121     missing_debug_implementations,
122     /* missing_docs,
123     rust_2018_idioms,*/
124     unreachable_pub
125 )]
126 #![forbid(unsafe_code)]
127 #![deny(broken_intra_doc_links)]
128 #![doc(test(
129     no_crate_inject,
130     attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables))
131 ))]
132 #![cfg_attr(docsrs, feature(doc_cfg))]
133 
134 pub mod certificate;
135 pub mod certification_request;
136 pub mod cri_attributes;
137 pub mod error;
138 pub mod extensions;
139 pub mod objects;
140 pub mod pem;
141 pub mod prelude;
142 pub mod revocation_list;
143 pub mod time;
144 pub mod traits;
145 #[cfg(feature = "validate")]
146 #[cfg_attr(docsrs, doc(cfg(feature = "validate")))]
147 pub mod validate;
148 pub mod x509;
149 
150 // reexports
151 pub use der_parser;
152 pub use der_parser::num_bigint;
153 pub use nom;
154 pub use oid_registry;
155 
156 use certificate::X509Certificate;
157 use error::X509Result;
158 use revocation_list::CertificateRevocationList;
159 use traits::FromDer;
160 
161 /// Parse a **DER-encoded** X.509 Certificate, and return the remaining of the input and the built
162 /// object.
163 ///
164 ///
165 /// This function is an alias to [X509Certificate::from_der](certificate::X509Certificate::from_der). See this function
166 /// for more information.
167 ///
168 /// For PEM-encoded certificates, use the [`pem`](pem/index.html) module.
169 #[inline]
parse_x509_certificate<'a>(i: &'a [u8]) -> X509Result<X509Certificate<'a>>170 pub fn parse_x509_certificate<'a>(i: &'a [u8]) -> X509Result<X509Certificate<'a>> {
171     X509Certificate::from_der(i)
172 }
173 
174 /// Parse a DER-encoded X.509 v2 CRL, and return the remaining of the input and the built
175 /// object.
176 ///
177 /// This function is an alias to [CertificateRevocationList::from_der](revocation_list::CertificateRevocationList::from_der). See this function
178 /// for more information.
179 #[inline]
parse_x509_crl(i: &[u8]) -> X509Result<CertificateRevocationList>180 pub fn parse_x509_crl(i: &[u8]) -> X509Result<CertificateRevocationList> {
181     CertificateRevocationList::from_der(i)
182 }
183 
184 /// Parse a DER-encoded X.509 Certificate, and return the remaining of the input and the built
185 #[deprecated(
186     since = "0.9.0",
187     note = "please use `parse_x509_certificate` or `X509Certificate::from_der` instead"
188 )]
189 #[inline]
parse_x509_der<'a>(i: &'a [u8]) -> X509Result<X509Certificate<'a>>190 pub fn parse_x509_der<'a>(i: &'a [u8]) -> X509Result<X509Certificate<'a>> {
191     X509Certificate::from_der(i)
192 }
193 
194 /// Parse a DER-encoded X.509 v2 CRL, and return the remaining of the input and the built
195 /// object.
196 #[deprecated(
197     since = "0.9.0",
198     note = "please use `parse_x509_crl` or `CertificateRevocationList::from_der` instead"
199 )]
200 #[inline]
parse_crl_der(i: &[u8]) -> X509Result<CertificateRevocationList>201 pub fn parse_crl_der(i: &[u8]) -> X509Result<CertificateRevocationList> {
202     CertificateRevocationList::from_der(i)
203 }
204