github.com/readium/readium-lcp-server@v0.0.0-20240101192032-6e95190e99f1/crypto/pad_test.go (about)

     1  // Copyright (c) 2016 Readium Foundation
     2  //
     3  // Redistribution and use in source and binary forms, with or without modification,
     4  // are permitted provided that the following conditions are met:
     5  //
     6  // 1. Redistributions of source code must retain the above copyright notice, this
     7  //    list of conditions and the following disclaimer.
     8  // 2. Redistributions in binary form must reproduce the above copyright notice,
     9  //    this list of conditions and the following disclaimer in the documentation and/or
    10  //    other materials provided with the distribution.
    11  // 3. Neither the name of the organization nor the names of its contributors may be
    12  //    used to endorse or promote products derived from this software without specific
    13  //    prior written permission
    14  //
    15  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
    16  // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    17  // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    18  // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
    19  // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    20  // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    21  // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
    22  // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    23  // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    24  // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
    25  
    26  package crypto
    27  
    28  import (
    29  	"bytes"
    30  	"io"
    31  	"testing"
    32  )
    33  
    34  func TestOneBlock(t *testing.T) {
    35  	buf := bytes.NewBufferString("4321")
    36  	reader := PaddedReader(buf, 6, true)
    37  	var out [12]byte
    38  	n, err := reader.Read(out[:])
    39  	if err != nil && err != io.EOF {
    40  		t.Error(err)
    41  	}
    42  	if n != 6 {
    43  		t.Errorf("should have read 6 bytes, read %d", n)
    44  	}
    45  
    46  	// PaddedReader constructor parameter "insertPadLengthAll" is true,
    47  	// means all last bytes equate the padding length
    48  	if out[4] != 2 || out[5] != 2 {
    49  		t.Errorf("last values were expected to be 2, got [%x %x]", out[4], out[5])
    50  	}
    51  }
    52  
    53  func TestFullPadding(t *testing.T) {
    54  	buf := bytes.NewBufferString("1234")
    55  	reader := PaddedReader(buf, 4, true)
    56  
    57  	var out [8]byte
    58  	n, err := io.ReadFull(reader, out[:])
    59  	if err != nil {
    60  		t.Error(err)
    61  	}
    62  	if n != 8 {
    63  		t.Errorf("should have read 8 bytes, read %d", n)
    64  	}
    65  
    66  	// PaddedReader constructor parameter "insertPadLengthAll" is true,
    67  	// means all last bytes equate the padding length
    68  	if out[4] != 4 || out[5] != 4 || out[6] != 4 || out[7] != 4 {
    69  		t.Errorf("last values were expected to be 4, got [%x %x %x %x]", out[4], out[5], out[6], out[7])
    70  	}
    71  }
    72  
    73  func TestManyBlocks(t *testing.T) {
    74  	buf := bytes.NewBufferString("1234")
    75  	reader := PaddedReader(buf, 3, true)
    76  	var out [3]byte
    77  	n, err := io.ReadFull(reader, out[:])
    78  	if err != nil {
    79  		t.Error(err)
    80  	}
    81  
    82  	n, err = io.ReadFull(reader, out[:])
    83  	if err != nil {
    84  		t.Error(err)
    85  	}
    86  
    87  	if n != 3 {
    88  		t.Errorf("should have read 3 bytes, read %d", n)
    89  	}
    90  
    91  	// PaddedReader constructor parameter "insertPadLengthAll" is true,
    92  	// means all last bytes equate the padding length
    93  	if out[1] != 2 || out[2] != 2 {
    94  		t.Errorf("last values were expected to be 2, got [%x %x]", out[1], out[2])
    95  	}
    96  }
    97  
    98  func TestOneBlock_Random(t *testing.T) {
    99  	buf := bytes.NewBufferString("4321")
   100  	reader := PaddedReader(buf, 6, false)
   101  	var out [12]byte
   102  	n, err := reader.Read(out[:])
   103  	if err != nil && err != io.EOF {
   104  		t.Error(err)
   105  	}
   106  	if n != 6 {
   107  		t.Errorf("should have read 6 bytes, read %d", n)
   108  	}
   109  
   110  	// the PaddedReader constructor parameter "insertPadLengthAll" is false,
   111  	// so only the last byte out[2] equates the padding length (the others are random)
   112  	if out[4] == 2 || out[5] != 2 {
   113  		t.Errorf("last values were expected to be [random, 2], got [%x %x]", out[4], out[5])
   114  	}
   115  }
   116  
   117  func TestFullPadding_Random(t *testing.T) {
   118  	buf := bytes.NewBufferString("1234")
   119  	reader := PaddedReader(buf, 4, false)
   120  
   121  	var out [8]byte
   122  	n, err := io.ReadFull(reader, out[:])
   123  	if err != nil {
   124  		t.Error(err)
   125  	}
   126  	if n != 8 {
   127  		t.Errorf("should have read 8 bytes, read %d", n)
   128  	}
   129  
   130  	// the PaddedReader constructor parameter "insertPadLengthAll" is false,
   131  	// so only the last byte out[7] equates the padding length (the others are random)
   132  	if out[4] == 4 || out[5] == 4 || out[6] == 4 || out[7] != 4 {
   133  		t.Errorf("last values were expected to be [random, random, random, 4], got [%x %x %x %x]", out[4], out[5], out[6], out[7])
   134  	}
   135  }
   136  
   137  func TestManyBlocks_Random(t *testing.T) {
   138  	buf := bytes.NewBufferString("1234")
   139  	reader := PaddedReader(buf, 3, false)
   140  	var out [3]byte
   141  	n, err := io.ReadFull(reader, out[:])
   142  	if err != nil {
   143  		t.Error(err)
   144  	}
   145  
   146  	n, err = io.ReadFull(reader, out[:])
   147  	if err != nil {
   148  		t.Error(err)
   149  	}
   150  
   151  	if n != 3 {
   152  		t.Errorf("should have read 3 bytes, read %d", n)
   153  	}
   154  
   155  	// the PaddedReader constructor parameter "insertPadLengthAll" is false,
   156  	// so only the last byte out[2] equates the padding length (the others are random)
   157  	if out[1] == 2 || out[2] != 2 {
   158  		t.Errorf("last values were expected to be [random 2], got [%x %x]", out[1], out[2])
   159  	}
   160  }
   161  
   162  func TestPaddingInMultipleCalls(t *testing.T) {
   163  	buf := bytes.NewBufferString("1")
   164  	reader := PaddedReader(buf, 6, false)
   165  	var out [3]byte
   166  	n, err := io.ReadFull(reader, out[:])
   167  
   168  	if err != nil {
   169  		t.Error(err)
   170  	}
   171  
   172  	if n != 3 {
   173  		t.Errorf("should have read 3 bytes, read %d", n)
   174  	}
   175  
   176  	n, err = io.ReadFull(reader, out[:])
   177  	if err != nil {
   178  		t.Error(err)
   179  	}
   180  
   181  	if n != 3 {
   182  		t.Errorf("should have read 3 bytes, read %d", n)
   183  	}
   184  
   185  }
   186  
   187  type failingReader struct {
   188  }
   189  
   190  func (r failingReader) Read(buf []byte) (int, error) {
   191  	return 0, io.ErrShortBuffer
   192  }
   193  
   194  func TestFailingReader(t *testing.T) {
   195  	reader := PaddedReader(failingReader{}, 8, false)
   196  	var out [8]byte
   197  	_, err := io.ReadFull(reader, out[:])
   198  
   199  	if err != io.ErrShortBuffer {
   200  		t.Error(err)
   201  	}
   202  }