From 557b936e27177718b62d31dcf3364f481bb15c2c Mon Sep 17 00:00:00 2001 From: mredlek Date: Thu, 26 Jan 2017 20:59:32 +0100 Subject: [PATCH 1/5] Added X509ReqRef.subject_name and X509ReqRef.version --- openssl-sys/src/lib.rs | 4 +++- openssl-sys/src/libressl.rs | 17 +++++++++++++++++ openssl-sys/src/ossl10x.rs | 17 +++++++++++++++++ openssl-sys/src/ossl110.rs | 6 ++++++ openssl/src/asn1.rs | 22 ++++++++++++++++++++++ openssl/src/x509/mod.rs | 27 +++++++++++++++++++++++++++ openssl/src/x509/tests.rs | 9 +++++++-- 7 files changed, 99 insertions(+), 3 deletions(-) diff --git a/openssl-sys/src/lib.rs b/openssl-sys/src/lib.rs index 01be1b23..e801ca98 100644 --- a/openssl-sys/src/lib.rs +++ b/openssl-sys/src/lib.rs @@ -51,7 +51,6 @@ pub enum X509_CRL {} pub enum X509_EXTENSION {} pub enum X509_NAME {} pub enum X509_NAME_ENTRY {} -pub enum X509_REQ {} pub enum X509_STORE {} pub enum X509_STORE_CTX {} pub enum bio_st {} @@ -1387,6 +1386,7 @@ extern { pub fn AES_set_decrypt_key(userKey: *const c_uchar, bits: c_int, key: *mut AES_KEY) -> c_int; pub fn AES_ige_encrypt(in_: *const c_uchar, out: *mut c_uchar, length: size_t, key: *const AES_KEY, ivec: *mut c_uchar, enc: c_int); + pub fn ASN1_INTEGER_get(dest: *mut ASN1_INTEGER) -> c_long; pub fn ASN1_INTEGER_set(dest: *mut ASN1_INTEGER, value: c_long) -> c_int; pub fn ASN1_GENERALIZEDTIME_free(tm: *mut ASN1_GENERALIZEDTIME); pub fn ASN1_GENERALIZEDTIME_print(b: *mut BIO, tm: *const ASN1_GENERALIZEDTIME) -> c_int; @@ -1918,6 +1918,8 @@ extern { pub fn ASN1_STRING_free(x: *mut ASN1_STRING); pub fn ASN1_STRING_length(x: *const ASN1_STRING) -> c_int; + pub fn ASN1_INTEGER_free(x: *mut ASN1_INTEGER); + pub fn X509_STORE_new() -> *mut X509_STORE; pub fn X509_STORE_free(store: *mut X509_STORE); pub fn X509_STORE_add_cert(store: *mut X509_STORE, x: *mut X509) -> c_int; diff --git a/openssl-sys/src/libressl.rs b/openssl-sys/src/libressl.rs index 2862a47e..0767df0d 100644 --- a/openssl-sys/src/libressl.rs +++ b/openssl-sys/src/libressl.rs @@ -298,6 +298,23 @@ pub struct X509_VAL { pub notAfter: *mut ::ASN1_TIME, } +#[repr(C)] +pub struct X509_REQ_INFO { + pub enc: ASN1_ENCODING, + pub version: *mut ::ASN1_INTEGER, + pub subject: *mut ::X509_NAME, + pub pubkey: *mut c_void, + pub attributes: *mut stack_st_X509_ATTRIBUTE +} + +#[repr(C)] +pub struct X509_REQ { + pub req_info: *mut X509_REQ_INFO, + pub sig_alg: *mut c_void, + pub signature: *mut c_void, + references: c_int +} + #[repr(C)] pub struct SSL { version: c_int, diff --git a/openssl-sys/src/ossl10x.rs b/openssl-sys/src/ossl10x.rs index 14b7c414..d9729b0d 100644 --- a/openssl-sys/src/ossl10x.rs +++ b/openssl-sys/src/ossl10x.rs @@ -305,6 +305,23 @@ pub struct X509_VAL { pub notAfter: *mut ::ASN1_TIME, } +#[repr(C)] +pub struct X509_REQ_INFO { + pub enc: ASN1_ENCODING, + pub version: *mut ::ASN1_INTEGER, + pub subject: *mut ::X509_NAME, + pub pubkey: *mut c_void, + pub attributes: *mut stack_st_X509_ATTRIBUTE +} + +#[repr(C)] +pub struct X509_REQ { + pub req_info: *mut X509_REQ_INFO, + pub sig_alg: *mut c_void, + pub signature: *mut c_void, + references: c_int +} + #[repr(C)] pub struct SSL { version: c_int, diff --git a/openssl-sys/src/ossl110.rs b/openssl-sys/src/ossl110.rs index b7fdebab..c3c95fa4 100644 --- a/openssl-sys/src/ossl110.rs +++ b/openssl-sys/src/ossl110.rs @@ -27,6 +27,7 @@ pub enum stack_st_X509_EXTENSION {} pub enum stack_st_SSL_CIPHER {} pub enum X509 {} pub enum X509_VERIFY_PARAM {} +pub enum X509_REQ {} pub const SSL_OP_MICROSOFT_SESS_ID_BUG: c_ulong = 0x00000000; pub const SSL_OP_NETSCAPE_CHALLENGE_BUG: c_ulong = 0x00000000; @@ -191,4 +192,9 @@ extern { iter: c_int, mac_iter: c_int, keytype: c_int) -> *mut PKCS12; + pub fn X509_REQ_get_version(req: *const X509_REQ) -> c_long; + pub fn X509_REQ_set_version(x: *mut X509_REQ, version: c_long) -> c_int; + pub fn X509_REQ_get_subject_name(req: *const X509_REQ) -> *mut ::X509_NAME; + pub fn X509_REQ_set_subject_name(req: *mut X509_REQ, name: *mut ::X509_NAME) -> c_int; + } diff --git a/openssl/src/asn1.rs b/openssl/src/asn1.rs index d177885e..f5d6a102 100644 --- a/openssl/src/asn1.rs +++ b/openssl/src/asn1.rs @@ -75,6 +75,28 @@ impl Asn1StringRef { } } +type_!(Asn1Integer, Asn1IntegerRef, ffi::ASN1_INTEGER, ffi::ASN1_INTEGER_free); + +impl Asn1IntegerRef { + pub fn get(&self) -> i64 { + unsafe { + return ::ffi::ASN1_INTEGER_get(self.as_ptr()); + } + } + + pub fn set(&self, value: i64) -> Result<(), ErrorStack> + { + unsafe { + let res = ::ffi::ASN1_INTEGER_set(self.as_ptr(), value); + if res < 0 { + return Err(ErrorStack::get()); + } + + Ok(()) + } + } +} + #[cfg(any(ossl101, ossl102))] use ffi::ASN1_STRING_data; diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index e75dcf5d..2edfa675 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -599,6 +599,21 @@ impl X509Req { impl X509ReqRef { to_pem!(ffi::PEM_write_bio_X509_REQ); to_der!(ffi::i2d_X509_REQ); + + pub fn version(&self) -> i64 + { + unsafe { + let version = compat::X509_REQ_get_version(self.as_ptr()); + version + } + } + + pub fn subject_name(&self) -> &X509NameRef { + unsafe { + let name = compat::X509_REQ_get_subject_name(self.as_ptr()); + X509NameRef::from_ptr(name) + } + } } /// A collection of X.509 extensions. @@ -779,6 +794,8 @@ mod compat { pub use ffi::X509_getm_notBefore as X509_get_notBefore; pub use ffi::X509_up_ref; pub use ffi::X509_get0_extensions; + pub use ffi::X509_REQ_get_version; + pub use ffi::X509_REQ_get_subject_name; } #[cfg(ossl10x)] @@ -812,4 +829,14 @@ mod compat { (*info).extensions } } + + pub unsafe fn X509_REQ_get_version(x: *mut ffi::X509_REQ) -> ::libc::c_long + { + ::ffi::ASN1_INTEGER_get((*(*x).req_info).version) + } + + pub unsafe fn X509_REQ_get_subject_name(x: *mut ffi::X509_REQ) -> *mut ::ffi::X509_NAME + { + (*(*x).req_info).subject + } } diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index 01cbf2ec..14fbb173 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -6,7 +6,7 @@ use nid::X9_62_PRIME256V1; use pkey::PKey; use rsa::Rsa; use ssl::{SslMethod, SslContextBuilder}; -use x509::{X509, X509Generator}; +use x509::{X509, X509Generator, X509Req}; use x509::extension::Extension::{KeyUsage, ExtKeyUsage, SubjectAltName, OtherNid, OtherStr}; use x509::extension::AltNameOption as SAN; use x509::extension::KeyUsageOption::{DigitalSignature, KeyEncipherment}; @@ -75,7 +75,12 @@ fn test_req_gen() { let pkey = pkey(); let req = get_generator().request(&pkey).unwrap(); - req.to_pem().unwrap(); + let reqpem = req.to_pem().unwrap(); + + let req = X509Req::from_pem(&reqpem).ok().expect("Failed to load PEM"); + let cn = (*req).subject_name().entries_by_nid(nid::COMMONNAME).next().unwrap(); + assert_eq!(0, (*req).version()); + assert_eq!(cn.data().as_slice(), b"test_me"); // FIXME: check data in result to be correct, needs implementation // of X509_REQ getters From 6a8f6f425f504459a6f4c54eac273f543c53a55e Mon Sep 17 00:00:00 2001 From: mredlek Date: Fri, 27 Jan 2017 19:11:05 +0100 Subject: [PATCH 2/5] Style changes according to review --- openssl-sys/src/lib.rs | 2 +- openssl-sys/src/libressl.rs | 6 +++--- openssl-sys/src/ossl10x.rs | 6 +++--- openssl/src/asn1.rs | 11 +++-------- openssl/src/x509/mod.rs | 5 ++--- 5 files changed, 12 insertions(+), 18 deletions(-) diff --git a/openssl-sys/src/lib.rs b/openssl-sys/src/lib.rs index e801ca98..47bc314c 100644 --- a/openssl-sys/src/lib.rs +++ b/openssl-sys/src/lib.rs @@ -1386,7 +1386,7 @@ extern { pub fn AES_set_decrypt_key(userKey: *const c_uchar, bits: c_int, key: *mut AES_KEY) -> c_int; pub fn AES_ige_encrypt(in_: *const c_uchar, out: *mut c_uchar, length: size_t, key: *const AES_KEY, ivec: *mut c_uchar, enc: c_int); - pub fn ASN1_INTEGER_get(dest: *mut ASN1_INTEGER) -> c_long; + pub fn ASN1_INTEGER_get(dest: *const ASN1_INTEGER) -> c_long; pub fn ASN1_INTEGER_set(dest: *mut ASN1_INTEGER, value: c_long) -> c_int; pub fn ASN1_GENERALIZEDTIME_free(tm: *mut ASN1_GENERALIZEDTIME); pub fn ASN1_GENERALIZEDTIME_print(b: *mut BIO, tm: *const ASN1_GENERALIZEDTIME) -> c_int; diff --git a/openssl-sys/src/libressl.rs b/openssl-sys/src/libressl.rs index 0767df0d..fd115a98 100644 --- a/openssl-sys/src/libressl.rs +++ b/openssl-sys/src/libressl.rs @@ -303,15 +303,15 @@ pub struct X509_REQ_INFO { pub enc: ASN1_ENCODING, pub version: *mut ::ASN1_INTEGER, pub subject: *mut ::X509_NAME, - pub pubkey: *mut c_void, + pubkey: *mut c_void, pub attributes: *mut stack_st_X509_ATTRIBUTE } #[repr(C)] pub struct X509_REQ { pub req_info: *mut X509_REQ_INFO, - pub sig_alg: *mut c_void, - pub signature: *mut c_void, + sig_alg: *mut c_void, + signature: *mut c_void, references: c_int } diff --git a/openssl-sys/src/ossl10x.rs b/openssl-sys/src/ossl10x.rs index d9729b0d..0b3376d0 100644 --- a/openssl-sys/src/ossl10x.rs +++ b/openssl-sys/src/ossl10x.rs @@ -310,15 +310,15 @@ pub struct X509_REQ_INFO { pub enc: ASN1_ENCODING, pub version: *mut ::ASN1_INTEGER, pub subject: *mut ::X509_NAME, - pub pubkey: *mut c_void, + pubkey: *mut c_void, pub attributes: *mut stack_st_X509_ATTRIBUTE } #[repr(C)] pub struct X509_REQ { pub req_info: *mut X509_REQ_INFO, - pub sig_alg: *mut c_void, - pub signature: *mut c_void, + sig_alg: *mut c_void, + signature: *mut c_void, references: c_int } diff --git a/openssl/src/asn1.rs b/openssl/src/asn1.rs index f5d6a102..dc616b59 100644 --- a/openssl/src/asn1.rs +++ b/openssl/src/asn1.rs @@ -80,19 +80,14 @@ type_!(Asn1Integer, Asn1IntegerRef, ffi::ASN1_INTEGER, ffi::ASN1_INTEGER_free); impl Asn1IntegerRef { pub fn get(&self) -> i64 { unsafe { - return ::ffi::ASN1_INTEGER_get(self.as_ptr()); + ::ffi::ASN1_INTEGER_get(self.as_ptr()) as i64 } } - pub fn set(&self, value: i64) -> Result<(), ErrorStack> + pub fn set(&mut self, value: i32) -> Result<(), ErrorStack> { unsafe { - let res = ::ffi::ASN1_INTEGER_set(self.as_ptr(), value); - if res < 0 { - return Err(ErrorStack::get()); - } - - Ok(()) + cvt(::ffi::ASN1_INTEGER_set(self.as_ptr(), value as c_long)).map(|_| ()) } } } diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 2edfa675..23d9bcaa 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -600,11 +600,10 @@ impl X509ReqRef { to_pem!(ffi::PEM_write_bio_X509_REQ); to_der!(ffi::i2d_X509_REQ); - pub fn version(&self) -> i64 + pub fn version(&self) -> i32 { unsafe { - let version = compat::X509_REQ_get_version(self.as_ptr()); - version + compat::X509_REQ_get_version(self.as_ptr()) as i32 } } From f5149eac5a5746c1cb45edab445ab0d240d33c86 Mon Sep 17 00:00:00 2001 From: mredlek Date: Fri, 27 Jan 2017 20:55:40 +0100 Subject: [PATCH 3/5] Add setters to new getter-functions in X509ReqRef --- openssl-sys/src/lib.rs | 3 +++ openssl-sys/src/ossl110.rs | 3 --- openssl/src/x509/mod.rs | 13 +++++++++++++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/openssl-sys/src/lib.rs b/openssl-sys/src/lib.rs index 47bc314c..1340a63f 100644 --- a/openssl-sys/src/lib.rs +++ b/openssl-sys/src/lib.rs @@ -1935,6 +1935,9 @@ extern { pub fn X509_REQ_add_extensions(req: *mut X509_REQ, exts: *mut stack_st_X509_EXTENSION) -> c_int; pub fn X509_REQ_sign(x: *mut X509_REQ, pkey: *mut EVP_PKEY, md: *const EVP_MD) -> c_int; + pub fn X509_REQ_set_version(x: *mut X509_REQ, version: c_long) -> c_int; + pub fn X509_REQ_set_subject_name(req: *mut X509_REQ, name: *mut ::X509_NAME) -> c_int; + #[cfg(not(ossl101))] pub fn X509_VERIFY_PARAM_free(param: *mut X509_VERIFY_PARAM); diff --git a/openssl-sys/src/ossl110.rs b/openssl-sys/src/ossl110.rs index c3c95fa4..84f08f29 100644 --- a/openssl-sys/src/ossl110.rs +++ b/openssl-sys/src/ossl110.rs @@ -193,8 +193,5 @@ extern { mac_iter: c_int, keytype: c_int) -> *mut PKCS12; pub fn X509_REQ_get_version(req: *const X509_REQ) -> c_long; - pub fn X509_REQ_set_version(x: *mut X509_REQ, version: c_long) -> c_int; pub fn X509_REQ_get_subject_name(req: *const X509_REQ) -> *mut ::X509_NAME; - pub fn X509_REQ_set_subject_name(req: *mut X509_REQ, name: *mut ::X509_NAME) -> c_int; - } diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 23d9bcaa..c08fc337 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -607,12 +607,25 @@ impl X509ReqRef { } } + pub fn set_version(&mut self, value: i32) -> Result<(), ErrorStack> + { + unsafe { + cvt(ffi::X509_REQ_set_version(self.as_ptr(), value as c_long)).map(|_| ()) + } + } + pub fn subject_name(&self) -> &X509NameRef { unsafe { let name = compat::X509_REQ_get_subject_name(self.as_ptr()); X509NameRef::from_ptr(name) } } + + pub fn set_subject_name(&self, value: &X509NameRef) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::X509_REQ_set_subject_name(self.as_ptr(), value.as_ptr())).map(|_| ()) + } + } } /// A collection of X.509 extensions. From 8ae424235e1a09b5fdcd2879a960742d529c04da Mon Sep 17 00:00:00 2001 From: mredlek Date: Tue, 7 Feb 2017 21:49:07 +0100 Subject: [PATCH 4/5] Make it compile again. Make self mut in set_subject_name. Add assert to prevent a null pointer in subject_name. --- openssl/src/asn1.rs | 8 +++++++- openssl/src/x509/mod.rs | 3 ++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/openssl/src/asn1.rs b/openssl/src/asn1.rs index 8016df13..46c09740 100644 --- a/openssl/src/asn1.rs +++ b/openssl/src/asn1.rs @@ -93,7 +93,13 @@ impl Asn1StringRef { } } -type_!(Asn1Integer, Asn1IntegerRef, ffi::ASN1_INTEGER, ffi::ASN1_INTEGER_free); +foreign_type! { + type CType = ffi::ASN1_INTEGER; + fn drop = ffi::ASN1_INTEGER_free; + + pub struct Asn1Integer; + pub struct Asn1IntegerRef; +} impl Asn1IntegerRef { pub fn get(&self) -> i64 { diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 174635ca..d9fd36ef 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -647,11 +647,12 @@ impl X509ReqRef { pub fn subject_name(&self) -> &X509NameRef { unsafe { let name = compat::X509_REQ_get_subject_name(self.as_ptr()); + assert!(!name.is_null()); X509NameRef::from_ptr(name) } } - pub fn set_subject_name(&self, value: &X509NameRef) -> Result<(), ErrorStack> { + pub fn set_subject_name(&mut self, value: &X509NameRef) -> Result<(), ErrorStack> { unsafe { cvt(ffi::X509_REQ_set_subject_name(self.as_ptr(), value.as_ptr())).map(|_| ()) } From 5ad4af70ae4bb2c04c1df5d4adda05c4f6b54295 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sat, 11 Feb 2017 09:17:39 -0800 Subject: [PATCH 5/5] Re-add reexport --- openssl/src/x509/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 79f36e7c..0d329da4 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -873,6 +873,7 @@ mod compat { pub use ffi::X509_getm_notAfter as X509_get_notAfter; pub use ffi::X509_getm_notBefore as X509_get_notBefore; pub use ffi::X509_up_ref; + pub use ffi::X509_get0_extensions; pub use ffi::X509_REQ_get_version; pub use ffi::X509_REQ_get_subject_name; pub use ffi::X509_get0_signature;