...

Source file src/github.com/google/certificate-transparency-go/asn1/asn1_test.go

Documentation: github.com/google/certificate-transparency-go/asn1

     1  // Copyright 2009 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 asn1
     6  
     7  import (
     8  	"bytes"
     9  	"encoding/hex"
    10  	"fmt"
    11  	"math"
    12  	"math/big"
    13  	"reflect"
    14  	"strings"
    15  	"testing"
    16  	"time"
    17  )
    18  
    19  type boolTest struct {
    20  	in  []byte
    21  	ok  bool
    22  	out bool
    23  }
    24  
    25  var boolTestData = []boolTest{
    26  	{[]byte{0x00}, true, false},
    27  	{[]byte{0xff}, true, true},
    28  	{[]byte{0x00, 0x00}, false, false},
    29  	{[]byte{0xff, 0xff}, false, false},
    30  	{[]byte{0x01}, false, false},
    31  }
    32  
    33  func TestParseBool(t *testing.T) {
    34  	for i, test := range boolTestData {
    35  		ret, err := parseBool(test.in, "fieldname")
    36  		if (err == nil) != test.ok {
    37  			t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok)
    38  		}
    39  		if test.ok && ret != test.out {
    40  			t.Errorf("#%d: Bad result: %v (expected %v)", i, ret, test.out)
    41  		}
    42  	}
    43  }
    44  
    45  type int64Test struct {
    46  	in    []byte
    47  	ok    bool
    48  	okLax bool
    49  	out   int64
    50  }
    51  
    52  var int64TestData = []int64Test{
    53  	{[]byte{0x00}, true, true, 0},
    54  	{[]byte{0x7f}, true, true, 127},
    55  	{[]byte{0x00, 0x80}, true, true, 128},
    56  	{[]byte{0x01, 0x00}, true, true, 256},
    57  	{[]byte{0x80}, true, true, -128},
    58  	{[]byte{0xff, 0x7f}, true, true, -129},
    59  	{[]byte{0xff}, true, true, -1},
    60  	{[]byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, true, true, -9223372036854775808},
    61  	{[]byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, false, false, 0},
    62  	{[]byte{}, false, false, 0},
    63  	{[]byte{0x00, 0x7f}, false, true, 127},
    64  	{[]byte{0xff, 0xf0}, false, true, -16},
    65  }
    66  
    67  func TestParseInt64(t *testing.T) {
    68  	for i, test := range int64TestData {
    69  		ret, err := parseInt64(test.in, false, "fieldname")
    70  		if (err == nil) != test.ok {
    71  			t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok)
    72  		}
    73  		if test.ok && ret != test.out {
    74  			t.Errorf("#%d: Bad result: %v (expected %v)", i, ret, test.out)
    75  		}
    76  
    77  		ret, err = parseInt64(test.in, true, "fieldname")
    78  		if (err == nil) != test.okLax {
    79  			t.Errorf("#%d: Incorrect lax error result (did fail? %v, expected: %v)", i, err == nil, test.okLax)
    80  		}
    81  		if test.okLax && ret != test.out {
    82  			t.Errorf("#%d: Bad lax result: %v (expected %v)", i, ret, test.out)
    83  		}
    84  	}
    85  }
    86  
    87  type int32Test struct {
    88  	in    []byte
    89  	ok    bool
    90  	okLax bool
    91  	out   int32
    92  }
    93  
    94  var int32TestData = []int32Test{
    95  	{[]byte{0x00}, true, true, 0},
    96  	{[]byte{0x7f}, true, true, 127},
    97  	{[]byte{0x00, 0x80}, true, true, 128},
    98  	{[]byte{0x01, 0x00}, true, true, 256},
    99  	{[]byte{0x80}, true, true, -128},
   100  	{[]byte{0xff, 0x7f}, true, true, -129},
   101  	{[]byte{0xff}, true, true, -1},
   102  	{[]byte{0x80, 0x00, 0x00, 0x00}, true, true, -2147483648},
   103  	{[]byte{0x80, 0x00, 0x00, 0x00, 0x00}, false, false, 0},
   104  	{[]byte{}, false, false, 0},
   105  	{[]byte{0x00, 0x7f}, false, true, 127},
   106  	{[]byte{0xff, 0xf0}, false, true, -16},
   107  }
   108  
   109  func TestParseInt32(t *testing.T) {
   110  	for i, test := range int32TestData {
   111  		ret, err := parseInt32(test.in, false, "fieldname")
   112  		if (err == nil) != test.ok {
   113  			t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok)
   114  		}
   115  		if test.ok && int32(ret) != test.out {
   116  			t.Errorf("#%d: Bad result: %v (expected %v)", i, ret, test.out)
   117  		}
   118  
   119  		ret, err = parseInt32(test.in, true, "fieldname")
   120  		if (err == nil) != test.okLax {
   121  			t.Errorf("#%d: Incorrect lax error result (did fail? %v, expected: %v)", i, err == nil, test.okLax)
   122  		}
   123  		if test.okLax && int32(ret) != test.out {
   124  			t.Errorf("#%d: Bad lax result: %v (expected %v)", i, ret, test.out)
   125  		}
   126  	}
   127  }
   128  
   129  var bigIntTests = []struct {
   130  	in     []byte
   131  	ok     bool
   132  	okLax  bool
   133  	base10 string
   134  }{
   135  	{[]byte{0xff}, true, true, "-1"},
   136  	{[]byte{0x00}, true, true, "0"},
   137  	{[]byte{0x01}, true, true, "1"},
   138  	{[]byte{0x00, 0xff}, true, true, "255"},
   139  	{[]byte{0xff, 0x00}, true, true, "-256"},
   140  	{[]byte{0x01, 0x00}, true, true, "256"},
   141  	{[]byte{}, false, false, ""},
   142  	{[]byte{0x00, 0x7f}, false, true, "127"},
   143  	{[]byte{0xff, 0xf0}, false, true, "-16"},
   144  }
   145  
   146  func TestParseBigInt(t *testing.T) {
   147  	for i, test := range bigIntTests {
   148  		ret, err := parseBigInt(test.in, false, "fieldname")
   149  		if (err == nil) != test.ok {
   150  			t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok)
   151  		}
   152  		if test.ok {
   153  			if ret.String() != test.base10 {
   154  				t.Errorf("#%d: bad result from %x, got %s want %s", i, test.in, ret.String(), test.base10)
   155  			}
   156  			e, err := makeBigInt(ret, "fieldname")
   157  			if err != nil {
   158  				t.Errorf("%d: err=%q", i, err)
   159  				continue
   160  			}
   161  			result := make([]byte, e.Len())
   162  			e.Encode(result)
   163  			if !bytes.Equal(result, test.in) {
   164  				t.Errorf("#%d: got %x from marshaling %s, want %x", i, result, ret, test.in)
   165  			}
   166  		}
   167  
   168  		ret, err = parseBigInt(test.in, true, "fieldname")
   169  		if (err == nil) != test.okLax {
   170  			t.Errorf("#%d: Incorrect lax error result (did fail? %v, expected: %v)", i, err == nil, test.okLax)
   171  		}
   172  		if test.okLax {
   173  			if ret.String() != test.base10 {
   174  				t.Errorf("#%d: bad result from %x, got %s want %s", i, test.in, ret.String(), test.base10)
   175  			}
   176  		}
   177  	}
   178  }
   179  
   180  type bitStringTest struct {
   181  	in        []byte
   182  	ok        bool
   183  	out       []byte
   184  	bitLength int
   185  }
   186  
   187  var bitStringTestData = []bitStringTest{
   188  	{[]byte{}, false, []byte{}, 0},
   189  	{[]byte{0x00}, true, []byte{}, 0},
   190  	{[]byte{0x07, 0x00}, true, []byte{0x00}, 1},
   191  	{[]byte{0x07, 0x01}, false, []byte{}, 0},
   192  	{[]byte{0x07, 0x40}, false, []byte{}, 0},
   193  	{[]byte{0x08, 0x00}, false, []byte{}, 0},
   194  }
   195  
   196  func TestBitString(t *testing.T) {
   197  	for i, test := range bitStringTestData {
   198  		ret, err := parseBitString(test.in, "fieldname")
   199  		if (err == nil) != test.ok {
   200  			t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok)
   201  		}
   202  		if err == nil {
   203  			if test.bitLength != ret.BitLength || !bytes.Equal(ret.Bytes, test.out) {
   204  				t.Errorf("#%d: Bad result: %v (expected %v %v)", i, ret, test.out, test.bitLength)
   205  			}
   206  		}
   207  	}
   208  }
   209  
   210  func TestBitStringAt(t *testing.T) {
   211  	bs := BitString{[]byte{0x82, 0x40}, 16}
   212  	if bs.At(0) != 1 {
   213  		t.Error("#1: Failed")
   214  	}
   215  	if bs.At(1) != 0 {
   216  		t.Error("#2: Failed")
   217  	}
   218  	if bs.At(6) != 1 {
   219  		t.Error("#3: Failed")
   220  	}
   221  	if bs.At(9) != 1 {
   222  		t.Error("#4: Failed")
   223  	}
   224  	if bs.At(-1) != 0 {
   225  		t.Error("#5: Failed")
   226  	}
   227  	if bs.At(17) != 0 {
   228  		t.Error("#6: Failed")
   229  	}
   230  }
   231  
   232  type bitStringRightAlignTest struct {
   233  	in    []byte
   234  	inlen int
   235  	out   []byte
   236  }
   237  
   238  var bitStringRightAlignTests = []bitStringRightAlignTest{
   239  	{[]byte{0x80}, 1, []byte{0x01}},
   240  	{[]byte{0x80, 0x80}, 9, []byte{0x01, 0x01}},
   241  	{[]byte{}, 0, []byte{}},
   242  	{[]byte{0xce}, 8, []byte{0xce}},
   243  	{[]byte{0xce, 0x47}, 16, []byte{0xce, 0x47}},
   244  	{[]byte{0x34, 0x50}, 12, []byte{0x03, 0x45}},
   245  }
   246  
   247  func TestBitStringRightAlign(t *testing.T) {
   248  	for i, test := range bitStringRightAlignTests {
   249  		bs := BitString{test.in, test.inlen}
   250  		out := bs.RightAlign()
   251  		if !bytes.Equal(out, test.out) {
   252  			t.Errorf("#%d got: %x want: %x", i, out, test.out)
   253  		}
   254  	}
   255  }
   256  
   257  type objectIdentifierTest struct {
   258  	in  []byte
   259  	lax bool
   260  	ok  bool
   261  	out ObjectIdentifier // has base type[]int
   262  }
   263  
   264  var objectIdentifierTestData = []objectIdentifierTest{
   265  	{in: []byte{}, ok: false},
   266  	{in: []byte{}, lax: true, ok: true, out: []int{}},
   267  	{in: []byte{85}, ok: true, out: []int{2, 5}},
   268  	{in: []byte{85, 0x02}, ok: true, out: []int{2, 5, 2}},
   269  	{in: []byte{85, 0x02, 0xc0, 0x00}, ok: true, out: []int{2, 5, 2, 0x2000}},
   270  	{in: []byte{0x81, 0x34, 0x03}, ok: true, out: []int{2, 100, 3}},
   271  	{in: []byte{85, 0x02, 0xc0, 0x80, 0x80, 0x80, 0x80}, ok: false},
   272  }
   273  
   274  func TestObjectIdentifier(t *testing.T) {
   275  	for i, test := range objectIdentifierTestData {
   276  		ret, err := parseObjectIdentifier(test.in, test.lax, "fieldname")
   277  		if (err == nil) != test.ok {
   278  			t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok)
   279  		}
   280  		if err == nil {
   281  			if !reflect.DeepEqual(test.out, ret) {
   282  				t.Errorf("#%d: Bad result: %v (expected %v)", i, ret, test.out)
   283  			}
   284  		}
   285  	}
   286  
   287  	if s := ObjectIdentifier([]int{1, 2, 3, 4}).String(); s != "1.2.3.4" {
   288  		t.Errorf("bad ObjectIdentifier.String(). Got %s, want 1.2.3.4", s)
   289  	}
   290  }
   291  
   292  type timeTest struct {
   293  	in  string
   294  	ok  bool
   295  	out time.Time
   296  }
   297  
   298  var utcTestData = []timeTest{
   299  	{"910506164540-0700", true, time.Date(1991, 05, 06, 16, 45, 40, 0, time.FixedZone("", -7*60*60))},
   300  	{"910506164540+0730", true, time.Date(1991, 05, 06, 16, 45, 40, 0, time.FixedZone("", 7*60*60+30*60))},
   301  	{"910506234540Z", true, time.Date(1991, 05, 06, 23, 45, 40, 0, time.UTC)},
   302  	{"9105062345Z", true, time.Date(1991, 05, 06, 23, 45, 0, 0, time.UTC)},
   303  	{"5105062345Z", true, time.Date(1951, 05, 06, 23, 45, 0, 0, time.UTC)},
   304  	{"a10506234540Z", false, time.Time{}},
   305  	{"91a506234540Z", false, time.Time{}},
   306  	{"9105a6234540Z", false, time.Time{}},
   307  	{"910506a34540Z", false, time.Time{}},
   308  	{"910506334a40Z", false, time.Time{}},
   309  	{"91050633444aZ", false, time.Time{}},
   310  	{"910506334461Z", false, time.Time{}},
   311  	{"910506334400Za", false, time.Time{}},
   312  	/* These are invalid times. However, the time package normalises times
   313  	 * and they were accepted in some versions. See #11134. */
   314  	{"000100000000Z", false, time.Time{}},
   315  	{"101302030405Z", false, time.Time{}},
   316  	{"100002030405Z", false, time.Time{}},
   317  	{"100100030405Z", false, time.Time{}},
   318  	{"100132030405Z", false, time.Time{}},
   319  	{"100231030405Z", false, time.Time{}},
   320  	{"100102240405Z", false, time.Time{}},
   321  	{"100102036005Z", false, time.Time{}},
   322  	{"100102030460Z", false, time.Time{}},
   323  	{"-100102030410Z", false, time.Time{}},
   324  	{"10-0102030410Z", false, time.Time{}},
   325  	{"10-0002030410Z", false, time.Time{}},
   326  	{"1001-02030410Z", false, time.Time{}},
   327  	{"100102-030410Z", false, time.Time{}},
   328  	{"10010203-0410Z", false, time.Time{}},
   329  	{"1001020304-10Z", false, time.Time{}},
   330  }
   331  
   332  func TestUTCTime(t *testing.T) {
   333  	for i, test := range utcTestData {
   334  		ret, err := parseUTCTime([]byte(test.in))
   335  		if err != nil {
   336  			if test.ok {
   337  				t.Errorf("#%d: parseUTCTime(%q) = error %v", i, test.in, err)
   338  			}
   339  			continue
   340  		}
   341  		if !test.ok {
   342  			t.Errorf("#%d: parseUTCTime(%q) succeeded, should have failed", i, test.in)
   343  			continue
   344  		}
   345  		const format = "Jan _2 15:04:05 -0700 2006" // ignore zone name, just offset
   346  		have := ret.Format(format)
   347  		want := test.out.Format(format)
   348  		if have != want {
   349  			t.Errorf("#%d: parseUTCTime(%q) = %s, want %s", i, test.in, have, want)
   350  		}
   351  	}
   352  }
   353  
   354  var generalizedTimeTestData = []timeTest{
   355  	{"20100102030405Z", true, time.Date(2010, 01, 02, 03, 04, 05, 0, time.UTC)},
   356  	{"20100102030405", false, time.Time{}},
   357  	{"20100102030405+0607", true, time.Date(2010, 01, 02, 03, 04, 05, 0, time.FixedZone("", 6*60*60+7*60))},
   358  	{"20100102030405-0607", true, time.Date(2010, 01, 02, 03, 04, 05, 0, time.FixedZone("", -6*60*60-7*60))},
   359  	/* These are invalid times. However, the time package normalises times
   360  	 * and they were accepted in some versions. See #11134. */
   361  	{"00000100000000Z", false, time.Time{}},
   362  	{"20101302030405Z", false, time.Time{}},
   363  	{"20100002030405Z", false, time.Time{}},
   364  	{"20100100030405Z", false, time.Time{}},
   365  	{"20100132030405Z", false, time.Time{}},
   366  	{"20100231030405Z", false, time.Time{}},
   367  	{"20100102240405Z", false, time.Time{}},
   368  	{"20100102036005Z", false, time.Time{}},
   369  	{"20100102030460Z", false, time.Time{}},
   370  	{"-20100102030410Z", false, time.Time{}},
   371  	{"2010-0102030410Z", false, time.Time{}},
   372  	{"2010-0002030410Z", false, time.Time{}},
   373  	{"201001-02030410Z", false, time.Time{}},
   374  	{"20100102-030410Z", false, time.Time{}},
   375  	{"2010010203-0410Z", false, time.Time{}},
   376  	{"201001020304-10Z", false, time.Time{}},
   377  }
   378  
   379  func TestGeneralizedTime(t *testing.T) {
   380  	for i, test := range generalizedTimeTestData {
   381  		ret, err := parseGeneralizedTime([]byte(test.in))
   382  		if (err == nil) != test.ok {
   383  			t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok)
   384  		}
   385  		if err == nil {
   386  			if !reflect.DeepEqual(test.out, ret) {
   387  				t.Errorf("#%d: Bad result: %q → %v (expected %v)", i, test.in, ret, test.out)
   388  			}
   389  		}
   390  	}
   391  }
   392  
   393  type tagAndLengthTest struct {
   394  	in  []byte
   395  	ok  bool
   396  	out tagAndLength
   397  }
   398  
   399  var tagAndLengthData = []tagAndLengthTest{
   400  	{[]byte{0x80, 0x01}, true, tagAndLength{2, 0, 1, false}},
   401  	{[]byte{0xa0, 0x01}, true, tagAndLength{2, 0, 1, true}},
   402  	{[]byte{0x02, 0x00}, true, tagAndLength{0, 2, 0, false}},
   403  	{[]byte{0xfe, 0x00}, true, tagAndLength{3, 30, 0, true}},
   404  	{[]byte{0x1f, 0x1f, 0x00}, true, tagAndLength{0, 31, 0, false}},
   405  	{[]byte{0x1f, 0x81, 0x00, 0x00}, true, tagAndLength{0, 128, 0, false}},
   406  	{[]byte{0x1f, 0x81, 0x80, 0x01, 0x00}, true, tagAndLength{0, 0x4001, 0, false}},
   407  	{[]byte{0x00, 0x81, 0x80}, true, tagAndLength{0, 0, 128, false}},
   408  	{[]byte{0x00, 0x82, 0x01, 0x00}, true, tagAndLength{0, 0, 256, false}},
   409  	{[]byte{0x00, 0x83, 0x01, 0x00}, false, tagAndLength{}},
   410  	{[]byte{0x1f, 0x85}, false, tagAndLength{}},
   411  	{[]byte{0x30, 0x80}, false, tagAndLength{}},
   412  	// Superfluous zeros in the length should be an error.
   413  	{[]byte{0xa0, 0x82, 0x00, 0xff}, false, tagAndLength{}},
   414  	// Lengths up to the maximum size of an int should work.
   415  	{[]byte{0xa0, 0x84, 0x7f, 0xff, 0xff, 0xff}, true, tagAndLength{2, 0, 0x7fffffff, true}},
   416  	// Lengths that would overflow an int should be rejected.
   417  	{[]byte{0xa0, 0x84, 0x80, 0x00, 0x00, 0x00}, false, tagAndLength{}},
   418  	// Long length form may not be used for lengths that fit in short form.
   419  	{[]byte{0xa0, 0x81, 0x7f}, false, tagAndLength{}},
   420  	// Tag numbers which would overflow int32 are rejected. (The value below is 2^31.)
   421  	{[]byte{0x1f, 0x88, 0x80, 0x80, 0x80, 0x00, 0x00}, false, tagAndLength{}},
   422  	// Tag numbers that fit in an int32 are valid. (The value below is 2^31 - 1.)
   423  	{[]byte{0x1f, 0x87, 0xFF, 0xFF, 0xFF, 0x7F, 0x00}, true, tagAndLength{tag: math.MaxInt32}},
   424  	// Long tag number form may not be used for tags that fit in short form.
   425  	{[]byte{0x1f, 0x1e, 0x00}, false, tagAndLength{}},
   426  }
   427  
   428  func TestParseTagAndLength(t *testing.T) {
   429  	for i, test := range tagAndLengthData {
   430  		tagAndLength, _, err := parseTagAndLength(test.in, 0, "fieldname")
   431  		if (err == nil) != test.ok {
   432  			t.Errorf("#%d: Incorrect error result (did pass? %v, expected: %v)", i, err == nil, test.ok)
   433  		}
   434  		if err == nil && !reflect.DeepEqual(test.out, tagAndLength) {
   435  			t.Errorf("#%d: Bad result: %v (expected %v)", i, tagAndLength, test.out)
   436  		}
   437  	}
   438  }
   439  
   440  type parseFieldParametersTest struct {
   441  	in  string
   442  	out fieldParameters
   443  }
   444  
   445  func newInt(n int) *int { return &n }
   446  
   447  func newInt64(n int64) *int64 { return &n }
   448  
   449  func newString(s string) *string { return &s }
   450  
   451  func newBool(b bool) *bool { return &b }
   452  
   453  var parseFieldParametersTestData = []parseFieldParametersTest{
   454  	{"", fieldParameters{}},
   455  	{"ia5", fieldParameters{stringType: TagIA5String}},
   456  	{"generalized", fieldParameters{timeType: TagGeneralizedTime}},
   457  	{"utc", fieldParameters{timeType: TagUTCTime}},
   458  	{"printable", fieldParameters{stringType: TagPrintableString}},
   459  	{"numeric", fieldParameters{stringType: TagNumericString}},
   460  	{"optional", fieldParameters{optional: true}},
   461  	{"explicit", fieldParameters{explicit: true, tag: new(int)}},
   462  	{"application", fieldParameters{application: true, tag: new(int)}},
   463  	{"private", fieldParameters{private: true, tag: new(int)}},
   464  	{"optional,explicit", fieldParameters{optional: true, explicit: true, tag: new(int)}},
   465  	{"default:42", fieldParameters{defaultValue: newInt64(42)}},
   466  	{"tag:17", fieldParameters{tag: newInt(17)}},
   467  	{"lax", fieldParameters{lax: true}},
   468  	{"optional,explicit,default:42,tag:17",
   469  		fieldParameters{optional: true, explicit: true, defaultValue: newInt64(42), tag: newInt(17)}},
   470  	{"optional,explicit,default:42,tag:17,rubbish1",
   471  		fieldParameters{optional: true, explicit: true, defaultValue: newInt64(42), tag: newInt(17)}},
   472  	{"set", fieldParameters{set: true}},
   473  }
   474  
   475  func TestParseFieldParameters(t *testing.T) {
   476  	for i, test := range parseFieldParametersTestData {
   477  		f := parseFieldParameters(test.in)
   478  		if !reflect.DeepEqual(f, test.out) {
   479  			t.Errorf("#%d: Bad result: %v (expected %v)", i, f, test.out)
   480  		}
   481  	}
   482  }
   483  
   484  type TestObjectIdentifierStruct struct {
   485  	OID ObjectIdentifier
   486  }
   487  
   488  type TestContextSpecificTags struct {
   489  	A int `asn1:"tag:1"`
   490  }
   491  
   492  type TestContextSpecificTags2 struct {
   493  	A int `asn1:"explicit,tag:1"`
   494  	B int
   495  }
   496  
   497  type TestContextSpecificTags3 struct {
   498  	S string `asn1:"tag:1,utf8"`
   499  }
   500  
   501  type TestElementsAfterString struct {
   502  	S    string
   503  	A, B int
   504  }
   505  
   506  type TestBigInt struct {
   507  	X *big.Int
   508  }
   509  
   510  type TestSet struct {
   511  	Ints []int `asn1:"set"`
   512  }
   513  
   514  type TestAuthKeyID struct {
   515  	ID           []byte   `asn1:"optional,tag:0"`
   516  	Issuer       RawValue `asn1:"optional,tag:1"`
   517  	SerialNumber *big.Int `asn1:"optional,tag:2"`
   518  }
   519  
   520  type TestSetOfAny struct {
   521  	Values anySET
   522  }
   523  type anySET []RawValue
   524  
   525  var unmarshalTestData = []struct {
   526  	in     []byte
   527  	params string
   528  	out    interface{}
   529  }{
   530  	{[]byte{0x02, 0x01, 0x42}, "", newInt(0x42)},
   531  	{[]byte{0x05, 0x00}, "", &RawValue{0, 5, false, []byte{}, []byte{0x05, 0x00}}},
   532  	{[]byte{0x30, 0x08, 0x06, 0x06, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d}, "", &TestObjectIdentifierStruct{[]int{1, 2, 840, 113549}}},
   533  	{[]byte{0x03, 0x04, 0x06, 0x6e, 0x5d, 0xc0}, "", &BitString{[]byte{110, 93, 192}, 18}},
   534  	{[]byte{0x30, 0x09, 0x02, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, 0x01, 0x03}, "", &[]int{1, 2, 3}},
   535  	{[]byte{0x02, 0x01, 0x10}, "", newInt(16)},
   536  	{[]byte{0x13, 0x04, 't', 'e', 's', 't'}, "", newString("test")},
   537  	{[]byte{0x16, 0x04, 't', 'e', 's', 't'}, "", newString("test")},
   538  	// Ampersand is allowed in PrintableString due to mistakes by major CAs.
   539  	{[]byte{0x13, 0x05, 't', 'e', 's', 't', '&'}, "", newString("test&")},
   540  	{[]byte{0x16, 0x04, 't', 'e', 's', 't'}, "", &RawValue{0, 22, false, []byte("test"), []byte("\x16\x04test")}},
   541  	{[]byte{0x04, 0x04, 1, 2, 3, 4}, "", &RawValue{0, 4, false, []byte{1, 2, 3, 4}, []byte{4, 4, 1, 2, 3, 4}}},
   542  	{[]byte{0x30, 0x03, 0x81, 0x01, 0x01}, "", &TestContextSpecificTags{1}},
   543  	{[]byte{0x30, 0x08, 0xa1, 0x03, 0x02, 0x01, 0x01, 0x02, 0x01, 0x02}, "", &TestContextSpecificTags2{1, 2}},
   544  	{[]byte{0x30, 0x03, 0x81, 0x01, '@'}, "", &TestContextSpecificTags3{"@"}},
   545  	{[]byte{0x01, 0x01, 0x00}, "", newBool(false)},
   546  	{[]byte{0x01, 0x01, 0xff}, "", newBool(true)},
   547  	{[]byte{0x30, 0x0b, 0x13, 0x03, 0x66, 0x6f, 0x6f, 0x02, 0x01, 0x22, 0x02, 0x01, 0x33}, "", &TestElementsAfterString{"foo", 0x22, 0x33}},
   548  	{[]byte{0x30, 0x05, 0x02, 0x03, 0x12, 0x34, 0x56}, "", &TestBigInt{big.NewInt(0x123456)}},
   549  	{[]byte{0x30, 0x0b, 0x31, 0x09, 0x02, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, 0x01, 0x03}, "", &TestSet{Ints: []int{1, 2, 3}}},
   550  	{[]byte{0x12, 0x0b, '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ' '}, "", newString("0123456789 ")},
   551  	{[]byte{0x30, 0x0e, 0x80, 0x04, 0x01, 0x02, 0x03, 0x04, 0x82, 0x06, 0x01, 0x22, 0x33, 0x44, 0x55, 0x66}, "",
   552  		&TestAuthKeyID{ID: []byte{0x01, 0x02, 0x03, 0x04}, SerialNumber: big.NewInt(0x12233445566)}},
   553  	{[]byte{0x30, 0x12,
   554  		0x80, 0x04, 0x01, 0x02, 0x03, 0x04,
   555  		0x81, 0x02, 0xFF, 0xFF,
   556  		0x82, 0x06, 0x01, 0x22, 0x33, 0x44, 0x55, 0x66}, "",
   557  		&TestAuthKeyID{
   558  			ID: []byte{0x01, 0x02, 0x03, 0x04},
   559  			Issuer: RawValue{
   560  				Class:      ClassContextSpecific,
   561  				Tag:        1,
   562  				IsCompound: false,
   563  				Bytes:      []byte{0xff, 0xff},
   564  				FullBytes:  []byte{0x81, 0x02, 0xff, 0xff},
   565  			},
   566  			SerialNumber: big.NewInt(0x12233445566),
   567  		}},
   568  	{[]byte{0x30, 0x06, 0x80, 0x04, 0x01, 0x02, 0x03, 0x04}, "", &TestAuthKeyID{ID: []byte{0x01, 0x02, 0x03, 0x04}}},
   569  	{[]byte{0x30, 0x05, 0x31, 0x03, 0x02, 0x01, 0x42}, "",
   570  		&TestSetOfAny{
   571  			Values: []RawValue{
   572  				RawValue{Class: 0, Tag: 2, Bytes: []byte{0x42}, FullBytes: []byte{0x02, 0x01, 0x42}},
   573  			},
   574  		},
   575  	},
   576  	// PrintableString that erroneously contains non-printable contents:
   577  	// 0xE9 is é in ISO8859-1, @ in T.61, taken to be the former.
   578  	{[]byte{0x13, 0x04, 'c', 'a', 'f', 0xE9}, "lax", newString("café")},
   579  	// 0xFB is û in ISO8859-1, ß in T.61, taken to be the former.
   580  	{[]byte{0x13, 0x04, 'a', 'b', 'c', 0xFB}, "lax", newString("abcû")},
   581  }
   582  
   583  func TestUnmarshal(t *testing.T) {
   584  	for i, test := range unmarshalTestData {
   585  		pv := reflect.New(reflect.TypeOf(test.out).Elem())
   586  		val := pv.Interface()
   587  		_, err := UnmarshalWithParams(test.in, val, test.params)
   588  		if err != nil {
   589  			t.Errorf("Unmarshal failed at index %d %v", i, err)
   590  		}
   591  		if !reflect.DeepEqual(val, test.out) {
   592  			t.Errorf("#%d:\nhave %#v\nwant %#v", i, val, test.out)
   593  		}
   594  	}
   595  }
   596  
   597  type stringHolder struct {
   598  	Value string
   599  }
   600  
   601  func TestLaxPropagate(t *testing.T) {
   602  	b := []byte{0x30, 0x06, // SEQUENCE length 6
   603  		0x13, 0x04, // PrintableString length 4
   604  		'c', 'a', 'f', 0xE9}
   605  	var got stringHolder
   606  
   607  	wantErr := "invalid character"
   608  	_, err := UnmarshalWithParams(b, &got, "")
   609  	if err == nil {
   610  		t.Errorf("Unmarshal()=_,nil; want _, err containing %q", wantErr)
   611  	} else if !strings.Contains(err.Error(), wantErr) {
   612  		t.Errorf("Unmarshal()=_,%v; want _, err containing %q", err, wantErr)
   613  	}
   614  
   615  	_, err = UnmarshalWithParams(b, &got, "lax")
   616  	if err != nil {
   617  		t.Errorf("Unmarshal(lax)=_,%v; want _, nil", err)
   618  	}
   619  	if want := "café"; got.Value != want {
   620  		t.Errorf("Unmarshal(lax)=%q; want %q", got.Value, want)
   621  	}
   622  }
   623  
   624  type Certificate struct {
   625  	TBSCertificate     TBSCertificate
   626  	SignatureAlgorithm AlgorithmIdentifier
   627  	SignatureValue     BitString
   628  }
   629  
   630  type TBSCertificate struct {
   631  	Version            int `asn1:"optional,explicit,default:0,tag:0"`
   632  	SerialNumber       RawValue
   633  	SignatureAlgorithm AlgorithmIdentifier
   634  	Issuer             RDNSequence
   635  	Validity           Validity
   636  	Subject            RDNSequence
   637  	PublicKey          PublicKeyInfo
   638  }
   639  
   640  type AlgorithmIdentifier struct {
   641  	Algorithm ObjectIdentifier
   642  }
   643  
   644  type RDNSequence []RelativeDistinguishedNameSET
   645  
   646  type RelativeDistinguishedNameSET []AttributeTypeAndValue
   647  
   648  type AttributeTypeAndValue struct {
   649  	Type  ObjectIdentifier
   650  	Value interface{}
   651  }
   652  
   653  type Validity struct {
   654  	NotBefore, NotAfter time.Time
   655  }
   656  
   657  type PublicKeyInfo struct {
   658  	Algorithm AlgorithmIdentifier
   659  	PublicKey BitString
   660  }
   661  
   662  func TestCertificate(t *testing.T) {
   663  	// This is a minimal, self-signed certificate that should parse correctly.
   664  	var cert Certificate
   665  	if _, err := Unmarshal(derEncodedSelfSignedCertBytes, &cert); err != nil {
   666  		t.Errorf("Unmarshal failed: %v", err)
   667  	}
   668  	if !reflect.DeepEqual(cert, derEncodedSelfSignedCert) {
   669  		t.Errorf("Bad result:\ngot: %+v\nwant: %+v", cert, derEncodedSelfSignedCert)
   670  	}
   671  }
   672  
   673  func TestCertificateWithNUL(t *testing.T) {
   674  	// This is the paypal NUL-hack certificate. It should fail to parse because
   675  	// NUL isn't a permitted character in a PrintableString.
   676  
   677  	var cert Certificate
   678  	if _, err := Unmarshal(derEncodedPaypalNULCertBytes, &cert); err == nil {
   679  		t.Error("Unmarshal succeeded, should not have")
   680  	}
   681  }
   682  
   683  type rawStructTest struct {
   684  	Raw RawContent
   685  	A   int
   686  }
   687  
   688  func TestRawStructs(t *testing.T) {
   689  	var s rawStructTest
   690  	input := []byte{0x30, 0x03, 0x02, 0x01, 0x50}
   691  
   692  	rest, err := Unmarshal(input, &s)
   693  	if len(rest) != 0 {
   694  		t.Errorf("incomplete parse: %x", rest)
   695  		return
   696  	}
   697  	if err != nil {
   698  		t.Error(err)
   699  		return
   700  	}
   701  	if s.A != 0x50 {
   702  		t.Errorf("bad value for A: got %d want %d", s.A, 0x50)
   703  	}
   704  	if !bytes.Equal([]byte(s.Raw), input) {
   705  		t.Errorf("bad value for Raw: got %x want %x", s.Raw, input)
   706  	}
   707  }
   708  
   709  func TestCouldBeISO8859_1(t *testing.T) {
   710  	for i := 0; i < 0xff; i++ {
   711  		b := []byte("StringWithA")
   712  		b = append(b, byte(i))
   713  		switch {
   714  		// These values are disallowed:
   715  		case i < 0x20, i >= 0x7f && i < 0xa0:
   716  			if couldBeISO8859_1(b) {
   717  				t.Fatalf("Allowed invalid value %d", i)
   718  			}
   719  
   720  		// These values are allowed:
   721  		case i >= 0x20 && i < 0x7f, i >= 0xa0 && i <= 0xff:
   722  			if !couldBeISO8859_1(b) {
   723  				t.Fatalf("Disallowed valid value %d", i)
   724  			}
   725  
   726  		default:
   727  			t.Fatalf("Test logic error - value %d not covered above", i)
   728  		}
   729  	}
   730  }
   731  
   732  func TestCouldBeT61(t *testing.T) {
   733  	for i := 0; i < 255; i++ {
   734  		b := []byte("StringWithA")
   735  		b = append(b, byte(i))
   736  
   737  		if couldBeT61(b) {
   738  			switch i {
   739  			case 0x00:
   740  				fallthrough
   741  			case 0x23, 0x24, 0x5C, 0x5E, 0x60, 0x7B, 0x7D, 0x7E, 0xA5, 0xA6, 0xAC, 0xAD, 0xAE, 0xAF,
   742  				0xB9, 0xBA, 0xC0, 0xC9, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9,
   743  				0xDA, 0xDB, 0xDC, 0xDE, 0xDF, 0xE5, 0xFF:
   744  				t.Fatalf("Allowed string with byte %d", i)
   745  			}
   746  		}
   747  	}
   748  }
   749  
   750  func TestISO8859_1ToUTF8(t *testing.T) {
   751  	b := []byte{'c', 'a', 'f', 0xE9} // 0xE9 == é in ISO8859-1, but is invalid in UTF8
   752  	if string(b) == "café" {
   753  		t.Fatal("Sanity failure: that shouldn't have matched")
   754  	}
   755  	if iso8859_1ToUTF8(b) != "café" {
   756  		t.Fatalf("Failed to convert properly, got %v", iso8859_1ToUTF8(b))
   757  	}
   758  }
   759  
   760  type oiEqualTest struct {
   761  	first  ObjectIdentifier
   762  	second ObjectIdentifier
   763  	same   bool
   764  }
   765  
   766  var oiEqualTests = []oiEqualTest{
   767  	{
   768  		ObjectIdentifier{1, 2, 3},
   769  		ObjectIdentifier{1, 2, 3},
   770  		true,
   771  	},
   772  	{
   773  		ObjectIdentifier{1},
   774  		ObjectIdentifier{1, 2, 3},
   775  		false,
   776  	},
   777  	{
   778  		ObjectIdentifier{1, 2, 3},
   779  		ObjectIdentifier{10, 11, 12},
   780  		false,
   781  	},
   782  }
   783  
   784  func TestObjectIdentifierEqual(t *testing.T) {
   785  	for _, o := range oiEqualTests {
   786  		if s := o.first.Equal(o.second); s != o.same {
   787  			t.Errorf("ObjectIdentifier.Equal: got: %t want: %t", s, o.same)
   788  		}
   789  	}
   790  }
   791  
   792  var derEncodedSelfSignedCert = Certificate{
   793  	TBSCertificate: TBSCertificate{
   794  		Version:            0,
   795  		SerialNumber:       RawValue{Class: 0, Tag: 2, IsCompound: false, Bytes: []uint8{0x0, 0x8c, 0xc3, 0x37, 0x92, 0x10, 0xec, 0x2c, 0x98}, FullBytes: []byte{2, 9, 0x0, 0x8c, 0xc3, 0x37, 0x92, 0x10, 0xec, 0x2c, 0x98}},
   796  		SignatureAlgorithm: AlgorithmIdentifier{Algorithm: ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}},
   797  		Issuer: RDNSequence{
   798  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 6}, Value: "XX"}},
   799  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 8}, Value: "Some-State"}},
   800  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 7}, Value: "City"}},
   801  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 10}, Value: "Internet Widgits Pty Ltd"}},
   802  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 3}, Value: "false.example.com"}},
   803  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: "false@example.com"}},
   804  		},
   805  		Validity: Validity{
   806  			NotBefore: time.Date(2009, 10, 8, 00, 25, 53, 0, time.UTC),
   807  			NotAfter:  time.Date(2010, 10, 8, 00, 25, 53, 0, time.UTC),
   808  		},
   809  		Subject: RDNSequence{
   810  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 6}, Value: "XX"}},
   811  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 8}, Value: "Some-State"}},
   812  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 7}, Value: "City"}},
   813  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 10}, Value: "Internet Widgits Pty Ltd"}},
   814  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 3}, Value: "false.example.com"}},
   815  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: "false@example.com"}},
   816  		},
   817  		PublicKey: PublicKeyInfo{
   818  			Algorithm: AlgorithmIdentifier{Algorithm: ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}},
   819  			PublicKey: BitString{
   820  				Bytes: []uint8{
   821  					0x30, 0x48, 0x2, 0x41, 0x0, 0xcd, 0xb7,
   822  					0x63, 0x9c, 0x32, 0x78, 0xf0, 0x6, 0xaa, 0x27, 0x7f, 0x6e, 0xaf, 0x42,
   823  					0x90, 0x2b, 0x59, 0x2d, 0x8c, 0xbc, 0xbe, 0x38, 0xa1, 0xc9, 0x2b, 0xa4,
   824  					0x69, 0x5a, 0x33, 0x1b, 0x1d, 0xea, 0xde, 0xad, 0xd8, 0xe9, 0xa5, 0xc2,
   825  					0x7e, 0x8c, 0x4c, 0x2f, 0xd0, 0xa8, 0x88, 0x96, 0x57, 0x72, 0x2a, 0x4f,
   826  					0x2a, 0xf7, 0x58, 0x9c, 0xf2, 0xc7, 0x70, 0x45, 0xdc, 0x8f, 0xde, 0xec,
   827  					0x35, 0x7d, 0x2, 0x3, 0x1, 0x0, 0x1,
   828  				},
   829  				BitLength: 592,
   830  			},
   831  		},
   832  	},
   833  	SignatureAlgorithm: AlgorithmIdentifier{Algorithm: ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}},
   834  	SignatureValue: BitString{
   835  		Bytes: []uint8{
   836  			0xa6, 0x7b, 0x6, 0xec, 0x5e, 0xce,
   837  			0x92, 0x77, 0x2c, 0xa4, 0x13, 0xcb, 0xa3, 0xca, 0x12, 0x56, 0x8f, 0xdc, 0x6c,
   838  			0x7b, 0x45, 0x11, 0xcd, 0x40, 0xa7, 0xf6, 0x59, 0x98, 0x4, 0x2, 0xdf, 0x2b,
   839  			0x99, 0x8b, 0xb9, 0xa4, 0xa8, 0xcb, 0xeb, 0x34, 0xc0, 0xf0, 0xa7, 0x8c, 0xf8,
   840  			0xd9, 0x1e, 0xde, 0x14, 0xa5, 0xed, 0x76, 0xbf, 0x11, 0x6f, 0xe3, 0x60, 0xaa,
   841  			0xfa, 0x88, 0x21, 0x49, 0x4, 0x35,
   842  		},
   843  		BitLength: 512,
   844  	},
   845  }
   846  
   847  var derEncodedSelfSignedCertBytes = []byte{
   848  	0x30, 0x82, 0x02, 0x18, 0x30,
   849  	0x82, 0x01, 0xc2, 0x02, 0x09, 0x00, 0x8c, 0xc3, 0x37, 0x92, 0x10, 0xec, 0x2c,
   850  	0x98, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
   851  	0x05, 0x05, 0x00, 0x30, 0x81, 0x92, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
   852  	0x04, 0x06, 0x13, 0x02, 0x58, 0x58, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
   853  	0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74,
   854  	0x65, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x04, 0x43,
   855  	0x69, 0x74, 0x79, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
   856  	0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64,
   857  	0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x31,
   858  	0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x66, 0x61, 0x6c,
   859  	0x73, 0x65, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f,
   860  	0x6d, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
   861  	0x01, 0x09, 0x01, 0x16, 0x11, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x40, 0x65, 0x78,
   862  	0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d,
   863  	0x30, 0x39, 0x31, 0x30, 0x30, 0x38, 0x30, 0x30, 0x32, 0x35, 0x35, 0x33, 0x5a,
   864  	0x17, 0x0d, 0x31, 0x30, 0x31, 0x30, 0x30, 0x38, 0x30, 0x30, 0x32, 0x35, 0x35,
   865  	0x33, 0x5a, 0x30, 0x81, 0x92, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
   866  	0x06, 0x13, 0x02, 0x58, 0x58, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
   867  	0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
   868  	0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x04, 0x43, 0x69,
   869  	0x74, 0x79, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x18,
   870  	0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
   871  	0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x31, 0x1a,
   872  	0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x66, 0x61, 0x6c, 0x73,
   873  	0x65, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
   874  	0x31, 0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
   875  	0x09, 0x01, 0x16, 0x11, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x40, 0x65, 0x78, 0x61,
   876  	0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06,
   877  	0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03,
   878  	0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, 0x00, 0xcd, 0xb7, 0x63, 0x9c, 0x32, 0x78,
   879  	0xf0, 0x06, 0xaa, 0x27, 0x7f, 0x6e, 0xaf, 0x42, 0x90, 0x2b, 0x59, 0x2d, 0x8c,
   880  	0xbc, 0xbe, 0x38, 0xa1, 0xc9, 0x2b, 0xa4, 0x69, 0x5a, 0x33, 0x1b, 0x1d, 0xea,
   881  	0xde, 0xad, 0xd8, 0xe9, 0xa5, 0xc2, 0x7e, 0x8c, 0x4c, 0x2f, 0xd0, 0xa8, 0x88,
   882  	0x96, 0x57, 0x72, 0x2a, 0x4f, 0x2a, 0xf7, 0x58, 0x9c, 0xf2, 0xc7, 0x70, 0x45,
   883  	0xdc, 0x8f, 0xde, 0xec, 0x35, 0x7d, 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x0d,
   884  	0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00,
   885  	0x03, 0x41, 0x00, 0xa6, 0x7b, 0x06, 0xec, 0x5e, 0xce, 0x92, 0x77, 0x2c, 0xa4,
   886  	0x13, 0xcb, 0xa3, 0xca, 0x12, 0x56, 0x8f, 0xdc, 0x6c, 0x7b, 0x45, 0x11, 0xcd,
   887  	0x40, 0xa7, 0xf6, 0x59, 0x98, 0x04, 0x02, 0xdf, 0x2b, 0x99, 0x8b, 0xb9, 0xa4,
   888  	0xa8, 0xcb, 0xeb, 0x34, 0xc0, 0xf0, 0xa7, 0x8c, 0xf8, 0xd9, 0x1e, 0xde, 0x14,
   889  	0xa5, 0xed, 0x76, 0xbf, 0x11, 0x6f, 0xe3, 0x60, 0xaa, 0xfa, 0x88, 0x21, 0x49,
   890  	0x04, 0x35,
   891  }
   892  
   893  var derEncodedPaypalNULCertBytes = []byte{
   894  	0x30, 0x82, 0x06, 0x44, 0x30,
   895  	0x82, 0x05, 0xad, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x03, 0x00, 0xf0, 0x9b,
   896  	0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
   897  	0x05, 0x00, 0x30, 0x82, 0x01, 0x12, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
   898  	0x04, 0x06, 0x13, 0x02, 0x45, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55,
   899  	0x04, 0x08, 0x13, 0x09, 0x42, 0x61, 0x72, 0x63, 0x65, 0x6c, 0x6f, 0x6e, 0x61,
   900  	0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x42, 0x61,
   901  	0x72, 0x63, 0x65, 0x6c, 0x6f, 0x6e, 0x61, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03,
   902  	0x55, 0x04, 0x0a, 0x13, 0x20, 0x49, 0x50, 0x53, 0x20, 0x43, 0x65, 0x72, 0x74,
   903  	0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
   904  	0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x73, 0x2e, 0x6c, 0x2e, 0x31, 0x2e,
   905  	0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x14, 0x25, 0x67, 0x65, 0x6e, 0x65,
   906  	0x72, 0x61, 0x6c, 0x40, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d,
   907  	0x20, 0x43, 0x2e, 0x49, 0x2e, 0x46, 0x2e, 0x20, 0x20, 0x42, 0x2d, 0x42, 0x36,
   908  	0x32, 0x32, 0x31, 0x30, 0x36, 0x39, 0x35, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03,
   909  	0x55, 0x04, 0x0b, 0x13, 0x25, 0x69, 0x70, 0x73, 0x43, 0x41, 0x20, 0x43, 0x4c,
   910  	0x41, 0x53, 0x45, 0x41, 0x31, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
   911  	0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
   912  	0x69, 0x74, 0x79, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
   913  	0x25, 0x69, 0x70, 0x73, 0x43, 0x41, 0x20, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41,
   914  	0x31, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69,
   915  	0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31,
   916  	0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09,
   917  	0x01, 0x16, 0x11, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x40, 0x69, 0x70,
   918  	0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39,
   919  	0x30, 0x32, 0x32, 0x34, 0x32, 0x33, 0x30, 0x34, 0x31, 0x37, 0x5a, 0x17, 0x0d,
   920  	0x31, 0x31, 0x30, 0x32, 0x32, 0x34, 0x32, 0x33, 0x30, 0x34, 0x31, 0x37, 0x5a,
   921  	0x30, 0x81, 0x94, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
   922  	0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13,
   923  	0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x16,
   924  	0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0d, 0x53, 0x61, 0x6e, 0x20,
   925  	0x46, 0x72, 0x61, 0x6e, 0x63, 0x69, 0x73, 0x63, 0x6f, 0x31, 0x11, 0x30, 0x0f,
   926  	0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x08, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69,
   927  	0x74, 0x79, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0b,
   928  	0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x55, 0x6e, 0x69, 0x74, 0x31, 0x2f,
   929  	0x30, 0x2d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x26, 0x77, 0x77, 0x77, 0x2e,
   930  	0x70, 0x61, 0x79, 0x70, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x73, 0x73,
   931  	0x6c, 0x2e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x6e, 0x65,
   932  	0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x63, 0x63, 0x30, 0x81, 0x9f, 0x30, 0x0d,
   933  	0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
   934  	0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xd2, 0x69,
   935  	0xfa, 0x6f, 0x3a, 0x00, 0xb4, 0x21, 0x1b, 0xc8, 0xb1, 0x02, 0xd7, 0x3f, 0x19,
   936  	0xb2, 0xc4, 0x6d, 0xb4, 0x54, 0xf8, 0x8b, 0x8a, 0xcc, 0xdb, 0x72, 0xc2, 0x9e,
   937  	0x3c, 0x60, 0xb9, 0xc6, 0x91, 0x3d, 0x82, 0xb7, 0x7d, 0x99, 0xff, 0xd1, 0x29,
   938  	0x84, 0xc1, 0x73, 0x53, 0x9c, 0x82, 0xdd, 0xfc, 0x24, 0x8c, 0x77, 0xd5, 0x41,
   939  	0xf3, 0xe8, 0x1e, 0x42, 0xa1, 0xad, 0x2d, 0x9e, 0xff, 0x5b, 0x10, 0x26, 0xce,
   940  	0x9d, 0x57, 0x17, 0x73, 0x16, 0x23, 0x38, 0xc8, 0xd6, 0xf1, 0xba, 0xa3, 0x96,
   941  	0x5b, 0x16, 0x67, 0x4a, 0x4f, 0x73, 0x97, 0x3a, 0x4d, 0x14, 0xa4, 0xf4, 0xe2,
   942  	0x3f, 0x8b, 0x05, 0x83, 0x42, 0xd1, 0xd0, 0xdc, 0x2f, 0x7a, 0xe5, 0xb6, 0x10,
   943  	0xb2, 0x11, 0xc0, 0xdc, 0x21, 0x2a, 0x90, 0xff, 0xae, 0x97, 0x71, 0x5a, 0x49,
   944  	0x81, 0xac, 0x40, 0xf3, 0x3b, 0xb8, 0x59, 0xb2, 0x4f, 0x02, 0x03, 0x01, 0x00,
   945  	0x01, 0xa3, 0x82, 0x03, 0x21, 0x30, 0x82, 0x03, 0x1d, 0x30, 0x09, 0x06, 0x03,
   946  	0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x11, 0x06, 0x09, 0x60, 0x86,
   947  	0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x01, 0x04, 0x04, 0x03, 0x02, 0x06, 0x40,
   948  	0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x03, 0xf8,
   949  	0x30, 0x13, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08,
   950  	0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x30, 0x1d, 0x06, 0x03, 0x55,
   951  	0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x61, 0x8f, 0x61, 0x34, 0x43, 0x55, 0x14,
   952  	0x7f, 0x27, 0x09, 0xce, 0x4c, 0x8b, 0xea, 0x9b, 0x7b, 0x19, 0x25, 0xbc, 0x6e,
   953  	0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
   954  	0x0e, 0x07, 0x60, 0xd4, 0x39, 0xc9, 0x1b, 0x5b, 0x5d, 0x90, 0x7b, 0x23, 0xc8,
   955  	0xd2, 0x34, 0x9d, 0x4a, 0x9a, 0x46, 0x39, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d,
   956  	0x11, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x1d, 0x12, 0x04,
   957  	0x15, 0x30, 0x13, 0x81, 0x11, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x40,
   958  	0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x72, 0x06, 0x09,
   959  	0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x0d, 0x04, 0x65, 0x16, 0x63,
   960  	0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
   961  	0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4e,
   962  	0x4f, 0x54, 0x20, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x45, 0x44, 0x2e,
   963  	0x20, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x20, 0x53, 0x65, 0x72, 0x76,
   964  	0x65, 0x72, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
   965  	0x65, 0x20, 0x69, 0x73, 0x73, 0x75, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x68,
   966  	0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70,
   967  	0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x2f, 0x06, 0x09, 0x60,
   968  	0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x02, 0x04, 0x22, 0x16, 0x20, 0x68,
   969  	0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70,
   970  	0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61,
   971  	0x32, 0x30, 0x30, 0x32, 0x2f, 0x30, 0x43, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
   972  	0x86, 0xf8, 0x42, 0x01, 0x04, 0x04, 0x36, 0x16, 0x34, 0x68, 0x74, 0x74, 0x70,
   973  	0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61,
   974  	0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 0x30,
   975  	0x32, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 0x32, 0x43, 0x4c,
   976  	0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x46, 0x06, 0x09,
   977  	0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x03, 0x04, 0x39, 0x16, 0x37,
   978  	0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69,
   979  	0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63,
   980  	0x61, 0x32, 0x30, 0x30, 0x32, 0x2f, 0x72, 0x65, 0x76, 0x6f, 0x63, 0x61, 0x74,
   981  	0x69, 0x6f, 0x6e, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x68, 0x74,
   982  	0x6d, 0x6c, 0x3f, 0x30, 0x43, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8,
   983  	0x42, 0x01, 0x07, 0x04, 0x36, 0x16, 0x34, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a,
   984  	0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63,
   985  	0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 0x32, 0x2f,
   986  	0x72, 0x65, 0x6e, 0x65, 0x77, 0x61, 0x6c, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41,
   987  	0x31, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x3f, 0x30, 0x41, 0x06, 0x09, 0x60, 0x86,
   988  	0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x08, 0x04, 0x34, 0x16, 0x32, 0x68, 0x74,
   989  	0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70, 0x73,
   990  	0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32,
   991  	0x30, 0x30, 0x32, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x43, 0x4c, 0x41,
   992  	0x53, 0x45, 0x41, 0x31, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x30, 0x81, 0x83, 0x06,
   993  	0x03, 0x55, 0x1d, 0x1f, 0x04, 0x7c, 0x30, 0x7a, 0x30, 0x39, 0xa0, 0x37, 0xa0,
   994  	0x35, 0x86, 0x33, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77,
   995  	0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70,
   996  	0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 0x32, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61,
   997  	0x32, 0x30, 0x30, 0x32, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x63,
   998  	0x72, 0x6c, 0x30, 0x3d, 0xa0, 0x3b, 0xa0, 0x39, 0x86, 0x37, 0x68, 0x74, 0x74,
   999  	0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x69,
  1000  	0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63,
  1001  	0x61, 0x32, 0x30, 0x30, 0x32, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30,
  1002  	0x30, 0x32, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x63, 0x72, 0x6c,
  1003  	0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
  1004  	0x26, 0x30, 0x24, 0x30, 0x22, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
  1005  	0x30, 0x01, 0x86, 0x16, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63,
  1006  	0x73, 0x70, 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
  1007  	0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
  1008  	0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x68, 0xee, 0x79, 0x97, 0x97, 0xdd, 0x3b,
  1009  	0xef, 0x16, 0x6a, 0x06, 0xf2, 0x14, 0x9a, 0x6e, 0xcd, 0x9e, 0x12, 0xf7, 0xaa,
  1010  	0x83, 0x10, 0xbd, 0xd1, 0x7c, 0x98, 0xfa, 0xc7, 0xae, 0xd4, 0x0e, 0x2c, 0x9e,
  1011  	0x38, 0x05, 0x9d, 0x52, 0x60, 0xa9, 0x99, 0x0a, 0x81, 0xb4, 0x98, 0x90, 0x1d,
  1012  	0xae, 0xbb, 0x4a, 0xd7, 0xb9, 0xdc, 0x88, 0x9e, 0x37, 0x78, 0x41, 0x5b, 0xf7,
  1013  	0x82, 0xa5, 0xf2, 0xba, 0x41, 0x25, 0x5a, 0x90, 0x1a, 0x1e, 0x45, 0x38, 0xa1,
  1014  	0x52, 0x58, 0x75, 0x94, 0x26, 0x44, 0xfb, 0x20, 0x07, 0xba, 0x44, 0xcc, 0xe5,
  1015  	0x4a, 0x2d, 0x72, 0x3f, 0x98, 0x47, 0xf6, 0x26, 0xdc, 0x05, 0x46, 0x05, 0x07,
  1016  	0x63, 0x21, 0xab, 0x46, 0x9b, 0x9c, 0x78, 0xd5, 0x54, 0x5b, 0x3d, 0x0c, 0x1e,
  1017  	0xc8, 0x64, 0x8c, 0xb5, 0x50, 0x23, 0x82, 0x6f, 0xdb, 0xb8, 0x22, 0x1c, 0x43,
  1018  	0x96, 0x07, 0xa8, 0xbb,
  1019  }
  1020  
  1021  var stringSliceTestData = [][]string{
  1022  	{"foo", "bar"},
  1023  	{"foo", "\\bar"},
  1024  	{"foo", "\"bar\""},
  1025  	{"foo", "åäö"},
  1026  }
  1027  
  1028  func TestStringSlice(t *testing.T) {
  1029  	for _, test := range stringSliceTestData {
  1030  		bs, err := Marshal(test)
  1031  		if err != nil {
  1032  			t.Error(err)
  1033  		}
  1034  
  1035  		var res []string
  1036  		_, err = Unmarshal(bs, &res)
  1037  		if err != nil {
  1038  			t.Error(err)
  1039  		}
  1040  
  1041  		if fmt.Sprintf("%v", res) != fmt.Sprintf("%v", test) {
  1042  			t.Errorf("incorrect marshal/unmarshal; %v != %v", res, test)
  1043  		}
  1044  	}
  1045  }
  1046  
  1047  type explicitTaggedTimeTest struct {
  1048  	Time time.Time `asn1:"explicit,tag:0"`
  1049  }
  1050  
  1051  var explicitTaggedTimeTestData = []struct {
  1052  	in  []byte
  1053  	out explicitTaggedTimeTest
  1054  }{
  1055  	{[]byte{0x30, 0x11, 0xa0, 0xf, 0x17, 0xd, '9', '1', '0', '5', '0', '6', '1', '6', '4', '5', '4', '0', 'Z'},
  1056  		explicitTaggedTimeTest{time.Date(1991, 05, 06, 16, 45, 40, 0, time.UTC)}},
  1057  	{[]byte{0x30, 0x17, 0xa0, 0xf, 0x18, 0x13, '2', '0', '1', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', '5', '+', '0', '6', '0', '7'},
  1058  		explicitTaggedTimeTest{time.Date(2010, 01, 02, 03, 04, 05, 0, time.FixedZone("", 6*60*60+7*60))}},
  1059  }
  1060  
  1061  func TestExplicitTaggedTime(t *testing.T) {
  1062  	// Test that a time.Time will match either tagUTCTime or
  1063  	// tagGeneralizedTime.
  1064  	for i, test := range explicitTaggedTimeTestData {
  1065  		var got explicitTaggedTimeTest
  1066  		_, err := Unmarshal(test.in, &got)
  1067  		if err != nil {
  1068  			t.Errorf("Unmarshal failed at index %d %v", i, err)
  1069  		}
  1070  		if !got.Time.Equal(test.out.Time) {
  1071  			t.Errorf("#%d: got %v, want %v", i, got.Time, test.out.Time)
  1072  		}
  1073  	}
  1074  }
  1075  
  1076  type implicitTaggedTimeTest struct {
  1077  	Time time.Time `asn1:"tag:24"`
  1078  }
  1079  
  1080  func TestImplicitTaggedTime(t *testing.T) {
  1081  	// An implicitly tagged time value, that happens to have an implicit
  1082  	// tag equal to a GENERALIZEDTIME, should still be parsed as a UTCTime.
  1083  	// (There's no "timeType" in fieldParameters to determine what type of
  1084  	// time should be expected when implicitly tagged.)
  1085  	der := []byte{0x30, 0x0f, 0x80 | 24, 0xd, '9', '1', '0', '5', '0', '6', '1', '6', '4', '5', '4', '0', 'Z'}
  1086  	var result implicitTaggedTimeTest
  1087  	if _, err := Unmarshal(der, &result); err != nil {
  1088  		t.Fatalf("Error while parsing: %s", err)
  1089  	}
  1090  	if expected := time.Date(1991, 05, 06, 16, 45, 40, 0, time.UTC); !result.Time.Equal(expected) {
  1091  		t.Errorf("Wrong result. Got %v, want %v", result.Time, expected)
  1092  	}
  1093  }
  1094  
  1095  type truncatedExplicitTagTest struct {
  1096  	Test int `asn1:"explicit,tag:0"`
  1097  }
  1098  
  1099  func TestTruncatedExplicitTag(t *testing.T) {
  1100  	// This crashed Unmarshal in the past. See #11154.
  1101  	der := []byte{
  1102  		0x30, // SEQUENCE
  1103  		0x02, // two bytes long
  1104  		0xa0, // context-specific, tag 0
  1105  		0x30, // 48 bytes long
  1106  	}
  1107  
  1108  	var result truncatedExplicitTagTest
  1109  	if _, err := Unmarshal(der, &result); err == nil {
  1110  		t.Error("Unmarshal returned without error")
  1111  	}
  1112  }
  1113  
  1114  type invalidUTF8Test struct {
  1115  	Str string `asn1:"utf8"`
  1116  }
  1117  
  1118  func TestUnmarshalInvalidUTF8(t *testing.T) {
  1119  	data := []byte("0\x05\f\x03a\xc9c")
  1120  	var result invalidUTF8Test
  1121  	_, err := Unmarshal(data, &result)
  1122  
  1123  	const expectedSubstring = "UTF"
  1124  	if err == nil {
  1125  		t.Fatal("Successfully unmarshaled invalid UTF-8 data")
  1126  	} else if !strings.Contains(err.Error(), expectedSubstring) {
  1127  		t.Fatalf("Expected error to mention %q but error was %q", expectedSubstring, err.Error())
  1128  	}
  1129  }
  1130  
  1131  func TestMarshalNilValue(t *testing.T) {
  1132  	nilValueTestData := []interface{}{
  1133  		nil,
  1134  		struct{ V interface{} }{},
  1135  	}
  1136  	for i, test := range nilValueTestData {
  1137  		if _, err := Marshal(test); err == nil {
  1138  			t.Fatalf("#%d: successfully marshaled nil value", i)
  1139  		}
  1140  	}
  1141  }
  1142  
  1143  type unexported struct {
  1144  	X int
  1145  	y int
  1146  }
  1147  
  1148  type exported struct {
  1149  	X int
  1150  	Y int
  1151  }
  1152  
  1153  func TestUnexportedStructField(t *testing.T) {
  1154  	want := StructuralError{"struct contains unexported fields", "y"}
  1155  
  1156  	_, err := Marshal(unexported{X: 5, y: 1})
  1157  	if err != want {
  1158  		t.Errorf("got %v, want %v", err, want)
  1159  	}
  1160  
  1161  	bs, err := Marshal(exported{X: 5, Y: 1})
  1162  	if err != nil {
  1163  		t.Fatal(err)
  1164  	}
  1165  	var u unexported
  1166  	_, err = Unmarshal(bs, &u)
  1167  	if err != want {
  1168  		t.Errorf("got %v, want %v", err, want)
  1169  	}
  1170  }
  1171  
  1172  func TestNull(t *testing.T) {
  1173  	marshaled, err := Marshal(NullRawValue)
  1174  	if err != nil {
  1175  		t.Fatal(err)
  1176  	}
  1177  	if !bytes.Equal(NullBytes, marshaled) {
  1178  		t.Errorf("Expected Marshal of NullRawValue to yield %x, got %x", NullBytes, marshaled)
  1179  	}
  1180  
  1181  	unmarshaled := RawValue{}
  1182  	if _, err := Unmarshal(NullBytes, &unmarshaled); err != nil {
  1183  		t.Fatal(err)
  1184  	}
  1185  
  1186  	unmarshaled.FullBytes = NullRawValue.FullBytes
  1187  	if len(unmarshaled.Bytes) == 0 {
  1188  		// DeepEqual considers a nil slice and an empty slice to be different.
  1189  		unmarshaled.Bytes = NullRawValue.Bytes
  1190  	}
  1191  
  1192  	if !reflect.DeepEqual(NullRawValue, unmarshaled) {
  1193  		t.Errorf("Expected Unmarshal of NullBytes to yield %v, got %v", NullRawValue, unmarshaled)
  1194  	}
  1195  }
  1196  
  1197  func TestExplicitTagRawValueStruct(t *testing.T) {
  1198  	type foo struct {
  1199  		A RawValue `asn1:"optional,explicit,tag:5"`
  1200  		B []byte   `asn1:"optional,explicit,tag:6"`
  1201  	}
  1202  	before := foo{B: []byte{1, 2, 3}}
  1203  	derBytes, err := Marshal(before)
  1204  	if err != nil {
  1205  		t.Fatal(err)
  1206  	}
  1207  
  1208  	var after foo
  1209  	if rest, err := Unmarshal(derBytes, &after); err != nil || len(rest) != 0 {
  1210  		t.Fatal(err)
  1211  	}
  1212  
  1213  	got := fmt.Sprintf("%#v", after)
  1214  	want := fmt.Sprintf("%#v", before)
  1215  	if got != want {
  1216  		t.Errorf("got %s, want %s (DER: %x)", got, want, derBytes)
  1217  	}
  1218  }
  1219  
  1220  func TestTaggedRawValue(t *testing.T) {
  1221  	type taggedRawValue struct {
  1222  		A RawValue `asn1:"tag:5"`
  1223  	}
  1224  	type untaggedRawValue struct {
  1225  		A RawValue
  1226  	}
  1227  	const isCompound = 0x20
  1228  	const tag = 5
  1229  
  1230  	tests := []struct {
  1231  		shouldMatch bool
  1232  		derBytes    []byte
  1233  	}{
  1234  		{false, []byte{0x30, 3, TagInteger, 1, 1}},
  1235  		{true, []byte{0x30, 3, (ClassContextSpecific << 6) | tag, 1, 1}},
  1236  		{true, []byte{0x30, 3, (ClassContextSpecific << 6) | tag | isCompound, 1, 1}},
  1237  		{false, []byte{0x30, 3, (ClassApplication << 6) | tag | isCompound, 1, 1}},
  1238  		{false, []byte{0x30, 3, (ClassPrivate << 6) | tag | isCompound, 1, 1}},
  1239  	}
  1240  
  1241  	for i, test := range tests {
  1242  		var tagged taggedRawValue
  1243  		if _, err := Unmarshal(test.derBytes, &tagged); (err == nil) != test.shouldMatch {
  1244  			t.Errorf("#%d: unexpected result parsing %x: %s", i, test.derBytes, err)
  1245  		}
  1246  
  1247  		// An untagged RawValue should accept anything.
  1248  		var untagged untaggedRawValue
  1249  		if _, err := Unmarshal(test.derBytes, &untagged); err != nil {
  1250  			t.Errorf("#%d: unexpected failure parsing %x with untagged RawValue: %s", i, test.derBytes, err)
  1251  		}
  1252  	}
  1253  }
  1254  
  1255  var bmpStringTests = []struct {
  1256  	decoded    string
  1257  	encodedHex string
  1258  }{
  1259  	{"", "0000"},
  1260  	// Example from https://tools.ietf.org/html/rfc7292#appendix-B.
  1261  	{"Beavis", "0042006500610076006900730000"},
  1262  	// Some characters from the "Letterlike Symbols Unicode block".
  1263  	{"\u2115 - Double-struck N", "21150020002d00200044006f00750062006c0065002d00730074007200750063006b0020004e0000"},
  1264  }
  1265  
  1266  func TestBMPString(t *testing.T) {
  1267  	for i, test := range bmpStringTests {
  1268  		encoded, err := hex.DecodeString(test.encodedHex)
  1269  		if err != nil {
  1270  			t.Fatalf("#%d: failed to decode from hex string", i)
  1271  		}
  1272  
  1273  		decoded, err := parseBMPString(encoded)
  1274  
  1275  		if err != nil {
  1276  			t.Errorf("#%d: decoding output gave an error: %s", i, err)
  1277  			continue
  1278  		}
  1279  
  1280  		if decoded != test.decoded {
  1281  			t.Errorf("#%d: decoding output resulted in %q, but it should have been %q", i, decoded, test.decoded)
  1282  			continue
  1283  		}
  1284  	}
  1285  }
  1286  

View as plain text