github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/auth/token_test.go (about)

     1  // Copyright 2015 Keybase, Inc. All rights reserved. Use of
     2  // this source code is governed by the included BSD license.
     3  
     4  package auth
     5  
     6  import (
     7  	"fmt"
     8  	"testing"
     9  	"time"
    10  
    11  	libkb "github.com/keybase/client/go/libkb"
    12  	keybase1 "github.com/keybase/client/go/protocol/keybase1"
    13  )
    14  
    15  const testMaxTokenExpireIn = 60
    16  
    17  func TestTokenVerifyToken(t *testing.T) {
    18  	keyPair, err := libkb.GenerateNaclSigningKeyPair()
    19  	if err != nil {
    20  		t.Fatal(err)
    21  	}
    22  	name := libkb.NewNormalizedUsername("alice")
    23  	uid := libkb.UsernameToUID(name.String())
    24  	expireIn := 10
    25  	server := "test"
    26  	clientName := "test_client"
    27  	clientVersion := "41651"
    28  	challenge, err := GenerateChallenge()
    29  	if err != nil {
    30  		t.Fatal(err)
    31  	}
    32  	token := NewToken(uid, name, keyPair.GetKID(), server, challenge,
    33  		time.Now().Unix(), expireIn, clientName, clientVersion)
    34  	sig, _, err := keyPair.SignToString(token.Bytes())
    35  	if err != nil {
    36  		t.Fatal(err)
    37  	}
    38  	_, err = VerifyToken("nope", server, challenge, testMaxTokenExpireIn)
    39  	if err == nil {
    40  		t.Fatal(fmt.Errorf("expected verification failure"))
    41  	}
    42  	token, err = VerifyToken(sig, server, challenge, testMaxTokenExpireIn)
    43  	if err != nil {
    44  		t.Fatal(err)
    45  	}
    46  	if err = checkToken(token, uid, name, keyPair.GetKID(),
    47  		server, challenge, expireIn, clientName, clientVersion); err != nil {
    48  		t.Fatal(err)
    49  	}
    50  }
    51  
    52  func TestTokenExpired(t *testing.T) {
    53  	keyPair, err := libkb.GenerateNaclSigningKeyPair()
    54  	if err != nil {
    55  		t.Fatal(err)
    56  	}
    57  	name := libkb.NewNormalizedUsername("bob")
    58  	uid := libkb.UsernameToUID(name.String())
    59  	expireIn := 0
    60  	server := "test"
    61  	clientName := "test_client"
    62  	clientVersion := "21021"
    63  	challenge, err := GenerateChallenge()
    64  	if err != nil {
    65  		t.Fatal(err)
    66  	}
    67  	token := NewToken(uid, name, keyPair.GetKID(), server, challenge,
    68  		time.Now().Unix(), expireIn, clientName, clientVersion)
    69  	sig, _, err := keyPair.SignToString(token.Bytes())
    70  	if err != nil {
    71  		t.Fatal(err)
    72  	}
    73  	_, err = VerifyToken(sig, server, challenge, testMaxTokenExpireIn)
    74  	_, expired := err.(TokenExpiredError)
    75  	if !expired {
    76  		t.Fatal(fmt.Errorf("expected token expired error"))
    77  	}
    78  }
    79  
    80  func TestMaxExpires(t *testing.T) {
    81  	keyPair, err := libkb.GenerateNaclSigningKeyPair()
    82  	if err != nil {
    83  		t.Fatal(err)
    84  	}
    85  	name := libkb.NewNormalizedUsername("charlie")
    86  	uid := libkb.UsernameToUID(name.String())
    87  	expireIn := testMaxTokenExpireIn + 10
    88  	server := "test"
    89  	clientName := "test_client"
    90  	clientVersion := "93021"
    91  	challenge, err := GenerateChallenge()
    92  	if err != nil {
    93  		t.Fatal(err)
    94  	}
    95  	token := NewToken(uid, name, keyPair.GetKID(), server, challenge,
    96  		time.Now().Unix(), expireIn, clientName, clientVersion)
    97  	sig, _, err := keyPair.SignToString(token.Bytes())
    98  	if err != nil {
    99  		t.Fatal(err)
   100  	}
   101  	_, err = VerifyToken(sig, server, challenge, testMaxTokenExpireIn)
   102  	_, maxExpires := err.(MaxTokenExpiresError)
   103  	if !maxExpires {
   104  		t.Fatal(fmt.Errorf("expected max token expires error"))
   105  	}
   106  }
   107  
   108  func TestTokenServerInvalid(t *testing.T) {
   109  	keyPair, err := libkb.GenerateNaclSigningKeyPair()
   110  	if err != nil {
   111  		t.Fatal(err)
   112  	}
   113  	name := libkb.NewNormalizedUsername("dana")
   114  	uid := libkb.UsernameToUID(name.String())
   115  	expireIn := 10
   116  	server := "test"
   117  	clientName := "test_client"
   118  	clientVersion := "20192"
   119  	challenge, err := GenerateChallenge()
   120  	if err != nil {
   121  		t.Fatal(err)
   122  	}
   123  	token := NewToken(uid, name, keyPair.GetKID(), server, challenge,
   124  		time.Now().Unix(), expireIn, clientName, clientVersion)
   125  	sig, _, err := keyPair.SignToString(token.Bytes())
   126  	if err != nil {
   127  		t.Fatal(err)
   128  	}
   129  	_, err = VerifyToken(sig, "nope", challenge, testMaxTokenExpireIn)
   130  	_, invalid := err.(InvalidTokenServerError)
   131  	if !invalid {
   132  		t.Fatal(fmt.Errorf("expected invalid token server error"))
   133  	}
   134  	token, err = VerifyToken(sig, server, challenge, testMaxTokenExpireIn)
   135  	if err != nil {
   136  		t.Fatal(err)
   137  	}
   138  	if err = checkToken(token, uid, name, keyPair.GetKID(),
   139  		server, challenge, expireIn, clientName, clientVersion); err != nil {
   140  		t.Fatal(err)
   141  	}
   142  }
   143  
   144  func TestTokenChallengeInvalid(t *testing.T) {
   145  	keyPair, err := libkb.GenerateNaclSigningKeyPair()
   146  	if err != nil {
   147  		t.Fatal(err)
   148  	}
   149  	name := libkb.NewNormalizedUsername("dana")
   150  	uid := libkb.UsernameToUID(name.String())
   151  	expireIn := 10
   152  	server := "test"
   153  	clientName := "test_client"
   154  	clientVersion := "20192"
   155  	challenge, err := GenerateChallenge()
   156  	if err != nil {
   157  		t.Fatal(err)
   158  	}
   159  	token := NewToken(uid, name, keyPair.GetKID(), server, challenge,
   160  		time.Now().Unix(), expireIn, clientName, clientVersion)
   161  	sig, _, err := keyPair.SignToString(token.Bytes())
   162  	if err != nil {
   163  		t.Fatal(err)
   164  	}
   165  	_, err = VerifyToken(sig, server, "nope", testMaxTokenExpireIn)
   166  	_, invalid := err.(InvalidTokenChallengeError)
   167  	if !invalid {
   168  		t.Fatal(fmt.Errorf("expected invalid token server error"))
   169  	}
   170  	token, err = VerifyToken(sig, server, challenge, testMaxTokenExpireIn)
   171  	if err != nil {
   172  		t.Fatal(err)
   173  	}
   174  	if err = checkToken(token, uid, name, keyPair.GetKID(),
   175  		server, challenge, expireIn, clientName, clientVersion); err != nil {
   176  		t.Fatal(err)
   177  	}
   178  }
   179  
   180  func checkToken(token *Token, uid keybase1.UID, username libkb.NormalizedUsername,
   181  	kid keybase1.KID, server, challenge string, expireIn int, clientName, clientVersion string) error {
   182  	if token.UID() != uid {
   183  		return fmt.Errorf("UID mismatch, expected: %s, got %s",
   184  			uid, token.UID())
   185  	}
   186  	if token.KID() != kid {
   187  		return fmt.Errorf("KID mismatch, expected: %s, got %s",
   188  			kid, token.KID())
   189  	}
   190  	if token.Username() != username {
   191  		return fmt.Errorf("Username mismatch, expected: %s, got %s",
   192  			username, token.Username())
   193  	}
   194  	if token.Type() != TokenType {
   195  		return fmt.Errorf("TokenType mismatch, expected: %s, got %s",
   196  			TokenType, token.Type())
   197  	}
   198  	if token.Server() != server {
   199  		return fmt.Errorf("Server mismatch, expected: %s, got %s",
   200  			server, token.Server())
   201  	}
   202  	if token.Challenge() != challenge {
   203  		return fmt.Errorf("Challenge mismatch, expected: %s, got %s",
   204  			challenge, token.Challenge())
   205  	}
   206  	if token.ExpireIn != expireIn {
   207  		return fmt.Errorf("ExpireIn mismatch, expected: %d, got %d",
   208  			expireIn, token.ExpireIn)
   209  	}
   210  	if token.ClientName() != clientName {
   211  		return fmt.Errorf("ClientName mismatch, expected: %s, got %s",
   212  			clientName, token.ClientName())
   213  	}
   214  	if token.ClientVersion() != clientVersion {
   215  		return fmt.Errorf("ClientVersion mismatch, expected: %s, got %s",
   216  			clientVersion, token.ClientVersion())
   217  	}
   218  	return nil
   219  }
   220  
   221  func TestIsValidChallenge(t *testing.T) {
   222  	challenge, err := GenerateChallenge()
   223  	if err != nil {
   224  		t.Fatal(err)
   225  	}
   226  	if !IsValidChallenge(challenge) {
   227  		t.Fatal(fmt.Errorf("Invalid challenge: %s", challenge))
   228  	}
   229  	if IsValidChallenge("nope") {
   230  		t.Fatal("Expected invalid challenge")
   231  	}
   232  	challenge = challenge[len(challenge)/2:]
   233  	if IsValidChallenge(challenge) {
   234  		t.Fatal("Expected invalid challenge")
   235  	}
   236  }