Full SSH support for RSA.

This commit is contained in:
2019-04-14 22:12:36 -07:00
parent 8c87f945a1
commit 031b4be14e
5 changed files with 297 additions and 46 deletions

View File

@@ -40,6 +40,8 @@ use cryptonum::signed::{EGCD,ModInv};
use cryptonum::unsigned::{CryptoNum,PrimeGen};
use cryptonum::unsigned::{U256,U512,U1024,U1536,U2048,U3072,U4096,U7680,U8192,U15360};
use rand::RngCore;
#[cfg(test)]
use std::fmt;
use std::ops::Sub;
use super::KeyPair;
@@ -60,6 +62,114 @@ pub struct RSAKeyPair<R: RSAMode> {
pub private: RSAPrivateKey<R>
}
#[derive(PartialEq)]
pub enum RSAPair {
R512(RSAPublicKey<U512>, RSAPrivateKey<U512>),
R1024(RSAPublicKey<U1024>, RSAPrivateKey<U1024>),
R2048(RSAPublicKey<U2048>, RSAPrivateKey<U2048>),
R3072(RSAPublicKey<U3072>, RSAPrivateKey<U3072>),
R4096(RSAPublicKey<U4096>, RSAPrivateKey<U4096>),
R8192(RSAPublicKey<U8192>, RSAPrivateKey<U8192>),
R15360(RSAPublicKey<U15360>, RSAPrivateKey<U15360>),
}
#[cfg(test)]
impl fmt::Debug for RSAPair {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error>
{
match self {
RSAPair::R512(_,_) => f.write_str("512-bit RSA key pair"),
RSAPair::R1024(_,_) => f.write_str("1024-bit RSA key pair"),
RSAPair::R2048(_,_) => f.write_str("2048-bit RSA key pair"),
RSAPair::R3072(_,_) => f.write_str("3072-bit RSA key pair"),
RSAPair::R4096(_,_) => f.write_str("4096-bit RSA key pair"),
RSAPair::R8192(_,_) => f.write_str("8192-bit RSA key pair"),
RSAPair::R15360(_,_) => f.write_str("15360-bit RSA key pair"),
}
}
}
impl KeyPair for RSAPair {
type Public = RSAPublic;
type Private = RSAPrivate;
fn new(pu: RSAPublic, pr: RSAPrivate) -> RSAPair
{
match (pu, pr) {
(RSAPublic::Key512(pbl), RSAPrivate::Key512(prv)) =>
RSAPair::R512(pbl, prv),
(RSAPublic::Key1024(pbl), RSAPrivate::Key1024(prv)) =>
RSAPair::R1024(pbl, prv),
(RSAPublic::Key2048(pbl), RSAPrivate::Key2048(prv)) =>
RSAPair::R2048(pbl, prv),
(RSAPublic::Key3072(pbl), RSAPrivate::Key3072(prv)) =>
RSAPair::R3072(pbl, prv),
(RSAPublic::Key4096(pbl), RSAPrivate::Key4096(prv)) =>
RSAPair::R4096(pbl, prv),
(RSAPublic::Key8192(pbl), RSAPrivate::Key8192(prv)) =>
RSAPair::R8192(pbl, prv),
(RSAPublic::Key15360(pbl), RSAPrivate::Key15360(prv)) =>
RSAPair::R15360(pbl, prv),
_ =>
panic!("Unmatched public/private arguments to RSAPair::new()")
}
}
}
impl RSAPair {
pub fn sign(&self, signhash: &SigningHash, msg: &[u8]) -> Vec<u8>
{
match self {
RSAPair::R512(_,prv) => prv.sign(signhash, msg),
RSAPair::R1024(_,prv) => prv.sign(signhash, msg),
RSAPair::R2048(_,prv) => prv.sign(signhash, msg),
RSAPair::R3072(_,prv) => prv.sign(signhash, msg),
RSAPair::R4096(_,prv) => prv.sign(signhash, msg),
RSAPair::R8192(_,prv) => prv.sign(signhash, msg),
RSAPair::R15360(_,prv) => prv.sign(signhash, msg),
}
}
pub fn verify(&self, signhash: &SigningHash, msg: &[u8], sig: &[u8]) -> bool
{
match self {
RSAPair::R512(pbl,_) => pbl.verify(signhash, msg, sig),
RSAPair::R1024(pbl,_) => pbl.verify(signhash, msg, sig),
RSAPair::R2048(pbl,_) => pbl.verify(signhash, msg, sig),
RSAPair::R3072(pbl,_) => pbl.verify(signhash, msg, sig),
RSAPair::R4096(pbl,_) => pbl.verify(signhash, msg, sig),
RSAPair::R8192(pbl,_) => pbl.verify(signhash, msg, sig),
RSAPair::R15360(pbl,_) => pbl.verify(signhash, msg, sig),
}
}
pub fn public(&self) -> RSAPublic
{
match self {
&RSAPair::R512(ref pbl,_) => RSAPublic::Key512(pbl.clone()),
&RSAPair::R1024(ref pbl,_) => RSAPublic::Key1024(pbl.clone()),
&RSAPair::R2048(ref pbl,_) => RSAPublic::Key2048(pbl.clone()),
&RSAPair::R3072(ref pbl,_) => RSAPublic::Key3072(pbl.clone()),
&RSAPair::R4096(ref pbl,_) => RSAPublic::Key4096(pbl.clone()),
&RSAPair::R8192(ref pbl,_) => RSAPublic::Key8192(pbl.clone()),
&RSAPair::R15360(ref pbl,_) => RSAPublic::Key15360(pbl.clone()),
}
}
pub fn private(&self) -> RSAPrivate
{
match self {
&RSAPair::R512(_,ref prv) => RSAPrivate::Key512(prv.clone()),
&RSAPair::R1024(_,ref prv) => RSAPrivate::Key1024(prv.clone()),
&RSAPair::R2048(_,ref prv) => RSAPrivate::Key2048(prv.clone()),
&RSAPair::R3072(_,ref prv) => RSAPrivate::Key3072(prv.clone()),
&RSAPair::R4096(_,ref prv) => RSAPrivate::Key4096(prv.clone()),
&RSAPair::R8192(_,ref prv) => RSAPrivate::Key8192(prv.clone()),
&RSAPair::R15360(_,ref prv) => RSAPrivate::Key15360(prv.clone()),
}
}
}
macro_rules! generate_rsa_pair
{
($uint: ident, $half: ident, $iterations: expr) => {

View File

@@ -5,12 +5,14 @@ use rsa::errors::RSAError;
use rsa::oaep::OAEPParams;
use rsa::signing_hashes::SigningHash;
#[derive(Clone,PartialEq)]
pub struct RSAPrivateKey<R: RSAMode>
{
pub(crate) nu: R::Barrett,
pub(crate) d: R
}
#[derive(Clone,PartialEq)]
pub enum RSAPrivate {
Key512(RSAPrivateKey<U512>),
Key1024(RSAPrivateKey<U1024>),

View File

@@ -12,13 +12,14 @@ use simple_asn1::{ASN1Block,ASN1DecodeErr,ASN1EncodeErr,
use std::fmt;
use utils::TranslateNums;
#[derive(PartialEq)]
#[derive(Clone,PartialEq)]
pub struct RSAPublicKey<R: RSAMode> {
pub(crate) n: R,
pub(crate) nu: R::Barrett,
pub(crate) e: R
}
#[derive(Clone,PartialEq)]
pub enum RSAPublic {
Key512( RSAPublicKey<U512>),
Key1024( RSAPublicKey<U1024>),
@@ -135,6 +136,21 @@ impl ToASN1 for RSAPublic {
}
}
#[cfg(test)]
impl fmt::Debug for RSAPublic {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match self {
RSAPublic::Key512(x) => write!(fmt, "RSA:{:?}", x),
RSAPublic::Key1024(x) => write!(fmt, "RSA:{:?}", x),
RSAPublic::Key2048(x) => write!(fmt, "RSA:{:?}", x),
RSAPublic::Key3072(x) => write!(fmt, "RSA:{:?}", x),
RSAPublic::Key4096(x) => write!(fmt, "RSA:{:?}", x),
RSAPublic::Key8192(x) => write!(fmt, "RSA:{:?}", x),
RSAPublic::Key15360(x) => write!(fmt, "RSA:{:?}", x)
}
}
}
macro_rules! generate_rsa_public
{
($num: ident, $bar: ident, $var: ident, $size: expr) => {