Skip to content

Commit

Permalink
Support identity creation
Browse files Browse the repository at this point in the history
  • Loading branch information
sfackler committed Apr 2, 2017
1 parent 513b872 commit 4ba1d68
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 1 deletion.
7 changes: 6 additions & 1 deletion security-framework-sys/src/identity.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use core_foundation_sys::base::{OSStatus, CFTypeID};
use core_foundation_sys::base::{OSStatus, CFTypeID, CFTypeRef};

use base::{SecCertificateRef, SecKeyRef, SecIdentityRef};

Expand All @@ -10,4 +10,9 @@ extern "C" {
pub fn SecIdentityCopyPrivateKey(identity: SecIdentityRef,
key_ref: *mut SecKeyRef)
-> OSStatus;
#[cfg(target_os = "macos")]
pub fn SecIdentityCreateWithCertificate(keychain_or_Array: CFTypeRef,
certificate_ref: SecCertificateRef,
identity_ref: *mut SecIdentityRef)
-> OSStatus;
}
57 changes: 57 additions & 0 deletions security-framework/src/os/macos/identity.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,49 @@
//! OSX specific extensions to identity functionality.
use core_foundation::array::CFArray;
use core_foundation::base::TCFType;
use std::ptr;
use security_framework_sys::identity::*;

use cvt;
use base::Result;
use certificate::SecCertificate;
use identity::SecIdentity;
use keychain::SecKeychain;

/// An extension trait adding OSX specific functionality to `SecIdentity`.
pub trait SecIdentityExt {
/// Creates an identity corresponding to a certificate, looking in the
/// provided keychains for the corresponding private key.
fn with_certificate(keychains: &[SecKeychain],
certificate: &SecCertificate)
-> Result<SecIdentity>;
}

impl SecIdentityExt for SecIdentity {
fn with_certificate(keychains: &[SecKeychain],
certificate: &SecCertificate)
-> Result<SecIdentity> {
let keychains = CFArray::from_CFTypes(keychains);
unsafe {
let mut identity = ptr::null_mut();
try!(cvt(SecIdentityCreateWithCertificate(keychains.as_CFTypeRef(),
certificate.as_concrete_TypeRef(),
&mut identity)));
Ok(SecIdentity::wrap_under_create_rule(identity))
}
}
}

#[cfg(test)]
mod test {
use tempdir::TempDir;

use os::macos::test::identity;
use os::macos::certificate::SecCertificateExt;
use os::macos::keychain::CreateOptions;
use os::macos::import_export::ImportOptions;
use test;
use super::*;

#[test]
fn certificate() {
Expand All @@ -19,4 +59,21 @@ mod test {
let identity = identity(dir.path());
p!(identity.private_key());
}

#[test]
fn with_certificate() {
let dir = p!(TempDir::new("with_certificate"));

let mut keychain =
p!(CreateOptions::new().password("foobar").create(dir.path().join("test.keychain")));

let key = include_bytes!("../../../test/server.key");
p!(ImportOptions::new()
.filename("server.key")
.keychain(&mut keychain)
.import(key));

let cert = test::certificate();
p!(SecIdentity::with_certificate(&[keychain], &cert));
}
}

0 comments on commit 4ba1d68

Please sign in to comment.