Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
770 changes: 670 additions & 100 deletions Cargo.lock

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
[workspace]
resolver = "2"
members = [
"native-pkcs11",
"native-pkcs11-core",
"native-pkcs11-traits",
"native-pkcs11-keychain",
"pkcs11-sys",
"native-pkcs11-traits",
"native-pkcs11-windows",
"native-pkcs11",
"pkcs11-sys",
]

[workspace.package]
Expand Down
19 changes: 19 additions & 0 deletions native-pkcs11-fake/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[package]
name = "native-pkcs11-fake"
version = "0.1.0"
authors.workspace = true
edition.workspace = true
rust-version.workspace = true
repository.workspace = true
license.workspace = true

[lib]
crate-type = ["cdylib"]


[dependencies]
native-pkcs11 = { path = "../native-pkcs11", features = [
"custom-function-list",
] }
native-pkcs11-traits = { path = "../native-pkcs11-traits" }
test-cdylib = "1.1.0"
64 changes: 64 additions & 0 deletions native-pkcs11-fake/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
use std::ptr::addr_of_mut;

use native_pkcs11::{CKR_OK, CK_FUNCTION_LIST_PTR_PTR, CK_RV, FUNC_LIST};
use native_pkcs11_traits::{register_backend, Backend};

#[allow(non_snake_case)]
#[no_mangle]
#[allow(clippy::missing_safety_doc)]
pub unsafe extern "C" fn C_GetFunctionList(ppFunctionList: CK_FUNCTION_LIST_PTR_PTR) -> CK_RV {
register_backend(Box::new(FakeBackend {}));
unsafe { *ppFunctionList = addr_of_mut!(FUNC_LIST) };
CKR_OK
}

struct FakeBackend {}

impl Backend for FakeBackend {
fn name(&self) -> String {
todo!()
}

fn find_all_certificates(
&self,
) -> native_pkcs11_traits::Result<Vec<Box<dyn native_pkcs11_traits::Certificate>>> {
todo!()
}

fn find_private_key(
&self,
_query: native_pkcs11_traits::KeySearchOptions,
) -> native_pkcs11_traits::Result<Option<std::sync::Arc<dyn native_pkcs11_traits::PrivateKey>>>
{
todo!()
}

fn find_public_key(
&self,
_query: native_pkcs11_traits::KeySearchOptions,
) -> native_pkcs11_traits::Result<Option<Box<dyn native_pkcs11_traits::PublicKey>>> {
todo!()
}

fn find_all_private_keys(
&self,
) -> native_pkcs11_traits::Result<Vec<std::sync::Arc<dyn native_pkcs11_traits::PrivateKey>>>
{
todo!()
}

fn find_all_public_keys(
&self,
) -> native_pkcs11_traits::Result<Vec<std::sync::Arc<dyn native_pkcs11_traits::PublicKey>>>
{
todo!()
}

fn generate_key(
&self,
_algorithm: native_pkcs11_traits::KeyAlgorithm,
_label: Option<&str>,
) -> native_pkcs11_traits::Result<std::sync::Arc<dyn native_pkcs11_traits::PrivateKey>> {
todo!()
}
}
8 changes: 7 additions & 1 deletion native-pkcs11/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ license.workspace = true

[features]
custom-function-list = []
fake-backend = ["custom-function-list"]

[dependencies]
cached = { version = "~0.55", default-features = false }
Expand All @@ -21,12 +22,17 @@ tracing = "0.1.41"
tracing-error = "0.2.1"
tracing-journald = "0.3"
tracing-subscriber = { version = "0.3.19", features = ["env-filter"] }
# TODO only for fake-backend feature
p256 = "0.13.2"
rsa = "0.9.7"

[lib]
crate-type = ["lib", "cdylib"]
crate-type = ["cdylib", "lib"]

[dev-dependencies]
goldenfile = "1.8.0"
serial_test = { version = "3.2.0", default-features = false }
test-cdylib = "1.1.0"
tracing = { version = "0.1.41", default-features = false }
tracing-subscriber = { version = "0.3.19", default-features = false, features = [
"env-filter",
Expand Down
158 changes: 158 additions & 0 deletions native-pkcs11/src/fake_backend.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
use std::{ptr::addr_of_mut, sync::Arc};

use native_pkcs11_traits::{Backend, KeyAlgorithm, register_backend};
use p256::{ecdsa::SigningKey, elliptic_curve::rand_core::OsRng};
use rsa::RsaPrivateKey;

use crate::{CK_FUNCTION_LIST_PTR_PTR, CK_RV, CKR_OK, FUNC_LIST};

#[allow(non_snake_case)]
#[unsafe(no_mangle)]
#[allow(clippy::missing_safety_doc)]
pub unsafe extern "C" fn C_GetFunctionList(ppFunctionList: CK_FUNCTION_LIST_PTR_PTR) -> CK_RV {
register_backend(Box::new(FakeBackend {}));
unsafe { *ppFunctionList = addr_of_mut!(FUNC_LIST) };
CKR_OK
}

struct FakeBackend {}

impl Backend for FakeBackend {
fn name(&self) -> String {
"native-pkcs11 fake backend".to_string()
}

fn find_all_certificates(
&self,
) -> native_pkcs11_traits::Result<Vec<Box<dyn native_pkcs11_traits::Certificate>>> {
Ok(vec![])
}

fn find_private_key(
&self,
query: native_pkcs11_traits::KeySearchOptions,
) -> native_pkcs11_traits::Result<Option<std::sync::Arc<dyn native_pkcs11_traits::PrivateKey>>>
{
match query {
native_pkcs11_traits::KeySearchOptions::Label(label) => {
Ok(Some(Arc::new(PrivateKey::new(&label, KeyAlgorithm::Ecc))))
}
native_pkcs11_traits::KeySearchOptions::PublicKeyHash(_) => {
Ok(Some(Arc::new(PrivateKey::new("TODO", KeyAlgorithm::Ecc))))
}
}
}

fn find_public_key(
&self,
query: native_pkcs11_traits::KeySearchOptions,
) -> native_pkcs11_traits::Result<Option<Box<dyn native_pkcs11_traits::PublicKey>>> {
match query {
native_pkcs11_traits::KeySearchOptions::Label(_) => todo!(),
native_pkcs11_traits::KeySearchOptions::PublicKeyHash(_) => {
Ok(Some(Box::new(PrivateKey::new("TODO", KeyAlgorithm::Ecc))))
}
}
}

fn find_all_private_keys(
&self,
) -> native_pkcs11_traits::Result<Vec<std::sync::Arc<dyn native_pkcs11_traits::PrivateKey>>>
{
Ok(vec![])
}

fn find_all_public_keys(
&self,
) -> native_pkcs11_traits::Result<Vec<std::sync::Arc<dyn native_pkcs11_traits::PublicKey>>>
{
todo!()
}

fn generate_key(
&self,
algorithm: native_pkcs11_traits::KeyAlgorithm,
_label: Option<&str>,
) -> native_pkcs11_traits::Result<std::sync::Arc<dyn native_pkcs11_traits::PrivateKey>> {
let key = Arc::new(PrivateKey::new("TODO", algorithm));
Ok(key)
}
}

#[allow(clippy::large_enum_variant)]
#[allow(dead_code)]
#[derive(Debug)]
enum PrivateKey {
Ecc(String, SigningKey),
Rsa(String, RsaPrivateKey),
}

impl PrivateKey {
fn new(label: &str, algorithm: KeyAlgorithm) -> Self {
match algorithm {
KeyAlgorithm::Rsa => {
Self::Rsa(label.to_owned(), RsaPrivateKey::new(&mut OsRng, 2048).unwrap())
}
KeyAlgorithm::Ecc => Self::Ecc(label.to_owned(), SigningKey::random(&mut OsRng)),
}
}
}

impl native_pkcs11_traits::PrivateKey for PrivateKey {
fn public_key_hash(&self) -> Vec<u8> {
vec![0; 20]
}

fn label(&self) -> String {
match self {
Self::Ecc(label, _) => label.clone(),
Self::Rsa(label, _) => label.clone(),
}
}

fn sign(
&self,
_algorithm: &native_pkcs11_traits::SignatureAlgorithm,
_data: &[u8],
) -> native_pkcs11_traits::Result<Vec<u8>> {
todo!()
}

fn delete(&self) {}

fn algorithm(&self) -> native_pkcs11_traits::KeyAlgorithm {
match self {
Self::Ecc(..) => KeyAlgorithm::Ecc,
Self::Rsa(..) => KeyAlgorithm::Rsa,
}
}
}

impl native_pkcs11_traits::PublicKey for PrivateKey {
fn public_key_hash(&self) -> Vec<u8> {
todo!()
}

fn label(&self) -> String {
todo!()
}

fn to_der(&self) -> Vec<u8> {
todo!()
}

fn verify(
&self,
_algorithm: &native_pkcs11_traits::SignatureAlgorithm,
_data: &[u8],
_signature: &[u8],
) -> native_pkcs11_traits::Result<()> {
todo!()
}

fn delete(self: Box<Self>) {}

fn algorithm(&self) -> KeyAlgorithm {
todo!()
}
}
20 changes: 11 additions & 9 deletions native-pkcs11/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,6 @@
#![allow(clippy::missing_safety_doc)]
#![deny(unsafe_op_in_unsafe_fn)]

pub use native_pkcs11_core::Error;
use native_pkcs11_traits::backend;
use tracing::metadata::LevelFilter;
use tracing_error::ErrorLayer;
use tracing_subscriber::{EnvFilter, Registry, fmt::format::FmtSpan, prelude::*};
mod object_store;
mod sessions;
mod utils;

use std::{
cmp,
slice,
Expand All @@ -34,18 +25,29 @@ use std::{
},
};

pub use native_pkcs11_core::Error;
use native_pkcs11_core::{
attribute::{Attribute, Attributes},
mechanism::{SUPPORTED_SIGNATURE_MECHANISMS, parse_mechanism},
object::{self, Object},
};
use native_pkcs11_traits::backend;
use pkcs11_sys::*;
use tracing::metadata::LevelFilter;
use tracing_error::ErrorLayer;
use tracing_subscriber::{EnvFilter, Registry, fmt::format::FmtSpan, prelude::*};

use crate::{
sessions::{FindContext, SignContext},
utils::right_pad_string_to_array,
};

#[cfg(feature = "fake-backend")]
mod fake_backend;
mod object_store;
mod sessions;
mod utils;

const LIBRARY_DESCRIPTION: &[u8; 32] = b" ";
const MANUFACTURER_ID: &[u8; 32] = b"google ";
const SLOT_DESCRIPTION: &[u8; 64] =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Interfaces are supported only in PKCS #11 3.0 and newer
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Using slot 0 with a present token (0x1)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Supported mechanisms:
RSA-PKCS, sign
SHA1-RSA-PKCS, sign
SHA256-RSA-PKCS, sign
SHA384-RSA-PKCS, sign
SHA512-RSA-PKCS, sign
ECDSA, sign
RSA-PKCS-PSS, sign
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Using slot 0 with a present token (0x1)
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Profile object 1
profile_id: CKP_BASELINE_PROVIDER (1)
Empty file.
11 changes: 11 additions & 0 deletions native-pkcs11/tests/goldens/pkcs11-tool/list_slots.stdout.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Available slots:
Slot 0 (0x1): Platform Cryptography Support
token label : native-pkcs11 fake backend
token manufacturer : google
token model : software
token flags : PIN pad present, token initialized, readonly
hardware version : 0.0
firmware version : 0.0
serial num : 0000000000000000
pin min/max : 0/0
uri : pkcs11:model=software;manufacturer=google;serial=0000000000000000;token=native-pkcs11%20fake%20backend
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Available slots:
Slot 0 (0x1): Platform Cryptography Support
token label : native-pkcs11 fake backend
token manufacturer : google
token model : software
token flags : PIN pad present, token initialized, readonly
hardware version : 0.0
firmware version : 0.0
serial num : 0000000000000000
pin min/max : 0/0
uri : pkcs11:model=software;manufacturer=google;serial=0000000000000000;token=native-pkcs11%20fake%20backend
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Using slot 0 with a present token (0x1)
3 changes: 3 additions & 0 deletions native-pkcs11/tests/goldens/pkcs11-tool/show_info.stdout.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Cryptoki version 3.1
Manufacturer google
Library (ver 0.1)
Loading
Loading