vapor / jwt-kit

🔑 JSON Web Token (JWT) signing and verification (HMAC, ECDSA, EdDSA, RSA, PSS) with support for JWS and JWK
https://api.vapor.codes/jwtkit/documentation/jwtkit/
MIT License
201 stars 53 forks source link

"signing algorithm error: signFailure" on macOS when app is built by "swift build" #26

Closed mczachurski closed 4 years ago

mczachurski commented 4 years ago

Hello,

I have a strange error only when I'm building application by "swift build" in terminal. When I'm using XCode everything is working.

Steps to reproduce:

  1. Generate new Vapor app
$ vapor-beta new jwttest
$ cd jwttest
  1. Edit three files

Package.swift

// swift-tools-version:5.2
import PackageDescription

let package = Package(
    name: "hello",
    platforms: [
       .macOS(.v10_15)
    ],
    dependencies: [
        // 💧 A server-side Swift web framework.
        .package(url: "https://github.com/vapor/vapor.git", from: "4.0.0-rc"),
        .package(url: "https://github.com/vapor/jwt-kit.git", from: "4.0.0-rc"),
        .package(url: "https://github.com/vapor/jwt.git", from: "4.0.0-rc")
    ],
    targets: [
        .target(
            name: "App",
            dependencies: [
                .product(name: "Vapor", package: "vapor"),
                .product(name: "JWT", package: "jwt"),
                .product(name: "JWTKit", package: "jwt-kit")
            ],
            swiftSettings: [
                // Enable better optimizations when building in Release configuration. Despite the use of
                // the `.unsafeFlags` construct required by SwiftPM, this flag is recommended for Release
                // builds. See <https://github.com/swift-server/guides#building-for-production> for details.
                .unsafeFlags(["-cross-module-optimization"], .when(configuration: .release))
            ]
        ),
        .target(name: "Run", dependencies: [.target(name: "App")]),
        .testTarget(name: "AppTests", dependencies: [
            .target(name: "App"),
            .product(name: "XCTVapor", package: "vapor"),
        ])
    ]
)

routes.swift

import Vapor
import JWT
import JWTKit

struct UserPayload: JWTPayload {
    var id: UUID
    var userName: String

    func verify(using signer: JWTSigner) throws {
    }
}

func routes(_ app: Application) throws {
    app.get { req -> String in

        let authorizationPayload = UserPayload(id: UUID(), userName: "John Smith")
        let accessToken = try req.jwt.sign(authorizationPayload)
        return accessToken
    }
}

configure.swift

import Vapor
import JWT
import JWTKit

extension String {
    var bytes: [UInt8] { .init(self.utf8) }
}

// configures your application
public func configure(_ app: Application) throws {
    // uncomment to serve files from /Public folder
    // app.middleware.use(FileMiddleware(publicDirectory: app.directory.publicDirectory))

    let privateKeyString =
"""
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAhAHFb1M+P7qjwVlR7Es/3GBq3yICZP1eZ/JShBuLO4stTGHR
akqlOYGC+ayTxOomjp4aHFNxzHxdVe9keGv0UltP8HbRTJTubOlWl2w7zG8xAKOy
2/9s+eE3obxPrf92Ffpbx3nef9hVh8PtiV9vSd8J9QoPtODujCBf+F8n/zIrLB0m
7Tf6e5POZ8aJ93hNyjekljITNHoCwqmkD1HSgXiaoMC17CItJoRLANIMQPNVwe8d
/2ZejydBVEWxNwbTzz6DPBX5uFXhmDmOcUfqT0L9l8iy66e6M/8g6roAYkTKs1vP
PT+NfM8KwyDpx/aMTxaDwjwyOO39erV95GY6ywIDAQABAoIBAC9OazCwBjjUa+bY
WZFyjhotu17nUzBZ1EEwB/4r2MOn5r3euCt9QKTREtziybnhp5uocPcBuGBtmQ04
0yqMlWwGKSmlivAE10TUgiGVugBTQJ5YC7rnWGhcG5GsaGmUiP7rT4S22dO69TvI
LRHzz3ALrAfSaTqK+THiUEIz56N+D3F9B8z35Epxug7+6o3OSWQ9u4fejnOqFexH
TsWWaX1nlic4hp6rQ771cVI1plNxmJEfXCI62fNMa25phTUDEszp3ubjdJw/tkEM
2WwNCyt+eocs54GA2HEmBVkOgsAYeAV8S7RjvWc7khkyR8AeP+2t7bfBZGlodGNx
KMmrt0ECgYEA95u+OQwQRk1gkpn/mPLpZxgHvYqUQLbhu3Lutv+RyIohGvPstb95
xtZDWJWbm71rUYQ1k72+K0mo+LrFVDKA4vtiUSj754A33Q3yWLWrbjCG35Ol6z9X
XkaK/KZ1WHWoH6kM067nreacvDRKpWJD45ck/y5UJKL0gu45e4GHYnsCgYEAiHsR
HDR6mKo4rZ1p4ZjgtE9avhC3f9fzbgZQv1vGw3HIKsa4Kd2AoaxNlojfRsEjvEVP
4ettKc77ts/92X26uJrd9qORaTokI1t7nMtjub5Q+As/uSZTbvsjoMcdWi2VzL5w
t2asQ6kyGJ2oMWeo74bDgRJFLon/K7hlHdhu//ECgYBjGsQVYz20Vc4cf2TtW/SN
nfGjLK9QA6Lv+v2O41X/VUIQ3qbUy/G64xGLiD4DJNqqgudK3fwaqV3nSCIpJBmw
P/vHDkddDlXNtYJVfUlDTkr9e8RCF1Up18RTgXCgWl9TZL9MjsoOMap0Ld3euikA
FAPr2yg0jcCeEymQxHRitwKBgD0CRnPFQchcz1lMtLgUDt6LWpT8BAsyDa9xQ0dH
T2KuyjvU+R491fJvg393T9fhHohas4raIsI9tGfUMjW27nD3SaGnHKldRCpKCsfc
Y4f0e11mKeYqK8HAofyNBaH6HqyXtOtHClp0l+BJGZZ8MBhitaJM+IAFT/vLQehF
h9kBAoGBANLA9PaqoPdS0zt2pFQ9P3nTPsbceFY4Uvz3gYcoCaY+ePPaPIhVAjqf
M1Bzv2/nwqtOLc7yGwiaC1kxJeKQ/9Q+sbsGHs2KKZMoeS9sYwPRpH34Kkg9h4Dc
waNSUrQp9XZJLA9SgN+N2JwuDi0bxsr0saaLdmWn3S3L6rsg5Cja
-----END RSA PRIVATE KEY-----
"""

    let rsaKey = try RSAKey.private(pem: privateKeyString.bytes)
    let privateSigner = JWTSigner.rs512(key: rsaKey)
    app.jwt.signers.use(privateSigner)

    // register routes
    try routes(app)
}
  1. Build application:
$ swift build

I have the following logs here:

Fetching https://github.com/vapor/console-kit.git
Fetching https://github.com/vapor/websocket-kit.git
Fetching https://github.com/apple/swift-nio-extras.git
Fetching https://github.com/apple/swift-nio.git
Fetching https://github.com/apple/swift-nio-http2.git
Fetching https://github.com/apple/swift-nio-ssl.git
Fetching https://github.com/swift-server/async-http-client.git
Fetching https://github.com/vapor/async-kit.git
Fetching https://github.com/vapor/jwt.git
Fetching https://github.com/apple/swift-crypto.git
Fetching https://github.com/vapor/jwt-kit.git
Fetching https://github.com/vapor/routing-kit.git
Fetching https://github.com/vapor/vapor.git
Fetching https://github.com/swift-server/swift-backtrace.git
Fetching https://github.com/apple/swift-log.git
Fetching https://github.com/apple/swift-metrics.git
Cloning https://github.com/vapor/async-kit.git
Resolving https://github.com/vapor/async-kit.git at 1.1.1
Cloning https://github.com/vapor/routing-kit.git
Resolving https://github.com/vapor/routing-kit.git at 4.1.0
Cloning https://github.com/apple/swift-metrics.git
Resolving https://github.com/apple/swift-metrics.git at 2.0.0
Cloning https://github.com/vapor/vapor.git
Resolving https://github.com/vapor/vapor.git at 4.8.0
Cloning https://github.com/swift-server/async-http-client.git
Resolving https://github.com/swift-server/async-http-client.git at 1.1.1
Cloning https://github.com/apple/swift-log.git
Resolving https://github.com/apple/swift-log.git at 1.2.0
Cloning https://github.com/vapor/jwt.git
Resolving https://github.com/vapor/jwt.git at 4.0.0-rc.2.1
Cloning https://github.com/apple/swift-nio-extras.git
Resolving https://github.com/apple/swift-nio-extras.git at 1.5.1
Cloning https://github.com/apple/swift-nio.git
Resolving https://github.com/apple/swift-nio.git at 2.17.0
Cloning https://github.com/apple/swift-nio-http2.git
Resolving https://github.com/apple/swift-nio-http2.git at 1.12.1
Cloning https://github.com/vapor/jwt-kit.git
Resolving https://github.com/vapor/jwt-kit.git at 4.0.0-rc.1.4
Cloning https://github.com/vapor/websocket-kit.git
Resolving https://github.com/vapor/websocket-kit.git at 2.1.0
Cloning https://github.com/apple/swift-crypto.git
Resolving https://github.com/apple/swift-crypto.git at 1.0.1
Cloning https://github.com/apple/swift-nio-ssl.git
Resolving https://github.com/apple/swift-nio-ssl.git at 2.7.3
Cloning https://github.com/swift-server/swift-backtrace.git
Resolving https://github.com/swift-server/swift-backtrace.git at 1.2.0
Cloning https://github.com/vapor/console-kit.git
Resolving https://github.com/vapor/console-kit.git at 4.1.0
[1798/1798] Linking Run
  1. Run application

Run application (.build/debug/Run) and open http://127.0.0.1:8080 page. I have following error:

[ ERROR ] signing algorithm error: signFailure

or

[1]    43923 segmentation fault  .build/debug/Run

My Swift version:

Apple Swift version 5.2.4 (swiftlang-1103.0.32.9 clang-1103.0.32.53)
Target: x86_64-apple-darwin19.5.0

Do you have same error after these steps or it's only something wrong in my macOS installation? Do you know what can be a reason of that error?

tanner0101 commented 4 years ago

Hmm I'm not able to reproduce this. I've added a test (https://github.com/vapor/jwt/pull/129) with the exact code you supplied and it's working correctly on all platforms. It's possible this was a bug in JWT / JWTKit that has been fixed already. If you still experience this after running swift package update, report to bugs.swift.org.

jstorm31 commented 4 years ago

@mczachurski Did you solve it? I'm facing the same issue. Signing works fine in XCode, but doesn't when running the app form terminal. Updating packages did not help.

tanner0101 commented 4 years ago

@jstorm31 hmm that might be related to https://bugs.swift.org/browse/SR-12424. It works fine in Xcode and on Linux?

jstorm31 commented 4 years ago

@tanner0101 It might be the same problem. I don't get a segfault though. I get this error both when running swift test and swift run. It could also be related to Vapor FCM package.

Fatal error: FCM Unable to generate JWT: JWTKit error: signing algorithm error: signFailure: file /Users/jstorm31/Dev/XCode/swapper-api/.build/checkouts/FCM/Sources/FCM/FCM.swift, line 72

It works on XCode macOS. I haven't tried on Linux. I've been trying to run the app inside a Docker Linux container, but the setup is still in progress so I haven't got this error so far due to fixing other issues.

UPDATE: There is a related issue (not resolved) in the Vapor FCM repo - https://github.com/MihaelIsaev/FCM/issues/24

jstorm31 commented 4 years ago

I managed to reproduce the issue in an isolated repo, see https://github.com/MihaelIsaev/FCM/issues/24#issuecomment-663140367. It probably really is the issue you reported @tanner0101.

mczachurski commented 4 years ago

@jstorm31 I checked today and I still have the same error.

Version of libraries:

Swift version:

Apple Swift version 5.2.4 (swiftlang-1103.0.32.9 clang-1103.0.32.53)
Target: x86_64-apple-darwin20.0.0

I can confirm that the bug occurs only from macOS terminal. On Xcode and in Linux there is no this bug.