Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

jwt_encode_str fails with errno 22 #69

Closed
MikeEdmansTest opened this issue Mar 14, 2018 · 5 comments
Closed

jwt_encode_str fails with errno 22 #69

MikeEdmansTest opened this issue Mar 14, 2018 · 5 comments

Comments

@MikeEdmansTest
Copy link

I'm trying to use libjwt to connect to google Core iot.

jwt_encode_str fails in my program. I've created the jwt object, added iat, expiry, project id and set the algorithm and key. What could be causing the encode to fail? Any ideas? Most of the code is copied from mqtt_ciotc.c, so it should work.

@benmcollins
Copy link
Owner

I'm not familiar with the file you reference. Can you supply your code? In what way does it fail? Did you check errno to see what might have been the cause?

@MikeEdmansTest
Copy link
Author

MikeEdmansTest commented Mar 15, 2018

The errno is 22 .Code below:

static void GetIatExp(char* iat, char* exp, int time_size) {
  time_t now_seconds = time(NULL);
  snprintf(iat, time_size, "%lu", now_seconds);
  snprintf(exp, time_size, "%lu", now_seconds + 3600);
}


static char* CreateJwt(const char* ec_private_path, const char* project_id) {
  char iat_time[sizeof(time_t) * 3 + 2];
  char exp_time[sizeof(time_t) * 3 + 2];
  uint8_t* key = NULL; // Stores the Base64 encoded certificate
  size_t key_len = 0;
  jwt_t *jwt = NULL;
  int ret = 0;
  char *out = NULL;

  // Read private key from file
  FILE *fp = fopen(ec_private_path, "r");
  if (fp == (void*) NULL) {
    printf("Could not open file: %s\n", ec_private_path);
    return "";
  }
  fseek(fp, 0L, SEEK_END);
  key_len = ftell(fp);
  fseek(fp, 0L, SEEK_SET);
  key = (uint8_t *)malloc(sizeof(uint8_t) * (key_len + 1)); // certificate length + \0

  fread(key, 1, key_len, fp);
  key[key_len] = '\0';
  fclose(fp);

  // Get JWT parts
  GetIatExp(iat_time, exp_time, sizeof(iat_time));

  jwt_new(&jwt);

  // Write JWT
  ret = jwt_add_grant(jwt, "iat", iat_time);
  if (ret) {
    printf("Error setting issue timestamp: %d", ret);
  }
  ret = jwt_add_grant(jwt, "exp", exp_time);
  if (ret) {
    printf("Error setting expiration: %d", ret);
  }
  ret = jwt_add_grant(jwt, "aud", project_id);
  if (ret) {
    printf("Error adding audience: %d", ret);
  }
  ret = jwt_set_alg(jwt, JWT_ALG_ES256, key, key_len);
  if (ret) {
    printf("Error during set alg: %d", ret);
  }
  out = jwt_encode_str(jwt);
  if (out==0)
    qDebug() <<"errno",   errno;

  // Print JWT
    qDebug() <<"JWT: [%s]", out;

  jwt_free(jwt);
  free(key);
  return out;
}

@benmcollins
Copy link
Owner

For one, I would suggest doing:

jwt_add_grant_int(jwt, "iat", now_seconds);
jwt_add_grant_int(jwt, "exp", now_seconds + 3600);

To save yourself some string manipulation and effort.

So there's lots of places in jwt_sign_sha_pem() that can cause EINVAL and all of them revolve around your key. Can you verify your private EC256 key is:

  1. The correct curve. You are using EC256, so it should be a 256-bit EC key. What curve did you use?

  2. That the private key file is in the right format. It should be a PEM file, and be in this format:

    -----BEGIN EC PRIVATE KEY-----
    MIGkAgEBBDBeLCgapjZmvTatMHaYX3A02+0Ys3Tr8kda+E9DFnmCSiCOEig519fT
    13edeU8YdDugBwYFK4EEACKhZANiAASibEL3JxzwCRdLBZCm7WQ3kWaDL+wP8omo
    3e2VJmZQRnfDdzopgl8r3s8w5JlBpR17J0Gir8g6CVBA6PzMuq5urkilppSINDnR
    4mDv0+9e4uJVQf3xwEv+jywNUH+wbPM=
    -----END EC PRIVATE KEY-----

@MikeEdmansTest
Copy link
Author

Bingo! You were right , the PEM file was RS256 and the algorithm was set to ES256. All working now - thanks for your help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants