@@ -51,6 +51,10 @@ import { EcdsaMPCv2KeyGenSendFn, KeyGenSenderForEnterprise } from './ecdsaMPCv2K
5151import { envRequiresBitgoPubGpgKeyConfig , isBitgoMpcPubKey } from '../../../tss/bitgoPubKeys' ;
5252
5353export class EcdsaMPCv2Utils extends BaseEcdsaUtils {
54+ private static readonly DKLS23_SIGNING_USER_GPG_KEY = 'DKLS23_SIGNING_USER_GPG_KEY' ;
55+ private static readonly DKLS23_SIGNING_ROUND1_STATE = 'DKLS23_SIGNING_ROUND1_STATE' ;
56+ private static readonly DKLS23_SIGNING_ROUND2_STATE = 'DKLS23_SIGNING_ROUND2_STATE' ;
57+
5458 /** @inheritdoc */
5559 async createKeychains ( params : {
5660 passphrase : string ;
@@ -964,17 +968,20 @@ export class EcdsaMPCv2Utils extends BaseEcdsaUtils {
964968 * @param {string } bitgoPublicGpgKey - the BitGo public GPG key
965969 * @param {string } encryptedUserGpgPrvKey - the encrypted user GPG private key
966970 * @param {string } walletPassphrase - the wallet passphrase
971+ * @param {string } adata - the additional data to validate the GPG keys
967972 * @returns {Promise<{ bitgoGpgKey: pgp.Key; userGpgKey: pgp.SerializedKeyPair<string> }> } - the BitGo and user GPG keys
968973 */
969974 private async getBitgoAndUserGpgKeys (
970975 bitgoPublicGpgKey : string ,
971976 encryptedUserGpgPrvKey : string ,
972- walletPassphrase : string
977+ walletPassphrase : string ,
978+ adata : string
973979 ) : Promise < {
974980 bitgoGpgKey : pgp . Key ;
975981 userGpgKey : pgp . SerializedKeyPair < string > ;
976982 } > {
977983 const bitgoGpgKey = await pgp . readKey ( { armoredKey : bitgoPublicGpgKey } ) ;
984+ this . validateAdata ( adata , encryptedUserGpgPrvKey , EcdsaMPCv2Utils . DKLS23_SIGNING_USER_GPG_KEY ) ;
978985 const userDecryptedKey = await pgp . readKey ( {
979986 armoredKey : this . bitgo . decrypt ( { input : encryptedUserGpgPrvKey , password : walletPassphrase } ) ,
980987 } ) ;
@@ -995,15 +1002,18 @@ 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+ decodeURIComponent ( cypherJson . adata ) !== decodeURIComponent ( `${ roundDomainSeparator } :${ adata } ` ) &&
1015+ decodeURIComponent ( cypherJson . adata ) !== decodeURIComponent ( adata )
1016+ ) {
10071017 throw new Error ( 'Adata does not match cyphertext adata' ) ;
10081018 }
10091019 }
@@ -1124,13 +1134,17 @@ export class EcdsaMPCv2Utils extends BaseEcdsaUtils {
11241134 const userSignerBroadcastMsg1 = await userSigner . init ( ) ;
11251135 const signatureShareRound1 = await getSignatureShareRoundOne ( userSignerBroadcastMsg1 , userGpgKey ) ;
11261136 const session = userSigner . getSession ( ) ;
1127- const encryptedRound1Session = this . bitgo . encrypt ( { input : session , password : walletPassphrase , adata } ) ;
1137+ const encryptedRound1Session = this . bitgo . encrypt ( {
1138+ input : session ,
1139+ password : walletPassphrase ,
1140+ adata : `${ EcdsaMPCv2Utils . DKLS23_SIGNING_ROUND1_STATE } :${ adata } ` ,
1141+ } ) ;
11281142
11291143 const userGpgPubKey = userGpgKey . publicKey ;
11301144 const encryptedUserGpgPrvKey = this . bitgo . encrypt ( {
11311145 input : userGpgKey . privateKey ,
11321146 password : walletPassphrase ,
1133- adata,
1147+ adata : ` ${ EcdsaMPCv2Utils . DKLS23_SIGNING_USER_GPG_KEY } : ${ adata } ` ,
11341148 } ) ;
11351149
11361150 return { signatureShareRound1, userGpgPubKey, encryptedRound1Session, encryptedUserGpgPrvKey } ;
@@ -1155,7 +1169,8 @@ export class EcdsaMPCv2Utils extends BaseEcdsaUtils {
11551169 const { bitgoGpgKey, userGpgKey } = await this . getBitgoAndUserGpgKeys (
11561170 bitgoPublicGpgKey ,
11571171 encryptedUserGpgPrvKey ,
1158- walletPassphrase
1172+ walletPassphrase ,
1173+ adata
11591174 ) ;
11601175
11611176 const signatureShares = txRequest . transactions ?. [ 0 ] . signatureShares ;
@@ -1172,9 +1187,9 @@ export class EcdsaMPCv2Utils extends BaseEcdsaUtils {
11721187 bitgoGpgKey
11731188 ) ;
11741189
1190+ this . validateAdata ( adata , encryptedRound1Session , EcdsaMPCv2Utils . DKLS23_SIGNING_ROUND1_STATE ) ;
11751191 const round1Session = this . bitgo . decrypt ( { input : encryptedRound1Session , password : walletPassphrase } ) ;
11761192
1177- this . validateAdata ( adata , encryptedRound1Session ) ;
11781193 const userKeyShare = Buffer . from ( prv , 'base64' ) ;
11791194 const userSigner = new DklsDsg . Dsg ( userKeyShare , 0 , derivationPath , hashBuffer ) ;
11801195 await userSigner . setSession ( round1Session ) ;
@@ -1195,7 +1210,11 @@ export class EcdsaMPCv2Utils extends BaseEcdsaUtils {
11951210 bitgoGpgKey
11961211 ) ;
11971212 const session = userSigner . getSession ( ) ;
1198- const encryptedRound2Session = this . bitgo . encrypt ( { input : session , password : walletPassphrase , adata } ) ;
1213+ const encryptedRound2Session = this . bitgo . encrypt ( {
1214+ input : session ,
1215+ password : walletPassphrase ,
1216+ adata : `${ EcdsaMPCv2Utils . DKLS23_SIGNING_ROUND2_STATE } :${ adata } ` ,
1217+ } ) ;
11991218
12001219 return {
12011220 signatureShareRound2,
@@ -1223,7 +1242,8 @@ export class EcdsaMPCv2Utils extends BaseEcdsaUtils {
12231242 const { bitgoGpgKey, userGpgKey } = await this . getBitgoAndUserGpgKeys (
12241243 bitgoPublicGpgKey ,
12251244 encryptedUserGpgPrvKey ,
1226- walletPassphrase
1245+ walletPassphrase ,
1246+ adata
12271247 ) ;
12281248
12291249 const signatureShares = txRequest . transactions ?. [ 0 ] . signatureShares ;
@@ -1245,8 +1265,9 @@ export class EcdsaMPCv2Utils extends BaseEcdsaUtils {
12451265 broadcastMessages : [ ] ,
12461266 } ) ;
12471267
1268+ this . validateAdata ( adata , encryptedRound2Session , EcdsaMPCv2Utils . DKLS23_SIGNING_ROUND2_STATE ) ;
12481269 const round2Session = this . bitgo . decrypt ( { input : encryptedRound2Session , password : walletPassphrase } ) ;
1249- this . validateAdata ( adata , encryptedRound2Session ) ;
1270+
12501271 const userKeyShare = Buffer . from ( prv , 'base64' ) ;
12511272 const userSigner = new DklsDsg . Dsg ( userKeyShare , 0 , derivationPath , hashBuffer ) ;
12521273 await userSigner . setSession ( round2Session ) ;
0 commit comments