#![cfg(feature = "alloc")]
use hex_literal::hex;
use ssh_key::{Algorithm, HashAlg, LineEnding, PublicKey, SshSig};
#[cfg(feature = "ed25519")]
use ssh_key::{Error, PrivateKey};
#[cfg(feature = "dsa")]
const DSA_PRIVATE_KEY: &str = include_str!("examples/id_dsa_1024");
#[cfg(feature = "dsa")]
const DSA_PUBLIC_KEY: &str = include_str!("examples/id_dsa_1024.pub");
#[cfg(feature = "p256")]
const ECDSA_P256_PRIVATE_KEY: &str = include_str!("examples/id_ecdsa_p256");
#[cfg(feature = "p256")]
const ECDSA_P256_PUBLIC_KEY: &str = include_str!("examples/id_ecdsa_p256.pub");
#[cfg(feature = "ed25519")]
const ED25519_PRIVATE_KEY: &str = include_str!("examples/id_ed25519");
const ED25519_PUBLIC_KEY: &str = include_str!("examples/id_ed25519.pub");
const ED25519_SIGNATURE: &str = include_str!("examples/sshsig_ed25519");
const ED25519_SIGNATURE_BYTES: [u8; 64] = hex!(
"4f11abfeb4c18d9e8c7832eccceeb947c9505a8c29fc074900ca2396c0f2a9ac"
"db06de2e97fafa33fd60928a4fc5a30630aa18020015094af457dc011154150f"
);
#[cfg(feature = "rsa")]
const RSA_PRIVATE_KEY: &str = include_str!("examples/id_rsa_3072");
#[cfg(feature = "rsa")]
const RSA_PUBLIC_KEY: &str = include_str!("examples/id_rsa_3072.pub");
#[cfg(feature = "ed25519")]
const MSG_EXAMPLE: &[u8] = b"testing";
const NAMESPACE_EXAMPLE: &str = "example";
#[test]
fn decode_ed25519() {
let sshsig = ED25519_SIGNATURE.parse::<SshSig>().unwrap();
let public_key = ED25519_PUBLIC_KEY.parse::<PublicKey>().unwrap();
assert_eq!(sshsig.algorithm(), Algorithm::Ed25519);
assert_eq!(sshsig.version(), 1);
assert_eq!(sshsig.public_key(), public_key.key_data());
assert_eq!(sshsig.namespace(), NAMESPACE_EXAMPLE);
assert_eq!(sshsig.reserved(), &[]);
assert_eq!(sshsig.hash_alg(), HashAlg::Sha512);
assert_eq!(sshsig.signature_bytes(), ED25519_SIGNATURE_BYTES);
}
#[test]
fn encode_ed25519() {
let sshsig = ED25519_SIGNATURE.parse::<SshSig>().unwrap();
let sshsig_pem = sshsig.to_pem(LineEnding::LF).unwrap();
assert_eq!(&sshsig_pem, ED25519_SIGNATURE);
}
#[test]
#[cfg(feature = "dsa")]
fn sign_dsa() {
let signing_key = PrivateKey::from_openssh(DSA_PRIVATE_KEY).unwrap();
let verifying_key = DSA_PUBLIC_KEY.parse::<PublicKey>().unwrap();
let signature = signing_key
.sign(NAMESPACE_EXAMPLE, HashAlg::Sha512, MSG_EXAMPLE)
.unwrap();
assert_eq!(
verifying_key.verify(NAMESPACE_EXAMPLE, MSG_EXAMPLE, &signature),
Ok(())
);
}
#[test]
#[cfg(feature = "p256")]
fn sign_ecdsa_p256() {
let signing_key = PrivateKey::from_openssh(ECDSA_P256_PRIVATE_KEY).unwrap();
let verifying_key = ECDSA_P256_PUBLIC_KEY.parse::<PublicKey>().unwrap();
let signature = signing_key
.sign(NAMESPACE_EXAMPLE, HashAlg::Sha512, MSG_EXAMPLE)
.unwrap();
assert_eq!(
verifying_key.verify(NAMESPACE_EXAMPLE, MSG_EXAMPLE, &signature),
Ok(())
);
}
#[test]
#[cfg(feature = "ed25519")]
fn sign_ed25519() {
let signing_key = PrivateKey::from_openssh(ED25519_PRIVATE_KEY).unwrap();
let signature = signing_key
.sign(NAMESPACE_EXAMPLE, HashAlg::Sha512, MSG_EXAMPLE)
.unwrap();
assert_eq!(signature, ED25519_SIGNATURE.parse::<SshSig>().unwrap());
}
#[test]
#[cfg(feature = "rsa")]
fn sign_rsa() {
let signing_key = PrivateKey::from_openssh(RSA_PRIVATE_KEY).unwrap();
let verifying_key = RSA_PUBLIC_KEY.parse::<PublicKey>().unwrap();
let signature = signing_key
.sign(NAMESPACE_EXAMPLE, HashAlg::Sha512, MSG_EXAMPLE)
.unwrap();
assert_eq!(
verifying_key.verify(NAMESPACE_EXAMPLE, MSG_EXAMPLE, &signature),
Ok(())
);
}
#[test]
#[cfg(feature = "ed25519")]
fn verify_ed25519() {
let verifying_key = ED25519_PUBLIC_KEY.parse::<PublicKey>().unwrap();
let signature = ED25519_SIGNATURE.parse::<SshSig>().unwrap();
assert_eq!(
verifying_key.verify(NAMESPACE_EXAMPLE, MSG_EXAMPLE, &signature),
Ok(())
);
assert_eq!(
verifying_key.verify("bogus namespace", MSG_EXAMPLE, &signature),
Err(Error::Namespace)
);
assert_eq!(
verifying_key.verify(NAMESPACE_EXAMPLE, b"bogus!", &signature),
Err(Error::Crypto)
);
}