@@ -52,6 +52,10 @@ import { EcdsaMPCv2KeyGenSendFn, KeyGenSenderForEnterprise } from './ecdsaMPCv2K
5252import { envRequiresBitgoPubGpgKeyConfig , isBitgoMpcPubKey } from '../../../tss/bitgoPubKeys' ;
5353
5454export class EcdsaMPCv2Utils extends BaseEcdsaUtils {
55+ private static readonly DKLS23_SIGNING_USER_GPG_KEY = 'DKLS23_SIGNING_USER_GPG_KEY' ;
56+ private static readonly DKLS23_SIGNING_ROUND1_STATE = 'DKLS23_SIGNING_ROUND1_STATE' ;
57+ private static readonly DKLS23_SIGNING_ROUND2_STATE = 'DKLS23_SIGNING_ROUND2_STATE' ;
58+
5559 /** @inheritdoc */
5660 async createKeychains ( params : {
5761 passphrase : string ;
@@ -968,17 +972,20 @@ export class EcdsaMPCv2Utils extends BaseEcdsaUtils {
968972 * @param {string } bitgoPublicGpgKey - the BitGo public GPG key
969973 * @param {string } encryptedUserGpgPrvKey - the encrypted user GPG private key
970974 * @param {string } walletPassphrase - the wallet passphrase
975+ * @param {string } adata - the additional data to validate the GPG keys
971976 * @returns {Promise<{ bitgoGpgKey: pgp.Key; userGpgKey: pgp.SerializedKeyPair<string> }> } - the BitGo and user GPG keys
972977 */
973978 private async getBitgoAndUserGpgKeys (
974979 bitgoPublicGpgKey : string ,
975980 encryptedUserGpgPrvKey : string ,
976- walletPassphrase : string
981+ walletPassphrase : string ,
982+ adata : string
977983 ) : Promise < {
978984 bitgoGpgKey : pgp . Key ;
979985 userGpgKey : pgp . SerializedKeyPair < string > ;
980986 } > {
981987 const bitgoGpgKey = await pgp . readKey ( { armoredKey : bitgoPublicGpgKey } ) ;
988+ this . validateAdata ( adata , encryptedUserGpgPrvKey , EcdsaMPCv2Utils . DKLS23_SIGNING_USER_GPG_KEY ) ;
982989 const userDecryptedKey = await pgp . readKey ( {
983990 armoredKey : this . bitgo . decrypt ( { input : encryptedUserGpgPrvKey , password : walletPassphrase } ) ,
984991 } ) ;
@@ -999,15 +1006,18 @@ export class EcdsaMPCv2Utils extends BaseEcdsaUtils {
9991006 * @returns void
10001007 * @throws {Error } if the adata or cyphertext is invalid
10011008 */
1002- private validateAdata ( adata : string , cyphertext : string ) : void {
1009+ private validateAdata ( adata : string , cyphertext : string , roundDomainSeparator : string ) : void {
10031010 let cypherJson ;
10041011 try {
10051012 cypherJson = JSON . parse ( cyphertext ) ;
10061013 } catch ( e ) {
10071014 throw new Error ( 'Failed to parse cyphertext to JSON, got: ' + cyphertext ) ;
10081015 }
10091016 // using decodeURIComponent to handle special characters
1010- if ( decodeURIComponent ( cypherJson . adata ) !== decodeURIComponent ( adata ) ) {
1017+ if (
1018+ decodeURIComponent ( cypherJson . adata ) !== decodeURIComponent ( `${ roundDomainSeparator } :${ adata } ` ) &&
1019+ decodeURIComponent ( cypherJson . adata ) !== decodeURIComponent ( adata )
1020+ ) {
10111021 throw new Error ( 'Adata does not match cyphertext adata' ) ;
10121022 }
10131023 }
@@ -1128,13 +1138,17 @@ export class EcdsaMPCv2Utils extends BaseEcdsaUtils {
11281138 const userSignerBroadcastMsg1 = await userSigner . init ( ) ;
11291139 const signatureShareRound1 = await getSignatureShareRoundOne ( userSignerBroadcastMsg1 , userGpgKey ) ;
11301140 const session = userSigner . getSession ( ) ;
1131- const encryptedRound1Session = this . bitgo . encrypt ( { input : session , password : walletPassphrase , adata } ) ;
1141+ const encryptedRound1Session = this . bitgo . encrypt ( {
1142+ input : session ,
1143+ password : walletPassphrase ,
1144+ adata : `${ EcdsaMPCv2Utils . DKLS23_SIGNING_ROUND1_STATE } :${ adata } ` ,
1145+ } ) ;
11321146
11331147 const userGpgPubKey = userGpgKey . publicKey ;
11341148 const encryptedUserGpgPrvKey = this . bitgo . encrypt ( {
11351149 input : userGpgKey . privateKey ,
11361150 password : walletPassphrase ,
1137- adata,
1151+ adata : ` ${ EcdsaMPCv2Utils . DKLS23_SIGNING_USER_GPG_KEY } : ${ adata } ` ,
11381152 } ) ;
11391153
11401154 return { signatureShareRound1, userGpgPubKey, encryptedRound1Session, encryptedUserGpgPrvKey } ;
@@ -1159,7 +1173,8 @@ export class EcdsaMPCv2Utils extends BaseEcdsaUtils {
11591173 const { bitgoGpgKey, userGpgKey } = await this . getBitgoAndUserGpgKeys (
11601174 bitgoPublicGpgKey ,
11611175 encryptedUserGpgPrvKey ,
1162- walletPassphrase
1176+ walletPassphrase ,
1177+ adata
11631178 ) ;
11641179
11651180 const signatureShares = txRequest . transactions ?. [ 0 ] . signatureShares ;
@@ -1176,9 +1191,9 @@ export class EcdsaMPCv2Utils extends BaseEcdsaUtils {
11761191 bitgoGpgKey
11771192 ) ;
11781193
1194+ this . validateAdata ( adata , encryptedRound1Session , EcdsaMPCv2Utils . DKLS23_SIGNING_ROUND1_STATE ) ;
11791195 const round1Session = this . bitgo . decrypt ( { input : encryptedRound1Session , password : walletPassphrase } ) ;
11801196
1181- this . validateAdata ( adata , encryptedRound1Session ) ;
11821197 const userKeyShare = Buffer . from ( prv , 'base64' ) ;
11831198 const userSigner = new DklsDsg . Dsg ( userKeyShare , 0 , derivationPath , hashBuffer ) ;
11841199 await userSigner . setSession ( round1Session ) ;
@@ -1199,7 +1214,11 @@ export class EcdsaMPCv2Utils extends BaseEcdsaUtils {
11991214 bitgoGpgKey
12001215 ) ;
12011216 const session = userSigner . getSession ( ) ;
1202- const encryptedRound2Session = this . bitgo . encrypt ( { input : session , password : walletPassphrase , adata } ) ;
1217+ const encryptedRound2Session = this . bitgo . encrypt ( {
1218+ input : session ,
1219+ password : walletPassphrase ,
1220+ adata : `${ EcdsaMPCv2Utils . DKLS23_SIGNING_ROUND2_STATE } :${ adata } ` ,
1221+ } ) ;
12031222
12041223 return {
12051224 signatureShareRound2,
@@ -1227,7 +1246,8 @@ export class EcdsaMPCv2Utils extends BaseEcdsaUtils {
12271246 const { bitgoGpgKey, userGpgKey } = await this . getBitgoAndUserGpgKeys (
12281247 bitgoPublicGpgKey ,
12291248 encryptedUserGpgPrvKey ,
1230- walletPassphrase
1249+ walletPassphrase ,
1250+ adata
12311251 ) ;
12321252
12331253 const signatureShares = txRequest . transactions ?. [ 0 ] . signatureShares ;
@@ -1249,8 +1269,9 @@ export class EcdsaMPCv2Utils extends BaseEcdsaUtils {
12491269 broadcastMessages : [ ] ,
12501270 } ) ;
12511271
1272+ this . validateAdata ( adata , encryptedRound2Session , EcdsaMPCv2Utils . DKLS23_SIGNING_ROUND2_STATE ) ;
12521273 const round2Session = this . bitgo . decrypt ( { input : encryptedRound2Session , password : walletPassphrase } ) ;
1253- this . validateAdata ( adata , encryptedRound2Session ) ;
1274+
12541275 const userKeyShare = Buffer . from ( prv , 'base64' ) ;
12551276 const userSigner = new DklsDsg . Dsg ( userKeyShare , 0 , derivationPath , hashBuffer ) ;
12561277 await userSigner . setSession ( round2Session ) ;
0 commit comments