mirror of
https://gitlab.com/futo-org/fcast.git
synced 2025-06-24 21:25:23 +00:00
Removal of encryption.,
This commit is contained in:
parent
9599c1931e
commit
a991b353a6
16 changed files with 24 additions and 980 deletions
|
@ -89,8 +89,6 @@ dependencies {
|
|||
implementation "com.squareup.okhttp3:okhttp:4.11.0"
|
||||
implementation 'com.journeyapps:zxing-android-embedded:4.3.0'
|
||||
implementation 'org.java-websocket:Java-WebSocket:1.5.4'
|
||||
implementation 'org.bouncycastle:bcpkix-jdk18on:1.77'
|
||||
implementation 'org.bouncycastle:bcprov-jdk18on:1.77'
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package com.futo.fcast.receiver
|
||||
|
||||
import SslKeyManager
|
||||
import WebSocketListenerService
|
||||
import android.app.*
|
||||
import android.content.Context
|
||||
|
@ -12,14 +11,11 @@ import android.util.Log
|
|||
import android.widget.Toast
|
||||
import androidx.core.app.NotificationCompat
|
||||
import kotlinx.coroutines.*
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider
|
||||
import java.security.Security
|
||||
|
||||
class NetworkService : Service() {
|
||||
private var _discoveryService: DiscoveryService? = null
|
||||
private var _stopped = false
|
||||
private var _tcpListenerService: TcpListenerService? = null
|
||||
private var _tlsListenerService: TlsListenerService? = null
|
||||
private var _webSocketListenerService: WebSocketListenerService? = null
|
||||
private var _scope: CoroutineScope? = null
|
||||
|
||||
|
@ -110,11 +106,6 @@ class NetworkService : Service() {
|
|||
start()
|
||||
}
|
||||
|
||||
val sslKeyManager = SslKeyManager("fcast_receiver")
|
||||
_tlsListenerService = TlsListenerService(this) { onNewSession(it) }.apply {
|
||||
start(sslKeyManager)
|
||||
}
|
||||
|
||||
Log.i(TAG, "Started NetworkService")
|
||||
Toast.makeText(this, "Started FCast service", Toast.LENGTH_LONG).show()
|
||||
|
||||
|
@ -144,9 +135,6 @@ class NetworkService : Service() {
|
|||
_tcpListenerService?.stop()
|
||||
_tcpListenerService = null
|
||||
|
||||
_tlsListenerService?.stop()
|
||||
_tlsListenerService = null
|
||||
|
||||
try {
|
||||
_webSocketListenerService?.stop()
|
||||
} catch (e: Throwable) {
|
||||
|
@ -197,7 +185,6 @@ class NetworkService : Service() {
|
|||
|
||||
_tcpListenerService?.forEachSession(sender)
|
||||
_webSocketListenerService?.forEachSession(sender)
|
||||
_tlsListenerService?.forEachSession(sender)
|
||||
}
|
||||
|
||||
fun sendPlaybackError(error: String) {
|
||||
|
|
|
@ -1,80 +0,0 @@
|
|||
import android.security.keystore.KeyGenParameterSpec
|
||||
import android.security.keystore.KeyProperties
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo
|
||||
import org.bouncycastle.cert.X509v3CertificateBuilder
|
||||
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider
|
||||
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder
|
||||
import java.io.FileInputStream
|
||||
import java.math.BigInteger
|
||||
import java.security.KeyPairGenerator
|
||||
import java.security.KeyStore
|
||||
import java.security.PrivateKey
|
||||
import java.security.PublicKey
|
||||
import java.util.Calendar
|
||||
import javax.net.ssl.KeyManagerFactory
|
||||
import javax.net.ssl.SSLContext
|
||||
import javax.net.ssl.SSLServerSocketFactory
|
||||
import java.security.cert.X509Certificate
|
||||
import javax.net.ssl.TrustManagerFactory
|
||||
|
||||
class SslKeyManager(private val alias: String) {
|
||||
|
||||
fun getSslServerSocketFactory(): SSLServerSocketFactory {
|
||||
val keyStore = KeyStore.getInstance("AndroidKeyStore").apply { load(null) }
|
||||
//if (!keyStore.containsAlias(alias)) {
|
||||
generateKeyPairAndCertificate(keyStore)
|
||||
//}
|
||||
|
||||
val trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()).apply {
|
||||
init(keyStore)
|
||||
}
|
||||
|
||||
val keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()).apply {
|
||||
init(keyStore, null)
|
||||
}
|
||||
|
||||
val sslContext = SSLContext.getInstance("TLS").apply {
|
||||
init(keyManagerFactory.keyManagers, trustManagerFactory.trustManagers, null)
|
||||
}
|
||||
|
||||
return sslContext.serverSocketFactory
|
||||
}
|
||||
|
||||
private fun generateKeyPairAndCertificate(keyStore: KeyStore) {
|
||||
val keyPairGenerator = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore")
|
||||
val parameterSpec = KeyGenParameterSpec
|
||||
.Builder(alias, KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT or KeyProperties.PURPOSE_SIGN or KeyProperties.PURPOSE_VERIFY)
|
||||
//.setBlockModes(KeyProperties.BLOCK_MODE_ECB)
|
||||
.setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
|
||||
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
|
||||
.setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
|
||||
.build()
|
||||
|
||||
keyPairGenerator.initialize(parameterSpec)
|
||||
|
||||
val keyPair = keyPairGenerator.generateKeyPair()
|
||||
val privateKey = keyPair.private
|
||||
val publicKey = keyPair.public
|
||||
val cert = generateSelfSignedCertificate(privateKey, publicKey)
|
||||
keyStore.setKeyEntry(alias, privateKey, null, arrayOf(cert))
|
||||
}
|
||||
|
||||
private fun generateSelfSignedCertificate(privateKey: PrivateKey, publicKey: PublicKey): X509Certificate {
|
||||
val start = Calendar.getInstance().time
|
||||
val end = Calendar.getInstance().apply { add(Calendar.YEAR, 1000) }.time
|
||||
|
||||
val certInfo = X509v3CertificateBuilder(
|
||||
X500Name("CN=FCastReceiver"),
|
||||
BigInteger.ONE,
|
||||
start,
|
||||
end,
|
||||
X500Name("CN=FCastReceiver"),
|
||||
SubjectPublicKeyInfo.getInstance(publicKey.encoded)
|
||||
)
|
||||
|
||||
val signer = JcaContentSignerBuilder("SHA256withRSA").build(privateKey)
|
||||
return JcaX509CertificateConverter().getCertificate(certInfo.build(signer))
|
||||
}
|
||||
}
|
|
@ -1,134 +0,0 @@
|
|||
package com.futo.fcast.receiver
|
||||
|
||||
import SslKeyManager
|
||||
import android.util.Log
|
||||
import java.io.BufferedInputStream
|
||||
import java.net.Socket
|
||||
import java.security.KeyStore
|
||||
import java.security.cert.Certificate
|
||||
import javax.net.ssl.KeyManagerFactory
|
||||
import javax.net.ssl.SSLContext
|
||||
import javax.net.ssl.SSLServerSocket
|
||||
import javax.net.ssl.TrustManagerFactory
|
||||
|
||||
class TlsListenerService(private val _networkService: NetworkService, private val _onNewSession: (session: FCastSession) -> Unit) {
|
||||
private var _serverSocket: SSLServerSocket? = null
|
||||
private var _stopped: Boolean = false
|
||||
private var _listenThread: Thread? = null
|
||||
private var _clientThreads: ArrayList<Thread> = arrayListOf()
|
||||
private var _sessions: ArrayList<FCastSession> = arrayListOf()
|
||||
|
||||
fun start(sslKeyManager: SslKeyManager) {
|
||||
Log.i(TAG, "Starting TlsListenerService")
|
||||
|
||||
val serverSocketFactory = sslKeyManager.getSslServerSocketFactory()
|
||||
_serverSocket = (serverSocketFactory.createServerSocket(PORT) as SSLServerSocket)
|
||||
|
||||
_listenThread = Thread {
|
||||
Log.i(TAG, "Starting TLS listener")
|
||||
|
||||
try {
|
||||
listenForIncomingConnections()
|
||||
} catch (e: Throwable) {
|
||||
Log.e(TAG, "Stopped TLS listening for connections due to an unexpected error", e)
|
||||
}
|
||||
}
|
||||
|
||||
_listenThread?.start()
|
||||
|
||||
Log.i(TAG, "Started TlsListenerService")
|
||||
}
|
||||
|
||||
fun stop() {
|
||||
Log.i(TAG, "Stopping TlsListenerService")
|
||||
|
||||
_stopped = true
|
||||
|
||||
_serverSocket?.close()
|
||||
_serverSocket = null
|
||||
|
||||
_listenThread?.join()
|
||||
_listenThread = null
|
||||
|
||||
synchronized(_clientThreads) {
|
||||
_clientThreads.clear()
|
||||
}
|
||||
|
||||
Log.i(TAG, "Stopped TlsListenerService")
|
||||
}
|
||||
|
||||
fun forEachSession(handler: (FCastSession) -> Unit) {
|
||||
synchronized(_sessions) {
|
||||
for (session in _sessions) {
|
||||
handler(session)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun listenForIncomingConnections() {
|
||||
Log.i(TAG, "Started TLS listening for incoming connections")
|
||||
|
||||
while (!_stopped) {
|
||||
val clientSocket = _serverSocket?.accept() ?: break
|
||||
|
||||
val clientThread = Thread {
|
||||
try {
|
||||
handleClientConnection(clientSocket)
|
||||
} catch (e: Throwable) {
|
||||
Log.e(TAG, "Failed handle TLS client connection due to an error", e)
|
||||
}
|
||||
}
|
||||
|
||||
synchronized(_clientThreads) {
|
||||
_clientThreads.add(clientThread)
|
||||
}
|
||||
|
||||
clientThread.start()
|
||||
}
|
||||
|
||||
Log.i(TAG, "Stopped TLS listening for incoming connections")
|
||||
}
|
||||
|
||||
private fun handleClientConnection(socket: Socket) {
|
||||
Log.i(TAG, "New TLS connection received from ${socket.remoteSocketAddress}")
|
||||
|
||||
val session = FCastSession(socket.getOutputStream(), socket.remoteSocketAddress, _networkService)
|
||||
synchronized(_sessions) {
|
||||
_sessions.add(session)
|
||||
}
|
||||
_onNewSession(session)
|
||||
|
||||
Log.i(TAG, "Waiting for data from ${socket.remoteSocketAddress}")
|
||||
|
||||
val bufferSize = 4096
|
||||
val buffer = ByteArray(bufferSize)
|
||||
val inputStream = BufferedInputStream(socket.getInputStream())
|
||||
|
||||
var bytesRead: Int
|
||||
while (!_stopped) {
|
||||
bytesRead = inputStream.read(buffer, 0, bufferSize)
|
||||
if (bytesRead == -1) {
|
||||
break
|
||||
}
|
||||
|
||||
session.processBytes(buffer, bytesRead)
|
||||
}
|
||||
|
||||
socket.close()
|
||||
|
||||
synchronized(_sessions) {
|
||||
_sessions.remove(session)
|
||||
}
|
||||
|
||||
synchronized(_clientThreads) {
|
||||
_clientThreads.remove(Thread.currentThread())
|
||||
}
|
||||
|
||||
Log.i(TAG, "Disconnected ${socket.remoteSocketAddress}")
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val TAG = "TlsListenerService"
|
||||
const val PORT = 46897
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue