Releases: obelisk/sshcerts
More Aggressive Yubikey Reconnect
This update fixes an issue where using sshcerts
may not have compiled when using bignum.
It also adds a more aggressive Yubikey reconnect policy. It will attempt a standard smartcard reconnect call first but if that fails, it will try to open a new connection to the same serial number yubikey. This happens completely transparently to the caller. When reconnecting to the yubikey, a slot that is set as PIN Once
will need to have the pin authentication call happen again (this currently can only happen by accessing the inner yk
sturct property).
Major Rewrite - "Builder" Pattern is Here!
I put a lot of work into trying to make the crate easier for other people to use. The biggest change is that of Certificate::new
which no longer exists. Before you would create a certificate like this:
let user_cert = Certificate::new(
ssh_pubkey.clone(),
CertType::User,
0xFEFEFEFEFEFEFEFE,
String::from("key_id"),
vec![String::from("obelisk")],
0,
0xFFFFFFFFFFFFFFFF,
CriticalOptions::None,
Extensions::Standard,
ca_pubkey.clone(),
test_ecdsa256_signer,
);
Now it's this:
let user_cert = Certificate::builder(&ssh_pubkey, CertType::User, &ca_pubkey).unwrap()
.serial(0xFEFEFEFEFEFEFEFE)
.key_id("key_id")
.principal("obelisk")
.valid_after(0)
.valid_before(0xFFFFFFFFFFFFFFFF)
.set_critical_options(CriticalOptions::None)
.set_extensions(Extensions::Standard)
.sign(test_ecdsa256_signer);
These generate equivalent certificates but the new version has significantly more flexibility in terms of adding new principals, critical options, or extensions. See tests for more examples.
The second big change is in the Yubikey module where the actions have been wrapped inside a structure. This makes it possible to guarantee that in a system with more than one yubikey, you continue using the same key (I still need to write more APIs to make this truly possible though).
Finally, error handling has been improved. Errors are now crate level and expose the type directly instead of through ErrorKind
which has now been removed.
x509 Certificate Conversion
When dealing with Yubikeys, the attestation certificate is an x509 certificate. So if you're validating the attestation chain, once you're done you need to convert the public key of the leaf certificate (the attestation certificate) to an SSH Public Key type. This adds a helper function for that.
The only reason it's in the Yubikey module is because the yubikey-piv library has a really handy function to do most of the heavy lifting for the conversion. Maybe one day I can reimplement and then it can be moved out but will still require more core dependencies.
PartialEq on Fingerprint
Makes it much easier to compare fingerprints.
ECDSA Signature Fix
In short: There was a bug verifying ECDSA signatures in that it would mark some valid signatures as invalid. This is now fixed.
Today I tracked down a bug in certificate creation and turns out verification was at fault. Specifically the step at the end to make sure we've generated a valid certificate. The ECDSA signature verification algorithm I'm using from ring
requires that signatures be r||s
(where ||
is the concatenation operator) and the resultant signature be exactly 64 bytes for 256bit keys and 96 bytes for 384bit keys.
I'd overlooked that the integers R and S may have some leading 0 bytes and thus rarely signature validation would fail when either of them were less than the required number of bytes after these bytes we're erroneously stripped.
Optional but Standard SSH Signing
In the last release, RSA certificate creation via PrivateKey was introduced. In doing so a number of dependencies had to be pulled in even if you never used this feature. Thus this release makes this new functionality an optional but standard feature.
Not using the new rsa-signing
features will give you 7 total dependencies from this library and trying to sign with an RSA PrivateKey will fail but in a standard build everything works normally because it would be weird for some PrivateKeys to work while others don't.
API Changes:
RSAPrivateKey
exp: Vec<u8>
-->exp: Option<Vec<u8>>
and will only beSome
iff the featurersa-signing
is usedexq: Vec<u8>
-->exq: Option<Vec<u8>>
and will only beSome
iff the featurersa-signing
is used- The
ToASN1
trait is defined iff the featurersa-signing
is used
RSA Signing
I finally got around to implementing RSA Signing. This means you can now parse an OpenSSH RSA Private Key
file into a PrivateKey
type and use it to sign certificates.
Unfortunately this comes at the cost of a couple more dependencies: num-bigint
and simple_asn1
. I may gate these behind an rsa_signing
feature in the future to help keep general dependencies low though so keep that in mind when depending on this crate currently.
For Yubikey users, this is still not done, just haven't had time yet but hopefully in the next little bit I'll have time to get a implementation done.
Also had our first PR from @diggyk for #1. Thank you so much for finding, fixing, and testing that!
Signer Release
There is a new signer module which adds the ability to generate functions that can be passed to Certificate::new
for signing.
There is also an impl
for PrivateKey
now that lets you convert a PrivateKey into a function that can be used for signing. I'm still working on just being able to pass in a PrivateKey
but this kept the API stable for now. I might introduce a breaking change later that allows this however.
Other than that, more tests have been added for all this functionality. You can generate Ed25519 certificates now!
Update Dependencies
Base64 was outdated
Ring had a new version available
Also removed an unused macro_use directive in yk-provision
sshcerts Renaming
Rustica-Keys (the old name for this project) was being increasingly incorrect for what this library was for in addition to not being descriptive for what it does. As of this release, the new name is sshcerts
and can be found in crates.io under that name. The versions are staying the same to prevent confusion.
Also new in this release:
- Way more tests covering pretty much every combination of certs possible. This should help prevent any regressions going forward and provides more certainty that replacing the byte order crate with stdlib was done correctly.
- Ed25519 private key support: sshcerts is now capable to parsing unencrypted ed25519.