· 6 years ago · May 12, 2019, 12:06 AM
1package com.sudox.protocol.controllers
2
3import com.sudox.cipher.Cipher
4import com.sudox.protocol.ProtocolController
5import java.util.LinkedList
6
7class HandshakeController(val protocolController: ProtocolController) {
8
9 private var ownPublicKey: ByteArray? = null
10 private var ownPrivateKey: ByteArray? = null
11 private var secretKey: ByteArray? = null
12
13 companion object {
14 private val PUBLIC_KEY_PACKET_NAME = "pub".toByteArray()
15 }
16
17 fun startHandshake() {
18 generateOwnKeysPair()
19 protocolController.sendPacket(PUBLIC_KEY_PACKET_NAME, ownPublicKey!!)
20 }
21
22 fun handleIncomingMessage(slices: LinkedList<ByteArray>) {
23 val name = slices.remove()!!
24
25 if (name.contentEquals(PUBLIC_KEY_PACKET_NAME)) {
26 handlePublicKeyMessage(slices)
27 }
28 }
29
30 private fun handlePublicKeyMessage(slices: LinkedList<ByteArray>) {
31 if (slices.size < 2) {
32 closeHandshakeSession()
33 return
34 }
35
36 val serverPublicKey = slices.remove()!!
37 val serverPublicKeySign = slices.remove()!!
38 val serverOkHmac = slices.remove()!!
39
40 // First step - checking server's public key
41 if (!Cipher.verifyMessageWithECDSA(serverPublicKey, serverPublicKeySign)) {
42 closeHandshakeSession()
43 return
44 }
45
46 // Second step - generate secret key ...
47 secretKey = Cipher.calculateSecretKey(ownPrivateKey, serverPublicKey)
48
49 if (secretKey!!.isEmpty()) {
50 closeHandshakeSession()
51 return
52 }
53
54 // Third step - checking secret key using hmac's comparing
55 val okHmac = Cipher.calculateHMAC(secretKey, "ok".toByteArray())
56
57 if (!serverOkHmac.contentEquals(okHmac)) {
58 closeHandshakeSession()
59 return
60 }
61 }
62
63 private fun generateOwnKeysPair() {
64 val keysPairId = Cipher.generateKeysPair()
65
66 ownPublicKey = Cipher.getPublicKey(keysPairId)
67 ownPrivateKey = Cipher.getPrivateKey(keysPairId)
68
69 Cipher.removeKeysPair(keysPairId)
70 }
71
72 private fun closeHandshakeSession() {
73 removeAllKeys()
74 protocolController.closeConnection(true)
75 }
76
77 private fun removeAllKeys() {
78 ownPublicKey = null
79 ownPrivateKey = null
80 secretKey = null
81 }
82}