package asn1
import (
)
const (
TagBoolean = 1
TagInteger = 2
TagBitString = 3
TagOctetString = 4
TagNull = 5
TagOID = 6
TagEnum = 10
TagUTF8String = 12
TagSequence = 16
TagSet = 17
TagNumericString = 18
TagPrintableString = 19
TagT61String = 20
TagIA5String = 22
TagUTCTime = 23
TagGeneralizedTime = 24
TagGeneralString = 27
TagBMPString = 30
)
const (
ClassUniversal = 0
ClassApplication = 1
ClassContextSpecific = 2
ClassPrivate = 3
)
type tagAndLength struct {
class, tag, length int
isCompound bool
}
type fieldParameters struct {
optional bool
explicit bool
application bool
private bool
defaultValue *int64
tag *int
stringType int
timeType int
set bool
omitEmpty bool
}
func ( string) ( fieldParameters) {
var string
for len() > 0 {
, , _ = strings.Cut(, ",")
switch {
case == "optional":
.optional = true
case == "explicit":
.explicit = true
if .tag == nil {
.tag = new(int)
}
case == "generalized":
.timeType = TagGeneralizedTime
case == "utc":
.timeType = TagUTCTime
case == "ia5":
.stringType = TagIA5String
case == "printable":
.stringType = TagPrintableString
case == "numeric":
.stringType = TagNumericString
case == "utf8":
.stringType = TagUTF8String
case strings.HasPrefix(, "default:"):
, := strconv.ParseInt([8:], 10, 64)
if == nil {
.defaultValue = new(int64)
*.defaultValue =
}
case strings.HasPrefix(, "tag:"):
, := strconv.Atoi([4:])
if == nil {
.tag = new(int)
*.tag =
}
case == "set":
.set = true
case == "application":
.application = true
if .tag == nil {
.tag = new(int)
}
case == "private":
.private = true
if .tag == nil {
.tag = new(int)
}
case == "omitempty":
.omitEmpty = true
}
}
return
}
func ( reflect.Type) ( bool, int, , bool) {
switch {
case rawValueType:
return true, -1, false, true
case objectIdentifierType:
return false, TagOID, false, true
case bitStringType:
return false, TagBitString, false, true
case timeType:
return false, TagUTCTime, false, true
case enumeratedType:
return false, TagEnum, false, true
case bigIntType:
return false, TagInteger, false, true
}
switch .Kind() {
case reflect.Bool:
return false, TagBoolean, false, true
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return false, TagInteger, false, true
case reflect.Struct:
return false, TagSequence, true, true
case reflect.Slice:
if .Elem().Kind() == reflect.Uint8 {
return false, TagOctetString, false, true
}
if strings.HasSuffix(.Name(), "SET") {
return false, TagSet, true, true
}
return false, TagSequence, true, true
case reflect.String:
return false, TagPrintableString, false, true
}
return false, 0, false, false
}