From 0b013852f2eb48699a72e4e110a2627706252925 Mon Sep 17 00:00:00 2001 From: Goncalo Frade Date: Mon, 29 Jan 2024 10:50:14 +0000 Subject: [PATCH] feat(jwa): removing curve 448 and open ssl since it was not being used This will be back in future implementation, but I noticed it actually didn't support all the targets I required. I will have to add the targets on a open ssl framework so then I can produce this work. this commit also adds a fix: secp256k1 bug when trying to recreate uncompressed key --- Package.swift | 3 - .../JWKCryptoPresentation.swift | 15 +- .../KeyManagement/JWKRepresentable.swift | 23 --- .../EC/Verifiers/ES256KVerifier.swift | 2 +- Sources/JSONWebKey/Curve448.swift | 135 ------------------ Sources/JSONWebSignature/JWS+Json.swift | 23 ++- 6 files changed, 30 insertions(+), 171 deletions(-) delete mode 100644 Sources/JSONWebKey/Curve448.swift diff --git a/Package.swift b/Package.swift index 9298369..d91dad6 100644 --- a/Package.swift +++ b/Package.swift @@ -31,8 +31,6 @@ let package = Package( ) ], dependencies: [ - // For `X448` support - .package(url: "https://github.com/krzyzanowskim/OpenSSL.git", .upToNextMinor(from: "3.1.4000")), // For `secp256k1` support .package(url: "https://github.com/GigaBitcoin/secp256k1.swift.git", .upToNextMinor(from: "0.15.0")), // For `AES_CBC_HMAC_SHA2`, `PBES2` and RSA DER encoding support @@ -78,7 +76,6 @@ let package = Package( .target( name: "JSONWebKey", dependencies: [ - "OpenSSL", "CryptoSwift", "Tools", .product(name: "secp256k1", package: "secp256k1.swift"), diff --git a/Sources/JSONWebAlgorithms/CryptoImplementation/JWKCryptoPresentation.swift b/Sources/JSONWebAlgorithms/CryptoImplementation/JWKCryptoPresentation.swift index 41ba999..5e62074 100644 --- a/Sources/JSONWebAlgorithms/CryptoImplementation/JWKCryptoPresentation.swift +++ b/Sources/JSONWebAlgorithms/CryptoImplementation/JWKCryptoPresentation.swift @@ -28,8 +28,7 @@ public extension JWK { is P384.KeyAgreement.PrivateKey.Type, is P521.KeyAgreement.PrivateKey.Type, is secp256k1.KeyAgreement.PrivateKey.Type, - is Curve25519.KeyAgreement.PrivateKey.Type, - is Curve448.KeyAgreement.PrivateKey.Type: + is Curve25519.KeyAgreement.PrivateKey.Type: guard let d else { throw JWK.Error.missingDComponent @@ -45,8 +44,6 @@ public extension JWK { return try secp256k1.KeyAgreement.PrivateKey(dataRepresentation: d, format: .uncompressed) as! T case is Curve25519.KeyAgreement.PrivateKey.Type: return try Curve25519.KeyAgreement.PrivateKey(rawRepresentation: d) as! T - case is Curve448.KeyAgreement.PrivateKey.Type: - return try Curve448.KeyAgreement.PrivateKey(rawRepresentation: d) as! T default: throw JWK.Error.notSupported } @@ -63,6 +60,11 @@ public extension JWK { throw JWK.Error.missingYComponent } let data = x + y + print(self.keyID) + print(x.toHexString()) + print(x.count) + print(y.toHexString()) + print(y.count) switch type { case is P256.KeyAgreement.PublicKey.Type: return try P256.KeyAgreement.PublicKey(rawRepresentation: data) as! T @@ -80,8 +82,7 @@ public extension JWK { throw JWK.Error.notSupported } - case is Curve25519.KeyAgreement.PublicKey.Type, - is Curve448.KeyAgreement.PublicKey.Type: + case is Curve25519.KeyAgreement.PublicKey.Type: guard let x else { throw JWK.Error.missingXComponent @@ -90,8 +91,6 @@ public extension JWK { switch type { case is Curve25519.KeyAgreement.PublicKey.Type: return try Curve25519.KeyAgreement.PublicKey(rawRepresentation: data) as! T - case is Curve448.KeyAgreement.PublicKey.Type: - return try Curve448.KeyAgreement.PublicKey(rawRepresentation: data) as! T default: throw JWK.Error.notSupported } diff --git a/Sources/JSONWebAlgorithms/KeyManagement/JWKRepresentable.swift b/Sources/JSONWebAlgorithms/KeyManagement/JWKRepresentable.swift index e03056b..7202fc0 100644 --- a/Sources/JSONWebAlgorithms/KeyManagement/JWKRepresentable.swift +++ b/Sources/JSONWebAlgorithms/KeyManagement/JWKRepresentable.swift @@ -177,18 +177,6 @@ extension Curve25519.KeyAgreement.PrivateKey: JWKRepresentable { } } -extension Curve448.KeyAgreement.PrivateKey: JWKRepresentable { - /// Returns the JWK representation of a `Curve448.KeyAgreement.PrivateKey` instance. - public var jwkRepresentation: JWK { - JWK( - keyType: .octetKeyPair, - curve: .x448, - x: publicKey.rawRepresentation, - d: rawRepresentation - ) - } -} - extension secp256k1.KeyAgreement.PublicKey: JWKRepresentable { /// Returns the JWK representation of a `secp256k1.KeyAgreement.PublicKey` instance. public var jwkRepresentation: JWK { @@ -344,14 +332,3 @@ extension Curve25519.Signing.PublicKey: JWKRepresentable { ) } } - -extension Curve448.KeyAgreement.PublicKey: JWKRepresentable { - /// Returns the JWK representation of a `Curve448.KeyAgreement.PublicKey` instance. - public var jwkRepresentation: JWK { - JWK( - keyType: .octetKeyPair, - curve: .x448, - x: rawRepresentation - ) - } -} diff --git a/Sources/JSONWebAlgorithms/Signatures/EC/Verifiers/ES256KVerifier.swift b/Sources/JSONWebAlgorithms/Signatures/EC/Verifiers/ES256KVerifier.swift index c8c73ef..c4307ec 100644 --- a/Sources/JSONWebAlgorithms/Signatures/EC/Verifiers/ES256KVerifier.swift +++ b/Sources/JSONWebAlgorithms/Signatures/EC/Verifiers/ES256KVerifier.swift @@ -26,7 +26,7 @@ struct ES256KVerifier: Verifier { let x = key?.x, let y = key?.y else { throw CryptoError.notValidPublicKey } - let publicKey = try secp256k1.Signing.PublicKey(dataRepresentation: x + y, format: .uncompressed) + let publicKey = try secp256k1.Signing.PublicKey(dataRepresentation: [0x04] + x + y, format: .uncompressed) let hash = SHA256.hash(data: data) return try publicKey.isValidSignature(getSignature(signature), for: hash) } diff --git a/Sources/JSONWebKey/Curve448.swift b/Sources/JSONWebKey/Curve448.swift deleted file mode 100644 index 8ca2d22..0000000 --- a/Sources/JSONWebKey/Curve448.swift +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright © 2023 Proxy, Inc. -// -// 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. - -import CryptoKit -import Foundation -@_implementationOnly import OpenSSL - -/// The Curve448 Elliptic Curve. -public enum Curve448 { - static let keySize = 56 -} - -extension Curve448 { - public enum KeyAgreement { - public struct PublicKey { - let x: Data - - /// Initializes a Curve448 Key for Key Agreement. - /// - /// - Parameter rawRepresentation: The data representation of the key - /// - Returns: An initialized key if the data is valid. - /// - Throws: Throws if the data is not a valid key. - public init(rawRepresentation: some ContiguousBytes) throws { - x = rawRepresentation.withUnsafeBytes { Data($0) } - var keyData = [UInt8](x) - let pkey = EVP_PKEY_new_raw_public_key(EVP_PKEY_X448, nil, &keyData, Curve448.keySize) - defer { EVP_PKEY_free(pkey) } - if pkey == nil { - throw CryptoKitError.underlyingCoreCryptoError(error: -1) - } - } - - /// A data representation of the public key - public var rawRepresentation: Data { - x - } - } - - public struct PrivateKey { - let d: Data - - /// Generates a new X448 private key. - public init() { - var pkey: OpaquePointer? - let ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_X448, nil) - defer { EVP_PKEY_CTX_free(ctx) } - EVP_PKEY_keygen_init(ctx) - EVP_PKEY_keygen(ctx, &pkey) - var keyLength = 0 - EVP_PKEY_get_raw_private_key(pkey, nil, &keyLength) - var keyData = [UInt8](repeating: 0, count: keyLength) - EVP_PKEY_get_raw_private_key(pkey, &keyData, &keyLength) - d = Data(keyData) - EVP_PKEY_free(pkey) - } - - /// Initializes the key with data. - /// - /// - Parameter data: The 56-bytes representation of the private key. - public init(rawRepresentation: some ContiguousBytes) throws { - d = rawRepresentation.withUnsafeBytes { Data($0) } - var keyData = [UInt8](d) - let pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_X448, nil, &keyData, Curve448.keySize) - defer { EVP_PKEY_free(pkey) } - if pkey == nil { - throw CryptoKitError.underlyingCoreCryptoError(error: -1) - } - } - - /// Returns the associated X448 public key. - /// - /// - Returns: The public key - public var publicKey: Curve448.KeyAgreement.PublicKey { - var keyData = [UInt8](d) - let pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_X448, nil, &keyData, Curve448.keySize) - defer { EVP_PKEY_free(pkey) } - var keyLength = 0 - EVP_PKEY_get_raw_public_key(pkey, nil, &keyLength) - var publicKeyData = [UInt8](repeating: 0, count: keyLength) - EVP_PKEY_get_raw_public_key(pkey, &publicKeyData, &keyLength) - return (try? Curve448.KeyAgreement.PublicKey(rawRepresentation: publicKeyData)).unsafelyUnwrapped - } - - /// Performs an elliptic curve Diffie-Hellmann key agreement over X448. - /// - /// - Parameter publicKeyShare: The public key share to perform the key agreement with. - /// - Returns: The shared secret - /// - Throws: Throws if the operation failed to be performed. - public func sharedSecretFromKeyAgreement(with publicKeyShare: Curve448.KeyAgreement.PublicKey) throws -> Data { - var sharedSecretKeyLength = 0 - var keyData = [UInt8](d) - let pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_X448, nil, &keyData, Curve448.keySize) - var peerKeyData = [UInt8](publicKeyShare.x) - let peerKey = EVP_PKEY_new_raw_public_key(EVP_PKEY_X448, nil, &peerKeyData, Curve448.keySize) - let ctx = EVP_PKEY_CTX_new(pkey, nil) - defer { - EVP_PKEY_free(pkey) - EVP_PKEY_free(peerKey) - EVP_PKEY_CTX_free(ctx) - } - if ctx == nil { - throw CryptoKitError.incorrectKeySize - } - let result_EVP_PKEY_derive_init = EVP_PKEY_derive_init(ctx) - if result_EVP_PKEY_derive_init <= 0 { - throw CryptoKitError.underlyingCoreCryptoError(error: result_EVP_PKEY_derive_init) - } - let result_EVP_PKEY_derive_set_peer = EVP_PKEY_derive_set_peer(ctx, peerKey) - if result_EVP_PKEY_derive_set_peer <= 0 { - throw CryptoKitError.underlyingCoreCryptoError(error: result_EVP_PKEY_derive_set_peer) - } - let result1_EVP_PKEY_derive = EVP_PKEY_derive(ctx, nil, &sharedSecretKeyLength) - if result1_EVP_PKEY_derive <= 0 { - throw CryptoKitError.underlyingCoreCryptoError(error: result1_EVP_PKEY_derive) - } - var sharedSecretKey = [UInt8](repeating: 0, count: sharedSecretKeyLength) - let result2_EVP_PKEY_derive = EVP_PKEY_derive(ctx, &sharedSecretKey, &sharedSecretKeyLength) - if result2_EVP_PKEY_derive <= 0 { - throw CryptoKitError.underlyingCoreCryptoError(error: result2_EVP_PKEY_derive) - } - return Data(sharedSecretKey) - } - - /// A data representation of the private key - public var rawRepresentation: Data { - d - } - } - } -} diff --git a/Sources/JSONWebSignature/JWS+Json.swift b/Sources/JSONWebSignature/JWS+Json.swift index 17ae89a..71bb9e6 100644 --- a/Sources/JSONWebSignature/JWS+Json.swift +++ b/Sources/JSONWebSignature/JWS+Json.swift @@ -27,7 +27,7 @@ public typealias DefaultJWSJson = JWSJson: Codable { +public struct JWSJson { /// `Signature` represents a single signature within the `JWSJson`, including its associated headers and signature data. public struct Signature { @@ -143,6 +143,27 @@ public struct JWSJson