2
2
#![ warn( rustdoc:: missing_doc_code_examples) ]
3
3
4
4
use aes:: cipher:: { StreamCipher , generic_array:: GenericArray } ;
5
- use rand:: { SeedableRng , Rng } ;
6
- use rand_chacha;
7
5
8
6
use std:: collections:: HashMap ;
9
7
use std:: fs:: File ;
10
8
use std:: io:: { BufRead , BufReader , Cursor , Read , Write , BufWriter } ;
11
- use std:: path:: Path ;
12
- use std:: sync:: Arc ;
9
+ use std:: path:: PathBuf ;
13
10
14
11
use base64:: engine:: general_purpose;
15
12
use base64:: Engine ;
@@ -57,9 +54,8 @@ lazy_static! {
57
54
. collect( ) ;
58
55
}
59
56
60
- fn read_lines < P > ( filename : P ) -> Result < Vec < String > , Crypt4GHError >
57
+ fn read_lines ( filename : & PathBuf ) -> Result < Vec < String > , Crypt4GHError >
61
58
where
62
- P : AsRef < Path > ,
63
59
{
64
60
let file = File :: open ( filename) ?;
65
61
Ok ( BufReader :: new ( file)
@@ -68,13 +64,14 @@ where
68
64
. collect ( ) )
69
65
}
70
66
71
- fn load_from_pem ( filepath : & ' static Path ) -> Result < Vec < u8 > , Crypt4GHError > {
67
+ fn load_from_pem ( filepath : & PathBuf ) -> Result < Vec < u8 > , Crypt4GHError > {
72
68
// Read lines
73
- let lines = read_lines ( filepath) . map_err ( |e| Crypt4GHError :: ReadLinesError ( filepath. into ( ) , e. into ( ) ) ) ?;
69
+ let lines = read_lines ( & filepath)
70
+ . map_err ( |e| Crypt4GHError :: ReadLinesError ( filepath. to_owned ( ) , Box :: new ( e) ) ) ?;
74
71
75
72
// Check format
76
73
if lines. len ( ) < 3 {
77
- return Err ( Crypt4GHError :: InvalidPEMFormatLength ( filepath) ) ;
74
+ return Err ( Crypt4GHError :: InvalidPEMFormatLength ( filepath. into ( ) ) ) ;
78
75
}
79
76
80
77
if lines. first ( ) . unwrap ( ) . starts_with ( "-----BEGIN " ) ||
@@ -83,7 +80,7 @@ fn load_from_pem(filepath: &'static Path) -> Result<Vec<u8>, Crypt4GHError> {
83
80
}
84
81
85
82
// Decode with base64
86
- general_purpose:: STANDARD . decode ( & lines[ 1 ..lines. len ( ) - 1 ] . join ( "" ) ) . map_err ( |e| Crypt4GHError :: BadBase64Error ( e. into ( ) ) )
83
+ general_purpose:: STANDARD . decode ( & lines[ 1 ..lines. len ( ) - 1 ] . join ( "" ) ) . map_err ( move |e| Crypt4GHError :: BadBase64Error ( e. into ( ) ) )
87
84
}
88
85
89
86
fn decode_string_ssh ( stream : & mut impl BufRead ) -> Result < Vec < u8 > , Crypt4GHError > {
@@ -124,9 +121,10 @@ fn derive_key(
124
121
match alg {
125
122
"scrypt" => {
126
123
// TODO: Review last param of ScryptParams (length of what, exactly?) carefully.
124
+ // TODO: Why is the output not used?
127
125
// Added "dklen" for now since it seemed fitting, but needs proper review.
128
126
let params = scrypt:: Params :: new ( 14 , 8 , 1 , dklen) ;
129
- scrypt:: scrypt (
127
+ let _ = scrypt:: scrypt (
130
128
passphrase. as_bytes ( ) ,
131
129
& salt. unwrap_or_else ( || {
132
130
log:: warn!( "Using default salt = [0_u8; 8]" ) ;
@@ -137,7 +135,7 @@ fn derive_key(
137
135
) ;
138
136
} ,
139
137
"bcrypt" => {
140
- bcrypt_pbkdf:: bcrypt_pbkdf (
138
+ let _ = bcrypt_pbkdf:: bcrypt_pbkdf (
141
139
passphrase. as_bytes ( ) ,
142
140
& salt. unwrap_or_else ( || {
143
141
log:: warn!( "Using default salt = [0_u8; 8]" ) ;
@@ -335,7 +333,8 @@ fn decipher(ciphername: &str, data: &[u8], private_ciphertext: &[u8]) -> Result<
335
333
assert ! ( ( private_ciphertext. len( ) % block_size( ciphername) ?) == 0 ) ;
336
334
337
335
// Decipher
338
- match ciphername {
336
+ // TODO: Why is this match not used? Was it used upstream?
337
+ let _ = match ciphername {
339
338
"aes128-ctr" => {
340
339
type Aes128Ctr = ctr:: Ctr128LE < aes:: Aes128 > ;
341
340
let iv_ga = GenericArray :: from_slice ( iv) ;
@@ -425,41 +424,40 @@ fn get_skpk_from_decrypted_private_blob(blob: &[u8]) -> Result<([u8; 32], [u8; 3
425
424
/// or if the key is not one of the two supported formats. Returns the decode key.
426
425
/// If the key is encrypted, the `callback` should return the passphrase of the key.
427
426
pub fn get_private_key (
428
- key_path : & Path ,
427
+ key_path : PathBuf ,
429
428
callback : impl Fn ( ) -> Result < String , Crypt4GHError > ,
430
429
) -> Result < Vec < u8 > , Crypt4GHError > {
431
- todo ! ( ) ;
432
- // let data = load_from_pem(key_path)?;
433
-
434
- // if data.starts_with(C4GH_MAGIC_WORD) {
435
- // log::info!("Loading a Crypt4GH private key");
436
- // let mut stream = BufReader::new(data.as_slice());
437
- // stream
438
- // .read_exact(&mut [0_u8; C4GH_MAGIC_WORD.len()])
439
- // .map_err(|e| Crypt4GHError::ReadMagicWord(e.into()))?;
440
- // parse_c4gh_private_key(stream, callback)
441
- // }
442
- // else if data.starts_with(SSH_MAGIC_WORD) {
443
- // log::info!("Loading an OpenSSH private key");
444
- // let mut stream = BufReader::new(data.as_slice());
445
- // stream
446
- // .read_exact(&mut [0_u8; SSH_MAGIC_WORD.len()])
447
- // .map_err(|e| Crypt4GHError::ReadMagicWord(e.into()))?;
448
- // let (seckey, pubkey) = parse_ssh_private_key(stream, callback)?;
449
- // Ok(vec![seckey, pubkey].concat())
450
- // }
451
- // else {
452
- // Err(Crypt4GHError::InvalidKeyFormat)
453
- // }
430
+ let data = load_from_pem ( & key_path) ?;
431
+
432
+ if data. starts_with ( C4GH_MAGIC_WORD ) {
433
+ log:: info!( "Loading a Crypt4GH private key" ) ;
434
+ let mut stream = BufReader :: new ( data. as_slice ( ) ) ;
435
+ stream
436
+ . read_exact ( & mut [ 0_u8 ; C4GH_MAGIC_WORD . len ( ) ] )
437
+ . map_err ( |e| Crypt4GHError :: ReadMagicWord ( e. into ( ) ) ) ?;
438
+ parse_c4gh_private_key ( stream, callback)
439
+ }
440
+ else if data. starts_with ( SSH_MAGIC_WORD ) {
441
+ log:: info!( "Loading an OpenSSH private key" ) ;
442
+ let mut stream = BufReader :: new ( data. as_slice ( ) ) ;
443
+ stream
444
+ . read_exact ( & mut [ 0_u8 ; SSH_MAGIC_WORD . len ( ) ] )
445
+ . map_err ( |e| Crypt4GHError :: ReadMagicWord ( e. into ( ) ) ) ?;
446
+ let ( seckey, pubkey) = parse_ssh_private_key ( stream, callback) ?;
447
+ Ok ( vec ! [ seckey, pubkey] . concat ( ) )
448
+ }
449
+ else {
450
+ Err ( Crypt4GHError :: InvalidKeyFormat )
451
+ }
454
452
}
455
453
456
454
/// Reads and decodes the public key stored in `key_path`.
457
455
///
458
456
/// It supports `Crypt4GH` and OpenSSH public keys. Fails if it can not read the file
459
457
/// or if the key is not one of the two supported formats. Returns the decoded key.
460
- pub fn get_public_key ( key_path : & Path ) -> Result < Vec < u8 > , Crypt4GHError > {
458
+ pub fn get_public_key ( key_path : PathBuf ) -> Result < Vec < u8 > , Crypt4GHError > {
461
459
// Read lines from public key file
462
- match read_lines ( key_path) {
460
+ match read_lines ( & key_path) {
463
461
Ok ( lines_vec) => {
464
462
// Empty key
465
463
if lines_vec. is_empty ( ) {
@@ -537,8 +535,8 @@ pub fn generate_private_key() -> Result<Vec<u8>, Crypt4GHError> {
537
535
/// The passphrase callback should return a string that will be used to encode the keys. You can add
538
536
/// an optional comment at the end of the keys.
539
537
pub fn generate_keys (
540
- seckey : & Path ,
541
- pubkey : & Path ,
538
+ seckey : PathBuf ,
539
+ pubkey : PathBuf ,
542
540
passphrase_callback : impl Fn ( ) -> Result < String , Crypt4GHError > ,
543
541
comment : Option < String > ,
544
542
) -> Result < ( ) , Crypt4GHError > {
0 commit comments