diff --git a/Sources/JWTKit/X5C/X5CVerifier.swift b/Sources/JWTKit/X5C/X5CVerifier.swift index 74b6b6c5..9acae5ee 100644 --- a/Sources/JWTKit/X5C/X5CVerifier.swift +++ b/Sources/JWTKit/X5C/X5CVerifier.swift @@ -221,6 +221,39 @@ extension X5CVerifier { case .eddsa: let eddsaKey = try EdDSA.PublicKey(pem: certificate.publicKey.serializeAsPEM().pemString) return JWTSigner(algorithm: EdDSASigner(key: eddsaKey), parser: parser) + case .rs256, .ps256: + let rsaKey = try Insecure.RSA.PublicKey(pem: certificate.publicKey.serializeAsPEM().pemString) + return JWTSigner( + algorithm: RSASigner( + key: rsaKey, + algorithm: .sha256, + name: "", + padding: alg == .rs256 ? .insecurePKCS1v1_5 : .PSS + ), + parser: parser + ) + case .rs384, .ps384: + let rsaKey = try Insecure.RSA.PublicKey(pem: certificate.publicKey.serializeAsPEM().pemString) + return JWTSigner( + algorithm: RSASigner( + key: rsaKey, + algorithm: .sha384, + name: "", + padding: alg == .rs384 ? .insecurePKCS1v1_5 : .PSS + ), + parser: parser + ) + case .rs512, .ps512: + let rsaKey = try Insecure.RSA.PublicKey(pem: certificate.publicKey.serializeAsPEM().pemString) + return JWTSigner( + algorithm: RSASigner( + key: rsaKey, + algorithm: .sha512, + name: "", + padding: alg == .rs512 ? .insecurePKCS1v1_5 : .PSS + ), + parser: parser + ) default: throw JWTError.unsupportedAlgorithm(alg: alg.rawValue) } diff --git a/Tests/JWTKitTests/X5CTests.swift b/Tests/JWTKitTests/X5CTests.swift index 12e92d49..2b5e8aed 100644 --- a/Tests/JWTKitTests/X5CTests.swift +++ b/Tests/JWTKitTests/X5CTests.swift @@ -278,7 +278,9 @@ struct X5CTests { } } - @Test("Test signing with invalid x5c chain", arguments: [JWK.Algorithm.es256, .es384, .es512]) + @Test( + "Test signing with invalid x5c chain", + arguments: [JWK.Algorithm.es256, .es384, .es512, .rs256, .ps256, .rs384, .ps384, .rs512, .ps512]) func signWithInvalidX5CChain(_ alg: JWK.Algorithm) async throws { let keyCollection = JWTKeyCollection() switch alg { @@ -288,6 +290,36 @@ struct X5CTests { try await keyCollection.add(ecdsa: ES384PrivateKey(pem: x5cLeafCertKeys[alg]!.serializeAsPEM().pemString)) case .es512: try await keyCollection.add(ecdsa: ES512PrivateKey(pem: x5cLeafCertKeys[alg]!.serializeAsPEM().pemString)) + case .rs256: + try await keyCollection.add( + rsa: Insecure.RSA.PrivateKey(pem: x5cLeafCertKeys[alg]!.serializeAsPEM().pemString), + digestAlgorithm: .sha256 + ) + case .ps256: + try await keyCollection.add( + pss: Insecure.RSA.PrivateKey(pem: x5cLeafCertKeys[alg]!.serializeAsPEM().pemString), + digestAlgorithm: .sha256 + ) + case .rs384: + try await keyCollection.add( + rsa: Insecure.RSA.PrivateKey(pem: x5cLeafCertKeys[alg]!.serializeAsPEM().pemString), + digestAlgorithm: .sha384 + ) + case .ps384: + try await keyCollection.add( + pss: Insecure.RSA.PrivateKey(pem: x5cLeafCertKeys[alg]!.serializeAsPEM().pemString), + digestAlgorithm: .sha384 + ) + case .rs512: + try await keyCollection.add( + rsa: Insecure.RSA.PrivateKey(pem: x5cLeafCertKeys[alg]!.serializeAsPEM().pemString), + digestAlgorithm: .sha512 + ) + case .ps512: + try await keyCollection.add( + pss: Insecure.RSA.PrivateKey(pem: x5cLeafCertKeys[alg]!.serializeAsPEM().pemString), + digestAlgorithm: .sha512 + ) default: return } @@ -315,8 +347,10 @@ struct X5CTests { } } - @Test("Test signing with ES x5c chain", arguments: [JWK.Algorithm.es256, .es384, .es512]) - func signWithESX5CChain(_ alg: JWK.Algorithm) async throws { + @Test( + "Test signing with ES, RS, PS x5c chains", + arguments: [JWK.Algorithm.es256, .es384, .es512, .rs256, .ps256, .rs384, .ps384, .rs512, .ps512]) + func signWithX5CChain(_ alg: JWK.Algorithm) async throws { let keyCollection = JWTKeyCollection() switch alg { case .es256: @@ -325,6 +359,36 @@ struct X5CTests { try await keyCollection.add(ecdsa: ES384PrivateKey(pem: x5cLeafCertKeys[alg]!.serializeAsPEM().pemString)) case .es512: try await keyCollection.add(ecdsa: ES512PrivateKey(pem: x5cLeafCertKeys[alg]!.serializeAsPEM().pemString)) + case .rs256: + try await keyCollection.add( + rsa: Insecure.RSA.PrivateKey(pem: x5cLeafCertKeys[alg]!.serializeAsPEM().pemString), + digestAlgorithm: .sha256 + ) + case .ps256: + try await keyCollection.add( + pss: Insecure.RSA.PrivateKey(pem: x5cLeafCertKeys[alg]!.serializeAsPEM().pemString), + digestAlgorithm: .sha256 + ) + case .rs384: + try await keyCollection.add( + rsa: Insecure.RSA.PrivateKey(pem: x5cLeafCertKeys[alg]!.serializeAsPEM().pemString), + digestAlgorithm: .sha384 + ) + case .ps384: + try await keyCollection.add( + pss: Insecure.RSA.PrivateKey(pem: x5cLeafCertKeys[alg]!.serializeAsPEM().pemString), + digestAlgorithm: .sha384 + ) + case .rs512: + try await keyCollection.add( + rsa: Insecure.RSA.PrivateKey(pem: x5cLeafCertKeys[alg]!.serializeAsPEM().pemString), + digestAlgorithm: .sha512 + ) + case .ps512: + try await keyCollection.add( + pss: Insecure.RSA.PrivateKey(pem: x5cLeafCertKeys[alg]!.serializeAsPEM().pemString), + digestAlgorithm: .sha512 + ) default: return } @@ -427,6 +491,12 @@ let x5cLeafCertKeys: [JWK.Algorithm: Certificate.PrivateKey] = try! [ .es384: Certificate.PrivateKey(pemEncoded: ES384PrivateKey().pemRepresentation), .es512: Certificate.PrivateKey(pemEncoded: ES512PrivateKey().pemRepresentation), .eddsa: Certificate.PrivateKey(pemEncoded: EdDSA.PrivateKey().pemRepresentation), + .rs256: Certificate.PrivateKey(pemEncoded: Insecure.RSA.PrivateKey(backing: .init(keySize: .bits2048)).pemRepresentation), + .ps256: Certificate.PrivateKey(pemEncoded: Insecure.RSA.PrivateKey(backing: .init(keySize: .bits2048)).pemRepresentation), + .rs384: Certificate.PrivateKey(pemEncoded: Insecure.RSA.PrivateKey(backing: .init(keySize: .bits2048)).pemRepresentation), + .ps384: Certificate.PrivateKey(pemEncoded: Insecure.RSA.PrivateKey(backing: .init(keySize: .bits2048)).pemRepresentation), + .rs512: Certificate.PrivateKey(pemEncoded: Insecure.RSA.PrivateKey(backing: .init(keySize: .bits2048)).pemRepresentation), + .ps512: Certificate.PrivateKey(pemEncoded: Insecure.RSA.PrivateKey(backing: .init(keySize: .bits2048)).pemRepresentation), ] let x5cCerts: [JWK.Algorithm: [String]] = [ @@ -434,6 +504,12 @@ let x5cCerts: [JWK.Algorithm: [String]] = [ .es384: getChain(alg: .es384), .es512: getChain(alg: .es512), .eddsa: getChain(alg: .eddsa), + .rs256: getChain(alg: .rs256), + .ps256: getChain(alg: .ps256), + .rs384: getChain(alg: .rs384), + .ps384: getChain(alg: .ps384), + .rs512: getChain(alg: .rs512), + .ps512: getChain(alg: .ps512), ] private func getChain(alg: JWK.Algorithm) -> [String] {