feat: v1.10.9, add se supprot
This commit is contained in:
30
swift-lib/Package.swift
Normal file
30
swift-lib/Package.swift
Normal file
@@ -0,0 +1,30 @@
|
||||
// swift-tools-version:5.3
|
||||
// The swift-tools-version declares the minimum version of Swift required to build this package.
|
||||
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "swift-lib",
|
||||
platforms: [
|
||||
.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.
|
||||
.library(
|
||||
name: "swift-lib",
|
||||
type: .static,
|
||||
targets: ["swift-lib"]),
|
||||
],
|
||||
dependencies: [
|
||||
// Dependencies declare other packages that this package depends on.
|
||||
.package(name: "SwiftRs", path: "../swift-rs")
|
||||
],
|
||||
targets: [
|
||||
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
|
||||
// Targets can depend on other targets in this package, and on products in packages this package depends on.
|
||||
.target(
|
||||
name: "swift-lib",
|
||||
dependencies: [.product(name: "SwiftRs", package: "SwiftRs")],
|
||||
path: "src")
|
||||
]
|
||||
)
|
||||
84
swift-lib/src/lib.swift
Normal file
84
swift-lib/src/lib.swift
Normal file
@@ -0,0 +1,84 @@
|
||||
import SwiftRs
|
||||
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 {
|
||||
return SecureEnclave.isAvailable
|
||||
}
|
||||
|
||||
@_cdecl("generate_secure_enclave_p256_ecdh_keypair")
|
||||
func generateSecureEnclaveP256KeyPairEcdh() -> SRString {
|
||||
return generateSecureEnclaveP256KeyPair(sign: false);
|
||||
}
|
||||
|
||||
@_cdecl("generate_secure_enclave_p256_ecsign_keypair")
|
||||
func generateSecureEnclaveP256KeyPairEcsign() -> SRString {
|
||||
return generateSecureEnclaveP256KeyPair(sign: true);
|
||||
}
|
||||
|
||||
func generateSecureEnclaveP256KeyPair(sign: Bool) -> SRString {
|
||||
var error: Unmanaged<CFError>? = nil;
|
||||
guard let accessCtrl = SecAccessControlCreateWithFlags(
|
||||
nil,
|
||||
kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
|
||||
[.privateKeyUsage, .biometryCurrentSet],
|
||||
&error
|
||||
) else {
|
||||
return SRString("err:\(error.debugDescription)")
|
||||
}
|
||||
do {
|
||||
if (sign) {
|
||||
let privateKeyReference = try SecureEnclave.P256.Signing.PrivateKey.init(
|
||||
accessControl: accessCtrl
|
||||
);
|
||||
let publicKeyBase64 = privateKeyReference.publicKey.x963Representation.base64EncodedString()
|
||||
let publicKeyPem = privateKeyReference.publicKey.derRepresentation.base64EncodedString()
|
||||
let dataRepresentationBase64 = privateKeyReference.dataRepresentation.base64EncodedString()
|
||||
return SRString("ok:\(publicKeyBase64),\(publicKeyPem),\(dataRepresentationBase64)")
|
||||
} else {
|
||||
let privateKeyReference = try SecureEnclave.P256.KeyAgreement.PrivateKey.init(
|
||||
accessControl: accessCtrl
|
||||
);
|
||||
let publicKeyBase64 = privateKeyReference.publicKey.x963Representation.base64EncodedString()
|
||||
let publicKeyPem = privateKeyReference.publicKey.derRepresentation.base64EncodedString()
|
||||
let dataRepresentationBase64 = privateKeyReference.dataRepresentation.base64EncodedString()
|
||||
return SRString("ok:\(publicKeyBase64),\(publicKeyPem),\(dataRepresentationBase64)")
|
||||
}
|
||||
} catch {
|
||||
return SRString("err:\(error)")
|
||||
}
|
||||
}
|
||||
|
||||
@_cdecl("compute_secure_enclave_p256_ecdh")
|
||||
func computeSecureEnclaveP256Ecdh(privateKeyDataRepresentation: SRString, ephemeraPublicKey: SRString) -> SRString {
|
||||
guard let privateKeyDataRepresentation = 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: privateKeyDataRepresentation,
|
||||
authenticationContext: context
|
||||
)
|
||||
|
||||
let ephemeralPublicKey = try P256.KeyAgreement.PublicKey.init(derRepresentation: ephemeralPublicKeyRepresentation)
|
||||
|
||||
let sharedSecret = try p.sharedSecretFromKeyAgreement(
|
||||
with: ephemeralPublicKey)
|
||||
|
||||
return SRString("ok:\(sharedSecret.description)")
|
||||
} catch {
|
||||
return SRString("err:\(error)")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user