feat: secure enclave is on going
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
.swiftpm/
|
||||
.build/
|
||||
_tinyencrypt_config-rs.json
|
||||
*.tinyenc
|
||||
|
||||
2
build.rs
2
build.rs
@@ -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();
|
||||
|
||||
@@ -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{}",
|
||||
|
||||
@@ -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() }
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user