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
use ed25519::pkcs8::EncodePrivateKey;
use rcgen::{CertificateParams, KeyPair, SignatureAlgorithm};
use crate::Certifiable;
#[cfg(test)]
#[path = "tests/ed25519_certgen_tests.rs"]
mod ed25519_certgen_tests;
fn dalek_to_keypair_bytes(dalek_kp: ed25519_dalek::Keypair) -> ed25519::KeypairBytes {
let private = dalek_kp.secret;
let _public = dalek_kp.public;
ed25519::KeypairBytes {
secret_key: private.to_bytes(),
public_key: None,
}
}
fn keypair_bytes_to_pkcs8_n_algo(
kpb: ed25519::KeypairBytes,
) -> Result<(pkcs8::PrivateKeyDocument, &'static SignatureAlgorithm), pkcs8::Error> {
let pkcs8 = kpb.to_pkcs8_der()?;
Ok((pkcs8, &rcgen::PKCS_ED25519))
}
fn gen_certificate(
subject_names: impl Into<Vec<String>>,
key_pair: (&[u8], &'static SignatureAlgorithm),
) -> Result<rustls::Certificate, anyhow::Error> {
let kp = KeyPair::from_der_and_sign_algo(key_pair.0, key_pair.1)?;
let mut cert_params = CertificateParams::new(subject_names);
cert_params.key_pair = Some(kp);
cert_params.distinguished_name = rcgen::DistinguishedName::new();
cert_params.alg = key_pair.1;
let cert = rcgen::Certificate::from_params(cert_params).expect(
"unreachable! from_params should only fail if the key is incompatible with params.algo",
);
let cert_bytes = cert.serialize_der()?;
Ok(rustls::Certificate(cert_bytes))
}
pub struct Ed25519 {}
impl Certifiable for Ed25519 {
type PublicKey = ed25519_dalek::PublicKey;
type KeyPair = ed25519_dalek::Keypair;
fn keypair_to_certificate(
subject_names: impl Into<Vec<String>>,
kp: Self::KeyPair,
) -> Result<rustls::Certificate, anyhow::Error> {
let keypair_bytes = dalek_to_keypair_bytes(kp);
let (pkcs_bytes, alg) =
keypair_bytes_to_pkcs8_n_algo(keypair_bytes).map_err(anyhow::Error::new)?;
let certificate = gen_certificate(subject_names, (pkcs_bytes.as_ref(), alg))?;
Ok(certificate)
}
fn public_key_to_spki(public_key: &Self::PublicKey) -> Vec<u8> {
let subject_public_key = public_key.as_bytes();
let key_info = pkcs8::spki::SubjectPublicKeyInfo {
algorithm: pkcs8::spki::AlgorithmIdentifier {
oid: ed25519::pkcs8::ALGORITHM_OID,
parameters: None,
},
subject_public_key,
};
pkcs8::der::Encodable::to_vec(&key_info).expect("Dalek public key should be valid!")
}
}