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