1
1
//! Certificate types
2
2
3
- use crate :: { name:: Name , serial_number:: SerialNumber , time:: Validity } ;
3
+ use crate :: { ext , name:: Name , serial_number:: SerialNumber , time:: Validity } ;
4
4
use alloc:: vec:: Vec ;
5
5
use const_oid:: AssociatedOid ;
6
6
use core:: { cmp:: Ordering , fmt:: Debug } ;
@@ -136,38 +136,109 @@ pub type TbsCertificate = TbsCertificateInner<Rfc5280>;
136
136
#[ derive( Clone , Debug , Eq , PartialEq , Sequence , ValueOrd ) ]
137
137
#[ allow( missing_docs) ]
138
138
pub struct TbsCertificateInner < P : Profile = Rfc5280 > {
139
- /// The certificate version
139
+ /// The certificate version.
140
140
///
141
141
/// Note that this value defaults to Version 1 per the RFC. However,
142
142
/// fields such as `issuer_unique_id`, `subject_unique_id` and `extensions`
143
143
/// require later versions. Care should be taken in order to ensure
144
144
/// standards compliance.
145
145
#[ asn1( context_specific = "0" , default = "Default::default" ) ]
146
- pub version : Version ,
146
+ pub ( crate ) version : Version ,
147
147
148
- pub serial_number : SerialNumber < P > ,
149
- pub signature : AlgorithmIdentifierOwned ,
150
- pub issuer : Name ,
151
- pub validity : Validity < P > ,
152
- pub subject : Name ,
153
- pub subject_public_key_info : SubjectPublicKeyInfoOwned ,
148
+ pub ( crate ) serial_number : SerialNumber < P > ,
149
+ pub ( crate ) signature : AlgorithmIdentifierOwned ,
150
+ pub ( crate ) issuer : Name ,
151
+ pub ( crate ) validity : Validity < P > ,
152
+ pub ( crate ) subject : Name ,
153
+ pub ( crate ) subject_public_key_info : SubjectPublicKeyInfoOwned ,
154
154
155
155
#[ asn1( context_specific = "1" , tag_mode = "IMPLICIT" , optional = "true" ) ]
156
- pub issuer_unique_id : Option < BitString > ,
156
+ pub ( crate ) issuer_unique_id : Option < BitString > ,
157
157
158
158
#[ asn1( context_specific = "2" , tag_mode = "IMPLICIT" , optional = "true" ) ]
159
- pub subject_unique_id : Option < BitString > ,
159
+ pub ( crate ) subject_unique_id : Option < BitString > ,
160
160
161
161
#[ asn1( context_specific = "3" , tag_mode = "EXPLICIT" , optional = "true" ) ]
162
- pub extensions : Option < crate :: ext:: Extensions > ,
162
+ pub ( crate ) extensions : Option < ext:: Extensions > ,
163
163
}
164
164
165
165
impl < P : Profile > TbsCertificateInner < P > {
166
- /// Decodes a single extension
166
+ /// [`Version`] of this certificate (v1/v2/v3).
167
+ pub fn version ( & self ) -> Version {
168
+ self . version
169
+ }
170
+
171
+ /// Serial number of this certificate.
172
+ ///
173
+ /// X.509 serial numbers are used to uniquely identify certificates issued by a given
174
+ /// Certificate Authority (CA) identified in the `issuer` field.
175
+ pub fn serial_number ( & self ) -> & SerialNumber < P > {
176
+ & self . serial_number
177
+ }
178
+
179
+ /// Identifies the signature algorithm that this `TBSCertificate` should be signed with.
180
+ ///
181
+ /// In a signed certificate, matches [`CertificateInner::signature_algorithm`].
182
+ pub fn signature ( & self ) -> & AlgorithmIdentifierOwned {
183
+ & self . signature
184
+ }
185
+
186
+ /// Certificate issuer: [`Name`] of the Certificate Authority (CA) which issued this
187
+ /// certificate.
188
+ pub fn issuer ( & self ) -> & Name {
189
+ & self . issuer
190
+ }
191
+
192
+ /// Validity period for this certificate: time range in which a certificate is considered valid,
193
+ /// after which it expires.
194
+ pub fn validity ( & self ) -> & Validity < P > {
195
+ & self . validity
196
+ }
197
+
198
+ /// Subject of this certificate: entity that the certificate is intended to represent or
199
+ /// authenticate, e.g. an individual, a device, or an organization.
200
+ pub fn subject ( & self ) -> & Name {
201
+ & self . subject
202
+ }
203
+
204
+ /// Subject Public Key Info (SPKI): public key information about this certificate including
205
+ /// algorithm identifier and key data.
206
+ pub fn subject_public_key_info ( & self ) -> & SubjectPublicKeyInfoOwned {
207
+ & self . subject_public_key_info
208
+ }
209
+
210
+ /// Issuer unique ID: unique identifier representing the issuing CA, as defined by the
211
+ /// issuing CA.
212
+ ///
213
+ /// (NOTE: added in X.509 v2)
214
+ pub fn issuer_unique_id ( & self ) -> & Option < BitString > {
215
+ & self . issuer_unique_id
216
+ }
217
+
218
+ /// Subject unique ID: unique identifier representing the certificate subject, as defined by the
219
+ /// issuing CA.
220
+ ///
221
+ /// (NOTE: added in X.509 v2)
222
+ pub fn subject_unique_id ( & self ) -> & Option < BitString > {
223
+ & self . subject_unique_id
224
+ }
225
+
226
+ /// Certificate extensions.
227
+ ///
228
+ /// Additional fields in a digital certificate that provide extra information beyond the
229
+ /// standard fields. These extensions enhance the functionality and flexibility of certificates,
230
+ /// allowing them to convey more specific details about the certificate's usage and constraints.
231
+ ///
232
+ /// (NOTE: added in X.509 v3)
233
+ pub fn extensions ( & self ) -> Option < & ext:: Extensions > {
234
+ self . extensions . as_ref ( )
235
+ }
236
+
237
+ /// Decodes a single extension.
167
238
///
168
239
/// Returns `Ok(None)` if the extension is not present.
169
240
///
170
- /// Otherwise returns the extension, and indicates if the extension was marked critical in the
241
+ /// Otherwise, returns the extension, and indicates if the extension was marked critical in the
171
242
/// boolean.
172
243
///
173
244
/// ```
@@ -177,7 +248,7 @@ impl<P: Profile> TbsCertificateInner<P> {
177
248
/// use x509_cert::{der::DecodePem, ext::pkix::BasicConstraints, Certificate};
178
249
/// let certificate = Certificate::from_pem(CERT_PEM.as_bytes()).expect("parse certificate");
179
250
///
180
- /// let (critical, constraints) = certificate.tbs_certificate.get_extension::<BasicConstraints>()
251
+ /// let (critical, constraints) = certificate.tbs_certificate() .get_extension::<BasicConstraints>()
181
252
/// .expect("Failed to parse extension")
182
253
/// .expect("Basic constraints expected");
183
254
/// # let _ = constraints;
@@ -213,7 +284,7 @@ impl<P: Profile> TbsCertificateInner<P> {
213
284
/// use x509_cert::{der::DecodePem, ext::pkix::BasicConstraints, Certificate};
214
285
/// let certificate = Certificate::from_pem(CERT_PEM.as_bytes()).expect("parse certificate");
215
286
///
216
- /// let mut extensions_found = certificate.tbs_certificate.filter_extensions::<BasicConstraints>();
287
+ /// let mut extensions_found = certificate.tbs_certificate() .filter_extensions::<BasicConstraints>();
217
288
/// while let Some(Ok((critical, extension))) = extensions_found.next() {
218
289
/// println!("Found (critical={critical}): {extension:?}");
219
290
/// }
@@ -258,9 +329,27 @@ pub type Certificate = CertificateInner<Rfc5280>;
258
329
#[ derive( Clone , Debug , Eq , PartialEq , Sequence , ValueOrd ) ]
259
330
#[ allow( missing_docs) ]
260
331
pub struct CertificateInner < P : Profile = Rfc5280 > {
261
- pub tbs_certificate : TbsCertificateInner < P > ,
262
- pub signature_algorithm : AlgorithmIdentifierOwned ,
263
- pub signature : BitString ,
332
+ pub ( crate ) tbs_certificate : TbsCertificateInner < P > ,
333
+ pub ( crate ) signature_algorithm : AlgorithmIdentifierOwned ,
334
+ pub ( crate ) signature : BitString ,
335
+ }
336
+
337
+ impl < P : Profile > CertificateInner < P > {
338
+ /// Get the [`TbsCertificateInner`] (i.e. the part the signature is computed over).
339
+ pub fn tbs_certificate ( & self ) -> & TbsCertificateInner < P > {
340
+ & self . tbs_certificate
341
+ }
342
+
343
+ /// Signature algorithm used to sign the serialization of [`CertificateInner::tbs_certificate`].
344
+ pub fn signature_algorithm ( & self ) -> & AlgorithmIdentifierOwned {
345
+ & self . signature_algorithm
346
+ }
347
+
348
+ /// Signature over the DER serialization of [`CertificateInner::tbs_certificate`] using the
349
+ /// algorithm identified in [`CertificateInner::signature_algorithm`].
350
+ pub fn signature ( & self ) -> & BitString {
351
+ & self . signature
352
+ }
264
353
}
265
354
266
355
#[ cfg( feature = "pem" ) ]
0 commit comments