1
1
//! X.509 `SubjectPublicKeyInfo`
2
2
3
- use crate :: { AlgorithmIdentifierRef , Error , Result } ;
3
+ use crate :: { AlgorithmIdentifier , Error , Result } ;
4
4
use core:: cmp:: Ordering ;
5
5
use der:: {
6
- asn1:: BitStringRef , Decode , DecodeValue , DerOrd , Encode , Header , Reader , Sequence , ValueOrd ,
6
+ asn1:: { AnyRef , BitStringRef } ,
7
+ Choice , Decode , DecodeValue , DerOrd , Encode , FixedTag , Header , Reader , Sequence , ValueOrd ,
7
8
} ;
8
9
9
10
#[ cfg( feature = "alloc" ) ]
10
- use der:: Document ;
11
+ use der:: {
12
+ asn1:: { Any , BitString } ,
13
+ Document ,
14
+ } ;
11
15
12
16
#[ cfg( feature = "fingerprint" ) ]
13
17
use crate :: { fingerprint, FingerprintBytes } ;
14
18
15
19
#[ cfg( feature = "pem" ) ]
16
20
use der:: pem:: PemLabel ;
17
21
18
- #[ cfg( doc) ]
19
- use crate :: AlgorithmIdentifier ;
22
+ /// [`SubjectPublicKeyInfo`] with [`AnyRef`] algorithm parameters, and [`BitStringRef`] params.
23
+ pub type SubjectPublicKeyInfoRef < ' a > = SubjectPublicKeyInfo < AnyRef < ' a > , BitStringRef < ' a > > ;
24
+
25
+ /// [`SubjectPublicKeyInfo`] with [`Any`] algorithm parameters, and [`BitString`] params.
26
+ #[ cfg( feature = "alloc" ) ]
27
+ pub type SubjectPublicKeyInfoOwned = SubjectPublicKeyInfo < Any , BitString > ;
20
28
21
29
/// X.509 `SubjectPublicKeyInfo` (SPKI) as defined in [RFC 5280 § 4.1.2.7].
22
30
///
@@ -30,16 +38,22 @@ use crate::AlgorithmIdentifier;
30
38
/// ```
31
39
///
32
40
/// [RFC 5280 § 4.1.2.7]: https://tools.ietf.org/html/rfc5280#section-4.1.2.7
33
- #[ derive( Copy , Clone , Debug , Eq , PartialEq ) ]
34
- pub struct SubjectPublicKeyInfo < ' a > {
41
+ #[ derive( Clone , Debug , Eq , PartialEq ) ]
42
+ pub struct SubjectPublicKeyInfo < Params , Key > {
35
43
/// X.509 [`AlgorithmIdentifier`] for the public key type
36
- pub algorithm : AlgorithmIdentifierRef < ' a > ,
44
+ pub algorithm : AlgorithmIdentifier < Params > ,
37
45
38
46
/// Public key data
39
- pub subject_public_key : & ' a [ u8 ] ,
47
+ pub subject_public_key : Key ,
40
48
}
41
49
42
- impl < ' a > SubjectPublicKeyInfo < ' a > {
50
+ impl < ' a , Params , Key > SubjectPublicKeyInfo < Params , Key >
51
+ where
52
+ Params : Choice < ' a > + Encode ,
53
+ // TODO: replace FixedTag with FixedTag<TAG = { Tag::BitString }> once
54
+ // https://github.com/rust-lang/rust/issues/92827 is fixed
55
+ Key : Decode < ' a > + Encode + FixedTag ,
56
+ {
43
57
/// Calculate the SHA-256 fingerprint of this [`SubjectPublicKeyInfo`] and
44
58
/// encode it as a Base64 string.
45
59
///
@@ -69,74 +83,93 @@ impl<'a> SubjectPublicKeyInfo<'a> {
69
83
self . encode ( & mut builder) ?;
70
84
Ok ( builder. finish ( ) )
71
85
}
72
-
73
- /// Get a [`BitString`] representing the `subject_public_key`
74
- fn bitstring ( & self ) -> der:: Result < BitStringRef < ' a > > {
75
- BitStringRef :: from_bytes ( self . subject_public_key )
76
- }
77
86
}
78
87
79
- impl < ' a > DecodeValue < ' a > for SubjectPublicKeyInfo < ' a > {
88
+ impl < ' a : ' k , ' k , Params , Key : ' k > DecodeValue < ' a > for SubjectPublicKeyInfo < Params , Key >
89
+ where
90
+ Params : Choice < ' a > + Encode ,
91
+ Key : Decode < ' a > ,
92
+ {
80
93
fn decode_value < R : Reader < ' a > > ( reader : & mut R , header : Header ) -> der:: Result < Self > {
81
94
reader. read_nested ( header. length , |reader| {
82
95
Ok ( Self {
83
96
algorithm : reader. decode ( ) ?,
84
- subject_public_key : BitStringRef :: decode ( reader) ?
85
- . as_bytes ( )
86
- . ok_or_else ( || der:: Tag :: BitString . value_error ( ) ) ?,
97
+ subject_public_key : Key :: decode ( reader) ?,
87
98
} )
88
99
} )
89
100
}
90
101
}
91
102
92
- impl < ' a > Sequence < ' a > for SubjectPublicKeyInfo < ' a > {
103
+ impl < ' a , Params , Key > Sequence < ' a > for SubjectPublicKeyInfo < Params , Key >
104
+ where
105
+ Params : Choice < ' a > + Encode ,
106
+ Key : Decode < ' a > + Encode + FixedTag ,
107
+ {
93
108
fn fields < F , T > ( & self , f : F ) -> der:: Result < T >
94
109
where
95
110
F : FnOnce ( & [ & dyn Encode ] ) -> der:: Result < T > ,
96
111
{
97
- f ( & [ & self . algorithm , & self . bitstring ( ) ? ] )
112
+ f ( & [ & self . algorithm , & self . subject_public_key ] )
98
113
}
99
114
}
100
115
101
- impl < ' a > TryFrom < & ' a [ u8 ] > for SubjectPublicKeyInfo < ' a > {
116
+ impl < ' a , Params , Key > TryFrom < & ' a [ u8 ] > for SubjectPublicKeyInfo < Params , Key >
117
+ where
118
+ Params : Choice < ' a > + Encode ,
119
+ Key : Decode < ' a > + Encode + FixedTag ,
120
+ {
102
121
type Error = Error ;
103
122
104
123
fn try_from ( bytes : & ' a [ u8 ] ) -> Result < Self > {
105
124
Ok ( Self :: from_der ( bytes) ?)
106
125
}
107
126
}
108
127
109
- impl ValueOrd for SubjectPublicKeyInfo < ' _ > {
128
+ impl < ' a , Params , Key > ValueOrd for SubjectPublicKeyInfo < Params , Key >
129
+ where
130
+ Params : Choice < ' a > + DerOrd + Encode ,
131
+ Key : ValueOrd ,
132
+ {
110
133
fn value_cmp ( & self , other : & Self ) -> der:: Result < Ordering > {
111
134
match self . algorithm . der_cmp ( & other. algorithm ) ? {
112
- Ordering :: Equal => self . bitstring ( ) ? . der_cmp ( & other. bitstring ( ) ? ) ,
135
+ Ordering :: Equal => self . subject_public_key . value_cmp ( & other. subject_public_key ) ,
113
136
other => Ok ( other) ,
114
137
}
115
138
}
116
139
}
117
140
118
141
#[ cfg( feature = "alloc" ) ]
119
142
#[ cfg_attr( docsrs, doc( cfg( feature = "alloc" ) ) ) ]
120
- impl TryFrom < SubjectPublicKeyInfo < ' _ > > for Document {
143
+ impl < ' a : ' k , ' k , Params , Key : ' k > TryFrom < SubjectPublicKeyInfo < Params , Key > > for Document
144
+ where
145
+ Params : Choice < ' a > + Encode ,
146
+ Key : Decode < ' a > + Encode + FixedTag ,
147
+ BitStringRef < ' a > : From < & ' k Key > ,
148
+ {
121
149
type Error = Error ;
122
150
123
- fn try_from ( spki : SubjectPublicKeyInfo < ' _ > ) -> Result < Document > {
151
+ fn try_from ( spki : SubjectPublicKeyInfo < Params , Key > ) -> Result < Document > {
124
152
Self :: try_from ( & spki)
125
153
}
126
154
}
127
155
128
156
#[ cfg( feature = "alloc" ) ]
129
157
#[ cfg_attr( docsrs, doc( cfg( feature = "alloc" ) ) ) ]
130
- impl TryFrom < & SubjectPublicKeyInfo < ' _ > > for Document {
158
+ impl < ' a : ' k , ' k , Params , Key : ' k > TryFrom < & SubjectPublicKeyInfo < Params , Key > > for Document
159
+ where
160
+ Params : Choice < ' a > + Encode ,
161
+ Key : Decode < ' a > + Encode + FixedTag ,
162
+ BitStringRef < ' a > : From < & ' k Key > ,
163
+ {
131
164
type Error = Error ;
132
165
133
- fn try_from ( spki : & SubjectPublicKeyInfo < ' _ > ) -> Result < Document > {
166
+ fn try_from ( spki : & SubjectPublicKeyInfo < Params , Key > ) -> Result < Document > {
134
167
Ok ( Self :: encode_msg ( spki) ?)
135
168
}
136
169
}
137
170
138
171
#[ cfg( feature = "pem" ) ]
139
172
#[ cfg_attr( docsrs, doc( cfg( feature = "pem" ) ) ) ]
140
- impl PemLabel for SubjectPublicKeyInfo < ' _ > {
173
+ impl < Params , Key > PemLabel for SubjectPublicKeyInfo < Params , Key > {
141
174
const PEM_LABEL : & ' static str = "PUBLIC KEY" ;
142
175
}
0 commit comments