Beispiel #1
0
/**
 * eap_sim_db_get_reauth_entry - EAP-SIM DB: Get re-authentication entry
 * @priv: Private data pointer from eap_sim_db_init()
 * @identity: Identity of the user (may be permanent identity, pseudonym, or
 * reauth_id)
 * @identity_len: Length of identity
 * @len: Buffer for length of the returned permanent identity
 * Returns: Pointer to the re-auth entry, or %NULL if not found
 */
struct eap_sim_reauth *
eap_sim_db_get_reauth_entry(void *priv, const u8 *identity,
			    size_t identity_len)
{
	struct eap_sim_db_data *data = priv;
	struct eap_sim_reauth *r;

	if (identity == NULL)
		return NULL;
	r = eap_sim_db_get_reauth(data, identity, identity_len);
	if (r == NULL)
		r = eap_sim_db_get_reauth_id(data, identity, identity_len);
	return r;
}
Beispiel #2
0
/**
 * eap_sim_db_add_reauth - EAP-SIM DB: Add new re-authentication entry
 * @priv: Private data pointer from eap_sim_db_init()
 * @identity: Identity of the user (may be permanent identity or pseudonym)
 * @identity_len: Length of identity
 * @reauth_id: reauth_id for this user. This needs to be an allocated buffer,
 * e.g., return value from eap_sim_db_get_next_reauth_id(). Caller must not
 * free it.
 * @mk: 16-byte MK from the previous full authentication
 * Returns: 0 on success, -1 on failure
 *
 * This function adds a new re-authentication entry for an EAP-SIM user.
 * EAP-SIM DB is responsible of freeing reauth_id buffer once it is not needed
 * anymore.
 */
int eap_sim_db_add_reauth(void *priv, const u8 *identity,
			  size_t identity_len, char *reauth_id, u16 counter,
			  const u8 *mk)
{
	struct eap_sim_db_data *data = priv;
	struct eap_sim_reauth *r;
	wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM DB: Add reauth_id for identity",
			  identity, identity_len);
	wpa_printf(MSG_DEBUG, "EAP-SIM DB: reauth_id: %s", reauth_id);

	r = eap_sim_db_get_reauth(data, identity, identity_len);
	if (r == NULL)
		r = eap_sim_db_get_reauth_id(data, identity, identity_len);

	if (r) {
		wpa_printf(MSG_DEBUG, "EAP-SIM DB: Replacing previous "
			   "reauth_id: %s", r->reauth_id);
		VM_FREE(r->reauth_id);
		r->reauth_id = reauth_id;
	} else {
		r = wpa_zalloc(sizeof(*r));
		if (r == NULL) {
			VM_FREE(reauth_id);
			return -1;
		}

		r->next = data->reauths;
		r->identity = VM_MALLOC(identity_len);
		if (r->identity == NULL) {
			VM_FREE(r);
			VM_FREE(reauth_id);
			return -1;
		}
		memcpy(r->identity, identity, identity_len);
		r->identity_len = identity_len;
		r->reauth_id = reauth_id;
		data->reauths = r;
		wpa_printf(MSG_DEBUG, "EAP-SIM DB: Added new reauth entry");
	}

	r->counter = counter;
	memcpy(r->mk, mk, EAP_SIM_MK_LEN);

	return 0;
}
static struct eap_sim_reauth *
eap_sim_db_add_reauth_data(struct eap_sim_db_data *data, const u8 *identity,
			   size_t identity_len, char *reauth_id, u16 counter)
{
	struct eap_sim_reauth *r;

	wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM DB: Add reauth_id for identity",
			  identity, identity_len);
	wpa_printf(MSG_DEBUG, "EAP-SIM DB: reauth_id: %s", reauth_id);

	r = eap_sim_db_get_reauth(data, identity, identity_len);
	if (r == NULL)
		r = eap_sim_db_get_reauth_id(data, identity, identity_len);

	if (r) {
		wpa_printf(MSG_DEBUG, "EAP-SIM DB: Replacing previous "
			   "reauth_id: %s", r->reauth_id);
		os_free(r->reauth_id);
		r->reauth_id = reauth_id;
	} else {
		r = os_zalloc(sizeof(*r));
		if (r == NULL) {
			os_free(reauth_id);
			return NULL;
		}

		r->next = data->reauths;
		r->identity = os_malloc(identity_len);
		if (r->identity == NULL) {
			os_free(r);
			os_free(reauth_id);
			return NULL;
		}
		os_memcpy(r->identity, identity, identity_len);
		r->identity_len = identity_len;
		r->reauth_id = reauth_id;
		data->reauths = r;
		wpa_printf(MSG_DEBUG, "EAP-SIM DB: Added new reauth entry");
	}

	r->counter = counter;

	return r;
}
Beispiel #4
0
/**
 * eap_sim_db_identity_known - Verify whether the given identity is known
 * @priv: Private data pointer from eap_sim_db_init()
 * @identity: User name identity
 * @identity_len: Length of identity in bytes 
 * Returns: 0 if the user is found or -1 on failure
 *
 * In most cases, the user name is ['0','1'] | IMSI, i.e., 1 followed by the
 * IMSI in ASCII format, ['2','3'] | pseudonym, or ['4','5'] | reauth_id.
 */
int eap_sim_db_identity_known(void *priv, const u8 *identity,
			      size_t identity_len)
{
	struct eap_sim_db_data *data = priv;

	if (identity == NULL || identity_len < 2)
		return -1;

	if (identity[0] == EAP_SIM_PSEUDONYM_PREFIX ||
	    identity[0] == EAP_AKA_PSEUDONYM_PREFIX) {
		struct eap_sim_pseudonym *p =
			eap_sim_db_get_pseudonym(data, identity, identity_len);
		return p ? 0 : -1;
	}

	if (identity[0] == EAP_SIM_REAUTH_ID_PREFIX ||
	    identity[0] == EAP_AKA_REAUTH_ID_PREFIX) {
		struct eap_sim_reauth *r =
			eap_sim_db_get_reauth(data, identity, identity_len);
		return r ? 0 : -1;
	}

	if (identity[0] != EAP_SIM_PERMANENT_PREFIX &&
	    identity[0] != EAP_AKA_PERMANENT_PREFIX) {
		/* Unknown identity prefix */
		return -1;
	}

	/* TODO: Should consider asking HLR/AuC gateway whether this permanent
	 * identity is known. If it is, EAP-SIM/AKA can skip identity request.
	 * In case of EAP-AKA, this would reduce number of needed round-trips.
	 * Ideally, this would be done with one wait, i.e., just request
	 * authentication data and store it for the next use. This would then
	 * need to use similar pending-request functionality as the normal
	 * request for authentication data at later phase.
	 */
	return -1;
}