diff --git a/Cargo.lock b/Cargo.lock index e1255c1..f7a69dd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -283,6 +283,9 @@ dependencies = [ "anyhow", "clap", "crossbeam-channel", + "detector-kotlin", + "detector-objc", + "detector-swift", "ignore", "indicatif", "once_cell", @@ -326,6 +329,22 @@ dependencies = [ "scanner-core", ] +[[package]] +name = "detector-kotlin" +version = "0.1.0" +dependencies = [ + "anyhow", + "scanner-core", +] + +[[package]] +name = "detector-objc" +version = "0.1.0" +dependencies = [ + "anyhow", + "scanner-core", +] + [[package]] name = "detector-php" version = "0.1.0" @@ -350,6 +369,14 @@ dependencies = [ "scanner-core", ] +[[package]] +name = "detector-swift" +version = "0.1.0" +dependencies = [ + "anyhow", + "scanner-core", +] + [[package]] name = "either" version = "1.15.0" diff --git a/Cargo.toml b/Cargo.toml index 5c8ce9f..1a28695 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,9 @@ members = [ "crates/detector-rust", "crates/detector-python", "crates/detector-php", + "crates/detector-swift", + "crates/detector-objc", + "crates/detector-kotlin", "crates/cli", ] resolver = "2" diff --git a/README.md b/README.md index 9c4af53..7cfaffd 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ## cryptofind -Fast, low-false-positive static scanner that finds third-party cryptographic libraries and call sites across Go, Java, C, C++, Rust, Python, PHP, Swift, Objective-C, and Kotlin codebases. +Fast, low-false-positive static scanner that finds third-party cryptographic libraries and call sites across 10 programming languages: Go, Java, C, C++, Rust, Python, PHP, Swift, Objective-C, and Kotlin. ### Install & Run @@ -78,9 +78,22 @@ The scanner automatically detects and processes files with these extensions: - **Aho-Corasick Prefiltering**: Fast substring matching before expensive regex operations - **Parallel Processing**: Multi-threaded file scanning using Rayon -### Extending Detectors +### Detector Architecture -Detectors are plugin-like. Add a new crate under `crates/` implementing the `Detector` trait, or extend the `patterns.toml` to cover additional libraries. See `crates/scanner-core/src/lib.rs` for the trait and pattern-driven detector. +The scanner uses a modular detector architecture with dedicated crates for each language: + +- **detector-c**: C language support +- **detector-cpp**: C++ language support +- **detector-go**: Go language support +- **detector-java**: Java language support +- **detector-rust**: Rust language support +- **detector-python**: Python language support +- **detector-php**: PHP language support +- **detector-swift**: Swift language support +- **detector-objc**: Objective-C language support +- **detector-kotlin**: Kotlin language support + +Each detector implements the `Detector` trait and can be extended independently. To add support for a new language, create a new detector crate under `crates/` or extend the `patterns.toml` to cover additional libraries. See `crates/scanner-core/src/lib.rs` for the trait definition and pattern-driven detector implementation. ### Tests & Benchmarks diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index fa6cf86..a6c65d5 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -18,6 +18,9 @@ aho-corasick = { workspace = true } crossbeam-channel = { workspace = true } indicatif = "0.17" scanner-core = { path = "../scanner-core" } +detector-swift = { path = "../detector-swift" } +detector-objc = { path = "../detector-objc" } +detector-kotlin = { path = "../detector-kotlin" } [[bin]] name = "cryptofind" diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 37866e6..5a185fc 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -132,6 +132,21 @@ fn main() -> Result<()> { &[Language::Php], reg.clone(), )), + Box::new(PatternDetector::new( + "detector-swift", + &[Language::Swift], + reg.clone(), + )), + Box::new(PatternDetector::new( + "detector-objc", + &[Language::ObjC], + reg.clone(), + )), + Box::new(PatternDetector::new( + "detector-kotlin", + &[Language::Kotlin], + reg.clone(), + )), ]; let mut cfg = Config::default(); diff --git a/crates/detector-kotlin/Cargo.toml b/crates/detector-kotlin/Cargo.toml new file mode 100644 index 0000000..82ee7bf --- /dev/null +++ b/crates/detector-kotlin/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "detector-kotlin" +version = "0.1.0" +edition = "2021" +license = "Apache-2.0" + +[dependencies] +scanner-core = { path = "../scanner-core" } +anyhow = { workspace = true } + +[lib] +name = "detector_kotlin" +path = "src/lib.rs" diff --git a/crates/detector-kotlin/src/lib.rs b/crates/detector-kotlin/src/lib.rs new file mode 100644 index 0000000..4da75ea --- /dev/null +++ b/crates/detector-kotlin/src/lib.rs @@ -0,0 +1,10 @@ +use scanner_core::{Detector, Language, PatternDetector, PatternRegistry}; +use std::sync::Arc; + +pub fn make(registry: Arc) -> Box { + Box::new(PatternDetector::new( + "detector-kotlin", + &[Language::Kotlin], + registry, + )) +} diff --git a/crates/detector-objc/Cargo.toml b/crates/detector-objc/Cargo.toml new file mode 100644 index 0000000..4e47b92 --- /dev/null +++ b/crates/detector-objc/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "detector-objc" +version = "0.1.0" +edition = "2021" +license = "Apache-2.0" + +[dependencies] +scanner-core = { path = "../scanner-core" } +anyhow = { workspace = true } + +[lib] +name = "detector_objc" +path = "src/lib.rs" diff --git a/crates/detector-objc/src/lib.rs b/crates/detector-objc/src/lib.rs new file mode 100644 index 0000000..22cd65d --- /dev/null +++ b/crates/detector-objc/src/lib.rs @@ -0,0 +1,10 @@ +use scanner_core::{Detector, Language, PatternDetector, PatternRegistry}; +use std::sync::Arc; + +pub fn make(registry: Arc) -> Box { + Box::new(PatternDetector::new( + "detector-objc", + &[Language::ObjC], + registry, + )) +} diff --git a/crates/detector-swift/Cargo.toml b/crates/detector-swift/Cargo.toml new file mode 100644 index 0000000..96eb78c --- /dev/null +++ b/crates/detector-swift/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "detector-swift" +version = "0.1.0" +edition = "2021" +license = "Apache-2.0" + +[dependencies] +scanner-core = { path = "../scanner-core" } +anyhow = { workspace = true } + +[lib] +name = "detector_swift" +path = "src/lib.rs" diff --git a/crates/detector-swift/src/lib.rs b/crates/detector-swift/src/lib.rs new file mode 100644 index 0000000..8bb1825 --- /dev/null +++ b/crates/detector-swift/src/lib.rs @@ -0,0 +1,10 @@ +use scanner_core::{Detector, Language, PatternDetector, PatternRegistry}; +use std::sync::Arc; + +pub fn make(registry: Arc) -> Box { + Box::new(PatternDetector::new( + "detector-swift", + &[Language::Swift], + registry, + )) +} diff --git a/crates/scanner-core/src/lib.rs b/crates/scanner-core/src/lib.rs index 68de602..60e3a98 100644 --- a/crates/scanner-core/src/lib.rs +++ b/crates/scanner-core/src/lib.rs @@ -96,8 +96,8 @@ pub trait Detector: Send + Sync { fn scan_optimized( &self, unit: &ScanUnit, - stripped_s: &str, - index: &LineIndex, + _stripped_s: &str, + _index: &LineIndex, em: &mut Emitter, ) -> Result<()> { // Default implementation falls back to the original scan method @@ -840,7 +840,7 @@ impl<'a> Scanner<'a> { let callback = callback.clone(); Some(std::thread::spawn(move || { let mut processed = 0; - let mut findings_count = 0; + let findings_count = 0; while let Ok(_) = progress_rx.recv() { processed += 1; diff --git a/patterns.toml b/patterns.toml index 4542a58..7797b7f 100644 --- a/patterns.toml +++ b/patterns.toml @@ -2,286 +2,343 @@ schema = "1" updated = "2025-09-12" +# ========================= +# C / C++ +# ========================= + [[library]] name = "OpenSSL" languages = ["C", "C++"] [library.patterns] -include = ["^\\s*#\\s*include\\s*]+>"] +include = [ + "^\\s*#\\s*include\\s*", +] apis = [ - "\\bEVP_EncryptInit_ex\\(", - "\\bEVP_DecryptInit_ex\\(", - "\\bHMAC_Init_ex\\(", - "\\bEVP_DigestSignInit\\(", - "\\bEVP_DigestVerifyInit\\(", - "\\bEVP_\\w+\\(", - "\\bRSA_\\w+\\(", - "\\bSSL_\\w+\\(", - "\\bHMAC_\\w+\\(", - "\\bMD5_\\w+\\(", - "\\bSHA1_\\w+\\(", - "\\bSHA256_\\w+\\(", + "\\bEVP_[A-Za-z0-9_]+\\s*\\(", + "\\bRSA_[A-Za-z0-9_]+\\s*\\(", + "\\bEC_KEY_[A-Za-z0-9_]+\\s*\\(", + "\\bECDSA_[A-Za-z0-9_]+\\s*\\(", + "\\bED25519_[A-Za-z0-9_]+\\s*\\(", + "\\bX509_[A-Za-z0-9_]+\\s*\\(", + "\\bPKCS\\d_[A-Za-z0-9_]+\\s*\\(", ] [[library]] -name = "LibreSSL" +name = "libsodium" languages = ["C", "C++"] [library.patterns] include = [ - "^\\s*#\\s*include\\s*]+>", + "^\\s*#\\s*include\\s*]+)?>", ] apis = [ - "LIBRESSL_VERSION_NUMBER", - "LIBRESSL_", + "\\bcrypto_secretbox_(?:easy|open_easy)\\s*\\(", + "\\bcrypto_aead_chacha20poly1305_ietf_(?:encrypt|decrypt)\\s*\\(", + "\\bcrypto_aead_xchacha20poly1305_ietf_(?:encrypt|decrypt)\\s*\\(", + "\\bcrypto_auth(?:_verify)?\\s*\\(", + "\\bcrypto_sign_(?:detached|verify_detached)\\s*\\(", + "\\bcrypto_generichash\\s*\\(", + "\\bcrypto_scalarmult\\s*\\(", ] [[library]] -name = "BoringSSL" +name = "Libgcrypt" languages = ["C", "C++"] [library.patterns] include = [ - "^\\s*#\\s*include\\s*]+>", + "^\\s*#\\s*include\\s*", ] apis = [ - "BORINGSSL_", - "OPENSSL_IS_BORINGSSL", + "\\bgcry_[A-Za-z0-9_]+\\s*\\(", ] [[library]] -name = "libsodium" +name = "MbedTLS" languages = ["C", "C++"] [library.patterns] -include = ["^\\s*#\\s*include\\s*]+)?>"] -apis = [ - "\\bcrypto_secretbox_easy\\(", - "\\bcrypto_secretbox_open_easy\\(", - "\\bcrypto_aead_chacha20poly1305_ietf_encrypt\\(", - "\\bcrypto_aead_chacha20poly1305_ietf_decrypt\\(", - "\\bcrypto_auth\\(", - "\\bcrypto_auth_verify\\(", - "\\bcrypto_sign_detached\\(", - "\\bcrypto_sign_verify_detached\\(", +include = [ + "^\\s*#\\s*include\\s*", ] - -[[library]] -name = "GnuTLS" -languages = ["C", "C++"] -[library.patterns] -include = ["^\\s*#\\s*include\\s*"] apis = [ - "\\bgnutls_cipher_encrypt2\\(", - "\\bgnutls_cipher_decrypt2\\(", - "\\bgnutls_hmac_init\\(", - "\\bgnutls_hmac\\(", - "\\bgnutls_privkey_sign_data\\(", - "\\bgnutls_pubkey_verify_data2\\(", + "\\bmbedtls_[A-Za-z0-9_]+\\s*\\(", ] [[library]] -name = "libgcrypt" +name = "wolfSSL/wolfCrypt" languages = ["C", "C++"] [library.patterns] -include = ["^\\s*#\\s*include\\s*"] +include = [ + "^\\s*#\\s*include\\s*", +] apis = [ - "\\bgcry_cipher_encrypt\\(", - "\\bgcry_cipher_decrypt\\(", - "\\bgcry_md_setkey\\(", - "\\bgcry_pk_sign\\(", - "\\bgcry_pk_verify\\(", + "\\bwc_[A-Za-z0-9_]+\\s*\\(", ] [[library]] name = "Crypto++" -languages = ["C", "C++"] +languages = ["C++"] [library.patterns] -include = ["^\\s*#\\s*include\\s*]+>"] -namespace = ["CryptoPP::"] +include = [ + "^\\s*#\\s*include\\s*", +] apis = [ - "CryptoPP::CBC_Mode<.*>::Encryption", - "CryptoPP::CBC_Mode<.*>::Decryption", - "CryptoPP::HMAC<", - "CryptoPP::RSASS<.*>::Signer", - "CryptoPP::RSASS<.*>::Verifier", - "CryptoPP::ECDSA<.*>::Signer", - "CryptoPP::ECDSA<.*>::Verifier", + "\\bCryptoPP::[A-Za-z0-9_:]+\\s*\\(", + "\\bCryptoPP::[A-Za-z0-9_:]+\\b", # namespace/class use ] [[library]] name = "Botan" -languages = ["C", "C++"] +languages = ["C++"] [library.patterns] -include = ["^\\s*#\\s*include\\s*]+>"] -namespace = ["Botan::"] -apis = [ - "Botan::Cipher_Mode::create", - "Botan::AEAD_Mode::create", - "Botan::MessageAuthenticationCode::create", - "Botan::PK_Signer", - "Botan::PK_Verifier", +include = [ + "^\\s*#\\s*include\\s*", ] - -[[library]] -name = "wolfSSL" -languages = ["C", "C++"] -[library.patterns] -include = ["^\\s*#\\s*include\\s*]+>"] apis = [ - "\\bwc_AesGcmEncrypt\\(", - "\\bwc_AesGcmDecrypt\\(", - "\\bwc_HmacSetKey\\(", - "\\bwc_HmacUpdate\\(", - "\\bwc_HmacFinal\\(", - "\\bwc_SignatureGenerate\\(", - "\\bwc_SignatureVerify\\(", + "\\bBotan::[A-Za-z0-9_:]+\\s*\\(", + "\\bBotan::[A-Za-z0-9_:]+\\b", ] +# ========================= +# Java +# ========================= + [[library]] -name = "mbedTLS" -languages = ["C", "C++"] +name = "Java JCA/JCE" +languages = ["Java"] [library.patterns] -include = ["^\\s*#\\s*include\\s*]+>"] +include = [ + "^\\s*import\\s+javax\\.crypto\\.", + "^\\s*import\\s+java\\.security\\.", +] apis = [ - "\\bmbedtls_gcm_crypt_and_tag\\(", - "\\bmbedtls_gcm_auth_decrypt\\(", - "\\bmbedtls_md_hmac\\(", - "\\bmbedtls_pk_sign\\(", - "\\bmbedtls_pk_verify\\(", + "\\b(?:Cipher|MessageDigest|Signature|KeyPairGenerator)\\.getInstance\\s*\\(", + "\\bKeyFactory\\.getInstance\\s*\\(", + "\\bKeyAgreement\\.getInstance\\s*\\(", ] [[library]] name = "BouncyCastle" languages = ["Java"] [library.patterns] -import = [ +include = [ "^\\s*import\\s+org\\.bouncycastle\\.", - "^\\s*import\\s+org\\.bouncycastle\\.jce\\.provider\\.BouncyCastleProvider", ] apis = [ - "Cipher\\.getInstance\\(.*,?\"BC\"?\\)", - "Mac\\.getInstance\\(", - "Signature\\.getInstance\\(", - "BouncyCastleProvider", - "\\.sign\\(", - "\\.verify\\(", + "\\borg\\.bouncycastle\\.[A-Za-z0-9_.]+\\b", + "\\bnew\\s+org\\.bouncycastle\\.[A-Za-z0-9_.]+\\s*\\(", ] [[library]] -name = "Google Tink" -languages = ["Java", "Python"] +name = "Google Tink (Java)" +languages = ["Java"] [library.patterns] -import = [ +include = [ "^\\s*import\\s+com\\.google\\.crypto\\.tink\\.", - "^\\s*from\\s+tink\\b", - "^\\s*import\\s+tink\\b", ] apis = [ - "TinkConfig\\.register\\(", - "\\.encrypt\\(", - "\\.decrypt\\(", - "computeMac\\(", - "verifyMac\\(", - "\\bsign\\(", - "\\bverify\\(", + "\\bTinkConfig\\.register\\s*\\(", + "\\b(?:Aead|Mac|HybridDecrypt|HybridEncrypt|PublicKeySign|PublicKeyVerify)\\b", ] [[library]] name = "Conscrypt" languages = ["Java"] [library.patterns] -import = ["^\\s*import\\s+org\\.conscrypt\\."] +include = [ + "^\\s*import\\s+org\\.conscrypt\\.", +] apis = [ - "Cipher\\.getInstance\\(", - "Signature\\.getInstance\\(", + "\\bConscrypt\\.newProvider\\s*\\(", + "\\bOpenSSLProvider\\b", ] +# ========================= +# Go +# ========================= + [[library]] -name = "Go x/crypto" +name = "Go std crypto" languages = ["Go"] [library.patterns] -import = [ - "^\\s*import\\s+\"golang\\.org/x/crypto(/[^\"]*)?\"", - "^\\s*\"golang\\.org/x/crypto(/[^\"]*)?\"", +include = [ + "^\\s*import\\s*(?:\\(.*\\)|)\\s*[\\s\\S]*?\"crypto/(?:aes|des|rc4|sha\\d*|md5|rsa|ecdsa|ed25519|x509|rand|tls)\"", ] apis = [ - "\\bbcrypt\\.GenerateFromPassword\\(", - "chacha20poly1305\\.New", - "scrypt\\.", + "\\bcrypto\\.[A-Z][A-Za-z0-9_]*\\b", ] [[library]] -name = "age" +name = "golang.org/x/crypto" languages = ["Go"] [library.patterns] -import = [ - "^\\s*import\\s+\"filippo\\.io/age\"", - "^\\s*\"filippo\\.io/age\"", - "^\\s*import\\s+\"filippo\\.io/age/cmd/\"", - "^\\s*\"filippo\\.io/age/cmd/\"", -] -apis = [ - "age\\.Encrypt\\(", - "age\\.Decrypt\\(", - "age\\.ParseRecipients\\(", - "age\\.ParseIdentities\\(", - "age\\.GenerateX25519Identity\\(", - "age\\.ScryptRecipient\\(", - "age\\.ScryptIdentity\\(", - "age\\.SSHRecipient\\(", - "age\\.SSHIdentity\\(", - "age\\.NewFile\\(", - "age\\.NewReader\\(", - "age\\.NewWriter\\(", - "age\\.NewX25519Recipient\\(", - "age\\.NewX25519Identity\\(", - "age\\.NewScryptRecipient\\(", - "age\\.NewScryptIdentity\\(", - "age\\.NewSSHRecipient\\(", - "age\\.NewSSHIdentity\\(", -] - -[[library]] -name = "RustCrypto" +include = [ + "^\\s*import\\s*(?:\\(.*\\)|)\\s*[\\s\\S]*?\"golang\\.org/x/crypto/", +] +apis = [ + "\\bx?crypto\\b", # weak signal; primary detection via import above +] + +[[library]] +name = "Google Tink (Go)" +languages = ["Go"] +[library.patterns] +include = [ + "^\\s*import\\s*(?:\\(.*\\)|)\\s*[\\s\\S]*?\"github\\.com/google/tink/go/", +] +apis = [ + "\\btink\\/[A-Za-z0-9_/]+\\b", +] + +# ========================= +# Rust +# ========================= + +[[library]] +name = "ring" +languages = ["Rust"] +[library.patterns] +include = [ + "\\bextern\\s+crate\\s+ring\\b", + "\\buse\\s+ring::", + "\\bring::[A-Za-z0-9_]+::", +] +apis = [ + "\\bring::[A-Za-z0-9_:]+\\b", +] + +[[library]] +name = "openssl (Rust)" languages = ["Rust"] [library.patterns] -import = [ - "^\\s*use\\s+(aes|aes_gcm|chacha20poly1305|sha2|blake3)::", - "^\\s*use\\s+ring::", - "^\\s*use\\s+rustls::", - "^\\s*use\\s+sodiumoxide::", - "^\\s*use\\s+openssl::", -] -apis = [ - "openssl::ssl::", - "ring::aead::", - "rustls::ClientConfig", - "sodiumoxide::crypto::", - "aes_gcm::Aes256Gcm", - "\\bAes256Gcm::new\\(", - "\\baead::Aead\\b", - "\\bencrypt\\(", - "\\bdecrypt\\(", - "\\bhmac::Hmac\\b", - "\\bMac::verify_slice\\(", - "ring::aead::seal_in_place", - "ring::aead::open_in_place", - "ring::hmac::sign", - "ring::signature::.*::sign", - "ring::signature::.*::verify", +include = [ + "\\bextern\\s+crate\\s+openssl\\b", + "\\buse\\s+openssl::", + "\\bopenssl::[A-Za-z0-9_]+::", +] +apis = [ + "\\bopenssl::[A-Za-z0-9_:]+\\b", +] + +[[library]] +name = "RustCrypto (common crates)" +languages = ["Rust"] +[library.patterns] +include = [ + "\\buse\\s+(?:aes|aes_gcm|chacha20|chacha20poly1305|poly1305|sha1|sha2|sha3|blake2|blake3|ed25519_dalek|curve25519_dalek|argon2|scrypt)[A-Za-z0-9_:]*", +] +apis = [ + "\\b(?:aes_gcm|chacha20poly1305|sha2|sha3|blake3|ed25519_dalek|curve25519_dalek)::[A-Za-z0-9_:]+\\b", +] + +# ========================= +# Swift +# ========================= + +[[library]] +name = "CryptoKit" +languages = ["Swift"] +[library.patterns] +include = [ + "^\\s*import\\s+CryptoKit\\b", +] +apis = [ + "\\b(SHA(?:256|384|512)|HMAC|ChaChaPoly|AES\\.GCM|Curve25519)\\b", +] + +[[library]] +name = "CommonCrypto (Swift)" +languages = ["Swift"] +[library.patterns] +include = [ + "^\\s*import\\s+CommonCrypto\\b", +] +apis = [ + "\\bCC_(?:Crypt|SHA(?:1|224|256|384|512)|MD5|KeyDerivation|Random)[A-Za-z0-9_]*\\s*\\(", +] + +[[library]] +name = "CryptoSwift" +languages = ["Swift"] +[library.patterns] +include = [ + "^\\s*import\\s+CryptoSwift\\b", +] +apis = [ + "\\bAES\\s*\\(", + "\\bChaCha20\\s*\\(", + "\\bPoly1305\\b", + "\\bHMAC\\b", + "\\bSHA(?:1|224|256|384|512)\\b", +] + +[[library]] +name = "Swift-Sodium" +languages = ["Swift"] +[library.patterns] +include = [ + "^\\s*import\\s+Sodium\\b", +] +apis = [ + "\\bSodium\\s*\\(", + "\\bsodium\\.[A-Za-z0-9_]+\\b", +] + +# ========================= +# Kotlin +# ========================= + +[[library]] +name = "JCA/JCE (Kotlin)" +languages = ["Kotlin"] +[library.patterns] +include = [ + "^\\s*import\\s+(?:javax\\.crypto\\.|java\\.security\\.)", +] +apis = [ + "\\b(?:Cipher|MessageDigest|Signature|KeyPairGenerator)\\.getInstance\\s*\\(", + "\\bKeyFactory\\.getInstance\\s*\\(", + "\\bKeyAgreement\\.getInstance\\s*\\(", ] +[[library]] +name = "BouncyCastle (Kotlin)" +languages = ["Kotlin"] +[library.patterns] +include = [ + "^\\s*import\\s+org\\.bouncycastle\\.", +] +apis = [ + "\\borg\\.bouncycastle\\.[A-Za-z0-9_.]+\\b", +] + +[[library]] +name = "Korlibs Krypto (Kotlin MPP)" +languages = ["Kotlin"] +[library.patterns] +include = [ + "^\\s*import\\s+com\\.soywiz\\.krypto\\.", +] +apis = [ + "\\bcom\\.soywiz\\.krypto\\.[A-Za-z0-9_.]+\\b", +] + +# ========================= +# Python +# ========================= + [[library]] name = "PyCA cryptography" languages = ["Python"] [library.patterns] -import = [ +include = [ "^\\s*from\\s+cryptography\\b", "^\\s*import\\s+cryptography\\b", ] apis = [ - "Fernet\\(", + "\\bFernet\\(", "\\.encrypt\\(", "\\.decrypt\\(", - "AESGCM\\(", - "hmac\\.HMAC\\(", + "\\bAESGCM\\(", + "\\bhmac\\.HMAC\\(", "\\.finalize\\(", "\\.verify\\(", "\\.sign\\(", @@ -291,24 +348,24 @@ apis = [ name = "PyCryptodome" languages = ["Python"] [library.patterns] -import = [ +include = [ "^\\s*from\\s+Crypto\\b", "^\\s*import\\s+Crypto\\b", ] apis = [ - "Crypto\\.Cipher\\.AES\\.new\\(", + "\\bCrypto\\.Cipher\\.AES\\.new\\(", "\\.encrypt\\(", "\\.decrypt\\(", - "Crypto\\.Hash\\.HMAC\\.new\\(", - "Crypto\\.Signature\\.pkcs1_15\\.new\\(.*\\)\\.sign\\(", - "Crypto\\.Signature\\.pkcs1_15\\.new\\(.*\\)\\.verify\\(", + "\\bCrypto\\.Hash\\.HMAC\\.new\\(", + "\\bCrypto\\.Signature\\.pkcs1_15\\.new\\(.*\\)\\.sign\\(", + "\\bCrypto\\.Signature\\.pkcs1_15\\.new\\(.*\\)\\.verify\\(", ] [[library]] name = "PyNaCl" languages = ["Python"] [library.patterns] -import = [ +include = [ "^\\s*from\\s+nacl\\b", "^\\s*import\\s+nacl\\b", "^\\s*from\\s+nacl\\.signing\\b", @@ -318,96 +375,158 @@ import = [ "^\\s*from\\s+nacl\\.pwhash\\b", ] apis = [ - "nacl\\.secret\\.SecretBox", - "nacl\\.signing\\.SigningKey", - "nacl\\.signing\\.VerifyKey", - "nacl\\.encoding\\.", - "nacl\\.hash\\.", - "nacl\\.pwhash\\.", - "nacl\\.hashlib\\.", - "SigningKey\\.generate\\(", - "SigningKey\\.sign\\(", - "VerifyKey\\.verify\\(", - "SignedMessage\\.", + "\\bnacl\\.secret\\.SecretBox", + "\\bnacl\\.signing\\.SigningKey", + "\\bnacl\\.signing\\.VerifyKey", + "\\bnacl\\.encoding\\.", + "\\bnacl\\.hash\\.", + "\\bnacl\\.pwhash\\.", + "\\bnacl\\.hashlib\\.", + "\\bSigningKey\\.generate\\(", + "\\bSigningKey\\.sign\\(", + "\\bVerifyKey\\.verify\\(", + "\\bSignedMessage\\.", "\\.encrypt\\(", "\\.decrypt\\(", "\\.sign\\(", "\\.verify\\(", - "HexEncoder", - "Base64Encoder", + "\\bHexEncoder", + "\\bBase64Encoder", ] +# ========================= +# PHP +# ========================= + [[library]] -name = "pyOpenSSL" -languages = ["Python"] +name = "OpenSSL (PHP)" +languages = ["PHP"] [library.patterns] -import = ["^\\s*import\\s+OpenSSL\\b"] +include = [] apis = [ - "OpenSSL\\.crypto\\.sign\\(", - "OpenSSL\\.crypto\\.verify\\(", + "\\bopenssl_[a-z0-9_]+\\s*\\(", ] [[library]] -name = "M2Crypto" -languages = ["Python"] +name = "Sodium (PHP)" +languages = ["PHP"] [library.patterns] -import = ["^\\s*import\\s+M2Crypto\\b"] +include = [] apis = [ - "EVP\\.Cipher\\(", - "EVP\\.HMAC\\(", - "RSA\\.sign\\(", - "RSA\\.verify\\(", + "\\bsodium_[a-z0-9_]+\\s*\\(", ] [[library]] name = "phpseclib" languages = ["PHP"] [library.patterns] -import = [ - "^\\s*use\\s+phpseclib", - "^\\s*use\\s+phpseclib\\\\Crypt\\\\", +include = [ + "^\\s*use\\s+phpseclib\\d*\\\\Crypt\\\\", ] apis = [ - "->encrypt\\(", - "->decrypt\\(", - "->sign\\(", - "->verify\\(", + "\\bnew\\s+\\\\?phpseclib\\d*\\\\Crypt\\\\[A-Za-z0-9_]+\\s*\\(", + "\\bnew\\s+Crypt_[A-Z][A-Za-z0-9_]*\\s*\\(", # legacy v2 ] [[library]] -name = "Defuse PHP Crypto" +name = "Halite (ParagonIE)" languages = ["PHP"] [library.patterns] -import = ["^\\s*use\\s+Defuse\\\\Crypto\\\\"] +include = [ + "^\\s*use\\s+ParagonIE\\\\Halite\\\\", +] apis = [ - "Defuse\\\\Crypto\\\\Crypto::encrypt\\(", - "Defuse\\\\Crypto\\\\Crypto::decrypt\\(", + "\\bParagonIE\\\\Halite\\\\[A-Za-z0-9_\\\\]+::[A-Za-z0-9_]+\\s*\\(", ] +# ========================= +# Objective-C: Apple/Common +# ========================= + [[library]] -name = "PHP sodium" -languages = ["PHP"] +name = "CommonCrypto (Objective-C)" +languages = ["Objective-C"] [library.patterns] +include = [ + "^\\s*#\\s*(?:import|include)\\s*", + "^\\s*@import\\s+CommonCrypto\\b", +] apis = [ - "\\bsodium_crypto_secretbox\\(", - "\\bsodium_crypto_secretbox_open\\(", - "\\bsodium_crypto_secretbox_keygen\\(", - "\\bsodium_crypto_aead_.*_encrypt\\(", - "\\bsodium_crypto_aead_.*_decrypt\\(", - "\\bsodium_crypto_auth\\(", - "\\bsodium_crypto_auth_verify\\(", - "\\bsodium_crypto_sign_detached\\(", - "\\bsodium_crypto_sign_verify_detached\\(", + "\\bCCCrypt\\s*\\(", + "\\bCCCryptor(?:Create|Update|Final|Release)\\s*\\(", + "\\bCCHmac\\s*\\(", + "\\bCC_SHA(?:1|224|256|384|512)\\s*\\(", + "\\bCC_MD5\\s*\\(", + "\\bCCKeyDerivationPBKDF\\s*\\(", + "\\bCCRandomGenerateBytes\\s*\\(", ] [[library]] -name = "PHP OpenSSL" -languages = ["PHP"] +name = "Security.framework (Objective-C)" +languages = ["Objective-C"] [library.patterns] +include = [ + "^\\s*#\\s*(?:import|include)\\s*", + "^\\s*@import\\s+Security\\b", +] apis = [ - "\\bopenssl_encrypt\\(", - "\\bopenssl_decrypt\\(", - "\\bopenssl_sign\\(", - "\\bopenssl_verify\\(", + "\\bSecKeyCreateRandomKey\\s*\\(", + "\\bSecKeyCreateEncryptedData\\s*\\(", + "\\bSecKeyCreateDecryptedData\\s*\\(", + "\\bSecKeyCreateSignature\\s*\\(", + "\\bSecKeyVerifySignature\\s*\\(", + "\\bSecRandomCopyBytes\\s*\\(", ] +# ========================= +# Objective-C: Third-party C libs used from Obj-C +# ========================= + +[[library]] +name = "OpenSSL (Objective-C)" +languages = ["Objective-C"] +[library.patterns] +include = [ + "^\\s*#\\s*(?:import|include)\\s*", +] +apis = [ + "\\bEVP_[A-Za-z0-9_]+\\s*\\(", + "\\bRSA_[A-Za-z0-9_]+\\s*\\(", + "\\bECDSA_[A-Za-z0-9_]+\\s*\\(", + "\\bEC_KEY_[A-Za-z0-9_]+\\s*\\(", + "\\bX509_[A-Za-z0-9_]+\\s*\\(", + "\\bPKCS\\d_[A-Za-z0-9_]+\\s*\\(", +] + +[[library]] +name = "libsodium (Objective-C)" +languages = ["Objective-C"] +[library.patterns] +include = [ + "^\\s*#\\s*(?:import|include)\\s*]+)?>", +] +apis = [ + "\\bcrypto_secretbox_(?:easy|open_easy)\\s*\\(", + "\\bcrypto_aead_(?:x?chacha20poly1305_ietf|aes256gcm)_(?:encrypt|decrypt)\\s*\\(", + "\\bcrypto_sign_(?:detached|verify_detached)\\s*\\(", + "\\bcrypto_generichash\\s*\\(", + "\\bcrypto_scalarmult\\s*\\(", +] + +# ========================= +# Objective-C: High-level but still primitive APIs +# ========================= + +[[library]] +name = "Google Tink (Objective-C)" +languages = ["Objective-C"] +[library.patterns] +include = [ + "^\\s*@import\\s+Tink\\b", + "^\\s*#\\s*import\\s*", + "^\\s*#\\s*import\\s*\"objc\\/TINK[A-Za-z0-9_]+\\.h\"", +] +apis = [ + "\\bTINK(?:Aead|Mac|Hybrid(?:Encrypt|Decrypt)|PublicKey(?:Sign|Verify)|KeysetHandle|Config)\\b", + "\\b\\[TINK[A-Za-z0-9_]+Factory\\s+[A-Za-z0-9_]+WithKeysetHandle:.*\\]", +]