js-rockeyarm
Version:
A javascript library for Feitian ROCKEY ARM dongle.
593 lines (522 loc) • 24.4 kB
JavaScript
import { platform, arch, cwd} from 'process'
import { dirname } from 'path'
import { Library as ffi_Library } from 'ffi-napi'
import {stringToByte, bytesToString, hexToBytes} from './convert.js'
import {rockeyInterface, ptrDongleInfo, ptrInt, ptrByte, ptrHandle, ptrUint, dataFileAttr} from './functions.js'
//
function genResult(retcode, info, msg, returnParam){
return { errorCode: retcode, result: info, message: msg, param: returnParam }
}
function genDongleInfoItem(versionL, versionR, type, userId, hardwareIdL, hardwareIdR, productId, isMother, devType){
var typeList = {0 : 'ROCKEY-ARM TIME', 2 : 'StoreROCKEY-ARM', 255 : 'ROCKEY-ARM'}
var motherTypeList = {0 : 'New Dongle', 1 : 'Master Dongle', 2 : 'User Dongle'}
var devTypeList = {0 : 'HID Device', 1 : 'Smart Card Device'}
return {
version: versionR.toString()+'.'+versionL.toString(),
type: typeList[type],
birthday: '',
userId: userId.toString(16).toUpperCase(),
hardwareId: hardwareIdR.toString(16).toUpperCase() + hardwareIdL.toString(16).toUpperCase(),
productId: productId.toString(16).toUpperCase(),
isMother: motherTypeList[isMother],
devType: devTypeList[devType]
}
}
function structToByteArray(struct){
var i = 0
var buffer = struct.ref()
var byteArray = new ptrByte(buffer.length)
for (i=0; i<buffer.length; i++){
byteArray[i] = buffer[i]
}
return byteArray
}
function getByteFromByteArray(buffer){
var i = 0
var str = ''
var s = ''
for(i=0; i<buffer.length; i++){
s = buffer[i].toString(16).toUpperCase()
if (s.length === 1) { //转成16进制后补零
s = '0' + s
}
str = str + s
}
return str
}
function getByteArrayFromString(str, flag){
var i = 0
var len
var byte = stringToByte(str)
if (flag === undefined) {
len = byte.length
} else {
len = byte.length + 1
}
var byteArray = new ptrByte(len)
byteArray[len-1] = 0
for(i = 0; i < len; i++){
byteArray[i] = byte[i]
}
return byteArray
}
function getByteArrayFromBytes(bytes){
var byteArray = new ptrByte(bytes.length)
for(var i=0; i<bytes.length; i++){
byteArray[i] = bytes[i]
}
return byteArray
}
function getFileAttr(fileType, fileAttr){
var dataAttr = new dataFileAttr(1)
if (fileType === 1) {
dataAttr.m_Size = fileAttr.size
dataAttr.m_Read_Priv = fileAttr.readPriv
dataAttr.m_Write_Priv = fileAttr.writePriv
return dataAttr
}
}
var RockeyArm = /** @class */ (function(){ //-class start
var ret = 0
function RockeyArm(){
this.productId = 'FFFFFFFF'
this.handle = 0
this.result = 0
this.handle = null
if (platform === 'win32' && arch === 'x64'){
this.libFilePath = cwd() + '\\lib\\x64\\Dongle_d.dll'
} else if (platform === 'linux' && arch === 'x64') {
this.libFilePath = cwd() + '/lib/x64/libRockeyARM.so.0.3'
}
this.libRockey = new ffi_Library(this.libFilePath, rockeyInterface)
}
RockeyArm.prototype.Enum = function(){
var piCount = new ptrInt(1)
ret = this.libRockey.Dongle_Enum(null, piCount)
if(ret !== 0 || piCount[0] < 1){
return genResult(ret, 'failed','Found 0 ROCKEY-ARM dongle.', null)
}
var DongleList = new ptrDongleInfo(piCount[0])
ret = this.libRockey.Dongle_Enum(DongleList, piCount)
if (ret !== 0) {
return genResult(ret, 'failed','Found 0 ROCKEY-ARM dongle.', null)
}
var i
var list = []
var item
for (i=0; i< piCount[0]; i++) {
item = genDongleInfoItem(
DongleList[i].m_VerL,
DongleList[i].m_VerR,
DongleList[i].m_Type,
DongleList[i].m_UserID,
DongleList[i].m_HIDL,
DongleList[i].m_HIDR,
DongleList[i].m_PID,
DongleList[i].m_IsMother,
DongleList[i].m_DevType
)
list.push(JSON.stringify(item))
}
return genResult(ret, 'success','Enum ROCKEY-ARM.', list)
}
RockeyArm.prototype.Open = function(index){
var pHandle = new ptrHandle(1)
ret = this.libRockey.Dongle_Open(pHandle, index)
if (ret !== 0) {
return genResult(ret, 'failed','Open ROCKEY-ARM dongle.', null)
}
this.handle = pHandle[0]
return genResult(ret, 'success','Open ROCKEY-ARM dongle.', null)
}
RockeyArm.prototype.ResetState = function() {
ret = this.libRockey.Dongle_ResetState(this.handle)
if(ret !== 0){
return genResult(ret, 'failed', 'Reset state.', null)
}
return genResult(ret, 'success', 'Reset state.', null)
}
RockeyArm.prototype.Close = function(){
ret = this.libRockey.Dongle_Close(this.handle)
if(ret !== 0) {
return genResult(ret, 'failed','Close ROCKEY-ARM dongle.', null)
}
this.handle = null
return genResult(ret, 'success','Close ROCKEY-ARM', null)
}
RockeyArm.prototype.GenRandom = function(len) {
var buffer = new ptrByte(len)
ret = this.libRockey.Dongle_GenRandom(this.handle, len, buffer)
if(ret !== 0) {
return genResult(ret, 'failed','Generate random.', null)
}
return genResult(ret, 'success','Generate random', {random: getByteFromByteArray(buffer)})
}
RockeyArm.prototype.LEDControl = function(flag){
ret = this.libRockey.Dongle_LEDControl(this.handle, flag)
if(ret !== 0) {
return genResult(ret, 'failed', 'Control LED', null)
}
return genResult(ret, 'success', 'Control LED', null)
}
RockeyArm.prototype.SwitchProtocol = function(flag){
ret = this.libRockey.Dongle_SwitchProtocol(this.handle, flag)
if(ret !== 0) {
return genResult(ret, 'failed', 'Switch device transmit protocol', null)
}
return genResult(ret, 'success', 'Switch device transmit protocol', null)
}
RockeyArm.prototype.RFS = function(){
ret = this.libRockey.Dongle_RFS(this.handle)
if(ret !== 0) {
return genResult(ret, 'failed', 'Restore factory setting', null)
}
return genResult(ret, 'success', 'Restore factory setting', null)
}
RockeyArm.prototype.CreateFile = function(fileType, fileId, fileAttr){
var attr = getFileAttr(fileType, fileAttr)
var bufAttr = structToByteArray(attr)
ret = this.libRockey.Dongle_CreateFile(this.handle, fileType, fileId, bufAttr)
if(ret !== 0) {
return genResult(ret, 'failed','Create file.', null)
}
return genResult(ret, 'success','Create file', null)
}
RockeyArm.prototype.WriteFile = function (fileType, fileId, offset, inData, dataLen){
var buffer = getByteArrayFromString(inData)
ret = this.libRockey.Dongle_WriteFile(this.handle, fileType, fileId, offset, buffer, dataLen)
if(ret !== 0) {
return genResult(ret, 'failed','Write file.', null)
}
return genResult(ret, 'success','Write file', null)
}
RockeyArm.prototype.ReadFile = function (fileId, offset, dataLen){
var buffer = new ptrByte(dataLen)
ret = this.libRockey.Dongle_ReadFile(this.handle, fileId, offset, buffer, dataLen)
if(ret !== 0) {
return genResult(ret, 'failed','Read file.', null)
}
return genResult(ret, 'success','Read file', null)
}
RockeyArm.prototype.DownloadExeFile = function () {
}
RockeyArm.prototype.RunExeFile = function (fileId, inBuffer, inOutLen) {
var temp = inBuffer
if (inOutLen * 2 > inBuffer.length ) {
for(var i = inBuffer.length; i < inOutLen*2; i++){
temp = temp + '0'
}
}
var buffer = getByteArrayFromString(temp)
var mainRet = new ptrInt(1)
ret = this.libRockey.Dongle_RunExeFile(this.handle, fileId, buffer, inOutLen, mainRet)
if(ret !== 0) {
return genResult(ret, 'failed','Run execute file.', null)
}
return genResult(ret, 'success','Run execute file', {retCode: mainRet[0], outBuffer: getByteFromByteArray(buffer)})
}
RockeyArm.prototype.DeleteFile = function (fileType, fileId) {
var ret = this.libRockey.Dongle_DeleteFile(this.handle, fileType, fileId)
if(ret !== 0) {
return genResult(ret, 'failed','Delete file.', null)
}
return genResult(ret, 'success','Delete file', null)
}
RockeyArm.prototype.ListFile = function (fileType, len) {
//var dataFileListSize = 12
var dataLen = new ptrInt(1)
dataLen[0] = 1//小于等于0回报参数错误
if (len === undefined) {
ret = this.libRockey.Dongle_ListFile(this.handle, fileType, null, dataLen)
if(ret !== 0) {
return genResult(ret, 'failed','Enum file.', null)
}
return genResult(ret, 'success','Enum file', {dataLen: dataLen[0]})
}
dataLen[0] = len
//var dataList = new ptrDataFileList(1)
var dataList = new ptrByte(len)
ret = this.libRockey.Dongle_ListFile(this.handle, fileType, dataList, dataLen)
if(ret !== 0) {
return genResult(ret, 'failed','Enum file.', null)
}
return genResult(ret, 'success','Enum file', {dataLen: getByteFromByteArray(dataList)}) //这个地方应该解析一下返回的结构体成json
}
RockeyArm.prototype.GenUniqueKey = function (seedLen, seed) {
var byteSeed = getByteArrayFromBytes(seed)
var bytePid = new ptrByte(8)
var byteAdminPin = new ptrByte(16)
ret = this.libRockey.Dongle_GenUniqueKey(this.handle, seedLen, byteSeed, bytePid, byteAdminPin)
if(ret !== 0) {
return genResult(ret, 'failed','Generate unique key.', null)
}
return genResult(ret, 'success','Generate unique key', {productId: bytesToString(bytePid.buffer), adminPIN: bytesToString(byteAdminPin.buffer)})
}
RockeyArm.prototype.VerifyPIN = function(flag, Pin){
var arrayPin = getByteArrayFromString(Pin, 'endmark')
var remainCount = new ptrInt(1)
ret = this.libRockey.Dongle_VerifyPIN(this.handle, flag, arrayPin, remainCount)
if (ret !== 0) {
return genResult(ret, 'failed','Verify PIN.', {retryTimes: remainCount[0]})
}
return genResult(ret, 'success','Verify PIN.', {retryTimes: remainCount[0]})
}
RockeyArm.prototype.ChangePIN = function(flag, oldPin, newPin, tryCount){
var byteOldPin = getByteArrayFromString(oldPin, 'endmark')
var byteNewPin = getByteArrayFromString(newPin, 'endmark')
ret = this.libRockey.Dongle_ChangePIN(this.handle, byteOldPin, byteNewPin, tryCount)
if (ret !== 0) {
return genResult(ret, 'failed','Change PIN.', null)
}
return genResult(ret, 'success','Change PIN.', null)
}
RockeyArm.prototype.ResetUserPIN = function(adminPin) {
var byteAdminPin = getByteArrayFromString(adminPin, 'endmark')
ret = this.libRockey.Dongle_ResetUserPIN(this.handle, byteAdminPin)
if (ret !== 0) {
return genResult(ret, 'failed','Reset user PIN.', null)
}
return genResult(ret, 'success','Reset user PIN.', null)
}
RockeyArm.prototype.SetUserID = function(userId) {
ret = this.libRockey.Dongle_SetUserID(userId)
if (ret !== 0) {
return genResult(ret, 'failed','Set user ID.', null)
}
return genResult(ret, 'success','Set user ID.', null)
}
RockeyArm.prototype.GetDeadline = function() {
var intTime = new ptrUint(1)
ret = this.libRockey.Dongle_GetDeadline(this.handle, intTime)
if (ret !== 0) {
return genResult(ret, 'failed','Get deadline.', null)
}
var strType = ''
var strTime = ''
if (intTime[0] === 0xFFFFFFFF) {
strType = 'NoLimit'
} else if ((intTime[0] & 0xFFFF0000) === 0 ) {
strType = 'RemainHour'
strTime = intTime[0].toString(10)
} else {
strType = 'ExpirationDate'
var date = new Date(intTime[0] * 1000)
strTime = date.toUTCString()
}
return genResult(ret, 'success','Get deadline.', {type: strType, deadline: strTime, rawTimestamp: intTime[0]})
}
RockeyArm.prototype.SetDeadline = function(deadline) {
var intTime
if (deadline.type === 'hours') {
intTime = deadline.time
} else if (deadline.type === 'timestamp'){
intTime = deadline.time / 1000
} else if (deadline.type === 'nolimit') {
intTime = 0
}
ret = this.libRockey.Dongle_SetDeadline(this.handle, intTime)
if (ret !== 0) {
return genResult(ret, 'failed','Get deadline.', null)
}
return genResult(ret, 'success','Get deadline.', null)
}
RockeyArm.prototype.GetUTCTime = function() {
var intTime = new ptrUint(1)
ret = this.libRockey.Dongle_GetUTCTime(this.handle, intTime)
if (ret !== 0) {
return genResult(ret, 'failed','Get UTC time in dongle.', null)
}
var date = new Date(intTime[0] * 1000)
var strTime = date.toUTCString()
return genResult(ret, 'success','Get UTC time in dongle.', {utctime: strTime})
}
RockeyArm.prototype.ReadData = function(offset, dataLen) {
var buffer = new ptrByte(dataLen)
ret = this.libRockey.Dongle_ReadData(this.handle, offset, buffer, dataLen)
if (ret !== 0) {
return genResult(ret, 'failed','Read data zone.', null)
}
return genResult(ret, 'success','Read data zone.', {data : getByteFromByteArray(buffer)})
}
RockeyArm.prototype.WriteData = function(offset, data, dataLen) {
var byteBuffer = getByteArrayFromBytes(hexToBytes(data))
ret = this.libRockey.Dongle_WriteData(this.handle, offset, byteBuffer, dataLen)
if (ret !== 0) {
return genResult(ret, 'failed','Write data zone.', null)
}
return genResult(ret, 'success','Write data zone.', null)
}
RockeyArm.prototype.ReadShareMemory = function() {
var buffer = new ptrByte(32)
ret = this.libRockey.Dongle_ReadShareMemory(this.handle, buffer)
if (ret !== 0) {
return genResult(ret, 'failed','Read share memory.', null)
}
return genResult(ret, 'success','Read share memory.', {data : getByteFromByteArray(buffer)})
}
RockeyArm.prototype.WriteShareMemory = function(data) {
var byteBuffer = getByteArrayFromBytes(hexToBytes(data))
ret = this.libRockey.Dongle_WriteShareMemory(this.handle, byteBuffer, 32) //写入数据长度必须固定32,文档中说小于32,其实只能等于32
if (ret !== 0) {
return genResult(ret, 'failed','Write share memory.', null)
}
return genResult(ret, 'success','Write share memory.', null)
}
RockeyArm.prototype.RsaGenPubPriKey = function(priFileId) {
var byteRsaPubKey = new ptrByte(264)
var byteRsaPriKey = new ptrByte(520)
ret = this.libRockey.Dongle_RsaGenPubPriKey(this.handle, priFileId, byteRsaPubKey, byteRsaPriKey)
if (ret !== 0) {
return genResult(ret, 'failed','Generate RSA key pairs.', null)
}
return genResult(ret, 'success','Generate RSA key pairs.', {publicKey: getByteFromByteArray(byteRsaPubKey), privateKey: getByteFromByteArray(byteRsaPriKey)})
}
RockeyArm.prototype.RsaPri = function(priFileId, flag, inData, inDataLen) {
var byteInData = getByteArrayFromBytes(hexToBytes(inData))
var byteOutData = new ptrByte(256)
var ptrIntOutDataLen = new ptrInt(1)
ptrIntOutDataLen[0] = 256
ret = this.libRockey.Dongle_RsaPri(this.handle, priFileId, flag, byteInData, inDataLen, byteOutData, ptrIntOutDataLen)
if (ret !== 0) {
return genResult(ret, 'failed','Calculate RSA private key.', null)
}
return genResult(ret, 'success','Calculate RSA private key.', {result: getByteFromByteArray(byteOutData), len: ptrIntOutDataLen[0]})
}
RockeyArm.prototype.RsaPub = function(flag, pubKey, inData, inDataLen) {
var byteInData = getByteArrayFromBytes(hexToBytes(inData))
var bytePubKey = getByteArrayFromBytes(hexToBytes(pubKey))
var byteOutData = new ptrByte(256)
var ptrIntOutDataLen = new ptrInt(1)
ptrIntOutDataLen[0] = 256
ret = this.libRockey.Dongle_RsaPub(this.handle, flag, bytePubKey, byteInData, inDataLen, byteOutData, ptrIntOutDataLen)
if (ret !== 0) {
return genResult(ret, 'failed','Calculate RSA public key.', null)
}
return genResult(ret, 'success','Calculate RSA public key.', {result: getByteFromByteArray(byteOutData), len: ptrIntOutDataLen[0]})
}
RockeyArm.prototype.EccGenPubPriKey = function(priFileId) {
var byteEccPubKey = new ptrByte(68)
var byteEccPriKey = new ptrByte(36)
ret = this.libRockey.Dongle_EccGenPubPriKey(this.handle, priFileId, byteEccPubKey, byteEccPriKey)
if (ret !== 0) {
return genResult(ret, 'failed','Generate ECC key pairs.', null)
}
return genResult(ret, 'success','Generate ECC key pairs.', {publicKey: getByteFromByteArray(byteEccPubKey), privateKey: getByteFromByteArray(byteEccPriKey)})
}
RockeyArm.prototype.EccSign = function(priFileId, hashData, hashDataLen) {
var byteHashData = getByteArrayFromBytes(hexToBytes(hashData))
var byteOutData = new ptrByte(64)
ret = this.libRockey.Dongle_EccSign(this.handle, priFileId, byteHashData, hashDataLen, byteOutData)
if (ret !== 0) {
return genResult(ret, 'failed','ECC sign.', null)
}
return genResult(ret, 'success','ECC sign.', {signature: getByteFromByteArray(byteOutData)})
}
RockeyArm.prototype.EccVerify = function(pubKey, hashData, hashDataLen, sign) {
var bytePubKey = getByteArrayFromBytes(hexToBytes(pubKey))
var byteHashData = getByteArrayFromBytes(hexToBytes(hashData))
var byteSign = getByteArrayFromBytes(hexToBytes(sign))
ret = this.libRockey.Dongle_EccVerify(this.handle, bytePubKey, byteHashData, hashDataLen, byteSign)
if (ret !== 0) {
return genResult(ret, 'failed','Verify ECC signature.', null)
}
return genResult(ret, 'success','Verify ECC signature.', null)
}
RockeyArm.prototype.SM2GenPubPriKey = function(priFileId) {
var byteEccPubKey = new ptrByte(68)
var byteEccPriKey = new ptrByte(36)
ret = this.libRockey.Dongle_SM2GenPubPriKey(this.handle, priFileId, byteEccPubKey, byteEccPriKey)
if (ret !== 0) {
return genResult(ret, 'failed','Generate Chinese Guomi SM2 key pairs.', null)
}
return genResult(ret, 'success','Generate Chinese Guomi SM2 key pairs.', {publicKey: getByteFromByteArray(byteEccPubKey), privateKey: getByteFromByteArray(byteEccPriKey)})
}
RockeyArm.prototype.SM2Sign = function(priFileId, hashData, hashDataLen) {
var byteHashData = getByteArrayFromBytes(hexToBytes(hashData))
var byteOutData = new ptrByte(64)
ret = this.libRockey.Dongle_SM2Sign(this.handle, priFileId, byteHashData, hashDataLen, byteOutData)
if (ret !== 0) {
return genResult(ret, 'failed','SM2 sign.', null)
}
return genResult(ret, 'success','SM2 sign.', {signature: getByteFromByteArray(byteOutData)})
}
RockeyArm.prototype.SM2Verify = function(pubKey, hashData, hashDataLen, sign) {
var bytePubKey = getByteArrayFromBytes(hexToBytes(pubKey))
var byteHashData = getByteArrayFromBytes(hexToBytes(hashData))
var byteSign = getByteArrayFromBytes(hexToBytes(sign))
ret = this.libRockey.Dongle_SM2Verify(this.handle, bytePubKey, byteHashData, hashDataLen, byteSign)
if (ret !== 0) {
return genResult(ret, 'failed','Verify SM2 signature.', null)
}
return genResult(ret, 'success','Verify SM2 signature.', null)
}
RockeyArm.prototype.TDES = function(keyFileId, flag, inData, dataLen) {
var byteInData = getByteArrayFromBytes(hexToBytes(inData))
var byteOutData = new ptrByte(dataLen)
ret = this.libRockey.Dongle_TDES(this.handle, keyFileId, flag, byteInData, byteOutData, dataLen)
if (ret != 0) {
return genResult(ret, 'failed', 'Calculate Triple DES.', null)
}
return genResult(ret, 'success', 'Calculate Triple DES.', {result: getByteFromByteArray(byteOutData)})
}
RockeyArm.prototype.SM4 = function(keyFileId, flag, inData, dataLen) {
var byteInData = getByteArrayFromBytes(hexToBytes(inData))
var byteOutData = new ptrByte(dataLen)
ret = this.libRockey.Dongle_SM4(this.handle, keyFileId, flag, byteInData, byteOutData, dataLen)
if (ret != 0) {
return genResult(ret, 'failed', 'Calculate SM4.', null)
}
return genResult(ret, 'success', 'Calculate SM4.', {result: getByteFromByteArray(byteOutData)})
}
RockeyArm.prototype.HASH = function(flag, inData, dataLen) {
var byteInData = getByteArrayFromBytes(hexToBytes(inData))
var len = 0
if(flag === 0) {
len = 16
} else if (flag === 1) {
len = 20
} else {
len = 32
}
var byteHashData = new ptrByte(len)
ret = this.libRockey.Dongle_HASH(this.handle, flag, byteInData, dataLen, byteHashData)
if (ret != 0) {
return genResult(ret, 'failed', 'Calculate hash.', null)
}
return genResult(ret, 'success', 'Calculate hash.', {result: getByteFromByteArray(byteHashData)})
}
RockeyArm.prototype.Seed = function(seed, seedLen) {
var byteSeed = getByteArrayFromBytes(hexToBytes(seed))
var byteOutData = new ptrByte(16)
ret = this.libRockey.Dongle_Seed(this.handle, byteSeed, seedLen, byteOutData)
if (ret != 0) {
return genResult(ret, 'failed', 'Calculate seed.', null)
}
return genResult(ret, 'success', 'Calculate seed.', {result: getByteFromByteArray(byteOutData)})
}
RockeyArm.prototype.LimitSeedCount = function(count) {
ret = this.libRockey.Dongle_LimitSeedCount(this.handle, count)
if (ret != 0) {
return genResult(ret, 'failed', 'Set seed limit count', null)
}
return genResult(ret, 'success', 'Set seed limit count', null)
}
RockeyArm.prototype.GenMotherKey = function(motherData) {
}
RockeyArm.prototype.RequestInit = function() {
}
RockeyArm.prototype.GetInitDataFromMother = function(request, dataLen) {
}
RockeyArm.prototype.InitSon = function(initData, dataLen) {
}
RockeyArm.prototype.SetUpdatePriKey = function(priKey) {
}
RockeyArm.prototype.MakeUpdatePacket = function(inData) {
}
RockeyArm.prototype.MakeUpdatePacketFromMother = function(inData) {
}
RockeyArm.prototype.Update = function(updateData, dataLen) {
}
return RockeyArm
}()) //-class end
export {RockeyArm}