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;
}