github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/engine/pgp_verify_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 engine
     5  
     6  import (
     7  	"io"
     8  	"strings"
     9  	"testing"
    10  
    11  	"github.com/keybase/client/go/libkb"
    12  	keybase1 "github.com/keybase/client/go/protocol/keybase1"
    13  )
    14  
    15  func doVerify(t *testing.T, msg string) {
    16  	tc := SetupEngineTest(t, "PGPVerify")
    17  	defer tc.Cleanup()
    18  	fu := createFakeUserWithPGPSibkey(tc)
    19  
    20  	uis := libkb.UIs{
    21  		IdentifyUI: &FakeIdentifyUI{},
    22  		SecretUI:   fu.NewSecretUI(),
    23  		LogUI:      tc.G.UI.GetLogUI(),
    24  		PgpUI:      &TestPgpUI{},
    25  	}
    26  
    27  	m := NewMetaContextForTest(tc).WithUIs(uis)
    28  
    29  	// create detached sig
    30  	detached := sign(m, tc, msg, keybase1.SignMode_DETACHED)
    31  
    32  	// create clearsign sig
    33  	clearsign := sign(m, tc, msg, keybase1.SignMode_CLEAR)
    34  
    35  	// create attached sig w/ sign
    36  	attached := sign(m, tc, msg, keybase1.SignMode_ATTACHED)
    37  
    38  	// create attached sig w/ encrypt
    39  	attachedEnc := signEnc(m, tc, msg)
    40  
    41  	// Start with a fresh secret ui so the Called* flags will be false.
    42  	// If the verify() func works, it will ensure that the ones it cares
    43  	// about are false after each time it is called.
    44  	m = m.WithSecretUI(fu.NewSecretUI())
    45  
    46  	// still logged in as signer:
    47  	verify(m, tc, msg, detached, "detached logged in", true)
    48  	verify(m, tc, clearsign, "", "clearsign logged in", true)
    49  	verify(m, tc, attached, "", "attached logged in", true)
    50  	verify(m, tc, attachedEnc, "", "attached/encrypted logged in", true)
    51  
    52  	Logout(tc)
    53  
    54  	// these are all valid logged out
    55  	verify(m, tc, msg, detached, "detached logged out", true)
    56  	verify(m, tc, clearsign, "", "clearsign logged out", true)
    57  	verify(m, tc, attached, "", "attached logged out", true)
    58  	// attached encrypted is not valid logged out:
    59  	verify(m, tc, attachedEnc, "", "attached/encrypted logged out", false)
    60  
    61  	// sign in as a different user
    62  	tc2 := SetupEngineTest(t, "PGPVerify")
    63  	defer tc2.Cleanup()
    64  	fu2 := CreateAndSignupFakeUser(tc2, "pgp")
    65  
    66  	m = m.WithSecretUI(fu2.NewSecretUI())
    67  	verify(m, tc2, msg, detached, "detached different user", true)
    68  	verify(m, tc2, clearsign, "", "clearsign different user", true)
    69  	verify(m, tc2, attached, "", "attached different user", true)
    70  	verify(m, tc2, attachedEnc, "", "attached/encrypted different user", false)
    71  
    72  	// extra credit:
    73  	// encrypt a message for another user and sign it
    74  	// verify that attached signature
    75  }
    76  
    77  func TestPGPVerify(t *testing.T) {
    78  	msg := "If you wish to stop receiving notifications from this topic, please click or visit the link below to unsubscribe:"
    79  	doVerify(t, msg)
    80  }
    81  
    82  func TestPGPVerifyShortMsg(t *testing.T) {
    83  	msg := "less than 100 characters"
    84  	doVerify(t, msg)
    85  }
    86  
    87  func sign(m libkb.MetaContext, tc libkb.TestContext, msg string, mode keybase1.SignMode) string {
    88  	sink := libkb.NewBufferCloser()
    89  	arg := &PGPSignArg{
    90  		Sink:   sink,
    91  		Source: io.NopCloser(strings.NewReader(msg)),
    92  		Opts:   keybase1.PGPSignOptions{Mode: mode},
    93  	}
    94  	eng := NewPGPSignEngine(tc.G, arg)
    95  	if err := RunEngine2(m, eng); err != nil {
    96  		tc.T.Fatal(err)
    97  	}
    98  	return sink.String()
    99  }
   100  
   101  func signEnc(m libkb.MetaContext, tc libkb.TestContext, msg string) string {
   102  	sink := libkb.NewBufferCloser()
   103  	arg := &PGPEncryptArg{
   104  		Sink:   sink,
   105  		Source: strings.NewReader(msg),
   106  	}
   107  	eng := NewPGPEncrypt(tc.G, arg)
   108  	if err := RunEngine2(m, eng); err != nil {
   109  		tc.T.Fatal(err)
   110  	}
   111  	return sink.String()
   112  }
   113  
   114  func verify(m libkb.MetaContext, tc libkb.TestContext, msg, sig, name string, valid bool) {
   115  	arg := &PGPVerifyArg{
   116  		Source:    strings.NewReader(msg),
   117  		Signature: []byte(sig),
   118  	}
   119  	eng := NewPGPVerify(tc.G, arg)
   120  	if err := RunEngine2(m, eng); err != nil {
   121  		if valid {
   122  			tc.T.Logf("%s: sig: %s", name, sig)
   123  			tc.T.Errorf("%s not valid: %s", name, err)
   124  		}
   125  		return
   126  	}
   127  	if !valid {
   128  		tc.T.Errorf("%s validated, but it shouldn't have", name)
   129  	}
   130  	s, ok := m.UIs().SecretUI.(*libkb.TestSecretUI)
   131  	if !ok {
   132  		tc.T.Fatalf("%s: invalid secret ui: %T", name, m.UIs().SecretUI)
   133  	}
   134  	if s.CalledGetPassphrase {
   135  		tc.T.Errorf("%s: called get passphrase, shouldn't have", name)
   136  		s.CalledGetPassphrase = false // reset it for next caller
   137  	}
   138  	p, ok := m.UIs().PgpUI.(*TestPgpUI)
   139  	if !ok {
   140  		tc.T.Fatalf("%s: invalid pgp ui: %T", name, m.UIs().PgpUI)
   141  	}
   142  	if p.OutputCount == 0 {
   143  		tc.T.Errorf("%s: did not output signature success", name)
   144  	}
   145  }