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`,
}

3
vendor/golang.org/x/net/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 http://tip.golang.org/AUTHORS.

3
vendor/golang.org/x/net/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 http://tip.golang.org/CONTRIBUTORS.

27
vendor/golang.org/x/net/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/net/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,583 +0,0 @@
// Copyright 2014 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 context
import (
"fmt"
"math/rand"
"runtime"
"strings"
"sync"
"testing"
"time"
)
// otherContext is a Context that's not one of the types defined in context.go.
// This lets us test code paths that differ based on the underlying type of the
// Context.
type otherContext struct {
Context
}
func TestBackground(t *testing.T) {
c := Background()
if c == nil {
t.Fatalf("Background returned nil")
}
select {
case x := <-c.Done():
t.Errorf("<-c.Done() == %v want nothing (it should block)", x)
default:
}
if got, want := fmt.Sprint(c), "context.Background"; got != want {
t.Errorf("Background().String() = %q want %q", got, want)
}
}
func TestTODO(t *testing.T) {
c := TODO()
if c == nil {
t.Fatalf("TODO returned nil")
}
select {
case x := <-c.Done():
t.Errorf("<-c.Done() == %v want nothing (it should block)", x)
default:
}
if got, want := fmt.Sprint(c), "context.TODO"; got != want {
t.Errorf("TODO().String() = %q want %q", got, want)
}
}
func TestWithCancel(t *testing.T) {
c1, cancel := WithCancel(Background())
if got, want := fmt.Sprint(c1), "context.Background.WithCancel"; got != want {
t.Errorf("c1.String() = %q want %q", got, want)
}
o := otherContext{c1}
c2, _ := WithCancel(o)
contexts := []Context{c1, o, c2}
for i, c := range contexts {
if d := c.Done(); d == nil {
t.Errorf("c[%d].Done() == %v want non-nil", i, d)
}
if e := c.Err(); e != nil {
t.Errorf("c[%d].Err() == %v want nil", i, e)
}
select {
case x := <-c.Done():
t.Errorf("<-c.Done() == %v want nothing (it should block)", x)
default:
}
}
cancel()
time.Sleep(100 * time.Millisecond) // let cancelation propagate
for i, c := range contexts {
select {
case <-c.Done():
default:
t.Errorf("<-c[%d].Done() blocked, but shouldn't have", i)
}
if e := c.Err(); e != Canceled {
t.Errorf("c[%d].Err() == %v want %v", i, e, Canceled)
}
}
}
func TestParentFinishesChild(t *testing.T) {
// Context tree:
// parent -> cancelChild
// parent -> valueChild -> timerChild
parent, cancel := WithCancel(Background())
cancelChild, stop := WithCancel(parent)
defer stop()
valueChild := WithValue(parent, "key", "value")
timerChild, stop := WithTimeout(valueChild, 10000*time.Hour)
defer stop()
select {
case x := <-parent.Done():
t.Errorf("<-parent.Done() == %v want nothing (it should block)", x)
case x := <-cancelChild.Done():
t.Errorf("<-cancelChild.Done() == %v want nothing (it should block)", x)
case x := <-timerChild.Done():
t.Errorf("<-timerChild.Done() == %v want nothing (it should block)", x)
case x := <-valueChild.Done():
t.Errorf("<-valueChild.Done() == %v want nothing (it should block)", x)
default:
}
// The parent's children should contain the two cancelable children.
pc := parent.(*cancelCtx)
cc := cancelChild.(*cancelCtx)
tc := timerChild.(*timerCtx)
pc.mu.Lock()
if len(pc.children) != 2 || !pc.children[cc] || !pc.children[tc] {
t.Errorf("bad linkage: pc.children = %v, want %v and %v",
pc.children, cc, tc)
}
pc.mu.Unlock()
if p, ok := parentCancelCtx(cc.Context); !ok || p != pc {
t.Errorf("bad linkage: parentCancelCtx(cancelChild.Context) = %v, %v want %v, true", p, ok, pc)
}
if p, ok := parentCancelCtx(tc.Context); !ok || p != pc {
t.Errorf("bad linkage: parentCancelCtx(timerChild.Context) = %v, %v want %v, true", p, ok, pc)
}
cancel()
pc.mu.Lock()
if len(pc.children) != 0 {
t.Errorf("pc.cancel didn't clear pc.children = %v", pc.children)
}
pc.mu.Unlock()
// parent and children should all be finished.
check := func(ctx Context, name string) {
select {
case <-ctx.Done():
default:
t.Errorf("<-%s.Done() blocked, but shouldn't have", name)
}
if e := ctx.Err(); e != Canceled {
t.Errorf("%s.Err() == %v want %v", name, e, Canceled)
}
}
check(parent, "parent")
check(cancelChild, "cancelChild")
check(valueChild, "valueChild")
check(timerChild, "timerChild")
// WithCancel should return a canceled context on a canceled parent.
precanceledChild := WithValue(parent, "key", "value")
select {
case <-precanceledChild.Done():
default:
t.Errorf("<-precanceledChild.Done() blocked, but shouldn't have")
}
if e := precanceledChild.Err(); e != Canceled {
t.Errorf("precanceledChild.Err() == %v want %v", e, Canceled)
}
}
func TestChildFinishesFirst(t *testing.T) {
cancelable, stop := WithCancel(Background())
defer stop()
for _, parent := range []Context{Background(), cancelable} {
child, cancel := WithCancel(parent)
select {
case x := <-parent.Done():
t.Errorf("<-parent.Done() == %v want nothing (it should block)", x)
case x := <-child.Done():
t.Errorf("<-child.Done() == %v want nothing (it should block)", x)
default:
}
cc := child.(*cancelCtx)
pc, pcok := parent.(*cancelCtx) // pcok == false when parent == Background()
if p, ok := parentCancelCtx(cc.Context); ok != pcok || (ok && pc != p) {
t.Errorf("bad linkage: parentCancelCtx(cc.Context) = %v, %v want %v, %v", p, ok, pc, pcok)
}
if pcok {
pc.mu.Lock()
if len(pc.children) != 1 || !pc.children[cc] {
t.Errorf("bad linkage: pc.children = %v, cc = %v", pc.children, cc)
}
pc.mu.Unlock()
}
cancel()
if pcok {
pc.mu.Lock()
if len(pc.children) != 0 {
t.Errorf("child's cancel didn't remove self from pc.children = %v", pc.children)
}
pc.mu.Unlock()
}
// child should be finished.
select {
case <-child.Done():
default:
t.Errorf("<-child.Done() blocked, but shouldn't have")
}
if e := child.Err(); e != Canceled {
t.Errorf("child.Err() == %v want %v", e, Canceled)
}
// parent should not be finished.
select {
case x := <-parent.Done():
t.Errorf("<-parent.Done() == %v want nothing (it should block)", x)
default:
}
if e := parent.Err(); e != nil {
t.Errorf("parent.Err() == %v want nil", e)
}
}
}
func testDeadline(c Context, wait time.Duration, t *testing.T) {
select {
case <-time.After(wait):
t.Fatalf("context should have timed out")
case <-c.Done():
}
if e := c.Err(); e != DeadlineExceeded {
t.Errorf("c.Err() == %v want %v", e, DeadlineExceeded)
}
}
func TestDeadline(t *testing.T) {
t.Parallel()
const timeUnit = 500 * time.Millisecond
c, _ := WithDeadline(Background(), time.Now().Add(1*timeUnit))
if got, prefix := fmt.Sprint(c), "context.Background.WithDeadline("; !strings.HasPrefix(got, prefix) {
t.Errorf("c.String() = %q want prefix %q", got, prefix)
}
testDeadline(c, 2*timeUnit, t)
c, _ = WithDeadline(Background(), time.Now().Add(1*timeUnit))
o := otherContext{c}
testDeadline(o, 2*timeUnit, t)
c, _ = WithDeadline(Background(), time.Now().Add(1*timeUnit))
o = otherContext{c}
c, _ = WithDeadline(o, time.Now().Add(3*timeUnit))
testDeadline(c, 2*timeUnit, t)
}
func TestTimeout(t *testing.T) {
t.Parallel()
const timeUnit = 500 * time.Millisecond
c, _ := WithTimeout(Background(), 1*timeUnit)
if got, prefix := fmt.Sprint(c), "context.Background.WithDeadline("; !strings.HasPrefix(got, prefix) {
t.Errorf("c.String() = %q want prefix %q", got, prefix)
}
testDeadline(c, 2*timeUnit, t)
c, _ = WithTimeout(Background(), 1*timeUnit)
o := otherContext{c}
testDeadline(o, 2*timeUnit, t)
c, _ = WithTimeout(Background(), 1*timeUnit)
o = otherContext{c}
c, _ = WithTimeout(o, 3*timeUnit)
testDeadline(c, 2*timeUnit, t)
}
func TestCanceledTimeout(t *testing.T) {
t.Parallel()
const timeUnit = 500 * time.Millisecond
c, _ := WithTimeout(Background(), 2*timeUnit)
o := otherContext{c}
c, cancel := WithTimeout(o, 4*timeUnit)
cancel()
time.Sleep(1 * timeUnit) // let cancelation propagate
select {
case <-c.Done():
default:
t.Errorf("<-c.Done() blocked, but shouldn't have")
}
if e := c.Err(); e != Canceled {
t.Errorf("c.Err() == %v want %v", e, Canceled)
}
}
type key1 int
type key2 int
var k1 = key1(1)
var k2 = key2(1) // same int as k1, different type
var k3 = key2(3) // same type as k2, different int
func TestValues(t *testing.T) {
check := func(c Context, nm, v1, v2, v3 string) {
if v, ok := c.Value(k1).(string); ok == (len(v1) == 0) || v != v1 {
t.Errorf(`%s.Value(k1).(string) = %q, %t want %q, %t`, nm, v, ok, v1, len(v1) != 0)
}
if v, ok := c.Value(k2).(string); ok == (len(v2) == 0) || v != v2 {
t.Errorf(`%s.Value(k2).(string) = %q, %t want %q, %t`, nm, v, ok, v2, len(v2) != 0)
}
if v, ok := c.Value(k3).(string); ok == (len(v3) == 0) || v != v3 {
t.Errorf(`%s.Value(k3).(string) = %q, %t want %q, %t`, nm, v, ok, v3, len(v3) != 0)
}
}
c0 := Background()
check(c0, "c0", "", "", "")
c1 := WithValue(Background(), k1, "c1k1")
check(c1, "c1", "c1k1", "", "")
if got, want := fmt.Sprint(c1), `context.Background.WithValue(1, "c1k1")`; got != want {
t.Errorf("c.String() = %q want %q", got, want)
}
c2 := WithValue(c1, k2, "c2k2")
check(c2, "c2", "c1k1", "c2k2", "")
c3 := WithValue(c2, k3, "c3k3")
check(c3, "c2", "c1k1", "c2k2", "c3k3")
c4 := WithValue(c3, k1, nil)
check(c4, "c4", "", "c2k2", "c3k3")
o0 := otherContext{Background()}
check(o0, "o0", "", "", "")
o1 := otherContext{WithValue(Background(), k1, "c1k1")}
check(o1, "o1", "c1k1", "", "")
o2 := WithValue(o1, k2, "o2k2")
check(o2, "o2", "c1k1", "o2k2", "")
o3 := otherContext{c4}
check(o3, "o3", "", "c2k2", "c3k3")
o4 := WithValue(o3, k3, nil)
check(o4, "o4", "", "c2k2", "")
}
func TestAllocs(t *testing.T) {
bg := Background()
for _, test := range []struct {
desc string
f func()
limit float64
gccgoLimit float64
}{
{
desc: "Background()",
f: func() { Background() },
limit: 0,
gccgoLimit: 0,
},
{
desc: fmt.Sprintf("WithValue(bg, %v, nil)", k1),
f: func() {
c := WithValue(bg, k1, nil)
c.Value(k1)
},
limit: 3,
gccgoLimit: 3,
},
{
desc: "WithTimeout(bg, 15*time.Millisecond)",
f: func() {
c, _ := WithTimeout(bg, 15*time.Millisecond)
<-c.Done()
},
limit: 8,
gccgoLimit: 16,
},
{
desc: "WithCancel(bg)",
f: func() {
c, cancel := WithCancel(bg)
cancel()
<-c.Done()
},
limit: 5,
gccgoLimit: 8,
},
{
desc: "WithTimeout(bg, 100*time.Millisecond)",
f: func() {
c, cancel := WithTimeout(bg, 100*time.Millisecond)
cancel()
<-c.Done()
},
limit: 8,
gccgoLimit: 25,
},
} {
limit := test.limit
if runtime.Compiler == "gccgo" {
// gccgo does not yet do escape analysis.
// TODO(iant): Remove this when gccgo does do escape analysis.
limit = test.gccgoLimit
}
if n := testing.AllocsPerRun(100, test.f); n > limit {
t.Errorf("%s allocs = %f want %d", test.desc, n, int(limit))
}
}
}
func TestSimultaneousCancels(t *testing.T) {
root, cancel := WithCancel(Background())
m := map[Context]CancelFunc{root: cancel}
q := []Context{root}
// Create a tree of contexts.
for len(q) != 0 && len(m) < 100 {
parent := q[0]
q = q[1:]
for i := 0; i < 4; i++ {
ctx, cancel := WithCancel(parent)
m[ctx] = cancel
q = append(q, ctx)
}
}
// Start all the cancels in a random order.
var wg sync.WaitGroup
wg.Add(len(m))
for _, cancel := range m {
go func(cancel CancelFunc) {
cancel()
wg.Done()
}(cancel)
}
// Wait on all the contexts in a random order.
for ctx := range m {
select {
case <-ctx.Done():
case <-time.After(1 * time.Second):
buf := make([]byte, 10<<10)
n := runtime.Stack(buf, true)
t.Fatalf("timed out waiting for <-ctx.Done(); stacks:\n%s", buf[:n])
}
}
// Wait for all the cancel functions to return.
done := make(chan struct{})
go func() {
wg.Wait()
close(done)
}()
select {
case <-done:
case <-time.After(1 * time.Second):
buf := make([]byte, 10<<10)
n := runtime.Stack(buf, true)
t.Fatalf("timed out waiting for cancel functions; stacks:\n%s", buf[:n])
}
}
func TestInterlockedCancels(t *testing.T) {
parent, cancelParent := WithCancel(Background())
child, cancelChild := WithCancel(parent)
go func() {
parent.Done()
cancelChild()
}()
cancelParent()
select {
case <-child.Done():
case <-time.After(1 * time.Second):
buf := make([]byte, 10<<10)
n := runtime.Stack(buf, true)
t.Fatalf("timed out waiting for child.Done(); stacks:\n%s", buf[:n])
}
}
func TestLayersCancel(t *testing.T) {
testLayers(t, time.Now().UnixNano(), false)
}
func TestLayersTimeout(t *testing.T) {
testLayers(t, time.Now().UnixNano(), true)
}
func testLayers(t *testing.T, seed int64, testTimeout bool) {
rand.Seed(seed)
errorf := func(format string, a ...interface{}) {
t.Errorf(fmt.Sprintf("seed=%d: %s", seed, format), a...)
}
const (
timeout = 200 * time.Millisecond
minLayers = 30
)
type value int
var (
vals []*value
cancels []CancelFunc
numTimers int
ctx = Background()
)
for i := 0; i < minLayers || numTimers == 0 || len(cancels) == 0 || len(vals) == 0; i++ {
switch rand.Intn(3) {
case 0:
v := new(value)
ctx = WithValue(ctx, v, v)
vals = append(vals, v)
case 1:
var cancel CancelFunc
ctx, cancel = WithCancel(ctx)
cancels = append(cancels, cancel)
case 2:
var cancel CancelFunc
ctx, cancel = WithTimeout(ctx, timeout)
cancels = append(cancels, cancel)
numTimers++
}
}
checkValues := func(when string) {
for _, key := range vals {
if val := ctx.Value(key).(*value); key != val {
errorf("%s: ctx.Value(%p) = %p want %p", when, key, val, key)
}
}
}
select {
case <-ctx.Done():
errorf("ctx should not be canceled yet")
default:
}
if s, prefix := fmt.Sprint(ctx), "context.Background."; !strings.HasPrefix(s, prefix) {
t.Errorf("ctx.String() = %q want prefix %q", s, prefix)
}
t.Log(ctx)
checkValues("before cancel")
if testTimeout {
select {
case <-ctx.Done():
case <-time.After(timeout + 100*time.Millisecond):
errorf("ctx should have timed out")
}
checkValues("after timeout")
} else {
cancel := cancels[rand.Intn(len(cancels))]
cancel()
select {
case <-ctx.Done():
default:
errorf("ctx should be canceled")
}
checkValues("after cancel")
}
}
func TestCancelRemoves(t *testing.T) {
checkChildren := func(when string, ctx Context, want int) {
if got := len(ctx.(*cancelCtx).children); got != want {
t.Errorf("%s: context has %d children, want %d", when, got, want)
}
}
ctx, _ := WithCancel(Background())
checkChildren("after creation", ctx, 0)
_, cancel := WithCancel(ctx)
checkChildren("with WithCancel child ", ctx, 1)
cancel()
checkChildren("after cancelling WithCancel child", ctx, 0)
ctx, _ = WithCancel(Background())
checkChildren("after creation", ctx, 0)
_, cancel = WithTimeout(ctx, 60*time.Minute)
checkChildren("with WithTimeout child ", ctx, 1)
cancel()
checkChildren("after cancelling WithTimeout child", ctx, 0)
}

View File

@ -1,29 +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.
// +build !plan9,go1.7
package ctxhttp
import (
"io"
"net/http"
"net/http/httptest"
"testing"
"context"
)
func TestGo17Context(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "ok")
}))
defer ts.Close()
ctx := context.Background()
resp, err := Get(ctx, http.DefaultClient, ts.URL)
if resp == nil || err != nil {
t.Fatalf("error received from client: %v %v", err, resp)
}
resp.Body.Close()
}

View File

@ -1,79 +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.
// +build !plan9,!go1.7
package ctxhttp
import (
"net"
"net/http"
"net/http/httptest"
"sync"
"testing"
"time"
"golang.org/x/net/context"
)
// golang.org/issue/14065
func TestClosesResponseBodyOnCancel(t *testing.T) {
defer func() { testHookContextDoneBeforeHeaders = nop }()
defer func() { testHookDoReturned = nop }()
defer func() { testHookDidBodyClose = nop }()
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}))
defer ts.Close()
ctx, cancel := context.WithCancel(context.Background())
// closed when Do enters select case <-ctx.Done()
enteredDonePath := make(chan struct{})
testHookContextDoneBeforeHeaders = func() {
close(enteredDonePath)
}
testHookDoReturned = func() {
// We now have the result (the Flush'd headers) at least,
// so we can cancel the request.
cancel()
// But block the client.Do goroutine from sending
// until Do enters into the <-ctx.Done() path, since
// otherwise if both channels are readable, select
// picks a random one.
<-enteredDonePath
}
sawBodyClose := make(chan struct{})
testHookDidBodyClose = func() { close(sawBodyClose) }
tr := &http.Transport{}
defer tr.CloseIdleConnections()
c := &http.Client{Transport: tr}
req, _ := http.NewRequest("GET", ts.URL, nil)
_, doErr := Do(ctx, c, req)
select {
case <-sawBodyClose:
case <-time.After(5 * time.Second):
t.Fatal("timeout waiting for body to close")
}
if doErr != ctx.Err() {
t.Errorf("Do error = %v; want %v", doErr, ctx.Err())
}
}
type noteCloseConn struct {
net.Conn
onceClose sync.Once
closefn func()
}
func (c *noteCloseConn) Close() error {
c.onceClose.Do(c.closefn)
return c.Conn.Close()
}

View File

@ -1,105 +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.
// +build !plan9
package ctxhttp
import (
"io"
"io/ioutil"
"net/http"
"net/http/httptest"
"testing"
"time"
"golang.org/x/net/context"
)
const (
requestDuration = 100 * time.Millisecond
requestBody = "ok"
)
func okHandler(w http.ResponseWriter, r *http.Request) {
time.Sleep(requestDuration)
io.WriteString(w, requestBody)
}
func TestNoTimeout(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(okHandler))
defer ts.Close()
ctx := context.Background()
res, err := Get(ctx, nil, ts.URL)
if err != nil {
t.Fatal(err)
}
defer res.Body.Close()
slurp, err := ioutil.ReadAll(res.Body)
if err != nil {
t.Fatal(err)
}
if string(slurp) != requestBody {
t.Errorf("body = %q; want %q", slurp, requestBody)
}
}
func TestCancelBeforeHeaders(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
blockServer := make(chan struct{})
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
cancel()
<-blockServer
io.WriteString(w, requestBody)
}))
defer ts.Close()
defer close(blockServer)
res, err := Get(ctx, nil, ts.URL)
if err == nil {
res.Body.Close()
t.Fatal("Get returned unexpected nil error")
}
if err != context.Canceled {
t.Errorf("err = %v; want %v", err, context.Canceled)
}
}
func TestCancelAfterHangingRequest(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.(http.Flusher).Flush()
<-w.(http.CloseNotifier).CloseNotify()
}))
defer ts.Close()
ctx, cancel := context.WithCancel(context.Background())
resp, err := Get(ctx, nil, ts.URL)
if err != nil {
t.Fatalf("unexpected error in Get: %v", err)
}
// Cancel befer reading the body.
// Reading Request.Body should fail, since the request was
// canceled before anything was written.
cancel()
done := make(chan struct{})
go func() {
b, err := ioutil.ReadAll(resp.Body)
if len(b) != 0 || err == nil {
t.Errorf(`Read got (%q, %v); want ("", error)`, b, err)
}
close(done)
}()
select {
case <-time.After(1 * time.Second):
t.Errorf("Test timed out")
case <-done:
}
}

View File

@ -1,31 +0,0 @@
// Copyright 2014 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 context_test
import (
"fmt"
"time"
"golang.org/x/net/context"
)
// This example passes a context with a timeout to tell a blocking function that
// it should abandon its work after the timeout elapses.
func ExampleWithTimeout() {
// Pass a context with a timeout to tell a blocking function that it
// should abandon its work after the timeout elapses.
ctx, cancel := context.WithTimeout(context.Background(), 50*time.Millisecond)
defer cancel()
select {
case <-time.After(1 * time.Second):
fmt.Println("overslept")
case <-ctx.Done():
fmt.Println(ctx.Err()) // prints "context deadline exceeded"
}
// Output:
// context deadline exceeded
}

View File

@ -1,67 +0,0 @@
// Copyright 2016 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 errgroup provides synchronization, error propagation, and Context
// cancelation for groups of goroutines working on subtasks of a common task.
package errgroup
import (
"sync"
"golang.org/x/net/context"
)
// A Group is a collection of goroutines working on subtasks that are part of
// the same overall task.
//
// A zero Group is valid and does not cancel on error.
type Group struct {
cancel func()
wg sync.WaitGroup
errOnce sync.Once
err error
}
// WithContext returns a new Group and an associated Context derived from ctx.
//
// The derived Context is canceled the first time a function passed to Go
// returns a non-nil error or the first time Wait returns, whichever occurs
// first.
func WithContext(ctx context.Context) (*Group, context.Context) {
ctx, cancel := context.WithCancel(ctx)
return &Group{cancel: cancel}, ctx
}
// Wait blocks until all function calls from the Go method have returned, then
// returns the first non-nil error (if any) from them.
func (g *Group) Wait() error {
g.wg.Wait()
if g.cancel != nil {
g.cancel()
}
return g.err
}
// Go calls the given function in a new goroutine.
//
// The first call to return a non-nil error cancels the group; its error will be
// returned by Wait.
func (g *Group) Go(f func() error) {
g.wg.Add(1)
go func() {
defer g.wg.Done()
if err := f(); err != nil {
g.errOnce.Do(func() {
g.err = err
if g.cancel != nil {
g.cancel()
}
})
}
}()
}

View File

@ -1,101 +0,0 @@
// Copyright 2016 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 errgroup_test
import (
"crypto/md5"
"fmt"
"io/ioutil"
"log"
"os"
"path/filepath"
"golang.org/x/net/context"
"golang.org/x/sync/errgroup"
)
// Pipeline demonstrates the use of a Group to implement a multi-stage
// pipeline: a version of the MD5All function with bounded parallelism from
// https://blog.golang.org/pipelines.
func ExampleGroup_pipeline() {
m, err := MD5All(context.Background(), ".")
if err != nil {
log.Fatal(err)
}
for k, sum := range m {
fmt.Printf("%s:\t%x\n", k, sum)
}
}
type result struct {
path string
sum [md5.Size]byte
}
// MD5All reads all the files in the file tree rooted at root and returns a map
// from file path to the MD5 sum of the file's contents. If the directory walk
// fails or any read operation fails, MD5All returns an error.
func MD5All(ctx context.Context, root string) (map[string][md5.Size]byte, error) {
// ctx is canceled when g.Wait() returns. When this version of MD5All returns
// - even in case of error! - we know that all of the goroutines have finished
// and the memory they were using can be garbage-collected.
g, ctx := errgroup.WithContext(ctx)
paths := make(chan string)
g.Go(func() error {
defer close(paths)
return filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if !info.Mode().IsRegular() {
return nil
}
select {
case paths <- path:
case <-ctx.Done():
return ctx.Err()
}
return nil
})
})
// Start a fixed number of goroutines to read and digest files.
c := make(chan result)
const numDigesters = 20
for i := 0; i < numDigesters; i++ {
g.Go(func() error {
for path := range paths {
data, err := ioutil.ReadFile(path)
if err != nil {
return err
}
select {
case c <- result{path, md5.Sum(data)}:
case <-ctx.Done():
return ctx.Err()
}
}
return nil
})
}
go func() {
g.Wait()
close(c)
}()
m := make(map[string][md5.Size]byte)
for r := range c {
m[r.path] = r.sum
}
// Check whether any of the goroutines failed. Since g is accumulating the
// errors, we don't need to send them (or check for them) in the individual
// results sent on the channel.
if err := g.Wait(); err != nil {
return nil, err
}
return m, nil
}

View File

@ -1,176 +0,0 @@
// Copyright 2016 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 errgroup_test
import (
"errors"
"fmt"
"net/http"
"os"
"testing"
"golang.org/x/net/context"
"golang.org/x/sync/errgroup"
)
var (
Web = fakeSearch("web")
Image = fakeSearch("image")
Video = fakeSearch("video")
)
type Result string
type Search func(ctx context.Context, query string) (Result, error)
func fakeSearch(kind string) Search {
return func(_ context.Context, query string) (Result, error) {
return Result(fmt.Sprintf("%s result for %q", kind, query)), nil
}
}
// JustErrors illustrates the use of a Group in place of a sync.WaitGroup to
// simplify goroutine counting and error handling. This example is derived from
// the sync.WaitGroup example at https://golang.org/pkg/sync/#example_WaitGroup.
func ExampleGroup_justErrors() {
var g errgroup.Group
var urls = []string{
"http://www.golang.org/",
"http://www.google.com/",
"http://www.somestupidname.com/",
}
for _, url := range urls {
// Launch a goroutine to fetch the URL.
url := url // https://golang.org/doc/faq#closures_and_goroutines
g.Go(func() error {
// Fetch the URL.
resp, err := http.Get(url)
if err == nil {
resp.Body.Close()
}
return err
})
}
// Wait for all HTTP fetches to complete.
if err := g.Wait(); err == nil {
fmt.Println("Successfully fetched all URLs.")
}
}
// Parallel illustrates the use of a Group for synchronizing a simple parallel
// task: the "Google Search 2.0" function from
// https://talks.golang.org/2012/concurrency.slide#46, augmented with a Context
// and error-handling.
func ExampleGroup_parallel() {
Google := func(ctx context.Context, query string) ([]Result, error) {
g, ctx := errgroup.WithContext(ctx)
searches := []Search{Web, Image, Video}
results := make([]Result, len(searches))
for i, search := range searches {
i, search := i, search // https://golang.org/doc/faq#closures_and_goroutines
g.Go(func() error {
result, err := search(ctx, query)
if err == nil {
results[i] = result
}
return err
})
}
if err := g.Wait(); err != nil {
return nil, err
}
return results, nil
}
results, err := Google(context.Background(), "golang")
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
for _, result := range results {
fmt.Println(result)
}
// Output:
// web result for "golang"
// image result for "golang"
// video result for "golang"
}
func TestZeroGroup(t *testing.T) {
err1 := errors.New("errgroup_test: 1")
err2 := errors.New("errgroup_test: 2")
cases := []struct {
errs []error
}{
{errs: []error{}},
{errs: []error{nil}},
{errs: []error{err1}},
{errs: []error{err1, nil}},
{errs: []error{err1, nil, err2}},
}
for _, tc := range cases {
var g errgroup.Group
var firstErr error
for i, err := range tc.errs {
err := err
g.Go(func() error { return err })
if firstErr == nil && err != nil {
firstErr = err
}
if gErr := g.Wait(); gErr != firstErr {
t.Errorf("after %T.Go(func() error { return err }) for err in %v\n"+
"g.Wait() = %v; want %v",
g, tc.errs[:i+1], err, firstErr)
}
}
}
}
func TestWithContext(t *testing.T) {
errDoom := errors.New("group_test: doomed")
cases := []struct {
errs []error
want error
}{
{want: nil},
{errs: []error{nil}, want: nil},
{errs: []error{errDoom}, want: errDoom},
{errs: []error{errDoom, nil}, want: errDoom},
}
for _, tc := range cases {
g, ctx := errgroup.WithContext(context.Background())
for _, err := range tc.errs {
err := err
g.Go(func() error { return err })
}
if err := g.Wait(); err != tc.want {
t.Errorf("after %T.Go(func() error { return err }) for err in %v\n"+
"g.Wait() = %v; want %v",
g, tc.errs, err, tc.want)
}
canceled := false
select {
case <-ctx.Done():
canceled = true
default:
}
if !canceled {
t.Errorf("after %T.Go(func() error { return err }) for err in %v\n"+
"ctx.Done() was not closed",
g, tc.errs)
}
}
}