...

Source file src/github.com/lestrrat-go/jwx/jwe/serializer.go

Documentation: github.com/lestrrat-go/jwx/jwe

     1  package jwe
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/lestrrat-go/jwx/internal/base64"
     7  	"github.com/lestrrat-go/jwx/internal/json"
     8  
     9  	"github.com/lestrrat-go/jwx/internal/pool"
    10  	"github.com/pkg/errors"
    11  )
    12  
    13  // Compact encodes the given message into a JWE compact serialization format.
    14  //
    15  // Currently `Compact()` does not take any options, but the API is
    16  // set up as such to allow future expansions
    17  func Compact(m *Message, _ ...SerializerOption) ([]byte, error) {
    18  	if len(m.recipients) != 1 {
    19  		return nil, errors.New("wrong number of recipients for compact serialization")
    20  	}
    21  
    22  	recipient := m.recipients[0]
    23  
    24  	// The protected header must be a merge between the message-wide
    25  	// protected header AND the recipient header
    26  
    27  	// There's something wrong if m.protectedHeaders is nil, but
    28  	// it could happen
    29  	if m.protectedHeaders == nil {
    30  		return nil, errors.New("invalid protected header")
    31  	}
    32  
    33  	ctx := context.TODO()
    34  	hcopy, err := m.protectedHeaders.Clone(ctx)
    35  	if err != nil {
    36  		return nil, errors.Wrap(err, "failed to copy protected header")
    37  	}
    38  	hcopy, err = hcopy.Merge(ctx, m.unprotectedHeaders)
    39  	if err != nil {
    40  		return nil, errors.Wrap(err, "failed to merge unprotected header")
    41  	}
    42  	hcopy, err = hcopy.Merge(ctx, recipient.Headers())
    43  	if err != nil {
    44  		return nil, errors.Wrap(err, "failed to merge recipient header")
    45  	}
    46  
    47  	protected, err := hcopy.Encode()
    48  	if err != nil {
    49  		return nil, errors.Wrap(err, "failed to encode header")
    50  	}
    51  
    52  	encryptedKey := base64.Encode(recipient.EncryptedKey())
    53  	iv := base64.Encode(m.initializationVector)
    54  	cipher := base64.Encode(m.cipherText)
    55  	tag := base64.Encode(m.tag)
    56  
    57  	buf := pool.GetBytesBuffer()
    58  	defer pool.ReleaseBytesBuffer(buf)
    59  
    60  	buf.Grow(len(protected) + len(encryptedKey) + len(iv) + len(cipher) + len(tag) + 4)
    61  	buf.Write(protected)
    62  	buf.WriteByte('.')
    63  	buf.Write(encryptedKey)
    64  	buf.WriteByte('.')
    65  	buf.Write(iv)
    66  	buf.WriteByte('.')
    67  	buf.Write(cipher)
    68  	buf.WriteByte('.')
    69  	buf.Write(tag)
    70  
    71  	result := make([]byte, buf.Len())
    72  	copy(result, buf.Bytes())
    73  	return result, nil
    74  }
    75  
    76  // JSON encodes the message into a JWE JSON serialization format.
    77  //
    78  // If `WithPrettyFormat(true)` is passed as an option, the returned
    79  // value will be formatted using `json.MarshalIndent()`
    80  func JSON(m *Message, options ...SerializerOption) ([]byte, error) {
    81  	var pretty bool
    82  	for _, option := range options {
    83  		//nolint:forcetypeassert
    84  		switch option.Ident() {
    85  		case identPrettyFormat{}:
    86  			pretty = option.Value().(bool)
    87  		}
    88  	}
    89  
    90  	if pretty {
    91  		return json.MarshalIndent(m, "", "  ")
    92  	}
    93  	return json.Marshal(m)
    94  }
    95  

View as plain text