IKKKVXOKA6MDXPPGVSDPFRY4TI6Y4SSKWO7FKDF4SRJU3WUTZ3MQC
SW5Z7UCNVHQNRXLVZQQMNJRQGQ2QBHYCTLPXU7GELNURZRYDZOMQC
NLPZS76WC64DN5RQEOB45KWXUSEP4VJOVEBR6OMCMFX4MYIOMKSAC
G3FNNIIUCVMPJUICDYPXVS6BP6225LIQZOV5MRNEGCBC5QY3N6NAC
7FRJYUI62VW257VVFQXND6OKSAILVTHGEJCXFE6CG6FIOIUTDVYAC
MCS77Y4VJGB6TU2HOLASGSRW4B6MT74XABD4KYALIRS54GGN2DDQC
MFMCIUMJUYCV2GW5P25D5753YBYXWIMLWKKWX4PABEM7ACUIBGWAC
2WEO7OZLWJJPUYK4WXLT5FD46G2MAEIHEYMDW5GASCBUNKOPXCVAC
Y67GNDVBCXX5V3SL3OAQCU3NX52OR34NXK7ARKHK7EQDGCLVTHTQC
2Q2DF2ROXVXS4WCJ3HTYPHMWFBIZLDYHMNFUODWBI7RACKFNFNZQC
XEKZBXNINGU2NELIKOQXWY5SS4MOVEVXX3QWQUSN42X7V46CQDKQC
2SFWWZ2RF742PDI3KLCCQ3CFK7E72I5MJLFNBSS2SVSRL5YOUJKAC
J4ZEHJHG4NGTGJPU5YMBW7IRTVZ7WOHIWI45FGM3Q3A7JHDTTXQAC
OQZGSEWMQXOSEDB6ACSY7NTNZYIYX4ECZWXJ6JD5I7FC64JHTLIQC
NHOSLQGG4CIWBE7VKL5MB7PSY3RZ5IVDFENMGZG6X755GGZ6B3VQC
//! const PKCS8_ENCRYPTED: &'static str = "-----BEGIN ENCRYPTED PRIVATE KEY-----\nMIIFLTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQITo1O0b8YrS0CAggA\nMAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBBtLH4T1KOfo1GGr7salhR8BIIE\n0KN9ednYwcTGSX3hg7fROhTw7JAJ1D4IdT1fsoGeNu2BFuIgF3cthGHe6S5zceI2\nMpkfwvHbsOlDFWMUIAb/VY8/iYxhNmd5J6NStMYRC9NC0fVzOmrJqE1wITqxtORx\nIkzqkgFUbaaiFFQPepsh5CvQfAgGEWV329SsTOKIgyTj97RxfZIKA+TR5J5g2dJY\nj346SvHhSxJ4Jc0asccgMb0HGh9UUDzDSql0OIdbnZW5KzYJPOx+aDqnpbz7UzY/\nP8N0w/pEiGmkdkNyvGsdttcjFpOWlLnLDhtLx8dDwi/sbEYHtpMzsYC9jPn3hnds\nTcotqjoSZ31O6rJD4z18FOQb4iZs3MohwEdDd9XKblTfYKM62aQJWH6cVQcg+1C7\njX9l2wmyK26Tkkl5Qg/qSfzrCveke5muZgZkFwL0GCcgPJ8RixSB4GOdSMa/hAMU\nkvFAtoV2GluIgmSe1pG5cNMhurxM1dPPf4WnD+9hkFFSsMkTAuxDZIdDk3FA8zof\nYhv0ZTfvT6V+vgH3Hv7Tqcxomy5Qr3tj5vvAqqDU6k7fC4FvkxDh2mG5ovWvc4Nb\nXv8sed0LGpYitIOMldu6650LoZAqJVv5N4cAA2Edqldf7S2Iz1QnA/usXkQd4tLa\nZ80+sDNv9eCVkfaJ6kOVLk/ghLdXWJYRLenfQZtVUXrPkaPpNXgD0dlaTN8KuvML\nUw/UGa+4ybnPsdVflI0YkJKbxouhp4iB4S5ACAwqHVmsH5GRnujf10qLoS7RjDAl\no/wSHxdT9BECp7TT8ID65u2mlJvH13iJbktPczGXt07nBiBse6OxsClfBtHkRLzE\nQF6UMEXsJnIIMRfrZQnduC8FUOkfPOSXc8r9SeZ3GhfbV/DmWZvFPCpjzKYPsM5+\nN8Bw/iZ7NIH4xzNOgwdp5BzjH9hRtCt4sUKVVlWfEDtTnkHNOusQGKu7HkBF87YZ\nRN/Nd3gvHob668JOcGchcOzcsqsgzhGMD8+G9T9oZkFCYtwUXQU2XjMN0R4VtQgZ\nrAxWyQau9xXMGyDC67gQ5xSn+oqMK0HmoW8jh2LG/cUowHFAkUxdzGadnjGhMOI2\nzwNJPIjF93eDF/+zW5E1l0iGdiYyHkJbWSvcCuvTwma9FIDB45vOh5mSR+YjjSM5\nnq3THSWNi7Cxqz12Q1+i9pz92T2myYKBBtu1WDh+2KOn5DUkfEadY5SsIu/Rb7ub\n5FBihk2RN3y/iZk+36I69HgGg1OElYjps3D+A9AjVby10zxxLAz8U28YqJZm4wA/\nT0HLxBiVw+rsHmLP79KvsT2+b4Diqih+VTXouPWC/W+lELYKSlqnJCat77IxgM9e\nYIhzD47OgWl33GJ/R10+RDoDvY4koYE+V5NLglEhbwjloo9Ryv5ywBJNS7mfXMsK\n/uf+l2AscZTZ1mhtL38efTQCIRjyFHc3V31DI0UdETADi+/Omz+bXu0D5VvX+7c6\nb1iVZKpJw8KUjzeUV8yOZhvGu3LrQbhkTPVYL555iP1KN0Eya88ra+FUKMwLgjYr\nJkUx4iad4dTsGPodwEP/Y9oX/Qk3ZQr+REZ8lg6IBoKKqqrQeBJ9gkm1jfKE6Xkc\nCog3JMeTrb3LiPHgN6gU2P30MRp6L1j1J/MtlOAr5rux\n-----END ENCRYPTED PRIVATE KEY-----\n";
//! const PKCS8_ENCRYPTED: &str = "-----BEGIN ENCRYPTED PRIVATE KEY-----\nMIIFLTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQITo1O0b8YrS0CAggA\nMAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBBtLH4T1KOfo1GGr7salhR8BIIE\n0KN9ednYwcTGSX3hg7fROhTw7JAJ1D4IdT1fsoGeNu2BFuIgF3cthGHe6S5zceI2\nMpkfwvHbsOlDFWMUIAb/VY8/iYxhNmd5J6NStMYRC9NC0fVzOmrJqE1wITqxtORx\nIkzqkgFUbaaiFFQPepsh5CvQfAgGEWV329SsTOKIgyTj97RxfZIKA+TR5J5g2dJY\nj346SvHhSxJ4Jc0asccgMb0HGh9UUDzDSql0OIdbnZW5KzYJPOx+aDqnpbz7UzY/\nP8N0w/pEiGmkdkNyvGsdttcjFpOWlLnLDhtLx8dDwi/sbEYHtpMzsYC9jPn3hnds\nTcotqjoSZ31O6rJD4z18FOQb4iZs3MohwEdDd9XKblTfYKM62aQJWH6cVQcg+1C7\njX9l2wmyK26Tkkl5Qg/qSfzrCveke5muZgZkFwL0GCcgPJ8RixSB4GOdSMa/hAMU\nkvFAtoV2GluIgmSe1pG5cNMhurxM1dPPf4WnD+9hkFFSsMkTAuxDZIdDk3FA8zof\nYhv0ZTfvT6V+vgH3Hv7Tqcxomy5Qr3tj5vvAqqDU6k7fC4FvkxDh2mG5ovWvc4Nb\nXv8sed0LGpYitIOMldu6650LoZAqJVv5N4cAA2Edqldf7S2Iz1QnA/usXkQd4tLa\nZ80+sDNv9eCVkfaJ6kOVLk/ghLdXWJYRLenfQZtVUXrPkaPpNXgD0dlaTN8KuvML\nUw/UGa+4ybnPsdVflI0YkJKbxouhp4iB4S5ACAwqHVmsH5GRnujf10qLoS7RjDAl\no/wSHxdT9BECp7TT8ID65u2mlJvH13iJbktPczGXt07nBiBse6OxsClfBtHkRLzE\nQF6UMEXsJnIIMRfrZQnduC8FUOkfPOSXc8r9SeZ3GhfbV/DmWZvFPCpjzKYPsM5+\nN8Bw/iZ7NIH4xzNOgwdp5BzjH9hRtCt4sUKVVlWfEDtTnkHNOusQGKu7HkBF87YZ\nRN/Nd3gvHob668JOcGchcOzcsqsgzhGMD8+G9T9oZkFCYtwUXQU2XjMN0R4VtQgZ\nrAxWyQau9xXMGyDC67gQ5xSn+oqMK0HmoW8jh2LG/cUowHFAkUxdzGadnjGhMOI2\nzwNJPIjF93eDF/+zW5E1l0iGdiYyHkJbWSvcCuvTwma9FIDB45vOh5mSR+YjjSM5\nnq3THSWNi7Cxqz12Q1+i9pz92T2myYKBBtu1WDh+2KOn5DUkfEadY5SsIu/Rb7ub\n5FBihk2RN3y/iZk+36I69HgGg1OElYjps3D+A9AjVby10zxxLAz8U28YqJZm4wA/\nT0HLxBiVw+rsHmLP79KvsT2+b4Diqih+VTXouPWC/W+lELYKSlqnJCat77IxgM9e\nYIhzD47OgWl33GJ/R10+RDoDvY4koYE+V5NLglEhbwjloo9Ryv5ywBJNS7mfXMsK\n/uf+l2AscZTZ1mhtL38efTQCIRjyFHc3V31DI0UdETADi+/Omz+bXu0D5VvX+7c6\nb1iVZKpJw8KUjzeUV8yOZhvGu3LrQbhkTPVYL555iP1KN0Eya88ra+FUKMwLgjYr\nJkUx4iad4dTsGPodwEP/Y9oX/Qk3ZQr+REZ8lg6IBoKKqqrQeBJ9gkm1jfKE6Xkc\nCog3JMeTrb3LiPHgN6gU2P30MRp6L1j1J/MtlOAr5rux\n-----END ENCRYPTED PRIVATE KEY-----\n";
match (hosts, key) {
(Some(h), Some(k)) => {
debug!("{:?} {:?}", h, k);
let host_matches = h.split(',').any(|x| x == host_port);
if host_matches {
if &parse_public_key_base64(k)? == pubkey {
return Ok(true);
} else {
return Err((Error::KeyChanged { line }).into());
}
if let (Some(h), Some(k)) = (hosts, key) {
debug!("{:?} {:?}", h, k);
let host_matches = h.split(',').any(|x| x == host_port);
if host_matches {
if &parse_public_key_base64(k)? == pubkey {
return Ok(true);
} else {
return Err(Error::KeyChanged { line });
if key_algo != b"ssh-rsa" && key_algo != b"rsa-sha2-256" && key_algo != b"rsa-sha2-512" {
return Err(Error::CouldNotReadKey.into());
if key_algo != b"ssh-rsa"
&& key_algo != b"rsa-sha2-256"
&& key_algo != b"rsa-sha2-512"
{
return Err(Error::CouldNotReadKey);
match self {
&KeyPair::Ed25519(ref secret) => Ok(Signature::Ed25519(SignatureBytes(
sodium::ed25519::sign_detached(to_sign.as_ref(), secret).0,
match *self {
KeyPair::Ed25519(ref secret) => Ok(Signature::Ed25519(SignatureBytes(
sodium::ed25519::sign_detached(to_sign, secret).0,
match self {
&KeyPair::Ed25519(ref secret) => {
let signature = sodium::ed25519::sign_detached(&buffer, secret);
match *self {
KeyPair::Ed25519(ref secret) => {
let signature = sodium::ed25519::sign_detached(buffer, secret);
const PBES2: &'static [u64] = &[1, 2, 840, 113549, 1, 5, 13];
const PBKDF2: &'static [u64] = &[1, 2, 840, 113549, 1, 5, 12];
const HMAC_SHA256: &'static [u64] = &[1, 2, 840, 113549, 2, 9];
const AES256CBC: &'static [u64] = &[2, 16, 840, 1, 101, 3, 4, 1, 42];
const ED25519: &'static [u64] = &[1, 3, 101, 112];
const PBES2: &[u64] = &[1, 2, 840, 113549, 1, 5, 13];
const PBKDF2: &[u64] = &[1, 2, 840, 113549, 1, 5, 12];
const HMAC_SHA256: &[u64] = &[1, 2, 840, 113549, 2, 9];
const AES256CBC: &[u64] = &[2, 16, 840, 1, 101, 3, 4, 1, 42];
const ED25519: &[u64] = &[1, 3, 101, 112];
for _ in 0..nkeys {
let key_type = position.read_string()?;
if key_type == KEYTYPE_ED25519 {
let pubkey = position.read_string()?;
let seckey = position.read_string()?;
let _comment = position.read_string()?;
assert_eq!(pubkey, &seckey[32..]);
use key::ed25519::*;
let mut secret = SecretKey::new_zeroed();
secret.key.clone_from_slice(seckey);
return Ok(key::KeyPair::Ed25519(secret));
} 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 key_type = position.read_string()?;
if key_type == KEYTYPE_ED25519 {
let pubkey = position.read_string()?;
let seckey = position.read_string()?;
let _comment = position.read_string()?;
assert_eq!(pubkey, &seckey[32..]);
use key::ed25519::*;
let mut secret = SecretKey::new_zeroed();
secret.key.clone_from_slice(seckey);
Ok(key::KeyPair::Ed25519(secret))
} 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,
});
}
} else {
return Err(Error::UnsupportedKeyType(key_type.to_vec()).into());
let key = openssl::rsa::RsaPrivateKeyBuilder::new(n, e, d)?
.set_factors(p, q)?
.set_crt_params(dmp1, dmq1, iqmp)?
.build();
key.check_key().unwrap();
Ok(key::KeyPair::RSA {
key,
hash: key::SignatureHash::SHA2_512,
})
} else {
match lower.as_str() {
"host" => {
if value.trim_start() == host {
let mut c = Config::default(host);
c.port = 22;
config = Some(c)
}
}
_ => {}
}
} else if lower.as_str() == "host" && value.trim_start() == host {
let mut c = Config::default(host);
c.port = 22;
config = Some(c)
if i >= 8 {
if &ssh_id.buf[0..8] == b"SSH-2.0-" {
// Either the line starts with "SSH-2.0-"
ssh_id.sshid_len = i;
return Ok(&ssh_id.buf[..ssh_id.sshid_len]);
}
if i >= 8 && &ssh_id.buf[0..8] == b"SSH-2.0-" {
// Either the line starts with "SSH-2.0-"
ssh_id.sshid_len = i;
return Ok(&ssh_id.buf[..ssh_id.sshid_len]);
) {
if enc.rekey.is_none() {
debug!("starting rekeying");
if let Some(exchange) = enc.exchange.take() {
let mut kexinit = KexInit::initiate_rekey(exchange, &enc.session_id);
kexinit.server_write(
&self.common.config.as_ref(),
&mut self.common.cipher,
&mut self.common.write_buffer,
)?;
enc.rekey = Some(Kex::KexInit(kexinit))
}
) && enc.rekey.is_none() {
debug!("starting rekeying");
if let Some(exchange) = enc.exchange.take() {
let mut kexinit = KexInit::initiate_rekey(exchange, &enc.session_id);
kexinit.server_write(
self.common.config.as_ref(),
&self.common.cipher,
&mut self.common.write_buffer,
)?;
enc.rekey = Some(Kex::KexInit(kexinit))
match method {
&auth::Method::PublicKey { ref key } => {
let i0 = self.client_make_to_sign(user, key.as_ref(), buffer);
// Extend with self-signature.
key.add_self_signature(buffer)?;
push_packet!(self.write, {
self.write.extend(&buffer[i0..]);
})
}
_ => {}
if let &auth::Method::PublicKey { ref key } = method {
let i0 = self.client_make_to_sign(user, key.as_ref(), buffer);
// Extend with self-signature.
key.add_self_signature(buffer)?;
push_packet!(self.write, {
self.write.extend(&buffer[i0..]);
})