ssh_key/lib.rs
1#![no_std]
2#![cfg_attr(docsrs, feature(doc_auto_cfg))]
3#![doc = include_str!("../README.md")]
4#![doc(
5 html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg",
6 html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg"
7)]
8#![forbid(unsafe_code)]
9#![warn(
10 clippy::arithmetic_side_effects,
11 clippy::mod_module_files,
12 clippy::panic,
13 clippy::panic_in_result_fn,
14 clippy::unwrap_used,
15 missing_docs,
16 rust_2018_idioms,
17 unused_lifetimes,
18 unused_qualifications
19)]
20
21//! ## Usage
22//!
23//! The main types provided by this library are:
24//!
25//! - [`Certificate`]: OpenSSH certificates
26//! - [`Fingerprint`]: public key fingerprints (i.e. hashes)
27//! - [`PrivateKey`]: SSH private keys (i.e. digital signature keys)
28//! - [`PublicKey`]: SSH public keys (i.e. signature verification keys)
29//! - [`SshSig`]: signatures with SSH keys ala `ssh-keygen -Y sign`/`ssh-keygen -Y verify`
30//!
31//! ### Parsing OpenSSH Public Keys
32//!
33//! OpenSSH-formatted public keys have the form:
34//!
35//! ```text
36//! <algorithm id> <base64 data> <comment>
37//! ```
38//!
39//! #### Example
40//!
41#![cfg_attr(feature = "std", doc = "```")]
42#![cfg_attr(not(feature = "std"), doc = "```ignore")]
43//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
44//! use ssh_key::PublicKey;
45//!
46//! let encoded_key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILM+rvN+ot98qgEN796jTiQfZfG1KaT0PtFDJ/XFSqti user@example.com";
47//! let public_key = PublicKey::from_openssh(encoded_key)?;
48//!
49//! // Key attributes
50//! assert_eq!(public_key.algorithm(), ssh_key::Algorithm::Ed25519);
51//! assert_eq!(public_key.comment(), "user@example.com");
52//!
53//! // Key data: in this example an Ed25519 key
54//! if let Some(ed25519_public_key) = public_key.key_data().ed25519() {
55//! assert_eq!(
56//! ed25519_public_key.as_ref(),
57//! [
58//! 0xb3, 0x3e, 0xae, 0xf3, 0x7e, 0xa2, 0xdf, 0x7c, 0xaa, 0x1, 0xd, 0xef, 0xde, 0xa3,
59//! 0x4e, 0x24, 0x1f, 0x65, 0xf1, 0xb5, 0x29, 0xa4, 0xf4, 0x3e, 0xd1, 0x43, 0x27, 0xf5,
60//! 0xc5, 0x4a, 0xab, 0x62
61//! ].as_ref()
62//! );
63//! }
64//! # Ok(())
65//! # }
66//! ```
67//!
68//! ### Parsing OpenSSH Private Keys
69//!
70//! *NOTE: for more private key usage examples, see the [`private`] module.*
71//!
72//! OpenSSH-formatted private keys are PEM-encoded and begin with the following:
73//!
74//! ```text
75//! -----BEGIN OPENSSH PRIVATE KEY-----
76//! ```
77//!
78//! #### Example
79//!
80#![cfg_attr(feature = "std", doc = " ```")]
81#![cfg_attr(not(feature = "std"), doc = " ```ignore")]
82//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
83//! use ssh_key::PrivateKey;
84//!
85//! // WARNING: don't actually hardcode private keys in source code!!!
86//! let encoded_key = r#"
87//! -----BEGIN OPENSSH PRIVATE KEY-----
88//! b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
89//! QyNTUxOQAAACCzPq7zfqLffKoBDe/eo04kH2XxtSmk9D7RQyf1xUqrYgAAAJgAIAxdACAM
90//! XQAAAAtzc2gtZWQyNTUxOQAAACCzPq7zfqLffKoBDe/eo04kH2XxtSmk9D7RQyf1xUqrYg
91//! AAAEC2BsIi0QwW2uFscKTUUXNHLsYX4FxlaSDSblbAj7WR7bM+rvN+ot98qgEN796jTiQf
92//! ZfG1KaT0PtFDJ/XFSqtiAAAAEHVzZXJAZXhhbXBsZS5jb20BAgMEBQ==
93//! -----END OPENSSH PRIVATE KEY-----
94//! "#;
95//!
96//! let private_key = PrivateKey::from_openssh(encoded_key)?;
97//!
98//! // Key attributes
99//! assert_eq!(private_key.algorithm(), ssh_key::Algorithm::Ed25519);
100//! assert_eq!(private_key.comment(), "user@example.com");
101//!
102//! // Key data: in this example an Ed25519 key
103//! if let Some(ed25519_keypair) = private_key.key_data().ed25519() {
104//! assert_eq!(
105//! ed25519_keypair.public.as_ref(),
106//! [
107//! 0xb3, 0x3e, 0xae, 0xf3, 0x7e, 0xa2, 0xdf, 0x7c, 0xaa, 0x1, 0xd, 0xef, 0xde, 0xa3,
108//! 0x4e, 0x24, 0x1f, 0x65, 0xf1, 0xb5, 0x29, 0xa4, 0xf4, 0x3e, 0xd1, 0x43, 0x27, 0xf5,
109//! 0xc5, 0x4a, 0xab, 0x62
110//! ].as_ref()
111//! );
112//!
113//! assert_eq!(
114//! ed25519_keypair.private.as_ref(),
115//! [
116//! 0xb6, 0x6, 0xc2, 0x22, 0xd1, 0xc, 0x16, 0xda, 0xe1, 0x6c, 0x70, 0xa4, 0xd4, 0x51,
117//! 0x73, 0x47, 0x2e, 0xc6, 0x17, 0xe0, 0x5c, 0x65, 0x69, 0x20, 0xd2, 0x6e, 0x56, 0xc0,
118//! 0x8f, 0xb5, 0x91, 0xed
119//! ].as_ref()
120//! )
121//! }
122//! # Ok(())
123//! # }
124//! ```
125//!
126//! ## `serde` support
127//!
128//! When the `serde` feature of this crate is enabled, the [`Certificate`],
129//! [`Fingerprint`], and [`PublicKey`] types receive impls of `serde`'s
130//! [`Deserialize`][`serde::Deserialize`] and [`Serialize`][`serde::Serialize`]
131//! traits.
132//!
133//! Serializing/deserializing [`PrivateKey`] using `serde` is presently
134//! unsupported.
135
136#[cfg(feature = "alloc")]
137#[macro_use]
138extern crate alloc;
139#[cfg(feature = "std")]
140extern crate std;
141
142pub mod authorized_keys;
143pub mod private;
144pub mod public;
145
146#[cfg(feature = "alloc")]
147pub mod certificate;
148#[cfg(feature = "alloc")]
149pub mod known_hosts;
150
151mod algorithm;
152mod error;
153mod fingerprint;
154mod kdf;
155
156#[cfg(feature = "alloc")]
157mod mpint;
158#[cfg(feature = "alloc")]
159mod signature;
160#[cfg(feature = "alloc")]
161mod sshsig;
162
163pub use crate::{
164 algorithm::{Algorithm, EcdsaCurve, HashAlg, KdfAlg},
165 authorized_keys::AuthorizedKeys,
166 error::{Error, Result},
167 fingerprint::Fingerprint,
168 kdf::Kdf,
169 private::PrivateKey,
170 public::PublicKey,
171};
172pub use cipher::Cipher;
173pub use encoding::LineEnding;
174pub use sha2;
175
176#[cfg(feature = "alloc")]
177pub use crate::{
178 algorithm::AlgorithmName,
179 certificate::Certificate,
180 known_hosts::KnownHosts,
181 mpint::Mpint,
182 signature::{Signature, SigningKey},
183 sshsig::SshSig,
184};
185
186#[cfg(feature = "ecdsa")]
187pub use sec1;
188
189#[cfg(feature = "rand_core")]
190pub use rand_core;