Skip to content

Commit

Permalink
feat: add appPrivateKeyFromWalletSalt (#1212)
Browse files Browse the repository at this point in the history
to pass incorrectly derived appPrivateKey
See issue 2238 in stacks-web-wallet repo
  • Loading branch information
beguene authored and janniks committed Mar 14, 2022
1 parent 4815900 commit ac3858c
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 2 deletions.
4 changes: 3 additions & 1 deletion packages/auth/src/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,8 @@ export async function makeAuthResponse(
transitPublicKey: string | null = null,
hubUrl: string | null = null,
blockstackAPIUrl: string | null = null,
associationToken: string | null = null
associationToken: string | null = null,
appPrivateKeyFromWalletSalt: string | null = null
): Promise<string> {
/* Convert the private key to a public key to an issuer */
const publicKey = SECP256K1Client.derivePublicKey(privateKey);
Expand Down Expand Up @@ -229,6 +230,7 @@ export async function makeAuthResponse(
iss: makeDIDFromAddress(address),
private_key: privateKeyPayload,
public_keys: [publicKey],
appPrivateKeyFromWalletSalt,
profile,
username,
core_token: coreTokenPayload,
Expand Down
2 changes: 2 additions & 0 deletions packages/auth/src/userData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,6 @@ export interface UserData {
profile: any;
// private: does not get sent to webapp at all.
gaiaHubConfig?: any;
// Based on issue with incorrect appPrivateKey derivation see stacks-web-wallet issue #2238
appPrivateKeyFromWalletSalt?: string;
}
1 change: 1 addition & 0 deletions packages/auth/src/userSession.ts
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,7 @@ export class UserSession {
coreSessionToken,
authResponseToken,
hubUrl,
appPrivateKeyFromWalletSalt: tokenPayload.appPrivateKeyFromWalletSalt as string,
coreNode: tokenPayload.blockstackAPIUrl as string,
// @ts-expect-error
gaiaAssociationToken,
Expand Down
52 changes: 52 additions & 0 deletions packages/auth/tests/auth.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ test('makeAuthResponse && verifyAuthResponse', async () => {
expect(authResponse).toBeTruthy();

const decodedToken = decodeToken(authResponse);

expect(decodedToken).toBeTruthy();

const address = publicKeyToAddress(publicKey);
Expand All @@ -196,6 +197,57 @@ test('makeAuthResponse && verifyAuthResponse', async () => {
});
});

test('auth response with invalid or empty appPrivateKeyFromWalletSalt', async () => {
let appPrivateKeyFromWalletSalt1;
const authResponse = await makeAuthResponse(
privateKey,
sampleProfiles.ryan,
null,
null,
null,
null,
undefined,
null,
null,
null,
null,
appPrivateKeyFromWalletSalt1
);
expect(authResponse).toBeTruthy();
const decodedToken = decodeToken(authResponse);
console.log('decodedToken', decodedToken);
expect(decodedToken).toBeTruthy();
expect((decodedToken.payload as any).appPrivateKeyFromWalletSalt).toBeNull();
});

test('auth response with valid appPrivateKeyFromWalletSalt', async () => {
const appPrivateKeyFromWalletSalt =
'ab9a2ad092b910902f4a74f7aeaee874497ed9bc3f6408ed8b07e22425471fde';
const authResponse = await makeAuthResponse(
privateKey,
sampleProfiles.ryan,
null,
null,
null,
null,
undefined,
null,
null,
null,
null,
appPrivateKeyFromWalletSalt
);
expect(authResponse).toBeTruthy();

const decodedToken = decodeToken(authResponse);
console.log('decodedToken', decodedToken);

expect(decodedToken).toBeTruthy();
expect((decodedToken.payload as any).appPrivateKeyFromWalletSalt).toEqual(
appPrivateKeyFromWalletSalt
);
});

test('auth response with username', async () => {
fetchMock.mockResponse(JSON.stringify(sampleNameRecords.ryan));

Expand Down
5 changes: 4 additions & 1 deletion packages/wallet-sdk/src/models/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,14 @@ export const makeAuthResponse = async ({
transitPublicKey,
scopes = [],
gaiaHubUrl,
appPrivateKeyFromWalletSalt = null,
}: {
account: Account;
appDomain: string;
transitPublicKey: string;
scopes?: string[];
gaiaHubUrl: string;
appPrivateKeyFromWalletSalt?: string | null;
}) => {
const appPrivateKey = getAppPrivateKey({ account, appDomain });
const hubInfo = await getHubInfo(gaiaHubUrl);
Expand Down Expand Up @@ -124,6 +126,7 @@ export const makeAuthResponse = async ({
transitPublicKey,
gaiaHubUrl,
undefined,
associationToken
associationToken,
appPrivateKeyFromWalletSalt
);
};
29 changes: 29 additions & 0 deletions packages/wallet-sdk/tests/models/account.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,33 @@ describe(makeAuthResponse, () => {
expect(appsMeta[appDomain].storage).toEqual(expectedDomain);
expect(appsMeta[appDomain].publicKey).toEqual(challengeSigner.publicKey.toString('hex'));
});

test('generates an auth response with appPrivateKeyFromWalletSalt', async () => {
const account = mockAccount;
const appDomain = 'https://banter.pub';
const transitPrivateKey = makeECPrivateKey();
const transitPublicKey = getPublicKeyFromPrivate(transitPrivateKey);
const appPrivateKeyFromWalletSalt =
'ab9a2ad092b910902f4a74f7aeaee874497ed9bc3f6408ed8b07e22425471fde';

fetchMock.once(mockGaiaHubInfo).once('', { status: 404 });

const authResponse = await makeAuthResponse({
appDomain,
gaiaHubUrl,
transitPublicKey,
account,
appPrivateKeyFromWalletSalt,
});

const decoded = decodeToken(authResponse);
const { payload } = decoded as Decoded;
expect(payload.profile_url).toEqual(
`https://gaia.blockstack.org/hub/${getGaiaAddress(account)}/profile.json`
);
const appPrivateKey = await decryptPrivateKey(transitPrivateKey, payload.private_key);
const expectedKey = '6f8b6a170f8b2ee57df5ead49b0f4c8acde05f9e1c4c6ef8223d6a42fabfa314';
expect(appPrivateKey).toEqual(expectedKey);
expect(payload.appPrivateKeyFromWalletSalt).toEqual(appPrivateKeyFromWalletSalt);
});
});

1 comment on commit ac3858c

@vercel
Copy link

@vercel vercel bot commented on ac3858c Mar 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.