Use exported types from "encoding/asn1" to retain compatibility.

This commit is contained in:
InfiniteLoopSpace 2018-11-14 13:12:15 +01:00
parent 7cda110d40
commit 8a079b0f10
4 changed files with 206 additions and 203 deletions

View File

@ -20,31 +20,31 @@ package asn1
// everything by any means. // everything by any means.
import ( import (
"encoding/asn1"
"errors" "errors"
"fmt" "fmt"
"log" "log"
"math" "math"
"math/big" "math/big"
"reflect" "reflect"
"strconv"
"time" "time"
"unicode/utf8" "unicode/utf8"
) )
// A StructuralError suggests that the ASN.1 data is valid, but the Go type // A StructuralError suggests that the ASN.1 data is valid, but the Go type
// which is receiving it doesn't match. // which is receiving it doesn't match.
type StructuralError struct { //type StructuralError struct {
Msg string // Msg string
} //}
func (e StructuralError) Error() string { return "asn1: structure error: " + e.Msg } //func (e StructuralError) Error() string { return "asn1: structure error: " + e.Msg }
// A SyntaxError suggests that the ASN.1 data is invalid. // A SyntaxError suggests that the ASN.1 data is invalid.
type SyntaxError struct { //type SyntaxError struct {
Msg string // Msg string
} //}
func (e SyntaxError) Error() string { return "asn1: syntax error: " + e.Msg } //func (e SyntaxError) Error() string { return "asn1: syntax error: " + e.Msg }
// We start by dealing with each of the primitive types in turn. // We start by dealing with each of the primitive types in turn.
@ -52,7 +52,7 @@ func (e SyntaxError) Error() string { return "asn1: syntax error: " + e.Msg }
func parseBool(bytes []byte) (ret bool, err error) { func parseBool(bytes []byte) (ret bool, err error) {
if len(bytes) != 1 { if len(bytes) != 1 {
err = SyntaxError{"invalid boolean"} err = asn1.SyntaxError{"invalid boolean"}
return return
} }
@ -65,7 +65,7 @@ func parseBool(bytes []byte) (ret bool, err error) {
case 0xff: case 0xff:
ret = true ret = true
default: default:
err = SyntaxError{"invalid boolean"} err = asn1.SyntaxError{"invalid boolean"}
} }
return return
@ -77,13 +77,13 @@ func parseBool(bytes []byte) (ret bool, err error) {
// INTEGER and an error otherwise. // INTEGER and an error otherwise.
func checkInteger(bytes []byte) error { func checkInteger(bytes []byte) error {
if len(bytes) == 0 { if len(bytes) == 0 {
return StructuralError{"empty integer"} return asn1.StructuralError{"empty integer"}
} }
if len(bytes) == 1 { if len(bytes) == 1 {
return nil return nil
} }
if (bytes[0] == 0 && bytes[1]&0x80 == 0) || (bytes[0] == 0xff && bytes[1]&0x80 == 0x80) { if (bytes[0] == 0 && bytes[1]&0x80 == 0) || (bytes[0] == 0xff && bytes[1]&0x80 == 0x80) {
return StructuralError{"integer not minimally-encoded"} return asn1.StructuralError{"integer not minimally-encoded"}
} }
return nil return nil
} }
@ -97,7 +97,7 @@ func parseInt64(bytes []byte) (ret int64, err error) {
} }
if len(bytes) > 8 { if len(bytes) > 8 {
// We'll overflow an int64 in this case. // We'll overflow an int64 in this case.
err = StructuralError{"integer too large"} err = asn1.StructuralError{"integer too large"}
return return
} }
for bytesRead := 0; bytesRead < len(bytes); bytesRead++ { for bytesRead := 0; bytesRead < len(bytes); bytesRead++ {
@ -122,7 +122,7 @@ func parseInt32(bytes []byte) (int32, error) {
return 0, err return 0, err
} }
if ret64 != int64(int32(ret64)) { if ret64 != int64(int32(ret64)) {
return 0, StructuralError{"integer too large"} return 0, asn1.StructuralError{"integer too large"}
} }
return int32(ret64), nil return int32(ret64), nil
} }
@ -156,51 +156,51 @@ func parseBigInt(bytes []byte) (*big.Int, error) {
// BitString is the structure to use when you want an ASN.1 BIT STRING type. A // 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 // bit string is padded up to the nearest byte in memory and the number of
// valid bits is recorded. Padding bits will be zero. // valid bits is recorded. Padding bits will be zero.
type BitString struct { //type BitString struct {
Bytes []byte // bits packed into bytes. // Bytes []byte // bits packed into bytes.
BitLength int // length in bits. // BitLength int // length in bits.
} //}
// At returns the bit at the given index. If the index is out of range it // At returns the bit at the given index. If the index is out of range it
// returns false. // returns false.
func (b BitString) At(i int) int { //func (b BitString) At(i int) int {
if i < 0 || i >= b.BitLength { // if i < 0 || i >= b.BitLength {
return 0 // return 0
} // }
x := i / 8 // x := i / 8
y := 7 - uint(i%8) // y := 7 - uint(i%8)
return int(b.Bytes[x]>>y) & 1 // return int(b.Bytes[x]>>y) & 1
} //}
// RightAlign returns a slice where the padding bits are at the beginning. The // RightAlign returns a slice where the padding bits are at the beginning. The
// slice may share memory with the BitString. // slice may share memory with the BitString.
func (b BitString) RightAlign() []byte { //func (b BitString) RightAlign() []byte {
shift := uint(8 - (b.BitLength % 8)) // shift := uint(8 - (b.BitLength % 8))
if shift == 8 || len(b.Bytes) == 0 { // if shift == 8 || len(b.Bytes) == 0 {
return b.Bytes // return b.Bytes
} // }
//
a := make([]byte, len(b.Bytes)) // a := make([]byte, len(b.Bytes))
a[0] = b.Bytes[0] >> shift // a[0] = b.Bytes[0] >> shift
for i := 1; i < len(b.Bytes); i++ { // for i := 1; i < len(b.Bytes); i++ {
a[i] = b.Bytes[i-1] << (8 - shift) // a[i] = b.Bytes[i-1] << (8 - shift)
a[i] |= b.Bytes[i] >> shift // a[i] |= b.Bytes[i] >> shift
} // }
//
return a // return a
} //}
// parseBitString parses an ASN.1 bit string from the given byte slice and returns it. // parseBitString parses an ASN.1 bit string from the given byte slice and returns it.
func parseBitString(bytes []byte) (ret BitString, err error) { func parseBitString(bytes []byte) (ret asn1.BitString, err error) {
if len(bytes) == 0 { if len(bytes) == 0 {
err = SyntaxError{"zero length BIT STRING"} err = asn1.SyntaxError{"zero length BIT STRING"}
return return
} }
paddingBits := int(bytes[0]) paddingBits := int(bytes[0])
if paddingBits > 7 || if paddingBits > 7 ||
len(bytes) == 1 && paddingBits > 0 || len(bytes) == 1 && paddingBits > 0 ||
bytes[len(bytes)-1]&((1<<bytes[0])-1) != 0 { bytes[len(bytes)-1]&((1<<bytes[0])-1) != 0 {
err = SyntaxError{"invalid padding bits in BIT STRING"} err = asn1.SyntaxError{"invalid padding bits in BIT STRING"}
return return
} }
ret.BitLength = (len(bytes)-1)*8 - paddingBits ret.BitLength = (len(bytes)-1)*8 - paddingBits
@ -211,49 +211,49 @@ func parseBitString(bytes []byte) (ret BitString, err error) {
// NULL // NULL
// NullRawValue is a RawValue with its Tag set to the ASN.1 NULL type tag (5). // NullRawValue is a RawValue with its Tag set to the ASN.1 NULL type tag (5).
var NullRawValue = RawValue{Tag: TagNull} //var NullRawValue = RawValue{Tag: TagNull}
// NullBytes contains bytes representing the DER-encoded ASN.1 NULL type. // NullBytes contains bytes representing the DER-encoded ASN.1 NULL type.
var NullBytes = []byte{TagNull, 0} //var NullBytes = []byte{TagNull, 0}
// OBJECT IDENTIFIER // OBJECT IDENTIFIER
// An ObjectIdentifier represents an ASN.1 OBJECT IDENTIFIER. // An ObjectIdentifier represents an ASN.1 OBJECT IDENTIFIER.
type ObjectIdentifier []int //type ObjectIdentifier []int
// Equal reports whether oi and other represent the same identifier. // Equal reports whether oi and other represent the same identifier.
func (oi ObjectIdentifier) Equal(other ObjectIdentifier) bool { //func (oi ObjectIdentifier) Equal(other ObjectIdentifier) bool {
if len(oi) != len(other) { // if len(oi) != len(other) {
return false // return false
} // }
for i := 0; i < len(oi); i++ { // for i := 0; i < len(oi); i++ {
if oi[i] != other[i] { // if oi[i] != other[i] {
return false // return false
} // }
} // }
//
// return true
//}
return true //func (oi ObjectIdentifier) String() string {
} // var s string
//
func (oi ObjectIdentifier) String() string { // for i, v := range oi {
var s string // if i > 0 {
// s += "."
for i, v := range oi { // }
if i > 0 { // s += strconv.Itoa(v)
s += "." // }
} //
s += strconv.Itoa(v) // return s
} //}
return s
}
// parseObjectIdentifier parses an OBJECT IDENTIFIER from the given bytes and // parseObjectIdentifier parses an OBJECT IDENTIFIER from the given bytes and
// returns it. An object identifier is a sequence of variable length integers // returns it. An object identifier is a sequence of variable length integers
// that are assigned in a hierarchy. // that are assigned in a hierarchy.
func parseObjectIdentifier(bytes []byte) (s ObjectIdentifier, err error) { func parseObjectIdentifier(bytes []byte) (s asn1.ObjectIdentifier, err error) {
if len(bytes) == 0 { if len(bytes) == 0 {
err = SyntaxError{"zero length OBJECT IDENTIFIER"} err = asn1.SyntaxError{"zero length OBJECT IDENTIFIER"}
return return
} }
@ -292,12 +292,12 @@ func parseObjectIdentifier(bytes []byte) (s ObjectIdentifier, err error) {
// ENUMERATED // ENUMERATED
// An Enumerated is represented as a plain int. // An Enumerated is represented as a plain int.
type Enumerated int //type Enumerated int
// FLAG // FLAG
// A Flag accepts any data and is set to true if present. // A Flag accepts any data and is set to true if present.
type Flag bool //type Flag bool
// parseBase128Int parses a base-128 encoded int from the given offset in the // parseBase128Int parses a base-128 encoded int from the given offset in the
// given byte slice. It returns the value and the new offset. // given byte slice. It returns the value and the new offset.
@ -308,7 +308,7 @@ func parseBase128Int(bytes []byte, initOffset int) (ret, offset int, err error)
// 5 * 7 bits per byte == 35 bits of data // 5 * 7 bits per byte == 35 bits of data
// Thus the representation is either non-minimal or too large for an int32 // Thus the representation is either non-minimal or too large for an int32
if shifted == 5 { if shifted == 5 {
err = StructuralError{"base 128 integer too large"} err = asn1.StructuralError{"base 128 integer too large"}
return return
} }
ret64 <<= 7 ret64 <<= 7
@ -319,12 +319,12 @@ func parseBase128Int(bytes []byte, initOffset int) (ret, offset int, err error)
ret = int(ret64) ret = int(ret64)
// Ensure that the returned value fits in an int on all platforms // Ensure that the returned value fits in an int on all platforms
if ret64 > math.MaxInt32 { if ret64 > math.MaxInt32 {
err = StructuralError{"base 128 integer too large"} err = asn1.StructuralError{"base 128 integer too large"}
} }
return return
} }
} }
err = SyntaxError{"truncated base 128 integer"} err = asn1.SyntaxError{"truncated base 128 integer"}
return return
} }
@ -380,7 +380,7 @@ func parseGeneralizedTime(bytes []byte) (ret time.Time, err error) {
func parseNumericString(bytes []byte) (ret string, err error) { func parseNumericString(bytes []byte) (ret string, err error) {
for _, b := range bytes { for _, b := range bytes {
if !isNumeric(b) { if !isNumeric(b) {
return "", SyntaxError{"NumericString contains invalid character"} return "", asn1.SyntaxError{"NumericString contains invalid character"}
} }
} }
return string(bytes), nil return string(bytes), nil
@ -399,7 +399,7 @@ func isNumeric(b byte) bool {
func parsePrintableString(bytes []byte) (ret string, err error) { func parsePrintableString(bytes []byte) (ret string, err error) {
for _, b := range bytes { for _, b := range bytes {
if !isPrintable(b, allowAsterisk, allowAmpersand) { if !isPrintable(b, allowAsterisk, allowAmpersand) {
err = SyntaxError{"PrintableString contains invalid character"} err = asn1.SyntaxError{"PrintableString contains invalid character"}
return return
} }
} }
@ -449,7 +449,7 @@ func isPrintable(b byte, asterisk asteriskFlag, ampersand ampersandFlag) bool {
func parseIA5String(bytes []byte) (ret string, err error) { func parseIA5String(bytes []byte) (ret string, err error) {
for _, b := range bytes { for _, b := range bytes {
if b >= utf8.RuneSelf { if b >= utf8.RuneSelf {
err = SyntaxError{"IA5String contains invalid character"} err = asn1.SyntaxError{"IA5String contains invalid character"}
return return
} }
} }
@ -477,17 +477,17 @@ func parseUTF8String(bytes []byte) (ret string, err error) {
} }
// A RawValue represents an undecoded ASN.1 object. // A RawValue represents an undecoded ASN.1 object.
type RawValue struct { //type RawValue struct {
Class, Tag int // Class, Tag int
IsCompound bool // IsCompound bool
Bytes []byte // Bytes []byte
FullBytes []byte // includes the tag and length // FullBytes []byte // includes the tag and length
} //}
// RawContent is used to signal that the undecoded, DER data needs to be // 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 // 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. // this type. It's an error for any of the other fields to have this type.
type RawContent []byte //type RawContent []byte
// Tagging // Tagging
@ -518,12 +518,12 @@ func parseTagAndLength(bytes []byte, initOffset int) (ret tagAndLength, offset i
} }
// Tags should be encoded in minimal form. // Tags should be encoded in minimal form.
if ret.tag < 0x1f { if ret.tag < 0x1f {
err = SyntaxError{"non-minimal tag"} err = asn1.SyntaxError{"non-minimal tag"}
return return
} }
} }
if offset >= len(bytes) { if offset >= len(bytes) {
err = SyntaxError{"truncated tag or length"} err = asn1.SyntaxError{"truncated tag or length"}
return return
} }
b = bytes[offset] b = bytes[offset]
@ -563,13 +563,13 @@ func parseTagAndLength(bytes []byte, initOffset int) (ret tagAndLength, offset i
} }
log.Println("indefinite length found (not DER)") log.Println("indefinite length found (not DER)")
} }
err = SyntaxError{"indefinite length found (not DER)"} err = asn1.SyntaxError{"indefinite length found (not DER)"}
return return
} }
ret.length = 0 ret.length = 0
for i := 0; i < numBytes; i++ { for i := 0; i < numBytes; i++ {
if offset >= len(bytes) { if offset >= len(bytes) {
err = SyntaxError{"truncated tag or length"} err = asn1.SyntaxError{"truncated tag or length"}
return return
} }
b = bytes[offset] b = bytes[offset]
@ -577,20 +577,20 @@ func parseTagAndLength(bytes []byte, initOffset int) (ret tagAndLength, offset i
if ret.length >= 1<<23 { if ret.length >= 1<<23 {
// We can't shift ret.length up without // We can't shift ret.length up without
// overflowing. // overflowing.
err = StructuralError{"length too large"} err = asn1.StructuralError{"length too large"}
return return
} }
ret.length <<= 8 ret.length <<= 8
ret.length |= int(b) ret.length |= int(b)
if ret.length == 0 { if ret.length == 0 {
// DER requires that lengths be minimal. // DER requires that lengths be minimal.
err = StructuralError{"superfluous leading zeros in length"} err = asn1.StructuralError{"superfluous leading zeros in length"}
return return
} }
} }
// Short lengths must be encoded in short form. // Short lengths must be encoded in short form.
if ret.length < 0x80 { if ret.length < 0x80 {
err = StructuralError{"non-minimal length"} err = asn1.StructuralError{"non-minimal length"}
return return
} }
} }
@ -604,7 +604,7 @@ func parseTagAndLength(bytes []byte, initOffset int) (ret tagAndLength, offset i
func parseSequenceOf(bytes []byte, sliceType reflect.Type, elemType reflect.Type, params fieldParameters) (ret reflect.Value, err error) { func parseSequenceOf(bytes []byte, sliceType reflect.Type, elemType reflect.Type, params fieldParameters) (ret reflect.Value, err error) {
matchAny, expectedTag, compoundType, ok := getUniversalType(elemType) matchAny, expectedTag, compoundType, ok := getUniversalType(elemType)
if !ok { if !ok {
err = StructuralError{"unknown Go type for slice"} err = asn1.StructuralError{"unknown Go type for slice"}
return return
} }
@ -629,11 +629,11 @@ func parseSequenceOf(bytes []byte, sliceType reflect.Type, elemType reflect.Type
} }
if !matchAny && (t.class != ClassUniversal || t.isCompound != compoundType || t.tag != expectedTag) && !params.choice { if !matchAny && (t.class != ClassUniversal || t.isCompound != compoundType || t.tag != expectedTag) && !params.choice {
err = StructuralError{"sequence tag mismatch"} err = asn1.StructuralError{"sequence tag mismatch"}
return return
} }
if invalidLength(offset, t.length, len(bytes)) { if invalidLength(offset, t.length, len(bytes)) {
err = SyntaxError{"truncated sequence"} err = asn1.SyntaxError{"truncated sequence"}
return return
} }
offset += t.length offset += t.length
@ -652,13 +652,13 @@ func parseSequenceOf(bytes []byte, sliceType reflect.Type, elemType reflect.Type
} }
var ( var (
bitStringType = reflect.TypeOf(BitString{}) bitStringType = reflect.TypeOf(asn1.BitString{})
objectIdentifierType = reflect.TypeOf(ObjectIdentifier{}) objectIdentifierType = reflect.TypeOf(asn1.ObjectIdentifier{})
enumeratedType = reflect.TypeOf(Enumerated(0)) enumeratedType = reflect.TypeOf(asn1.Enumerated(0))
flagType = reflect.TypeOf(Flag(false)) flagType = reflect.TypeOf(asn1.Flag(false))
timeType = reflect.TypeOf(time.Time{}) timeType = reflect.TypeOf(time.Time{})
rawValueType = reflect.TypeOf(RawValue{}) rawValueType = reflect.TypeOf(asn1.RawValue{})
rawContentsType = reflect.TypeOf(RawContent(nil)) rawContentsType = reflect.TypeOf(asn1.RawContent(nil))
bigIntType = reflect.TypeOf(new(big.Int)) bigIntType = reflect.TypeOf(new(big.Int))
) )
@ -678,7 +678,7 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam
// If we have run out of data, it may be that there are optional elements at the end. // If we have run out of data, it may be that there are optional elements at the end.
if offset == len(bytes) { if offset == len(bytes) {
if !setDefaultValue(v, params) { if !setDefaultValue(v, params) {
err = SyntaxError{"sequence truncated"} err = asn1.SyntaxError{"sequence truncated"}
} }
return return
} }
@ -691,7 +691,7 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam
return return
} }
if invalidLength(offset, t.length, len(bytes)) { if invalidLength(offset, t.length, len(bytes)) {
err = SyntaxError{"data truncated"} err = asn1.SyntaxError{"data truncated"}
return return
} }
var result interface{} var result interface{}
@ -744,7 +744,7 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam
expectedClass = ClassApplication expectedClass = ClassApplication
} }
if offset == len(bytes) { if offset == len(bytes) {
err = StructuralError{"explicit tag has no child"} err = asn1.StructuralError{"explicit tag has no child"}
return return
} }
if t.class == expectedClass && t.tag == *params.tag && (t.length == 0 || t.isCompound) { if t.class == expectedClass && t.tag == *params.tag && (t.length == 0 || t.isCompound) {
@ -757,7 +757,7 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam
} }
} else { } else {
if fieldType != flagType { if fieldType != flagType {
err = StructuralError{"zero length explicit tag was not an asn1.Flag"} err = asn1.StructuralError{"zero length explicit tag was not an asn1.Flag"}
return return
} }
v.SetBool(true) v.SetBool(true)
@ -769,7 +769,7 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam
if ok { if ok {
offset = initOffset offset = initOffset
} else { } else {
err = StructuralError{"explicitly tagged member didn't match"} err = asn1.StructuralError{"explicitly tagged member didn't match"}
} }
return return
} }
@ -777,7 +777,7 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam
matchAny, universalTag, compoundType, ok1 := getUniversalType(fieldType) matchAny, universalTag, compoundType, ok1 := getUniversalType(fieldType)
if !ok1 { if !ok1 {
err = StructuralError{fmt.Sprintf("unknown Go type: %v", fieldType)} err = asn1.StructuralError{fmt.Sprintf("unknown Go type: %v", fieldType)}
return return
} }
@ -836,12 +836,12 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam
if ok { if ok {
offset = initOffset offset = initOffset
} else { } else {
err = StructuralError{fmt.Sprintf("tags don't match (%d vs %+v) %+v %s @%d", expectedTag, t, params, fieldType.Name(), offset)} err = asn1.StructuralError{fmt.Sprintf("tags don't match (%d vs %+v) %+v %s @%d", expectedTag, t, params, fieldType.Name(), offset)}
} }
return return
} }
if invalidLength(offset, t.length, len(bytes)) { if invalidLength(offset, t.length, len(bytes)) {
err = SyntaxError{"data truncated"} err = asn1.SyntaxError{"data truncated"}
return return
} }
innerBytes := bytes[offset : offset+t.length] innerBytes := bytes[offset : offset+t.length]
@ -850,7 +850,7 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam
// We deal with the structures defined in this package first. // We deal with the structures defined in this package first.
switch fieldType { switch fieldType {
case rawValueType: case rawValueType:
result := RawValue{t.class, t.tag, t.isCompound, innerBytes, bytes[initOffset:offset]} result := asn1.RawValue{t.class, t.tag, t.isCompound, innerBytes, bytes[initOffset:offset]}
v.Set(reflect.ValueOf(result)) v.Set(reflect.ValueOf(result))
return return
case objectIdentifierType: case objectIdentifierType:
@ -928,7 +928,7 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam
for i := 0; i < structType.NumField(); i++ { for i := 0; i < structType.NumField(); i++ {
if structType.Field(i).PkgPath != "" { if structType.Field(i).PkgPath != "" {
err = StructuralError{"struct contains unexported fields"} err = asn1.StructuralError{"struct contains unexported fields"}
return return
} }
} }
@ -936,7 +936,7 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam
if structType.NumField() > 0 && if structType.NumField() > 0 &&
structType.Field(0).Type == rawContentsType { structType.Field(0).Type == rawContentsType {
bytes := bytes[initOffset:offset] bytes := bytes[initOffset:offset]
val.Field(0).Set(reflect.ValueOf(RawContent(bytes))) val.Field(0).Set(reflect.ValueOf(asn1.RawContent(bytes)))
} }
innerOffset := 0 innerOffset := 0
@ -998,14 +998,14 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam
// such. We give up and pass it as an 8-bit string. // such. We give up and pass it as an 8-bit string.
v, err = parseT61String(innerBytes) v, err = parseT61String(innerBytes)
default: default:
err = SyntaxError{fmt.Sprintf("internal error: unknown string type %d", universalTag)} err = asn1.SyntaxError{fmt.Sprintf("internal error: unknown string type %d", universalTag)}
} }
if err == nil { if err == nil {
val.SetString(v) val.SetString(v)
} }
return return
} }
err = StructuralError{"unsupported: " + v.Type().String()} err = asn1.StructuralError{"unsupported: " + v.Type().String()}
return return
} }

View File

@ -6,6 +6,7 @@ package asn1
import ( import (
"bytes" "bytes"
"encoding/asn1"
"fmt" "fmt"
"math" "math"
"math/big" "math/big"
@ -178,7 +179,7 @@ func TestBitString(t *testing.T) {
} }
func TestBitStringAt(t *testing.T) { func TestBitStringAt(t *testing.T) {
bs := BitString{[]byte{0x82, 0x40}, 16} bs := asn1.BitString{[]byte{0x82, 0x40}, 16}
if bs.At(0) != 1 { if bs.At(0) != 1 {
t.Error("#1: Failed") t.Error("#1: Failed")
} }
@ -216,7 +217,7 @@ var bitStringRightAlignTests = []bitStringRightAlignTest{
func TestBitStringRightAlign(t *testing.T) { func TestBitStringRightAlign(t *testing.T) {
for i, test := range bitStringRightAlignTests { for i, test := range bitStringRightAlignTests {
bs := BitString{test.in, test.inlen} bs := asn1.BitString{test.in, test.inlen}
out := bs.RightAlign() out := bs.RightAlign()
if !bytes.Equal(out, test.out) { if !bytes.Equal(out, test.out) {
t.Errorf("#%d got: %x want: %x", i, out, test.out) t.Errorf("#%d got: %x want: %x", i, out, test.out)
@ -227,7 +228,7 @@ func TestBitStringRightAlign(t *testing.T) {
type objectIdentifierTest struct { type objectIdentifierTest struct {
in []byte in []byte
ok bool ok bool
out ObjectIdentifier // has base type[]int out asn1.ObjectIdentifier // has base type[]int
} }
var objectIdentifierTestData = []objectIdentifierTest{ var objectIdentifierTestData = []objectIdentifierTest{
@ -252,7 +253,7 @@ func TestObjectIdentifier(t *testing.T) {
} }
} }
if s := ObjectIdentifier([]int{1, 2, 3, 4}).String(); s != "1.2.3.4" { if s := asn1.ObjectIdentifier([]int{1, 2, 3, 4}).String(); s != "1.2.3.4" {
t.Errorf("bad ObjectIdentifier.String(). Got %s, want 1.2.3.4", s) t.Errorf("bad ObjectIdentifier.String(). Got %s, want 1.2.3.4", s)
} }
} }
@ -447,7 +448,7 @@ func TestParseFieldParameters(t *testing.T) {
} }
type TestObjectIdentifierStruct struct { type TestObjectIdentifierStruct struct {
OID ObjectIdentifier OID asn1.ObjectIdentifier
} }
type TestContextSpecificTags struct { type TestContextSpecificTags struct {
@ -481,17 +482,17 @@ var unmarshalTestData = []struct {
out interface{} out interface{}
}{ }{
{[]byte{0x02, 0x01, 0x42}, newInt(0x42)}, {[]byte{0x02, 0x01, 0x42}, newInt(0x42)},
{[]byte{0x05, 0x00}, &RawValue{0, 5, false, []byte{}, []byte{0x05, 0x00}}}, {[]byte{0x05, 0x00}, &asn1.RawValue{0, 5, false, []byte{}, []byte{0x05, 0x00}}},
{[]byte{0x30, 0x08, 0x06, 0x06, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d}, &TestObjectIdentifierStruct{[]int{1, 2, 840, 113549}}}, {[]byte{0x30, 0x08, 0x06, 0x06, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d}, &TestObjectIdentifierStruct{[]int{1, 2, 840, 113549}}},
{[]byte{0x03, 0x04, 0x06, 0x6e, 0x5d, 0xc0}, &BitString{[]byte{110, 93, 192}, 18}}, {[]byte{0x03, 0x04, 0x06, 0x6e, 0x5d, 0xc0}, &asn1.BitString{[]byte{110, 93, 192}, 18}},
{[]byte{0x30, 0x09, 0x02, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, 0x01, 0x03}, &[]int{1, 2, 3}}, {[]byte{0x30, 0x09, 0x02, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, 0x01, 0x03}, &[]int{1, 2, 3}},
{[]byte{0x02, 0x01, 0x10}, newInt(16)}, {[]byte{0x02, 0x01, 0x10}, newInt(16)},
{[]byte{0x13, 0x04, 't', 'e', 's', 't'}, newString("test")}, {[]byte{0x13, 0x04, 't', 'e', 's', 't'}, newString("test")},
{[]byte{0x16, 0x04, 't', 'e', 's', 't'}, newString("test")}, {[]byte{0x16, 0x04, 't', 'e', 's', 't'}, newString("test")},
// Ampersand is allowed in PrintableString due to mistakes by major CAs. // Ampersand is allowed in PrintableString due to mistakes by major CAs.
{[]byte{0x13, 0x05, 't', 'e', 's', 't', '&'}, newString("test&")}, {[]byte{0x13, 0x05, 't', 'e', 's', 't', '&'}, newString("test&")},
{[]byte{0x16, 0x04, 't', 'e', 's', 't'}, &RawValue{0, 22, false, []byte("test"), []byte("\x16\x04test")}}, {[]byte{0x16, 0x04, 't', 'e', 's', 't'}, &asn1.RawValue{0, 22, false, []byte("test"), []byte("\x16\x04test")}},
{[]byte{0x04, 0x04, 1, 2, 3, 4}, &RawValue{0, 4, false, []byte{1, 2, 3, 4}, []byte{4, 4, 1, 2, 3, 4}}}, {[]byte{0x04, 0x04, 1, 2, 3, 4}, &asn1.RawValue{0, 4, false, []byte{1, 2, 3, 4}, []byte{4, 4, 1, 2, 3, 4}}},
{[]byte{0x30, 0x03, 0x81, 0x01, 0x01}, &TestContextSpecificTags{1}}, {[]byte{0x30, 0x03, 0x81, 0x01, 0x01}, &TestContextSpecificTags{1}},
{[]byte{0x30, 0x08, 0xa1, 0x03, 0x02, 0x01, 0x01, 0x02, 0x01, 0x02}, &TestContextSpecificTags2{1, 2}}, {[]byte{0x30, 0x08, 0xa1, 0x03, 0x02, 0x01, 0x01, 0x02, 0x01, 0x02}, &TestContextSpecificTags2{1, 2}},
{[]byte{0x30, 0x03, 0x81, 0x01, '@'}, &TestContextSpecificTags3{"@"}}, {[]byte{0x30, 0x03, 0x81, 0x01, '@'}, &TestContextSpecificTags3{"@"}},
@ -520,12 +521,12 @@ func TestUnmarshal(t *testing.T) {
type Certificate struct { type Certificate struct {
TBSCertificate TBSCertificate TBSCertificate TBSCertificate
SignatureAlgorithm AlgorithmIdentifier SignatureAlgorithm AlgorithmIdentifier
SignatureValue BitString SignatureValue asn1.BitString
} }
type TBSCertificate struct { type TBSCertificate struct {
Version int `asn1:"optional,explicit,default:0,tag:0"` Version int `asn1:"optional,explicit,default:0,tag:0"`
SerialNumber RawValue SerialNumber asn1.RawValue
SignatureAlgorithm AlgorithmIdentifier SignatureAlgorithm AlgorithmIdentifier
Issuer RDNSequence Issuer RDNSequence
Validity Validity Validity Validity
@ -534,7 +535,7 @@ type TBSCertificate struct {
} }
type AlgorithmIdentifier struct { type AlgorithmIdentifier struct {
Algorithm ObjectIdentifier Algorithm asn1.ObjectIdentifier
} }
type RDNSequence []RelativeDistinguishedNameSET type RDNSequence []RelativeDistinguishedNameSET
@ -542,7 +543,7 @@ type RDNSequence []RelativeDistinguishedNameSET
type RelativeDistinguishedNameSET []AttributeTypeAndValue type RelativeDistinguishedNameSET []AttributeTypeAndValue
type AttributeTypeAndValue struct { type AttributeTypeAndValue struct {
Type ObjectIdentifier Type asn1.ObjectIdentifier
Value interface{} Value interface{}
} }
@ -552,7 +553,7 @@ type Validity struct {
type PublicKeyInfo struct { type PublicKeyInfo struct {
Algorithm AlgorithmIdentifier Algorithm AlgorithmIdentifier
PublicKey BitString PublicKey asn1.BitString
} }
func TestCertificate(t *testing.T) { func TestCertificate(t *testing.T) {
@ -577,7 +578,7 @@ func TestCertificateWithNUL(t *testing.T) {
} }
type rawStructTest struct { type rawStructTest struct {
Raw RawContent Raw asn1.RawContent
A int A int
} }
@ -603,25 +604,25 @@ func TestRawStructs(t *testing.T) {
} }
type oiEqualTest struct { type oiEqualTest struct {
first ObjectIdentifier first asn1.ObjectIdentifier
second ObjectIdentifier second asn1.ObjectIdentifier
same bool same bool
} }
var oiEqualTests = []oiEqualTest{ var oiEqualTests = []oiEqualTest{
{ {
ObjectIdentifier{1, 2, 3}, asn1.ObjectIdentifier{1, 2, 3},
ObjectIdentifier{1, 2, 3}, asn1.ObjectIdentifier{1, 2, 3},
true, true,
}, },
{ {
ObjectIdentifier{1}, asn1.ObjectIdentifier{1},
ObjectIdentifier{1, 2, 3}, asn1.ObjectIdentifier{1, 2, 3},
false, false,
}, },
{ {
ObjectIdentifier{1, 2, 3}, asn1.ObjectIdentifier{1, 2, 3},
ObjectIdentifier{10, 11, 12}, asn1.ObjectIdentifier{10, 11, 12},
false, false,
}, },
} }
@ -637,31 +638,31 @@ func TestObjectIdentifierEqual(t *testing.T) {
var derEncodedSelfSignedCert = Certificate{ var derEncodedSelfSignedCert = Certificate{
TBSCertificate: TBSCertificate{ TBSCertificate: TBSCertificate{
Version: 0, Version: 0,
SerialNumber: RawValue{Class: 0, Tag: 2, IsCompound: false, Bytes: []uint8{0x0, 0x8c, 0xc3, 0x37, 0x92, 0x10, 0xec, 0x2c, 0x98}, FullBytes: []byte{2, 9, 0x0, 0x8c, 0xc3, 0x37, 0x92, 0x10, 0xec, 0x2c, 0x98}}, SerialNumber: asn1.RawValue{Class: 0, Tag: 2, IsCompound: false, Bytes: []uint8{0x0, 0x8c, 0xc3, 0x37, 0x92, 0x10, 0xec, 0x2c, 0x98}, FullBytes: []byte{2, 9, 0x0, 0x8c, 0xc3, 0x37, 0x92, 0x10, 0xec, 0x2c, 0x98}},
SignatureAlgorithm: AlgorithmIdentifier{Algorithm: ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}}, SignatureAlgorithm: AlgorithmIdentifier{Algorithm: asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}},
Issuer: RDNSequence{ Issuer: RDNSequence{
RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 6}, Value: "XX"}}, RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: asn1.ObjectIdentifier{2, 5, 4, 6}, Value: "XX"}},
RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 8}, Value: "Some-State"}}, RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: asn1.ObjectIdentifier{2, 5, 4, 8}, Value: "Some-State"}},
RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 7}, Value: "City"}}, RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: asn1.ObjectIdentifier{2, 5, 4, 7}, Value: "City"}},
RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 10}, Value: "Internet Widgits Pty Ltd"}}, RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: asn1.ObjectIdentifier{2, 5, 4, 10}, Value: "Internet Widgits Pty Ltd"}},
RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 3}, Value: "false.example.com"}}, RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: asn1.ObjectIdentifier{2, 5, 4, 3}, Value: "false.example.com"}},
RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: "false@example.com"}}, RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: "false@example.com"}},
}, },
Validity: Validity{ Validity: Validity{
NotBefore: time.Date(2009, 10, 8, 00, 25, 53, 0, time.UTC), NotBefore: time.Date(2009, 10, 8, 00, 25, 53, 0, time.UTC),
NotAfter: time.Date(2010, 10, 8, 00, 25, 53, 0, time.UTC), NotAfter: time.Date(2010, 10, 8, 00, 25, 53, 0, time.UTC),
}, },
Subject: RDNSequence{ Subject: RDNSequence{
RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 6}, Value: "XX"}}, RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: asn1.ObjectIdentifier{2, 5, 4, 6}, Value: "XX"}},
RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 8}, Value: "Some-State"}}, RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: asn1.ObjectIdentifier{2, 5, 4, 8}, Value: "Some-State"}},
RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 7}, Value: "City"}}, RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: asn1.ObjectIdentifier{2, 5, 4, 7}, Value: "City"}},
RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 10}, Value: "Internet Widgits Pty Ltd"}}, RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: asn1.ObjectIdentifier{2, 5, 4, 10}, Value: "Internet Widgits Pty Ltd"}},
RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 3}, Value: "false.example.com"}}, RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: asn1.ObjectIdentifier{2, 5, 4, 3}, Value: "false.example.com"}},
RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: "false@example.com"}}, RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: "false@example.com"}},
}, },
PublicKey: PublicKeyInfo{ PublicKey: PublicKeyInfo{
Algorithm: AlgorithmIdentifier{Algorithm: ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}}, Algorithm: AlgorithmIdentifier{Algorithm: asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}},
PublicKey: BitString{ PublicKey: asn1.BitString{
Bytes: []uint8{ Bytes: []uint8{
0x30, 0x48, 0x2, 0x41, 0x0, 0xcd, 0xb7, 0x30, 0x48, 0x2, 0x41, 0x0, 0xcd, 0xb7,
0x63, 0x9c, 0x32, 0x78, 0xf0, 0x6, 0xaa, 0x27, 0x7f, 0x6e, 0xaf, 0x42, 0x63, 0x9c, 0x32, 0x78, 0xf0, 0x6, 0xaa, 0x27, 0x7f, 0x6e, 0xaf, 0x42,
@ -675,8 +676,8 @@ var derEncodedSelfSignedCert = Certificate{
}, },
}, },
}, },
SignatureAlgorithm: AlgorithmIdentifier{Algorithm: ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}}, SignatureAlgorithm: AlgorithmIdentifier{Algorithm: asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}},
SignatureValue: BitString{ SignatureValue: asn1.BitString{
Bytes: []uint8{ Bytes: []uint8{
0xa6, 0x7b, 0x6, 0xec, 0x5e, 0xce, 0xa6, 0x7b, 0x6, 0xec, 0x5e, 0xce,
0x92, 0x77, 0x2c, 0xa4, 0x13, 0xcb, 0xa3, 0xca, 0x12, 0x56, 0x8f, 0xdc, 0x6c, 0x92, 0x77, 0x2c, 0xa4, 0x13, 0xcb, 0xa3, 0xca, 0x12, 0x56, 0x8f, 0xdc, 0x6c,
@ -996,7 +997,7 @@ type exported struct {
} }
func TestUnexportedStructField(t *testing.T) { func TestUnexportedStructField(t *testing.T) {
want := StructuralError{"struct contains unexported fields"} want := asn1.StructuralError{"struct contains unexported fields"}
_, err := Marshal(unexported{X: 5, y: 1}) _, err := Marshal(unexported{X: 5, y: 1})
if err != want { if err != want {
@ -1015,34 +1016,34 @@ func TestUnexportedStructField(t *testing.T) {
} }
func TestNull(t *testing.T) { func TestNull(t *testing.T) {
marshaled, err := Marshal(NullRawValue) marshaled, err := Marshal(asn1.NullRawValue)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if !bytes.Equal(NullBytes, marshaled) { if !bytes.Equal(asn1.NullBytes, marshaled) {
t.Errorf("Expected Marshal of NullRawValue to yield %x, got %x", NullBytes, marshaled) t.Errorf("Expected Marshal of NullRawValue to yield %x, got %x", asn1.NullBytes, marshaled)
} }
unmarshaled := RawValue{} unmarshaled := asn1.RawValue{}
if _, err := Unmarshal(NullBytes, &unmarshaled); err != nil { if _, err := Unmarshal(asn1.NullBytes, &unmarshaled); err != nil {
t.Fatal(err) t.Fatal(err)
} }
unmarshaled.FullBytes = NullRawValue.FullBytes unmarshaled.FullBytes = asn1.NullRawValue.FullBytes
if len(unmarshaled.Bytes) == 0 { if len(unmarshaled.Bytes) == 0 {
// DeepEqual considers a nil slice and an empty slice to be different. // DeepEqual considers a nil slice and an empty slice to be different.
unmarshaled.Bytes = NullRawValue.Bytes unmarshaled.Bytes = asn1.NullRawValue.Bytes
} }
if !reflect.DeepEqual(NullRawValue, unmarshaled) { if !reflect.DeepEqual(asn1.NullRawValue, unmarshaled) {
t.Errorf("Expected Unmarshal of NullBytes to yield %v, got %v", NullRawValue, unmarshaled) t.Errorf("Expected Unmarshal of NullBytes to yield %v, got %v", asn1.NullRawValue, unmarshaled)
} }
} }
func TestExplicitTagRawValueStruct(t *testing.T) { func TestExplicitTagRawValueStruct(t *testing.T) {
type foo struct { type foo struct {
A RawValue `asn1:"optional,explicit,tag:5"` A asn1.RawValue `asn1:"optional,explicit,tag:5"`
B []byte `asn1:"optional,explicit,tag:6"` B []byte `asn1:"optional,explicit,tag:6"`
} }
before := foo{B: []byte{1, 2, 3}} before := foo{B: []byte{1, 2, 3}}
derBytes, err := Marshal(before) derBytes, err := Marshal(before)
@ -1064,10 +1065,10 @@ func TestExplicitTagRawValueStruct(t *testing.T) {
func TestTaggedRawValue(t *testing.T) { func TestTaggedRawValue(t *testing.T) {
type taggedRawValue struct { type taggedRawValue struct {
A RawValue `asn1:"tag:5"` A asn1.RawValue `asn1:"tag:5"`
} }
type untaggedRawValue struct { type untaggedRawValue struct {
A RawValue A asn1.RawValue
} }
const isCompound = 0x20 const isCompound = 0x20
const tag = 5 const tag = 5

View File

@ -5,6 +5,7 @@
package asn1 package asn1
import ( import (
"encoding/asn1"
"errors" "errors"
"fmt" "fmt"
"math/big" "math/big"
@ -152,7 +153,7 @@ func appendBase128Int(dst []byte, n int64) []byte {
func makeBigInt(n *big.Int) (encoder, error) { func makeBigInt(n *big.Int) (encoder, error) {
if n == nil { if n == nil {
return nil, StructuralError{"empty integer"} return nil, asn1.StructuralError{"empty integer"}
} }
if n.Sign() < 0 { if n.Sign() < 0 {
@ -228,7 +229,7 @@ func appendTagAndLength(dst []byte, t tagAndLength) []byte {
return dst return dst
} }
type bitStringEncoder BitString type bitStringEncoder asn1.BitString
func (b bitStringEncoder) Len() int { func (b bitStringEncoder) Len() int {
return len(b.Bytes) + 1 return len(b.Bytes) + 1
@ -260,7 +261,7 @@ func (oid oidEncoder) Encode(dst []byte) {
func makeObjectIdentifier(oid []int) (e encoder, err error) { func makeObjectIdentifier(oid []int) (e encoder, err error) {
if len(oid) < 2 || oid[0] > 2 || (oid[0] < 2 && oid[1] >= 40) { if len(oid) < 2 || oid[0] > 2 || (oid[0] < 2 && oid[1] >= 40) {
return nil, StructuralError{"invalid object identifier"} return nil, asn1.StructuralError{"invalid object identifier"}
} }
return oidEncoder(oid), nil return oidEncoder(oid), nil
@ -275,7 +276,7 @@ func makePrintableString(s string) (e encoder, err error) {
// certificates, however when making new certificates // certificates, however when making new certificates
// it is rejected. // it is rejected.
if !isPrintable(s[i], allowAsterisk, rejectAmpersand) { if !isPrintable(s[i], allowAsterisk, rejectAmpersand) {
return nil, StructuralError{"PrintableString contains invalid character"} return nil, asn1.StructuralError{"PrintableString contains invalid character"}
} }
} }
@ -285,7 +286,7 @@ func makePrintableString(s string) (e encoder, err error) {
func makeIA5String(s string) (e encoder, err error) { func makeIA5String(s string) (e encoder, err error) {
for i := 0; i < len(s); i++ { for i := 0; i < len(s); i++ {
if s[i] > 127 { if s[i] > 127 {
return nil, StructuralError{"IA5String contains invalid character"} return nil, asn1.StructuralError{"IA5String contains invalid character"}
} }
} }
@ -295,7 +296,7 @@ func makeIA5String(s string) (e encoder, err error) {
func makeNumericString(s string) (e encoder, err error) { func makeNumericString(s string) (e encoder, err error) {
for i := 0; i < len(s); i++ { for i := 0; i < len(s); i++ {
if !isNumeric(s[i]) { if !isNumeric(s[i]) {
return nil, StructuralError{"NumericString contains invalid character"} return nil, asn1.StructuralError{"NumericString contains invalid character"}
} }
} }
@ -355,7 +356,7 @@ func appendUTCTime(dst []byte, t time.Time) (ret []byte, err error) {
case 2000 <= year && year < 2050: case 2000 <= year && year < 2050:
dst = appendTwoDigits(dst, year-2000) dst = appendTwoDigits(dst, year-2000)
default: default:
return nil, StructuralError{"cannot represent time as UTCTime"} return nil, asn1.StructuralError{"cannot represent time as UTCTime"}
} }
return appendTimeCommon(dst, t), nil return appendTimeCommon(dst, t), nil
@ -364,7 +365,7 @@ func appendUTCTime(dst []byte, t time.Time) (ret []byte, err error) {
func appendGeneralizedTime(dst []byte, t time.Time) (ret []byte, err error) { func appendGeneralizedTime(dst []byte, t time.Time) (ret []byte, err error) {
year := t.Year() year := t.Year()
if year < 0 || year > 9999 { if year < 0 || year > 9999 {
return nil, StructuralError{"cannot represent time as GeneralizedTime"} return nil, asn1.StructuralError{"cannot represent time as GeneralizedTime"}
} }
dst = appendFourDigits(dst, year) dst = appendFourDigits(dst, year)
@ -425,9 +426,9 @@ func makeBody(value reflect.Value, params fieldParameters) (e encoder, err error
} }
return makeUTCTime(t) return makeUTCTime(t)
case bitStringType: case bitStringType:
return bitStringEncoder(value.Interface().(BitString)), nil return bitStringEncoder(value.Interface().(asn1.BitString)), nil
case objectIdentifierType: case objectIdentifierType:
return makeObjectIdentifier(value.Interface().(ObjectIdentifier)) return makeObjectIdentifier(value.Interface().(asn1.ObjectIdentifier))
case bigIntType: case bigIntType:
return makeBigInt(value.Interface().(*big.Int)) return makeBigInt(value.Interface().(*big.Int))
} }
@ -445,7 +446,7 @@ func makeBody(value reflect.Value, params fieldParameters) (e encoder, err error
for i := 0; i < t.NumField(); i++ { for i := 0; i < t.NumField(); i++ {
if t.Field(i).PkgPath != "" { if t.Field(i).PkgPath != "" {
return nil, StructuralError{"struct contains unexported fields"} return nil, asn1.StructuralError{"struct contains unexported fields"}
} }
} }
@ -534,7 +535,7 @@ func makeBody(value reflect.Value, params fieldParameters) (e encoder, err error
} }
} }
return nil, StructuralError{"unknown Go type"} return nil, asn1.StructuralError{"unknown Go type"}
} }
func makeField(v reflect.Value, params fieldParameters) (e encoder, err error) { func makeField(v reflect.Value, params fieldParameters) (e encoder, err error) {
@ -569,7 +570,7 @@ func makeField(v reflect.Value, params fieldParameters) (e encoder, err error) {
} }
if v.Type() == rawValueType { if v.Type() == rawValueType {
rv := v.Interface().(RawValue) rv := v.Interface().(asn1.RawValue)
if len(rv.FullBytes) != 0 { if len(rv.FullBytes) != 0 {
return bytesEncoder(rv.FullBytes), nil return bytesEncoder(rv.FullBytes), nil
} }
@ -584,15 +585,15 @@ func makeField(v reflect.Value, params fieldParameters) (e encoder, err error) {
matchAny, tag, isCompound, ok := getUniversalType(v.Type()) matchAny, tag, isCompound, ok := getUniversalType(v.Type())
if !ok || matchAny { if !ok || matchAny {
return nil, StructuralError{fmt.Sprintf("unknown Go type: %v", v.Type())} return nil, asn1.StructuralError{fmt.Sprintf("unknown Go type: %v", v.Type())}
} }
if params.timeType != 0 && tag != TagUTCTime { if params.timeType != 0 && tag != TagUTCTime {
return nil, StructuralError{"explicit time type given to non-time member"} return nil, asn1.StructuralError{"explicit time type given to non-time member"}
} }
if params.stringType != 0 && tag != TagPrintableString { if params.stringType != 0 && tag != TagPrintableString {
return nil, StructuralError{"explicit string type given to non-string member"} return nil, asn1.StructuralError{"explicit string type given to non-string member"}
} }
switch tag { switch tag {
@ -621,7 +622,7 @@ func makeField(v reflect.Value, params fieldParameters) (e encoder, err error) {
if params.set { if params.set {
if tag != TagSequence { if tag != TagSequence {
return nil, StructuralError{"non sequence tagged as set"} return nil, asn1.StructuralError{"non sequence tagged as set"}
} }
tag = TagSet tag = TagSet
} }

View File

@ -6,6 +6,7 @@ package asn1
import ( import (
"bytes" "bytes"
"encoding/asn1"
"encoding/hex" "encoding/hex"
"math/big" "math/big"
"reflect" "reflect"
@ -32,7 +33,7 @@ type nestedStruct struct {
} }
type rawContentsStruct struct { type rawContentsStruct struct {
Raw RawContent Raw asn1.RawContent
A int A int
} }
@ -45,7 +46,7 @@ type explicitTagTest struct {
} }
type flagTest struct { type flagTest struct {
A Flag `asn1:"tag:0,optional"` A asn1.Flag `asn1:"tag:0,optional"`
} }
type generalizedTimeTest struct { type generalizedTimeTest struct {
@ -65,7 +66,7 @@ type genericStringTest struct {
} }
type optionalRawValueTest struct { type optionalRawValueTest struct {
A RawValue `asn1:"optional"` A asn1.RawValue `asn1:"optional"`
} }
type omitEmptyTest struct { type omitEmptyTest struct {
@ -129,11 +130,11 @@ var marshalTests = []marshalTest{
{time.Unix(1258325776, 0).In(PST), "17113039313131353134353631362d30383030"}, {time.Unix(1258325776, 0).In(PST), "17113039313131353134353631362d30383030"},
{farFuture(), "180f32313030303430353132303130315a"}, {farFuture(), "180f32313030303430353132303130315a"},
{generalizedTimeTest{time.Unix(1258325776, 0).UTC()}, "3011180f32303039313131353232353631365a"}, {generalizedTimeTest{time.Unix(1258325776, 0).UTC()}, "3011180f32303039313131353232353631365a"},
{BitString{[]byte{0x80}, 1}, "03020780"}, {asn1.BitString{[]byte{0x80}, 1}, "03020780"},
{BitString{[]byte{0x81, 0xf0}, 12}, "03030481f0"}, {asn1.BitString{[]byte{0x81, 0xf0}, 12}, "03030481f0"},
{ObjectIdentifier([]int{1, 2, 3, 4}), "06032a0304"}, {asn1.ObjectIdentifier([]int{1, 2, 3, 4}), "06032a0304"},
{ObjectIdentifier([]int{1, 2, 840, 133549, 1, 1, 5}), "06092a864888932d010105"}, {asn1.ObjectIdentifier([]int{1, 2, 840, 133549, 1, 1, 5}), "06092a864888932d010105"},
{ObjectIdentifier([]int{2, 100, 3}), "0603813403"}, {asn1.ObjectIdentifier([]int{2, 100, 3}), "0603813403"},
{"test", "130474657374"}, {"test", "130474657374"},
{ {
"" + "" +
@ -168,7 +169,7 @@ var marshalTests = []marshalTest{
{genericStringTest{"test&"}, "30070c057465737426"}, {genericStringTest{"test&"}, "30070c057465737426"},
{rawContentsStruct{nil, 64}, "3003020140"}, {rawContentsStruct{nil, 64}, "3003020140"},
{rawContentsStruct{[]byte{0x30, 3, 1, 2, 3}, 64}, "3003010203"}, {rawContentsStruct{[]byte{0x30, 3, 1, 2, 3}, 64}, "3003010203"},
{RawValue{Tag: 1, Class: 2, IsCompound: false, Bytes: []byte{1, 2, 3}}, "8103010203"}, {asn1.RawValue{Tag: 1, Class: 2, IsCompound: false, Bytes: []byte{1, 2, 3}}, "8103010203"},
{testSET([]int{10}), "310302010a"}, {testSET([]int{10}), "310302010a"},
{omitEmptyTest{[]string{}}, "3000"}, {omitEmptyTest{[]string{}}, "3000"},
{omitEmptyTest{[]string{"1"}}, "30053003130131"}, {omitEmptyTest{[]string{"1"}}, "30053003130131"},
@ -258,9 +259,9 @@ func TestMarshalOID(t *testing.T) {
var marshalTestsOID = []marshalTest{ var marshalTestsOID = []marshalTest{
{[]byte("\x06\x01\x30"), "0403060130"}, // bytes format returns a byte sequence \x04 {[]byte("\x06\x01\x30"), "0403060130"}, // bytes format returns a byte sequence \x04
// {ObjectIdentifier([]int{0}), "060100"}, // returns an error as OID 0.0 has the same encoding // {ObjectIdentifier([]int{0}), "060100"}, // returns an error as OID 0.0 has the same encoding
{[]byte("\x06\x010"), "0403060130"}, // same as above "\x06\x010" = "\x06\x01" + "0" {[]byte("\x06\x010"), "0403060130"}, // same as above "\x06\x010" = "\x06\x01" + "0"
{ObjectIdentifier([]int{2, 999, 3}), "0603883703"}, // Example of ITU-T X.690 {asn1.ObjectIdentifier([]int{2, 999, 3}), "0603883703"}, // Example of ITU-T X.690
{ObjectIdentifier([]int{0, 0}), "060100"}, // zero OID {asn1.ObjectIdentifier([]int{0, 0}), "060100"}, // zero OID
} }
for i, test := range marshalTestsOID { for i, test := range marshalTestsOID {
data, err := Marshal(test.in) data, err := Marshal(test.in)
@ -283,7 +284,7 @@ func TestIssue11130(t *testing.T) {
t.Errorf("%v", err) t.Errorf("%v", err)
return return
} }
if reflect.TypeOf(v).String() != reflect.TypeOf(ObjectIdentifier{}).String() { if reflect.TypeOf(v).String() != reflect.TypeOf(asn1.ObjectIdentifier{}).String() {
t.Errorf("marshal OID returned an invalid type") t.Errorf("marshal OID returned an invalid type")
return return
} }