🔥 Remove duplicate code
This commit is contained in:
parent
fafabf64a3
commit
37cda3df56
@ -62,13 +62,13 @@ object V3MessageFactory {
|
|||||||
fun getPayload(command: String, stream: InputStream, length: Int): MessagePayload? = when (command) {
|
fun getPayload(command: String, stream: InputStream, length: Int): MessagePayload? = when (command) {
|
||||||
"version" -> parseVersion(stream)
|
"version" -> parseVersion(stream)
|
||||||
"verack" -> VerAck()
|
"verack" -> VerAck()
|
||||||
"addr" -> parseAddr(stream)
|
"addr" -> Addr(parseList(stream) { parseAddress(it, false) })
|
||||||
"inv" -> parseInv(stream)
|
"inv" -> Inv(parseList(stream) { parseInventoryVector(it) })
|
||||||
"getdata" -> parseGetData(stream)
|
"getdata" -> GetData(parseList(stream) { parseInventoryVector(it) })
|
||||||
"object" -> readObject(stream, length)
|
"object" -> readObject(stream, length)
|
||||||
"custom" -> readCustom(stream, length)
|
"custom" -> readCustom(stream, length)
|
||||||
else -> {
|
else -> {
|
||||||
LOG.debug("Unknown command: " + command)
|
LOG.debug("Unknown command: $command")
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -85,73 +85,40 @@ object V3MessageFactory {
|
|||||||
val stream = Decode.varInt(input, counter)
|
val stream = Decode.varInt(input, counter)
|
||||||
|
|
||||||
val data = Decode.bytes(input, length - counter.length())
|
val data = Decode.bytes(input, length - counter.length())
|
||||||
var payload: ObjectPayload
|
val payload: ObjectPayload = try {
|
||||||
try {
|
Factory.getObjectPayload(objectType, version, stream, ByteArrayInputStream(data), data.size)
|
||||||
val dataStream = ByteArrayInputStream(data)
|
|
||||||
payload = Factory.getObjectPayload(objectType, version, stream, dataStream, data.size)
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
if (LOG.isTraceEnabled) {
|
if (LOG.isTraceEnabled) {
|
||||||
LOG.trace("Could not parse object payload - using generic payload instead", e)
|
LOG.trace("Could not parse object payload - using generic payload instead", e)
|
||||||
LOG.trace(Strings.hex(data))
|
LOG.trace(Strings.hex(data))
|
||||||
}
|
}
|
||||||
payload = GenericPayload(version, stream, data)
|
GenericPayload(version, stream, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ObjectMessage.Builder()
|
return ObjectMessage(
|
||||||
.nonce(nonce)
|
nonce, expiresTime, payload, objectType, version, stream
|
||||||
.expiresTime(expiresTime)
|
)
|
||||||
.objectType(objectType)
|
|
||||||
.stream(stream)
|
|
||||||
.payload(payload)
|
|
||||||
.build()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun parseGetData(stream: InputStream): GetData {
|
private fun <T> parseList(stream: InputStream, reader: (InputStream) -> (T)): List<T> {
|
||||||
val count = Decode.varInt(stream)
|
val count = Decode.varInt(stream)
|
||||||
val inventoryVectors = LinkedList<InventoryVector>()
|
val items = LinkedList<T>()
|
||||||
for (i in 0 until count) {
|
for (i in 0 until count) {
|
||||||
inventoryVectors.add(parseInventoryVector(stream))
|
items.add(reader(stream))
|
||||||
}
|
}
|
||||||
return GetData(inventoryVectors)
|
return items
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun parseInv(stream: InputStream): Inv {
|
private fun parseVersion(stream: InputStream) = Version(
|
||||||
val count = Decode.varInt(stream)
|
version = Decode.int32(stream),
|
||||||
val inventoryVectors = LinkedList<InventoryVector>()
|
services = Decode.int64(stream),
|
||||||
for (i in 0 until count) {
|
timestamp = Decode.int64(stream),
|
||||||
inventoryVectors.add(parseInventoryVector(stream))
|
addrRecv = parseAddress(stream, true),
|
||||||
}
|
addrFrom = parseAddress(stream, true),
|
||||||
return Inv(inventoryVectors)
|
nonce = Decode.int64(stream),
|
||||||
}
|
userAgent = Decode.varString(stream),
|
||||||
|
streams = Decode.varIntList(stream)
|
||||||
private fun parseAddr(stream: InputStream): Addr {
|
)
|
||||||
val count = Decode.varInt(stream)
|
|
||||||
val networkAddresses = LinkedList<NetworkAddress>()
|
|
||||||
for (i in 0 until count) {
|
|
||||||
networkAddresses.add(parseAddress(stream, false))
|
|
||||||
}
|
|
||||||
return Addr(networkAddresses)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun parseVersion(stream: InputStream): Version {
|
|
||||||
val version = Decode.int32(stream)
|
|
||||||
val services = Decode.int64(stream)
|
|
||||||
val timestamp = Decode.int64(stream)
|
|
||||||
val addrRecv = parseAddress(stream, true)
|
|
||||||
val addrFrom = parseAddress(stream, true)
|
|
||||||
val nonce = Decode.int64(stream)
|
|
||||||
val userAgent = Decode.varString(stream)
|
|
||||||
val streamNumbers = Decode.varIntList(stream)
|
|
||||||
|
|
||||||
return Version.Builder()
|
|
||||||
.version(version)
|
|
||||||
.services(services)
|
|
||||||
.timestamp(timestamp)
|
|
||||||
.addrRecv(addrRecv).addrFrom(addrFrom)
|
|
||||||
.nonce(nonce)
|
|
||||||
.userAgent(userAgent)
|
|
||||||
.streams(*streamNumbers).build()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun parseInventoryVector(stream: InputStream) = InventoryVector(Decode.bytes(stream, 32))
|
private fun parseInventoryVector(stream: InputStream) = InventoryVector(Decode.bytes(stream, 32))
|
||||||
|
|
||||||
@ -168,13 +135,10 @@ object V3MessageFactory {
|
|||||||
val services = Decode.int64(stream)
|
val services = Decode.int64(stream)
|
||||||
val ipv6 = Decode.bytes(stream, 16)
|
val ipv6 = Decode.bytes(stream, 16)
|
||||||
val port = Decode.uint16(stream)
|
val port = Decode.uint16(stream)
|
||||||
return NetworkAddress.Builder()
|
|
||||||
.time(time)
|
return NetworkAddress(
|
||||||
.stream(streamNumber)
|
time, streamNumber, services, ipv6, port
|
||||||
.services(services)
|
)
|
||||||
.ipv6(ipv6)
|
|
||||||
.port(port)
|
|
||||||
.build()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun testChecksum(checksum: ByteArray, payload: ByteArray): Boolean {
|
private fun testChecksum(checksum: ByteArray, payload: ByteArray): Boolean {
|
||||||
|
@ -36,12 +36,16 @@ import javax.crypto.spec.SecretKeySpec
|
|||||||
/**
|
/**
|
||||||
* Implements everything that isn't directly dependent on either Spongy- or Bouncycastle.
|
* Implements everything that isn't directly dependent on either Spongy- or Bouncycastle.
|
||||||
*/
|
*/
|
||||||
abstract class AbstractCryptography protected constructor(@JvmField protected val provider: Provider) : Cryptography, InternalContext.ContextHolder {
|
abstract class AbstractCryptography protected constructor(@JvmField protected val provider: Provider) : Cryptography,
|
||||||
|
InternalContext.ContextHolder {
|
||||||
private lateinit var ctx: InternalContext
|
private lateinit var ctx: InternalContext
|
||||||
|
|
||||||
@JvmField protected val ALGORITHM_ECDSA = "ECDSA"
|
@JvmField
|
||||||
@JvmField protected val ALGORITHM_ECDSA_SHA1 = "SHA1withECDSA"
|
protected val ALGORITHM_ECDSA = "ECDSA"
|
||||||
@JvmField protected val ALGORITHM_EVP_SHA256 = "SHA256withECDSA"
|
@JvmField
|
||||||
|
protected val ALGORITHM_ECDSA_SHA1 = "SHA1withECDSA"
|
||||||
|
@JvmField
|
||||||
|
protected val ALGORITHM_EVP_SHA256 = "SHA256withECDSA"
|
||||||
|
|
||||||
override fun setContext(context: InternalContext) {
|
override fun setContext(context: InternalContext) {
|
||||||
ctx = context
|
ctx = context
|
||||||
@ -65,8 +69,12 @@ abstract class AbstractCryptography protected constructor(@JvmField protected va
|
|||||||
return mda.digest(mda.digest())
|
return mda.digest(mda.digest())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun doubleSha512(data: ByteArray, length: Int): ByteArray {
|
override fun doubleSha512(data: ByteArray, length: Int) = doubleHash("SHA-512", data, length);
|
||||||
val mda = md("SHA-512")
|
|
||||||
|
override fun doubleSha256(data: ByteArray, length: Int) = doubleHash("SHA-256", data, length);
|
||||||
|
|
||||||
|
private fun doubleHash(method: String, data: ByteArray, length: Int): ByteArray {
|
||||||
|
val mda = md(method)
|
||||||
mda.update(data, 0, length)
|
mda.update(data, 0, length)
|
||||||
return mda.digest(mda.digest())
|
return mda.digest(mda.digest())
|
||||||
}
|
}
|
||||||
@ -75,12 +83,6 @@ abstract class AbstractCryptography protected constructor(@JvmField protected va
|
|||||||
return hash("RIPEMD160", *data)
|
return hash("RIPEMD160", *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun doubleSha256(data: ByteArray, length: Int): ByteArray {
|
|
||||||
val mda = md("SHA-256")
|
|
||||||
mda.update(data, 0, length)
|
|
||||||
return mda.digest(mda.digest())
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun sha1(vararg data: ByteArray): ByteArray {
|
override fun sha1(vararg data: ByteArray): ByteArray {
|
||||||
return hash("SHA-1", *data)
|
return hash("SHA-1", *data)
|
||||||
}
|
}
|
||||||
@ -91,13 +93,17 @@ abstract class AbstractCryptography protected constructor(@JvmField protected va
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun doProofOfWork(objectMessage: ObjectMessage, nonceTrialsPerByte: Long,
|
override fun doProofOfWork(
|
||||||
extraBytes: Long, callback: ProofOfWorkEngine.Callback) {
|
objectMessage: ObjectMessage, nonceTrialsPerByte: Long,
|
||||||
|
extraBytes: Long, callback: ProofOfWorkEngine.Callback
|
||||||
|
) {
|
||||||
|
|
||||||
val initialHash = getInitialHash(objectMessage)
|
val initialHash = getInitialHash(objectMessage)
|
||||||
|
|
||||||
val target = getProofOfWorkTarget(objectMessage,
|
val target = getProofOfWorkTarget(
|
||||||
max(nonceTrialsPerByte, NETWORK_NONCE_TRIALS_PER_BYTE), max(extraBytes, NETWORK_EXTRA_BYTES))
|
objectMessage,
|
||||||
|
max(nonceTrialsPerByte, NETWORK_NONCE_TRIALS_PER_BYTE), max(extraBytes, NETWORK_EXTRA_BYTES)
|
||||||
|
)
|
||||||
|
|
||||||
ctx.proofOfWorkEngine.calculateNonce(initialHash, target, callback)
|
ctx.proofOfWorkEngine.calculateNonce(initialHash, target, callback)
|
||||||
}
|
}
|
||||||
@ -105,7 +111,10 @@ abstract class AbstractCryptography protected constructor(@JvmField protected va
|
|||||||
@Throws(InsufficientProofOfWorkException::class)
|
@Throws(InsufficientProofOfWorkException::class)
|
||||||
override fun checkProofOfWork(objectMessage: ObjectMessage, nonceTrialsPerByte: Long, extraBytes: Long) {
|
override fun checkProofOfWork(objectMessage: ObjectMessage, nonceTrialsPerByte: Long, extraBytes: Long) {
|
||||||
val target = getProofOfWorkTarget(objectMessage, nonceTrialsPerByte, extraBytes)
|
val target = getProofOfWorkTarget(objectMessage, nonceTrialsPerByte, extraBytes)
|
||||||
val value = doubleSha512(objectMessage.nonce ?: throw ApplicationException("Object without nonce"), getInitialHash(objectMessage))
|
val value = doubleSha512(
|
||||||
|
objectMessage.nonce ?: throw ApplicationException("Object without nonce"),
|
||||||
|
getInitialHash(objectMessage)
|
||||||
|
)
|
||||||
if (Bytes.lt(target, value, 8)) {
|
if (Bytes.lt(target, value, 8)) {
|
||||||
throw InsufficientProofOfWorkException(target, value)
|
throw InsufficientProofOfWorkException(target, value)
|
||||||
}
|
}
|
||||||
@ -136,7 +145,11 @@ abstract class AbstractCryptography protected constructor(@JvmField protected va
|
|||||||
return sha512(objectMessage.payloadBytesWithoutNonce)
|
return sha512(objectMessage.payloadBytesWithoutNonce)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getProofOfWorkTarget(objectMessage: ObjectMessage, nonceTrialsPerByte: Long, extraBytes: Long): ByteArray {
|
override fun getProofOfWorkTarget(
|
||||||
|
objectMessage: ObjectMessage,
|
||||||
|
nonceTrialsPerByte: Long,
|
||||||
|
extraBytes: Long
|
||||||
|
): ByteArray {
|
||||||
@Suppress("NAME_SHADOWING")
|
@Suppress("NAME_SHADOWING")
|
||||||
val nonceTrialsPerByte = if (nonceTrialsPerByte == 0L) NETWORK_NONCE_TRIALS_PER_BYTE else nonceTrialsPerByte
|
val nonceTrialsPerByte = if (nonceTrialsPerByte == 0L) NETWORK_NONCE_TRIALS_PER_BYTE else nonceTrialsPerByte
|
||||||
@Suppress("NAME_SHADOWING")
|
@Suppress("NAME_SHADOWING")
|
||||||
@ -181,12 +194,16 @@ abstract class AbstractCryptography protected constructor(@JvmField protected va
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createPubkey(version: Long, stream: Long, privateSigningKey: ByteArray, privateEncryptionKey: ByteArray,
|
override fun createPubkey(
|
||||||
nonceTrialsPerByte: Long, extraBytes: Long, vararg features: Pubkey.Feature): Pubkey {
|
version: Long, stream: Long, privateSigningKey: ByteArray, privateEncryptionKey: ByteArray,
|
||||||
return Factory.createPubkey(version, stream,
|
nonceTrialsPerByte: Long, extraBytes: Long, vararg features: Pubkey.Feature
|
||||||
|
): Pubkey {
|
||||||
|
return Factory.createPubkey(
|
||||||
|
version, stream,
|
||||||
createPublicKey(privateSigningKey),
|
createPublicKey(privateSigningKey),
|
||||||
createPublicKey(privateEncryptionKey),
|
createPublicKey(privateEncryptionKey),
|
||||||
nonceTrialsPerByte, extraBytes, *features)
|
nonceTrialsPerByte, extraBytes, *features
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun keyToBigInt(privateKey: ByteArray): BigInteger {
|
override fun keyToBigInt(privateKey: ByteArray): BigInteger {
|
||||||
|
@ -32,15 +32,11 @@ import java.util.*
|
|||||||
|
|
||||||
class JdbcAddressRepository(config: JdbcConfig) : JdbcHelper(config), AddressRepository {
|
class JdbcAddressRepository(config: JdbcConfig) : JdbcHelper(config), AddressRepository {
|
||||||
|
|
||||||
override fun findContact(ripeOrTag: ByteArray) = find("private_key is null").firstOrNull {
|
override fun findContact(ripeOrTag: ByteArray) = find("private_key is null").getByRipeOrTag(ripeOrTag)
|
||||||
if (it.version > 3) {
|
|
||||||
Arrays.equals(ripeOrTag, it.tag)
|
|
||||||
} else {
|
|
||||||
Arrays.equals(ripeOrTag, it.ripe)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun findIdentity(ripeOrTag: ByteArray) = find("private_key is not null").firstOrNull {
|
override fun findIdentity(ripeOrTag: ByteArray) = find("private_key is not null").getByRipeOrTag(ripeOrTag)
|
||||||
|
|
||||||
|
private fun List<BitmessageAddress>.getByRipeOrTag(ripeOrTag: ByteArray): BitmessageAddress? = firstOrNull {
|
||||||
if (it.version > 3) {
|
if (it.version > 3) {
|
||||||
Arrays.equals(ripeOrTag, it.tag)
|
Arrays.equals(ripeOrTag, it.tag)
|
||||||
} else {
|
} else {
|
||||||
@ -67,11 +63,13 @@ class JdbcAddressRepository(config: JdbcConfig) : JdbcHelper(config), AddressRep
|
|||||||
try {
|
try {
|
||||||
config.getConnection().use { connection ->
|
config.getConnection().use { connection ->
|
||||||
connection.createStatement().use { stmt ->
|
connection.createStatement().use { stmt ->
|
||||||
stmt.executeQuery("""
|
stmt.executeQuery(
|
||||||
|
"""
|
||||||
SELECT address, alias, public_key, private_key, subscribed, chan
|
SELECT address, alias, public_key, private_key, subscribed, chan
|
||||||
FROM Address
|
FROM Address
|
||||||
WHERE $where
|
WHERE $where
|
||||||
""").use { rs ->
|
"""
|
||||||
|
).use { rs ->
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
val address: BitmessageAddress
|
val address: BitmessageAddress
|
||||||
|
|
||||||
@ -79,8 +77,10 @@ class JdbcAddressRepository(config: JdbcConfig) : JdbcHelper(config), AddressRep
|
|||||||
if (privateKeyStream == null) {
|
if (privateKeyStream == null) {
|
||||||
address = BitmessageAddress(rs.getString("address"))
|
address = BitmessageAddress(rs.getString("address"))
|
||||||
rs.getBlob("public_key")?.let { publicKeyBlob ->
|
rs.getBlob("public_key")?.let { publicKeyBlob ->
|
||||||
var pubkey: Pubkey = Factory.readPubkey(address.version, address.stream,
|
var pubkey: Pubkey = Factory.readPubkey(
|
||||||
publicKeyBlob.binaryStream, publicKeyBlob.length().toInt(), false)!!
|
address.version, address.stream,
|
||||||
|
publicKeyBlob.binaryStream, publicKeyBlob.length().toInt(), false
|
||||||
|
)!!
|
||||||
if (address.version == 4L && pubkey is V3Pubkey) {
|
if (address.version == 4L && pubkey is V3Pubkey) {
|
||||||
pubkey = V4Pubkey(pubkey)
|
pubkey = V4Pubkey(pubkey)
|
||||||
}
|
}
|
||||||
@ -109,8 +109,10 @@ class JdbcAddressRepository(config: JdbcConfig) : JdbcHelper(config), AddressRep
|
|||||||
private fun exists(address: BitmessageAddress): Boolean {
|
private fun exists(address: BitmessageAddress): Boolean {
|
||||||
config.getConnection().use { connection ->
|
config.getConnection().use { connection ->
|
||||||
connection.createStatement().use { stmt ->
|
connection.createStatement().use { stmt ->
|
||||||
stmt.executeQuery("SELECT '1' FROM Address " +
|
stmt.executeQuery(
|
||||||
"WHERE address='" + address.address + "'").use { rs -> return rs.next() }
|
"SELECT '1' FROM Address " +
|
||||||
|
"WHERE address='" + address.address + "'"
|
||||||
|
).use { rs -> return rs.next() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -159,7 +161,8 @@ class JdbcAddressRepository(config: JdbcConfig) : JdbcHelper(config), AddressRep
|
|||||||
private fun insert(address: BitmessageAddress) {
|
private fun insert(address: BitmessageAddress) {
|
||||||
config.getConnection().use { connection ->
|
config.getConnection().use { connection ->
|
||||||
connection.prepareStatement(
|
connection.prepareStatement(
|
||||||
"INSERT INTO Address (address, version, alias, public_key, private_key, subscribed, chan) " + "VALUES (?, ?, ?, ?, ?, ?, ?)").use { ps ->
|
"INSERT INTO Address (address, version, alias, public_key, private_key, subscribed, chan) " + "VALUES (?, ?, ?, ?, ?, ?, ?)"
|
||||||
|
).use { ps ->
|
||||||
ps.setString(1, address.address)
|
ps.setString(1, address.address)
|
||||||
ps.setLong(2, address.version)
|
ps.setLong(2, address.version)
|
||||||
ps.setString(3, address.alias)
|
ps.setString(3, address.alias)
|
||||||
@ -184,7 +187,10 @@ class JdbcAddressRepository(config: JdbcConfig) : JdbcHelper(config), AddressRep
|
|||||||
|
|
||||||
override fun remove(address: BitmessageAddress) {
|
override fun remove(address: BitmessageAddress) {
|
||||||
try {
|
try {
|
||||||
config.getConnection().use { connection -> connection.createStatement().use { stmt -> stmt.executeUpdate("DELETE FROM Address WHERE address = '" + address.address + "'") } }
|
config.getConnection().use { connection ->
|
||||||
|
connection.createStatement()
|
||||||
|
.use { stmt -> stmt.executeUpdate("DELETE FROM Address WHERE address = '" + address.address + "'") }
|
||||||
|
}
|
||||||
} catch (e: SQLException) {
|
} catch (e: SQLException) {
|
||||||
LOG.error(e.message, e)
|
LOG.error(e.message, e)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user