1 /* 2 * Conditions Of Use 3 * 4 * This software was developed by employees of the National Institute of 5 * Standards and Technology (NIST), an agency of the Federal Government. 6 * Pursuant to title 15 Untied States Code Section 105, works of NIST 7 * employees are not subject to copyright protection in the United States 8 * and are considered to be in the public domain. As a result, a formal 9 * license is not needed to use the software. 10 * 11 * This software is provided by NIST as a service and is expressly 12 * provided "AS IS." NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED 13 * OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF 14 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT 15 * AND DATA ACCURACY. NIST does not warrant or make any representations 16 * regarding the use of the software or the results thereof, including but 17 * not limited to the correctness, accuracy, reliability or usefulness of 18 * the software. 19 * 20 * Permission to use this software is contingent upon your acceptance 21 * of the terms of this agreement 22 * 23 * . 24 * 25 */ 26 package gov.nist.core.net; 27 28 import java.io.FileInputStream; 29 import java.io.FileNotFoundException; 30 import java.io.IOException; 31 import java.net.DatagramSocket; 32 import java.net.InetAddress; 33 import java.net.InetSocketAddress; 34 import java.net.ServerSocket; 35 import java.net.Socket; 36 import java.net.SocketException; 37 import java.security.GeneralSecurityException; 38 import java.security.KeyStore; 39 import java.security.SecureRandom; 40 41 import javax.net.ssl.KeyManagerFactory; 42 import javax.net.ssl.SSLContext; 43 import javax.net.ssl.SSLServerSocket; 44 import javax.net.ssl.SSLServerSocketFactory; 45 import javax.net.ssl.SSLSocket; 46 import javax.net.ssl.SSLSocketFactory; 47 import javax.net.ssl.TrustManagerFactory; 48 49 /** 50 * extended implementation of a network layer that allows to define a private java 51 * keystores/truststores 52 * 53 * @author f.reif 54 * @version 1.2 55 * @since 1.2 56 * 57 */ 58 public class SslNetworkLayer implements NetworkLayer { 59 60 private SSLSocketFactory sslSocketFactory; 61 62 private SSLServerSocketFactory sslServerSocketFactory; 63 64 public SslNetworkLayer( 65 String trustStoreFile, 66 String keyStoreFile, 67 char[] keyStorePassword, 68 String keyStoreType) throws GeneralSecurityException, FileNotFoundException, IOException 69 { 70 SSLContext sslContext; 71 sslContext = SSLContext.getInstance("TLS"); 72 String algorithm = KeyManagerFactory.getDefaultAlgorithm(); 73 TrustManagerFactory tmFactory = TrustManagerFactory.getInstance(algorithm); 74 KeyManagerFactory kmFactory = KeyManagerFactory.getInstance(algorithm); 75 SecureRandom secureRandom = new SecureRandom(); 76 secureRandom.nextInt(); 77 KeyStore keyStore = KeyStore.getInstance(keyStoreType); 78 KeyStore trustStore = KeyStore.getInstance(keyStoreType); 79 keyStore.load(new FileInputStream(keyStoreFile), keyStorePassword); 80 trustStore.load(new FileInputStream(trustStoreFile), keyStorePassword); 81 tmFactory.init(trustStore); 82 kmFactory.init(keyStore, keyStorePassword); 83 sslContext.init(kmFactory.getKeyManagers(), tmFactory.getTrustManagers(), secureRandom); 84 sslServerSocketFactory = sslContext.getServerSocketFactory(); 85 sslSocketFactory = sslContext.getSocketFactory(); 86 } 87 88 public ServerSocket createServerSocket(int port, int backlog, 89 InetAddress bindAddress) throws IOException { 90 return new ServerSocket(port, backlog, bindAddress); 91 } 92 93 public Socket createSocket(InetAddress address, int port) 94 throws IOException { 95 return new Socket(address, port); 96 } 97 98 public DatagramSocket createDatagramSocket() throws SocketException { 99 return new DatagramSocket(); 100 } 101 102 public DatagramSocket createDatagramSocket(int port, InetAddress laddr) 103 throws SocketException { 104 return new DatagramSocket(port, laddr); 105 } 106 107 /* Added by Daniel J. Martinez Manzano <dani (at) dif.um.es> */ 108 public SSLServerSocket createSSLServerSocket(int port, int backlog, 109 InetAddress bindAddress) throws IOException { 110 return (SSLServerSocket) sslServerSocketFactory.createServerSocket( 111 port, backlog, bindAddress); 112 } 113 114 /* Added by Daniel J. Martinez Manzano <dani (at) dif.um.es> */ 115 public SSLSocket createSSLSocket(InetAddress address, int port) 116 throws IOException { 117 return (SSLSocket) sslSocketFactory.createSocket(address, port); 118 } 119 120 /* Added by Daniel J. Martinez Manzano <dani (at) dif.um.es> */ 121 public SSLSocket createSSLSocket(InetAddress address, int port, 122 InetAddress myAddress) throws IOException { 123 return (SSLSocket) sslSocketFactory.createSocket(address, port, 124 myAddress, 0); 125 } 126 127 public Socket createSocket(InetAddress address, int port, 128 InetAddress myAddress) throws IOException { 129 if (myAddress != null) 130 return new Socket(address, port, myAddress, 0); 131 else 132 return new Socket(address, port); 133 } 134 135 /** 136 * Creates a new Socket, binds it to myAddress:myPort and connects it to 137 * address:port. 138 * 139 * @param address the InetAddress that we'd like to connect to. 140 * @param port the port that we'd like to connect to 141 * @param myAddress the address that we are supposed to bind on or null 142 * for the "any" address. 143 * @param myPort the port that we are supposed to bind on or 0 for a random 144 * one. 145 * 146 * @return a new Socket, bound on myAddress:myPort and connected to 147 * address:port. 148 * @throws IOException if binding or connecting the socket fail for a reason 149 * (exception relayed from the correspoonding Socket methods) 150 */ 151 public Socket createSocket(InetAddress address, int port, 152 InetAddress myAddress, int myPort) 153 throws IOException 154 { 155 if (myAddress != null) 156 return new Socket(address, port, myAddress, myPort); 157 else if (port != 0) 158 { 159 //myAddress is null (i.e. any) but we have a port number 160 Socket sock = new Socket(); 161 sock.bind(new InetSocketAddress(port)); 162 sock.connect(new InetSocketAddress(address, port)); 163 return sock; 164 } 165 else 166 return new Socket(address, port); 167 } 168 } 169