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 >