Start the infrastructure for ECDSA SSH keys.
This commit is contained in:
@@ -10,7 +10,7 @@ use rand::Rng;
|
|||||||
use rand::distributions::Standard;
|
use rand::distributions::Standard;
|
||||||
use self::curve::{EllipticCurve,P192,P224,P256,P384,P521};
|
use self::curve::{EllipticCurve,P192,P224,P256,P384,P521};
|
||||||
use self::point::{ECCPoint,Point};
|
use self::point::{ECCPoint,Point};
|
||||||
pub use self::private::ECCPrivateKey;
|
pub use self::private::{ECDSAPrivate,ECCPrivateKey};
|
||||||
pub use self::public::{ECDSAPublic,ECCPublicKey};
|
pub use self::public::{ECDSAPublic,ECCPublicKey};
|
||||||
pub use self::public::{ECDSADecodeErr,ECDSAEncodeErr};
|
pub use self::public::{ECDSADecodeErr,ECDSAEncodeErr};
|
||||||
use super::KeyPair;
|
use super::KeyPair;
|
||||||
@@ -20,6 +20,32 @@ pub struct ECDSAKeyPair<Curve: EllipticCurve> {
|
|||||||
pub private: ECCPrivateKey<Curve>
|
pub private: ECCPrivateKey<Curve>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum ECDSAPair {
|
||||||
|
P192(ECCPublicKey<P192>,ECCPrivateKey<P192>),
|
||||||
|
P224(ECCPublicKey<P224>,ECCPrivateKey<P224>),
|
||||||
|
P256(ECCPublicKey<P256>,ECCPrivateKey<P256>),
|
||||||
|
P384(ECCPublicKey<P384>,ECCPrivateKey<P384>),
|
||||||
|
P521(ECCPublicKey<P521>,ECCPrivateKey<P521>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl KeyPair for ECDSAPair {
|
||||||
|
type Public = ECDSAPublic;
|
||||||
|
type Private = ECDSAPrivate;
|
||||||
|
|
||||||
|
fn new(pu: ECDSAPublic, pr: ECDSAPrivate) -> ECDSAPair
|
||||||
|
{
|
||||||
|
match (pu, pr) {
|
||||||
|
(ECDSAPublic::P192(pbl),ECDSAPrivate::P192(prv)) => ECDSAPair::P192(pbl,prv),
|
||||||
|
(ECDSAPublic::P224(pbl),ECDSAPrivate::P224(prv)) => ECDSAPair::P224(pbl,prv),
|
||||||
|
(ECDSAPublic::P256(pbl),ECDSAPrivate::P256(prv)) => ECDSAPair::P256(pbl,prv),
|
||||||
|
(ECDSAPublic::P384(pbl),ECDSAPrivate::P384(prv)) => ECDSAPair::P384(pbl,prv),
|
||||||
|
(ECDSAPublic::P521(pbl),ECDSAPrivate::P521(prv)) => ECDSAPair::P521(pbl,prv),
|
||||||
|
_ =>
|
||||||
|
panic!("Non-matching public/private pairs in ECDSAPair::new()")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! generate_impl {
|
macro_rules! generate_impl {
|
||||||
($curve: ident, $un: ident, $si: ident) => {
|
($curve: ident, $un: ident, $si: ident) => {
|
||||||
impl KeyPair for ECDSAKeyPair<$curve> {
|
impl KeyPair for ECDSAKeyPair<$curve> {
|
||||||
|
|||||||
@@ -10,6 +10,14 @@ pub struct ECCPrivateKey<Curve: EllipticCurve> {
|
|||||||
d: Curve::Unsigned
|
d: Curve::Unsigned
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum ECDSAPrivate {
|
||||||
|
P192(ECCPrivateKey<P192>),
|
||||||
|
P224(ECCPrivateKey<P224>),
|
||||||
|
P256(ECCPrivateKey<P256>),
|
||||||
|
P384(ECCPrivateKey<P384>),
|
||||||
|
P521(ECCPrivateKey<P521>),
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! generate_privates
|
macro_rules! generate_privates
|
||||||
{
|
{
|
||||||
($curve: ident, $base: ident, $sig: ident, $dbl: ident, $quad: ident) => {
|
($curve: ident, $base: ident, $sig: ident, $dbl: ident, $quad: ident) => {
|
||||||
|
|||||||
@@ -13,11 +13,11 @@ pub struct ECCPublicKey<Curve: EllipticCurve> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub enum ECDSAPublic {
|
pub enum ECDSAPublic {
|
||||||
ECCPublicP192(ECCPublicKey<P192>),
|
P192(ECCPublicKey<P192>),
|
||||||
ECCPublicP224(ECCPublicKey<P224>),
|
P224(ECCPublicKey<P224>),
|
||||||
ECCPublicP256(ECCPublicKey<P256>),
|
P256(ECCPublicKey<P256>),
|
||||||
ECCPublicP384(ECCPublicKey<P384>),
|
P384(ECCPublicKey<P384>),
|
||||||
ECCPublicP521(ECCPublicKey<P521>),
|
P521(ECCPublicKey<P521>),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum ECDSAEncodeErr {
|
pub enum ECDSAEncodeErr {
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ fn check_signature(alg: &AlgorithmIdentifier,
|
|||||||
Err(X509ParseError::InvalidSignatureHash)
|
Err(X509ParseError::InvalidSignatureHash)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(PublicKeyInfo::ECDSA, &X509PublicKey::ECDSA(ECDSAPublic::ECCPublicP192(ref key))) => {
|
(PublicKeyInfo::ECDSA, &X509PublicKey::ECDSA(ECDSAPublic::P192(ref key))) => {
|
||||||
let ecdsa_sig = der_decode(&sig)?;
|
let ecdsa_sig = der_decode(&sig)?;
|
||||||
match alg.hash {
|
match alg.hash {
|
||||||
HashAlgorithm::SHA1 if key.verify::<Sha1>(block, &ecdsa_sig) => Ok(()),
|
HashAlgorithm::SHA1 if key.verify::<Sha1>(block, &ecdsa_sig) => Ok(()),
|
||||||
@@ -194,7 +194,7 @@ fn check_signature(alg: &AlgorithmIdentifier,
|
|||||||
Err(X509ParseError::InvalidSignatureHash)
|
Err(X509ParseError::InvalidSignatureHash)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(PublicKeyInfo::ECDSA, &X509PublicKey::ECDSA(ECDSAPublic::ECCPublicP224(ref key))) => {
|
(PublicKeyInfo::ECDSA, &X509PublicKey::ECDSA(ECDSAPublic::P224(ref key))) => {
|
||||||
let ecdsa_sig = der_decode(&sig)?;
|
let ecdsa_sig = der_decode(&sig)?;
|
||||||
match alg.hash {
|
match alg.hash {
|
||||||
HashAlgorithm::SHA1 if key.verify::<Sha1>(block, &ecdsa_sig) => Ok(()),
|
HashAlgorithm::SHA1 if key.verify::<Sha1>(block, &ecdsa_sig) => Ok(()),
|
||||||
@@ -206,7 +206,7 @@ fn check_signature(alg: &AlgorithmIdentifier,
|
|||||||
Err(X509ParseError::InvalidSignatureHash)
|
Err(X509ParseError::InvalidSignatureHash)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(PublicKeyInfo::ECDSA, &X509PublicKey::ECDSA(ECDSAPublic::ECCPublicP256(ref key))) => {
|
(PublicKeyInfo::ECDSA, &X509PublicKey::ECDSA(ECDSAPublic::P256(ref key))) => {
|
||||||
let ecdsa_sig = der_decode(&sig)?;
|
let ecdsa_sig = der_decode(&sig)?;
|
||||||
match alg.hash {
|
match alg.hash {
|
||||||
HashAlgorithm::SHA1 if key.verify::<Sha1>(block, &ecdsa_sig) => Ok(()),
|
HashAlgorithm::SHA1 if key.verify::<Sha1>(block, &ecdsa_sig) => Ok(()),
|
||||||
@@ -218,7 +218,7 @@ fn check_signature(alg: &AlgorithmIdentifier,
|
|||||||
Err(X509ParseError::InvalidSignatureHash)
|
Err(X509ParseError::InvalidSignatureHash)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(PublicKeyInfo::ECDSA, &X509PublicKey::ECDSA(ECDSAPublic::ECCPublicP384(ref key))) => {
|
(PublicKeyInfo::ECDSA, &X509PublicKey::ECDSA(ECDSAPublic::P384(ref key))) => {
|
||||||
let ecdsa_sig = der_decode(&sig)?;
|
let ecdsa_sig = der_decode(&sig)?;
|
||||||
match alg.hash {
|
match alg.hash {
|
||||||
HashAlgorithm::SHA1 if key.verify::<Sha1>(block, &ecdsa_sig) => Ok(()),
|
HashAlgorithm::SHA1 if key.verify::<Sha1>(block, &ecdsa_sig) => Ok(()),
|
||||||
@@ -230,7 +230,7 @@ fn check_signature(alg: &AlgorithmIdentifier,
|
|||||||
Err(X509ParseError::InvalidSignatureHash)
|
Err(X509ParseError::InvalidSignatureHash)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(PublicKeyInfo::ECDSA, &X509PublicKey::ECDSA(ECDSAPublic::ECCPublicP521(ref key))) => {
|
(PublicKeyInfo::ECDSA, &X509PublicKey::ECDSA(ECDSAPublic::P521(ref key))) => {
|
||||||
let ecdsa_sig = der_decode(&sig)?;
|
let ecdsa_sig = der_decode(&sig)?;
|
||||||
match alg.hash {
|
match alg.hash {
|
||||||
HashAlgorithm::SHA1 if key.verify::<Sha1>(block, &ecdsa_sig) => Ok(()),
|
HashAlgorithm::SHA1 if key.verify::<Sha1>(block, &ecdsa_sig) => Ok(()),
|
||||||
|
|||||||
@@ -255,11 +255,11 @@ fn encode_ecdsa_key(c: ASN1Class, x: &ECDSAPublic) -> Result<ASN1Block,ECDSAEnco
|
|||||||
{
|
{
|
||||||
let objoid = ASN1Block::ObjectIdentifier(c, 0, oid!(1,2,840,10045,2,1));
|
let objoid = ASN1Block::ObjectIdentifier(c, 0, oid!(1,2,840,10045,2,1));
|
||||||
let (base_curve_oid, mut keyvec) = match x {
|
let (base_curve_oid, mut keyvec) = match x {
|
||||||
ECDSAPublic::ECCPublicP192(k) => (oid!(1,2,840,10045,3,1,1), k.to_asn1_class(c)?),
|
ECDSAPublic::P192(k) => (oid!(1,2,840,10045,3,1,1), k.to_asn1_class(c)?),
|
||||||
ECDSAPublic::ECCPublicP224(k) => (oid!(1,3,132,0,33), k.to_asn1_class(c)?),
|
ECDSAPublic::P224(k) => (oid!(1,3,132,0,33), k.to_asn1_class(c)?),
|
||||||
ECDSAPublic::ECCPublicP256(k) => (oid!(1,2,840,10045,3,1,7), k.to_asn1_class(c)?),
|
ECDSAPublic::P256(k) => (oid!(1,2,840,10045,3,1,7), k.to_asn1_class(c)?),
|
||||||
ECDSAPublic::ECCPublicP384(k) => (oid!(1,3,132,0,34), k.to_asn1_class(c)?),
|
ECDSAPublic::P384(k) => (oid!(1,3,132,0,34), k.to_asn1_class(c)?),
|
||||||
ECDSAPublic::ECCPublicP521(k) => (oid!(1,3,132,0,35), k.to_asn1_class(c)?),
|
ECDSAPublic::P521(k) => (oid!(1,3,132,0,35), k.to_asn1_class(c)?),
|
||||||
};
|
};
|
||||||
let curve_oid = ASN1Block::ObjectIdentifier(c, 0, base_curve_oid);
|
let curve_oid = ASN1Block::ObjectIdentifier(c, 0, base_curve_oid);
|
||||||
let header = ASN1Block::Sequence(c, 0, vec![objoid, curve_oid]);
|
let header = ASN1Block::Sequence(c, 0, vec![objoid, curve_oid]);
|
||||||
@@ -272,27 +272,27 @@ fn decode_ecdsa_key(info: ASN1Block, keybls: &[ASN1Block]) -> Result<ECDSAPublic
|
|||||||
if let ASN1Block::ObjectIdentifier(_, _, oid) = info {
|
if let ASN1Block::ObjectIdentifier(_, _, oid) = info {
|
||||||
if oid == oid!(1,2,840,10045,3,1,1) {
|
if oid == oid!(1,2,840,10045,3,1,1) {
|
||||||
let (res, _) = ECCPublicKey::<P192>::from_asn1(keybls)?;
|
let (res, _) = ECCPublicKey::<P192>::from_asn1(keybls)?;
|
||||||
return Ok(ECDSAPublic::ECCPublicP192(res));
|
return Ok(ECDSAPublic::P192(res));
|
||||||
}
|
}
|
||||||
|
|
||||||
if oid == oid!(1,3,132,0,33) {
|
if oid == oid!(1,3,132,0,33) {
|
||||||
let (res, _) = ECCPublicKey::<P224>::from_asn1(keybls)?;
|
let (res, _) = ECCPublicKey::<P224>::from_asn1(keybls)?;
|
||||||
return Ok(ECDSAPublic::ECCPublicP224(res));
|
return Ok(ECDSAPublic::P224(res));
|
||||||
}
|
}
|
||||||
|
|
||||||
if oid == oid!(1,2,840,10045,3,1,7) {
|
if oid == oid!(1,2,840,10045,3,1,7) {
|
||||||
let (res, _) = ECCPublicKey::<P256>::from_asn1(keybls)?;
|
let (res, _) = ECCPublicKey::<P256>::from_asn1(keybls)?;
|
||||||
return Ok(ECDSAPublic::ECCPublicP256(res));
|
return Ok(ECDSAPublic::P256(res));
|
||||||
}
|
}
|
||||||
|
|
||||||
if oid == oid!(1,3,132,0,34) {
|
if oid == oid!(1,3,132,0,34) {
|
||||||
let (res, _) = ECCPublicKey::<P384>::from_asn1(keybls)?;
|
let (res, _) = ECCPublicKey::<P384>::from_asn1(keybls)?;
|
||||||
return Ok(ECDSAPublic::ECCPublicP384(res));
|
return Ok(ECDSAPublic::P384(res));
|
||||||
}
|
}
|
||||||
|
|
||||||
if oid == oid!(1,3,132,0,35) {
|
if oid == oid!(1,3,132,0,35) {
|
||||||
let (res, _) = ECCPublicKey::<P521>::from_asn1(keybls)?;
|
let (res, _) = ECCPublicKey::<P521>::from_asn1(keybls)?;
|
||||||
return Ok(ECDSAPublic::ECCPublicP521(res));
|
return Ok(ECDSAPublic::P521(res));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user