Skip to content

Commit 5efceaa

Browse files
authored
Merge pull request #1854 from alex/davids-openssl-of-horrors
Fix a series of security issues
2 parents 690eeb2 + 6ced4f3 commit 5efceaa

File tree

6 files changed

+274
-99
lines changed

6 files changed

+274
-99
lines changed

openssl-sys/src/handwritten/x509.rs

+7
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,13 @@ extern "C" {
550550
pub fn X509_EXTENSION_get_object(ext: *mut X509_EXTENSION) -> *mut ASN1_OBJECT;
551551
pub fn X509_EXTENSION_get_data(ext: *mut X509_EXTENSION) -> *mut ASN1_OCTET_STRING;
552552
}
553+
554+
const_ptr_api! {
555+
extern "C" {
556+
pub fn i2d_X509_EXTENSION(ext: #[const_ptr_if(ossl300)] X509_EXTENSION, pp: *mut *mut c_uchar) -> c_int;
557+
}
558+
}
559+
553560
const_ptr_api! {
554561
extern "C" {
555562
// in X509

openssl-sys/src/handwritten/x509v3.rs

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use libc::*;
44
pub enum CONF_METHOD {}
55

66
extern "C" {
7+
pub fn GENERAL_NAME_new() -> *mut GENERAL_NAME;
78
pub fn GENERAL_NAME_free(name: *mut GENERAL_NAME);
89
}
910

openssl/src/asn1.rs

+5
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ use crate::bio::MemBio;
3939
use crate::bn::{BigNum, BigNumRef};
4040
use crate::error::ErrorStack;
4141
use crate::nid::Nid;
42+
use crate::stack::Stackable;
4243
use crate::string::OpensslString;
4344
use crate::{cvt, cvt_p};
4445
use openssl_macros::corresponds;
@@ -592,6 +593,10 @@ foreign_type_and_impl_send_sync! {
592593
pub struct Asn1ObjectRef;
593594
}
594595

596+
impl Stackable for Asn1Object {
597+
type StackType = ffi::stack_st_ASN1_OBJECT;
598+
}
599+
595600
impl Asn1Object {
596601
/// Constructs an ASN.1 Object Identifier from a string representation of the OID.
597602
#[corresponds(OBJ_txt2obj)]

openssl/src/x509/extension.rs

+69-90
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@
1818
//! ```
1919
use std::fmt::Write;
2020

21+
use crate::asn1::Asn1Object;
2122
use crate::error::ErrorStack;
2223
use crate::nid::Nid;
23-
use crate::x509::{X509Extension, X509v3Context};
24+
use crate::x509::{GeneralName, Stack, X509Extension, X509v3Context};
25+
use foreign_types::ForeignType;
2426

2527
/// An extension which indicates whether a certificate is a CA certificate.
2628
pub struct BasicConstraints {
@@ -222,18 +224,7 @@ impl KeyUsage {
222224
/// for which the certificate public key can be used for.
223225
pub struct ExtendedKeyUsage {
224226
critical: bool,
225-
server_auth: bool,
226-
client_auth: bool,
227-
code_signing: bool,
228-
email_protection: bool,
229-
time_stamping: bool,
230-
ms_code_ind: bool,
231-
ms_code_com: bool,
232-
ms_ctl_sign: bool,
233-
ms_sgc: bool,
234-
ms_efs: bool,
235-
ns_sgc: bool,
236-
other: Vec<String>,
227+
items: Vec<String>,
237228
}
238229

239230
impl Default for ExtendedKeyUsage {
@@ -247,18 +238,7 @@ impl ExtendedKeyUsage {
247238
pub fn new() -> ExtendedKeyUsage {
248239
ExtendedKeyUsage {
249240
critical: false,
250-
server_auth: false,
251-
client_auth: false,
252-
code_signing: false,
253-
email_protection: false,
254-
time_stamping: false,
255-
ms_code_ind: false,
256-
ms_code_com: false,
257-
ms_ctl_sign: false,
258-
ms_sgc: false,
259-
ms_efs: false,
260-
ns_sgc: false,
261-
other: vec![],
241+
items: vec![],
262242
}
263243
}
264244

@@ -270,101 +250,74 @@ impl ExtendedKeyUsage {
270250

271251
/// Sets the `serverAuth` flag to `true`.
272252
pub fn server_auth(&mut self) -> &mut ExtendedKeyUsage {
273-
self.server_auth = true;
274-
self
253+
self.other("serverAuth")
275254
}
276255

277256
/// Sets the `clientAuth` flag to `true`.
278257
pub fn client_auth(&mut self) -> &mut ExtendedKeyUsage {
279-
self.client_auth = true;
280-
self
258+
self.other("clientAuth")
281259
}
282260

283261
/// Sets the `codeSigning` flag to `true`.
284262
pub fn code_signing(&mut self) -> &mut ExtendedKeyUsage {
285-
self.code_signing = true;
286-
self
263+
self.other("codeSigning")
287264
}
288265

289266
/// Sets the `emailProtection` flag to `true`.
290267
pub fn email_protection(&mut self) -> &mut ExtendedKeyUsage {
291-
self.email_protection = true;
292-
self
268+
self.other("emailProtection")
293269
}
294270

295271
/// Sets the `timeStamping` flag to `true`.
296272
pub fn time_stamping(&mut self) -> &mut ExtendedKeyUsage {
297-
self.time_stamping = true;
298-
self
273+
self.other("timeStamping")
299274
}
300275

301276
/// Sets the `msCodeInd` flag to `true`.
302277
pub fn ms_code_ind(&mut self) -> &mut ExtendedKeyUsage {
303-
self.ms_code_ind = true;
304-
self
278+
self.other("msCodeInd")
305279
}
306280

307281
/// Sets the `msCodeCom` flag to `true`.
308282
pub fn ms_code_com(&mut self) -> &mut ExtendedKeyUsage {
309-
self.ms_code_com = true;
310-
self
283+
self.other("msCodeCom")
311284
}
312285

313286
/// Sets the `msCTLSign` flag to `true`.
314287
pub fn ms_ctl_sign(&mut self) -> &mut ExtendedKeyUsage {
315-
self.ms_ctl_sign = true;
316-
self
288+
self.other("msCTLSign")
317289
}
318290

319291
/// Sets the `msSGC` flag to `true`.
320292
pub fn ms_sgc(&mut self) -> &mut ExtendedKeyUsage {
321-
self.ms_sgc = true;
322-
self
293+
self.other("msSGC")
323294
}
324295

325296
/// Sets the `msEFS` flag to `true`.
326297
pub fn ms_efs(&mut self) -> &mut ExtendedKeyUsage {
327-
self.ms_efs = true;
328-
self
298+
self.other("msEFS")
329299
}
330300

331301
/// Sets the `nsSGC` flag to `true`.
332302
pub fn ns_sgc(&mut self) -> &mut ExtendedKeyUsage {
333-
self.ns_sgc = true;
334-
self
303+
self.other("nsSGC")
335304
}
336305

337306
/// Sets a flag not already defined.
338307
pub fn other(&mut self, other: &str) -> &mut ExtendedKeyUsage {
339-
self.other.push(other.to_owned());
308+
self.items.push(other.to_string());
340309
self
341310
}
342311

343312
/// Return the `ExtendedKeyUsage` extension as an `X509Extension`.
344313
pub fn build(&self) -> Result<X509Extension, ErrorStack> {
345-
let mut value = String::new();
346-
let mut first = true;
347-
append(&mut value, &mut first, self.critical, "critical");
348-
append(&mut value, &mut first, self.server_auth, "serverAuth");
349-
append(&mut value, &mut first, self.client_auth, "clientAuth");
350-
append(&mut value, &mut first, self.code_signing, "codeSigning");
351-
append(
352-
&mut value,
353-
&mut first,
354-
self.email_protection,
355-
"emailProtection",
356-
);
357-
append(&mut value, &mut first, self.time_stamping, "timeStamping");
358-
append(&mut value, &mut first, self.ms_code_ind, "msCodeInd");
359-
append(&mut value, &mut first, self.ms_code_com, "msCodeCom");
360-
append(&mut value, &mut first, self.ms_ctl_sign, "msCTLSign");
361-
append(&mut value, &mut first, self.ms_sgc, "msSGC");
362-
append(&mut value, &mut first, self.ms_efs, "msEFS");
363-
append(&mut value, &mut first, self.ns_sgc, "nsSGC");
364-
for other in &self.other {
365-
append(&mut value, &mut first, true, other);
314+
let mut stack = Stack::new()?;
315+
for item in &self.items {
316+
stack.push(Asn1Object::from_str(item)?)?;
317+
}
318+
unsafe {
319+
X509Extension::new_internal(Nid::EXT_KEY_USAGE, self.critical, stack.as_ptr().cast())
366320
}
367-
X509Extension::new_nid(None, None, Nid::EXT_KEY_USAGE, &value)
368321
}
369322
}
370323

@@ -463,11 +416,19 @@ impl AuthorityKeyIdentifier {
463416
}
464417
}
465418

419+
enum RustGeneralName {
420+
Dns(String),
421+
Email(String),
422+
Uri(String),
423+
Ip(String),
424+
Rid(String),
425+
}
426+
466427
/// An extension that allows additional identities to be bound to the subject
467428
/// of the certificate.
468429
pub struct SubjectAlternativeName {
469430
critical: bool,
470-
names: Vec<String>,
431+
items: Vec<RustGeneralName>,
471432
}
472433

473434
impl Default for SubjectAlternativeName {
@@ -481,7 +442,7 @@ impl SubjectAlternativeName {
481442
pub fn new() -> SubjectAlternativeName {
482443
SubjectAlternativeName {
483444
critical: false,
484-
names: vec![],
445+
items: vec![],
485446
}
486447
}
487448

@@ -493,55 +454,73 @@ impl SubjectAlternativeName {
493454

494455
/// Sets the `email` flag.
495456
pub fn email(&mut self, email: &str) -> &mut SubjectAlternativeName {
496-
self.names.push(format!("email:{}", email));
457+
self.items.push(RustGeneralName::Email(email.to_string()));
497458
self
498459
}
499460

500461
/// Sets the `uri` flag.
501462
pub fn uri(&mut self, uri: &str) -> &mut SubjectAlternativeName {
502-
self.names.push(format!("URI:{}", uri));
463+
self.items.push(RustGeneralName::Uri(uri.to_string()));
503464
self
504465
}
505466

506467
/// Sets the `dns` flag.
507468
pub fn dns(&mut self, dns: &str) -> &mut SubjectAlternativeName {
508-
self.names.push(format!("DNS:{}", dns));
469+
self.items.push(RustGeneralName::Dns(dns.to_string()));
509470
self
510471
}
511472

512473
/// Sets the `rid` flag.
513474
pub fn rid(&mut self, rid: &str) -> &mut SubjectAlternativeName {
514-
self.names.push(format!("RID:{}", rid));
475+
self.items.push(RustGeneralName::Rid(rid.to_string()));
515476
self
516477
}
517478

518479
/// Sets the `ip` flag.
519480
pub fn ip(&mut self, ip: &str) -> &mut SubjectAlternativeName {
520-
self.names.push(format!("IP:{}", ip));
481+
self.items.push(RustGeneralName::Ip(ip.to_string()));
521482
self
522483
}
523484

524485
/// Sets the `dirName` flag.
525-
pub fn dir_name(&mut self, dir_name: &str) -> &mut SubjectAlternativeName {
526-
self.names.push(format!("dirName:{}", dir_name));
527-
self
486+
///
487+
/// Not currently actually supported, always panics.
488+
#[deprecated = "dir_name is deprecated and always panics. Please file a bug if you have a use case for this."]
489+
pub fn dir_name(&mut self, _dir_name: &str) -> &mut SubjectAlternativeName {
490+
unimplemented!(
491+
"This has not yet been adapted for the new internals. File a bug if you need this."
492+
);
528493
}
529494

530495
/// Sets the `otherName` flag.
531-
pub fn other_name(&mut self, other_name: &str) -> &mut SubjectAlternativeName {
532-
self.names.push(format!("otherName:{}", other_name));
533-
self
496+
///
497+
/// Not currently actually supported, always panics.
498+
#[deprecated = "other_name is deprecated and always panics. Please file a bug if you have a use case for this."]
499+
pub fn other_name(&mut self, _other_name: &str) -> &mut SubjectAlternativeName {
500+
unimplemented!(
501+
"This has not yet been adapted for the new internals. File a bug if you need this."
502+
);
534503
}
535504

536505
/// Return a `SubjectAlternativeName` extension as an `X509Extension`.
537-
pub fn build(&self, ctx: &X509v3Context<'_>) -> Result<X509Extension, ErrorStack> {
538-
let mut value = String::new();
539-
let mut first = true;
540-
append(&mut value, &mut first, self.critical, "critical");
541-
for name in &self.names {
542-
append(&mut value, &mut first, true, name);
506+
pub fn build(&self, _ctx: &X509v3Context<'_>) -> Result<X509Extension, ErrorStack> {
507+
let mut stack = Stack::new()?;
508+
for item in &self.items {
509+
let gn = match item {
510+
RustGeneralName::Dns(s) => GeneralName::new_dns(s.as_bytes())?,
511+
RustGeneralName::Email(s) => GeneralName::new_email(s.as_bytes())?,
512+
RustGeneralName::Uri(s) => GeneralName::new_uri(s.as_bytes())?,
513+
RustGeneralName::Ip(s) => {
514+
GeneralName::new_ip(s.parse().map_err(|_| ErrorStack::get())?)?
515+
}
516+
RustGeneralName::Rid(s) => GeneralName::new_rid(Asn1Object::from_str(s)?)?,
517+
};
518+
stack.push(gn)?;
519+
}
520+
521+
unsafe {
522+
X509Extension::new_internal(Nid::SUBJECT_ALT_NAME, self.critical, stack.as_ptr().cast())
543523
}
544-
X509Extension::new_nid(None, Some(ctx), Nid::SUBJECT_ALT_NAME, &value)
545524
}
546525
}
547526

0 commit comments

Comments
 (0)