11import type { Readable } from 'readable-stream' ;
2- import type { UnsignedRecordsWriteMessage } from '../interfaces/records/types.js' ;
32import type { DerivedPrivateJwk , DerivedPublicJwk } from './hd-key.js' ;
3+ import type { RecordsWriteDescriptor , UnsignedRecordsWriteMessage } from '../interfaces/records/types.js' ;
44
55import { Encoder } from './encoder.js' ;
66import { Encryption } from './encryption.js' ;
@@ -20,7 +20,7 @@ export class Records {
2020 ancestorPrivateKey : DerivedPrivateJwk ,
2121 cipherStream : Readable
2222 ) : Promise < Readable > {
23- const { encryption , contextId, descriptor } = recordsWrite ;
23+ const { recordId , contextId, descriptor, encryption } = recordsWrite ;
2424
2525 // look for an encrypted symmetric key that is encrypted using the same scheme as the given derived private key
2626 const matchingEncryptedKey = encryption ! . keyEncryption . find ( key => key . derivationScheme === ancestorPrivateKey . derivationScheme ) ;
@@ -31,13 +31,11 @@ export class Records {
3131 ) ;
3232 }
3333
34- // NOTE: right now only `protocol-context` scheme is supported so we will assume that's the scheme without additional switch/if statements
35- // derive the leaf private key
36- const leafDerivationPath = [ KeyDerivationScheme . ProtocolContext , descriptor . protocol ! , contextId ! ] ;
34+ const fullDerivationPath = Records . constructKeyDerivationPath ( matchingEncryptedKey . derivationScheme , recordId , contextId , descriptor ) ;
3735
3836 // NOTE: right now only `ECIES-ES256K` algorithm is supported for asymmetric encryption,
3937 // so we will assume that's the algorithm without additional switch/if statements
40- const leafPrivateKey = await Records . deriveLeafPrivateKey ( ancestorPrivateKey , leafDerivationPath ) ;
38+ const leafPrivateKey = await Records . deriveLeafPrivateKey ( ancestorPrivateKey , fullDerivationPath ) ;
4139 const encryptedKeyBytes = Encoder . base64UrlToBytes ( matchingEncryptedKey . encryptedKey ) ;
4240 const ephemeralPublicKey = Secp256k1 . publicJwkToBytes ( matchingEncryptedKey . ephemeralPublicKey ) ;
4341 const keyEncryptionInitializationVector = Encoder . base64UrlToBytes ( matchingEncryptedKey . initializationVector ) ;
@@ -58,6 +56,51 @@ export class Records {
5856 return plaintextStream ;
5957 }
6058
59+ /**
60+ * Constructs full key derivation path using the specified scheme.
61+ */
62+ public static constructKeyDerivationPath (
63+ _keyDerivationScheme : KeyDerivationScheme ,
64+ recordId : string ,
65+ contextId : string | undefined ,
66+ descriptor : RecordsWriteDescriptor
67+ ) : string [ ] {
68+
69+ // NOTE: right now only `protocols` derivation scheme is supported so we will assume that's the scheme without additional switch/if statements
70+ const fullDerivationPath = Records . constructKeyDerivationPathUsingProtocolsScheme ( recordId , contextId , descriptor ) ;
71+ return fullDerivationPath ;
72+ }
73+
74+ /**
75+ * Constructs the full key derivation path using `protocols` scheme.
76+ */
77+ private static constructKeyDerivationPathUsingProtocolsScheme (
78+ recordId : string ,
79+ contextId : string | undefined ,
80+ descriptor : RecordsWriteDescriptor
81+ ) : string [ ] {
82+ // ensure `protocol` is defined
83+ // NOTE: no need to check `protocolPath` and `contextId` because earlier code ensures that if `protocol` is defined, those are defined also
84+ if ( descriptor . protocol === undefined ) {
85+ throw new DwnError (
86+ DwnErrorCode . RecordsProtocolsDerivationSchemeMissingProtocol ,
87+ 'Unable to construct key derivation path using `protocols` scheme because `protocol` is missing.'
88+ ) ;
89+ }
90+
91+ const protocolPathSegments = descriptor . protocolPath ! . split ( '/' ) ;
92+ const fullDerivationPath = [
93+ KeyDerivationScheme . Protocols ,
94+ descriptor . protocol ,
95+ contextId ! ,
96+ ...protocolPathSegments ,
97+ descriptor . dataFormat ,
98+ recordId
99+ ] ;
100+
101+ return fullDerivationPath ;
102+ }
103+
61104 /**
62105 * Derives a descendant public key given an ancestor public key.
63106 * NOTE: right now only `ECIES-ES256K` algorithm is supported for asymmetric encryption,
0 commit comments