Skip to content

Commit

Permalink
Deprecated VerifiableSignVerifier. Use Verifiable, VerifiableCredenti…
Browse files Browse the repository at this point in the history
…al, VerifiablePresentation Instead
  • Loading branch information
YoungBaeJeon committed Jun 1, 2021
1 parent b157b6f commit 8d0cfb6
Show file tree
Hide file tree
Showing 6 changed files with 288 additions and 35 deletions.
85 changes: 57 additions & 28 deletions Example/Tests/Tests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ class Tests: XCTestCase {
// Test VerfiableCredential,VerifiablePresentation sign/verify
func testVcVp() {
do {
let currentDate = Date.init(timeIntervalSince1970: 1565941504)
let expireDate = Date.init(timeIntervalSince1970: 1568533504)
let currentDate = Date()
let expireDate = Date() + 60*60

// Make vc
let vc = try VerifiableCredential.init()
Expand All @@ -66,20 +66,24 @@ class Tests: XCTestCase {
print("publickey = "+hexString(data: publicKey))

// Signing vc
let verifiableSigner = VerifiableSignVerifier.init()
let signer = ECDSASigner.init(privateKey: privateKey)
guard let signedVC = try verifiableSigner.sign(verifiable: vc, algorithm: .ES256K, kid: "did:meta:387834#ManagementKey#89349348", nonce: "nonce", signer: signer) else {
XCTAssert(false)
return
}
let signedVC = try vc.sign(kid: "did:meta:387834#ManagementKey#89349348", nonce: "nonce", signer: signer)

// serialize signed vc
let serializedVC = try signedVC.serialize()
print("VC = "+serializedVC)

// verify serialized vc
let verifier = ECDSAVerifier.init(publicKey: publicKey)
guard let verifiedVC = try verifiableSigner.verify(serializedVerifiable: serializedVC, verifier: verifier) as! VerifiableCredential? else {
let jws = try JWSObject.init(string: serializedVC)
guard try jws.verify(verifier: verifier) else {
XCTAssert(false)
return
}

let verifiedVC = try VerifiableCredential.init(jws: jws)
// Check expiration
if verifiedVC.expirationDate != nil && verifiedVC.expirationDate! < Date() {
XCTAssert(false)
return
}
Expand All @@ -91,7 +95,10 @@ class Tests: XCTestCase {
XCTAssertEqual(verifiedVC.expirationDate, vc.expirationDate)
XCTAssertEqual((verifiedVC.credentialSubject as! [String: Any])["id"] as? String, (vc.credentialSubject as! [String: Any])["id"] as? String)
XCTAssertEqual((verifiedVC.credentialSubject as! [String: Any])["name"] as? String, (vc.credentialSubject as! [String: Any])["name"] as? String)

// check issuanceDate
let vcJWT = try JWT.init(jsonData: jws.payload)
XCTAssertEqual(vcJWT.notBeforeTime, vc.issuanceDate)


// Make VP
let vp = try VerifiablePresentation.init()
Expand All @@ -107,35 +114,47 @@ class Tests: XCTestCase {
XCTAssertEqual(serializedVC, vp.verifiableCredentials()![0] as! String)
XCTAssertEqual(serializedVC, vp.verifiableCredentials()![1] as! String)

// Add expiration date
let jwt = JWT.init()
jwt.expirationTime = expireDate
jwt.notBeforeTime = currentDate

// Sign vc
guard let signedVP = try verifiableSigner.sign(verifiable: vp, algorithm: .ES256K, kid: "did:meta:43894835", nonce: "vp nonce", signer: signer) else {
XCTAssert(false)
return
}
let signedVP = try vp.sign(kid: "did:meta:43894835", nonce: "vp nonce", signer: signer, baseClaims: jwt)

// Serialize signed vp
let vpString = try signedVP.serialize()
print("vp = "+vpString)

// Verify serialized vp
guard let verifiedVp = try verifiableSigner.verify(serializedVerifiable: vpString, verifier: verifier) as? VerifiablePresentation else {
let vpJws = try JWSObject.init(string: vpString)
guard try vpJws.verify(verifier: verifier) else {
XCTAssert(false)
return
}
// Check expiration
let vpJwt = try JWT.init(jsonData: vpJws.payload)
if vpJwt.expirationTime != nil && vpJwt.expirationTime! < Date() {
XCTAssert(false)
return
}
XCTAssertEqual(UInt64(currentDate.timeIntervalSince1970), UInt64(vpJwt.notBeforeTime!.timeIntervalSince1970))
XCTAssertEqual(UInt64(expireDate.timeIntervalSince1970), UInt64(vpJwt.expirationTime!.timeIntervalSince1970))

let verifiedVp = try VerifiablePresentation.init(jws: vpJws)
XCTAssertEqual(verifiedVp.id, vp.id)
XCTAssertEqual(verifiedVp.holder, vp.holder)
XCTAssertEqual(verifiedVp.verifiableCredentials()![0] as? String, vp.verifiableCredentials()![0] as? String)
XCTAssertEqual(verifiedVp.verifiableCredentials()![1] as? String, vp.verifiableCredentials()![1] as? String)

// Verify vc in vp
for svc in verifiedVp.verifiableCredentials()! {
guard let _ = try verifiableSigner.verify(serializedVerifiable: svc as! String, verifier: verifier) else {
let vcJws = try JWSObject.init(string: svc as! String)
guard try vcJws.verify(verifier: verifier) else {
XCTAssert(false)
continue
return
}
}

}
catch {
print(error.localizedDescription)
Expand All @@ -148,15 +167,15 @@ class Tests: XCTestCase {
let vcString = "eyJraWQiOiJkaWQ6bWV0YTowMDAwMDM0ODkzODQ5MzI4NTk0MjAjS2V5TWFuYWdlbWVudCM3Mzg3NTg5MjQ3NSIsInR5cCI6IkpXVCIsImFsZyI6IkVTMjU2SyJ9.eyJzdWIiOiJkaWQ6bWV0YToweDExMTExMTExMTIwIiwiaXNzIjoiZGlkOm1ldGE6MHgzNDg5Mzg0OTMyODU5NDIwIiwiZXhwIjoxNTc0OTExNTk4LCJpYXQiOjE1NjYyNzE1OTgsIm5vbmNlIjoiMGQ4bWYwMyIsInZjIjp7IkBjb250ZXh0IjpbImh0dHBzOlwvXC93M2lkLm9yZ1wvY3JlZGVudGlhbHNcL3YxIl0sInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiLCJOYW1lQ3JlZGVudGlhbCJdLCJjcmVkZW50aWFsU3ViamVjdCI6eyJuYW1lIjoibWFuc3VkIn19LCJqdGkiOiJodHRwOlwvXC9hYS5tZXRhZGl1bS5jb21cL2NyZWRlbnRpYWxcLzM0MyJ9.A9x_gdqPMG3hqzP7yPqouqz4y-HIx4wVjOSGh4oXxufkyQjvQD3uDDmviNv7Xk7F3GXxGg_1hu-nL4cAirjLvA"
let publicKey = hexadecimal(hexString:"043696d164c46a63ff57498e3e0e6a3d698a2c4f130ea174afd0cfb38b92991e6286c2c3587efac3b9e3cf7e7d5f5af5a048de557d5e976d38e829545b549bcebe")

// Verify VC
let verifier = ECDSAVerifier.init(publicKey: publicKey!)
let verifiableJwt = VerifiableSignVerifier.init()

let vc = try verifiableJwt.verify(serializedVerifiable: vcString, verifier: verifier) as? VerifiableCredential
if vc == nil {
let vcJws = try JWSObject.init(string: vcString)
guard try vcJws.verify(verifier: verifier) else {
XCTAssert(false)
return;
return
}
let vcJsonString = vc!.jsonString()
let vc = try VerifiableCredential.init(jws: vcJws)
let vcJsonString = vc.jsonString()
print("vc = "+vcJsonString!)
}

Expand All @@ -176,29 +195,39 @@ class Tests: XCTestCase {
}
let vp = "eyJraWQiOiJkaWQ6bWV0YToweDM0ODkzODQ5MzI4NTk0MjAjTWFuYWdlbWVudEtleSM0MzgyNzU4Mjk1IiwidHlwIjoiSldUIiwiYWxnIjoiRVMyNTZLIn0.eyJpc3MiOiJkaWQ6bWV0YToweDM0ODkzODQ5MzI4NTk0MjAiLCJ2cCI6eyJAY29udGV4dCI6WyJodHRwczpcL1wvdzNpZC5vcmdcL2NyZWRlbnRpYWxzXC92MSJdLCJ0eXBlIjpbIlZlcmlmaWFibGVQcmVzZW50YXRpb24iLCJUZXN0UHJlc2VudGF0aW9uIl0sInZlcmlmaWFibGVDcmVkZW50aWFsIjpbImV5SnJhV1FpT2lKa2FXUTZiV1YwWVRvd01EQXdNRE0wT0Rrek9EUTVNekk0TlRrME1qQWpTMlY1VFdGdVlXZGxiV1Z1ZENNM016ZzNOVGc1TWpRM05TSXNJblI1Y0NJNklrcFhWQ0lzSW1Gc1p5STZJa1ZUTWpVMlN5SjkuZXlKemRXSWlPaUprYVdRNmJXVjBZVG93ZURFeE1URXhNVEV4TVRJd0lpd2lhWE56SWpvaVpHbGtPbTFsZEdFNk1IZ3pORGc1TXpnME9UTXlPRFU1TkRJd0lpd2laWGh3SWpveE5UYzBPVE13TnpNMkxDSnBZWFFpT2pFMU5qWXlPVEEzTXpZc0ltNXZibU5sSWpvaU1HUTRiV1l3TXlJc0luWmpJanA3SWtCamIyNTBaWGgwSWpwYkltaDBkSEJ6T2x3dlhDOTNNMmxrTG05eVoxd3ZZM0psWkdWdWRHbGhiSE5jTDNZeElsMHNJblI1Y0dVaU9sc2lWbVZ5YVdacFlXSnNaVU55WldSbGJuUnBZV3dpTENKT1lXMWxRM0psWkdWdWRHbGhiQ0pkTENKamNtVmtaVzUwYVdGc1UzVmlhbVZqZENJNmV5SnVZVzFsSWpvaWJXRnVjM1ZrSW4xOUxDSnFkR2tpT2lKb2RIUndPbHd2WEM5aFlTNXRaWFJoWkdsMWJTNWpiMjFjTDJOeVpXUmxiblJwWVd4Y0x6TTBNeUo5Lnh2UzJzWk11SXJJZ0g3Rm1DYVVmbk51V3hUeW9YeFJUTFpwdjZNU0toNUxFUFV4M190RnZhOVVtZ2JrQ2xqQzctUloxY2NVUnpfRjJfeGM3UXBrdUZnIiwiZXlKcmFXUWlPaUprYVdRNmJXVjBZVG93TURBd01ETTBPRGt6T0RRNU16STROVGswTWpBalMyVjVUV0Z1WVdkbGJXVnVkQ00zTXpnM05UZzVNalEzTlNJc0luUjVjQ0k2SWtwWFZDSXNJbUZzWnlJNklrVlRNalUyU3lKOS5leUp6ZFdJaU9pSmthV1E2YldWMFlUb3dlREV4TVRFeE1URXhNVEl3SWl3aWFYTnpJam9pWkdsa09tMWxkR0U2TUhnek5EZzVNemcwT1RNeU9EVTVOREl3SWl3aVpYaHdJam94TlRjME9UTXdOelUzTENKcFlYUWlPakUxTmpZeU9UQTNOVGNzSW01dmJtTmxJam9pTUdRNGJXWXdNeUlzSW5aaklqcDdJa0JqYjI1MFpYaDBJanBiSW1oMGRIQnpPbHd2WEM5M00ybGtMbTl5WjF3dlkzSmxaR1Z1ZEdsaGJITmNMM1l4SWwwc0luUjVjR1VpT2xzaVZtVnlhV1pwWVdKc1pVTnlaV1JsYm5ScFlXd2lMQ0pPWVcxbFEzSmxaR1Z1ZEdsaGJDSmRMQ0pqY21Wa1pXNTBhV0ZzVTNWaWFtVmpkQ0k2ZXlKdVlXMWxJam9pYldGdWMzVmtJbjE5TENKcWRHa2lPaUpvZEhSd09sd3ZYQzloWVM1dFpYUmhaR2wxYlM1amIyMWNMMk55WldSbGJuUnBZV3hjTHpNME15SjkuSmtsU1hNMkJvT25kOTN0d3B5WEpuZkpZUmI4Vm1NU1FMNWtkNWNDS0RWdWYxdjNtU2NOeUQwRVhuZ25GX3pRT1dlVjItS2V3VHBQeURXcmhxUmwxTHciXX0sIm5vbmNlIjoiMGQ4bWYwMyIsImp0aSI6Imh0dHA6XC9cL2FhLm1ldGFkaXVtLmNvbVwvcHJlc2VudGF0aW9uXC8zNDMifQ.FW_nEPTRg18D2zaX3ACh1atqlJ1alPMGmNzalmUdloo_bG-DevmkcpMm5yPoKB0uaL_oQLYHb6xvFNNwCRSXig"

// Verify VP
let verifier = ECDSAVerifier.init(publicKey: publicKey)
let vpJws = try JWSObject.init(string: vp)
guard try vpJws.verify(verifier: verifier) else {
XCTAssert(false)
return
}

let verifiableJwt = VerifiableSignVerifier.init()

guard let verifiedVP = try verifiableJwt.verify(serializedVerifiable: vp, verifier: verifier) as! VerifiablePresentation? else {
// Check expiration of VP
let vpJwt = try JWT.init(jsonData: vpJws.payload)
if vpJwt.expirationTime != nil && vpJwt.expirationTime! < Date() {
XCTAssert(false)
return
}

let verifiedVP = try VerifiablePresentation.init(jws: vpJws)

guard let vcList = verifiedVP.verifiableCredentials() else {
XCTAssert(false)
return
}
XCTAssertEqual(vcList.count, 2)

let verifier1 = ECDSAVerifier.init(publicKey: vc1PublciKey)
guard let _ = try verifiableJwt.verify(serializedVerifiable: vcList[0] as! String, verifier: verifier1) as! VerifiableCredential? else {
let vcJws1 = try JWSObject.init(string: vcList[0] as! String)
guard try vcJws1.verify(verifier: verifier1) else {
XCTAssert(false)
return
}

let verifier2 = ECDSAVerifier.init(publicKey: vc2PublicKey)
guard let _ = try verifiableJwt.verify(serializedVerifiable: vcList[1] as! String, verifier: verifier2) as! VerifiableCredential? else {
let vcJws2 = try JWSObject.init(string: vcList[1] as! String)
guard try vcJws2.verify(verifier: verifier2) else {
XCTAssert(false)
return
}
Expand Down
2 changes: 1 addition & 1 deletion VerifiableSwift.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

Pod::Spec.new do |s|
s.name = 'VerifiableSwift'
s.version = '0.1.0'
s.version = '0.2.0'
s.summary = 'Verifiable Credential and Presentation of Metadium.'

# This description is used to generate tags and improve search results.
Expand Down
63 changes: 63 additions & 0 deletions VerifiableSwift/Classes/Verifiable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,24 @@
//

import Foundation
import JWTsSwift


/// JWT 로 변환할 delegator
protocol VerifiableDelegator {
func toJWT(nonce: String?, claims: JWT?) throws -> JWT
}

/// Verifiable error
///
/// - NullType: type is null. Need override func getType()
/// - InvalidCredential: invalid credentail
/// - InvalidCredential: invalid presentation
enum VerifiableError: Error {
case NullType
case InvalidCredential
case InvalidPresentation
case Unknown
}


Expand All @@ -23,6 +34,8 @@ public class Verifiable {
/// verifiable data
var jsonObject: [String: Any]

var delegator: VerifiableDelegator?


/// init
///
Expand Down Expand Up @@ -135,4 +148,54 @@ public class Verifiable {
public func getJson() -> [String: Any] {
return jsonObject
}


/// Sign credential or presentation
/// - Parameters:
/// - algorithm: signature algorithm
/// - kid: key id
/// - nonce: nonce
/// - signer: JWS signer
/// - baseClaims: base JWT claims. presentation 에 issuanceDate, expirationDate 추가사 사용
/// - Throws: error to sign
/// - Returns: signed jws
public func sign(algorithm: SignatureAlgorithm, kid: String, nonce: String?, signer: JWSSigner, baseClaims: JWT?) throws -> JWSObject {
// To JWT
guard let jsonData = try delegator?.toJWT(nonce: nonce, claims: baseClaims).data() else {
throw VerifiableError.Unknown
}

// Sign JWT
let header: JWSHeader = JWSHeader.init(algorithm: algorithm)
header.kid = kid
let jws:JWSObject = JWSObject.init(header: header, payload: jsonData)
try jws.sign(signer: signer)

return jws
}


/// Sign credential or presentation. algorithm is ES256K
/// - Parameters:
/// - kid: key id
/// - nonce: nonce
/// - signer: JWS signer
/// - baseClaims: base JWT claims. presentation 에 issuanceDate, expirationDate 추가사 사용
/// - Throws: error to sign
/// - Returns: signed jws
public func sign(kid: String, nonce: String?, signer: JWSSigner, baseClaims: JWT?) throws -> JWSObject {
return try sign(algorithm: .ES256K, kid: kid, nonce: nonce, signer: signer, baseClaims: baseClaims)
}

/// Sign credential or presentation. . algorithm is ES256K
/// - Parameters:
/// - kid: key id
/// - nonce: nonce
/// - signer: JWS signer
/// - Throws: error to sign
/// - Returns: signed jws
public func sign(kid: String, nonce: String?, signer: JWSSigner) throws -> JWSObject {
return try sign(kid: kid, nonce: nonce, signer: signer, baseClaims: nil)
}

}
Loading

0 comments on commit 8d0cfb6

Please sign in to comment.