public static PartnerSyncMessage PrepareSignedMessage(byte[] data) { PartnerSyncMessage msg = new PartnerSyncMessage(); /* Provide certificate data */ msg.certId = CryptoEngine.GetInstance().Certificate.Cert.Id; msg.cert = new byte[CryptoEngine.GetInstance().Certificate.Cert.Signature.ToByteArray().Length]; CryptoEngine.GetInstance().Certificate.Cert.Signature.ToByteArray().CopyTo(msg.cert, 0); msg.key = CryptoEngine.GetInstance().Certificate.Keys.PublicKey.PublicKey.ToByteArray(); /* Copy data itself */ msg.data = data; var dsa = CryptoEngine.GetInstance().ECLoad(CryptoEngine.GetInstance().Certificate.Keys.PublicKey.PublicKey.ToByteArray(), CryptoEngine.GetInstance().Certificate.Keys.PrivateKey.ToByteArray()); /* Sign the data */ msg.signature = dsa.SignData(data, HashAlgorithmName.SHA256); return(msg); }
public static void PartnerJoinRequest(PartnerSyncRequestJoin requestJoin) { /* Build the message */ var content = PreparePartnerSyncRequest(PartnerSyncMessageType.PARTNER_JOIN, JSONSerializer <PartnerSyncRequestJoin> .Serialize(requestJoin)); byte[] dbDump = null; var newPartners = new List <string>(); /* Ask each of the participants to send its database version */ foreach (var partner in Partners) { var request = Request(partner); try { JSONSerializer <PartnerSyncMessage> .Serialize(content, request.GetRequestStream()).Close(); } catch (WebException) { /* Node might be down */ continue; } PartnerSyncMessage signedResponse; try { /* Get the response */ signedResponse = JSONSerializer <PartnerSyncMessage> .Deserialize(request.GetResponse().GetResponseStream()); } catch (SerializationException) { continue; } if (!CryptoEngine.GetInstance().verifyCertificate(signedResponse.key, signedResponse.certId, signedResponse.cert).VerifyData(signedResponse.data, signedResponse.signature)) { /* Invalid response. Ignore. */ continue; } var response = JSONSerializer <PartnerSyncResponseDBDump> .Deserialize(JSONSerializer <PartnerSyncMessageData> .Deserialize(signedResponse.data).Data); foreach (var newPartner in response.Partners) { if ((!Partners.Exists(s => s == newPartner)) && (newPartners.Exists(s => s == newPartner)) && (newPartner != Config <string> .GetInstance()["PUBLIC_ADDRESS"]) && (newPartner.StartsWith("http://") || newPartner.StartsWith("https://"))) { newPartners.Add(newPartner); } } /* Choose largest dump too sync with (TODO: Not sure it's the best idea) - Currently best-effort. */ if ((dbDump == null) || (dbDump.Length < response.DBDump.Length)) { dbDump = response.DBDump; } } if (dbDump != null) { /* Write DB To file */ var dbFile = File.Open(Config <string> .GetInstance()["DB_Filename"], FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite); using (var writer = new BinaryWriter(dbFile)) { writer.Write(dbDump); } } /* Add additional partners */ foreach (var newPartner in newPartners) { Partners.Add(newPartner); } }