mirror of
https://github.com/laosb/swift-minisign.git
synced 2025-04-30 18:01:08 +00:00
Initial fork.
This commit is contained in:
parent
bea7edf8c4
commit
e162e99e2c
8 changed files with 450 additions and 23 deletions
4
.spi.yml
Normal file
4
.spi.yml
Normal file
|
@ -0,0 +1,4 @@
|
|||
version: 1
|
||||
builder:
|
||||
configs:
|
||||
- documentation_targets: [Minisign]
|
79
.swiftpm/xcode/xcshareddata/xcschemes/Minisign.xcscheme
Normal file
79
.swiftpm/xcode/xcshareddata/xcschemes/Minisign.xcscheme
Normal file
|
@ -0,0 +1,79 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1630"
|
||||
version = "1.7">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES"
|
||||
buildArchitectures = "Automatic">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "Minisign"
|
||||
BuildableName = "Minisign"
|
||||
BlueprintName = "Minisign"
|
||||
ReferencedContainer = "container:">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
shouldAutocreateTestPlan = "YES">
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "MinisignTests"
|
||||
BuildableName = "MinisignTests"
|
||||
BlueprintName = "MinisignTests"
|
||||
ReferencedContainer = "container:">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "Minisign"
|
||||
BuildableName = "Minisign"
|
||||
BlueprintName = "Minisign"
|
||||
ReferencedContainer = "container:">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
21
LICENSE
Normal file
21
LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2021 Stephen Larew, 2025 Shibo Lyu
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
24
Package.resolved
Normal file
24
Package.resolved
Normal file
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"originHash" : "def130774b50dc2ba17b29adfc982eea080e276d775b67d2d3d92bd096b2287d",
|
||||
"pins" : [
|
||||
{
|
||||
"identity" : "swift-blake2",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/lovetodream/swift-blake2",
|
||||
"state" : {
|
||||
"revision" : "b8074b87567037046445ce0859644c283dcce8cc",
|
||||
"version" : "0.1.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-crypto",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-crypto",
|
||||
"state" : {
|
||||
"revision" : "60f13f60c4d093691934dc6cfdf5f508ada1f894",
|
||||
"version" : "2.6.0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"version" : 3
|
||||
}
|
|
@ -4,21 +4,46 @@
|
|||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "Minisign",
|
||||
products: [
|
||||
// Products define the executables and libraries a package produces, making them visible to other packages.
|
||||
.library(
|
||||
name: "Minisign",
|
||||
targets: ["Minisign"]),
|
||||
],
|
||||
targets: [
|
||||
// Targets are the basic building blocks of a package, defining a module or a test suite.
|
||||
// Targets can depend on other targets in this package and products from dependencies.
|
||||
.target(
|
||||
name: "Minisign"),
|
||||
.testTarget(
|
||||
name: "MinisignTests",
|
||||
dependencies: ["Minisign"]
|
||||
),
|
||||
]
|
||||
name: "Minisign",
|
||||
platforms: [
|
||||
.macOS(.v10_15),
|
||||
.iOS(.v13),
|
||||
.visionOS(.v1),
|
||||
.tvOS(.v13),
|
||||
.watchOS(.v6)
|
||||
],
|
||||
products: [
|
||||
// Products define the executables and libraries a package produces, making them visible to other packages.
|
||||
.library(
|
||||
name: "Minisign",
|
||||
targets: ["Minisign"]
|
||||
)
|
||||
],
|
||||
traits: [
|
||||
.init(
|
||||
name: "UseSwiftCrypto",
|
||||
description:
|
||||
"Use Swift Crypto instead of Apple's CryptoKit. If targeting Apple platforms only, remove this trait to cut dependency on Swift Crypto."
|
||||
),
|
||||
.default(enabledTraits: ["UseSwiftCrypto"]),
|
||||
],
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/apple/swift-crypto", from: "2.0.0"),
|
||||
.package(url: "https://github.com/lovetodream/swift-blake2", from: "0.1.0")
|
||||
],
|
||||
targets: [
|
||||
// Targets are the basic building blocks of a package, defining a module or a test suite.
|
||||
// Targets can depend on other targets in this package and products from dependencies.
|
||||
.target(
|
||||
name: "Minisign",
|
||||
dependencies: [
|
||||
.product(name: "Crypto", package: "swift-crypto", condition: .when(traits: ["UseSwiftCrypto"])),
|
||||
.product(name: "BLAKE2", package: "swift-blake2")
|
||||
]
|
||||
),
|
||||
.testTarget(
|
||||
name: "MinisignTests",
|
||||
dependencies: ["Minisign"]
|
||||
),
|
||||
]
|
||||
)
|
||||
|
|
15
README.md
Normal file
15
README.md
Normal file
|
@ -0,0 +1,15 @@
|
|||
# Swift Minisign
|
||||
|
||||
Swift implementation of Minisign, a simple and secure tool for signing and verifying files.
|
||||
|
||||
This is a fork of [slarew/swift-minisign](https://github.com/slarew/swift-minisign), with these improvements:
|
||||
|
||||
- Convenient & efficient API for verifying (big) files
|
||||
- Replaced C wrapping `swift-crypto-blake2` with [pure Swift implementation of blake2b](https://github.com/lovetodream/swift-blake2).
|
||||
- For Apple platforms, Swift Crypto dependency is now optional, controllable via trait `UseSwiftCrypto`.
|
||||
|
||||
*but still, only signature verification is supported, signing not yet!*
|
||||
|
||||
## License
|
||||
|
||||
[MIT](LICENSE).
|
|
@ -1,2 +1,157 @@
|
|||
// The Swift Programming Language
|
||||
// https://docs.swift.org/swift-book
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Based on https://github.com/slarew/swift-minisign
|
||||
// Copyright 2021 Stephen Larew, 2025 Shibo Lyu
|
||||
|
||||
import BLAKE2
|
||||
import Foundation
|
||||
|
||||
#if UseSwiftCrypto
|
||||
import Crypto
|
||||
#else
|
||||
import CryptoKit
|
||||
#endif
|
||||
|
||||
public enum SignatureAlgorithm: RawRepresentable {
|
||||
case pureEdDSA
|
||||
case hashedEdDSA
|
||||
|
||||
private static let dataEd = "Ed".data(using: .utf8)!
|
||||
private static let dataED = "ED".data(using: .utf8)!
|
||||
|
||||
public init?(rawValue: Data) {
|
||||
if rawValue == Self.dataEd {
|
||||
self = .pureEdDSA
|
||||
} else if rawValue == Self.dataED {
|
||||
self = .hashedEdDSA
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
public var rawValue: Data {
|
||||
switch self {
|
||||
case .pureEdDSA: return Self.dataEd
|
||||
case .hashedEdDSA: return Self.dataED
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private let untrustedCommentHeader = "untrusted comment: ".data(using: .utf8)!
|
||||
private let trustedCommentHeader = "trusted comment: ".data(using: .utf8)!
|
||||
|
||||
public struct PublicKey {
|
||||
public let untrustedComment: String
|
||||
public let signatureAlgorithm: SignatureAlgorithm
|
||||
public let keyID: Data
|
||||
public let publicKey: Curve25519.Signing.PublicKey
|
||||
|
||||
public init?<D>(text: D) where D: DataProtocol {
|
||||
let lines = text.split(separator: UInt8(ascii: "\n"), maxSplits: 2, omittingEmptySubsequences: false)
|
||||
guard lines.count == 2 || lines[2].isEmpty else { return nil }
|
||||
guard lines[0].starts(with: untrustedCommentHeader) else { return nil }
|
||||
guard
|
||||
let untrustedComment = String(
|
||||
data: Data(lines[0].suffix(from: untrustedCommentHeader.count as! D.Index)),
|
||||
encoding: .utf8
|
||||
)
|
||||
else { return nil }
|
||||
self.untrustedComment = untrustedComment
|
||||
guard let decLine2 = Data(base64Encoded: Data(lines[1]), options: []) else { return nil }
|
||||
guard decLine2.count == 42 else { return nil }
|
||||
guard let sigAlgo = SignatureAlgorithm(rawValue: decLine2.prefix(2)),
|
||||
sigAlgo == .pureEdDSA
|
||||
else { return nil }
|
||||
self.signatureAlgorithm = sigAlgo
|
||||
self.keyID = decLine2[2..<10]
|
||||
guard let publicKey = try? Curve25519.Signing.PublicKey(rawRepresentation: decLine2[10..<42]) else {
|
||||
return nil
|
||||
}
|
||||
self.publicKey = publicKey
|
||||
}
|
||||
|
||||
public func isValidSignature<D>(_ signature: Signature, for data: D) -> Bool where D: DataProtocol {
|
||||
guard signature.keyID == keyID else { return false }
|
||||
switch signature.signatureAlgorithm {
|
||||
case .pureEdDSA:
|
||||
guard publicKey.isValidSignature(signature.signature, for: data) else { return false }
|
||||
case .hashedEdDSA:
|
||||
let digest = try! BLAKE2b.hash(data: data) // Default parameters are guaranteed to be correct
|
||||
guard publicKey.isValidSignature(signature.signature, for: digest) else { return false }
|
||||
}
|
||||
let globalData = signature.signature + signature.trustedCommentData
|
||||
guard publicKey.isValidSignature(signature.globalSignature, for: globalData) else { return false }
|
||||
return true
|
||||
}
|
||||
|
||||
/// Verify the signature for a file using the hashed EdDSA algorithm.
|
||||
///
|
||||
/// This method reads the file in chunks to avoid loading the entire file into memory, but does so in a blocking manner.
|
||||
/// It's recommended to use this method in a background thread or task.
|
||||
public func isValidSignature(_ signature: Signature, forFileAt url: URL) throws -> Bool {
|
||||
guard signature.signatureAlgorithm == .hashedEdDSA else { throw SignatureVerifyError.algorithmNotSupportedForFile }
|
||||
var blake2b = try! BLAKE2b()
|
||||
|
||||
let fileHandle = try FileHandle(forReadingFrom: url)
|
||||
|
||||
let bufferSize = 4096
|
||||
while true {
|
||||
let data = fileHandle.readData(ofLength: bufferSize)
|
||||
if data.isEmpty { break }
|
||||
blake2b.update(data: data)
|
||||
}
|
||||
|
||||
defer { try? fileHandle.close() }
|
||||
|
||||
let digest = blake2b.finalize()
|
||||
guard publicKey.isValidSignature(signature.signature, for: digest) else { return false }
|
||||
let globalData = signature.signature + signature.trustedCommentData
|
||||
guard publicKey.isValidSignature(signature.globalSignature, for: globalData) else { return false }
|
||||
return true
|
||||
}
|
||||
|
||||
public enum SignatureVerifyError: Error {
|
||||
/// For ``PublicKey/isValidSignature(_:forFileAt:)``, only ``SignatureAlgorithm/hashedEdDSA`` algorithm is supported.
|
||||
case algorithmNotSupportedForFile
|
||||
}
|
||||
}
|
||||
|
||||
public struct Signature {
|
||||
public let untrustedComment: String
|
||||
public let signatureAlgorithm: SignatureAlgorithm
|
||||
public let keyID: Data
|
||||
public let signature: Data
|
||||
public let trustedCommentData: Data
|
||||
public let globalSignature: Data
|
||||
|
||||
public var trustedComment: String? {
|
||||
return String(data: trustedCommentData, encoding: .utf8)
|
||||
}
|
||||
|
||||
public init?<D>(text: D) where D: DataProtocol {
|
||||
let lines = text.split(separator: UInt8(ascii: "\n"), maxSplits: 4, omittingEmptySubsequences: false)
|
||||
guard lines.count == 4 || lines[4].isEmpty else { return nil }
|
||||
|
||||
guard lines[0].starts(with: untrustedCommentHeader) else { return nil }
|
||||
guard
|
||||
let untrustedComment = String(
|
||||
data: Data(lines[0].suffix(from: untrustedCommentHeader.count as! D.Index)),
|
||||
encoding: .utf8
|
||||
)
|
||||
else { return nil }
|
||||
self.untrustedComment = untrustedComment
|
||||
|
||||
guard let decLine2 = Data(base64Encoded: Data(lines[1]), options: []) else { return nil }
|
||||
guard decLine2.count == 74 else { return nil }
|
||||
guard let sigAlgo = SignatureAlgorithm(rawValue: decLine2.prefix(2)) else { return nil }
|
||||
self.signatureAlgorithm = sigAlgo
|
||||
self.keyID = decLine2[2..<10]
|
||||
self.signature = decLine2[10..<74]
|
||||
|
||||
guard lines[2].starts(with: trustedCommentHeader) else { return nil }
|
||||
self.trustedCommentData = Data(lines[2]).suffix(from: trustedCommentHeader.count)
|
||||
|
||||
guard let decLine4 = Data(base64Encoded: Data(lines[3]), options: []) else { return nil }
|
||||
guard decLine4.count == 64 else { return nil }
|
||||
self.globalSignature = decLine4
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,110 @@
|
|||
import Testing
|
||||
@testable import Minisign
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Based on https://github.com/slarew/swift-minisign
|
||||
// Copyright 2021 Stephen Larew, 2025 Shibo Lyu
|
||||
|
||||
@Test func example() async throws {
|
||||
// Write your test here and use APIs like `#expect(...)` to check expected conditions.
|
||||
import Foundation
|
||||
import Minisign
|
||||
import Testing
|
||||
|
||||
struct MinisignTests {
|
||||
|
||||
// password: test
|
||||
static let privKey = """
|
||||
untrusted comment: minisign encrypted secret key
|
||||
RWRTY0Iyvmea6pdrXYdDVqn91GknFBllkJmsQyS2jpVGoBqETB4AAAACAAAAAAAAAEAAAAAAr5jLDlb+ahHMPoPZAawLCKbUilW5ECEFsFCFSQLXfKrFQDv54sYqJzr3rR4gTmDnplQY+/T+EYCZkc5+QJOWwmaKBHPRx+Tw3rFH4CfCGkYRr4WNdZprmAzi1ZNzTl/wyvc1/uplgO8=
|
||||
|
||||
"""
|
||||
|
||||
static let pubKey = """
|
||||
untrusted comment: minisign public key E28A983382D6D7E9
|
||||
RWTp19aCM5iK4plw14gbtviwUSISZP++TJMfOfNTKoCcRIkcrV13Oppe
|
||||
|
||||
"""
|
||||
|
||||
static let signature = """
|
||||
untrusted comment: signature from minisign secret key
|
||||
RWTp19aCM5iK4olS02BlgllVHi3lvR9OYUVu7gM/lMsTRsO2Qb1IBxJBt3xW14hAFZo7Zlceavr7u69Rt0Wk5wMX0ShF13DZygY=
|
||||
trusted comment: timestamp:1629695994\tfile:test.pub
|
||||
o4E++I6KyX1h3iYMQ5yNyqEfhphdrIXiFmnWarzbB1BQpsckcO1I3LLttzS1w2CjCEauKZ3bOeY//sYui8rbAQ==
|
||||
|
||||
"""
|
||||
|
||||
static let badSignature = """
|
||||
untrusted comment: signature from minisign secret key
|
||||
RWTp19aCM5iK4olS02BlgllVHi3lvR9OYUVu7gM/lMsTRsO2Qb1IBxJBt3xW14hAFZo7Zlceavr7u69Rt0Wk5wMX0ShF13DZygY=
|
||||
trusted comment: timestamp:1629695994\tfile:test.pu
|
||||
o4E++I6KyX1h3iYMQ5yNyqEfhphdrIXiFmnWarzbB1BQpsckcO1I3LLttzS1w2CjCEauKZ3bOeY//sYui8rbAQ==
|
||||
|
||||
"""
|
||||
|
||||
static let prehashedSignature = """
|
||||
untrusted comment: signature from minisign secret key
|
||||
RUTp19aCM5iK4qzCz7Z/Y4YGsKxamuPediRB9WhvHRWnrJFREb/m9TCwxQUlug1QMYMqgaEi3IGS0trOxy4xhCkS3D7ksjLEFQg=
|
||||
trusted comment: timestamp:1629695918\tfile:test.pub
|
||||
0sZUtAIqxCkdV8nQ5+bODUIX09QZS4ilrsCT6wjkTXhsMJ2cQKL0wYH3Km8ZGG46Q2OhOY8sPl+2DTLjvrMmBg==
|
||||
|
||||
"""
|
||||
|
||||
static let badPrehashedSignature = """
|
||||
untrusted comment: signature from minisign secret key
|
||||
RUTp19aCM5iK4qzCz7Z/Y4YGsKxamuPediRB9WhvHRWnrJFREb/m9TCwxQUlug1QMYMqgaEi3IGS0trOxy4xhCkS3D7ksjLEFQg=
|
||||
trusted comment: timestamp:1629695918\tfile:test.pu
|
||||
0sZUtAIqxCkdV8nQ5+bODUIX09QZS4ilrsCT6wjkTXhsMJ2cQKL0wYH3Km8ZGG46Q2OhOY8sPl+2DTLjvrMmBg==
|
||||
|
||||
"""
|
||||
|
||||
@Test func parse() {
|
||||
let pubKey = PublicKey(text: Self.pubKey.data(using: .utf8)!)
|
||||
#expect(pubKey != nil)
|
||||
#expect(pubKey?.untrustedComment == "minisign public key E28A983382D6D7E9")
|
||||
#expect(pubKey?.keyID == Data(base64Encoded: "6dfWgjOYiuI=")!)
|
||||
#expect(pubKey?.signatureAlgorithm == .pureEdDSA)
|
||||
let sig = Signature(text: Self.signature.data(using: .utf8)!)
|
||||
#expect(sig != nil)
|
||||
#expect(sig?.untrustedComment == "signature from minisign secret key")
|
||||
#expect(sig?.trustedComment == "timestamp:1629695994\tfile:test.pub")
|
||||
#expect(sig?.signatureAlgorithm == .pureEdDSA)
|
||||
#expect(sig?.keyID == Data(base64Encoded: "6dfWgjOYiuI=")!)
|
||||
}
|
||||
|
||||
@Test func signature() {
|
||||
let pubKey = PublicKey(text: Self.pubKey.data(using: .utf8)!)
|
||||
#expect(pubKey != nil)
|
||||
let sig = Signature(text: Self.signature.data(using: .utf8)!)
|
||||
#expect(sig != nil)
|
||||
|
||||
#expect(pubKey!.isValidSignature(sig!, for: Self.pubKey.data(using: .utf8)!))
|
||||
#expect(!pubKey!.isValidSignature(sig!, for: Self.pubKey.data(using: .utf8)!.advanced(by: 1)))
|
||||
|
||||
let badSig = Signature(text: Self.badSignature.data(using: .utf8)!)
|
||||
#expect(badSig != nil)
|
||||
#expect(!pubKey!.isValidSignature(badSig!, for: Self.pubKey.data(using: .utf8)!))
|
||||
}
|
||||
|
||||
@Test func prehashedSignature() {
|
||||
let pubKey = PublicKey(text: Self.pubKey.data(using: .utf8)!)
|
||||
#expect(pubKey != nil)
|
||||
let phSig = Signature(text: Self.prehashedSignature.data(using: .utf8)!)
|
||||
#expect(phSig != nil)
|
||||
|
||||
#expect(pubKey!.isValidSignature(phSig!, for: Self.pubKey.data(using: .utf8)!))
|
||||
#expect(!pubKey!.isValidSignature(phSig!, for: Self.pubKey.data(using: .utf8)!.advanced(by: 1)))
|
||||
|
||||
let badPhSig = Signature(text: Self.badPrehashedSignature.data(using: .utf8)!)
|
||||
#expect(badPhSig != nil)
|
||||
#expect(!pubKey!.isValidSignature(badPhSig!, for: Self.pubKey.data(using: .utf8)!))
|
||||
}
|
||||
|
||||
@Test func prehashedSignatureForFile() {
|
||||
let pubKey = PublicKey(text: Self.pubKey.data(using: .utf8)!)
|
||||
#expect(pubKey != nil)
|
||||
let phSig = Signature(text: Self.prehashedSignature.data(using: .utf8)!)
|
||||
#expect(phSig != nil)
|
||||
|
||||
let fileURL = URL.temporaryDirectory.appending(component: "SwiftMinisignTests-\(UUID())-test.pub")
|
||||
defer { try? FileManager.default.removeItem(at: fileURL) }
|
||||
|
||||
try! Self.pubKey.data(using: .utf8)!.write(to: fileURL)
|
||||
#expect(try! pubKey!.isValidSignature(phSig!, forFileAt: fileURL))
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue