[package]
name = "sspi"
version = "0.18.7"
edition = "2021"
readme = "README.md"
license = "MIT OR Apache-2.0"
homepage = "https://github.com/devolutions/sspi-rs"
repository = "https://github.com/devolutions/sspi-rs"
authors = ["Devolutions Inc. <infos@devolutions.net>"]
description = "A Rust implementation of the Security Support Provider Interface (SSPI) API"
keywords = ["ntlm", "auth", "sspi", "windows", "kerberos"]

[workspace]
resolver = "2"
members = [
  "ffi",
  "ffi/symbol-rename-macro",
  "crates/winscard",
  "crates/ffi-types",
  "crates/dpapi",
  "crates/dpapi-core",
  "crates/dpapi-pdu",
  "crates/dpapi-transport",
  "crates/dpapi-native-transport",
  "crates/dpapi-fuzzing",
  "crates/dpapi-web",
  "crates/kdc",
]
exclude = [
  "tools/wasm-testcompile",
  "tools/dpapi-cli-client",
]

[workspace.lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(fuzzing)'] }

# == Correctness == #
ambiguous_negative_literals = "warn"

# == Style, readability == #
unreachable_pub = "warn"
single_use_lifetimes = "warn"
elided_lifetimes_in_paths = "warn"
unused_lifetimes = "warn"
redundant_lifetimes = "warn"
trivial_numeric_casts = "warn"
unused_qualifications = "warn"

[workspace.lints.clippy]

# == Safer unsafe == #
as_ptr_cast_mut = "warn"
fn_to_numeric_cast_any = "warn"
ptr_cast_constness = "warn"
unnecessary_safety_comment = "warn"
missing_safety_doc = "warn"
as_pointer_underscore = "warn"
undocumented_unsafe_blocks = "warn"
multiple_unsafe_ops_per_block = "warn"

# == Correctness == #
as_underscore = "warn"
filetype_is_file = "warn"
float_cmp_const = "warn"
float_cmp = "warn"
get_unwrap = "warn"
lossy_float_literal = "warn"
mem_forget = "warn"
mixed_read_write_in_expression = "warn"
needless_raw_strings = "warn"
non_ascii_literal = "warn"
panic = "warn"
rc_mutex = "warn"
suspicious_xor_used_as_pow = "warn"
unused_result_ok = "warn"

[workspace.dependencies]
uuid = { version = "1.18", default-features = false }
tracing = { version = "0.1",  default-features = false }
bitflags = "2.9"
rand = "0.9"
getrandom = "0.3"
cfg-if = "1"
time = { version = "0.3", default-features = false }
sha1 = { version = "=0.11.0-rc.2", default-features = false }
sha2 = "=0.11.0-rc.2"
num-derive = "0.4"
num-traits = { version = "0.2", default-features = false }

picky = { version = "=7.0.0-rc.20", default-features = false }
picky-asn1 = "0.10"
picky-asn1-der = "0.5"
picky-asn1-x509 = "0.15"
picky-krb = "0.12"

tokio = "1.47"
ffi-types = { path = "crates/ffi-types" }
winscard = { version = "0.2", path = "crates/winscard" }

dpapi = { version = "0.0.0", path = "crates/dpapi" }
dpapi-core = { version = "0.1.0", path = "crates/dpapi-core" }
dpapi-pdu = { version = "0.1.0", path = "crates/dpapi-pdu" }
dpapi-transport = { version = "0.1.0", path = "crates/dpapi-transport" }
dpapi-native-transport = { version = "0.1.0", path = "crates/dpapi-native-transport" }

rsa = { version = "=0.10.0-rc.9", default-features = false }
base64 = "0.22"
whoami = "1.6"
tracing-subscriber = "0.3"
proptest = "1.6"
serde = "1"
byteorder = "1.5"
crypto-bigint = { version = "=0.7.0-rc.8", default-features = false, features = ["alloc"] }
hmac = "=0.13.0-rc.2"

[features]
default = ["aws-lc-rs"]

# Enable reqwest for HTTP requests.
network_client = ["dep:reqwest", "dep:portpicker", "dep:rustls-native-certs", "__rustls-used"]
# KDC discovery by querying DNS records.
dns_resolver = ["dep:hickory-resolver", "dep:hickory-proto","dep:tokio"]
# TSSSP should be used only on Windows as a native CredSSP replacement.
tsssp = ["dep:rustls", "__rustls-used"]
# Turns on Kerberos smart card logon.
scard = ["dep:winscard", "dep:cryptoki"]
# Use AWS LC as TLS cryptography provider.
aws-lc-rs = ["rustls?/aws-lc-rs", "__install-crypto-provider"]
# Use ring as TLS cryptography provider.
ring = ["rustls?/ring", "reqwest?/rustls-tls-native-roots", "__install-crypto-provider"]

# Internal (PRIVATE!) features. Do not rely on these whatsoever. They may disappear at anytime.

__test-data = []
__rustls-used = ["dep:rustls"]
__install-crypto-provider = []

[dependencies]
bitflags.workspace = true
rand.workspace = true
getrandom.workspace = true
cfg-if.workspace = true
picky.workspace = true
sha1.workspace = true
sha2.workspace = true
num-derive.workspace = true
num-traits = { workspace = true, default-features = true }
picky-asn1-der.workspace = true
picky-asn1-x509 = { workspace = true, features = ["pkcs7"] }
uuid = { workspace = true, features = ["v4"], default-features = true }
# `rt-multi-thread` feature is required for `tokio::task::block_in_place` function.
tokio = { workspace = true, optional = true, features = ["time", "rt", "rt-multi-thread"] }
winscard = { workspace = true, optional = true }
rsa = { workspace = true, features = ["sha1"] }
tracing = { workspace = true, default-features = true }
serde.workspace = true
picky-krb.workspace = true
picky-asn1 = { workspace = true, features = ["time_conversion"] }
byteorder.workspace = true
crypto-bigint.workspace = true
hmac.workspace = true
url = "2.5"

md-5 = "=0.11.0-rc.2"
md4 = "0.10"
crypto-mac = "0.11"
oid = "0.2"

reqwest = { version = "0.12", optional = true, default-features = false, features = ["blocking", "rustls-tls-no-provider"] }
hickory-resolver = { version = "0.25", optional = true }
hickory-proto = { version = "0.25", optional = true }
portpicker = { version = "0.1", optional = true }
rustls = { version = "0.23", optional = true, default-features = false, features = ["logging", "std", "tls12"] }
rustls-native-certs = { version = "0.8", optional = true }
zeroize = { version = "1.8", features = ["zeroize_derive"] }
async-recursion = "1.1"


[target.'cfg(windows)'.dependencies]
windows-registry = "0.6"
windows = { version = "0.62", features = [ "Win32_Foundation", "Win32_System", "Win32_NetworkManagement_Dns", "Win32_Security_Cryptography"] }

[target.'cfg(target_arch = "wasm32")'.dependencies]
uuid = { workspace = true, features = ["js"]}
getrandom = { workspace = true, features = ["wasm_js"] }
time = { workspace = true, features = ["wasm-bindgen"] }

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
cryptoki = { version = "0.10", optional = true }
time = { workspace = true, features = ["std"] }

[target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies]
async-dnssd = "0.5"
futures = "0.3"
tokio = { workspace = true, features = ["time", "rt", "rt-multi-thread"] }

# Pin transitive dependencies
# TODO: Remove when stable versions will be released
# RustCrypto crates
digest = "=0.11.0-rc.3"
block-buffer = "=0.11.0-rc.5"
crypto-common = "=0.2.0-rc.4"
pkcs1 = "=0.8.0-rc.4"
pkcs8 = "=0.11.0-rc.7"
der = "=0.8.0-rc.9"
spki = "=0.8.0-rc.4"
pem-rfc7468 = "=1.0.0-rc.3"
signature = "=3.0.0-rc.4"
p256 = "=0.14.0-pre.11"
primefield = "=0.14.0-pre.6"
primeorder = "=0.14.0-pre.9"
p384 = "=0.14.0-pre.11"
p521 = "=0.14.0-pre.11"
crypto-primes = "=0.7.0-pre.3"

# "Zero-knowledge Cryptography in Rust" crates
ff = { version = "=0.14.0-pre.0", default-features = false }
group = "=0.14.0-pre.0"

# "dalek cryptography" crates
ed25519-dalek = "=3.0.0-pre.1"
curve25519-dalek = "=5.0.0-pre.1"

[dev-dependencies]
base64.workspace = true
static_assertions = "1"
whoami.workspace = true
picky = { workspace = true, features = ["x509"] }
tracing-subscriber = { workspace = true, features = ["env-filter"] }
proptest.workspace = true
cfg-if.workspace = true

[lints]
workspace = true

[[example]]
name = "kerberos"
required-features = ["network_client"]

[profile.ffi-production]
inherits = "release"
strip = "symbols"
lto = true
opt-level = "z"
codegen-units = 1
panic = "abort"

# Optimize for speed the cryptographic libraries.
[profile.ffi-production.package.num-bigint-dig]
opt-level = 3
[profile.ffi-production.package.crypto-bigint]
opt-level = 3
[profile.ffi-production.package.p256]
opt-level = 3
[profile.ffi-production.package.p384]
opt-level = 3
[profile.ffi-production.package.p521]
opt-level = 3
[profile.ffi-production.package.rsa]
opt-level = 3
[profile.ffi-production.package.sha1]
opt-level = 3
[profile.ffi-production.package.sha2]
opt-level = 3
[profile.ffi-production.package.sha3]
opt-level = 3
[profile.ffi-production.package.aes-gcm]
opt-level = 3
[profile.ffi-production.package.aes]
opt-level = 3
[profile.ffi-production.package.aes-kw]
opt-level = 3
[profile.ffi-production.package.argon2]
opt-level = 3
[profile.ffi-production.package.ctr]
opt-level = 3
[profile.ffi-production.package.cbc]
opt-level = 3
[profile.ffi-production.package.bcrypt-pbkdf]
opt-level = 3
[profile.ffi-production.package.des]
opt-level = 3
[profile.ffi-production.package.pbkdf2]
opt-level = 3
[profile.ffi-production.package.hmac]
opt-level = 3
