github.com/zmap/zcrypto@v0.0.0-20240512203510-0fef58d9a9db/x509/ct/serialization_test.go (about)

     1  package ct
     2  
     3  // This file contains selectively chosen snippets of
     4  // github.com/google/certificate-transparency-go@ 5cfe585726ad9d990d4db524d6ce2567b13e2f80
     5  //
     6  // These snippets only perform deserialization for SCTs and are recreated here to prevent pulling in the whole of the ct
     7  // which contains yet another version of x509,asn1 and tls
     8  
     9  import (
    10  	"bytes"
    11  	"encoding/hex"
    12  	"strings"
    13  	"testing"
    14  
    15  	"github.com/stretchr/testify/assert"
    16  )
    17  
    18  func mustDehex(t *testing.T, h string) []byte {
    19  	r, err := hex.DecodeString(h)
    20  	if err != nil {
    21  		t.Fatalf("Failed to decode hex string (%s): %v", h, err)
    22  	}
    23  	return r
    24  }
    25  
    26  // Returns a "variable-length" byte buffer containing |dataSize| data bytes
    27  // along with an appropriate header.
    28  // The buffer format is [header][data]
    29  // where [header] is a bigendian representation of the size of [data].
    30  // sizeof([header]) is the minimum number of bytes necessary to represent
    31  // |dataSize|.
    32  func createVarByteBuf(dataSize uint64) []byte {
    33  	lenBytes := uint64(0)
    34  	for x := dataSize; x > 0; x >>= 8 {
    35  		lenBytes++
    36  	}
    37  	buf := make([]byte, dataSize+lenBytes)
    38  	for t, x := dataSize, uint64(0); x < lenBytes; x++ {
    39  		buf[lenBytes-x-1] = byte(t)
    40  		t >>= 8
    41  	}
    42  	for x := uint64(0); x < dataSize; x++ {
    43  		buf[lenBytes+x] = byte(x)
    44  	}
    45  	return buf
    46  }
    47  
    48  func TestCreateVarByteBuf(t *testing.T) {
    49  	buf := createVarByteBuf(56)
    50  	if len(buf) != 56+1 {
    51  		t.Errorf("Wrong buffer size returned, expected %d", 56+1)
    52  	}
    53  	if buf[0] != 56 {
    54  		t.Errorf("Buffer has incorrect size header %02x", buf[0])
    55  	}
    56  	buf = createVarByteBuf(256)
    57  	if len(buf) != 256+2 {
    58  		t.Errorf("Wrong buffer size returned, expected %d", 256+2)
    59  	}
    60  	if buf[0] != 0x01 || buf[1] != 0x00 {
    61  		t.Errorf("Buffer has incorrect size header %02x,%02x", buf[0], buf[1])
    62  	}
    63  	buf = createVarByteBuf(65536)
    64  	if len(buf) != 65536+3 {
    65  		t.Errorf("Wrong buffer size returned, expected %d", 65536+3)
    66  	}
    67  	if buf[0] != 0x01 || buf[1] != 0x00 || buf[2] != 0x00 {
    68  		t.Errorf("Buffer has incorrect size header %02x,%02x,%02x", buf[0], buf[1], buf[2])
    69  	}
    70  }
    71  
    72  func TestWriteVarBytes(t *testing.T) {
    73  	const dataSize = 453641
    74  	data := make([]byte, dataSize)
    75  	for x := uint64(0); x < dataSize; x++ {
    76  		data[x] = byte(x)
    77  	}
    78  
    79  	var buf bytes.Buffer
    80  	if err := writeVarBytes(&buf, data, 3); err != nil {
    81  		t.Errorf("Failed to write data to buffer: %v", err)
    82  	}
    83  	if buf.Len() != dataSize+3 {
    84  		t.Errorf("Wrong buffer size created, expected %d but got %d", dataSize+3, buf.Len())
    85  	}
    86  	b := buf.Bytes()
    87  	if b[0] != 0x06 || b[1] != 0xec || b[2] != 0x09 {
    88  		t.Errorf("Buffer has incorrect size header %02x,%02x,%02x", b[0], b[1], b[2])
    89  	}
    90  	if bytes.Compare(data, b[3:]) != 0 {
    91  		t.Errorf("Buffer data corrupt")
    92  	}
    93  }
    94  
    95  func TestReadVarBytes(t *testing.T) {
    96  	const BufSize = 453641
    97  	r := createVarByteBuf(BufSize)
    98  	buf, err := readVarBytes(bytes.NewReader(r), 3)
    99  	if err != nil {
   100  		t.Fatal(err)
   101  	}
   102  	if len(buf) != BufSize {
   103  		t.Fatalf("Incorrect size buffer returned, expected %d, got %d", BufSize, len(buf))
   104  	}
   105  	for i := range buf {
   106  		if buf[i] != byte(i) {
   107  			t.Fatalf("Buffer contents incorrect, expected %02x, got %02x.", byte(i), buf[i])
   108  		}
   109  	}
   110  }
   111  
   112  func TestReadVarBytesTooLarge(t *testing.T) {
   113  	_, err := readVarBytes(nil, 9)
   114  	if err == nil || !strings.Contains(err.Error(), "too large") {
   115  		t.Fatal("readVarBytes didn't fail when trying to read too large a data size: ", err)
   116  	}
   117  }
   118  
   119  func TestReadVarBytesZero(t *testing.T) {
   120  	_, err := readVarBytes(nil, 0)
   121  	if err == nil || !strings.Contains(err.Error(), "should be > 0") {
   122  		t.Fatal("readVarBytes didn't fail when trying to read zero length data")
   123  	}
   124  }
   125  
   126  func TestReadVarBytesShortRead(t *testing.T) {
   127  	r := make([]byte, 2)
   128  	r[0] = 2 // but only 1 byte available...
   129  	_, err := readVarBytes(bytes.NewReader(r), 1)
   130  	if err == nil || !strings.Contains(err.Error(), "short read") {
   131  		t.Fatal("readVarBytes didn't fail with a short read")
   132  	}
   133  }
   134  
   135  const (
   136  	defaultSCTLogIDString     string = "iamapublickeyshatwofivesixdigest"
   137  	defaultSCTTimestamp       uint64 = 1234
   138  	defaultSCTSignatureString string = "\x04\x03\x00\x09signature"
   139  	defaultSCTHexString       string =
   140  	// version, 1 byte
   141  	"00" +
   142  		// keyid, 32 bytes
   143  		"69616d617075626c69636b657973686174776f66697665736978646967657374" +
   144  		// timestamp, 8 bytes
   145  		"00000000000004d2" +
   146  		// extensions length, 2 bytes
   147  		"0000" +
   148  		// extensions, 0 bytes
   149  		// hash algo, sig algo, 2 bytes
   150  		"0403" +
   151  		// signature length, 2 bytes
   152  		"0009" +
   153  		// signature, 9 bytes
   154  		"7369676e6174757265"
   155  )
   156  
   157  func defaultSCTLogID() SHA256Hash {
   158  	var id SHA256Hash
   159  	copy(id[:], defaultSCTLogIDString)
   160  	return id
   161  }
   162  
   163  func defaultSCTSignature() DigitallySigned {
   164  	ds, err := UnmarshalDigitallySigned(bytes.NewReader([]byte(defaultSCTSignatureString)))
   165  	if err != nil {
   166  		panic(err)
   167  	}
   168  	return *ds
   169  }
   170  
   171  func defaultSCT() SignedCertificateTimestamp {
   172  	return SignedCertificateTimestamp{
   173  		SCTVersion: V1,
   174  		LogID:      defaultSCTLogID(),
   175  		Timestamp:  defaultSCTTimestamp,
   176  		Extensions: []byte{},
   177  		Signature:  defaultSCTSignature()}
   178  }
   179  
   180  // ////////////////////////////////////////////////////////////////////////////////
   181  // Tests start here:
   182  // ////////////////////////////////////////////////////////////////////////////////
   183  func TestMarshalDigitallySigned(t *testing.T) {
   184  	b, err := MarshalDigitallySigned(
   185  		DigitallySigned{
   186  			HashAlgorithm:      SHA512,
   187  			SignatureAlgorithm: ECDSA,
   188  			Signature:          []byte("signature")})
   189  	if err != nil {
   190  		t.Fatalf("Failed to marshal DigitallySigned struct: %v", err)
   191  	}
   192  	if b[0] != byte(SHA512) {
   193  		t.Fatalf("Expected b[0] == SHA512, but found %v", HashAlgorithm(b[0]))
   194  	}
   195  	if b[1] != byte(ECDSA) {
   196  		t.Fatalf("Expected b[1] == ECDSA, but found %v", SignatureAlgorithm(b[1]))
   197  	}
   198  	if b[2] != 0x00 || b[3] != 0x09 {
   199  		t.Fatalf("Found incorrect length bytes, expected (0x00, 0x09) found %v", b[2:3])
   200  	}
   201  	if string(b[4:]) != "signature" {
   202  		t.Fatalf("Found incorrect signature bytes, expected %v, found %v", []byte("signature"), b[4:])
   203  	}
   204  }
   205  
   206  func TestUnmarshalDigitallySigned(t *testing.T) {
   207  	ds, err := UnmarshalDigitallySigned(bytes.NewReader([]byte("\x01\x02\x00\x0aSiGnAtUrE!")))
   208  	if err != nil {
   209  		t.Fatalf("Failed to unmarshal DigitallySigned: %v", err)
   210  	}
   211  	if ds.HashAlgorithm != MD5 {
   212  		t.Fatalf("Expected HashAlgorithm %v, but got %v", MD5, ds.HashAlgorithm)
   213  	}
   214  	if ds.SignatureAlgorithm != DSA {
   215  		t.Fatalf("Expected SignatureAlgorithm %v, but got %v", DSA, ds.SignatureAlgorithm)
   216  	}
   217  	if string(ds.Signature) != "SiGnAtUrE!" {
   218  		t.Fatalf("Expected Signature %v, but got %v", []byte("SiGnAtUrE!"), ds.Signature)
   219  	}
   220  }
   221  
   222  func TestDeserializeSCT(t *testing.T) {
   223  	sct, err := DeserializeSCT(bytes.NewReader(mustDehex(t, defaultSCTHexString)))
   224  	if err != nil {
   225  		t.Fatalf("Failed to deserialize SCT: %v", err)
   226  	}
   227  	assert.Equal(t, defaultSCT(), *sct)
   228  }