Searches are templates, not uniqueness guarantees. This recipe selects private
RSA objects with an exact CKA_ID. Set AttributeTemplateLimits for three
attributes, their scalar storage and ID bytes; choose a nonzero batch size and
the application’s result bound. maximum_objects: None chooses an unbounded
result count, subject to configured object resources.
use fe11::*;
use std::num::NonZeroUsize;
pub fn find_private_rsa(
session: &Session, id: &[u8], batch_size: NonZeroUsize,
maximum_objects: Option<usize>, template_limits: AttributeTemplateLimits,
) -> Result<NativeObjectMatches> {
let template = [
AttributeInput {
attribute: AttributeType::Standard(StandardAttribute::CLASS),
value: AttributeInputValue::Unsigned(fe11_sys::CKO_PRIVATE_KEY as u64),
},
AttributeInput {
attribute: AttributeType::Standard(StandardAttribute::KEY_TYPE),
value: AttributeInputValue::Unsigned(fe11_sys::CKK_RSA as u64),
},
AttributeInput {
attribute: AttributeType::Standard(StandardAttribute::ID),
value: AttributeInputValue::Bytes(id),
},
];
session.find_native_objects(
&template,
template_limits,
SearchPlan { maximum_objects, batch_size },
)
}Inspect matches.as_slice(). If the application requires a unique key, accept
exactly one match and report zero or multiple matches as an application selection
error. Retain that NativeObjectRef for the operation. To verify, search for the
corresponding public RSA object by using CKO_PUBLIC_KEY in an otherwise explicit
template. Authenticate the public key’s association through your application.
use fe11::*;
pub fn generate_rsa(
session: &Session, mut spec: KeySpec,
) -> Result<CreatedObjects<KeyPair>> {
spec.public_usages.verify = Some(true);
spec.private_usages.sign = Some(true);
session.generate_rsa_signing_key_pair(spec)
}Construct KeySpec with the desired bits, exponent,
id, label, persistence, visibility, private protection and separate public and
private observation plans. For example, an application’s selected RSA-3072 key
uses bits: 3072 and exponent: 65537. These are application choices, not library
defaults. Start usage requests from KeyUsageRequest::omitted() and set the
requested flags; this helper adds public verification and private signing.
ObjectVisibility controls CKA_PRIVATE, independently of public/private key
class. Set CurrentKeyProtection to the desired sensitive/extractable attributes.
ObjectAdmission selects searches and observations after creation; provision its
read capacities for the public representation and requested attributes. See
ObjectAdmission for all observation fields.
Treat CreatedObjects<KeyPair> as a creation outcome: native objects can exist
even when a requested observation fails. Preserve objects, observation and
remainder. into_observation() returns a failure retaining the created objects;
do not regenerate a key merely because its metadata observation failed. The
generated pair’s ObjectRef::native_object() gives the native-operation reference.
use fe11::*;
pub fn sign_message(
session: &Session, key: &NativeObjectRef, message: &[u8],
limits: InputLimits, signature_capacity: usize,
) -> Result<NativeSignature> {
session.sign_native(
key,
NativeSignatureParameters::Parameterless(NativeSignatureAlgorithm::SHA256_RSA_PKCS),
MessageRoute::Single,
&[message],
limits,
signature_capacity,
None,
)
}
pub fn verify_message(
session: &Session, key: &NativeObjectRef, message: &[u8],
signature: &[u8], limits: InputLimits,
) -> Result<()> {
session.verify_native(
key,
NativeSignatureParameters::Parameterless(NativeSignatureAlgorithm::SHA256_RSA_PKCS),
MessageRoute::Single,
&[message],
signature,
limits,
None,
)
}The combined SHA256_RSA_PKCS mechanism hashes the original message at the
module. Supply the message, not an external digest. Select signature_capacity
from the chosen key’s modulus width (384 bytes for RSA-3072). Handle a reported
capacity requirement using its retained continuation, rather than starting an
unrelated second operation. These helpers select a single-part route and no
contextual authentication; use the explicit authentication argument when the key
requires it.
NativeSignature::as_bytes() borrows the result. verify_native returns Ok(())
for a successful native verification and an error for a native refusal. Preserve
that native code. Destroy persistent objects explicitly when retiring them;
dropping a Rust reference alone does not destroy a token object.