static int GetExtension()

in src/oslogin_sshca.cc [148:243]


static int GetExtension(const char *key, size_t k_len, char **exts) {
  SSHCertType* impl = NULL;
  size_t n_len, t_len, tmp_exts_len, ret = -1;
  char *tmp_exts, *tmp_head, *type, *key_b64, *head;

  head = tmp_head = NULL;

  head = key_b64 = (char *)calloc(k_len, sizeof(char));
  if (key_b64 == NULL) {
    SysLogErr("Could not allocate b64 buffer.");
    goto out;
  }

  if ((n_len = b64_pton(key, (u_char *)key_b64, k_len)) < 0) {
    SysLogErr("Could encode buffer b64.");
    goto out;
  }

  // Invalid key (?)
  if (n_len <= 4) {
    goto out;
  }

  if (GetString(&key_b64, &n_len, &type, &t_len) < 0) {
    SysLogErr("Could not get cert's type string.");
    goto out;
  }

  impl = GetImplementation(type);
  if (impl == NULL) {
    SysLogErr("Invalid cert type: %s.", type);
    goto out;
  }

  // Skip nonce for all types of certificates.
  if (GetString(&key_b64, &n_len, NULL, NULL) < 0) {
    SysLogErr("Failed to skip cert's \"nonce\" field.");
    goto out;
  }

  // Skip type specific fields.
  if (impl->SkipCustomField(&key_b64, &n_len) < 0) {
    SysLogErr("Failed to skip cert's custom/specific fields.");
    goto out;
  }

  // Skip serial.
  SKIP_UINT64(key_b64, n_len);

  // Skip type.
  SKIP_UINT32(key_b64, n_len);

  // Skip key id.
  if (GetString(&key_b64, &n_len, NULL, NULL) < 0) {
    SysLogErr("Failed to skip cert's \"key id\" field.");
    goto out;
  }

  // Skip valid principals.
  if (GetString(&key_b64, &n_len, NULL, NULL) < 0) {
    SysLogErr("Failed to skip cert's \"valid principals\" field.");
    goto out;
  }

  // Skip valid after.
  SKIP_UINT64(key_b64, n_len);

  // Skip valid before.
  SKIP_UINT64(key_b64, n_len);

  // Skip critical options.
  if (GetString(&key_b64, &n_len, NULL, NULL) < 0) {
    SysLogErr("Failed to skip cert's \"critical options\" field.");
    goto out;
  }

  // Get extensions buffer.
  if (GetString(&key_b64, &n_len, &tmp_exts, &tmp_exts_len) < 0) {
    SysLogErr("Failed to get cert's \"extensions\" field.");
    goto out;
  }

  // The field extensions is a self described/sized buffer.
  tmp_head = tmp_exts;
  if (GetString(&tmp_exts, &tmp_exts_len, exts, &ret) < 0) {
    SysLogErr("Failed to read Google's extension.");
    goto out;
  }

out:
  free(tmp_head);
  free(type);
  free(head);

  return ret;
}