Farm off the SSH DSA support into its own module.
This commit is contained in:
81
src/ssh/dsa.rs
Normal file
81
src/ssh/dsa.rs
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
use cryptonum::unsigned::*;
|
||||||
|
use dsa::{DSAKeyPair,DSAParameters,DSAPubKey,DSAPublicKey,DSAPrivKey,DSAPrivateKey,L1024N160};
|
||||||
|
use std::io::{Read,Write};
|
||||||
|
use ssh::errors::{SSHKeyParseError,SSHKeyRenderError};
|
||||||
|
use ssh::frame::*;
|
||||||
|
use ssh::SSHKey;
|
||||||
|
|
||||||
|
impl SSHKey for DSAKeyPair<L1024N160> {
|
||||||
|
fn parse_ssh_public_info<I: Read>(inp: &mut I) -> Result<Self::Public,SSHKeyParseError>
|
||||||
|
{
|
||||||
|
let pubkey_type = parse_openssh_string(inp)?;
|
||||||
|
if pubkey_type != "ssh-dss" {
|
||||||
|
return Err(SSHKeyParseError::UnknownKeyType(pubkey_type));
|
||||||
|
}
|
||||||
|
let pubp = parse_openssh_number(inp)?;
|
||||||
|
let pubq = parse_openssh_number(inp)?;
|
||||||
|
let pubg = parse_openssh_number(inp)?;
|
||||||
|
let pubparams = L1024N160::new(pubp, pubg, pubq);
|
||||||
|
let puby: U1024 = parse_openssh_number(inp)?;
|
||||||
|
for _ in inp.bytes() { return Err(SSHKeyParseError::UnknownTrailingData); }
|
||||||
|
Ok(DSAPubKey::<L1024N160>::new(pubparams.clone(), puby.clone()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_ssh_private_info<I: Read>(inp: &mut I) -> Result<(Self::Private,String),SSHKeyParseError>
|
||||||
|
{
|
||||||
|
let check1 = parse_openssh_u32(inp)?;
|
||||||
|
let check2 = parse_openssh_u32(inp)?;
|
||||||
|
if check1 != check2 {
|
||||||
|
return Err(SSHKeyParseError::PrivateKeyCorruption);
|
||||||
|
}
|
||||||
|
let privkey_type = parse_openssh_string(inp)?;
|
||||||
|
if privkey_type != "ssh-dss" {
|
||||||
|
return Err(SSHKeyParseError::InconsistentKeyTypes("ssh-dss".to_string(), privkey_type));
|
||||||
|
}
|
||||||
|
let privp = parse_openssh_number(inp)?;
|
||||||
|
let privq = parse_openssh_number(inp)?;
|
||||||
|
let privg = parse_openssh_number(inp)?;
|
||||||
|
let privparams = L1024N160::new(privp, privg, privq);
|
||||||
|
let _ = parse_openssh_buffer(inp)?; // a copy of y we don't need
|
||||||
|
let privx = parse_openssh_number(inp)?;
|
||||||
|
|
||||||
|
let privkey = DSAPrivKey::<L1024N160>::new(privparams, privx);
|
||||||
|
let comment = parse_openssh_string(inp)?;
|
||||||
|
for (idx,byte) in inp.bytes().enumerate() {
|
||||||
|
if ((idx+1) as u8) != byte? {
|
||||||
|
return Err(SSHKeyParseError::InvalidPadding);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok((privkey,comment))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_ssh_public_info<O: Write>(&self, out: &mut O) -> Result<(),SSHKeyRenderError>
|
||||||
|
{
|
||||||
|
render_openssh_string(out, "ssh-dss")?;
|
||||||
|
render_openssh_number(out, &self.public.params.p)?;
|
||||||
|
render_openssh_number(out, &self.public.params.q)?;
|
||||||
|
render_openssh_number(out, &self.public.params.g)?;
|
||||||
|
render_openssh_number(out, &self.public.y)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_ssh_private_info<O: Write>(&self, out: &mut O, comment: &str) -> Result<(),SSHKeyRenderError>
|
||||||
|
{
|
||||||
|
render_openssh_u32(out, 0xDEADBEEF)?; // FIXME: Any reason for this to be random?
|
||||||
|
render_openssh_u32(out, 0xDEADBEEF)?; // ditto
|
||||||
|
render_openssh_string(out, "ssh-dss")?;
|
||||||
|
render_openssh_number(out, &self.private.params.p)?;
|
||||||
|
render_openssh_number(out, &self.private.params.q)?;
|
||||||
|
render_openssh_number(out, &self.private.params.g)?;
|
||||||
|
render_openssh_number(out, &self.public.y)?;
|
||||||
|
render_openssh_number(out, &self.private.x)?;
|
||||||
|
render_openssh_string(out, comment)?;
|
||||||
|
// add some padding (not quite sure why)
|
||||||
|
let mut i = comment.len();
|
||||||
|
while (i % 16) != 0 {
|
||||||
|
out.write(&[(i - comment.len() + 1) as u8])?;
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +1,9 @@
|
|||||||
|
mod dsa;
|
||||||
mod errors;
|
mod errors;
|
||||||
mod frame;
|
mod frame;
|
||||||
|
|
||||||
pub use self::errors::{SSHKeyParseError,SSHKeyRenderError};
|
pub use self::errors::{SSHKeyParseError,SSHKeyRenderError};
|
||||||
|
|
||||||
use cryptonum::unsigned::*;
|
|
||||||
use dsa::{DSAKeyPair,DSAParameters,DSAPubKey,DSAPublicKey,DSAPrivKey,DSAPrivateKey,L1024N160};
|
|
||||||
use self::frame::*;
|
use self::frame::*;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{Cursor,Read,Write};
|
use std::io::{Cursor,Read,Write};
|
||||||
@@ -100,81 +99,9 @@ pub fn write_ssh_keyfile<KP,P>(path: P, x: &KP, comment: &str) -> Result<(),SSHK
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl SSHKey for DSAKeyPair<L1024N160> {
|
|
||||||
fn parse_ssh_public_info<I: Read>(inp: &mut I) -> Result<Self::Public,SSHKeyParseError>
|
|
||||||
{
|
|
||||||
let pubkey_type = parse_openssh_string(inp)?;
|
|
||||||
if pubkey_type != "ssh-dss" {
|
|
||||||
return Err(SSHKeyParseError::UnknownKeyType(pubkey_type));
|
|
||||||
}
|
|
||||||
let pubp = parse_openssh_number(inp)?;
|
|
||||||
let pubq = parse_openssh_number(inp)?;
|
|
||||||
let pubg = parse_openssh_number(inp)?;
|
|
||||||
let pubparams = L1024N160::new(pubp, pubg, pubq);
|
|
||||||
let puby: U1024 = parse_openssh_number(inp)?;
|
|
||||||
for _ in inp.bytes() { return Err(SSHKeyParseError::UnknownTrailingData); }
|
|
||||||
Ok(DSAPubKey::<L1024N160>::new(pubparams.clone(), puby.clone()))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_ssh_private_info<I: Read>(inp: &mut I) -> Result<(Self::Private,String),SSHKeyParseError>
|
|
||||||
{
|
|
||||||
let check1 = parse_openssh_u32(inp)?;
|
|
||||||
let check2 = parse_openssh_u32(inp)?;
|
|
||||||
if check1 != check2 {
|
|
||||||
return Err(SSHKeyParseError::PrivateKeyCorruption);
|
|
||||||
}
|
|
||||||
let privkey_type = parse_openssh_string(inp)?;
|
|
||||||
if privkey_type != "ssh-dss" {
|
|
||||||
return Err(SSHKeyParseError::InconsistentKeyTypes("ssh-dss".to_string(), privkey_type));
|
|
||||||
}
|
|
||||||
let privp = parse_openssh_number(inp)?;
|
|
||||||
let privq = parse_openssh_number(inp)?;
|
|
||||||
let privg = parse_openssh_number(inp)?;
|
|
||||||
let privparams = L1024N160::new(privp, privg, privq);
|
|
||||||
let _ = parse_openssh_buffer(inp)?; // a copy of y we don't need
|
|
||||||
let privx = parse_openssh_number(inp)?;
|
|
||||||
|
|
||||||
let privkey = DSAPrivKey::<L1024N160>::new(privparams, privx);
|
|
||||||
let comment = parse_openssh_string(inp)?;
|
|
||||||
for (idx,byte) in inp.bytes().enumerate() {
|
|
||||||
if ((idx+1) as u8) != byte? {
|
|
||||||
return Err(SSHKeyParseError::InvalidPadding);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok((privkey,comment))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render_ssh_public_info<O: Write>(&self, out: &mut O) -> Result<(),SSHKeyRenderError>
|
|
||||||
{
|
|
||||||
render_openssh_string(out, "ssh-dss")?;
|
|
||||||
render_openssh_number(out, &self.public.params.p)?;
|
|
||||||
render_openssh_number(out, &self.public.params.q)?;
|
|
||||||
render_openssh_number(out, &self.public.params.g)?;
|
|
||||||
render_openssh_number(out, &self.public.y)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render_ssh_private_info<O: Write>(&self, out: &mut O, comment: &str) -> Result<(),SSHKeyRenderError>
|
|
||||||
{
|
|
||||||
render_openssh_u32(out, 0xDEADBEEF)?; // FIXME: Any reason for this to be random?
|
|
||||||
render_openssh_u32(out, 0xDEADBEEF)?; // ditto
|
|
||||||
render_openssh_string(out, "ssh-dss")?;
|
|
||||||
render_openssh_number(out, &self.private.params.p)?;
|
|
||||||
render_openssh_number(out, &self.private.params.q)?;
|
|
||||||
render_openssh_number(out, &self.private.params.g)?;
|
|
||||||
render_openssh_number(out, &self.public.y)?;
|
|
||||||
render_openssh_number(out, &self.private.x)?;
|
|
||||||
render_openssh_string(out, comment)?;
|
|
||||||
// add some padding (not quite sure why)
|
|
||||||
let mut i = comment.len();
|
|
||||||
while (i % 16) != 0 {
|
|
||||||
out.write(&[(i - comment.len() + 1) as u8])?;
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
use dsa::{DSAKeyPair,DSAPublicKey,DSAPrivateKey,L1024N160};
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use sha2::Sha256;
|
use sha2::Sha256;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user