impl PublicKey { /// Get the HPKE serialization of the public key. /// /// # Errors /// /// When the key cannot be exported, which can be because the type is not supported. /// /// # Panics /// /// When keys are too large to fit in `c_uint/usize`. So only on programming error. pubfn key_data(&self) -> Res<Vec<u8>> { letmut buf = vec![0; 100]; letmut len: c_uint = 0;
secstatus_to_res(unsafe {
PK11_HPKE_Serialize(
**self,
buf.as_mut_ptr(),
&mut len,
c_uint::try_from(buf.len())?,
)
})?;
buf.truncate(usize::try_from(len)?);
Ok(buf)
}
}
impl PrivateKey { /// Get the bits of the private key. /// /// # Errors /// /// When the key cannot be exported, which can be because the type is not supported /// or because the key data cannot be extracted from the PKCS#11 module. /// /// # Panics /// /// When the values are too large to fit. So never. pubfn key_data(&self) -> Res<Vec<u8>> { letmut key_item = Item::make_empty();
secstatus_to_res(unsafe {
PK11_ReadRawAttribute(
PK11ObjectType::PK11_TypePrivKey,
(**self).cast(),
CK_ATTRIBUTE_TYPE::from(CKA_VALUE),
&mut key_item,
)
})?; let slc = unsafe { null_safe_slice(key_item.data, key_item.len) }; let key = Vec::from(slc); // The data that `key_item` refers to needs to be freed, but we can't // use the scoped `Item` implementation. This is OK as long as nothing // panics between `PK11_ReadRawAttribute` succeeding and here. unsafe {
SECITEM_FreeItem(&mut key_item, PRBool::from(false));
}
Ok(key)
}
} unsafeimpl Send for PrivateKey {}
impl Slot { pubfn internal() -> Res<Self> { let p = unsafe { PK11_GetInternalSlot() }; Self::from_ptr(p)
}
}
scoped_ptr!(SymKey, PK11SymKey, PK11_FreeSymKey);
impl SymKey { /// You really don't want to use this. /// /// # Errors /// /// Internal errors in case of failures in NSS. pubfn as_bytes(&self) -> Res<&[u8]> {
secstatus_to_res(unsafe { PK11_ExtractKeyValue(self.ptr) })?;
let key_item = unsafe { PK11_GetKeyData(self.ptr) }; // This is accessing a value attached to the key, so we can treat this as a borrow. matchunsafe { key_item.as_mut() } {
None => Err(Error::InternalError),
Some(key) => Ok(unsafe { null_safe_slice(key.data, key.len) }),
}
}
}
impl Item { /// Create a wrapper for a slice of this object. /// Creating this object is technically safe, but using it is extremely dangerous. /// Minimally, it can only be passed as a `const SECItem*` argument to functions, /// or those that treat their argument as `const`. pubfn wrap(buf: &[u8]) -> SECItem {
SECItem {
type_: SECItemType::siBuffer,
data: buf.as_ptr().cast_mut(),
len: c_uint::try_from(buf.len()).unwrap(),
}
}
/// Create a wrapper for a struct. /// Creating this object is technically safe, but using it is extremely dangerous. /// Minimally, it can only be passed as a `const SECItem*` argument to functions, /// or those that treat their argument as `const`. pubfn wrap_struct<T>(v: &T) -> SECItem { let data: *const T = v;
SECItem {
type_: SECItemType::siBuffer,
data: data.cast_mut().cast(),
len: c_uint::try_from(mem::size_of::<T>()).unwrap(),
}
}
/// Make an empty `SECItem` for passing as a mutable `SECItem*` argument. pubconstfn make_empty() -> SECItem {
SECItem {
type_: SECItemType::siBuffer,
data: null_mut(),
len: 0,
}
}
/// This dereferences the pointer held by the item and makes a copy of the /// content that is referenced there. /// /// # Safety /// /// This dereferences two pointers. It doesn't get much less safe. pubunsafefn into_vec(self) -> Vec<u8> { let b = self.ptr.as_ref().unwrap(); // Sanity check the type, as some types don't count bytes in `Item::len`.
assert_eq!(b.type_, SECItemType::siBuffer); let slc = null_safe_slice(b.data, b.len);
Vec::from(slc)
}
}
#[cfg(feature = "disable-random")] /// Fill a buffer with a predictable sequence of bytes. pubfn randomize<B: AsMut<[u8]>>(mut buf: B) -> B { let m_buf = buf.as_mut(); for v in m_buf.iter_mut() {
*v = CURRENT_VALUE.get();
CURRENT_VALUE.set(v.wrapping_add(1));
}
buf
}
/// Fill a buffer with randomness. /// /// # Panics /// /// When `size` is too large or NSS fails. #[cfg(not(feature = "disable-random"))] pubfn randomize<B: AsMut<[u8]>>(mut buf: B) -> B { let m_buf = buf.as_mut(); let len = std::os::raw::c_int::try_from(m_buf.len()).unwrap();
secstatus_to_res(unsafe { PK11_GenerateRandom(m_buf.as_mut_ptr(), len) }).unwrap();
buf
}
fixture_init(); // If any of these ever fail, there is either a bug, or it's time to buy a lottery ticket.
assert_ne!(random::<16>(), randomize([0; 16]));
assert_ne!([0; 16], random::<16>());
assert_ne!([0; 64], random::<64>());
}
for _ in0..100 { let len = loop { let len = usize::from(random::<1>()[0] & mask) + 1; if len <= RandomCache::CUTOFF { break len;
}
};
buf.fill(0); if len >= 16 {
assert_ne!(&cache.randomize(&mut buf[..len])[..len], &ZERO[..len]);
}
}
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.15 Sekunden
(vorverarbeitet am 2026-06-18)
¤
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.