feat: secure enclave is on going

This commit is contained in:
2023-12-09 11:43:21 +08:00
parent fa1cd80fc8
commit 2034db589a
6 changed files with 104 additions and 6 deletions

1
.gitignore vendored
View File

@@ -1,3 +1,4 @@
.swiftpm/
.build/
_tinyencrypt_config-rs.json
*.tinyenc

View File

@@ -4,7 +4,7 @@ use swift_rs::SwiftLinker;
fn main() {
// Ensure this matches the versions set in your `Package.swift` file.
#[cfg(feature = "secure-enclave")]
SwiftLinker::new("10.15")
SwiftLinker::new("11")
.with_ios("11")
.with_package("swift-lib", "./swift-lib/")
.link();

View File

@@ -15,7 +15,7 @@ pub fn version(_cmd_version: CmdVersion) -> XResult<()> {
#[cfg(feature = "macos")]
features.push("macos".to_string());
#[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()); }
println!(
"User-Agent: {} [with features: {}]\n{}",

View File

@@ -1,3 +1,12 @@
pub fn is_support_secure_enclave() -> bool {
false
use swift_rs::{Bool, SRString};
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() }
}

View File

@@ -6,7 +6,7 @@ import PackageDescription
let package = Package(
name: "swift-lib",
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 define the executables and libraries a package produces, and make them visible to other packages.

View File

@@ -1,5 +1,93 @@
import SwiftRs
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")
func getFileThumbnailBase64(path: SRString) -> SRString {
@@ -91,4 +179,4 @@ func returnNullable(null: Bool) -> Test? {
if (null == true) { return nil }
return Test(null)
}
}