From 999cf8c744213aaa8d32e5d06457f24deb78c8c9 Mon Sep 17 00:00:00 2001 From: Dave Mihalcik Date: Mon, 31 Aug 2026 22:07:27 -0400 Subject: [PATCH] chore(sdk): alias experimental/tdf manifest and assertion types `sdk/experimental/tdf` carried its own copies of the manifest and assertion types -- `Manifest`, `Segment`, `KeyAccess`, `Assertion`, `Statement`, `AssertionKey` and the rest -- structurally identical to the ones in `sdk` but distinct to the type system, so anything crossing the boundary needed conversion. Two copies of the JWT signing and verification logic also had to be kept in step by hand. Replaces both files' definitions with type aliases. `sdk` owns the definitions; this package re-exports them. Every exported name and every method survives: `Assertion.Sign` / `Verify` / `GetHash`, `Statement.UnmarshalJSON`, `AssertionKey.IsEmpty` / `Algorithm`, `AssertionVerificationKeys.Get` / `IsEmpty` and the five `String()` methods all come along with the aliased types, so importers compile unchanged. A manifest produced here can now be handed to the stable SDK without conversion, which is what the follow-up delegation needs. Two deliberate non-aliases: `Policy`, `PolicyBody` and `PolicyAttribute` stay local. `sdk.PolicyObject` declares `Body` as an anonymous struct over an unexported element type, so there is no nameable sdk equivalent to alias to. Exporting those in `sdk` first would make the alias possible; that is a separate change. `IntegrityAlgorithm` stays a distinct `int` type. `sdk.IntegrityAlgorithm` is itself `= int`, so no method can be attached to it, and aliasing would silently drop `String()` from this package's public API. The underlying values match, so the two convert freely. `kSplitKeyType`, `kPolicyBindingAlg`, `kGMACPayloadLength` and `calculateSignature` are retained verbatim: this package still builds its own manifests and they have callers in `writer.go` and `key_access.go`. The change that removes those callers removes these too. No behavior change. The package's existing tests pass unmodified. Signed-off-by: Dave Mihalcik --- sdk/experimental/tdf/assertion.go | 506 +++++++----------------------- sdk/experimental/tdf/manifest.go | 139 ++++---- 2 files changed, 176 insertions(+), 469 deletions(-) diff --git a/sdk/experimental/tdf/assertion.go b/sdk/experimental/tdf/assertion.go index db417a5479..b008cf543a 100644 --- a/sdk/experimental/tdf/assertion.go +++ b/sdk/experimental/tdf/assertion.go @@ -3,422 +3,126 @@ package tdf import ( - "encoding/json" - "errors" - "fmt" - - "github.com/gowebpki/jcs" - "github.com/lestrrat-go/jwx/v2/cert" - "github.com/lestrrat-go/jwx/v2/jwa" - "github.com/lestrrat-go/jwx/v2/jws" - "github.com/lestrrat-go/jwx/v2/jwt" - "github.com/opentdf/platform/lib/ocrypto" + "github.com/opentdf/platform/sdk" ) const ( - // SystemMetadataAssertionID is the standard ID for system metadata assertions - SystemMetadataAssertionID = "system-metadata" - // SystemMetadataSchemaV1 defines the schema version for system metadata - SystemMetadataSchemaV1 = "system-metadata-v1" // kAssertionSignature is the JWT claim key for assertion signatures kAssertionSignature = "assertionSig" // kAssertionHash is the JWT claim key for assertion hashes kAssertionHash = "assertionHash" ) -// AssertionConfig defines an assertion to be included in the TDF during creation. -// -// AssertionConfig extends Assertion with a signing key, enabling creation -// of cryptographically signed assertions. The signing key is used during -// TDF creation but is not stored in the final TDF. -// -// Required fields: -// - ID: Unique identifier for the assertion -// - Type: The kind of assertion (BaseAssertion, HandlingAssertion) -// - Scope: What the assertion applies to (PayloadScope, TrustedDataObjScope) -// - AppliesToState: When the assertion is relevant (Encrypted, Unencrypted) -// - Statement: The assertion content and metadata -// -// Optional fields: -// - SigningKey: Custom signing key (defaults to DEK with HS256) -// -// Example: -// -// assertion := AssertionConfig{ -// ID: "retention-policy", -// Type: HandlingAssertion, -// Scope: PayloadScope, -// AppliesToState: Unencrypted, -// Statement: Statement{ -// Format: "json", -// Schema: "retention-v1", -// Value: `{"retain_days": 90, "auto_delete": true}`, -// }, -// } -type AssertionConfig struct { - ID string `validate:"required"` - Type AssertionType `validate:"required"` - Scope Scope `validate:"required"` - AppliesToState AppliesToState `validate:"required"` - Statement Statement - SigningKey AssertionKey -} - -// Assertion represents a cryptographically signed assertion in the TDF manifest. -// -// Assertions provide integrity verification and handling instructions that are -// cryptographically bound to the TDF. They cannot be modified or copied to -// another TDF without detection due to the cryptographic binding. -// -// The assertion structure includes: -// - Metadata: ID, type, scope, and state applicability -// - Statement: The actual assertion content in structured format -// - Binding: Cryptographic signature ensuring integrity -// -// Assertions are verified during TDF reading to ensure they haven't been -// tampered with since TDF creation. -type Assertion struct { - ID string `json:"id"` - Type AssertionType `json:"type"` - Scope Scope `json:"scope"` - AppliesToState AppliesToState `json:"appliesToState,omitempty"` - Statement Statement `json:"statement"` - Binding Binding `json:"binding,omitempty"` -} - -var errAssertionVerifyKeyFailure = errors.New("assertion: failed to verify with provided key") - -// Sign signs the assertion with the given hash and signature using the key. -// It returns an error if the signing fails. -// The assertion binding is updated with the method and the signature. -func (a *Assertion) Sign(hash, sig string, key AssertionKey) error { - tok := jwt.New() - if err := tok.Set(kAssertionHash, hash); err != nil { - return fmt.Errorf("failed to set assertion hash: %w", err) - } - if err := tok.Set(kAssertionSignature, sig); err != nil { - return fmt.Errorf("failed to set assertion signature: %w", err) - } - - // sign the hash and signature - signedTok, err := jwt.Sign(tok, jwt.WithKey(jwa.KeyAlgorithmFrom(key.Alg.String()), key.Key)) - if err != nil { - return fmt.Errorf("signing assertion failed: %w", err) - } - - // set the binding - a.Binding.Method = JWS.String() - a.Binding.Signature = string(signedTok) - - return nil -} - -// Verify checks the binding signature of the assertion and -// returns the hash and the signature. It returns an error if the verification fails. -func (a Assertion) Verify(key AssertionKey) (string, string, error) { - parseOptions := []jwt.ParseOption{ - jwt.WithKey(jwa.KeyAlgorithmFrom(key.Alg.String()), key.Key), - } - - // Try to get a key from the JWS protected header if it exists - if decodedSig, err := jws.Parse([]byte(a.Binding.Signature)); err == nil && len(decodedSig.Signatures()) > 0 { //nolint:nestif // many keys - sig := decodedSig.Signatures()[0] - // First, try to get a JWK from the header - if jwkKey := sig.ProtectedHeaders().JWK(); jwkKey != nil { - var rawKey interface{} - if err := jwkKey.Raw(&rawKey); err == nil { - parseOptions = append(parseOptions, jwt.WithKey(sig.ProtectedHeaders().Algorithm(), rawKey)) - } - } - // Also try to get a key from x5c (certificate chain) header - if x5cChain := sig.ProtectedHeaders().X509CertChain(); x5cChain != nil && x5cChain.Len() > 0 { - // Get the first certificate (the signing certificate) - certBytes, ok := x5cChain.Get(0) - if ok { - // Parse the certificate to extract the public key - x509Cert, err := cert.Parse(certBytes) - if err == nil && x509Cert != nil { - parseOptions = append(parseOptions, jwt.WithKey(sig.ProtectedHeaders().Algorithm(), x509Cert.PublicKey)) - } - } - } - } - - tok, err := jwt.Parse([]byte(a.Binding.Signature), parseOptions...) - if err != nil { - return "", "", fmt.Errorf("%w: %w", errAssertionVerifyKeyFailure, err) - } - hashClaim, found := tok.Get(kAssertionHash) - if !found { - return "", "", errors.New("hash claim not found") - } - hash, ok := hashClaim.(string) - if !ok { - return "", "", errors.New("hash claim is not a string") - } - - sigClaim, found := tok.Get(kAssertionSignature) - if !found { - return "", "", errors.New("signature claim not found") - } - sig, ok := sigClaim.(string) - if !ok { - return "", "", errors.New("signature claim is not a string") - } - return hash, sig, nil -} - -// GetHash returns the hash of the assertion in hex format. -func (a Assertion) GetHash() ([]byte, error) { - // Clear out the binding - a.Binding = Binding{} - - // Marshal the assertion to JSON - assertionJSON, err := json.Marshal(a) - if err != nil { - return nil, fmt.Errorf("json.Marshal failed: %w", err) - } - - // Unmarshal the JSON into a map to manipulate it - var jsonObject map[string]interface{} - if err := json.Unmarshal(assertionJSON, &jsonObject); err != nil { - return nil, fmt.Errorf("json.Unmarshal failed: %w", err) - } - - // Remove the binding key - delete(jsonObject, "binding") - - // Marshal the map back to JSON - assertionJSON, err = json.Marshal(jsonObject) - if err != nil { - return nil, fmt.Errorf("json.Marshal failed: %w", err) - } - - // Transform the JSON using JCS - transformedJSON, err := jcs.Transform(assertionJSON) - if err != nil { - return nil, fmt.Errorf("jcs.Transform failed: %w", err) - } - - return ocrypto.SHA256AsHex(transformedJSON), nil -} - -func (s *Statement) UnmarshalJSON(data []byte) error { - // Define a custom struct for deserialization - type Alias Statement - aux := &struct { - Value json.RawMessage `json:"value,omitempty"` - *Alias - }{ - Alias: (*Alias)(s), - } - - if err := json.Unmarshal(data, &aux); err != nil { - return err - } - - // Attempt to decode Value as an object - var temp map[string]interface{} - if json.Unmarshal(aux.Value, &temp) == nil { - // Re-encode the object as a string and assign to Value - objAsString, err := json.Marshal(temp) - if err != nil { - return err - } - s.Value = string(objAsString) - } else { - // Assign raw string to Value - var str string - if err := json.Unmarshal(aux.Value, &str); err != nil { - return fmt.Errorf("value is neither a valid JSON object nor a string: %s", string(aux.Value)) - } - s.Value = str - } - - return nil -} - -// Statement includes information applying to the scope of the assertion. -// It could contain rights, handling instructions, or general metadata. -type Statement struct { - // Format describes the payload encoding format. (e.g. json) - Format string `json:"format,omitempty" validate:"required"` - // Schema describes the schema of the payload. (e.g. tdf) - Schema string `json:"schema,omitempty" validate:"required"` - // Value is the payload of the assertion. - Value string `json:"value,omitempty" validate:"required"` -} - -// Binding enforces cryptographic integrity of the assertion. -// So the can't be modified or copied to another tdf. -type Binding struct { - // Method used to bind the assertion. (e.g. jws) - Method string `json:"method,omitempty"` - // Signature of the assertion. - Signature string `json:"signature,omitempty"` -} - -// AssertionType represents the category of assertion being made. -// -// Different assertion types serve different purposes in TDF handling: -// - HandlingAssertion: Instructions for data processing, retention, deletion -// - BaseAssertion: General-purpose assertions including metadata, audit info -type AssertionType string - -const ( - // HandlingAssertion provides instructions for data handling and processing. - // Examples: retention policies, deletion schedules, processing requirements - HandlingAssertion AssertionType = "handling" - // BaseAssertion is a general-purpose assertion type for metadata and other content. - // Examples: audit information, system metadata, custom business logic - BaseAssertion AssertionType = "other" +// The assertion types below are aliases onto their [github.com/opentdf/platform/sdk] +// counterparts, which own the implementation. They are kept here so that +// existing importers of this experimental package continue to compile +// unchanged, and so that assertions produced here interoperate directly with +// the stable SDK. Prefer the sdk-scoped names in new code. +type ( + // AssertionConfig defines an assertion to be included in the TDF during + // creation. It extends [Assertion] with a signing key, which is used + // during TDF creation but is not stored in the final TDF. + // + // See [sdk.AssertionConfig]. + AssertionConfig = sdk.AssertionConfig + + // Assertion represents a cryptographically signed assertion in the TDF + // manifest. Assertions provide integrity verification and handling + // instructions that are cryptographically bound to the TDF, so they + // cannot be modified or copied to another TDF without detection. + // + // See [sdk.Assertion]. + Assertion = sdk.Assertion + + // Statement includes information applying to the scope of the assertion. + // It could contain rights, handling instructions, or general metadata. + // + // See [sdk.Statement]. + Statement = sdk.Statement + + // Binding enforces cryptographic integrity of the assertion, so it + // cannot be modified or copied to another TDF. + // + // See [sdk.Binding]. + Binding = sdk.Binding + + // AssertionType represents the category of assertion being made. + // + // See [sdk.AssertionType]. + AssertionType = sdk.AssertionType + + // Scope defines what component of the TDF the assertion applies to. + // + // See [sdk.Scope]. + Scope = sdk.Scope + + // AppliesToState indicates when the assertion is relevant in the TDF + // lifecycle: before decryption (Encrypted) or after (Unencrypted). + // + // See [sdk.AppliesToState]. + AppliesToState = sdk.AppliesToState + + // BindingMethod represents the cryptographic method used to bind + // assertions to the TDF. + // + // See [sdk.BindingMethod]. + BindingMethod = sdk.BindingMethod + + // AssertionKeyAlg represents the cryptographic algorithm for assertion + // signing keys. + // + // See [sdk.AssertionKeyAlg]. + AssertionKeyAlg = sdk.AssertionKeyAlg + + // AssertionKey represents a cryptographic key for signing and verifying + // assertions. For RS256 the Key is an RSA private key (or a + // [crypto.Signer] for hardware-backed keys); for HS256 it is the shared + // secret bytes. + // + // See [sdk.AssertionKey]. + AssertionKey = sdk.AssertionKey + + // AssertionVerificationKeys represents the verification keys for + // assertions, with an optional default for unlisted assertion IDs. + // + // See [sdk.AssertionVerificationKeys]. + AssertionVerificationKeys = sdk.AssertionVerificationKeys ) -// String returns the string representation of the assertion type. -func (at AssertionType) String() string { - return string(at) -} - -// Scope defines what component of the TDF the assertion applies to. -// -// Scope determines which part of the TDF structure the assertion governs: -// - TrustedDataObjScope: Assertion applies to the entire TDF object -// - PayloadScope: Assertion applies only to the encrypted payload data -type Scope string - const ( - // TrustedDataObjScope indicates the assertion applies to the complete TDF object. - // This includes manifest, key access objects, and payload. - TrustedDataObjScope Scope = "tdo" + // SystemMetadataAssertionID is the standard ID for system metadata assertions. + SystemMetadataAssertionID = sdk.SystemMetadataAssertionID + // SystemMetadataSchemaV1 defines the schema version for system metadata. + SystemMetadataSchemaV1 = sdk.SystemMetadataSchemaV1 + + // HandlingAssertion provides instructions for data handling and processing. + // Examples: retention policies, deletion schedules, processing requirements. + HandlingAssertion = sdk.HandlingAssertion + // BaseAssertion is a general-purpose assertion type for metadata and other + // content. Examples: audit information, system metadata, custom business logic. + BaseAssertion = sdk.BaseAssertion + + // TrustedDataObjScope indicates the assertion applies to the complete TDF + // object, including manifest, key access objects, and payload. + TrustedDataObjScope = sdk.TrustedDataObjScope // PayloadScope indicates the assertion applies only to the payload data. // This is the most common scope for data handling assertions. - PayloadScope Scope = "payload" -) - -// String returns the string representation of the scope. -func (s Scope) String() string { - return string(s) -} - -// AppliesToState indicates when the assertion is relevant in the TDF lifecycle. -// -// This determines whether the assertion should be processed before or after -// decryption, enabling different handling patterns: -// - Encrypted: Process before decryption (e.g., access logging) -// - Unencrypted: Process after decryption (e.g., content filtering) -type AppliesToState string - -const ( - // Encrypted means the assertion should be processed before payload decryption. - // Used for access control, audit logging, and pre-processing requirements. - Encrypted AppliesToState = "encrypted" - // Unencrypted means the assertion should be processed after payload decryption. - // Used for content analysis, post-processing, and data handling requirements. - Unencrypted AppliesToState = "unencrypted" -) - -// String returns the string representation of the applies to state. -func (ats AppliesToState) String() string { - return string(ats) -} + PayloadScope = sdk.PayloadScope -// BindingMethod represents the cryptographic method used to bind assertions to the TDF. -// -// The binding method ensures assertions cannot be modified or transferred -// to other TDFs without detection. -type BindingMethod string + // Encrypted means the assertion should be processed before payload + // decryption. Used for access control, audit logging, and pre-processing. + Encrypted = sdk.Encrypted + // Unencrypted means the assertion should be processed after payload + // decryption. Used for content analysis and post-processing. + Unencrypted = sdk.Unencrypted -const ( // JWS (JSON Web Signature) is the standard method for assertion binding. - // Uses JWT-based cryptographic signatures for tamper detection. - JWS BindingMethod = "jws" + JWS = sdk.JWS + + // AssertionKeyAlgRS256 uses RSA-SHA256 for assertion signatures. Suitable + // when assertions must be verified without access to the signing key. + AssertionKeyAlgRS256 = sdk.AssertionKeyAlgRS256 + // AssertionKeyAlgHS256 uses HMAC-SHA256 for assertion signatures. More + // efficient, and lets the TDF's DEK double as the signing key. + AssertionKeyAlgHS256 = sdk.AssertionKeyAlgHS256 ) - -// String returns the string representation of the binding method. -func (bm BindingMethod) String() string { - return string(bm) -} - -// AssertionKeyAlg represents the cryptographic algorithm for assertion signing keys. -// -// Different algorithms provide different security and compatibility characteristics: -// - RS256: RSA-based signatures, widely supported, good for public key scenarios -// - HS256: HMAC-based signatures, simpler, good for shared key scenarios -type AssertionKeyAlg string - -const ( - // AssertionKeyAlgRS256 uses RSA-SHA256 for assertion signatures. - // Suitable when assertions need to be verified by parties without access to signing keys. - AssertionKeyAlgRS256 AssertionKeyAlg = "RS256" - // AssertionKeyAlgHS256 uses HMAC-SHA256 for assertion signatures. - // More efficient, suitable when the same key used for TDF encryption can sign assertions. - AssertionKeyAlgHS256 AssertionKeyAlg = "HS256" -) - -// String returns the string representation of the algorithm. -func (a AssertionKeyAlg) String() string { - return string(a) -} - -// AssertionKey represents a cryptographic key for signing and verifying assertions. -// -// The key can be either RSA or HMAC-based depending on the algorithm: -// - RS256: Key should be an RSA private key (*rsa.PrivateKey or jwk.Key) -// - HS256: Key should be a byte slice containing the shared secret -// -// Example usage: -// -// // HMAC key using TDF's Data Encryption Key -// hmacKey := AssertionKey{ -// Alg: AssertionKeyAlgHS256, -// Key: dek, // 32-byte AES key -// } -// -// // RSA key for public key scenarios -// rsaKey := AssertionKey{ -// Alg: AssertionKeyAlgRS256, -// Key: privateKey, // *rsa.PrivateKey -// } -type AssertionKey struct { - // Alg specifies the cryptographic algorithm for this key - Alg AssertionKeyAlg - // Key contains the actual key material (type depends on algorithm). - // Can be raw key material or a crypto.Signer for hardware-backed keys (HSM/KMS). - Key interface{} -} - -// Algorithm returns the cryptographic algorithm of the key. -func (k AssertionKey) Algorithm() AssertionKeyAlg { - return k.Alg -} - -// IsEmpty returns true if the key has no algorithm or key material configured. -// Used to check if a default signing key should be used instead. -func (k AssertionKey) IsEmpty() bool { - return k.Key == nil && k.Alg == "" -} - -// AssertionVerificationKeys represents the verification keys for assertions. -type AssertionVerificationKeys struct { - // Default key to use if the key for the assertion ID is not found. - DefaultKey AssertionKey - // Map of assertion ID to key. - Keys map[string]AssertionKey -} - -// Get returns the key for the given assertion ID or the default key if the key is not found. -// If the default key is not set, it returns an empty key. -func (k AssertionVerificationKeys) Get(assertionID string) (AssertionKey, error) { - if key, ok := k.Keys[assertionID]; ok { - return key, nil - } - if k.DefaultKey.IsEmpty() { - return AssertionKey{}, nil - } - return k.DefaultKey, nil -} - -// IsEmpty returns true if the default key and the keys map are empty. -func (k AssertionVerificationKeys) IsEmpty() bool { - return k.DefaultKey.IsEmpty() && len(k.Keys) == 0 -} diff --git a/sdk/experimental/tdf/manifest.go b/sdk/experimental/tdf/manifest.go index 10f5eceb0f..e9268859eb 100644 --- a/sdk/experimental/tdf/manifest.go +++ b/sdk/experimental/tdf/manifest.go @@ -7,69 +7,83 @@ import ( "errors" "github.com/opentdf/platform/lib/ocrypto" + "github.com/opentdf/platform/sdk" ) +// These are unchanged copies of what sdk defines unexported. They stay +// here only while this package still builds manifests itself; the +// delegation that removes their last callers is a follow-up. const ( kGMACPayloadLength = 16 kSplitKeyType = "split" kPolicyBindingAlg = "HS256" ) -type RootSignature struct { - Algorithm string `json:"alg"` - Signature string `json:"sig"` -} - -type IntegrityInformation struct { - RootSignature `json:"rootSignature"` - SegmentHashAlgorithm string `json:"segmentHashAlg"` - DefaultSegmentSize int64 `json:"segmentSizeDefault"` - DefaultEncryptedSegSize int64 `json:"encryptedSegmentSizeDefault"` - Segments []Segment `json:"segments"` -} - -type KeyAccess struct { - KeyType string `json:"type"` - KasURL string `json:"url"` - Protocol string `json:"protocol"` - WrappedKey string `json:"wrappedKey"` - PolicyBinding interface{} `json:"policyBinding"` - EncryptedMetadata string `json:"encryptedMetadata,omitempty"` - KID string `json:"kid,omitempty"` - SplitID string `json:"sid,omitempty"` - SchemaVersion string `json:"schemaVersion,omitempty"` - EphemeralPublicKey string `json:"ephemeralPublicKey,omitempty"` -} - -type Method struct { - Algorithm string `json:"algorithm"` - IV string `json:"iv"` - IsStreamable bool `json:"isStreamable"` -} - -type Payload struct { - Type string `json:"type"` - URL string `json:"url"` - Protocol string `json:"protocol"` - MimeType string `json:"mimeType"` - IsEncrypted bool `json:"isEncrypted"` - // IntegrityInformation IntegrityInformation `json:"integrityInformation"` -} - -type EncryptionInformation struct { - KeyAccessType string `json:"type"` - Policy string `json:"policy"` - KeyAccessObjs []KeyAccess `json:"keyAccess"` - Method Method `json:"method"` - IntegrityInformation `json:"integrityInformation"` -} +// The manifest types below are aliases onto their +// [github.com/opentdf/platform/sdk] counterparts, which own the definitions. +// They are kept here so that existing importers of this experimental package +// continue to compile unchanged, and so a manifest produced here can be +// handed to the stable SDK without conversion. Prefer the sdk-scoped names in +// new code. +type ( + // RootSignature is the signature over the concatenated segment hashes. + // + // See [sdk.RootSignature]. + RootSignature = sdk.RootSignature + + // IntegrityInformation describes segment layout and the hashes that + // protect the payload. + // + // See [sdk.IntegrityInformation]. + IntegrityInformation = sdk.IntegrityInformation + + // KeyAccess is one wrapped key share addressed to a single KAS. + // + // See [sdk.KeyAccess]. + KeyAccess = sdk.KeyAccess + + // Method describes the payload encryption algorithm and IV. + // + // See [sdk.Method]. + Method = sdk.Method + + // Payload describes the encrypted payload entry in the archive. + // + // See [sdk.Payload]. + Payload = sdk.Payload + + // EncryptionInformation carries the policy, key access objects, and + // integrity information for a TDF. + // + // See [sdk.EncryptionInformation]. + EncryptionInformation = sdk.EncryptionInformation + + // Manifest is the TDF manifest written to manifest.json. + // + // See [sdk.Manifest]. + Manifest = sdk.Manifest + + // Segment is one encrypted chunk of the payload plus its integrity hash. + // + // See [sdk.Segment]. + Segment = sdk.Segment + + // PolicyBinding is the HMAC binding a key share to the policy. + // + // See [sdk.PolicyBinding]. + PolicyBinding = sdk.PolicyBinding + + // EncryptedMetadata is the AES-GCM envelope for a key access object's + // opaque metadata. + // + // See [sdk.EncryptedMetadata]. + EncryptedMetadata = sdk.EncryptedMetadata +) -type Manifest struct { - EncryptionInformation `json:"encryptionInformation"` - Payload `json:"payload"` - Assertions []Assertion `json:"assertions,omitempty"` - TDFVersion string `json:"schemaVersion,omitempty"` -} +// Policy, PolicyBody, and PolicyAttribute are deliberately not aliased onto +// [sdk.PolicyObject]: the sdk type declares Body as an anonymous struct over +// an unexported element type, so it has no nameable equivalent for these +// three. Exporting those in sdk first would make the alias possible. type PolicyAttribute struct { Attribute string `json:"attribute"` @@ -89,20 +103,9 @@ type PolicyBody struct { Dissem []string `json:"dissem"` } -type Segment struct { - Hash string `json:"hash"` - Size int64 `json:"segmentSize"` - EncryptedSize int64 `json:"encryptedSegmentSize"` -} -type PolicyBinding struct { - Alg string `json:"alg"` - Hash string `json:"hash"` -} -type EncryptedMetadata struct { - Cipher string `json:"ciphertext"` - Iv string `json:"iv"` -} - +// calculateSignature is an unchanged copy of the sdk function of the +// same name, retained only until this package stops building manifests +// itself. func calculateSignature(data []byte, secret []byte, alg IntegrityAlgorithm, isLegacyTDF bool) (string, error) { if alg == HS256 { hmac := ocrypto.CalculateSHA256Hmac(secret, data)