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

Reply via email to