feat: add tests, add sshpubkey, sshprivkey, sshcert, sshbase
This commit is contained in:
@@ -1 +1,5 @@
|
||||
mod sshrw;
|
||||
mod sshbase;
|
||||
mod sshrw;
|
||||
mod sshpubkey;
|
||||
mod sshprivkey;
|
||||
mod sshcert;
|
||||
3
src/sshbase.rs
Normal file
3
src/sshbase.rs
Normal file
@@ -0,0 +1,3 @@
|
||||
use std::error::Error;
|
||||
|
||||
pub type SshResult<T> = Result<T, Box<dyn Error>>;
|
||||
1
src/sshcert.rs
Normal file
1
src/sshcert.rs
Normal file
@@ -0,0 +1 @@
|
||||
pub struct SshCert {}
|
||||
1
src/sshprivkey.rs
Normal file
1
src/sshprivkey.rs
Normal file
@@ -0,0 +1 @@
|
||||
pub struct SshPrivateKey {}
|
||||
41
src/sshpubkey.rs
Normal file
41
src/sshpubkey.rs
Normal file
@@ -0,0 +1,41 @@
|
||||
use crate::sshbase::SshResult;
|
||||
|
||||
pub struct SshPubicKey {
|
||||
pub algorithm: String,
|
||||
pub value: SshPubicKeyValue,
|
||||
pub comment: Option<String>,
|
||||
}
|
||||
|
||||
pub enum SshPubicKeyValue {
|
||||
Rsa(SshRsaPublicKeyValue),
|
||||
Ecdsa(SshEcdsaPublicKeyValue),
|
||||
Ed25519(SshEd25519PublicKeyValue),
|
||||
}
|
||||
|
||||
pub struct SshRsaPublicKeyValue {
|
||||
pub e: Vec<u8>,
|
||||
pub n: Vec<u8>,
|
||||
}
|
||||
|
||||
pub enum SshEcdsaPublicKeyAlgorithm {
|
||||
Sha2NistP256,
|
||||
Sha2NistP384,
|
||||
Sha2NistP521,
|
||||
}
|
||||
|
||||
pub struct SshEcdsaPublicKeyValue {
|
||||
pub a: SshEcdsaPublicKeyAlgorithm,
|
||||
pub p: String,
|
||||
}
|
||||
|
||||
pub struct SshEd25519PublicKeyValue {
|
||||
pub p: Vec<u8>,
|
||||
}
|
||||
|
||||
impl SshPubicKey {
|
||||
pub fn parse(key: &str) -> SshResult<Self> {
|
||||
// TODO ...
|
||||
|
||||
Err("".to_string())?
|
||||
}
|
||||
}
|
||||
74
src/sshrw.rs
74
src/sshrw.rs
@@ -1,11 +1,7 @@
|
||||
use crate::sshbase::SshResult;
|
||||
use base64::Engine;
|
||||
use std::error::Error;
|
||||
use std::io::{Cursor, Read};
|
||||
|
||||
const ED25519_PK_SZ: u32 = 32;
|
||||
|
||||
pub type SshResult<T> = Result<T, Box<dyn Error>>;
|
||||
|
||||
pub struct SshReader {
|
||||
buffer_len: usize,
|
||||
read_len: usize,
|
||||
@@ -43,6 +39,15 @@ impl SshReader {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_big_num(&mut self) -> SshResult<Vec<u8>> {
|
||||
let bn = self.read_string()?;
|
||||
if bn.len() > 1 && bn[0] == 0 {
|
||||
Ok(bn[1..].to_vec())
|
||||
} else {
|
||||
Ok(bn)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_left(&mut self) -> SshResult<Vec<u8>> {
|
||||
self.read_bytes(self.left_bytes() as u32)
|
||||
}
|
||||
@@ -59,12 +64,16 @@ pub struct SshWriter {
|
||||
}
|
||||
|
||||
impl SshWriter {
|
||||
pub fn new(bytes: Vec<u8>) -> Self {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
buffer: bytes,
|
||||
buffer: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_slice(&self) -> &[u8] {
|
||||
self.buffer.as_slice()
|
||||
}
|
||||
|
||||
pub fn write_bytes(&mut self, bytes: &[u8]) {
|
||||
self.buffer.extend_from_slice(bytes);
|
||||
}
|
||||
@@ -77,6 +86,17 @@ impl SshWriter {
|
||||
self.write_u32(bytes.len() as u32);
|
||||
self.write_bytes(bytes);
|
||||
}
|
||||
|
||||
pub fn write_big_num(&mut self, bn: &[u8]) {
|
||||
if (bn.len() > 0) && (bn[0] & 0x80 != 0) {
|
||||
let mut buff = Vec::with_capacity(bn.len() + 1);
|
||||
buff.push(0_u8);
|
||||
buff.extend_from_slice(bn);
|
||||
self.write_string(&buff);
|
||||
} else {
|
||||
self.write_string(bn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -93,6 +113,28 @@ k/QQmZ2Nu29OYSWITbWcoeszsC+AmpFa9zhF/TG+iwmRFKlmodyCWU=";
|
||||
let algorithm = ssh_reader.read_string().unwrap();
|
||||
assert_eq!(b"ssh-rsa", algorithm.as_slice());
|
||||
|
||||
let e = ssh_reader.read_big_num().unwrap();
|
||||
let n = ssh_reader.read_big_num().unwrap();
|
||||
assert_eq!("010001", hex::encode(&e));
|
||||
assert_eq!("bcda85520bae21bb91f76e9772646352f70ee227f9c5f2207a0187e99577403126690ea1ec18b\
|
||||
7e38fcf2794981bea6242474bf536130d0d101c67854eff02e72df646dfce2d8296c4bae049b1adb56186af71\
|
||||
d3c858a9e5865b8d47434f1aa3246bac8512b27dee23c469325974ad11d6270e63918d93bd672860d03f4ebc9\
|
||||
7f1a11f4091c33644da002c7c0de496775bd4dd3048568d506ad56da45f19bfca5d02c918950fe859f4267000\
|
||||
44d3288e16288093987c5ea3caa9dfca7e4d67113dccbff29021d908a5d9cdf44accd64c27935c0c386a91fa1\
|
||||
3eda8adaf24cfdf5042417ca7964986df48052fa7fde791ff84130e554d49817478f1dcc6670944a09c5e6f7e\
|
||||
51181cc1aee084485914e05cca8c5710c586ed8170bfe7398dd39bdba666776503bd0b04771110e990336f31e\
|
||||
971771179dbd1308b78a81e5fb77c954c8e7675f0150690e9f46df547228bd7f7e269ea6870a24fd042667636\
|
||||
edbd3984962136d67287accec0be026a456bdce117f4c6fa2c264452a59a87720965", hex::encode(&n));
|
||||
|
||||
assert_eq!(0, ssh_reader.left_bytes());
|
||||
|
||||
let mut ssh_writer = SshWriter::new();
|
||||
ssh_writer.write_string(b"ssh-rsa");
|
||||
ssh_writer.write_big_num(&e);
|
||||
ssh_writer.write_big_num(&n);
|
||||
|
||||
assert_eq!(id_rsa_pub, STANDARD.encode(ssh_writer.as_slice()));
|
||||
|
||||
let id_rsa = "b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn\
|
||||
NhAAAAAwEAAQAAAYEAvNqFUguuIbuR926XcmRjUvcO4if5xfIgegGH6ZV3QDEmaQ6h7Bi3\
|
||||
44/PJ5SYG+piQkdL9TYTDQ0QHGeFTv8C5y32Rt/OLYKWxLrgSbGttWGGr3HTyFip5YZbjU\
|
||||
@@ -148,10 +190,19 @@ M9hkSeHxHrJ1+FMK2xNTd+LF17A/WW3YYTBCz8tQvhtgOQDiSk/9Lnc+vFlMF7LN0dwgwl4zIg07h0M=
|
||||
assert_eq!(
|
||||
"04bb03d7aa0f33d86449e1f11eb275f8530adb135377e2c5d7b03f596dd8613042cfcb50be1b603900e24a4\
|
||||
ffd2e773ebc594c17b2cdd1dc20c25e33220d3b8743",
|
||||
hex::encode(ecc_key_point));
|
||||
hex::encode(&ecc_key_point));
|
||||
|
||||
assert_eq!(0, ssh_reader.left_bytes());
|
||||
|
||||
let mut ssh_writer = SshWriter::new();
|
||||
ssh_writer.write_string(b"ecdsa-sha2-nistp256");
|
||||
let mut ecc_key_blob_writer = SshWriter::new();
|
||||
ecc_key_blob_writer.write_string(&ssh_algorithm);
|
||||
ecc_key_blob_writer.write_string(&ecc_key_point);
|
||||
ssh_writer.write_bytes(ecc_key_blob_writer.as_slice());
|
||||
|
||||
assert_eq!(id_ecdsa_pub, STANDARD.encode(ssh_writer.as_slice()));
|
||||
|
||||
let id_ecdsa = "b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAaAAAABNlY2RzYS\
|
||||
1zaGEyLW5pc3RwMjU2AAAACG5pc3RwMjU2AAAAQQS7A9eqDzPYZEnh8R6ydfhTCtsTU3fi\
|
||||
xdewP1lt2GEwQs/LUL4bYDkA4kpP/S53PrxZTBeyzdHcIMJeMyINO4dDAAAAuK3kG36t5B\"
|
||||
@@ -170,11 +221,18 @@ fn test_ed25519() {
|
||||
assert_eq!(b"ssh-ed25519", algorithm.as_slice());
|
||||
|
||||
let pub_key = ssh_reader.read_string().unwrap();
|
||||
assert_eq!(32, pub_key.len());
|
||||
assert_eq!("4c1c2f991eda6a910d7316337e155b8df633b7e30127ef014513bbb03b42acd6",
|
||||
hex::encode(&pub_key));
|
||||
|
||||
assert_eq!(0, ssh_reader.left_bytes());
|
||||
|
||||
let mut ssh_writer = SshWriter::new();
|
||||
ssh_writer.write_string(b"ssh-ed25519");
|
||||
ssh_writer.write_string(&pub_key);
|
||||
|
||||
assert_eq!(id_ed25519_pub, STANDARD.encode(ssh_writer.as_slice()));
|
||||
|
||||
let id_ed25519 = "b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW\
|
||||
QyNTUxOQAAACBMHC+ZHtpqkQ1zFjN+FVuN9jO34wEn7wFFE7uwO0Ks1gAAAKCwNsNtsDbD\
|
||||
bQAAAAtzc2gtZWQyNTUxOQAAACBMHC+ZHtpqkQ1zFjN+FVuN9jO34wEn7wFFE7uwO0Ks1g\
|
||||
|
||||
Reference in New Issue
Block a user