@@ -7,6 +7,7 @@ use std::convert::TryFrom;
77use std:: fmt;
88use yasna:: DERWriter ;
99
10+ use crate :: error:: ExternalError ;
1011use crate :: sign_algo:: algo:: * ;
1112use crate :: sign_algo:: SignAlgo ;
1213#[ cfg( feature = "pem" ) ]
@@ -58,14 +59,16 @@ impl KeyPair {
5859 pub fn from_der ( der : & [ u8 ] ) -> Result < Self , Error > {
5960 Ok ( der. try_into ( ) ?)
6061 }
62+
6163 /// Returns the key pair's signature algorithm
6264 pub fn algorithm ( & self ) -> & ' static SignatureAlgorithm {
6365 self . alg
6466 }
67+
6568 /// Parses the key pair from the ASCII PEM format
6669 #[ cfg( feature = "pem" ) ]
6770 pub fn from_pem ( pem_str : & str ) -> Result < Self , Error > {
68- let private_key = pem:: parse ( pem_str) ?;
71+ let private_key = pem:: parse ( pem_str) . _err ( ) ?;
6972 let private_key_der: & [ _ ] = private_key. contents ( ) ;
7073 Ok ( private_key_der. try_into ( ) ?)
7174 }
@@ -88,7 +91,7 @@ impl KeyPair {
8891 pem_str : & str ,
8992 alg : & ' static SignatureAlgorithm ,
9093 ) -> Result < Self , Error > {
91- let private_key = pem:: parse ( pem_str) ?;
94+ let private_key = pem:: parse ( pem_str) . _err ( ) ?;
9295 let private_key_der: & [ _ ] = private_key. contents ( ) ;
9396 Ok ( Self :: from_der_and_sign_algo ( private_key_der, alg) ?)
9497 }
@@ -110,30 +113,28 @@ impl KeyPair {
110113 let pkcs8_vec = pkcs8. to_vec ( ) ;
111114
112115 let kind = if alg == & PKCS_ED25519 {
113- KeyPairKind :: Ed ( Ed25519KeyPair :: from_pkcs8_maybe_unchecked ( pkcs8) ?)
116+ KeyPairKind :: Ed ( Ed25519KeyPair :: from_pkcs8_maybe_unchecked ( pkcs8) . _err ( ) ?)
114117 } else if alg == & PKCS_ECDSA_P256_SHA256 {
115- KeyPairKind :: Ec ( EcdsaKeyPair :: from_pkcs8 (
116- & signature:: ECDSA_P256_SHA256_ASN1_SIGNING ,
117- pkcs8,
118- rng,
119- ) ?)
118+ KeyPairKind :: Ec (
119+ EcdsaKeyPair :: from_pkcs8 ( & signature:: ECDSA_P256_SHA256_ASN1_SIGNING , pkcs8, rng)
120+ . _err ( ) ?,
121+ )
120122 } else if alg == & PKCS_ECDSA_P384_SHA384 {
121- KeyPairKind :: Ec ( EcdsaKeyPair :: from_pkcs8 (
122- & signature:: ECDSA_P384_SHA384_ASN1_SIGNING ,
123- pkcs8,
124- rng,
125- ) ?)
123+ KeyPairKind :: Ec (
124+ EcdsaKeyPair :: from_pkcs8 ( & signature:: ECDSA_P384_SHA384_ASN1_SIGNING , pkcs8, rng)
125+ . _err ( ) ?,
126+ )
126127 } else if alg == & PKCS_RSA_SHA256 {
127- let rsakp = RsaKeyPair :: from_pkcs8 ( pkcs8) ?;
128+ let rsakp = RsaKeyPair :: from_pkcs8 ( pkcs8) . _err ( ) ?;
128129 KeyPairKind :: Rsa ( rsakp, & signature:: RSA_PKCS1_SHA256 )
129130 } else if alg == & PKCS_RSA_SHA384 {
130- let rsakp = RsaKeyPair :: from_pkcs8 ( pkcs8) ?;
131+ let rsakp = RsaKeyPair :: from_pkcs8 ( pkcs8) . _err ( ) ?;
131132 KeyPairKind :: Rsa ( rsakp, & signature:: RSA_PKCS1_SHA384 )
132133 } else if alg == & PKCS_RSA_SHA512 {
133- let rsakp = RsaKeyPair :: from_pkcs8 ( pkcs8) ?;
134+ let rsakp = RsaKeyPair :: from_pkcs8 ( pkcs8) . _err ( ) ?;
134135 KeyPairKind :: Rsa ( rsakp, & signature:: RSA_PKCS1_SHA512 )
135136 } else if alg == & PKCS_RSA_PSS_SHA256 {
136- let rsakp = RsaKeyPair :: from_pkcs8 ( pkcs8) ?;
137+ let rsakp = RsaKeyPair :: from_pkcs8 ( pkcs8) . _err ( ) ?;
137138 KeyPairKind :: Rsa ( rsakp, & signature:: RSA_PSS_SHA256 )
138139 } else {
139140 panic ! ( "Unknown SignatureAlgorithm specified!" ) ;
@@ -170,57 +171,14 @@ impl KeyPair {
170171 } ;
171172 Ok ( ( kind, alg) )
172173 }
173- }
174-
175- /// A private key that is not directly accessible, but can be used to sign messages
176- ///
177- /// Trait objects based on this trait can be passed to the [`KeyPair::from_remote`] function for generating certificates
178- /// from a remote and raw private key, for example an HSM.
179- pub trait RemoteKeyPair {
180- /// Returns the public key of this key pair in the binary format as in [`KeyPair::public_key_raw`]
181- fn public_key ( & self ) -> & [ u8 ] ;
182174
183- /// Signs `msg` using the selected algorithm
184- fn sign ( & self , msg : & [ u8 ] ) -> Result < Vec < u8 > , Error > ;
185-
186- /// Reveals the algorithm to be used when calling `sign()`
187- fn algorithm ( & self ) -> & ' static SignatureAlgorithm ;
188- }
189-
190- impl TryFrom < & [ u8 ] > for KeyPair {
191- type Error = Error ;
192-
193- fn try_from ( pkcs8 : & [ u8 ] ) -> Result < KeyPair , Error > {
194- let ( kind, alg) = KeyPair :: from_raw ( pkcs8) ?;
195- Ok ( KeyPair {
196- kind,
197- alg,
198- serialized_der : pkcs8. to_vec ( ) ,
199- } )
200- }
201- }
202-
203- impl TryFrom < Vec < u8 > > for KeyPair {
204- type Error = Error ;
205-
206- fn try_from ( pkcs8 : Vec < u8 > ) -> Result < KeyPair , Error > {
207- let ( kind, alg) = KeyPair :: from_raw ( pkcs8. as_slice ( ) ) ?;
208- Ok ( KeyPair {
209- kind,
210- alg,
211- serialized_der : pkcs8,
212- } )
213- }
214- }
215-
216- impl KeyPair {
217175 /// Generate a new random key pair for the specified signature algorithm
218176 pub fn generate ( alg : & ' static SignatureAlgorithm ) -> Result < Self , Error > {
219177 let rng = & SystemRandom :: new ( ) ;
220178
221179 match alg. sign_alg {
222180 SignAlgo :: EcDsa ( sign_alg) => {
223- let key_pair_doc = EcdsaKeyPair :: generate_pkcs8 ( sign_alg, rng) ?;
181+ let key_pair_doc = EcdsaKeyPair :: generate_pkcs8 ( sign_alg, rng) . _err ( ) ?;
224182 let key_pair_serialized = key_pair_doc. as_ref ( ) . to_vec ( ) ;
225183
226184 let key_pair =
@@ -232,7 +190,7 @@ impl KeyPair {
232190 } )
233191 } ,
234192 SignAlgo :: EdDsa ( _sign_alg) => {
235- let key_pair_doc = Ed25519KeyPair :: generate_pkcs8 ( rng) ?;
193+ let key_pair_doc = Ed25519KeyPair :: generate_pkcs8 ( rng) . _err ( ) ?;
236194 let key_pair_serialized = key_pair_doc. as_ref ( ) . to_vec ( ) ;
237195
238196 let key_pair = Ed25519KeyPair :: from_pkcs8 ( & & key_pair_doc. as_ref ( ) ) . unwrap ( ) ;
@@ -248,6 +206,7 @@ impl KeyPair {
248206 SignAlgo :: Rsa ( ) => Err ( Error :: KeyGenerationUnavailable ) ,
249207 }
250208 }
209+
251210 /// Get the raw public key of this key pair
252211 ///
253212 /// The key is in raw format, as how [`ring::signature::KeyPair::public_key`]
@@ -256,20 +215,23 @@ impl KeyPair {
256215 pub fn public_key_raw ( & self ) -> & [ u8 ] {
257216 self . raw_bytes ( )
258217 }
218+
259219 /// Check if this key pair can be used with the given signature algorithm
260220 pub fn is_compatible ( & self , signature_algorithm : & SignatureAlgorithm ) -> bool {
261221 self . alg == signature_algorithm
262222 }
223+
263224 /// Returns (possibly multiple) compatible [`SignatureAlgorithm`]'s
264225 /// that the key can be used with
265226 pub fn compatible_algs ( & self ) -> impl Iterator < Item = & ' static SignatureAlgorithm > {
266227 std:: iter:: once ( self . alg )
267228 }
229+
268230 pub ( crate ) fn sign ( & self , msg : & [ u8 ] , writer : DERWriter ) -> Result < ( ) , Error > {
269231 match & self . kind {
270232 KeyPairKind :: Ec ( kp) => {
271233 let system_random = SystemRandom :: new ( ) ;
272- let signature = kp. sign ( & system_random, msg) ?;
234+ let signature = kp. sign ( & system_random, msg) . _err ( ) ?;
273235 let sig = & signature. as_ref ( ) ;
274236 writer. write_bitvec_bytes ( & sig, & sig. len ( ) * 8 ) ;
275237 } ,
@@ -281,7 +243,8 @@ impl KeyPair {
281243 KeyPairKind :: Rsa ( kp, padding_alg) => {
282244 let system_random = SystemRandom :: new ( ) ;
283245 let mut signature = vec ! [ 0 ; kp. public( ) . modulus_len( ) ] ;
284- kp. sign ( * padding_alg, & system_random, msg, & mut signature) ?;
246+ kp. sign ( * padding_alg, & system_random, msg, & mut signature)
247+ . _err ( ) ?;
285248 let sig = & signature. as_ref ( ) ;
286249 writer. write_bitvec_bytes ( & sig, & sig. len ( ) * 8 ) ;
287250 } ,
@@ -292,6 +255,7 @@ impl KeyPair {
292255 }
293256 Ok ( ( ) )
294257 }
258+
295259 /// Return the key pair's public key in DER format
296260 ///
297261 /// The key is formatted according to the SubjectPublicKeyInfo struct of
@@ -300,6 +264,7 @@ impl KeyPair {
300264 pub fn public_key_der ( & self ) -> Vec < u8 > {
301265 yasna:: construct_der ( |writer| self . serialize_public_key_der ( writer) )
302266 }
267+
303268 /// Return the key pair's public key in PEM format
304269 ///
305270 /// The returned string can be interpreted with `openssl pkey --inform PEM -pubout -pubin -text`
@@ -309,6 +274,7 @@ impl KeyPair {
309274 let p = Pem :: new ( "PUBLIC KEY" , contents) ;
310275 pem:: encode_config ( & p, ENCODE_CONFIG )
311276 }
277+
312278 /// Serializes the key pair (including the private key) in PKCS#8 format in DER
313279 ///
314280 /// Panics if called on a remote key pair.
@@ -350,6 +316,32 @@ impl KeyPair {
350316 }
351317}
352318
319+ impl TryFrom < & [ u8 ] > for KeyPair {
320+ type Error = Error ;
321+
322+ fn try_from ( pkcs8 : & [ u8 ] ) -> Result < KeyPair , Error > {
323+ let ( kind, alg) = KeyPair :: from_raw ( pkcs8) ?;
324+ Ok ( KeyPair {
325+ kind,
326+ alg,
327+ serialized_der : pkcs8. to_vec ( ) ,
328+ } )
329+ }
330+ }
331+
332+ impl TryFrom < Vec < u8 > > for KeyPair {
333+ type Error = Error ;
334+
335+ fn try_from ( pkcs8 : Vec < u8 > ) -> Result < KeyPair , Error > {
336+ let ( kind, alg) = KeyPair :: from_raw ( pkcs8. as_slice ( ) ) ?;
337+ Ok ( KeyPair {
338+ kind,
339+ alg,
340+ serialized_der : pkcs8,
341+ } )
342+ }
343+ }
344+
353345impl PublicKeyData for KeyPair {
354346 fn alg ( & self ) -> & SignatureAlgorithm {
355347 self . alg
@@ -364,9 +356,44 @@ impl PublicKeyData for KeyPair {
364356 }
365357}
366358
359+ /// A private key that is not directly accessible, but can be used to sign messages
360+ ///
361+ /// Trait objects based on this trait can be passed to the [`KeyPair::from_remote`] function for generating certificates
362+ /// from a remote and raw private key, for example an HSM.
363+ pub trait RemoteKeyPair {
364+ /// Returns the public key of this key pair in the binary format as in [`KeyPair::public_key_raw`]
365+ fn public_key ( & self ) -> & [ u8 ] ;
366+
367+ /// Signs `msg` using the selected algorithm
368+ fn sign ( & self , msg : & [ u8 ] ) -> Result < Vec < u8 > , Error > ;
369+
370+ /// Reveals the algorithm to be used when calling `sign()`
371+ fn algorithm ( & self ) -> & ' static SignatureAlgorithm ;
372+ }
373+
374+ impl < T > ExternalError < T > for Result < T , ring:: error:: KeyRejected > {
375+ fn _err ( self ) -> Result < T , Error > {
376+ self . map_err ( |e| Error :: RingKeyRejected ( e. to_string ( ) ) )
377+ }
378+ }
379+
380+ impl < T > ExternalError < T > for Result < T , ring:: error:: Unspecified > {
381+ fn _err ( self ) -> Result < T , Error > {
382+ self . map_err ( |_| Error :: RingUnspecified )
383+ }
384+ }
385+
386+ impl < T > ExternalError < T > for Result < T , pem:: PemError > {
387+ fn _err ( self ) -> Result < T , Error > {
388+ self . map_err ( |e| Error :: PemError ( e. to_string ( ) ) )
389+ }
390+ }
391+
367392pub ( crate ) trait PublicKeyData {
368393 fn alg ( & self ) -> & SignatureAlgorithm ;
394+
369395 fn raw_bytes ( & self ) -> & [ u8 ] ;
396+
370397 fn serialize_public_key_der ( & self , writer : DERWriter ) {
371398 writer. write_sequence ( |writer| {
372399 self . alg ( ) . write_oids_sign_alg ( writer. next ( ) ) ;
0 commit comments