Post not yet marked as solved
Click to stop watching this thread.
You have stopped watching this post. Click to start watching again.
Post marked as unsolved with 2 replies, 0 views
Replied In
How to get a Digest object from raw Data
I managed to do it by creating my own class of Digest:
public struct MyDigest : Digest {
let bytes: (UInt64, UInt64, UInt64, UInt64)
public static var byteCount: Int = 32
public func withUnsafeBytes<R>(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R {
return try Swift.withUnsafeBytes(of: bytes) {
let boundsCheckedPtr = UnsafeRawBufferPointer(start: $0.baseAddress,
count: Self.byteCount)
return try body(boundsCheckedPtr)
}
}
public func hash(into hasher: inout Hasher) {
self.withUnsafeBytes { hasher.combine(bytes: $0) }
}
init?(bufferPointer: UnsafeRawBufferPointer) {
guard bufferPointer.count == 32 else {
return nil
}
var bytes = (UInt64(0), UInt64(0), UInt64(0), UInt64(0))
withUnsafeMutableBytes(of: &bytes) { targetPtr in
targetPtr.copyMemory(from: bufferPointer)
}
self.bytes = bytes
}
func toArray() -> ArraySlice<UInt8> {
var array = [UInt8]()
array.appendByte(bytes.0)
array.appendByte(bytes.1)
array.appendByte(bytes.2)
array.appendByte(bytes.3)
return array.prefix(upTo: SHA256Digest.byteCount)
}
}
extension MutableDataProtocol {
mutating func appendByte(_ byte: UInt64) {
withUnsafePointer(to: byte.littleEndian, { self.append(contentsOf: UnsafeRawBufferPointer(start: $0, count: 8)) })
}
}
(thank you world of open source )
Then I used it by passing my input data as an UnsafeRawBufferPointer
fileprivate func signADigest(digestToSignAsData: Data, keyObjectID: Any) -> P256.Signing.ECDSASignature {
var signature: P256.Signing.ECDSASignature?
let dataAsBufferPointer : UnsafeRawBufferPointer = digestToSignAsData.withUnsafeBytes {
print("-")
return $0
}
let dataAsDigest = MyDigest(bufferPointer: dataAsBufferPointer)!
if let privateKey = try? SecureEnclave.P256.Signing.PrivateKey.init(dataRepresentation: keyObjectID as! Data) {
signature = try? privateKey.signature(for: dataAsDigest)
}
return signature!
}
To make sur that it works I changed the method where I used to sign messages. Instead of calling privateKey.signature(for: data), I make the digest myself with SHA256.hash(data: dataToSign) and then call my method that handle digest signature. I then call privateKey.publicKey.isValidSignature(digestSignature, for: data) on input data to check validity.
So everything is fine, but coding my own Digest by almost copying the source code of SHA256Digest feels more like a hack than a clean solution. If anybody has a better way of doing this I would love to hear it.