@@ -84,6 +84,74 @@ mod test_convert_x509_subject_alternative_name {
84
84
}
85
85
}
86
86
87
+ #[ cfg( feature = "x509-parser" ) ]
88
+ mod test_x509_custom_ext {
89
+ use crate :: util;
90
+ use crate :: Certificate ;
91
+
92
+ use rcgen:: CustomExtension ;
93
+ use x509_parser:: oid_registry:: asn1_rs;
94
+ use x509_parser:: prelude:: {
95
+ FromDer , ParsedCriAttribute , X509Certificate , X509CertificationRequest ,
96
+ } ;
97
+
98
+ #[ test]
99
+ fn custom_ext ( ) {
100
+ // Create an imaginary critical custom extension for testing.
101
+ let test_oid = asn1_rs:: Oid :: from ( & [ 2 , 5 , 29 , 999999 ] ) . unwrap ( ) ;
102
+ let test_ext = yasna:: construct_der ( |writer| {
103
+ writer. write_utf8_string ( "🦀 greetz to ferris 🦀" ) ;
104
+ } ) ;
105
+ let mut custom_ext = CustomExtension :: from_oid_content (
106
+ test_oid. iter ( ) . unwrap ( ) . collect :: < Vec < u64 > > ( ) . as_slice ( ) ,
107
+ test_ext. clone ( ) ,
108
+ ) ;
109
+ custom_ext. set_criticality ( true ) ;
110
+
111
+ // Generate a certificate with the custom extension, parse it with x509-parser.
112
+ let mut params = util:: default_params ( ) ;
113
+ params. custom_extensions = vec ! [ custom_ext] ;
114
+ let test_cert = Certificate :: from_params ( params) . unwrap ( ) ;
115
+ let test_cert_der = test_cert. serialize_der ( ) . unwrap ( ) ;
116
+ let ( _, x509_test_cert) = X509Certificate :: from_der ( & test_cert_der) . unwrap ( ) ;
117
+
118
+ // We should be able to find the extension by OID, with expected criticality and value.
119
+ let favorite_drink_ext = x509_test_cert
120
+ . get_extension_unique ( & test_oid)
121
+ . expect ( "invalid extensions" )
122
+ . expect ( "missing custom extension" ) ;
123
+ assert_eq ! ( favorite_drink_ext. critical, true ) ;
124
+ assert_eq ! ( favorite_drink_ext. value, test_ext) ;
125
+
126
+ // Generate a CSR with the custom extension, parse it with x509-parser.
127
+ let test_cert_csr_der = test_cert. serialize_request_der ( ) . unwrap ( ) ;
128
+ let ( _, x509_csr) = X509CertificationRequest :: from_der ( & test_cert_csr_der) . unwrap ( ) ;
129
+
130
+ // We should find that the CSR contains requested extensions.
131
+ // Note: we can't use `x509_csr.requested_extensions()` here because it maps the raw extension
132
+ // request extensions to their parsed form, and of course x509-parser doesn't parse our custom extension.
133
+ let exts = x509_csr
134
+ . certification_request_info
135
+ . iter_attributes ( )
136
+ . find_map ( |attr| {
137
+ if let ParsedCriAttribute :: ExtensionRequest ( requested) = & attr. parsed_attribute ( ) {
138
+ Some ( requested. extensions . iter ( ) . collect :: < Vec < _ > > ( ) )
139
+ } else {
140
+ None
141
+ }
142
+ } )
143
+ . expect ( "missing requested extensions" ) ;
144
+
145
+ // We should find the custom extension with expected criticality and value.
146
+ let custom_ext = exts
147
+ . iter ( )
148
+ . find ( |ext| ext. oid == test_oid)
149
+ . expect ( "missing requested custom extension" ) ;
150
+ assert_eq ! ( custom_ext. critical, true ) ;
151
+ assert_eq ! ( custom_ext. value, test_ext) ;
152
+ }
153
+ }
154
+
87
155
#[ cfg( feature = "x509-parser" ) ]
88
156
mod test_x509_parser_crl {
89
157
use crate :: util;
0 commit comments