UserInfo: implement setting and getting the keypair.

master
Tom Hacohen 7 years ago
parent 45db0c12c5
commit 1f961fbad1

@ -9,6 +9,16 @@ sjcl.random.startCollectors();
export const HMAC_SIZE_BYTES = 32;
export class AsymmetricKeyPair {
publicKey: byte[];
privateKey: byte[];
constructor(publicKey: byte[], privateKey: byte[]) {
this.publicKey = publicKey;
this.privateKey = privateKey;
}
}
export function deriveKey(salt: string, password: string): string {
const keySize = 190 * 8;

@ -129,27 +129,28 @@ it('Journal Entry sync', async () => {
});
it('User info sync', async () => {
const cryptoManager = new EteSync.CryptoManager(keyBase64, 'userInfo');
const userInfoManager = new EteSync.UserInfoManager(credentials, testApiBase);
// Get when there's nothing
await expect(userInfoManager.fetch(USER)).rejects.toBeInstanceOf(EteSync.HTTPError);
// Create
let userInfo = new EteSync.UserInfo();
userInfo.deserialize({pubkey: 'dGVzdAo=', content: 'dGVzdAo=', owner: USER});
let userInfo = new EteSync.UserInfo(USER);
userInfo.setKeyPair(cryptoManager, new EteSync.AsymmetricKeyPair([0, 1, 2, 3], [4, 5, 6, 6]));
await expect(userInfoManager.create(userInfo)).resolves.not.toBeNull();
// Get
let userInfo2 = await userInfoManager.fetch(USER);
expect(userInfo2).not.toBeNull();
expect(userInfo.serialize().content).toEqual(userInfo2!.serialize().content);
expect(userInfo.getKeyPair(cryptoManager)).toEqual(userInfo2!.getKeyPair(cryptoManager));
// Update
userInfo.deserialize({pubkey: 'dGVzdDIK', content: 'dGVzdDIK', owner: USER});
userInfo.setKeyPair(cryptoManager, new EteSync.AsymmetricKeyPair([1, 94, 45], [4, 34, 45, 45]));
await userInfoManager.update(userInfo);
userInfo2 = await userInfoManager.fetch(USER);
expect(userInfo2).not.toBeNull();
expect(userInfo.serialize().content).toEqual(userInfo2!.serialize().content);
expect(userInfo.getKeyPair(cryptoManager)).toEqual(userInfo2!.getKeyPair(cryptoManager));
// Delete
await userInfoManager.delete(userInfo);

@ -6,8 +6,8 @@ import * as Constants from './Constants';
import * as fetch from 'isomorphic-fetch';
import { byte, base64, stringToByteArray } from './Helpers';
import { CryptoManager, HMAC_SIZE_BYTES } from './Crypto';
export { CryptoManager, deriveKey } from './Crypto';
import { CryptoManager, AsymmetricKeyPair, HMAC_SIZE_BYTES } from './Crypto';
export { CryptoManager, AsymmetricKeyPair, deriveKey } from './Crypto';
class ExtendableError extends Error {
constructor(message: any) {
@ -226,22 +226,53 @@ export class Entry extends BaseJournal<EntryJson> {
export interface UserInfoJson extends BaseItemJson {
version?: number;
owner: string;
owner?: string;
pubkey: base64;
}
export class UserInfo extends BaseItem<UserInfoJson> {
constructor(version: number = Constants.CURRENT_VERSION) {
_owner: string;
constructor(owner: string, version: number = Constants.CURRENT_VERSION) {
super();
this._json.version = version;
this._owner = owner;
}
get version(): number {
return this._json.version!;
}
get owner() {
return this._json.owner;
get owner(): string {
return this._owner;
}
get publicKey() {
return this._json.pubkey;
}
serialize(): UserInfoJson {
let ret = super.serialize();
ret.owner = this._owner;
return ret;
}
setKeyPair(cryptoManager: CryptoManager, keyPair: AsymmetricKeyPair) {
this._json.pubkey = sjcl.codec.base64.fromBits(sjcl.codec.bytes.toBits(keyPair.publicKey));
this._content = keyPair.privateKey;
const encrypted = cryptoManager.encryptBytes(keyPair.privateKey);
this._encrypted = this.calculateHmac(cryptoManager, encrypted).concat(encrypted);
}
getKeyPair(cryptoManager: CryptoManager): AsymmetricKeyPair {
this.verify(cryptoManager);
if (this._content === undefined) {
this._content = cryptoManager.decryptBytes(this.encryptedContent());
}
const pubkey = sjcl.codec.bytes.fromBits(sjcl.codec.base64.toBits(this._json.pubkey));
return new AsymmetricKeyPair(pubkey, this._content as byte[]);
}
calculateHmac(cryptoManager: CryptoManager, encrypted: byte[]): byte[] {
@ -472,7 +503,7 @@ export class UserInfoManager extends BaseManager {
fetch(owner: string): Promise<UserInfo> {
return new Promise((resolve, reject) => {
this.newCall([owner, '']).then((json: UserInfoJson) => {
let userInfo = new UserInfo(json.version);
let userInfo = new UserInfo(owner, json.version);
userInfo.deserialize(json);
resolve(userInfo);
}).catch((error: Error) => {

Loading…
Cancel
Save