diff --git a/.gitignore b/.gitignore index 06f515a..f4619cd 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,6 @@ Cargo.lock /target/ # Editor and IDE environments -.vscode/ \ No newline at end of file +.vscode/ +/target-wsl +/vcpkg_installed diff --git a/Cargo.toml b/Cargo.toml index 947447f..50ef815 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,22 +1,25 @@ [package] -name = "xmlsec" -version = "0.2.3" -authors = ["Leonhard Weber "] -edition = "2021" -readme = "README.md" -license = "MIT" -description = "Wrapper for xmlsec1 library" -homepage = "https://github.com/voipir/rust-xmlsec" -repository = "https://github.com/voipir/rust-xmlsec" -keywords = ["xml", "xmlsec", "dsig"] +name = "xmlsec" +version = "0.2.3" +authors = ["Leonhard Weber "] +edition = "2021" +readme = "README.md" +license = "MIT" +description = "Wrapper for xmlsec1 library" +homepage = "https://github.com/voipir/rust-xmlsec" +repository = "https://github.com/voipir/rust-xmlsec" +keywords = ["xml", "xmlsec", "dsig"] build = "bindings.rs" [dependencies] -libc = {version = "^0.2"} -libxml = {version = "^0.3"} -lazy_static = {version = "^1.4"} +libc = { version = "^0.2" } +libxml = { version = "^0.3" } +lazy_static = { version = "^1.4" } [build-dependencies] -pkg-config = {version = "^0.3"} -bindgen = {version = "^0.65"} +pkg-config = { version = "^0.3" } +bindgen = { version = "^0.71" } + +[target.'cfg(windows)'.build-dependencies] +vcpkg = { version = "0.2", git = "https://github.com/mcgoo/vcpkg-rs.git", branch = "master" } diff --git a/bindings.rs b/bindings.rs index d48087f..c87611a 100644 --- a/bindings.rs +++ b/bindings.rs @@ -1,85 +1,94 @@ //! //! XmlSec Bindings Generation //! -use bindgen::Builder as BindgenBuilder; +use bindgen::Builder as BindgenBuilder; use bindgen::Formatter as BindgenFormatter; -use pkg_config::Config as PkgConfig; - +use std::collections::HashMap; use std::env; use std::path::PathBuf; -use std::process::Command; - const BINDINGS: &str = "bindings.rs"; +fn main() { + let dependencies = locate_and_link_dependencies(); -fn main() -{ - println!("cargo:rustc-link-lib=xmlsec1-openssl"); // -lxmlsec1-openssl - println!("cargo:rustc-link-lib=xmlsec1"); // -lxmlsec1 - println!("cargo:rustc-link-lib=xml2"); // -lxml2 - println!("cargo:rustc-link-lib=ssl"); // -lssl - println!("cargo:rustc-link-lib=crypto"); // -lcrypto - - let path_out = PathBuf::from(env::var("OUT_DIR").unwrap()); + let path_out = PathBuf::from(env::var("OUT_DIR").unwrap()); let path_bindings = path_out.join(BINDINGS); - if !path_bindings.exists() - { - PkgConfig::new() - .probe("xmlsec1") - .expect("Could not find xmlsec1 using pkg-config"); - + if !path_bindings.exists() { let bindbuild = BindgenBuilder::default() .header("bindings.h") - .clang_args(fetch_xmlsec_config_flags()) - .clang_args(fetch_xmlsec_config_libs()) + .allowlist_type("xml.*") + .allowlist_function("xml.*") + .allowlist_var("xml.*") + .clang_args(dependencies.clang_args()) .layout_tests(true) .formatter(BindgenFormatter::default()) .generate_comments(true); - let bindings = bindbuild.generate() - .expect("Unable to generate bindings"); + let bindings = bindbuild.generate().expect("Unable to generate bindings"); - bindings.write_to_file(path_bindings) + bindings + .write_to_file(path_bindings) .expect("Couldn't write bindings!"); } } - -fn fetch_xmlsec_config_flags() -> Vec -{ - let out = Command::new("xmlsec1-config") - .arg("--cflags") - .output() - .expect("Failed to get --cflags from xmlsec1-config. Is xmlsec1 installed?") - .stdout; - - args_from_output(out) +struct LocatedDependencies { + include_paths: Vec, + defines: HashMap>, } - -fn fetch_xmlsec_config_libs() -> Vec -{ - let out = Command::new("xmlsec1-config") - .arg("--libs") - .output() - .expect("Failed to get --libs from xmlsec1-config. Is xmlsec1 installed?") - .stdout; - - args_from_output(out) +impl LocatedDependencies { + fn clang_args(&self) -> Vec { + let mut result = Vec::new(); + for include_path in &self.include_paths { + result.push(format!("-I{}", include_path.display())); + } + for (define, value) in &self.defines { + match value { + Some(value) => result.push(format!("-D{}={}", define, value)), + None => result.push(format!("-D{}", define)), + } + } + result + } } +#[cfg(not(windows))] +fn locate_and_link_dependencies() -> LocatedDependencies { + let library = + pkg_config::probe_library("xmlsec1").expect("Could not find xmlsec1 using pkg-config"); -fn args_from_output(args: Vec) -> Vec -{ - let decoded = String::from_utf8(args) - .expect("Got invalid UTF8 from xmlsec1-config"); - - let args = decoded.split_whitespace() - .map(|p| p.to_owned()) - .collect::>(); + LocatedDependencies { + include_paths: library.include_paths, + defines: library.defines, + } +} - args +#[cfg(windows)] +fn locate_and_link_dependencies() -> LocatedDependencies { + let library = + vcpkg::find_package("xmlsec").expect("Failed to find xmlsec using vcpkg. Is it installed?"); + + println!("cargo:rustc-link-lib=crypt32"); + println!("cargo:rustc-link-lib=user32"); + println!("cargo:rustc-link-lib=bcrypt"); + + // vcpkg does not provide the defines, so we have to provide them ourselves + // -DXMLSEC_DL_LIBLTDL=1 -DXMLSEC_CRYPTO_OPENSSL=1 + let mut defines = HashMap::new(); + defines.insert("__XMLSEC_FUNCTION__".into(), Some("__func__".into())); + defines.insert("XMLSEC_NO_SIZE_T".into(), None); + defines.insert("XMLSEC_DL_LIBLTDL".into(), Some("1".into())); + defines.insert("XMLSEC_CRYPTO_OPENSSL".into(), Some("1".into())); + defines.insert("XMLSEC_NO_CRYPTO_DYNAMIC_LOADING".into(), Some("1".into())); + defines.insert("XMLSEC_NO_GOST".into(), Some("1".into())); + defines.insert("XMLSEC_NO_GOST2012".into(), Some("1".into())); + + LocatedDependencies { + include_paths: library.include_paths, + defines, + } } diff --git a/src/crypto/openssl.rs b/src/crypto/openssl.rs index 041aae0..77438ea 100644 --- a/src/crypto/openssl.rs +++ b/src/crypto/openssl.rs @@ -3,11 +3,9 @@ //! use crate::bindings; - /// Supported digesting and signing methods as specified by the XML standard. #[allow(missing_docs)] -pub enum XmlSecSignatureMethod -{ +pub enum XmlSecSignatureMethod { Aes128Cbc, Aes192Cbc, Aes256Cbc, @@ -26,16 +24,16 @@ pub enum XmlSecSignatureMethod EcdsaSha256, EcdsaSha384, EcdsaSha512, - HmacMd5, + // HmacMd5, HmacRipemd160, HmacSha1, HmacSha224, HmacSha256, HmacSha384, HmacSha512, - Md5, + // Md5, Ripemd160, - RsaMd5, + // RsaMd5, RsaRipemd160, RsaSha1, RsaSha224, @@ -51,55 +49,53 @@ pub enum XmlSecSignatureMethod Sha512, } - -impl XmlSecSignatureMethod -{ +impl XmlSecSignatureMethod { /// Returns the resource pointer for the corresponding digesting/signing resource - pub fn to_method(&self) -> bindings::xmlSecTransformId - { - match self - { - Self::Aes128Cbc => unsafe { bindings::xmlSecOpenSSLTransformAes128CbcGetKlass() }, - Self::Aes192Cbc => unsafe { bindings::xmlSecOpenSSLTransformAes192CbcGetKlass() }, - Self::Aes256Cbc => unsafe { bindings::xmlSecOpenSSLTransformAes256CbcGetKlass() }, + pub fn to_method(&self) -> bindings::xmlSecTransformId { + match self { + Self::Aes128Cbc => unsafe { bindings::xmlSecOpenSSLTransformAes128CbcGetKlass() }, + Self::Aes192Cbc => unsafe { bindings::xmlSecOpenSSLTransformAes192CbcGetKlass() }, + Self::Aes256Cbc => unsafe { bindings::xmlSecOpenSSLTransformAes256CbcGetKlass() }, // Self::Aes128Gcm => unsafe { bindings::xmlSecOpenSSLTransformAes128GcmGetKlass() }, // Self::Aes192Gcm => unsafe { bindings::xmlSecOpenSSLTransformAes192GcmGetKlass() }, // Self::Aes256Gcm => unsafe { bindings::xmlSecOpenSSLTransformAes256GcmGetKlass() }, - Self::KWAes128 => unsafe { bindings::xmlSecOpenSSLTransformKWAes128GetKlass() }, - Self::KWAes192 => unsafe { bindings::xmlSecOpenSSLTransformKWAes192GetKlass() }, - Self::KWAes256 => unsafe { bindings::xmlSecOpenSSLTransformKWAes256GetKlass() }, - Self::Des3Cbc => unsafe { bindings::xmlSecOpenSSLTransformDes3CbcGetKlass() }, - Self::KWDes3 => unsafe { bindings::xmlSecOpenSSLTransformKWDes3GetKlass() }, - Self::DsaSha1 => unsafe { bindings::xmlSecOpenSSLTransformDsaSha1GetKlass() }, - Self::DsaSha256 => unsafe { bindings::xmlSecOpenSSLTransformDsaSha256GetKlass() }, - Self::EcdsaSha1 => unsafe { bindings::xmlSecOpenSSLTransformEcdsaSha1GetKlass() }, - Self::EcdsaSha224 => unsafe { bindings::xmlSecOpenSSLTransformEcdsaSha224GetKlass() }, - Self::EcdsaSha256 => unsafe { bindings::xmlSecOpenSSLTransformEcdsaSha256GetKlass() }, - Self::EcdsaSha384 => unsafe { bindings::xmlSecOpenSSLTransformEcdsaSha384GetKlass() }, - Self::EcdsaSha512 => unsafe { bindings::xmlSecOpenSSLTransformEcdsaSha512GetKlass() }, - Self::HmacMd5 => unsafe { bindings::xmlSecOpenSSLTransformHmacMd5GetKlass() }, - Self::HmacRipemd160 => unsafe { bindings::xmlSecOpenSSLTransformHmacRipemd160GetKlass() }, - Self::HmacSha1 => unsafe { bindings::xmlSecOpenSSLTransformHmacSha1GetKlass() }, - Self::HmacSha224 => unsafe { bindings::xmlSecOpenSSLTransformHmacSha224GetKlass() }, - Self::HmacSha256 => unsafe { bindings::xmlSecOpenSSLTransformHmacSha256GetKlass() }, - Self::HmacSha384 => unsafe { bindings::xmlSecOpenSSLTransformHmacSha384GetKlass() }, - Self::HmacSha512 => unsafe { bindings::xmlSecOpenSSLTransformHmacSha512GetKlass() }, - Self::Md5 => unsafe { bindings::xmlSecOpenSSLTransformMd5GetKlass() }, - Self::Ripemd160 => unsafe { bindings::xmlSecOpenSSLTransformRipemd160GetKlass() }, - Self::RsaMd5 => unsafe { bindings::xmlSecOpenSSLTransformRsaMd5GetKlass() }, - Self::RsaRipemd160 => unsafe { bindings::xmlSecOpenSSLTransformRsaRipemd160GetKlass() }, - Self::RsaSha1 => unsafe { bindings::xmlSecOpenSSLTransformRsaSha1GetKlass() }, - Self::RsaSha224 => unsafe { bindings::xmlSecOpenSSLTransformRsaSha224GetKlass() }, - Self::RsaSha256 => unsafe { bindings::xmlSecOpenSSLTransformRsaSha256GetKlass() }, - Self::RsaSha384 => unsafe { bindings::xmlSecOpenSSLTransformRsaSha384GetKlass() }, - Self::RsaSha512 => unsafe { bindings::xmlSecOpenSSLTransformRsaSha512GetKlass() }, - Self::RsaPkcs1 => unsafe { bindings::xmlSecOpenSSLTransformRsaPkcs1GetKlass() }, - Self::RsaOaep => unsafe { bindings::xmlSecOpenSSLTransformRsaOaepGetKlass() }, - Self::Sha1 => unsafe { bindings::xmlSecOpenSSLTransformSha1GetKlass() }, - Self::Sha224 => unsafe { bindings::xmlSecOpenSSLTransformSha224GetKlass() }, - Self::Sha256 => unsafe { bindings::xmlSecOpenSSLTransformSha256GetKlass() }, - Self::Sha384 => unsafe { bindings::xmlSecOpenSSLTransformSha384GetKlass() }, - Self::Sha512 => unsafe { bindings::xmlSecOpenSSLTransformSha512GetKlass() }, + Self::KWAes128 => unsafe { bindings::xmlSecOpenSSLTransformKWAes128GetKlass() }, + Self::KWAes192 => unsafe { bindings::xmlSecOpenSSLTransformKWAes192GetKlass() }, + Self::KWAes256 => unsafe { bindings::xmlSecOpenSSLTransformKWAes256GetKlass() }, + Self::Des3Cbc => unsafe { bindings::xmlSecOpenSSLTransformDes3CbcGetKlass() }, + Self::KWDes3 => unsafe { bindings::xmlSecOpenSSLTransformKWDes3GetKlass() }, + Self::DsaSha1 => unsafe { bindings::xmlSecOpenSSLTransformDsaSha1GetKlass() }, + Self::DsaSha256 => unsafe { bindings::xmlSecOpenSSLTransformDsaSha256GetKlass() }, + Self::EcdsaSha1 => unsafe { bindings::xmlSecOpenSSLTransformEcdsaSha1GetKlass() }, + Self::EcdsaSha224 => unsafe { bindings::xmlSecOpenSSLTransformEcdsaSha224GetKlass() }, + Self::EcdsaSha256 => unsafe { bindings::xmlSecOpenSSLTransformEcdsaSha256GetKlass() }, + Self::EcdsaSha384 => unsafe { bindings::xmlSecOpenSSLTransformEcdsaSha384GetKlass() }, + Self::EcdsaSha512 => unsafe { bindings::xmlSecOpenSSLTransformEcdsaSha512GetKlass() }, + // Self::HmacMd5 => unsafe { bindings::xmlSecOpenSSLTransformHmacMd5GetKlass() }, + Self::HmacRipemd160 => unsafe { + bindings::xmlSecOpenSSLTransformHmacRipemd160GetKlass() + }, + Self::HmacSha1 => unsafe { bindings::xmlSecOpenSSLTransformHmacSha1GetKlass() }, + Self::HmacSha224 => unsafe { bindings::xmlSecOpenSSLTransformHmacSha224GetKlass() }, + Self::HmacSha256 => unsafe { bindings::xmlSecOpenSSLTransformHmacSha256GetKlass() }, + Self::HmacSha384 => unsafe { bindings::xmlSecOpenSSLTransformHmacSha384GetKlass() }, + Self::HmacSha512 => unsafe { bindings::xmlSecOpenSSLTransformHmacSha512GetKlass() }, + // Self::Md5 => unsafe { bindings::xmlSecOpenSSLTransformMd5GetKlass() }, + Self::Ripemd160 => unsafe { bindings::xmlSecOpenSSLTransformRipemd160GetKlass() }, + // Self::RsaMd5 => unsafe { bindings::xmlSecOpenSSLTransformRsaMd5GetKlass() }, + Self::RsaRipemd160 => unsafe { bindings::xmlSecOpenSSLTransformRsaRipemd160GetKlass() }, + Self::RsaSha1 => unsafe { bindings::xmlSecOpenSSLTransformRsaSha1GetKlass() }, + Self::RsaSha224 => unsafe { bindings::xmlSecOpenSSLTransformRsaSha224GetKlass() }, + Self::RsaSha256 => unsafe { bindings::xmlSecOpenSSLTransformRsaSha256GetKlass() }, + Self::RsaSha384 => unsafe { bindings::xmlSecOpenSSLTransformRsaSha384GetKlass() }, + Self::RsaSha512 => unsafe { bindings::xmlSecOpenSSLTransformRsaSha512GetKlass() }, + Self::RsaPkcs1 => unsafe { bindings::xmlSecOpenSSLTransformRsaPkcs1GetKlass() }, + Self::RsaOaep => unsafe { bindings::xmlSecOpenSSLTransformRsaOaepGetKlass() }, + Self::Sha1 => unsafe { bindings::xmlSecOpenSSLTransformSha1GetKlass() }, + Self::Sha224 => unsafe { bindings::xmlSecOpenSSLTransformSha224GetKlass() }, + Self::Sha256 => unsafe { bindings::xmlSecOpenSSLTransformSha256GetKlass() }, + Self::Sha384 => unsafe { bindings::xmlSecOpenSSLTransformSha384GetKlass() }, + Self::Sha512 => unsafe { bindings::xmlSecOpenSSLTransformSha512GetKlass() }, } } } diff --git a/src/keys.rs b/src/keys.rs index 7905de6..f0e02b3 100644 --- a/src/keys.rs +++ b/src/keys.rs @@ -15,56 +15,55 @@ use std::os::raw::c_uchar; use std::ffi::CStr; use std::ffi::CString; - /// x509 key format. #[allow(missing_docs)] #[repr(u32)] -pub enum XmlSecKeyFormat -{ - Unknown = bindings::xmlSecKeyDataFormat_xmlSecKeyDataFormatUnknown, - Binary = bindings::xmlSecKeyDataFormat_xmlSecKeyDataFormatBinary, - Pem = bindings::xmlSecKeyDataFormat_xmlSecKeyDataFormatPem, - Der = bindings::xmlSecKeyDataFormat_xmlSecKeyDataFormatDer, - Pkcs8Pem = bindings::xmlSecKeyDataFormat_xmlSecKeyDataFormatPkcs8Pem, - Pkcs8Der = bindings::xmlSecKeyDataFormat_xmlSecKeyDataFormatPkcs8Der, - Pkcs12 = bindings::xmlSecKeyDataFormat_xmlSecKeyDataFormatPkcs12, - CertPem = bindings::xmlSecKeyDataFormat_xmlSecKeyDataFormatCertPem, - CertDer = bindings::xmlSecKeyDataFormat_xmlSecKeyDataFormatCertDer, +pub enum XmlSecKeyFormat { + Unknown = bindings::xmlSecKeyDataFormat_xmlSecKeyDataFormatUnknown as u32, + Binary = bindings::xmlSecKeyDataFormat_xmlSecKeyDataFormatBinary as u32, + Pem = bindings::xmlSecKeyDataFormat_xmlSecKeyDataFormatPem as u32, + Der = bindings::xmlSecKeyDataFormat_xmlSecKeyDataFormatDer as u32, + Pkcs8Pem = bindings::xmlSecKeyDataFormat_xmlSecKeyDataFormatPkcs8Pem as u32, + Pkcs8Der = bindings::xmlSecKeyDataFormat_xmlSecKeyDataFormatPkcs8Der as u32, + Pkcs12 = bindings::xmlSecKeyDataFormat_xmlSecKeyDataFormatPkcs12 as u32, + CertPem = bindings::xmlSecKeyDataFormat_xmlSecKeyDataFormatCertPem as u32, + CertDer = bindings::xmlSecKeyDataFormat_xmlSecKeyDataFormatCertDer as u32, } - /// Key with which we sign/verify signatures or encrypt data. Used by [`XmlSecSignatureContext`][sigctx]. /// /// [sigctx]: struct.XmlSecSignatureContext.html #[derive(Debug)] pub struct XmlSecKey(*mut bindings::xmlSecKey); - -impl XmlSecKey -{ +impl XmlSecKey { /// Load key from file by specifying path, its format in the file, and optionally the password required to /// decrypt/unlock. - pub fn from_file(path: &str, format: XmlSecKeyFormat, password: Option<&str>) -> XmlSecResult - { + pub fn from_file( + path: &str, + format: XmlSecKeyFormat, + password: Option<&str>, + ) -> XmlSecResult { // TODO deprecate internals for Rust read-from-file and then loading with `from_memory` crate::xmlsec::guarantee_xmlsec_init(); // TODO proper sanitization/error handling of input - let cpath = CString::new(path).unwrap(); + let cpath = CString::new(path).unwrap(); let cpasswd = password.map(|p| CString::new(p).unwrap()); - let cpasswd_ptr = cpasswd.map(|cstr| cstr.as_ptr()) - .unwrap_or(null()); + let cpasswd_ptr = cpasswd.map(|cstr| cstr.as_ptr()).unwrap_or(null()); // Load key from file - let key = unsafe { bindings::xmlSecOpenSSLAppKeyLoad( - cpath.as_ptr(), - format as u32, - cpasswd_ptr, - null_mut(), - null_mut() - ) }; + let key = unsafe { + bindings::xmlSecOpenSSLAppKeyLoad( + cpath.as_ptr(), + format as bindings::xmlSecKeyDataFormat, + cpasswd_ptr, + null_mut(), + null_mut(), + ) + }; if key.is_null() { return Err(XmlSecError::KeyLoadError); @@ -74,25 +73,29 @@ impl XmlSecKey } /// Load key from buffer in memory, specifying format and optionally the password required to decrypt/unlock. - pub fn from_memory(buffer: &[u8], format: XmlSecKeyFormat, password: Option<&str>) -> XmlSecResult - { + pub fn from_memory( + buffer: &[u8], + format: XmlSecKeyFormat, + password: Option<&str>, + ) -> XmlSecResult { crate::xmlsec::guarantee_xmlsec_init(); // TODO proper sanitization/error handling of input let cpasswd = password.map(|p| CString::new(p).unwrap()); - let cpasswd_ptr = cpasswd.map(|cstr| cstr.as_ptr()) - .unwrap_or(null()); + let cpasswd_ptr = cpasswd.map(|cstr| cstr.as_ptr()).unwrap_or(null()); // Load key from buffer - let key = unsafe { bindings::xmlSecOpenSSLAppKeyLoadMemory( - buffer.as_ptr(), - buffer.len() as u32, - format as u32, - cpasswd_ptr, - null_mut(), - null_mut() - ) }; + let key = unsafe { + bindings::xmlSecOpenSSLAppKeyLoadMemory( + buffer.as_ptr(), + buffer.len() as u32, + format as bindings::xmlSecKeyDataFormat, + cpasswd_ptr, + null_mut(), + null_mut(), + ) + }; if key.is_null() { return Err(XmlSecError::KeyLoadError); @@ -102,11 +105,16 @@ impl XmlSecKey } /// Load certificate into key by specifying path and ints format. - pub fn load_cert_from_file(&self, path: &str, format: XmlSecKeyFormat) -> XmlSecResult<()> - { + pub fn load_cert_from_file(&self, path: &str, format: XmlSecKeyFormat) -> XmlSecResult<()> { let cpath = CString::new(path).unwrap(); - let rc = unsafe { bindings::xmlSecOpenSSLAppKeyCertLoad(self.0, cpath.as_ptr(), format as u32) }; + let rc = unsafe { + bindings::xmlSecOpenSSLAppKeyCertLoad( + self.0, + cpath.as_ptr(), + format as bindings::xmlSecKeyDataFormat, + ) + }; if rc != 0 { return Err(XmlSecError::CertLoadError); @@ -116,14 +124,13 @@ impl XmlSecKey } /// Load certificate into key by specifying buffer to its contents. - pub fn load_cert_from_memory(&self, buff: &[u8], format: XmlSecKeyFormat) -> XmlSecResult<()> - { + pub fn load_cert_from_memory(&self, buff: &[u8], format: XmlSecKeyFormat) -> XmlSecResult<()> { let rc = unsafe { bindings::xmlSecOpenSSLAppKeyCertLoadMemory( self.0, buff.as_ptr(), buff.len() as u32, - format as u32 + format as bindings::xmlSecKeyDataFormat, ) }; @@ -135,43 +142,36 @@ impl XmlSecKey } /// Set name of the key. - pub fn set_name(&mut self, name: &str) - { + pub fn set_name(&mut self, name: &str) { let cname = CString::new(name).unwrap(); - let rc = unsafe { bindings::xmlSecKeySetName( - self.0, - cname.as_ptr() as *const c_uchar - ) }; + let rc = unsafe { bindings::xmlSecKeySetName(self.0, cname.as_ptr() as *const c_uchar) }; if rc < 0 { - panic!("Failed to set name for key"); // TODO proper error handling + panic!("Failed to set name for key"); // TODO proper error handling } } /// Get the name currently set for the key. - pub fn get_name(&self) -> &str - { - let raw = unsafe { bindings::xmlSecKeyGetName(self.0) }; + pub fn get_name(&self) -> &str { + let raw = unsafe { bindings::xmlSecKeyGetName(self.0) }; let cname = unsafe { CStr::from_ptr(raw as *const c_char) }; - cname.to_str().unwrap() // TODO proper error handling + cname.to_str().unwrap() // TODO proper error handling } /// # Safety /// /// Create from raw pointer to an underlying xmlsec key structure. Henceforth its lifetime will be managed by this /// object. - pub unsafe fn from_ptr(ptr: *mut bindings::xmlSecKey) -> Self - { + pub unsafe fn from_ptr(ptr: *mut bindings::xmlSecKey) -> Self { Self(ptr) } /// # Safety /// /// Returns a raw pointer to the underlying xmlsec structure. - pub unsafe fn as_ptr(&self) -> *mut bindings::xmlSecKey - { + pub unsafe fn as_ptr(&self) -> *mut bindings::xmlSecKey { self.0 } @@ -182,8 +182,7 @@ impl XmlSecKey /// verification. /// /// [sigctx]: struct.XmlSecSignatureContext.html - pub unsafe fn leak(key: Self) -> *mut bindings::xmlSecKey - { + pub unsafe fn leak(key: Self) -> *mut bindings::xmlSecKey { let ptr = key.0; std::mem::forget(key); @@ -192,34 +191,24 @@ impl XmlSecKey } } - -impl PartialEq for XmlSecKey -{ - fn eq(&self, other: &Self) -> bool - { - self.0 == other.0 // compare pointer addresses +impl PartialEq for XmlSecKey { + fn eq(&self, other: &Self) -> bool { + self.0 == other.0 // compare pointer addresses } } - impl Eq for XmlSecKey {} - -impl Clone for XmlSecKey -{ - fn clone(&self) -> Self - { +impl Clone for XmlSecKey { + fn clone(&self) -> Self { let new = unsafe { bindings::xmlSecKeyDuplicate(self.0) }; Self(new) } } - -impl Drop for XmlSecKey -{ - fn drop(&mut self) - { +impl Drop for XmlSecKey { + fn drop(&mut self) { unsafe { bindings::xmlSecKeyDestroy(self.0) }; } } diff --git a/src/xmldsig.rs b/src/xmldsig.rs index 63feb43..53adadd 100644 --- a/src/xmldsig.rs +++ b/src/xmldsig.rs @@ -3,30 +3,25 @@ //! use crate::bindings; -use crate::XmlSecKey; use crate::XmlSecError; +use crate::XmlSecKey; use crate::XmlSecResult; -use crate::XmlNode; use crate::XmlDocument; +use crate::XmlNode; -use std::os::raw::c_uchar; use std::mem::forget; +use std::os::raw::c_uchar; use std::ptr::null_mut; - /// Signature signing/veryfying context -pub struct XmlSecSignatureContext -{ +pub struct XmlSecSignatureContext { ctx: *mut bindings::xmlSecDSigCtx, } - -impl XmlSecSignatureContext -{ +impl XmlSecSignatureContext { /// Builds a context, ensuring xmlsec is initialized. - pub fn new() -> Self - { + pub fn new() -> Self { crate::xmlsec::guarantee_xmlsec_init(); let ctx = unsafe { bindings::xmlSecDSigCtxCreate(null_mut()) }; @@ -35,17 +30,16 @@ impl XmlSecSignatureContext panic!("Failed to create dsig context"); } - Self {ctx} + Self { ctx } } /// Sets the key to use for signature or verification. In case a key had /// already been set, the latter one gets released in the optional return. - pub fn insert_key(&mut self, key: XmlSecKey) -> Option - { + pub fn insert_key(&mut self, key: XmlSecKey) -> Option { let mut old = None; unsafe { - if ! (*self.ctx).signKey.is_null() { + if !(*self.ctx).signKey.is_null() { old = Some(XmlSecKey::from_ptr((*self.ctx).signKey)); } @@ -56,8 +50,7 @@ impl XmlSecSignatureContext } /// Releases a currently set key returning `Some(key)` or None otherwise. - pub fn release_key(&mut self) -> Option - { + pub fn release_key(&mut self) -> Option { unsafe { if (*self.ctx).signKey.is_null() { None @@ -72,8 +65,7 @@ impl XmlSecSignatureContext } /// UNTESTED - pub fn sign_node(&self, node: &XmlNode) -> XmlSecResult<()> - { + pub fn sign_node(&self, node: &XmlNode) -> XmlSecResult<()> { self.key_is_set()?; let node = node.node_ptr() as bindings::xmlNodePtr; @@ -90,19 +82,17 @@ impl XmlSecSignatureContext /// /// [xmldoc]: http://kwarc.github.io/rust-libxml/libxml/tree/document/struct.Document.html /// [inskey]: struct.XmlSecSignatureContext.html#method.insert_key - pub fn sign_document(&self, doc: &XmlDocument) -> XmlSecResult<()> - { + pub fn sign_document(&self, doc: &XmlDocument) -> XmlSecResult<()> { self.key_is_set()?; let root = find_root(doc)?; - let sig = find_signode(root)?; + let sig = find_signode(root)?; self.sign_node_raw(sig) } /// UNTESTED - pub fn verify_node(&self, node: &XmlNode) -> XmlSecResult - { + pub fn verify_node(&self, node: &XmlNode) -> XmlSecResult { self.key_is_set()?; let node = node.node_ptr() as bindings::xmlNodePtr; @@ -120,12 +110,11 @@ impl XmlSecSignatureContext /// /// [xmldoc]: http://kwarc.github.io/rust-libxml/libxml/tree/document/struct.Document.html /// [inskey]: struct.XmlSecSignatureContext.html#method.insert_key - pub fn verify_document(&self, doc: &XmlDocument) -> XmlSecResult - { + pub fn verify_document(&self, doc: &XmlDocument) -> XmlSecResult { self.key_is_set()?; let root = find_root(doc)?; - let sig = find_signode(root)?; + let sig = find_signode(root)?; self.verify_node_raw(sig) } @@ -134,8 +123,7 @@ impl XmlSecSignatureContext /// /// Returns a raw pointer to the underlying xmlsec signature context. Beware that it is still managed by this /// wrapping object and will be deallocated once `self` gets dropped. - pub unsafe fn as_ptr(&self) -> *mut bindings::xmlSecDSigCtx - { + pub unsafe fn as_ptr(&self) -> *mut bindings::xmlSecDSigCtx { self.ctx } @@ -143,23 +131,19 @@ impl XmlSecSignatureContext /// /// Returns a raw pointer to the underlying xmlsec signature context. Beware that it will be forgotten by this /// wrapping object and *must* be deallocated manually by the callee. - pub unsafe fn into_ptr(self) -> *mut bindings::xmlSecDSigCtx - { - let ctx = self.ctx; // keep a copy of the pointer + pub unsafe fn into_ptr(self) -> *mut bindings::xmlSecDSigCtx { + let ctx = self.ctx; // keep a copy of the pointer - forget(self); // release our copy of the pointer without deallocating it + forget(self); // release our copy of the pointer without deallocating it - ctx // return the only remaining copy + ctx // return the only remaining copy } } - -impl XmlSecSignatureContext -{ - fn key_is_set(&self) -> XmlSecResult<()> - { +impl XmlSecSignatureContext { + fn key_is_set(&self) -> XmlSecResult<()> { unsafe { - if ! (*self.ctx).signKey.is_null() { + if !(*self.ctx).signKey.is_null() { Ok(()) } else { Err(XmlSecError::KeyNotLoaded) @@ -167,8 +151,7 @@ impl XmlSecSignatureContext } } - fn sign_node_raw(&self, node: *mut bindings::xmlNode) -> XmlSecResult<()> - { + fn sign_node_raw(&self, node: *mut bindings::xmlNode) -> XmlSecResult<()> { let rc = unsafe { bindings::xmlSecDSigCtxSign(self.ctx, node) }; if rc < 0 { @@ -178,56 +161,47 @@ impl XmlSecSignatureContext } } - fn verify_node_raw(&self, node: *mut bindings::xmlNode) -> XmlSecResult - { + fn verify_node_raw(&self, node: *mut bindings::xmlNode) -> XmlSecResult { let rc = unsafe { bindings::xmlSecDSigCtxVerify(self.ctx, node) }; if rc < 0 { return Err(XmlSecError::VerifyError); } - match unsafe { (*self.ctx).status } - { - bindings::xmlSecDSigStatus_xmlSecDSigStatusUnknown => Ok(false), + match unsafe { (*self.ctx).status } { + bindings::xmlSecDSigStatus_xmlSecDSigStatusUnknown => Ok(false), bindings::xmlSecDSigStatus_xmlSecDSigStatusSucceeded => Ok(true), - bindings::xmlSecDSigStatus_xmlSecDSigStatusInvalid => Ok(false), + bindings::xmlSecDSigStatus_xmlSecDSigStatusInvalid => Ok(false), - _ => panic!("Failed to interprete xmlSecDSigStatus code") + _ => panic!("Failed to interprete xmlSecDSigStatus code"), } } } - -impl Drop for XmlSecSignatureContext -{ - fn drop(&mut self) - { +impl Drop for XmlSecSignatureContext { + fn drop(&mut self) { unsafe { bindings::xmlSecDSigCtxDestroy(self.ctx) }; } } - -fn find_root(doc: &XmlDocument) -> XmlSecResult<*mut bindings::xmlNode> -{ - if let Some(root) = doc.get_root_element() - { +fn find_root(doc: &XmlDocument) -> XmlSecResult<*mut bindings::xmlNode> { + if let Some(root) = doc.get_root_element() { let rawroot = root.node_ptr() as *mut bindings::xmlNode; - let signode = find_signode(rawroot)?; - Ok(signode) + Ok(rawroot) } else { Err(XmlSecError::RootNotFound) } } - -fn find_signode(tree: *mut bindings::xmlNode) -> XmlSecResult<*mut bindings::xmlNode> -{ - let signode = unsafe {bindings::xmlSecFindNode( - tree, - &bindings::xmlSecNodeSignature as *const c_uchar, - &bindings::xmlSecDSigNs as *const c_uchar, - ) }; +fn find_signode(tree: *mut bindings::xmlNode) -> XmlSecResult<*mut bindings::xmlNode> { + let signode = unsafe { + bindings::xmlSecFindNode( + tree, + &bindings::xmlSecNodeSignature as *const c_uchar, + &bindings::xmlSecDSigNs as *const c_uchar, + ) + }; if signode.is_null() { return Err(XmlSecError::NodeNotFound); diff --git a/vcpkg.json b/vcpkg.json new file mode 100644 index 0000000..58429ef --- /dev/null +++ b/vcpkg.json @@ -0,0 +1,10 @@ +{ + "builtin-baseline": "1faad557cd7435901d7eac7b0b7f38e3e865701c", + "dependencies": ["libxslt", "xmlsec"], + "overrides": [ + { + "name": "xmlsec", + "version": "1.2.37" + } + ] +}