ykoath icon indicating copy to clipboard operation
ykoath copied to clipboard

Add VALIDATE calls

Open ViViDboarder opened this issue 5 years ago • 9 comments

My Yubikey Neo is password protected and requires a call to validate the password before listing or performing other actions.

In order to make the magic numbers more readable I added all the ones I found on the Yubico site to constants.go.

Other smaller changes:

  • Export CALCULATE as CalculateOne and CALCULATE_ALL as CalculateAll
  • Add more error codes to codes.go

This is used as follows:

package main

import (
	"fmt"
	"git.iamthefij.com/iamthefij/slog"
	"github.com/yawn/ykoath"
	"golang.org/x/crypto/ssh/terminal"
	"syscall"
)

func main() {
	oath, err := ykoath.New()
	slog.FatalOnErr(err, "failed to initialize new oath")
	oath.Debug = slog.Debug

	defer oath.Close()

	s, err := oath.Select()
	slog.FatalOnErr(err, "failed to select oath")

	if s.Challenge != nil {
		fmt.Println("Passphrase? ")
		passphrase, err := terminal.ReadPassword(int(syscall.Stdin))
		slog.FatalOnErr(err, "failed reading passphrase")
		key := s.DeriveKey(string(passphrase))

		ok, err := oath.Validate(s, key)
		slog.FatalOnErr(err, "validation failed")
		if !ok {
			panic("could not validate")
		}
	}

	names, err := oath.List()
	slog.FatalOnErr(err, "failed to list names")

	for _, name := range names {
		slog.Log(name.Name)
	}

	otp, err := oath.Calculate(names[0].Name, ykoath.ErrorTouchCallback)
	slog.FatalOnErr(err, "Failed to retrieve otp")
	slog.Log(otp)
}

ViViDboarder avatar Dec 09 '20 22:12 ViViDboarder

Awesome PR @ViViDboarder, thanks a lot! Review will be done ~Monday.

yawn avatar Dec 10 '20 07:12 yawn

For some reason I started getting 8 digit codes where I was supposed to get 6. I didn't change anything so I wonder if it has something to do with drivers or a dependency. To resolve it, I implemented a similar solution to yubikey-manager

ViViDboarder avatar Dec 18 '20 20:12 ViViDboarder

Any chance of a review in the next week or so? I wrote a cli tool and an Alfred Workflow that depends on this. I can build and distribute binaries using replace in my go.mod for now, but it's easier for others to test and write patches if they can build directly.

ViViDboarder avatar Jan 04 '21 17:01 ViViDboarder

Yeah, sorry about that. I'll do the review today / in the afternoon.

yawn avatar Jan 07 '21 10:01 yawn

Hey @ViViDboarder - are the remaining issues clear? Should we proceed with this PR?

yawn avatar Feb 01 '21 17:02 yawn

Thanks @yawn. I'm still a little confused on errors, which I think are the only outstanding items.

The way I understand error handling in Go right now (it seems to change frequently) is that a class should do something like this:

package example

import (
    "errors"
    "fmt"
)

var (
    ErrSomethingNotFound = errors.New("thing not found")
)

func CalledError() error {
    err := maybeHasError()
    if err != nil {
        return fmt.Errorf("error in this thing: %w", err)
    }

    return nil
}

func FindThing(p string) error {
    var b bool
    b = isThingFound(p)
    if !b {
        return fmt.Errorf("error finding %p: %w", p, ErrSomethingNotFound)
    }

    return nil
}

This allows some using the module and function to handle errors from findThing by using the wraps.

package main

import (
    "errors"
    "fmt"

    "example"
)

func main() {
    err = example.FindThing("foo")
    if errors.Is(err, example.ErrSomethingNotFound) {
        fmt.Println("Thing wasn't found")
    } else {
        panic(err)
    }
}

I can definitely do this, but it would be inconsistent with some of the others. I can refactor those as well, but maybe in a different patch.

ViViDboarder avatar Feb 01 '21 19:02 ViViDboarder

As an alternative: just add the tests and I'll do the minor / cosmetic changes in your PR? Maybe easier?

yawn avatar Feb 02 '21 10:02 yawn

That works for me.

Regarding the tests, I can definitely write some, but I do not have a spare Yubikey to test with. It also looks like I'll need to implement the SET CODE instruction that sets up authentication if a full test is to be written so that auth can be enabled, validated, and disabled.

ViViDboarder avatar Feb 02 '21 17:02 ViViDboarder

I can totally live without SET CODE if you can substitute it with a ykman call. For the test environment that's fine. Spare Yubikey, hm - that's an issue of course :-)

yawn avatar Feb 02 '21 18:02 yawn