132 lines
2.2 KiB
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
|
|
}
|