org.bitcoinj.crypto.TrustStoreLoader Maven / Gradle / Ivy
/*
* Copyright 2014 Andreas Schildbach
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.bitcoinj.crypto;
import javax.annotation.Nonnull;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.KeyStoreException;
/**
* An implementation of TrustStoreLoader handles fetching a KeyStore from the operating system, a file, etc. It's
* necessary because the Java {@link java.security.KeyStore} abstraction is not completely seamless and for example
* we sometimes need slightly different techniques to load the key store on different versions of Android, MacOS,
* Windows, etc.
*/
public interface TrustStoreLoader {
KeyStore getKeyStore() throws FileNotFoundException, KeyStoreException;
String DEFAULT_KEYSTORE_TYPE = KeyStore.getDefaultType();
String DEFAULT_KEYSTORE_PASSWORD = "changeit";
class DefaultTrustStoreLoader implements TrustStoreLoader {
@Override
public KeyStore getKeyStore() throws FileNotFoundException, KeyStoreException {
String keystorePath = null;
String keystoreType = DEFAULT_KEYSTORE_TYPE;
try {
// Check if we are on Android.
Class> version = Class.forName("android.os.Build$VERSION");
// Build.VERSION_CODES.ICE_CREAM_SANDWICH is 14.
if (version.getDeclaredField("SDK_INT").getInt(version) >= 14) {
return loadIcsKeyStore();
} else {
keystoreType = "BKS";
keystorePath = System.getProperty("java.home")
+ "/etc/security/cacerts.bks".replace('/', File.separatorChar);
}
} catch (ClassNotFoundException e) {
// NOP. android.os.Build is not present, so we are not on Android. Fall through.
} catch (NoSuchFieldException e) {
throw new RuntimeException(e); // Should never happen.
} catch (IllegalAccessException e) {
throw new RuntimeException(e); // Should never happen.
}
if (keystorePath == null) {
keystorePath = System.getProperty("javax.net.ssl.trustStore");
}
if (keystorePath == null) {
return loadFallbackStore();
}
try {
return X509Utils.loadKeyStore(keystoreType, DEFAULT_KEYSTORE_PASSWORD,
new FileInputStream(keystorePath));
} catch (FileNotFoundException e) {
// If we failed to find a system trust store, load our own fallback trust store. This can fail on
// Android but we should never reach it there.
return loadFallbackStore();
}
}
private KeyStore loadIcsKeyStore() throws KeyStoreException {
try {
// After ICS, Android provided this nice method for loading the keystore,
// so we don't have to specify the location explicitly.
KeyStore keystore = KeyStore.getInstance("AndroidCAStore");
keystore.load(null, null);
return keystore;
} catch (IOException x) {
throw new KeyStoreException(x);
} catch (GeneralSecurityException x) {
throw new KeyStoreException(x);
}
}
private KeyStore loadFallbackStore() throws FileNotFoundException, KeyStoreException {
return X509Utils.loadKeyStore("JKS", DEFAULT_KEYSTORE_PASSWORD, getClass().getResourceAsStream("cacerts"));
}
}
class FileTrustStoreLoader implements TrustStoreLoader {
private final File path;
public FileTrustStoreLoader(@Nonnull File path) throws FileNotFoundException {
if (!path.exists())
throw new FileNotFoundException(path.toString());
this.path = path;
}
@Override
public KeyStore getKeyStore() throws FileNotFoundException, KeyStoreException {
return X509Utils.loadKeyStore(DEFAULT_KEYSTORE_TYPE, DEFAULT_KEYSTORE_PASSWORD, new FileInputStream(path));
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy