Code Monkey home page Code Monkey logo

Comments (19)

sfackler avatar sfackler commented on July 17, 2024 4

Looks like that works just fine: kornelski/rust-security-framework@4ba1d68

I just need to add some similar functionality to schannel and we'll be able to get rid of the PKCS#12 silliness.

from rust-native-tls.

sfackler avatar sfackler commented on July 17, 2024 2

Success, thanks @jethrogb! steffengy/schannel-rs#31

from rust-native-tls.

briansmith avatar briansmith commented on July 17, 2024

/cc @aidanhs. This is related to #26.

from rust-native-tls.

sfackler avatar sfackler commented on July 17, 2024

PKCS#12 was not my first choice either, but it wasn't clear to me how to get a SecIdentity from separate key and cert files on the macOS side.

from rust-native-tls.

shepmaster avatar shepmaster commented on July 17, 2024

but it wasn't clear to me how to get a SecIdentity from separate key and cert files on the macOS side.

I'm sure I'm not adding anything that y'all don't already know, but just in case, it looks like SecIdentityCreateWithCertificate is useful:

    #[test]
    fn identity_pem() {
        let dir = TempDir::new("identity").unwrap();
        let keychain = keychain::CreateOptions::new()
                           .password("password")
                           .create(dir.path().join("identity.keychain"))
                           .unwrap();

        let mut items = SecItems::default();

        let data = include_bytes!("../../../test/localhost.crt");
        ImportOptions::new()
            .filename("localhost.crt")
            .items(&mut items)
            .keychain(&keychain)
            .import(data)
            .unwrap();

        let data2 = include_bytes!("../../../test/localhost.key");
        ImportOptions::new()
            .filename("localhost.key")
            .items(&mut items)
            .keychain(&keychain)
            .import(data2)
            .unwrap();

        unsafe {
            let mut x = ptr::null_mut();
            let ret = ::security_framework_sys::identity::SecIdentityCreateWithCertificate(keychain.as_concrete_TypeRef() as *const _, items.certificates[0].as_concrete_TypeRef(), &mut x);
            if ret != errSecSuccess {
                panic!("{:?}", Error::from_code(ret));
            }

            let x = SecIdentity::wrap_under_create_rule(x);
            panic!("{:?}", x);
        }
    }

Oh high-level inspection, this works:

	thread 'os::macos::import_export::test::identity_pem' panicked at 'SecIdentity { certificate: SecCertificate { subject: "Integer32, LLC" }, private_key: SecKey }', src/os/macos/import_export.rs:316

from rust-native-tls.

sfackler avatar sfackler commented on July 17, 2024

Oh awesome! I somehow missed that method.

from rust-native-tls.

shepmaster avatar shepmaster commented on July 17, 2024

And if useful, the FFI signature (added to security-framework-sys/src/identity.rs):

    pub fn SecIdentityCreateWithCertificate(keychain_rr_array: CFTypeRef,
                                            certificate_ref: SecCertificateRef,
                                            identity_ref: *mut SecIdentityRef)
                                            -> OSStatus;

from rust-native-tls.

sfackler avatar sfackler commented on July 17, 2024

The blocker is now on Windows. I have some WIP changes but can't get them to actually work: https://github.com/sfackler/schannel-rs/tree/key-import. If anyone knows how CryptoAPI works or has friends at Microsoft they can yell at about woefully insufficient documentation, help would be appreciated!

from rust-native-tls.

steffengy avatar steffengy commented on July 17, 2024

@sfackler
interestingly enough switching KeySpec::signature() to KeySpec::key_exchange() gives
80090304 "The Local Security Authority Cannot Be Contacted" as error, but I also have no clue whats going on there. (the TLSStream InitializeSecurityContext call returns that error sec_e_internal_error)

from rust-native-tls.

steffengy avatar steffengy commented on July 17, 2024

@sfackler
I compared your key_import branch against for example
https://github.com/zeroc-ice/ice/blob/master/cpp/src/IceSSL/SChannelEngine.cpp
and changed some stuff to match their implementation (key_exchange, provider, ...).

Still in split_cert_key during the initialization (InitializeSecurityContext) of the stream
(the client thread here) SEC_E_INTERNAL_ERROR is returned.

Feel free to take a look at it, maybe you'll spot something else.

As reference also the current state which returns that error for me as a patch:
https://gist.github.com/steffengy/245ecaa9125928cf788b7e9afdac8730

from rust-native-tls.

jethrogb avatar jethrogb commented on July 17, 2024

@sfackler this works for me on Windows 2016 jethrogb/schannel-rs@7c7660c (Note: I re-extracted the certificate from identity.p12, as it did not contain the right public key, which was not helpful in debugging)

NB a good strategy to get things working is to look at the CERT_KEY_PROV_INFO_PROP_ID from a key imported using ImportPfxOptions.

Note however that your code imports PKCS#1 RSAPrivateKey objects, not PKCS#8 PrivateKeyInfo objects. I haven't tried this, but I think you'd be able to parse PKCS#8 by calling CryptDecodeObjectEx twice, first with PKCS_PRIVATE_KEY_INFO and then with PKCS_RSA_PRIVATE_KEY on the PrivateKey member of CRYPT_PRIVATE_KEY_INFO.

Can we change TlsConnectorBuilder::identity too?

from rust-native-tls.

sfackler avatar sfackler commented on July 17, 2024

Awesome! I'll look into the schannel side again with that help.

I imagine we would get rid of the Identity type in favor of a new PrivateKey type and the existing Certificate type.

from rust-native-tls.

sfackler avatar sfackler commented on July 17, 2024

I have a prototype working in a branch: c7bc56e

Right now you have to provide separate DER files for all of the certificates. A much more common approach is to have a single file with a chain of PEM-formatted certificates. OpenSSL and Security.framework can parse that natively, but I don't think SChannel can, so there'll need to be some amount of extra work for that implementation.

from rust-native-tls.

sfackler avatar sfackler commented on July 17, 2024

The server tests are also very flaky when running in parallel on OSX which is a bit concerning, but I believe that's an unrelated issue.

from rust-native-tls.

nicklan avatar nicklan commented on July 17, 2024

So this looks much better than what's there now. Right now that branch looks like only TlsAcceptor gets the new stuff, but TlsConnector should have it too right? Any idea what the final API for this will look like?

from rust-native-tls.

anowell avatar anowell commented on July 17, 2024

I'm looking to wire this into reqwest and then consume it in a kubernetes client. It seems like using a similar API in reqwest would be ideal, so I'd also love to see the final API here.

from rust-native-tls.

anowell avatar anowell commented on July 17, 2024

And for reference, the overall changes proposed in this thread do seem right for my scenario where I'm pulling a cert and key from a kubernets conf file and currently building a Pkcs12 purely for the sake of plumbing them through to native-tls.

from rust-native-tls.

Goirad avatar Goirad commented on July 17, 2024

@sfackler I am interested in completing this feature. Based on my reading of this thread and linked threads, it seems like it is almost done. What is missing to finish this?

from rust-native-tls.

sfackler avatar sfackler commented on July 17, 2024

There's a (very out of date) branch with some in-progress work: https://github.com/sfackler/rust-native-tls/tree/private-key. I believe the Windows side of things was still a work in progress.

from rust-native-tls.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.