cdoc2

package
v2.0.4 Latest Latest
Warning

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

Go to latest
Published: May 12, 2026 License: MIT Imports: 19 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// Label is the magic label for CDOC2 files (5 bytes: "CDOC\x02")
	Label = "CDOC\x02"

	// CEK is the label used for Content Encryption Key derivation via HKDF
	CEK = "CDOC20cek"

	// HMAC is the label used for HMAC key derivation via HKDF
	HMAC = "CDOC20hmac"

	// KEK is the label used for Key Encryption Key derivation via HKDF
	KEK = "CDOC20kek"

	// KEKPREMASTER is the label used for KEK premaster key derivation via HKDF
	KEKPREMASTER = "CDOC20kekpremaster"

	// PAYLOAD is the label used in AAD for payload encryption
	PAYLOAD = "CDOC20payload"

	// SALT is the label used for salt in HKDF extract operations
	SALT = "CDOC20salt"

	// KeyLen is the length of keys in bytes (32 bytes = 256 bits)
	KeyLen = 32

	// NonceLen is the length of nonces in bytes (12 bytes for ChaCha20-Poly1305)
	NonceLen = 12

	// KeyLabelVersion is the version of key label format
	KeyLabelVersion = 1
)

Variables

This section is empty.

Functions

func DeriveCEK

func DeriveCEK(fmk []byte) ([]byte, error)

DeriveCEK derives the Content Encryption Key from FMK CEK = HKDF-Expand(FMK, "CDOC20cek", 32)

func DeriveHMACKey

func DeriveHMACKey(fmk []byte) ([]byte, error)

DeriveHMACKey derives the HMAC key from FMK HMAC key = HKDF-Expand(FMK, "CDOC20hmac", 32)

func ExtractFMKFromLock

func ExtractFMKFromLock(lock Lock, privateKey interface{}, symmetricKey []byte, password string, action *KeyServerAction, pkcs11Token PKCS11TokenInterface) ([]byte, error)

ExtractFMKFromLock extracts the File Master Key (FMK) from a lock This handles RSA, ECC, Symmetric Key, Password, and Key Server recipients. For Symmetric: symmetricKey must be provided. For Password: password must be provided. For Key Server: action must be a *KeyServerAction (defined in reader.go) For PKCS#11: pkcs11Token must be a PKCS11TokenInterface (e.g., *PKCS11Token)

func GenerateFMK

func GenerateFMK() ([]byte, error)

GenerateFMK generates a File Master Key using random bytes and HKDF-Extract Returns a 32-byte FMK

func GetSaltForExpand

func GetSaltForExpand(label string) string

GetSaltForExpand creates the salt string for foxesHKDF Expand operation Used for deriving KEK from pre-master keys Pattern: KEK + FMKEncryptionMethodName + label

func GetSaltForExpandWithKeyMaterial

func GetSaltForExpandWithKeyMaterial(recipientKey, keyMaterial []byte) string

GetSaltForExpandWithKeyMaterial creates the salt string for HKDF Expand Pattern: KEK + FMKEncryptionMethodName + recipient_key + key_material

func VerifyHeaderHMAC

func VerifyHeaderHMAC(header *Header, hmacKey, expectedHMAC []byte) error

VerifyHeaderHMAC verifies the HMAC of the header using the provided HMAC key

func XOREncrypt

func XOREncrypt(data, key []byte) []byte

XOREncrypt performs XOR encryption/decryption For CDOC2, FMK is encrypted with XOR using a derived KEK

Types

type Capsule

type Capsule interface {
	// Type returns the capsule type identifier
	Type() string
}

Capsule represents different recipient capsule types

type DataFile

type DataFile struct {
	Name     string
	Content  io.Reader
	Size     int64
	MimeType string
}

DataFile represents a file to be encrypted in CDOC2

type ECCPublicKeyCapsule

type ECCPublicKeyCapsule struct {
	RecipientPublicKey []byte
	SenderPublicKey    []byte
}

func (ECCPublicKeyCapsule) Type

func (ECCPublicKeyCapsule) Type() string

type FMKEncryptionMethod

type FMKEncryptionMethod byte

FMKEncryptionMethod represents the encryption method for FMK

const (
	FMKEncryptionMethodUnknown FMKEncryptionMethod = iota
	FMKEncryptionMethodXOR
)

type FMKOptions

type FMKOptions struct {
	RSAPrivateKey   *rsa.PrivateKey
	ECDSAPrivateKey *ecdsa.PrivateKey
	SymmetricKey    []byte
	Password        string
	KeyServerAction *KeyServerAction
	PKCS11Token     PKCS11TokenInterface // Token interface for PKCS#11 hardware tokens
}

FMKOptions provides decryption inputs for different recipient types Only one of RSAPrivateKey or ECDSAPrivateKey should be set for PUBLIC_KEY For SYMMETRIC_KEY provide SymmetricKey; for PASSWORD provide Password For KEY_SERVER provide KeyServerAction For PKCS#11 tokens, provide PKCS11Token instead of private keys

type Header struct {
	Recipients              []RecipientRecord
	PayloadEncryptionMethod PayloadEncryptionMethod
	HeaderData              []byte // Raw header bytes for HMAC verification
}

Header represents a parsed CDOC2 header

func ParseHeader

func ParseHeader(reader io.Reader) (*Header, []byte, error)

ParseHeader parses a CDOC2 header from a reader It reads the magic label, header length, header data, and header HMAC Returns the parsed header and the header HMAC bytes

type KeyServerAction

type KeyServerAction struct {
	KeyServerClient *keyserver.Client
	KeyServerConfig keyserver.KeyServerConfig
}

KeyServerAction provides key server client and config for decryption

type KeyServerCapsule

type KeyServerCapsule struct {
	RecipientKey  []byte
	PKType        PKType
	KeyServerID   string
	TransactionID string
}

func (KeyServerCapsule) Type

func (KeyServerCapsule) Type() string

type KeyShare

type KeyShare struct {
	URL           string
	TransactionID string
}

type KeySharesCapsule

type KeySharesCapsule struct {
	Shares        []KeyShare
	Salt          []byte
	RecipientType byte
	Scheme        byte
	RecipientID   string
}

func (KeySharesCapsule) Type

func (KeySharesCapsule) Type() string

type Lock

type Lock struct {
	Type         LockType
	PKType       PKType
	Label        string
	EncryptedFMK []byte

	// For PUBLIC_KEY and SERVER types
	RecipientKey  []byte // Public key (RSA or ECC)
	KeyMaterial   []byte // Encrypted KEK (RSA) or ephemeral public key (ECC)
	ServerID      string // For SERVER type
	TransactionID string // For SERVER type

	// For SYMMETRIC_KEY type
	Salt []byte

	// For PASSWORD type
	PasswordSalt []byte
	KDFIter      int32 // PBKDF2 iterations

	// For certificate matching
	Certificate *x509.Certificate // Optional: parsed certificate for matching
}

Lock represents a recipient lock in CDOC2

func (*Lock) HasSameKey

func (l *Lock) HasSameKey(otherKey []byte) bool

HasSameKey checks if the lock's recipient key matches the provided public key

func (*Lock) IsECC

func (l *Lock) IsECC() bool

IsECC returns true if the lock uses ECC public key

func (*Lock) IsRSA

func (l *Lock) IsRSA() bool

IsRSA returns true if the lock uses RSA public key

func (*Lock) MatchesCertificate

func (l *Lock) MatchesCertificate(cert *x509.Certificate) (bool, error)

MatchesCertificate checks if the lock matches the given certificate

type LockType

type LockType int

LockType represents the type of lock/recipient

const (
	LockTypeUnknown      LockType = iota
	LockTypePublicKey             // RSA or ECC public key
	LockTypeServer                // Key server (Smart-ID/Mobile-ID)
	LockTypeSymmetricKey          // Symmetric key
	LockTypePassword              // Password-based (PBKDF2)
)

type PBKDF2Capsule

type PBKDF2Capsule struct {
	Salt         []byte
	PasswordSalt []byte
	Iterations   int32
}

func (PBKDF2Capsule) Type

func (PBKDF2Capsule) Type() string

type PKCS11TokenInterface

type PKCS11TokenInterface interface {
	// DecryptRSA decrypts RSA-encrypted data using the PKCS#11 token
	DecryptRSA(encryptedKey []byte) ([]byte, error)
	// DecryptECSharedSecret performs ECDH key agreement and returns the shared secret
	// For CDOC2, we only need the shared secret (not the full transport key unwrapping like CDOC 1.x)
	DecryptECSharedSecret(ephemeralPublicKey *ecdsa.PublicKey) ([]byte, error)
}

PKCS11TokenInterface is a minimal interface for PKCS#11 token operations needed by CDOC2 This avoids circular imports (cdoc2 cannot import cdoc package)

type PKType

type PKType int

PKType represents the public key type

const (
	PKTypeUnknown PKType = iota
	PKTypeRSA
	PKTypeECC
)

type PayloadEncryptionMethod

type PayloadEncryptionMethod byte

PayloadEncryptionMethod represents the encryption method for payload

const (
	PayloadEncryptionMethodUnknown PayloadEncryptionMethod = iota
	PayloadEncryptionMethodChaCha20Poly1305
)

type RSAPublicKeyCapsule

type RSAPublicKeyCapsule struct {
	RecipientPublicKey []byte
	EncryptedKEK       []byte
}

Capsule concrete types for parsed header mapping

func (RSAPublicKeyCapsule) Type

func (RSAPublicKeyCapsule) Type() string

type Reader

type Reader struct {
	// contains filtered or unexported fields
}

Reader implements reading and decrypting CDOC2 files

func NewReader

func NewReader(source io.ReaderAt) (*Reader, error)

NewReader creates a new CDOC2 Chrome reader source must support io.ReaderAt (e.g., *os.File, *bytes.Reader)

func (*Reader) AddKeyServerConfig

func (r *Reader) AddKeyServerConfig(config keyserver.KeyServerConfig)

AddKeyServerConfig adds a key server configuration

func (*Reader) BeginDecryption

func (r *Reader) BeginDecryption(fmk []byte) error

BeginDecryption starts the decryption process using the provided FMK

func (*Reader) ExtractFMK

func (r *Reader) ExtractFMK(lockIndex int, opts FMKOptions) ([]byte, error)

ExtractFMK extracts the File Master Key for the given lock index This performs the key derivation and decryption based on lock type

func (*Reader) FinishDecryption

func (r *Reader) FinishDecryption() error

FinishDecryption cleans up resources

func (*Reader) GetLocks

func (r *Reader) GetLocks() ([]Lock, error)

GetLocks returns all recipient locks from the header

func (*Reader) NextFile

func (r *Reader) NextFile() (name string, size int64, err error)

NextFile reads the next file from the decrypted TAR archive Returns file name, size, and an error Returns io.EOF when no more files are available

func (*Reader) Read

func (r *Reader) Read(p []byte) (int, error)

Read reads data from the current file in the TAR archive

func (*Reader) ReadHeader

func (r *Reader) ReadHeader() (*Header, error)

ReadHeader reads and parses the CDOC2 header This should be called first before decryption

func (*Reader) SetKeyServerClient

func (r *Reader) SetKeyServerClient(client *keyserver.Client)

SetKeyServerClient sets the key server client for the reader

type Recipient

type Recipient struct {
	Certificate   *x509.Certificate // For RSA/ECC recipients
	Password      string            // For password-based recipients
	SymmetricKey  []byte            // For symmetric key recipients
	Label         string            // Optional label
	ServerID      string            // For key-server recipients
	ExpiryTime    uint64            // Optional expiry time
	KDFIterations int32             // For password-based (PBKDF2)
}

Recipient represents a recipient for CDOC2 encryption

type RecipientRecord

type RecipientRecord struct {
	Capsule             Capsule
	KeyLabel            string
	EncryptedFMK        []byte
	FMKEncryptionMethod FMKEncryptionMethod
}

RecipientRecord represents a recipient in the CDOC2 header

type SymmetricKeyCapsule

type SymmetricKeyCapsule struct {
	Salt []byte
}

func (SymmetricKeyCapsule) Type

func (SymmetricKeyCapsule) Type() string

type Writer

type Writer struct {
	// contains filtered or unexported fields
}

Writer implements writing and encrypting CDOC2 files

func NewWriter

func NewWriter(destination io.Writer) *Writer

NewWriter creates a new CDOC2 writer

func (*Writer) AddFileToArchive

func (w *Writer) AddFileToArchive(name string, content io.Reader, size int64) error

AddFileToArchive adds a file to the TAR archive being built

func (*Writer) AddKeyServerConfig

func (w *Writer) AddKeyServerConfig(config keyserver.KeyServerConfig)

AddKeyServerConfig adds a key server configuration

func (*Writer) AddRecipient

func (w *Writer) AddRecipient(recipient Recipient) error

AddRecipient adds a recipient to the writer

func (*Writer) BeginEncryption

func (w *Writer) BeginEncryption() error

BeginEncryption starts the encryption process

func (*Writer) FinishEncryption

func (w *Writer) FinishEncryption() error

FinishEncryption finalizes the encryption and cleans up This should be called after all files have been added

func (*Writer) SetKeyServerClient

func (w *Writer) SetKeyServerClient(client *keyserver.Client)

SetKeyServerClient sets the key server client for the writer

func (*Writer) WriteEncryptedData

func (w *Writer) WriteEncryptedData(files []DataFile) error

WriteEncryptedData writes encrypted payload to destination

Directories

Path Synopsis
schema

Jump to

Keyboard shortcuts

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