-
Notifications
You must be signed in to change notification settings - Fork 13
Open
Description
Hi, thanks for the amazing work, I am facing an issue while setting up capability container, I have followed your article on medium however when I try to set it then it becomes read only and I see No ndef data populated but I see url in ndef file contents and my url does not work while scanning here is the code. Please throw some light on this, thanks.
private fun runWorkerCC() {
val worker = Thread(Runnable {
var success = false
try {
dnaC = DnaCommunicator()
try {
dnaC!!.setTransceiver { bytesToSend -> isoDep!!.transceive(bytesToSend) }
} catch (npe: java.lang.NullPointerException) {
return@Runnable
}
dnaC!!.setLogger { info ->
}
dnaC!!.beginCommunication()
// authentication
var isLrpAuthenticationMode = false
success = AESEncryptionMode.authenticateEV2(dnaC, ACCESS_KEY0, FACTORY_KEY)
if (success) {
} else {
// if the returnCode is '919d' = permission denied the tag is in LRP mode authentication
if (dnaC!!.lastCommandResult.status2 === PERMISSION_DENIED) {
// try to run the LRP authentication
success = LRPEncryptionMode.authenticateLRP(dnaC, ACCESS_KEY0, FACTORY_KEY)
if (success) {
isLrpAuthenticationMode = true
} else {
return@Runnable
}
} else {
return@Runnable
}
}
// write CC to file 01
try {
WriteData.run(dnaC, CC_FILE_NUMBER, NDEF_FILE_01_CAPABILITY_CONTAINER_R, 0)
} catch (e: IOException) {
return@Runnable
}
// public static final byte[] NDEF_FILE_01_CAPABILITY_CONTAINER_R = Utils.hexStringToByteArray("000F55555A00340406E104010000FF"); // Free Read Access only, no Write Access
// get the file settings
var fileSettings01: FileSettings? = null
try {
fileSettings01 = GetFileSettings.run(dnaC, CC_FILE_NUMBER)
} catch (e: java.lang.Exception) {
}
if (fileSettings01 == null) {
return@Runnable
}
fileSettings01.readPerm = ACCESS_EVERYONE
// write the file setings
try {
ChangeFileSettings.run(dnaC, CC_FILE_NUMBER, fileSettings01)
} catch (e: IOException) {
return@Runnable
}
// get File Settings for File 2 to get the key number necessary for writing (key 0 or key 2 ?)
var fileSettings02: FileSettings? = null
try {
fileSettings02 = GetFileSettings.run(dnaC, NDEF_FILE_NUMBER)
} catch (e: java.lang.Exception) {
}
if (fileSettings02 == null) {
return@Runnable
}
val ACCESS_KEY_RW = fileSettings02.readWritePerm
val ACCESS_KEY_CAR =
fileSettings02.changePerm // we do need this information later when changing the file settings
// in fabric settings or after unset the RW Access Key is 'Eh' = 14 meaning free read and write access
// we have to skip an authentication with this key as it does not exist !
if (ACCESS_KEY_RW == 14) {
// do nothing, skip authentication
} else {
if (ACCESS_KEY_RW != ACCESS_KEY0) {
success = if (!isLrpAuthenticationMode) {
AESEncryptionMode.authenticateEV2(dnaC, ACCESS_KEY_RW, FACTORY_KEY)
} else {
LRPEncryptionMode.authenticateLRP(dnaC, ACCESS_KEY_RW, FACTORY_KEY)
}
if (!success) {
return@Runnable
}
}
}
val sdmSettings = SDMSettings()
sdmSettings.sdmEnabled =
true // at this point we are just preparing the templated but do not enable the SUN/SDM feature
sdmSettings.sdmMetaReadPerm = ACCESS_KEY3 // Set to a key to get encrypted PICC data
sdmSettings.sdmFileReadPerm =
ACCESS_KEY4 // Used to create the MAC and Encrypted File data
sdmSettings.sdmReadCounterRetrievalPerm = ACCESS_NONE // Not sure what this is for
sdmSettings.sdmOptionEncryptFileData = true
var ndefRecord: ByteArray? = null
val master = NdefTemplateMaster()
master.usesLRP = isLrpAuthenticationMode
master.fileDataLength =
32 // encrypted file data available. The timestamp is 19 bytes long, but we need multiples of 16 for this feature
sdmSettings.sdmOptionUid = true
sdmSettings.sdmOptionReadCounter = true
ndefRecord = master.generateNdefTemplateFromUrlString(
"https://verify.abcd.com/tag?picc_data={PICC}&enc={FILE}&cmac={MAC}",
sdmSettings
)
uid.value = byteArrayToHexString(GetCardUid.run(dnaC))
try {
WriteData.run(dnaC, NDEF_FILE_NUMBER, ndefRecord, 0)
} catch (e: IOException) {
return@Runnable
}
//System.out.println("*** NdefRecord: " + new String(ndefRecord, StandardCharsets.UTF_8));
// write the timestamp data (19 characters long + 5 characters '#1234'
val fileData: ByteArray =
(getTimestampLog() + "#1234").toByteArray(
StandardCharsets.UTF_8
)
try {
if (isLrpAuthenticationMode) {
WriteData.run(
dnaC,
NDEF_FILE_NUMBER,
fileData,
(87 + 16)
) // LRP Encrypted PICC data is 16 bytes longer
} else {
WriteData.run(dnaC, NDEF_FILE_NUMBER, fileData, 87)
}
} catch (e: IOException) {
return@Runnable
}
// check if we authenticated with the right key - to change the key settings we need the CAR key
if (ACCESS_KEY_CAR != ACCESS_KEY_RW) {
success = if (!isLrpAuthenticationMode) {
AESEncryptionMode.authenticateEV2(dnaC, ACCESS_KEY_CAR, FACTORY_KEY)
} else {
LRPEncryptionMode.authenticateLRP(dnaC, ACCESS_KEY_CAR, FACTORY_KEY)
}
if (!success) {
return@Runnable
}
}
// change the auth key settings
fileSettings02.sdmSettings = sdmSettings
fileSettings02.readWritePerm = ACCESS_KEY2
fileSettings02.changePerm = ACCESS_KEY0
fileSettings02.readPerm = ACCESS_KEY2
fileSettings02.writePerm = ACCESS_KEY2
try {
ChangeFileSettings.run(dnaC, NDEF_FILE_NUMBER, fileSettings02)
} catch (e: IOException) {
e.printStackTrace()
return@Runnable
}
} catch (e: IOException) {
}
vibrateShort(context)
})
worker.start()
}
Metadata
Metadata
Assignees
Labels
No labels