From 45b732af3978c4348d051446b9c8623305e6f448 Mon Sep 17 00:00:00 2001 From: Hampus Lidin Date: Thu, 10 Feb 2022 09:42:42 +0100 Subject: [PATCH 1/2] Implement fingerprint randomart generation --- assets/openssh_dsa.randomart | 11 +++ assets/openssh_dsa_enc.randomart | 11 +++ assets/openssh_ecdsa.randomart | 11 +++ assets/openssh_ecdsa_enc.randomart | 11 +++ assets/openssh_ed25519.randomart | 11 +++ assets/openssh_ed25519_enc.randomart | 11 +++ assets/openssh_rsa.randomart | 11 +++ assets/openssh_rsa_enc.randomart | 11 +++ assets/pem_dsa.randomart | 11 +++ assets/pem_dsa_enc.randomart | 11 +++ assets/pem_ecdsa.randomart | 11 +++ assets/pem_ecdsa_enc.randomart | 11 +++ assets/pem_rsa.randomart | 11 +++ assets/pem_rsa_enc.randomart | 11 +++ assets/pkcs8_rsa.randomart | 11 +++ assets/pkcs8_rsa_enc.randomart | 11 +++ src/keys/dsa.rs | 10 ++ src/keys/ecdsa.rs | 10 ++ src/keys/ed25519.rs | 10 ++ src/keys/mod.rs | 141 ++++++++++++++++++++++++++- src/keys/rsa.rs | 10 ++ tests/keyfiles.rs | 5 + tests/utils.rs | 8 ++ 23 files changed, 369 insertions(+), 1 deletion(-) create mode 100644 assets/openssh_dsa.randomart create mode 100644 assets/openssh_dsa_enc.randomart create mode 100644 assets/openssh_ecdsa.randomart create mode 100644 assets/openssh_ecdsa_enc.randomart create mode 100644 assets/openssh_ed25519.randomart create mode 100644 assets/openssh_ed25519_enc.randomart create mode 100644 assets/openssh_rsa.randomart create mode 100644 assets/openssh_rsa_enc.randomart create mode 100644 assets/pem_dsa.randomart create mode 100644 assets/pem_dsa_enc.randomart create mode 100644 assets/pem_ecdsa.randomart create mode 100644 assets/pem_ecdsa_enc.randomart create mode 100644 assets/pem_rsa.randomart create mode 100644 assets/pem_rsa_enc.randomart create mode 100644 assets/pkcs8_rsa.randomart create mode 100644 assets/pkcs8_rsa_enc.randomart diff --git a/assets/openssh_dsa.randomart b/assets/openssh_dsa.randomart new file mode 100644 index 0000000..0f0c3c3 --- /dev/null +++ b/assets/openssh_dsa.randomart @@ -0,0 +1,11 @@ ++---[DSA 1024]----+ +| .=+ | +| ..... . | +| .+oo . .o | +| .== + o++o | +| .==+ =+S=.. | +|.+Eo...+*.o | +|+ . +.=. | +| . . +... . | +| .o .. .o | ++----[SHA256]-----+ \ No newline at end of file diff --git a/assets/openssh_dsa_enc.randomart b/assets/openssh_dsa_enc.randomart new file mode 100644 index 0000000..4be6840 --- /dev/null +++ b/assets/openssh_dsa_enc.randomart @@ -0,0 +1,11 @@ ++---[DSA 1024]----+ +| | +| | +| E o| +| . . = | +| . . S. o = o| +| . o ooo . * @.| +| o o.... + @ +| +| o.+=o+ o * + | +| B+.+.*=o o.+| ++----[SHA256]-----+ \ No newline at end of file diff --git a/assets/openssh_ecdsa.randomart b/assets/openssh_ecdsa.randomart new file mode 100644 index 0000000..5bab968 --- /dev/null +++ b/assets/openssh_ecdsa.randomart @@ -0,0 +1,11 @@ ++---[ECDSA 256]---+ +| . o=++++ .o.| +| + ..+..= =o.o| +| o + .++ * o=*| +| + o .+ * . +B| +| . . oS.E + .o+| +| . . .o o +| +| . . . | +| | +| | ++----[SHA256]-----+ \ No newline at end of file diff --git a/assets/openssh_ecdsa_enc.randomart b/assets/openssh_ecdsa_enc.randomart new file mode 100644 index 0000000..a59874b --- /dev/null +++ b/assets/openssh_ecdsa_enc.randomart @@ -0,0 +1,11 @@ ++---[ECDSA 384]---+ +| . ..+| +| . . o .=| +| . . o o o o ...| +| o . + O o = .| +| . o S X o + =| +| . * + o Bo| +| E o o.*| +| . +o*| +| .. OO| ++----[SHA256]-----+ \ No newline at end of file diff --git a/assets/openssh_ed25519.randomart b/assets/openssh_ed25519.randomart new file mode 100644 index 0000000..941e999 --- /dev/null +++ b/assets/openssh_ed25519.randomart @@ -0,0 +1,11 @@ ++--[ED25519 256]--+ +| .... . =.| +| o+o. . o . =E*| +| o=+.+ + o o =.| +| ++..o + . + | +| ... + S + o | +| .+ o . . o | +| .o o o . | +|.....=. | +| ++oo+o | ++----[SHA256]-----+ \ No newline at end of file diff --git a/assets/openssh_ed25519_enc.randomart b/assets/openssh_ed25519_enc.randomart new file mode 100644 index 0000000..8aaa864 --- /dev/null +++ b/assets/openssh_ed25519_enc.randomart @@ -0,0 +1,11 @@ ++--[ED25519 256]--+ +| . | +|E o | +|++. . | +|@o+ . . | +|=X+.o + S | +|.=+= = + . | +| @ = + . | +|.=o% o | +|++O*+ | ++----[SHA256]-----+ \ No newline at end of file diff --git a/assets/openssh_rsa.randomart b/assets/openssh_rsa.randomart new file mode 100644 index 0000000..6a44c20 --- /dev/null +++ b/assets/openssh_rsa.randomart @@ -0,0 +1,11 @@ ++---[RSA 2048]----+ +| | +| o | +| . . o . | +| o . . . | +| o . S . | +|oo. .. . . | +|+=*+E= . o | +|B@=*= * . | +|#@@*==.. | ++----[SHA256]-----+ \ No newline at end of file diff --git a/assets/openssh_rsa_enc.randomart b/assets/openssh_rsa_enc.randomart new file mode 100644 index 0000000..b728aa9 --- /dev/null +++ b/assets/openssh_rsa_enc.randomart @@ -0,0 +1,11 @@ ++---[RSA 2048]----+ +|o . .. | +|.+ o . . . | +|... E . . o | +|+ o o o. + | +|Bo .. S oo + | +|+O.o + .* o | +|++B o o . * | +|++.* . o | +|ooo.+ .. | ++----[SHA256]-----+ \ No newline at end of file diff --git a/assets/pem_dsa.randomart b/assets/pem_dsa.randomart new file mode 100644 index 0000000..7715b59 --- /dev/null +++ b/assets/pem_dsa.randomart @@ -0,0 +1,11 @@ ++---[DSA 1024]----+ +|B=o**BOo. | +|+*B +Eoo. | +|O+.= . +o | +|*.. o o+. | +| + ooSo | +| + o .oo o | +| + o | +| | +| | ++----[SHA256]-----+ \ No newline at end of file diff --git a/assets/pem_dsa_enc.randomart b/assets/pem_dsa_enc.randomart new file mode 100644 index 0000000..9c4a3cc --- /dev/null +++ b/assets/pem_dsa_enc.randomart @@ -0,0 +1,11 @@ ++---[DSA 1024]----+ +| + o+.. | +|o *.oo | +| = = . | +|o =o.. + . | +|+=E.o S o . | +|+=+. o o | +|+=B. | +|B*oo | +|BBBo | ++----[SHA256]-----+ \ No newline at end of file diff --git a/assets/pem_ecdsa.randomart b/assets/pem_ecdsa.randomart new file mode 100644 index 0000000..7df0a2f --- /dev/null +++ b/assets/pem_ecdsa.randomart @@ -0,0 +1,11 @@ ++---[ECDSA 256]---+ +|@*=. .*.... | +|*=@+o + +.. | +|=@=O.. +o+ | +|=+Eo* .o+o. | +|. o . S. . | +| . | +| | +| | +| | ++----[SHA256]-----+ \ No newline at end of file diff --git a/assets/pem_ecdsa_enc.randomart b/assets/pem_ecdsa_enc.randomart new file mode 100644 index 0000000..b5ed89b --- /dev/null +++ b/assets/pem_ecdsa_enc.randomart @@ -0,0 +1,11 @@ ++---[ECDSA 256]---+ +| E+ o.**oo++ | +| . . *==oo.....| +| o BoO . +.+| +| . = % = o o+| +| o S = o o .| +| o o . | +| + . | +| o | +| | ++----[SHA256]-----+ \ No newline at end of file diff --git a/assets/pem_rsa.randomart b/assets/pem_rsa.randomart new file mode 100644 index 0000000..6a44c20 --- /dev/null +++ b/assets/pem_rsa.randomart @@ -0,0 +1,11 @@ ++---[RSA 2048]----+ +| | +| o | +| . . o . | +| o . . . | +| o . S . | +|oo. .. . . | +|+=*+E= . o | +|B@=*= * . | +|#@@*==.. | ++----[SHA256]-----+ \ No newline at end of file diff --git a/assets/pem_rsa_enc.randomart b/assets/pem_rsa_enc.randomart new file mode 100644 index 0000000..95aaf63 --- /dev/null +++ b/assets/pem_rsa_enc.randomart @@ -0,0 +1,11 @@ ++---[RSA 2048]----+ +| ...E==+=| +| .+.* ooo.| +| ...* = ..| +| +.o + .o | +| o S o o =oo| +| o = = o.==| +| o o . .o=| +| ++| +| .+| ++----[SHA256]-----+ \ No newline at end of file diff --git a/assets/pkcs8_rsa.randomart b/assets/pkcs8_rsa.randomart new file mode 100644 index 0000000..26d5ae8 --- /dev/null +++ b/assets/pkcs8_rsa.randomart @@ -0,0 +1,11 @@ ++---[RSA 4096]----+ +| .oX%==o+=E+| +| oo*OBO..o =| +| =o.@ o .. | +| .ooo = . ..| +| o.So o .| +| . . | +| | +| | +| | ++----[SHA256]-----+ \ No newline at end of file diff --git a/assets/pkcs8_rsa_enc.randomart b/assets/pkcs8_rsa_enc.randomart new file mode 100644 index 0000000..79d0ea0 --- /dev/null +++ b/assets/pkcs8_rsa_enc.randomart @@ -0,0 +1,11 @@ ++---[RSA 4096]----+ +| | +| . . | +| + | +| + . | +| = S. | +| . Bo+. | +| ..o.+..Bo+ | +|.o*+oo+oo=.o | +|.*X@B+o+o.++E | ++----[SHA256]-----+ \ No newline at end of file diff --git a/src/keys/dsa.rs b/src/keys/dsa.rs index 54d47f4..b3ecdcd 100644 --- a/src/keys/dsa.rs +++ b/src/keys/dsa.rs @@ -10,6 +10,8 @@ use std::fmt; /// The key name returned by [`Key::keyname()`](../trait.Key.html#method.keyname) pub const DSA_NAME: &str = "ssh-dss"; +/// The key name returned by [`Key::short_keyname()`](../trait.Key.html#method.short_keyname) +pub const DSA_SHORT_NAME: &str = "DSA"; /// Represent the DSA public key #[derive(Debug, Clone)] @@ -51,6 +53,10 @@ impl Key for DsaPublicKey { fn keyname(&self) -> &'static str { DSA_NAME } + + fn short_keyname(&self) -> &'static str { + DSA_SHORT_NAME + } } impl PublicParts for DsaPublicKey { @@ -128,6 +134,10 @@ impl Key for DsaKeyPair { fn keyname(&self) -> &'static str { DSA_NAME } + + fn short_keyname(&self) -> &'static str { + DSA_SHORT_NAME + } } impl PublicParts for DsaKeyPair { diff --git a/src/keys/ecdsa.rs b/src/keys/ecdsa.rs index 428656a..c7d1f6b 100644 --- a/src/keys/ecdsa.rs +++ b/src/keys/ecdsa.rs @@ -18,6 +18,8 @@ pub const NIST_P256_NAME: &str = "ecdsa-sha2-nistp256"; pub const NIST_P384_NAME: &str = "ecdsa-sha2-nistp384"; /// The name of 521 bits curve key returned by [`Key::keyname()`](../trait.Key.html#method.keyname) pub const NIST_P521_NAME: &str = "ecdsa-sha2-nistp521"; +/// The short name of ECDSA returned by [`Key::short_keyname()`](../trait.Key.html#method.short_keyname) +pub const ECDSA_SHORT_NAME: &str = "ECDSA"; /// An enum of the supported elliptic curves #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -155,6 +157,10 @@ impl Key for EcDsaPublicKey { fn keyname(&self) -> &'static str { self.curve.name() } + + fn short_keyname(&self) -> &'static str { + ECDSA_SHORT_NAME + } } impl PublicParts for EcDsaPublicKey { @@ -277,6 +283,10 @@ impl Key for EcDsaKeyPair { fn keyname(&self) -> &'static str { self.curve.name() } + + fn short_keyname(&self) -> &'static str { + ECDSA_SHORT_NAME + } } impl PublicParts for EcDsaKeyPair { diff --git a/src/keys/ed25519.rs b/src/keys/ed25519.rs index 57b30d5..c6d2614 100644 --- a/src/keys/ed25519.rs +++ b/src/keys/ed25519.rs @@ -18,6 +18,8 @@ use std::{convert::TryFrom, fmt}; /// The key name returned by [`Key::keyname()`](../trait.Key.html#method.keyname) pub const ED25519_NAME: &str = "ssh-ed25519"; +/// The short key name returned by [`Key::short_keyname()`](../trait.Key.html#method.short_keyname) +pub const ED25519_SHORT_NAME: &str = "ED25519"; /// Represent the Ed25519 public key #[derive(Debug, Clone)] @@ -42,6 +44,10 @@ impl Key for Ed25519PublicKey { fn keyname(&self) -> &'static str { ED25519_NAME } + + fn short_keyname(&self) -> &'static str { + ED25519_SHORT_NAME + } } impl PublicParts for Ed25519PublicKey { @@ -80,6 +86,10 @@ impl Key for Ed25519KeyPair { fn keyname(&self) -> &'static str { ED25519_NAME } + + fn short_keyname(&self) -> &'static str { + ED25519_SHORT_NAME + } } impl Ed25519KeyPair { diff --git a/src/keys/mod.rs b/src/keys/mod.rs index 9e6547e..911c111 100644 --- a/src/keys/mod.rs +++ b/src/keys/mod.rs @@ -20,9 +20,18 @@ pub mod ed25519; /// RSA key type pub mod rsa; +/// The name of the MD5 hashing algorithm returned by [`FingerprintHash::name()`](enum.FingerprintHash.html#method.name) +pub const MD5_NAME: &str = "MD5"; +/// The name of the sha2-256 algorithm returned by [`FingerprintHash::name()`](enum.FingerprintHash.html#method.name) +pub const SHA256_NAME: &str = "SHA256"; +/// The name of the sha2-512 algorithm returned by [`FingerprintHash::name()`](enum.FingerprintHash.html#method.name) +pub const SHA512_NAME: &str = "SHA512"; + /// An enum representing the hash function used to generate fingerprint /// -/// Used with [`PublicPart::fingerprint()`](trait.PublicPart.html#method.fingerprint) to generate different types fingerprint. +/// Used with [`PublicPart::fingerprint()`](trait.PublicPart.html#method.fingerprint) and +/// [`PublicPart::fingerprint_randomart()`](trait.PublicPart.html#method.fingerprint) to generate +/// different types fingerprint and randomarts. /// /// # Hash Algorithm /// MD5: This is the default fingerprint type in older versions of openssh. @@ -49,6 +58,13 @@ impl FingerprintHash { FingerprintHash::SHA512 => digest_hash(&mut Sha512::default(), data), } } + fn name(self) -> &'static str { + match self { + FingerprintHash::MD5 => MD5_NAME, + FingerprintHash::SHA256 => SHA256_NAME, + FingerprintHash::SHA512 => SHA512_NAME, + } + } } /// An enum representing the type of key being stored @@ -168,6 +184,10 @@ impl Key for PublicKey { fn keyname(&self) -> &'static str { self.inner_key().keyname() } + + fn short_keyname(&self) -> &'static str { + self.inner_key().short_keyname() + } } impl PublicParts for PublicKey { @@ -398,6 +418,9 @@ impl Key for KeyPair { fn keyname(&self) -> &'static str { self.inner_key().keyname() } + fn short_keyname(&self) -> &'static str { + self.inner_key().short_keyname() + } } impl PublicParts for KeyPair { @@ -457,6 +480,8 @@ pub trait Key { fn size(&self) -> usize; /// The key name of the key fn keyname(&self) -> &'static str; + /// The short key name of the key + fn short_keyname(&self) -> &'static str; } /// A trait for operations of a public key @@ -470,6 +495,120 @@ pub trait PublicParts: Key { let b = self.blob()?; Ok(hash.hash(&b)) } + + // Rewritten from the OpenSSH project. OpenBSD notice is included below. + + /* $OpenBSD: sshkey.c,v 1.120 2022/01/06 22:05:42 djm Exp $ */ + /* + * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. + * Copyright (c) 2008 Alexander von Gernler. All rights reserved. + * Copyright (c) 2010,2011 Damien Miller. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + /// Draw an ASCII-art picture from the fingerprint, also known as "randomart" + fn fingerprint_randomart(&self, hash: FingerprintHash) -> OsshResult { + const FLDBASE: usize = 8; + const FLDSIZE_Y: usize = FLDBASE + 1; + const FLDSIZE_X: usize = FLDBASE * 2 + 1; + + // Chars to be used after each other every time the worm intersects with itself. Matter of + // taste. + const AUGMENTATION_CHARS: &[u8] = b" .o+=*BOX@%&#/^SE"; + + let len = AUGMENTATION_CHARS.len() - 1; + + let mut art = String::with_capacity((FLDSIZE_X + 3) * (FLDSIZE_Y + 2)); + + // Initialize field. + let mut field = [[0; FLDSIZE_X]; FLDSIZE_Y]; + let mut x = FLDSIZE_X / 2; + let mut y = FLDSIZE_Y / 2; + + // Process raw key. + let dgst_raw = self.fingerprint(hash)?; + for i in 0..dgst_raw.len() { + // Each byte conveys four 2-bit move commands. + let mut input = dgst_raw[i]; + for _ in 0..4 { + // Evaluate 2 bit, rest is shifted later. + x = if (input & 0x1) != 0 { + x + 1 + } else { + x.saturating_sub(1) + }; + y = if (input & 0x2) != 0 { + y + 1 + } else { + y.saturating_sub(1) + }; + + // Assure we are still in bounds. + x = x.min(FLDSIZE_X - 1); + y = y.min(FLDSIZE_Y - 1); + + // Augment the field. + if field[y][x] < len as u8 - 2 { + field[y][x] += 1; + } + input >>= 2; + } + } + + // Mark starting point and end point. + field[FLDSIZE_Y / 2][FLDSIZE_X / 2] = len as u8 - 1; + field[y][x] = len as u8; + + // Assemble title. + let title = format!("[{} {}]", self.short_keyname(), self.size()); + // If [type size] won't fit, then try [type]; fits "[ED25519-CERT]". + let title = if title.chars().count() > FLDSIZE_X { + format!("[{}]", self.short_keyname()) + } else { + title + }; + + // Assemble hash ID. + let hash = format!("[{}]", hash.name()); + + // Output upper border. + art += &format!("+{:-^width$}+\n", title, width = FLDSIZE_X); + + // Output content. + for y in 0..FLDSIZE_Y { + art.push('|'); + art.extend( + field[y] + .iter() + .map(|&c| AUGMENTATION_CHARS[c as usize] as char), + ); + art += "|\n"; + } + + // Output lower border. + art += &format!("+{:-^width$}+", hash, width = FLDSIZE_X); + + Ok(art) + } } /// A trait for operations of a private key diff --git a/src/keys/rsa.rs b/src/keys/rsa.rs index f06c596..cf73a4e 100644 --- a/src/keys/rsa.rs +++ b/src/keys/rsa.rs @@ -17,6 +17,8 @@ pub const RSA_NAME: &str = "ssh-rsa"; pub const RSA_SHA256_NAME: &str = "rsa-sha2-256"; /// The sha2-512 algorithm name of RSA key returned by [`Key::keyname()`](../trait.Key.html#method.keyname) pub const RSA_SHA512_NAME: &str = "rsa-sha2-512"; +/// The short name of the of RSA key returned by [`Key::short_keyname()`](../trait.Key.html#method.short_keyname) +pub const RSA_SHORT_NAME: &str = "RSA"; /// An enum determining the hash function which used to sign or verify #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -118,6 +120,10 @@ impl Key for RsaPublicKey { fn keyname(&self) -> &'static str { self.signhash.name() } + + fn short_keyname(&self) -> &'static str { + RSA_SHORT_NAME + } } impl PublicParts for RsaPublicKey { @@ -210,6 +216,10 @@ impl Key for RsaKeyPair { fn keyname(&self) -> &'static str { self.signhash.name() } + + fn short_keyname(&self) -> &'static str { + RSA_SHORT_NAME + } } impl PublicParts for RsaKeyPair { diff --git a/tests/keyfiles.rs b/tests/keyfiles.rs index e6badd0..e181948 100644 --- a/tests/keyfiles.rs +++ b/tests/keyfiles.rs @@ -12,6 +12,7 @@ const TEST_FILE_PASS: &str = "12345678"; fn verify_key>(keyfile: P, passphrase: Option<&str>) { let keypath = utils::locate_crate_files(keyfile); let pubkeypath = keypath.with_extension("pub"); + let randomartpath = keypath.with_extension("randomart"); let privdata = fs::read(keypath).unwrap(); let privkey = @@ -20,7 +21,11 @@ fn verify_key>(keyfile: P, passphrase: Option<&str>) { let pubdata = fs::read(pubkeypath).unwrap(); let pubkey = PublicKey::from_keystr(from_utf8(pubdata.as_slice()).unwrap()).unwrap(); + let randomartdata = fs::read(randomartpath).unwrap(); + let randomart = String::from_utf8(randomartdata).unwrap(); + utils::fingerprint_assert(&privkey, &pubkey); + utils::fingerprint_randomart_assert(&randomart, &pubkey); // Make sure that privkey can be serialized // https://github.com/Leo1003/rust-osshkeys/issues/4 diff --git a/tests/utils.rs b/tests/utils.rs index ea773de..ec16f76 100644 --- a/tests/utils.rs +++ b/tests/utils.rs @@ -22,6 +22,14 @@ pub fn fingerprint_assert(key1: &dyn PublicParts, key2: &dyn PublicParts) { ); } +#[inline] +pub fn fingerprint_randomart_assert(randomart: &str, key: &dyn PublicParts) { + assert_eq!( + randomart, + &key.fingerprint_randomart(FingerprintHash::SHA256).unwrap() + ); +} + // This function is for test only, // not providing any security protection. pub fn gen_random_pass(len: usize) -> String { From 9ccaa2fb1faeb3f7d34f4be08c609e76ceef2e59 Mon Sep 17 00:00:00 2001 From: Hampus Lidin Date: Thu, 10 Feb 2022 11:17:27 +0100 Subject: [PATCH 2/2] Remove index bound check by using iterator instead --- src/keys/mod.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/keys/mod.rs b/src/keys/mod.rs index 911c111..c95e5b3 100644 --- a/src/keys/mod.rs +++ b/src/keys/mod.rs @@ -546,9 +546,8 @@ pub trait PublicParts: Key { // Process raw key. let dgst_raw = self.fingerprint(hash)?; - for i in 0..dgst_raw.len() { + for mut input in dgst_raw.iter().copied() { // Each byte conveys four 2-bit move commands. - let mut input = dgst_raw[i]; for _ in 0..4 { // Evaluate 2 bit, rest is shifted later. x = if (input & 0x1) != 0 {