MCS77Y4VJGB6TU2HOLASGSRW4B6MT74XABD4KYALIRS54GGN2DDQC
//! The following example shows how to do all these in a single
//! example: start and SSH agent server, connect to it with a client,
//! decipher an encrypted private key (the password is `b"blabla"`),
//! send it to the agent, and ask the agent to sign a piece of data
//! (`b"Please sign this", below).
//! The following example (which uses the `openssl` feature) shows how
//! to do all these in a single example: start and SSH agent server,
//! connect to it with a client, decipher an encrypted private key
//! (the password is `b"blabla"`), send it to the agent, and ask the
//! agent to sign a piece of data (`b"Please sign this", below).
//! fn confirm(&self, _: std::sync::Arc<key::KeyPair>) -> Box<dyn Future<Output = bool> + Send + Unpin> {
//! Box::new(futures::future::ready(true))
//! fn confirm(self, _: std::sync::Arc<key::KeyPair>) -> Box<dyn Future<Output = (Self, bool)> + Send + Unpin> {
//! Box::new(futures::future::ready((self, true)))
//! let sig = client.sign_request(&public, buf).await?.unwrap();
//! assert!(public.verify_detached(buf, sig.as_ref()));
//! let sig = client.sign_request(&public, cryptovec::CryptoVec::from_slice(&buf[..])).await.1.unwrap();
//! // Here, `sig` is encoded in a format usable internally by the SSH protocol.
b"ssh-rsa" | b"rsa-sha2-256" | b"rsa-sha2-512" => {
let mut p = pubkey.reader(0);
let key_algo = p.read_string()?;
debug!("{:?}", std::str::from_utf8(key_algo));
if key_algo != b"ssh-rsa"
&& key_algo != b"rsa-sha2-256"
&& key_algo != b"rsa-sha2-512"
b"ssh-rsa" | b"rsa-sha2-256" | b"rsa-sha2-512" if cfg!(feature = "openssl") => {
#[cfg(feature = "openssl")]
{
let mut p = pubkey.reader(0);
let key_algo = p.read_string()?;
debug!("{:?}", std::str::from_utf8(key_algo));
if key_algo != b"ssh-rsa" && key_algo != b"rsa-sha2-256" && key_algo != b"rsa-sha2-512" {
return Err(Error::CouldNotReadKey.into());
}
let key_e = p.read_string()?;
let key_n = p.read_string()?;
use openssl::bn::BigNum;
use openssl::pkey::PKey;
use openssl::rsa::Rsa;
Ok(PublicKey::RSA {
key: OpenSSLPKey(PKey::from_rsa(Rsa::from_public_components(
BigNum::from_slice(key_n)?,
BigNum::from_slice(key_e)?,
)?)?),
hash: {
if algo == b"rsa-sha2-256" {
SignatureHash::SHA2_256
} else if algo == b"rsa-sha2-512" {
SignatureHash::SHA2_512
} else {
SignatureHash::SHA1
}
},
})
}
#[cfg(not(feature = "openssl"))]
let key_e = p.read_string()?;
let key_n = p.read_string()?;
use openssl::bn::BigNum;
use openssl::pkey::PKey;
use openssl::rsa::Rsa;
Ok(PublicKey::RSA {
key: OpenSSLPKey(PKey::from_rsa(Rsa::from_public_components(
BigNum::from_slice(key_n)?,
BigNum::from_slice(key_e)?,
)?)?),
hash: {
if algo == b"rsa-sha2-256" {
SignatureHash::SHA2_256
} else if algo == b"rsa-sha2-512" {
SignatureHash::SHA2_512
} else {
SignatureHash::SHA1
}
},
})
let e = pos.read_string()?;
let n = pos.read_string()?;
use openssl::bn::*;
use openssl::pkey::*;
use openssl::rsa::*;
return Ok(PublicKey::RSA {
key: OpenSSLPKey(PKey::from_rsa(Rsa::from_public_components(
BigNum::from_slice(n)?,
BigNum::from_slice(e)?,
)?)?),
hash: SignatureHash::SHA2_256,
});
#[cfg(feature = "openssl")]
{
let e = pos.read_string()?;
let n = pos.read_string()?;
use openssl::bn::*;
use openssl::pkey::*;
use openssl::rsa::*;
return Ok(PublicKey::RSA {
key: OpenSSLPKey(PKey::from_rsa(Rsa::from_public_components(
BigNum::from_slice(n)?,
BigNum::from_slice(e)?,
)?)?),
hash: SignatureHash::SHA2_256,
});
}
let (cipher, iv) = match *self {
Encryption::Aes128Cbc(ref iv) => (Cipher::aes_128_cbc(), iv),
Encryption::Aes256Cbc(ref iv) => (Cipher::aes_256_cbc(), iv),
};
let mut dec = decrypt(cipher, &key, Some(&iv[..]), ciphertext)?;
pkcs_unpad(&mut dec);
Ok(dec)
match *self {
Encryption::Aes128Cbc(ref iv) => {
let c = Aes128Cbc::new_from_slices(key, iv).unwrap();
let mut dec = ciphertext.to_vec();
c.decrypt(&mut dec)?;
pkcs_unpad(&mut dec);
Ok(dec)
},
Encryption::Aes256Cbc(ref iv) => {
let c = Aes256Cbc::new_from_slices(key, iv).unwrap();
let mut dec = ciphertext.to_vec();
c.decrypt(&mut dec)?;
pkcs_unpad(&mut dec);
Ok(dec)
},
}
let mut h = Hasher::new(MessageDigest::md5()).unwrap();
h.update(pass).unwrap();
h.update(&iv[..8]).unwrap();
let md5 = h.finish().unwrap();
let mut dec = decrypt(Cipher::aes_128_cbc(), &md5, Some(&iv[..]), secret)?;
let mut c = md5::Context::new();
c.consume(pass.as_bytes());
c.consume(&iv[..8]);
let md5 = c.compute();
let c = Aes128Cbc::new_from_slices(&md5.0, &iv[..]).unwrap();
let mut dec = secret.to_vec();
c.decrypt(&mut dec).unwrap();
} else if key_type == KEYTYPE_RSA {
let n = BigNum::from_slice(position.read_string()?)?;
let e = BigNum::from_slice(position.read_string()?)?;
let d = BigNum::from_slice(position.read_string()?)?;
let iqmp = BigNum::from_slice(position.read_string()?)?;
let p = BigNum::from_slice(position.read_string()?)?;
let q = BigNum::from_slice(position.read_string()?)?;
} else if key_type == KEYTYPE_RSA && cfg!(feature = "openssl") {
#[cfg(feature = "openssl")]
{
let n = BigNum::from_slice(position.read_string()?)?;
let e = BigNum::from_slice(position.read_string()?)?;
let d = BigNum::from_slice(position.read_string()?)?;
let iqmp = BigNum::from_slice(position.read_string()?)?;
let p = BigNum::from_slice(position.read_string()?)?;
let q = BigNum::from_slice(position.read_string()?)?;
let mut ctx = openssl::bn::BigNumContext::new()?;
let un = openssl::bn::BigNum::from_u32(1)?;
let mut p1 = openssl::bn::BigNum::new()?;
let mut q1 = openssl::bn::BigNum::new()?;
p1.checked_sub(&p, &un)?;
q1.checked_sub(&q, &un)?;
let mut dmp1 = openssl::bn::BigNum::new()?; // d mod p-1
dmp1.checked_rem(&d, &p1, &mut ctx)?;
let mut dmq1 = openssl::bn::BigNum::new()?; // d mod q-1
dmq1.checked_rem(&d, &q1, &mut ctx)?;
let mut ctx = openssl::bn::BigNumContext::new()?;
let un = openssl::bn::BigNum::from_u32(1)?;
let mut p1 = openssl::bn::BigNum::new()?;
let mut q1 = openssl::bn::BigNum::new()?;
p1.checked_sub(&p, &un)?;
q1.checked_sub(&q, &un)?;
let mut dmp1 = openssl::bn::BigNum::new()?; // d mod p-1
dmp1.checked_rem(&d, &p1, &mut ctx)?;
let mut dmq1 = openssl::bn::BigNum::new()?; // d mod q-1
dmq1.checked_rem(&d, &q1, &mut ctx)?;
let key = openssl::rsa::RsaPrivateKeyBuilder::new(n, e, d)?
.set_factors(p, q)?
.set_crt_params(dmp1, dmq1, iqmp)?
.build();
key.check_key().unwrap();
return Ok(key::KeyPair::RSA {
key,
hash: key::SignatureHash::SHA2_512,
});
let key = openssl::rsa::RsaPrivateKeyBuilder::new(n, e, d)?
.set_factors(p, q)?
.set_crt_params(dmp1, dmq1, iqmp)?
.build();
key.check_key().unwrap();
return Ok(key::KeyPair::RSA {
key,
hash: key::SignatureHash::SHA2_512,
});
}
let mut key = CryptoVec::new();
let cipher = match ciphername {
b"aes128-cbc" => {
key.resize(16 + 16);
Cipher::aes_128_cbc()
}
b"aes128-ctr" => {
key.resize(16 + 16);
Cipher::aes_128_ctr()
}
b"aes256-cbc" => {
key.resize(16 + 32);
Cipher::aes_256_cbc()
}
b"aes256-ctr" => {
key.resize(16 + 32);
Cipher::aes_256_ctr()
}
let mut key = [0; 48];
let n = match ciphername {
b"aes128-cbc" | b"aes128-ctr" => 32,
b"aes256-cbc" | b"aes256-ctr" => 48,
let iv = &key[32..];
let key = &key[..32];
let mut c = Crypter::new(cipher, Mode::Decrypt, &key, Some(&iv))?;
c.pad(false);
let mut dec = vec![0; secret_key.len() + 32];
let n = c.update(&secret_key, &mut dec)?;
let n = n + c.finalize(&mut dec[n..])?;
dec.truncate(n);
let (key, iv) = key.split_at(n - 16);
let mut dec = secret_key.to_vec();
dec.resize(dec.len() + 32, 0u8);
use aes::cipher::{NewCipher, StreamCipher};
use block_modes::BlockMode;
match ciphername {
b"aes128-cbc" => {
let cipher = Aes128Cbc::new_from_slices(key, iv).unwrap();
let n = cipher.decrypt(&mut dec)?.len();
dec.truncate(n)
}
b"aes256-cbc" => {
let cipher = Aes256Cbc::new_from_slices(key, iv).unwrap();
let n = cipher.decrypt(&mut dec)?.len();
dec.truncate(n)
}
b"aes128-ctr" => {
let mut cipher = Aes128Ctr::new_from_slices(key, iv).unwrap();
cipher.apply_keystream(&mut dec);
dec.truncate(secret_key.len())
}
b"aes256-ctr" => {
let mut cipher = Aes256Ctr::new_from_slices(key, iv).unwrap();
cipher.apply_keystream(&mut dec);
dec.truncate(secret_key.len())
}
_ => {}
}
let iv_: Vec<u8> =
HEXLOWER_PERMISSIVE.decode(l.split_at(AES_128_CBC.len()).1.as_bytes())?;
if iv_.len() != 16 {
return Err(Error::CouldNotReadKey.into());
#[cfg(feature = "openssl")]
{
let iv_: Vec<u8> = HEXLOWER_PERMISSIVE
.decode(l.split_at(AES_128_CBC.len()).1.as_bytes())?;
if iv_.len() != 16 {
return Err(Error::CouldNotReadKey.into());
}
let mut iv = [0; 16];
iv.clone_from_slice(&iv_);
format = Some(Format::Pkcs5Encrypted(Encryption::Aes128Cbc(iv)))
} else if l == "-----BEGIN RSA PRIVATE KEY-----" {
started = true;
format = Some(Format::Rsa);
} else if l == "-----BEGIN RSA PRIVATE KEY-----" && cfg!(feature = "openssl") {
#[cfg(feature = "openssl")]
{
started = true;
format = Some(Format::Rsa);
}
byteorder = "1.3"
tokio = { version = "1.4", features = [ "io-util", "rt-multi-thread", "time", "net" ] }
byteorder = "1.4"
tokio = { version = "1.6", features = [ "io-util", "rt-multi-thread", "time", "net" ] }
tokio-stream = { version = "0.1", features = [ "net" ] }