-
-
Notifications
You must be signed in to change notification settings - Fork 22
/
signer.rs
157 lines (124 loc) · 4.09 KB
/
signer.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
//! A generic interface to a signer.
use std::fmt;
use super::keys::{PublicKey, PublicKeyFormat};
use super::signature::{SignatureAlgorithm, Signature};
//------------ Signer --------------------------------------------------------
/// A type that allow creating signatures.
pub trait Signer {
/// The type used for identifying keys.
type KeyId;
/// An operational error happened in the signer.
type Error: fmt::Debug + fmt::Display;
/// Creates a new key and returns an identifier.
fn create_key(
&self,
algorithm: PublicKeyFormat
) -> Result<Self::KeyId, Self::Error>;
/// Returns the public key information for the given key.
///
/// If the key identified by `key` does not exist, returns `None`.
fn get_key_info(
&self,
key: &Self::KeyId
) -> Result<PublicKey, KeyError<Self::Error>>;
/// Destroys a key.
///
/// Returns whether the key identified by `key` existed.
fn destroy_key(
&self,
key: &Self::KeyId
) -> Result<(), KeyError<Self::Error>>;
/// Signs data.
fn sign<Alg: SignatureAlgorithm, D: AsRef<[u8]> + ?Sized>(
&self,
key: &Self::KeyId,
algorithm: Alg,
data: &D
) -> Result<Signature<Alg>, SigningError<Self::Error>>;
/// Signs data using a one time use keypair.
///
/// Returns both the signature and the public key of the key pair,
/// but will not store this key pair.
fn sign_one_off<Alg: SignatureAlgorithm, D: AsRef<[u8]> + ?Sized>(
&self,
algorithm: Alg,
data: &D
) -> Result<(Signature<Alg>, PublicKey), Self::Error>;
/// Creates random data.
///
/// The method fills the provide bytes slice with random data.
fn rand(&self, target: &mut [u8]) -> Result<(), Self::Error>;
}
//------------ SigningAlgorithm ----------------------------------------------
/// The algorithm to use for signing.
#[derive(Clone, Copy, Debug)]
pub enum SigningAlgorithm {
/// RSA with PKCS#1 1.5 padding using SHA-256.
RsaSha256,
/// ECDSA using the P-256 curva and SHA-256.
EcdsaP256Sha256,
}
impl SigningAlgorithm {
/// Returns the preferred public key format for this algorithm.
pub fn public_key_format(self) -> PublicKeyFormat {
match self {
SigningAlgorithm::RsaSha256 => PublicKeyFormat::Rsa,
SigningAlgorithm::EcdsaP256Sha256 => PublicKeyFormat::EcdsaP256,
}
}
}
//------------ KeyError ------------------------------------------------------
#[derive(Clone, Debug)]
pub enum KeyError<S> {
/// A key with the given key ID doesn’t exist.
KeyNotFound,
/// An error happened during signing.
Signer(S)
}
impl<S> From<S> for KeyError<S> {
fn from(err: S) -> Self {
KeyError::Signer(err)
}
}
impl<S: fmt::Display> fmt::Display for KeyError<S> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::KeyError::*;
match *self {
KeyNotFound => write!(f, "key not found"),
Signer(ref s) => s.fmt(f)
}
}
}
//------------ SigningError --------------------------------------------------
#[derive(Clone, Debug)]
pub enum SigningError<S> {
/// A key with the given key ID doesn’t exist.
KeyNotFound,
/// The key cannot be used with the algorithm.
IncompatibleKey,
/// An error happened during signing.
Signer(S)
}
impl<S> From<S> for SigningError<S> {
fn from(err: S) -> Self {
SigningError::Signer(err)
}
}
impl<S> From<KeyError<S>> for SigningError<S> {
fn from(err: KeyError<S>) -> Self {
match err {
KeyError::KeyNotFound => SigningError::KeyNotFound,
KeyError::Signer(err) => SigningError::Signer(err)
}
}
}
impl<S: fmt::Display> fmt::Display for SigningError<S> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::SigningError::*;
match *self {
KeyNotFound => write!(f, "key not found"),
IncompatibleKey => write!(f, "key not compatible with algorithm"),
Signer(ref s) => s.fmt(f)
}
}
}