1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 |
- // Package asn1tools provides tools for managing ASN1 marshaled data.
- package asn1tools
- import (
- "github.com/jcmturner/gofork/encoding/asn1"
- )
- // MarshalLengthBytes returns the ASN1 encoded bytes for the length 'l'
- //
- // There are two forms: short (for lengths between 0 and 127), and long definite (for lengths between 0 and 2^1008 -1).
- //
- // Short form: One octet. Bit 8 has value "0" and bits 7-1 give the length.
- //
- // Long form: Two to 127 octets. Bit 8 of first octet has value "1" and bits 7-1 give the number of additional length octets. Second and following octets give the length, base 256, most significant digit first.
- func MarshalLengthBytes(l int) []byte {
- if l <= 127 {
- return []byte{byte(l)}
- }
- var b []byte
- p := 1
- for i := 1; i < 127; {
- b = append([]byte{byte((l % (p * 256)) / p)}, b...)
- p = p * 256
- l = l - l%p
- if l <= 0 {
- break
- }
- }
- return append([]byte{byte(128 + len(b))}, b...)
- }
- // GetLengthFromASN returns the length of a slice of ASN1 encoded bytes from the ASN1 length header it contains.
- func GetLengthFromASN(b []byte) int {
- if int(b[1]) <= 127 {
- return int(b[1])
- }
- // The bytes that indicate the length
- lb := b[2 : 2+int(b[1])-128]
- base := 1
- l := 0
- for i := len(lb) - 1; i >= 0; i-- {
- l += int(lb[i]) * base
- base = base * 256
- }
- return l
- }
- // GetNumberBytesInLengthHeader returns the number of bytes in the ASn1 header that indicate the length.
- func GetNumberBytesInLengthHeader(b []byte) int {
- if int(b[1]) <= 127 {
- return 1
- }
- // The bytes that indicate the length
- return 1 + int(b[1]) - 128
- }
- // AddASNAppTag adds an ASN1 encoding application tag value to the raw bytes provided.
- func AddASNAppTag(b []byte, tag int) []byte {
- r := asn1.RawValue{
- Class: asn1.ClassApplication,
- IsCompound: true,
- Tag: tag,
- Bytes: b,
- }
- ab, _ := asn1.Marshal(r)
- return ab
- }
- /*
- // The Marshal method of golang's asn1 package does not enable you to define wrapping the output in an application tag.
- // This method adds that wrapping tag.
- func AddASNAppTag(b []byte, tag int) []byte {
- // The ASN1 wrapping consists of 2 bytes:
- // 1st byte -> Identifier Octet - Application Tag
- // 2nd byte -> The length (this will be the size indicated in the input bytes + 2 for the additional bytes we add here.
- // Application Tag:
- //| Bit: | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
- //| Value: | 0 | 1 | 1 | From the RFC spec 4120 |
- //| Explanation | Defined by the ASN1 encoding rules for an application tag | A value of 1 indicates a constructed type | The ASN Application tag value |
- // Therefore the value of the byte is an integer = ( Application tag value + 96 )
- //b = append(MarshalLengthBytes(int(b[1])+2), b...)
- b = append(MarshalLengthBytes(len(b)), b...)
- b = append([]byte{byte(96 + tag)}, b...)
- return b
- }
- */
|