Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial winscard implementation and integration #210

Merged
merged 7 commits into from
Feb 15, 2024
Merged
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
696 changes: 459 additions & 237 deletions Cargo.lock

Large diffs are not rendered by default.

11 changes: 6 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,10 @@ required-features = ["network_client"]
members = [
"ffi",
"ffi/symbol-rename-macro",
"crates/winscard",
"crates/ffi-types"
]
exclude = [
"tools/sspi-ffi-attacker",
"tools/wasm-testcompile",
]
exclude = ["tools/sspi-ffi-attacker", "tools/wasm-testcompile"]

[features]
default = []
Expand All @@ -31,7 +30,7 @@ dns_resolver = ["dep:trust-dns-resolver", "dep:tokio", "tokio/rt-multi-thread"]
# TSSSP should be used only on Windows as a native CREDSSP replacement
tsssp = ["dep:rustls"]
# Turns on Kerberos smart card login (available only on Windows and users WinSCard API)
scard = ["dep:pcsc"]
scard = ["dep:pcsc", "dep:winscard"]

[dependencies]
byteorder = "1.4"
Expand Down Expand Up @@ -70,6 +69,7 @@ zeroize = { version = "1.6", features = ["zeroize_derive"] }
tokio = { version = "1.32", features = ["time", "rt"], optional = true }
pcsc = { version = "2.8", optional = true }
async-recursion = "1.0.5"
winscard = { path = "./crates/winscard", optional = true }

[target.'cfg(windows)'.dependencies]
winreg = "0.51"
Expand All @@ -90,3 +90,4 @@ whoami = "1.4"
picky = { version = "7.0.0-rc.8", features = ["x509"] }
tracing-subscriber = "0.3"
proptest = "1.3.1"
cfg-if = "1"
10 changes: 10 additions & 0 deletions crates/ffi-types/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "ffi-types"
version = "0.1.0"
edition = "2021"

[features]
default = []
winscard = []

[dependencies]
35 changes: 35 additions & 0 deletions crates/ffi-types/src/common.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use std::ffi::c_void;

pub type LpStr = *mut u8;
pub type LpCStr = *const u8;
pub type LpDword = *mut u32;
pub type LpWStr = *mut u16;
pub type LpCWStr = *const u16;
pub type LpCByte = *const u8;
pub type LpByte = *mut u8;
pub type LpCVoid = *const c_void;
pub type LpVoid = *mut c_void;
pub type Handle = *mut c_void;
pub type Bool = i32;

/// [Guid](https://learn.microsoft.com/en-us/windows/win32/api/guiddef/ns-guiddef-guid)
///
/// ```not_rust
/// typedef struct _GUID {
/// unsigned long Data1;
/// unsigned short Data2;
/// unsigned short Data3;
/// unsigned char Data4[8];
/// } GUID;
/// ```
#[repr(C)]
pub struct Guid {
pub data1: u32,
pub data2: u32,
pub data3: u32,
pub data4: [u8; 8],
}
pub type LpCGuid = *const Guid;
pub type LpGuid = *mut Guid;
pub type Uuid = Guid;
pub type LpUuid = *mut Uuid;
5 changes: 5 additions & 0 deletions crates/ffi-types/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pub mod common;
#[cfg(feature = "winscard")]
pub mod winscard;

pub use common::*;
199 changes: 199 additions & 0 deletions crates/ffi-types/src/winscard/functions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
use std::ffi::c_void;

use super::{
LpOpenCardNameA, LpOpenCardNameExA, LpOpenCardNameExW, LpOpenCardNameW, LpScardAtrMask, LpScardContext,
LpScardHandle, LpScardIoRequest, LpScardReaderStateA, LpScardReaderStateW, ScardContext, ScardHandle, ScardStatus,
};
use crate::{
Handle, LpByte, LpCByte, LpCGuid, LpCStr, LpCVoid, LpCWStr, LpDword, LpGuid, LpStr, LpUuid, LpVoid, LpWStr,
};

pub type SCardEstablishContextFn =
unsafe extern "system" fn(u32, *const c_void, *const c_void, LpScardContext) -> ScardStatus;
pub type SCardReleaseContextFn = unsafe extern "system" fn(ScardContext) -> ScardStatus;
pub type SCardIsValidContextFn = unsafe extern "system" fn(ScardContext) -> ScardStatus;
pub type SCardListReaderGroupsAFn = extern "system" fn(ScardContext, LpStr, LpDword) -> ScardStatus;
pub type SCardListReaderGroupsWFn = extern "system" fn(ScardContext, LpWStr, LpDword) -> ScardStatus;
pub type SCardListReadersAFn = unsafe extern "system" fn(ScardContext, LpCStr, LpStr, LpDword) -> ScardStatus;
pub type SCardListReadersWFn = unsafe extern "system" fn(ScardContext, LpCWStr, LpWStr, LpDword) -> ScardStatus;
pub type SCardListCardsAFn =
unsafe extern "system" fn(ScardContext, LpCByte, LpCGuid, u32, *mut u8, LpDword) -> ScardStatus;
pub type SCardListCardsWFn =
unsafe extern "system" fn(ScardContext, LpCByte, LpCGuid, u32, *mut u16, LpDword) -> ScardStatus;
pub type SCardListInterfacesAFn = extern "system" fn(ScardContext, LpCStr, LpGuid, LpDword) -> ScardStatus;
pub type SCardListInterfacesWFn = extern "system" fn(ScardContext, LpCWStr, LpGuid, LpDword) -> ScardStatus;
pub type SCardGetProviderIdAFn = extern "system" fn(ScardContext, LpCStr, LpGuid) -> ScardStatus;
pub type SCardGetProviderIdWFn = extern "system" fn(ScardContext, LpCWStr, LpGuid) -> ScardStatus;
pub type SCardGetCardTypeProviderNameAFn =
unsafe extern "system" fn(ScardContext, LpCStr, u32, *mut u8, LpDword) -> ScardStatus;
pub type SCardGetCardTypeProviderNameWFn =
unsafe extern "system" fn(ScardContext, LpCWStr, u32, *mut u16, LpDword) -> ScardStatus;
pub type SCardIntroduceReaderGroupAFn = extern "system" fn(ScardContext, LpCStr) -> ScardStatus;
pub type SCardIntroduceReaderGroupWFn = extern "system" fn(ScardContext, LpCWStr) -> ScardStatus;
pub type SCardForgetReaderGroupAFn = extern "system" fn(ScardContext, LpCStr) -> ScardStatus;
pub type SCardForgetReaderGroupWFn = extern "system" fn(ScardContext, LpCWStr) -> ScardStatus;
pub type SCardIntroduceReaderAFn = extern "system" fn(ScardContext, LpCStr, LpCStr) -> ScardStatus;
pub type SCardIntroduceReaderWFn = extern "system" fn(ScardContext, LpCWStr, LpCWStr) -> ScardStatus;
pub type SCardForgetReaderAFn = extern "system" fn(ScardContext, LpCStr) -> ScardStatus;
pub type SCardForgetReaderWFn = extern "system" fn(ScardContext, LpCWStr) -> ScardStatus;
pub type SCardAddReaderToGroupAFn = extern "system" fn(ScardContext, LpCStr, LpCStr) -> ScardStatus;
pub type SCardAddReaderToGroupWFn = extern "system" fn(ScardContext, LpCWStr, LpCWStr) -> ScardStatus;
pub type SCardRemoveReaderFromGroupAFn = extern "system" fn(ScardContext, LpCStr, LpCStr) -> ScardStatus;
pub type SCardRemoveReaderFromGroupWFn = extern "system" fn(ScardContext, LpCWStr, LpCWStr) -> ScardStatus;
pub type SCardIntroduceCardTypeAFn =
extern "system" fn(ScardContext, LpCStr, LpCGuid, LpCGuid, u32, LpCByte, LpCByte, u32) -> ScardStatus;
pub type SCardIntroduceCardTypeWFn =
extern "system" fn(ScardContext, LpCWStr, LpCGuid, LpCGuid, u32, LpCByte, LpCByte, u32) -> ScardStatus;
pub type SCardSetCardTypeProviderNameAFn = extern "system" fn(ScardContext, LpCStr, u32, LpCStr) -> ScardStatus;
pub type SCardSetCardTypeProviderNameWFn = extern "system" fn(ScardContext, LpCWStr, u32, LpCWStr) -> ScardStatus;
pub type SCardForgetCardTypeAFn = extern "system" fn(ScardContext, LpCStr) -> ScardStatus;
pub type SCardForgetCardTypeWFn = extern "system" fn(ScardContext, LpCWStr) -> ScardStatus;
pub type SCardFreeMemoryFn = unsafe extern "system" fn(ScardContext, LpCVoid) -> ScardStatus;
pub type SCardAccessStartedEventFn = extern "system" fn() -> Handle;
pub type SCardReleaseStartedEventFn = extern "system" fn();
pub type SCardLocateCardsAFn = extern "system" fn(ScardContext, LpCStr, LpScardReaderStateA, u32) -> ScardStatus;
pub type SCardLocateCardsWFn = extern "system" fn(ScardContext, LpCWStr, LpScardReaderStateW, u32) -> ScardStatus;
pub type SCardLocateCardsByATRAFn =
extern "system" fn(ScardContext, LpScardAtrMask, u32, LpScardReaderStateA, u32) -> ScardStatus;
pub type SCardLocateCardsByATRWFn =
extern "system" fn(ScardContext, LpScardAtrMask, u32, LpScardReaderStateW, u32) -> ScardStatus;
pub type SCardGetStatusChangeAFn =
unsafe extern "system" fn(ScardContext, u32, LpScardReaderStateA, u32) -> ScardStatus;
pub type SCardGetStatusChangeWFn =
unsafe extern "system" fn(ScardContext, u32, LpScardReaderStateW, u32) -> ScardStatus;
pub type SCardCancelFn = extern "system" fn(ScardContext) -> ScardStatus;
pub type SCardReadCacheAFn =
unsafe extern "system" fn(ScardContext, LpUuid, u32, LpStr, LpByte, LpDword) -> ScardStatus;
pub type SCardReadCacheWFn =
unsafe extern "system" fn(ScardContext, LpUuid, u32, LpWStr, LpByte, LpDword) -> ScardStatus;
pub type SCardWriteCacheAFn = unsafe extern "system" fn(ScardContext, LpUuid, u32, LpStr, LpByte, u32) -> ScardStatus;
pub type SCardWriteCacheWFn = unsafe extern "system" fn(ScardContext, LpUuid, u32, LpWStr, LpByte, u32) -> ScardStatus;
pub type SCardGetReaderIconAFn = unsafe extern "system" fn(ScardContext, LpCStr, LpByte, LpDword) -> ScardStatus;
pub type SCardGetReaderIconWFn = unsafe extern "system" fn(ScardContext, LpCWStr, LpByte, LpDword) -> ScardStatus;
pub type SCardGetDeviceTypeIdAFn = unsafe extern "system" fn(ScardContext, LpCStr, LpDword) -> ScardStatus;
pub type SCardGetDeviceTypeIdWFn = unsafe extern "system" fn(ScardContext, LpCWStr, LpDword) -> ScardStatus;
pub type SCardGetReaderDeviceInstanceIdAFn = extern "system" fn(ScardContext, LpCStr, LpStr, LpDword) -> ScardStatus;
pub type SCardGetReaderDeviceInstanceIdWFn = extern "system" fn(ScardContext, LpCWStr, LpWStr, LpDword) -> ScardStatus;
pub type SCardListReadersWithDeviceInstanceIdAFn =
extern "system" fn(ScardContext, LpCStr, LpStr, LpDword) -> ScardStatus;
pub type SCardListReadersWithDeviceInstanceIdWFn =
extern "system" fn(ScardContext, LpCWStr, LpWStr, LpDword) -> ScardStatus;
pub type SCardAuditFn = extern "system" fn(ScardContext, u32) -> ScardStatus;
pub type SCardConnectAFn =
unsafe extern "system" fn(ScardContext, LpCStr, u32, u32, LpScardHandle, LpDword) -> ScardStatus;
pub type SCardConnectWFn =
unsafe extern "system" fn(ScardContext, LpCWStr, u32, u32, LpScardHandle, LpDword) -> ScardStatus;
pub type SCardReconnectFn = extern "system" fn(ScardHandle, u32, u32, u32, LpDword) -> ScardStatus;
pub type SCardDisconnectFn = unsafe extern "system" fn(ScardHandle, u32) -> ScardStatus;
pub type SCardBeginTransactionFn = unsafe extern "system" fn(ScardHandle) -> ScardStatus;
pub type SCardEndTransactionFn = unsafe extern "system" fn(ScardHandle, u32) -> ScardStatus;
pub type SCardCancelTransactionFn = extern "system" fn(ScardHandle) -> ScardStatus;
pub type SCardStateFn = extern "system" fn(ScardHandle, LpDword, LpDword, LpByte, LpDword) -> ScardStatus;
pub type SCardStatusAFn =
unsafe extern "system" fn(ScardHandle, LpStr, LpDword, LpDword, LpDword, LpByte, LpDword) -> ScardStatus;
pub type SCardStatusWFn =
unsafe extern "system" fn(ScardHandle, LpWStr, LpDword, LpDword, LpDword, LpByte, LpDword) -> ScardStatus;
pub type SCardTransmitFn = unsafe extern "system" fn(
ScardHandle,
LpScardIoRequest,
LpCByte,
u32,
LpScardIoRequest,
LpByte,
LpDword,
) -> ScardStatus;
pub type SCardGetTransmitCountFn = extern "system" fn(ScardHandle, LpDword) -> ScardStatus;
pub type SCardControlFn =
unsafe extern "system" fn(ScardHandle, u32, LpCVoid, u32, LpVoid, u32, LpDword) -> ScardStatus;
pub type SCardGetAttribFn = extern "system" fn(ScardHandle, u32, LpByte, LpDword) -> ScardStatus;
pub type SCardSetAttribFn = extern "system" fn(ScardHandle, u32, LpCByte, u32) -> ScardStatus;
pub type SCardUIDlgSelectCardAFn = extern "system" fn(LpOpenCardNameExA) -> ScardStatus;
pub type SCardUIDlgSelectCardWFn = extern "system" fn(LpOpenCardNameExW) -> ScardStatus;
pub type GetOpenCardNameAFn = extern "system" fn(LpOpenCardNameA) -> ScardStatus;
pub type GetOpenCardNameWFn = extern "system" fn(LpOpenCardNameW) -> ScardStatus;
// Not a part of the standard winscard.h API
pub type GetSCardApiFunctionTableFn = extern "system" fn() -> PSCardApiFunctionTable;

// https://github.com/FreeRDP/FreeRDP/blob/88f79c5748f4031cb50dfae3ebadcc6619b69f1c/winpr/include/winpr/smartcard.h#L1114
#[repr(C)]
#[allow(non_snake_case)]
pub struct SCardApiFunctionTable {
pub dw_version: u32,
pub dw_flags: u32,

pub SCardEstablishContext: SCardEstablishContextFn,
pub SCardReleaseContext: SCardReleaseContextFn,
pub SCardIsValidContext: SCardIsValidContextFn,
pub SCardListReaderGroupsA: SCardListReaderGroupsAFn,
pub SCardListReaderGroupsW: SCardListReaderGroupsWFn,
pub SCardListReadersA: SCardListReadersAFn,
pub SCardListReadersW: SCardListReadersWFn,
pub SCardListCardsA: SCardListCardsAFn,
pub SCardListCardsW: SCardListCardsWFn,
pub SCardListInterfacesA: SCardListInterfacesAFn,
pub SCardListInterfacesW: SCardListInterfacesWFn,
pub SCardGetProviderIdA: SCardGetProviderIdAFn,
pub SCardGetProviderIdW: SCardGetProviderIdWFn,
pub SCardGetCardTypeProviderNameA: SCardGetCardTypeProviderNameAFn,
pub SCardGetCardTypeProviderNameW: SCardGetCardTypeProviderNameWFn,
pub SCardIntroduceReaderGroupA: SCardIntroduceReaderGroupAFn,
pub SCardIntroduceReaderGroupW: SCardIntroduceReaderGroupWFn,
pub SCardForgetReaderGroupA: SCardForgetReaderGroupAFn,
pub SCardForgetReaderGroupW: SCardForgetReaderGroupWFn,
pub SCardIntroduceReaderA: SCardIntroduceReaderAFn,
pub SCardIntroduceReaderW: SCardIntroduceReaderWFn,
pub SCardForgetReaderA: SCardForgetReaderAFn,
pub SCardForgetReaderW: SCardForgetReaderWFn,
pub SCardAddReaderToGroupA: SCardAddReaderToGroupAFn,
pub SCardAddReaderToGroupW: SCardAddReaderToGroupWFn,
pub SCardRemoveReaderFromGroupA: SCardRemoveReaderFromGroupAFn,
pub SCardRemoveReaderFromGroupW: SCardRemoveReaderFromGroupWFn,
pub SCardIntroduceCardTypeA: SCardIntroduceCardTypeAFn,
pub SCardIntroduceCardTypeW: SCardIntroduceCardTypeWFn,
pub SCardSetCardTypeProviderNameA: SCardSetCardTypeProviderNameAFn,
pub SCardSetCardTypeProviderNameW: SCardSetCardTypeProviderNameWFn,
pub SCardFreeMemory: SCardFreeMemoryFn,
pub SCardAccessStartedEvent: SCardAccessStartedEventFn,
pub SCardReleaseStartedEvent: SCardReleaseStartedEventFn,
pub SCardLocateCardsA: SCardLocateCardsAFn,
pub SCardLocateCardsW: SCardLocateCardsWFn,
pub SCardLocateCardsByATRA: SCardLocateCardsByATRAFn,
pub SCardLocateCardsByATRW: SCardLocateCardsByATRWFn,
pub SCardGetStatusChangeA: SCardGetStatusChangeAFn,
pub SCardGetStatusChangeW: SCardGetStatusChangeWFn,
pub SCardCancel: SCardCancelFn,
pub SCardConnectA: SCardConnectAFn,
pub SCardConnectW: SCardConnectWFn,
pub SCardReconnect: SCardReconnectFn,
pub SCardDisconnect: SCardDisconnectFn,
pub SCardBeginTransaction: SCardBeginTransactionFn,
pub SCardEndTransaction: SCardEndTransactionFn,
pub SCardCancelTransaction: SCardCancelTransactionFn,
pub SCardState: SCardStateFn,
pub SCardStatusA: SCardStatusAFn,
pub SCardStatusW: SCardStatusWFn,
pub SCardTransmit: SCardTransmitFn,
pub SCardGetTransmitCount: SCardGetTransmitCountFn,
pub SCardControl: SCardControlFn,
pub SCardGetAttrib: SCardGetAttribFn,
pub SCardSetAttrib: SCardSetAttribFn,
pub SCardUIDlgSelectCardA: SCardUIDlgSelectCardAFn,
pub SCardUIDlgSelectCardW: SCardUIDlgSelectCardWFn,
pub GetOpenCardNameA: GetOpenCardNameAFn,
pub GetOpenCardNameW: GetOpenCardNameWFn,
pub SCardReadCacheA: SCardReadCacheAFn,
pub SCardReadCacheW: SCardReadCacheWFn,
pub SCardWriteCacheA: SCardWriteCacheAFn,
pub SCardWriteCacheW: SCardWriteCacheWFn,
pub SCardGetReaderIconA: SCardGetReaderIconAFn,
pub SCardGetReaderIconW: SCardGetReaderIconWFn,
pub SCardGetDeviceTypeIdA: SCardGetDeviceTypeIdAFn,
pub SCardGetDeviceTypeIdW: SCardGetDeviceTypeIdWFn,
pub SCardGetReaderDeviceInstanceIdA: SCardGetReaderDeviceInstanceIdAFn,
pub SCardGetReaderDeviceInstanceIdW: SCardGetReaderDeviceInstanceIdWFn,
pub SCardListReadersWithDeviceInstanceIdA: SCardListReadersWithDeviceInstanceIdAFn,
pub SCardListReadersWithDeviceInstanceIdW: SCardListReadersWithDeviceInstanceIdWFn,
pub SCardAudit: SCardAuditFn,
}

pub type PSCardApiFunctionTable = *mut SCardApiFunctionTable;
Loading
Loading