mirror of
https://github.com/status-im/keycard-go.git
synced 2025-02-22 00:28:21 +00:00
add FindTag utils function to parse TLV data
This commit is contained in:
parent
739696e6f9
commit
0c3a4d0c01
@ -4,12 +4,14 @@ import (
|
|||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"regexp"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func hexToBytes(s string) []byte {
|
func hexToBytes(s string) []byte {
|
||||||
|
s = regexp.MustCompile(" ").ReplaceAllString(s, "")
|
||||||
b := make([]byte, hex.DecodedLen(len(s)))
|
b := make([]byte, hex.DecodedLen(len(s)))
|
||||||
_, err := hex.Decode(b, []byte(s))
|
_, err := hex.Decode(b, []byte(s))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
61
apdu/utils.go
Normal file
61
apdu/utils.go
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
package apdu
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ErrTagNotFound struct {
|
||||||
|
tag uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *ErrTagNotFound) Error() string {
|
||||||
|
return fmt.Sprintf("tag %x not found", e.tag)
|
||||||
|
}
|
||||||
|
|
||||||
|
func FindTag(raw []byte, tags ...uint8) ([]byte, error) {
|
||||||
|
if len(tags) == 0 {
|
||||||
|
return raw, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
target := tags[0]
|
||||||
|
buf := bytes.NewBuffer(raw)
|
||||||
|
|
||||||
|
var (
|
||||||
|
tag uint8
|
||||||
|
length uint8
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
for {
|
||||||
|
tag, err = buf.ReadByte()
|
||||||
|
switch {
|
||||||
|
case err == io.EOF:
|
||||||
|
return []byte{}, &ErrTagNotFound{target}
|
||||||
|
case err != nil:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
length, err = buf.ReadByte()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
data := make([]byte, length)
|
||||||
|
if length != 0 {
|
||||||
|
_, err = buf.Read(data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if tag == target {
|
||||||
|
if len(tags) == 1 {
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return FindTag(data, tags[1:]...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
42
apdu/utils_test.go
Normal file
42
apdu/utils_test.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package apdu
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestFindTag(t *testing.T) {
|
||||||
|
var (
|
||||||
|
tagData []byte
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
data := hexToBytes("C1 02 BB CC C2 04 C3 02 11 22 C3 02 88 99")
|
||||||
|
|
||||||
|
tagData, err = FindTag(data, uint8(0xC1))
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, "BB CC", bytesToHexWithSpaces(tagData))
|
||||||
|
|
||||||
|
tagData, err = FindTag(data, uint8(0xC2))
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, "C3 02 11 22", bytesToHexWithSpaces(tagData))
|
||||||
|
|
||||||
|
tagData, err = FindTag(data, uint8(0xC3))
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, "88 99", bytesToHexWithSpaces(tagData))
|
||||||
|
|
||||||
|
tagData, err = FindTag(data, uint8(0xC2), uint8(0xC3))
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, "11 22", bytesToHexWithSpaces(tagData))
|
||||||
|
|
||||||
|
// tag not found
|
||||||
|
badData := hexToBytes("C1 00")
|
||||||
|
_, err = FindTag(badData, uint8(0xC2))
|
||||||
|
assert.Equal(t, &ErrTagNotFound{uint8(0xC2)}, err)
|
||||||
|
|
||||||
|
// sub-tag not found
|
||||||
|
badData = hexToBytes("C1 02 C2 00")
|
||||||
|
_, err = FindTag(badData, uint8(0xC1), uint8(0xC3))
|
||||||
|
assert.Equal(t, &ErrTagNotFound{uint8(0xC3)}, err)
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user