Remove some stuff we wont need in signing and identity service

This commit is contained in:
Daniel Krol 2022-05-04 18:25:06 -04:00
parent a761ba1a06
commit 970c0e68e7
3 changed files with 32 additions and 118 deletions

View file

@ -3,7 +3,7 @@ import {ActivatedRoute} from '@angular/router';
import {IdentityService} from '../identity.service'; import {IdentityService} from '../identity.service';
import {AccountService} from '../account.service'; import {AccountService} from '../account.service';
import {GlobalVarsService} from '../global-vars.service'; import {GlobalVarsService} from '../global-vars.service';
import {SigningService} from '../signing.service'; // import {SigningService} from '../signing.service';
import {BackendAPIService, User} from '../backend-api.service'; import {BackendAPIService, User} from '../backend-api.service';
import {Observable, of} from 'rxjs'; import {Observable, of} from 'rxjs';
import {map} from 'rxjs/operators'; import {map} from 'rxjs/operators';
@ -51,7 +51,7 @@ export class ApproveComponent implements OnInit {
private identityService: IdentityService, private identityService: IdentityService,
private accountService: AccountService, private accountService: AccountService,
public globalVars: GlobalVarsService, public globalVars: GlobalVarsService,
private signingService: SigningService, // private signingService: SigningService,
private backendApi: BackendAPIService, private backendApi: BackendAPIService,
) { } ) { }
@ -77,9 +77,11 @@ export class ApproveComponent implements OnInit {
onSubmit(): void { onSubmit(): void {
// TODO // TODO
throw "replace all of this transaction parsing and checking with bitcoinjs-lib." throw "replace all of this transaction parsing and checking with bitcoinjs-lib."
/*
const seedHex = "" const seedHex = ""
const signedTransactionHex = this.signingService.signTransaction(seedHex, this.transactionHex); const signedTransactionHex = this.signingService.signTransaction(seedHex, this.transactionHex);
this.finishFlow(signedTransactionHex); this.finishFlow(signedTransactionHex);
*/
} }
finishFlow(signedTransactionHex?: string): void { finishFlow(signedTransactionHex?: string): void {

View file

@ -7,30 +7,6 @@ import {GlobalVarsService} from './global-vars.service';
import {CookieService} from 'ngx-cookie'; import {CookieService} from 'ngx-cookie';
import {SigningService} from './signing.service'; import {SigningService} from './signing.service';
import {HttpParams} from '@angular/common/http'; import {HttpParams} from '@angular/common/http';
import {
Transaction,
TransactionMetadataBasicTransfer,
TransactionMetadataBitcoinExchange,
TransactionMetadataCreatorCoin,
TransactionMetadataCreatorCoinTransfer,
TransactionMetadataFollow,
TransactionMetadataLike,
TransactionMetadataPrivateMessage,
TransactionMetadataSubmitPost,
TransactionMetadataSwapIdentity,
TransactionMetadataUpdateBitcoinUSDExchangeRate,
TransactionMetadataUpdateGlobalParams,
TransactionMetadataUpdateProfile,
TransactionMetadataNFTTransfer,
TransactionMetadataAcceptNFTTransfer,
TransactionMetadataBurnNFT,
TransactionMetadataNFTBid,
TransactionMetadataAcceptNFTBid,
TransactionMetadataUpdateNFT,
TransactionMetadataCreateNFT,
TransactionMetadataDAOCoin,
TransactionMetadataTransferDAOCoin
} from '../lib/deso/transaction';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
@ -89,11 +65,14 @@ export class IdentityService {
// Incoming Messages // Incoming Messages
private handleSign(data: any): void { private handleSign(data: any): void {
const { id, payload: { encryptedSeedHex, transactionHex } } = data; // TODO
throw "implement for lbry"
/*
const transaction or action details = data;
// This will tell us whether we need full signing access or just ApproveLarge // This will tell us whether we need full signing access or just ApproveLarge
// level of access. // level of access.
const requiredAccessLevel = this.getRequiredAccessLevel(transactionHex); const requiredAccessLevel = this.getRequiredAccessLevel(transaction or action details);
// In the case that approve() fails, it responds with a message indicating // In the case that approve() fails, it responds with a message indicating
// that approvalRequired = true, which the caller can then uses to trigger // that approvalRequired = true, which the caller can then uses to trigger
@ -102,21 +81,18 @@ export class IdentityService {
return; return;
} }
// If we get to this point, no approval UI was required. This typically // TODO - this.signingService.signPSBT instead
// happens if the caller has full signing access or signing access for if it's a transaction
// non-spending txns such as like, post, update profile, etc. In the const signedTransactionHex = this.signingService.signPSBT(transaction details);
// latter case we need a subsequent check to ensure that the txn is not else // just an action
// sending money to any public keys other than the sender himself. const signedActionHex = this.signingService.signActiov(action details);
if (!this.approveSpending(data)) {
return;
}
const seedHex = this.cryptoService.decryptSeedHex(encryptedSeedHex, this.globalVars.hostname);
const signedTransactionHex = this.signingService.signTransaction(seedHex, transactionHex);
// TODO figure this out...
this.respond(id, { this.respond(id, {
signedTransactionHex, signedTransactionHex,
signedActionHex,
}); });
*/
} }
private handleJwt(data: any): void { private handleJwt(data: any): void {
@ -163,42 +139,12 @@ export class IdentityService {
}); });
} }
// Access levels // Access levels
private getRequiredAccessLevel(transactionHex: string): AccessLevel { // TODO implement for lbry
const txBytes = new Buffer(transactionHex, 'hex'); // private getRequiredAccessLevel(transactionHex: string): AccessLevel {
const transaction = Transaction.fromBytes(txBytes)[0] as Transaction<any>; // switch case on the type of transaction or action, and return the required access level
// unless required access level is going to be case by case for each user
switch (transaction.metadata.constructor) {
case TransactionMetadataBasicTransfer:
case TransactionMetadataBitcoinExchange:
case TransactionMetadataUpdateBitcoinUSDExchangeRate:
case TransactionMetadataCreatorCoin:
case TransactionMetadataCreatorCoinTransfer:
case TransactionMetadataSwapIdentity:
case TransactionMetadataUpdateGlobalParams:
case TransactionMetadataUpdateProfile:
case TransactionMetadataCreateNFT:
case TransactionMetadataUpdateNFT:
case TransactionMetadataAcceptNFTBid:
case TransactionMetadataNFTBid:
case TransactionMetadataNFTTransfer:
case TransactionMetadataAcceptNFTTransfer:
case TransactionMetadataBurnNFT:
case TransactionMetadataDAOCoin:
case TransactionMetadataTransferDAOCoin:
return AccessLevel.Full;
case TransactionMetadataFollow:
case TransactionMetadataPrivateMessage:
case TransactionMetadataSubmitPost:
case TransactionMetadataLike:
return AccessLevel.ApproveLarge;
}
return AccessLevel.Full;
}
private hasAccessLevel(data: any, requiredAccessLevel: AccessLevel): boolean { private hasAccessLevel(data: any, requiredAccessLevel: AccessLevel): boolean {
const { payload: { encryptedSeedHex, accessLevel, accessLevelHmac }} = data; const { payload: { encryptedSeedHex, accessLevel, accessLevelHmac }} = data;
@ -210,25 +156,6 @@ export class IdentityService {
return this.cryptoService.validAccessLevelHmac(accessLevel, seedHex, accessLevelHmac); return this.cryptoService.validAccessLevelHmac(accessLevel, seedHex, accessLevelHmac);
} }
// This method checks if transaction in the payload has correct outputs for requested AccessLevel.
private approveSpending(data: any): boolean {
const { payload: { accessLevel, transactionHex }} = data;
// If the requested access level is ApproveLarge, we want to confirm that transaction doesn't
// attempt sending $DESO to a non-owner public key. If it does, we respond with approvalRequired.
if (accessLevel === AccessLevel.ApproveLarge) {
const txBytes = new Buffer(transactionHex, 'hex');
const transaction = Transaction.fromBytes(txBytes)[0] as Transaction<any>;
for (const output of transaction.outputs) {
if (output.publicKey.toString('hex') !== transaction.publicKey.toString('hex')) {
this.respond(data.id, {approvalRequired: true});
return false;
}
}
}
return true;
}
private approve(data: any, accessLevel: AccessLevel): boolean { private approve(data: any, accessLevel: AccessLevel): boolean {
const hasAccess = this.hasAccessLevel(data, accessLevel); const hasAccess = this.hasAccessLevel(data, accessLevel);
const hasEncryptionKey = this.cryptoService.hasSeedHexEncryptionKey(this.globalVars.hostname); const hasEncryptionKey = this.cryptoService.hasSeedHexEncryptionKey(this.globalVars.hostname);

View file

@ -1,9 +1,6 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import KeyEncoder from 'key-encoder'; import KeyEncoder from 'key-encoder';
import * as jsonwebtoken from 'jsonwebtoken'; import * as jsonwebtoken from 'jsonwebtoken';
import {CryptoService} from './crypto.service';
import * as sha256 from 'sha256';
import { uvarint64ToBuf } from '../lib/bindata/util';
import * as bip32 from 'bip32'; import * as bip32 from 'bip32';
import { BIP32Interface } from 'bip32'; // TODO: Installed 2.0.6 instead of latest version, only because of weird typescript compilation stuff. Should probably get the latest. import { BIP32Interface } from 'bip32'; // TODO: Installed 2.0.6 instead of latest version, only because of weird typescript compilation stuff. Should probably get the latest.
@ -18,9 +15,7 @@ const NETWORK = lbry.networks.mainnet
}) })
export class SigningService { export class SigningService {
constructor( constructor() { }
private cryptoService: CryptoService,
) { }
// this should be audited and go into a library. hobbled this together from // this should be audited and go into a library. hobbled this together from
// code in bitcoinjs-lib. // code in bitcoinjs-lib.
@ -75,39 +70,29 @@ export class SigningService {
} }
signJWT(seedHex: string): string { signJWT(seedHex: string): string {
return ""
// TODO - use bitcoinjs-lib and do an actual signature with the actual key in the wallet, send the identifier of the wallet over, etc etc etc.
// Assuming we want to keep this
const keyEncoder = new KeyEncoder('secp256k1'); const keyEncoder = new KeyEncoder('secp256k1');
const encodedPrivateKey = keyEncoder.encodePrivate(seedHex, 'raw', 'pem'); const encodedPrivateKey = keyEncoder.encodePrivate(seedHex, 'raw', 'pem');
return jsonwebtoken.sign({ }, encodedPrivateKey, { algorithm: 'ES256', expiresIn: 60 * 10 }); return jsonwebtoken.sign({ }, encodedPrivateKey, { algorithm: 'ES256', expiresIn: 60 * 10 });
} }
signAction(seedHex: string, actionHex: string): string { signAction(seedHex: string, actionHex: string): string {
return ""
// TODO - use bitcoinjs-lib and do an actual signature with the actual key in the wallet, send the identifier of the wallet over, etc etc etc. // TODO - use bitcoinjs-lib and do an actual signature with the actual key in the wallet, send the identifier of the wallet over, etc etc etc.
/*
const privateKey = this.cryptoService.seedHexToPrivateKey(seedHex); const privateKey = this.cryptoService.seedHexToPrivateKey(seedHex);
const actionBytes = new Buffer(actionHex, 'hex'); const actionBytes = new Buffer(actionHex, 'hex');
const actionHash = new Buffer(sha256.x2(actionBytes), 'hex'); const actionHash = new Buffer(sha256.x2(actionBytes), 'hex');
const signature = privateKey.sign(actionHash); const signature = privateKey.sign(actionHash);
return new Buffer(signature.toDER()).toString('hex'); return new Buffer(signature.toDER()).toString('hex');
} */
signTransaction(seedHex: string, transactionHex: string): string {
const privateKey = this.cryptoService.seedHexToPrivateKey(seedHex);
const transactionBytes = new Buffer(transactionHex, 'hex');
const transactionHash = new Buffer(sha256.x2(transactionBytes), 'hex');
const signature = privateKey.sign(transactionHash);
const signatureBytes = new Buffer(signature.toDER());
const signatureLength = uvarint64ToBuf(signatureBytes.length);
const signedTransactionBytes = Buffer.concat([
// This slice is bad. We need to remove the existing signature length field prior to appending the new one.
// Once we have frontend transaction construction we won't need to do this.
transactionBytes.slice(0, -1),
signatureLength,
signatureBytes,
]);
return signedTransactionBytes.toString('hex');
} }
} }