Field Summary
Modifier and TypeFieldDescriptionprivate final I2PAppContextThe app context.private final SSLSocketFactoryThe "real" factory.private static booleanTrue once the matcher was loaded.private static final String[]Extra top level domains that are allowed, missing from the country list and the public suffix list.private static final StringDefault country list file name.private static PublicSuffixMatcherThe cached public suffix matcher.private static final String[]The public top level domains allowed by default, not the private ones, from the country list.We exclude everything that Java 8 disables by default, plus some others.Unmodifiable.private static final StringDefault GeoIP directory name.Nothing for now.Java 7 does not enable 1.1 or 1.2 by default on the client side.private static final StringConfig key for disabling hostname verification.private static final StringConfig key of the GeoIP directory.private static final StringFile holding the public suffix list.Constructor Summary
ConstructorsConstructorDescriptionI2PSSLSocketFactory(I2PAppContext context, boolean loadSystemCerts, String relativeCertPath) Create a socket factory with the given context and certificate path.Method Summary
Modifier and TypeMethodDescriptionprivate static voidaddCountries(I2PAppContext ctx, List<String> tlds) Read in the country file and add all TLDs to the list.createSocket(String host, int port) Returns a socket to the host.createSocket(InetAddress host, int port) Returns a socket to the host.private static PublicSuffixMatcherFrom ApachePublicSuffixMatcherLoader.getDefault()private static SSLSocketFactoryinitSSLContext(I2PAppContext context, boolean loadSystemCerts, String relativeCertPath) Loads certs from the ~/.i2p/certificates/ and $I2P/certificates/ directories, or from the absolute path given.private static PublicSuffixListMerge two PublicSuffixLists Have to do this because they are unmodifiable.private static String[]Adapted from Jetty SslContextFactory.java.private static String[]selectCipherSuites(String[] enabledCipherSuites, String[] supportedCipherSuites) Select cipher suites to be used based on configured inclusion and exclusion lists as well as enabled and supported cipher suite lists.private static String[]selectProtocols(String[] enabledProtocols, String[] supportedProtocols) Select protocols to be used based on configured inclusion and exclusion lists as well as enabled and supported protocols.static voidSelect protocols and cipher suites to be used based on configured inclusion and exclusion lists as well as enabled and supported protocols and cipher suites.static voidsetProtocolsAndCiphers(SSLSocket socket) Select protocols and cipher suites to be used based on configured inclusion and exclusion lists as well as enabled and supported protocols and cipher suites.static voidverifyHostname(I2PAppContext ctx, SSLSocket socket, String host) Validate the hostname.
Field Details
PROP_DISABLE
Config key for disabling hostname verification.- See Also:
PROP_GEOIP_DIR
Config key of the GeoIP directory.- See Also:
GEOIP_DIR_DEFAULT
Default GeoIP directory name.- See Also:
COUNTRY_FILE_DEFAULT
Default country list file name.- See Also:
PUBLIC_SUFFIX_LIST
File holding the public suffix list.- See Also:
DEFAULT_MATCHER
The cached public suffix matcher._matcherLoaded
private static volatile boolean _matcherLoadedTrue once the matcher was loaded.DEFAULT_TLDS
The public top level domains allowed by default, not the private ones, from the country list.ADDITIONAL_TLDS
Extra top level domains that are allowed, missing from the country list and the public suffix list.EXCLUDE_PROTOCOLS
INCLUDE_PROTOCOLS
Java 7 does not enable 1.1 or 1.2 by default on the client side. Java 8 does enable 1.1 and 1.2 by default on the client side. 1.3 in Java 11, but it requires: ChaCha20/Poly1305 in Java 12 (we could add a provider) X25519 in Java 13 but may be pulled in to 12 (can't use our unsigned provider) Ed25519 in Java 13 (but we can use our provider) ref: https://openjdk.java.net/jeps/332ref: http://docs.oracle.com/javase/7/docs/technotes/guides/security/SunProviders.html Unmodifiable. Public for RouterConsoleRunner.
EXCLUDE_CIPHERS
We exclude everything that Java 8 disables by default, plus some others. ref: http://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html See also: https://developer.android.com/reference/javax/net/ssl/SSLSocket.html Unmodifiable. Public for RouterConsoleRunner.INCLUDE_CIPHERS
_factory
The "real" factory._context
The app context.
Constructor Details
I2PSSLSocketFactory
public I2PSSLSocketFactory(I2PAppContext context, boolean loadSystemCerts, String relativeCertPath) throws GeneralSecurityException Create a socket factory with the given context and certificate path.- Parameters:
context- the app context whose config and base dirs hold the certificatesloadSystemCerts- true to trust the JVM key store in addition to the loaded certsrelativeCertPath- e.g. "certificates/i2cp"; as of 0.9.41, may be absolute- Throws:
GeneralSecurityException- if the key store cannot be loaded or the context cannot be initialized
Method Details
createSocket
Returns a socket to the host.A host argument that's an IP address (instead of a host name) is not recommended, as this will probably fail SSL certificate validation.
Hostname validation is skipped for localhost addresses, but you still must trust the certificate.
- Parameters:
host- the hostname to validate the certificate against, not an IP literalport- the TCP port to connect to- Returns:
- an SSL socket with the protocol, ciphers and hostname already checked
- Throws:
IOException- if the connection cannot be established
createSocket
Returns a socket to the host.An InetAddress argument created with an IP address (instead of a host name) is not recommended, as this will perform a reverse DNS lookup to get the host name for certificate validation, which will probably then fail.
Hostname validation is skipped for localhost addresses, but you still must trust the certificate.
- Parameters:
host- the address to connect to, reverse resolved for certificate validationport- the TCP port to connect to- Returns:
- an SSL socket with the protocol, ciphers and hostname already checked
- Throws:
IOException- if the connection cannot be established
verifyHostname
public static void verifyHostname(I2PAppContext ctx, SSLSocket socket, String host) throws SSLException Validate the hostname. Warning - be sure to remove [] from IPv6 addresses in host parameter if you got it fromURI.getHost().ref: https://developer.android.com/training/articles/security-ssl.html ref: http://op-co.de/blog/posts/java_sslsocket_mitm/ ref: http://kevinlocke.name/bits/2012/10/03/ssl-certificate-verification-in-dispatch-and-asynchttpclient/
- Parameters:
ctx- the app context supplying the config that can disable verificationsocket- the connected socket whose certificate is checkedhost- the hostname to validate against, without [] around an IPv6 literal- Throws:
SSLException- on hostname verification failure
getDefaultMatcher
From ApachePublicSuffixMatcherLoader.getDefault()https://publicsuffix.org/list/effective_tld_names.dat What does this get us? Deciding whether to issue or accept an SSL wildcard certificate for *.public.suffix.
- Parameters:
ctx- the app context supplying the geoip directory property- Returns:
- null on failure
merge
Merge two PublicSuffixLists Have to do this because they are unmodifiable.- Parameters:
a- the first list, its rules and exceptions come firstb- the second list, appended after the first- Returns:
- a new list holding the rules and exceptions of both
addCountries
Read in the country file and add all TLDs to the list. It would almost be easier just to add all possible 26*26 two-letter codes. Adapted from the GeoIP country-file loader.- Parameters:
ctx- the app context supplying the geoip directory propertytlds- list that collects each lowercased TLD read from the country file
initSSLContext
private static SSLSocketFactory initSSLContext(I2PAppContext context, boolean loadSystemCerts, String relativeCertPath) throws GeneralSecurityException Loads certs from the ~/.i2p/certificates/ and $I2P/certificates/ directories, or from the absolute path given.- Parameters:
context- the app context, source of the log, the config and base directories, and the randomness for the SSL contextloadSystemCerts- true to start from the JVM's default trust store, which also lets the result stand when no I2P certificates are foundrelativeCertPath- e.g. "certificates/i2cp"; as of 0.9.41, may be absolute- Returns:
- a socket factory trusting the certificates that were loaded
- Throws:
GeneralSecurityException- if the key store cannot be created, or no trusted certificates were found at all
setProtocolsAndCiphers
Select protocols and cipher suites to be used based on configured inclusion and exclusion lists as well as enabled and supported protocols and cipher suites.Adapted from Jetty SslContextFactory.java.
- Parameters:
socket- the socket whose enabled protocols and cipher suites are narrowed
setProtocolsAndCiphers
Select protocols and cipher suites to be used based on configured inclusion and exclusion lists as well as enabled and supported protocols and cipher suites.Adapted from Jetty SslContextFactory.java.
- Parameters:
socket- the server socket whose enabled protocols and cipher suites are narrowed
selectProtocols
Select protocols to be used based on configured inclusion and exclusion lists as well as enabled and supported protocols.Adapted from Jetty SslContextFactory.java.
- Parameters:
enabledProtocols- Array of enabled protocolssupportedProtocols- Array of supported protocols- Returns:
- Array of protocols to enable
selectCipherSuites
private static String[] selectCipherSuites(String[] enabledCipherSuites, String[] supportedCipherSuites) Select cipher suites to be used based on configured inclusion and exclusion lists as well as enabled and supported cipher suite lists.Adapted from Jetty SslContextFactory.java.
- Parameters:
enabledCipherSuites- Array of enabled cipher suitessupportedCipherSuites- Array of supported cipher suites- Returns:
- Array of cipher suites to enable
select
private static String[] select(String[] enabledArr, String[] supportedArr, List<String> toEnable, List<String> toExclude) Adapted from Jetty SslContextFactory.java.- Parameters:
enabledArr- the cipher suites the socket has enabled to start fromsupportedArr- the cipher suites the socket supports, the only ones that can be addedtoEnable- Add all these to what is enabled, if supportedtoExclude- Remove all these from what is enabled- Returns:
- the cipher suites to enable, in no particular order, or enabledArr unchanged when the selection comes out empty