...

Source file src/golang.org/x/crypto/cryptobyte/cryptobyte_test.go

Documentation: golang.org/x/crypto/cryptobyte

     1  // Copyright 2017 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 cryptobyte
     6  
     7  import (
     8  	"bytes"
     9  	"errors"
    10  	"fmt"
    11  	"testing"
    12  )
    13  
    14  func builderBytesEq(b *Builder, want ...byte) error {
    15  	got := b.BytesOrPanic()
    16  	if !bytes.Equal(got, want) {
    17  		return fmt.Errorf("Bytes() = %v, want %v", got, want)
    18  	}
    19  	return nil
    20  }
    21  
    22  func TestContinuationError(t *testing.T) {
    23  	const errorStr = "TestContinuationError"
    24  	var b Builder
    25  	b.AddUint8LengthPrefixed(func(b *Builder) {
    26  		b.AddUint8(1)
    27  		panic(BuildError{Err: errors.New(errorStr)})
    28  	})
    29  
    30  	ret, err := b.Bytes()
    31  	if ret != nil {
    32  		t.Error("expected nil result")
    33  	}
    34  	if err == nil {
    35  		t.Fatal("unexpected nil error")
    36  	}
    37  	if s := err.Error(); s != errorStr {
    38  		t.Errorf("expected error %q, got %v", errorStr, s)
    39  	}
    40  }
    41  
    42  func TestContinuationNonError(t *testing.T) {
    43  	defer func() {
    44  		recover()
    45  	}()
    46  
    47  	var b Builder
    48  	b.AddUint8LengthPrefixed(func(b *Builder) {
    49  		b.AddUint8(1)
    50  		panic(1)
    51  	})
    52  
    53  	t.Error("Builder did not panic")
    54  }
    55  
    56  func TestGeneratedPanic(t *testing.T) {
    57  	defer func() {
    58  		recover()
    59  	}()
    60  
    61  	var b Builder
    62  	b.AddUint8LengthPrefixed(func(b *Builder) {
    63  		var p *byte
    64  		*p = 0
    65  	})
    66  
    67  	t.Error("Builder did not panic")
    68  }
    69  
    70  func TestBytes(t *testing.T) {
    71  	var b Builder
    72  	v := []byte("foobarbaz")
    73  	b.AddBytes(v[0:3])
    74  	b.AddBytes(v[3:4])
    75  	b.AddBytes(v[4:9])
    76  	if err := builderBytesEq(&b, v...); err != nil {
    77  		t.Error(err)
    78  	}
    79  	s := String(b.BytesOrPanic())
    80  	for _, w := range []string{"foo", "bar", "baz"} {
    81  		var got []byte
    82  		if !s.ReadBytes(&got, 3) {
    83  			t.Errorf("ReadBytes() = false, want true (w = %v)", w)
    84  		}
    85  		want := []byte(w)
    86  		if !bytes.Equal(got, want) {
    87  			t.Errorf("ReadBytes(): got = %v, want %v", got, want)
    88  		}
    89  	}
    90  	if len(s) != 0 {
    91  		t.Errorf("len(s) = %d, want 0", len(s))
    92  	}
    93  }
    94  
    95  func TestUint8(t *testing.T) {
    96  	var b Builder
    97  	b.AddUint8(42)
    98  	if err := builderBytesEq(&b, 42); err != nil {
    99  		t.Error(err)
   100  	}
   101  
   102  	var s String = b.BytesOrPanic()
   103  	var v uint8
   104  	if !s.ReadUint8(&v) {
   105  		t.Error("ReadUint8() = false, want true")
   106  	}
   107  	if v != 42 {
   108  		t.Errorf("v = %d, want 42", v)
   109  	}
   110  	if len(s) != 0 {
   111  		t.Errorf("len(s) = %d, want 0", len(s))
   112  	}
   113  }
   114  
   115  func TestUint16(t *testing.T) {
   116  	var b Builder
   117  	b.AddUint16(65534)
   118  	if err := builderBytesEq(&b, 255, 254); err != nil {
   119  		t.Error(err)
   120  	}
   121  	var s String = b.BytesOrPanic()
   122  	var v uint16
   123  	if !s.ReadUint16(&v) {
   124  		t.Error("ReadUint16() == false, want true")
   125  	}
   126  	if v != 65534 {
   127  		t.Errorf("v = %d, want 65534", v)
   128  	}
   129  	if len(s) != 0 {
   130  		t.Errorf("len(s) = %d, want 0", len(s))
   131  	}
   132  }
   133  
   134  func TestUint24(t *testing.T) {
   135  	var b Builder
   136  	b.AddUint24(0xfffefd)
   137  	if err := builderBytesEq(&b, 255, 254, 253); err != nil {
   138  		t.Error(err)
   139  	}
   140  
   141  	var s String = b.BytesOrPanic()
   142  	var v uint32
   143  	if !s.ReadUint24(&v) {
   144  		t.Error("ReadUint24() = false, want true")
   145  	}
   146  	if v != 0xfffefd {
   147  		t.Errorf("v = %d, want fffefd", v)
   148  	}
   149  	if len(s) != 0 {
   150  		t.Errorf("len(s) = %d, want 0", len(s))
   151  	}
   152  }
   153  
   154  func TestUint24Truncation(t *testing.T) {
   155  	var b Builder
   156  	b.AddUint24(0x10111213)
   157  	if err := builderBytesEq(&b, 0x11, 0x12, 0x13); err != nil {
   158  		t.Error(err)
   159  	}
   160  }
   161  
   162  func TestUint32(t *testing.T) {
   163  	var b Builder
   164  	b.AddUint32(0xfffefdfc)
   165  	if err := builderBytesEq(&b, 255, 254, 253, 252); err != nil {
   166  		t.Error(err)
   167  	}
   168  
   169  	var s String = b.BytesOrPanic()
   170  	var v uint32
   171  	if !s.ReadUint32(&v) {
   172  		t.Error("ReadUint32() = false, want true")
   173  	}
   174  	if v != 0xfffefdfc {
   175  		t.Errorf("v = %x, want fffefdfc", v)
   176  	}
   177  	if len(s) != 0 {
   178  		t.Errorf("len(s) = %d, want 0", len(s))
   179  	}
   180  }
   181  
   182  func TestUint48(t *testing.T) {
   183  	var b Builder
   184  	var u uint64 = 0xfefcff3cfdfc
   185  	b.AddUint48(u)
   186  	if err := builderBytesEq(&b, 254, 252, 255, 60, 253, 252); err != nil {
   187  		t.Error(err)
   188  	}
   189  
   190  	var s String = b.BytesOrPanic()
   191  	var v uint64
   192  	if !s.ReadUint48(&v) {
   193  		t.Error("ReadUint48() = false, want true")
   194  	}
   195  	if v != u {
   196  		t.Errorf("v = %x, want %x", v, u)
   197  	}
   198  	if len(s) != 0 {
   199  		t.Errorf("len(s) = %d, want 0", len(s))
   200  	}
   201  }
   202  
   203  func TestUint64(t *testing.T) {
   204  	var b Builder
   205  	b.AddUint64(0xf2fefefcff3cfdfc)
   206  	if err := builderBytesEq(&b, 242, 254, 254, 252, 255, 60, 253, 252); err != nil {
   207  		t.Error(err)
   208  	}
   209  
   210  	var s String = b.BytesOrPanic()
   211  	var v uint64
   212  	if !s.ReadUint64(&v) {
   213  		t.Error("ReadUint64() = false, want true")
   214  	}
   215  	if v != 0xf2fefefcff3cfdfc {
   216  		t.Errorf("v = %x, want f2fefefcff3cfdfc", v)
   217  	}
   218  	if len(s) != 0 {
   219  		t.Errorf("len(s) = %d, want 0", len(s))
   220  	}
   221  }
   222  
   223  func TestUMultiple(t *testing.T) {
   224  	var b Builder
   225  	b.AddUint8(23)
   226  	b.AddUint32(0xfffefdfc)
   227  	b.AddUint16(42)
   228  	if err := builderBytesEq(&b, 23, 255, 254, 253, 252, 0, 42); err != nil {
   229  		t.Error(err)
   230  	}
   231  
   232  	var s String = b.BytesOrPanic()
   233  	var (
   234  		x uint8
   235  		y uint32
   236  		z uint16
   237  	)
   238  	if !s.ReadUint8(&x) || !s.ReadUint32(&y) || !s.ReadUint16(&z) {
   239  		t.Error("ReadUint8() = false, want true")
   240  	}
   241  	if x != 23 || y != 0xfffefdfc || z != 42 {
   242  		t.Errorf("x, y, z = %d, %d, %d; want 23, 4294901244, 5", x, y, z)
   243  	}
   244  	if len(s) != 0 {
   245  		t.Errorf("len(s) = %d, want 0", len(s))
   246  	}
   247  }
   248  
   249  func TestUint8LengthPrefixedSimple(t *testing.T) {
   250  	var b Builder
   251  	b.AddUint8LengthPrefixed(func(c *Builder) {
   252  		c.AddUint8(23)
   253  		c.AddUint8(42)
   254  	})
   255  	if err := builderBytesEq(&b, 2, 23, 42); err != nil {
   256  		t.Error(err)
   257  	}
   258  
   259  	var base, child String = b.BytesOrPanic(), nil
   260  	var x, y uint8
   261  	if !base.ReadUint8LengthPrefixed(&child) || !child.ReadUint8(&x) ||
   262  		!child.ReadUint8(&y) {
   263  		t.Error("parsing failed")
   264  	}
   265  	if x != 23 || y != 42 {
   266  		t.Errorf("want x, y == 23, 42; got %d, %d", x, y)
   267  	}
   268  	if len(base) != 0 {
   269  		t.Errorf("len(base) = %d, want 0", len(base))
   270  	}
   271  	if len(child) != 0 {
   272  		t.Errorf("len(child) = %d, want 0", len(child))
   273  	}
   274  }
   275  
   276  func TestUint8LengthPrefixedMulti(t *testing.T) {
   277  	var b Builder
   278  	b.AddUint8LengthPrefixed(func(c *Builder) {
   279  		c.AddUint8(23)
   280  		c.AddUint8(42)
   281  	})
   282  	b.AddUint8(5)
   283  	b.AddUint8LengthPrefixed(func(c *Builder) {
   284  		c.AddUint8(123)
   285  		c.AddUint8(234)
   286  	})
   287  	if err := builderBytesEq(&b, 2, 23, 42, 5, 2, 123, 234); err != nil {
   288  		t.Error(err)
   289  	}
   290  
   291  	var s, child String = b.BytesOrPanic(), nil
   292  	var u, v, w, x, y uint8
   293  	if !s.ReadUint8LengthPrefixed(&child) || !child.ReadUint8(&u) || !child.ReadUint8(&v) ||
   294  		!s.ReadUint8(&w) || !s.ReadUint8LengthPrefixed(&child) || !child.ReadUint8(&x) || !child.ReadUint8(&y) {
   295  		t.Error("parsing failed")
   296  	}
   297  	if u != 23 || v != 42 || w != 5 || x != 123 || y != 234 {
   298  		t.Errorf("u, v, w, x, y = %d, %d, %d, %d, %d; want 23, 42, 5, 123, 234",
   299  			u, v, w, x, y)
   300  	}
   301  	if len(s) != 0 {
   302  		t.Errorf("len(s) = %d, want 0", len(s))
   303  	}
   304  	if len(child) != 0 {
   305  		t.Errorf("len(child) = %d, want 0", len(child))
   306  	}
   307  }
   308  
   309  func TestUint8LengthPrefixedNested(t *testing.T) {
   310  	var b Builder
   311  	b.AddUint8LengthPrefixed(func(c *Builder) {
   312  		c.AddUint8(5)
   313  		c.AddUint8LengthPrefixed(func(d *Builder) {
   314  			d.AddUint8(23)
   315  			d.AddUint8(42)
   316  		})
   317  		c.AddUint8(123)
   318  	})
   319  	if err := builderBytesEq(&b, 5, 5, 2, 23, 42, 123); err != nil {
   320  		t.Error(err)
   321  	}
   322  
   323  	var base, child1, child2 String = b.BytesOrPanic(), nil, nil
   324  	var u, v, w, x uint8
   325  	if !base.ReadUint8LengthPrefixed(&child1) {
   326  		t.Error("parsing base failed")
   327  	}
   328  	if !child1.ReadUint8(&u) || !child1.ReadUint8LengthPrefixed(&child2) || !child1.ReadUint8(&x) {
   329  		t.Error("parsing child1 failed")
   330  	}
   331  	if !child2.ReadUint8(&v) || !child2.ReadUint8(&w) {
   332  		t.Error("parsing child2 failed")
   333  	}
   334  	if u != 5 || v != 23 || w != 42 || x != 123 {
   335  		t.Errorf("u, v, w, x = %d, %d, %d, %d, want 5, 23, 42, 123",
   336  			u, v, w, x)
   337  	}
   338  	if len(base) != 0 {
   339  		t.Errorf("len(base) = %d, want 0", len(base))
   340  	}
   341  	if len(child1) != 0 {
   342  		t.Errorf("len(child1) = %d, want 0", len(child1))
   343  	}
   344  	if len(base) != 0 {
   345  		t.Errorf("len(child2) = %d, want 0", len(child2))
   346  	}
   347  }
   348  
   349  func TestPreallocatedBuffer(t *testing.T) {
   350  	var buf [5]byte
   351  	b := NewBuilder(buf[0:0])
   352  	b.AddUint8(1)
   353  	b.AddUint8LengthPrefixed(func(c *Builder) {
   354  		c.AddUint8(3)
   355  		c.AddUint8(4)
   356  	})
   357  	b.AddUint16(1286) // Outgrow buf by one byte.
   358  	want := []byte{1, 2, 3, 4, 0}
   359  	if !bytes.Equal(buf[:], want) {
   360  		t.Errorf("buf = %v want %v", buf, want)
   361  	}
   362  	if err := builderBytesEq(b, 1, 2, 3, 4, 5, 6); err != nil {
   363  		t.Error(err)
   364  	}
   365  }
   366  
   367  func TestWriteWithPendingChild(t *testing.T) {
   368  	var b Builder
   369  	b.AddUint8LengthPrefixed(func(c *Builder) {
   370  		c.AddUint8LengthPrefixed(func(d *Builder) {
   371  			func() {
   372  				defer func() {
   373  					if recover() == nil {
   374  						t.Errorf("recover() = nil, want error; c.AddUint8() did not panic")
   375  					}
   376  				}()
   377  				c.AddUint8(2) // panics
   378  			}()
   379  
   380  			defer func() {
   381  				if recover() == nil {
   382  					t.Errorf("recover() = nil, want error; b.AddUint8() did not panic")
   383  				}
   384  			}()
   385  			b.AddUint8(2) // panics
   386  		})
   387  
   388  		defer func() {
   389  			if recover() == nil {
   390  				t.Errorf("recover() = nil, want error; b.AddUint8() did not panic")
   391  			}
   392  		}()
   393  		b.AddUint8(2) // panics
   394  	})
   395  }
   396  
   397  func TestSetError(t *testing.T) {
   398  	const errorStr = "TestSetError"
   399  	var b Builder
   400  	b.SetError(errors.New(errorStr))
   401  
   402  	ret, err := b.Bytes()
   403  	if ret != nil {
   404  		t.Error("expected nil result")
   405  	}
   406  	if err == nil {
   407  		t.Fatal("unexpected nil error")
   408  	}
   409  	if s := err.Error(); s != errorStr {
   410  		t.Errorf("expected error %q, got %v", errorStr, s)
   411  	}
   412  }
   413  
   414  func TestUnwrite(t *testing.T) {
   415  	var b Builder
   416  	b.AddBytes([]byte{1, 2, 3, 4, 5})
   417  	b.Unwrite(2)
   418  	if err := builderBytesEq(&b, 1, 2, 3); err != nil {
   419  		t.Error(err)
   420  	}
   421  
   422  	func() {
   423  		defer func() {
   424  			if recover() == nil {
   425  				t.Errorf("recover() = nil, want error; b.Unwrite() did not panic")
   426  			}
   427  		}()
   428  		b.Unwrite(4) // panics
   429  	}()
   430  
   431  	b = Builder{}
   432  	b.AddBytes([]byte{1, 2, 3, 4, 5})
   433  	b.AddUint8LengthPrefixed(func(b *Builder) {
   434  		b.AddBytes([]byte{1, 2, 3, 4, 5})
   435  
   436  		defer func() {
   437  			if recover() == nil {
   438  				t.Errorf("recover() = nil, want error; b.Unwrite() did not panic")
   439  			}
   440  		}()
   441  		b.Unwrite(6) // panics
   442  	})
   443  
   444  	b = Builder{}
   445  	b.AddBytes([]byte{1, 2, 3, 4, 5})
   446  	b.AddUint8LengthPrefixed(func(c *Builder) {
   447  		defer func() {
   448  			if recover() == nil {
   449  				t.Errorf("recover() = nil, want error; b.Unwrite() did not panic")
   450  			}
   451  		}()
   452  		b.Unwrite(2) // panics (attempted unwrite while child is pending)
   453  	})
   454  }
   455  
   456  func TestFixedBuilderLengthPrefixed(t *testing.T) {
   457  	bufCap := 10
   458  	inner := bytes.Repeat([]byte{0xff}, bufCap-2)
   459  	buf := make([]byte, 0, bufCap)
   460  	b := NewFixedBuilder(buf)
   461  	b.AddUint16LengthPrefixed(func(b *Builder) {
   462  		b.AddBytes(inner)
   463  	})
   464  	if got := b.BytesOrPanic(); len(got) != bufCap {
   465  		t.Errorf("Expected output length to be %d, got %d", bufCap, len(got))
   466  	}
   467  }
   468  
   469  func TestFixedBuilderPanicReallocate(t *testing.T) {
   470  	defer func() {
   471  		recover()
   472  	}()
   473  
   474  	b := NewFixedBuilder(make([]byte, 0, 10))
   475  	b1 := NewFixedBuilder(make([]byte, 0, 10))
   476  	b.AddUint16LengthPrefixed(func(b *Builder) {
   477  		*b = *b1
   478  	})
   479  
   480  	t.Error("Builder did not panic")
   481  }
   482  
   483  // ASN.1
   484  
   485  func TestASN1Int64(t *testing.T) {
   486  	tests := []struct {
   487  		in   int64
   488  		want []byte
   489  	}{
   490  		{-0x800000, []byte{2, 3, 128, 0, 0}},
   491  		{-256, []byte{2, 2, 255, 0}},
   492  		{-129, []byte{2, 2, 255, 127}},
   493  		{-128, []byte{2, 1, 128}},
   494  		{-1, []byte{2, 1, 255}},
   495  		{0, []byte{2, 1, 0}},
   496  		{1, []byte{2, 1, 1}},
   497  		{2, []byte{2, 1, 2}},
   498  		{127, []byte{2, 1, 127}},
   499  		{128, []byte{2, 2, 0, 128}},
   500  		{256, []byte{2, 2, 1, 0}},
   501  		{0x800000, []byte{2, 4, 0, 128, 0, 0}},
   502  	}
   503  	for i, tt := range tests {
   504  		var b Builder
   505  		b.AddASN1Int64(tt.in)
   506  		if err := builderBytesEq(&b, tt.want...); err != nil {
   507  			t.Errorf("%v, (i = %d; in = %v)", err, i, tt.in)
   508  		}
   509  
   510  		var n int64
   511  		s := String(b.BytesOrPanic())
   512  		ok := s.ReadASN1Integer(&n)
   513  		if !ok || n != tt.in {
   514  			t.Errorf("s.ReadASN1Integer(&n) = %v, n = %d; want true, n = %d (i = %d)",
   515  				ok, n, tt.in, i)
   516  		}
   517  		if len(s) != 0 {
   518  			t.Errorf("len(s) = %d, want 0", len(s))
   519  		}
   520  	}
   521  }
   522  
   523  func TestASN1Uint64(t *testing.T) {
   524  	tests := []struct {
   525  		in   uint64
   526  		want []byte
   527  	}{
   528  		{0, []byte{2, 1, 0}},
   529  		{1, []byte{2, 1, 1}},
   530  		{2, []byte{2, 1, 2}},
   531  		{127, []byte{2, 1, 127}},
   532  		{128, []byte{2, 2, 0, 128}},
   533  		{256, []byte{2, 2, 1, 0}},
   534  		{0x800000, []byte{2, 4, 0, 128, 0, 0}},
   535  		{0x7fffffffffffffff, []byte{2, 8, 127, 255, 255, 255, 255, 255, 255, 255}},
   536  		{0x8000000000000000, []byte{2, 9, 0, 128, 0, 0, 0, 0, 0, 0, 0}},
   537  		{0xffffffffffffffff, []byte{2, 9, 0, 255, 255, 255, 255, 255, 255, 255, 255}},
   538  	}
   539  	for i, tt := range tests {
   540  		var b Builder
   541  		b.AddASN1Uint64(tt.in)
   542  		if err := builderBytesEq(&b, tt.want...); err != nil {
   543  			t.Errorf("%v, (i = %d; in = %v)", err, i, tt.in)
   544  		}
   545  
   546  		var n uint64
   547  		s := String(b.BytesOrPanic())
   548  		ok := s.ReadASN1Integer(&n)
   549  		if !ok || n != tt.in {
   550  			t.Errorf("s.ReadASN1Integer(&n) = %v, n = %d; want true, n = %d (i = %d)",
   551  				ok, n, tt.in, i)
   552  		}
   553  		if len(s) != 0 {
   554  			t.Errorf("len(s) = %d, want 0", len(s))
   555  		}
   556  	}
   557  }
   558  

View as plain text