Struct ssh_key::certificate::Certificate

source ·
pub struct Certificate { /* private fields */ }
Expand description

OpenSSH certificate as specified in PROTOCOL.certkeys.

OpenSSH supports X.509-like certificate authorities, but using a custom encoding format.

§⚠️ Security Warning

Certificates must be validated before they can be trusted!

The Certificate type does not automatically perform validation checks and supports parsing certificates which may potentially be invalid. Just because a Certificate parses successfully does not mean that it can be trusted.

See “Certificate Validation” documentation below for more information on how to properly validate certificates.

§Certificate Validation

For a certificate to be trusted, the following properties MUST be validated:

  • Certificate is signed by a trusted certificate authority (CA)
  • Signature over the certificate verifies successfully
  • Current time is within the certificate’s validity window
  • Certificate authorizes the expected principal
  • All critical extensions to the certificate are recognized and validate successfully.

The Certificate::validate and Certificate::validate_at methods can be used to validate a certificate.

§Example

The following example walks through how to implement the steps outlined above for validating a certificate:

use ssh_key::{Certificate, Fingerprint};
use std::str::FromStr;

// List of trusted certificate authority (CA) fingerprints
let ca_fingerprints = [
   Fingerprint::from_str("SHA256:JQ6FV0rf7qqJHZqIj4zNH8eV0oB8KLKh9Pph3FTD98g")?
];

// Certificate to be validated
let certificate = Certificate::from_str(
   "ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIE7x9ln6uZLLkfXM8iatrnAAuytVHeCznU8VlEgx7TvLAAAAILM+rvN+ot98qgEN796jTiQfZfG1KaT0PtFDJ/XFSqtiAAAAAAAAAAAAAAABAAAAFGVkMjU1MTktd2l0aC1wMjU2LWNhAAAAAAAAAABiUZm7AAAAAPTaMrsAAAAAAAAAggAAABVwZXJtaXQtWDExLWZvcndhcmRpbmcAAAAAAAAAF3Blcm1pdC1hZ2VudC1mb3J3YXJkaW5nAAAAAAAAABZwZXJtaXQtcG9ydC1mb3J3YXJkaW5nAAAAAAAAAApwZXJtaXQtcHR5AAAAAAAAAA5wZXJtaXQtdXNlci1yYwAAAAAAAAAAAAAAaAAAABNlY2RzYS1zaGEyLW5pc3RwMjU2AAAACG5pc3RwMjU2AAAAQQR8H9hzDOU0V76NkkCY7DZIgw+SqoojY6xlb91FIfpjE+UR8YkbTp5ar44ULQatFaZqQlfz8FHYTooOL5G6gHBHAAAAZAAAABNlY2RzYS1zaGEyLW5pc3RwMjU2AAAASQAAACEA/0Cwxhkac5AeNYE958j8GgvmkIESDH1TE7QYIqxsFsIAAAAgTEw8WVjlz8AnvyaKGOUELMpyFFJagtD2JFAIAJvilrc= user@example.com"
)?;

// Perform basic certificate validation, ensuring that the certificate is
// signed by a trusted certificate authority (CA) and checking that the
// current system clock time is within the certificate's validity window
certificate.validate(&ca_fingerprints)?;

// Check that the certificate includes the expected principal name
// (i.e. username or hostname)
// if !certificate.principals().contains(expected_principal) { return Err(...) }

// Check that all of the critical extensions are recognized
// if !certificate.critical_options.iter().all(|critical| ...) { return Err(...) }

// If we've made it this far, the certificate can be trusted
Ok(())

§Certificate Builder (SSH CA support)

This crate implements all of the functionality needed for a pure Rust SSH certificate authority which can build and sign OpenSSH certificates.

See the Builder type’s documentation for more information.

§serde support

When the serde feature of this crate is enabled, this type receives impls of [Deserialize][serde::Deserialize] and [Serialize][serde::Serialize].

The serialization uses a binary encoding with binary formats like bincode and CBOR, and the OpenSSH string serialization when used with human-readable formats like JSON and TOML.

Implementations§

source§

impl Certificate

source

pub fn from_openssh(certificate_str: &str) -> Result<Self>

Parse an OpenSSH-formatted certificate.

OpenSSH-formatted certificates look like the following (i.e. similar to OpenSSH public keys with -cert-v01@openssh.com):

ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlc...8REbCaAw== user@example.com
source

pub fn from_bytes(bytes: &[u8]) -> Result<Self>

Parse a raw binary OpenSSH certificate.

source

pub fn to_openssh(&self) -> Result<String>

Encode OpenSSH certificate to a String.

source

pub fn to_bytes(&self) -> Result<Vec<u8>>

Serialize OpenSSH certificate as raw bytes.

source

pub fn read_file(path: &Path) -> Result<Self>

Read OpenSSH certificate from a file.

source

pub fn write_file(&self, path: &Path) -> Result<()>

Write OpenSSH certificate to a file.

source

pub fn algorithm(&self) -> Algorithm

Get the public key algorithm for this certificate.

source

pub fn comment(&self) -> &str

Get the comment on this certificate.

source

pub fn nonce(&self) -> &[u8]

Nonces are a CA-provided random bitstring of arbitrary length (but typically 16 or 32 bytes).

It’s included to make attacks that depend on inducing collisions in the signature hash infeasible.

source

pub fn public_key(&self) -> &KeyData

Get this certificate’s public key data.

source

pub fn serial(&self) -> u64

Optional certificate serial number set by the CA to provide an abbreviated way to refer to certificates from that CA.

If a CA does not wish to number its certificates, it must set this field to zero.

source

pub fn cert_type(&self) -> CertType

Specifies whether this certificate is for identification of a user or a host.

source

pub fn key_id(&self) -> &str

Key IDs are a free-form text field that is filled in by the CA at the time of signing.

The intention is that the contents of this field are used to identify the identity principal in log messages.

source

pub fn valid_principals(&self) -> &[String]

List of zero or more principals which this certificate is valid for.

Principals are hostnames for host certificates and usernames for user certificates.

As a special case, a zero-length “valid principals” field means the certificate is valid for any principal of the specified type.

source

pub fn valid_after(&self) -> u64

Valid after (Unix time).

source

pub fn valid_before(&self) -> u64

Valid before (Unix time).

source

pub fn valid_after_time(&self) -> SystemTime

Valid after (system time).

source

pub fn valid_before_time(&self) -> SystemTime

Valid before (system time).

source

pub fn critical_options(&self) -> &OptionsMap

The critical options section of the certificate specifies zero or more options on the certificate’s validity.

Each named option may only appear once in a certificate.

All options are “critical”; if an implementation does not recognize an option, then the validating party should refuse to accept the certificate.

source

pub fn extensions(&self) -> &OptionsMap

The extensions section of the certificate specifies zero or more non-critical certificate extensions.

If an implementation does not recognise an extension, then it should ignore it.

source

pub fn signature_key(&self) -> &KeyData

Signature key of signing CA.

source

pub fn signature(&self) -> &Signature

Signature computed over all preceding fields from the initial string up to, and including the signature key.

source

pub fn validate<'a, I>(&self, ca_fingerprints: I) -> Result<()>
where I: IntoIterator<Item = &'a Fingerprint>,

Perform certificate validation using the system clock to check that the current time is within the certificate’s validity window.

§⚠️ Security Warning: Some Assembly Required

See Certificate::validate_at documentation for important notes on how to properly validate certificates!

source

pub fn validate_at<'a, I>( &self, unix_timestamp: u64, ca_fingerprints: I ) -> Result<()>
where I: IntoIterator<Item = &'a Fingerprint>,

Perform certificate validation.

Checks for the following:

  • Specified Unix timestamp is within the certificate’s valid range
  • Certificate’s signature validates against the public key included in the certificate
  • Fingerprint of the public key included in the certificate matches one of the trusted certificate authority (CA) fingerprints provided in the ca_fingerprints parameter.

NOTE: only SHA-256 fingerprints are supported at this time.

§⚠️ Security Warning: Some Assembly Required

This method does not perform the full set of validation checks needed to determine if a certificate is to be trusted.

If this method succeeds, the following properties still need to be checked to ensure the certificate is valid:

  • valid_principals is empty or contains the expected principal
  • critical_options is empty or contains only options which are recognized, and that the recognized options are all valid
§Returns
  • Ok if the certificate validated successfully
  • Error::CertificateValidation if the certificate failed to validate

Trait Implementations§

source§

impl Clone for Certificate

source§

fn clone(&self) -> Certificate

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Certificate

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl FromStr for Certificate

§

type Err = Error

The associated error which can be returned from parsing.
source§

fn from_str(s: &str) -> Result<Self>

Parses a string s to return a value of this type. Read more
source§

impl Ord for Certificate

source§

fn cmp(&self, other: &Certificate) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl PartialEq for Certificate

source§

fn eq(&self, other: &Certificate) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl PartialOrd for Certificate

source§

fn partial_cmp(&self, other: &Certificate) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= operator. Read more
source§

impl ToString for Certificate

source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl Eq for Certificate

source§

impl StructuralPartialEq for Certificate

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.