github.com/glycerine/xcryptossh@v7.0.4+incompatible/cipher_test.go (about)

     1  // Copyright 2011 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package ssh
     6  
     7  import (
     8  	"bytes"
     9  	"crypto"
    10  	"crypto/aes"
    11  	"crypto/rand"
    12  	"testing"
    13  )
    14  
    15  func TestDefaultCiphersExist(t *testing.T) {
    16  	defer xtestend(xtestbegin(t))
    17  
    18  	for _, cipherAlgo := range supportedCiphers {
    19  		if _, ok := cipherModes[cipherAlgo]; !ok {
    20  			t.Errorf("default cipher %q is unknown", cipherAlgo)
    21  		}
    22  	}
    23  }
    24  
    25  func TestPacketCiphers(t *testing.T) {
    26  	defer xtestend(xtestbegin(t))
    27  
    28  	// Still test aes128cbc cipher although it's commented out.
    29  	cipherModes[aes128cbcID] = &streamCipherMode{16, aes.BlockSize, 0, nil}
    30  	defer delete(cipherModes, aes128cbcID)
    31  
    32  	for cipher := range cipherModes {
    33  		for mac := range macModes {
    34  			kr := &kexResult{Hash: crypto.SHA1}
    35  			algs := directionAlgorithms{
    36  				Cipher:      cipher,
    37  				MAC:         mac,
    38  				Compression: "none",
    39  			}
    40  			client, err := newPacketCipher(clientKeys, algs, kr)
    41  			if err != nil {
    42  				t.Errorf("newPacketCipher(client, %q, %q): %v", cipher, mac, err)
    43  				continue
    44  			}
    45  			server, err := newPacketCipher(clientKeys, algs, kr)
    46  			if err != nil {
    47  				t.Errorf("newPacketCipher(client, %q, %q): %v", cipher, mac, err)
    48  				continue
    49  			}
    50  
    51  			want := "bla bla"
    52  			input := []byte(want)
    53  			buf := &bytes.Buffer{}
    54  			if err := client.writePacket(0, buf, rand.Reader, input); err != nil {
    55  				t.Errorf("writePacket(%q, %q): %v", cipher, mac, err)
    56  				continue
    57  			}
    58  
    59  			packet, err := server.readPacket(0, buf)
    60  			if err != nil {
    61  				t.Errorf("readPacket(%q, %q): %v", cipher, mac, err)
    62  				continue
    63  			}
    64  
    65  			if string(packet) != want {
    66  				t.Errorf("roundtrip(%q, %q): got %q, want %q", cipher, mac, packet, want)
    67  			}
    68  		}
    69  	}
    70  }
    71  
    72  func TestCBCOracleCounterMeasure(t *testing.T) {
    73  	defer xtestend(xtestbegin(t))
    74  
    75  	cipherModes[aes128cbcID] = &streamCipherMode{16, aes.BlockSize, 0, nil}
    76  	defer delete(cipherModes, aes128cbcID)
    77  
    78  	kr := &kexResult{Hash: crypto.SHA1}
    79  	algs := directionAlgorithms{
    80  		Cipher:      aes128cbcID,
    81  		MAC:         "hmac-sha1",
    82  		Compression: "none",
    83  	}
    84  	client, err := newPacketCipher(clientKeys, algs, kr)
    85  	if err != nil {
    86  		t.Fatalf("newPacketCipher(client): %v", err)
    87  	}
    88  
    89  	want := "bla bla"
    90  	input := []byte(want)
    91  	buf := &bytes.Buffer{}
    92  	if err := client.writePacket(0, buf, rand.Reader, input); err != nil {
    93  		t.Errorf("writePacket: %v", err)
    94  	}
    95  
    96  	packetSize := buf.Len()
    97  	buf.Write(make([]byte, 2*maxPacket))
    98  
    99  	// We corrupt each byte, but this usually will only test the
   100  	// 'packet too large' or 'MAC failure' cases.
   101  	lastRead := -1
   102  	for i := 0; i < packetSize; i++ {
   103  		server, err := newPacketCipher(clientKeys, algs, kr)
   104  		if err != nil {
   105  			t.Fatalf("newPacketCipher(client): %v", err)
   106  		}
   107  
   108  		fresh := &bytes.Buffer{}
   109  		fresh.Write(buf.Bytes())
   110  		fresh.Bytes()[i] ^= 0x01
   111  
   112  		before := fresh.Len()
   113  		_, err = server.readPacket(0, fresh)
   114  		if err == nil {
   115  			t.Errorf("corrupt byte %d: readPacket succeeded ", i)
   116  			continue
   117  		}
   118  		if _, ok := err.(cbcError); !ok {
   119  			t.Errorf("corrupt byte %d: got %v (%T), want cbcError", i, err, err)
   120  			continue
   121  		}
   122  
   123  		after := fresh.Len()
   124  		bytesRead := before - after
   125  		if bytesRead < maxPacket {
   126  			t.Errorf("corrupt byte %d: read %d bytes, want more than %d", i, bytesRead, maxPacket)
   127  			continue
   128  		}
   129  
   130  		if i > 0 && bytesRead != lastRead {
   131  			t.Errorf("corrupt byte %d: read %d bytes, want %d bytes read", i, bytesRead, lastRead)
   132  		}
   133  		lastRead = bytesRead
   134  	}
   135  }