Skip to content

Commit

Permalink
Merge pull request #4 from amosavian/bugfix/signing-seckey
Browse files Browse the repository at this point in the history
fix: Issues related to signing with SecKey.
  • Loading branch information
amosavian authored Oct 31, 2023
2 parents 8cee900 + 703d15a commit 4c15849
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 19 deletions.
20 changes: 13 additions & 7 deletions Sources/JWSETKit/Cryptography/EC/JWK-EC.swift
Original file line number Diff line number Diff line change
Expand Up @@ -123,29 +123,35 @@ enum ECHelper {
let length = data.count
if isPrivateKey {
return [
data[0 ..< (length / 3)],
data[(length / 3) ..< (2 * length / 3)],
data[(2 * length / 3)...],
data.prefix(length / 3),
data.dropFirst(length / 3).prefix(length / 3),
data.suffix(from: length / 3),
]
} else {
return [
data[0 ..< (length / 2)],
data[(length / 2)...],
data.prefix(length / 2),
data.suffix(from: length / 2),
]
}
}

static func ecWebKey(data: Data, isPrivateKey: Bool) throws -> any JSONWebKey {
let components = try ecComponents(data, isPrivateKey: isPrivateKey)
var key = AnyJSONWebKey()

guard !components.isEmpty else {
throw JSONWebKeyError.unknownKeyType
}

key.keyType = .ellipticCurve
key.curve = .init(rawValue: "P-\(components[0].count * 8)")

switch components.count {
case 2:
key.keyType = .ellipticCurve
key.xCoordinate = components[0]
key.yCoordinate = components[1]
return JSONWebECPublicKey(storage: key.storage)
case 3:
key.keyType = .ellipticCurve
key.xCoordinate = components[0]
key.yCoordinate = components[1]
key.privateKey = components[2]
Expand Down
32 changes: 20 additions & 12 deletions Sources/JWSETKit/Cryptography/RSA/SecKey.swift
Original file line number Diff line number Diff line change
Expand Up @@ -166,22 +166,27 @@ extension SecKey: JSONWebKey {

extension SecKey: JSONWebValidatingKey {
fileprivate static let signingAlgorithms: [JSONWebSignatureAlgorithm: SecKeyAlgorithm] = [
.rsaSignaturePKCS1v15SHA256: .rsaSignatureMessagePKCS1v15SHA256,
.rsaSignaturePKCS1v15SHA384: .rsaSignatureMessagePKCS1v15SHA384,
.rsaSignaturePKCS1v15SHA512: .rsaSignatureMessagePKCS1v15SHA512,
.rsaSignaturePSSSHA256: .rsaSignatureMessagePSSSHA256,
.rsaSignaturePSSSHA384: .rsaSignatureMessagePSSSHA384,
.rsaSignaturePSSSHA512: .rsaSignatureMessagePSSSHA512,
.ecdsaSignatureP256SHA256: .ecdsaSignatureRFC4754,
.ecdsaSignatureP384SHA384: .ecdsaSignatureRFC4754,
.ecdsaSignatureP521SHA512: .ecdsaSignatureRFC4754,
.rsaSignaturePKCS1v15SHA256: .rsaSignatureDigestPKCS1v15SHA256,
.rsaSignaturePKCS1v15SHA384: .rsaSignatureDigestPKCS1v15SHA384,
.rsaSignaturePKCS1v15SHA512: .rsaSignatureDigestPKCS1v15SHA512,
.rsaSignaturePSSSHA256: .rsaSignatureDigestPSSSHA256,
.rsaSignaturePSSSHA384: .rsaSignatureDigestPSSSHA384,
.rsaSignaturePSSSHA512: .rsaSignatureDigestPSSSHA512,
]

public func verifySignature<S, D>(_ signature: S, for data: D, using algorithm: JSONWebSignatureAlgorithm) throws where S: DataProtocol, D: DataProtocol {
guard let secAlgorithm = Self.signingAlgorithms[algorithm] else {
guard let secAlgorithm = Self.signingAlgorithms[algorithm], let hashFunction = algorithm.hashFunction else {
throw JSONWebKeyError.operationNotAllowed
}

let digest = hashFunction.hash(data: data).withUnsafeBytes { Data($0) }
let result = try handle { error in
SecKeyVerifySignature(
self, secAlgorithm,
Data(data) as CFData, Data(signature) as CFData,
self.publicKey, secAlgorithm,
digest as CFData, Data(signature) as CFData,
&error
)
}
Expand Down Expand Up @@ -237,11 +242,14 @@ extension JSONWebSigningKey where Self: SecKey {

extension SecKey: JSONWebSigningKey {
public func signature<D>(_ data: D, using algorithm: JSONWebSignatureAlgorithm) throws -> Data where D: DataProtocol {
guard let secAlgorithm = Self.signingAlgorithms[algorithm] else {
guard let secAlgorithm = Self.signingAlgorithms[algorithm], let hashFunction = algorithm.hashFunction else {
throw JSONWebKeyError.operationNotAllowed
}

let digest = hashFunction.hash(data: data).withUnsafeBytes { Data($0) }

return try handle { error in
SecKeyCreateSignature(self, secAlgorithm, Data(data) as CFData, &error)
SecKeyCreateSignature(self, secAlgorithm, digest as CFData, &error)
} as Data
}
}
Expand Down

0 comments on commit 4c15849

Please sign in to comment.