P12Breaker.java
/*
* Copyright (C) 2019 sw4j.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.sw4j.tool.p12breaker.breaker;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author Uwe Plonus
*/
public class P12Breaker {
private final Logger logger = Logger.getLogger(P12Breaker.class.getName());
private final InputStream p12Stream;
private final char[] password;
private final PasswordResultListener listener;
private ErrorType errorType;
private boolean errorOccured = false;
private boolean passwordCorrect = false;
private Exception errorCause;
public P12Breaker(final InputStream p12Stream, final char[] password, final PasswordResultListener listener) {
this.p12Stream = p12Stream;
this.password = password;
this.listener = listener;
}
public void testPassword() {
logger.fine(String.format("Testing password %s", String.valueOf(password)));
KeyStore ks;
try {
ks = KeyStore.getInstance("pkcs12");
} catch (KeyStoreException ksex) {
logger.warning(String.format("KeyStoreException occured for password %s", String.valueOf(password)));
errorOccured = true;
errorType = ErrorType.PKCS12_UNKNOWN;
errorCause = ksex;
return;
}
try {
ks.load(p12Stream, password);
} catch (IOException ioex) {
if (ioex.getCause() instanceof UnrecoverableKeyException) {
logger.fine(String.format("Password %s incorrect", String.valueOf(password)));
passwordCorrect = false;
} else {
logger.log(Level.WARNING,
String.format("IOException occured for password %s", String.valueOf(password)),
ioex);
errorOccured = true;
errorType = ErrorType.IO_ERROR;
errorCause = ioex;
}
return;
} catch (NoSuchAlgorithmException nsaex) {
logger.warning(String.format("NoSuchAlgorithmException occured for password %s", String.valueOf(password)));
errorOccured = true;
errorType = ErrorType.ALGORITHM_ERROR;
errorCause = nsaex;
return;
} catch (CertificateException cex) {
logger.warning(String.format("CertificateException occured for password %s", String.valueOf(password)));
errorOccured = true;
errorType = ErrorType.CERTIFICATE_ERROR;
errorCause = cex;
return;
}
logger.fine(String.format("Password %s correct", String.valueOf(password)));
passwordCorrect = true;
listener.passwordFound(String.valueOf(password));
}
public ErrorType getErrorType() {
return errorType;
}
public boolean hasErrorOccured() {
return errorOccured;
}
public boolean isPasswordCorrect() {
return passwordCorrect;
}
public Exception getErrorCause() {
return errorCause;
}
public enum ErrorType {
PKCS12_UNKNOWN,
IO_ERROR,
ALGORITHM_ERROR,
CERTIFICATE_ERROR;
}
public interface PasswordResultListener {
void passwordFound(String password);
}
}