Hot questions for Using Vapor in openssl

Question:

I installed vapor via homebrew and then immediately wanted to jump into a project by executing vapor new Hello but then got the following message back in the terminal:

dyld: Library not loaded: /usr/local/opt/openssl/lib/libssl.1.0.0.dylib
Referenced from: /usr/local/bin/vapor
Reason: image not found
zsh: abort      vapor new Hello

I tried some approaches to fix this like uninstalling and reinstalling openssl via brew but that didn't work . Also tried something I found in the internet but nothing worked. I assume it has something to do with vapor only working with version 1.0.0 but not 1.1.1 and that's what I have. I guess I need to downgrade to 1.0.0 but how'd I do that? I'm on MacOS Catalina if that matters. Thanks in advance.


Answer:

Switch to an older openssl package

brew switch openssl 1.0.2s

Question:

How can I fix these OpenSSL / TLS issues I'm getting with Vapor 2? They are preventing me from compiling my project on the command line and in Xcode.

During SPM build:

note: you may be able to install ctls using your system-packager:

    brew install ctls

note: you may be able to install ctls using your system-packager:

    brew install openssl

Upon failure of SPM build:

Linking ./.build/debug/Run
ld: library not found for -lcrypto for architecture x86_64
<unknown>:0: error: link command failed with exit code 1 (use -v to see invocation)
<unknown>:0: error: build had 1 command failures
error: exit(1): /Library/Developer/Toolchains/swift-3.1-DEVELOPMENT-SNAPSHOT-2017-03-07-a.xctoolchain/usr/bin/swift-build-tool -f /Users/tanner/Desktop/PackageConfig/.build/debug.yaml

Also in SPM:

<module-includes>:1:9: note: in file included from <module-includes>:1:
#import "shim.h"
        ^
/Users/tanner/Desktop/PackageConfigTwo/.build/checkouts/ctls.git-9210868160426949823/shim.h:4:10: error: 'openssl/conf.h' file not found
#include <openssl/conf.h>
         ^
/Users/tanner/Desktop/PackageConfigTwo/.build/checkouts/crypto.git-7980259129511365902/Sources/Crypto/Cipher/Cipher+Method.swift:1:8: error: could not build Objective-C module 'CTLS'
import CTLS
       ^

In Xcode:

/Users/tanner/PackageConfig/.build/checkouts/ctls.git-9210868160426949823/shim.h:4:10: 'openssl/conf.h' file not found

/Users/tanner/PackageConfig/.build/checkouts/crypto.git-7980259129511365902/Sources/Crypto/Cipher/Cipher+Method.swift:1:8: Could not build Objective-C module 'CTLS'

ld: library not found for -lssl


Answer:

This error means OpenSSL is either not installed or not being properly linked. There are three solutions to this problem.

Option 1: Use Vapor Toolbox (Recommended)

Install the latest version of the Vapor toolbox.

If you have already installed the toolbox, try uninstalling it first:

which vapor
rm -rf /path/to/vapor
1.1 Install (macOS)

Add Vapor's Homebrew Tap

brew tap vapor/homebrew-tap

Update Homebrew and install the toolbox.

brew update
brew install vapor
1.2 Install (Ubuntu)

Add Vapor's APT repo.

Quick Script
eval "$(curl -sL https://apt.vapor.sh)"
Manual
wget -q https://repo.vapor.codes/apt/keyring.gpg -O- | sudo apt-key add -
echo "deb https://repo.vapor.codes/apt $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/vapor.list
Install
sudo apt-get update
sudo apt-get install vapor
1.3 Done

You should now have access to the vapor program and all required dependencies should be installed.

vapor build
vapor xcode

swift build and related commands should now also work normally.

swift build
swift package generate-xcodeproj
Option 2: Install Vapor's CTLS Package
2.1 Install (macOS)

Add Vapor's Homebrew Tap

brew tap vapor/homebrew-tap

Update Homebrew and install CTLS

brew update
brew install ctls

Restart your terminal, re-generate your Xcode project (if using Xcode), and try again.

2.2 Install (Ubuntu)

Add Vapor's APT repo.

Quick Script
eval "$(curl -sL https://apt.vapor.sh)"
Manual
wget -q https://repo.vapor.codes/apt/keyring.gpg -O- | sudo apt-key add -
echo "deb https://repo.vapor.codes/apt $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/vapor.list

Update APT and install CTLS.

sudo apt-get update
sudo apt-get install ctls
2.3 Done

swift build and other commands should now work normally.

Option 3: Manually Install and Link OpenSSL or Equivalent
3.1 Install (macOS)

Install OpenSSL (or any other similar SSL library)

brew install openssl
brew install libressl
3.2 Install (Ubuntu)

Install OpenSSL (or any other similar SSL library)

sudo apt-get install libssl-dev
3.3 Finding Linker Flags

You can use pkg-config (available on brew and apt) to find linker flags or most packages.

pkg-config <package-name> --cflags
pkg-config <package-name> --libs

However, OpenSSL installed through Homebrew cannot be linked and thus does not work with pkg-config. These flags should work:

include: /usr/local/opt/openssl/include
libs: /usr/local/opt/openssl/lib

Note, some libraries will be installed into /usr/include and /usr/lib which does not require explicit linker flags. OpenSSL through APT is installed this way.

3.4 Using Linker Flags

Linker flags can be added during swift build

swift build -Xswiftc -I/path/to/include -Xlinker -L/path/to/lib

They can also be added during Xcode project generation.

swift package -Xswiftc -I/path/to/include -Xlinker -L/path/to/lib generate-xcodeproj

Question:

I want to install SSL(Comodo wildcard certificate, ex: "*.test.com") in Vapor Web framework, the "servers.json" I got is:

{
    "default": {
        "port": "$PORT:443",
        "host": "api.test.com",
        "securityLayer": "tls",
        "tls": {
            "certificates": "chain",
            "certificateFile": "/path/ssl-bundle.crt",
            "chainFile": "/path/ssl-bundle.crt",
            "privateKeyFile": "/path/key.pem",
            "signature": "signedFile",
            "caCertificateFile": "/path/AddTrustExternalCARoot.crt"
            }
    }
}

I already make sure that "public/private" key matches already using openssl command. And about the certificateFile part like "ssl-bundle.crt", I also tried "*.test.com.crt" with the "key.pem" as well(still pass the validation using openssl, the only difference is one is test.com's certificate, the other is bundle certificate, combined by correct orders already.). Besides, all certs and key's format are correct as well. And I also make sure the cert/key files location is correct so that the Vapor can find these files. But I still can't launch the server correctly, and always display the error. I try to locate the exact location in xcode, but I can only see it fails in this method: "tls_accept_fds()", which is in tls_server.c of CLibreSSL library.

Also, I saw the error message the xcode displayed to me:

After use debug mode to trace, I can only know that it seems the program throws the error in "SSL_set_rfd()" or "SSL_set_rfd()", but I don't know exactly. The xcode only shows this to me, and I can't find any other error messages in the debug console. As result, so far I can only make sure that the error should be in this block:

int
tls_accept_fds(struct tls *ctx, struct tls **cctx, int fd_read, int fd_write)
{
struct tls *conn_ctx = NULL;

// I pass this block
if ((ctx->flags & TLS_SERVER) == 0) {
    tls_set_errorx(ctx, "not a server context");
    goto err;
}

// I pass this block
if ((conn_ctx = tls_server_conn(ctx)) == NULL) {
    tls_set_errorx(ctx, "connection context failure");
    goto err;
}

// I pass this block
if ((conn_ctx->ssl_conn = SSL_new(ctx->ssl_ctx)) == NULL) {
    tls_set_errorx(ctx, "ssl failure");
    goto err;
}

// I pass this block
if (SSL_set_app_data(conn_ctx->ssl_conn, conn_ctx) != 1) {
    tls_set_errorx(ctx, "ssl application data failure");
    goto err;
}

// The error occurs here, in SSL_set_rfd or SSL_set_wfd, it will then go to err part: "*cctx = NULL;", not even go into the if block.
if (SSL_set_rfd(conn_ctx->ssl_conn, fd_read) != 1 ||
    SSL_set_wfd(conn_ctx->ssl_conn, fd_write) != 1) {
    tls_set_errorx(ctx, "ssl file descriptor failure");
    goto err;
}

*cctx = conn_ctx;

return (0);

err:
tls_free(conn_ctx);

*cctx = NULL;

return (-1);
}

So, the above is all the info I got right now, and I can't find the solution on the internet for several days already... Could anyone give me any hint about how to install SSL in Vapor web framework? I can correctly install the SSL in Apache, Nginx, Tomcat, etc already. But never success in Vapor, it seems like C library issue, but I don't know the real reason why it fails, thank you very much for any possible help.


Answer:

The bug has been found and fixed here: https://github.com/vapor/tls/pull/27