github.com/egonelbre/exp@v0.0.0-20240430123955-ed1d3aa93911/ber/marshaling.go (about)

     1  /*
     2  Example how you would translate the ASN1 spec
     3  
     4    SignerInfo ::= SEQUENCE {
     5       version CMSVersion,
     6       sid SignerIdentifier,
     7       digestAlgorithm DigestAlgorithmIdentifier,
     8       signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL,
     9       signatureAlgorithm SignatureAlgorithmIdentifier,
    10       signature SignatureValue,
    11       unsignedAttrs [1] IMPLICIT UnsignedAttributes OPTIONAL }
    12  
    13     SignerIdentifier ::= CHOICE {
    14       issuerAndSerialNumber IssuerAndSerialNumber,
    15       subjectKeyIdentifier [0] SubjectKeyIdentifier }
    16  
    17     SignatureValue ::= OCTET STRING
    18  
    19  type asnSignerInfo struct {
    20  	Version            int64
    21  	Issuer             asnIssuerAndSerialNumber
    22  	SubjectKeyId       []byte
    23  	DigestAlgorithm    pkix.AlgorithmIdentifier
    24  	SignedAttrs        asnAttributeSet
    25  	SignatureAlgorithm pkix.AlgorithmIdentifier
    26  	Signature          []byte
    27  	UnsignedAttrs      asnAttributeSet
    28  }
    29  
    30  func (d *asnSignerInfo) marshaler() ber.Marshaler {
    31  	return ber.Sequence{
    32  		ber.Check{ber.Universal, ber.TagInteger, ber.Int64{&d.Version}},
    33  		ber.Choice{
    34  			ber.Check{ber.Universal, ber.TagSequence, &d.Issuer},
    35  			ber.Check{ber.Context, 0, ber.OctetString{&d.SubjectKeyId}},
    36  		},
    37  		ber.Check{ber.Universal, ber.TagSequence, (*asnAlgorithmIdentifier)(&d.DigestAlgorithm)},
    38  		ber.Optional{ber.Check{ber.Context, 0, &d.SignedAttrs}},
    39  		ber.Check{ber.Universal, ber.TagSequence, (*asnAlgorithmIdentifier)(&d.SignatureAlgorithm)},
    40  		ber.Check{ber.Universal, ber.TagOctetString, ber.OctetString{&d.Signature}},
    41  		ber.Optional{ber.Check{ber.Context, 1, &d.UnsignedAttrs}},
    42  	}
    43  }
    44  
    45  func (d *asnSignerInfo) Unmarshal(tree *ber.Tree) error { return d.marshaler().Unmarshal(tree) }
    46  func (d *asnSignerInfo) Marshal() (*ber.Tree, error) { return d.marshaler().Marshal() }
    47  */
    48  
    49  package ber
    50  
    51  // http://play.golang.org/p/MdL7k8-5ER
    52  
    53  import (
    54  	"encoding/asn1"
    55  	"errors"
    56  	"fmt"
    57  	"math/big"
    58  )
    59  
    60  // TODO: Optional/Check/Explicit should be all be a single type,
    61  // otherwise it's hard to make them work nicely with nesting
    62  
    63  type Marshaler interface {
    64  	Marshal() (*Tree, error)
    65  	Unmarshal(*Tree) error
    66  }
    67  
    68  type RawTree struct {
    69  	Tree **Tree
    70  }
    71  
    72  func (m RawTree) Unmarshal(tree *Tree) error {
    73  	*m.Tree = tree
    74  	return nil
    75  }
    76  
    77  func (m RawTree) Marshal() (*Tree, error) {
    78  	return *m.Tree, nil
    79  }
    80  
    81  type DER struct {
    82  	V *[]byte
    83  }
    84  
    85  func (m DER) Unmarshal(tree *Tree) (err error) {
    86  	*m.V, err = EncodeTree(tree)
    87  	return
    88  }
    89  
    90  func (m DER) Marshal() (*Tree, error) {
    91  	return DecodeTree(*m.V)
    92  }
    93  
    94  type ASN1RawValue struct {
    95  	V *asn1.RawValue
    96  }
    97  
    98  func (m ASN1RawValue) Unmarshal(tree *Tree) (err error) {
    99  	var data []byte
   100  	if data, err = EncodeTree(tree); err != nil {
   101  		return
   102  	}
   103  
   104  	_, err = asn1.Unmarshal(data, m.V)
   105  	return
   106  }
   107  
   108  func (m ASN1RawValue) Marshal() (*Tree, error) {
   109  	return ASN1Tree(m.V)
   110  }
   111  
   112  type Check struct {
   113  	Class int
   114  	Tag   int
   115  	Sub   Marshaler
   116  }
   117  
   118  func (m Check) Unmarshal(tree *Tree) (err error) {
   119  	if tree.Class != m.Class || tree.Tag != m.Tag {
   120  		return fmt.Errorf("class/tag doesn't match: got %d/%d expected %d/%d", tree.Class, tree.Tag, m.Class, m.Tag)
   121  	}
   122  	return m.Sub.Unmarshal(tree)
   123  }
   124  
   125  func (m Check) Marshal() (*Tree, error) {
   126  	tree, err := m.Sub.Marshal()
   127  	if err != nil {
   128  		return nil, err
   129  	}
   130  
   131  	tree.Class = m.Class
   132  	tree.Tag = m.Tag
   133  	return tree, nil
   134  }
   135  
   136  type Sequence []Marshaler
   137  
   138  func (s Sequence) Unmarshal(tree *Tree) (err error) {
   139  	children := tree.Children
   140  
   141  	var si, ti int
   142  	for si < len(s) {
   143  		m := s[si]
   144  		if opt, ok := m.(Optional); ok {
   145  			if ti >= len(children) {
   146  				si += 1
   147  				continue
   148  			}
   149  
   150  			switch optsub := opt.Sub.(type) {
   151  			case Check:
   152  				sub := children[ti]
   153  				if optsub.Class == sub.Class && optsub.Tag == sub.Tag {
   154  					if err = optsub.Sub.Unmarshal(sub); err != nil {
   155  						return
   156  					}
   157  					ti += 1
   158  				}
   159  				si += 1
   160  			default:
   161  				if err = optsub.Unmarshal(children[ti]); err != nil {
   162  					return
   163  				}
   164  				ti += 1
   165  				si += 1
   166  			}
   167  		} else {
   168  			if ti >= len(children) {
   169  				return fmt.Errorf("not enough children in tree")
   170  			}
   171  
   172  			sub := children[ti]
   173  			if err = m.Unmarshal(sub); err != nil {
   174  				return
   175  			}
   176  
   177  			ti += 1
   178  			si += 1
   179  		}
   180  	}
   181  	return
   182  }
   183  
   184  func (s Sequence) Marshal() (root *Tree, err error) {
   185  	root = &Tree{
   186  		Token: &Token{
   187  			Kind:  Constructed,
   188  			Class: Universal,
   189  			Tag:   TagSequence,
   190  		},
   191  	}
   192  
   193  	var sub *Tree
   194  	for _, m := range s {
   195  		if sub, err = m.Marshal(); err != nil {
   196  			return
   197  		}
   198  		if _, optional := m.(Optional); optional && sub == nil {
   199  			// we can safely skip this
   200  		} else {
   201  			if sub == nil {
   202  				err = errors.New("marshaling returned nil")
   203  				return
   204  			}
   205  			root.Children = append(root.Children, sub)
   206  		}
   207  	}
   208  	return
   209  }
   210  
   211  type Choice []Marshaler
   212  
   213  func (s Choice) Unmarshal(tree *Tree) (err error) {
   214  	for _, m := range s {
   215  		check, ok := m.(Check)
   216  		if !ok {
   217  			return fmt.Errorf("choice sequence doesn't contain check")
   218  		}
   219  
   220  		if check.Class == tree.Class && check.Tag == tree.Tag {
   221  			err = check.Unmarshal(tree)
   222  			return
   223  		}
   224  	}
   225  
   226  	return fmt.Errorf("applicable choice element not found")
   227  }
   228  
   229  func (s Choice) Marshal() (*Tree, error) {
   230  	// is there a way to handle this?
   231  	panic("choice shoudln't be used while marshaling")
   232  	return nil, nil
   233  }
   234  
   235  type Optional struct {
   236  	Sub Marshaler
   237  }
   238  
   239  func (m Optional) Unmarshal(tree *Tree) (err error) {
   240  	return m.Sub.Unmarshal(tree)
   241  }
   242  
   243  func isExplicit(s Marshaler) bool {
   244  	_, ok := s.(Explicit)
   245  	return ok
   246  }
   247  
   248  func isZero(tree *Tree) bool {
   249  	return (tree == nil) ||
   250  		(tree.Kind == Value && len(tree.Bytes) == 0) ||
   251  		(tree.Kind == Constructed && len(tree.Children) == 0)
   252  }
   253  
   254  func (m Optional) Marshal() (tree *Tree, err error) {
   255  	if tree, err = m.Sub.Marshal(); err != nil {
   256  		return
   257  	}
   258  
   259  	if isZero(tree) {
   260  		return nil, nil
   261  	} else if isExplicit(m.Sub) && isZero(tree.Children[0]) {
   262  		return nil, nil
   263  	}
   264  	return
   265  }
   266  
   267  type Explicit struct {
   268  	Sub Marshaler
   269  }
   270  
   271  func (m Explicit) Unmarshal(tree *Tree) (err error) {
   272  	if len(tree.Children) != 1 {
   273  		return fmt.Errorf("not enough values for explicit type")
   274  	}
   275  	return m.Sub.Unmarshal(tree.Children[0])
   276  }
   277  
   278  func (m Explicit) Marshal() (tree *Tree, err error) {
   279  	var sub *Tree
   280  	if sub, err = m.Sub.Marshal(); err != nil {
   281  		return
   282  	}
   283  	tree = &Tree{
   284  		Token: &Token{
   285  			Kind:  Constructed,
   286  			Class: Context,
   287  			Tag:   0,
   288  		},
   289  		Children: []*Tree{sub},
   290  	}
   291  	return
   292  }
   293  
   294  // TYPES
   295  
   296  type OctetString struct {
   297  	V *[]byte
   298  }
   299  
   300  func (m OctetString) Unmarshal(tree *Tree) error {
   301  	val, err := tree.AsOctetString()
   302  	*m.V = val
   303  	return err
   304  }
   305  
   306  func (m OctetString) Marshal() (*Tree, error) {
   307  	return &Tree{
   308  		Token: &Token{
   309  			Kind:  Value,
   310  			Class: Universal,
   311  			Tag:   TagOctetString,
   312  			Bytes: *m.V,
   313  		},
   314  	}, nil
   315  }
   316  
   317  type Int64 struct {
   318  	V *int64
   319  }
   320  
   321  func (m Int64) Unmarshal(tree *Tree) error {
   322  	val, err := tree.AsInt64()
   323  	*m.V = val
   324  	return err
   325  }
   326  
   327  func (m Int64) Marshal() (*Tree, error) {
   328  	return ASN1Tree(m.V)
   329  }
   330  
   331  type BigInt struct {
   332  	V **big.Int
   333  }
   334  
   335  func (m BigInt) Unmarshal(tree *Tree) error {
   336  	val, err := tree.AsBigInt()
   337  	*m.V = val
   338  	return err
   339  }
   340  func (m BigInt) Marshal() (*Tree, error) {
   341  	return ASN1Tree(m.V)
   342  }
   343  
   344  type ObjectIdentifier struct {
   345  	V *asn1.ObjectIdentifier
   346  }
   347  
   348  func (m ObjectIdentifier) Unmarshal(tree *Tree) error {
   349  	val, err := tree.AsObjectIdentifier()
   350  	*m.V = val
   351  	return err
   352  }
   353  func (m ObjectIdentifier) Marshal() (*Tree, error) {
   354  	return ASN1Tree(m.V)
   355  }
   356  
   357  func ASN1Tree(v interface{}) (*Tree, error) {
   358  	bytes, err := asn1.Marshal(v)
   359  	if err != nil {
   360  		return nil, err
   361  	}
   362  	return DecodeTree(bytes)
   363  }