Skip to content

Commit

Permalink
Abandon CryptoKit.
Browse files Browse the repository at this point in the history
  • Loading branch information
yspreen committed Apr 15, 2021
1 parent 1ee4bc5 commit 96c7896
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 99 deletions.
4 changes: 4 additions & 0 deletions PatientScannerDemo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
objects = {

/* Begin PBXBuildFile section */
CE3CC93C2628A7820079FB78 /* ASN1.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE3CC93B2628A7820079FB78 /* ASN1.swift */; };
CE7DE7FA2625EF18007E6694 /* SwiftCBOR in Frameworks */ = {isa = PBXBuildFile; productRef = CE7DE7F92625EF18007E6694 /* SwiftCBOR */; };
CEA6D6EC261F8D2700715333 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA6D6EB261F8D2700715333 /* AppDelegate.swift */; };
CEA6D6EE261F8D2700715333 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA6D6ED261F8D2700715333 /* SceneDelegate.swift */; };
Expand Down Expand Up @@ -44,6 +45,7 @@
/* End PBXContainerItemProxy section */

/* Begin PBXFileReference section */
CE3CC93B2628A7820079FB78 /* ASN1.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASN1.swift; sourceTree = "<group>"; };
CEA6D6E8261F8D2700715333 /* PatientScannerDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PatientScannerDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
CEA6D6EB261F8D2700715333 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
CEA6D6ED261F8D2700715333 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -129,6 +131,7 @@
CEA6D6F6261F8D2900715333 /* LaunchScreen.storyboard */,
CEA6D6F9261F8D2900715333 /* Info.plist */,
CEFAD86C2625F164009AFEF9 /* EC256.swift */,
CE3CC93B2628A7820079FB78 /* ASN1.swift */,
CEFAD87926271414009AFEF9 /* COSE.swift */,
CEFAD88626271B9A009AFEF9 /* Data+hexString.swift */,
);
Expand Down Expand Up @@ -294,6 +297,7 @@
CEC2C4C32625ED030056E406 /* JWK.swift in Sources */,
CEC2C4C42625ED030056E406 /* Base45.swift in Sources */,
CEA6D6F0261F8D2700715333 /* ViewController.swift in Sources */,
CE3CC93C2628A7820079FB78 /* ASN1.swift in Sources */,
CEFAD87A26271414009AFEF9 /* COSE.swift in Sources */,
CEFAD86D2625F164009AFEF9 /* EC256.swift in Sources */,
CEA6D6EC261F8D2700715333 /* AppDelegate.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,16 @@

import Foundation

public class Asn1Encoder {

public init() {}

public class ASN1 {
// 32 for ES256
public func convertRawSignatureIntoAsn1(_ data: Data, _ digestLengthInBytes: Int = 32) -> Data {
public static func signature(from data: Data, _ digestLengthInBytes: Int = 32) -> Data {
let sigR = encodeIntegerToAsn1(data.prefix(data.count - digestLengthInBytes))
let sigS = encodeIntegerToAsn1(data.suffix(digestLengthInBytes))
let tagSequence: UInt8 = 0x30
return Data([tagSequence] + [UInt8(sigR.count + sigS.count)] + sigR + sigS)
}

private func encodeIntegerToAsn1(_ data: Data) -> Data {
private static func encodeIntegerToAsn1(_ data: Data) -> Data {
let firstBitIsSet: UInt8 = 0x80 // would be decoded as a negative number
let tagInteger: UInt8 = 0x02
if (data.first! >= firstBitIsSet) {
Expand Down
36 changes: 7 additions & 29 deletions PatientScannerDemo/COSE.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,17 @@

import Foundation
import SwiftCBOR
import CryptoKit
//import CryptoKit

struct COSE {
public static func verify(_ cbor: CBOR, with xHex: String, and yHex: String) -> Bool {
let COSE_TAG = UInt64(18)
let COSE_PHDR_SIG = CBOR.unsignedInt(1)

guard
case let CBOR.tagged(tag, cborElement) = cbor,
tag.rawValue == COSE_TAG, // SIGN1
case let CBOR.array(array) = cborElement,
case let CBOR.byteString(protectedBytes) = array[0],
case let CBOR.map(unprotected) = array[1],
case let CBOR.byteString(payloadBytes) = array[2],
case let CBOR.byteString(signature) = array[3],
let protected = try? CBOR.decode(protectedBytes),
let payload = try? CBOR.decode(payloadBytes),
case let CBOR.map(protectedMap) = protected,
let sig = protectedMap[COSE_PHDR_SIG]
case let CBOR.byteString(signature) = array[3]
else {
return false
}
Expand All @@ -38,26 +30,12 @@ struct COSE {
array[2]
]
)
let d = Data(bytes: signedPayload, count: signedPayload.count)
let digest = SHA256.hash(data: signedPayload)
guard
let signatureForData = try? P256.Signing.ECDSASignature(rawRepresentation: signature)
else {
let d = Data(signedPayload)//Data(bytes: signedPayload, count: signedPayload.count)
// let digest = SHA256.hash(data: signedPayload)
let s = Data(signature)//Data(bytes: signature, count: signature.count)
guard let key = JWK.ecFrom(x: xHex, y: yHex) else {
return false
}

let x = Data(hexString: xHex)?.uint ?? []
let y = Data(hexString: yHex)?.uint ?? []
let rawk: [UInt8] = [04] + x + y
let _ = (unprotected, sig, d, payload) // unused

if
rawk.count == 32+32+1,
let publicKey = try? P256.Signing.PublicKey(x963Representation: rawk),
publicKey.isValidSignature(signatureForData, for: digest)
{
return true
}
return false
return EC256.verify(signature: s, for: d, with: key)
}
}
31 changes: 15 additions & 16 deletions PatientScannerDemo/EC256.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,27 @@ import Foundation

struct EC256 {
public static func verify(signature: Data, for data: Data, with publicKey: SecKey) -> Bool {
var error: Unmanaged<CFError>?
let targetsSignedData = data as NSData

guard SecKeyIsAlgorithmSupported(publicKey, .verify, .ecdsaSignatureMessageX962SHA256) else {
print("Pubkey not supported.")
return false
}

let sig = ASN1.signature(from: signature)

// verify signature
if SecKeyVerifySignature(
publicKey,
SecKeyAlgorithm.ecdsaSignatureMessageX962SHA256,
targetsSignedData,
signature as NSData,
&error
) {
return true
}
else {
print(error?.takeUnretainedValue().localizedDescription ?? "Something went wrong")
return false
var error: Unmanaged<CFError>?
let result = SecKeyVerifySignature(
publicKey,
.ecdsaSignatureMessageX962SHA256,
data as NSData,
sig as NSData,
&error
)
if let err = error?.takeUnretainedValue().localizedDescription {
print(err)
}
error?.release()

return result
}
}

58 changes: 33 additions & 25 deletions PatientScannerDemo/JWK.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,42 +10,50 @@
import Foundation

struct JWK {
public static func from(x: String, y: String) -> SecKey? {
var xStr = x // Base64 Formatted data
var yStr = y
public static func ecFrom(x: String, y: String) -> SecKey? {
var xBytes: Data?
var yBytes: Data?
if (x + y).count == 128 {
xBytes = Data(hexString: x)
yBytes = Data(hexString: y)
} else {
var xStr = x // Base64 Formatted data
var yStr = y

xStr = xStr.replacingOccurrences(of: "-", with: "+").replacingOccurrences(of: "_", with: "/")
while xStr.count % 4 != 0 {
xStr.append("=")
xStr = xStr.replacingOccurrences(of: "-", with: "+").replacingOccurrences(of: "_", with: "/")
while xStr.count % 4 != 0 {
xStr.append("=")
}
yStr = yStr.replacingOccurrences(of: "-", with: "+").replacingOccurrences(of: "_", with: "/")
while yStr.count % 4 != 0 {
yStr.append("=")
}
xBytes = Data(base64Encoded: xStr)
yBytes = Data(base64Encoded: yStr)
}
yStr = yStr.replacingOccurrences(of: "-", with: "+").replacingOccurrences(of: "_", with: "/")
while yStr.count % 4 != 0 {
yStr.append("=")
}
guard
let xBytes = Data(base64Encoded: xStr),
let yBytes = Data(base64Encoded: yStr)
else { return nil }

// Now this bytes we have to append such that [0x04 , /* xBytes */, /* yBytes */, /* dBytes */]
// Now this bytes we have to append such that [0x04 , /* xBytes */, /* yBytes */]
// Initial byte for uncompressed y as Key.
let keyData = NSMutableData.init(bytes: [0x04], length: [0x04].count)
keyData.append(xBytes)
keyData.append(yBytes)
let keyData = NSMutableData.init(bytes: [0x04], length: 1)
keyData.append(xBytes ?? Data())
keyData.append(yBytes ?? Data())
let attributes: [String: Any] = [
kSecAttrKeyType as String: kSecAttrKeyTypeEC,
kSecAttrKeyClass as String: kSecAttrKeyClassPublic,
kSecAttrKeySizeInBits as String: 256,
kSecAttrIsPermanent as String: false
String(kSecAttrKeyType): kSecAttrKeyTypeEC,
String(kSecAttrKeyClass): kSecAttrKeyClassPublic,
String(kSecAttrKeySizeInBits): 256,
String(kSecAttrIsPermanent): false
]
var error: Unmanaged<CFError>?
let keyReference = SecKeyCreateWithData(keyData as CFData, attributes as CFDictionary, &error)
let errorString = error?.takeUnretainedValue().localizedDescription ?? "Something went wrong"
error?.release()
guard
let keyReference = SecKeyCreateWithData(keyData as CFData, attributes as CFDictionary, &error)
let key = keyReference
else {
print(error?.takeUnretainedValue().localizedDescription ?? "Something went wrong")
print(errorString)
return nil
}

return keyReference
return key
}
}
2 changes: 1 addition & 1 deletion PatientScannerDemo/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ extension ViewController {
guard
let x = keyJWK["x"] as? String,
let y = keyJWK["y"] as? String,
let pubKey = JWK.from(x: x, y: y)
let pubKey = JWK.ecFrom(x: x, y: y)
else { return }

print(EC256.verify(signature: Data(signature), for: Data(payloadBytes), with: pubKey))
Expand Down
43 changes: 21 additions & 22 deletions PatientScannerDemoTests/EHNTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,29 @@ import XCTest
import CryptoKit
import SwiftCBOR

var barcode = "HC1NCFY70R30FFWTWGSLKC 4O992$V M63TMF2V*D9LPC.3EHPCGEC27B72VF/347O4-M6Y9M6FOYG4ILDEI8GR3ZI$15MABL:E9CVBGEEWRMLE C39S0/ANZ52T82Z-73D63P1U 1$PKC 72H2XX09WDH889V5"

let trustJson = """
[
{
\"kid\" : \"DEFBBA3378B322F5\",
\"coord\" : [
\"230ca0433313f4ef14ec0ab0477b241781d135ee09369507fcf44ca988ed09d6\",
\"bf1bfe3d2bda606c841242b59c568d00e5c8dd114d223b2f5036d8c5bc68bf5d\"
]
},
{
\"kid\" : \"FFFBBA3378B322F5\",
\"coord\" : [
\"9999a0433313f4ef14ec0ab0477b241781d135ee09369507fcf44ca988ed09d6\",
\"9999fe3d2bda606c841242b59c568d00e5c8dd114d223b2f5036d8c5bc68bf5d\"
]
}
]
"""


class EHNTests: XCTestCase {
func test_cose() throws {

var barcode = "HC1NCFY70R30FFWTWGSLKC 4O992$V M63TMF2V*D9LPC.3EHPCGEC27B72VF/347O4-M6Y9M6FOYG4ILDEI8GR3ZI$15MABL:E9CVBGEEWRMLE C39S0/ANZ52T82Z-73D63P1U 1$PKC 72H2XX09WDH889V5"

let trustJson = """
[
{
\"kid\" : \"DEFBBA3378B322F5\",
\"coord\" : [
\"230ca0433313f4ef14ec0ab0477b241781d135ee09369507fcf44ca988ed09d6\",
\"bf1bfe3d2bda606c841242b59c568d00e5c8dd114d223b2f5036d8c5bc68bf5d\"
]
},
{
\"kid\" : \"FFFBBA3378B322F5\",
\"coord\" : [
\"9999a0433313f4ef14ec0ab0477b241781d135ee09369507fcf44ca988ed09d6\",
\"9999fe3d2bda606c841242b59c568d00e5c8dd114d223b2f5036d8c5bc68bf5d\"
]
}
]
"""
let COSE_TAG = UInt64(18)
let COSE_PHDR_KID = CBOR.unsignedInt(4)

Expand Down

0 comments on commit 96c7896

Please sign in to comment.