feat: secure enclave is on going
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
|||||||
|
.swiftpm/
|
||||||
.build/
|
.build/
|
||||||
_tinyencrypt_config-rs.json
|
_tinyencrypt_config-rs.json
|
||||||
*.tinyenc
|
*.tinyenc
|
||||||
|
|||||||
2
build.rs
2
build.rs
@@ -4,7 +4,7 @@ use swift_rs::SwiftLinker;
|
|||||||
fn main() {
|
fn main() {
|
||||||
// Ensure this matches the versions set in your `Package.swift` file.
|
// Ensure this matches the versions set in your `Package.swift` file.
|
||||||
#[cfg(feature = "secure-enclave")]
|
#[cfg(feature = "secure-enclave")]
|
||||||
SwiftLinker::new("10.15")
|
SwiftLinker::new("11")
|
||||||
.with_ios("11")
|
.with_ios("11")
|
||||||
.with_package("swift-lib", "./swift-lib/")
|
.with_package("swift-lib", "./swift-lib/")
|
||||||
.link();
|
.link();
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ pub fn version(_cmd_version: CmdVersion) -> XResult<()> {
|
|||||||
#[cfg(feature = "macos")]
|
#[cfg(feature = "macos")]
|
||||||
features.push("macos".to_string());
|
features.push("macos".to_string());
|
||||||
#[cfg(feature = "secure-enclave")]
|
#[cfg(feature = "secure-enclave")]
|
||||||
features.push(format!("secure-enclave{}", iff!(util_keychainkey::is_support_secure_enclave(), "*", "")));
|
features.push(format!("secure-enclave{}", iff!(util_keychainkey::is_support_se(), "*", "")));
|
||||||
if features.is_empty() { features.push("-".to_string()); }
|
if features.is_empty() { features.push("-".to_string()); }
|
||||||
println!(
|
println!(
|
||||||
"User-Agent: {} [with features: {}]\n{}",
|
"User-Agent: {} [with features: {}]\n{}",
|
||||||
|
|||||||
@@ -1,3 +1,12 @@
|
|||||||
pub fn is_support_secure_enclave() -> bool {
|
use swift_rs::{Bool, SRString};
|
||||||
false
|
use swift_rs::swift;
|
||||||
|
|
||||||
|
swift!(fn is_support_secure_enclave() -> Bool);
|
||||||
|
swift!(fn print_greeting(name: SRString) -> Bool);
|
||||||
|
|
||||||
|
pub fn is_support_se() -> bool {
|
||||||
|
unsafe {
|
||||||
|
print_greeting(SRString::from("hatter"));
|
||||||
|
}
|
||||||
|
unsafe { is_support_secure_enclave() }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import PackageDescription
|
|||||||
let package = Package(
|
let package = Package(
|
||||||
name: "swift-lib",
|
name: "swift-lib",
|
||||||
platforms: [
|
platforms: [
|
||||||
.macOS(.v10_15), // macOS Catalina. Earliest version that is officially supported by Apple.
|
.macOS(.v11), // macOS Catalina. Earliest version that is officially supported by Apple.
|
||||||
],
|
],
|
||||||
products: [
|
products: [
|
||||||
// Products define the executables and libraries a package produces, and make them visible to other packages.
|
// Products define the executables and libraries a package produces, and make them visible to other packages.
|
||||||
|
|||||||
@@ -1,5 +1,93 @@
|
|||||||
import SwiftRs
|
import SwiftRs
|
||||||
import AppKit
|
import AppKit
|
||||||
|
import CryptoKit
|
||||||
|
import LocalAuthentication
|
||||||
|
|
||||||
|
// reference:
|
||||||
|
// https://zenn.dev/iceman/scraps/380f69137c7ea2
|
||||||
|
// https://www.andyibanez.com/posts/cryptokit-secure-enclave/
|
||||||
|
@_cdecl("is_support_secure_enclave")
|
||||||
|
func isSupportSecureEnclave() -> Bool {
|
||||||
|
// TODO pending delete
|
||||||
|
let epub = "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE76jmqKrSs8tIVcvYYLpCA2za9GG7VxLdaI8FqynT+G65QgakCjT/P2ey7plz4KEl6ffORfZtZXO+lq2qQaaBHw=="
|
||||||
|
|
||||||
|
guard let ephemeralPublicKeyRepresentation = Data(
|
||||||
|
base64Encoded: epub
|
||||||
|
) else {
|
||||||
|
print("err:ephemeral public key base64 decode failed")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
let a = try CryptoKit.P256.KeyAgreement.PublicKey.init(derRepresentation: ephemeralPublicKeyRepresentation)
|
||||||
|
print("\(a)")
|
||||||
|
} catch {
|
||||||
|
print("error: \(error)")
|
||||||
|
}
|
||||||
|
return SecureEnclave.isAvailable
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO delete print_greeting
|
||||||
|
@_cdecl("print_greeting")
|
||||||
|
func printGreeting(name: SRString) {
|
||||||
|
print("Hello \(name.toString())!")
|
||||||
|
}
|
||||||
|
|
||||||
|
@_cdecl("generate_secure_enclave_p256_keypair")
|
||||||
|
func generateSecureEnclaveP256KeyPair() -> SRString {
|
||||||
|
var error: Unmanaged<CFError>? = nil;
|
||||||
|
guard let accessCtrl = SecAccessControlCreateWithFlags(
|
||||||
|
nil,
|
||||||
|
kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
|
||||||
|
[.privateKeyUsage, .biometryCurrentSet],
|
||||||
|
&error
|
||||||
|
) else {
|
||||||
|
return SRString("err:\(error.debugDescription)")
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
let privateKeyReference = try CryptoKit.SecureEnclave.P256.KeyAgreement.PrivateKey.init(
|
||||||
|
accessControl: accessCtrl
|
||||||
|
);
|
||||||
|
let dataRepresentation = privateKeyReference.dataRepresentation;
|
||||||
|
print("Private key reference: \(privateKeyReference)");
|
||||||
|
print("Private key reference - publicKey: \(privateKeyReference.publicKey)");
|
||||||
|
print("Private key reference - dataRepresentation: \(privateKeyReference.dataRepresentation)");
|
||||||
|
print("Private key reference - dataRepresentation: \(privateKeyReference.dataRepresentation.base64EncodedString())");
|
||||||
|
return SRString("")
|
||||||
|
} catch {
|
||||||
|
return SRString("err:\(error)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func computeSecureEnclaveP256Ecdh(privateKeyDataRepresentation: SRString, ephemeraPublicKey: SRString) -> SRString {
|
||||||
|
guard let dataRepresentation = Data(
|
||||||
|
base64Encoded: privateKeyDataRepresentation.toString()
|
||||||
|
) else {
|
||||||
|
return SRString("err:private key base64 decode failed")
|
||||||
|
}
|
||||||
|
guard let ephemeralPublicKeyRepresentation = Data(
|
||||||
|
base64Encoded: ephemeraPublicKey.toString()
|
||||||
|
) else {
|
||||||
|
return SRString("err:ephemeral public key base64 decode failed")
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
let context = LAContext();
|
||||||
|
let p = try SecureEnclave.P256.KeyAgreement.PrivateKey(
|
||||||
|
dataRepresentation: dataRepresentation,
|
||||||
|
authenticationContext: context
|
||||||
|
)
|
||||||
|
|
||||||
|
let ephemeralPublicKey = try CryptoKit.P256.KeyAgreement.PublicKey.init(derRepresentation: ephemeralPublicKeyRepresentation)
|
||||||
|
|
||||||
|
let sharedSecret = try p.sharedSecretFromKeyAgreement(
|
||||||
|
with: ephemeralPublicKey)
|
||||||
|
print("Shared secret: \(sharedSecret)")
|
||||||
|
|
||||||
|
return SRString("ok:\(sharedSecret.description)")
|
||||||
|
} catch {
|
||||||
|
return SRString("err:\(error)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@_cdecl("get_file_thumbnail_base64")
|
@_cdecl("get_file_thumbnail_base64")
|
||||||
func getFileThumbnailBase64(path: SRString) -> SRString {
|
func getFileThumbnailBase64(path: SRString) -> SRString {
|
||||||
|
|||||||
Reference in New Issue
Block a user