From 50ec40ed1d0203a78e197ad0f07582efc5449c1e Mon Sep 17 00:00:00 2001 From: Mike Nachbaur Date: Thu, 16 May 2024 16:43:26 -0700 Subject: [PATCH 1/3] Allow JWK algorithms to support unknown values --- .../AuthFoundation/JWT/Enums/JWK+Enums.swift | 63 ++++++------- .../JWT/Extensions/JWK+EnumExtensions.swift | 88 +++++++++++++++++++ 2 files changed, 121 insertions(+), 30 deletions(-) create mode 100644 Sources/AuthFoundation/JWT/Extensions/JWK+EnumExtensions.swift diff --git a/Sources/AuthFoundation/JWT/Enums/JWK+Enums.swift b/Sources/AuthFoundation/JWT/Enums/JWK+Enums.swift index 82ecbf0d4..3899d8d27 100644 --- a/Sources/AuthFoundation/JWT/Enums/JWK+Enums.swift +++ b/Sources/AuthFoundation/JWT/Enums/JWK+Enums.swift @@ -28,40 +28,43 @@ extension JWK { // swiftlint:disable identifier_name /// The algorithm this key is intended to be used with. - public enum Algorithm: String, Codable { + public enum Algorithm: Codable { // JWS Algorithms according to https://www.rfc-editor.org/rfc/rfc7518.html#section-3.1 - case hs256 = "HS256" - case hs384 = "HS384" - case hs512 = "HS512" - case rs256 = "RS256" - case rs384 = "RS384" - case rs512 = "RS512" - case es256 = "ES256" - case es384 = "ES384" - case es512 = "ES512" - case ps256 = "PS256" - case ps384 = "PS384" - case ps512 = "PS512" + case hs256 + case hs384 + case hs512 + case rs256 + case rs384 + case rs512 + case es256 + case es384 + case es512 + case ps256 + case ps384 + case ps512 case none // JWE Algorithms according to https://www.rfc-editor.org/rfc/rfc7518.html#section-4.1 - case rsa1_5 = "RSA1_5" - case rsaOAEP = "RSA-OAEP" - case rsaOAEP256 = "RSA-OAEP-256" - case a128KW = "A128KW" - case a192KW = "A192KW" - case a256KW = "A256KW" - case dir = "dir" - case ecdhES = "ECDH-ES" - case ecdhES_a128KW = "ECDH-ES+A128KW" - case ecdhES_a192KW = "ECDH-ES+A192KW" - case ecdhES_a256KW = "ECDH-ES+A256KW" - case a128GCMKW = "A128GCMKW" - case a192GCMKW = "A192GCMKW" - case a256GCMKW = "A256GCMKW" - case pbes2_HS256_A128KW = "PBES2-HS256+A128KW" - case pbes2_HS384_A192KW = "PBES2-HS384+A192KW" - case pbes2_HS512_A256KW = "PBES2-HS512+A256KW" + case rsa1_5 + case rsaOAEP + case rsaOAEP256 + case a128KW + case a192KW + case a256KW + case dir + case ecdhES + case ecdhES_a128KW + case ecdhES_a192KW + case ecdhES_a256KW + case edDSA + case a128GCMKW + case a192GCMKW + case a256GCMKW + case pbes2_HS256_A128KW + case pbes2_HS384_A192KW + case pbes2_HS512_A256KW + + case other(algorithm: String) } // swiftlint:enable identifier_name } diff --git a/Sources/AuthFoundation/JWT/Extensions/JWK+EnumExtensions.swift b/Sources/AuthFoundation/JWT/Extensions/JWK+EnumExtensions.swift new file mode 100644 index 000000000..c2404387d --- /dev/null +++ b/Sources/AuthFoundation/JWT/Extensions/JWK+EnumExtensions.swift @@ -0,0 +1,88 @@ +// +// Copyright (c) 2024-Present, Okta, Inc. and/or its affiliates. All rights reserved. +// The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.") +// +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and limitations under the License. +// + +import Foundation + +extension JWK.Algorithm: RawRepresentable, Equatable, Hashable { + public init?(rawValue: RawValue) { + switch rawValue { + case "HS256": self = .hs256 + case "HS384": self = .hs384 + case "HS512": self = .hs512 + case "RS256": self = .rs256 + case "RS384": self = .rs384 + case "RS512": self = .rs512 + case "ES256": self = .es256 + case "ES384": self = .es384 + case "ES512": self = .es512 + case "PS256": self = .ps256 + case "PS384": self = .ps384 + case "PS512": self = .ps512 + case "RSA1_5": self = .rsa1_5 + case "RSA-OAEP": self = .rsaOAEP + case "RSA-OAEP-256": self = .rsaOAEP256 + case "A128KW": self = .a128KW + case "A192KW": self = .a192KW + case "A256KW": self = .a256KW + case "dir": self = .dir + case "ECDH-ES": self = .ecdhES + case "ECDH-ES+A128KW": self = .ecdhES_a128KW + case "ECDH-ES+A192KW": self = .ecdhES_a192KW + case "ECDH-ES+A256KW": self = .ecdhES_a256KW + case "EdDSA": self = .edDSA + case "A128GCMKW": self = .a128GCMKW + case "A192GCMKW": self = .a192GCMKW + case "A256GCMKW": self = .a256GCMKW + case "PBES2-HS256+A128KW": self = .pbes2_HS256_A128KW + case "PBES2-HS384+A192KW": self = .pbes2_HS384_A192KW + case "PBES2-HS512+A256KW": self = .pbes2_HS512_A256KW + default: self = .other(algorithm: rawValue) + } + } + + public var rawValue: String { + switch self { + case .hs256: return "HS256" + case .hs384: return "HS384" + case .hs512: return "HS512" + case .rs256: return "RS256" + case .rs384: return "RS384" + case .rs512: return "RS512" + case .es256: return "ES256" + case .es384: return "ES384" + case .es512: return "ES512" + case .ps256: return "PS256" + case .ps384: return "PS384" + case .ps512: return "PS512" + case .rsa1_5: return "RSA1_5" + case .rsaOAEP: return "RSA-OAEP" + case .rsaOAEP256: return "RSA-OAEP-256" + case .a128KW: return "A128KW" + case .a192KW: return "A192KW" + case .a256KW: return "A256KW" + case .dir: return "dir" + case .ecdhES: return "ECDH-ES" + case .ecdhES_a128KW: return "ECDH-ES+A128KW" + case .ecdhES_a192KW: return "ECDH-ES+A192KW" + case .ecdhES_a256KW: return "ECDH-ES+A256KW" + case .edDSA: return "EdDSA" + case .a128GCMKW: return "A128GCMKW" + case .a192GCMKW: return "A192GCMKW" + case .a256GCMKW: return "A256GCMKW" + case .pbes2_HS256_A128KW: return "PBES2-HS256+A128KW" + case .pbes2_HS384_A192KW: return "PBES2-HS384+A192KW" + case .pbes2_HS512_A256KW: return "PBES2-HS512+A256KW" + case .other(algorithm: let value): return value + case .none: return "" + } + } +} From 27bb4f81813d5a59f9ce04545c6346dc92bcc4bf Mon Sep 17 00:00:00 2001 From: Mike Nachbaur Date: Thu, 16 May 2024 16:50:44 -0700 Subject: [PATCH 2/3] Silence swiftlint warning --- Sources/AuthFoundation/JWT/Extensions/JWK+EnumExtensions.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Sources/AuthFoundation/JWT/Extensions/JWK+EnumExtensions.swift b/Sources/AuthFoundation/JWT/Extensions/JWK+EnumExtensions.swift index c2404387d..fe0a7ad73 100644 --- a/Sources/AuthFoundation/JWT/Extensions/JWK+EnumExtensions.swift +++ b/Sources/AuthFoundation/JWT/Extensions/JWK+EnumExtensions.swift @@ -12,6 +12,7 @@ import Foundation +// swiftlint:disable cyclomatic_complexity extension JWK.Algorithm: RawRepresentable, Equatable, Hashable { public init?(rawValue: RawValue) { switch rawValue { @@ -86,3 +87,4 @@ extension JWK.Algorithm: RawRepresentable, Equatable, Hashable { } } } +// swiftlint:enable cyclomatic_complexity From 8c7e8d601e6363afd7b43b0d7195ad452faf69f9 Mon Sep 17 00:00:00 2001 From: Mike Nachbaur Date: Fri, 17 May 2024 10:03:15 -0700 Subject: [PATCH 3/3] Ensure the JWK type alias is specified --- Sources/AuthFoundation/JWT/Extensions/JWK+EnumExtensions.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Sources/AuthFoundation/JWT/Extensions/JWK+EnumExtensions.swift b/Sources/AuthFoundation/JWT/Extensions/JWK+EnumExtensions.swift index fe0a7ad73..1d8787ce8 100644 --- a/Sources/AuthFoundation/JWT/Extensions/JWK+EnumExtensions.swift +++ b/Sources/AuthFoundation/JWT/Extensions/JWK+EnumExtensions.swift @@ -14,6 +14,8 @@ import Foundation // swiftlint:disable cyclomatic_complexity extension JWK.Algorithm: RawRepresentable, Equatable, Hashable { + public typealias RawValue = String + public init?(rawValue: RawValue) { switch rawValue { case "HS256": self = .hs256