Bindings to the macOS Security.framework

Overview

macOS/iOS Security framework for Rust

Latest Version

Documentation

Bindings to the Apple's Security.framework. Allows use of TLS and Keychain from Rust.

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you shall be dual licensed as above, without any additional terms or conditions.

Comments
  • Add support for generic password functions.

    Add support for generic password functions.

    I'm not sure if this is the right place to make this change (vs. creating an entirely new library), so I am completely open to recommendations on how to make this more useful.

    Also, I wasn't sure how to correctly call CFRelease on a SecKeychainItemRef variable. In the end, I removed the Opaque version in security-framework-sys/src/base.rs. Better alternatives welcome.

    • Able to get, set, modify, and delete generic passwords in the keychain.
    • Only works with the default keychain search list.
    • Currently no support for internet passwords.
    • All tests pass.
    opened by neonquill 14
  • Propagate panics harder

    Propagate panics harder

    Once a Connection has panicked in I/O it's effectively poisoned and we shouldn't come back to it (due to a lack of UnwindSafe bound). Set a flag on Connection and bail early before we access the stream.

    opened by alexcrichton 12
  • Make Error not Copy

    Make Error not Copy

    It is required to implement #114: error cannot be encoded as copyable type, because error may contain a string, like a domain name.

    Technically this is a backwards-incompatible change, but this is important, so better do it early.

    opened by stepancheg 11
  • "The trust policy was not trusted."

    I'm using native-tls with Tokio to set up encrypted IRC connections. When I attempt to connect to my server irc.pdgn.co, I get a TlsError saying "The trust policy was not trusted." This also occurs when I'm trying to connect to chat.freenode.net over TLS. Both servers use Lets Encrypt certificates. I haven't tested with anything that uses another CA (because I don't know of any IRC servers that do).

    Here is the full chain in pem format for one of my servers:

    -----BEGIN CERTIFICATE-----
    MIIFDzCCA/egAwIBAgISBMCp9mv7iTtbgkA8t5uuALq5MA0GCSqGSIb3DQEBCwUA
    MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD
    ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0xNzA1MDIyMDEzMDBaFw0x
    NzA3MzEyMDEzMDBaMBoxGDAWBgNVBAMTD2NvbHVtYmEucGRnbi5jbzCCASIwDQYJ
    KoZIhvcNAQEBBQADggEPADCCAQoCggEBAOO14hNklUQyfdedvU3m48WZzEC7c9mu
    2j9pKCnZdQsPJ9G6Aa2AfdBqZOoBpOiFPeXlArfjzdMfzRCg3dVJp6eS9CLdwvf/
    z0zqOPU7CbTsIP6gvyqAlys//EznJsC1o0NBl1dSYyHFZf3Pg0UJhMliyrVivMa6
    0Lr/aCjL8svZi+kWaT+c0hST7h6ulQtcF3v+hjF1iMHBRVwkuaenNsaaZzqjky7X
    skSlzV1jseaMMoCo7XoyZGPKgxU29qSzvyPu+hpOwyxqjAQwi346YkOKpSvB8tGm
    OAlR4pSQnF6DdmI+/iTfXc69IX6jzFqF/IAIdvervRK3KtKkTBHyVmECAwEAAaOC
    Ah0wggIZMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYB
    BQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQU/L1Wd+Ol04xJv8BdvqDcC20G
    VKYwHwYDVR0jBBgwFoAUqEpqYwR93brm0Tm3pkVl7/Oo7KEwcAYIKwYBBQUHAQEE
    ZDBiMC8GCCsGAQUFBzABhiNodHRwOi8vb2NzcC5pbnQteDMubGV0c2VuY3J5cHQu
    b3JnLzAvBggrBgEFBQcwAoYjaHR0cDovL2NlcnQuaW50LXgzLmxldHNlbmNyeXB0
    Lm9yZy8wJwYDVR0RBCAwHoIPY29sdW1iYS5wZGduLmNvggtpcmMucGRnbi5jbzCB
    /gYDVR0gBIH2MIHzMAgGBmeBDAECATCB5gYLKwYBBAGC3xMBAQEwgdYwJgYIKwYB
    BQUHAgEWGmh0dHA6Ly9jcHMubGV0c2VuY3J5cHQub3JnMIGrBggrBgEFBQcCAjCB
    ngyBm1RoaXMgQ2VydGlmaWNhdGUgbWF5IG9ubHkgYmUgcmVsaWVkIHVwb24gYnkg
    UmVseWluZyBQYXJ0aWVzIGFuZCBvbmx5IGluIGFjY29yZGFuY2Ugd2l0aCB0aGUg
    Q2VydGlmaWNhdGUgUG9saWN5IGZvdW5kIGF0IGh0dHBzOi8vbGV0c2VuY3J5cHQu
    b3JnL3JlcG9zaXRvcnkvMA0GCSqGSIb3DQEBCwUAA4IBAQBDbmlcU53FxJryuWFV
    CBOjDTGjoTrgqTNwiwrvaR4McOknTDJdfAsVtCfBIkE3usAJA9vHTlAVq9lO8jdb
    JkRmfAHiaZ0wYKyDbNOipV91E3R2oiiC4odUXuy1h1TGrJ9GYQ/nd0L9nRdS/8zI
    BG64itXdUlsUvUi3vYzRUHcA1WsJ4ZBWwfBgzafoqzPi//Z0DDTaK3rWcIP0eRIu
    zjV69T+UE0U0A6SXaOe99rXp3GCfe0sDLGOc+LgBRfWAN0ODEj/+6vIAR9nmCQ3G
    VirY236kv3mOO3/AlVsQn27uLXj/Jid5/DHv5rEwNX/1gc12X306J8AWRfH1+BHA
    Q3T5
    -----END CERTIFICATE-----
    -----BEGIN CERTIFICATE-----
    MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/
    MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
    DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow
    SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT
    GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC
    AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF
    q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8
    SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0
    Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA
    a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj
    /PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T
    AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG
    CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv
    bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k
    c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw
    VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC
    ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz
    MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu
    Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF
    AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo
    uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/
    wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu
    X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG
    PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6
    KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==
    -----END CERTIFICATE-----
    

    Here is the relevant portion of code:

    let domain = format!("{}:{}", config.server(), config.port());
    let connector = TlsConnector::builder()?.build()?;
    let stream = TcpStream::connect(&config.socket_addr(), handle).map_err(|e| {
        let res: error::Error = e.into();
        res
    }).and_then(move |socket| {
        connector.connect_async(&domain, socket).map_err(|e| e.into())
    }).boxed();
    
    opened by aatxe 11
  • Keychain Services support

    Keychain Services support

    FYI, I've started writing a crate which provides a somewhat idiomatic Keychain Services binding:

    https://github.com/iqlusioninc/keychain-services-rs

    I'd be interested in trying to contribute its functionality upstream to this crate, or otherwise finding a way to share code (e.g. SecKey).

    See also: https://github.com/iqlusioninc/keychain-services-rs/issues/3

    help wanted 
    opened by tarcieri 10
  • Calling it 1.0

    Calling it 1.0

    The interface of the library has been stable for over a year. I don't see a need to do any major changes. Would it be fine to release it as 1.0?

    Is there some semver-breaking tweak that you'd like to do before it's called final?

    question 
    opened by kornelski 8
  • security-framework-sys: Update core-foundation-sys dependency

    security-framework-sys: Update core-foundation-sys dependency

    security-framework-sys currently depends on:

    core-foundation-sys = "0.5.1"
    

    even though the latest released version is 0.6.2. Would you mind bumping the dependency? Thanks!

    opened by kpcyrd 8
  • Allow calling functions that may not exist

    Allow calling functions that may not exist

    This crate uses Cargo features to define the API, gating access to APIs which weren't enabled. This isn't necessarily always the desired use case, however. Sometimes a binary wants to be compiled as maximally flexible (e.g runs almost anywhere) but still call newer APIs where it can.

    To accommodate this use case, this commit implements a fallback for APIs where features are not enabled. Currently this is just a proof-of-concept for one function to gauge interest, but the theory is that this could generally apply to many APIs to provide a uniform API for this crate across all OS versions.

    Technically speaking, this enables a feature where when an FFI function wouldn't otherwise be defined we define our own. Our own wrapper then looks up the symbol at runtime (via dlopen + dlsym) and caches the result in a global. The wrapper then also provides a fallback implementation which typically just returns an error. This is similar to what's done in the standard library as well.

    opened by alexcrichton 7
  • Add subject, issuer, and serial_number methods

    Add subject, issuer, and serial_number methods

    These methods expose the subject, issuer and serial number fields in their DER-encoded form.

    Happy to write tests, just not sure what style would fit best with the package. Would you prefer comparing against a hard coded values (byte vectors or files) or adding a test dependency on a package that can programmatically build X.509 names?

    opened by brandonweeks 6
  • New Release

    New Release

    Hey, When you get a chance, think you could review PRs #34, #35, and then cut a release? I have some rust-native-tls work that depends on master and the outstanding PRs, and then some hyper-native-tls stuff on top of that so it'd be nice to clean up my local replaces a bit :)

    Let me know if any of the open issues are blockers to a new release, and I'd be glad to help with them.

    opened by jchien14 6
  • Add option to allow connections with invalid ssl certificates

    Add option to allow connections with invalid ssl certificates

    Motivation

    I know this is just... wrong, and everyone should be using letsencrypt, or adding their self-signed cert as a trusted root. Allowing invalid SSL connections is still a "feature" that rust doesn't have, and I'd like to fix that.

    Changes

    This change adds an optional flag onto the ClientBuilder to accept invalid certificates.

    Previously

    The validation logic treated the RecoverableTrustFailure identically to the FatalTrustFailure. Upon a limited reading of the documentation, it seems as though the intended use of the RecoverableTrustFailure was to allow the user to opt into the insecure connection.

    Now

    During validation, if we get a RecoverableTrustFailure, and the user has opted into allowing invalid certs, I treat it just like a Proceed. If the user has not opted-in, the result is the same as it was before.

    In keeping with rust's theme of not wanting you to shoot yourself in the foot, I've named the function danger_accept_invalid_certs(), and put a big warning in the doc comments. If you want this to be more obnoxious name, I'm open to suggestions.

    Testing

    I added a test-case from badssl.com. I also tested this by making connections to a variety of bad servers from my osx workstation.

    opened by scottschroeder 5
  • write() should not return the error from write_func()

    write() should not return the error from write_func()

    First of all thanks a lot for this lib, helps a lot writing stuff for apple ecosystem.

    As far as I understand from apple documentation, SSLWrite() will call SSLWriteFunc(), but if there is any kind of error returned by SSLWriteFunc(), SSLWrite() itself will return an error of its own, ie there is no responsibility the coder has to "save" the error returned by SSLWriteFunc() and then check that after calling SSLWrite() etc.. In fact, doing that might be erroneous - consider this example.

    1. We called SSLWrite(), SSLWriteFunc() might have returned errSslWouldBlock, but SSLWrite() itself succeeded because SSL lib is gonna buffer up the data we provide (and encrypt it and call SSLWriteFunc() on the encrypted data) - so the library has now "cached" an error errSslWouldBlock in conn.err
    2. Later again we call SSLWrite(), this time just as an example say there was some error and the API returned errSSLPeerCertExpired
    3. Now write() will go and check conn.err and will find errSslWouldBlock and that is what the caller to write() gets as an error, which is incorrect

    So in summary, IMO there is no need to cache conn.err and return it - unless there was a reason for it, which ill be curious to know

    opened by gopakumarce 3
  • Is there a better approach than the minimum OS version feature flags?

    Is there a better approach than the minimum OS version feature flags?

    There have been some occasions where people introduce new APIs but forget to properly specify the respective supported OS or minimum OS version, which is understandable because it's easy to get wrong. I wouldn't be surprised if there were APIs in use today that aren't behind the correct feature flags.

    Off the top of my head there might be two ways to improve the situation:

    • Make use of -mmacosx-version-min and related flags to get compile time warnings (ideally errors?) about using APIs which won't be available for the target. If this an improvement, how can we make it easy for users of the crate to use this approach? Are there any issues regarding cross compilation?
    • Perhaps bindgen could be extended to expose availability info and create feature flags for the rust implementations?

    If anyone has thoughts or other suggestions I'd love to hear them.

    opened by steven-joruk 5
  • THIRD_PARTY License

    THIRD_PARTY License

    WRT: APPLE PUBLIC SOURCE LICENSE

    The license states, "This project contains documentation adapted from Apple Inc.'s Security Framework".

    What documentation necessitates this license? I was hoping to use this in a project but this license is an issue for us.

    opened by mboetger 3
  • Memory leak on macOS Catalina

    Memory leak on macOS Catalina

    See sfackler/rust-native-tls#171, which also contains the test program for the leak. Cargo.lock says:

    [[package]]
    name = "security-framework"
    version = "0.4.4"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "64808902d7d99f78eaddd2b4e2509713babc3dc3c85ad6f4c447680f3c01e535"
    dependencies = [
     "bitflags",
     "core-foundation",
     "core-foundation-sys",
     "libc",
     "security-framework-sys",
    ]
    
    [[package]]
    name = "security-framework-sys"
    version = "0.4.3"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "17bf11d99252f512695eb468de5516e5cf75455521e69dfe343f3b74e4748405"
    dependencies = [
     "core-foundation-sys",
     "libc",
    ]
    

    Note that I have limited access to macOS machines, and can't run GUI tools such as Instruments.

    help wanted 
    opened by inejge 2
  • Run tests under sanitizers when they're available

    Run tests under sanitizers when they're available

    The nightly toolchain had support for compiling with sanitizers enabled up until a recent regression, which will soon be fixed: https://github.com/rust-lang/rust/pull/65241

    Once it's resolved it would be good to run the tests using them, I intended to for the authorization PR given that Valgrind is also still broken on macOS, but no luck :(

    opened by steven-joruk 0
Releases(v0.4.1)
  • v0.4.1(Feb 1, 2020)

  • v0.3.0(Apr 20, 2019)

    • Bump to 0.3 due to core-foundation-sys upgrade (Kornel)
    • Upgrade ctest (Kornel)
    • Fix for older rustc (#77) (Sergej Jurečko)
    • Public key DER export (#75) (Sergej Jurečko)
    • additional exports and wrappers (#73) (Sergej Jurečko)
    • Remove dependency on MacTypes-sys (luben karavelov)
    • Improve Keychain Item SearchResult(s). (Geoff Cant)
    Source code(tar.gz)
    Source code(zip)
  • v0.2.2(Jan 19, 2019)

    • Add ALPN protocols bindings (Qifan Lu)
    • macOS Keychain support for Generic and Internet passwords (David Watson, Kornel Lesiński)
    • Add bindings for password functions (David Watson)
    • Support ALPN with weak linkage (Kazuyoshi Kato)
    • Update secure_transport.rs (Christoph Walcher)
    Source code(tar.gz)
    Source code(zip)
  • v0.2.1(Jun 1, 2018)

  • v0.2.0(Mar 24, 2018)

    • Dropped support for OSX 10.7.
    • Replaced enums with wrapper types and associated constants.
    • SNI and hostname verification are now configured separately in ClientBuilder.
    Source code(tar.gz)
    Source code(zip)
  • v0.1.10(Dec 20, 2016)

  • v0.1.9(Nov 8, 2016)

    • SslStream no longer calls SSLClose in its destructor. A close method has been added instead.
    • Add SslContext::set_protocol_version_enabled. This is deprecated, but the replacement is not available on OSX 10.8.
    • Implement Sync and Send for all types.
    • Error now has a public constructor.
    • Add MidHandshakeSslStream::error.
    Source code(tar.gz)
    Source code(zip)
Owner
Kornel
Rust, image compression, web performance.
Kornel
Automate device security provisioning with edge intelligence.

UNiD Automate device security provisioning with edge intelligence Features Decentralized PKI(DPKI), DIDs, DKMS, and Credential Management End-to-End E

UNiD 101 Oct 21, 2022
OpenSK is an open-source implementation for security keys written in Rust that supports both FIDO U2F and FIDO2 standards.

OpenSK This repository contains a Rust implementation of a FIDO2 authenticator. We developed OpenSK as a Tock OS application. We intend to bring a ful

Google 2.4k Jan 7, 2023
A utility like pkg-audit for Arch Linux. Based on Arch Security Team data.

arch-audit pkg-audit-like utility for Arch Linux. Based on data from security.archlinux.org collected by the awesome Arch Security Team. Installation

Andrea Scarpino 316 Nov 22, 2022
The Swiss Army Knife for Binary (In)security

binsec Swiss Army Knife for Binary (In)security binsec is a minimal static analysis utility for detecting security capabilities in ELF/PE/Mach-O execu

Alan 15 Dec 16, 2022
A Rust implementation of the Message Layer Security group messaging protocol

Molasses An extremely early implementation of the Message Layer Security group messaging protocol. This repo is based on draft 4 of the MLS protocol s

Trail of Bits 109 Dec 13, 2022
Minimal and persistent key-value store designed with security in mind

microkv Minimal and persistent key-value store designed with security in mind. Introduction microkv is a persistent key-value store implemented in Rus

Alan 17 Jan 2, 2023
Applied offensive security with the Rust programming language

Black Hat Rust Applied offensive security with the Rust programming language Buy the book now! While the Rust Book does an excellent job teaching What

Sylvain Kerkour 2.2k Jan 8, 2023
Audit Cargo.lock files for dependencies with security vulnerabilities

RustSec Crates ?? ??️ ?? The RustSec Advisory Database is a repository of security advisories filed against Rust crates published via crates.io. The a

RustSec 1.2k Jan 5, 2023
Security advisory database for Rust crates published through crates.io

RustSec Advisory Database The RustSec Advisory Database is a repository of security advisories filed against Rust crates published via https://crates.

RustSec 682 Jan 1, 2023
🕵️‍♀️ Find, locate, and query files for ops and security experts ⚡️⚡️⚡️

Recon Find, locate, and query files for ops and security experts Key Features • How To Use • Download • Contributing • License Key Features Query with

Rusty Ferris Club 11 Dec 16, 2022
irulescan is a static security analyzer for iRules

irulescan is a tool to scan iRules for unexpected/unsafe expressions that may have undesirable effects like double substitution.

Simon Kowallik 2 Dec 18, 2022
Rust bindings for libinjection

libinjection-rs Rust bindings for libinjection. How to use Add libinjection to dependencies of Cargo.toml: libinjection = "0.2" Import crate: extern c

ArvanCloud 35 Sep 24, 2022
Rust bindings for VirusTotal/Yara

yara-rust Bindings for the Yara library from VirusTotal. More documentation can be found on the Yara's documentation. Example The implementation is in

null 43 Dec 17, 2022
Rust bindings for the unicorn CPU emulator

unicorn-rs THIS PACKAGE IS DEPRECATED AND NO LONGER MAINTAINED. Rust bindings are now included with unicorn and will be maintained there from now on.

null 129 Oct 10, 2022
An esoteric language/compiler written with Rust and Rust LLVM bindings

MeidoLang (メイドラング) A not so useful and esoteric language. The goal of this project was to contain some quirky or novel syntax in a stack-style program

null 0 Dec 24, 2021
Semi-automatic OSINT framework and package manager

sn0int sn0int (pronounced /snoɪnt/) is a semi-automatic OSINT framework and package manager. It was built for IT security professionals and bug hunter

null 1.4k Dec 31, 2022
link is a command and control framework written in rust

link link is a command and control framework written in rust. Currently in alpha. Table of Contents Introduction Features Feedback Build Process Ackno

null 427 Dec 24, 2022
Rust implementation of The Update Framework (TUF)

rust-tuf A Rust implementation of The Update Framework (TUF). Full documentation is hosted at docs.rs. Warning: Beta Software This is under active dev

heartsucker 152 Dec 11, 2022
A fuzzer framework built in Rust

lain This crate provides functionality one may find useful while developing a fuzzer. A recent nightly Rust build is required for the specialization f

Microsoft 469 Dec 9, 2022