1// Copyright 2019 Keybase Inc. All rights reserved.
2// Use of this source code is governed by a BSD
3// license that can be found in the LICENSE file.
4
5package idutil
6
7import (
8	"context"
9
10	"github.com/keybase/client/go/kbfs/kbfscrypto"
11	kbname "github.com/keybase/client/go/kbun"
12	"github.com/keybase/client/go/libkb"
13	"github.com/keybase/client/go/protocol/keybase1"
14)
15
16// GetCurrentSessionIfPossible returns the current username and UID
17// from kbpki.GetCurrentSession.  If sessionNotRequired is true
18// NoCurrentSessionError is ignored and empty username and uid will be
19// returned. If it is false all errors are returned.
20func GetCurrentSessionIfPossible(
21	ctx context.Context, kbpki CurrentSessionGetter, sessionNotRequired bool) (
22	SessionInfo, error) {
23	session, err := kbpki.GetCurrentSession(ctx)
24	if err == nil {
25		return session, nil
26	}
27	// Return all errors if a session is required.
28	if !sessionNotRequired {
29		return SessionInfo{}, err
30	}
31
32	// If not logged in, return empty session.
33	if _, notLoggedIn := err.(NoCurrentSessionError); notLoggedIn {
34		return SessionInfo{}, nil
35	}
36
37	// Otherwise, just return the error.
38	return SessionInfo{}, err
39}
40
41// SessionInfoFromProtocol returns SessionInfo from Session
42func SessionInfoFromProtocol(session keybase1.Session) (SessionInfo, error) {
43	// Import the KIDs to validate them.
44	deviceSubkey, err := libkb.ImportKeypairFromKID(session.DeviceSubkeyKid)
45	if err != nil {
46		return SessionInfo{}, err
47	}
48	deviceSibkey, err := libkb.ImportKeypairFromKID(session.DeviceSibkeyKid)
49	if err != nil {
50		return SessionInfo{}, err
51	}
52	cryptPublicKey := kbfscrypto.MakeCryptPublicKey(deviceSubkey.GetKID())
53	verifyingKey := kbfscrypto.MakeVerifyingKey(deviceSibkey.GetKID())
54	return SessionInfo{
55		Name:           kbname.NewNormalizedUsername(session.Username),
56		UID:            session.Uid,
57		CryptPublicKey: cryptPublicKey,
58		VerifyingKey:   verifyingKey,
59	}, nil
60}
61