1
1
#[ cfg( feature = "pem" ) ]
2
2
use pem:: Pem ;
3
+ #[ cfg( feature = "crypto" ) ]
4
+ use pki_types:: PrivatePkcs8KeyDer ;
3
5
use std:: fmt;
4
6
use yasna:: DERWriter ;
5
7
@@ -158,8 +160,14 @@ impl KeyPair {
158
160
/// Parses the key pair from the DER format
159
161
///
160
162
/// Equivalent to using the [`TryFrom`] implementation.
163
+ ///
164
+ /// You can use [`rustls_pemfile::private_key`] to get the `der` input. If
165
+ /// you have already a byte slice, just calling `into()` and take a reference
166
+ /// will convert it to a [`PrivatePkcs8KeyDer`].
167
+ ///
168
+ /// [`rustls_pemfile::private_key`]: https://docs.rs/rustls-pemfile/latest/rustls_pemfile/fn.private_key.html
161
169
#[ cfg( feature = "crypto" ) ]
162
- pub fn from_der ( der : & [ u8 ] ) -> Result < Self , Error > {
170
+ pub fn from_der ( der : & PrivatePkcs8KeyDer < ' _ > ) -> Result < Self , Error > {
163
171
der. try_into ( )
164
172
}
165
173
@@ -169,11 +177,15 @@ impl KeyPair {
169
177
}
170
178
171
179
/// Parses the key pair from the ASCII PEM format
180
+ ///
181
+ /// The key must be a DER-encoded plaintext private key; as specified in PKCS #8/RFC 5958;
182
+ ///
183
+ /// Appears as "PRIVATE KEY" in PEM files.
172
184
#[ cfg( all( feature = "pem" , feature = "crypto" ) ) ]
173
185
pub fn from_pem ( pem_str : & str ) -> Result < Self , Error > {
174
186
let private_key = pem:: parse ( pem_str) . _err ( ) ?;
175
187
let private_key_der: & [ _ ] = private_key. contents ( ) ;
176
- private_key_der. try_into ( )
188
+ Self :: from_der ( & private_key_der. into ( ) )
177
189
}
178
190
179
191
/// Obtains the key pair from a raw public key and a remote private key
@@ -188,6 +200,9 @@ impl KeyPair {
188
200
/// Obtains the key pair from a DER formatted key
189
201
/// using the specified [`SignatureAlgorithm`]
190
202
///
203
+ /// The key must be a DER-encoded plaintext private key; as specified in PKCS #8/RFC 5958;
204
+ ///
205
+ /// Appears as "PRIVATE KEY" in PEM files
191
206
/// Same as [from_pem_and_sign_algo](Self::from_pem_and_sign_algo).
192
207
#[ cfg( all( feature = "pem" , feature = "crypto" ) ) ]
193
208
pub fn from_pem_and_sign_algo (
@@ -196,7 +211,7 @@ impl KeyPair {
196
211
) -> Result < Self , Error > {
197
212
let private_key = pem:: parse ( pem_str) . _err ( ) ?;
198
213
let private_key_der: & [ _ ] = private_key. contents ( ) ;
199
- Self :: from_der_and_sign_algo ( private_key_der, alg)
214
+ Self :: from_der_and_sign_algo ( & PrivatePkcs8KeyDer :: from ( private_key_der) , alg)
200
215
}
201
216
202
217
/// Obtains the key pair from a DER formatted key
@@ -208,39 +223,45 @@ impl KeyPair {
208
223
/// key pair. However, sometimes multiple signature algorithms fit for the
209
224
/// same der key. In that instance, you can use this function to precisely
210
225
/// specify the `SignatureAlgorithm`.
226
+ ///
227
+ /// You can use [`rustls_pemfile::private_key`] to get the `pkcs8` input. If
228
+ /// you have already a byte slice, just calling `into()` and take a reference
229
+ /// will convert it to a [`PrivatePkcs8KeyDer`].
230
+ ///
231
+ /// [`rustls_pemfile::private_key`]: https://docs.rs/rustls-pemfile/latest/rustls_pemfile/fn.private_key.html
211
232
#[ cfg( feature = "crypto" ) ]
212
233
pub fn from_der_and_sign_algo (
213
- pkcs8 : & [ u8 ] ,
234
+ pkcs8 : & PrivatePkcs8KeyDer < ' _ > ,
214
235
alg : & ' static SignatureAlgorithm ,
215
236
) -> Result < Self , Error > {
216
237
let rng = & SystemRandom :: new ( ) ;
217
- let pkcs8_vec = pkcs8. to_vec ( ) ;
238
+ let serialized_der = pkcs8. secret_pkcs8_der ( ) . to_vec ( ) ;
218
239
219
240
let kind = if alg == & PKCS_ED25519 {
220
- KeyPairKind :: Ed ( Ed25519KeyPair :: from_pkcs8_maybe_unchecked ( pkcs8 ) . _err ( ) ?)
241
+ KeyPairKind :: Ed ( Ed25519KeyPair :: from_pkcs8_maybe_unchecked ( & serialized_der ) . _err ( ) ?)
221
242
} else if alg == & PKCS_ECDSA_P256_SHA256 {
222
243
KeyPairKind :: Ec ( ecdsa_from_pkcs8 (
223
244
& signature:: ECDSA_P256_SHA256_ASN1_SIGNING ,
224
- pkcs8 ,
245
+ & serialized_der ,
225
246
rng,
226
247
) ?)
227
248
} else if alg == & PKCS_ECDSA_P384_SHA384 {
228
249
KeyPairKind :: Ec ( ecdsa_from_pkcs8 (
229
250
& signature:: ECDSA_P384_SHA384_ASN1_SIGNING ,
230
- pkcs8 ,
251
+ & serialized_der ,
231
252
rng,
232
253
) ?)
233
254
} else if alg == & PKCS_RSA_SHA256 {
234
- let rsakp = RsaKeyPair :: from_pkcs8 ( pkcs8 ) . _err ( ) ?;
255
+ let rsakp = RsaKeyPair :: from_pkcs8 ( & serialized_der ) . _err ( ) ?;
235
256
KeyPairKind :: Rsa ( rsakp, & signature:: RSA_PKCS1_SHA256 )
236
257
} else if alg == & PKCS_RSA_SHA384 {
237
- let rsakp = RsaKeyPair :: from_pkcs8 ( pkcs8 ) . _err ( ) ?;
258
+ let rsakp = RsaKeyPair :: from_pkcs8 ( & serialized_der ) . _err ( ) ?;
238
259
KeyPairKind :: Rsa ( rsakp, & signature:: RSA_PKCS1_SHA384 )
239
260
} else if alg == & PKCS_RSA_SHA512 {
240
- let rsakp = RsaKeyPair :: from_pkcs8 ( pkcs8 ) . _err ( ) ?;
261
+ let rsakp = RsaKeyPair :: from_pkcs8 ( & serialized_der ) . _err ( ) ?;
241
262
KeyPairKind :: Rsa ( rsakp, & signature:: RSA_PKCS1_SHA512 )
242
263
} else if alg == & PKCS_RSA_PSS_SHA256 {
243
- let rsakp = RsaKeyPair :: from_pkcs8 ( pkcs8 ) . _err ( ) ?;
264
+ let rsakp = RsaKeyPair :: from_pkcs8 ( & serialized_der ) . _err ( ) ?;
244
265
KeyPairKind :: Rsa ( rsakp, & signature:: RSA_PSS_SHA256 )
245
266
} else {
246
267
panic ! ( "Unknown SignatureAlgorithm specified!" ) ;
@@ -249,14 +270,22 @@ impl KeyPair {
249
270
Ok ( KeyPair {
250
271
kind,
251
272
alg,
252
- serialized_der : pkcs8_vec ,
273
+ serialized_der,
253
274
} )
254
275
}
255
276
277
+ /// Parses the key pair from the DER format
278
+ ///
279
+ /// You can use [`rustls_pemfile::private_key`] to get the `pkcs8` input. If
280
+ /// you have already a byte slice, just calling `into()` and take a reference
281
+ /// will convert it to a [`PrivatePkcs8KeyDer`].
282
+ ///
283
+ /// [`rustls_pemfile::private_key`]: https://docs.rs/rustls-pemfile/latest/rustls_pemfile/fn.private_key.html
256
284
#[ cfg( feature = "crypto" ) ]
257
285
pub ( crate ) fn from_raw (
258
- pkcs8 : & [ u8 ] ,
286
+ pkcs8 : & PrivatePkcs8KeyDer ,
259
287
) -> Result < ( KeyPairKind , & ' static SignatureAlgorithm ) , Error > {
288
+ let pkcs8 = pkcs8. secret_pkcs8_der ( ) ;
260
289
let rng = SystemRandom :: new ( ) ;
261
290
let ( kind, alg) = if let Ok ( edkp) = Ed25519KeyPair :: from_pkcs8_maybe_unchecked ( pkcs8) {
262
291
( KeyPairKind :: Ed ( edkp) , & PKCS_ED25519 )
@@ -399,7 +428,7 @@ impl TryFrom<&[u8]> for KeyPair {
399
428
type Error = Error ;
400
429
401
430
fn try_from ( pkcs8 : & [ u8 ] ) -> Result < KeyPair , Error > {
402
- let ( kind, alg) = KeyPair :: from_raw ( pkcs8) ?;
431
+ let ( kind, alg) = KeyPair :: from_raw ( & pkcs8. into ( ) ) ?;
403
432
Ok ( KeyPair {
404
433
kind,
405
434
alg,
@@ -413,7 +442,7 @@ impl TryFrom<Vec<u8>> for KeyPair {
413
442
type Error = Error ;
414
443
415
444
fn try_from ( pkcs8 : Vec < u8 > ) -> Result < KeyPair , Error > {
416
- let ( kind, alg) = KeyPair :: from_raw ( pkcs8. as_slice ( ) ) ?;
445
+ let ( kind, alg) = KeyPair :: from_raw ( & pkcs8. as_slice ( ) . into ( ) ) ?;
417
446
Ok ( KeyPair {
418
447
kind,
419
448
alg,
@@ -422,6 +451,20 @@ impl TryFrom<Vec<u8>> for KeyPair {
422
451
}
423
452
}
424
453
454
+ #[ cfg( feature = "crypto" ) ]
455
+ impl TryFrom < & PrivatePkcs8KeyDer < ' _ > > for KeyPair {
456
+ type Error = Error ;
457
+
458
+ fn try_from ( pkcs8 : & PrivatePkcs8KeyDer ) -> Result < KeyPair , Error > {
459
+ let ( kind, alg) = KeyPair :: from_raw ( pkcs8) ?;
460
+ Ok ( KeyPair {
461
+ kind,
462
+ alg,
463
+ serialized_der : pkcs8. secret_pkcs8_der ( ) . into ( ) ,
464
+ } )
465
+ }
466
+ }
467
+
425
468
/// The key size used for RSA key generation
426
469
#[ cfg( all( feature = "crypto" , feature = "aws_lc_rs" , not( feature = "ring" ) ) ) ]
427
470
#[ derive( Debug , Copy , Clone , PartialEq , Eq , Hash ) ]
0 commit comments