public override string LoadAccountKey(string wallet, string address, string key, IDbConnectorService dbservice, string pubkey = "", string password = "", string name = "", bool storeInDb = true, bool isItMainAccountKey = false, bool alreadyEncrypted = false, EncryptionKeyType type = EncryptionKeyType.BasicSecurity) { try { if (EconomyMainContext.Wallets.TryGetValue(wallet, out var w)) { if (w.Accounts.TryGetValue(address, out var account)) { if (isItMainAccountKey) { // todo load already encrypted key account.AccountKey = new Security.EncryptionKey(key, password); account.AccountKey.RelatedItemId = account.Id; account.AccountKey.Type = Security.EncryptionKeyType.AccountKey; account.AccountKeyId = account.AccountKey.Id; account.AccountKey.PublicKey = account.Address; if (!string.IsNullOrEmpty(password)) { account.AccountKey.PasswordHash = Security.SecurityUtil.HashPassword(password); } account.AccountKey.Name = name; if (EconomyMainContext.WorkWithDb) { dbservice.SaveKey(account.AccountKey); } account.AccountKeyId = account.AccountKey.Id; if (EconomyMainContext.WorkWithDb) { dbservice.SaveAccount(account); } return("OK"); } else { EncryptionKey k = null; if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(pubkey)) { // validate the key pair if it is correct combination of RSA keys try { if (type != EncryptionKeyType.AccountKey) { if (alreadyEncrypted) { var kd = SymetricProvider.DecryptString(password, key); if (kd != null) { key = kd; } } var m = AsymmetricProvider.EncryptString("test", pubkey); var r = AsymmetricProvider.DecryptString(m, key); if (r != "test") { throw new Exception("Key pair is not valid RSA key pair!"); } } k = new EncryptionKey(key, password); } catch (Exception ex) { throw new Exception("Key pair is not valid RSA key pair!"); } } else if (!string.IsNullOrEmpty(key) && string.IsNullOrEmpty(pubkey)) { if (alreadyEncrypted) { var kd = SymetricProvider.DecryptString(password, key); if (kd != null) { k = new Security.EncryptionKey(kd, password); } } else { k = new Security.EncryptionKey(key, password); k.LoadNewKey(key, fromDb: true); } } else if (!string.IsNullOrEmpty(pubkey) && string.IsNullOrEmpty(key)) { // create enc object k = new Security.EncryptionKey("passtest", password, true); // this can be used for testing the password k.PublicKey = pubkey; } else if (string.IsNullOrEmpty(key) && string.IsNullOrEmpty(pubkey)) { // obtain new RSA key pair var keypair = Security.AsymmetricProvider.GenerateNewKeyPair(); // create enc object k = new EncryptionKey(keypair.PrivateKey, password); k.PublicKey = keypair.PublicKey; } else { throw new Exception("Strange input!"); } k.RelatedItemId = account.Id; k.Type = Security.EncryptionKeyType.BasicSecurity; if (!string.IsNullOrEmpty(password)) { k.PasswordHash = Security.SecurityUtil.HashPassword(password); } k.Name = name; account.AccountKeys.Add(k); if (EconomyMainContext.WorkWithDb) { dbservice.SaveKey(k); } if (isItMainAccountKey) { account.AccountKeyId = account.AccountKey.Id; if (EconomyMainContext.WorkWithDb) { dbservice.SaveAccount(account); } } return("OK"); } } } } catch (Exception ex) { log.Error("Cannot load key to the account!", ex); } return("Load Account Key - ERROR"); }
public static async Task <string> SendMessage(SendMessageDto dto) { if (EconomyMainContext.Wallets.TryGetValue(dto.WalletId, out var wallet)) { if (wallet.Accounts.TryGetValue(dto.SenderAddress, out var account)) { var txdto = new SendTokenTxData(); txdto.Amount = 1; txdto.Id = TokenId; // token ID - todo MSGT txdto.Symbol = TokenSymbol; // token symbol - todo MSGT txdto.UseRPCPrimarily = false; txdto.Password = dto.AccountPassword; txdto.SenderAddress = dto.SenderAddress; txdto.ReceiverAddress = dto.ReceiverAddress; /////////////////////////////// // prepare the message to send if (dto.InitMessage) { // for init message lets create new uid txdto.Metadata.Add("MessageStreamUID", Guid.NewGuid().ToString()); } else { // for not init message message stream uid must be filled if (!string.IsNullOrEmpty(dto.MessageStreamUID)) { txdto.Metadata.Add("MessageStreamUID", dto.MessageStreamUID.ToString()); } else { throw new Exception("Cannot send message - this is not set as init message but no MessageStreamUID was provided!"); } } var msg = string.Empty; var prevmsgdata = string.Empty; var prevmsg = string.Empty; var prevtxid = string.Empty; if (!dto.InitMessage) { var pretoken = await NeblioTransactionHelpers.TokenMetadataAsync(TokenTypes.NTP1, TokenId, dto.TokenTxId); if (string.IsNullOrEmpty(pretoken.TxId)) { throw new Exception("Cannot send message - Cannot find previous message token metadata!"); } if (pretoken.MetadataAvailable) { if (pretoken.Metadata.TryGetValue("PrevTxId", out var prevtxidfrommeta)) { prevtxid = prevtxidfrommeta; } IToken prepretoken = null; if (pretoken.Metadata.TryGetValue("InitMessage", out var prevmsginit)) { if (prevmsginit != "true") { prepretoken = await NeblioTransactionHelpers.TokenMetadataAsync(TokenTypes.NTP1, TokenId, prevtxid); if (string.IsNullOrEmpty(prepretoken.TxId)) { throw new Exception("Cannot send message - Cannot find pre-previous message token metadata and previous message is not init message!"); } } } if (pretoken.Metadata.TryGetValue("MessageData", out var prevmsgdatafromMeta)) { prevmsgdata = prevmsgdatafromMeta; if (prepretoken != null) { if (prepretoken.MetadataAvailable) { if (prepretoken.Metadata.TryGetValue("SenderPubKey", out var preprevtokenReceiverKey)) { var accEncKey = account.AccountKeys.FirstOrDefault(k => k.PublicKey == preprevtokenReceiverKey); if (accEncKey != null) { try { // dencrypt my prevoious message just when I know that it will be encrypt before send // if this will not happen, the prevmsgdata will contain original data from token metadata which can be encrypted if (pretoken.Metadata.ContainsKey("SenderPubKey")) { var decprevmsg = AsymmetricProvider.DecryptString(prevmsgdata, accEncKey.GetEncryptedKey(dto.Password)); prevmsgdata = decprevmsg; } } catch (Exception ex) { throw new Exception("Cannot send message - Cannot decrypt prevouis message, requeired keuy is not correct format!"); } } } } } } // if sender sent in previous message pubkey he wants to encrypt the message before sending if (pretoken.Metadata.TryGetValue("SenderPubKey", out var receiverpubkey)) { if (!string.IsNullOrEmpty(receiverpubkey)) { try { // encrypt new message msg = AsymmetricProvider.EncryptString(dto.Message, receiverpubkey); // encrypt prevoius message prevmsg = AsymmetricProvider.EncryptString(prevmsgdata, receiverpubkey); } catch (Exception ex) { throw new Exception("Cannot send message - Cannot encrypt the message, probably wrong Key"); } } else { throw new Exception("Cannot send message - Required key is not correct format!"); } } else { // if he dont want to encrypt message just copy msg = dto.Message; // if he dont want encrypted message copy previous message too // but if that message was encrypted before witout his new encryption request it will not be provided in decrypted form and he cannot read it // this is because i dont want to publish my encrypted previous message if this transfer will not be encrypted prevmsg = prevmsgdata; } } } var senderPUB = string.Empty; if (dto.Encrypt) { if (!string.IsNullOrEmpty(dto.KeyId)) { var key = account.AccountKeys.FirstOrDefault(k => k.Id.ToString() == dto.KeyId); if (key != null) { senderPUB = key.PublicKey; // if encryption is required token metadata will contains sender pub key txdto.Metadata.Add("SenderPubKey", senderPUB); } } } if (msg == null) { msg = string.Empty; } if (dto.InitMessage) { txdto.Metadata.Add("InitMessage", "true"); msg = dto.Message; } else { txdto.Metadata.Add("InitMessage", "false"); } txdto.Metadata.Add("PrevTxId", dto.TokenTxId); txdto.Metadata.Add("PreviousMessage", prevmsg); txdto.Metadata.Add("MessageData", msg); var res = await NeblioTransactionHelpers.SendNTP1TokenAPI(txdto, 50000); return(res); } else { throw new Exception("Cannot send message - Cannot find the Account!"); } } else { throw new Exception("Cannot send message - Cannot find the wallet!"); } }