Skip to content

Commit

Permalink
Refactor Storage Layer
Browse files Browse the repository at this point in the history
This splits out the storage spefcific knowledge from the token
to the actual storage backend.

The storage backend is restructured so that multiple storage types can
use a common information organizational schema for non standardized
objects like user pins and token info and non standardized
authenticationand encryption layers for the actual data.

This is in preparation for adding code to read databases written by
other software tokens that follow different storage philosophies.

While woring on this refactoring a few minor issues with how pin/login
were handled was found and have been fixed.

Additionally the code now uses a common Key encryption Key that both the
Ueer and SO Pins can unlock allowing recovery of the database via SO
pin if the user pin is lost. This means the SO pin needs to be set to a
non-default value on initialization to maintain the confidentaility of
the token.
It can be set to a random value if recovery is never desired.

Signed-off-by: Simo Sorce <[email protected]>
  • Loading branch information
simo5 committed Oct 29, 2024
1 parent 8f23768 commit dabafcb
Show file tree
Hide file tree
Showing 16 changed files with 1,630 additions and 1,166 deletions.
2 changes: 1 addition & 1 deletion .github/codespell.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/bash

CODESPELL="codespell --ignore-words-list=gost,sorce,clen,ot,crate"
CODESPELL="codespell --ignore-words-list=gost,sorce,clen,ot,crate,aci"

result=0
echo "Running codespell on source code..."
Expand Down
14 changes: 10 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ pkg-config = "0.3"

[dependencies]
asn1 = "0.16.2"
bimap = "0.6.3"
bitflags = "2.4.1"
cfg-if = "1.0.0"
constant_time_eq = "0.3.0"
Expand All @@ -37,7 +38,7 @@ num-integer = "0.1.45"
num-traits = "0.2.17"
once_cell = "1.18.0"
paste = "1.0.15"
rusqlite = "0.31.0"
rusqlite = { version = "0.31.0", optional = true }
serde = { version = "1.0.180", features = ["derive"] }
serde_json = "1.0.104"
serial_test = "3.1.1"
Expand All @@ -58,10 +59,15 @@ sp800_108 = []
sshkdf = []
tlskdf = []

# tese are always required, so easier to specify this way
basic = [ "aes", "hmac", "pbkdf2" ]
# Databases
jsondb = ["memorydb"]
memorydb = []
sqlitedb = ["dep:rusqlite"]

#select everythign by default
# these are always required, so easier to specify this way
basic = [ "aes", "hmac", "pbkdf2", "sqlitedb", "jsondb" ]

#select everything by default
# Use --no-default-features --features basic, xxx for custom selections
default = [ "basic", "ecc", "eddsa", "hash", "hkdf", "rsa", "sp800_108", "sshkdf", "tlskdf"]

Expand Down
2 changes: 1 addition & 1 deletion src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ impl Config {
* the more common one of specifying a .sql file with no
* slot specification. */
if name.ends_with(".sql") {
match storage::name_to_type(name) {
match storage::suffix_to_type(name) {
Ok(typ_) => {
let mut slot = Slot::new();
slot.dbtype = Some(typ_.to_string());
Expand Down
30 changes: 24 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,7 @@ extern "C" fn fn_init_token(
if res_or_ret!(rstate.has_sessions(slot_id)) {
return CKR_SESSION_EXISTS;
}
let vpin: Vec<u8> = bytes_to_vec!(pin, pin_len);
let vpin = bytes_to_slice!(pin, pin_len, u8);
let vlabel: Vec<u8> = if label.is_null() {
vec![0x20u8; 32]
} else {
Expand Down Expand Up @@ -565,7 +565,7 @@ extern "C" fn fn_init_pin(
return CKR_USER_NOT_LOGGED_IN;
}

let vpin: Vec<u8> = bytes_to_vec!(pin, pin_len);
let vpin = bytes_to_slice!(pin, pin_len, u8);

ret_to_rv!(token.set_pin(CKU_USER, &vpin, &vec![0u8; 0]))
}
Expand All @@ -581,12 +581,30 @@ extern "C" fn fn_set_pin(
if !session.is_writable() {
return CKR_SESSION_READ_ONLY;
}
let vpin: Vec<u8> = bytes_to_vec!(new_pin, new_len);
let vold: Vec<u8> = bytes_to_vec!(old_pin, old_len);
let vpin = bytes_to_slice!(new_pin, new_len, u8);
let vold = bytes_to_slice!(old_pin, old_len, u8);

if vpin.len() == 0 || vold.len() == 0 {
return CKR_PIN_INVALID;
}

let slot_id = session.get_slot_id();
let mut token = res_or_ret!(rstate.get_token_from_slot_mut(slot_id));
ret_to_rv!(token.set_pin(CK_UNAVAILABLE_INFORMATION, &vpin, &vold))
let do_logout = if token.is_logged_in(KRY_UNSPEC) {
false
} else {
ok_or_ret!(token.login(CKU_USER, &vold));
true
};

let ret =
ret_to_rv!(token.set_pin(CK_UNAVAILABLE_INFORMATION, &vpin, &vold));

if do_logout {
let _ = token.logout();
}

ret
}
extern "C" fn fn_open_session(
slot_id: CK_SLOT_ID,
Expand Down Expand Up @@ -673,7 +691,7 @@ extern "C" fn fn_login(
return CKR_SESSION_READ_ONLY_EXISTS;
}
}
let vpin: Vec<u8> = bytes_to_vec!(pin, pin_len);
let vpin = bytes_to_slice!(pin, pin_len, u8);
let mut token = res_or_ret!(rstate.get_token_from_slot_mut(slot_id));
if user_type == CKU_CONTEXT_SPECIFIC {
let session = res_or_ret!(rstate.get_session_mut(s_handle));
Expand Down
1 change: 1 addition & 0 deletions src/pkcs11/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ pub const KRA_SERIAL_NUMBER: CK_ATTRIBUTE_TYPE = KRY_VENDOR_OFFSET + 6;
/* Errors */
pub const KRR_TOKEN_NOT_INITIALIZED: CK_ULONG = KRY_VENDOR_OFFSET + 1;
pub const KRR_SLOT_CONFIG: CK_ULONG = KRY_VENDOR_OFFSET + 2;
pub const KRR_CONFIG_ERROR: CK_ULONG = KRY_VENDOR_OFFSET + 3;

pub const KRY_UNSPEC: CK_ULONG = CK_UNAVAILABLE_INFORMATION;

Expand Down
36 changes: 0 additions & 36 deletions src/storage.rs

This file was deleted.

Loading

0 comments on commit dabafcb

Please sign in to comment.