Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose a card's key attestation into a facade #272

Merged
merged 1 commit into from
Apr 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions TangemSdk/TangemSdk.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,7 @@
DCE3281729D5DEE500AAC4AC /* ImportWallet.json in Resources */ = {isa = PBXBuildFile; fileRef = DCE3281629D5DEE500AAC4AC /* ImportWallet.json */; };
DCEA3ABC2875AEBA00B0B0DA /* BiometricsStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCEA3ABB2875AEBA00B0B0DA /* BiometricsStorage.swift */; };
DCEA3ABE2875AF0F00B0B0DA /* SecureStorageKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCEA3ABD2875AF0F00B0B0DA /* SecureStorageKey.swift */; };
DCF6188429F069DB001BE133 /* AttestCardKey.json in Resources */ = {isa = PBXBuildFile; fileRef = DCF6188329F069DB001BE133 /* AttestCardKey.json */; };
DCFCA17728F5629F0037586C /* FocusableTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCFCA17628F5629F0037586C /* FocusableTextField.swift */; };
/* End PBXBuildFile section */

Expand Down Expand Up @@ -667,6 +668,7 @@
DCE3281629D5DEE500AAC4AC /* ImportWallet.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = ImportWallet.json; sourceTree = "<group>"; };
DCEA3ABB2875AEBA00B0B0DA /* BiometricsStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BiometricsStorage.swift; sourceTree = "<group>"; };
DCEA3ABD2875AF0F00B0B0DA /* SecureStorageKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureStorageKey.swift; sourceTree = "<group>"; };
DCF6188329F069DB001BE133 /* AttestCardKey.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = AttestCardKey.json; sourceTree = "<group>"; };
DCFCA17628F5629F0037586C /* FocusableTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FocusableTextField.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

Expand Down Expand Up @@ -848,6 +850,7 @@
5D54408F268226BC00F7D05B /* PurgeWallet.json */,
5D5440912682297A00F7D05B /* CreateWallet.json */,
DCE3281629D5DEE500AAC4AC /* ImportWallet.json */,
DCF6188329F069DB001BE133 /* AttestCardKey.json */,
5D544093268243F700F7D05B /* Card.json */,
);
path = Jsons;
Expand Down Expand Up @@ -1677,6 +1680,7 @@
5D46F53C274E41100004681F /* DeriveWalletPublicKeys.json in Resources */,
5D46F15F26811D4000DC6447 /* SignHash.json in Resources */,
5D38D06E26790B1A0052F67C /* Scan.json in Resources */,
DCF6188429F069DB001BE133 /* AttestCardKey.json in Resources */,
5D4B127B26D3D32E006E173C /* ChangeFileSettings.json in Resources */,
5D4B127926D3CF4F006E173C /* DeleteFiles.json in Resources */,
5D544094268243F700F7D05B /* Card.json in Resources */,
Expand Down
11 changes: 11 additions & 0 deletions TangemSdk/TangemSdk/Common/JSON/Handlers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -239,3 +239,14 @@ class SetUserCodeRecoveryAllowedHandler: JSONRPCHandler {
}
}

@available(iOS 13.0, *)
class AttestCardKeyHandler: JSONRPCHandler {
var method: String { "ATTEST_CARD_KEY" }

func makeRunnable(from parameters: [String : Any]) throws -> AnyJSONRPCRunnable {
let challenge: Data? = try parameters.value(for: "challenge")

let command = AttestCardKeyCommand(challenge: challenge)
return command.eraseToAnyRunnable()
}
}
19 changes: 10 additions & 9 deletions TangemSdk/TangemSdk/Common/JSON/JSONRPC.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,25 @@ import Foundation
public final class JSONRPCConverter {
public static let shared: JSONRPCConverter = {
let converter = JSONRPCConverter()
converter.register(SignHashesHandler())
converter.register(SignHashHandler())
converter.register(ScanHandler())
converter.register(AttestCardKeyHandler())
converter.register(SignHashHandler())
converter.register(SignHashesHandler())
converter.register(CreateWalletHandler())
converter.register(ImportWalletHandler())
converter.register(PurgeWalletHandler())
converter.register(PersonalizeHandler())
converter.register(DepersonalizeHandler())
converter.register(SetAccessCodeHandler())
converter.register(SetPasscodeHandler())
converter.register(ResetUserCodesHandler())
converter.register(SetUserCodeRecoveryAllowedHandler())
converter.register(DeriveWalletPublicKeyHandler())
converter.register(DeriveWalletPublicKeysHandler())
converter.register(ReadFilesHandler())
converter.register(ChangeFileSettingsHandler())
converter.register(WriteFilesHandler())
converter.register(DeleteFilesHandler())
converter.register(ChangeFileSettingsHandler())
converter.register(DeriveWalletPublicKeyHandler())
converter.register(DeriveWalletPublicKeysHandler())
converter.register(ImportWalletHandler())
converter.register(SetUserCodeRecoveryAllowedHandler())
converter.register(PersonalizeHandler())
converter.register(DepersonalizeHandler())
return converter
}()

Expand Down
17 changes: 17 additions & 0 deletions TangemSdk/TangemSdk/TangemSdk.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,23 @@ public extension TangemSdk {
completion: @escaping CompletionResult<Card>) {
startSession(with: ScanTask(), cardId: nil, initialMessage: initialMessage, completion: completion)
}

/// Perform a card's key attestation
/// - Parameters:
/// - challenge: Optional challenge. If nil, it will be created automatically and returned in command response
/// - cardId: CID, Unique Tangem card ID number
/// - initialMessage: A custom description that shows at the beginning of the NFC session. If nil, default message will be used
/// - completion: Returns `Swift.Result<AttestCardKeyResponse,TangemSdkError>`
func attestCardKey(challenge: Data? = nil,
cardId: String? = nil,
initialMessage: Message? = nil,
completion: @escaping CompletionResult<AttestCardKeyResponse>) {
let command = AttestCardKeyCommand(challenge: challenge)
startSession(with: command,
cardId: cardId,
initialMessage: initialMessage,
completion: completion)
}

/// This method allows you to sign one hash and will return a corresponding signature.
/// Please note that Tangem cards usually protect the signing with a security delay
Expand Down
10 changes: 10 additions & 0 deletions TangemSdk/TangemSdkTests/JSONRPCTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,16 @@ class JSONRPCTests: XCTestCase {
testMethod(name: "SetUserCodeRecoveryAllowed", result: result)
}

func testAttestCardKey() {
let result = AttestCardKeyResponse(cardId: "c000111122223333",
salt: Data(hexString: "BBBBBBBBBBBB"),
cardSignature: Data(hexString: "AAAAAAAAAAAA"),
challenge: Data(hexString: "000000000000"))

testMethod(name: "AttestCardKey", result: result)
}


func testFiles() {
testMethod(name: "ReadFiles", result: [File(data: Data(hexString: "00AABBCCDD"),
index: 0,
Expand Down
20 changes: 20 additions & 0 deletions TangemSdk/TangemSdkTests/Jsons/AttestCardKey.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"request" : {
"jsonrpc": "2.0",
"id": 1,
"method": "attest_card_key",
"params": {
"challenge": "000000000000"
}
},
"response" : {
"jsonrpc" : "2.0",
"result" : {
"cardId": "c000111122223333",
"salt": "BBBBBBBBBBBB",
"cardSignature": "AAAAAAAAAAAA",
"challenge": "000000000000"
},
"id" : 1
}
}