Bug fix.
- Add handling of errors from getPublicKeys function. - Check if added private keys are encrypted.
This commit is contained in:
parent
8c2b659360
commit
aceccedf5e
@ -1,7 +1,6 @@
|
|||||||
import { KeyStore } from 'cic-client-meta';
|
import { KeyStore } from 'cic-client-meta';
|
||||||
// const openpgp = require('openpgp'); //TODO should we put this on the mutalble key store object
|
// TODO should we put this on the mutalble key store object
|
||||||
import * as openpgp from 'openpgp';
|
import * as openpgp from 'openpgp';
|
||||||
import {throwError} from 'rxjs';
|
|
||||||
const keyring = new openpgp.Keyring();
|
const keyring = new openpgp.Keyring();
|
||||||
|
|
||||||
interface MutableKeyStore extends KeyStore {
|
interface MutableKeyStore extends KeyStore {
|
||||||
@ -16,6 +15,7 @@ interface MutableKeyStore extends KeyStore {
|
|||||||
getPrivateKeys(): Array<any>;
|
getPrivateKeys(): Array<any>;
|
||||||
getPrivateKey(): any;
|
getPrivateKey(): any;
|
||||||
isValidKey(key: any): Promise<boolean>;
|
isValidKey(key: any): Promise<boolean>;
|
||||||
|
isEncryptedPrivateKey(privateKey: any): Promise<boolean>;
|
||||||
getFingerprint(): string;
|
getFingerprint(): string;
|
||||||
getKeyId(key: any): string;
|
getKeyId(key: any): string;
|
||||||
getPrivateKeyId(): string;
|
getPrivateKeyId(): string;
|
||||||
@ -35,8 +35,6 @@ class MutablePgpKeyStore implements MutableKeyStore{
|
|||||||
|
|
||||||
async loadKeyring(): Promise<void> {
|
async loadKeyring(): Promise<void> {
|
||||||
await keyring.load();
|
await keyring.load();
|
||||||
// clear any keys already in the keychain
|
|
||||||
// keyring.clear();
|
|
||||||
await keyring.store();
|
await keyring.store();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,6 +81,17 @@ class MutablePgpKeyStore implements MutableKeyStore{
|
|||||||
return !_key.err;
|
return !_key.err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async isEncryptedPrivateKey(privateKey: any): Promise<boolean> {
|
||||||
|
const imported = await openpgp.key.readArmored(privateKey);
|
||||||
|
for (let i = 0; i < imported.keys.length; i++) {
|
||||||
|
const key = imported.keys[i];
|
||||||
|
if (key.isDecrypted()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
getFingerprint(): string {
|
getFingerprint(): string {
|
||||||
// TODO Handle multiple keys
|
// TODO Handle multiple keys
|
||||||
return keyring.privateKeys.keys[0].keyPacket.fingerprint;
|
return keyring.privateKeys.keys[0].keyPacket.fingerprint;
|
||||||
|
@ -5,10 +5,8 @@ import {environment} from '@src/environments/environment';
|
|||||||
import {LoggingService} from '@app/_services/logging.service';
|
import {LoggingService} from '@app/_services/logging.service';
|
||||||
import {MutableKeyStore, MutablePgpKeyStore} from '@app/_pgp';
|
import {MutableKeyStore, MutablePgpKeyStore} from '@app/_pgp';
|
||||||
import {ErrorDialogService} from '@app/_services/error-dialog.service';
|
import {ErrorDialogService} from '@app/_services/error-dialog.service';
|
||||||
import {tap} from 'rxjs/operators';
|
|
||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import {Observable } from 'rxjs';
|
import {Observable } from 'rxjs';
|
||||||
import * as openpgp from 'openpgp';
|
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
@ -125,18 +123,19 @@ export class AuthService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async setKey(privateKeyArmored): Promise<boolean> {
|
async setKey(privateKeyArmored): Promise<boolean> {
|
||||||
// TODO Check if key is encrypted else warn user.
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const isValidKeyCheck = await this.mutableKeyStore.isValidKey(privateKeyArmored);
|
const isValidKeyCheck = await this.mutableKeyStore.isValidKey(privateKeyArmored);
|
||||||
if (!isValidKeyCheck) {
|
if (!isValidKeyCheck) {
|
||||||
throw Error('The private key is invalid');
|
throw Error('The private key is invalid');
|
||||||
}
|
}
|
||||||
|
const isEncryptedKeyCheck = await this.mutableKeyStore.isEncryptedPrivateKey(privateKeyArmored);
|
||||||
|
if (!isEncryptedKeyCheck) {
|
||||||
|
throw Error('The private key doesn\'t have a password!');
|
||||||
|
}
|
||||||
const key = await this.mutableKeyStore.importPrivateKey(privateKeyArmored);
|
const key = await this.mutableKeyStore.importPrivateKey(privateKeyArmored);
|
||||||
localStorage.setItem(btoa('CICADA_PRIVATE_KEY'), privateKeyArmored);
|
localStorage.setItem(btoa('CICADA_PRIVATE_KEY'), privateKeyArmored);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.loggingService.sendErrorLevelMessage('Failed setting key', this, {error: err});
|
this.loggingService.sendErrorLevelMessage(`Failed to set key: ${err.message || err.statusText}`, this, {error: err});
|
||||||
// TODO use a global error handler here
|
|
||||||
this.errorDialogService.openDialog({
|
this.errorDialogService.openDialog({
|
||||||
message: `Failed to set key: ${err.message || err.statusText}`,
|
message: `Failed to set key: ${err.message || err.statusText}`,
|
||||||
});
|
});
|
||||||
@ -158,14 +157,7 @@ export class AuthService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getPublicKeys(): Observable<any> {
|
getPublicKeys(): Observable<any> {
|
||||||
return this.httpClient.get(`${environment.publicKeysUrl}`, {responseType: 'text'})
|
return this.httpClient.get(`${environment.publicKeysUrl}`, {responseType: 'text'});
|
||||||
.pipe(tap(
|
|
||||||
data => { },
|
|
||||||
error => {
|
|
||||||
this.loggingService.sendErrorLevelMessage('Unable to load trusted public keys.', this, {error});
|
|
||||||
this.errorDialogService.openDialog({message: 'Trusted keys endpoint can\'t be reached. Please try again later.'});
|
|
||||||
}
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async getPrivateKeys(): Promise<void> {
|
async getPrivateKeys(): Promise<void> {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import {ChangeDetectionStrategy, Component, HostListener} from '@angular/core';
|
import {ChangeDetectionStrategy, Component, HostListener} from '@angular/core';
|
||||||
import {AuthService, LoggingService, TokenService, TransactionService} from '@app/_services';
|
import {AuthService, ErrorDialogService, LoggingService, TransactionService} from '@app/_services';
|
||||||
|
import {catchError} from 'rxjs/operators';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
@ -15,15 +16,17 @@ export class AppComponent {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private authService: AuthService,
|
private authService: AuthService,
|
||||||
private tokenService: TokenService,
|
|
||||||
private transactionService: TransactionService,
|
private transactionService: TransactionService,
|
||||||
private loggingService: LoggingService,
|
private loggingService: LoggingService,
|
||||||
|
private errorDialogService: ErrorDialogService
|
||||||
) {
|
) {
|
||||||
(async () => {
|
(async () => {
|
||||||
await this.authService.mutableKeyStore.loadKeyring();
|
await this.authService.mutableKeyStore.loadKeyring();
|
||||||
// TODO Handle error from get public keys function.
|
this.authService.getPublicKeys()
|
||||||
this.authService.getPublicKeys().subscribe(this.authService.mutableKeyStore.importPublicKey);
|
.pipe(catchError(async (error) => {
|
||||||
// this.loggingService.sendInfoLevelMessage(await this.tokenService.getTokens());
|
this.loggingService.sendErrorLevelMessage('Unable to load trusted public keys.', this, {error});
|
||||||
|
this.errorDialogService.openDialog({message: 'Trusted keys endpoint can\'t be reached. Please try again later.'});
|
||||||
|
})).subscribe(this.authService.mutableKeyStore.importPublicKey);
|
||||||
})();
|
})();
|
||||||
this.mediaQuery.addListener(this.onResize);
|
this.mediaQuery.addListener(this.onResize);
|
||||||
this.onResize(this.mediaQuery);
|
this.onResize(this.mediaQuery);
|
||||||
|
Loading…
Reference in New Issue
Block a user