In addition to Theo's advice about LibreSSL, for porting "-march=native" will need disabling, otherwise the compiled code will use CPU features detected as being available on the build machine - that's no good for packages.

--
 Sent from a phone, apologies for poor formatting.

On 18 February 2025 02:55:09 Christian Schulte <c...@schulte.it> wrote:

Hi @ports,

I am currently trying to create a port (first time doing this) for a library
using an OpenSSL function which does not seem to be available in LibreSSL in
base. The FAQ mentions "The most important thing to do is to communicate." so I
am asking for help here.

The output of the build currently is:

Script started on Tue Feb 18 03:33:52 2025
x500# make FETCH_PACKAGES=
===> Building from scratch libjwt-1.18.3
===> libjwt-1.18.3 depends on: cmake-* -> cmake-3.30.1v1
===> libjwt-1.18.3 depends on: ninja-* -> ninja-1.11.1p0v0
===> libjwt-1.18.3 depends on: unzip-* -> unzip-6.0p17-iconv
===> libjwt-1.18.3 depends on: jansson-* -> jansson-2.14
===>  Verifying specs:  jansson
===>  found jansson.4.2
===>  Checking files for libjwt-1.18.3
`/usr/ports/distfiles/libjwt-1.18.3.zip' is up to date.
(SHA256) libjwt-1.18.3.zip: OK
===>  Extracting for libjwt-1.18.3
===>  Patching for libjwt-1.18.3
===>  Compiler link: clang -> /usr/bin/clang
===>  Compiler link: clang++ -> /usr/bin/clang++
===>  Compiler link: cc -> /usr/bin/cc
===>  Compiler link: c++ -> /usr/bin/c++
===>  Generating configure for libjwt-1.18.3
===>  Configuring for libjwt-1.18.3
-- The C compiler identification is Clang 16.0.6
-- The CXX compiler identification is Clang 16.0.6
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/ports/pobj/libjwt-1.18.3/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/ports/pobj/libjwt-1.18.3/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found PkgConfig: /usr/bin/pkg-config (found version "0.29.2")
-- Found OpenSSL: /usr/lib/libcrypto.so.55.0 (found version "2.0.0")
-- Checking for one of the modules 'jansson'
-- version from configure.ac: '1.18.3'
-- Configuring done (7.0s)
-- Generating done (0.2s)
CMake Warning:
 Manually-specified variables were not used by the project:

   CMAKE_ASM_COMPILER_AR
   CMAKE_ASM_COMPILER_RANLIB
   CMAKE_Fortran_COMPILER_AR
   CMAKE_Fortran_COMPILER_RANLIB
   CMAKE_OBJCXX_COMPILER_AR
   CMAKE_OBJCXX_COMPILER_RANLIB
   CMAKE_OBJC_COMPILER_AR
   CMAKE_OBJC_COMPILER_RANLIB


-- Build files have been written to: /usr/ports/pobj/libjwt-1.18.3/build-amd64
===>  Building for libjwt-1.18.3
Change Dir: '/usr/ports/pobj/libjwt-1.18.3/build-amd64'

Run Build Command(s): /usr/local/bin/ninja -v -j 1
[1/8] /usr/ports/pobj/libjwt-1.18.3/bin/cc -D_GNU_SOURCE -I/usr/ports/pobj/libjwt-1.18.3/libjwt-1.18.3/include -I/src -I/android -I/usr/ports/pobj/libjwt-1.18.3/build-amd64/libjwt -O2 -pipe -I/usr/local/include -march=native -DNDEBUG -MD -MT libjwt/CMakeFiles/jwt.dir/base64.c.o -MF libjwt/CMakeFiles/jwt.dir/base64.c.o.d -o libjwt/CMakeFiles/jwt.dir/base64.c.o -c /usr/ports/pobj/libjwt-1.18.3/libjwt-1.18.3/libjwt/base64.c [2/8] /usr/ports/pobj/libjwt-1.18.3/bin/cc -D_GNU_SOURCE -I/usr/ports/pobj/libjwt-1.18.3/libjwt-1.18.3/include -I/src -I/android -I/usr/ports/pobj/libjwt-1.18.3/build-amd64/libjwt -O2 -pipe -I/usr/local/include -march=native -DNDEBUG -MD -MT libjwt/CMakeFiles/jwt.dir/jwt-openssl.c.o -MF libjwt/CMakeFiles/jwt.dir/jwt-openssl.c.o.d -o libjwt/CMakeFiles/jwt.dir/jwt-openssl.c.o -c /usr/ports/pobj/libjwt-1.18.3/libjwt-1.18.3/libjwt/jwt-openssl.c /usr/ports/pobj/libjwt-1.18.3/libjwt-1.18.3/libjwt/jwt-openssl.c:163:7: warning: call to undeclared function 'EVP_PKEY_get_group_name'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] if (!EVP_PKEY_get_group_name(pkey, groupNameBuffer, sizeof(groupNameBuffer), &groupNameBufferLen))

1 warning generated.
[3/8] /usr/ports/pobj/libjwt-1.18.3/bin/cc -D_GNU_SOURCE -I/usr/ports/pobj/libjwt-1.18.3/libjwt-1.18.3/include -I/src -I/android -I/usr/ports/pobj/libjwt-1.18.3/build-amd64/libjwt -O2 -pipe -I/usr/local/include -march=native -DNDEBUG -MD -MT libjwt/CMakeFiles/jwt.dir/jwt.c.o -MF libjwt/CMakeFiles/jwt.dir/jwt.c.o.d -o libjwt/CMakeFiles/jwt.dir/jwt.c.o -c /usr/ports/pobj/libjwt-1.18.3/libjwt-1.18.3/libjwt/jwt.c [4/8] : && /usr/local/bin/cmake -E rm -f libjwt/libjwt.a && /usr/bin/ar qc libjwt/libjwt.a libjwt/CMakeFiles/jwt.dir/base64.c.o libjwt/CMakeFiles/jwt.dir/jwt-openssl.c.o libjwt/CMakeFiles/jwt.dir/jwt.c.o && /usr/bin/ranlib libjwt/libjwt.a && : [5/8] /usr/ports/pobj/libjwt-1.18.3/bin/cc -D_GNU_SOURCE -I/usr/ports/pobj/libjwt-1.18.3/libjwt-1.18.3/include -I/usr/ports/pobj/libjwt-1.18.3/libjwt-1.18.3/libjwt/../include -O2 -pipe -I/usr/local/include -march=native -DNDEBUG -std=gnu11 -Werror -Wall -Wextra -g -fPIC -O2 -funwind-tables -MD -MT examples/CMakeFiles/jwtauth.dir/main-auth.c.o -MF examples/CMakeFiles/jwtauth.dir/main-auth.c.o.d -o examples/CMakeFiles/jwtauth.dir/main-auth.c.o -c /usr/ports/pobj/libjwt-1.18.3/libjwt-1.18.3/examples/main-auth.c [6/8] : && /usr/ports/pobj/libjwt-1.18.3/bin/cc -O2 -pipe -I/usr/local/include -march=native -DNDEBUG -L/usr/local/lib examples/CMakeFiles/jwtauth.dir/main-auth.c.o -o examples/jwtauth libjwt/libjwt.a /usr/lib/libcrypto.so.55.0 /usr/lib/libssl.so.58.0 /usr/lib/libcrypto.so.55.0 /usr/lib/libssl.so.58.0 -ljansson -Wl,-rpath-link,/usr/X11R6/lib && :
FAILED: examples/jwtauth
: && /usr/ports/pobj/libjwt-1.18.3/bin/cc -O2 -pipe -I/usr/local/include -march=native -DNDEBUG -L/usr/local/lib examples/CMakeFiles/jwtauth.dir/main-auth.c.o -o examples/jwtauth libjwt/libjwt.a /usr/lib/libcrypto.so.55.0 /usr/lib/libssl.so.58.0 /usr/lib/libcrypto.so.55.0 /usr/lib/libssl.so.58.0 -ljansson -Wl,-rpath-link,/usr/X11R6/lib && : ld: warning: jwt.c(jwt.c.o:(jwt_encode) in archive libjwt/libjwt.a): warning: strcpy() is almost always misused, please use strlcpy() ld: warning: jwt.c(jwt.c.o:(jwt_encode) in archive libjwt/libjwt.a): warning: strcat() is almost always misused, please use strlcat()
ld: error: undefined symbol: EVP_PKEY_get_group_name
referenced by jwt-openssl.c
              jwt-openssl.c.o:(jwt_degree_for_key) in archive libjwt/libjwt.a
cc: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.

*** Error 1 in . (/usr/ports/devel/cmake/cmake.port.mk:50 'do-build': @cd /usr/ports/pobj/libjwt-1.18.3/build-amd64 && exec /usr/bin/env -i ...) *** Error 2 in . (/usr/ports/infrastructure/mk/bsd.port.mk:3057 '/usr/ports/pobj/libjwt-1.18.3/build-amd64/.build_done': @cd /usr/ports/www/...) *** Error 2 in /usr/ports/www/libjwt (/usr/ports/infrastructure/mk/bsd.port.mk:2704 'all': @lock=libjwt-1.18.3; export _LOCKS_HELD=" libjwt...)
x500# ^D

Script done on Tue Feb 18 03:34:29 2025

The function in question looks like this:

static int jwt_degree_for_key(EVP_PKEY *pkey, jwt_t *jwt)
{
        int degree = 0;
        char groupNameBuffer[24] = {0};
        size_t groupNameBufferLen = 0;

if (!EVP_PKEY_get_group_name(pkey, groupNameBuffer, sizeof(groupNameBuffer), &groupNameBufferLen))
                return -EINVAL;

        groupNameBuffer[groupNameBufferLen] = '\0';

        /* We only perform this check for ES256K. All others we just check
         * the degree (bits). */
        if (jwt->alg == JWT_ALG_ES256K) {
                if (strcmp(groupNameBuffer, "secp256k1"))
                        return -EINVAL;
        }

#if OPENSSL_VERSION_NUMBER >= 0x30000000L
        int curve_nid;
        EC_GROUP *group;
        /* OpenSSL 3.0.0 and later has a new API for this. */

        curve_nid = OBJ_txt2nid(groupNameBuffer);
        if (curve_nid == NID_undef)
                return -EINVAL;

        group = EC_GROUP_new_by_curve_name(curve_nid);
        if (group == NULL)
                return -ENOMEM;

        /* Get the degree of the curve */
        degree = EC_GROUP_get_degree(group);

        EC_GROUP_free(group);
#else
        EC_KEY *ec_key;

        if (EVP_PKEY_id(pkey) != EVP_PKEY_EC)
                return -EINVAL;

        /* Get the actual ec_key */
        ec_key = EVP_PKEY_get1_EC_KEY(pkey);
        if (ec_key == NULL)
                return -ENOMEM;

        degree = EC_GROUP_get_degree(EC_KEY_get0_group(ec_key));

        EC_KEY_free(ec_key);
#endif

        /* Final check for matching degree */
        switch (jwt->alg) {
        case JWT_ALG_ES256:
        case JWT_ALG_ES256K:
                if (degree != 256)
                        return -EINVAL;
                break;
        case JWT_ALG_ES384:
                if (degree != 384)
                        return -EINVAL;
                break;
        case JWT_ALG_ES512:
                /* This is not a typo. ES512 uses secp521r1 */
                if (degree != 521)
                        return -EINVAL;
                break;
        default:
                return -EINVAL;
        }

        return degree;
}

I would not want to remove that extra "secp256k1" check. It will be there for a
reason I do not understand. I would like to ask what to do about it. Is there
a similar function I could use from LibreSSL?

Regards,
--
Christian

Reply via email to