/* This Source Code Form is subject to the terms of the Mozilla Public *License,v.2.0.IfacopyoftheMPLwasnotdistributedwiththis
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use pkcs11_bindings::*; use rsclientcerts::cryptoki::*; use rsclientcerts::manager::{ClientCertsBackend, CryptokiObject, Sign}; use rsclientcerts_util::error::{Error, ErrorType}; use rsclientcerts_util::*; use std::ffi::c_void;
// Wrapper of C DoFindObject function implemented in nsNSSIOLayer.h fn DoFindObjectsWrapper(callback: FindObjectsCallback, ctx: &mut FindObjectsContext) { // The function makes the parent process to find certificates and keys and send identifying // information about them over IPC. extern"C" { fn DoFindObjects(callback: FindObjectsCallback, ctx: *mut c_void);
}
unsafe {
DoFindObjects(callback, ctx as *mut _ as *mut c_void);
}
}
// Wrapper of C DoSign function implemented in nsNSSIOLayer.h fn DoSignWrapper(
cert_len: usize,
cert: *const u8,
data_len: usize,
data: *const u8,
params_len: usize,
params: *const u8,
callback: SignCallback,
ctx: &mut Vec<u8>,
) { // The function makes the parent to sign the given data using the key corresponding to the // given certificate, using the given parameters. extern"C" { fn DoSign(
cert_len: usize,
cert: *const u8,
data_len: usize,
data: *const u8,
params_len: usize,
params: *const u8,
callback: SignCallback,
ctx: *mut c_void,
);
}
unsafe {
DoSign(
cert_len,
cert,
data_len,
data,
params_len,
params,
callback,
ctx as *mut _ as *mut c_void,
);
}
}
impl Sign for Key { fn get_signature_length(
&mutself,
data: &[u8],
params: &Option<CK_RSA_PKCS_PSS_PARAMS>,
) -> Result<usize, Error> { // Unfortunately we don't have a way of getting the length of a signature without creating // one. let dummy_signature_bytes = self.sign(data, params)?;
Ok(dummy_signature_bytes.len())
}
fn sign(
&mutself,
data: &[u8],
params: &Option<CK_RSA_PKCS_PSS_PARAMS>,
) -> Result<Vec<u8>, Error> { letmut signature = Vec::new(); let (sign_params_len, sign_params) = match params {
Some(params) => (
std::mem::size_of::<CK_RSA_PKCS_PSS_PARAMS>(),
params as *const _ as *const u8,
),
None => (0, std::ptr::null()),
};
DoSignWrapper( self.cert.len(), self.cert.as_ptr(),
data.len(),
data.as_ptr(),
sign_params_len,
sign_params,
Some(sign_callback),
&mut signature,
); // If this succeeded, return the result. if signature.len() > 0 { return Ok(signature);
} // If signing failed and this is an RSA-PSS signature, perhaps the token the key is on does // not support RSA-PSS. In that case, emsa-pss-encode the data (hash, really) and try // signing with raw RSA. let Some(params) = params.as_ref() else { return Err(error_here!(ErrorType::LibraryFailure));
}; // `params` should only be `Some` if this is an RSA key. let Some(modulus) = self.cryptoki_key.modulus().as_ref() else { return Err(error_here!(ErrorType::LibraryFailure));
}; let emsa_pss_encoded = emsa_pss_encode(data, modulus_bit_length(modulus) - 1, params)?;
DoSignWrapper( self.cert.len(), self.cert.as_ptr(),
emsa_pss_encoded.len(),
emsa_pss_encoded.as_ptr(), 0,
std::ptr::null(),
Some(sign_callback),
&mut signature,
); if signature.len() > 0 {
Ok(signature)
} else {
Err(error_here!(ErrorType::LibraryFailure))
}
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.