forked from bastiaanv/EversenseKit
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathECDSASignature.swift
More file actions
59 lines (49 loc) · 1.44 KB
/
ECDSASignature.swift
File metadata and controls
59 lines (49 loc) · 1.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
enum DERSignatureError: Error {
case invalidFormat
case unsupportedLength
}
func parseECDSASignature(_ der: Data) throws -> Data {
var index = 0
let bytes = [UInt8](der)
func readByte() throws -> UInt8 {
guard index < bytes.count else { throw DERSignatureError.invalidFormat }
defer { index += 1 }
return bytes[index]
}
func readLength() throws -> Int {
let first = try readByte()
if first & 0x80 == 0 {
return Int(first)
}
let count = Int(first & 0x7F)
guard count > 0, count <= 2 else {
throw DERSignatureError.unsupportedLength
}
var length = 0
for _ in 0 ..< count {
length = (length << 8) | Int(try readByte())
}
return length
}
// Expect SEQUENCE
guard try readByte() == 0x30 else {
throw DERSignatureError.invalidFormat
}
_ = try readLength()
// Read INTEGER r
guard try readByte() == 0x02 else {
throw DERSignatureError.invalidFormat
}
let rLength = try readLength()
var r = Data(bytes[index ..< index + rLength])
index += rLength
// Read INTEGER s
guard try readByte() == 0x02 else {
throw DERSignatureError.invalidFormat
}
let sLength = try readLength()
var s = Data(bytes[index ..< index + sLength])
if r.first == 0 { r.removeFirst() }
if s.first == 0 { s.removeFirst() }
return r + s
}