github.com/grafana/pyroscope@v1.18.0/pkg/frontend/vcs/encryption.go (about)

     1  package vcs
     2  
     3  import (
     4  	"crypto/aes"
     5  	"crypto/cipher"
     6  	"crypto/rand"
     7  	"encoding/base64"
     8  	"encoding/json"
     9  	"errors"
    10  	"io"
    11  
    12  	"golang.org/x/oauth2"
    13  )
    14  
    15  func encryptToken(token *oauth2.Token, key []byte) (string, error) {
    16  	plaintext, err := json.Marshal(token)
    17  	if err != nil {
    18  		return "", err
    19  	}
    20  
    21  	block, err := aes.NewCipher(key)
    22  	if err != nil {
    23  		return "", err
    24  	}
    25  
    26  	gcm, err := cipher.NewGCM(block)
    27  	if err != nil {
    28  		return "", err
    29  	}
    30  
    31  	nonce := make([]byte, gcm.NonceSize())
    32  	if _, err = io.ReadFull(rand.Reader, nonce); err != nil {
    33  		return "", err
    34  	}
    35  
    36  	// Using nonce as Seal's dst argument results in it being the first
    37  	// chunk of bytes in the ciphertext. Decrypt retrieves the nonce/IV from this.
    38  	ciphertext := gcm.Seal(nonce, nonce, plaintext, nil)
    39  
    40  	return base64.StdEncoding.EncodeToString(ciphertext), nil
    41  }
    42  
    43  func decryptToken(ciphertextBase64 string, key []byte) (*oauth2.Token, error) {
    44  	ciphertext, err := base64.StdEncoding.DecodeString(ciphertextBase64)
    45  	if err != nil {
    46  		return nil, err
    47  	}
    48  
    49  	block, err := aes.NewCipher(key)
    50  	if err != nil {
    51  		return nil, err
    52  	}
    53  
    54  	gcm, err := cipher.NewGCM(block)
    55  	if err != nil {
    56  		return nil, err
    57  	}
    58  
    59  	nonceSize := gcm.NonceSize()
    60  	if len(ciphertext) < nonceSize {
    61  		return nil, errors.New("malformed token")
    62  	}
    63  	nonce, ciphertext := ciphertext[:nonceSize], ciphertext[nonceSize:]
    64  
    65  	plaintext, err := gcm.Open(nil, nonce, ciphertext, nil)
    66  	if err != nil {
    67  		return nil, err
    68  	}
    69  
    70  	var token oauth2.Token
    71  	if err = json.Unmarshal(plaintext, &token); err != nil {
    72  		return nil, err
    73  	}
    74  
    75  	return &token, nil
    76  }