Skip to content

Commit f80dcb5

Browse files
committed
feat(service): use public AES protected key from lib/ocrypto
Update service components to use the newly exposed AESProtectedKey implementation from lib/ocrypto instead of internal implementation. - Update trust/key_manager.go with type aliases for backward compatibility - Replace InProcessAESKey usage with ocrypto.NewAESProtectedKey() - Remove duplicate implementation from security package - Maintain all existing functionality and interfaces
1 parent 2960978 commit f80dcb5

File tree

4 files changed

+11
-119
lines changed

4 files changed

+11
-119
lines changed

service/internal/security/basic_manager.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ func (b *BasicManager) Decrypt(ctx context.Context, keyDetails trust.KeyDetails,
7575
if err != nil {
7676
return nil, fmt.Errorf("failed to decrypt with RSA: %w", err)
7777
}
78-
return NewInProcessAESKey(plaintext), nil
78+
return ocrypto.NewAESProtectedKey(plaintext), nil
7979
case policy.Algorithm_ALGORITHM_EC_P256.String(), policy.Algorithm_ALGORITHM_EC_P384.String(), policy.Algorithm_ALGORITHM_EC_P521.String():
8080
ecPrivKey, err := ocrypto.ECPrivateKeyFromPem(privKey)
8181
if err != nil {
@@ -89,7 +89,7 @@ func (b *BasicManager) Decrypt(ctx context.Context, keyDetails trust.KeyDetails,
8989
if err != nil {
9090
return nil, fmt.Errorf("failed to decrypt with ephemeral key: %w", err)
9191
}
92-
return NewInProcessAESKey(plaintext), nil
92+
return ocrypto.NewAESProtectedKey(plaintext), nil
9393
}
9494

9595
return nil, fmt.Errorf("unsupported algorithm: %s", keyDetails.Algorithm())
@@ -131,7 +131,7 @@ func (b *BasicManager) DeriveKey(ctx context.Context, keyDetails trust.KeyDetail
131131
if err != nil {
132132
return nil, fmt.Errorf("failed to calculate HKDF: %w", err)
133133
}
134-
return NewInProcessAESKey(key), nil
134+
return ocrypto.NewAESProtectedKey(key), nil
135135
}
136136

137137
func (b *BasicManager) GenerateECSessionKey(_ context.Context, ephemeralPublicKey string) (trust.Encapsulator, error) {

service/internal/security/in_process_provider.go

Lines changed: 2 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@ import (
44
"context"
55
"crypto"
66
"crypto/elliptic"
7-
"crypto/hmac"
8-
"crypto/sha256"
97
"errors"
10-
"fmt"
118
"log/slog"
129

1310
"github.com/opentdf/platform/lib/ocrypto"
@@ -17,87 +14,6 @@ import (
1714

1815
const inProcessSystemName = "opentdf.io/in-process"
1916

20-
// InProcessAESKey implements the trust.ProtectedKey interface with an in-memory secret key
21-
type InProcessAESKey struct {
22-
rawKey []byte
23-
logger *slog.Logger
24-
}
25-
26-
var _ trust.ProtectedKey = (*InProcessAESKey)(nil)
27-
28-
// NewInProcessAESKey creates a new instance of StandardUnwrappedKey
29-
func NewInProcessAESKey(rawKey []byte) *InProcessAESKey {
30-
return &InProcessAESKey{
31-
rawKey: rawKey,
32-
logger: slog.Default(),
33-
}
34-
}
35-
36-
func (k *InProcessAESKey) DecryptAESGCM(iv []byte, body []byte, tagSize int) ([]byte, error) {
37-
aesGcm, err := ocrypto.NewAESGcm(k.rawKey)
38-
if err != nil {
39-
return nil, err
40-
}
41-
42-
decryptedData, err := aesGcm.DecryptWithIVAndTagSize(iv, body, tagSize)
43-
if err != nil {
44-
return nil, err
45-
}
46-
47-
return decryptedData, nil
48-
}
49-
50-
// Export returns the raw key data, optionally encrypting it with the provided trust.Encapsulator
51-
func (k *InProcessAESKey) Export(encapsulator trust.Encapsulator) ([]byte, error) {
52-
if encapsulator == nil {
53-
if k.logger != nil {
54-
k.logger.Warn("exporting raw key data without encryption")
55-
}
56-
return k.rawKey, nil
57-
}
58-
59-
// If an encryptor is provided, encrypt the key data before returning
60-
encryptedKey, err := encapsulator.Encrypt(k.rawKey)
61-
if err != nil {
62-
if k.logger != nil {
63-
k.logger.Warn("failed to encrypt key data for export", slog.Any("err", err))
64-
}
65-
return nil, err
66-
}
67-
68-
return encryptedKey, nil
69-
}
70-
71-
// VerifyBinding checks if the policy binding matches the given policy data
72-
func (k *InProcessAESKey) VerifyBinding(ctx context.Context, policy, policyBinding []byte) error {
73-
if len(k.rawKey) == 0 {
74-
return errors.New("key data is empty")
75-
}
76-
77-
actualHMAC, err := k.generateHMACDigest(ctx, policy)
78-
if err != nil {
79-
return fmt.Errorf("unable to generate policy hmac: %w", err)
80-
}
81-
82-
if !hmac.Equal(actualHMAC, policyBinding) {
83-
return errors.New("policy hmac mismatch")
84-
}
85-
86-
return nil
87-
}
88-
89-
// generateHMACDigest is a helper to generate an HMAC digest from a message using the key
90-
func (k *InProcessAESKey) generateHMACDigest(ctx context.Context, msg []byte) ([]byte, error) {
91-
mac := hmac.New(sha256.New, k.rawKey)
92-
_, err := mac.Write(msg)
93-
if err != nil {
94-
if k.logger != nil {
95-
k.logger.WarnContext(ctx, "failed to compute hmac")
96-
}
97-
return nil, errors.New("policy hmac")
98-
}
99-
return mac.Sum(nil), nil
100-
}
10117

10218
func convertPEMToJWK(_ string) (string, error) {
10319
// Implement the conversion logic here or use an external library if available.
@@ -328,16 +244,13 @@ func (a *InProcessProvider) Decrypt(ctx context.Context, keyDetails trust.KeyDet
328244
return nil, err
329245
}
330246

331-
return &InProcessAESKey{
332-
rawKey: rawKey,
333-
logger: a.logger,
334-
}, nil
247+
return ocrypto.NewAESProtectedKey(rawKey), nil
335248
}
336249

337250
// DeriveKey generates a symmetric key for NanoTDF
338251
func (a *InProcessProvider) DeriveKey(_ context.Context, keyDetails trust.KeyDetails, ephemeralPublicKeyBytes []byte, curve elliptic.Curve) (trust.ProtectedKey, error) {
339252
k, err := a.cryptoProvider.GenerateNanoTDFSymmetricKey(string(keyDetails.ID()), ephemeralPublicKeyBytes, curve)
340-
return NewInProcessAESKey(k), err
253+
return ocrypto.NewAESProtectedKey(k), err
341254
}
342255

343256
// GenerateECSessionKey generates a session key for NanoTDF

service/internal/security/standard_crypto.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -488,8 +488,5 @@ func (s *StandardCrypto) Decrypt(_ context.Context, keyID trust.KeyIdentifier, c
488488
return nil, fmt.Errorf("unsupported key type for key ID [%s]", kid)
489489
}
490490

491-
return &InProcessAESKey{
492-
rawKey: rawKey,
493-
logger: slog.Default(),
494-
}, nil
491+
return ocrypto.NewAESProtectedKey(rawKey), nil
495492
}

service/trust/key_manager.go

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,13 @@ package trust
33
import (
44
"context"
55
"crypto/elliptic"
6-
)
7-
8-
type Encapsulator interface {
9-
// Encrypt wraps a secret key with the encapsulation key
10-
Encrypt(data []byte) ([]byte, error)
11-
12-
// PublicKeyInPemFormat Returns public key in pem format, or the empty string if not present
13-
PublicKeyInPemFormat() (string, error)
14-
15-
// For EC schemes, this method returns the public part of the ephemeral key.
16-
// Otherwise, it returns nil.
17-
EphemeralKey() []byte
18-
}
19-
20-
// ProtectedKey represents a decrypted key with operations that can be performed on it
21-
type ProtectedKey interface {
22-
// VerifyBinding checks if the policy binding matches the given policy data
23-
VerifyBinding(ctx context.Context, policy, binding []byte) error
246

25-
// Export returns the raw key data, optionally encrypting it with the provided encryptor
26-
Export(encryptor Encapsulator) ([]byte, error)
7+
"github.com/opentdf/platform/lib/ocrypto"
8+
)
279

28-
// Used to decrypt encrypted policies and metadata
29-
DecryptAESGCM(iv []byte, body []byte, tagSize int) ([]byte, error)
30-
}
10+
// Type aliases for backward compatibility - these interfaces are now defined in lib/ocrypto
11+
type Encapsulator = ocrypto.Encapsulator
12+
type ProtectedKey = ocrypto.ProtectedKey
3113

3214
// KeyManager combines key lookup functionality with cryptographic operations
3315
type KeyManager interface {

0 commit comments

Comments
 (0)