most missing docs for llcrypto
This commit is contained in:
parent
3c7f75302b
commit
b48597fb18
|
@ -1,4 +1,7 @@
|
|||
//! Ciphers used to implement the Tor protocols.
|
||||
//!
|
||||
//! Fortunately, Tor has managed not to proliferate ciphers. It only
|
||||
//! uses AES, and (so far) only uses AES in counter mode.
|
||||
|
||||
/// Re-exports implementations of counter-mode AES
|
||||
pub mod aes {
|
||||
|
|
|
@ -3,13 +3,16 @@
|
|||
//! In various places, for legacy reasons, Tor uses SHA1, SHA2,
|
||||
//! SHA3, and SHAKE. We re-export them all here, implementing
|
||||
//! the Digest trait.
|
||||
//!
|
||||
//! Other code should access these digests via the Digest trait.
|
||||
|
||||
// These implement Digest, so we can just use them as-is.
|
||||
pub use sha2::{Sha256, Sha512};
|
||||
pub use sha3::{Sha3_256, Shake128, Shake256};
|
||||
|
||||
// The Sha1 crate, OTOH, doesn't expose Digest. I'll do it myself.
|
||||
/// Wrapper for Sha1 that implements the Digest trait.
|
||||
/// A Sha1 implementation that implements the Digest trait.
|
||||
///
|
||||
/// (This is just a thin wrapper around the Sha1 crate.)
|
||||
#[derive(Clone, Default)]
|
||||
pub struct Sha1(sha1::Sha1);
|
||||
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
//! Low-level crypto implementations for Tor.
|
||||
//!
|
||||
//! This crate doesn't have anything interesting: it just wraps other
|
||||
//! crates that implement lower-level cryptographic functionality that
|
||||
//! Tor does not implement itself. In some cases the functionality is
|
||||
//! just re-exported; in others, it is wrapped to present a
|
||||
//! conseistent interface.
|
||||
//! This crate doesn't have much of interest: for the most part it
|
||||
//! just wraps other crates that implement lower-level cryptographic
|
||||
//! functionality. In some cases the functionality is just
|
||||
//! re-exported; in others, it is wrapped to present a conseistent
|
||||
//! interface.
|
||||
//!
|
||||
//! Encryption is implemented in `cipher`, digests are in `d`, and
|
||||
//! public key cryptography (including signatures, encryption, and key
|
||||
//! agreement) are in `pk`.
|
||||
|
||||
// TODO -- the long-term intention here is that this functionality
|
||||
// should be replaceable at compile time with other implementations.
|
||||
#![deny(missing_docs)]
|
||||
|
||||
pub mod cipher;
|
||||
pub mod d;
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
//! Re-exporting public-key cryptography.
|
||||
//! Public-key cryptography for Tor.
|
||||
//!
|
||||
//! In old places, Tor uses RSA; newer Tor public-key cryptography is
|
||||
//! basd on curve25519 and ed25519.
|
||||
|
||||
pub mod keymanip;
|
||||
pub mod rsa;
|
||||
|
@ -6,7 +9,7 @@ pub mod rsa;
|
|||
/// Re-exporting Curve25519 implementations.
|
||||
///
|
||||
/// Eventually there should probably be a key-agreement trait or two
|
||||
/// that this implements, but for now I'm just using the API from
|
||||
/// that this implements, but for now I'm just re-using the API from
|
||||
/// x25519-dalek.
|
||||
pub mod curve25519 {
|
||||
pub use x25519_dalek::{EphemeralSecret, PublicKey, SharedSecret, StaticSecret};
|
||||
|
|
|
@ -1,3 +1,15 @@
|
|||
//! Key manipulation functions for use with public keys.
|
||||
//!
|
||||
//! Tor does some interesting and not-really-standard things with its
|
||||
//! curve25519 and ed25519 keys, for several reasons.
|
||||
//!
|
||||
//! In order to prove ownership of a curve25519 private key, Tor
|
||||
//! converts it into an ed25519 key, and then uses that ed25519 key to
|
||||
//! sign its identity key.
|
||||
//!
|
||||
//! TODO: This is also where we would put the key-derivation code that
|
||||
//! Tor uses in the hsv3 onion services protocol.
|
||||
|
||||
use crate::pk;
|
||||
use digest::Digest;
|
||||
use zeroize::Zeroizing;
|
||||
|
@ -7,6 +19,7 @@ use zeroize::Zeroizing;
|
|||
///
|
||||
/// Note that this formula is not terribly standardized; don't use
|
||||
/// it for anything besides cross-certification.
|
||||
///
|
||||
pub fn convert_curve25519_to_ed25519_public(
|
||||
pubkey: &pk::curve25519::PublicKey,
|
||||
signbit: u8,
|
||||
|
@ -16,9 +29,10 @@ pub fn convert_curve25519_to_ed25519_public(
|
|||
let point = MontgomeryPoint(*pubkey.as_bytes());
|
||||
let edpoint = point.to_edwards(signbit)?;
|
||||
|
||||
// TODO: This is inefficient; we shouldn't have to re-compress this
|
||||
// point to get the public key we wanted. But there's no way I
|
||||
// can to construct an ed25519 public key from a compressed point.
|
||||
// TODO: This is inefficient; we shouldn't have to re-compress
|
||||
// this point to get the public key we wanted. But there's no way
|
||||
// with the current API that I can to construct an ed25519 public
|
||||
// key from a compressed point.
|
||||
let compressed_y = edpoint.compress();
|
||||
pk::ed25519::PublicKey::from_bytes(compressed_y.as_bytes()).ok()
|
||||
}
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
//! Re-exporting RSA implementations.
|
||||
//!
|
||||
//! This module can currently handle public keys and signature
|
||||
//! verification as they work in the Tor directory protocol and
|
||||
//! verification used in the Tor directory protocol and
|
||||
//! similar places.
|
||||
//!
|
||||
//! Currently, that means supporting validating PKCSv1
|
||||
//! signatures, and encoding and decoding keys from DER.
|
||||
//!
|
||||
//! Currently missing is signing and RSA-OEAP.
|
||||
use arrayref::array_ref;
|
||||
use subtle::*;
|
||||
use zeroize::Zeroize;
|
||||
|
@ -16,7 +18,7 @@ use zeroize::Zeroize;
|
|||
pub const RSA_ID_LEN: usize = 20;
|
||||
|
||||
/// An identifier for a Tor relay, based on its legacy RSA
|
||||
/// identity key.
|
||||
/// identity key. These are used all over the Tor protocol.
|
||||
#[derive(Clone, Zeroize, Debug)]
|
||||
pub struct RSAIdentity {
|
||||
pub id: [u8; RSA_ID_LEN],
|
||||
|
@ -31,9 +33,23 @@ impl PartialEq<RSAIdentity> for RSAIdentity {
|
|||
impl Eq for RSAIdentity {}
|
||||
|
||||
impl RSAIdentity {
|
||||
/// Expose and RSAIdentity as a slice of bytes.
|
||||
pub fn as_bytes(&self) -> &[u8] {
|
||||
&self.id[..]
|
||||
}
|
||||
/// Construct an RSAIdentity from a slice of bytes.
|
||||
///
|
||||
/// Returns None if the input is not of the correct length.
|
||||
///
|
||||
/// ```
|
||||
/// let bytes = b"xyzzyxyzzyxyzzyxyzzy";
|
||||
/// let id = RSAIdentity::from_bytes(&bytes);
|
||||
/// assert_eq!(id.unwrap().as_bytes(), bytes);
|
||||
///
|
||||
/// let truncated = b"xyzzy";
|
||||
/// let id = RSAIdentity::from_bytes(truncated);
|
||||
/// assert_eq!(id, None);
|
||||
/// ```
|
||||
pub fn from_bytes(bytes: &[u8]) -> Option<Self> {
|
||||
if bytes.len() == RSA_ID_LEN {
|
||||
Some(RSAIdentity {
|
||||
|
@ -46,11 +62,15 @@ impl RSAIdentity {
|
|||
}
|
||||
|
||||
/// An RSA public key.
|
||||
///
|
||||
/// This implementation is a simple wrapper so that we can define new
|
||||
/// methods and traits on the type.
|
||||
pub struct PublicKey(rsa::RSAPublicKey);
|
||||
/// An RSA Private key.
|
||||
/// An RSA private key.
|
||||
pub struct PrivateKey(rsa::RSAPrivateKey);
|
||||
|
||||
impl PrivateKey {
|
||||
/// Return the public component of this key.
|
||||
pub fn to_public_key(&self) -> PublicKey {
|
||||
PublicKey(self.0.to_public_key())
|
||||
}
|
||||
|
@ -73,16 +93,22 @@ impl PublicKey {
|
|||
///
|
||||
/// Tor uses RSA-PKCSv1 signatures, with hash algorithm OIDs
|
||||
/// omitted.
|
||||
///
|
||||
/// ## Issues
|
||||
///
|
||||
/// XXXX We probably shouldn't be exposing rsa::errors::Result().
|
||||
///
|
||||
pub fn verify(&self, hashed: &[u8], sig: &[u8]) -> rsa::errors::Result<()> {
|
||||
use rsa::PublicKey;
|
||||
self.0
|
||||
.verify::<rsa::hash::Hashes>(rsa::PaddingScheme::PKCS1v15, None, hashed, sig)
|
||||
// XXXX I don't want to expose rsa::errors::Result, really.
|
||||
}
|
||||
/// Decode an alleged DER byte string into a PublicKey. Return None
|
||||
/// if the DER string does not have a valid PublicKey.
|
||||
/// Decode an alleged DER byte string into a PublicKey.
|
||||
///
|
||||
/// (Does not expect or allow an OID.)
|
||||
/// Return None if the DER string does not have a valid PublicKey.
|
||||
///
|
||||
/// (This function expects an RSAPublicKey, as used by Tor. It
|
||||
/// does not expect or accept a PublicKeyInfo.)
|
||||
pub fn from_der(der: &[u8]) -> Option<Self> {
|
||||
// We can't use the rsa-der crate, since it expects to find the
|
||||
// key inside of a bitstring inside of another asn1 object.
|
||||
|
@ -120,7 +146,7 @@ impl PublicKey {
|
|||
}
|
||||
/// Encode this public key into the DER format as used by Tor.
|
||||
///
|
||||
/// Does not attach an OID.
|
||||
/// The result is an RSAPublicKey, not a PublicKeyInfo.
|
||||
pub fn to_der(&self) -> Vec<u8> {
|
||||
use simple_asn1::ASN1Block;
|
||||
// XXX do I really need both of these crates? rsa uses
|
||||
|
|
Loading…
Reference in New Issue