diff --git a/.gitignore b/.gitignore index 8fb6036..ef5422b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +swift-secure-enclave-tool # ---> Swift # Xcode # diff --git a/swift-secure-enclave-tool.swift b/swift-secure-enclave-tool.swift new file mode 100644 index 0000000..c72d1cd --- /dev/null +++ b/swift-secure-enclave-tool.swift @@ -0,0 +1,63 @@ +// Reference: +// - https://developer.apple.com/documentation/swift/commandline/arguments +// - https://git.hatter.ink/hatter/card-cli/src/branch/master/swift-lib/src/lib.swift + +import CryptoKit +import LocalAuthentication + +func isSupportSecureEnclave() -> Bool { + return SecureEnclave.isAvailable +} + +func generateSecureEnclaveP256KeyPair(sign: Bool) -> String { + var error: Unmanaged? = nil; + guard let accessCtrl = SecAccessControlCreateWithFlags( + nil, + kSecAttrAccessibleWhenUnlockedThisDeviceOnly, + [.privateKeyUsage, .biometryCurrentSet], + &error + ) else { + return "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 "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 "ok:\(publicKeyBase64),\(publicKeyPem),\(dataRepresentationBase64)" + } + } catch { + return "err:\(error)" + } +} + +if (CommandLine.arguments.count == 1) { + print("err:requireArguments") + exit(1) +} + +let action = CommandLine.arguments[1]; + +if (action == "checkSecureEnclaveEnabled") { + print("ok:\(isSupportSecureEnclave())") + exit(0); +} + +if (action == "generateSecureEnclaveP256SingingKeyPair") { + print(generateSecureEnclaveP256KeyPair(sign: true)) + exit(0); +} + +print("err:unknownAction") +exit(1) \ No newline at end of file