@@ -51,6 +51,9 @@ import { EcdsaMPCv2KeyGenSendFn, KeyGenSenderForEnterprise } from './ecdsaMPCv2K
5151import { envRequiresBitgoPubGpgKeyConfig , isBitgoMpcPubKey } from '../../../tss/bitgoPubKeys' ;
5252
5353export class EcdsaMPCv2Utils extends BaseEcdsaUtils {
54+ private static readonly DKLS23_SIGNING_ROUND1_STATE = 'DKLS23_SIGNING_ROUND1_STATE' ;
55+ private static readonly DKLS23_SIGNING_ROUND2_STATE = 'DKLS23_SIGNING_ROUND2_STATE' ;
56+
5457 /** @inheritdoc */
5558 async createKeychains ( params : {
5659 passphrase : string ;
@@ -964,19 +967,23 @@ export class EcdsaMPCv2Utils extends BaseEcdsaUtils {
964967 * @param {string } bitgoPublicGpgKey - the BitGo public GPG key
965968 * @param {string } encryptedUserGpgPrvKey - the encrypted user GPG private key
966969 * @param {string } walletPassphrase - the wallet passphrase
970+ * @param {string } adata - the additional data to validate the GPG keys
967971 * @returns {Promise<{ bitgoGpgKey: pgp.Key; userGpgKey: pgp.SerializedKeyPair<string> }> } - the BitGo and user GPG keys
968972 */
969973 private async getBitgoAndUserGpgKeys (
970974 bitgoPublicGpgKey : string ,
971975 encryptedUserGpgPrvKey : string ,
972- walletPassphrase : string
976+ walletPassphrase : string ,
977+ adata : string
973978 ) : Promise < {
974979 bitgoGpgKey : pgp . Key ;
975980 userGpgKey : pgp . SerializedKeyPair < string > ;
976981 } > {
977982 const bitgoGpgKey = await pgp . readKey ( { armoredKey : bitgoPublicGpgKey } ) ;
983+ const armoredUserPrvKey = this . bitgo . decrypt ( { input : encryptedUserGpgPrvKey , password : walletPassphrase } ) ;
984+ this . validateAdata ( adata , armoredUserPrvKey ) ;
978985 const userDecryptedKey = await pgp . readKey ( {
979- armoredKey : this . bitgo . decrypt ( { input : encryptedUserGpgPrvKey , password : walletPassphrase } ) ,
986+ armoredKey : armoredUserPrvKey ,
980987 } ) ;
981988 const userGpgKey : pgp . SerializedKeyPair < string > = {
982989 privateKey : userDecryptedKey . armor ( ) ,
@@ -995,15 +1002,20 @@ export class EcdsaMPCv2Utils extends BaseEcdsaUtils {
9951002 * @returns void
9961003 * @throws {Error } if the adata or cyphertext is invalid
9971004 */
998- private validateAdata ( adata : string , cyphertext : string ) : void {
1005+ private validateAdata ( adata : string , cyphertext : string , roundDomainSeparator ?: string ) : void {
9991006 let cypherJson ;
10001007 try {
10011008 cypherJson = JSON . parse ( cyphertext ) ;
10021009 } catch ( e ) {
10031010 throw new Error ( 'Failed to parse cyphertext to JSON, got: ' + cyphertext ) ;
10041011 }
10051012 // using decodeURIComponent to handle special characters
1006- if ( decodeURIComponent ( cypherJson . adata ) !== decodeURIComponent ( adata ) ) {
1013+ if (
1014+ ( roundDomainSeparator
1015+ ? decodeURIComponent ( cypherJson . adata ) !== decodeURIComponent ( `${ roundDomainSeparator } :${ adata } ` )
1016+ : true ) &&
1017+ decodeURIComponent ( cypherJson . adata ) !== decodeURIComponent ( adata )
1018+ ) {
10071019 throw new Error ( 'Adata does not match cyphertext adata' ) ;
10081020 }
10091021 }
@@ -1124,7 +1136,11 @@ export class EcdsaMPCv2Utils extends BaseEcdsaUtils {
11241136 const userSignerBroadcastMsg1 = await userSigner . init ( ) ;
11251137 const signatureShareRound1 = await getSignatureShareRoundOne ( userSignerBroadcastMsg1 , userGpgKey ) ;
11261138 const session = userSigner . getSession ( ) ;
1127- const encryptedRound1Session = this . bitgo . encrypt ( { input : session , password : walletPassphrase , adata } ) ;
1139+ const encryptedRound1Session = this . bitgo . encrypt ( {
1140+ input : session ,
1141+ password : walletPassphrase ,
1142+ adata : `${ EcdsaMPCv2Utils . DKLS23_SIGNING_ROUND1_STATE } :${ adata } ` ,
1143+ } ) ;
11281144
11291145 const userGpgPubKey = userGpgKey . publicKey ;
11301146 const encryptedUserGpgPrvKey = this . bitgo . encrypt ( {
@@ -1155,7 +1171,8 @@ export class EcdsaMPCv2Utils extends BaseEcdsaUtils {
11551171 const { bitgoGpgKey, userGpgKey } = await this . getBitgoAndUserGpgKeys (
11561172 bitgoPublicGpgKey ,
11571173 encryptedUserGpgPrvKey ,
1158- walletPassphrase
1174+ walletPassphrase ,
1175+ adata
11591176 ) ;
11601177
11611178 const signatureShares = txRequest . transactions ?. [ 0 ] . signatureShares ;
@@ -1174,7 +1191,7 @@ export class EcdsaMPCv2Utils extends BaseEcdsaUtils {
11741191
11751192 const round1Session = this . bitgo . decrypt ( { input : encryptedRound1Session , password : walletPassphrase } ) ;
11761193
1177- this . validateAdata ( adata , encryptedRound1Session ) ;
1194+ this . validateAdata ( adata , encryptedRound1Session , EcdsaMPCv2Utils . DKLS23_SIGNING_ROUND1_STATE ) ;
11781195 const userKeyShare = Buffer . from ( prv , 'base64' ) ;
11791196 const userSigner = new DklsDsg . Dsg ( userKeyShare , 0 , derivationPath , hashBuffer ) ;
11801197 await userSigner . setSession ( round1Session ) ;
@@ -1195,7 +1212,11 @@ export class EcdsaMPCv2Utils extends BaseEcdsaUtils {
11951212 bitgoGpgKey
11961213 ) ;
11971214 const session = userSigner . getSession ( ) ;
1198- const encryptedRound2Session = this . bitgo . encrypt ( { input : session , password : walletPassphrase , adata } ) ;
1215+ const encryptedRound2Session = this . bitgo . encrypt ( {
1216+ input : session ,
1217+ password : walletPassphrase ,
1218+ adata : `${ EcdsaMPCv2Utils . DKLS23_SIGNING_ROUND2_STATE } :${ adata } ` ,
1219+ } ) ;
11991220
12001221 return {
12011222 signatureShareRound2,
@@ -1223,7 +1244,8 @@ export class EcdsaMPCv2Utils extends BaseEcdsaUtils {
12231244 const { bitgoGpgKey, userGpgKey } = await this . getBitgoAndUserGpgKeys (
12241245 bitgoPublicGpgKey ,
12251246 encryptedUserGpgPrvKey ,
1226- walletPassphrase
1247+ walletPassphrase ,
1248+ adata
12271249 ) ;
12281250
12291251 const signatureShares = txRequest . transactions ?. [ 0 ] . signatureShares ;
@@ -1246,7 +1268,7 @@ export class EcdsaMPCv2Utils extends BaseEcdsaUtils {
12461268 } ) ;
12471269
12481270 const round2Session = this . bitgo . decrypt ( { input : encryptedRound2Session , password : walletPassphrase } ) ;
1249- this . validateAdata ( adata , encryptedRound2Session ) ;
1271+ this . validateAdata ( adata , encryptedRound2Session , EcdsaMPCv2Utils . DKLS23_SIGNING_ROUND2_STATE ) ;
12501272 const userKeyShare = Buffer . from ( prv , 'base64' ) ;
12511273 const userSigner = new DklsDsg . Dsg ( userKeyShare , 0 , derivationPath , hashBuffer ) ;
12521274 await userSigner . setSession ( round2Session ) ;
0 commit comments