// LoadKeyStore attempts to load a keystore from the given path. If // the keystore doesn't exist, a new one is created with a // freshly-generated keys if the orNew argument is true. func LoadKeyStore(path string, orNew bool) (*KeyStore, bool) { data, err := ioutil.ReadFile(path) if err != nil && os.IsNotExist(err) && orNew { var priv *public.PrivateKey priv, err = public.GenerateKey() if err != nil { util.Errorf("Failed to generate key.") return nil, false } return NewPrivateKeyStore(priv) } else if err != nil { util.Errorf("%v", err) return nil, false } store := new(KeyStore) err = json.Unmarshal(data, store) if err != nil { util.Errorf("%v", err) return nil, false } if store.Keys == nil { store.Keys = map[string]*PublicKeyRecord{} } if store.PrivateKey != nil { store.locked = true } if !store.Valid(true) { util.Errorf("invalid keystore %v", store) return nil, false } return store, true }
// TestSessionSetup validates creating a new session and successful // validation of an OTP. func TestSessionSetup(t *testing.T) { var err error peerPrivate, err = public.GenerateKey() if err != nil { t.Fatalf("%v", err) } peer, err = public.MarshalPublic(peerPrivate.PublicKey) if err != nil { t.Fatalf("%v", err) } sessionAuth, sessionPub, err = NewSession(peer) if err != nil { t.Fatalf("%v", err) } newOTP := testCreateOTP(t) shouldUpdate, err := ValidateSession(sessionAuth, newOTP) if err != nil { t.Fatalf("%v", err) } if !shouldUpdate { t.Fatal("auth: ValidateSession should signal that an update is required") } }
// NewSession sets up a new session. The Last field should be sent // to the client. The returned public key should be sent to the // user for generating a shared MAC key. The authenticator should ensure // some mechanism for expiring sessions exists. func NewSession(pub []byte) (*Authenticator, []byte, error) { next := util.RandBytes(sessionLength) if next == nil { return nil, nil, errors.New("auth: PRNG failure") } ephemeral, err := public.GenerateKey() if err != nil || !ephemeral.Valid() { return nil, nil, errors.New("auth: failed to set up session key") } // Validated that the key was correct previously. ephemeralPublic, _ := public.MarshalPublic(ephemeral.PublicKey) peer, err := public.UnmarshalPublic(pub) if err != nil { return nil, nil, err } shared := public.KeyExchange(ephemeral, peer) return &Authenticator{ Type: TypeSession, Last: hex.EncodeToString(next), Secret: shared, }, ephemeralPublic, nil }