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