mirror of
https://github.com/status-im/keycard-go.git
synced 2025-02-21 08:08:07 +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"
|
||||
"fmt"
|
||||
"log"
|
||||
"regexp"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func hexToBytes(s string) []byte {
|
||||
s = regexp.MustCompile(" ").ReplaceAllString(s, "")
|
||||
b := make([]byte, hex.DecodedLen(len(s)))
|
||||
_, err := hex.Decode(b, []byte(s))
|
||||
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