-
Notifications
You must be signed in to change notification settings - Fork 172
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* Add SerializationPolicy type * savepoint * savepoint * Add envelope * update serialize method * update envelope * handle envelope in Sign sdk * extract envelope to a new file * add getPublicKey method to kms * fix kms errors * fix kms tests * add kms tests scheme fix codec tests * fix serializer tests * update kms test, fix type 0 envelope key size issue * simplify serialiser, add envelope init * Fix envelope type, fix serialiser tests * remove debugging prints * update codec docs * remove unused error * remove unused error * move serializing protocol to serializer * prevent potential crash on envelope init * add serializing file * run lint * Add client auth core components * Add client auth mocks * Add signing private key * Add signing crypto kit wrapper * Add Socket Authenticator Test * update SocketAuthenticator * savepoint * savepoint * pass jwt test * extract jwt encoder * savepoint * update signer * fix tests * extract ED25519DIDKeyFactoryMock * clean up * remove commented code * run lint fix * change relay url * test * update relay url * test * test * revert * test * fix typo * savepoint * Update ED25519DIDKeyFactoryTests * update test
- Loading branch information
1 parent
ec9f3a3
commit 8e2fc42
Showing
24 changed files
with
421 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
83 changes: 83 additions & 0 deletions
83
Sources/WalletConnectKMS/Crypto/CryptoKitWrapper/SigningKeyCryptoKit.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import Foundation | ||
import CryptoKit | ||
|
||
// MARK: - CryptoKit extensions | ||
|
||
extension Curve25519.Signing.PublicKey: Equatable { | ||
public static func == (lhs: Curve25519.Signing.PublicKey, rhs: Curve25519.Signing.PublicKey) -> Bool { | ||
lhs.rawRepresentation == rhs.rawRepresentation | ||
} | ||
} | ||
|
||
extension Curve25519.Signing.PrivateKey: Equatable { | ||
public static func == (lhs: Curve25519.Signing.PrivateKey, rhs: Curve25519.Signing.PrivateKey) -> Bool { | ||
lhs.rawRepresentation == rhs.rawRepresentation | ||
} | ||
} | ||
|
||
// MARK: - Public Key | ||
|
||
public struct SigningPublicKey: GenericPasswordConvertible, Equatable { | ||
public init<D>(rawRepresentation data: D) throws where D: ContiguousBytes { | ||
self.key = try Curve25519.Signing.PublicKey(rawRepresentation: data) | ||
} | ||
|
||
fileprivate let key: Curve25519.Signing.PublicKey | ||
|
||
fileprivate init(publicKey: Curve25519.Signing.PublicKey) { | ||
self.key = publicKey | ||
} | ||
|
||
public init(hex: String) throws { | ||
let data = Data(hex: hex) | ||
try self.init(rawRepresentation: data) | ||
} | ||
|
||
public var rawRepresentation: Data { | ||
key.rawRepresentation | ||
} | ||
|
||
public var hexRepresentation: String { | ||
key.rawRepresentation.toHexString() | ||
} | ||
} | ||
|
||
extension SigningPublicKey: Codable { | ||
|
||
public func encode(to encoder: Encoder) throws { | ||
var container = encoder.singleValueContainer() | ||
try container.encode(key.rawRepresentation) | ||
} | ||
|
||
public init(from decoder: Decoder) throws { | ||
let container = try decoder.singleValueContainer() | ||
let buffer = try container.decode(Data.self) | ||
try self.init(rawRepresentation: buffer) | ||
} | ||
} | ||
|
||
public struct SigningPrivateKey: GenericPasswordConvertible, Equatable { | ||
|
||
private let key: Curve25519.Signing.PrivateKey | ||
|
||
public init() { | ||
self.key = Curve25519.Signing.PrivateKey() | ||
} | ||
|
||
public init<D>(rawRepresentation: D) throws where D: ContiguousBytes { | ||
|
||
self.key = try Curve25519.Signing.PrivateKey(rawRepresentation: rawRepresentation) | ||
} | ||
|
||
public var rawRepresentation: Data { | ||
key.rawRepresentation | ||
} | ||
|
||
public var publicKey: SigningPublicKey { | ||
SigningPublicKey(publicKey: key.publicKey) | ||
} | ||
|
||
public func signature(_ data: Data) throws -> Data { | ||
return try key.signature(for: data) | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
Sources/WalletConnectRelay/ClientAuth/AuthChallengeProvider.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import Foundation | ||
|
||
protocol AuthChallengeProviding { | ||
func getChallenge(for clientId: String) async throws -> String | ||
} | ||
|
||
actor AuthChallengeProvider: AuthChallengeProviding { | ||
func getChallenge(for clientId: String) async throws -> String { | ||
fatalError("not implemented") | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
Sources/WalletConnectRelay/ClientAuth/ClientIdStorage.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import Foundation | ||
import WalletConnectKMS | ||
|
||
protocol ClientIdStoring { | ||
func getOrCreateKeyPair() async throws -> SigningPrivateKey | ||
} | ||
|
||
actor ClientIdStorage: ClientIdStoring { | ||
func getOrCreateKeyPair() async throws -> SigningPrivateKey { | ||
fatalError("not implemented") | ||
} | ||
|
||
} |
33 changes: 33 additions & 0 deletions
33
Sources/WalletConnectRelay/ClientAuth/ED25519DIDKeyFactory.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import Foundation | ||
|
||
protocol ED25519DIDKeyFactory { | ||
func make(pubKey: Data) -> String | ||
} | ||
|
||
/// did-key-format := did:key:MULTIBASE(base58-btc, MULTICODEC(public-key-type, raw-public-key-bytes)) | ||
struct ED25519DIDKeyFactoryImpl: ED25519DIDKeyFactory { | ||
private static let DID_DELIMITER = ":" | ||
private static let DID_PREFIX = "did" | ||
private static let DID_METHOD = "key" | ||
private static let MULTICODEC_ED25519_HEADER = "K36" | ||
private static let MULTICODEC_ED25519_ENCODING = "base58btc" | ||
private static let MULTICODEC_ED25519_BASE = "z" | ||
|
||
func make(pubKey: Data) -> String { | ||
fatalError("not implemented") | ||
|
||
let multicodec = multicodec() | ||
|
||
let multibase = multibase(multicodec: multicodec) | ||
|
||
return [Self.DID_PREFIX, Self.DID_METHOD, multibase].joined(separator: Self.DID_DELIMITER) | ||
} | ||
|
||
private func multibase(multicodec: String) -> String { | ||
fatalError("not implemented") | ||
} | ||
|
||
private func multicodec() -> String { | ||
fatalError("not implemented") | ||
} | ||
} |
14 changes: 14 additions & 0 deletions
14
Sources/WalletConnectRelay/ClientAuth/JWT/JWT+Claims.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import Foundation | ||
|
||
extension JWT { | ||
struct Claims: Codable, Equatable { | ||
let iss: String | ||
let sub: String | ||
func encode() throws -> String { | ||
let jsonEncoder = JSONEncoder() | ||
jsonEncoder.dateEncodingStrategy = .secondsSince1970 | ||
let data = try jsonEncoder.encode(self) | ||
return JWTEncoder.base64urlEncodedString(data: data) | ||
} | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
Sources/WalletConnectRelay/ClientAuth/JWT/JWT+Header.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import Foundation | ||
|
||
extension JWT { | ||
struct Header: Codable, Equatable { | ||
var alg: String! | ||
let typ: String | ||
|
||
init(alg: String? = nil) { | ||
self.alg = alg | ||
typ = "JWT" | ||
} | ||
|
||
func encode() throws -> String { | ||
let jsonEncoder = JSONEncoder() | ||
jsonEncoder.dateEncodingStrategy = .secondsSince1970 | ||
let data = try jsonEncoder.encode(self) | ||
return JWTEncoder.base64urlEncodedString(data: data) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import Foundation | ||
|
||
struct JWT: Codable, Equatable { | ||
enum Errors: Error { | ||
case jwtNotSigned | ||
} | ||
|
||
var header: Header | ||
var claims: Claims | ||
var signature: String? | ||
|
||
public init(header: Header = Header(), claims: Claims) { | ||
self.header = header | ||
self.claims = claims | ||
} | ||
|
||
public mutating func sign(using jwtSigner: JWTSigning) throws { | ||
header.alg = jwtSigner.alg | ||
let headerString = try header.encode() | ||
let claimsString = try claims.encode() | ||
self.signature = try jwtSigner.sign(header: headerString, claims: claimsString) | ||
} | ||
|
||
func encoded() throws -> String { | ||
guard let signature = signature else { throw Errors.jwtNotSigned } | ||
let headerString = try header.encode() | ||
let claimsString = try claims.encode() | ||
return [headerString, claimsString, signature].joined(separator: ".") | ||
} | ||
} |
14 changes: 14 additions & 0 deletions
14
Sources/WalletConnectRelay/ClientAuth/JWT/JWTEncoder.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import Foundation | ||
|
||
struct JWTEncoder { | ||
/// Returns a `String` representation of this data, encoded in base64url format | ||
/// as defined in RFC4648 (https://tools.ietf.org/html/rfc4648). | ||
/// | ||
/// This is the appropriate format for encoding the header and claims of a JWT. | ||
public static func base64urlEncodedString(data: Data) -> String { | ||
let result = data.base64EncodedString() | ||
return result.replacingOccurrences(of: "+", with: "-") | ||
.replacingOccurrences(of: "/", with: "_") | ||
.replacingOccurrences(of: "=", with: "") | ||
} | ||
} |
29 changes: 29 additions & 0 deletions
29
Sources/WalletConnectRelay/ClientAuth/JWT/JWTSigning.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import Foundation | ||
import WalletConnectKMS | ||
|
||
protocol JWTSigning { | ||
var alg: String {get} | ||
func sign(header: String, claims: String) throws -> String | ||
} | ||
|
||
struct EdDSASigner: JWTSigning { | ||
enum Errors: Error { | ||
case invalidJWTString | ||
} | ||
var alg = "EdDSA" | ||
let privateKey: SigningPrivateKey | ||
|
||
init(_ keys: SigningPrivateKey) { | ||
self.privateKey = keys | ||
} | ||
|
||
func sign(header: String, claims: String) throws -> String { | ||
let unsignedJWT = header + "." + claims | ||
guard let unsignedData = unsignedJWT.data(using: .utf8) else { | ||
throw Errors.invalidJWTString | ||
} | ||
let signature = try privateKey.signature(unsignedData) | ||
let signatureString = JWTEncoder.base64urlEncodedString(data: signature) | ||
return signatureString | ||
} | ||
} |
34 changes: 34 additions & 0 deletions
34
Sources/WalletConnectRelay/ClientAuth/SocketAuthenticator.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import Foundation | ||
import WalletConnectKMS | ||
|
||
protocol SocketAuthenticating { | ||
func createAuthToken() async throws -> String | ||
} | ||
|
||
actor SocketAuthenticator: SocketAuthenticating { | ||
private let authChallengeProvider: AuthChallengeProviding | ||
private let clientIdStorage: ClientIdStoring | ||
private let didKeyFactory: ED25519DIDKeyFactory | ||
|
||
init(authChallengeProvider: AuthChallengeProviding = AuthChallengeProvider(), | ||
clientIdStorage: ClientIdStoring = ClientIdStorage(), | ||
didKeyFactory: ED25519DIDKeyFactory = ED25519DIDKeyFactoryImpl()) { | ||
self.authChallengeProvider = authChallengeProvider | ||
self.clientIdStorage = clientIdStorage | ||
self.didKeyFactory = didKeyFactory | ||
} | ||
|
||
func createAuthToken() async throws -> String { | ||
let clientIdKeyPair = try await clientIdStorage.getOrCreateKeyPair() | ||
let challenge = try await authChallengeProvider.getChallenge(for: clientIdKeyPair.publicKey.hexRepresentation) | ||
return try signJWT(subject: challenge, keyPair: clientIdKeyPair) | ||
} | ||
|
||
private func signJWT(subject: String, keyPair: SigningPrivateKey) throws -> String { | ||
let issuer = didKeyFactory.make(pubKey: keyPair.publicKey.rawRepresentation) | ||
let claims = JWT.Claims(iss: issuer, sub: subject) | ||
var jwt = JWT(claims: claims) | ||
try jwt.sign(using: EdDSASigner(keyPair)) | ||
return try jwt.encoded() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import Foundation | ||
import XCTest | ||
@testable import WalletConnectRelay | ||
|
||
final class ED25519DIDKeyFactoryTests: XCTestCase { | ||
let expectedDid = "did:key:z6MkodHZwneVRShtaLf8JKYkxpDGp1vGZnpGmdBpX8M2exxH" | ||
let pubKey = Data(hex: "884ab67f787b69e534bfdba8d5beb4e719700e90ac06317ed177d49e5a33be5a") | ||
var sut: ED25519DIDKeyFactoryImpl! | ||
|
||
override func setUp() { | ||
sut = ED25519DIDKeyFactoryImpl() | ||
} | ||
|
||
func test() { | ||
// let did = sut.make(pubKey: pubKey) | ||
// XCTAssertEqual(expectedDid, did) | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import Foundation | ||
import XCTest | ||
import WalletConnectKMS | ||
@testable import WalletConnectRelay | ||
|
||
final class EdDSASignerTests: XCTestCase { | ||
var sut: EdDSASigner! | ||
|
||
func testSign() { | ||
let keyRaw = Data(hex: "58e0254c211b858ef7896b00e3f36beeb13d568d47c6031c4218b87718061295") | ||
let signingKey = try! SigningPrivateKey(rawRepresentation: keyRaw) | ||
sut = EdDSASigner(signingKey) | ||
let header = try! JWT.Header(alg: "EdDSA").encode() | ||
let claims = try! JWT.Claims( | ||
iss: "did:key:z6MkodHZwneVRShtaLf8JKYkxpDGp1vGZnpGmdBpX8M2exxH", | ||
sub: "c479fe5dc464e771e78b193d239a65b58d278cad1c34bfb0b5716e5bb514928e") | ||
.encode() | ||
let signature = try! sut.sign(header: header, claims: claims) | ||
XCTAssertNotNil(signature) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import Foundation | ||
import XCTest | ||
@testable import WalletConnectRelay | ||
|
||
final class JWTTests: XCTestCase { | ||
let expectedJWT = "eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJkaWQ6a2V5Ono2TWtvZEhad25lVlJTaHRhTGY4SktZa3hwREdwMXZHWm5wR21kQnBYOE0yZXh4SCIsInN1YiI6ImM0NzlmZTVkYzQ2NGU3NzFlNzhiMTkzZDIzOWE2NWI1OGQyNzhjYWQxYzM0YmZiMGI1NzE2ZTViYjUxNDkyOGUifQ.0JkxOM-FV21U7Hk-xycargj_qNRaYV2H5HYtE4GzAeVQYiKWj7YySY5AdSqtCgGzX4Gt98XWXn2kSr9rE1qvCA" | ||
|
||
func testJWTEncoding() { | ||
let iss = "did:key:z6MkodHZwneVRShtaLf8JKYkxpDGp1vGZnpGmdBpX8M2exxH" | ||
let sub = "c479fe5dc464e771e78b193d239a65b58d278cad1c34bfb0b5716e5bb514928e" | ||
let claims = JWT.Claims(iss: iss, sub: sub) | ||
var jwt = JWT(claims: claims) | ||
let signer = EdDSASignerMock() | ||
signer.signature = "0JkxOM-FV21U7Hk-xycargj_qNRaYV2H5HYtE4GzAeVQYiKWj7YySY5AdSqtCgGzX4Gt98XWXn2kSr9rE1qvCA" | ||
try! jwt.sign(using: signer) | ||
let encoded = try! jwt.encoded() | ||
XCTAssertEqual(expectedJWT, encoded) | ||
} | ||
|
||
} |
Oops, something went wrong.