github.com/rsc/go@v0.0.0-20150416155037-e040fd465409/src/encoding/asn1/asn1_test.go (about)

     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  	"fmt"
    10  	"math/big"
    11  	"reflect"
    12  	"testing"
    13  	"time"
    14  )
    15  
    16  type boolTest struct {
    17  	in  []byte
    18  	ok  bool
    19  	out bool
    20  }
    21  
    22  var boolTestData = []boolTest{
    23  	{[]byte{0x00}, true, false},
    24  	{[]byte{0xff}, true, true},
    25  	{[]byte{0x00, 0x00}, false, false},
    26  	{[]byte{0xff, 0xff}, false, false},
    27  	{[]byte{0x01}, false, false},
    28  }
    29  
    30  func TestParseBool(t *testing.T) {
    31  	for i, test := range boolTestData {
    32  		ret, err := parseBool(test.in)
    33  		if (err == nil) != test.ok {
    34  			t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok)
    35  		}
    36  		if test.ok && ret != test.out {
    37  			t.Errorf("#%d: Bad result: %v (expected %v)", i, ret, test.out)
    38  		}
    39  	}
    40  }
    41  
    42  type int64Test struct {
    43  	in  []byte
    44  	ok  bool
    45  	out int64
    46  }
    47  
    48  var int64TestData = []int64Test{
    49  	{[]byte{0x00}, true, 0},
    50  	{[]byte{0x7f}, true, 127},
    51  	{[]byte{0x00, 0x80}, true, 128},
    52  	{[]byte{0x01, 0x00}, true, 256},
    53  	{[]byte{0x80}, true, -128},
    54  	{[]byte{0xff, 0x7f}, true, -129},
    55  	{[]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, true, -1},
    56  	{[]byte{0xff}, true, -1},
    57  	{[]byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, true, -9223372036854775808},
    58  	{[]byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, false, 0},
    59  }
    60  
    61  func TestParseInt64(t *testing.T) {
    62  	for i, test := range int64TestData {
    63  		ret, err := parseInt64(test.in)
    64  		if (err == nil) != test.ok {
    65  			t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok)
    66  		}
    67  		if test.ok && ret != test.out {
    68  			t.Errorf("#%d: Bad result: %v (expected %v)", i, ret, test.out)
    69  		}
    70  	}
    71  }
    72  
    73  type int32Test struct {
    74  	in  []byte
    75  	ok  bool
    76  	out int32
    77  }
    78  
    79  var int32TestData = []int32Test{
    80  	{[]byte{0x00}, true, 0},
    81  	{[]byte{0x7f}, true, 127},
    82  	{[]byte{0x00, 0x80}, true, 128},
    83  	{[]byte{0x01, 0x00}, true, 256},
    84  	{[]byte{0x80}, true, -128},
    85  	{[]byte{0xff, 0x7f}, true, -129},
    86  	{[]byte{0xff, 0xff, 0xff, 0xff}, true, -1},
    87  	{[]byte{0xff}, true, -1},
    88  	{[]byte{0x80, 0x00, 0x00, 0x00}, true, -2147483648},
    89  	{[]byte{0x80, 0x00, 0x00, 0x00, 0x00}, false, 0},
    90  }
    91  
    92  func TestParseInt32(t *testing.T) {
    93  	for i, test := range int32TestData {
    94  		ret, err := parseInt32(test.in)
    95  		if (err == nil) != test.ok {
    96  			t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok)
    97  		}
    98  		if test.ok && int32(ret) != test.out {
    99  			t.Errorf("#%d: Bad result: %v (expected %v)", i, ret, test.out)
   100  		}
   101  	}
   102  }
   103  
   104  var bigIntTests = []struct {
   105  	in     []byte
   106  	base10 string
   107  }{
   108  	{[]byte{0xff}, "-1"},
   109  	{[]byte{0x00}, "0"},
   110  	{[]byte{0x01}, "1"},
   111  	{[]byte{0x00, 0xff}, "255"},
   112  	{[]byte{0xff, 0x00}, "-256"},
   113  	{[]byte{0x01, 0x00}, "256"},
   114  }
   115  
   116  func TestParseBigInt(t *testing.T) {
   117  	for i, test := range bigIntTests {
   118  		ret := parseBigInt(test.in)
   119  		if ret.String() != test.base10 {
   120  			t.Errorf("#%d: bad result from %x, got %s want %s", i, test.in, ret.String(), test.base10)
   121  		}
   122  		fw := newForkableWriter()
   123  		marshalBigInt(fw, ret)
   124  		result := fw.Bytes()
   125  		if !bytes.Equal(result, test.in) {
   126  			t.Errorf("#%d: got %x from marshaling %s, want %x", i, result, ret, test.in)
   127  		}
   128  	}
   129  }
   130  
   131  type bitStringTest struct {
   132  	in        []byte
   133  	ok        bool
   134  	out       []byte
   135  	bitLength int
   136  }
   137  
   138  var bitStringTestData = []bitStringTest{
   139  	{[]byte{}, false, []byte{}, 0},
   140  	{[]byte{0x00}, true, []byte{}, 0},
   141  	{[]byte{0x07, 0x00}, true, []byte{0x00}, 1},
   142  	{[]byte{0x07, 0x01}, false, []byte{}, 0},
   143  	{[]byte{0x07, 0x40}, false, []byte{}, 0},
   144  	{[]byte{0x08, 0x00}, false, []byte{}, 0},
   145  }
   146  
   147  func TestBitString(t *testing.T) {
   148  	for i, test := range bitStringTestData {
   149  		ret, err := parseBitString(test.in)
   150  		if (err == nil) != test.ok {
   151  			t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok)
   152  		}
   153  		if err == nil {
   154  			if test.bitLength != ret.BitLength || !bytes.Equal(ret.Bytes, test.out) {
   155  				t.Errorf("#%d: Bad result: %v (expected %v %v)", i, ret, test.out, test.bitLength)
   156  			}
   157  		}
   158  	}
   159  }
   160  
   161  func TestBitStringAt(t *testing.T) {
   162  	bs := BitString{[]byte{0x82, 0x40}, 16}
   163  	if bs.At(0) != 1 {
   164  		t.Error("#1: Failed")
   165  	}
   166  	if bs.At(1) != 0 {
   167  		t.Error("#2: Failed")
   168  	}
   169  	if bs.At(6) != 1 {
   170  		t.Error("#3: Failed")
   171  	}
   172  	if bs.At(9) != 1 {
   173  		t.Error("#4: Failed")
   174  	}
   175  	if bs.At(-1) != 0 {
   176  		t.Error("#5: Failed")
   177  	}
   178  	if bs.At(17) != 0 {
   179  		t.Error("#6: Failed")
   180  	}
   181  }
   182  
   183  type bitStringRightAlignTest struct {
   184  	in    []byte
   185  	inlen int
   186  	out   []byte
   187  }
   188  
   189  var bitStringRightAlignTests = []bitStringRightAlignTest{
   190  	{[]byte{0x80}, 1, []byte{0x01}},
   191  	{[]byte{0x80, 0x80}, 9, []byte{0x01, 0x01}},
   192  	{[]byte{}, 0, []byte{}},
   193  	{[]byte{0xce}, 8, []byte{0xce}},
   194  	{[]byte{0xce, 0x47}, 16, []byte{0xce, 0x47}},
   195  	{[]byte{0x34, 0x50}, 12, []byte{0x03, 0x45}},
   196  }
   197  
   198  func TestBitStringRightAlign(t *testing.T) {
   199  	for i, test := range bitStringRightAlignTests {
   200  		bs := BitString{test.in, test.inlen}
   201  		out := bs.RightAlign()
   202  		if !bytes.Equal(out, test.out) {
   203  			t.Errorf("#%d got: %x want: %x", i, out, test.out)
   204  		}
   205  	}
   206  }
   207  
   208  type objectIdentifierTest struct {
   209  	in  []byte
   210  	ok  bool
   211  	out []int
   212  }
   213  
   214  var objectIdentifierTestData = []objectIdentifierTest{
   215  	{[]byte{}, false, []int{}},
   216  	{[]byte{85}, true, []int{2, 5}},
   217  	{[]byte{85, 0x02}, true, []int{2, 5, 2}},
   218  	{[]byte{85, 0x02, 0xc0, 0x00}, true, []int{2, 5, 2, 0x2000}},
   219  	{[]byte{0x81, 0x34, 0x03}, true, []int{2, 100, 3}},
   220  	{[]byte{85, 0x02, 0xc0, 0x80, 0x80, 0x80, 0x80}, false, []int{}},
   221  }
   222  
   223  func TestObjectIdentifier(t *testing.T) {
   224  	for i, test := range objectIdentifierTestData {
   225  		ret, err := parseObjectIdentifier(test.in)
   226  		if (err == nil) != test.ok {
   227  			t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok)
   228  		}
   229  		if err == nil {
   230  			if !reflect.DeepEqual(test.out, ret) {
   231  				t.Errorf("#%d: Bad result: %v (expected %v)", i, ret, test.out)
   232  			}
   233  		}
   234  	}
   235  
   236  	if s := ObjectIdentifier([]int{1, 2, 3, 4}).String(); s != "1.2.3.4" {
   237  		t.Errorf("bad ObjectIdentifier.String(). Got %s, want 1.2.3.4", s)
   238  	}
   239  }
   240  
   241  type timeTest struct {
   242  	in  string
   243  	ok  bool
   244  	out time.Time
   245  }
   246  
   247  var utcTestData = []timeTest{
   248  	{"910506164540-0700", true, time.Date(1991, 05, 06, 16, 45, 40, 0, time.FixedZone("", -7*60*60))},
   249  	{"910506164540+0730", true, time.Date(1991, 05, 06, 16, 45, 40, 0, time.FixedZone("", 7*60*60+30*60))},
   250  	{"910506234540Z", true, time.Date(1991, 05, 06, 23, 45, 40, 0, time.UTC)},
   251  	{"9105062345Z", true, time.Date(1991, 05, 06, 23, 45, 0, 0, time.UTC)},
   252  	{"5105062345Z", true, time.Date(1951, 05, 06, 23, 45, 0, 0, time.UTC)},
   253  	{"a10506234540Z", false, time.Time{}},
   254  	{"91a506234540Z", false, time.Time{}},
   255  	{"9105a6234540Z", false, time.Time{}},
   256  	{"910506a34540Z", false, time.Time{}},
   257  	{"910506334a40Z", false, time.Time{}},
   258  	{"91050633444aZ", false, time.Time{}},
   259  	{"910506334461Z", false, time.Time{}},
   260  	{"910506334400Za", false, time.Time{}},
   261  }
   262  
   263  func TestUTCTime(t *testing.T) {
   264  	for i, test := range utcTestData {
   265  		ret, err := parseUTCTime([]byte(test.in))
   266  		if err != nil {
   267  			if test.ok {
   268  				t.Errorf("#%d: parseUTCTime(%q) = error %v", i, test.in, err)
   269  			}
   270  			continue
   271  		}
   272  		if !test.ok {
   273  			t.Errorf("#%d: parseUTCTime(%q) succeeded, should have failed", i, test.in)
   274  			continue
   275  		}
   276  		const format = "Jan _2 15:04:05 -0700 2006" // ignore zone name, just offset
   277  		have := ret.Format(format)
   278  		want := test.out.Format(format)
   279  		if have != want {
   280  			t.Errorf("#%d: parseUTCTime(%q) = %s, want %s", i, test.in, have, want)
   281  		}
   282  	}
   283  }
   284  
   285  var generalizedTimeTestData = []timeTest{
   286  	{"20100102030405Z", true, time.Date(2010, 01, 02, 03, 04, 05, 0, time.UTC)},
   287  	{"20100102030405", false, time.Time{}},
   288  	{"20100102030405+0607", true, time.Date(2010, 01, 02, 03, 04, 05, 0, time.FixedZone("", 6*60*60+7*60))},
   289  	{"20100102030405-0607", true, time.Date(2010, 01, 02, 03, 04, 05, 0, time.FixedZone("", -6*60*60-7*60))},
   290  }
   291  
   292  func TestGeneralizedTime(t *testing.T) {
   293  	for i, test := range generalizedTimeTestData {
   294  		ret, err := parseGeneralizedTime([]byte(test.in))
   295  		if (err == nil) != test.ok {
   296  			t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok)
   297  		}
   298  		if err == nil {
   299  			if !reflect.DeepEqual(test.out, ret) {
   300  				t.Errorf("#%d: Bad result: %v (expected %v)", i, ret, test.out)
   301  			}
   302  		}
   303  	}
   304  }
   305  
   306  type tagAndLengthTest struct {
   307  	in  []byte
   308  	ok  bool
   309  	out tagAndLength
   310  }
   311  
   312  var tagAndLengthData = []tagAndLengthTest{
   313  	{[]byte{0x80, 0x01}, true, tagAndLength{2, 0, 1, false}},
   314  	{[]byte{0xa0, 0x01}, true, tagAndLength{2, 0, 1, true}},
   315  	{[]byte{0x02, 0x00}, true, tagAndLength{0, 2, 0, false}},
   316  	{[]byte{0xfe, 0x00}, true, tagAndLength{3, 30, 0, true}},
   317  	{[]byte{0x1f, 0x01, 0x00}, true, tagAndLength{0, 1, 0, false}},
   318  	{[]byte{0x1f, 0x81, 0x00, 0x00}, true, tagAndLength{0, 128, 0, false}},
   319  	{[]byte{0x1f, 0x81, 0x80, 0x01, 0x00}, true, tagAndLength{0, 0x4001, 0, false}},
   320  	{[]byte{0x00, 0x81, 0x01}, true, tagAndLength{0, 0, 1, false}},
   321  	{[]byte{0x00, 0x82, 0x01, 0x00}, true, tagAndLength{0, 0, 256, false}},
   322  	{[]byte{0x00, 0x83, 0x01, 0x00}, false, tagAndLength{}},
   323  	{[]byte{0x1f, 0x85}, false, tagAndLength{}},
   324  	{[]byte{0x30, 0x80}, false, tagAndLength{}},
   325  	// Superfluous zeros in the length should be an error.
   326  	{[]byte{0xa0, 0x82, 0x00, 0x01}, false, tagAndLength{}},
   327  	// Lengths up to the maximum size of an int should work.
   328  	{[]byte{0xa0, 0x84, 0x7f, 0xff, 0xff, 0xff}, true, tagAndLength{2, 0, 0x7fffffff, true}},
   329  	// Lengths that would overflow an int should be rejected.
   330  	{[]byte{0xa0, 0x84, 0x80, 0x00, 0x00, 0x00}, false, tagAndLength{}},
   331  }
   332  
   333  func TestParseTagAndLength(t *testing.T) {
   334  	for i, test := range tagAndLengthData {
   335  		tagAndLength, _, err := parseTagAndLength(test.in, 0)
   336  		if (err == nil) != test.ok {
   337  			t.Errorf("#%d: Incorrect error result (did pass? %v, expected: %v)", i, err == nil, test.ok)
   338  		}
   339  		if err == nil && !reflect.DeepEqual(test.out, tagAndLength) {
   340  			t.Errorf("#%d: Bad result: %v (expected %v)", i, tagAndLength, test.out)
   341  		}
   342  	}
   343  }
   344  
   345  type parseFieldParametersTest struct {
   346  	in  string
   347  	out fieldParameters
   348  }
   349  
   350  func newInt(n int) *int { return &n }
   351  
   352  func newInt64(n int64) *int64 { return &n }
   353  
   354  func newString(s string) *string { return &s }
   355  
   356  func newBool(b bool) *bool { return &b }
   357  
   358  var parseFieldParametersTestData []parseFieldParametersTest = []parseFieldParametersTest{
   359  	{"", fieldParameters{}},
   360  	{"ia5", fieldParameters{stringType: tagIA5String}},
   361  	{"printable", fieldParameters{stringType: tagPrintableString}},
   362  	{"optional", fieldParameters{optional: true}},
   363  	{"explicit", fieldParameters{explicit: true, tag: new(int)}},
   364  	{"application", fieldParameters{application: true, tag: new(int)}},
   365  	{"optional,explicit", fieldParameters{optional: true, explicit: true, tag: new(int)}},
   366  	{"default:42", fieldParameters{defaultValue: newInt64(42)}},
   367  	{"tag:17", fieldParameters{tag: newInt(17)}},
   368  	{"optional,explicit,default:42,tag:17", fieldParameters{optional: true, explicit: true, defaultValue: newInt64(42), tag: newInt(17)}},
   369  	{"optional,explicit,default:42,tag:17,rubbish1", fieldParameters{true, true, false, newInt64(42), newInt(17), 0, false, false}},
   370  	{"set", fieldParameters{set: true}},
   371  }
   372  
   373  func TestParseFieldParameters(t *testing.T) {
   374  	for i, test := range parseFieldParametersTestData {
   375  		f := parseFieldParameters(test.in)
   376  		if !reflect.DeepEqual(f, test.out) {
   377  			t.Errorf("#%d: Bad result: %v (expected %v)", i, f, test.out)
   378  		}
   379  	}
   380  }
   381  
   382  type TestObjectIdentifierStruct struct {
   383  	OID ObjectIdentifier
   384  }
   385  
   386  type TestContextSpecificTags struct {
   387  	A int `asn1:"tag:1"`
   388  }
   389  
   390  type TestContextSpecificTags2 struct {
   391  	A int `asn1:"explicit,tag:1"`
   392  	B int
   393  }
   394  
   395  type TestContextSpecificTags3 struct {
   396  	S string `asn1:"tag:1,utf8"`
   397  }
   398  
   399  type TestElementsAfterString struct {
   400  	S    string
   401  	A, B int
   402  }
   403  
   404  type TestBigInt struct {
   405  	X *big.Int
   406  }
   407  
   408  type TestSet struct {
   409  	Ints []int `asn1:"set"`
   410  }
   411  
   412  var unmarshalTestData = []struct {
   413  	in  []byte
   414  	out interface{}
   415  }{
   416  	{[]byte{0x02, 0x01, 0x42}, newInt(0x42)},
   417  	{[]byte{0x30, 0x08, 0x06, 0x06, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d}, &TestObjectIdentifierStruct{[]int{1, 2, 840, 113549}}},
   418  	{[]byte{0x03, 0x04, 0x06, 0x6e, 0x5d, 0xc0}, &BitString{[]byte{110, 93, 192}, 18}},
   419  	{[]byte{0x30, 0x09, 0x02, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, 0x01, 0x03}, &[]int{1, 2, 3}},
   420  	{[]byte{0x02, 0x01, 0x10}, newInt(16)},
   421  	{[]byte{0x13, 0x04, 't', 'e', 's', 't'}, newString("test")},
   422  	{[]byte{0x16, 0x04, 't', 'e', 's', 't'}, newString("test")},
   423  	{[]byte{0x16, 0x04, 't', 'e', 's', 't'}, &RawValue{0, 22, false, []byte("test"), []byte("\x16\x04test")}},
   424  	{[]byte{0x04, 0x04, 1, 2, 3, 4}, &RawValue{0, 4, false, []byte{1, 2, 3, 4}, []byte{4, 4, 1, 2, 3, 4}}},
   425  	{[]byte{0x30, 0x03, 0x81, 0x01, 0x01}, &TestContextSpecificTags{1}},
   426  	{[]byte{0x30, 0x08, 0xa1, 0x03, 0x02, 0x01, 0x01, 0x02, 0x01, 0x02}, &TestContextSpecificTags2{1, 2}},
   427  	{[]byte{0x30, 0x03, 0x81, 0x01, '@'}, &TestContextSpecificTags3{"@"}},
   428  	{[]byte{0x01, 0x01, 0x00}, newBool(false)},
   429  	{[]byte{0x01, 0x01, 0xff}, newBool(true)},
   430  	{[]byte{0x30, 0x0b, 0x13, 0x03, 0x66, 0x6f, 0x6f, 0x02, 0x01, 0x22, 0x02, 0x01, 0x33}, &TestElementsAfterString{"foo", 0x22, 0x33}},
   431  	{[]byte{0x30, 0x05, 0x02, 0x03, 0x12, 0x34, 0x56}, &TestBigInt{big.NewInt(0x123456)}},
   432  	{[]byte{0x30, 0x0b, 0x31, 0x09, 0x02, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, 0x01, 0x03}, &TestSet{Ints: []int{1, 2, 3}}},
   433  }
   434  
   435  func TestUnmarshal(t *testing.T) {
   436  	for i, test := range unmarshalTestData {
   437  		pv := reflect.New(reflect.TypeOf(test.out).Elem())
   438  		val := pv.Interface()
   439  		_, err := Unmarshal(test.in, val)
   440  		if err != nil {
   441  			t.Errorf("Unmarshal failed at index %d %v", i, err)
   442  		}
   443  		if !reflect.DeepEqual(val, test.out) {
   444  			t.Errorf("#%d:\nhave %#v\nwant %#v", i, val, test.out)
   445  		}
   446  	}
   447  }
   448  
   449  type Certificate struct {
   450  	TBSCertificate     TBSCertificate
   451  	SignatureAlgorithm AlgorithmIdentifier
   452  	SignatureValue     BitString
   453  }
   454  
   455  type TBSCertificate struct {
   456  	Version            int `asn1:"optional,explicit,default:0,tag:0"`
   457  	SerialNumber       RawValue
   458  	SignatureAlgorithm AlgorithmIdentifier
   459  	Issuer             RDNSequence
   460  	Validity           Validity
   461  	Subject            RDNSequence
   462  	PublicKey          PublicKeyInfo
   463  }
   464  
   465  type AlgorithmIdentifier struct {
   466  	Algorithm ObjectIdentifier
   467  }
   468  
   469  type RDNSequence []RelativeDistinguishedNameSET
   470  
   471  type RelativeDistinguishedNameSET []AttributeTypeAndValue
   472  
   473  type AttributeTypeAndValue struct {
   474  	Type  ObjectIdentifier
   475  	Value interface{}
   476  }
   477  
   478  type Validity struct {
   479  	NotBefore, NotAfter time.Time
   480  }
   481  
   482  type PublicKeyInfo struct {
   483  	Algorithm AlgorithmIdentifier
   484  	PublicKey BitString
   485  }
   486  
   487  func TestCertificate(t *testing.T) {
   488  	// This is a minimal, self-signed certificate that should parse correctly.
   489  	var cert Certificate
   490  	if _, err := Unmarshal(derEncodedSelfSignedCertBytes, &cert); err != nil {
   491  		t.Errorf("Unmarshal failed: %v", err)
   492  	}
   493  	if !reflect.DeepEqual(cert, derEncodedSelfSignedCert) {
   494  		t.Errorf("Bad result:\ngot: %+v\nwant: %+v", cert, derEncodedSelfSignedCert)
   495  	}
   496  }
   497  
   498  func TestCertificateWithNUL(t *testing.T) {
   499  	// This is the paypal NUL-hack certificate. It should fail to parse because
   500  	// NUL isn't a permitted character in a PrintableString.
   501  
   502  	var cert Certificate
   503  	if _, err := Unmarshal(derEncodedPaypalNULCertBytes, &cert); err == nil {
   504  		t.Error("Unmarshal succeeded, should not have")
   505  	}
   506  }
   507  
   508  type rawStructTest struct {
   509  	Raw RawContent
   510  	A   int
   511  }
   512  
   513  func TestRawStructs(t *testing.T) {
   514  	var s rawStructTest
   515  	input := []byte{0x30, 0x03, 0x02, 0x01, 0x50}
   516  
   517  	rest, err := Unmarshal(input, &s)
   518  	if len(rest) != 0 {
   519  		t.Errorf("incomplete parse: %x", rest)
   520  		return
   521  	}
   522  	if err != nil {
   523  		t.Error(err)
   524  		return
   525  	}
   526  	if s.A != 0x50 {
   527  		t.Errorf("bad value for A: got %d want %d", s.A, 0x50)
   528  	}
   529  	if !bytes.Equal([]byte(s.Raw), input) {
   530  		t.Errorf("bad value for Raw: got %x want %x", s.Raw, input)
   531  	}
   532  }
   533  
   534  type oiEqualTest struct {
   535  	first  ObjectIdentifier
   536  	second ObjectIdentifier
   537  	same   bool
   538  }
   539  
   540  var oiEqualTests = []oiEqualTest{
   541  	{
   542  		ObjectIdentifier{1, 2, 3},
   543  		ObjectIdentifier{1, 2, 3},
   544  		true,
   545  	},
   546  	{
   547  		ObjectIdentifier{1},
   548  		ObjectIdentifier{1, 2, 3},
   549  		false,
   550  	},
   551  	{
   552  		ObjectIdentifier{1, 2, 3},
   553  		ObjectIdentifier{10, 11, 12},
   554  		false,
   555  	},
   556  }
   557  
   558  func TestObjectIdentifierEqual(t *testing.T) {
   559  	for _, o := range oiEqualTests {
   560  		if s := o.first.Equal(o.second); s != o.same {
   561  			t.Errorf("ObjectIdentifier.Equal: got: %t want: %t", s, o.same)
   562  		}
   563  	}
   564  }
   565  
   566  var derEncodedSelfSignedCert = Certificate{
   567  	TBSCertificate: TBSCertificate{
   568  		Version:            0,
   569  		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}},
   570  		SignatureAlgorithm: AlgorithmIdentifier{Algorithm: ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}},
   571  		Issuer: RDNSequence{
   572  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 6}, Value: "XX"}},
   573  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 8}, Value: "Some-State"}},
   574  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 7}, Value: "City"}},
   575  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 10}, Value: "Internet Widgits Pty Ltd"}},
   576  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 3}, Value: "false.example.com"}},
   577  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: "false@example.com"}},
   578  		},
   579  		Validity: Validity{
   580  			NotBefore: time.Date(2009, 10, 8, 00, 25, 53, 0, time.UTC),
   581  			NotAfter:  time.Date(2010, 10, 8, 00, 25, 53, 0, time.UTC),
   582  		},
   583  		Subject: RDNSequence{
   584  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 6}, Value: "XX"}},
   585  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 8}, Value: "Some-State"}},
   586  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 7}, Value: "City"}},
   587  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 10}, Value: "Internet Widgits Pty Ltd"}},
   588  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 3}, Value: "false.example.com"}},
   589  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: "false@example.com"}},
   590  		},
   591  		PublicKey: PublicKeyInfo{
   592  			Algorithm: AlgorithmIdentifier{Algorithm: ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}},
   593  			PublicKey: BitString{
   594  				Bytes: []uint8{
   595  					0x30, 0x48, 0x2, 0x41, 0x0, 0xcd, 0xb7,
   596  					0x63, 0x9c, 0x32, 0x78, 0xf0, 0x6, 0xaa, 0x27, 0x7f, 0x6e, 0xaf, 0x42,
   597  					0x90, 0x2b, 0x59, 0x2d, 0x8c, 0xbc, 0xbe, 0x38, 0xa1, 0xc9, 0x2b, 0xa4,
   598  					0x69, 0x5a, 0x33, 0x1b, 0x1d, 0xea, 0xde, 0xad, 0xd8, 0xe9, 0xa5, 0xc2,
   599  					0x7e, 0x8c, 0x4c, 0x2f, 0xd0, 0xa8, 0x88, 0x96, 0x57, 0x72, 0x2a, 0x4f,
   600  					0x2a, 0xf7, 0x58, 0x9c, 0xf2, 0xc7, 0x70, 0x45, 0xdc, 0x8f, 0xde, 0xec,
   601  					0x35, 0x7d, 0x2, 0x3, 0x1, 0x0, 0x1,
   602  				},
   603  				BitLength: 592,
   604  			},
   605  		},
   606  	},
   607  	SignatureAlgorithm: AlgorithmIdentifier{Algorithm: ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}},
   608  	SignatureValue: BitString{
   609  		Bytes: []uint8{
   610  			0xa6, 0x7b, 0x6, 0xec, 0x5e, 0xce,
   611  			0x92, 0x77, 0x2c, 0xa4, 0x13, 0xcb, 0xa3, 0xca, 0x12, 0x56, 0x8f, 0xdc, 0x6c,
   612  			0x7b, 0x45, 0x11, 0xcd, 0x40, 0xa7, 0xf6, 0x59, 0x98, 0x4, 0x2, 0xdf, 0x2b,
   613  			0x99, 0x8b, 0xb9, 0xa4, 0xa8, 0xcb, 0xeb, 0x34, 0xc0, 0xf0, 0xa7, 0x8c, 0xf8,
   614  			0xd9, 0x1e, 0xde, 0x14, 0xa5, 0xed, 0x76, 0xbf, 0x11, 0x6f, 0xe3, 0x60, 0xaa,
   615  			0xfa, 0x88, 0x21, 0x49, 0x4, 0x35,
   616  		},
   617  		BitLength: 512,
   618  	},
   619  }
   620  
   621  var derEncodedSelfSignedCertBytes = []byte{
   622  	0x30, 0x82, 0x02, 0x18, 0x30,
   623  	0x82, 0x01, 0xc2, 0x02, 0x09, 0x00, 0x8c, 0xc3, 0x37, 0x92, 0x10, 0xec, 0x2c,
   624  	0x98, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
   625  	0x05, 0x05, 0x00, 0x30, 0x81, 0x92, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
   626  	0x04, 0x06, 0x13, 0x02, 0x58, 0x58, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
   627  	0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74,
   628  	0x65, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x04, 0x43,
   629  	0x69, 0x74, 0x79, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
   630  	0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64,
   631  	0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x31,
   632  	0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x66, 0x61, 0x6c,
   633  	0x73, 0x65, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f,
   634  	0x6d, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
   635  	0x01, 0x09, 0x01, 0x16, 0x11, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x40, 0x65, 0x78,
   636  	0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d,
   637  	0x30, 0x39, 0x31, 0x30, 0x30, 0x38, 0x30, 0x30, 0x32, 0x35, 0x35, 0x33, 0x5a,
   638  	0x17, 0x0d, 0x31, 0x30, 0x31, 0x30, 0x30, 0x38, 0x30, 0x30, 0x32, 0x35, 0x35,
   639  	0x33, 0x5a, 0x30, 0x81, 0x92, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
   640  	0x06, 0x13, 0x02, 0x58, 0x58, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
   641  	0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
   642  	0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x04, 0x43, 0x69,
   643  	0x74, 0x79, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x18,
   644  	0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
   645  	0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x31, 0x1a,
   646  	0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x66, 0x61, 0x6c, 0x73,
   647  	0x65, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
   648  	0x31, 0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
   649  	0x09, 0x01, 0x16, 0x11, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x40, 0x65, 0x78, 0x61,
   650  	0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06,
   651  	0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03,
   652  	0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, 0x00, 0xcd, 0xb7, 0x63, 0x9c, 0x32, 0x78,
   653  	0xf0, 0x06, 0xaa, 0x27, 0x7f, 0x6e, 0xaf, 0x42, 0x90, 0x2b, 0x59, 0x2d, 0x8c,
   654  	0xbc, 0xbe, 0x38, 0xa1, 0xc9, 0x2b, 0xa4, 0x69, 0x5a, 0x33, 0x1b, 0x1d, 0xea,
   655  	0xde, 0xad, 0xd8, 0xe9, 0xa5, 0xc2, 0x7e, 0x8c, 0x4c, 0x2f, 0xd0, 0xa8, 0x88,
   656  	0x96, 0x57, 0x72, 0x2a, 0x4f, 0x2a, 0xf7, 0x58, 0x9c, 0xf2, 0xc7, 0x70, 0x45,
   657  	0xdc, 0x8f, 0xde, 0xec, 0x35, 0x7d, 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x0d,
   658  	0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00,
   659  	0x03, 0x41, 0x00, 0xa6, 0x7b, 0x06, 0xec, 0x5e, 0xce, 0x92, 0x77, 0x2c, 0xa4,
   660  	0x13, 0xcb, 0xa3, 0xca, 0x12, 0x56, 0x8f, 0xdc, 0x6c, 0x7b, 0x45, 0x11, 0xcd,
   661  	0x40, 0xa7, 0xf6, 0x59, 0x98, 0x04, 0x02, 0xdf, 0x2b, 0x99, 0x8b, 0xb9, 0xa4,
   662  	0xa8, 0xcb, 0xeb, 0x34, 0xc0, 0xf0, 0xa7, 0x8c, 0xf8, 0xd9, 0x1e, 0xde, 0x14,
   663  	0xa5, 0xed, 0x76, 0xbf, 0x11, 0x6f, 0xe3, 0x60, 0xaa, 0xfa, 0x88, 0x21, 0x49,
   664  	0x04, 0x35,
   665  }
   666  
   667  var derEncodedPaypalNULCertBytes = []byte{
   668  	0x30, 0x82, 0x06, 0x44, 0x30,
   669  	0x82, 0x05, 0xad, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x03, 0x00, 0xf0, 0x9b,
   670  	0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
   671  	0x05, 0x00, 0x30, 0x82, 0x01, 0x12, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
   672  	0x04, 0x06, 0x13, 0x02, 0x45, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55,
   673  	0x04, 0x08, 0x13, 0x09, 0x42, 0x61, 0x72, 0x63, 0x65, 0x6c, 0x6f, 0x6e, 0x61,
   674  	0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x42, 0x61,
   675  	0x72, 0x63, 0x65, 0x6c, 0x6f, 0x6e, 0x61, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03,
   676  	0x55, 0x04, 0x0a, 0x13, 0x20, 0x49, 0x50, 0x53, 0x20, 0x43, 0x65, 0x72, 0x74,
   677  	0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
   678  	0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x73, 0x2e, 0x6c, 0x2e, 0x31, 0x2e,
   679  	0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x14, 0x25, 0x67, 0x65, 0x6e, 0x65,
   680  	0x72, 0x61, 0x6c, 0x40, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d,
   681  	0x20, 0x43, 0x2e, 0x49, 0x2e, 0x46, 0x2e, 0x20, 0x20, 0x42, 0x2d, 0x42, 0x36,
   682  	0x32, 0x32, 0x31, 0x30, 0x36, 0x39, 0x35, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03,
   683  	0x55, 0x04, 0x0b, 0x13, 0x25, 0x69, 0x70, 0x73, 0x43, 0x41, 0x20, 0x43, 0x4c,
   684  	0x41, 0x53, 0x45, 0x41, 0x31, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
   685  	0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
   686  	0x69, 0x74, 0x79, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
   687  	0x25, 0x69, 0x70, 0x73, 0x43, 0x41, 0x20, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41,
   688  	0x31, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69,
   689  	0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31,
   690  	0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09,
   691  	0x01, 0x16, 0x11, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x40, 0x69, 0x70,
   692  	0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39,
   693  	0x30, 0x32, 0x32, 0x34, 0x32, 0x33, 0x30, 0x34, 0x31, 0x37, 0x5a, 0x17, 0x0d,
   694  	0x31, 0x31, 0x30, 0x32, 0x32, 0x34, 0x32, 0x33, 0x30, 0x34, 0x31, 0x37, 0x5a,
   695  	0x30, 0x81, 0x94, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
   696  	0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13,
   697  	0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x16,
   698  	0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0d, 0x53, 0x61, 0x6e, 0x20,
   699  	0x46, 0x72, 0x61, 0x6e, 0x63, 0x69, 0x73, 0x63, 0x6f, 0x31, 0x11, 0x30, 0x0f,
   700  	0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x08, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69,
   701  	0x74, 0x79, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0b,
   702  	0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x55, 0x6e, 0x69, 0x74, 0x31, 0x2f,
   703  	0x30, 0x2d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x26, 0x77, 0x77, 0x77, 0x2e,
   704  	0x70, 0x61, 0x79, 0x70, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x73, 0x73,
   705  	0x6c, 0x2e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x6e, 0x65,
   706  	0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x63, 0x63, 0x30, 0x81, 0x9f, 0x30, 0x0d,
   707  	0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
   708  	0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xd2, 0x69,
   709  	0xfa, 0x6f, 0x3a, 0x00, 0xb4, 0x21, 0x1b, 0xc8, 0xb1, 0x02, 0xd7, 0x3f, 0x19,
   710  	0xb2, 0xc4, 0x6d, 0xb4, 0x54, 0xf8, 0x8b, 0x8a, 0xcc, 0xdb, 0x72, 0xc2, 0x9e,
   711  	0x3c, 0x60, 0xb9, 0xc6, 0x91, 0x3d, 0x82, 0xb7, 0x7d, 0x99, 0xff, 0xd1, 0x29,
   712  	0x84, 0xc1, 0x73, 0x53, 0x9c, 0x82, 0xdd, 0xfc, 0x24, 0x8c, 0x77, 0xd5, 0x41,
   713  	0xf3, 0xe8, 0x1e, 0x42, 0xa1, 0xad, 0x2d, 0x9e, 0xff, 0x5b, 0x10, 0x26, 0xce,
   714  	0x9d, 0x57, 0x17, 0x73, 0x16, 0x23, 0x38, 0xc8, 0xd6, 0xf1, 0xba, 0xa3, 0x96,
   715  	0x5b, 0x16, 0x67, 0x4a, 0x4f, 0x73, 0x97, 0x3a, 0x4d, 0x14, 0xa4, 0xf4, 0xe2,
   716  	0x3f, 0x8b, 0x05, 0x83, 0x42, 0xd1, 0xd0, 0xdc, 0x2f, 0x7a, 0xe5, 0xb6, 0x10,
   717  	0xb2, 0x11, 0xc0, 0xdc, 0x21, 0x2a, 0x90, 0xff, 0xae, 0x97, 0x71, 0x5a, 0x49,
   718  	0x81, 0xac, 0x40, 0xf3, 0x3b, 0xb8, 0x59, 0xb2, 0x4f, 0x02, 0x03, 0x01, 0x00,
   719  	0x01, 0xa3, 0x82, 0x03, 0x21, 0x30, 0x82, 0x03, 0x1d, 0x30, 0x09, 0x06, 0x03,
   720  	0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x11, 0x06, 0x09, 0x60, 0x86,
   721  	0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x01, 0x04, 0x04, 0x03, 0x02, 0x06, 0x40,
   722  	0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x03, 0xf8,
   723  	0x30, 0x13, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08,
   724  	0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x30, 0x1d, 0x06, 0x03, 0x55,
   725  	0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x61, 0x8f, 0x61, 0x34, 0x43, 0x55, 0x14,
   726  	0x7f, 0x27, 0x09, 0xce, 0x4c, 0x8b, 0xea, 0x9b, 0x7b, 0x19, 0x25, 0xbc, 0x6e,
   727  	0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
   728  	0x0e, 0x07, 0x60, 0xd4, 0x39, 0xc9, 0x1b, 0x5b, 0x5d, 0x90, 0x7b, 0x23, 0xc8,
   729  	0xd2, 0x34, 0x9d, 0x4a, 0x9a, 0x46, 0x39, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d,
   730  	0x11, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x1d, 0x12, 0x04,
   731  	0x15, 0x30, 0x13, 0x81, 0x11, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x40,
   732  	0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x72, 0x06, 0x09,
   733  	0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x0d, 0x04, 0x65, 0x16, 0x63,
   734  	0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
   735  	0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4e,
   736  	0x4f, 0x54, 0x20, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x45, 0x44, 0x2e,
   737  	0x20, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x20, 0x53, 0x65, 0x72, 0x76,
   738  	0x65, 0x72, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
   739  	0x65, 0x20, 0x69, 0x73, 0x73, 0x75, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x68,
   740  	0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70,
   741  	0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x2f, 0x06, 0x09, 0x60,
   742  	0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x02, 0x04, 0x22, 0x16, 0x20, 0x68,
   743  	0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70,
   744  	0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61,
   745  	0x32, 0x30, 0x30, 0x32, 0x2f, 0x30, 0x43, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
   746  	0x86, 0xf8, 0x42, 0x01, 0x04, 0x04, 0x36, 0x16, 0x34, 0x68, 0x74, 0x74, 0x70,
   747  	0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61,
   748  	0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 0x30,
   749  	0x32, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 0x32, 0x43, 0x4c,
   750  	0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x46, 0x06, 0x09,
   751  	0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x03, 0x04, 0x39, 0x16, 0x37,
   752  	0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69,
   753  	0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63,
   754  	0x61, 0x32, 0x30, 0x30, 0x32, 0x2f, 0x72, 0x65, 0x76, 0x6f, 0x63, 0x61, 0x74,
   755  	0x69, 0x6f, 0x6e, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x68, 0x74,
   756  	0x6d, 0x6c, 0x3f, 0x30, 0x43, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8,
   757  	0x42, 0x01, 0x07, 0x04, 0x36, 0x16, 0x34, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a,
   758  	0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63,
   759  	0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 0x32, 0x2f,
   760  	0x72, 0x65, 0x6e, 0x65, 0x77, 0x61, 0x6c, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41,
   761  	0x31, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x3f, 0x30, 0x41, 0x06, 0x09, 0x60, 0x86,
   762  	0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x08, 0x04, 0x34, 0x16, 0x32, 0x68, 0x74,
   763  	0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70, 0x73,
   764  	0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32,
   765  	0x30, 0x30, 0x32, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x43, 0x4c, 0x41,
   766  	0x53, 0x45, 0x41, 0x31, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x30, 0x81, 0x83, 0x06,
   767  	0x03, 0x55, 0x1d, 0x1f, 0x04, 0x7c, 0x30, 0x7a, 0x30, 0x39, 0xa0, 0x37, 0xa0,
   768  	0x35, 0x86, 0x33, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77,
   769  	0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70,
   770  	0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 0x32, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61,
   771  	0x32, 0x30, 0x30, 0x32, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x63,
   772  	0x72, 0x6c, 0x30, 0x3d, 0xa0, 0x3b, 0xa0, 0x39, 0x86, 0x37, 0x68, 0x74, 0x74,
   773  	0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x69,
   774  	0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63,
   775  	0x61, 0x32, 0x30, 0x30, 0x32, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30,
   776  	0x30, 0x32, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x63, 0x72, 0x6c,
   777  	0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
   778  	0x26, 0x30, 0x24, 0x30, 0x22, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
   779  	0x30, 0x01, 0x86, 0x16, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63,
   780  	0x73, 0x70, 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
   781  	0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
   782  	0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x68, 0xee, 0x79, 0x97, 0x97, 0xdd, 0x3b,
   783  	0xef, 0x16, 0x6a, 0x06, 0xf2, 0x14, 0x9a, 0x6e, 0xcd, 0x9e, 0x12, 0xf7, 0xaa,
   784  	0x83, 0x10, 0xbd, 0xd1, 0x7c, 0x98, 0xfa, 0xc7, 0xae, 0xd4, 0x0e, 0x2c, 0x9e,
   785  	0x38, 0x05, 0x9d, 0x52, 0x60, 0xa9, 0x99, 0x0a, 0x81, 0xb4, 0x98, 0x90, 0x1d,
   786  	0xae, 0xbb, 0x4a, 0xd7, 0xb9, 0xdc, 0x88, 0x9e, 0x37, 0x78, 0x41, 0x5b, 0xf7,
   787  	0x82, 0xa5, 0xf2, 0xba, 0x41, 0x25, 0x5a, 0x90, 0x1a, 0x1e, 0x45, 0x38, 0xa1,
   788  	0x52, 0x58, 0x75, 0x94, 0x26, 0x44, 0xfb, 0x20, 0x07, 0xba, 0x44, 0xcc, 0xe5,
   789  	0x4a, 0x2d, 0x72, 0x3f, 0x98, 0x47, 0xf6, 0x26, 0xdc, 0x05, 0x46, 0x05, 0x07,
   790  	0x63, 0x21, 0xab, 0x46, 0x9b, 0x9c, 0x78, 0xd5, 0x54, 0x5b, 0x3d, 0x0c, 0x1e,
   791  	0xc8, 0x64, 0x8c, 0xb5, 0x50, 0x23, 0x82, 0x6f, 0xdb, 0xb8, 0x22, 0x1c, 0x43,
   792  	0x96, 0x07, 0xa8, 0xbb,
   793  }
   794  
   795  var stringSliceTestData = [][]string{
   796  	{"foo", "bar"},
   797  	{"foo", "\\bar"},
   798  	{"foo", "\"bar\""},
   799  	{"foo", "åäö"},
   800  }
   801  
   802  func TestStringSlice(t *testing.T) {
   803  	for _, test := range stringSliceTestData {
   804  		bs, err := Marshal(test)
   805  		if err != nil {
   806  			t.Error(err)
   807  		}
   808  
   809  		var res []string
   810  		_, err = Unmarshal(bs, &res)
   811  		if err != nil {
   812  			t.Error(err)
   813  		}
   814  
   815  		if fmt.Sprintf("%v", res) != fmt.Sprintf("%v", test) {
   816  			t.Errorf("incorrect marshal/unmarshal; %v != %v", res, test)
   817  		}
   818  	}
   819  }
   820  
   821  type explicitTaggedTimeTest struct {
   822  	Time time.Time `asn1:"explicit,tag:0"`
   823  }
   824  
   825  var explicitTaggedTimeTestData = []struct {
   826  	in  []byte
   827  	out explicitTaggedTimeTest
   828  }{
   829  	{[]byte{0x30, 0x11, 0xa0, 0xf, 0x17, 0xd, '9', '1', '0', '5', '0', '6', '1', '6', '4', '5', '4', '0', 'Z'},
   830  		explicitTaggedTimeTest{time.Date(1991, 05, 06, 16, 45, 40, 0, time.UTC)}},
   831  	{[]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'},
   832  		explicitTaggedTimeTest{time.Date(2010, 01, 02, 03, 04, 05, 0, time.FixedZone("", 6*60*60+7*60))}},
   833  }
   834  
   835  func TestExplicitTaggedTime(t *testing.T) {
   836  	// Test that a time.Time will match either tagUTCTime or
   837  	// tagGeneralizedTime.
   838  	for i, test := range explicitTaggedTimeTestData {
   839  		var got explicitTaggedTimeTest
   840  		_, err := Unmarshal(test.in, &got)
   841  		if err != nil {
   842  			t.Errorf("Unmarshal failed at index %d %v", i, err)
   843  		}
   844  		if !got.Time.Equal(test.out.Time) {
   845  			t.Errorf("#%d: got %v, want %v", i, got.Time, test.out.Time)
   846  		}
   847  	}
   848  }
   849  
   850  type implicitTaggedTimeTest struct {
   851  	Time time.Time `asn1:"tag:24"`
   852  }
   853  
   854  func TestImplicitTaggedTime(t *testing.T) {
   855  	// An implicitly tagged time value, that happens to have an implicit
   856  	// tag equal to a GENERALIZEDTIME, should still be parsed as a UTCTime.
   857  	// (There's no "timeType" in fieldParameters to determine what type of
   858  	// time should be expected when implicitly tagged.)
   859  	der := []byte{0x30, 0x0f, 0x80 | 24, 0xd, '9', '1', '0', '5', '0', '6', '1', '6', '4', '5', '4', '0', 'Z'}
   860  	var result implicitTaggedTimeTest
   861  	if _, err := Unmarshal(der, &result); err != nil {
   862  		t.Fatalf("Error while parsing: %s", err)
   863  	}
   864  	if expected := time.Date(1991, 05, 06, 16, 45, 40, 0, time.UTC); !result.Time.Equal(expected) {
   865  		t.Errorf("Wrong result. Got %v, want %v", result.Time, expected)
   866  	}
   867  }