On 2/18/25 07:14, Theo Buehler wrote: > On Tue, Feb 18, 2025 at 03:54:42AM +0100, Christian Schulte 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. > > EVP_PKEY_get_group_name() is OpenSSL 3 API and should therefore be > guarded by the OPENSSL_VERSION_NUMBER path. This is a bug introduced in > > https://github.com/benmcollins/libjwt/commit/e12bba8a4463788f1b327b4cb522b484e269c433 > > I don't know why secp256k1 neeeds this extra check while all other curves > don't but it is easy to implement it: > >> 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; > > Add > > #if OPENSSL_VERSION_NUMBER >= 0x30000000L > >> 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 > > remove the above line > >> 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; > > Add this: > > if (jwt-alg == JWT_ALG_ES256K) { > const EC_GROUP *group; > > if ((group = EC_KEY_get0_group(ec_key)) == NULL) { > EC_KEY_free(ec_key); > return -EINVAL; > } > if (EC_GROUP_get_curve_name(group)) != NID_secp256k1) { > EC_KEY_free(ec_key); > return -EINVAL; > } > } > >> >> 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 >>
Thanks a lot. I will create an upstream issue for this. Could you also point me to some port example using custom build instructions? This library is using cmake for compiling 2 C source files and this already introduces the issue that it does not seem to be possible to build a shared and a static library in one go. All it needs to do is calling the compiler to compile 2 source files and then install one header, a .so and a .a version. It should be straight forward to just do this manually without cmake, configure, whatever. Does a port already exist doing something like this I could take a look at? Regards, -- Christian