Posts

Post not yet marked as solved
2 Replies
0 Views
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.