This repository has moved to:
tendermint / yubihsm-rs Goto Github PK
View Code? Open in Web Editor NEWPure Rust client for YubiHSM2 devices
Home Page: https://docs.rs/yubihsm/
Pure Rust client for YubiHSM2 devices
Home Page: https://docs.rs/yubihsm/
This repository has moved to:
The Session::create()
and Session::create_with_password()
methods accept a reconnect
parameter which will stash the static keys to use to reconnect dead sessions into the Session
struct, however it does not yet automatically reconnect sessions if the static keys are available (i.e. presently this parameter is a lie!)
See TODOs in:
https://github.com/tendermint/yubihsm-rs/blob/master/src/session/mod.rs
Error "HSM error: MemoryError" occured after accidentally deleting the first key:
client.delete_object(1, object::Type::AuthenticationKey);
Can't access it by Client
, is it broken? if not, how can i fix it? T.T
Right now the serialization logic for serializing/deserializing commands and responses is all hand-written.
It would be nice to replace this with some kind of procedural macro which can generate these serializers/deserializers automatically from a struct definition.
The YubiHSM2 serialization format might not be a good fit for serde, in which case we could write our own procedural macro.
for example, privKey/pubKey should be:
privKey: nELFcMHxcWNa7diMreQxgCanEvNAvphfFUfZnY+WYRM=
pubKey: A3fPi9YOUMooFqjJ8lnAyu3OfBbVoNOrrIulAsmR7aea
but get result from yubihsm by using get_public_key:
let key_id = 12;
if let Err(e) = client.put_asymmetric_key(
key_id,
Label::from("test1"),
DOMAINS[1],
yubihsm::Capability::SIGN_EDDSA,
yubihsm::asymmetric::Algorithm::Ed25519,
base64::decode("nELFcMHxcWNa7diMreQxgCanEvNAvphfFUfZnY+WYRM=".as_bytes()).unwrap(),
) {
println!("key set failed #{}: {}", key_id, e);
}
let pub_key = client.get_public_key(key_id).unwrap_or_else(|e| {
println!("couldn't get public key for key #{}: {}", key_id, e);
process::exit(1);
});
// will get `vcIrFxllqZZePS7NvTzC2XdIUrkkXAWJU40BPS+ysro=`, it's very strange
println!("key_id: {}, pub_key: {:?}", key_id, String::from_utf8(base64::encode(pub_key.clone().into_vec())));
The default AuthKey (id:1) on a reset YubiHSM2 has capabilities and delegated_capabilities of 18446744073709551615 (all 1s). This can't be decoded by Capability/deserialize as it specifies invalid bitflags (guessing).
The bytes for the default authkey are: [255, 255, 255, 255, 255, 255, 255, 255, 0, 1, 0, 40, 255, 255, 2, 38, 0, 2, 68, 69, 70, 65, 85, 76, 84, 32, 65, 85, 84, 72, 75, 69, 89, 32, 67, 72, 65, 78, 71, 69, 32, 84, 72, 73, 83, 32, 65, 83, 65, 80, 0, 192, 255, 238, 192, 255, 238, 1, 255, 255, 255, 255, 255, 255, 255, 255]
.
There are invalid characters at the end of the default AuthKey Label - these prevent the Label.to_string()
function working correctly. Using from_utf8_lossy
isn't a whole lot better as you get a series of unicode blips at the end: DEFAULT AUTHKEY CHANGE THIS ASAP������
.
My use-case is to add support to rage for decrypting messages encrypted to an ssh-rsa key stored in a Yubikey.
#13 added a "happy path" unit test for SecureChannel
, however MAC/cryptogram verification failures are presently untested (and extremely important for security!)
https://github.com/tendermint/yubihsm-client/blob/master/src/securechannel/channel.rs#L590
Really all of the SecureChannel
(pseudo-)state machine should be better tested...
As of #36, we no longer support HTTPS. For users who want to run connectors remotely instead of on localhost, we should provide an option for doing this.
rustls should be compatible with our goals of keeping the codebase pure Rust and compatible with use inside of SGX.
Note that the connection between yubihsm-rs and the YubiHSM2 is already encrypted, however it's with a fully symmetric protocol which therefore has no forward secrecy, and also not the world's greatest transport encryption protocol which is using, among other things, 8-byte MACs, so TLS would be nice to support.
The release notes for the new Yubico SDK document a number of name changes for which we should make corresponding changes in this crate's API:
https://developers.yubico.com/yubihsm-shell/API_Changes.html
In the spec,
Vc = K || L || D || C || A || DC || W
But in the code of commands/put_wrap_key.rs,
pub fn put_wrap_key<C: Connector, T: Into<Vec<u8>>>(
session: &mut Session<C>,
key_id: ObjectId,
label: ObjectLabel,
domains: Domain,
capabilities: Capability,
algorithm: WrapAlgorithm,
key_bytes: T,
)
missed the delegated capabilities.
The put auth key function @ put_auth_key.rs:23 is missing a delegated capabilities parameter, which is specified in https://developers.yubico.com/YubiHSM2/Commands/Put_Authkey.html as 8 bytes before the key material.
I think this needs to be changed to something along the lines of put_wrap_key.
The example is:
use yubihsm::{Client, Credentials, UsbConnector};
fn main() {
// Connect to the first YubiHSM 2 we detect
let connector = UsbConnector::default();
// Default auth key ID and password for YubiHSM 2
// NOTE: DON'T USE THIS IN PRODUCTION!
let credentials = Credentials::default();
// Connect to the HSM and authenticate with the given credentials
let mut hsm_client = Client::open(connector, credentials, true).unwrap();
// Note: You'll need to create this key first. Run the following from yubihsm-shell:
// `generate asymmetric 0 100 ed25519_test_key 1 asymmetric_sign_eddsa ed25519`
let signature = hsm_client.sign_ed25519(100, "Hello, world!").unwrap();
println!("Ed25519 signature: {:?}", signature);
}
Error reporting at compile time:no 'UsbConnector' in the root
version is 0.23.0
rust version is 1.35.0
Or at least appears to be. There is a small issue with it currently which hasn't had a resolution in the repo, and so it has been forked to rusb
.
Check out the issue here
FYI, your website states:
the closed-source libyubihsm library
I believe that as of the end of November, Yubi have open-sourced the library on their GitHub ? (https://github.com/Yubico/yubihsm-shell/tree/master/lib)
I want to protect my Validator private key.
Hi,
i'm trying to put a wrap key to the HSM but the process is stuck indefinitely. It never reaches
println!("labelXYZ: Created! Label: labelXYZ, ID: 0");
I also encounter this issue when using the http connector, so I am assuming this is somehow my mistake. Using the yubihsm-shell it works as described below.
use anyhow::Result;
use yubihsm::{capability::Capability, wrap, Client, Connector, Credentials, UsbConfig};
fn main() -> Result<()> {
let usb_cfg = UsbConfig::default();
let connector = Connector::usb(&usb_cfg);
let credentials = Credentials::default();
println!("HSM: Opening connection to HSM via USB");
let hsm_client = Client::open(connector, credentials, true)?;
println!("HSM: Connected to HSM");
println!("HSM: Opening session using default password");
let session_guard = hsm_client.session()?;
println!("HSM: Session (id: {}) open", session_guard.id());
println!("labelXYZ: Generating AES-256 random wrap key");
let mut key_builder = wrap::Key::generate_random(0, wrap::Algorithm::Aes256Ccm);
key_builder = key_builder.label("labelXYZ".into());
key_builder = key_builder.capabilities(
Capability::WRAP_DATA
| Capability::UNWRAP_DATA
| Capability::EXPORT_WRAPPED
| Capability::IMPORT_WRAPPED,
);
println!("labelXYZ: Creating key within HSM");
key_builder.create(&hsm_client)?;
println!("labelXYZ: Created! Label: labelXYZ, ID: 0");
}
Output:
HSM: Opening connection to HSM via USB
HSM: Connected to HSM
HSM: Opening session using default password
HSM: Session (id: 0) open
labelXYZ: Generating AES-256 random wrap key
labelXYZ: Creating key within HSM
Using yubi-shell succeeds:
connect
session open 1 password
get random 0 32
put wrapkey 0 0 labelXYZ 1 wrap-data,unwrap-data export-wrapped,import-wrapped RANDOMOUTPUT
--> Stored Wrap key ...
Hardware: Yubihsm 2
This might be useful
https://crates.io/crates/gotp
ECDSA signatures over the secp256k1 elliptic curve sporadically fail to verify against the secp256k1 crate. I've opened an issue against the secp256k1 crate in hopes of investigating further:
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.