@@ -197,11 +197,6 @@ export type RewrapRequest = {
197197
198198export type KasPublicKeyFormat = 'pkcs8' | 'jwks' ;
199199
200- export type RewrapResponse = {
201- entityWrappedKey : string ;
202- sessionPublicKey : string ;
203- } ;
204-
205200/**
206201 * If we have KAS url but not public key we can fetch it from KAS, fetching
207202 * the value from `${kas}/kas_public_key`.
@@ -791,19 +786,7 @@ async function unwrapKey({
791786
792787 const clientPublicKey = ephemeralEncryptionKeys . publicKey ;
793788
794- // TODO: how to handle defaults here?
795789 // Convert keySplitInfo to protobuf KeyAccess
796- // const keyAccessProto = create(KeyAccessSchema, {
797- // keyType: keySplitInfo.type || '',
798- // kasUrl: keySplitInfo.url || '',
799- // protocol: keySplitInfo.protocol || '',
800- // wrappedKey: keySplitInfo.wrappedKey ? new Uint8Array(base64.decodeArrayBuffer(keySplitInfo.wrappedKey)) : new Uint8Array(),
801- // policyBinding: keySplitInfo.policyBinding,
802- // kid: keySplitInfo.kid || '',
803- // splitId: keySplitInfo.sid || '',
804- // encryptedMetadata: keySplitInfo.encryptedMetadata || '',
805- // });
806-
807790 const keyAccessProto = create ( KeyAccessSchema , {
808791 ...( keySplitInfo . type && { keyType : keySplitInfo . type } ) ,
809792 ...( keySplitInfo . url && { kasUrl : keySplitInfo . url } ) ,
@@ -847,39 +830,57 @@ async function unwrapKey({
847830 authProvider ,
848831 fulfillableObligations
849832 ) ;
850- const { entityWrappedKey , metadata , sessionPublicKey } = rewrapResp ;
833+ const { sessionPublicKey } = rewrapResp ;
851834 const requiredObligations = getRequiredObligationFQNs ( rewrapResp ) ;
835+ // Assume only one response and one result for now (V1 style)
836+ const result = rewrapResp . responses [ 0 ] . results [ 0 ] ;
837+ const metadata = result . metadata ;
838+ // Handle the different cases of result.result
839+ switch ( result . result . case ) {
840+ case "kasWrappedKey" : {
841+ const entityWrappedKey = result . result . value ;
842+
843+ if ( wrappingKeyAlgorithm === 'ec:secp256r1' ) {
844+ const serverEphemeralKey : CryptoKey = await pemPublicToCrypto ( sessionPublicKey ) ;
845+ const ekr = ephemeralEncryptionKeysRaw as CryptoKeyPair ;
846+ const kek = await keyAgreement ( ekr . privateKey , serverEphemeralKey , {
847+ hkdfSalt : await ztdfSalt ,
848+ hkdfHash : 'SHA-256' ,
849+ } ) ;
850+ const wrappedKeyAndNonce = entityWrappedKey ;
851+ const iv = wrappedKeyAndNonce . slice ( 0 , 12 ) ;
852+ const wrappedKey = wrappedKeyAndNonce . slice ( 12 ) ;
852853
853- if ( wrappingKeyAlgorithm === 'ec:secp256r1' ) {
854- const serverEphemeralKey : CryptoKey = await pemPublicToCrypto ( sessionPublicKey ) ;
855- const ekr = ephemeralEncryptionKeysRaw as CryptoKeyPair ;
856- const kek = await keyAgreement ( ekr . privateKey , serverEphemeralKey , {
857- hkdfSalt : await ztdfSalt ,
858- hkdfHash : 'SHA-256' ,
859- } ) ;
860- const wrappedKeyAndNonce = entityWrappedKey ;
861- const iv = wrappedKeyAndNonce . slice ( 0 , 12 ) ;
862- const wrappedKey = wrappedKeyAndNonce . slice ( 12 ) ;
863-
864- const dek = await crypto . subtle . decrypt ( { name : 'AES-GCM' , iv } , kek , wrappedKey ) ;
865-
866- return {
867- key : new Uint8Array ( dek ) ,
868- metadata,
869- requiredObligations,
870- } ;
871- }
872- const key = Binary . fromArrayBuffer ( entityWrappedKey ) ;
873- const decryptedKeyBinary = await cryptoService . decryptWithPrivateKey (
874- key ,
875- ephemeralEncryptionKeys . privateKey
876- ) ;
854+ const dek = await crypto . subtle . decrypt ( { name : 'AES-GCM' , iv } , kek , wrappedKey ) ;
877855
878- return {
879- key : new Uint8Array ( decryptedKeyBinary . asByteArray ( ) ) ,
880- metadata,
881- requiredObligations,
882- } ;
856+ return {
857+ key : new Uint8Array ( dek ) ,
858+ metadata,
859+ requiredObligations,
860+ } ;
861+ }
862+ const key = Binary . fromArrayBuffer ( entityWrappedKey ) ;
863+ const decryptedKeyBinary = await cryptoService . decryptWithPrivateKey (
864+ key ,
865+ ephemeralEncryptionKeys . privateKey
866+ ) ;
867+
868+ return {
869+ key : new Uint8Array ( decryptedKeyBinary . asByteArray ( ) ) ,
870+ metadata,
871+ requiredObligations,
872+ } ;
873+ }
874+
875+ case "error" : {
876+ const errorMessage = result . result . value ;
877+ throw new DecryptError ( `KAS rewrap failed: ${ errorMessage } ` ) ;
878+ }
879+
880+ default : {
881+ throw new DecryptError ( 'KAS rewrap response missing wrapped key' ) ;
882+ }
883+ }
883884 }
884885
885886 let poolSize = 1 ;
0 commit comments