diff --git a/vendor/github.com/jcmturner/gofork/LICENSE b/vendor/github.com/jcmturner/gofork/LICENSE
new file mode 100644
index 0000000..6a66aea
--- /dev/null
+++ b/vendor/github.com/jcmturner/gofork/LICENSE
@@ -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.
diff --git a/vendor/github.com/jcmturner/gofork/encoding/asn1/README.md b/vendor/github.com/jcmturner/gofork/encoding/asn1/README.md
new file mode 100644
index 0000000..66a2a8c
--- /dev/null
+++ b/vendor/github.com/jcmturner/gofork/encoding/asn1/README.md
@@ -0,0 +1,5 @@
+This is a temporary repository that will be removed when the issues below are fixed in the core golang code.
+
+## Issues
+* [encoding/asn1: cannot marshal into a GeneralString](https://github.com/golang/go/issues/18832)
+* [encoding/asn1: cannot marshal into slice of strings and pass stringtype parameter tags to members](https://github.com/golang/go/issues/18834)
\ No newline at end of file
diff --git a/vendor/github.com/jcmturner/gofork/encoding/asn1/asn1.go b/vendor/github.com/jcmturner/gofork/encoding/asn1/asn1.go
new file mode 100644
index 0000000..f1bb767
--- /dev/null
+++ b/vendor/github.com/jcmturner/gofork/encoding/asn1/asn1.go
@@ -0,0 +1,1003 @@
+// Copyright 2009 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 asn1 implements parsing of DER-encoded ASN.1 data structures,
+// as defined in ITU-T Rec X.690.
+//
+// See also ``A Layman's Guide to a Subset of ASN.1, BER, and DER,''
+// http://luca.ntop.org/Teaching/Appunti/asn1.html.
+package asn1
+
+// ASN.1 is a syntax for specifying abstract objects and BER, DER, PER, XER etc
+// are different encoding formats for those objects. Here, we'll be dealing
+// with DER, the Distinguished Encoding Rules. DER is used in X.509 because
+// it's fast to parse and, unlike BER, has a unique encoding for every object.
+// When calculating hashes over objects, it's important that the resulting
+// bytes be the same at both ends and DER removes this margin of error.
+//
+// ASN.1 is very complex and this package doesn't attempt to implement
+// everything by any means.
+
+import (
+	"errors"
+	"fmt"
+	"math/big"
+	"reflect"
+	"strconv"
+	"time"
+	"unicode/utf8"
+)
+
+// A StructuralError suggests that the ASN.1 data is valid, but the Go type
+// which is receiving it doesn't match.
+type StructuralError struct {
+	Msg string
+}
+
+func (e StructuralError) Error() string { return "asn1: structure error: " + e.Msg }
+
+// A SyntaxError suggests that the ASN.1 data is invalid.
+type SyntaxError struct {
+	Msg string
+}
+
+func (e SyntaxError) Error() string { return "asn1: syntax error: " + e.Msg }
+
+// We start by dealing with each of the primitive types in turn.
+
+// BOOLEAN
+
+func parseBool(bytes []byte) (ret bool, err error) {
+	if len(bytes) != 1 {
+		err = SyntaxError{"invalid boolean"}
+		return
+	}
+
+	// DER demands that "If the encoding represents the boolean value TRUE,
+	// its single contents octet shall have all eight bits set to one."
+	// Thus only 0 and 255 are valid encoded values.
+	switch bytes[0] {
+	case 0:
+		ret = false
+	case 0xff:
+		ret = true
+	default:
+		err = SyntaxError{"invalid boolean"}
+	}
+
+	return
+}
+
+// INTEGER
+
+// checkInteger returns nil if the given bytes are a valid DER-encoded
+// INTEGER and an error otherwise.
+func checkInteger(bytes []byte) error {
+	if len(bytes) == 0 {
+		return StructuralError{"empty integer"}
+	}
+	if len(bytes) == 1 {
+		return nil
+	}
+	if (bytes[0] == 0 && bytes[1]&0x80 == 0) || (bytes[0] == 0xff && bytes[1]&0x80 == 0x80) {
+		return StructuralError{"integer not minimally-encoded"}
+	}
+	return nil
+}
+
+// parseInt64 treats the given bytes as a big-endian, signed integer and
+// returns the result.
+func parseInt64(bytes []byte) (ret int64, err error) {
+	err = checkInteger(bytes)
+	if err != nil {
+		return
+	}
+	if len(bytes) > 8 {
+		// We'll overflow an int64 in this case.
+		err = StructuralError{"integer too large"}
+		return
+	}
+	for bytesRead := 0; bytesRead < len(bytes); bytesRead++ {
+		ret <<= 8
+		ret |= int64(bytes[bytesRead])
+	}
+
+	// Shift up and down in order to sign extend the result.
+	ret <<= 64 - uint8(len(bytes))*8
+	ret >>= 64 - uint8(len(bytes))*8
+	return
+}
+
+// parseInt treats the given bytes as a big-endian, signed integer and returns
+// the result.
+func parseInt32(bytes []byte) (int32, error) {
+	if err := checkInteger(bytes); err != nil {
+		return 0, err
+	}
+	ret64, err := parseInt64(bytes)
+	if err != nil {
+		return 0, err
+	}
+	if ret64 != int64(int32(ret64)) {
+		return 0, StructuralError{"integer too large"}
+	}
+	return int32(ret64), nil
+}
+
+var bigOne = big.NewInt(1)
+
+// parseBigInt treats the given bytes as a big-endian, signed integer and returns
+// the result.
+func parseBigInt(bytes []byte) (*big.Int, error) {
+	if err := checkInteger(bytes); err != nil {
+		return nil, err
+	}
+	ret := new(big.Int)
+	if len(bytes) > 0 && bytes[0]&0x80 == 0x80 {
+		// This is a negative number.
+		notBytes := make([]byte, len(bytes))
+		for i := range notBytes {
+			notBytes[i] = ^bytes[i]
+		}
+		ret.SetBytes(notBytes)
+		ret.Add(ret, bigOne)
+		ret.Neg(ret)
+		return ret, nil
+	}
+	ret.SetBytes(bytes)
+	return ret, nil
+}
+
+// BIT STRING
+
+// BitString is the structure to use when you want an ASN.1 BIT STRING type. A
+// bit string is padded up to the nearest byte in memory and the number of
+// valid bits is recorded. Padding bits will be zero.
+type BitString struct {
+	Bytes     []byte // bits packed into bytes.
+	BitLength int    // length in bits.
+}
+
+// At returns the bit at the given index. If the index is out of range it
+// returns false.
+func (b BitString) At(i int) int {
+	if i < 0 || i >= b.BitLength {
+		return 0
+	}
+	x := i / 8
+	y := 7 - uint(i%8)
+	return int(b.Bytes[x]>>y) & 1
+}
+
+// RightAlign returns a slice where the padding bits are at the beginning. The
+// slice may share memory with the BitString.
+func (b BitString) RightAlign() []byte {
+	shift := uint(8 - (b.BitLength % 8))
+	if shift == 8 || len(b.Bytes) == 0 {
+		return b.Bytes
+	}
+
+	a := make([]byte, len(b.Bytes))
+	a[0] = b.Bytes[0] >> shift
+	for i := 1; i < len(b.Bytes); i++ {
+		a[i] = b.Bytes[i-1] << (8 - shift)
+		a[i] |= b.Bytes[i] >> shift
+	}
+
+	return a
+}
+
+// parseBitString parses an ASN.1 bit string from the given byte slice and returns it.
+func parseBitString(bytes []byte) (ret BitString, err error) {
+	if len(bytes) == 0 {
+		err = SyntaxError{"zero length BIT STRING"}
+		return
+	}
+	paddingBits := int(bytes[0])
+	if paddingBits > 7 ||
+		len(bytes) == 1 && paddingBits > 0 ||
+		bytes[len(bytes)-1]&((1<<bytes[0])-1) != 0 {
+		err = SyntaxError{"invalid padding bits in BIT STRING"}
+		return
+	}
+	ret.BitLength = (len(bytes)-1)*8 - paddingBits
+	ret.Bytes = bytes[1:]
+	return
+}
+
+// OBJECT IDENTIFIER
+
+// An ObjectIdentifier represents an ASN.1 OBJECT IDENTIFIER.
+type ObjectIdentifier []int
+
+// Equal reports whether oi and other represent the same identifier.
+func (oi ObjectIdentifier) Equal(other ObjectIdentifier) bool {
+	if len(oi) != len(other) {
+		return false
+	}
+	for i := 0; i < len(oi); i++ {
+		if oi[i] != other[i] {
+			return false
+		}
+	}
+
+	return true
+}
+
+func (oi ObjectIdentifier) String() string {
+	var s string
+
+	for i, v := range oi {
+		if i > 0 {
+			s += "."
+		}
+		s += strconv.Itoa(v)
+	}
+
+	return s
+}
+
+// parseObjectIdentifier parses an OBJECT IDENTIFIER from the given bytes and
+// returns it. An object identifier is a sequence of variable length integers
+// that are assigned in a hierarchy.
+func parseObjectIdentifier(bytes []byte) (s []int, err error) {
+	if len(bytes) == 0 {
+		err = SyntaxError{"zero length OBJECT IDENTIFIER"}
+		return
+	}
+
+	// In the worst case, we get two elements from the first byte (which is
+	// encoded differently) and then every varint is a single byte long.
+	s = make([]int, len(bytes)+1)
+
+	// The first varint is 40*value1 + value2:
+	// According to this packing, value1 can take the values 0, 1 and 2 only.
+	// When value1 = 0 or value1 = 1, then value2 is <= 39. When value1 = 2,
+	// then there are no restrictions on value2.
+	v, offset, err := parseBase128Int(bytes, 0)
+	if err != nil {
+		return
+	}
+	if v < 80 {
+		s[0] = v / 40
+		s[1] = v % 40
+	} else {
+		s[0] = 2
+		s[1] = v - 80
+	}
+
+	i := 2
+	for ; offset < len(bytes); i++ {
+		v, offset, err = parseBase128Int(bytes, offset)
+		if err != nil {
+			return
+		}
+		s[i] = v
+	}
+	s = s[0:i]
+	return
+}
+
+// ENUMERATED
+
+// An Enumerated is represented as a plain int.
+type Enumerated int
+
+// FLAG
+
+// A Flag accepts any data and is set to true if present.
+type Flag bool
+
+// parseBase128Int parses a base-128 encoded int from the given offset in the
+// given byte slice. It returns the value and the new offset.
+func parseBase128Int(bytes []byte, initOffset int) (ret, offset int, err error) {
+	offset = initOffset
+	for shifted := 0; offset < len(bytes); shifted++ {
+		if shifted == 4 {
+			err = StructuralError{"base 128 integer too large"}
+			return
+		}
+		ret <<= 7
+		b := bytes[offset]
+		ret |= int(b & 0x7f)
+		offset++
+		if b&0x80 == 0 {
+			return
+		}
+	}
+	err = SyntaxError{"truncated base 128 integer"}
+	return
+}
+
+// UTCTime
+
+func parseUTCTime(bytes []byte) (ret time.Time, err error) {
+	s := string(bytes)
+
+	formatStr := "0601021504Z0700"
+	ret, err = time.Parse(formatStr, s)
+	if err != nil {
+		formatStr = "060102150405Z0700"
+		ret, err = time.Parse(formatStr, s)
+	}
+	if err != nil {
+		return
+	}
+
+	if serialized := ret.Format(formatStr); serialized != s {
+		err = fmt.Errorf("asn1: time did not serialize back to the original value and may be invalid: given %q, but serialized as %q", s, serialized)
+		return
+	}
+
+	if ret.Year() >= 2050 {
+		// UTCTime only encodes times prior to 2050. See https://tools.ietf.org/html/rfc5280#section-4.1.2.5.1
+		ret = ret.AddDate(-100, 0, 0)
+	}
+
+	return
+}
+
+// parseGeneralizedTime parses the GeneralizedTime from the given byte slice
+// and returns the resulting time.
+func parseGeneralizedTime(bytes []byte) (ret time.Time, err error) {
+	const formatStr = "20060102150405Z0700"
+	s := string(bytes)
+
+	if ret, err = time.Parse(formatStr, s); err != nil {
+		return
+	}
+
+	if serialized := ret.Format(formatStr); serialized != s {
+		err = fmt.Errorf("asn1: time did not serialize back to the original value and may be invalid: given %q, but serialized as %q", s, serialized)
+	}
+
+	return
+}
+
+// PrintableString
+
+// parsePrintableString parses a ASN.1 PrintableString from the given byte
+// array and returns it.
+func parsePrintableString(bytes []byte) (ret string, err error) {
+	for _, b := range bytes {
+		if !isPrintable(b) {
+			err = SyntaxError{"PrintableString contains invalid character"}
+			return
+		}
+	}
+	ret = string(bytes)
+	return
+}
+
+// isPrintable reports whether the given b is in the ASN.1 PrintableString set.
+func isPrintable(b byte) bool {
+	return 'a' <= b && b <= 'z' ||
+		'A' <= b && b <= 'Z' ||
+		'0' <= b && b <= '9' ||
+		'\'' <= b && b <= ')' ||
+		'+' <= b && b <= '/' ||
+		b == ' ' ||
+		b == ':' ||
+		b == '=' ||
+		b == '?' ||
+		// This is technically not allowed in a PrintableString.
+		// However, x509 certificates with wildcard strings don't
+		// always use the correct string type so we permit it.
+		b == '*'
+}
+
+// IA5String
+
+// parseIA5String parses a ASN.1 IA5String (ASCII string) from the given
+// byte slice and returns it.
+func parseIA5String(bytes []byte) (ret string, err error) {
+	for _, b := range bytes {
+		if b >= utf8.RuneSelf {
+			err = SyntaxError{"IA5String contains invalid character"}
+			return
+		}
+	}
+	ret = string(bytes)
+	return
+}
+
+// T61String
+
+// parseT61String parses a ASN.1 T61String (8-bit clean string) from the given
+// byte slice and returns it.
+func parseT61String(bytes []byte) (ret string, err error) {
+	return string(bytes), nil
+}
+
+// UTF8String
+
+// parseUTF8String parses a ASN.1 UTF8String (raw UTF-8) from the given byte
+// array and returns it.
+func parseUTF8String(bytes []byte) (ret string, err error) {
+	if !utf8.Valid(bytes) {
+		return "", errors.New("asn1: invalid UTF-8 string")
+	}
+	return string(bytes), nil
+}
+
+// A RawValue represents an undecoded ASN.1 object.
+type RawValue struct {
+	Class, Tag int
+	IsCompound bool
+	Bytes      []byte
+	FullBytes  []byte // includes the tag and length
+}
+
+// RawContent is used to signal that the undecoded, DER data needs to be
+// preserved for a struct. To use it, the first field of the struct must have
+// this type. It's an error for any of the other fields to have this type.
+type RawContent []byte
+
+// Tagging
+
+// parseTagAndLength parses an ASN.1 tag and length pair from the given offset
+// into a byte slice. It returns the parsed data and the new offset. SET and
+// SET OF (tag 17) are mapped to SEQUENCE and SEQUENCE OF (tag 16) since we
+// don't distinguish between ordered and unordered objects in this code.
+func parseTagAndLength(bytes []byte, initOffset int) (ret tagAndLength, offset int, err error) {
+	offset = initOffset
+	// parseTagAndLength should not be called without at least a single
+	// byte to read. Thus this check is for robustness:
+	if offset >= len(bytes) {
+		err = errors.New("asn1: internal error in parseTagAndLength")
+		return
+	}
+	b := bytes[offset]
+	offset++
+	ret.class = int(b >> 6)
+	ret.isCompound = b&0x20 == 0x20
+	ret.tag = int(b & 0x1f)
+
+	// If the bottom five bits are set, then the tag number is actually base 128
+	// encoded afterwards
+	if ret.tag == 0x1f {
+		ret.tag, offset, err = parseBase128Int(bytes, offset)
+		if err != nil {
+			return
+		}
+		// Tags should be encoded in minimal form.
+		if ret.tag < 0x1f {
+			err = SyntaxError{"non-minimal tag"}
+			return
+		}
+	}
+	if offset >= len(bytes) {
+		err = SyntaxError{"truncated tag or length"}
+		return
+	}
+	b = bytes[offset]
+	offset++
+	if b&0x80 == 0 {
+		// The length is encoded in the bottom 7 bits.
+		ret.length = int(b & 0x7f)
+	} else {
+		// Bottom 7 bits give the number of length bytes to follow.
+		numBytes := int(b & 0x7f)
+		if numBytes == 0 {
+			err = SyntaxError{"indefinite length found (not DER)"}
+			return
+		}
+		ret.length = 0
+		for i := 0; i < numBytes; i++ {
+			if offset >= len(bytes) {
+				err = SyntaxError{"truncated tag or length"}
+				return
+			}
+			b = bytes[offset]
+			offset++
+			if ret.length >= 1<<23 {
+				// We can't shift ret.length up without
+				// overflowing.
+				err = StructuralError{"length too large"}
+				return
+			}
+			ret.length <<= 8
+			ret.length |= int(b)
+			if ret.length == 0 {
+				// DER requires that lengths be minimal.
+				err = StructuralError{"superfluous leading zeros in length"}
+				return
+			}
+		}
+		// Short lengths must be encoded in short form.
+		if ret.length < 0x80 {
+			err = StructuralError{"non-minimal length"}
+			return
+		}
+	}
+
+	return
+}
+
+// parseSequenceOf is used for SEQUENCE OF and SET OF values. It tries to parse
+// a number of ASN.1 values from the given byte slice and returns them as a
+// slice of Go values of the given type.
+func parseSequenceOf(bytes []byte, sliceType reflect.Type, elemType reflect.Type) (ret reflect.Value, err error) {
+	expectedTag, compoundType, ok := getUniversalType(elemType)
+	if !ok {
+		err = StructuralError{"unknown Go type for slice"}
+		return
+	}
+
+	// First we iterate over the input and count the number of elements,
+	// checking that the types are correct in each case.
+	numElements := 0
+	for offset := 0; offset < len(bytes); {
+		var t tagAndLength
+		t, offset, err = parseTagAndLength(bytes, offset)
+		if err != nil {
+			return
+		}
+		switch t.tag {
+		case TagIA5String, TagGeneralString, TagT61String, TagUTF8String:
+			// We pretend that various other string types are
+			// PRINTABLE STRINGs so that a sequence of them can be
+			// parsed into a []string.
+			t.tag = TagPrintableString
+		case TagGeneralizedTime, TagUTCTime:
+			// Likewise, both time types are treated the same.
+			t.tag = TagUTCTime
+		}
+
+		if t.class != ClassUniversal || t.isCompound != compoundType || t.tag != expectedTag {
+			err = StructuralError{"sequence tag mismatch"}
+			return
+		}
+		if invalidLength(offset, t.length, len(bytes)) {
+			err = SyntaxError{"truncated sequence"}
+			return
+		}
+		offset += t.length
+		numElements++
+	}
+	ret = reflect.MakeSlice(sliceType, numElements, numElements)
+	params := fieldParameters{}
+	offset := 0
+	for i := 0; i < numElements; i++ {
+		offset, err = parseField(ret.Index(i), bytes, offset, params)
+		if err != nil {
+			return
+		}
+	}
+	return
+}
+
+var (
+	bitStringType        = reflect.TypeOf(BitString{})
+	objectIdentifierType = reflect.TypeOf(ObjectIdentifier{})
+	enumeratedType       = reflect.TypeOf(Enumerated(0))
+	flagType             = reflect.TypeOf(Flag(false))
+	timeType             = reflect.TypeOf(time.Time{})
+	rawValueType         = reflect.TypeOf(RawValue{})
+	rawContentsType      = reflect.TypeOf(RawContent(nil))
+	bigIntType           = reflect.TypeOf(new(big.Int))
+)
+
+// invalidLength returns true iff offset + length > sliceLength, or if the
+// addition would overflow.
+func invalidLength(offset, length, sliceLength int) bool {
+	return offset+length < offset || offset+length > sliceLength
+}
+
+// parseField is the main parsing function. Given a byte slice and an offset
+// into the array, it will try to parse a suitable ASN.1 value out and store it
+// in the given Value.
+func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParameters) (offset int, err error) {
+	offset = initOffset
+	fieldType := v.Type()
+
+	// If we have run out of data, it may be that there are optional elements at the end.
+	if offset == len(bytes) {
+		if !setDefaultValue(v, params) {
+			err = SyntaxError{"sequence truncated"}
+		}
+		return
+	}
+
+	// Deal with raw values.
+	if fieldType == rawValueType {
+		var t tagAndLength
+		t, offset, err = parseTagAndLength(bytes, offset)
+		if err != nil {
+			return
+		}
+		if invalidLength(offset, t.length, len(bytes)) {
+			err = SyntaxError{"data truncated"}
+			return
+		}
+		result := RawValue{t.class, t.tag, t.isCompound, bytes[offset : offset+t.length], bytes[initOffset : offset+t.length]}
+		offset += t.length
+		v.Set(reflect.ValueOf(result))
+		return
+	}
+
+	// Deal with the ANY type.
+	if ifaceType := fieldType; ifaceType.Kind() == reflect.Interface && ifaceType.NumMethod() == 0 {
+		var t tagAndLength
+		t, offset, err = parseTagAndLength(bytes, offset)
+		if err != nil {
+			return
+		}
+		if invalidLength(offset, t.length, len(bytes)) {
+			err = SyntaxError{"data truncated"}
+			return
+		}
+		var result interface{}
+		if !t.isCompound && t.class == ClassUniversal {
+			innerBytes := bytes[offset : offset+t.length]
+			switch t.tag {
+			case TagPrintableString:
+				result, err = parsePrintableString(innerBytes)
+			case TagIA5String:
+				result, err = parseIA5String(innerBytes)
+			// jtasn1 addition of following case
+			case TagGeneralString:
+				result, err = parseIA5String(innerBytes)
+			case TagT61String:
+				result, err = parseT61String(innerBytes)
+			case TagUTF8String:
+				result, err = parseUTF8String(innerBytes)
+			case TagInteger:
+				result, err = parseInt64(innerBytes)
+			case TagBitString:
+				result, err = parseBitString(innerBytes)
+			case TagOID:
+				result, err = parseObjectIdentifier(innerBytes)
+			case TagUTCTime:
+				result, err = parseUTCTime(innerBytes)
+			case TagGeneralizedTime:
+				result, err = parseGeneralizedTime(innerBytes)
+			case TagOctetString:
+				result = innerBytes
+			default:
+				// If we don't know how to handle the type, we just leave Value as nil.
+			}
+		}
+		offset += t.length
+		if err != nil {
+			return
+		}
+		if result != nil {
+			v.Set(reflect.ValueOf(result))
+		}
+		return
+	}
+	universalTag, compoundType, ok1 := getUniversalType(fieldType)
+	if !ok1 {
+		err = StructuralError{fmt.Sprintf("unknown Go type: %v", fieldType)}
+		return
+	}
+
+	t, offset, err := parseTagAndLength(bytes, offset)
+	if err != nil {
+		return
+	}
+	if params.explicit {
+		expectedClass := ClassContextSpecific
+		if params.application {
+			expectedClass = ClassApplication
+		}
+		if offset == len(bytes) {
+			err = StructuralError{"explicit tag has no child"}
+			return
+		}
+		if t.class == expectedClass && t.tag == *params.tag && (t.length == 0 || t.isCompound) {
+			if t.length > 0 {
+				t, offset, err = parseTagAndLength(bytes, offset)
+				if err != nil {
+					return
+				}
+			} else {
+				if fieldType != flagType {
+					err = StructuralError{"zero length explicit tag was not an asn1.Flag"}
+					return
+				}
+				v.SetBool(true)
+				return
+			}
+		} else {
+			// The tags didn't match, it might be an optional element.
+			ok := setDefaultValue(v, params)
+			if ok {
+				offset = initOffset
+			} else {
+				err = StructuralError{"explicitly tagged member didn't match"}
+			}
+			return
+		}
+	}
+
+	// Special case for strings: all the ASN.1 string types map to the Go
+	// type string. getUniversalType returns the tag for PrintableString
+	// when it sees a string, so if we see a different string type on the
+	// wire, we change the universal type to match.
+	if universalTag == TagPrintableString {
+		if t.class == ClassUniversal {
+			switch t.tag {
+			case TagIA5String, TagGeneralString, TagT61String, TagUTF8String:
+				universalTag = t.tag
+			}
+		} else if params.stringType != 0 {
+			universalTag = params.stringType
+		}
+	}
+
+	// Special case for time: UTCTime and GeneralizedTime both map to the
+	// Go type time.Time.
+	if universalTag == TagUTCTime && t.tag == TagGeneralizedTime && t.class == ClassUniversal {
+		universalTag = TagGeneralizedTime
+	}
+
+	if params.set {
+		universalTag = TagSet
+	}
+
+	expectedClass := ClassUniversal
+	expectedTag := universalTag
+
+	if !params.explicit && params.tag != nil {
+		expectedClass = ClassContextSpecific
+		expectedTag = *params.tag
+	}
+
+	if !params.explicit && params.application && params.tag != nil {
+		expectedClass = ClassApplication
+		expectedTag = *params.tag
+	}
+
+	// We have unwrapped any explicit tagging at this point.
+	if t.class != expectedClass || t.tag != expectedTag || t.isCompound != compoundType {
+		// Tags don't match. Again, it could be an optional element.
+		ok := setDefaultValue(v, params)
+		if ok {
+			offset = initOffset
+		} else {
+			err = StructuralError{fmt.Sprintf("tags don't match (%d vs %+v) %+v %s @%d", expectedTag, t, params, fieldType.Name(), offset)}
+		}
+		return
+	}
+	if invalidLength(offset, t.length, len(bytes)) {
+		err = SyntaxError{"data truncated"}
+		return
+	}
+	innerBytes := bytes[offset : offset+t.length]
+	offset += t.length
+
+	// We deal with the structures defined in this package first.
+	switch fieldType {
+	case objectIdentifierType:
+		newSlice, err1 := parseObjectIdentifier(innerBytes)
+		v.Set(reflect.MakeSlice(v.Type(), len(newSlice), len(newSlice)))
+		if err1 == nil {
+			reflect.Copy(v, reflect.ValueOf(newSlice))
+		}
+		err = err1
+		return
+	case bitStringType:
+		bs, err1 := parseBitString(innerBytes)
+		if err1 == nil {
+			v.Set(reflect.ValueOf(bs))
+		}
+		err = err1
+		return
+	case timeType:
+		var time time.Time
+		var err1 error
+		if universalTag == TagUTCTime {
+			time, err1 = parseUTCTime(innerBytes)
+		} else {
+			time, err1 = parseGeneralizedTime(innerBytes)
+		}
+		if err1 == nil {
+			v.Set(reflect.ValueOf(time))
+		}
+		err = err1
+		return
+	case enumeratedType:
+		parsedInt, err1 := parseInt32(innerBytes)
+		if err1 == nil {
+			v.SetInt(int64(parsedInt))
+		}
+		err = err1
+		return
+	case flagType:
+		v.SetBool(true)
+		return
+	case bigIntType:
+		parsedInt, err1 := parseBigInt(innerBytes)
+		if err1 == nil {
+			v.Set(reflect.ValueOf(parsedInt))
+		}
+		err = err1
+		return
+	}
+	switch val := v; val.Kind() {
+	case reflect.Bool:
+		parsedBool, err1 := parseBool(innerBytes)
+		if err1 == nil {
+			val.SetBool(parsedBool)
+		}
+		err = err1
+		return
+	case reflect.Int, reflect.Int32, reflect.Int64:
+		if val.Type().Size() == 4 {
+			parsedInt, err1 := parseInt32(innerBytes)
+			if err1 == nil {
+				val.SetInt(int64(parsedInt))
+			}
+			err = err1
+		} else {
+			parsedInt, err1 := parseInt64(innerBytes)
+			if err1 == nil {
+				val.SetInt(parsedInt)
+			}
+			err = err1
+		}
+		return
+	// TODO(dfc) Add support for the remaining integer types
+	case reflect.Struct:
+		structType := fieldType
+
+		if structType.NumField() > 0 &&
+			structType.Field(0).Type == rawContentsType {
+			bytes := bytes[initOffset:offset]
+			val.Field(0).Set(reflect.ValueOf(RawContent(bytes)))
+		}
+
+		innerOffset := 0
+		for i := 0; i < structType.NumField(); i++ {
+			field := structType.Field(i)
+			if i == 0 && field.Type == rawContentsType {
+				continue
+			}
+			innerOffset, err = parseField(val.Field(i), innerBytes, innerOffset, parseFieldParameters(field.Tag.Get("asn1")))
+			if err != nil {
+				return
+			}
+		}
+		// We allow extra bytes at the end of the SEQUENCE because
+		// adding elements to the end has been used in X.509 as the
+		// version numbers have increased.
+		return
+	case reflect.Slice:
+		sliceType := fieldType
+		if sliceType.Elem().Kind() == reflect.Uint8 {
+			val.Set(reflect.MakeSlice(sliceType, len(innerBytes), len(innerBytes)))
+			reflect.Copy(val, reflect.ValueOf(innerBytes))
+			return
+		}
+		newSlice, err1 := parseSequenceOf(innerBytes, sliceType, sliceType.Elem())
+		if err1 == nil {
+			val.Set(newSlice)
+		}
+		err = err1
+		return
+	case reflect.String:
+		var v string
+		switch universalTag {
+		case TagPrintableString:
+			v, err = parsePrintableString(innerBytes)
+		case TagIA5String:
+			v, err = parseIA5String(innerBytes)
+		case TagT61String:
+			v, err = parseT61String(innerBytes)
+		case TagUTF8String:
+			v, err = parseUTF8String(innerBytes)
+		case TagGeneralString:
+			// GeneralString is specified in ISO-2022/ECMA-35,
+			// A brief review suggests that it includes structures
+			// that allow the encoding to change midstring and
+			// such. We give up and pass it as an 8-bit string.
+			v, err = parseT61String(innerBytes)
+		default:
+			err = SyntaxError{fmt.Sprintf("internal error: unknown string type %d", universalTag)}
+		}
+		if err == nil {
+			val.SetString(v)
+		}
+		return
+	}
+	err = StructuralError{"unsupported: " + v.Type().String()}
+	return
+}
+
+// canHaveDefaultValue reports whether k is a Kind that we will set a default
+// value for. (A signed integer, essentially.)
+func canHaveDefaultValue(k reflect.Kind) bool {
+	switch k {
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return true
+	}
+
+	return false
+}
+
+// setDefaultValue is used to install a default value, from a tag string, into
+// a Value. It is successful if the field was optional, even if a default value
+// wasn't provided or it failed to install it into the Value.
+func setDefaultValue(v reflect.Value, params fieldParameters) (ok bool) {
+	if !params.optional {
+		return
+	}
+	ok = true
+	if params.defaultValue == nil {
+		return
+	}
+	if canHaveDefaultValue(v.Kind()) {
+		v.SetInt(*params.defaultValue)
+	}
+	return
+}
+
+// Unmarshal parses the DER-encoded ASN.1 data structure b
+// and uses the reflect package to fill in an arbitrary value pointed at by val.
+// Because Unmarshal uses the reflect package, the structs
+// being written to must use upper case field names.
+//
+// An ASN.1 INTEGER can be written to an int, int32, int64,
+// or *big.Int (from the math/big package).
+// If the encoded value does not fit in the Go type,
+// Unmarshal returns a parse error.
+//
+// An ASN.1 BIT STRING can be written to a BitString.
+//
+// An ASN.1 OCTET STRING can be written to a []byte.
+//
+// An ASN.1 OBJECT IDENTIFIER can be written to an
+// ObjectIdentifier.
+//
+// An ASN.1 ENUMERATED can be written to an Enumerated.
+//
+// An ASN.1 UTCTIME or GENERALIZEDTIME can be written to a time.Time.
+//
+// An ASN.1 PrintableString or IA5String can be written to a string.
+//
+// Any of the above ASN.1 values can be written to an interface{}.
+// The value stored in the interface has the corresponding Go type.
+// For integers, that type is int64.
+//
+// An ASN.1 SEQUENCE OF x or SET OF x can be written
+// to a slice if an x can be written to the slice's element type.
+//
+// An ASN.1 SEQUENCE or SET can be written to a struct
+// if each of the elements in the sequence can be
+// written to the corresponding element in the struct.
+//
+// The following tags on struct fields have special meaning to Unmarshal:
+//
+//	application	specifies that a APPLICATION tag is used
+//	default:x	sets the default value for optional integer fields
+//	explicit	specifies that an additional, explicit tag wraps the implicit one
+//	optional	marks the field as ASN.1 OPTIONAL
+//	set		causes a SET, rather than a SEQUENCE type to be expected
+//	tag:x		specifies the ASN.1 tag number; implies ASN.1 CONTEXT SPECIFIC
+//
+// If the type of the first field of a structure is RawContent then the raw
+// ASN1 contents of the struct will be stored in it.
+//
+// If the type name of a slice element ends with "SET" then it's treated as if
+// the "set" tag was set on it. This can be used with nested slices where a
+// struct tag cannot be given.
+//
+// Other ASN.1 types are not supported; if it encounters them,
+// Unmarshal returns a parse error.
+func Unmarshal(b []byte, val interface{}) (rest []byte, err error) {
+	return UnmarshalWithParams(b, val, "")
+}
+
+// UnmarshalWithParams allows field parameters to be specified for the
+// top-level element. The form of the params is the same as the field tags.
+func UnmarshalWithParams(b []byte, val interface{}, params string) (rest []byte, err error) {
+	v := reflect.ValueOf(val).Elem()
+	offset, err := parseField(v, b, 0, parseFieldParameters(params))
+	if err != nil {
+		return nil, err
+	}
+	return b[offset:], nil
+}
diff --git a/vendor/github.com/jcmturner/gofork/encoding/asn1/common.go b/vendor/github.com/jcmturner/gofork/encoding/asn1/common.go
new file mode 100644
index 0000000..7a9da49
--- /dev/null
+++ b/vendor/github.com/jcmturner/gofork/encoding/asn1/common.go
@@ -0,0 +1,173 @@
+// Copyright 2009 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 asn1
+
+import (
+	"reflect"
+	"strconv"
+	"strings"
+)
+
+// ASN.1 objects have metadata preceding them:
+//   the tag: the type of the object
+//   a flag denoting if this object is compound or not
+//   the class type: the namespace of the tag
+//   the length of the object, in bytes
+
+// Here are some standard tags and classes
+
+// ASN.1 tags represent the type of the following object.
+const (
+	TagBoolean         = 1
+	TagInteger         = 2
+	TagBitString       = 3
+	TagOctetString     = 4
+	TagOID             = 6
+	TagEnum            = 10
+	TagUTF8String      = 12
+	TagSequence        = 16
+	TagSet             = 17
+	TagPrintableString = 19
+	TagT61String       = 20
+	TagIA5String       = 22
+	TagUTCTime         = 23
+	TagGeneralizedTime = 24
+	TagGeneralString   = 27
+)
+
+// ASN.1 class types represent the namespace of the tag.
+const (
+	ClassUniversal       = 0
+	ClassApplication     = 1
+	ClassContextSpecific = 2
+	ClassPrivate         = 3
+)
+
+type tagAndLength struct {
+	class, tag, length int
+	isCompound         bool
+}
+
+// ASN.1 has IMPLICIT and EXPLICIT tags, which can be translated as "instead
+// of" and "in addition to". When not specified, every primitive type has a
+// default tag in the UNIVERSAL class.
+//
+// For example: a BIT STRING is tagged [UNIVERSAL 3] by default (although ASN.1
+// doesn't actually have a UNIVERSAL keyword). However, by saying [IMPLICIT
+// CONTEXT-SPECIFIC 42], that means that the tag is replaced by another.
+//
+// On the other hand, if it said [EXPLICIT CONTEXT-SPECIFIC 10], then an
+// /additional/ tag would wrap the default tag. This explicit tag will have the
+// compound flag set.
+//
+// (This is used in order to remove ambiguity with optional elements.)
+//
+// You can layer EXPLICIT and IMPLICIT tags to an arbitrary depth, however we
+// don't support that here. We support a single layer of EXPLICIT or IMPLICIT
+// tagging with tag strings on the fields of a structure.
+
+// fieldParameters is the parsed representation of tag string from a structure field.
+type fieldParameters struct {
+	optional     bool   // true iff the field is OPTIONAL
+	explicit     bool   // true iff an EXPLICIT tag is in use.
+	application  bool   // true iff an APPLICATION tag is in use.
+	defaultValue *int64 // a default value for INTEGER typed fields (maybe nil).
+	tag          *int   // the EXPLICIT or IMPLICIT tag (maybe nil).
+	stringType   int    // the string tag to use when marshaling.
+	timeType     int    // the time tag to use when marshaling.
+	set          bool   // true iff this should be encoded as a SET
+	omitEmpty    bool   // true iff this should be omitted if empty when marshaling.
+
+	// Invariants:
+	//   if explicit is set, tag is non-nil.
+}
+
+// Given a tag string with the format specified in the package comment,
+// parseFieldParameters will parse it into a fieldParameters structure,
+// ignoring unknown parts of the string.
+func parseFieldParameters(str string) (ret fieldParameters) {
+	for _, part := range strings.Split(str, ",") {
+		switch {
+		case part == "optional":
+			ret.optional = true
+		case part == "explicit":
+			ret.explicit = true
+			if ret.tag == nil {
+				ret.tag = new(int)
+			}
+		case part == "generalized":
+			ret.timeType = TagGeneralizedTime
+		case part == "utc":
+			ret.timeType = TagUTCTime
+		case part == "ia5":
+			ret.stringType = TagIA5String
+		// jtasn1 case below added
+		case part == "generalstring":
+			ret.stringType = TagGeneralString
+		case part == "printable":
+			ret.stringType = TagPrintableString
+		case part == "utf8":
+			ret.stringType = TagUTF8String
+		case strings.HasPrefix(part, "default:"):
+			i, err := strconv.ParseInt(part[8:], 10, 64)
+			if err == nil {
+				ret.defaultValue = new(int64)
+				*ret.defaultValue = i
+			}
+		case strings.HasPrefix(part, "tag:"):
+			i, err := strconv.Atoi(part[4:])
+			if err == nil {
+				ret.tag = new(int)
+				*ret.tag = i
+			}
+		case part == "set":
+			ret.set = true
+		case part == "application":
+			ret.application = true
+			if ret.tag == nil {
+				ret.tag = new(int)
+			}
+		case part == "omitempty":
+			ret.omitEmpty = true
+		}
+	}
+	return
+}
+
+// Given a reflected Go type, getUniversalType returns the default tag number
+// and expected compound flag.
+func getUniversalType(t reflect.Type) (tagNumber int, isCompound, ok bool) {
+	switch t {
+	case objectIdentifierType:
+		return TagOID, false, true
+	case bitStringType:
+		return TagBitString, false, true
+	case timeType:
+		return TagUTCTime, false, true
+	case enumeratedType:
+		return TagEnum, false, true
+	case bigIntType:
+		return TagInteger, false, true
+	}
+	switch t.Kind() {
+	case reflect.Bool:
+		return TagBoolean, false, true
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return TagInteger, false, true
+	case reflect.Struct:
+		return TagSequence, true, true
+	case reflect.Slice:
+		if t.Elem().Kind() == reflect.Uint8 {
+			return TagOctetString, false, true
+		}
+		if strings.HasSuffix(t.Name(), "SET") {
+			return TagSet, true, true
+		}
+		return TagSequence, true, true
+	case reflect.String:
+		return TagPrintableString, false, true
+	}
+	return 0, false, false
+}
diff --git a/vendor/github.com/jcmturner/gofork/encoding/asn1/marshal.go b/vendor/github.com/jcmturner/gofork/encoding/asn1/marshal.go
new file mode 100644
index 0000000..f52eee9
--- /dev/null
+++ b/vendor/github.com/jcmturner/gofork/encoding/asn1/marshal.go
@@ -0,0 +1,659 @@
+// Copyright 2009 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 asn1
+
+import (
+	"bytes"
+	"errors"
+	"fmt"
+	"io"
+	"math/big"
+	"reflect"
+	"time"
+	"unicode/utf8"
+)
+
+// A forkableWriter is an in-memory buffer that can be
+// 'forked' to create new forkableWriters that bracket the
+// original. After
+//    pre, post := w.fork()
+// the overall sequence of bytes represented is logically w+pre+post.
+type forkableWriter struct {
+	*bytes.Buffer
+	pre, post *forkableWriter
+}
+
+func newForkableWriter() *forkableWriter {
+	return &forkableWriter{new(bytes.Buffer), nil, nil}
+}
+
+func (f *forkableWriter) fork() (pre, post *forkableWriter) {
+	if f.pre != nil || f.post != nil {
+		panic("have already forked")
+	}
+	f.pre = newForkableWriter()
+	f.post = newForkableWriter()
+	return f.pre, f.post
+}
+
+func (f *forkableWriter) Len() (l int) {
+	l += f.Buffer.Len()
+	if f.pre != nil {
+		l += f.pre.Len()
+	}
+	if f.post != nil {
+		l += f.post.Len()
+	}
+	return
+}
+
+func (f *forkableWriter) writeTo(out io.Writer) (n int, err error) {
+	n, err = out.Write(f.Bytes())
+	if err != nil {
+		return
+	}
+
+	var nn int
+
+	if f.pre != nil {
+		nn, err = f.pre.writeTo(out)
+		n += nn
+		if err != nil {
+			return
+		}
+	}
+
+	if f.post != nil {
+		nn, err = f.post.writeTo(out)
+		n += nn
+	}
+	return
+}
+
+func marshalBase128Int(out *forkableWriter, n int64) (err error) {
+	if n == 0 {
+		err = out.WriteByte(0)
+		return
+	}
+
+	l := 0
+	for i := n; i > 0; i >>= 7 {
+		l++
+	}
+
+	for i := l - 1; i >= 0; i-- {
+		o := byte(n >> uint(i*7))
+		o &= 0x7f
+		if i != 0 {
+			o |= 0x80
+		}
+		err = out.WriteByte(o)
+		if err != nil {
+			return
+		}
+	}
+
+	return nil
+}
+
+func marshalInt64(out *forkableWriter, i int64) (err error) {
+	n := int64Length(i)
+
+	for ; n > 0; n-- {
+		err = out.WriteByte(byte(i >> uint((n-1)*8)))
+		if err != nil {
+			return
+		}
+	}
+
+	return nil
+}
+
+func int64Length(i int64) (numBytes int) {
+	numBytes = 1
+
+	for i > 127 {
+		numBytes++
+		i >>= 8
+	}
+
+	for i < -128 {
+		numBytes++
+		i >>= 8
+	}
+
+	return
+}
+
+func marshalBigInt(out *forkableWriter, n *big.Int) (err error) {
+	if n.Sign() < 0 {
+		// A negative number has to be converted to two's-complement
+		// form. So we'll subtract 1 and invert. If the
+		// most-significant-bit isn't set then we'll need to pad the
+		// beginning with 0xff in order to keep the number negative.
+		nMinus1 := new(big.Int).Neg(n)
+		nMinus1.Sub(nMinus1, bigOne)
+		bytes := nMinus1.Bytes()
+		for i := range bytes {
+			bytes[i] ^= 0xff
+		}
+		if len(bytes) == 0 || bytes[0]&0x80 == 0 {
+			err = out.WriteByte(0xff)
+			if err != nil {
+				return
+			}
+		}
+		_, err = out.Write(bytes)
+	} else if n.Sign() == 0 {
+		// Zero is written as a single 0 zero rather than no bytes.
+		err = out.WriteByte(0x00)
+	} else {
+		bytes := n.Bytes()
+		if len(bytes) > 0 && bytes[0]&0x80 != 0 {
+			// We'll have to pad this with 0x00 in order to stop it
+			// looking like a negative number.
+			err = out.WriteByte(0)
+			if err != nil {
+				return
+			}
+		}
+		_, err = out.Write(bytes)
+	}
+	return
+}
+
+func marshalLength(out *forkableWriter, i int) (err error) {
+	n := lengthLength(i)
+
+	for ; n > 0; n-- {
+		err = out.WriteByte(byte(i >> uint((n-1)*8)))
+		if err != nil {
+			return
+		}
+	}
+
+	return nil
+}
+
+func lengthLength(i int) (numBytes int) {
+	numBytes = 1
+	for i > 255 {
+		numBytes++
+		i >>= 8
+	}
+	return
+}
+
+func marshalTagAndLength(out *forkableWriter, t tagAndLength) (err error) {
+	b := uint8(t.class) << 6
+	if t.isCompound {
+		b |= 0x20
+	}
+	if t.tag >= 31 {
+		b |= 0x1f
+		err = out.WriteByte(b)
+		if err != nil {
+			return
+		}
+		err = marshalBase128Int(out, int64(t.tag))
+		if err != nil {
+			return
+		}
+	} else {
+		b |= uint8(t.tag)
+		err = out.WriteByte(b)
+		if err != nil {
+			return
+		}
+	}
+
+	if t.length >= 128 {
+		l := lengthLength(t.length)
+		err = out.WriteByte(0x80 | byte(l))
+		if err != nil {
+			return
+		}
+		err = marshalLength(out, t.length)
+		if err != nil {
+			return
+		}
+	} else {
+		err = out.WriteByte(byte(t.length))
+		if err != nil {
+			return
+		}
+	}
+
+	return nil
+}
+
+func marshalBitString(out *forkableWriter, b BitString) (err error) {
+	paddingBits := byte((8 - b.BitLength%8) % 8)
+	err = out.WriteByte(paddingBits)
+	if err != nil {
+		return
+	}
+	_, err = out.Write(b.Bytes)
+	return
+}
+
+func marshalObjectIdentifier(out *forkableWriter, oid []int) (err error) {
+	if len(oid) < 2 || oid[0] > 2 || (oid[0] < 2 && oid[1] >= 40) {
+		return StructuralError{"invalid object identifier"}
+	}
+
+	err = marshalBase128Int(out, int64(oid[0]*40+oid[1]))
+	if err != nil {
+		return
+	}
+	for i := 2; i < len(oid); i++ {
+		err = marshalBase128Int(out, int64(oid[i]))
+		if err != nil {
+			return
+		}
+	}
+
+	return
+}
+
+func marshalPrintableString(out *forkableWriter, s string) (err error) {
+	b := []byte(s)
+	for _, c := range b {
+		if !isPrintable(c) {
+			return StructuralError{"PrintableString contains invalid character"}
+		}
+	}
+
+	_, err = out.Write(b)
+	return
+}
+
+func marshalIA5String(out *forkableWriter, s string) (err error) {
+	b := []byte(s)
+	for _, c := range b {
+		if c > 127 {
+			return StructuralError{"IA5String contains invalid character"}
+		}
+	}
+
+	_, err = out.Write(b)
+	return
+}
+
+func marshalUTF8String(out *forkableWriter, s string) (err error) {
+	_, err = out.Write([]byte(s))
+	return
+}
+
+func marshalTwoDigits(out *forkableWriter, v int) (err error) {
+	err = out.WriteByte(byte('0' + (v/10)%10))
+	if err != nil {
+		return
+	}
+	return out.WriteByte(byte('0' + v%10))
+}
+
+func marshalFourDigits(out *forkableWriter, v int) (err error) {
+	var bytes [4]byte
+	for i := range bytes {
+		bytes[3-i] = '0' + byte(v%10)
+		v /= 10
+	}
+	_, err = out.Write(bytes[:])
+	return
+}
+
+func outsideUTCRange(t time.Time) bool {
+	year := t.Year()
+	return year < 1950 || year >= 2050
+}
+
+func marshalUTCTime(out *forkableWriter, t time.Time) (err error) {
+	year := t.Year()
+
+	switch {
+	case 1950 <= year && year < 2000:
+		err = marshalTwoDigits(out, year-1900)
+	case 2000 <= year && year < 2050:
+		err = marshalTwoDigits(out, year-2000)
+	default:
+		return StructuralError{"cannot represent time as UTCTime"}
+	}
+	if err != nil {
+		return
+	}
+
+	return marshalTimeCommon(out, t)
+}
+
+func marshalGeneralizedTime(out *forkableWriter, t time.Time) (err error) {
+	year := t.Year()
+	if year < 0 || year > 9999 {
+		return StructuralError{"cannot represent time as GeneralizedTime"}
+	}
+	if err = marshalFourDigits(out, year); err != nil {
+		return
+	}
+
+	return marshalTimeCommon(out, t)
+}
+
+func marshalTimeCommon(out *forkableWriter, t time.Time) (err error) {
+	_, month, day := t.Date()
+
+	err = marshalTwoDigits(out, int(month))
+	if err != nil {
+		return
+	}
+
+	err = marshalTwoDigits(out, day)
+	if err != nil {
+		return
+	}
+
+	hour, min, sec := t.Clock()
+
+	err = marshalTwoDigits(out, hour)
+	if err != nil {
+		return
+	}
+
+	err = marshalTwoDigits(out, min)
+	if err != nil {
+		return
+	}
+
+	err = marshalTwoDigits(out, sec)
+	if err != nil {
+		return
+	}
+
+	_, offset := t.Zone()
+
+	switch {
+	case offset/60 == 0:
+		err = out.WriteByte('Z')
+		return
+	case offset > 0:
+		err = out.WriteByte('+')
+	case offset < 0:
+		err = out.WriteByte('-')
+	}
+
+	if err != nil {
+		return
+	}
+
+	offsetMinutes := offset / 60
+	if offsetMinutes < 0 {
+		offsetMinutes = -offsetMinutes
+	}
+
+	err = marshalTwoDigits(out, offsetMinutes/60)
+	if err != nil {
+		return
+	}
+
+	err = marshalTwoDigits(out, offsetMinutes%60)
+	return
+}
+
+func stripTagAndLength(in []byte) []byte {
+	_, offset, err := parseTagAndLength(in, 0)
+	if err != nil {
+		return in
+	}
+	return in[offset:]
+}
+
+func marshalBody(out *forkableWriter, value reflect.Value, params fieldParameters) (err error) {
+	switch value.Type() {
+	case flagType:
+		return nil
+	case timeType:
+		t := value.Interface().(time.Time)
+		if params.timeType == TagGeneralizedTime || outsideUTCRange(t) {
+			return marshalGeneralizedTime(out, t)
+		} else {
+			return marshalUTCTime(out, t)
+		}
+	case bitStringType:
+		return marshalBitString(out, value.Interface().(BitString))
+	case objectIdentifierType:
+		return marshalObjectIdentifier(out, value.Interface().(ObjectIdentifier))
+	case bigIntType:
+		return marshalBigInt(out, value.Interface().(*big.Int))
+	}
+
+	switch v := value; v.Kind() {
+	case reflect.Bool:
+		if v.Bool() {
+			return out.WriteByte(255)
+		} else {
+			return out.WriteByte(0)
+		}
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return marshalInt64(out, v.Int())
+	case reflect.Struct:
+		t := v.Type()
+
+		startingField := 0
+
+		// If the first element of the structure is a non-empty
+		// RawContents, then we don't bother serializing the rest.
+		if t.NumField() > 0 && t.Field(0).Type == rawContentsType {
+			s := v.Field(0)
+			if s.Len() > 0 {
+				bytes := make([]byte, s.Len())
+				for i := 0; i < s.Len(); i++ {
+					bytes[i] = uint8(s.Index(i).Uint())
+				}
+				/* The RawContents will contain the tag and
+				 * length fields but we'll also be writing
+				 * those ourselves, so we strip them out of
+				 * bytes */
+				_, err = out.Write(stripTagAndLength(bytes))
+				return
+			} else {
+				startingField = 1
+			}
+		}
+
+		for i := startingField; i < t.NumField(); i++ {
+			var pre *forkableWriter
+			pre, out = out.fork()
+			err = marshalField(pre, v.Field(i), parseFieldParameters(t.Field(i).Tag.Get("asn1")))
+			if err != nil {
+				return
+			}
+		}
+		return
+	case reflect.Slice:
+		sliceType := v.Type()
+		if sliceType.Elem().Kind() == reflect.Uint8 {
+			bytes := make([]byte, v.Len())
+			for i := 0; i < v.Len(); i++ {
+				bytes[i] = uint8(v.Index(i).Uint())
+			}
+			_, err = out.Write(bytes)
+			return
+		}
+
+		// jtasn1 Pass on the tags to the members but need to unset explicit switch and implicit value
+		//var fp fieldParameters
+		params.explicit = false
+		params.tag = nil
+		for i := 0; i < v.Len(); i++ {
+			var pre *forkableWriter
+			pre, out = out.fork()
+			err = marshalField(pre, v.Index(i), params)
+			if err != nil {
+				return
+			}
+		}
+		return
+	case reflect.String:
+		switch params.stringType {
+		case TagIA5String:
+			return marshalIA5String(out, v.String())
+		case TagPrintableString:
+			return marshalPrintableString(out, v.String())
+		default:
+			return marshalUTF8String(out, v.String())
+		}
+	}
+
+	return StructuralError{"unknown Go type"}
+}
+
+func marshalField(out *forkableWriter, v reflect.Value, params fieldParameters) (err error) {
+	if !v.IsValid() {
+		return fmt.Errorf("asn1: cannot marshal nil value")
+	}
+	// If the field is an interface{} then recurse into it.
+	if v.Kind() == reflect.Interface && v.Type().NumMethod() == 0 {
+		return marshalField(out, v.Elem(), params)
+	}
+
+	if v.Kind() == reflect.Slice && v.Len() == 0 && params.omitEmpty {
+		return
+	}
+
+	if params.optional && params.defaultValue != nil && canHaveDefaultValue(v.Kind()) {
+		defaultValue := reflect.New(v.Type()).Elem()
+		defaultValue.SetInt(*params.defaultValue)
+
+		if reflect.DeepEqual(v.Interface(), defaultValue.Interface()) {
+			return
+		}
+	}
+
+	// If no default value is given then the zero value for the type is
+	// assumed to be the default value. This isn't obviously the correct
+	// behaviour, but it's what Go has traditionally done.
+	if params.optional && params.defaultValue == nil {
+		if reflect.DeepEqual(v.Interface(), reflect.Zero(v.Type()).Interface()) {
+			return
+		}
+	}
+
+	if v.Type() == rawValueType {
+		rv := v.Interface().(RawValue)
+		if len(rv.FullBytes) != 0 {
+			_, err = out.Write(rv.FullBytes)
+		} else {
+			err = marshalTagAndLength(out, tagAndLength{rv.Class, rv.Tag, len(rv.Bytes), rv.IsCompound})
+			if err != nil {
+				return
+			}
+			_, err = out.Write(rv.Bytes)
+		}
+		return
+	}
+
+	tag, isCompound, ok := getUniversalType(v.Type())
+	if !ok {
+		err = StructuralError{fmt.Sprintf("unknown Go type: %v", v.Type())}
+		return
+	}
+	class := ClassUniversal
+
+	if params.timeType != 0 && tag != TagUTCTime {
+		return StructuralError{"explicit time type given to non-time member"}
+	}
+
+	// jtasn1 updated to allow slices of strings
+	if params.stringType != 0 && !(tag == TagPrintableString || (v.Kind() == reflect.Slice && tag == 16 && v.Type().Elem().Kind() == reflect.String)) {
+		return StructuralError{"explicit string type given to non-string member"}
+	}
+
+	switch tag {
+	case TagPrintableString:
+		if params.stringType == 0 {
+			// This is a string without an explicit string type. We'll use
+			// a PrintableString if the character set in the string is
+			// sufficiently limited, otherwise we'll use a UTF8String.
+			for _, r := range v.String() {
+				if r >= utf8.RuneSelf || !isPrintable(byte(r)) {
+					if !utf8.ValidString(v.String()) {
+						return errors.New("asn1: string not valid UTF-8")
+					}
+					tag = TagUTF8String
+					break
+				}
+			}
+		} else {
+			tag = params.stringType
+		}
+	case TagUTCTime:
+		if params.timeType == TagGeneralizedTime || outsideUTCRange(v.Interface().(time.Time)) {
+			tag = TagGeneralizedTime
+		}
+	}
+
+	if params.set {
+		if tag != TagSequence {
+			return StructuralError{"non sequence tagged as set"}
+		}
+		tag = TagSet
+	}
+
+	tags, body := out.fork()
+
+	err = marshalBody(body, v, params)
+	if err != nil {
+		return
+	}
+
+	bodyLen := body.Len()
+
+	var explicitTag *forkableWriter
+	if params.explicit {
+		explicitTag, tags = tags.fork()
+	}
+
+	if !params.explicit && params.tag != nil {
+		// implicit tag.
+		tag = *params.tag
+		class = ClassContextSpecific
+	}
+
+	err = marshalTagAndLength(tags, tagAndLength{class, tag, bodyLen, isCompound})
+	if err != nil {
+		return
+	}
+
+	if params.explicit {
+		err = marshalTagAndLength(explicitTag, tagAndLength{
+			class:      ClassContextSpecific,
+			tag:        *params.tag,
+			length:     bodyLen + tags.Len(),
+			isCompound: true,
+		})
+	}
+
+	return err
+}
+
+// Marshal returns the ASN.1 encoding of val.
+//
+// In addition to the struct tags recognised by Unmarshal, the following can be
+// used:
+//
+//	ia5:		causes strings to be marshaled as ASN.1, IA5 strings
+//	omitempty:	causes empty slices to be skipped
+//	printable:	causes strings to be marshaled as ASN.1, PrintableString strings.
+//	utf8:		causes strings to be marshaled as ASN.1, UTF8 strings
+func Marshal(val interface{}) ([]byte, error) {
+	var out bytes.Buffer
+	v := reflect.ValueOf(val)
+	f := newForkableWriter()
+	err := marshalField(f, v, fieldParameters{})
+	if err != nil {
+		return nil, err
+	}
+	_, err = f.writeTo(&out)
+	return out.Bytes(), err
+}
diff --git a/vendor/github.com/jcmturner/gofork/x/crypto/pbkdf2/pbkdf2.go b/vendor/github.com/jcmturner/gofork/x/crypto/pbkdf2/pbkdf2.go
new file mode 100644
index 0000000..75d4187
--- /dev/null
+++ b/vendor/github.com/jcmturner/gofork/x/crypto/pbkdf2/pbkdf2.go
@@ -0,0 +1,98 @@
+// Copyright 2012 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 pbkdf2 implements the key derivation function PBKDF2 as defined in RFC
+2898 / PKCS #5 v2.0.
+
+A key derivation function is useful when encrypting data based on a password
+or any other not-fully-random data. It uses a pseudorandom function to derive
+a secure encryption key based on the password.
+
+While v2.0 of the standard defines only one pseudorandom function to use,
+HMAC-SHA1, the drafted v2.1 specification allows use of all five FIPS Approved
+Hash Functions SHA-1, SHA-224, SHA-256, SHA-384 and SHA-512 for HMAC. To
+choose, you can pass the `New` functions from the different SHA packages to
+pbkdf2.Key.
+*/
+package pbkdf2
+
+import (
+	"crypto/hmac"
+	"hash"
+)
+
+// Key derives a key from the password, salt and iteration count, returning a
+// []byte of length keylen that can be used as cryptographic key. The key is
+// derived based on the method described as PBKDF2 with the HMAC variant using
+// the supplied hash function.
+//
+// For example, to use a HMAC-SHA-1 based PBKDF2 key derivation function, you
+// can get a derived key for e.g. AES-256 (which needs a 32-byte key) by
+// doing:
+//
+// 	dk := pbkdf2.Key([]byte("some password"), salt, 4096, 32, sha1.New)
+//
+// Remember to get a good random salt. At least 8 bytes is recommended by the
+// RFC.
+//
+// Using a higher iteration count will increase the cost of an exhaustive
+// search but will also make derivation proportionally slower.
+func Key(password, salt []byte, iter, keyLen int, h func() hash.Hash) []byte {
+	return Key64(password, salt, int64(iter), int64(keyLen), h)
+}
+
+// Key64 derives a key from the password, salt and iteration count, returning a
+// []byte of length keylen that can be used as cryptographic key. Key64 uses
+// int64 for the iteration count and key length to allow larger values.
+// The key is derived based on the method described as PBKDF2 with the HMAC
+// variant using the supplied hash function.
+//
+// For example, to use a HMAC-SHA-1 based PBKDF2 key derivation function, you
+// can get a derived key for e.g. AES-256 (which needs a 32-byte key) by
+// doing:
+//
+// 	dk := pbkdf2.Key([]byte("some password"), salt, 4096, 32, sha1.New)
+//
+// Remember to get a good random salt. At least 8 bytes is recommended by the
+// RFC.
+//
+// Using a higher iteration count will increase the cost of an exhaustive
+// search but will also make derivation proportionally slower.
+func Key64(password, salt []byte, iter, keyLen int64, h func() hash.Hash) []byte {
+	prf := hmac.New(h, password)
+	hashLen := int64(prf.Size())
+	numBlocks := (keyLen + hashLen - 1) / hashLen
+
+	var buf [4]byte
+	dk := make([]byte, 0, numBlocks*hashLen)
+	U := make([]byte, hashLen)
+	for block := int64(1); block <= numBlocks; block++ {
+		// N.B.: || means concatenation, ^ means XOR
+		// for each block T_i = U_1 ^ U_2 ^ ... ^ U_iter
+		// U_1 = PRF(password, salt || uint(i))
+		prf.Reset()
+		prf.Write(salt)
+		buf[0] = byte(block >> 24)
+		buf[1] = byte(block >> 16)
+		buf[2] = byte(block >> 8)
+		buf[3] = byte(block)
+		prf.Write(buf[:4])
+		dk = prf.Sum(dk)
+		T := dk[int64(len(dk))-hashLen:]
+		copy(U, T)
+
+		// U_n = PRF(password, U_(n-1))
+		for n := int64(2); n <= iter; n++ {
+			prf.Reset()
+			prf.Write(U)
+			U = U[:0]
+			U = prf.Sum(U)
+			for x := range U {
+				T[x] ^= U[x]
+			}
+		}
+	}
+	return dk[:keyLen]
+}
