BOOL ValidateStringIdKeyW( LPCWSTR lpszDeviceStringId, LPCWSTR lpszDeviceStringKey, PBOOL pbWritable) { NDAS_ID_KEY_INFO info; ::ZeroMemory(&info, sizeof(NDAS_ID_KEY_INFO)); // check id length if (lpszDeviceStringId[NDAS_DEVICE_STRING_ID_LEN] != L'\0') { return FALSE; } // copy id for (DWORD i = 0; i < NDAS_DEVICE_STRING_ID_PARTS; ++i) { for (DWORD j = 0; j < NDAS_DEVICE_STRING_ID_PART_LEN; ++j) { info.serialNo[i][j] = static_cast<CHAR>(lpszDeviceStringId[i * NDAS_DEVICE_STRING_ID_PART_LEN + j]); } } if (NULL != lpszDeviceStringKey) { // check key length if (lpszDeviceStringKey[NDAS_DEVICE_STRING_KEY_LEN] != L'\0') { return FALSE; } // copy key for (DWORD i = 0; i < NDAS_DEVICE_STRING_KEY_LEN; ++i) { info.writeKey[i] = static_cast<CHAR>(lpszDeviceStringKey[i]); } } ::CopyMemory(info.key1, NDIDV1Key1, 8 * sizeof(CHAR)); ::CopyMemory(info.key2, NDIDV1Key2, 8 * sizeof(CHAR)); // // Only string id will be validated on its return and // write key is validated by info.bWritable // BOOL fSuccess = NdasIdKey_Decrypt(&info); if (NULL == lpszDeviceStringKey) { if (pbWritable) *pbWritable = FALSE; return fSuccess; } else { if (fSuccess && info.writable) { if (pbWritable) *pbWritable = TRUE; return TRUE; } else { if (pbWritable) *pbWritable = FALSE; return FALSE; } } }
BOOL ConvertStringIdToRealIdW( LPCWSTR lpszDeviceStringId, PNDAS_DEVICE_ID pDeviceId) { _ASSERTE(!::IsBadStringPtrW(lpszDeviceStringId,NDAS_DEVICE_STRING_ID_LEN + 1)); _ASSERTE(!::IsBadWritePtr(pDeviceId, sizeof(NDAS_DEVICE_ID))); NDAS_ID_KEY_INFO info; ::ZeroMemory(&info, sizeof(NDAS_ID_KEY_INFO)); // check id length if (lpszDeviceStringId[NDAS_DEVICE_STRING_ID_LEN] != L'\0') { return FALSE; } // copy id for (DWORD i = 0; i < NDAS_DEVICE_STRING_ID_PARTS; ++i) { for (DWORD j = 0; j < NDAS_DEVICE_STRING_ID_PART_LEN; ++j) { info.serialNo[i][j] = static_cast<CHAR>( lpszDeviceStringId[i * NDAS_DEVICE_STRING_ID_PART_LEN + j]); } } // fill required keys ::CopyMemory(info.key1, NDIDV1Key1, 8 * sizeof(CHAR)); ::CopyMemory(info.key2, NDIDV1Key2, 8 * sizeof(CHAR)); // try decrypt if (!NdasIdKey_Decrypt(&info)) { return FALSE; } // fill the output ::CopyMemory( pDeviceId->Node, info.address, sizeof(BYTE) * 6); return TRUE; }
void CMainDialog::OnCmdParse(UINT wNotifyCode, int wID, HWND hWndCtl) { NDAS_ID_KEY_INFO info = {0}; for (int i = 0; i < RTL_NUMBER_OF(m_wndAddresses); ++i) { m_wndAddresses[i].SetWindowText(_T("")); } C_ASSERT(RTL_NUMBER_OF(m_wndKeys1) == RTL_NUMBER_OF(info.key1)); for (int i = 0; i < RTL_NUMBER_OF(m_wndKeys1); ++i) { if (!pGetByteFromEdit(m_wndKeys1[i], info.key1[i])) { return; } } C_ASSERT(RTL_NUMBER_OF(m_wndKeys2) == RTL_NUMBER_OF(info.key2)); for (int i = 0; i < RTL_NUMBER_OF(m_wndKeys2); ++i) { if (!pGetByteFromEdit(m_wndKeys2[i], info.key2[i])) { return; } } for (int i = 0; i < 4; ++i) { TCHAR part[6] = {0}; m_wndNdasId[i].GetWindowText(part, 6); for (int j = 0; j < 5; ++j) { info.serialNo[i][j] = static_cast<char>(part[j]); } } if (!NdasIdKey_Decrypt(&info)) { m_wndNdasId[0].SetFocus(); m_wndNdasId[0].SetSel(0, -1); return; } for (int i = 0; i < RTL_NUMBER_OF(m_wndAddresses); ++i) { CString s = pBytesToString(&info.address[i], 1); m_wndAddresses[i].SetWindowText(s); } { CString s = pBytesToString(&info.vid, 1); m_wndVID.SetWindowText(s); } C_ASSERT(RTL_NUMBER_OF(m_wndReserved) == RTL_NUMBER_OF(info.reserved)); for (int i = 0; i < RTL_NUMBER_OF(m_wndReserved); ++i) { CString s = pBytesToString(&info.reserved[i], 1); m_wndReserved[i].SetWindowText(s); } { CString s = pBytesToString(&info.random, 1); m_wndSeed.SetWindowText(s); } m_wndSerialNumberDigit.SetWindowText(pGetSNDigitString(info.address)); }
// internal function BOOL WINAPI pNdasIdStringToDeviceA( __in LPCSTR NdasId, __in_opt LPCSTR WriteKey, __out_opt NDAS_DEVICE_ID* DeviceID, __in_opt const NDASID_EXT_KEY* ExtKey, __out_opt NDASID_EXT_DATA* ExtData) { // internal function validate parameters minimally. // // Decryption parameters: // // in: key1, key2, serialNo, writeKey // out: address, vid, random, reserved, writable // NDAS_ID_KEY_INFO ni = {0}; // // input parameters // if (NULL == ExtKey) { ExtKey = &NDASID_EXT_KEY_DEFAULT; } CopyMemory(ni.serialNo, NdasId, sizeof(ni.serialNo)); if (NULL != WriteKey && 0 != WriteKey[0]) { CopyMemory(ni.writeKey, WriteKey, sizeof(ni.writeKey)); } C_ASSERT_EQUALSIZE(ni.key1, ExtKey->Key1); CopyMemory(ni.key1, ExtKey->Key1, sizeof(ni.key1)); C_ASSERT_EQUALSIZE(ni.key2, ExtKey->Key2); CopyMemory(ni.key2, ExtKey->Key2, sizeof(ni.key2)); // // Decryption // if (!NdasIdKey_Decrypt(&ni)) { return SetLastError(NDAS_ERROR_INVALID_ID_FORMAT), FALSE; } // // Is Write Key valid? // if (WriteKey && WriteKey[0] && !ni.writable) { return SetLastError(NDAS_ERROR_INVALID_ID_FORMAT), FALSE; } #define NDASID_USE_SINGLE_MAPPING #ifdef NDASID_USE_SINGLE_MAPPING // // NDAS ID Encryption - Decryption Mapping Problem // // For a given, AAAA1-BBBB2-CCCC3-DDDD4, // other IDs which has incremented values of last digit of any part // are treated as same, e.g. AAAA1-BBBB3-CCCC4-DDDD4 generates the // same value as above. So is the write key. // // To prevent such anomalies, we should regenerate a string ID with // a generated device ID and re-compare to test a validity of the // given string ID. // // This means, even though there can be more than one string IDs // which map to a device ID, we ratify only a single ID, // that is generated from the device ID. // { NDAS_DEVICE_ID compDeviceID; NDASID_EXT_DATA compExtData; C_ASSERT_EQUALSIZE(compDeviceID.Node, ni.address); CopyMemory(compDeviceID.Node, ni.address, sizeof(ni.address)); compExtData.Seed = ni.random; compExtData.VID = ni.vid; C_ASSERT_EQUALSIZE(compExtData.Reserved, ni.reserved); CopyMemory(compExtData.Reserved, ni.reserved, sizeof(ni.reserved)); CHAR newNdasId[NDAS_DEVICE_STRING_ID_LEN + 1] = {0}; CHAR newWriteKey[NDAS_DEVICE_STRING_KEY_LEN + 1] = {0}; BOOL success = NdasIdDeviceToStringExA( &compDeviceID, newNdasId, newWriteKey, ExtKey, // constant &compExtData); if (!success) { _ASSERTE(FALSE); // should not fail! return FALSE; } // // We should compare both case-insensitively! // NdasIdDeviceToStringExA always returns capital letters // but lpszStringId may have mixed cases. // if (0 != lstrcmpiA(newNdasId, NdasId)) { return SetLastError(NDAS_ERROR_INVALID_ID_FORMAT), FALSE; } // check write key also, if given if (WriteKey && WriteKey [0] && 0 != lstrcmpiA(newWriteKey, WriteKey )) { return SetLastError(NDAS_ERROR_INVALID_ID_FORMAT), FALSE; } } #endif // // Copy outputs // if (NULL != DeviceID) { C_ASSERT_EQUALSIZE(DeviceID->Node, ni.address); CopyMemory(DeviceID->Node, ni.address, sizeof(ni.address)); } if (NULL != ExtData) { ExtData->Seed = ni.random; ExtData->VID = ni.vid; C_ASSERT_EQUALSIZE(ni.reserved, ExtData->Reserved); CopyMemory(ExtData->Reserved, ni.reserved, sizeof(ni.reserved)); } return TRUE; }