uploads

package
v0.1.110 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 8, 2026 License: Apache-2.0 Imports: 12 Imported by: 0

Documentation

Overview

Package uploads provides helpers for client-side-encrypted upload storage: the wire envelope shape and Seal / Parse / Open functions that mirror the browser's encryption.ts. Consumers:

  • Client-side, on upload: Seal a fresh AES-256 key around the plaintext, wrap the key under the org's RSA-OAEP public key, and ship the JSON envelope.
  • Server-side, on upload: Parse the envelope to validate its shape without ever touching the plaintext.
  • Client-side, on break-glass read: Open the envelope, which verifies the JSON shell with Parse and AES-GCM-decrypts the ciphertext using an injected unwrap callback (typically a KMS AsymmetricDecrypt against the version recorded in the envelope).

Index

Constants

View Source
const EncryptionAlgorithm = "RSA_DECRYPT_OAEP_3072_SHA256"

EncryptionAlgorithm is the KMS algorithm string the client is hardcoded against. The org public key endpoint advertises this; SealEnvelope refuses to run against any other value rather than silently producing payloads no reader can decrypt.

Variables

This section is empty.

Functions

func OpenEnvelope

func OpenEnvelope(payload string, unwrapAESKey func(wrappedKey []byte) (aesKey []byte, err error)) ([]byte, error)

OpenEnvelope is the inverse of SealEnvelope. The caller supplies an unwrap function that decrypts the RSA-OAEP-wrapped AES key (typically a KMS AsymmetricDecrypt call against the version recorded in env.KeyVersion); this package stays GCP-free.

The split lets break-glass / reader code reuse the same AES-GCM / base64 logic the upload side uses, without forcing every SDK consumer to pull in cloud.google.com/go/kms.

func SealEnvelope

func SealEnvelope(plaintext []byte, publicKeyPEM, algorithm, keyVersion string) (string, error)

SealEnvelope produces the JSON-encoded payload string the upload service expects in the request's payload field. It mirrors the browser's hybrid AES-GCM / RSA-OAEP encryption minus the network call:

  1. Generate a fresh AES-256 key + 12-byte IV.
  2. AES-256-GCM encrypt the plaintext.
  3. Parse the SPKI PEM into an RSA public key.
  4. RSA-OAEP-SHA256 wrap the AES key.
  5. Base64-encode each binary field, marshal the envelope.

The algorithm parameter is the value advertised by the server's GetOrgPublicKey response; mismatch against the client's hardcoded EncryptionAlgorithm is a hard failure rather than silently producing payloads no reader can decrypt.

keyVersion is the CryptoKeyVersion (e.g. "1") that wrapped this envelope, recorded so post-rotation readers know which private key to call AsymmetricDecrypt against.

Types

type Envelope

type Envelope struct {
	Ciphertext   string `json:"ciphertext"`
	EncryptedKey string `json:"encryptedKey"`
	IV           string `json:"iv"`
	Timestamp    string `json:"timestamp"`

	// KeyVersion is the integer CryptoKeyVersion the client used for
	// RSA-OAEP wrapping (matches Cloud KMS' version numbering, e.g. "1").
	// Carried in the envelope so decrypters can pick the right version
	// regardless of what's currently the published primary — required
	// for any post-rotation read of pre-rotation blobs. Empty means "1"
	// for backward compatibility with envelopes uploaded before this
	// field existed.
	KeyVersion string `json:"keyVersion,omitempty"`
}

Envelope is the wire shape the client encrypts and the server stores as-is. All binary fields are base64-encoded; the server treats the JSON-encoded envelope as opaque and never inspects its contents.

func ParseEnvelope

func ParseEnvelope(payload string) (*Envelope, error)

ParseEnvelope decodes the JSON envelope without performing the RSA-OAEP/AES-GCM decryption. Useful on the upload path when the server wants to read non-sensitive metadata (Timestamp) without touching the plaintext.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL