Skip to content

Commit 8f6272d

Browse files
committed
fix self-signed server certs
we were using a CA cert as server cert, which for some cases is ok, but plenty of flows bork on these (and rightfully so)
1 parent c65ed6b commit 8f6272d

File tree

2 files changed

+135
-7
lines changed

2 files changed

+135
-7
lines changed

rama-tls/src/boring/server/acceptor_data.rs

Lines changed: 131 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use crate::boring::dep::boring::{
1010
X509NameBuilder, X509,
1111
},
1212
};
13+
use boring::x509::extension::AuthorityKeyIdentifier;
1314
use rama_core::error::{ErrorContext, OpaqueError};
1415
use rama_net::tls::{
1516
server::{ClientVerifyMode, SelfSignedData, ServerAuth},
@@ -128,6 +129,17 @@ impl TryFrom<rama_net::tls::server::ServerConfig> for TlsAcceptorData {
128129
fn self_signed_server_auth(
129130
data: SelfSignedData,
130131
) -> Result<(Vec<X509>, PKey<Private>), OpaqueError> {
132+
let (ca_cert, ca_privkey) = self_signed_server_auth_gen_ca(&data).context("self-signed CA")?;
133+
let (cert, privkey) = self_signed_server_auth_gen_cert(&data, &ca_cert, &ca_privkey)
134+
.context("self-signed cert using self-signed CA")?;
135+
Ok((vec![cert, ca_cert], privkey))
136+
}
137+
138+
fn self_signed_server_auth_gen_cert(
139+
data: &SelfSignedData,
140+
ca_cert: &X509,
141+
ca_privkey: &PKey<Private>,
142+
) -> Result<(X509, PKey<Private>), OpaqueError> {
131143
let rsa = Rsa::generate(4096).context("generate 4096 RSA key")?;
132144
let privkey = PKey::from_rsa(rsa).context("create private key from 4096 RSA key")?;
133145

@@ -167,6 +179,12 @@ fn self_signed_server_auth(
167179
cert_builder
168180
.set_serial_number(&serial_number)
169181
.context("x509 cert builder: set serial number")?;
182+
cert_builder
183+
.set_issuer_name(ca_cert.subject_name())
184+
.context("x509 cert builder: set issuer name")?;
185+
cert_builder
186+
.set_pubkey(&privkey)
187+
.context("x509 cert builder: set pub key")?;
170188
cert_builder
171189
.set_subject_name(&x509_name)
172190
.context("x509 cert builder: set subject name")?;
@@ -190,8 +208,6 @@ fn self_signed_server_auth(
190208
cert_builder
191209
.append_extension(
192210
BasicConstraints::new()
193-
.critical()
194-
.ca()
195211
.build()
196212
.context("x509 cert builder: build basic constraints")?,
197213
)
@@ -200,8 +216,9 @@ fn self_signed_server_auth(
200216
.append_extension(
201217
KeyUsage::new()
202218
.critical()
203-
.key_cert_sign()
204-
.crl_sign()
219+
.non_repudiation()
220+
.digital_signature()
221+
.key_encipherment()
205222
.build()
206223
.context("x509 cert builder: create key usage")?,
207224
)
@@ -214,10 +231,118 @@ fn self_signed_server_auth(
214231
.append_extension(subject_key_identifier)
215232
.context("x509 cert builder: add subject key id x509 extension")?;
216233

234+
let auth_key_identifier = AuthorityKeyIdentifier::new()
235+
.keyid(false)
236+
.issuer(false)
237+
.build(&cert_builder.x509v3_context(Some(ca_cert), None))
238+
.context("x509 cert builder: build auth key id")?;
217239
cert_builder
218-
.sign(&privkey, MessageDigest::sha256())
240+
.append_extension(auth_key_identifier)
241+
.context("x509 cert builder: set auth key id extension")?;
242+
243+
cert_builder
244+
.sign(ca_privkey, MessageDigest::sha256())
219245
.context("x509 cert builder: sign cert")?;
246+
220247
let cert = cert_builder.build();
221248

222-
Ok((vec![cert], privkey))
249+
Ok((cert, privkey))
250+
}
251+
252+
fn self_signed_server_auth_gen_ca(
253+
data: &SelfSignedData,
254+
) -> Result<(X509, PKey<Private>), OpaqueError> {
255+
let rsa = Rsa::generate(4096).context("generate 4096 RSA key")?;
256+
let privkey = PKey::from_rsa(rsa).context("create private key from 4096 RSA key")?;
257+
258+
let mut x509_name = X509NameBuilder::new().context("create x509 name builder")?;
259+
x509_name
260+
.append_entry_by_nid(
261+
Nid::ORGANIZATIONNAME,
262+
data.organisation_name.as_deref().unwrap_or("Anonymous"),
263+
)
264+
.context("append organisation name to x509 name builder")?;
265+
for subject_alt_name in data.subject_alternative_names.iter().flatten() {
266+
x509_name
267+
.append_entry_by_nid(Nid::SUBJECT_ALT_NAME, subject_alt_name.as_ref())
268+
.context("append subject alt name to x509 name builder")?;
269+
}
270+
x509_name
271+
.append_entry_by_nid(
272+
Nid::COMMONNAME,
273+
data.common_name.as_deref().unwrap_or("localhost"),
274+
)
275+
.context("append common name to x509 name builder")?;
276+
let x509_name = x509_name.build();
277+
278+
let mut ca_cert_builder = X509::builder().context("create x509 (cert) builder")?;
279+
ca_cert_builder
280+
.set_version(2)
281+
.context("x509 cert builder: set version = 2")?;
282+
let serial_number = {
283+
let mut serial = BigNum::new().context("x509 cert builder: create big num (serial")?;
284+
serial
285+
.rand(159, MsbOption::MAYBE_ZERO, false)
286+
.context("x509 cert builder: randomise serial number (big num)")?;
287+
serial
288+
.to_asn1_integer()
289+
.context("x509 cert builder: convert serial to ASN1 integer")?
290+
};
291+
ca_cert_builder
292+
.set_serial_number(&serial_number)
293+
.context("x509 cert builder: set serial number")?;
294+
ca_cert_builder
295+
.set_subject_name(&x509_name)
296+
.context("x509 cert builder: set subject name")?;
297+
ca_cert_builder
298+
.set_issuer_name(&x509_name)
299+
.context("x509 cert builder: set issuer (self-signed")?;
300+
ca_cert_builder
301+
.set_pubkey(&privkey)
302+
.context("x509 cert builder: set public key using private key (ref)")?;
303+
let not_before =
304+
Asn1Time::days_from_now(0).context("x509 cert builder: create ASN1Time for today")?;
305+
ca_cert_builder
306+
.set_not_before(&not_before)
307+
.context("x509 cert builder: set not before to today")?;
308+
let not_after = Asn1Time::days_from_now(90)
309+
.context("x509 cert builder: create ASN1Time for 90 days in future")?;
310+
ca_cert_builder
311+
.set_not_after(&not_after)
312+
.context("x509 cert builder: set not after to 90 days in future")?;
313+
314+
ca_cert_builder
315+
.append_extension(
316+
BasicConstraints::new()
317+
.critical()
318+
.ca()
319+
.build()
320+
.context("x509 cert builder: build basic constraints")?,
321+
)
322+
.context("x509 cert builder: add basic constraints as x509 extension")?;
323+
ca_cert_builder
324+
.append_extension(
325+
KeyUsage::new()
326+
.critical()
327+
.key_cert_sign()
328+
.crl_sign()
329+
.build()
330+
.context("x509 cert builder: create key usage")?,
331+
)
332+
.context("x509 cert builder: add key usage x509 extension")?;
333+
334+
let subject_key_identifier = SubjectKeyIdentifier::new()
335+
.build(&ca_cert_builder.x509v3_context(None, None))
336+
.context("x509 cert builder: build subject key id")?;
337+
ca_cert_builder
338+
.append_extension(subject_key_identifier)
339+
.context("x509 cert builder: add subject key id x509 extension")?;
340+
341+
ca_cert_builder
342+
.sign(&privkey, MessageDigest::sha256())
343+
.context("x509 cert builder: sign cert")?;
344+
345+
let cert = ca_cert_builder.build();
346+
347+
Ok((cert, privkey))
223348
}

rama-tls/src/boring/server/service.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,10 @@ where
206206
.map_err(|err| match err.as_io_error() {
207207
Some(err) => OpaqueError::from_display(err.to_string())
208208
.context("boring ssl acceptor: accept"),
209-
None => OpaqueError::from_display("boring ssl acceptor: accept"),
209+
None => OpaqueError::from_display(format!(
210+
"boring ssl acceptor: accept ({:?})",
211+
err.code()
212+
)),
210213
})?;
211214

212215
match stream.ssl().session() {

0 commit comments

Comments
 (0)