jasn1/asn1/tag.go

132 lines
2.2 KiB
Go

package asn1
import (
"fmt"
"strconv"
"time"
)
type TagType uint8
const (
INTEGER = 0x02
BIT_STRING = 0x03
OCTET_STRING = 0x04
NULL = 0x05
OBJECT_IDENTIFIER = 0x06
UTF8_STRING = 0x0C
SEQUENCE_OF = 0x10
SET_OF = 0x11
PRINTABLE_STRING = 0x13
IA5_STRING = 0x16
UTC_TIME = 0x17
GENERALIZED_TIME = 0x18
)
type TagClass uint8
const (
UNIVERSAL = iota
APPLICATION
CONTEXT_SPECIFIC
PRIVATE
)
type Tag struct {
kind TagType
constructed bool
class TagClass
children []*Tag
value []byte
}
func (tag *Tag) String() string {
repr := fmt.Sprintf("Tag[kind:%d,", tag.kind)
if tag.constructed {
repr += fmt.Sprintf("children:%s]", tag.children)
} else {
repr += fmt.Sprintf("value:[% X]]", tag.value)
}
return repr
}
func (tag *Tag) At(idxs ...uint) *Tag {
var at_tag *Tag = tag
for _, idx := range idxs {
at_tag = at_tag.children[idx]
}
return at_tag
}
func (tag *Tag) Class() TagClass {
return tag.class
}
func (tag *Tag) Children() []*Tag {
return tag.children
}
func (tag *Tag) Value() []byte {
return tag.value
}
func (tag *Tag) BoolValue() bool {
return tag.value[0] == 0xFF
}
func (tag *Tag) Uint8Value() uint8 {
return tag.value[0]
}
func (tag *Tag) Uint64Value() uint64 {
return build_uint64(tag.value)
}
func (tag *Tag) DateValue() time.Time {
date, _ := time.Parse("060102150405Z", string(tag.value))
return date
}
func oid_to_str(components []uint64) string {
oid := strconv.FormatUint(components[0], 10)
for idx := 1; idx < len(components); idx += 1 {
oid += "." + strconv.FormatUint(components[idx], 10)
}
return oid
}
func (tag *Tag) OidValue() ([]uint64, string) {
component := uint64(0)
components := []uint64 { 0, }
for _, piece := range tag.value {
component = (component << 7) | uint64(piece & 0x7F)
if ((piece & 0x80) >> 7) == 0 {
components = append(components, component)
component = 0
}
}
if components[1] < 80 {
components[0] = components[1] / 40
components[1] = components[1] % 40
} else {
components[0] = 2
components[1] = components[1] - 80
}
oid, ok := OID_NAMES[oid_to_str(components)]
if !ok {
oid = "unknownObjectIdentifier"
}
return components, oid
}