github.com/psiphon-labs/psiphon-tunnel-core@v2.0.28+incompatible/psiphon/common/authPackage_test.go (about)

     1  /*
     2   * Copyright (c) 2016, Psiphon Inc.
     3   * All rights reserved.
     4   *
     5   * This program is free software: you can redistribute it and/or modify
     6   * it under the terms of the GNU General Public License as published by
     7   * the Free Software Foundation, either version 3 of the License, or
     8   * (at your option) any later version.
     9   *
    10   * This program is distributed in the hope that it will be useful,
    11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13   * GNU General Public License for more details.
    14   *
    15   * You should have received a copy of the GNU General Public License
    16   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17   *
    18   */
    19  
    20  package common
    21  
    22  import (
    23  	"encoding/base64"
    24  	"encoding/json"
    25  	"io"
    26  	"io/ioutil"
    27  	"math/rand"
    28  	"os"
    29  	"testing"
    30  
    31  	"github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/errors"
    32  )
    33  
    34  func TestAuthenticatedPackage(t *testing.T) {
    35  
    36  	signingPublicKey, signingPrivateKey, err := GenerateAuthenticatedDataPackageKeys()
    37  	if err != nil {
    38  		t.Fatalf("GenerateAuthenticatedDataPackageKeys failed: %s", err)
    39  	}
    40  
    41  	expectedContent := "TestAuthenticatedPackage"
    42  
    43  	packagePayload, err := WriteAuthenticatedDataPackage(
    44  		expectedContent,
    45  		signingPublicKey,
    46  		signingPrivateKey)
    47  	if err != nil {
    48  		t.Fatalf("WriteAuthenticatedDataPackage failed: %s", err)
    49  	}
    50  
    51  	tempFileName, err := makeTempFile(packagePayload)
    52  	if err != nil {
    53  		t.Fatalf("makeTempFile failed: %s", err)
    54  	}
    55  	defer os.Remove(tempFileName)
    56  
    57  	wrongSigningPublicKey, _, err := GenerateAuthenticatedDataPackageKeys()
    58  	if err != nil {
    59  		t.Fatalf("GenerateAuthenticatedDataPackageKeys failed: %s", err)
    60  	}
    61  
    62  	packageJSON, err := Decompress(packagePayload)
    63  	if err != nil {
    64  		t.Fatalf("Uncompress failed: %s", err)
    65  	}
    66  
    67  	var authDataPackage AuthenticatedDataPackage
    68  	err = json.Unmarshal(packageJSON, &authDataPackage)
    69  	if err != nil {
    70  		t.Fatalf("Unmarshal failed: %s", err)
    71  	}
    72  	authDataPackage.Data = "TamperedData"
    73  
    74  	tamperedPackageJSON, err := json.Marshal(&authDataPackage)
    75  	if err != nil {
    76  		t.Fatalf("Marshal failed: %s", err)
    77  	}
    78  
    79  	tamperedPackagePayload := Compress(tamperedPackageJSON)
    80  
    81  	tamperedTempFileName, err := makeTempFile(tamperedPackagePayload)
    82  	if err != nil {
    83  		t.Fatalf("makeTempFile failed: %s", err)
    84  	}
    85  	defer os.Remove(tempFileName)
    86  
    87  	t.Run("read package: success", func(t *testing.T) {
    88  		content, err := ReadAuthenticatedDataPackage(
    89  			packagePayload, true, signingPublicKey)
    90  		if err != nil {
    91  			t.Fatalf("ReadAuthenticatedDataPackage failed: %s", err)
    92  		}
    93  		if content != expectedContent {
    94  			t.Fatalf(
    95  				"unexpected package content: expected %s got %s",
    96  				expectedContent, content)
    97  		}
    98  	})
    99  
   100  	t.Run("streaming read package: success", func(t *testing.T) {
   101  		file, err := os.Open(tempFileName)
   102  		if err != nil {
   103  			t.Fatalf("Open failed: %s", err)
   104  		}
   105  		defer file.Close()
   106  		contentReader, err := NewAuthenticatedDataPackageReader(
   107  			file, signingPublicKey)
   108  		if err != nil {
   109  			t.Fatalf("NewAuthenticatedDataPackageReader failed: %s", err)
   110  		}
   111  		content, err := ioutil.ReadAll(contentReader)
   112  		if err != nil {
   113  			t.Fatalf("ReadAll failed: %s", err)
   114  		}
   115  		if string(content) != expectedContent {
   116  			t.Fatalf(
   117  				"unexpected package content: expected %s got %s",
   118  				expectedContent, content)
   119  		}
   120  	})
   121  
   122  	t.Run("read package: wrong signing key", func(t *testing.T) {
   123  		_, err = ReadAuthenticatedDataPackage(
   124  			packagePayload, true, wrongSigningPublicKey)
   125  		if err == nil {
   126  			t.Fatalf("ReadAuthenticatedDataPackage unexpectedly succeeded")
   127  		}
   128  	})
   129  
   130  	t.Run("streaming read package: wrong signing key", func(t *testing.T) {
   131  		file, err := os.Open(tempFileName)
   132  		if err != nil {
   133  			t.Fatalf("Open failed: %s", err)
   134  		}
   135  		defer file.Close()
   136  		_, err = NewAuthenticatedDataPackageReader(
   137  			file, wrongSigningPublicKey)
   138  		if err == nil {
   139  			t.Fatalf("NewAuthenticatedDataPackageReader unexpectedly succeeded")
   140  		}
   141  	})
   142  
   143  	t.Run("read package: tampered data", func(t *testing.T) {
   144  		_, err = ReadAuthenticatedDataPackage(
   145  			tamperedPackagePayload, true, signingPublicKey)
   146  		if err == nil {
   147  			t.Fatalf("ReadAuthenticatedDataPackage unexpectedly succeeded")
   148  		}
   149  	})
   150  
   151  	t.Run("streaming read package: tampered data", func(t *testing.T) {
   152  		file, err := os.Open(tamperedTempFileName)
   153  		if err != nil {
   154  			t.Fatalf("Open failed: %s", err)
   155  		}
   156  		defer file.Close()
   157  		_, err = NewAuthenticatedDataPackageReader(
   158  			file, signingPublicKey)
   159  		if err == nil {
   160  			t.Fatalf("NewAuthenticatedDataPackageReader unexpectedly succeeded")
   161  		}
   162  	})
   163  }
   164  
   165  func BenchmarkAuthenticatedPackage(b *testing.B) {
   166  
   167  	signingPublicKey, signingPrivateKey, err := GenerateAuthenticatedDataPackageKeys()
   168  	if err != nil {
   169  		b.Fatalf("GenerateAuthenticatedDataPackageKeys failed: %s", err)
   170  	}
   171  
   172  	data := make([]byte, 104857600)
   173  	rand.Read(data)
   174  
   175  	packagePayload, err := WriteAuthenticatedDataPackage(
   176  		base64.StdEncoding.EncodeToString(data),
   177  		signingPublicKey,
   178  		signingPrivateKey)
   179  	if err != nil {
   180  		b.Fatalf("WriteAuthenticatedDataPackage failed: %s", err)
   181  	}
   182  
   183  	tempFileName, err := makeTempFile(packagePayload)
   184  	if err != nil {
   185  		b.Fatalf("makeTempFile failed: %s", err)
   186  	}
   187  	defer os.Remove(tempFileName)
   188  
   189  	b.Run("read package", func(b *testing.B) {
   190  		for i := 0; i < b.N; i++ {
   191  			_, err := ReadAuthenticatedDataPackage(
   192  				packagePayload, true, signingPublicKey)
   193  			if err != nil {
   194  				b.Fatalf("ReadAuthenticatedDataPackage failed: %s", err)
   195  			}
   196  		}
   197  	})
   198  
   199  	b.Run("streaming read package", func(b *testing.B) {
   200  		for i := 0; i < b.N; i++ {
   201  			file, err := os.Open(tempFileName)
   202  			if err != nil {
   203  				b.Fatalf("Open failed: %s", err)
   204  			}
   205  			contentReader, err := NewAuthenticatedDataPackageReader(
   206  				file, signingPublicKey)
   207  			if err != nil {
   208  				file.Close()
   209  				b.Fatalf("NewAuthenticatedDataPackageReader failed: %s", err)
   210  			}
   211  			_, err = io.Copy(ioutil.Discard, contentReader)
   212  			if err != nil {
   213  				file.Close()
   214  				b.Fatalf("Read failed: %s", err)
   215  			}
   216  			file.Close()
   217  		}
   218  	})
   219  }
   220  
   221  func makeTempFile(data []byte) (string, error) {
   222  	file, err := ioutil.TempFile("", "authPackage_test")
   223  	if err != nil {
   224  		return "", errors.Trace(err)
   225  	}
   226  	defer file.Close()
   227  	_, err = file.Write(data)
   228  	if err != nil {
   229  		return "", errors.Trace(err)
   230  	}
   231  	return file.Name(), nil
   232  }