opentdf / platform

Persistent data centric security that extends owner control wherever data travels
BSD 3-Clause Clear License
18 stars 9 forks source link

KAS URL validation problem decrypting gRPC-created TDF3 in the browser over REST (KasUpsertError) #945

Open jakedoublev opened 4 months ago

jakedoublev commented 4 months ago

With an authenticated SDK in a Go service, I am able to successfully encrypt a TDF3 with the following:

attrValues := []string{"https://namespace.com/attr/attr1/value/value1"}

sdk.CreateTDF(enc, bytes.NewReader(b),
        sdk.WithDataAttributes(attrValues...),
        sdk.WithKasInformation(sdk.KASInfo{
            URL:       "http://localhost:8080", // the gRPC endpoint of the OpenTDF platform known to the Go service
            PublicKey: "",
        },
        ),
    )

When I save the bytes to a file, and cat it, I get:

PK??0   0.payload|??Y,zJ??[
?:^?\?7߶!]??q??Uy?lͶ?4?MS:?)v6??t??0.p?ycv?+?2?,i+%0?؁Ei1'U?`? 
MR??}9?"??fo?>?K????q?q(KUIK??1?pW.Ф:?\^ņ?ǝ<]Q?WhH?&?T
                                                      ????ux#?$<???H??P?Y???PK??00.manifest.json{"encryptionInformation":{"type":"split","policy":"eyJ1dWlkIjoiY2U0NDk5ZjAtMjQzZS0xMWVmLWFmNzYtMWU2Y2E5Zjg3OGQ1IiwiYm9keSI6eyJkYXRhQXR0cmlidXRlcyI6W3siYXR0cmlidXRlIjoiaHR0cHM6Ly9uYW1lc3BhY2UuY29tL2F0dHIvYXR0cjEvdmFsdWUvdmFsdWUxIiwiZGlzcGxheU5hbWUiOiIiLCJpc0RlZmF1bHQiOmZhbHNlLCJwdWJLZXkiOiIiLCJrYXNVUkwiOiIifV0sImRpc3NlbSI6W119fQ==","keyAccess":[{"type":"wrapped","url":"https://myhost:8080","protocol":"kas","wrappedKey":"ddqtkdDb1ZaXJqaTHth3hbgZ7Dlv+ptXckZ5Z5i8wHOu1ha5IOWp7dw5amnSx+1o6b94xNuvANW/1+IAf4AyiocKOfNwnL1/Enu6waWXAlRw5Ubkg0aTiC5ptCVzOvw7R5qhlAQqt7arufyCoA9EHHaG624qNbl+D4QsUocIM0h5zdyGjJFX9t5fnY87MGqla+4sot4PrwgeAEjgM2PK1Fe5SatPGkbxpVJLzyGHjBPP96cbGBVYZuA47Sgf+ccvQuO/pnxylSjC481PKa8Al5Mm9b+ZiXFzqQdC8Sw5JgksmMYSB/lwcTqRxuZYEEmejdEOn+u1Fc/rO7CWP7/OHA==","policyBinding":"MTM2MTc3Njg1ZGExN2IyOGYxNmY2M2ZmZDkxZDQ5MWNmMGJjMjBmMWYwZTVjZmYyYTNhYmMwMjA3NmY1ZDIyMQ=="}],"method":{"algorithm":"AES-256-GCM","iv":"","isStreamable":true},"integrityInformation":{"rootSignature":{"alg":"HS256","sig":"NzhkMTMzZmQ0NGFhOGQwMWVjMDg1YmUwMWI4MjNhNjVlNTg2OGU5NjRiMzBkYzIzZDIzNjUyMzEwNTY4NjJiMQ=="},"segmentHashAlg":"GMAC","segmentSizeDefault":2097152,"encryptedSegmentSizeDefault":2097180,"segments":[{"hash":"YWVmNTc1NzgyM2UzMjQzYzlmZTdmODQ4MDM4ZGVjYWQ=","segmentSize":148,"encryptedSegmentSize":176}]}},"payload":{"type":"reference","url":"0.payload","protocol":"zip","mimeType":"application/octet-stream","isEncrypted":true}}PoZUB??PK-??0?Y???    0.payloadPK-??0oZUB???0.manifest.jsonPKt?

When I decrypt in the browser using a TDF3Client from opentdf/client-web, I get an error KasUpsertError: Unexpected KAS url: [https://myhost:8080].

However, If I create my TDF3 in my Go service with the below, I get no such error in the browser and am able to decrypt successfully:

attrValues := []string{"https://namespace.com/attr/attr1/value/value1"}

sdk.CreateTDF(enc, bytes.NewReader(b),
        sdk.WithDataAttributes(attrValues...),
        sdk.WithKasInformation(sdk.KASInfo{
            URL:       "http://localhost:8080" + "/kas", // the REST endpoint found by the browser
            PublicKey: "",
        },
        ),
    )

When I inspect that TDF, it looks like:

PK}??0  0.payload?G??<֣?P?Nxib??$?ƚ
q???>?"ZB?f????5??J??Ÿ??g?BNn?>n?-?FٿA1??Dz-??۞:D???ZاM0??(+Zzk???????F?{`Gh?s???:G??~??1?'*??Z??;?m??J?\C?a???>?
                                         P?D?V??PK}??00.manifest.json{"encryptionInformation":{"type":"split","policy":"eyJ1dWlkIjoiNGJmMTM1NjYtMjQzZi0xMWVmLTgxOGEtMWU2Y2E5Zjg3OGQ1IiwiYm9keSI6eyJkYXRhQXR0cmlidXRlcyI6W3siYXR0cmlidXRlIjoiaHR0cHM6Ly9uYW1lc3BhY2UuY29tL2F0dHIvYXR0cjEvdmFsdWUvdmFsdWUxIiwiZGlzcGxheU5hbWUiOiIiLCJpc0RlZmF1bHQiOmZhbHNlLCJwdWJLZXkiOiIiLCJrYXNVUkwiOiIifV0sImRpc3NlbSI6W119fQ==","keyAccess":[{"type":"wrapped","url":"https://myhost:8080/kas","protocol":"kas","wrappedKey":"mkJt1Z/UmTrhL4vXXc0ERB9//Znf5v1DmOB+APAALgne+RQQHUVsZ5iJ+YyGBPRMSqj5OuSgO08OILCUZgfqxuEYAno9k1VoTY/Pl4Be/tUYp7G8YYuJNXK40/CxXu9z6KK+Rw/Jhh4KQrgWCgu+k8tn921Q469gC65lZqpGTEgRGHuVKiTtAUKGeFVkBG/rCluI2rV7DNUtLAqEsBQRyK3fls0J23tvBplXxJFFLShir8yCH2W28LhhinJl9q8qNCa1djjzUfnTEmf+I1ZOjrzlN0ksbABj6ZReH2Fq/U1NdPs6mIhvUNg2k23aYf3gtrWzHwtBgTWlm7+PR7KZMA==","policyBinding":"MTkxMmRmNjc3OTBjNzc0ZDM3MzU1YzMyYjU5NDEyNjhhZDA4MGE0YmIyY2JjZjBkZjgyZDAyODQ4NDJhYWJiZQ=="}],"method":{"algorithm":"AES-256-GCM","iv":"","isStreamable":true},"integrityInformation":{"rootSignature":{"alg":"HS256","sig":"NjYwMjE3MTA2NGZkNWU3ODMzYmRmNzk3MmZiMWU1M2E4YTI2MzhkM2I5YjMyYWIxNjk1MmIxNWVkYWI3ODg0OQ=="},"segmentHashAlg":"GMAC","segmentSizeDefault":2097152,"encryptedSegmentSizeDefault":2097180,"segments":[{"hash":"MDgwNzNlNmU5YzJkMWRhYjQ2ZDliZjQxMzE5ZGNjMGM=","segmentSize":148,"encryptedSegmentSize":176}]}},"payload":{"type":"reference","url":"0.payload","protocol":"zip","mimeType":"application/octet-stream","isEncrypted":true}}P??L??PK-}??0?D?V??  0.payloadPK-}??0??L???0.manifest.jsonPKt?

This appears to be incompatibility between TDF3s created through gRPC-driven flows and those created through RESTful flows.

jakedoublev commented 4 months ago

This could be related to #873 or the same issue, but I wasn't sure so wanted to document the steps to reproduce here.

jakedoublev commented 4 months ago

This might also be stemming from an issue in @opentdf/client-web instead as the validation error is client-side.

https://github.com/opentdf/client-web/blob/2dbca15deb0b590055c70a4ba93b828cd27ee3d1/lib/tdf3/src/tdf.ts#L484

https://github.com/opentdf/client-web/blob/2dbca15deb0b590055c70a4ba93b828cd27ee3d1/lib/tdf3/src/tdf.ts#L827

Adding both endpoints to the allowedKases in the client config options did not lead to successful decryption.