package ber type Class byte const ( classUniversal Class = iota << 6 classApplication classContextSpecific classPrivate classMask Class = 3 << 6 ) var classNames = map[Class]string{ classUniversal: "Universal", classApplication: "Application", classContextSpecific: "Context-specific", classPrivate: "Private", } func (c Class) String() string { return classNames[c] } type Kind byte const ( kindPrimitive Kind = iota << 5 kindConstructed kindMask Kind = 1 << 5 ) var kindNames = map[Kind]string{ kindPrimitive: "Primitive", kindConstructed: "Constructed", } func (k Kind) String() string { return kindNames[k] } type Tag int const ( tagEOT Tag = iota tagBoolean tagInteger tagBitString tagOctetString tagNull tagObjectIdentifier tagObjectDescriptor tagInstanceOf tagReal tagEnumerated tagEmbeddedPDV tagUTF8String tagRelativeOID _ _ tagSequence // SequenceOf tagSet // SetOf tagNumericString tagPrintableString tagTeletexString // T61String tagVideotexString tagIA5String tagUTCTime tagGeneralizedTime tagGraphicString tagVisibleString // ISO646String tagGeneralString tagUniversalString tagCharacterString tagBMPString tagMask Tag = (1 << 5) - 1 ) var tagNames = map[Tag]string{ tagEOT: "End-of-Content", tagBoolean: "Boolean", tagInteger: "Integer", tagBitString: "Bit String", tagOctetString: "Octet String", tagNull: "Null", tagObjectIdentifier: "Object Identifier", tagObjectDescriptor: "Object Descriptor", tagInstanceOf: "Instance Of", tagReal: "Real", tagEnumerated: "Enumerated", tagEmbeddedPDV: "Embedded PDV", tagUTF8String: "UTF8 String", tagRelativeOID: "Relative OID", tagSequence: "Sequence (Of)", tagSet: "Set (Of)", tagNumericString: "Numeric String", tagPrintableString: "Printable String", tagTeletexString: "Teletext String", tagVideotexString: "Videotex String", tagIA5String: "IA5 String", tagUTCTime: "UTC Time", tagGeneralizedTime: "Generalized Time", tagGraphicString: "Graphic String", tagVisibleString: "Visible String", tagGeneralString: "General String", tagUniversalString: "Universal String", tagCharacterString: "Character String", tagBMPString: "BMP String", } func (t Tag) String() string { return tagNames[t] } func Ident(b []byte) (Class, Kind, Tag, int) { var d, n int c := Class(b[0]) & classMask k := Kind(b[0]) & kindMask t := Tag(b[0]) & tagMask if t == tagMask { d, n = debase128(b[1:]) t = Tag(d) } return c, k, t, n + 1 } func Length(b []byte) (int, int) { if b[0]&0x80 != 0 { l := int(b[0] & 0x7f) i := unmarshalUint(b[1 : l+1]) return int(i), int(l + 1) } else { return int(b[0]), 1 } } func Unversal(b []byte) (int, bool) { c, _, t, _ := Ident(b) return int(t), c == classUniversal } func Application(b []byte) (int, bool) { c, _, t, _ := Ident(b) return int(t), c == classApplication } func ContextSpecific(b []byte) (int, bool) { c, _, t, _ := Ident(b) return int(t), c == classContextSpecific } func Private(b []byte) (int, bool) { c, _, t, _ := Ident(b) return int(t), c == classPrivate }