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
MyCitadel Wallet app for Linux, Windows & MacOS desktop made with GTK+

MyCitadel Desktop Bitcoin, Lightning and RGB wallet MyCitadel is a wallet for bitcoin, digital assets and bitcoin finance (#BiFi) smart contracts. It

My Citadel 88 Jan 2, 2023
VVVVVV autosplitter for macOS and Linux

Vitellary Vitellary is a work-in-progress autosplitter for VVVVVV v2.3.6 on macOS and Linux systems. More notes here soon when it’s done. Thanks / See

iliana etaoin 5 Mar 6, 2023
Nostr Vanity Address Generator (Windows, Linux and macOS)

Nostr Vanity Address Generator CLI tool to generate vanity addresses for Nostr Usage Download the latest release built by GitHub CI from the releases

Chawye Hsu 7 Mar 1, 2023
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
A suite of programs for Solana key management and security.

?? goki Goki is a suite of programs for Solana key management and security. It currently features: Goki Smart Wallet: A wallet loosely based on the Se

Goki Protocol 157 Dec 8, 2022
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 Dec 30, 2022
An uploader honeypot designed to look like poor website security.

HoneyUp An uploader honeypot designed to look like poor website security. Requirements Linux server NGiNX Rust toolchain (build only) Installation Bui

Chad Baxter 21 Dec 20, 2022
Ingraind - a security monitoring agent built around RedBPF for complex containerized environments and endpoints.

ingraind is a security monitoring agent built around RedBPF for complex containerized environments and endpoints. The ingraind agent uses eBPF probes to provide safe and performant instrumentation for any Linux-based environment.

KingoOo 5 Apr 6, 2022
security.txt for Solana Contracts

security.txt This library defines a macro, which allows developers to provide easy-to-parse information to security researchers that wish to contact t

Neodyme 79 Dec 28, 2022
Automated security testing for open source libraries and applications.

autovet continuously searches for security breaches in open source libraries and applications. Recently processed packages package version channel las

null 5 Aug 23, 2022
Koofr Vault is an open-source, client-side encrypted folder for your Koofr cloud storage offering an extra layer of security for your most sensitive files.

Koofr Vault https://vault.koofr.net Koofr Vault is an open-source, client-side encrypted folder for your Koofr cloud storage offering an extra layer o

Koofr 12 Dec 30, 2022
Implementation of Sunny's Mesh Security talk (Hackathon / Prototype status)

mesh-security (Hackathon / Prototype status) An implementation of Sunny's Mesh Security talk from Cosmoverse 2022. This should run on any CosmWasm ena

CosmWasm 83 Apr 17, 2023
A CLI application that implements multi-key-turn security via Shamir's Secret Sharing.

agree agree is a CLI tool for easily applying multi-key-turn security via Shamirs Secret Sharing. Project state agree is unstable. Version semantics:

Alexander Weber 19 Aug 29, 2023
Standing watch over the Pi Network, PiSentinel is a consensus algorithm that safeguards security, decentralization, and scalability.

pi-sentinel Standing watch over the Pi Network, PiSentinel is a consensus algorithm that safeguards security, decentralization, and scalability. Intro

KOSASIH 3 Aug 4, 2024
Glommio Messaging Framework (GMF) is a high-performance RPC system designed to work with the Glommio framework.

Glommio Messaging Framework (GMF) The GMF library is a powerful and innovative framework developed for facilitating Remote Procedure Calls (RPCs) in R

Mohsen Zainalpour 29 Jun 13, 2023
Sodium Oxide: Fast cryptographic library for Rust (bindings to libsodium)

sodiumoxide |Crate|Documentation|Gitter| |:---:|:-----------:|:--------:|:-----:|:------:|:----:| |||| NaCl (pronounced "salt") is a new easy-to-use h

sodiumoxide 642 Dec 17, 2022
rust-native-tls — Bindings for native TLS libraries

rust-native-tls Documentation An abstraction over platform-specific TLS implementations. Specifically, this crate uses SChannel on Windows (via the sc

Steven Fackler 371 Jan 8, 2023
OpenSSL bindings for Rust

rust-openssl OpenSSL bindings for the Rust programming language. Documentation. Release Support The current supported release of openssl is 0.10 and o

Steven Fackler 1k Jan 7, 2023
Rust FFI bindings for StarkWare's crypto-cpp library

starkware-crypto-rs Rust FFI bindings for StarkWare's crypto-cpp library Note that currently target x86_64-pc-windows-msvc is not supported. If you're

Jonathan LEI 11 Aug 22, 2022