0

EDIT: SOLVED I was using an incorrect path for the header file and library linking, I was linking to the old SSL path instead of the new one, for me the command that ended up compiling was

g++ main.cpp -o privateKeySign -I /usr/local/include/openssl/ -L /usr/local/ssl/lib64 -lssl -lcrypto

I'm trying to build a jwt generator using c++ and openssl, however I'm getting this error:

/usr/bin/ld: /tmp/cc8Ik5Wp.o: in function `signJWT(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, evp_pkey_st*)':
main.cpp:(.text+0x59a): undefined reference to `EVP_PKEY_get_size'
collect2: error: ld returned 1 exit status

after running

gcc main.cpp -o privateKeySign -I /usr/local/ssl/include -L /usr/local/ssl/lib -lssl -lcrypto -lstdc++
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/sha.h>
#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

string base64UrlEncode(const string &input) {
    BIO *b64 = BIO_new(BIO_f_base64());
    BIO *bmem = BIO_new(BIO_s_mem());
    b64 = BIO_push(b64, bmem);
    BIO_write(b64, input.c_str(), input.length());
    //BIO_flush(b64);

    BUF_MEM *bptr;
    BIO_get_mem_ptr(b64, &bptr);

    string output(bptr->data, bptr->length);
    output = output.substr(0, output.length() - 1);
    replace(output.begin(), output.end(), '+', '-');
    replace(output.begin(), output.end(), '/', '_');

    BIO_free_all(b64);
    return output;
}

string base64UrlDecode(const string &input) {
    string output(input);
    replace(output.begin(), output.end(), '-', '+');
    replace(output.begin(), output.end(), '_', '/');
    output.append((4 - (output.length() % 4)) % 4, '=');

    BIO *b64 = BIO_new(BIO_f_base64());
    BIO *bmem = BIO_new_mem_buf(output.c_str(), output.length());
    b64 = BIO_push(b64, bmem);

    char *decoded = new char[output.length()];
    int decodedLength = BIO_read(b64, decoded, output.length());

    output = string(decoded, decodedLength);

    BIO_free_all(b64);
    return output;
}

string signJWT(const string &header, const string &payload, EVP_PKEY *privateKey) {
    string encodedHeader = base64UrlEncode(header);
    string encodedPayload = base64UrlEncode(payload);

    string input = encodedHeader + "." + encodedPayload;
    unsigned char hash[SHA256_DIGEST_LENGTH];
    unsigned int hashLength;

    EVP_MD_CTX *mdctx = EVP_MD_CTX_create();
    EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL);
    EVP_DigestUpdate(mdctx, input.c_str(), input.length());
    EVP_DigestFinal_ex(mdctx, hash, &hashLength);

    EVP_PKEY_CTX *pkeyCtx = NULL;

    EVP_SignInit(mdctx,  EVP_sha256());
    EVP_PKEY_sign_init(pkeyCtx);

    size_t signatureLength = EVP_PKEY_size(privateKey);
    auto *signature = new unsigned char[signatureLength];

    EVP_SignUpdate(mdctx, hash, hashLength);
    EVP_SignFinal(mdctx, signature, reinterpret_cast<unsigned int *>(&signatureLength), privateKey);

    string encodedSignature = base64UrlEncode(string(reinterpret_cast<char *>(signature), signatureLength));
    string jwt = input + "." + encodedSignature;

    delete[] signature;
    EVP_MD_CTX_destroy(mdctx);
    return jwt;
}

int main () {
    EVP_PKEY *privateKey = NULL;
    FILE *privateKeyFile = fopen("private.pem", "r");
    PEM_read_PrivateKey(privateKeyFile, &privateKey, NULL, NULL);
    fclose(privateKeyFile);

    string jwt = signJWT(R"({"alg":"RS256","typ":"JWT"})", R"({"iss":"test","sub":"test","aud":"test","exp":9999999999,"iat":9999999999})", privateKey);

    cout << jwt << endl;

    return 0;
}

I tried reinstalling openssl, tracking the error down and various linking options it just does not go away

  • Use a C++ compiler instead of a C compiler: `g++ main.cpp -o privateKeySign -I /usr/local/ssl/include -L /usr/local/ssl/lib -lssl -lcrypto` - there's no need to explicitly link with `-lstdc++` if you do that. What does the command `pkg-config --cflags --libs openssl` show? – Ted Lyngmo Jan 31 '23 at 16:46
  • @TedLyngmo Hi Ted, I appreciate your advice, the error still remains unfortunately. The output of the pkg-config is : -lssl -lcrypto – HamzaStarcevic Jan 31 '23 at 16:51
  • Oh I also wanted to point out that if I don't link anything that many other undefined references appear out of Openssl but only the get size one persists – HamzaStarcevic Jan 31 '23 at 16:53
  • Ok, but continue using `g++` for compiling C++ programs nevertheless. It'll save you from a lot of problems down the road. Please include the full output from `g++ main.cpp -o privateKeySign -I /usr/local/ssl/include -L /usr/local/ssl/lib -lssl -lcrypto` in the question if you haven't already. I mean _all_ of it. – Ted Lyngmo Jan 31 '23 at 16:54
  • @HamzaStarcevic **The output of the pkg-config is : -lssl -lcrypto** It cant be a true output of `pkg-config --cflags --libs openssl`. Why do you hide the important info? – 273K Jan 31 '23 at 16:55
  • @273K My `pkg-config --cflags --libs openssl` says `-lssl -lcrypto` too :-) (Fedora 37) – Ted Lyngmo Jan 31 '23 at 16:56
  • If it says true, then openssl is located in /usr and OP seems to mix different openssl versions or its target platforms. – 273K Jan 31 '23 at 16:58
  • Could be. The output from `find /usr/lib* -name 'libssl.*' 2> /dev/null` would be interesting to see – Ted Lyngmo Jan 31 '23 at 17:03
  • I just got off work, that was all of the output actually, i have a lot of things do to tonight so I'll update you on the output of the find command. There might be leftovers from the previous openssl version as the current project insists on openssl3.0.# – HamzaStarcevic Jan 31 '23 at 17:08
  • This is the output from the find command: /usr/lib/i386-linux-gnu/libssl.so.1.1 /usr/lib/x86_64-linux-gnu/libssl.so.1.1 /usr/lib/x86_64-linux-gnu/pkgconfig/libssl.pc /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libssl.a /usr/lib/x86_64-linux-gnu/android/libssl.so.0 – HamzaStarcevic Feb 01 '23 at 08:09
  • @HamzaStarcevic That `/usr/lib/x86_64-linux-gnu/android/libssl.so.0` looks interesting. Do you have `boringssl` installed too? Are you sure you're linking against the corrent `ssl` library? – Ted Lyngmo Feb 10 '23 at 08:11

0 Answers0