swiftubuntuvapor

Connect MySQL configuration with CA certificate?


I am using mysqlkit for Vapor server side project and used to configure MySQL like below:

let config = MySQLConfiguration(hostname: "127.0.0.1", port: 3306, username: "root", password: "s3#12412r657f", database: "Admin", tlsConfiguration: nil)

It was successfully connected to the local database. Now, I've SSL CA file (Certficate Authority file for SSL) for remote database.

In mysql workbench I selected that ca_cert.crt file on the SSL tab at Path to Certificate Authority file for SSL field. Works fine!

But I don't know how to configure TLS or where to put my cacertificate.crt file & I've tested the crt file is PEM format only.

static let prod: MySQLConfiguration = {
    
    var tls = TLSConfiguration.makeClientConfiguration()
      
    do {

        let bytes = [UInt8]("""
        -----BEGIN CERTIFICATE-----
        EX_CERTIFICATE_STRINGS...
        -----END CERTIFICATE-----
        """.data(using: .utf8)!)
        let cert: NIOSSLCertificate = try .init(bytes: bytes, format: .pem)
        tls.certificateChain = [.certificate(cert)]
        tls.privateKey = nil
        let config = MySQLConfiguration(hostname: "192.65.85.577", port: 3658, username: "testadmin", password: "dd#246$@erjt!df^67", database: "Elevate", tlsConfiguration: tls)
        return config
        
    } catch {
        
        fatalError("DB SSL CA Error: \(error.localizedDescription)")
    }
}()

When I query database I'm getting the error that tells,

{
    "error": true,
    "reason": "handshakeFailed(NIOSSL.BoringSSLError.sslError([Error: 268435581 error:1000007d:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED at /Users/At4/Library/Developer/Xcode/DerivedData/Elevate-xcftyy3423/SourcePackages/checkouts/swift-nio-ssl/Sources/CNIOBoringSSL/ssl/handshake.cc:393]))"
}

But the same certificate and other parameters works fine with MySQLWorkBench.


Solution

  • The crt should assigned to the trustRoots:

    tls.certificateVerification = .fullVerification
    tls.trustRoots = .certificates([cert])
    

    Or It could be connected without certificate verification (unsafe):

    tls.certificateVerification = .none