check hosts in ssl certificates

This commit is contained in:
Mikaël Cluseau
2018-08-09 15:07:53 +02:00
parent 481115e0d0
commit 331f9ea96c
362 changed files with 2499 additions and 59344 deletions

3
vendor/golang.org/x/crypto/AUTHORS generated vendored Normal file
View File

@ -0,0 +1,3 @@
# This source code refers to The Go Authors for copyright purposes.
# The master list of authors is in the main Go distribution,
# visible at https://tip.golang.org/AUTHORS.

3
vendor/golang.org/x/crypto/CONTRIBUTORS generated vendored Normal file
View File

@ -0,0 +1,3 @@
# This source code was written by the Go contributors.
# The master list of contributors is in the main Go distribution,
# visible at https://tip.golang.org/CONTRIBUTORS.

27
vendor/golang.org/x/crypto/LICENSE generated vendored Normal file
View File

@ -0,0 +1,27 @@
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

22
vendor/golang.org/x/crypto/PATENTS generated vendored Normal file
View File

@ -0,0 +1,22 @@
Additional IP Rights Grant (Patents)
"This implementation" means the copyrightable works distributed by
Google as part of the Go project.
Google hereby grants to You a perpetual, worldwide, non-exclusive,
no-charge, royalty-free, irrevocable (except as stated in this section)
patent license to make, have made, use, offer to sell, sell, import,
transfer and otherwise run, modify and propagate the contents of this
implementation of Go, where such license applies only to those patent
claims, both currently owned or controlled by Google and acquired in
the future, licensable by Google that are necessarily infringed by this
implementation of Go. This grant does not include claims that would be
infringed only as a consequence of further modification of this
implementation. If you or your agent or exclusive licensee institute or
order or agree to the institution of patent litigation against any
entity (including a cross-claim or counterclaim in a lawsuit) alleging
that this implementation of Go or any code incorporated within this
implementation of Go constitutes direct or contributory patent
infringement, or inducement of patent infringement, then any patent
rights granted to you under this License for this implementation of Go
shall terminate as of the date such litigation is filed.

View File

@ -1,333 +0,0 @@
// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package cryptobyte
import (
"bytes"
encoding_asn1 "encoding/asn1"
"math/big"
"reflect"
"testing"
"time"
"golang.org/x/crypto/cryptobyte/asn1"
)
type readASN1Test struct {
name string
in []byte
tag asn1.Tag
ok bool
out interface{}
}
var readASN1TestData = []readASN1Test{
{"valid", []byte{0x30, 2, 1, 2}, 0x30, true, []byte{1, 2}},
{"truncated", []byte{0x30, 3, 1, 2}, 0x30, false, nil},
{"zero length of length", []byte{0x30, 0x80}, 0x30, false, nil},
{"invalid long form length", []byte{0x30, 0x81, 1, 1}, 0x30, false, nil},
{"non-minimal length", append([]byte{0x30, 0x82, 0, 0x80}, make([]byte, 0x80)...), 0x30, false, nil},
{"invalid tag", []byte{0xa1, 3, 0x4, 1, 1}, 31, false, nil},
{"high tag", []byte{0x1f, 0x81, 0x80, 0x01, 2, 1, 2}, 0xff /* actually 0x4001, but tag is uint8 */, false, nil},
}
func TestReadASN1(t *testing.T) {
for _, test := range readASN1TestData {
t.Run(test.name, func(t *testing.T) {
var in, out String = test.in, nil
ok := in.ReadASN1(&out, test.tag)
if ok != test.ok || ok && !bytes.Equal(out, test.out.([]byte)) {
t.Errorf("in.ReadASN1() = %v, want %v; out = %v, want %v", ok, test.ok, out, test.out)
}
})
}
}
func TestReadASN1Optional(t *testing.T) {
var empty String
var present bool
ok := empty.ReadOptionalASN1(nil, &present, 0xa0)
if !ok || present {
t.Errorf("empty.ReadOptionalASN1() = %v, want true; present = %v want false", ok, present)
}
var in, out String = []byte{0xa1, 3, 0x4, 1, 1}, nil
ok = in.ReadOptionalASN1(&out, &present, 0xa0)
if !ok || present {
t.Errorf("in.ReadOptionalASN1() = %v, want true, present = %v, want false", ok, present)
}
ok = in.ReadOptionalASN1(&out, &present, 0xa1)
wantBytes := []byte{4, 1, 1}
if !ok || !present || !bytes.Equal(out, wantBytes) {
t.Errorf("in.ReadOptionalASN1() = %v, want true; present = %v, want true; out = %v, want = %v", ok, present, out, wantBytes)
}
}
var optionalOctetStringTestData = []struct {
readASN1Test
present bool
}{
{readASN1Test{"empty", []byte{}, 0xa0, true, []byte{}}, false},
{readASN1Test{"invalid", []byte{0xa1, 3, 0x4, 2, 1}, 0xa1, false, []byte{}}, true},
{readASN1Test{"missing", []byte{0xa1, 3, 0x4, 1, 1}, 0xa0, true, []byte{}}, false},
{readASN1Test{"present", []byte{0xa1, 3, 0x4, 1, 1}, 0xa1, true, []byte{1}}, true},
}
func TestReadASN1OptionalOctetString(t *testing.T) {
for _, test := range optionalOctetStringTestData {
t.Run(test.name, func(t *testing.T) {
in := String(test.in)
var out []byte
var present bool
ok := in.ReadOptionalASN1OctetString(&out, &present, test.tag)
if ok != test.ok || present != test.present || !bytes.Equal(out, test.out.([]byte)) {
t.Errorf("in.ReadOptionalASN1OctetString() = %v, want %v; present = %v want %v; out = %v, want %v", ok, test.ok, present, test.present, out, test.out)
}
})
}
}
const defaultInt = -1
var optionalIntTestData = []readASN1Test{
{"empty", []byte{}, 0xa0, true, defaultInt},
{"invalid", []byte{0xa1, 3, 0x2, 2, 127}, 0xa1, false, 0},
{"missing", []byte{0xa1, 3, 0x2, 1, 127}, 0xa0, true, defaultInt},
{"present", []byte{0xa1, 3, 0x2, 1, 42}, 0xa1, true, 42},
}
func TestReadASN1OptionalInteger(t *testing.T) {
for _, test := range optionalIntTestData {
t.Run(test.name, func(t *testing.T) {
in := String(test.in)
var out int
ok := in.ReadOptionalASN1Integer(&out, test.tag, defaultInt)
if ok != test.ok || ok && out != test.out.(int) {
t.Errorf("in.ReadOptionalASN1Integer() = %v, want %v; out = %v, want %v", ok, test.ok, out, test.out)
}
})
}
}
func TestReadASN1IntegerSigned(t *testing.T) {
testData64 := []struct {
in []byte
out int64
}{
{[]byte{2, 3, 128, 0, 0}, -0x800000},
{[]byte{2, 2, 255, 0}, -256},
{[]byte{2, 2, 255, 127}, -129},
{[]byte{2, 1, 128}, -128},
{[]byte{2, 1, 255}, -1},
{[]byte{2, 1, 0}, 0},
{[]byte{2, 1, 1}, 1},
{[]byte{2, 1, 2}, 2},
{[]byte{2, 1, 127}, 127},
{[]byte{2, 2, 0, 128}, 128},
{[]byte{2, 2, 1, 0}, 256},
{[]byte{2, 4, 0, 128, 0, 0}, 0x800000},
}
for i, test := range testData64 {
in := String(test.in)
var out int64
ok := in.ReadASN1Integer(&out)
if !ok || out != test.out {
t.Errorf("#%d: in.ReadASN1Integer() = %v, want true; out = %d, want %d", i, ok, out, test.out)
}
}
// Repeat the same cases, reading into a big.Int.
t.Run("big.Int", func(t *testing.T) {
for i, test := range testData64 {
in := String(test.in)
var out big.Int
ok := in.ReadASN1Integer(&out)
if !ok || out.Int64() != test.out {
t.Errorf("#%d: in.ReadASN1Integer() = %v, want true; out = %d, want %d", i, ok, out.Int64(), test.out)
}
}
})
// Repeat with the implicit-tagging functions
t.Run("WithTag", func(t *testing.T) {
for i, test := range testData64 {
tag := asn1.Tag((i * 3) % 32).ContextSpecific()
testData := make([]byte, len(test.in))
copy(testData, test.in)
// Alter the tag of the test case.
testData[0] = uint8(tag)
in := String(testData)
var out int64
ok := in.ReadASN1Int64WithTag(&out, tag)
if !ok || out != test.out {
t.Errorf("#%d: in.ReadASN1Int64WithTag() = %v, want true; out = %d, want %d", i, ok, out, test.out)
}
var b Builder
b.AddASN1Int64WithTag(test.out, tag)
result, err := b.Bytes()
if err != nil {
t.Errorf("#%d: AddASN1Int64WithTag failed: %s", i, err)
continue
}
if !bytes.Equal(result, testData) {
t.Errorf("#%d: AddASN1Int64WithTag: got %x, want %x", i, result, testData)
}
}
})
}
func TestReadASN1IntegerUnsigned(t *testing.T) {
testData := []struct {
in []byte
out uint64
}{
{[]byte{2, 1, 0}, 0},
{[]byte{2, 1, 1}, 1},
{[]byte{2, 1, 2}, 2},
{[]byte{2, 1, 127}, 127},
{[]byte{2, 2, 0, 128}, 128},
{[]byte{2, 2, 1, 0}, 256},
{[]byte{2, 4, 0, 128, 0, 0}, 0x800000},
{[]byte{2, 8, 127, 255, 255, 255, 255, 255, 255, 255}, 0x7fffffffffffffff},
{[]byte{2, 9, 0, 128, 0, 0, 0, 0, 0, 0, 0}, 0x8000000000000000},
{[]byte{2, 9, 0, 255, 255, 255, 255, 255, 255, 255, 255}, 0xffffffffffffffff},
}
for i, test := range testData {
in := String(test.in)
var out uint64
ok := in.ReadASN1Integer(&out)
if !ok || out != test.out {
t.Errorf("#%d: in.ReadASN1Integer() = %v, want true; out = %d, want %d", i, ok, out, test.out)
}
}
}
func TestReadASN1IntegerInvalid(t *testing.T) {
testData := []String{
[]byte{3, 1, 0}, // invalid tag
// truncated
[]byte{2, 1},
[]byte{2, 2, 0},
// not minimally encoded
[]byte{2, 2, 0, 1},
[]byte{2, 2, 0xff, 0xff},
}
for i, test := range testData {
var out int64
if test.ReadASN1Integer(&out) {
t.Errorf("#%d: in.ReadASN1Integer() = true, want false (out = %d)", i, out)
}
}
}
func TestASN1ObjectIdentifier(t *testing.T) {
testData := []struct {
in []byte
ok bool
out []int
}{
{[]byte{}, false, []int{}},
{[]byte{6, 0}, false, []int{}},
{[]byte{5, 1, 85}, false, []int{2, 5}},
{[]byte{6, 1, 85}, true, []int{2, 5}},
{[]byte{6, 2, 85, 0x02}, true, []int{2, 5, 2}},
{[]byte{6, 4, 85, 0x02, 0xc0, 0x00}, true, []int{2, 5, 2, 0x2000}},
{[]byte{6, 3, 0x81, 0x34, 0x03}, true, []int{2, 100, 3}},
{[]byte{6, 7, 85, 0x02, 0xc0, 0x80, 0x80, 0x80, 0x80}, false, []int{}},
}
for i, test := range testData {
in := String(test.in)
var out encoding_asn1.ObjectIdentifier
ok := in.ReadASN1ObjectIdentifier(&out)
if ok != test.ok || ok && !out.Equal(test.out) {
t.Errorf("#%d: in.ReadASN1ObjectIdentifier() = %v, want %v; out = %v, want %v", i, ok, test.ok, out, test.out)
continue
}
var b Builder
b.AddASN1ObjectIdentifier(out)
result, err := b.Bytes()
if builderOk := err == nil; test.ok != builderOk {
t.Errorf("#%d: error from Builder.Bytes: %s", i, err)
continue
}
if test.ok && !bytes.Equal(result, test.in) {
t.Errorf("#%d: reserialisation didn't match, got %x, want %x", i, result, test.in)
continue
}
}
}
func TestReadASN1GeneralizedTime(t *testing.T) {
testData := []struct {
in string
ok bool
out time.Time
}{
{"20100102030405Z", true, time.Date(2010, 01, 02, 03, 04, 05, 0, time.UTC)},
{"20100102030405", false, time.Time{}},
{"20100102030405+0607", true, time.Date(2010, 01, 02, 03, 04, 05, 0, time.FixedZone("", 6*60*60+7*60))},
{"20100102030405-0607", true, time.Date(2010, 01, 02, 03, 04, 05, 0, time.FixedZone("", -6*60*60-7*60))},
/* These are invalid times. However, the time package normalises times
* and they were accepted in some versions. See #11134. */
{"00000100000000Z", false, time.Time{}},
{"20101302030405Z", false, time.Time{}},
{"20100002030405Z", false, time.Time{}},
{"20100100030405Z", false, time.Time{}},
{"20100132030405Z", false, time.Time{}},
{"20100231030405Z", false, time.Time{}},
{"20100102240405Z", false, time.Time{}},
{"20100102036005Z", false, time.Time{}},
{"20100102030460Z", false, time.Time{}},
{"-20100102030410Z", false, time.Time{}},
{"2010-0102030410Z", false, time.Time{}},
{"2010-0002030410Z", false, time.Time{}},
{"201001-02030410Z", false, time.Time{}},
{"20100102-030410Z", false, time.Time{}},
{"2010010203-0410Z", false, time.Time{}},
{"201001020304-10Z", false, time.Time{}},
}
for i, test := range testData {
in := String(append([]byte{byte(asn1.GeneralizedTime), byte(len(test.in))}, test.in...))
var out time.Time
ok := in.ReadASN1GeneralizedTime(&out)
if ok != test.ok || ok && !reflect.DeepEqual(out, test.out) {
t.Errorf("#%d: in.ReadASN1GeneralizedTime() = %v, want %v; out = %q, want %q", i, ok, test.ok, out, test.out)
}
}
}
func TestReadASN1BitString(t *testing.T) {
testData := []struct {
in []byte
ok bool
out encoding_asn1.BitString
}{
{[]byte{}, false, encoding_asn1.BitString{}},
{[]byte{0x00}, true, encoding_asn1.BitString{}},
{[]byte{0x07, 0x00}, true, encoding_asn1.BitString{Bytes: []byte{0}, BitLength: 1}},
{[]byte{0x07, 0x01}, false, encoding_asn1.BitString{}},
{[]byte{0x07, 0x40}, false, encoding_asn1.BitString{}},
{[]byte{0x08, 0x00}, false, encoding_asn1.BitString{}},
{[]byte{0xff}, false, encoding_asn1.BitString{}},
{[]byte{0xfe, 0x00}, false, encoding_asn1.BitString{}},
}
for i, test := range testData {
in := String(append([]byte{3, byte(len(test.in))}, test.in...))
var out encoding_asn1.BitString
ok := in.ReadASN1BitString(&out)
if ok != test.ok || ok && (!bytes.Equal(out.Bytes, test.out.Bytes) || out.BitLength != test.out.BitLength) {
t.Errorf("#%d: in.ReadASN1BitString() = %v, want %v; out = %v, want %v", i, ok, test.ok, out, test.out)
}
}
}

View File

@ -1,428 +0,0 @@
// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package cryptobyte
import (
"bytes"
"errors"
"fmt"
"testing"
)
func builderBytesEq(b *Builder, want ...byte) error {
got := b.BytesOrPanic()
if !bytes.Equal(got, want) {
return fmt.Errorf("Bytes() = %v, want %v", got, want)
}
return nil
}
func TestContinuationError(t *testing.T) {
const errorStr = "TestContinuationError"
var b Builder
b.AddUint8LengthPrefixed(func(b *Builder) {
b.AddUint8(1)
panic(BuildError{Err: errors.New(errorStr)})
})
ret, err := b.Bytes()
if ret != nil {
t.Error("expected nil result")
}
if err == nil {
t.Fatal("unexpected nil error")
}
if s := err.Error(); s != errorStr {
t.Errorf("expected error %q, got %v", errorStr, s)
}
}
func TestContinuationNonError(t *testing.T) {
defer func() {
recover()
}()
var b Builder
b.AddUint8LengthPrefixed(func(b *Builder) {
b.AddUint8(1)
panic(1)
})
t.Error("Builder did not panic")
}
func TestGeneratedPanic(t *testing.T) {
defer func() {
recover()
}()
var b Builder
b.AddUint8LengthPrefixed(func(b *Builder) {
var p *byte
*p = 0
})
t.Error("Builder did not panic")
}
func TestBytes(t *testing.T) {
var b Builder
v := []byte("foobarbaz")
b.AddBytes(v[0:3])
b.AddBytes(v[3:4])
b.AddBytes(v[4:9])
if err := builderBytesEq(&b, v...); err != nil {
t.Error(err)
}
s := String(b.BytesOrPanic())
for _, w := range []string{"foo", "bar", "baz"} {
var got []byte
if !s.ReadBytes(&got, 3) {
t.Errorf("ReadBytes() = false, want true (w = %v)", w)
}
want := []byte(w)
if !bytes.Equal(got, want) {
t.Errorf("ReadBytes(): got = %v, want %v", got, want)
}
}
if len(s) != 0 {
t.Errorf("len(s) = %d, want 0", len(s))
}
}
func TestUint8(t *testing.T) {
var b Builder
b.AddUint8(42)
if err := builderBytesEq(&b, 42); err != nil {
t.Error(err)
}
var s String = b.BytesOrPanic()
var v uint8
if !s.ReadUint8(&v) {
t.Error("ReadUint8() = false, want true")
}
if v != 42 {
t.Errorf("v = %d, want 42", v)
}
if len(s) != 0 {
t.Errorf("len(s) = %d, want 0", len(s))
}
}
func TestUint16(t *testing.T) {
var b Builder
b.AddUint16(65534)
if err := builderBytesEq(&b, 255, 254); err != nil {
t.Error(err)
}
var s String = b.BytesOrPanic()
var v uint16
if !s.ReadUint16(&v) {
t.Error("ReadUint16() == false, want true")
}
if v != 65534 {
t.Errorf("v = %d, want 65534", v)
}
if len(s) != 0 {
t.Errorf("len(s) = %d, want 0", len(s))
}
}
func TestUint24(t *testing.T) {
var b Builder
b.AddUint24(0xfffefd)
if err := builderBytesEq(&b, 255, 254, 253); err != nil {
t.Error(err)
}
var s String = b.BytesOrPanic()
var v uint32
if !s.ReadUint24(&v) {
t.Error("ReadUint8() = false, want true")
}
if v != 0xfffefd {
t.Errorf("v = %d, want fffefd", v)
}
if len(s) != 0 {
t.Errorf("len(s) = %d, want 0", len(s))
}
}
func TestUint24Truncation(t *testing.T) {
var b Builder
b.AddUint24(0x10111213)
if err := builderBytesEq(&b, 0x11, 0x12, 0x13); err != nil {
t.Error(err)
}
}
func TestUint32(t *testing.T) {
var b Builder
b.AddUint32(0xfffefdfc)
if err := builderBytesEq(&b, 255, 254, 253, 252); err != nil {
t.Error(err)
}
var s String = b.BytesOrPanic()
var v uint32
if !s.ReadUint32(&v) {
t.Error("ReadUint8() = false, want true")
}
if v != 0xfffefdfc {
t.Errorf("v = %x, want fffefdfc", v)
}
if len(s) != 0 {
t.Errorf("len(s) = %d, want 0", len(s))
}
}
func TestUMultiple(t *testing.T) {
var b Builder
b.AddUint8(23)
b.AddUint32(0xfffefdfc)
b.AddUint16(42)
if err := builderBytesEq(&b, 23, 255, 254, 253, 252, 0, 42); err != nil {
t.Error(err)
}
var s String = b.BytesOrPanic()
var (
x uint8
y uint32
z uint16
)
if !s.ReadUint8(&x) || !s.ReadUint32(&y) || !s.ReadUint16(&z) {
t.Error("ReadUint8() = false, want true")
}
if x != 23 || y != 0xfffefdfc || z != 42 {
t.Errorf("x, y, z = %d, %d, %d; want 23, 4294901244, 5", x, y, z)
}
if len(s) != 0 {
t.Errorf("len(s) = %d, want 0", len(s))
}
}
func TestUint8LengthPrefixedSimple(t *testing.T) {
var b Builder
b.AddUint8LengthPrefixed(func(c *Builder) {
c.AddUint8(23)
c.AddUint8(42)
})
if err := builderBytesEq(&b, 2, 23, 42); err != nil {
t.Error(err)
}
var base, child String = b.BytesOrPanic(), nil
var x, y uint8
if !base.ReadUint8LengthPrefixed(&child) || !child.ReadUint8(&x) ||
!child.ReadUint8(&y) {
t.Error("parsing failed")
}
if x != 23 || y != 42 {
t.Errorf("want x, y == 23, 42; got %d, %d", x, y)
}
if len(base) != 0 {
t.Errorf("len(base) = %d, want 0", len(base))
}
if len(child) != 0 {
t.Errorf("len(child) = %d, want 0", len(child))
}
}
func TestUint8LengthPrefixedMulti(t *testing.T) {
var b Builder
b.AddUint8LengthPrefixed(func(c *Builder) {
c.AddUint8(23)
c.AddUint8(42)
})
b.AddUint8(5)
b.AddUint8LengthPrefixed(func(c *Builder) {
c.AddUint8(123)
c.AddUint8(234)
})
if err := builderBytesEq(&b, 2, 23, 42, 5, 2, 123, 234); err != nil {
t.Error(err)
}
var s, child String = b.BytesOrPanic(), nil
var u, v, w, x, y uint8
if !s.ReadUint8LengthPrefixed(&child) || !child.ReadUint8(&u) || !child.ReadUint8(&v) ||
!s.ReadUint8(&w) || !s.ReadUint8LengthPrefixed(&child) || !child.ReadUint8(&x) || !child.ReadUint8(&y) {
t.Error("parsing failed")
}
if u != 23 || v != 42 || w != 5 || x != 123 || y != 234 {
t.Errorf("u, v, w, x, y = %d, %d, %d, %d, %d; want 23, 42, 5, 123, 234",
u, v, w, x, y)
}
if len(s) != 0 {
t.Errorf("len(s) = %d, want 0", len(s))
}
if len(child) != 0 {
t.Errorf("len(child) = %d, want 0", len(child))
}
}
func TestUint8LengthPrefixedNested(t *testing.T) {
var b Builder
b.AddUint8LengthPrefixed(func(c *Builder) {
c.AddUint8(5)
c.AddUint8LengthPrefixed(func(d *Builder) {
d.AddUint8(23)
d.AddUint8(42)
})
c.AddUint8(123)
})
if err := builderBytesEq(&b, 5, 5, 2, 23, 42, 123); err != nil {
t.Error(err)
}
var base, child1, child2 String = b.BytesOrPanic(), nil, nil
var u, v, w, x uint8
if !base.ReadUint8LengthPrefixed(&child1) {
t.Error("parsing base failed")
}
if !child1.ReadUint8(&u) || !child1.ReadUint8LengthPrefixed(&child2) || !child1.ReadUint8(&x) {
t.Error("parsing child1 failed")
}
if !child2.ReadUint8(&v) || !child2.ReadUint8(&w) {
t.Error("parsing child2 failed")
}
if u != 5 || v != 23 || w != 42 || x != 123 {
t.Errorf("u, v, w, x = %d, %d, %d, %d, want 5, 23, 42, 123",
u, v, w, x)
}
if len(base) != 0 {
t.Errorf("len(base) = %d, want 0", len(base))
}
if len(child1) != 0 {
t.Errorf("len(child1) = %d, want 0", len(child1))
}
if len(base) != 0 {
t.Errorf("len(child2) = %d, want 0", len(child2))
}
}
func TestPreallocatedBuffer(t *testing.T) {
var buf [5]byte
b := NewBuilder(buf[0:0])
b.AddUint8(1)
b.AddUint8LengthPrefixed(func(c *Builder) {
c.AddUint8(3)
c.AddUint8(4)
})
b.AddUint16(1286) // Outgrow buf by one byte.
want := []byte{1, 2, 3, 4, 0}
if !bytes.Equal(buf[:], want) {
t.Errorf("buf = %v want %v", buf, want)
}
if err := builderBytesEq(b, 1, 2, 3, 4, 5, 6); err != nil {
t.Error(err)
}
}
func TestWriteWithPendingChild(t *testing.T) {
var b Builder
b.AddUint8LengthPrefixed(func(c *Builder) {
c.AddUint8LengthPrefixed(func(d *Builder) {
defer func() {
if recover() == nil {
t.Errorf("recover() = nil, want error; c.AddUint8() did not panic")
}
}()
c.AddUint8(2) // panics
defer func() {
if recover() == nil {
t.Errorf("recover() = nil, want error; b.AddUint8() did not panic")
}
}()
b.AddUint8(2) // panics
})
defer func() {
if recover() == nil {
t.Errorf("recover() = nil, want error; b.AddUint8() did not panic")
}
}()
b.AddUint8(2) // panics
})
}
// ASN.1
func TestASN1Int64(t *testing.T) {
tests := []struct {
in int64
want []byte
}{
{-0x800000, []byte{2, 3, 128, 0, 0}},
{-256, []byte{2, 2, 255, 0}},
{-129, []byte{2, 2, 255, 127}},
{-128, []byte{2, 1, 128}},
{-1, []byte{2, 1, 255}},
{0, []byte{2, 1, 0}},
{1, []byte{2, 1, 1}},
{2, []byte{2, 1, 2}},
{127, []byte{2, 1, 127}},
{128, []byte{2, 2, 0, 128}},
{256, []byte{2, 2, 1, 0}},
{0x800000, []byte{2, 4, 0, 128, 0, 0}},
}
for i, tt := range tests {
var b Builder
b.AddASN1Int64(tt.in)
if err := builderBytesEq(&b, tt.want...); err != nil {
t.Errorf("%v, (i = %d; in = %v)", err, i, tt.in)
}
var n int64
s := String(b.BytesOrPanic())
ok := s.ReadASN1Integer(&n)
if !ok || n != tt.in {
t.Errorf("s.ReadASN1Integer(&n) = %v, n = %d; want true, n = %d (i = %d)",
ok, n, tt.in, i)
}
if len(s) != 0 {
t.Errorf("len(s) = %d, want 0", len(s))
}
}
}
func TestASN1Uint64(t *testing.T) {
tests := []struct {
in uint64
want []byte
}{
{0, []byte{2, 1, 0}},
{1, []byte{2, 1, 1}},
{2, []byte{2, 1, 2}},
{127, []byte{2, 1, 127}},
{128, []byte{2, 2, 0, 128}},
{256, []byte{2, 2, 1, 0}},
{0x800000, []byte{2, 4, 0, 128, 0, 0}},
{0x7fffffffffffffff, []byte{2, 8, 127, 255, 255, 255, 255, 255, 255, 255}},
{0x8000000000000000, []byte{2, 9, 0, 128, 0, 0, 0, 0, 0, 0, 0}},
{0xffffffffffffffff, []byte{2, 9, 0, 255, 255, 255, 255, 255, 255, 255, 255}},
}
for i, tt := range tests {
var b Builder
b.AddASN1Uint64(tt.in)
if err := builderBytesEq(&b, tt.want...); err != nil {
t.Errorf("%v, (i = %d; in = %v)", err, i, tt.in)
}
var n uint64
s := String(b.BytesOrPanic())
ok := s.ReadASN1Integer(&n)
if !ok || n != tt.in {
t.Errorf("s.ReadASN1Integer(&n) = %v, n = %d; want true, n = %d (i = %d)",
ok, n, tt.in, i)
}
if len(s) != 0 {
t.Errorf("len(s) = %d, want 0", len(s))
}
}
}

View File

@ -1,154 +0,0 @@
// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package cryptobyte_test
import (
"errors"
"fmt"
"golang.org/x/crypto/cryptobyte"
"golang.org/x/crypto/cryptobyte/asn1"
)
func ExampleString_lengthPrefixed() {
// This is an example of parsing length-prefixed data (as found in, for
// example, TLS). Imagine a 16-bit prefixed series of 8-bit prefixed
// strings.
input := cryptobyte.String([]byte{0, 12, 5, 'h', 'e', 'l', 'l', 'o', 5, 'w', 'o', 'r', 'l', 'd'})
var result []string
var values cryptobyte.String
if !input.ReadUint16LengthPrefixed(&values) ||
!input.Empty() {
panic("bad format")
}
for !values.Empty() {
var value cryptobyte.String
if !values.ReadUint8LengthPrefixed(&value) {
panic("bad format")
}
result = append(result, string(value))
}
// Output: []string{"hello", "world"}
fmt.Printf("%#v\n", result)
}
func ExampleString_aSN1() {
// This is an example of parsing ASN.1 data that looks like:
// Foo ::= SEQUENCE {
// version [6] INTEGER DEFAULT 0
// data OCTET STRING
// }
input := cryptobyte.String([]byte{0x30, 12, 0xa6, 3, 2, 1, 2, 4, 5, 'h', 'e', 'l', 'l', 'o'})
var (
version int64
data, inner, versionBytes cryptobyte.String
haveVersion bool
)
if !input.ReadASN1(&inner, asn1.SEQUENCE) ||
!input.Empty() ||
!inner.ReadOptionalASN1(&versionBytes, &haveVersion, asn1.Tag(6).Constructed().ContextSpecific()) ||
(haveVersion && !versionBytes.ReadASN1Integer(&version)) ||
(haveVersion && !versionBytes.Empty()) ||
!inner.ReadASN1(&data, asn1.OCTET_STRING) ||
!inner.Empty() {
panic("bad format")
}
// Output: haveVersion: true, version: 2, data: hello
fmt.Printf("haveVersion: %t, version: %d, data: %s\n", haveVersion, version, string(data))
}
func ExampleBuilder_aSN1() {
// This is an example of building ASN.1 data that looks like:
// Foo ::= SEQUENCE {
// version [6] INTEGER DEFAULT 0
// data OCTET STRING
// }
version := int64(2)
data := []byte("hello")
const defaultVersion = 0
var b cryptobyte.Builder
b.AddASN1(asn1.SEQUENCE, func(b *cryptobyte.Builder) {
if version != defaultVersion {
b.AddASN1(asn1.Tag(6).Constructed().ContextSpecific(), func(b *cryptobyte.Builder) {
b.AddASN1Int64(version)
})
}
b.AddASN1OctetString(data)
})
result, err := b.Bytes()
if err != nil {
panic(err)
}
// Output: 300ca603020102040568656c6c6f
fmt.Printf("%x\n", result)
}
func ExampleBuilder_lengthPrefixed() {
// This is an example of building length-prefixed data (as found in,
// for example, TLS). Imagine a 16-bit prefixed series of 8-bit
// prefixed strings.
input := []string{"hello", "world"}
var b cryptobyte.Builder
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
for _, value := range input {
b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddBytes([]byte(value))
})
}
})
result, err := b.Bytes()
if err != nil {
panic(err)
}
// Output: 000c0568656c6c6f05776f726c64
fmt.Printf("%x\n", result)
}
func ExampleBuilder_lengthPrefixOverflow() {
// Writing more data that can be expressed by the length prefix results
// in an error from Bytes().
tooLarge := make([]byte, 256)
var b cryptobyte.Builder
b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddBytes(tooLarge)
})
result, err := b.Bytes()
fmt.Printf("len=%d err=%s\n", len(result), err)
// Output: len=0 err=cryptobyte: pending child length 256 exceeds 1-byte length prefix
}
func ExampleBuilderContinuation_errorHandling() {
var b cryptobyte.Builder
// Continuations that panic with a BuildError will cause Bytes to
// return the inner error.
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddUint32(0)
panic(cryptobyte.BuildError{Err: errors.New("example error")})
})
result, err := b.Bytes()
fmt.Printf("len=%d err=%s\n", len(result), err)
// Output: len=0 err=example error
}

View File

@ -1,875 +0,0 @@
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build go1.7
package ocsp
import (
"bytes"
"crypto"
"crypto/sha1"
"crypto/x509"
"crypto/x509/pkix"
"encoding/asn1"
"encoding/hex"
"math/big"
"reflect"
"testing"
"time"
)
func TestOCSPDecode(t *testing.T) {
responseBytes, _ := hex.DecodeString(ocspResponseHex)
resp, err := ParseResponse(responseBytes, nil)
if err != nil {
t.Fatal(err)
}
responderCert, _ := hex.DecodeString(startComResponderCertHex)
responder, err := x509.ParseCertificate(responderCert)
if err != nil {
t.Fatal(err)
}
expected := Response{
Status: Good,
SerialNumber: big.NewInt(0x1d0fa),
RevocationReason: Unspecified,
ThisUpdate: time.Date(2010, 7, 7, 15, 1, 5, 0, time.UTC),
NextUpdate: time.Date(2010, 7, 7, 18, 35, 17, 0, time.UTC),
RawResponderName: responder.RawSubject,
}
if !reflect.DeepEqual(resp.ThisUpdate, expected.ThisUpdate) {
t.Errorf("resp.ThisUpdate: got %v, want %v", resp.ThisUpdate, expected.ThisUpdate)
}
if !reflect.DeepEqual(resp.NextUpdate, expected.NextUpdate) {
t.Errorf("resp.NextUpdate: got %v, want %v", resp.NextUpdate, expected.NextUpdate)
}
if resp.Status != expected.Status {
t.Errorf("resp.Status: got %d, want %d", resp.Status, expected.Status)
}
if resp.SerialNumber.Cmp(expected.SerialNumber) != 0 {
t.Errorf("resp.SerialNumber: got %x, want %x", resp.SerialNumber, expected.SerialNumber)
}
if resp.RevocationReason != expected.RevocationReason {
t.Errorf("resp.RevocationReason: got %d, want %d", resp.RevocationReason, expected.RevocationReason)
}
if !bytes.Equal(resp.RawResponderName, expected.RawResponderName) {
t.Errorf("resp.RawResponderName: got %x, want %x", resp.RawResponderName, expected.RawResponderName)
}
if !bytes.Equal(resp.ResponderKeyHash, expected.ResponderKeyHash) {
t.Errorf("resp.ResponderKeyHash: got %x, want %x", resp.ResponderKeyHash, expected.ResponderKeyHash)
}
}
func TestOCSPDecodeWithoutCert(t *testing.T) {
responseBytes, _ := hex.DecodeString(ocspResponseWithoutCertHex)
_, err := ParseResponse(responseBytes, nil)
if err != nil {
t.Error(err)
}
}
func TestOCSPDecodeWithExtensions(t *testing.T) {
responseBytes, _ := hex.DecodeString(ocspResponseWithCriticalExtensionHex)
_, err := ParseResponse(responseBytes, nil)
if err == nil {
t.Error(err)
}
responseBytes, _ = hex.DecodeString(ocspResponseWithExtensionHex)
response, err := ParseResponse(responseBytes, nil)
if err != nil {
t.Fatal(err)
}
if len(response.Extensions) != 1 {
t.Errorf("len(response.Extensions): got %v, want %v", len(response.Extensions), 1)
}
extensionBytes := response.Extensions[0].Value
expectedBytes, _ := hex.DecodeString(ocspExtensionValueHex)
if !bytes.Equal(extensionBytes, expectedBytes) {
t.Errorf("response.Extensions[0]: got %x, want %x", extensionBytes, expectedBytes)
}
}
func TestOCSPSignature(t *testing.T) {
issuerCert, _ := hex.DecodeString(startComHex)
issuer, err := x509.ParseCertificate(issuerCert)
if err != nil {
t.Fatal(err)
}
response, _ := hex.DecodeString(ocspResponseHex)
if _, err := ParseResponse(response, issuer); err != nil {
t.Error(err)
}
}
func TestOCSPRequest(t *testing.T) {
leafCert, _ := hex.DecodeString(leafCertHex)
cert, err := x509.ParseCertificate(leafCert)
if err != nil {
t.Fatal(err)
}
issuerCert, _ := hex.DecodeString(issuerCertHex)
issuer, err := x509.ParseCertificate(issuerCert)
if err != nil {
t.Fatal(err)
}
request, err := CreateRequest(cert, issuer, nil)
if err != nil {
t.Fatal(err)
}
expectedBytes, _ := hex.DecodeString(ocspRequestHex)
if !bytes.Equal(request, expectedBytes) {
t.Errorf("request: got %x, wanted %x", request, expectedBytes)
}
decodedRequest, err := ParseRequest(expectedBytes)
if err != nil {
t.Fatal(err)
}
if decodedRequest.HashAlgorithm != crypto.SHA1 {
t.Errorf("request.HashAlgorithm: got %v, want %v", decodedRequest.HashAlgorithm, crypto.SHA1)
}
var publicKeyInfo struct {
Algorithm pkix.AlgorithmIdentifier
PublicKey asn1.BitString
}
_, err = asn1.Unmarshal(issuer.RawSubjectPublicKeyInfo, &publicKeyInfo)
if err != nil {
t.Fatal(err)
}
h := sha1.New()
h.Write(publicKeyInfo.PublicKey.RightAlign())
issuerKeyHash := h.Sum(nil)
h.Reset()
h.Write(issuer.RawSubject)
issuerNameHash := h.Sum(nil)
if got := decodedRequest.IssuerKeyHash; !bytes.Equal(got, issuerKeyHash) {
t.Errorf("request.IssuerKeyHash: got %x, want %x", got, issuerKeyHash)
}
if got := decodedRequest.IssuerNameHash; !bytes.Equal(got, issuerNameHash) {
t.Errorf("request.IssuerKeyHash: got %x, want %x", got, issuerNameHash)
}
if got := decodedRequest.SerialNumber; got.Cmp(cert.SerialNumber) != 0 {
t.Errorf("request.SerialNumber: got %x, want %x", got, cert.SerialNumber)
}
marshaledRequest, err := decodedRequest.Marshal()
if err != nil {
t.Fatal(err)
}
if bytes.Compare(expectedBytes, marshaledRequest) != 0 {
t.Errorf(
"Marshaled request doesn't match expected: wanted %x, got %x",
expectedBytes,
marshaledRequest,
)
}
}
func TestOCSPResponse(t *testing.T) {
leafCert, _ := hex.DecodeString(leafCertHex)
leaf, err := x509.ParseCertificate(leafCert)
if err != nil {
t.Fatal(err)
}
issuerCert, _ := hex.DecodeString(issuerCertHex)
issuer, err := x509.ParseCertificate(issuerCert)
if err != nil {
t.Fatal(err)
}
responderCert, _ := hex.DecodeString(responderCertHex)
responder, err := x509.ParseCertificate(responderCert)
if err != nil {
t.Fatal(err)
}
responderPrivateKeyDER, _ := hex.DecodeString(responderPrivateKeyHex)
responderPrivateKey, err := x509.ParsePKCS1PrivateKey(responderPrivateKeyDER)
if err != nil {
t.Fatal(err)
}
extensionBytes, _ := hex.DecodeString(ocspExtensionValueHex)
extensions := []pkix.Extension{
{
Id: ocspExtensionOID,
Critical: false,
Value: extensionBytes,
},
}
thisUpdate := time.Date(2010, 7, 7, 15, 1, 5, 0, time.UTC)
nextUpdate := time.Date(2010, 7, 7, 18, 35, 17, 0, time.UTC)
template := Response{
Status: Revoked,
SerialNumber: leaf.SerialNumber,
ThisUpdate: thisUpdate,
NextUpdate: nextUpdate,
RevokedAt: thisUpdate,
RevocationReason: KeyCompromise,
Certificate: responder,
ExtraExtensions: extensions,
}
template.IssuerHash = crypto.MD5
_, err = CreateResponse(issuer, responder, template, responderPrivateKey)
if err == nil {
t.Fatal("CreateResponse didn't fail with non-valid template.IssuerHash value crypto.MD5")
}
testCases := []struct {
name string
issuerHash crypto.Hash
}{
{"Zero value", 0},
{"crypto.SHA1", crypto.SHA1},
{"crypto.SHA256", crypto.SHA256},
{"crypto.SHA384", crypto.SHA384},
{"crypto.SHA512", crypto.SHA512},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
template.IssuerHash = tc.issuerHash
responseBytes, err := CreateResponse(issuer, responder, template, responderPrivateKey)
if err != nil {
t.Fatalf("CreateResponse failed: %s", err)
}
resp, err := ParseResponse(responseBytes, nil)
if err != nil {
t.Fatalf("ParseResponse failed: %s", err)
}
if !reflect.DeepEqual(resp.ThisUpdate, template.ThisUpdate) {
t.Errorf("resp.ThisUpdate: got %v, want %v", resp.ThisUpdate, template.ThisUpdate)
}
if !reflect.DeepEqual(resp.NextUpdate, template.NextUpdate) {
t.Errorf("resp.NextUpdate: got %v, want %v", resp.NextUpdate, template.NextUpdate)
}
if !reflect.DeepEqual(resp.RevokedAt, template.RevokedAt) {
t.Errorf("resp.RevokedAt: got %v, want %v", resp.RevokedAt, template.RevokedAt)
}
if !reflect.DeepEqual(resp.Extensions, template.ExtraExtensions) {
t.Errorf("resp.Extensions: got %v, want %v", resp.Extensions, template.ExtraExtensions)
}
delay := time.Since(resp.ProducedAt)
if delay < -time.Hour || delay > time.Hour {
t.Errorf("resp.ProducedAt: got %s, want close to current time (%s)", resp.ProducedAt, time.Now())
}
if resp.Status != template.Status {
t.Errorf("resp.Status: got %d, want %d", resp.Status, template.Status)
}
if resp.SerialNumber.Cmp(template.SerialNumber) != 0 {
t.Errorf("resp.SerialNumber: got %x, want %x", resp.SerialNumber, template.SerialNumber)
}
if resp.RevocationReason != template.RevocationReason {
t.Errorf("resp.RevocationReason: got %d, want %d", resp.RevocationReason, template.RevocationReason)
}
expectedHash := tc.issuerHash
if tc.issuerHash == 0 {
expectedHash = crypto.SHA1
}
if resp.IssuerHash != expectedHash {
t.Errorf("resp.IssuerHash: got %d, want %d", resp.IssuerHash, expectedHash)
}
})
}
}
func TestErrorResponse(t *testing.T) {
responseBytes, _ := hex.DecodeString(errorResponseHex)
_, err := ParseResponse(responseBytes, nil)
respErr, ok := err.(ResponseError)
if !ok {
t.Fatalf("expected ResponseError from ParseResponse but got %#v", err)
}
if respErr.Status != Malformed {
t.Fatalf("expected Malformed status from ParseResponse but got %d", respErr.Status)
}
}
func TestOCSPDecodeMultiResponse(t *testing.T) {
inclCert, _ := hex.DecodeString(ocspMultiResponseCertHex)
cert, err := x509.ParseCertificate(inclCert)
if err != nil {
t.Fatal(err)
}
responseBytes, _ := hex.DecodeString(ocspMultiResponseHex)
resp, err := ParseResponseForCert(responseBytes, cert, nil)
if err != nil {
t.Fatal(err)
}
if resp.SerialNumber.Cmp(cert.SerialNumber) != 0 {
t.Errorf("resp.SerialNumber: got %x, want %x", resp.SerialNumber, cert.SerialNumber)
}
}
func TestOCSPDecodeMultiResponseWithoutMatchingCert(t *testing.T) {
wrongCert, _ := hex.DecodeString(startComHex)
cert, err := x509.ParseCertificate(wrongCert)
if err != nil {
t.Fatal(err)
}
responseBytes, _ := hex.DecodeString(ocspMultiResponseHex)
_, err = ParseResponseForCert(responseBytes, cert, nil)
want := ParseError("no response matching the supplied certificate")
if err != want {
t.Errorf("err: got %q, want %q", err, want)
}
}
// This OCSP response was taken from Thawte's public OCSP responder.
// To recreate:
// $ openssl s_client -tls1 -showcerts -servername www.google.com -connect www.google.com:443
// Copy and paste the first certificate into /tmp/cert.crt and the second into
// /tmp/intermediate.crt
// $ openssl ocsp -issuer /tmp/intermediate.crt -cert /tmp/cert.crt -url http://ocsp.thawte.com -resp_text -respout /tmp/ocsp.der
// Then hex encode the result:
// $ python -c 'print file("/tmp/ocsp.der", "r").read().encode("hex")'
const ocspResponseHex = "308206bc0a0100a08206b5308206b106092b0601050507300101048206a23082069e3081" +
"c9a14e304c310b300906035504061302494c31163014060355040a130d5374617274436f" +
"6d204c74642e312530230603550403131c5374617274436f6d20436c6173732031204f43" +
"5350205369676e6572180f32303130303730373137333531375a30663064303c30090605" +
"2b0e03021a050004146568874f40750f016a3475625e1f5c93e5a26d580414eb4234d098" +
"b0ab9ff41b6b08f7cc642eef0e2c45020301d0fa8000180f323031303037303731353031" +
"30355aa011180f32303130303730373138333531375a300d06092a864886f70d01010505" +
"000382010100ab557ff070d1d7cebbb5f0ec91a15c3fed22eb2e1b8244f1b84545f013a4" +
"fb46214c5e3fbfbebb8a56acc2b9db19f68fd3c3201046b3824d5ba689f99864328710cb" +
"467195eb37d84f539e49f859316b32964dc3e47e36814ce94d6c56dd02733b1d0802f7ff" +
"4eebdbbd2927dcf580f16cbc290f91e81b53cb365e7223f1d6e20a88ea064104875e0145" +
"672b20fc14829d51ca122f5f5d77d3ad6c83889c55c7dc43680ba2fe3cef8b05dbcabdc0" +
"d3e09aaf9725597f8c858c2fa38c0d6aed2e6318194420dd1a1137445d13e1c97ab47896" +
"17a4e08925f46f867b72e3a4dc1f08cb870b2b0717f7207faa0ac512e628a029aba7457a" +
"e63dcf3281e2162d9349a08204ba308204b6308204b23082039aa003020102020101300d" +
"06092a864886f70d010105050030818c310b300906035504061302494c31163014060355" +
"040a130d5374617274436f6d204c74642e312b3029060355040b13225365637572652044" +
"69676974616c204365727469666963617465205369676e696e6731383036060355040313" +
"2f5374617274436f6d20436c6173732031205072696d61727920496e7465726d65646961" +
"746520536572766572204341301e170d3037313032353030323330365a170d3132313032" +
"333030323330365a304c310b300906035504061302494c31163014060355040a130d5374" +
"617274436f6d204c74642e312530230603550403131c5374617274436f6d20436c617373" +
"2031204f435350205369676e657230820122300d06092a864886f70d0101010500038201" +
"0f003082010a0282010100b9561b4c45318717178084e96e178df2255e18ed8d8ecc7c2b" +
"7b51a6c1c2e6bf0aa3603066f132fe10ae97b50e99fa24b83fc53dd2777496387d14e1c3" +
"a9b6a4933e2ac12413d085570a95b8147414a0bc007c7bcf222446ef7f1a156d7ea1c577" +
"fc5f0facdfd42eb0f5974990cb2f5cefebceef4d1bdc7ae5c1075c5a99a93171f2b0845b" +
"4ff0864e973fcfe32f9d7511ff87a3e943410c90a4493a306b6944359340a9ca96f02b66" +
"ce67f028df2980a6aaee8d5d5d452b8b0eb93f923cc1e23fcccbdbe7ffcb114d08fa7a6a" +
"3c404f825d1a0e715935cf623a8c7b59670014ed0622f6089a9447a7a19010f7fe58f841" +
"29a2765ea367824d1c3bb2fda308530203010001a382015c30820158300c0603551d1301" +
"01ff04023000300b0603551d0f0404030203a8301e0603551d250417301506082b060105" +
"0507030906092b0601050507300105301d0603551d0e0416041445e0a36695414c5dd449" +
"bc00e33cdcdbd2343e173081a80603551d230481a030819d8014eb4234d098b0ab9ff41b" +
"6b08f7cc642eef0e2c45a18181a47f307d310b300906035504061302494c311630140603" +
"55040a130d5374617274436f6d204c74642e312b3029060355040b132253656375726520" +
"4469676974616c204365727469666963617465205369676e696e67312930270603550403" +
"13205374617274436f6d2043657274696669636174696f6e20417574686f726974798201" +
"0a30230603551d12041c301a8618687474703a2f2f7777772e737461727473736c2e636f" +
"6d2f302c06096086480186f842010d041f161d5374617274436f6d205265766f63617469" +
"6f6e20417574686f72697479300d06092a864886f70d01010505000382010100182d2215" +
"8f0fc0291324fa8574c49bb8ff2835085adcbf7b7fc4191c397ab6951328253fffe1e5ec" +
"2a7da0d50fca1a404e6968481366939e666c0a6209073eca57973e2fefa9ed1718e8176f" +
"1d85527ff522c08db702e3b2b180f1cbff05d98128252cf0f450f7dd2772f4188047f19d" +
"c85317366f94bc52d60f453a550af58e308aaab00ced33040b62bf37f5b1ab2a4f7f0f80" +
"f763bf4d707bc8841d7ad9385ee2a4244469260b6f2bf085977af9074796048ecc2f9d48" +
"a1d24ce16e41a9941568fec5b42771e118f16c106a54ccc339a4b02166445a167902e75e" +
"6d8620b0825dcd18a069b90fd851d10fa8effd409deec02860d26d8d833f304b10669b42"
const startComResponderCertHex = "308204b23082039aa003020102020101300d06092a864886f70d010105050030818c310b" +
"300906035504061302494c31163014060355040a130d5374617274436f6d204c74642e31" +
"2b3029060355040b1322536563757265204469676974616c204365727469666963617465" +
"205369676e696e67313830360603550403132f5374617274436f6d20436c617373203120" +
"5072696d61727920496e7465726d65646961746520536572766572204341301e170d3037" +
"313032353030323330365a170d3132313032333030323330365a304c310b300906035504" +
"061302494c31163014060355040a130d5374617274436f6d204c74642e31253023060355" +
"0403131c5374617274436f6d20436c6173732031204f435350205369676e657230820122" +
"300d06092a864886f70d01010105000382010f003082010a0282010100b9561b4c453187" +
"17178084e96e178df2255e18ed8d8ecc7c2b7b51a6c1c2e6bf0aa3603066f132fe10ae97" +
"b50e99fa24b83fc53dd2777496387d14e1c3a9b6a4933e2ac12413d085570a95b8147414" +
"a0bc007c7bcf222446ef7f1a156d7ea1c577fc5f0facdfd42eb0f5974990cb2f5cefebce" +
"ef4d1bdc7ae5c1075c5a99a93171f2b0845b4ff0864e973fcfe32f9d7511ff87a3e94341" +
"0c90a4493a306b6944359340a9ca96f02b66ce67f028df2980a6aaee8d5d5d452b8b0eb9" +
"3f923cc1e23fcccbdbe7ffcb114d08fa7a6a3c404f825d1a0e715935cf623a8c7b596700" +
"14ed0622f6089a9447a7a19010f7fe58f84129a2765ea367824d1c3bb2fda30853020301" +
"0001a382015c30820158300c0603551d130101ff04023000300b0603551d0f0404030203" +
"a8301e0603551d250417301506082b0601050507030906092b0601050507300105301d06" +
"03551d0e0416041445e0a36695414c5dd449bc00e33cdcdbd2343e173081a80603551d23" +
"0481a030819d8014eb4234d098b0ab9ff41b6b08f7cc642eef0e2c45a18181a47f307d31" +
"0b300906035504061302494c31163014060355040a130d5374617274436f6d204c74642e" +
"312b3029060355040b1322536563757265204469676974616c2043657274696669636174" +
"65205369676e696e6731293027060355040313205374617274436f6d2043657274696669" +
"636174696f6e20417574686f7269747982010a30230603551d12041c301a861868747470" +
"3a2f2f7777772e737461727473736c2e636f6d2f302c06096086480186f842010d041f16" +
"1d5374617274436f6d205265766f636174696f6e20417574686f72697479300d06092a86" +
"4886f70d01010505000382010100182d22158f0fc0291324fa8574c49bb8ff2835085adc" +
"bf7b7fc4191c397ab6951328253fffe1e5ec2a7da0d50fca1a404e6968481366939e666c" +
"0a6209073eca57973e2fefa9ed1718e8176f1d85527ff522c08db702e3b2b180f1cbff05" +
"d98128252cf0f450f7dd2772f4188047f19dc85317366f94bc52d60f453a550af58e308a" +
"aab00ced33040b62bf37f5b1ab2a4f7f0f80f763bf4d707bc8841d7ad9385ee2a4244469" +
"260b6f2bf085977af9074796048ecc2f9d48a1d24ce16e41a9941568fec5b42771e118f1" +
"6c106a54ccc339a4b02166445a167902e75e6d8620b0825dcd18a069b90fd851d10fa8ef" +
"fd409deec02860d26d8d833f304b10669b42"
const startComHex = "308206343082041ca003020102020118300d06092a864886f70d0101050500307d310b30" +
"0906035504061302494c31163014060355040a130d5374617274436f6d204c74642e312b" +
"3029060355040b1322536563757265204469676974616c20436572746966696361746520" +
"5369676e696e6731293027060355040313205374617274436f6d20436572746966696361" +
"74696f6e20417574686f72697479301e170d3037313032343230353431375a170d313731" +
"3032343230353431375a30818c310b300906035504061302494c31163014060355040a13" +
"0d5374617274436f6d204c74642e312b3029060355040b13225365637572652044696769" +
"74616c204365727469666963617465205369676e696e67313830360603550403132f5374" +
"617274436f6d20436c6173732031205072696d61727920496e7465726d65646961746520" +
"53657276657220434130820122300d06092a864886f70d01010105000382010f00308201" +
"0a0282010100b689c6acef09527807ac9263d0f44418188480561f91aee187fa3250b4d3" +
"4706f0e6075f700e10f71dc0ce103634855a0f92ac83c6ac58523fba38e8fce7a724e240" +
"a60876c0926e9e2a6d4d3f6e61200adb59ded27d63b33e46fefa215118d7cd30a6ed076e" +
"3b7087b4f9faebee823c056f92f7a4dc0a301e9373fe07cad75f809d225852ae06da8b87" +
"2369b0e42ad8ea83d2bdf371db705a280faf5a387045123f304dcd3baf17e50fcba0a95d" +
"48aab16150cb34cd3c5cc30be810c08c9bf0030362feb26c3e720eee1c432ac9480e5739" +
"c43121c810c12c87fe5495521f523c31129b7fe7c0a0a559d5e28f3ef0d5a8e1d77031a9" +
"c4b3cfaf6d532f06f4a70203010001a38201ad308201a9300f0603551d130101ff040530" +
"030101ff300e0603551d0f0101ff040403020106301d0603551d0e04160414eb4234d098" +
"b0ab9ff41b6b08f7cc642eef0e2c45301f0603551d230418301680144e0bef1aa4405ba5" +
"17698730ca346843d041aef2306606082b06010505070101045a3058302706082b060105" +
"05073001861b687474703a2f2f6f6373702e737461727473736c2e636f6d2f6361302d06" +
"082b060105050730028621687474703a2f2f7777772e737461727473736c2e636f6d2f73" +
"667363612e637274305b0603551d1f045430523027a025a0238621687474703a2f2f7777" +
"772e737461727473736c2e636f6d2f73667363612e63726c3027a025a023862168747470" +
"3a2f2f63726c2e737461727473736c2e636f6d2f73667363612e63726c3081800603551d" +
"20047930773075060b2b0601040181b5370102013066302e06082b060105050702011622" +
"687474703a2f2f7777772e737461727473736c2e636f6d2f706f6c6963792e7064663034" +
"06082b060105050702011628687474703a2f2f7777772e737461727473736c2e636f6d2f" +
"696e7465726d6564696174652e706466300d06092a864886f70d01010505000382020100" +
"2109493ea5886ee00b8b48da314d8ff75657a2e1d36257e9b556f38545753be5501f048b" +
"e6a05a3ee700ae85d0fbff200364cbad02e1c69172f8a34dd6dee8cc3fa18aa2e37c37a7" +
"c64f8f35d6f4d66e067bdd21d9cf56ffcb302249fe8904f385e5aaf1e71fe875904dddf9" +
"46f74234f745580c110d84b0c6da5d3ef9019ee7e1da5595be741c7bfc4d144fac7e5547" +
"7d7bf4a50d491e95e8f712c1ccff76a62547d0f37535be97b75816ebaa5c786fec5330af" +
"ea044dcca902e3f0b60412f630b1113d904e5664d7dc3c435f7339ef4baf87ebf6fe6888" +
"4472ead207c669b0c1a18bef1749d761b145485f3b2021e95bb2ccf4d7e931f50b15613b" +
"7a94e3ebd9bc7f94ae6ae3626296a8647cb887f399327e92a252bebbf865cfc9f230fc8b" +
"c1c2a696d75f89e15c3480f58f47072fb491bfb1a27e5f4b5ad05b9f248605515a690365" +
"434971c5e06f94346bf61bd8a9b04c7e53eb8f48dfca33b548fa364a1a53a6330cd089cd" +
"4915cd89313c90c072d7654b52358a461144b93d8e2865a63e799e5c084429adb035112e" +
"214eb8d2e7103e5d8483b3c3c2e4d2c6fd094b7409ddf1b3d3193e800da20b19f038e7c5" +
"c2afe223db61e29d5c6e2089492e236ab262c145b49faf8ba7f1223bf87de290d07a19fb" +
"4a4ce3d27d5f4a8303ed27d6239e6b8db459a2d9ef6c8229dd75193c3f4c108defbb7527" +
"d2ae83a7a8ce5ba7"
const ocspResponseWithoutCertHex = "308201d40a0100a08201cd308201c906092b0601050507300101048201ba3082" +
"01b630819fa2160414884451ff502a695e2d88f421bad90cf2cecbea7c180f3230313330" +
"3631383037323434335a30743072304a300906052b0e03021a0500041448b60d38238df8" +
"456e4ee5843ea394111802979f0414884451ff502a695e2d88f421bad90cf2cecbea7c02" +
"1100f78b13b946fc9635d8ab49de9d2148218000180f3230313330363138303732343433" +
"5aa011180f32303133303632323037323434335a300d06092a864886f70d010105050003" +
"82010100103e18b3d297a5e7a6c07a4fc52ac46a15c0eba96f3be17f0ffe84de5b8c8e05" +
"5a8f577586a849dc4abd6440eb6fedde4622451e2823c1cbf3558b4e8184959c9fe96eff" +
"8bc5f95866c58c6d087519faabfdae37e11d9874f1bc0db292208f645dd848185e4dd38b" +
"6a8547dfa7b74d514a8470015719064d35476b95bebb03d4d2845c5ca15202d2784878f2" +
"0f904c24f09736f044609e9c271381713400e563023d212db422236440c6f377bbf24b2b" +
"9e7dec8698e36a8df68b7592ad3489fb2937afb90eb85d2aa96b81c94c25057dbd4759d9" +
"20a1a65c7f0b6427a224b3c98edd96b9b61f706099951188b0289555ad30a216fb774651" +
"5a35fca2e054dfa8"
// PKIX nonce extension
var ocspExtensionOID = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 1, 2}
var ocspExtensionValueHex = "0403000000"
const ocspResponseWithCriticalExtensionHex = "308204fe0a0100a08204f7308204f306092b0601050507300101048204e4308204e03081" +
"dba003020100a11b3019311730150603550403130e4f43535020526573706f6e64657218" +
"0f32303136303130343137303130305a3081a53081a23049300906052b0e03021a050004" +
"14c0fe0278fc99188891b3f212e9c7e1b21ab7bfc004140dfc1df0a9e0f01ce7f2b21317" +
"7e6f8d157cd4f60210017f77deb3bcbb235d44ccc7dba62e72a116180f32303130303730" +
"373135303130355aa0030a0101180f32303130303730373135303130355aa011180f3230" +
"3130303730373138333531375aa1193017301506092b06010505073001020101ff040504" +
"03000000300d06092a864886f70d01010b0500038201010031c730ca60a7a0d92d8e4010" +
"911b469de95b4d27e89de6537552436237967694f76f701cf6b45c932bd308bca4a8d092" +
"5c604ba94796903091d9e6c000178e72c1f0a24a277dd262835af5d17d3f9d7869606c9f" +
"e7c8e708a41645699895beee38bfa63bb46296683761c5d1d65439b8ab868dc3017c9eeb" +
"b70b82dbf3a31c55b457d48bb9e82b335ed49f445042eaf606b06a3e0639824924c89c63" +
"eccddfe85e6694314138b2536f5e15e07085d0f6e26d4b2f8244bab0d70de07283ac6384" +
"a0501fc3dea7cf0adfd4c7f34871080900e252ddc403e3f0265f2a704af905d3727504ed" +
"28f3214a219d898a022463c78439799ca81c8cbafdbcec34ea937cd6a08202ea308202e6" +
"308202e2308201caa003020102020101300d06092a864886f70d01010b05003019311730" +
"150603550403130e4f43535020526573706f6e646572301e170d31353031333031353530" +
"33335a170d3136303133303135353033335a3019311730150603550403130e4f43535020" +
"526573706f6e64657230820122300d06092a864886f70d01010105000382010f00308201" +
"0a0282010100e8155f2d3e6f2e8d14c62a788bd462f9f844e7a6977c83ef1099f0f6616e" +
"c5265b56f356e62c5400f0b06a2e7945a82752c636df32a895152d6074df1701dc6ccfbc" +
"bec75a70bd2b55ae2be7e6cad3b5fd4cd5b7790ab401a436d3f5f346074ffde8a99d5b72" +
"3350f0a112076614b12ef79c78991b119453445acf2416ab0046b540db14c9fc0f27b898" +
"9ad0f63aa4b8aefc91aa8a72160c36307c60fec78a93d3fddf4259902aa77e7332971c7d" +
"285b6a04f648993c6922a3e9da9adf5f81508c3228791843e5d49f24db2f1290bafd97e6" +
"55b1049a199f652cd603c4fafa330c390b0da78fbbc67e8fa021cbd74eb96222b12ace31" +
"a77dcf920334dc94581b0203010001a3353033300e0603551d0f0101ff04040302078030" +
"130603551d25040c300a06082b06010505070309300c0603551d130101ff04023000300d" +
"06092a864886f70d01010b05000382010100718012761b5063e18f0dc44644d8e6ab8612" +
"31c15fd5357805425d82aec1de85bf6d3e30fce205e3e3b8b795bbe52e40a439286d2288" +
"9064f4aeeb150359b9425f1da51b3a5c939018555d13ac42c565a0603786a919328f3267" +
"09dce52c22ad958ecb7873b9771d1148b1c4be2efe80ba868919fc9f68b6090c2f33c156" +
"d67156e42766a50b5d51e79637b7e58af74c2a951b1e642fa7741fec982cc937de37eff5" +
"9e2005d5939bfc031589ca143e6e8ab83f40ee08cc20a6b4a95a318352c28d18528dcaf9" +
"66705de17afa19d6e8ae91ddf33179d16ebb6ac2c69cae8373d408ebf8c55308be6c04d9" +
"3a25439a94299a65a709756c7a3e568be049d5c38839"
const ocspResponseWithExtensionHex = "308204fb0a0100a08204f4308204f006092b0601050507300101048204e1308204dd3081" +
"d8a003020100a11b3019311730150603550403130e4f43535020526573706f6e64657218" +
"0f32303136303130343136353930305a3081a230819f3049300906052b0e03021a050004" +
"14c0fe0278fc99188891b3f212e9c7e1b21ab7bfc004140dfc1df0a9e0f01ce7f2b21317" +
"7e6f8d157cd4f60210017f77deb3bcbb235d44ccc7dba62e72a116180f32303130303730" +
"373135303130355aa0030a0101180f32303130303730373135303130355aa011180f3230" +
"3130303730373138333531375aa1163014301206092b0601050507300102040504030000" +
"00300d06092a864886f70d01010b05000382010100c09a33e0b2324c852421bb83f85ac9" +
"9113f5426012bd2d2279a8166e9241d18a33c870894250622ffc7ed0c4601b16d624f90b" +
"779265442cdb6868cf40ab304ab4b66e7315ed02cf663b1601d1d4751772b31bc299db23" +
"9aebac78ed6797c06ed815a7a8d18d63cfbb609cafb47ec2e89e37db255216eb09307848" +
"d01be0a3e943653c78212b96ff524b74c9ec456b17cdfb950cc97645c577b2e09ff41dde" +
"b03afb3adaa381cc0f7c1d95663ef22a0f72f2c45613ae8e2b2d1efc96e8463c7d1d8a1d" +
"7e3b35df8fe73a301fc3f804b942b2b3afa337ff105fc1462b7b1c1d75eb4566c8665e59" +
"f80393b0adbf8004ff6c3327ed34f007cb4a3348a7d55e06e3a08202ea308202e6308202" +
"e2308201caa003020102020101300d06092a864886f70d01010b05003019311730150603" +
"550403130e4f43535020526573706f6e646572301e170d3135303133303135353033335a" +
"170d3136303133303135353033335a3019311730150603550403130e4f43535020526573" +
"706f6e64657230820122300d06092a864886f70d01010105000382010f003082010a0282" +
"010100e8155f2d3e6f2e8d14c62a788bd462f9f844e7a6977c83ef1099f0f6616ec5265b" +
"56f356e62c5400f0b06a2e7945a82752c636df32a895152d6074df1701dc6ccfbcbec75a" +
"70bd2b55ae2be7e6cad3b5fd4cd5b7790ab401a436d3f5f346074ffde8a99d5b723350f0" +
"a112076614b12ef79c78991b119453445acf2416ab0046b540db14c9fc0f27b8989ad0f6" +
"3aa4b8aefc91aa8a72160c36307c60fec78a93d3fddf4259902aa77e7332971c7d285b6a" +
"04f648993c6922a3e9da9adf5f81508c3228791843e5d49f24db2f1290bafd97e655b104" +
"9a199f652cd603c4fafa330c390b0da78fbbc67e8fa021cbd74eb96222b12ace31a77dcf" +
"920334dc94581b0203010001a3353033300e0603551d0f0101ff04040302078030130603" +
"551d25040c300a06082b06010505070309300c0603551d130101ff04023000300d06092a" +
"864886f70d01010b05000382010100718012761b5063e18f0dc44644d8e6ab861231c15f" +
"d5357805425d82aec1de85bf6d3e30fce205e3e3b8b795bbe52e40a439286d22889064f4" +
"aeeb150359b9425f1da51b3a5c939018555d13ac42c565a0603786a919328f326709dce5" +
"2c22ad958ecb7873b9771d1148b1c4be2efe80ba868919fc9f68b6090c2f33c156d67156" +
"e42766a50b5d51e79637b7e58af74c2a951b1e642fa7741fec982cc937de37eff59e2005" +
"d5939bfc031589ca143e6e8ab83f40ee08cc20a6b4a95a318352c28d18528dcaf966705d" +
"e17afa19d6e8ae91ddf33179d16ebb6ac2c69cae8373d408ebf8c55308be6c04d93a2543" +
"9a94299a65a709756c7a3e568be049d5c38839"
const ocspMultiResponseHex = "30820ee60a0100a0820edf30820edb06092b060105050730010104820ecc30820ec83082" +
"0839a216041445ac2ecd75f53f1cf6e4c51d3de0047ad0aa7465180f3230313530363032" +
"3130303033305a3082080c3065303d300906052b0e03021a05000414f7452a0080601527" +
"72e4a135e76e9e52fde0f1580414edd8f2ee977252853a330b297a18f5c993853b3f0204" +
"5456656a8000180f32303135303630323039303230375aa011180f323031353036303331" +
"30303033305a3065303d300906052b0e03021a05000414f7452a008060152772e4a135e7" +
"6e9e52fde0f1580414edd8f2ee977252853a330b297a18f5c993853b3f02045456656b80" +
"00180f32303135303630323039303230375aa011180f3230313530363033313030303330" +
"5a3065303d300906052b0e03021a05000414f7452a008060152772e4a135e76e9e52fde0" +
"f1580414edd8f2ee977252853a330b297a18f5c993853b3f02045456656c8000180f3230" +
"3135303630323039303230375aa011180f32303135303630333130303033305a3065303d" +
"300906052b0e03021a05000414f7452a008060152772e4a135e76e9e52fde0f1580414ed" +
"d8f2ee977252853a330b297a18f5c993853b3f02045456656d8000180f32303135303630" +
"323039303230375aa011180f32303135303630333130303033305a3065303d300906052b" +
"0e03021a05000414f7452a008060152772e4a135e76e9e52fde0f1580414edd8f2ee9772" +
"52853a330b297a18f5c993853b3f02045456656e8000180f323031353036303230393032" +
"30375aa011180f32303135303630333130303033305a3065303d300906052b0e03021a05" +
"000414f7452a008060152772e4a135e76e9e52fde0f1580414edd8f2ee977252853a330b" +
"297a18f5c993853b3f02045456656f8000180f32303135303630323039303230375aa011" +
"180f32303135303630333130303033305a3065303d300906052b0e03021a05000414f745" +
"2a008060152772e4a135e76e9e52fde0f1580414edd8f2ee977252853a330b297a18f5c9" +
"93853b3f0204545665708000180f32303135303630323039303230375aa011180f323031" +
"35303630333130303033305a3065303d300906052b0e03021a05000414f7452a00806015" +
"2772e4a135e76e9e52fde0f1580414edd8f2ee977252853a330b297a18f5c993853b3f02" +
"04545665718000180f32303135303630323039303230375aa011180f3230313530363033" +
"3130303033305a3065303d300906052b0e03021a05000414f7452a008060152772e4a135" +
"e76e9e52fde0f1580414edd8f2ee977252853a330b297a18f5c993853b3f020454566572" +
"8000180f32303135303630323039303230375aa011180f32303135303630333130303033" +
"305a3065303d300906052b0e03021a05000414f7452a008060152772e4a135e76e9e52fd" +
"e0f1580414edd8f2ee977252853a330b297a18f5c993853b3f0204545665738000180f32" +
"303135303630323039303230375aa011180f32303135303630333130303033305a306530" +
"3d300906052b0e03021a05000414f7452a008060152772e4a135e76e9e52fde0f1580414" +
"edd8f2ee977252853a330b297a18f5c993853b3f0204545665748000180f323031353036" +
"30323039303230375aa011180f32303135303630333130303033305a3065303d30090605" +
"2b0e03021a05000414f7452a008060152772e4a135e76e9e52fde0f1580414edd8f2ee97" +
"7252853a330b297a18f5c993853b3f0204545665758000180f3230313530363032303930" +
"3230375aa011180f32303135303630333130303033305a3065303d300906052b0e03021a" +
"05000414f7452a008060152772e4a135e76e9e52fde0f1580414edd8f2ee977252853a33" +
"0b297a18f5c993853b3f0204545665768000180f32303135303630323039303230375aa0" +
"11180f32303135303630333130303033305a3065303d300906052b0e03021a05000414f7" +
"452a008060152772e4a135e76e9e52fde0f1580414edd8f2ee977252853a330b297a18f5" +
"c993853b3f0204545665778000180f32303135303630323039303230375aa011180f3230" +
"3135303630333130303033305a3065303d300906052b0e03021a05000414f7452a008060" +
"152772e4a135e76e9e52fde0f1580414edd8f2ee977252853a330b297a18f5c993853b3f" +
"0204545665788000180f32303135303630323039303230375aa011180f32303135303630" +
"333130303033305a3065303d300906052b0e03021a05000414f7452a008060152772e4a1" +
"35e76e9e52fde0f1580414edd8f2ee977252853a330b297a18f5c993853b3f0204545665" +
"798000180f32303135303630323039303230375aa011180f323031353036303331303030" +
"33305a3065303d300906052b0e03021a05000414f7452a008060152772e4a135e76e9e52" +
"fde0f1580414edd8f2ee977252853a330b297a18f5c993853b3f02045456657a8000180f" +
"32303135303630323039303230375aa011180f32303135303630333130303033305a3065" +
"303d300906052b0e03021a05000414f7452a008060152772e4a135e76e9e52fde0f15804" +
"14edd8f2ee977252853a330b297a18f5c993853b3f02045456657b8000180f3230313530" +
"3630323039303230375aa011180f32303135303630333130303033305a3065303d300906" +
"052b0e03021a05000414f7452a008060152772e4a135e76e9e52fde0f1580414edd8f2ee" +
"977252853a330b297a18f5c993853b3f02045456657c8000180f32303135303630323039" +
"303230375aa011180f32303135303630333130303033305a3065303d300906052b0e0302" +
"1a05000414f7452a008060152772e4a135e76e9e52fde0f1580414edd8f2ee977252853a" +
"330b297a18f5c993853b3f02045456657d8000180f32303135303630323039303230375a" +
"a011180f32303135303630333130303033305a300d06092a864886f70d01010505000382" +
"01010016b73b92859979f27d15eb018cf069eed39c3d280213565f3026de11ba15bdb94d" +
"764cf2d0fdd204ef926c588d7b183483c8a2b1995079c7ed04dcefcc650c1965be4b6832" +
"a8839e832f7f60f638425eccdf9bc3a81fbe700fda426ddf4f06c29bee431bbbe81effda" +
"a60b7da5b378f199af2f3c8380be7ba6c21c8e27124f8a4d8989926aea19055700848d33" +
"799e833512945fd75364edbd2dd18b783c1e96e332266b17979a0b88c35b43f47c87c493" +
"19155056ad8dbbae5ff2afad3c0e1c69ed111206ffda49875e8e4efc0926264823bc4423" +
"c8a002f34288c4bc22516f98f54fc609943721f590ddd8d24f989457526b599b0eb75cb5" +
"a80da1ad93a621a08205733082056f3082056b30820453a0030201020204545638c4300d" +
"06092a864886f70d01010b0500308182310b300906035504061302555331183016060355" +
"040a130f552e532e20476f7665726e6d656e7431233021060355040b131a446570617274" +
"6d656e74206f662074686520547265617375727931223020060355040b13194365727469" +
"6669636174696f6e20417574686f7269746965733110300e060355040b13074f43494f20" +
"4341301e170d3135303332303131353531335a170d3135303633303034303030305a3081" +
"98310b300906035504061302555331183016060355040a130f552e532e20476f7665726e" +
"6d656e7431233021060355040b131a4465706172746d656e74206f662074686520547265" +
"617375727931223020060355040b131943657274696669636174696f6e20417574686f72" +
"69746965733110300e060355040b13074f43494f204341311430120603550403130b4f43" +
"5350205369676e657230820122300d06092a864886f70d01010105000382010f00308201" +
"0a0282010100c1b6fe1ba1ad50bb98c855811acbd67fe68057f48b8e08d3800e7f2c51b7" +
"9e20551934971fd92b9c9e6c49453097927cba83a94c0b2fea7124ba5ac442b38e37dba6" +
"7303d4962dd7d92b22a04b0e0e182e9ea67620b1c6ce09ee607c19e0e6e3adae81151db1" +
"2bb7f706149349a292e21c1eb28565b6839df055e1a838a772ff34b5a1452618e2c26042" +
"705d53f0af4b57aae6163f58216af12f3887813fe44b0321827b3a0c52b0e47d0aab94a2" +
"f768ab0ba3901d22f8bb263823090b0e37a7f8856db4b0d165c42f3aa7e94f5f6ce1855e" +
"98dc57adea0ae98ad39f67ecdec00b88685566e9e8d69f6cefb6ddced53015d0d3b862bc" +
"be21f3d72251eefcec730203010001a38201cf308201cb300e0603551d0f0101ff040403" +
"020780306b0603551d2004643062300c060a60864801650302010502300c060a60864801" +
"650302010503300c060a60864801650302010504300c060a60864801650302010507300c" +
"060a60864801650302010508300c060a6086480165030201030d300c060a608648016503" +
"020103113081e506082b060105050701010481d83081d5303006082b0601050507300286" +
"24687474703a2f2f706b692e74726561732e676f762f746f63615f65655f6169612e7037" +
"633081a006082b060105050730028681936c6461703a2f2f6c6461702e74726561732e67" +
"6f762f6f753d4f43494f25323043412c6f753d43657274696669636174696f6e25323041" +
"7574686f7269746965732c6f753d4465706172746d656e742532306f6625323074686525" +
"323054726561737572792c6f3d552e532e253230476f7665726e6d656e742c633d55533f" +
"634143657274696669636174653b62696e61727930130603551d25040c300a06082b0601" +
"0505070309300f06092b060105050730010504020500301f0603551d23041830168014a2" +
"13a8e5c607546c243d4eb72b27a2a7711ab5af301d0603551d0e0416041451f98046818a" +
"e46d953ac90c210ccfaa1a06980c300d06092a864886f70d01010b050003820101003a37" +
"0b301d14ffdeb370883639bec5ae6f572dcbddadd672af16ee2a8303316b14e1fbdca8c2" +
"8f4bad9c7b1410250e149c14e9830ca6f17370a8d13151205d956e28c141cc0500379596" +
"c5b9239fcfa3d2de8f1d4f1a2b1bf2d1851bed1c86012ee8135bdc395cd4496ce69fadd0" +
"3b682b90350ca7b4f458190b7a0ab5c33a04cf1347a77d541877a380a4c94988c5658908" +
"44fdc22637a72b9fa410333e2caf969477f9fe07f50e3681c204fb3bf073b9da01cd8d91" +
"8044c40b1159955af12a3263ab1d34119d7f59bfa6cae88ed058addc4e08250263f8f836" +
"2f5bdffd45636fea7474c60a55c535954477b2f286e1b2535f0dd12c162f1b353c370e08" +
"be67"
const ocspMultiResponseCertHex = "308207943082067ca003020102020454566573300d06092a864886f70d01010b05003081" +
"82310b300906035504061302555331183016060355040a130f552e532e20476f7665726e" +
"6d656e7431233021060355040b131a4465706172746d656e74206f662074686520547265" +
"617375727931223020060355040b131943657274696669636174696f6e20417574686f72" +
"69746965733110300e060355040b13074f43494f204341301e170d313530343130313535" +
"3733385a170d3138303431303136323733385a30819d310b300906035504061302555331" +
"183016060355040a130f552e532e20476f7665726e6d656e7431233021060355040b131a" +
"4465706172746d656e74206f662074686520547265617375727931253023060355040b13" +
"1c427572656175206f66207468652046697363616c20536572766963653110300e060355" +
"040b130744657669636573311630140603550403130d706b692e74726561732e676f7630" +
"820122300d06092a864886f70d01010105000382010f003082010a0282010100c7273623" +
"8c49c48bf501515a2490ef6e5ae0c06e0ad2aa9a6bb77f3d0370d846b2571581ebf38fd3" +
"1948daad3dec7a4da095f1dcbe9654e65bcf7acdfd4ee802421dad9b90536c721d2bca58" +
"8413e6bfd739a72470560bb7d64f9a09284f90ff8af1d5a3c5c84d0f95a00f9c6d988dd0" +
"d87f1d0d3344580901c955139f54d09de0acdbd3322b758cb0c58881bf04913243401f44" +
"013fd9f6d8348044cc8bb0a71978ad93366b2a4687a5274b2ee07d0fb40225453eb244ed" +
"b20152251ac77c59455260ff07eeceb3cb3c60fb8121cf92afd3daa2a4650e1942ccb555" +
"de10b3d481feb299838ef05d0fd1810b146753472ae80da65dd34da25ca1f89971f10039" +
"0203010001a38203f3308203ef300e0603551d0f0101ff0404030205a030170603551d20" +
"0410300e300c060a60864801650302010503301106096086480186f84201010404030206" +
"4030130603551d25040c300a06082b060105050703013082010806082b06010505070101" +
"0481fb3081f8303006082b060105050730028624687474703a2f2f706b692e7472656173" +
"2e676f762f746f63615f65655f6169612e7037633081a006082b06010505073002868193" +
"6c6461703a2f2f6c6461702e74726561732e676f762f6f753d4f43494f25323043412c6f" +
"753d43657274696669636174696f6e253230417574686f7269746965732c6f753d446570" +
"6172746d656e742532306f6625323074686525323054726561737572792c6f3d552e532e" +
"253230476f7665726e6d656e742c633d55533f634143657274696669636174653b62696e" +
"617279302106082b060105050730018615687474703a2f2f6f6373702e74726561732e67" +
"6f76307b0603551d1104743072811c6373612d7465616d4066697363616c2e7472656173" +
"7572792e676f768210706b692e74726561737572792e676f768210706b692e64696d632e" +
"6468732e676f76820d706b692e74726561732e676f76811f6563622d686f7374696e6740" +
"66697363616c2e74726561737572792e676f76308201890603551d1f048201803082017c" +
"3027a025a0238621687474703a2f2f706b692e74726561732e676f762f4f43494f5f4341" +
"332e63726c3082014fa082014ba0820147a48197308194310b3009060355040613025553" +
"31183016060355040a130f552e532e20476f7665726e6d656e7431233021060355040b13" +
"1a4465706172746d656e74206f662074686520547265617375727931223020060355040b" +
"131943657274696669636174696f6e20417574686f7269746965733110300e060355040b" +
"13074f43494f2043413110300e0603550403130743524c313430398681aa6c6461703a2f" +
"2f6c6461702e74726561732e676f762f636e3d43524c313430392c6f753d4f43494f2532" +
"3043412c6f753d43657274696669636174696f6e253230417574686f7269746965732c6f" +
"753d4465706172746d656e742532306f6625323074686525323054726561737572792c6f" +
"3d552e532e253230476f7665726e6d656e742c633d55533f636572746966696361746552" +
"65766f636174696f6e4c6973743b62696e617279302b0603551d1004243022800f323031" +
"35303431303135353733385a810f32303138303431303136323733385a301f0603551d23" +
"041830168014a213a8e5c607546c243d4eb72b27a2a7711ab5af301d0603551d0e041604" +
"14b0869c12c293914cd460e33ed43e6c5a26e0d68f301906092a864886f67d074100040c" +
"300a1b0456382e31030203a8300d06092a864886f70d01010b050003820101004968d182" +
"8f9efdc147e747bb5dda15536a42a079b32d3d7f87e619b483aeee70b7e26bda393c6028" +
"7c733ecb468fe8b8b11bf809ff76add6b90eb25ad8d3a1052e43ee281e48a3a1ebe7efb5" +
"9e2c4a48765dedeb23f5346242145786cc988c762d230d28dd33bf4c2405d80cbb2cb1d6" +
"4c8f10ba130d50cb174f6ffb9cfc12808297a2cefba385f4fad170f39b51ebd87c12abf9" +
"3c51fc000af90d8aaba78f48923908804a5eb35f617ccf71d201e3708a559e6d16f9f13e" +
"074361eb9007e28d86bb4e0bfa13aad0e9ddd9124e84519de60e2fc6040b18d9fd602b02" +
"684b4c071c3019fc842197d00c120c41654bcbfbc4a096a1c637b79112b81ce1fa3899f9"
const ocspRequestHex = "3051304f304d304b3049300906052b0e03021a05000414c0fe0278fc99188891b3f212e9" +
"c7e1b21ab7bfc004140dfc1df0a9e0f01ce7f2b213177e6f8d157cd4f60210017f77deb3" +
"bcbb235d44ccc7dba62e72"
const leafCertHex = "308203c830820331a0030201020210017f77deb3bcbb235d44ccc7dba62e72300d06092a" +
"864886f70d01010505003081ba311f301d060355040a1316566572695369676e20547275" +
"7374204e6574776f726b31173015060355040b130e566572695369676e2c20496e632e31" +
"333031060355040b132a566572695369676e20496e7465726e6174696f6e616c20536572" +
"766572204341202d20436c617373203331493047060355040b13407777772e7665726973" +
"69676e2e636f6d2f43505320496e636f72702e6279205265662e204c494142494c495459" +
"204c54442e286329393720566572695369676e301e170d3132303632313030303030305a" +
"170d3133313233313233353935395a3068310b3009060355040613025553311330110603" +
"550408130a43616c69666f726e6961311230100603550407130950616c6f20416c746f31" +
"173015060355040a130e46616365626f6f6b2c20496e632e311730150603550403140e2a" +
"2e66616365626f6f6b2e636f6d30819f300d06092a864886f70d010101050003818d0030" +
"818902818100ae94b171e2deccc1693e051063240102e0689ae83c39b6b3e74b97d48d7b" +
"23689100b0b496ee62f0e6d356bcf4aa0f50643402f5d1766aa972835a7564723f39bbef" +
"5290ded9bcdbf9d3d55dfad23aa03dc604c54d29cf1d4b3bdbd1a809cfae47b44c7eae17" +
"c5109bee24a9cf4a8d911bb0fd0415ae4c3f430aa12a557e2ae10203010001a382011e30" +
"82011a30090603551d130402300030440603551d20043d303b3039060b6086480186f845" +
"01071703302a302806082b06010505070201161c68747470733a2f2f7777772e76657269" +
"7369676e2e636f6d2f727061303c0603551d1f043530333031a02fa02d862b687474703a" +
"2f2f535652496e746c2d63726c2e766572697369676e2e636f6d2f535652496e746c2e63" +
"726c301d0603551d250416301406082b0601050507030106082b06010505070302300b06" +
"03551d0f0404030205a0303406082b0601050507010104283026302406082b0601050507" +
"30018618687474703a2f2f6f6373702e766572697369676e2e636f6d30270603551d1104" +
"20301e820e2a2e66616365626f6f6b2e636f6d820c66616365626f6f6b2e636f6d300d06" +
"092a864886f70d0101050500038181005b6c2b75f8ed30aa51aad36aba595e555141951f" +
"81a53b447910ac1f76ff78fc2781616b58f3122afc1c87010425e9ed43df1a7ba6498060" +
"67e2688af03db58c7df4ee03309a6afc247ccb134dc33e54c6bc1d5133a532a73273b1d7" +
"9cadc08e7e1a83116d34523340b0305427a21742827c98916698ee7eaf8c3bdd71700817"
const issuerCertHex = "30820383308202eca003020102021046fcebbab4d02f0f926098233f93078f300d06092a" +
"864886f70d0101050500305f310b300906035504061302555331173015060355040a130e" +
"566572695369676e2c20496e632e31373035060355040b132e436c617373203320507562" +
"6c6963205072696d6172792043657274696669636174696f6e20417574686f7269747930" +
"1e170d3937303431373030303030305a170d3136313032343233353935395a3081ba311f" +
"301d060355040a1316566572695369676e205472757374204e6574776f726b3117301506" +
"0355040b130e566572695369676e2c20496e632e31333031060355040b132a5665726953" +
"69676e20496e7465726e6174696f6e616c20536572766572204341202d20436c61737320" +
"3331493047060355040b13407777772e766572697369676e2e636f6d2f43505320496e63" +
"6f72702e6279205265662e204c494142494c495459204c54442e28632939372056657269" +
"5369676e30819f300d06092a864886f70d010101050003818d0030818902818100d88280" +
"e8d619027d1f85183925a2652be1bfd405d3bce6363baaf04c6c5bb6e7aa3c734555b2f1" +
"bdea9742ed9a340a15d4a95cf54025ddd907c132b2756cc4cabba3fe56277143aa63f530" +
"3e9328e5faf1093bf3b74d4e39f75c495ab8c11dd3b28afe70309542cbfe2b518b5a3c3a" +
"f9224f90b202a7539c4f34e7ab04b27b6f0203010001a381e33081e0300f0603551d1304" +
"0830060101ff02010030440603551d20043d303b3039060b6086480186f8450107010130" +
"2a302806082b06010505070201161c68747470733a2f2f7777772e766572697369676e2e" +
"636f6d2f43505330340603551d25042d302b06082b0601050507030106082b0601050507" +
"030206096086480186f8420401060a6086480186f845010801300b0603551d0f04040302" +
"0106301106096086480186f842010104040302010630310603551d1f042a30283026a024" +
"a0228620687474703a2f2f63726c2e766572697369676e2e636f6d2f706361332e63726c" +
"300d06092a864886f70d010105050003818100408e4997968a73dd8e4def3e61b7caa062" +
"adf40e0abb753de26ed82cc7bff4b98c369bcaa2d09c724639f6a682036511c4bcbf2da6" +
"f5d93b0ab598fab378b91ef22b4c62d5fdb27a1ddf33fd73f9a5d82d8c2aead1fcb028b6" +
"e94948134b838a1b487b24f738de6f4154b8ab576b06dfc7a2d4a9f6f136628088f28b75" +
"d68071"
// Key and certificate for the OCSP responder were not taken from the Thawte
// responder, since CreateResponse requires that we have the private key.
// Instead, they were generated randomly.
const responderPrivateKeyHex = "308204a40201000282010100e8155f2d3e6f2e8d14c62a788bd462f9f844e7a6977c83ef" +
"1099f0f6616ec5265b56f356e62c5400f0b06a2e7945a82752c636df32a895152d6074df" +
"1701dc6ccfbcbec75a70bd2b55ae2be7e6cad3b5fd4cd5b7790ab401a436d3f5f346074f" +
"fde8a99d5b723350f0a112076614b12ef79c78991b119453445acf2416ab0046b540db14" +
"c9fc0f27b8989ad0f63aa4b8aefc91aa8a72160c36307c60fec78a93d3fddf4259902aa7" +
"7e7332971c7d285b6a04f648993c6922a3e9da9adf5f81508c3228791843e5d49f24db2f" +
"1290bafd97e655b1049a199f652cd603c4fafa330c390b0da78fbbc67e8fa021cbd74eb9" +
"6222b12ace31a77dcf920334dc94581b02030100010282010100bcf0b93d7238bda329a8" +
"72e7149f61bcb37c154330ccb3f42a85c9002c2e2bdea039d77d8581cd19bed94078794e" +
"56293d601547fc4bf6a2f9002fe5772b92b21b254403b403585e3130cc99ccf08f0ef81a" +
"575b38f597ba4660448b54f44bfbb97072b5a2bf043bfeca828cf7741d13698e3f38162b" +
"679faa646b82abd9a72c5c7d722c5fc577a76d2c2daac588accad18516d1bbad10b0dfa2" +
"05cfe246b59e28608a43942e1b71b0c80498075121de5b900d727c31c42c78cf1db5c0aa" +
"5b491e10ea4ed5c0962aaf2ae025dd81fa4ce490d9d6b4a4465411d8e542fc88617e5695" +
"1aa4fc8ea166f2b4d0eb89ef17f2b206bd5f1014bf8fe0e71fe62f2cccf102818100f2dc" +
"ddf878d553286daad68bac4070a82ffec3dc4666a2750f47879eec913f91836f1d976b60" +
"daf9356e078446dafab5bd2e489e5d64f8572ba24a4ba4f3729b5e106c4dd831cc2497a7" +
"e6c7507df05cb64aeb1bbc81c1e340d58b5964cf39cff84ea30c29ec5d3f005ee1362698" +
"07395037955955655292c3e85f6187fa1f9502818100f4a33c102630840705f8c778a47b" +
"87e8da31e68809af981ac5e5999cf1551685d761cdf0d6520361b99aebd5777a940fa64d" +
"327c09fa63746fbb3247ec73a86edf115f1fe5c83598db803881ade71c33c6e956118345" +
"497b98b5e07bb5be75971465ec78f2f9467e1b74956ca9d4c7c3e314e742a72d8b33889c" +
"6c093a466cef0281801d3df0d02124766dd0be98349b19eb36a508c4e679e793ba0a8bef" +
"4d786888c1e9947078b1ea28938716677b4ad8c5052af12eb73ac194915264a913709a0b" +
"7b9f98d4a18edd781a13d49899f91c20dbd8eb2e61d991ba19b5cdc08893f5cb9d39e5a6" +
"0629ea16d426244673b1b3ee72bd30e41fac8395acac40077403de5efd028180050731dd" +
"d71b1a2b96c8d538ba90bb6b62c8b1c74c03aae9a9f59d21a7a82b0d572ef06fa9c807bf" +
"c373d6b30d809c7871df96510c577421d9860c7383fda0919ece19996b3ca13562159193" +
"c0c246471e287f975e8e57034e5136aaf44254e2650def3d51292474c515b1588969112e" +
"0a85cc77073e9d64d2c2fc497844284b02818100d71d63eabf416cf677401ebf965f8314" +
"120b568a57dd3bd9116c629c40dc0c6948bab3a13cc544c31c7da40e76132ef5dd3f7534" +
"45a635930c74326ae3df0edd1bfb1523e3aa259873ac7cf1ac31151ec8f37b528c275622" +
"48f99b8bed59fd4da2576aa6ee20d93a684900bf907e80c66d6e2261ae15e55284b4ed9d" +
"6bdaa059"
const responderCertHex = "308202e2308201caa003020102020101300d06092a864886f70d01010b05003019311730" +
"150603550403130e4f43535020526573706f6e646572301e170d31353031333031353530" +
"33335a170d3136303133303135353033335a3019311730150603550403130e4f43535020" +
"526573706f6e64657230820122300d06092a864886f70d01010105000382010f00308201" +
"0a0282010100e8155f2d3e6f2e8d14c62a788bd462f9f844e7a6977c83ef1099f0f6616e" +
"c5265b56f356e62c5400f0b06a2e7945a82752c636df32a895152d6074df1701dc6ccfbc" +
"bec75a70bd2b55ae2be7e6cad3b5fd4cd5b7790ab401a436d3f5f346074ffde8a99d5b72" +
"3350f0a112076614b12ef79c78991b119453445acf2416ab0046b540db14c9fc0f27b898" +
"9ad0f63aa4b8aefc91aa8a72160c36307c60fec78a93d3fddf4259902aa77e7332971c7d" +
"285b6a04f648993c6922a3e9da9adf5f81508c3228791843e5d49f24db2f1290bafd97e6" +
"55b1049a199f652cd603c4fafa330c390b0da78fbbc67e8fa021cbd74eb96222b12ace31" +
"a77dcf920334dc94581b0203010001a3353033300e0603551d0f0101ff04040302078030" +
"130603551d25040c300a06082b06010505070309300c0603551d130101ff04023000300d" +
"06092a864886f70d01010b05000382010100718012761b5063e18f0dc44644d8e6ab8612" +
"31c15fd5357805425d82aec1de85bf6d3e30fce205e3e3b8b795bbe52e40a439286d2288" +
"9064f4aeeb150359b9425f1da51b3a5c939018555d13ac42c565a0603786a919328f3267" +
"09dce52c22ad958ecb7873b9771d1148b1c4be2efe80ba868919fc9f68b6090c2f33c156" +
"d67156e42766a50b5d51e79637b7e58af74c2a951b1e642fa7741fec982cc937de37eff5" +
"9e2005d5939bfc031589ca143e6e8ab83f40ee08cc20a6b4a95a318352c28d18528dcaf9" +
"66705de17afa19d6e8ae91ddf33179d16ebb6ac2c69cae8373d408ebf8c55308be6c04d9" +
"3a25439a94299a65a709756c7a3e568be049d5c38839"
const errorResponseHex = "30030a0101"

View File

@ -1,63 +0,0 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package pkcs12
import (
"bytes"
"encoding/hex"
"testing"
)
var bmpStringTests = []struct {
in string
expectedHex string
shouldFail bool
}{
{"", "0000", false},
// Example from https://tools.ietf.org/html/rfc7292#appendix-B.
{"Beavis", "0042006500610076006900730000", false},
// Some characters from the "Letterlike Symbols Unicode block".
{"\u2115 - Double-struck N", "21150020002d00200044006f00750062006c0065002d00730074007200750063006b0020004e0000", false},
// any character outside the BMP should trigger an error.
{"\U0001f000 East wind (Mahjong)", "", true},
}
func TestBMPString(t *testing.T) {
for i, test := range bmpStringTests {
expected, err := hex.DecodeString(test.expectedHex)
if err != nil {
t.Fatalf("#%d: failed to decode expectation", i)
}
out, err := bmpString(test.in)
if err == nil && test.shouldFail {
t.Errorf("#%d: expected to fail, but produced %x", i, out)
continue
}
if err != nil && !test.shouldFail {
t.Errorf("#%d: failed unexpectedly: %s", i, err)
continue
}
if !test.shouldFail {
if !bytes.Equal(out, expected) {
t.Errorf("#%d: expected %s, got %x", i, test.expectedHex, out)
continue
}
roundTrip, err := decodeBMPString(out)
if err != nil {
t.Errorf("#%d: decoding output gave an error: %s", i, err)
continue
}
if roundTrip != test.in {
t.Errorf("#%d: decoding output resulted in %q, but it should have been %q", i, roundTrip, test.in)
continue
}
}
}
}

View File

@ -1,125 +0,0 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package pkcs12
import (
"bytes"
"crypto/x509/pkix"
"encoding/asn1"
"testing"
)
var sha1WithTripleDES = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 12, 1, 3})
func TestPbDecrypterFor(t *testing.T) {
params, _ := asn1.Marshal(pbeParams{
Salt: []byte{1, 2, 3, 4, 5, 6, 7, 8},
Iterations: 2048,
})
alg := pkix.AlgorithmIdentifier{
Algorithm: asn1.ObjectIdentifier([]int{1, 2, 3}),
Parameters: asn1.RawValue{
FullBytes: params,
},
}
pass, _ := bmpString("Sesame open")
_, _, err := pbDecrypterFor(alg, pass)
if _, ok := err.(NotImplementedError); !ok {
t.Errorf("expected not implemented error, got: %T %s", err, err)
}
alg.Algorithm = sha1WithTripleDES
cbc, blockSize, err := pbDecrypterFor(alg, pass)
if err != nil {
t.Errorf("unexpected error from pbDecrypterFor %v", err)
}
if blockSize != 8 {
t.Errorf("unexpected block size %d, wanted 8", blockSize)
}
plaintext := []byte{1, 2, 3, 4, 5, 6, 7, 8}
expectedCiphertext := []byte{185, 73, 135, 249, 137, 1, 122, 247}
ciphertext := make([]byte, len(plaintext))
cbc.CryptBlocks(ciphertext, plaintext)
if bytes.Compare(ciphertext, expectedCiphertext) != 0 {
t.Errorf("bad ciphertext, got %x but wanted %x", ciphertext, expectedCiphertext)
}
}
var pbDecryptTests = []struct {
in []byte
expected []byte
expectedError error
}{
{
[]byte("\x33\x73\xf3\x9f\xda\x49\xae\xfc\xa0\x9a\xdf\x5a\x58\xa0\xea\x46"), // 7 padding bytes
[]byte("A secret!"),
nil,
},
{
[]byte("\x33\x73\xf3\x9f\xda\x49\xae\xfc\x96\x24\x2f\x71\x7e\x32\x3f\xe7"), // 8 padding bytes
[]byte("A secret"),
nil,
},
{
[]byte("\x35\x0c\xc0\x8d\xab\xa9\x5d\x30\x7f\x9a\xec\x6a\xd8\x9b\x9c\xd9"), // 9 padding bytes, incorrect
nil,
ErrDecryption,
},
{
[]byte("\xb2\xf9\x6e\x06\x60\xae\x20\xcf\x08\xa0\x7b\xd9\x6b\x20\xef\x41"), // incorrect padding bytes: [ ... 0x04 0x02 ]
nil,
ErrDecryption,
},
}
func TestPbDecrypt(t *testing.T) {
for i, test := range pbDecryptTests {
decryptable := testDecryptable{
data: test.in,
algorithm: pkix.AlgorithmIdentifier{
Algorithm: sha1WithTripleDES,
Parameters: pbeParams{
Salt: []byte("\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8"),
Iterations: 4096,
}.RawASN1(),
},
}
password, _ := bmpString("sesame")
plaintext, err := pbDecrypt(decryptable, password)
if err != test.expectedError {
t.Errorf("#%d: got error %q, but wanted %q", i, err, test.expectedError)
continue
}
if !bytes.Equal(plaintext, test.expected) {
t.Errorf("#%d: got %x, but wanted %x", i, plaintext, test.expected)
}
}
}
type testDecryptable struct {
data []byte
algorithm pkix.AlgorithmIdentifier
}
func (d testDecryptable) Algorithm() pkix.AlgorithmIdentifier { return d.algorithm }
func (d testDecryptable) Data() []byte { return d.data }
func (params pbeParams) RawASN1() (raw asn1.RawValue) {
asn1Bytes, err := asn1.Marshal(params)
if err != nil {
panic(err)
}
_, err = asn1.Unmarshal(asn1Bytes, &raw)
if err != nil {
panic(err)
}
return
}

View File

@ -1,27 +0,0 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package rc2
import (
"testing"
)
func BenchmarkEncrypt(b *testing.B) {
r, _ := New([]byte{0, 0, 0, 0, 0, 0, 0, 0}, 64)
b.ResetTimer()
var src [8]byte
for i := 0; i < b.N; i++ {
r.Encrypt(src[:], src[:])
}
}
func BenchmarkDecrypt(b *testing.B) {
r, _ := New([]byte{0, 0, 0, 0, 0, 0, 0, 0}, 64)
b.ResetTimer()
var src [8]byte
for i := 0; i < b.N; i++ {
r.Decrypt(src[:], src[:])
}
}

View File

@ -1,92 +0,0 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package rc2
import (
"bytes"
"encoding/hex"
"testing"
)
func TestEncryptDecrypt(t *testing.T) {
// TODO(dgryski): add the rest of the test vectors from the RFC
var tests = []struct {
key string
plain string
cipher string
t1 int
}{
{
"0000000000000000",
"0000000000000000",
"ebb773f993278eff",
63,
},
{
"ffffffffffffffff",
"ffffffffffffffff",
"278b27e42e2f0d49",
64,
},
{
"3000000000000000",
"1000000000000001",
"30649edf9be7d2c2",
64,
},
{
"88",
"0000000000000000",
"61a8a244adacccf0",
64,
},
{
"88bca90e90875a",
"0000000000000000",
"6ccf4308974c267f",
64,
},
{
"88bca90e90875a7f0f79c384627bafb2",
"0000000000000000",
"1a807d272bbe5db1",
64,
},
{
"88bca90e90875a7f0f79c384627bafb2",
"0000000000000000",
"2269552ab0f85ca6",
128,
},
{
"88bca90e90875a7f0f79c384627bafb216f80a6f85920584c42fceb0be255daf1e",
"0000000000000000",
"5b78d3a43dfff1f1",
129,
},
}
for _, tt := range tests {
k, _ := hex.DecodeString(tt.key)
p, _ := hex.DecodeString(tt.plain)
c, _ := hex.DecodeString(tt.cipher)
b, _ := New(k, tt.t1)
var dst [8]byte
b.Encrypt(dst[:], p)
if !bytes.Equal(dst[:], c) {
t.Errorf("encrypt failed: got % 2x wanted % 2x\n", dst, c)
}
b.Decrypt(dst[:], c)
if !bytes.Equal(dst[:], p) {
t.Errorf("decrypt failed: got % 2x wanted % 2x\n", dst, p)
}
}
}

View File

@ -1,42 +0,0 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package pkcs12
import (
"encoding/asn1"
"testing"
)
func TestVerifyMac(t *testing.T) {
td := macData{
Mac: digestInfo{
Digest: []byte{0x18, 0x20, 0x3d, 0xff, 0x1e, 0x16, 0xf4, 0x92, 0xf2, 0xaf, 0xc8, 0x91, 0xa9, 0xba, 0xd6, 0xca, 0x9d, 0xee, 0x51, 0x93},
},
MacSalt: []byte{1, 2, 3, 4, 5, 6, 7, 8},
Iterations: 2048,
}
message := []byte{11, 12, 13, 14, 15}
password, _ := bmpString("")
td.Mac.Algorithm.Algorithm = asn1.ObjectIdentifier([]int{1, 2, 3})
err := verifyMac(&td, message, password)
if _, ok := err.(NotImplementedError); !ok {
t.Errorf("err: %v", err)
}
td.Mac.Algorithm.Algorithm = asn1.ObjectIdentifier([]int{1, 3, 14, 3, 2, 26})
err = verifyMac(&td, message, password)
if err != ErrIncorrectPassword {
t.Errorf("Expected incorrect password, got err: %v", err)
}
password, _ = bmpString("Sesame open")
err = verifyMac(&td, message, password)
if err != nil {
t.Errorf("err: %v", err)
}
}

View File

@ -1,34 +0,0 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package pkcs12
import (
"bytes"
"testing"
)
func TestThatPBKDFWorksCorrectlyForLongKeys(t *testing.T) {
cipherInfo := shaWithTripleDESCBC{}
salt := []byte("\xff\xff\xff\xff\xff\xff\xff\xff")
password, _ := bmpString("sesame")
key := cipherInfo.deriveKey(salt, password, 2048)
if expected := []byte("\x7c\xd9\xfd\x3e\x2b\x3b\xe7\x69\x1a\x44\xe3\xbe\xf0\xf9\xea\x0f\xb9\xb8\x97\xd4\xe3\x25\xd9\xd1"); bytes.Compare(key, expected) != 0 {
t.Fatalf("expected key '%x', but found '%x'", expected, key)
}
}
func TestThatPBKDFHandlesLeadingZeros(t *testing.T) {
// This test triggers a case where I_j (in step 6C) ends up with leading zero
// byte, meaning that len(Ijb) < v (leading zeros get stripped by big.Int).
// This was previously causing bug whereby certain inputs would break the
// derivation and produce the wrong output.
key := pbkdf(sha1Sum, 20, 64, []byte("\xf3\x7e\x05\xb5\x18\x32\x4b\x4b"), []byte("\x00\x00"), 2048, 1, 24)
expected := []byte("\x00\xf7\x59\xff\x47\xd1\x4d\xd0\x36\x65\xd5\x94\x3c\xb3\xc4\xa3\x9a\x25\x55\xc0\x2a\xed\x66\xe1")
if bytes.Compare(key, expected) != 0 {
t.Fatalf("expected key '%x', but found '%x'", expected, key)
}
}

View File

@ -1,138 +0,0 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package pkcs12
import (
"crypto/rsa"
"crypto/tls"
"encoding/base64"
"encoding/pem"
"testing"
)
func TestPfx(t *testing.T) {
for commonName, base64P12 := range testdata {
p12, _ := base64.StdEncoding.DecodeString(base64P12)
priv, cert, err := Decode(p12, "")
if err != nil {
t.Fatal(err)
}
if err := priv.(*rsa.PrivateKey).Validate(); err != nil {
t.Errorf("error while validating private key: %v", err)
}
if cert.Subject.CommonName != commonName {
t.Errorf("expected common name to be %q, but found %q", commonName, cert.Subject.CommonName)
}
}
}
func TestPEM(t *testing.T) {
for commonName, base64P12 := range testdata {
p12, _ := base64.StdEncoding.DecodeString(base64P12)
blocks, err := ToPEM(p12, "")
if err != nil {
t.Fatalf("error while converting to PEM: %s", err)
}
var pemData []byte
for _, b := range blocks {
pemData = append(pemData, pem.EncodeToMemory(b)...)
}
cert, err := tls.X509KeyPair(pemData, pemData)
if err != nil {
t.Errorf("err while converting to key pair: %v", err)
}
config := tls.Config{
Certificates: []tls.Certificate{cert},
}
config.BuildNameToCertificate()
if _, exists := config.NameToCertificate[commonName]; !exists {
t.Errorf("did not find our cert in PEM?: %v", config.NameToCertificate)
}
}
}
func ExampleToPEM() {
p12, _ := base64.StdEncoding.DecodeString(`MIIJzgIBAzCCCZQGCS ... CA+gwggPk==`)
blocks, err := ToPEM(p12, "password")
if err != nil {
panic(err)
}
var pemData []byte
for _, b := range blocks {
pemData = append(pemData, pem.EncodeToMemory(b)...)
}
// then use PEM data for tls to construct tls certificate:
cert, err := tls.X509KeyPair(pemData, pemData)
if err != nil {
panic(err)
}
config := &tls.Config{
Certificates: []tls.Certificate{cert},
}
_ = config
}
var testdata = map[string]string{
// 'null' password test case
"Windows Azure Tools": `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`,
// empty string password test case
"testing@example.com": `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
HQ8CAggA`,
}