-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMyTLSFileServer.java
More file actions
167 lines (137 loc) · 5.62 KB
/
MyTLSFileServer.java
File metadata and controls
167 lines (137 loc) · 5.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
// Java provides SSLSocket and SSLServerSocket classes, which are roughly
// equivalent to Socket and ServerSocket:
// SSLServerSocket listens on a port for incoming connections, like ServerSocket
// SSLSocket connects to an SSLServerSocket, like Socket, and represents an individual
// connection accepted from an SSLServerSocket.
// To create a SSLSocket or SSLServerSocket, we must use "factories"
// Socket factories are a convenient way to set TLS parameters that will
// apply to Sockets created from the factory, e.g:
// Which TLS versions to support
// Which Ciphers and Hashes to use
// Which Keys to use and which Certificates to trust
// As you might guess by the names
// SSLServerSocketFactory creates SSLServerSocket objects
// SSLSocketFactory creates SSLSocket objects
// Java uses KeyStore objects to store Keys and Certificates
// A KeyStore object is used when encrypting and authenticating
// The files that contain Keys and Certificates are password protected
// THE CODE BELOW IS INCOMPLETE AND HAS PROBLEMS
// FOR EXAMPLE, IT IS MISSING THE NECESSARY EXCEPTION HANDLING
import java.io.BufferedReader;
import java.io.Console;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.security.KeyStore;
import javax.net.ServerSocketFactory;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocket;
public class MyTLSFileServer {
private static ServerSocketFactory getSSF()
{
try{
// Get
// an SSL Context that speaks some version of TLS,
// a KeyManager that can hold certs in X.509 format,
// and a JavaKeyStore (JKS) instance
SSLContext ctx = SSLContext.getInstance("TLS");
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
KeyStore ks = KeyStore.getInstance("JKS");
// Obtain the passphrase to unlock the JKS file.
Console console = System.console();
char[] passphrase = console.readPassword("Enter passphrase: ");
// Load the keystore file. The passphrase is
// an optional parameter to allow for integrity
// checking of the keystore. Could be null
ks.load(new FileInputStream("server.jks"), passphrase);
// Init the KeyManagerFactory with a source
// of key material. The passphrase is necessary
// to unlock the private key contained.
kmf.init(ks, passphrase);
// initialise the SSL context with the keys.
ctx.init(kmf.getKeyManagers(), null, null);
// Get the factory we will use to create
// our SSLServerSocket
SSLServerSocketFactory ssf = ctx.getServerSocketFactory();
return ssf;
}
catch(Exception e){
System.out.println(e);
System.out.println("Error creating ServerSocketFactory");
return null;
}
}
public static void sendFile(SSLSocket socket){
try{
System.out.println("Sending file");
// Get the input and output streams so the
// server can read and write to the socket
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
// Get the filename from the Client
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String filename = br.readLine();
File file = new File(filename);
// Show the file requested
System.out.println("File requested: " + filename);
// Checks if file exists on the server
if(!file.exists()){
System.out.println("File does not exist");
return;
}
// Open the file and read it into a byte array
FileInputStream fileInputStream = new FileInputStream(filename);
byte[] buffer = new byte[1024];
int bytesRead = 0;
// Write the file to the socket
while ((bytesRead = fileInputStream.read(buffer)) != -1){
out.write(buffer, 0, bytesRead);
}
//Confim file was sent
System.out.println("File sent");
// Close the file and the socket
fileInputStream.close();
socket.close();
}
catch(Exception e){
System.out.println(e);
System.out.println("Error sending file");
}
}
public static void main(String args[])
{
//Error message if port is not specified
if(args.length != 1){
System.out.println("MyTLSFileServer Incorrect: <port>");
System.exit(1);
}
int port = Integer.parseInt(args[0]);
// use the getSSF method to get a SSLServerSocketFactory and
// create our SSLServerSocket, bound to specified port
ServerSocketFactory ssf = getSSF();
SSLServerSocket ss = null;
try{
ss = (SSLServerSocket) ssf.createServerSocket(port);
String EnabledProtocols[] = {"TLSv1.2", "TLSv1.3"};
ss.setEnabledProtocols(EnabledProtocols);
//Wait for incoming connections
while(true){
SSLSocket s = (SSLSocket)ss.accept();
//Show client has connected
System.out.println("Client connected" + s.getInetAddress());
//handshake
s.startHandshake();
//Send the file to the client
sendFile(s);
}
} catch(Exception e){
System.out.println(e);
System.out.println("Error creating ServerSocket");
}
}
}