From 80652cb522e1457be43c78d08f9f3dc575f642c4 Mon Sep 17 00:00:00 2001 From: David Mihalcik Date: Tue, 4 Mar 2025 08:50:15 -0500 Subject: [PATCH 1/3] fix(core): Updates ec-wrapped to newer salt --- lib/ocrypto/asym_decryption.go | 7 +++++-- lib/ocrypto/asym_encryption.go | 6 ++++-- sdk/kas_client.go | 7 ++++++- sdk/tdf.go | 6 +++++- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/lib/ocrypto/asym_decryption.go b/lib/ocrypto/asym_decryption.go index 1982b58dc7..768a651dba 100644 --- a/lib/ocrypto/asym_decryption.go +++ b/lib/ocrypto/asym_decryption.go @@ -107,8 +107,11 @@ type ECDecryptor struct { } func NewECDecryptor(sk *ecdh.PrivateKey) (ECDecryptor, error) { - // TK Make these reasonable? IIRC salt should be longer, info maybe a parameters? - salt := []byte("salt") + // TK Move salt and info out of library, into API option functions + digest := sha256.New() + digest.Write([]byte("TDF")) + salt := digest.Sum(nil) + return ECDecryptor{sk, salt, nil}, nil } diff --git a/lib/ocrypto/asym_encryption.go b/lib/ocrypto/asym_encryption.go index f8cfd68b95..ef251322a2 100644 --- a/lib/ocrypto/asym_encryption.go +++ b/lib/ocrypto/asym_encryption.go @@ -81,8 +81,10 @@ func FromPublicPEM(publicKeyInPem string) (PublicKeyEncryptor, error) { func newECIES(pub *ecdh.PublicKey) (ECEncryptor, error) { ek, err := pub.Curve().GenerateKey(rand.Reader) - // TK Make these reasonable? IIRC salt should be longer, info maybe a parameters? - salt := []byte("salt") + // TK Move salt and info out of library, into API option functions + digest := sha256.New() + digest.Write([]byte("TDF")) + salt := digest.Sum(nil) return ECEncryptor{pub, ek, salt, nil}, err } diff --git a/sdk/kas_client.go b/sdk/kas_client.go index 8c685f25af..cfa426e35c 100644 --- a/sdk/kas_client.go +++ b/sdk/kas_client.go @@ -2,6 +2,7 @@ package sdk import ( "context" + "crypto/sha256" "errors" "fmt" "net" @@ -194,7 +195,11 @@ func (k *KASClient) handleECKeyResponse(response *kas.RewrapResponse) (map[strin if err != nil { return nil, fmt.Errorf("ocrypto.ComputeECDHKey failed: %w", err) } - sessionKey, err := ocrypto.CalculateHKDF([]byte("salt"), ecdhKey) + + digest := sha256.New() + digest.Write([]byte("TDF")) + salt := digest.Sum(nil) + sessionKey, err := ocrypto.CalculateHKDF(salt, ecdhKey) if err != nil { return nil, fmt.Errorf("ocrypto.CalculateHKDF failed: %w", err) } diff --git a/sdk/tdf.go b/sdk/tdf.go index 87d853a46f..d0bf2491c1 100644 --- a/sdk/tdf.go +++ b/sdk/tdf.go @@ -3,6 +3,7 @@ package sdk import ( "bytes" "context" + "crypto/sha256" "encoding/hex" "encoding/json" "errors" @@ -579,7 +580,10 @@ func generateWrapKeyWithEC(mode ocrypto.ECCMode, kasPublicKey string, symKey []b return ecKeyWrappedKeyInfo{}, fmt.Errorf("ocrypto.ComputeECDHKey failed:%w", err) } - sessionKey, err := ocrypto.CalculateHKDF([]byte("salt"), ecdhKey) + digest := sha256.New() + digest.Write([]byte("TDF")) + salt := digest.Sum(nil) + sessionKey, err := ocrypto.CalculateHKDF([]byte(salt), ecdhKey) if err != nil { return ecKeyWrappedKeyInfo{}, fmt.Errorf("ocrypto.CalculateHKDF failed:%w", err) } From 27c1d87cf0840887e9571adff70f4dea2ba140a7 Mon Sep 17 00:00:00 2001 From: David Mihalcik Date: Tue, 4 Mar 2025 11:24:13 -0500 Subject: [PATCH 2/3] Update tdf.go --- sdk/tdf.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/tdf.go b/sdk/tdf.go index d0bf2491c1..413603ae86 100644 --- a/sdk/tdf.go +++ b/sdk/tdf.go @@ -583,7 +583,7 @@ func generateWrapKeyWithEC(mode ocrypto.ECCMode, kasPublicKey string, symKey []b digest := sha256.New() digest.Write([]byte("TDF")) salt := digest.Sum(nil) - sessionKey, err := ocrypto.CalculateHKDF([]byte(salt), ecdhKey) + sessionKey, err := ocrypto.CalculateHKDF(salt, ecdhKey) if err != nil { return ecKeyWrappedKeyInfo{}, fmt.Errorf("ocrypto.CalculateHKDF failed:%w", err) } From 89f2520719606cd0ade155506586ad341b3454f5 Mon Sep 17 00:00:00 2001 From: David Mihalcik Date: Wed, 5 Mar 2025 10:28:30 -0500 Subject: [PATCH 3/3] fix 500s and other nonspecific errors in bulk --- service/kas/access/rewrap.go | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/service/kas/access/rewrap.go b/service/kas/access/rewrap.go index 7b7fd2e9d3..d8ac34fc33 100644 --- a/service/kas/access/rewrap.go +++ b/service/kas/access/rewrap.go @@ -367,6 +367,7 @@ func addResultsToResponse(response *kaspb.RewrapResponse, result policyKAOResult } } +// Gets the only value in a singleton map, or an arbitrary value from a map with multiple values. func getMapValue[Map ~map[K]V, K comparable, V any](m Map) *V { for _, v := range m { return &v @@ -427,7 +428,7 @@ func (p *Provider) Rewrap(ctx context.Context, req *connect.Request[kaspb.Rewrap kao := *getMapValue(kaoResults) if kao.Error != nil { - p.Logger.DebugContext(ctx, "forwarding legacy err", "err", err) + p.Logger.DebugContext(ctx, "forwarding legacy err", "err", kao.Error) return nil, kao.Error } resp.EntityWrappedKey = kao.Encapped //nolint:staticcheck // deprecated but keeping behavior for backwards compatibility @@ -469,39 +470,53 @@ func (p *Provider) verifyRewrapRequests(ctx context.Context, req *kaspb.Unsigned // Get EC key size and convert to mode keySize, err := ocrypto.GetECKeySize([]byte(ephemeralPubKeyPEM)) if err != nil { - return nil, results, fmt.Errorf("failed to get EC key size: %w", err) + p.Logger.WarnContext(ctx, "failed to get EC key size", "err", err, "kao", kao) + failedKAORewrap(results, kao, err400("bad request")) + continue } mode, err := ocrypto.ECSizeToMode(keySize) if err != nil { - return nil, results, fmt.Errorf("failed to convert key size to mode: %w", err) + p.Logger.WarnContext(ctx, "failed to convert key size to mode", "err", err, "kao", kao) + failedKAORewrap(results, kao, err400("bad request")) + continue } // Parse the PEM public key block, _ := pem.Decode([]byte(ephemeralPubKeyPEM)) if block == nil { - return nil, results, fmt.Errorf("failed to decode PEM block") + p.Logger.WarnContext(ctx, "failed to decode PEM block", "err", err, "kao", kao) + failedKAORewrap(results, kao, err400("bad request")) + continue } pub, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { - return nil, results, fmt.Errorf("failed to parse public key: %w", err) + p.Logger.WarnContext(ctx, "failed to parse public key", "err", err, "kao", kao) + failedKAORewrap(results, kao, err400("bad request")) + continue } ecPub, ok := pub.(*ecdsa.PublicKey) if !ok { - return nil, results, fmt.Errorf("not an EC public key") + p.Logger.WarnContext(ctx, "not an EC public key", "err", err) + failedKAORewrap(results, kao, err400("bad request")) + continue } // Compress the public key compressedKey, err := ocrypto.CompressedECPublicKey(mode, *ecPub) if err != nil { - return nil, results, fmt.Errorf("failed to compress public key: %w", err) + p.Logger.WarnContext(ctx, "failed to compress public key", "err", err) + failedKAORewrap(results, kao, err400("bad request")) + continue } symKey, err = p.CryptoProvider.ECDecrypt(kao.GetKeyAccessObject().GetKid(), compressedKey, kao.GetKeyAccessObject().GetWrappedKey()) if err != nil { - return nil, results, fmt.Errorf("failed to decrypt EC key: %w", err) + p.Logger.WarnContext(ctx, "failed to decrypt EC key", "err", err) + failedKAORewrap(results, kao, err400("bad request")) + continue } case "wrapped": var kidsToCheck []string