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
static FAKE_PKCS12: &'static [u8] = include_bytes!("fake_key.p12");
static FAKE_PASS: &'static str = "hello";
use openssl::{
asn1::Asn1Time,
bn::{BigNum, MsbOption},
hash::MessageDigest,
pkey::{PKey, Private},
rsa::Rsa,
x509::{self, X509Name, X509},
};
type PrivateKey = PKey<Private>;
type Certificate = x509::X509;
fn generate_self_signed(name: X509Name) -> (PrivateKey, Certificate) {
let rsa = Rsa::generate(2048).unwrap();
let key = PKey::from_rsa(rsa).unwrap();
let serial_number = {
let mut serial = BigNum::new().unwrap();
serial.rand(159, MsbOption::MAYBE_ZERO, false).unwrap();
serial.to_asn1_integer().unwrap()
};
let mut builder = X509::builder().unwrap();
builder.set_serial_number(&serial_number).unwrap();
builder.set_version(2).unwrap();
builder.set_subject_name(&name).unwrap();
builder.set_issuer_name(&name).unwrap();
builder.set_pubkey(&key).unwrap();
let not_before = Asn1Time::days_from_now(0).unwrap();
builder.set_not_before(¬_before).unwrap();
let not_after = Asn1Time::days_from_now(3650).unwrap();
builder.set_not_after(¬_after).unwrap();
builder.sign(&key, MessageDigest::sha256()).unwrap();
let cert: Certificate = builder.build();
(key, cert)
}
fn generate_dev() -> (PrivateKey, Certificate) {
let o = "InStreamDevCertificate";
let cn = nanoid::simple();
let mut name = X509Name::builder().unwrap();
name.append_entry_by_nid(openssl::nid::Nid::ORGANIZATIONNAME, o)
.unwrap();
name.append_entry_by_nid(openssl::nid::Nid::COMMONNAME, &cn)
.unwrap();
let name = name.build();
generate_self_signed(name)
}
#[derive(Debug, Clone, PartialEq)]
pub struct TlsCertificate {
pub pkcs12_data: Vec<u8>,
pub passphrase: String,
}
impl TlsCertificate {
pub fn generate_dev() -> Self {
let (key, cert) = generate_dev();
let pkcs12 = openssl::pkcs12::Pkcs12::builder()
.build("dev-passphrase", "in_stream_tls", &*key, &cert)
.unwrap();
Self {
pkcs12_data: pkcs12.to_der().unwrap(),
passphrase: "dev-passphrase".to_string(),
}
}
pub fn with_fake_certificate() -> Self {
Self {
pkcs12_data: FAKE_PKCS12.to_vec(),
passphrase: FAKE_PASS.to_string(),
}
}
}