コード例 #1
0
void
reg_proto_encrypt_data(BufferObj *plainText, BufferObj *encrKey, BufferObj *authKey,
	BufferObj *cipherText, BufferObj *iv)
{
	BufferObj *buf = buffobj_new();
	uint8 ivBuf[SIZE_128_BITS];
	/*  10 rounds for cbc 128  = (10+1) * 4 uint32 */
	uint32 rk[44];
	uint8 outBuf[1024];
	int encrypt_len;

	if (!buf)
		return;

	if (plainText->m_dataLength == 0) {
		TUTRACE((TUTRACE_ERR, "Invalid parameters \n"));
		buffobj_del(buf);
		return;
	}

	/* Generate a random iv */
	RAND_bytes(ivBuf, SIZE_128_BITS);
	buffobj_Reset(iv);
	buffobj_Append(iv, SIZE_128_BITS, ivBuf);

	/* Now encrypt the plaintext and mac using the encryption key and IV. */
	buffobj_Append(buf, plainText->m_dataLength, plainText->pBase);

	TUTRACE((TUTRACE_ERR, "RPROTO: calling encryption of %d bytes\n", buf->m_dataLength));
	rijndaelKeySetupEnc(rk, encrKey->pBase, 128);
	encrypt_len = aes_cbc_encrypt_pad(rk, 16, ivBuf, buf->m_dataLength,
		plainText->pBase, outBuf, PAD_LEN_PADDING);
	buffobj_Append(cipherText, encrypt_len, outBuf);
	buffobj_del(buf);
}
コード例 #2
0
void
reg_proto_derivekey(BufferObj *KDK, BufferObj *prsnlString, uint32 keyBits, BufferObj *key)
{
	uint32 i = 0, iterations = 0;
	BufferObj *input, *output;
	uint8 hmac[SIZE_256_BITS];
	uint32 hmacLen = 0;
	uint8 *inPtr;
	uint32 temp;

	input = buffobj_new();
	if (!input)
		return;
	output = buffobj_new();
	if (!output) {
		buffobj_del(input);
		return;
	}

	TUTRACE((TUTRACE_INFO, "RPROTO: Deriving a key of %d bits\n", keyBits));

	iterations = ((keyBits/8) + PRF_DIGEST_SIZE - 1)/PRF_DIGEST_SIZE;

	/* 
	 * Prepare the input buffer. During the iterations, we need only replace the
	 * value of i at the start of the buffer.
	 */
	temp = WpsHtonl(i);
	buffobj_Append(input, SIZE_4_BYTES, (uint8 *)&temp);
	buffobj_Append(input, prsnlString->m_dataLength, prsnlString->pBase);
	temp = WpsHtonl(keyBits);
	buffobj_Append(input, SIZE_4_BYTES, (uint8 *)&temp);
	inPtr = input->pBase;

	for (i = 0; i < iterations; i++) {
		/* Set the current value of i at the start of the input buffer */
		*(uint32 *)inPtr = WpsHtonl(i+1) ; /* i should start at 1 */
		hmac_sha256(KDK->pBase, SIZE_256_BITS, input->pBase,
			input->m_dataLength, hmac, &hmacLen);
		buffobj_Append(output, hmacLen, hmac);
	}

	/* Sanity check */
	if (keyBits/8 > output->m_dataLength) {
		TUTRACE((TUTRACE_ERR, "RPROTO: Key derivation generated less bits "
			"than asked\n"));
		buffobj_del(output);
		buffobj_del(input);
		return;
	}

	/*
	 * We now have at least the number of key bits requested.
	 * Return only the number of bits asked for. Discard the excess.
	 */
	buffobj_Append(key, keyBits/8, output->pBase);
	buffobj_del(output);
	buffobj_del(input);
	TUTRACE((TUTRACE_INFO, "RPROTO: End Deriving a key of %d bits\n", keyBits));
}
コード例 #3
0
/* Add support for Windows Rally Vertical Pairing */
uint32
reg_proto_vendor_ext_vp(DevInfo *devInfo, BufferObj *msg)
{
#ifdef WCN_NET_SUPPORT
	CTlvVendorExt   vendorExt;
	uint16          data = 0;
	BufferObj       *pBufObj = NULL;

	if ((devInfo == NULL) || (msg == NULL)) {
		TUTRACE((TUTRACE_ERR, "RPROTO: Invalid parameters! \n"));
		return WPS_ERR_INVALID_PARAMETERS;
	}

	TUTRACE((TUTRACE_INFO, "RPROTO: Adding WCN-NET VP Vendor Extension \n"));

	pBufObj   = buffobj_new();
	data = (WPS_MS_VPI_TRANSPORT_UPNP << 8) | WPS_MS_VPI_PROFILE_REQ;

	if (pBufObj == NULL) {
		TUTRACE((TUTRACE_ERR, "RPROTO: Ran out of memory!\n"));
		return WPS_ERR_OUTOFMEMORY;
	}

	/* Add the VPI TLV */
	tlv_serialize_ve(MS_VENDOR_EXT_ID, WPS_MS_ID_VPI, pBufObj, &data, sizeof(data));

	/* Add the Transport UUID TLV */
	tlv_serialize_ve(MS_VENDOR_EXT_ID, WPS_MS_ID_TRANSPORT_UUID, pBufObj,
		devInfo->transport_uuid, SIZE_16_BYTES);

	/* Serialize subelemetns to Vendor Extension */
	vendorExt.vendorId = (uint8 *)MS_VENDOR_EXT_ID;
	vendorExt.vendorData = buffobj_GetBuf(pBufObj);
	vendorExt.dataLength = buffobj_Length(pBufObj);
	tlv_vendorExtWrite(&vendorExt, msg);

	buffobj_del(pBufObj);
	TUTRACE((TUTRACE_INFO, "RPROTO: Finished Adding WCN-NET VP Vendor Extension \n"));
#endif /* WCN_NET_SUPPORT */
	return WPS_SUCCESS;
}
コード例 #4
0
ファイル: ap_api.c プロジェクト: 3sOx/asuswrt-merlin
/*
* NOTE: The caller MUST call tlv_delete(ssrmsg->authorizedMacs, 1) to free memory which
* allocated in this fcuntion.
*/
int
wps_get_upnpDevSSR(WPSAPI_T *g_mc, void *p_cbData, uint32 length, CTlvSsrIE *ssrmsg)
{
	int ret = WPS_CONT;
	uint8 data8;
	DevInfo *info = g_mc->dev_info;

	TUTRACE((TUTRACE_INFO, "wps_get_upnpDevSSR\n"));

	if (info->sc_mode == SCMODE_AP_REGISTRAR) {
		BufferObj *vendorExt_bufObj = NULL;
		BufferObj *wlidcardMac_bufObj = NULL;

		/* De-serialize the data to get the TLVs */
		BufferObj *bufObj = buffobj_new();
		if (!bufObj)
			return WPS_ERR_SYSTEM;

		buffobj_dserial(bufObj, (uint8 *)p_cbData, length);

		memset(ssrmsg, 0, sizeof(CTlvSsrIE));

		/* Version */
		tlv_dserialize(&ssrmsg->version, WPS_ID_VERSION, bufObj, 0, 0);
		/* Selected Registrar */
		tlv_dserialize(&ssrmsg->selReg, WPS_ID_SEL_REGISTRAR, bufObj, 0, 0);
		/* Device Password ID */
		tlv_dserialize(&ssrmsg->devPwdId, WPS_ID_DEVICE_PWD_ID, bufObj, 0, 0);
		/* Selected Registrar Config Methods */
		tlv_dserialize(&ssrmsg->selRegCfgMethods, WPS_ID_SEL_REG_CFG_METHODS,
			bufObj, 0, 0);

		/* WSC 2.0 */
		data8 = info->version2;
		if (data8 >= WPS_VERSION2) {
			/* Check subelement in WFA Vendor Extension */
			if (tlv_find_vendorExtParse(&ssrmsg->vendorExt, bufObj,
				(uint8 *)WFA_VENDOR_EXT_ID) != 0)
				goto add_wildcard_mac;

			/* Deserialize subelement */
			vendorExt_bufObj = buffobj_new();
			if (!vendorExt_bufObj) {
				buffobj_del(bufObj);
				return -1;
			}

			buffobj_dserial(vendorExt_bufObj, ssrmsg->vendorExt.vendorData,
				ssrmsg->vendorExt.dataLength);

			/* Get Version2 and AuthorizedMACs subelement */
			if (subtlv_dserialize(&ssrmsg->version2, WPS_WFA_SUBID_VERSION2,
				vendorExt_bufObj, 0, 0) == 0) {
				/* AuthorizedMACs, <= 30B */
				subtlv_dserialize(&ssrmsg->authorizedMacs,
					WPS_WFA_SUBID_AUTHORIZED_MACS,
					vendorExt_bufObj, 0, 0);
			}

			/* Add wildcard MAC when authorized mac not specified */
			if (ssrmsg->authorizedMacs.subtlvbase.m_len == 0) {
add_wildcard_mac:
				/*
				 * If the External Registrar is WSC version 1.0 it
				 * will not have included an AuthorizedMACs subelement.
				 * In this case the AP shall add the wildcard MAC Address
				 * (FF:FF:FF:FF:FF:FF) in an AuthorizedMACs subelement in
				 * Beacon and Probe Response frames
				 */
				wlidcardMac_bufObj = buffobj_new();
				if (!wlidcardMac_bufObj) {
					buffobj_del(vendorExt_bufObj);
					buffobj_del(bufObj);
					return -1;
				}

				/* Serialize the wildcard_authorizedMacs to wlidcardMac_Obj */
				subtlv_serialize(WPS_WFA_SUBID_AUTHORIZED_MACS, wlidcardMac_bufObj,
					(char *)wildcard_authorizedMacs, SIZE_MAC_ADDR);
				buffobj_Rewind(wlidcardMac_bufObj);
				/*
				 * De-serialize the wlidcardMac_Obj data to get the TLVs
				 * Do allocation, because wlidcardMac_bufObj will be freed here but
				 * ssrmsg->authorizedMacs return and used by caller.
				 */
				subtlv_dserialize(&ssrmsg->authorizedMacs,
					WPS_WFA_SUBID_AUTHORIZED_MACS,
					wlidcardMac_bufObj, 0, 1); /* Need to free it */
			}

			/* Get UUID-R after WFA-Vendor Extension (wpa_supplicant use this way) */
			tlv_find_dserialize(&ssrmsg->uuid_R, WPS_ID_UUID_R, bufObj, 0, 0);
		}

		/* Other... */

		if (bufObj)
			buffobj_del(bufObj);

		if (wlidcardMac_bufObj)
			buffobj_del(wlidcardMac_bufObj);

		if (vendorExt_bufObj)
			buffobj_del(vendorExt_bufObj);

		ret = WPS_SUCCESS;
	}

	return ret;
}
コード例 #5
0
ファイル: ap_api.c プロジェクト: 3sOx/asuswrt-merlin
static uint32
wps_setAssocRespIE(WPSAPI_T *g_mc, IN uint8 respType)
{
	uint32 ret;
	uint8 data8;
	CTlvVendorExt vendorExt;
	BufferObj *bufObj, *vendorExt_bufObj;
	DevInfo *info = g_mc->dev_info;

	bufObj = buffobj_new();
	if (!bufObj)
		return WPS_ERR_SYSTEM;

	vendorExt_bufObj = buffobj_new();
	if (vendorExt_bufObj == NULL) {
		buffobj_del(bufObj);
		return WPS_ERR_SYSTEM;
	}

	/* Version */
	data8 = WPS_VERSION;
	tlv_serialize(WPS_ID_VERSION, bufObj, &data8, WPS_ID_VERSION_S);

	/* Response Type */
	tlv_serialize(WPS_ID_RESP_TYPE, bufObj, &respType, WPS_ID_RESP_TYPE_S);

	/* WSC 2.0, add WFA vendor id and subelements to vendor extension attribute  */
	data8 = info->version2;
	subtlv_serialize(WPS_WFA_SUBID_VERSION2, vendorExt_bufObj, &data8,
		WPS_WFA_SUBID_VERSION2_S);

	/* Serialize subelemetns to Vendor Extension */
	vendorExt.vendorId = (uint8 *)WFA_VENDOR_EXT_ID;
	vendorExt.vendorData = buffobj_GetBuf(vendorExt_bufObj);
	vendorExt.dataLength = buffobj_Length(vendorExt_bufObj);
	tlv_vendorExtWrite(&vendorExt, bufObj);

	buffobj_del(vendorExt_bufObj);

#ifdef WFA_WPS_20_TESTBED
{
	char *pc_data;
	uint16 data16;

	/* New unknown attribute */
	pc_data = info->nattr_tlv;
	data16 = info->nattr_len;
	if (data16 && pc_data)
		buffobj_Append(bufObj, data16, pc_data);
}
#endif /* WFA_WPS_20_TESTBED */
	/* Send a pointer to the serialized data to Transport */
	if (0 != wps_set_wps_ie(g_mc->bcmwps, bufObj->pBase, bufObj->m_dataLength,
		WPS_IE_TYPE_SET_ASSOC_RESPONSE_IE)) {
		TUTRACE((TUTRACE_ERR, "wps_setAssocRespIE: call wps_set_wps_ie() failed\n"));
		ret = WPS_ERR_GENERIC;
	}
	else {
		TUTRACE((TUTRACE_ERR, "wps_setAssocRespIE: call wps_set_wps_ie() ok\n"));
		ret = WPS_SUCCESS;
	}

	/* bufObj will be destroyed when we exit this function */
	buffobj_del(bufObj);
	return ret;
}
コード例 #6
0
ファイル: ap_api.c プロジェクト: 3sOx/asuswrt-merlin
/*
 * Name        : SetProbeRespIE
 * Description : Push WPS Probe Resp WPS IE information to transport
 * Arguments   :
 * Return type : uint32 - result of the operation
 */
static uint32
wps_setProbeRespIE(WPSAPI_T *g_mc, IN uint8 respType, IN uint8 scState,
	IN bool b_selRegistrar, IN uint16 devPwdId, IN uint16 selRegCfgMethods,
	uint8 *authorizedMacs_buf, int authorizedMacs_len)
{
	uint32 ret;
	BufferObj *bufObj, *vendorExt_bufObj;
	uint16 data16;
	uint8 data8, *p_data8;
	char *pc_data;
	CTlvPrimDeviceType tlvPrimDeviceType;
	CTlvVendorExt vendorExt;
	DevInfo *info = g_mc->dev_info;

	bufObj = buffobj_new();
	if (!bufObj)
		return WPS_ERR_SYSTEM;

	/* Version */
	data8 = WPS_VERSION;
	tlv_serialize(WPS_ID_VERSION, bufObj, &data8, WPS_ID_VERSION_S);

	/* Simple Config State */
	tlv_serialize(WPS_ID_SC_STATE, bufObj, &scState, WPS_ID_SC_STATE_S);

	/* AP Setup Locked - optional if false.  If implemented and TRUE, include this attribute. */
	/*
	 * tlv_serialize(WPS_ID_AP_SETUP_LOCKED, bufObj, &b_APSetupLocked,
	 * WPS_ID_AP_SETUP_LOCKED_S);
	 */

	/* Selected Registrar */
	tlv_serialize(WPS_ID_SEL_REGISTRAR, bufObj, &b_selRegistrar, WPS_ID_SEL_REGISTRAR_S);

	/*
	 * Selected Registrar Config Methods - optional, required if b_selRegistrar
	 * is true
	 * Device Password ID - optional, required if b_selRegistrar is true
	 * Enrollee UUID - optional, required if b_selRegistrar is true
	 */
	if (b_selRegistrar) {
		/* Device Password ID */
		tlv_serialize(WPS_ID_DEVICE_PWD_ID, bufObj, &devPwdId, WPS_ID_DEVICE_PWD_ID_S);
		/* Selected Registrar Config Methods */
		tlv_serialize(WPS_ID_SEL_REG_CFG_METHODS, bufObj, &selRegCfgMethods,
			WPS_ID_SEL_REG_CFG_METHODS_S);
		/* Per 1.0b spec, removed Enrollee UUID */
	}

	/* Response Type */
	tlv_serialize(WPS_ID_RESP_TYPE, bufObj, &respType, WPS_ID_RESP_TYPE_S);

	p_data8 = info->uuid;
	tlv_serialize(WPS_ID_UUID_E, bufObj, p_data8, SIZE_UUID);

	/* Manufacturer */
	pc_data = info->manufacturer;
	data16 = strlen(pc_data);
	tlv_serialize(WPS_ID_MANUFACTURER, bufObj, pc_data, data16);

	/* Model Name */
	pc_data = info->modelName;
	data16 = strlen(pc_data);
	tlv_serialize(WPS_ID_MODEL_NAME, bufObj, pc_data, data16);

	/* Model Number */
	pc_data = info->modelNumber;
	data16 = strlen(pc_data);
	tlv_serialize(WPS_ID_MODEL_NUMBER, bufObj, pc_data, data16);

	/* Serial Number */
	pc_data = info->serialNumber;
	data16 = strlen(pc_data);
	tlv_serialize(WPS_ID_SERIAL_NUM, bufObj, pc_data, data16);

	/*
	 * Primary Device Type
	 * This is a complex TLV, so will be handled differently
	 */
	tlvPrimDeviceType.categoryId = info->primDeviceCategory;
	tlvPrimDeviceType.oui = info->primDeviceOui;
	tlvPrimDeviceType.subCategoryId = info->primDeviceSubCategory;
	tlv_primDeviceTypeWrite(&tlvPrimDeviceType, bufObj);

	/* Device Name */
	pc_data = info->deviceName;
	data16 = strlen(pc_data);
	tlv_serialize(WPS_ID_DEVICE_NAME, bufObj, pc_data, data16);

	/* Config Methods */
	/*
	* 1: In WPS Test Plan 2.0.3, case 4.1.2 step4. APUT cannot use push button to add ER,
	* 2: In P2P Test Plan 4.2.1, PBC bit is checked to be disabled in WPS2.0.
	* 3: DMT PBC testing check the PBC method from CONFIG_METHODS field (for now, DMT
	* testing only avaliable on WPS 1.0.
	* Remove PBC in WPS 2.0 anyway.
	*/
	data16 = info->configMethods;
	data8 = info->version2;
	if (data8 >= WPS_VERSION2)
		data16 &= ~(WPS_CONFMET_VIRT_PBC | WPS_CONFMET_PHY_PBC);
	else
	{
		/* WPS 1.0 */
		if (scState == WPS_SCSTATE_UNCONFIGURED)
		{
			data16 &= ~WPS_CONFMET_PBC;
		}
	}
	tlv_serialize(WPS_ID_CONFIG_METHODS, bufObj, &data16, WPS_ID_CONFIG_METHODS_S);

	/* RF Bands - optional */
	data8 = info->rfBand;
	if (data8 == 3)
		tlv_serialize(WPS_ID_RF_BAND, bufObj, &data8, WPS_ID_RF_BAND_S);

	/* WSC 2.0, add WFA vendor id and subelements to vendor extension attribute  */
	data8 = info->version2;
	if (data8 >= WPS_VERSION2) {
		vendorExt_bufObj = buffobj_new();
		if (vendorExt_bufObj == NULL) {
			buffobj_del(bufObj);
			return WPS_ERR_SYSTEM;
		}

		subtlv_serialize(WPS_WFA_SUBID_VERSION2, vendorExt_bufObj,
			&data8, WPS_WFA_SUBID_VERSION2_S);

		/* AuthorizedMACs */
		if (authorizedMacs_buf && authorizedMacs_len) {
			subtlv_serialize(WPS_WFA_SUBID_AUTHORIZED_MACS, vendorExt_bufObj,
				authorizedMacs_buf, authorizedMacs_len);
		}

		/* Serialize subelemetns to Vendor Extension */
		vendorExt.vendorId = (uint8 *)WFA_VENDOR_EXT_ID;
		vendorExt.vendorData = buffobj_GetBuf(vendorExt_bufObj);
		vendorExt.dataLength = buffobj_Length(vendorExt_bufObj);
		tlv_vendorExtWrite(&vendorExt, bufObj);

		buffobj_del(vendorExt_bufObj);
#ifdef WFA_WPS_20_TESTBED
		/* New unknown attribute */
		pc_data = info->nattr_tlv;
		data16 = info->nattr_len;
		if (data16 && pc_data)
			buffobj_Append(bufObj, data16, pc_data);
#endif /* WFA_WPS_20_TESTBED */
	}

	/* Send a pointer to the serialized data to Transport */
	if (0 != wps_set_wps_ie(g_mc->bcmwps, bufObj->pBase, bufObj->m_dataLength,
		WPS_IE_TYPE_SET_PROBE_RESPONSE_IE)) {
		TUTRACE((TUTRACE_ERR, "wps_setProbeRespIE: call wps_set_wps_ie() failed\n"));
		ret = WPS_ERR_GENERIC;
	}
	else {
		TUTRACE((TUTRACE_ERR, "wps_setProbeRespIE: call wps_set_wps_ie() ok\n"));
		ret = WPS_SUCCESS;
	}

	/* bufObj will be destroyed when we exit this function */
	buffobj_del(bufObj);
	return ret;
}
コード例 #7
0
ファイル: ap_api.c プロジェクト: 3sOx/asuswrt-merlin
/*
 * Name        : SetBeaconIE
 * Description : Push Beacon WPS IE information to transport
 * Arguments   : IN bool b_configured - is the AP configured?
 * IN bool b_selRegistrar - is this flag set?
 * IN uint16 devPwdId - valid if b_selRegistrar is true
 * IN uint16 selRegCfgMethods - valid if b_selRegistrar is true
 * Return type : uint32 - result of the operation
 */
static uint32
wps_setBeaconIE(WPSAPI_T *g_mc, IN bool b_configured, IN bool b_selRegistrar,
	IN uint16 devPwdId, IN uint16 selRegCfgMethods, uint8 *authorizedMacs_buf,
	int authorizedMacs_len)
{
	uint32 ret;
	uint8 data8;
	uint8 *p_data8;
	CTlvVendorExt vendorExt;
	DevInfo *info = g_mc->dev_info;

	BufferObj *bufObj, *vendorExt_bufObj;

	bufObj = buffobj_new();
	if (!bufObj)
		return WPS_ERR_SYSTEM;

	/* Version */
	data8 = WPS_VERSION;
	tlv_serialize(WPS_ID_VERSION, bufObj, &data8, WPS_ID_VERSION_S);

	/* Simple Config State */
	if (b_configured)
		data8 = WPS_SCSTATE_CONFIGURED;
	else
		data8 = WPS_SCSTATE_UNCONFIGURED;
	tlv_serialize(WPS_ID_SC_STATE, bufObj, &data8, WPS_ID_SC_STATE_S);

	/*
	 * AP Setup Locked - optional if false.  If implemented and TRUE, include this attribute.
	 * CTlvAPSetupLocked(WPS_ID_AP_SETUP_LOCKED, bufObj, &b_APSetupLocked);
	 *
	 * Selected Registrar - optional
	 * Add this TLV only if b_selRegistrar is true
	 */
	if (b_selRegistrar) {
		tlv_serialize(WPS_ID_SEL_REGISTRAR, bufObj, &b_selRegistrar,
			WPS_ID_SEL_REGISTRAR_S);
		/* Add in other related params as well Device Password ID */
		tlv_serialize(WPS_ID_DEVICE_PWD_ID, bufObj, &devPwdId, WPS_ID_DEVICE_PWD_ID_S);
		/* Selected Registrar Config Methods */
		tlv_serialize(WPS_ID_SEL_REG_CFG_METHODS, bufObj,
			&selRegCfgMethods, WPS_ID_SEL_REG_CFG_METHODS_S);
		/* Enrollee UUID removed */
	}

	data8 = info->rfBand;
	/* dual band, it's become require */
	if (data8 == 3) {
		p_data8 = info->uuid;
		tlv_serialize(WPS_ID_UUID_E, bufObj, p_data8, SIZE_UUID);
		tlv_serialize(WPS_ID_RF_BAND, bufObj, &data8, WPS_ID_RF_BAND_S);
	}

	/* WSC 2.0,  support WPS V2 or not */
	data8 = info->version2;
	if (data8 >= WPS_VERSION2) {
		vendorExt_bufObj = buffobj_new();
		if (vendorExt_bufObj == NULL) {
			buffobj_del(bufObj);
			return WPS_ERR_SYSTEM;
		}

		/* WSC 2.0 */
		subtlv_serialize(WPS_WFA_SUBID_VERSION2, vendorExt_bufObj,
			&data8, WPS_WFA_SUBID_VERSION2_S);
		/* AuthorizedMACs */
		if (authorizedMacs_buf && authorizedMacs_len) {
			subtlv_serialize(WPS_WFA_SUBID_AUTHORIZED_MACS, vendorExt_bufObj,
				authorizedMacs_buf, authorizedMacs_len);
		}

		/* Serialize subelemetns to Vendor Extension */
		vendorExt.vendorId = (uint8 *)WFA_VENDOR_EXT_ID;
		vendorExt.vendorData = buffobj_GetBuf(vendorExt_bufObj);
		vendorExt.dataLength = buffobj_Length(vendorExt_bufObj);
		tlv_vendorExtWrite(&vendorExt, bufObj);

		buffobj_del(vendorExt_bufObj);
#ifdef WFA_WPS_20_TESTBED
{
	char *pc_data;
	uint16 data16;

	/* New unknown attribute */
	pc_data = info->nattr_tlv;
	data16 = info->nattr_len;
	if (data16 && pc_data)
		buffobj_Append(bufObj, data16, pc_data);
}
#endif /* WFA_WPS_20_TESTBED */
	}

	/* Send a pointer to the serialized data to Transport */
	if (0 != wps_set_wps_ie(g_mc->bcmwps, bufObj->pBase, bufObj->m_dataLength,
		1 /* WPS_IE_TYPE_SET_BEACON_IE */ )) {
		TUTRACE((TUTRACE_ERR, "MC_SetBeaconIE: call to trans->SetBeaconIE() failed\n"));
		ret = WPS_ERR_GENERIC;
	}
	else {
		TUTRACE((TUTRACE_ERR, "MC_SetBeaconIE: call to trans->SetBeaconIE() ok\n"));
		ret = WPS_SUCCESS;
	}

	buffobj_del(bufObj);
	return ret;
}
コード例 #8
0
ファイル: ap_api.c プロジェクト: 3sOx/asuswrt-merlin
int
wps_processMsg(void *mc_dev, void *inbuffer, uint32 in_len, void *outbuffer, uint32 *out_len,
	TRANSPORT_TYPE m_transportType)
{
	WPSAPI_T *g_mc = (WPSAPI_T *)mc_dev;
	RegData *regInfo;
	EnrSM *e;
	int ret = WPS_CONT;

	if (!g_mc)
		return WPS_MESSAGE_PROCESSING_ERROR;

	if (wps_get_mode(g_mc) == SCMODE_AP_ENROLLEE) {
		if (g_mc->mp_enrSM) {
			g_mc->mp_enrSM->reg_info->transportType = m_transportType;

			/* Pre-process upnp */
			ret  = wps_enrUpnpGetDeviceInfoCheck(g_mc->mp_enrSM, inbuffer,
				in_len, outbuffer, out_len);
			if (ret != WPS_CONT) {
				if (ret == WPS_SUCCESS)
					return WPS_CONT;
				else
					return ret;
			}

			/* Hacking,
			 * set regInfo's e_lastMsgSent to M1,  m_m2dStatus to SM_AWAIT_M2 and
			 * regInfo's e_smState to CONTINUE,
			 * and create M1 to get regInfo's outMsg which needed in M2 process
			 */
			e = g_mc->mp_enrSM;
			regInfo = e->reg_info;

			if (START == regInfo->e_smState &&
			    (regInfo->dev_info->flags & DEVINFO_FLAG_PRE_NONCE)) {
				uint32 msgType = 0, err;
				BufferObj *inMsg, *outMsg;

				inMsg = buffobj_new();
				if (!inMsg)
					return WPS_ERR_SYSTEM;

				buffobj_dserial(inMsg, inbuffer, in_len);
				err = reg_proto_get_msg_type(&msgType, inMsg);
				buffobj_del(inMsg);

				if (WPS_SUCCESS == err && WPS_ID_MESSAGE_M2 == msgType) {
					outMsg = buffobj_setbuf((uint8 *)outbuffer, *out_len);
					if (!outMsg)
						return WPS_ERR_SYSTEM;

					memcpy(regInfo->enrolleeNonce,
						regInfo->dev_info->pre_nonce,
						SIZE_128_BITS);

					e->reg_info->e_lastMsgSent = M1;
					/* Set the m2dstatus. */
					e->m_m2dStatus = SM_AWAIT_M2;
					/* set the message state to CONTINUE */
					e->reg_info->e_smState = CONTINUE;

					reg_proto_create_m1(regInfo, outMsg);

					buffobj_del(outMsg);
				}
			}

			ret = enr_sm_step(g_mc->mp_enrSM, in_len, ((uint8 *)inbuffer),
				((uint8 *)outbuffer), out_len);
		}
	}
	else {
		if (g_mc->mp_regSM) {
			g_mc->mp_regSM->reg_info->transportType = m_transportType;

			/* Pre-process upnp */
			ret  = wps_regUpnpForwardingCheck(g_mc->mp_regSM, inbuffer,
				in_len, outbuffer, out_len);
			if (ret != WPS_CONT) {
				return ret;
			}

			ret = reg_sm_step(g_mc->mp_regSM, in_len, ((uint8 *)inbuffer),
				((uint8 *)outbuffer), out_len);
		}
	}

	return ret;
}
コード例 #9
0
ファイル: ap_api.c プロジェクト: 3sOx/asuswrt-merlin
uint32
wps_regUpnpForwardingCheck(RegSM *r, void *inbuffer, uint32 in_len,
	void *outbuffer, uint32 *out_len)
{
	uint32 msgType = 0, err = WPS_SUCCESS, retVal = WPS_CONT;
	TRANSPORT_TYPE trType;
	BufferObj *inMsg = NULL, *outMsg = NULL;

	if (false == r->reg_info->initialized) {
		TUTRACE((TUTRACE_ERR, "REGSM: Not yet initialized.\n"));
		return WPS_ERR_NOT_INITIALIZED;
	}

	/* Irrespective of whether the local registrar is enabled or whether we're
	 * using an external registrar, we need to send a WPS_Start over EAP to
	 * kickstart the protocol.
	 * If we send a WPS_START msg, we don't need to do anything else i.e.
	 * invoke the local registrar or pass the message over UPnP
	 */
	if ((!in_len) && (START == r->reg_info->e_smState) &&
		((TRANSPORT_TYPE_EAP == r->reg_info->transportType) ||
		(TRANSPORT_TYPE_UPNP_CP == r->reg_info->transportType))) {
		err = wps_sendStartMessage(r->g_mc, r->reg_info->transportType);
		if (WPS_SUCCESS != err) {
			TUTRACE((TUTRACE_ERR, "REGSM: SendStartMessage failed. Err = %d\n", err));
		}
		return WPS_CONT;
	}

	/* Now send the message over UPnP. Else, if the message has come over UPnP
	 * send it over EAP.
	 * if(m_passThruEnabled)
	 */
	/* temporarily disable forwarding to/from UPnP if we've already sent M2
	 * this is a stop-gap measure to prevent multiple registrars from cluttering
	 * up the EAP session.
	 */
	if ((r->m_passThruEnabled) && (!r->m_sentM2) &&
	    wps_get_mode(r->g_mc) == SCMODE_AP_REGISTRAR) {

		if ((inMsg = buffobj_new()) == NULL)
			return WPS_ERR_SYSTEM;

		if (in_len) {
			buffobj_dserial(inMsg, inbuffer, in_len);
			err = reg_proto_get_msg_type(&msgType, inMsg);
		}

		switch (r->reg_info->transportType) {
		case TRANSPORT_TYPE_EAP:
			/* EAP to UPnP:
			 * if add client was performed by AP, skip this forward
			 * if (getBuiltInStart())
			 * break;
			 */
			if (r->reg_info->dev_info->b_ap)
				trType = TRANSPORT_TYPE_UPNP_DEV;
			else
				trType = TRANSPORT_TYPE_UPNP_CP;

			/* recvd from EAP, send over UPnP */
			if (msgType != WPS_ID_MESSAGE_ACK) {
				TUTRACE((TUTRACE_INFO, "REGSM: Forwarding message from "
					"EAP to UPnP.\n"));
				TUTRACE((TUTRACE_INFO, "\n###EAP to UPnP msgType=%x (%s)"
					" ###\n", msgType, wps_msg_type_str(msgType)));
				err = wps_sendMsg(r->g_mc, trType, (char *)inbuffer, in_len);
			}

			/* Now check to see if the EAP message is a WPS_NACK.  If so,
			 * terminate the EAP connection with an EAP-Fail.
			 * if (msgType == WPS_ID_MESSAGE_NACK && WPS_SUCCESS == err) {
			 */
			if (msgType == WPS_ID_MESSAGE_NACK) {
				TUTRACE((TUTRACE_ERR, "REGSM: Notifying MC of failure.\n"));

				/* reset the SM */
				reg_sm_restartsm(r);
				retVal = WPS_MESSAGE_PROCESSING_ERROR;
				break;
			}

			if ((WPS_SUCCESS == err) && (msgType == WPS_ID_MESSAGE_DONE)) {
				TUTRACE((TUTRACE_INFO, "REGSM: Send EAP fail when "
					"DONE or ACK (type=%x).\n", msgType));

				retVal = WPS_SUCCESS;
				break;
			}

			break;

		default:
			/* UPnP to EAP: */
			TUTRACE((TUTRACE_INFO, "REGSM: Forwarding message from UPnP to EAP.\n"));

			/* recvd over UPNP, send it out over EAP */
			TUTRACE((TUTRACE_INFO, "\n======== GetDeviceInfo=%d  =======\n",
				wps_getUpnpDevGetDeviceInfo(r->g_mc)));
			if (in_len) {
				TUTRACE((TUTRACE_INFO, "\n###UPnP to EAP msgType=%x (%s) ###\n",
					msgType, wps_msg_type_str(msgType)));

				if (WPS_SUCCESS == err && msgType == WPS_ID_MESSAGE_M2D) {
					TUTRACE((TUTRACE_INFO, "\n ==received M2D ==\n"));
				}
			}

			if (wps_getUpnpDevGetDeviceInfo(r->g_mc)) {
				outMsg = buffobj_setbuf(outbuffer, *out_len);
				if (!outMsg) {
					retVal = WPS_ERR_SYSTEM;
					break;
				}

				wps_setUpnpDevGetDeviceInfo(r->g_mc, false);

				err = reg_proto_create_devinforsp(r->reg_info, outMsg);
				if (WPS_SUCCESS != err) {
					TUTRACE((TUTRACE_ERR, "BuildMessageM1: %d\n", err));
				}
				else {
					/* Now send the message to the transport */
					err = wps_sendMsg(r->g_mc, r->reg_info->transportType,
						(char *)outMsg->pBase, outMsg->m_dataLength);
				}

				if (WPS_SUCCESS != err) {
					r->reg_info->e_smState = FAILURE;
					TUTRACE((TUTRACE_ERR, "ENRSM: TrWrite generated an "
						"error: %d\n", err));
				}
			}

			if (in_len) {
				if (wps_regUpnpERFilter(r, inMsg, msgType) == WPS_CONT)
					break;

				err = wps_sendMsg(r->g_mc, TRANSPORT_TYPE_EAP,
					(char *)inbuffer, in_len);
			}

			break;
		}
	}

	if (inMsg)
		buffobj_del(inMsg);
	if (outMsg)
		buffobj_del(outMsg);

	return retVal;
}
コード例 #10
0
ファイル: nfc_utils.c プロジェクト: 3sOx/asuswrt-merlin
uint32
nfc_utils_parse_pw(WpsOobDevPw *devpw, uint8 wsp_version2, uint8 *buf, uint buflen)
{
	uint32 ret = WPS_SUCCESS;
	char *cp_data;
	uint16 data16;
	BufferObj *bufObj = NULL;
	BufferObj *vendorExt_bufObj = NULL;
	CTlvVersion version;
	CSubTlvVersion2 version2;
	CTlvVendorExt vendorExt;
	CTlvOobDevPwd *p_oobDevPwd = NULL;

	/* Sanity check */
	if (devpw == NULL || buf == NULL || buflen == 0) {
		TUTRACE((TUTRACE_NFC, "Pase WPS PW: Invalid parameters!\n"));
		ret = WPS_ERR_INVALID_PARAMETERS;
		goto error;
	}

	if (buflen < 7) {
		TUTRACE((TUTRACE_NFC, "Pase WPS PW: buf length too short!\n"));
		ret = WPS_ERR_INVALID_PARAMETERS;
		goto error;
	}

	if (buf[5] != 0x10 || buf[6] != 0x2C) {
		TUTRACE((TUTRACE_NFC, "Pase WPS PW: Not a Password Token!\n"));
		ret = WPS_ERR_INVALID_PARAMETERS;
		goto error;
	}

	/* Dserial raw data to bufObj */
	bufObj = buffobj_new();
	if (bufObj == NULL) {
		TUTRACE((TUTRACE_NFC, "Pase WPS PW: Malloc fail!\n"));
		ret = WPS_ERR_OUTOFMEMORY;
		goto error;
	}

	WPS_HexDumpAscii("NFC_UTILS_PARSE_PW", -1, buf, buflen);

	buffobj_dserial(bufObj, buf, buflen);

	/* Version 1 */
	if (tlv_dserialize(&version, WPS_ID_VERSION, bufObj, 0, 0) != 0) {
		TUTRACE((TUTRACE_NFC, "Pase WPS PW: TLV missing\n"));
		ret = RPROT_ERR_REQD_TLV_MISSING;
		goto error;
	}

	/* Must be 0x10, See WSC2.0 Clause 7.9 Version Negotiation */
	if (version.m_data != WPS_VERSION) {
		TUTRACE((TUTRACE_NFC, "Pase WPS PW: Message version should always set to 1\n"));
		ret = RPROT_ERR_INCOMPATIBLE;
		goto error;
	}

	/* OOB Device Password */
	p_oobDevPwd = (CTlvOobDevPwd *)malloc(sizeof(CTlvOobDevPwd));
	if (!p_oobDevPwd) {
		TUTRACE((TUTRACE_NFC, "Pase WPS PW: Malloc fail!\n"));
		ret = WPS_ERR_OUTOFMEMORY;
		goto error;
	}
	memset(p_oobDevPwd, 0, sizeof(CTlvOobDevPwd));
	if (tlv_oobDevPwdParse(p_oobDevPwd, bufObj) != 0) {
		ret = WPS_ERR_SYSTEM;
		goto error;
	}

	/* Save CTlvOobDevPwd to WpsOobDevPw */
	memcpy(devpw->pub_key_hash, p_oobDevPwd->publicKeyHash, SIZE_160_BITS);
	devpw->devPwdId = p_oobDevPwd->pwdId;
	memcpy(devpw->pin, p_oobDevPwd->ip_devPwd, p_oobDevPwd->devPwdLength);
	devpw->pin_len = p_oobDevPwd->devPwdLength;

	/* Version2, here you don't is peer WSC 2.0 or not */
	if (wsp_version2 >= WPS_VERSION2) {
		if (tlv_find_vendorExtParse(&vendorExt, bufObj, (uint8 *)WFA_VENDOR_EXT_ID) != 0) {
			TUTRACE((TUTRACE_NFC, "Pase WPS PW: Cannot find vendor extension\n"));
			/* ret = RPROT_ERR_INCOMPATIBLE; */
			goto error;
		}

		/* Deserialize subelement */
		if ((vendorExt_bufObj = buffobj_new()) == NULL) {
			TUTRACE((TUTRACE_NFC, "Pase WPS PW: Fail to allocate "
				"vendor extension buffer, Out of memory\n"));

			ret = WPS_ERR_OUTOFMEMORY;
			goto error;
		}

		buffobj_dserial(vendorExt_bufObj, vendorExt.vendorData,
			vendorExt.dataLength);

		/* Get Version2 subelement */
		if ((buffobj_NextSubId(vendorExt_bufObj) != WPS_WFA_SUBID_VERSION2) ||
		    (subtlv_dserialize(&version2, WPS_WFA_SUBID_VERSION2, vendorExt_bufObj,
		     0, 0) != 0)) {
			TUTRACE((TUTRACE_NFC, "Pase WPS PW: Cannot get Version2\n"));
			/* ret = RPROT_ERR_INCOMPATIBLE; */
			goto error;
		}

		if (version2.m_data < WPS_VERSION2) {
			TUTRACE((TUTRACE_NFC, "Pase WPS PW: Invalid Version2 number\n"));
			ret = RPROT_ERR_INCOMPATIBLE;
			goto error;
		}
	}

error:
	/* free local alloc pointers */
	if (vendorExt_bufObj)
		buffobj_del(vendorExt_bufObj);

	if (p_oobDevPwd)
		free(p_oobDevPwd);

	if (bufObj)
		buffobj_del(bufObj);

	return ret;
}
コード例 #11
0
ファイル: nfc_utils.c プロジェクト: 3sOx/asuswrt-merlin
uint32
nfc_utils_parse_cfg(WpsEnrCred *cred, uint8 wsp_version2, uint8 *buf, uint buflen)
{
	uint32 ret = WPS_SUCCESS;
	char *cp_data;
	uint16 data16;
	BufferObj *bufObj = NULL;
	BufferObj *vendorExt_bufObj = NULL;
	CTlvVersion version;
	CSubTlvVersion2 version2;
	CTlvVendorExt vendorExt;
	CTlvCredential *p_tlvCred = NULL;

	/* Sanity check */
	if (cred == NULL || buf == NULL || buflen == 0) {
		TUTRACE((TUTRACE_NFC, "Pase WPS CFG: Invalid parameters!\n"));
		ret = WPS_ERR_INVALID_PARAMETERS;
		goto error;
	}

	if (buflen < 7) {
		TUTRACE((TUTRACE_NFC, "Pase WPS CFG: buf length too short!\n"));
		ret = WPS_ERR_INVALID_PARAMETERS;
		goto error;
	}

	if (buf[5] != 0x10 || buf[6] != 0x0E) {
		TUTRACE((TUTRACE_NFC, "Pase WPS CFG: Not a Configuration Token!\n"));
		ret = WPS_ERR_INVALID_PARAMETERS;
		goto error;
	}

	/* Dserial raw data to bufObj */
	bufObj = buffobj_new();
	if (bufObj == NULL) {
		TUTRACE((TUTRACE_NFC, "Pase WPS CFG: Malloc fail!\n"));
		ret = WPS_ERR_OUTOFMEMORY;
		goto error;
	}

	WPS_HexDumpAscii("NFC_UTILS_PARSE_CFG", -1, buf, buflen);

	buffobj_dserial(bufObj, buf, buflen);

	/* Version 1 */
	if (tlv_dserialize(&version, WPS_ID_VERSION, bufObj, 0, 0) != 0) {
		TUTRACE((TUTRACE_NFC, "Pase WPS CFG: TLV missing\n"));
		ret = RPROT_ERR_REQD_TLV_MISSING;
		goto error;
	}

	/* Must be 0x10, See WSC2.0 Clause 7.9 Version Negotiation */
	if (version.m_data != WPS_VERSION) {
		TUTRACE((TUTRACE_NFC, "Pase WPS CFG: Message version should always set to 1\n"));
		ret = RPROT_ERR_INCOMPATIBLE;
		goto error;
	}

	/* Configuration */
	/* Parse Credential */
	p_tlvCred = (CTlvCredential *)malloc(sizeof(CTlvCredential));
	if (!p_tlvCred) {
		TUTRACE((TUTRACE_NFC, "Pase WPS CFG: Malloc fail!\n"));
		ret = WPS_ERR_OUTOFMEMORY;
		goto error;
	}
	memset(p_tlvCred, 0, sizeof(CTlvCredential));
	tlv_credentialParse(p_tlvCred, bufObj, true);

	/* Save CTlvCredential to WpsEnrCred */
	/* Fill in SSID */
	cp_data = (char *)(p_tlvCred->ssid.m_data);
	data16 = cred->ssidLen = p_tlvCred->ssid.tlvbase.m_len;
	strncpy(cred->ssid, cp_data, data16);
	cred->ssid[data16] = '\0';

	/* Fill in keyMgmt */
	if (p_tlvCred->authType.m_data == WPS_AUTHTYPE_SHARED) {
		strncpy(cred->keyMgmt, "SHARED", 6);
		cred->keyMgmt[6] = '\0';
	}
	else  if (p_tlvCred->authType.m_data == WPS_AUTHTYPE_WPAPSK) {
		strncpy(cred->keyMgmt, "WPA-PSK", 7);
		cred->keyMgmt[7] = '\0';
	}
	else if (p_tlvCred->authType.m_data == WPS_AUTHTYPE_WPA2PSK) {
		strncpy(cred->keyMgmt, "WPA2-PSK", 8);
		cred->keyMgmt[8] = '\0';
	}
	else if (p_tlvCred->authType.m_data == (WPS_AUTHTYPE_WPAPSK | WPS_AUTHTYPE_WPA2PSK)) {
		strncpy(cred->keyMgmt, "WPA-PSK WPA2-PSK", 16);
		cred->keyMgmt[16] = '\0';
	}
	else {
		strncpy(cred->keyMgmt, "OPEN", 4);
		cred->keyMgmt[4] = '\0';
	}

	/* get the real cypher */
	cred->encrType = p_tlvCred->encrType.m_data;

	/* Fill in WEP index, no matter it's WEP type or not */
	cred->wepIndex = p_tlvCred->WEPKeyIndex.m_data;

	/* Fill in PSK */
	data16 = p_tlvCred->nwKey.tlvbase.m_len;
	memset(cred->nwKey, 0, SIZE_64_BYTES);
	memcpy(cred->nwKey, p_tlvCred->nwKey.m_data, data16);
	/* we have to set key length here */
	cred->nwKeyLen = data16;

	/* WSC 2.0,  nwKeyShareable */
	cred->nwKeyShareable = p_tlvCred->nwKeyShareable.m_data;

	/* Version2, here you don't is peer WSC 2.0 or not */
	if (wsp_version2 >= WPS_VERSION2) {
		if (tlv_find_vendorExtParse(&vendorExt, bufObj, (uint8 *)WFA_VENDOR_EXT_ID) != 0) {
			TUTRACE((TUTRACE_NFC, "Pase WPS CFG: Cannot find vendor extension\n"));
			/* ret = RPROT_ERR_INCOMPATIBLE; */
			goto error;
		}

		/* Deserialize subelement */
		if ((vendorExt_bufObj = buffobj_new()) == NULL) {
			TUTRACE((TUTRACE_NFC, "Pase WPS CFG: Fail to allocate "
				"vendor extension buffer, Out of memory\n"));

			ret = WPS_ERR_OUTOFMEMORY;
			goto error;
		}

		buffobj_dserial(vendorExt_bufObj, vendorExt.vendorData,
			vendorExt.dataLength);

		/* Get Version2 subelement */
		if ((buffobj_NextSubId(vendorExt_bufObj) != WPS_WFA_SUBID_VERSION2) ||
		    (subtlv_dserialize(&version2, WPS_WFA_SUBID_VERSION2, vendorExt_bufObj,
		     0, 0) != 0)) {
			TUTRACE((TUTRACE_NFC, "Pase WPS CFG: Cannot get Version2\n"));
			/* ret = RPROT_ERR_INCOMPATIBLE; */
			goto error;
		}

		if (version2.m_data < WPS_VERSION2) {
			TUTRACE((TUTRACE_NFC, "Pase WPS NDEF: Invalid Version2 number\n"));
			ret = RPROT_ERR_INCOMPATIBLE;
			goto error;
		}
	}

error:
	/* free local alloc pointers */
	if (vendorExt_bufObj)
		buffobj_del(vendorExt_bufObj);

	if (p_tlvCred)
		tlv_credentialDelete(p_tlvCred, 0);

	if (bufObj)
		buffobj_del(bufObj);

	return ret;
}
コード例 #12
0
ファイル: nfc_utils.c プロジェクト: 3sOx/asuswrt-merlin
uint32
nfc_utils_build_cfg(DevInfo *info, uint8 *buf, uint *buflen)
{
	char *p_nwKey, *cp_data;
	uint8 *p_macAddr, wep_exist = 0, version = WPS_VERSION;
	uint16 data16;
	uint32 ret = WPS_SUCCESS, nwKeyLen = 0;
	BufferObj *bufObj = NULL, *vendorExt_bufObj = NULL;
	CTlvVendorExt vendorExt;
	CTlvCredential *p_tlvCred = NULL;

	TUTRACE((TUTRACE_NFC, "Build NFC Configuration\n"));

	if (info == NULL || buf == NULL || *buflen == 0) {
		TUTRACE((TUTRACE_NFC, "nfc_utils_build_cfg: Invalid arguments\n"));
		return WPS_ERR_SYSTEM;
	}

	if ((bufObj = buffobj_new()) == NULL) {
		TUTRACE((TUTRACE_NFC, "nfc_utils_build_cfg: Out of memory\n"));
		return WPS_ERR_OUTOFMEMORY;
	}

	/* Version */
	tlv_serialize(WPS_ID_VERSION, bufObj, &version, WPS_ID_VERSION_S);

	/* Credential */
	if ((p_tlvCred = (CTlvCredential *)malloc(sizeof(CTlvCredential))) == NULL) {
		TUTRACE((TUTRACE_NFC, "nfc_utils_build_cfg: Out of memory\n"));
		ret = WPS_ERR_OUTOFMEMORY;
		goto error;
	}
	memset(p_tlvCred, 0, sizeof(CTlvCredential));

	/* Credential items */
	/* nwIndex */
	tlv_set(&p_tlvCred->nwIndex, WPS_ID_NW_INDEX, (void *)1, 0);

	/* ssid */
	cp_data = info->ssid;
	data16 = strlen(cp_data);
	tlv_set(&p_tlvCred->ssid, WPS_ID_SSID, cp_data, data16);

	/* auth */
	if (info->auth)
		data16 = WPS_AUTHTYPE_SHARED;
	else if (devinfo_getKeyMgmtType(info) == WPS_WL_AKM_PSK)
		data16 = WPS_AUTHTYPE_WPAPSK;
	else if (devinfo_getKeyMgmtType(info) == WPS_WL_AKM_PSK2)
		data16 = WPS_AUTHTYPE_WPA2PSK;
	else if (devinfo_getKeyMgmtType(info) == WPS_WL_AKM_BOTH)
		data16 = WPS_AUTHTYPE_WPAPSK | WPS_AUTHTYPE_WPA2PSK;
	else
		data16 = WPS_AUTHTYPE_OPEN;
	tlv_set(&p_tlvCred->authType, WPS_ID_AUTH_TYPE, UINT2PTR(data16), 0);

	/* encrType */
	if (info->auth)
		data16 = WPS_ENCRTYPE_WEP;
	else if (data16 == WPS_AUTHTYPE_OPEN) {
		if (info->wep)
			data16 = WPS_ENCRTYPE_WEP;
		else
			data16 = WPS_ENCRTYPE_NONE;
	}
	else
		data16 = info->crypto;
	tlv_set(&p_tlvCred->encrType, WPS_ID_ENCR_TYPE, UINT2PTR(data16), 0);

	if (data16 == WPS_ENCRTYPE_WEP)
		wep_exist = 1;

	/* nwKeyIndex
	 * WSC 2.0, "Network Key Index" deprecated - only included by WSC 1.0 devices.
	 * Ignored by WSC 2.0 or newer devices.
	 */
	if (info->version2 < WPS_VERSION2) {
		tlv_set(&p_tlvCred->nwKeyIndex, WPS_ID_NW_KEY_INDEX, (void *)1, 0);
	}

	/* nwKey */
	p_nwKey = info->nwKey;
	nwKeyLen = strlen(info->nwKey);
	tlv_set(&p_tlvCred->nwKey, WPS_ID_NW_KEY, p_nwKey, nwKeyLen);

	/* enrollee's mac */
	p_macAddr = info->peerMacAddr;
	data16 = SIZE_MAC_ADDR;
	tlv_set(&p_tlvCred->macAddr, WPS_ID_MAC_ADDR, p_macAddr, data16);

	/* WepKeyIdx */
	if (wep_exist)
		tlv_set(&p_tlvCred->WEPKeyIndex, WPS_ID_WEP_TRANSMIT_KEY,
			UINT2PTR(info->wepKeyIdx), 0);

	/* WSC 2.0, WFA "Network Key Shareable" subelement */
	if (info->version2 >= WPS_VERSION2) {
		/* Always shareable */
		data16 = 1;
		subtlv_set(&p_tlvCred->nwKeyShareable, WPS_WFA_SUBID_NW_KEY_SHAREABLE,
			UINT2PTR(data16), 0);
	}
	tlv_credentialWrite(p_tlvCred, bufObj);

	/* Version2 */
	if (info->version2 >= WPS_VERSION2) {
		if ((vendorExt_bufObj = buffobj_new()) == NULL) {
			TUTRACE((TUTRACE_NFC, "nfc_utils_build_cfg: Out of memory\n"));
			ret = WPS_ERR_OUTOFMEMORY;
			goto error;
		}

		subtlv_serialize(WPS_WFA_SUBID_VERSION2, vendorExt_bufObj,
			&info->version2, WPS_WFA_SUBID_VERSION2_S);

		/* Serialize subelemetns to Vendor Extension */
		vendorExt.vendorId = (uint8 *)WFA_VENDOR_EXT_ID;
		vendorExt.vendorData = buffobj_GetBuf(vendorExt_bufObj);
		vendorExt.dataLength = buffobj_Length(vendorExt_bufObj);
		tlv_vendorExtWrite(&vendorExt, bufObj);
	}

	/* Check copy back avaliable buf length */
	if (*buflen < buffobj_Length(bufObj)) {
		TUTRACE((TUTRACE_NFC, "nfc_utils_build_cfg: In buffer len too short\n"));
		ret = WPS_ERR_SYSTEM;
		goto error;
	}

	/* Copy back data and length */
	*buflen = buffobj_Length(bufObj);
	memcpy(buf, buffobj_GetBuf(bufObj), buffobj_Length(bufObj));

error:
	/* Free local vendorExt_bufObj */
	if (vendorExt_bufObj)
		buffobj_del(vendorExt_bufObj);

	/* Free local p_tlvCred */
	if (p_tlvCred)
		tlv_credentialDelete(p_tlvCred, 0);

	/* Free local bufObj */
	if (bufObj)
		buffobj_del(bufObj);

	return ret;
}
コード例 #13
0
ファイル: nfc_utils.c プロジェクト: 3sOx/asuswrt-merlin
uint32
nfc_utils_build_pw(DevInfo *info, uint8 *buf, uint *buflen)
{
	uint8 version = WPS_VERSION;
	uint32 ret = WPS_SUCCESS;
	BufferObj *bufObj = NULL, *vendorExt_bufObj = NULL;
	CTlvVendorExt vendorExt;
	CTlvOobDevPwd oobDevPwd;
	unsigned char hex_pin[SIZE_32_BYTES];
	int hex_pin_len;

	TUTRACE((TUTRACE_NFC, "Build NFC Password\n"));

	if (info == NULL || buf == NULL || *buflen == 0) {
		TUTRACE((TUTRACE_NFC, "nfc_utils_build_pw: Invalid arguments\n"));
		return WPS_ERR_SYSTEM;
	}

	if ((bufObj = buffobj_new()) == NULL) {
		TUTRACE((TUTRACE_NFC, "nfc_utils_build_pw: Out of memory\n"));
		return WPS_ERR_OUTOFMEMORY;
	}

	/* Version */
	tlv_serialize(WPS_ID_VERSION, bufObj, &version, WPS_ID_VERSION_S);

	/* OOB Device Password */
	oobDevPwd.publicKeyHash = info->pub_key_hash;
	oobDevPwd.pwdId = info->devPwdId;

	/* Do String to Hex translation */
	hex_pin_len = wps_str2hex(hex_pin, sizeof(hex_pin), info->pin);
	if (hex_pin_len == 0) {
		TUTRACE((TUTRACE_NFC, "nfc_utils_build_pw: invalid parameters\n"));
		ret = WPS_ERR_INVALID_PARAMETERS;
		goto error;
	}

	oobDevPwd.ip_devPwd = hex_pin;
	oobDevPwd.devPwdLength = hex_pin_len;
	tlv_oobDevPwdWrite(&oobDevPwd, bufObj);

	/* Version2 */
	if (info->version2 >= WPS_VERSION2) {
		if ((vendorExt_bufObj = buffobj_new()) == NULL) {
			TUTRACE((TUTRACE_NFC, "nfc_utils_build_pw: Out of memory\n"));
			ret = WPS_ERR_OUTOFMEMORY;
			goto error;
		}

		subtlv_serialize(WPS_WFA_SUBID_VERSION2, vendorExt_bufObj,
			&info->version2, WPS_WFA_SUBID_VERSION2_S);

		/* Serialize subelemetns to Vendor Extension */
		vendorExt.vendorId = (uint8 *)WFA_VENDOR_EXT_ID;
		vendorExt.vendorData = buffobj_GetBuf(vendorExt_bufObj);
		vendorExt.dataLength = buffobj_Length(vendorExt_bufObj);
		tlv_vendorExtWrite(&vendorExt, bufObj);
	}

	/* Check copy back avaliable buf length */
	if (*buflen < buffobj_Length(bufObj)) {
		TUTRACE((TUTRACE_NFC, "nfc_utils_build_cfg: In buffer len too short\n"));
		ret = WPS_ERR_SYSTEM;
		goto error;
	}

	/* Copy back data and length */
	*buflen = buffobj_Length(bufObj);
	memcpy(buf, buffobj_GetBuf(bufObj), buffobj_Length(bufObj));

error:
	/* Free local vendorExt_bufObj */
	if (vendorExt_bufObj)
		buffobj_del(vendorExt_bufObj);

	/* Free local bufObj */
	if (bufObj)
		buffobj_del(bufObj);

	return ret;
}