jasn1/x509/loader.go

73 lines
2 KiB
Go

package x509
import (
"jasn1/asn1"
)
func LoadCertificate(tree *asn1.Tag) *Certificate {
cert := Certificate {
Data: TBSCertificate { },
}
cert.Data.Version = tree.At(0, 0, 0).Uint8Value()
cert.Data.Serial = tree.At(0, 1).Value()
kind, name := tree.At(0, 2, 0).OidValue()
cert.Data.Signature.Kind = kind
cert.Data.Signature.Name = name
for _, branch := range tree.At(0, 3).Children() {
attr := Attribute {
Value: branch.At(0, 1).Value(),
}
attr.Kind, attr.Name = branch.At(0, 0).OidValue()
cert.Data.Issuer = append(cert.Data.Issuer, attr)
}
cert.Data.Validity.NotBefore = tree.At(0, 4, 0).DateValue()
cert.Data.Validity.NotAfter = tree.At(0, 4, 1).DateValue()
for _, branch := range tree.At(0, 5).Children() {
attr := Attribute {
Value: branch.At(0, 1).Value(),
}
attr.Kind, attr.Name = branch.At(0, 0).OidValue()
cert.Data.Subject = append(cert.Data.Subject, attr)
}
kind, name = tree.At(0, 6, 0, 0).OidValue()
cert.Data.SubjectPublicKey.Algorithm.Kind = kind
cert.Data.SubjectPublicKey.Algorithm.Name = name
key_data := tree.At(0, 6, 1).Value()
if key_data[0] == 0 {
key := asn1.DecodeByteString(key_data[1:])
// this probably shouldn't be hard coded to RSA
cert.Data.SubjectPublicKey.Modulus = key.At(0).Value()
cert.Data.SubjectPublicKey.Exponent = key.At(1).Uint64Value()
}
// this should probably be variable to handle all optional fields
if tree.At(0, 7).Class() == 2 {
for _, branch := range tree.At(0, 7, 0).Children() {
ext := Extension { }
ext.Kind, ext.Name = branch.At(0).OidValue()
if len(branch.Children()) > 2 {
ext.Critical = branch.At(1).BoolValue()
ext.Value = branch.At(2).Value()
} else {
ext.Value = branch.At(1).Value()
}
cert.Data.Exts = append(cert.Data.Exts, ext)
}
}
kind, name = tree.At(1, 0).OidValue()
cert.SignatureAlgo.Kind = kind
cert.SignatureAlgo.Name = name
cert.SignatureValue = tree.At(2).Value()
return &cert
}