/* Copyright 2006 VPAC
*
* This file is part of Grix.
* Grix 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 2 of the License, or
* any later version.
* Grix 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 Grix; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package org.vpac.grix.model.certificate;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchProviderException;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.RSAKeyGenParameterSpec;
import java.util.Arrays;
import org.globus.gsi.bc.BouncyCastleOpenSSLKey;
/**
* A special keypair class for this application. It holds a private key which is
* compatible to an openssl-generated one and a RSA private key.
*
* @author Markus Binsteiner
*
*/
public class GlobusKeyPair {
private PublicKey publicKey;
private BouncyCastleOpenSSLKey privateKey;
private boolean encryptedPrivate = false;
/**
* Constructor does nothing.
*/
public GlobusKeyPair() {
}
/**
* This factory function generates a pair of keys suitable for use with
* globus.
*
* @return The newly created keypair.
* @throws NoSuchProviderException
* @throws GeneralSecurityException
* @throws NoSuchPropertyException
* @throws SecurityProviderException
*/
public static GlobusKeyPair globusKeyPairFactory(int keysize)
throws GeneralSecurityException, NoSuchProviderException {
GlobusKeyPair globus_pair = new GlobusKeyPair();
SecureRandom random = new SecureRandom();
KeyPairGenerator generator = null;
generator = KeyPairGenerator.getInstance("RSA", "BC");
try {
generator.initialize(
// initialize the generator with the your chosen Keysize and the
// defaults recommended in X.509
new RSAKeyGenParameterSpec(keysize,
RSAKeyGenParameterSpec.F4), random);
} catch (IllegalArgumentException e) {
throw new GeneralSecurityException(e.getMessage());
}
KeyPair pair = generator.generateKeyPair();
globus_pair
.setPrivateKey(new BouncyCastleOpenSSLKey(pair.getPrivate()));
// TODO check whether casting is ok??
globus_pair.setPublicKey((RSAPublicKey) pair.getPublic());
globus_pair.encryptedPrivate = false;
return globus_pair;
}
/**
* @return the privateKey
*/
public BouncyCastleOpenSSLKey getPrivateKey() {
return privateKey;
}
/**
* @param privateKey
* the privateKey to set
*/
public void setPrivateKey(BouncyCastleOpenSSLKey privateKey) {
this.privateKey = privateKey;
}
/**
* @return the publicKey
*/
public PublicKey getPublicKey() {
return publicKey;
}
/**
* @param publicKey
* the publicKey to set
*/
public void setPublicKey(RSAPublicKey publicKey) {
this.publicKey = publicKey;
}
/**
* @return whether the containing private key is encrypted or not
*/
public boolean privateKeyisEncrypted() {
return encryptedPrivate;
}
/**
* Encrypts the private key with the given passphrase.
*
* @param passphrase
* the passphrase to encrypt the private key
* @throws GeneralSecurityException
*/
public void encryptPrivateKey(char[] passphrase)
throws GeneralSecurityException {
this.privateKey.encrypt(new String(passphrase));
// Arrays.fill(passphrase,'x');
this.encryptedPrivate = true;
}
/**
* Decrypts the private key.
*
* @param passphrase
* the passphrase to decrypt the private key
* @throws GeneralSecurityException
* @throws GeneralSecurityException
*/
public void decryptPrivateKey(char[] passphrase)
throws GeneralSecurityException {
this.privateKey.decrypt(passphrase.toString());
Arrays.fill(passphrase, 'x');
this.encryptedPrivate = false;
}
/**
* Saves the private Key into a file. Does not check whether the key is
* encrypted or not.
*
* @param privKeyFile
* @throws IOException
* @throws FileAlreadyExistsException
* @throws PathNotAvailableException
*/
public void savePrivateKeyToFile(File privKeyFile) throws IOException {
if (privKeyFile.exists())
throw new IOException("File: " + privKeyFile.toString()
+ " already exists.");
if (!privKeyFile.getParentFile().exists()) {
if (!privKeyFile.getParentFile().mkdirs())
throw new IOException("Can't create directory: "
+ privKeyFile.getParent());
}
if (!privKeyFile.canWrite())
throw new IOException("Can't write file: " + privKeyFile.toString());
this.privateKey.writeTo(new FileOutputStream(privKeyFile));
}
/**
* Not implemented (yet?). Do I need it at all?
*
* @param pubKeyFile
*/
public void savePublicKeyToFile(String pubKeyFile) {
throw new RuntimeException("Not implemented.");
// TODO save public key
}
}