Skip to content

Commit

Permalink
Merge pull request #20 from iqlusioninc/2018-edition
Browse files Browse the repository at this point in the history
Update to 2018 edition
  • Loading branch information
tony-iqlusion authored Dec 10, 2018
2 parents 787a67d + c9fa31f commit f5d6e4b
Show file tree
Hide file tree
Showing 17 changed files with 64 additions and 112 deletions.
16 changes: 8 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
[package]
name = "keychain-services"
description = """
Rust access to macOS Keychain Services, including TouchID-guarded
access to cryptographic keys stored in the Secure Enclave
Processor (SEP).
"""

name = "keychain-services"
description = """
Rust access to macOS Keychain Services, including TouchID-guarded
access to cryptographic keys stored in the Secure Enclave
Processor (SEP).
"""
version = "0.1.0"
authors = ["Tony Arcieri <tony@iqlusion.io>"]
license = "Apache-2.0"
Expand All @@ -15,10 +14,11 @@ repository = "/~https://github.com/iqlusioninc/keychain-services-rs/"
readme = "README.md"
categories = ["api-bindings", "authentication", "cryptography", "hardware-support"]
keywords = ["ecdsa", "macos", "keychain", "touchid", "signatures"]
edition = "2018"

[badges]
maintenance = { status = "experimental" }
travis-ci = { repository = "iqlusioninc/keychain-services-rs" }
travis-ci = { repository = "iqlusioninc/keychain-services.rs" }

[dependencies]
core-foundation = "0.6"
Expand Down
7 changes: 2 additions & 5 deletions src/access.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! Keychain item access control types: ACLs and policies around usage of
//! private keys stored in the keychain.
use crate::{attr::AttrAccessible, error::Error, ffi::*};
use core_foundation::{
base::{kCFAllocatorDefault, CFOptionFlags, TCFType},
error::CFErrorRef,
Expand All @@ -10,10 +11,6 @@ use std::{
ptr,
};

use attr::AttrAccessible;
use error::Error;
use ffi::*;

/// Marker trait for types which can be used as `AccessControlFlags`.
pub trait AccessControlFlag: Copy + Clone + Sized + Into<CFOptionFlags> {}

Expand Down Expand Up @@ -163,7 +160,7 @@ where
}
}

declare_TCFType!{
declare_TCFType! {
/// Access control policy (a.k.a. ACL) for a keychain item, combining both a
/// set of `AccessControlFlags` and a `AttrAccessible` restriction.
///
Expand Down
3 changes: 1 addition & 2 deletions src/attr.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Keychain item attributes (i.e. `SecAttr*`)
use crate::ffi::*;
use core_foundation::{
base::{CFType, TCFType, ToVoid},
data::CFData,
Expand All @@ -11,8 +12,6 @@ use std::{
str::{self, Utf8Error},
};

use ffi::*;

/// Trait implemented by all `Attr*` types to simplify adding them to
/// attribute dictionaries.
pub(crate) trait TAttr {
Expand Down
5 changes: 1 addition & 4 deletions src/dictionary.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Builder for constructing a `CFDictionary` from attribute pairs.
use crate::{attr::TAttr, ffi::kSecClass, keychain::item};
use core_foundation::{
self,
base::{CFType, TCFType},
Expand All @@ -8,10 +9,6 @@ use core_foundation::{
string::{CFString, CFStringRef},
};

use attr::TAttr;
use ffi::kSecClass;
use keychain::item;

/// All CFDictionary types we use follow this signature
pub(crate) type Dictionary = core_foundation::dictionary::CFDictionary<CFType, CFType>;

Expand Down
9 changes: 2 additions & 7 deletions src/error.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Error types
use crate::ffi::*;
use core_foundation::{
base::{CFRelease, CFTypeRef, OSStatus, TCFType},
error::{CFErrorCopyDescription, CFErrorGetCode, CFErrorGetDomain, CFErrorRef},
Expand All @@ -11,8 +12,6 @@ use std::{
io, ptr,
};

use ffi::*;

/// No error occurred.
/// <https://developer.apple.com/documentation/security/errsecsuccess>
const errSecSuccess: OSStatus = 0;
Expand Down Expand Up @@ -468,11 +467,7 @@ pub enum ErrorKind {
///
/// For more information, see:
/// <https://developer.apple.com/documentation/corefoundation/1494656-cferrorgetcode?language=objc>
#[fail(
display = "Core Foundation error (code: {}, domain: {})",
code,
domain
)]
#[fail(display = "Core Foundation error (code: {}, domain: {})", code, domain)]
CFError {
/// Code identifying this type of `CFError`.
///
Expand Down
3 changes: 1 addition & 2 deletions src/keychain/item/class.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use crate::ffi::*;
use core_foundation::{base::TCFType, string::CFString};

use ffi::*;

/// Classes of keychain items supported by Keychain Services
/// (not to be confused with `SecAttrClass` or `SecType`)
///
Expand Down
24 changes: 12 additions & 12 deletions src/keychain/item/mod.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
//! Items stored in a keychain (e.g. certificates, keys, passwords)
use core_foundation::base::TCFType;
use std::{mem, os::raw::c_void, ptr, slice};

use attr::AttrKind;
use error::*;
use ffi::*;

mod class;
mod password;
mod query;

pub use self::{class::*, password::*, query::*};
use crate::{attr::AttrKind, error::*, ffi::*};
use core_foundation::base::TCFType;
use std::{mem, os::raw::c_void, ptr, slice};

declare_TCFType!{
declare_TCFType! {
/// Items stored in the keychain.
///
/// Wrapper for the `SecKeychainItem`/`SecKeychainItemRef` types:
Expand All @@ -36,7 +32,8 @@ impl Item {
ptr::null_mut(),
ptr::null_mut(),
)
}).unwrap();
})
.unwrap();

result.into()
}
Expand Down Expand Up @@ -70,7 +67,8 @@ impl Item {
// Free the original data
Error::maybe_from_OSStatus(unsafe {
SecKeychainItemFreeContent(ptr::null_mut(), result_ptr as *mut c_void)
}).unwrap();
})
.unwrap();

Ok(result)
}
Expand All @@ -89,11 +87,13 @@ impl Item {
} else {
false
}
}).map(|attr| String::from_utf8(attr.data().unwrap().into()).unwrap());
})
.map(|attr| String::from_utf8(attr.data().unwrap().into()).unwrap());

Error::maybe_from_OSStatus(unsafe {
SecKeychainItemFreeContent(&mut attrs, ptr::null_mut())
}).unwrap();
})
.unwrap();

result.ok_or_else(|| {
Error::new(
Expand Down
7 changes: 1 addition & 6 deletions src/keychain/item/password.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
use crate::{attr::*, dictionary::DictionaryBuilder, error::Error, ffi::*, keychain::*};
use std::str;
use zeroize::Zeroize;

use attr::*;
use dictionary::DictionaryBuilder;
use error::Error;
use ffi::*;
use keychain::*;

/// Generic passwords
pub struct GenericPassword(Item);

Expand Down
5 changes: 1 addition & 4 deletions src/keychain/item/query.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
//! Query the keychain, looking for particular items
use crate::{attr::*, dictionary::DictionaryBuilder, ffi::*};
use core_foundation::{
base::{CFType, TCFType},
number::CFNumber,
string::CFString,
};

use attr::*;
use dictionary::DictionaryBuilder;
use ffi::*;

/// Limit the number of matched items to one or an unlimited number.
///
/// Wrapper for the `kSecMatchLimit` attribute key. See:
Expand Down
3 changes: 1 addition & 2 deletions src/keychain/key/algorithm.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use crate::ffi::*;
use core_foundation::{base::TCFType, string::CFString};

use ffi::*;

/// Cryptographic algorithms for use with keys stored in the keychain.
///
/// Wrapper for `SecKeyAlgorithm`. See:
Expand Down
26 changes: 13 additions & 13 deletions src/keychain/key/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
//! Keys stored in macOS Keychain Services.
mod algorithm;
mod pair;

pub use self::{algorithm::*, pair::*};
use crate::{
attr::*,
dictionary::{Dictionary, DictionaryBuilder},
error::Error,
ffi::*,
keychain::item::{self, MatchLimit},
signature::Signature,
};
use core_foundation::{
base::{CFTypeRef, TCFType},
data::{CFData, CFDataRef},
Expand All @@ -11,19 +23,7 @@ use std::{
ptr,
};

use attr::*;
use dictionary::{Dictionary, DictionaryBuilder};
use error::Error;
use ffi::*;
use keychain::item::{self, MatchLimit};
use signature::Signature;

mod algorithm;
mod pair;

pub use self::{algorithm::*, pair::*};

declare_TCFType!{
declare_TCFType! {
/// Object which represents a cryptographic key.
///
/// Wrapper for the `SecKey`/`SecKeyRef` types:
Expand Down
7 changes: 2 additions & 5 deletions src/keychain/key/pair.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
use super::*;
use crate::{access::AccessControl, dictionary::*, error::Error};
use core_foundation::base::TCFType;
use std::ptr;

use super::*;
use access::AccessControl;
use dictionary::*;
use error::Error;

/// Public key pairs (i.e. public and private key) stored in the keychain.
#[derive(Debug)]
pub struct KeyPair {
Expand Down
14 changes: 6 additions & 8 deletions src/keychain/mod.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
//! Keychains
use core_foundation::base::{CFTypeRef, TCFType};
use std::{ffi::CString, os::raw::c_char, os::unix::ffi::OsStrExt, path::Path, ptr};

use dictionary::*;
use error::Error;
use ffi::*;

pub mod item;
pub mod key;

use self::item::MatchLimit;
pub use self::{item::Item, key::Key};
use crate::dictionary::*;
use crate::error::Error;
use crate::ffi::*;
use core_foundation::base::{CFTypeRef, TCFType};
use std::{ffi::CString, os::raw::c_char, os::unix::ffi::OsStrExt, path::Path, ptr};

declare_TCFType!{
declare_TCFType! {
/// Keychains which store cryptographic keys, passwords, and other secrets.
///
/// Wrapper for the `SecKeychain`/`SecKeychainRef` types:
Expand Down
32 changes: 9 additions & 23 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,28 +40,14 @@
#![crate_name = "keychain_services"]
#![crate_type = "rlib"]
#![allow(
unknown_lints,
suspicious_arithmetic_impl,
non_snake_case,
non_upper_case_globals
)]
#![deny(
warnings,
missing_docs,
unused_import_braces,
unused_qualifications
)]
#![allow(non_snake_case, non_upper_case_globals)]
#![deny(warnings, missing_docs, unused_import_braces, unused_qualifications)]

#[cfg(not(target_os = "macos"))]
compile_error!("This crate presently only compiles on macOS.");
compile_error!("This crate presently only compiles on macOS (see GH issue #5 for iOS support)");

#[macro_use]
extern crate core_foundation;
extern crate failure;
#[macro_use]
extern crate failure_derive;
extern crate zeroize;

mod access;
mod attr;
Expand All @@ -71,9 +57,9 @@ mod ffi;
pub mod keychain;
mod signature;

pub use access::*;
pub use attr::*;
pub use error::*;
pub use key::*;
pub use keychain::*;
pub use signature::*;
pub use crate::access::*;
pub use crate::attr::*;
pub use crate::error::*;
pub use crate::key::*;
pub use crate::keychain::*;
pub use crate::signature::*;
2 changes: 1 addition & 1 deletion src/signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//! This type doesn't map directly to any type in the Keychain Services API,
//! but instead provides a newtype for signatures this binding produces.
use key::KeyAlgorithm;
use crate::key::KeyAlgorithm;

/// Cryptographic signatures
#[derive(Clone, Debug)]
Expand Down
8 changes: 2 additions & 6 deletions tests/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@
//! This suite is mainly intended to run in CI. See `tests/interactive.rs`
//! for notes on how to run the full test suite.
extern crate keychain_services;
extern crate ring;
extern crate tempfile;
extern crate untrusted;

use keychain_services::*;

const TEST_MESSAGE: &[u8] = b"Embed confidential information in items that you store in a keychain";
Expand Down Expand Up @@ -35,5 +30,6 @@ fn generate_and_sign_with_ecdsa_keys() {
untrusted::Input::from(&public_key_bytes),
untrusted::Input::from(TEST_MESSAGE),
untrusted::Input::from(signature.as_ref()),
).unwrap();
)
.unwrap();
}
5 changes: 1 addition & 4 deletions tests/interactive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,7 @@
//!
//! <https://developer.apple.com/library/archive/documentation/Security/Conceptual/CodeSigningGuide/Procedures/Procedures.html>
// TODO: these aren't working correctly yet.

extern crate keychain_services;
extern crate tempfile;
// TODO: these tests presently fail (possibly due to a codesigning issue?)

use keychain_services::*;
use tempfile::TempDir;
Expand Down

0 comments on commit f5d6e4b

Please sign in to comment.