-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[PM-10405] Add bitwarden-ssh crate with keygeneration support #35
base: main
Are you sure you want to change the base?
Conversation
No New Or Fixed Issues Found |
…ernal into km/pm-10942/ssh-keygen
47e2059
to
9419971
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #35 +/- ##
==========================================
- Coverage 63.39% 63.14% -0.26%
==========================================
Files 184 187 +3
Lines 12935 12982 +47
==========================================
- Hits 8200 8197 -3
- Misses 4735 4785 +50 ☔ View full report in Codecov by Sentry. 🚨 Try these New Features:
|
8024d3a
to
0c5a83d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great start, let's get this function unit tested if possible, and remove some of the dependencies. I also started a discussion in slack about the divergence from our standard rand generator.
crates/bitwarden-ssh/Cargo.toml
Outdated
uniffi = { workspace = true, optional = true } | ||
uuid = { workspace = true } | ||
wasm-bindgen = { workspace = true, optional = true } | ||
tsify-next = { workspace = true, optional = true } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unused? Only needed for full errors.
crates/bitwarden-ssh/src/lib.rs
Outdated
pub fn generate_keypair( | ||
key_algorithm: KeyAlgorithm, | ||
) -> Result<models::SshKey, error::KeyGenerationError> { | ||
// sourced from cryptographically secure entropy source, with sources for all targets: https://docs.rs/getrandom | ||
// if it cannot be securely sourced, this will panic instead of leading to a weak key | ||
let mut rng: ChaCha8Rng = ChaCha8Rng::from_entropy(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue: Please create a new private function which takes mut rng: impl rand::RngCore,
as input. This way we can unit test it using chacha iniitalized from a seed. There are some examples in bitwarden-crypto
on how to do this.
crates/bitwarden-ssh/src/models.rs
Outdated
pub struct SshKey { | ||
pub private_key: String, | ||
pub public_key: String, | ||
pub key_fingerprint: String, | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: I think the naming here can be confusing. We already have a concept of SshKey
, and they are not the same type. We can either re-use SshKeyView
, or change this to be a DTO, we generally call these the same as the function and append result, i.e. GenerateKeypairResult
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With a DTO we can also lift this into the lib.rs to keep it closer to the function producing it.
crates/bitwarden-ssh/src/lib.rs
Outdated
Rsa4096, | ||
} | ||
|
||
pub fn generate_keypair( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: keypair
generally means an RSA keypair. In this case we generate an ssh keypair and we may benefit from including ssh in the name, to avoid confusion on the calling side where we can depend on bitwarden-crypto and bitwarden-ssh.
crates/bitwarden-ssh/src/lib.rs
Outdated
|
||
let private_key = ssh_key::PrivateKey::new( | ||
ssh_key::private::KeypairData::from(rsa_keypair), | ||
"".to_string(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://docs.rs/ssh-key/0.6.7/ssh_key/private/struct.PrivateKey.html#method.new accepts Into<String>
which should work with string slices, i.e ""
.
crates/bitwarden-ssh/src/lib.rs
Outdated
}; | ||
|
||
let rsa_keypair = ssh_key::private::RsaKeypair::random(&mut rng, bits) | ||
.map_err(|e| error::KeyGenerationError::KeyGenerationError(e.to_string()))?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: Please import the used error rather than always using the full path.
.map_err(|e| error::KeyGenerationError::KeyGenerationError(e.to_string()))?; | |
.map_err(|e| KeyGenerationError::KeyGenerationError(e.to_string()))?; |
#[wasm_bindgen] | ||
pub enum KeyAlgorithm { | ||
Ed25519, | ||
Rsa3072, | ||
Rsa4096, | ||
} | ||
|
||
// impl conversion | ||
impl From<KeyAlgorithm> for bitwarden_ssh::KeyAlgorithm { | ||
fn from(key_algorithm: KeyAlgorithm) -> Self { | ||
match key_algorithm { | ||
KeyAlgorithm::Ed25519 => bitwarden_ssh::KeyAlgorithm::Ed25519, | ||
KeyAlgorithm::Rsa3072 => bitwarden_ssh::KeyAlgorithm::Rsa3072, | ||
KeyAlgorithm::Rsa4096 => bitwarden_ssh::KeyAlgorithm::Rsa4096, | ||
} | ||
} | ||
} | ||
|
||
#[wasm_bindgen] | ||
pub struct SshKey { | ||
private_key: String, | ||
public_key: String, | ||
key_fingerprint: String, | ||
} | ||
|
||
impl From<bitwarden_ssh::models::SshKey> for SshKey { | ||
fn from(key: bitwarden_ssh::models::SshKey) -> Self { | ||
SshKey { | ||
private_key: key.private_key, | ||
public_key: key.public_key, | ||
key_fingerprint: key.key_fingerprint, | ||
} | ||
} | ||
} | ||
|
||
impl SshKey { | ||
pub fn private_key(&self) -> &str { | ||
&self.private_key | ||
} | ||
|
||
pub fn public_key(&self) -> &str { | ||
&self.public_key | ||
} | ||
|
||
pub fn key_fingerprint(&self) -> &str { | ||
&self.key_fingerprint | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@coroiu Do we need to re-define the types? We should look into a way to conditionally apply wasm_bindgen
in the original crates, similar to our uniffi flow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should be able to use #[cfg_attr(feature = "wasm", wasm_bindgen)]
at the source but ideally bitwarden_ssh::models::SshKey
would implement serialize
and tsify
instead. See https://contributing.bitwarden.com/architecture/sdk/password-manager/web/interoperability#how-to-use-tsify
🎟️ Tracking
https://bitwarden.atlassian.net/browse/PM-10405
📔 Objective
Adds a new bitwarden-ssh crate to the sdk. This should later include both import-parsing and key generation.
This PR also exposes this for the web clients (not mobile yet).
⏰ Reminders before review
team
🦮 Reviewer guidelines
:+1:
) or similar for great changes:memo:
) or ℹ️ (:information_source:
) for notes or general info:question:
) for questions:thinking:
) or 💭 (:thought_balloon:
) for more open inquiry that's not quite a confirmedissue and could potentially benefit from discussion
:art:
) for suggestions / improvements:x:
) or:warning:
) for more significant problems or concerns needing attention:seedling:
) or ♻️ (:recycle:
) for future improvements or indications of technical debt:pick:
) for minor or nitpick changes