@@ -4,15 +4,15 @@ use crate::{Error, Result, Version};
4
4
use core:: fmt;
5
5
use der:: {
6
6
asn1:: { AnyRef , BitStringRef , ContextSpecific , OctetStringRef } ,
7
- Decode , DecodeValue , Encode , EncodeValue , Header , Length , Reader , Sequence , TagMode , TagNumber ,
8
- Writer ,
7
+ Decode , DecodeValue , Encode , EncodeValue , FixedTag , Header , Length , Reader , Sequence , TagMode ,
8
+ TagNumber , Writer ,
9
9
} ;
10
10
use spki:: AlgorithmIdentifier ;
11
11
12
12
#[ cfg( feature = "alloc" ) ]
13
- use {
14
- alloc :: boxed :: Box ,
15
- der :: { asn1 :: Any , SecretDocument } ,
13
+ use der :: {
14
+ asn1 :: { Any , BitString , OctetString } ,
15
+ SecretDocument ,
16
16
} ;
17
17
18
18
#[ cfg( feature = "encryption" ) ]
@@ -92,18 +92,18 @@ const PUBLIC_KEY_TAG: TagNumber = TagNumber::N1;
92
92
/// [RFC 5208 Section 5]: https://tools.ietf.org/html/rfc5208#section-5
93
93
/// [RFC 5958 Section 2]: https://datatracker.ietf.org/doc/html/rfc5958#section-2
94
94
#[ derive( Clone ) ]
95
- pub struct PrivateKeyInfoInner < Params , Key > {
95
+ pub struct PrivateKeyInfoInner < Params , Key , PubKey > {
96
96
/// X.509 `AlgorithmIdentifier` for the private key type.
97
97
pub algorithm : AlgorithmIdentifier < Params > ,
98
98
99
99
/// Private key data.
100
100
pub private_key : Key ,
101
101
102
102
/// Public key data, optionally available if version is V2.
103
- pub public_key : Option < Key > ,
103
+ pub public_key : Option < PubKey > ,
104
104
}
105
105
106
- impl < Params , Key > PrivateKeyInfoInner < Params , Key > {
106
+ impl < Params , Key , PubKey > PrivateKeyInfoInner < Params , Key , PubKey > {
107
107
/// Create a new PKCS#8 [`PrivateKeyInfoInner`] message.
108
108
///
109
109
/// This is a helper method which initializes `attributes` and `public_key`
@@ -127,10 +127,14 @@ impl<Params, Key> PrivateKeyInfoInner<Params, Key> {
127
127
}
128
128
}
129
129
}
130
- impl < ' a , Params , Key > PrivateKeyInfoInner < Params , Key >
130
+
131
+ impl < ' a , Params , Key , PubKey > PrivateKeyInfoInner < Params , Key , PubKey >
131
132
where
132
133
Params : der:: Choice < ' a , Error = der:: Error > + Encode ,
133
- Key : From < & ' a [ u8 ] > + AsRef < [ u8 ] > + ' a ,
134
+ Key : DecodeValue < ' a , Error = der:: Error > + FixedTag + ' a ,
135
+ Key : EncodeValue ,
136
+ PubKey : DecodeValue < ' a , Error = der:: Error > + FixedTag + ' a ,
137
+ PubKey : BitStringLike ,
134
138
{
135
139
/// Encrypt this private key using a symmetric encryption key derived
136
140
/// from the provided password.
@@ -164,30 +168,29 @@ where
164
168
}
165
169
}
166
170
167
- impl < ' a , Params , Key > PrivateKeyInfoInner < Params , Key >
171
+ impl < ' a , Params , Key , PubKey > PrivateKeyInfoInner < Params , Key , PubKey >
168
172
where
169
173
Params : der:: Choice < ' a > + Encode ,
170
- Key : AsRef < [ u8 ] > ,
174
+ PubKey : BitStringLike ,
171
175
{
172
176
/// Get a `BIT STRING` representation of the public key, if present.
173
- fn public_key_bit_string ( & self ) -> der:: Result < Option < ContextSpecific < BitStringRef < ' _ > > > > {
174
- self . public_key
175
- . as_ref ( )
176
- . map ( |pk| {
177
- BitStringRef :: from_bytes ( pk. as_ref ( ) ) . map ( |value| ContextSpecific {
178
- tag_number : PUBLIC_KEY_TAG ,
179
- tag_mode : TagMode :: Implicit ,
180
- value,
181
- } )
182
- } )
183
- . transpose ( )
177
+ fn public_key_bit_string ( & self ) -> Option < ContextSpecific < BitStringRef < ' _ > > > {
178
+ self . public_key . as_ref ( ) . map ( |pk| {
179
+ let value = pk. as_bit_string ( ) ;
180
+ ContextSpecific {
181
+ tag_number : PUBLIC_KEY_TAG ,
182
+ tag_mode : TagMode :: Implicit ,
183
+ value,
184
+ }
185
+ } )
184
186
}
185
187
}
186
188
187
- impl < ' a , Params , Key > DecodeValue < ' a > for PrivateKeyInfoInner < Params , Key >
189
+ impl < ' a , Params , Key , PubKey > DecodeValue < ' a > for PrivateKeyInfoInner < Params , Key , PubKey >
188
190
where
189
191
Params : der:: Choice < ' a , Error = der:: Error > + Encode ,
190
- Key : From < & ' a [ u8 ] > ,
192
+ Key : DecodeValue < ' a , Error = der:: Error > + FixedTag + ' a ,
193
+ PubKey : DecodeValue < ' a , Error = der:: Error > + FixedTag + ' a ,
191
194
{
192
195
type Error = der:: Error ;
193
196
@@ -196,16 +199,9 @@ where
196
199
// Parse and validate `version` INTEGER.
197
200
let version = Version :: decode ( reader) ?;
198
201
let algorithm = reader. decode ( ) ?;
199
- let private_key: & [ u8 ] = OctetStringRef :: decode ( reader) ?. into ( ) ;
200
- let private_key = Key :: try_from ( private_key) ?;
201
- let public_key = reader
202
- . context_specific :: < BitStringRef < ' _ > > ( PUBLIC_KEY_TAG , TagMode :: Implicit ) ?
203
- . map ( |bs| {
204
- bs. as_bytes ( )
205
- . ok_or_else ( || der:: Tag :: BitString . value_error ( ) )
206
- . map ( Key :: from)
207
- } )
208
- . transpose ( ) ?;
202
+ let private_key = Key :: decode ( reader) ?;
203
+ let public_key =
204
+ reader. context_specific :: < PubKey > ( PUBLIC_KEY_TAG , TagMode :: Implicit ) ?;
209
205
210
206
if version. has_public_key ( ) != public_key. is_some ( ) {
211
207
return Err ( reader. error (
@@ -232,38 +228,45 @@ where
232
228
}
233
229
}
234
230
235
- impl < ' a , Params , Key > EncodeValue for PrivateKeyInfoInner < Params , Key >
231
+ impl < ' a , Params , Key , PubKey > EncodeValue for PrivateKeyInfoInner < Params , Key , PubKey >
236
232
where
237
233
Params : der:: Choice < ' a , Error = der:: Error > + Encode ,
238
- Key : AsRef < [ u8 ] > ,
234
+ Key : EncodeValue + FixedTag ,
235
+ PubKey : BitStringLike ,
239
236
{
240
237
fn value_len ( & self ) -> der:: Result < Length > {
241
238
self . version ( ) . encoded_len ( ) ?
242
239
+ self . algorithm . encoded_len ( ) ?
243
- + OctetStringRef :: new ( self . private_key . as_ref ( ) ) ? . encoded_len ( ) ?
244
- + self . public_key_bit_string ( ) ? . encoded_len ( ) ?
240
+ + self . private_key . encoded_len ( ) ?
241
+ + self . public_key_bit_string ( ) . encoded_len ( ) ?
245
242
}
246
243
247
244
fn encode_value ( & self , writer : & mut impl Writer ) -> der:: Result < ( ) > {
248
245
self . version ( ) . encode ( writer) ?;
249
246
self . algorithm . encode ( writer) ?;
250
- OctetStringRef :: new ( self . private_key . as_ref ( ) ) ? . encode ( writer) ?;
251
- self . public_key_bit_string ( ) ? . encode ( writer) ?;
247
+ self . private_key . encode ( writer) ?;
248
+ self . public_key_bit_string ( ) . encode ( writer) ?;
252
249
Ok ( ( ) )
253
250
}
254
251
}
255
252
256
- impl < ' a , Params , Key > Sequence < ' a > for PrivateKeyInfoInner < Params , Key >
253
+ impl < ' a , Params , Key , PubKey > Sequence < ' a > for PrivateKeyInfoInner < Params , Key , PubKey >
257
254
where
258
255
Params : der:: Choice < ' a , Error = der:: Error > + Encode ,
259
- Key : From < & ' a [ u8 ] > + AsRef < [ u8 ] > ,
256
+ Key : DecodeValue < ' a , Error = der:: Error > + FixedTag + ' a ,
257
+ Key : EncodeValue ,
258
+ PubKey : DecodeValue < ' a , Error = der:: Error > + FixedTag + ' a ,
259
+ PubKey : BitStringLike ,
260
260
{
261
261
}
262
262
263
- impl < ' a , Params , Key > TryFrom < & ' a [ u8 ] > for PrivateKeyInfoInner < Params , Key >
263
+ impl < ' a , Params , Key , PubKey > TryFrom < & ' a [ u8 ] > for PrivateKeyInfoInner < Params , Key , PubKey >
264
264
where
265
265
Params : der:: Choice < ' a , Error = der:: Error > + Encode ,
266
- Key : From < & ' a [ u8 ] > + AsRef < [ u8 ] > + ' a ,
266
+ Key : DecodeValue < ' a , Error = der:: Error > + FixedTag + ' a ,
267
+ Key : EncodeValue ,
268
+ PubKey : DecodeValue < ' a , Error = der:: Error > + FixedTag + ' a ,
269
+ PubKey : BitStringLike ,
267
270
{
268
271
type Error = Error ;
269
272
@@ -272,10 +275,10 @@ where
272
275
}
273
276
}
274
277
275
- impl < Params , Key > fmt:: Debug for PrivateKeyInfoInner < Params , Key >
278
+ impl < Params , Key , PubKey > fmt:: Debug for PrivateKeyInfoInner < Params , Key , PubKey >
276
279
where
277
280
Params : fmt:: Debug ,
278
- Key : fmt:: Debug ,
281
+ PubKey : fmt:: Debug ,
279
282
{
280
283
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
281
284
f. debug_struct ( "PrivateKeyInfoInner" )
@@ -287,41 +290,48 @@ where
287
290
}
288
291
289
292
#[ cfg( feature = "alloc" ) ]
290
- impl < ' a , Params , Key > TryFrom < PrivateKeyInfoInner < Params , Key > > for SecretDocument
293
+ impl < ' a , Params , Key , PubKey > TryFrom < PrivateKeyInfoInner < Params , Key , PubKey > > for SecretDocument
291
294
where
292
295
Params : der:: Choice < ' a , Error = der:: Error > + Encode ,
293
- Key : From < & ' a [ u8 ] > + AsRef < [ u8 ] > ,
296
+ Key : DecodeValue < ' a , Error = der:: Error > + FixedTag + ' a ,
297
+ Key : EncodeValue ,
298
+ PubKey : DecodeValue < ' a , Error = der:: Error > + FixedTag + ' a ,
299
+ PubKey : BitStringLike ,
294
300
{
295
301
type Error = Error ;
296
302
297
- fn try_from ( private_key : PrivateKeyInfoInner < Params , Key > ) -> Result < SecretDocument > {
303
+ fn try_from ( private_key : PrivateKeyInfoInner < Params , Key , PubKey > ) -> Result < SecretDocument > {
298
304
SecretDocument :: try_from ( & private_key)
299
305
}
300
306
}
301
307
302
308
#[ cfg( feature = "alloc" ) ]
303
- impl < ' a , Params , Key > TryFrom < & PrivateKeyInfoInner < Params , Key > > for SecretDocument
309
+ impl < ' a , Params , Key , PubKey > TryFrom < & PrivateKeyInfoInner < Params , Key , PubKey > > for SecretDocument
304
310
where
305
311
Params : der:: Choice < ' a , Error = der:: Error > + Encode ,
306
- Key : From < & ' a [ u8 ] > + AsRef < [ u8 ] > ,
312
+ Key : DecodeValue < ' a , Error = der:: Error > + FixedTag + ' a ,
313
+ Key : EncodeValue ,
314
+ PubKey : DecodeValue < ' a , Error = der:: Error > + FixedTag + ' a ,
315
+ PubKey : BitStringLike ,
307
316
{
308
317
type Error = Error ;
309
318
310
- fn try_from ( private_key : & PrivateKeyInfoInner < Params , Key > ) -> Result < SecretDocument > {
319
+ fn try_from ( private_key : & PrivateKeyInfoInner < Params , Key , PubKey > ) -> Result < SecretDocument > {
311
320
Ok ( Self :: encode_msg ( private_key) ?)
312
321
}
313
322
}
314
323
315
324
#[ cfg( feature = "pem" ) ]
316
- impl < Params , Key > PemLabel for PrivateKeyInfoInner < Params , Key > {
325
+ impl < Params , Key , PubKey > PemLabel for PrivateKeyInfoInner < Params , Key , PubKey > {
317
326
const PEM_LABEL : & ' static str = "PRIVATE KEY" ;
318
327
}
319
328
320
329
#[ cfg( feature = "subtle" ) ]
321
- impl < Params , Key > ConstantTimeEq for PrivateKeyInfoInner < Params , Key >
330
+ impl < Params , Key , PubKey > ConstantTimeEq for PrivateKeyInfoInner < Params , Key , PubKey >
322
331
where
323
332
Params : Eq ,
324
333
Key : PartialEq + AsRef < [ u8 ] > ,
334
+ PubKey : PartialEq ,
325
335
{
326
336
fn ct_eq ( & self , other : & Self ) -> Choice {
327
337
// NOTE: public fields are not compared in constant time
@@ -334,36 +344,54 @@ where
334
344
}
335
345
336
346
#[ cfg( feature = "subtle" ) ]
337
- impl < Params , Key > Eq for PrivateKeyInfoInner < Params , Key >
347
+ impl < Params , Key , PubKey > Eq for PrivateKeyInfoInner < Params , Key , PubKey >
338
348
where
339
349
Params : Eq ,
340
350
Key : AsRef < [ u8 ] > + Eq ,
351
+ PubKey : Eq ,
341
352
{
342
353
}
343
354
344
355
#[ cfg( feature = "subtle" ) ]
345
- impl < Params , Key > PartialEq for PrivateKeyInfoInner < Params , Key >
356
+ impl < Params , Key , PubKey > PartialEq for PrivateKeyInfoInner < Params , Key , PubKey >
346
357
where
347
358
Params : Eq ,
348
359
Key : PartialEq + AsRef < [ u8 ] > ,
360
+ PubKey : PartialEq ,
349
361
{
350
362
fn eq ( & self , other : & Self ) -> bool {
351
363
self . ct_eq ( other) . into ( )
352
364
}
353
365
}
354
366
355
367
/// [`PrivateKeyInfoInner`] with [`AnyRef`] algorithm parameters, and `&[u8]` key.
356
- pub type PrivateKeyInfo < ' a > = PrivateKeyInfoInner < AnyRef < ' a > , & ' a [ u8 ] > ;
368
+ pub type PrivateKeyInfo < ' a > = PrivateKeyInfoInner < AnyRef < ' a > , OctetStringRef < ' a > , BitStringRef < ' a > > ;
357
369
358
370
/// [`PrivateKeyInfo`] with [`Any`] algorithm parameters, and `Box<[u8]>` key.
359
371
#[ cfg( feature = "alloc" ) ]
360
- pub type PrivateKeyInfoOwned = PrivateKeyInfoInner < Any , Box < [ u8 ] > > ;
372
+ pub type PrivateKeyInfoOwned = PrivateKeyInfoInner < Any , OctetString , BitString > ;
373
+
374
+ pub trait BitStringLike {
375
+ fn as_bit_string ( & self ) -> BitStringRef < ' _ > ;
376
+ }
377
+
378
+ impl < ' a > BitStringLike for BitStringRef < ' a > {
379
+ fn as_bit_string ( & self ) -> BitStringRef < ' _ > {
380
+ BitStringRef :: from ( self )
381
+ }
382
+ }
361
383
362
384
#[ cfg( feature = "alloc" ) ]
363
385
mod allocating {
364
386
use super :: * ;
365
387
use der:: referenced:: * ;
366
388
389
+ impl BitStringLike for BitString {
390
+ fn as_bit_string ( & self ) -> BitStringRef < ' _ > {
391
+ BitStringRef :: from ( self )
392
+ }
393
+ }
394
+
367
395
impl < ' a > RefToOwned < ' a > for PrivateKeyInfo < ' a > {
368
396
type Owned = PrivateKeyInfoOwned ;
369
397
fn ref_to_owned ( & self ) -> Self :: Owned {
0 commit comments