//$Header: /as2/sqlscript/runtime/Update29to30.java 2 11.11.11 12:14 Heller $
package sqlscript.runtime;
import de.mendelson.comm.as2.database.IUpdater;
import de.mendelson.comm.as2.preferences.PreferencesAS2;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.cert.Certificate;
import java.security.KeyStore;
import java.security.MessageDigest;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Enumeration;
/*
* Copyright (C) mendelson-e-commerce GmbH Berlin Germany
*
* This software is subject to the license agreement set forth in the license.
* Please read and agree to all terms before using this software.
* Other product and brand names are trademarks of their respective owners.
*/
/**
*
* Update the database from version 29 to version 30
* @author S.Heller
* @version $Revision: 2 $
* @since build 128
*/
public class Update29to30 implements IUpdater {
/**Store if this was a successfully operation*/
private boolean success = false;
/** Return if the update was successfully */
@Override
public boolean updateWasSuccessfully() {
return (this.success);
}
/** Starts the update process */
@Override
public void startUpdate(Connection connection) throws Exception {
Statement statement = connection.createStatement();
statement.execute("ALTER TABLE certificates ADD COLUMN fingerprintsha1 VARCHAR(255)");
ResultSet result = statement.executeQuery("SELECT * FROM certificates");
while (result.next()) {
int partnerId = result.getInt("partnerid");
int category = result.getInt("category");
int prio = result.getInt("prio");
String serial = result.getString("serialid");
this.updateCertEntry(connection, partnerId, category, prio, serial);
}
result.close();
statement.execute("ALTER TABLE certificates DROP COLUMN serialid");
statement.close();
this.success = true;
}
/**Inserts a new entry into the certificate table*/
private void updateCertEntry(Connection connection, int partnerId, int category, int prio, String serial) {
try {
KeyStore keystore = KeyStore.getInstance("PKCS12", "BC");
PreferencesAS2 preferences = new PreferencesAS2();
char[] keystorePass = preferences.get(PreferencesAS2.KEYSTORE_PASS).toCharArray();
this.loadKeyStore(keystore, "certificates.p12", keystorePass);
X509Certificate cert = this.getCertificateBySerial(keystore, serial);
if (cert == null) {
System.out.println("WARNING: Certificate with serial \"" + serial + "\" NOT found in the underlaying keystore. Please visit the partner settings for the partner \"" + partnerId + "\".");
} else {
PreparedStatement statement = connection.prepareStatement(
"UPDATE certificates SET fingerprintsha1=? WHERE partnerid=? AND category=? AND prio=? AND serialid=?");
statement.setString(1, this.getFingerPrintSHA1(cert));
statement.setInt(2, partnerId);
statement.setInt(3, category);
statement.setInt(4, prio);
statement.setString(5, serial);
statement.execute();
statement.close();
}
} catch (Exception e) {
System.out.println("WARNING: " + e.getMessage());
}
}
/**Loads a keystore and returns it. The passed keystore has to be created
*first by the security provider, e.g. using the code
*KeyStore.getInstance(<keystoretype>, <provider>);
*If the passed filename does not exist a new, empty keystore will be created
*/
private void loadKeyStore(KeyStore keystoreInstance,
String filename, char[] keystorePass) throws Exception {
File inFile = new File(filename);
if (inFile.exists()) {
FileInputStream inStream = new FileInputStream(inFile);
keystoreInstance.load(inStream, keystorePass);
inStream.close();
} else {
keystoreInstance.load(null, null);
}
}
/**Converts the passed certificate to an X509 certificate. Mainly it is already
*in this format.
*/
private X509Certificate convertToX509Certificate(Certificate certificate)
throws CertificateException, IOException {
CertificateFactory factory = CertificateFactory.getInstance("X.509");
ByteArrayInputStream inStream =
new ByteArrayInputStream(certificate.getEncoded());
X509Certificate cert = (X509Certificate) factory.generateCertificate(inStream);
inStream.close();
return (cert);
}
private X509Certificate getCertificateBySerial(KeyStore keystore, String serial) throws Exception {
Enumeration<String> enumeration = keystore.aliases();
while (enumeration.hasMoreElements()) {
String alias = enumeration.nextElement();
X509Certificate testCert = this.convertToX509Certificate(keystore.getCertificate(alias));
if (testCert.getSerialNumber().toString().equals(serial)) {
return (testCert);
}
}
return (null);
}
/**@param digest to create the hash value, please use SHA1 or MD5 only
*
*/
private String getFingerPrintSHA1(X509Certificate certificate) throws Exception {
MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
byte[] bytes = messageDigest.digest(certificate.getEncoded());
StringBuilder fingerprint = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
if (i > 0) {
fingerprint.append(":");
}
String singleByte = Integer.toHexString(bytes[i] & 0xFF).toUpperCase();
if (singleByte.length() == 0) {
fingerprint.append("00");
} else if (singleByte.length() == 1) {
fingerprint.append("0");
}
fingerprint.append(singleByte);
}
return fingerprint.toString();
}
}