add keycard-set-pinless-path command

This commit is contained in:
Andrea Franz 2019-03-16 10:03:35 +01:00
parent 8809bfb0f5
commit 8537d3370d
No known key found for this signature in database
GPG Key ID: 4F0D2F2D9DE7F29D
3 changed files with 52 additions and 0 deletions

View File

@ -59,6 +59,7 @@ func NewShell(t globalplatform.Transmitter) *Shell {
"keycard-generate-key": s.commandKeycardGenerateKey,
"keycard-derive-key": s.commandKeycardDeriveKey,
"keycard-sign": s.commandKeycardSign,
"keycard-set-pinless-path": s.commandKeycardSetPinlessPath,
}
return s
@ -430,6 +431,20 @@ func (s *Shell) commandKeycardSign(args ...string) error {
return nil
}
func (s *Shell) commandKeycardSetPinlessPath(args ...string) error {
if err := s.requireArgs(args, 1); err != nil {
return err
}
logger.Info(fmt.Sprintf("set pinless path %s", args[0]))
if err := s.kCmdSet.SetPinlessPath(args[0]); err != nil {
logger.Error("set pinless path failed", "error", err)
return err
}
return nil
}
func (s *Shell) requireArgs(args []string, possibleArgsN ...int) error {
for _, n := range possibleArgsN {
if len(args) == n {

View File

@ -196,6 +196,16 @@ func (cs *CommandSet) DeriveKey(path string) error {
return cs.checkOK(resp, err)
}
func (cs *CommandSet) SetPinlessPath(path string) error {
cmd, err := NewCommandDeriveKey(path)
if err != nil {
return err
}
resp, err := cs.sc.Send(cmd)
return cs.checkOK(resp, err)
}
func (cs *CommandSet) Sign(data []byte) (*types.Signature, error) {
cmd, err := NewCommandSign(data)
if err != nil {

View File

@ -20,6 +20,7 @@ const (
InsVerifyPIN = uint8(0x20)
InsDeriveKey = uint8(0xD1)
InsSign = uint8(0xC0)
InsSetPinlessPath = uint8(0xC1)
P1PairingFirstStep = uint8(0x00)
P1PairingFinalStep = uint8(0x01)
@ -144,6 +145,32 @@ func NewCommandDeriveKey(pathStr string) (*apdu.Command, error) {
), nil
}
func NewCommandSetPinlessPath(pathStr string) (*apdu.Command, error) {
startingPoint, path, err := derivationpath.Decode(pathStr)
if err != nil {
return nil, err
}
if startingPoint != derivationpath.StartingPointMaster {
return nil, fmt.Errorf("pinless path must be set with an absolute path")
}
data := new(bytes.Buffer)
for _, segment := range path {
if err := binary.Write(data, binary.BigEndian, segment); err != nil {
return nil, err
}
}
return apdu.NewCommand(
globalplatform.ClaGp,
InsSetPinlessPath,
uint8(0),
uint8(0),
data.Bytes(),
), nil
}
func NewCommandSign(data []byte) (*apdu.Command, error) {
if len(data) != 32 {
return nil, fmt.Errorf("data length must be 32, got %d", len(data))