aboutsummaryrefslogtreecommitdiff
path: root/openssl/src
diff options
context:
space:
mode:
authorJethro Beekman <[email protected]>2015-06-30 18:54:48 -0700
committerJethro Beekman <[email protected]>2015-07-01 00:18:45 -0700
commit8d1abf5156840cb718f637959a1f98f499a64519 (patch)
treebe3aaaed5ffd0118e2ac5ef89764fca55397424d /openssl/src
parentTurn assertions into unwraps such that tests provide useful output on panic. (diff)
downloadrust-openssl-8d1abf5156840cb718f637959a1f98f499a64519.tar.xz
rust-openssl-8d1abf5156840cb718f637959a1f98f499a64519.zip
Implement "extensions" field in X509generator, and change existing extensions to use that
Diffstat (limited to 'openssl/src')
-rw-r--r--openssl/src/nid.rs2
-rw-r--r--openssl/src/x509/extension.rs42
-rw-r--r--openssl/src/x509/mod.rs34
3 files changed, 53 insertions, 25 deletions
diff --git a/openssl/src/nid.rs b/openssl/src/nid.rs
index c5b9e277..81cc4975 100644
--- a/openssl/src/nid.rs
+++ b/openssl/src/nid.rs
@@ -1,5 +1,5 @@
#[allow(non_camel_case_types)]
-#[derive(Copy, Clone)]
+#[derive(Copy, Clone, Hash, PartialEq, Eq)]
#[repr(usize)]
pub enum Nid {
Undefined,
diff --git a/openssl/src/x509/extension.rs b/openssl/src/x509/extension.rs
index b7f5fc52..4f8a3c3b 100644
--- a/openssl/src/x509/extension.rs
+++ b/openssl/src/x509/extension.rs
@@ -1,4 +1,11 @@
use std::fmt;
+use nid::Nid;
+
+#[derive(Clone,Copy,Hash,PartialEq,Eq)]
+pub enum ExtensionType {
+ KeyUsage,
+ ExtKeyUsage,
+}
#[derive(Clone)]
pub enum Extension {
@@ -6,6 +13,41 @@ pub enum Extension {
ExtKeyUsage(Vec<ExtKeyUsageOption>),
}
+impl Extension {
+ pub fn get_type(&self) -> ExtensionType {
+ match self {
+ &Extension::KeyUsage(_) => ExtensionType::KeyUsage,
+ &Extension::ExtKeyUsage(_) => ExtensionType::ExtKeyUsage,
+ }
+ }
+
+ pub fn get_nid(&self) -> Nid {
+ match self {
+ &Extension::KeyUsage(_) => Nid::KeyUsage,
+ &Extension::ExtKeyUsage(_) => Nid::ExtendedKeyUsage,
+ }
+ }
+}
+
+// FIXME: This would be nicer as a method on Iterator<Item=ToString>. This can
+// eventually be replaced by the successor to std::slice::SliceConcatExt.connect
+fn join<I: Iterator<Item=T>,T: ToString>(iter: I, sep: &str) -> String {
+ iter.enumerate().fold(String::new(), |mut acc, (idx, v)| {
+ if idx > 0 { acc.push_str(sep) };
+ acc.push_str(&v.to_string());
+ acc
+ })
+}
+
+impl ToString for Extension {
+ fn to_string(&self) -> String {
+ match self {
+ &Extension::KeyUsage(ref purposes) => join(purposes.iter(),","),
+ &Extension::ExtKeyUsage(ref purposes) => join(purposes.iter(),","),
+ }
+ }
+}
+
#[derive(Clone,Copy)]
pub enum KeyUsageOption {
DigitalSignature,
diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs
index 864e94c8..7d936f7e 100644
--- a/openssl/src/x509/mod.rs
+++ b/openssl/src/x509/mod.rs
@@ -9,6 +9,7 @@ use std::ptr;
use std::ops::Deref;
use std::fmt;
use std::str;
+use std::collections::HashMap;
use asn1::{Asn1Time};
use bio::{MemBio};
@@ -22,6 +23,8 @@ use nid;
mod extension;
+use self::extension::{ExtensionType,Extension};
+
#[cfg(test)]
mod tests;
@@ -103,16 +106,6 @@ impl X509StoreContext {
pub use self::extension::KeyUsageOption as KeyUsage;
pub use self::extension::ExtKeyUsageOption as ExtKeyUsage;
-// FIXME: This would be nicer as a method on Iterator<Item=ToString>. This can
-// eventually be replaced by the successor to std::slice::SliceConcatExt.connect
-fn join<I: Iterator<Item=T>,T: ToString>(iter: I, sep: &str) -> String {
- iter.enumerate().fold(String::new(), |mut acc, (idx, v)| {
- if idx > 0 { acc.push_str(sep) };
- acc.push_str(&v.to_string());
- acc
- })
-}
-
#[allow(non_snake_case)]
/// Generator of private key/certificate pairs
///
@@ -153,8 +146,8 @@ pub struct X509Generator {
bits: u32,
days: u32,
CN: String,
- key_usage: Vec<KeyUsage>,
- ext_key_usage: Vec<ExtKeyUsage>,
+ // RFC 3280 ยง4.2: A certificate MUST NOT include more than one instance of a particular extension.
+ extensions: HashMap<ExtensionType,Extension>,
hash_type: HashType,
}
@@ -173,8 +166,7 @@ impl X509Generator {
bits: 1024,
days: 365,
CN: "rust-openssl".to_string(),
- key_usage: Vec::new(),
- ext_key_usage: Vec::new(),
+ extensions: HashMap::new(),
hash_type: HashType::SHA1
}
}
@@ -200,13 +192,13 @@ impl X509Generator {
/// Sets what for certificate could be used
pub fn set_usage(mut self, purposes: &[KeyUsage]) -> X509Generator {
- self.key_usage = purposes.to_vec();
+ self.extensions.insert(ExtensionType::KeyUsage,Extension::KeyUsage(purposes.to_owned()));
self
}
/// Sets allowed extended usage of certificate
pub fn set_ext_usage(mut self, purposes: &[ExtKeyUsage]) -> X509Generator {
- self.ext_key_usage = purposes.to_vec();
+ self.extensions.insert(ExtensionType::ExtKeyUsage,Extension::ExtKeyUsage(purposes.to_owned()));
self
}
@@ -304,14 +296,8 @@ impl X509Generator {
try!(X509Generator::add_name(name, "CN", &self.CN));
ffi::X509_set_issuer_name(x509.handle, name);
- if self.key_usage.len() > 0 {
- try!(X509Generator::add_extension(x509.handle, ffi::NID_key_usage,
- &join(self.key_usage.iter(),",")));
- }
-
- if self.ext_key_usage.len() > 0 {
- try!(X509Generator::add_extension(x509.handle, ffi::NID_ext_key_usage,
- &join(self.ext_key_usage.iter(),",")));
+ for ext in self.extensions.values() {
+ try!(X509Generator::add_extension(x509.handle, ext.get_nid() as c_int, &ext.to_string()));
}
let hash_fn = self.hash_type.evp_md();