Coverage Summary for Class: PeerDiscoveryMessage (co.rsk.net.discovery.message)

Class Class, % Method, % Line, %
PeerDiscoveryMessage 0% (0/1) 0% (0/16) 0% (0/60)


1 /* 2  * This file is part of RskJ 3  * Copyright (C) 2017 RSK Labs Ltd. 4  * 5  * This program is free software: you can redistribute it and/or modify 6  * it under the terms of the GNU Lesser General Public License as published by 7  * the Free Software Foundation, either version 3 of the License, or 8  * (at your option) any later version. 9  * 10  * This program is distributed in the hope that it will be useful, 11  * but WITHOUT ANY WARRANTY; without even the implied warranty of 12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13  * GNU Lesser General Public License for more details. 14  * 15  * You should have received a copy of the GNU Lesser General Public License 16  * along with this program. If not, see <http://www.gnu.org/licenses/>. 17  */ 18  19 package co.rsk.net.discovery.message; 20  21 import co.rsk.net.NodeID; 22 import org.apache.commons.lang3.builder.ToStringBuilder; 23 import org.bouncycastle.util.BigIntegers; 24 import org.ethereum.crypto.ECKey; 25 import org.ethereum.crypto.HashUtil; 26 import org.ethereum.crypto.signature.ECDSASignature; 27 import org.ethereum.crypto.signature.Secp256k1; 28 import org.ethereum.util.ByteUtil; 29 import org.ethereum.util.RLPElement; 30 import org.slf4j.Logger; 31 import org.slf4j.LoggerFactory; 32  33 import java.security.SignatureException; 34 import java.util.Optional; 35 import java.util.OptionalInt; 36  37 import static org.ethereum.crypto.HashUtil.keccak256; 38 import static org.ethereum.util.ByteUtil.merge; 39  40 public abstract class PeerDiscoveryMessage { 41  private static final Logger logger = LoggerFactory.getLogger(PeerDiscoveryMessage.class); 42  43  private byte[] wire; 44  45  private byte[] mdc; 46  private byte[] signature; 47  private byte[] type; 48  private byte[] data; 49  private OptionalInt networkId; 50  51  public PeerDiscoveryMessage() {} 52  53  public PeerDiscoveryMessage(byte[] wire, byte[] mdc, byte[] signature, byte[] type, byte[] data){ 54  this.mdc = mdc; 55  this.signature = signature; 56  this.type = type; 57  this.data = data; 58  this.wire = wire; 59  } 60  61  public PeerDiscoveryMessage encode(byte[] type, byte[] data, ECKey privKey) { 62  /* [1] Calc sha3 - prepare for sig */ 63  byte[] payload = new byte[type.length + data.length]; 64  payload[0] = type[0]; 65  System.arraycopy(data, 0, payload, 1, data.length); 66  byte[] forSig = HashUtil.keccak256(payload); 67  68  /* [2] Crate signature*/ 69  ECDSASignature ecdsaSignature = ECDSASignature.fromSignature(privKey.sign(forSig)); 70  71  ecdsaSignature.setV((byte)(ecdsaSignature.getV() - 27)); 72  73  byte[] sigBytes = 74  merge(BigIntegers.asUnsignedByteArray(32, ecdsaSignature.getR()), 75  BigIntegers.asUnsignedByteArray(32, ecdsaSignature.getS()), new byte[]{ecdsaSignature.getV()}); 76  77  // [3] calculate MDC 78  byte[] forSha = merge(sigBytes, type, data); 79  80  // wrap all the data in to the packet 81  this.mdc = HashUtil.keccak256(forSha); 82  this.signature = sigBytes; 83  this.type = type; 84  this.data = data; 85  86  this.wire = merge(this.mdc, this.signature, this.type, this.data); 87  88  return this; 89  } 90  91  public ECKey getKey() { 92  93  byte[] r = new byte[32]; 94  byte[] s = new byte[32]; 95  byte v = signature[64]; 96  97  if (v == 1) { 98  v = 28; 99  } 100  101  if (v == 0) { 102  v = 27; 103  } 104  105  System.arraycopy(signature, 0, r, 0, 32); 106  System.arraycopy(signature, 32, s, 0, 32); 107  108  byte[] msgHash = keccak256(wire, 97, wire.length - 97); 109  110  ECKey outKey = null; 111  try { 112  outKey = Secp256k1.getInstance().signatureToKey(msgHash, ECDSASignature.fromComponents(r, s, v)); 113  } catch (SignatureException e) { 114  logger.error("Error generating key from message", e); 115  } 116  117  return outKey; 118  } 119  120  public OptionalInt getNetworkId() { 121  return this.networkId; 122  } 123  124  protected void setNetworkId(final OptionalInt networkId) { 125  this.networkId = networkId; 126  } 127  128  protected void setNetworkIdWithRLP(final RLPElement networkId) { 129  Integer setValue = null; 130  if (networkId != null) { 131  setValue = ByteUtil.byteArrayToInt(networkId.getRLPData()); 132  } 133  this.setNetworkId(Optional.ofNullable(setValue).map(OptionalInt::of).orElseGet(OptionalInt::empty)); 134  } 135  136  public NodeID getNodeId() { 137  byte[] nodeID = new byte[64]; 138  139  System.arraycopy(getKey().getPubKey(), 1, nodeID, 0, 64); 140  141  return new NodeID(nodeID); 142  } 143  144  public byte[] getPacket() { 145  return wire; 146  } 147  148  public byte[] getMdc() { 149  return mdc; 150  } 151  152  public byte[] getSignature() { 153  return signature; 154  } 155  156  public byte[] getType() { 157  return type; 158  } 159  160  public byte[] getData() { 161  return data; 162  } 163  164  public abstract void parse(byte[] data); 165  166  public DiscoveryMessageType getMessageType() { 167  return null; 168  } 169  170  @Override 171  public String toString() { 172  return new ToStringBuilder(this) 173  .append("mdc", ByteUtil.toHexString(mdc)) 174  .append("signature", ByteUtil.toHexString(signature)) 175  .append("type", ByteUtil.toHexString(type)) 176  .append("data", ByteUtil.toHexString(data)).toString(); 177  } 178 }