/** * shishi_authenticator_get_subkey: * @handle: shishi handle as allocated by shishi_init(). * @authenticator: authenticator as allocated by shishi_authenticator(). * @subkey: output newly allocated subkey from authenticator. * * Read subkey value from authenticator. * * Return value: Returns SHISHI_OK if successful or SHISHI_ASN1_NO_ELEMENT * if subkey is not present. **/ int shishi_authenticator_get_subkey (Shishi * handle, Shishi_asn1 authenticator, Shishi_key ** subkey) { int res; int subkeytype; char *subkeyvalue; size_t subkeylen; res = shishi_asn1_read_int32 (handle, authenticator, "subkey.keytype", &subkeytype); if (res != SHISHI_OK) return res; res = shishi_asn1_read (handle, authenticator, "subkey.keyvalue", &subkeyvalue, &subkeylen); if (res != SHISHI_OK) return res; res = shishi_key (handle, subkey); if (res != SHISHI_OK) return res; shishi_key_type_set (*subkey, subkeytype); shishi_key_value_set (*subkey, subkeyvalue); return SHISHI_OK; }
/** * shishi_keys_add: * @keys: key set handle as allocated by shishi_keys(). * @key: key to be added to key set. * * Add a key to the key set. A deep copy of the key is stored, so * changing @key, or deallocating it, will not modify the value stored * in the key set. * * Return value: Returns SHISHI_OK iff succesful. **/ int shishi_keys_add (Shishi_keys * keys, Shishi_key * key) { int rc; if (!key) return SHISHI_INVALID_KEY; keys->nkeys++; keys->keys = xrealloc (keys->keys, sizeof (*keys->keys) * keys->nkeys); rc = shishi_key (keys->handle, &(keys->keys[keys->nkeys - 1])); if (rc != SHISHI_OK) return rc; shishi_key_copy (keys->keys[keys->nkeys - 1], key); return SHISHI_OK; }
/** * shishi_keys_add_keytab_mem: * @handle: shishi handle as allocated by shishi_init(). * @data: constant memory buffer with keytab of @len size. * @len: size of memory buffer with keytab data. * @keys: allocated key set to store keys in. * * Read keys from a MIT keytab data structure, and add them to the key * set. * * The format of keytab's is proprietary, and this function support * the 0x0501 and 0x0502 formats. See the section The MIT Kerberos * Keytab Binary File Format in the Shishi manual for a description of * the reverse-engineered format. * * Returns: Returns %SHISHI_KEYTAB_ERROR if the data does not * represent a valid keytab structure, and %SHISHI_OK on success. **/ int shishi_keys_add_keytab_mem (Shishi * handle, const char *data, size_t len, Shishi_keys *keys) { int rc; uint16_t file_format_version; size_t entrystartpos; uint16_t num_components; /* sub 1 if version 0x501 */ size_t i; Shishi_key *key; if (VERBOSENOISE (handle)) { printf ("keytab len %d (0x%x)\n", len, len); _shishi_hexprint (data, len); } /* Check file format. */ file_format_version = (data[0] << 8) | data[1]; if (VERBOSENOISE (handle)) printf ("keytab file_format_version %04X\n", file_format_version); if (file_format_version != 0x0501 && file_format_version != 0x0502) return SHISHI_KEYTAB_ERROR; /* Check file integrity first, to avoid error-checking below. */ entrystartpos = 2; while (entrystartpos < len) { int32_t size = data[entrystartpos] << 24 | data[entrystartpos+1] << 16 | data[entrystartpos+2] << 8 | data[entrystartpos+3]; entrystartpos += 4; if (VERBOSENOISE (handle)) { printf ("keytab size %d (%x)\n", size, size); printf ("keytab pos %d < %d\n", entrystartpos + size, len); } if (entrystartpos + size > len) return SHISHI_KEYTAB_ERROR; /* Go to next entry... */ entrystartpos += size; } if (entrystartpos != len) return SHISHI_KEYTAB_ERROR; rc = shishi_key (handle, &key); if (rc != SHISHI_OK) return rc; entrystartpos = 2; while (entrystartpos < len) { size_t pos = entrystartpos; uint16_t size = data[pos] << 24 | data[pos+1] << 16 | data[pos+2] << 8 | data[pos+3]; pos += 4; if (VERBOSENOISE (handle)) printf ("keytab size %d (%x)\n", size, size); /* Num_components */ num_components = data[pos] << 8 | data[pos+1]; pos += 2; if (file_format_version == 0x0501) num_components--; /* Realm */ { uint16_t realmlen = data[pos] << 8 | data[pos+1]; char *realm = xstrndup (&data[pos + 2], realmlen);; pos += 2 + realmlen; shishi_key_realm_set (key, realm); free (realm); } /* Principal components. */ { char *name = NULL; size_t namelen = 0; for (i = 0; i < num_components; i++) { size_t l; l = data[pos] << 8 | data[pos+1]; pos += 2; name = xrealloc (name, namelen + l + 1); memcpy (name + namelen, &data[pos], l); name[namelen + l] = '/'; namelen += l + 1; pos += l; } name[namelen - 1] = '\0'; shishi_key_principal_set (key, name); free (name); } /* Name_type */ { uint32_t name_type /* not present if version 0x501 */ = data[pos] << 24 | data[pos+1] << 16 | data[pos+2] << 8 | data[pos+3]; pos += 4; if (VERBOSENOISE (handle)) printf ("keytab nametype %d (0x%08x)\n", name_type, name_type); } /* Timestamp */ { uint32_t timestamp = data[pos] << 24 | data[pos+1] << 16 | data[pos+2] << 8 | data[pos+3]; pos += 4; if (VERBOSENOISE (handle)) printf ("keytab timestamp %u (0x%08ux)\n", timestamp, timestamp); } /* keyvno8 */ { uint8_t vno8 = data[pos++]; if (VERBOSENOISE (handle)) printf ("keytab kvno8 %d (0x%02x)\n", vno8, vno8); shishi_key_version_set (key, vno8); } /* key, keytype */ { uint32_t keytype = data[pos] << 8 | data[pos+1]; pos += 2; if (VERBOSENOISE (handle)) printf ("keytab keytype %d (0x%x)\n", keytype, keytype); shishi_key_type_set (key, keytype); } /* key, length and data */ { uint16_t keylen = data[pos] << 8 | data[pos+1]; pos += 2; if (VERBOSENOISE (handle)) printf ("keytab keylen %d (0x%x) eq? %d\n", keylen, keylen, shishi_key_length (key)); if (VERBOSENOISE (handle)) _shishi_hexprint (data + pos, keylen); shishi_key_value_set (key, data + pos); pos += keylen; } if (pos - entrystartpos < (size_t) size + 4) { uint32_t vno /* only present if >= 4 bytes left in entry */ = data[pos] << 24 | data[pos+1] << 16 | data[pos+2] << 8 | data[pos+3]; pos += 4; if (VERBOSENOISE (handle)) printf ("keytab kvno %d (0x%08x)\n", vno, vno); shishi_key_version_set (key, vno); } if (VERBOSECRYPTONOISE (handle)) shishi_key_print (handle, stdout, key); rc = shishi_keys_add (keys, key); if (rc != SHISHI_OK) goto done; /* Go to next entry... */ entrystartpos += size + 4; } rc = SHISHI_OK; done: shishi_key_done (key); return rc; }