org.cryptacular.spec.BufferedBlockCipherSpec Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of com.liferay.saml.opensaml.integration Show documentation
Show all versions of com.liferay.saml.opensaml.integration Show documentation
Liferay SAML OpenSAML Integration
/* See LICENSE for licensing and NOTICE for copyright. */
package org.cryptacular.spec;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.BufferedBlockCipher;
import org.bouncycastle.crypto.modes.CBCBlockCipher;
import org.bouncycastle.crypto.modes.CFBBlockCipher;
import org.bouncycastle.crypto.modes.OFBBlockCipher;
import org.bouncycastle.crypto.paddings.BlockCipherPadding;
import org.bouncycastle.crypto.paddings.ISO10126d2Padding;
import org.bouncycastle.crypto.paddings.ISO7816d4Padding;
import org.bouncycastle.crypto.paddings.PKCS7Padding;
import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
import org.bouncycastle.crypto.paddings.TBCPadding;
import org.bouncycastle.crypto.paddings.X923Padding;
import org.bouncycastle.crypto.paddings.ZeroBytePadding;
/**
* Describes a block cipher in terms of a (algorithm, mode, padding) tuple and provides a facility to create a new
* instance of the cipher via the {@link #newInstance()} method.
*
* @author Middleware Services
* @version $Revision: 2744 $
*/
public class BufferedBlockCipherSpec implements Spec
{
/** String specification format, algorithm/mode/padding
. */
public static final Pattern FORMAT = Pattern.compile("(?[A-Za-z0-9_-]+)/(?\\w+)/(?\\w+)");
/** Cipher algorithm algorithm. */
private final String algorithm;
/** Cipher mode, e.g. CBC, OFB. */
private final String mode;
/** Cipher padding scheme, e.g. PKCS5Padding. */
private final String padding;
/**
* Creates a new instance from an algorithm name.
*
* @param algName Cipher algorithm name.
*/
public BufferedBlockCipherSpec(final String algName)
{
this(algName, null, null);
}
/**
* Creates a new instance from a cipher algorithm and mode.
*
* @param algName Cipher algorithm name.
* @param cipherMode Cipher mode.
*/
public BufferedBlockCipherSpec(final String algName, final String cipherMode)
{
this(algName, cipherMode, null);
}
/**
* Creates a new instance from the given cipher specifications.
*
* @param algName Cipher algorithm name.
* @param cipherMode Cipher mode.
* @param cipherPadding Cipher padding scheme algorithm.
*/
public BufferedBlockCipherSpec(final String algName, final String cipherMode, final String cipherPadding)
{
this.algorithm = algName;
this.mode = cipherMode;
this.padding = cipherPadding;
}
@Override
public String getAlgorithm()
{
return algorithm;
}
/**
* Gets the cipher mode.
*
* @return Cipher mode, e.g. CBC, OFB.
*/
public String getMode()
{
return mode;
}
/**
* Gets the cipher padding scheme.
*
* @return Padding scheme algorithm, e.g. PKCS5Padding. The following names are equivalent for no padding: NULL,
* Zero, None.
*/
public String getPadding()
{
return padding;
}
/**
* Gets the simple block cipher specification corresponding to this instance.
*
* @return Simple block cipher specification.
*/
public BlockCipherSpec getBlockCipherSpec()
{
return new BlockCipherSpec(this.algorithm);
}
/**
* Creates a new buffered block cipher from the specification in this instance.
*
* @return New buffered block cipher instance.
*/
@Override
public BufferedBlockCipher newInstance()
{
BlockCipher cipher = getBlockCipherSpec().newInstance();
switch (mode) {
case "CBC":
cipher = new CBCBlockCipher(cipher);
break;
case "OFB":
cipher = new OFBBlockCipher(cipher, cipher.getBlockSize());
break;
case "CFB":
cipher = new CFBBlockCipher(cipher, cipher.getBlockSize());
break;
default:
break;
}
if (padding != null) {
return new PaddedBufferedBlockCipher(cipher, getPadding(padding));
}
return new BufferedBlockCipher(cipher);
}
@Override
public String toString()
{
return algorithm + '/' + mode + '/' + padding;
}
/**
* Parses a string representation of a buffered block cipher specification into an instance of this class.
*
* @param specification Block cipher specification of the form algorithm/mode/padding
.
*
* @return Buffered block cipher specification instance.
*/
public static BufferedBlockCipherSpec parse(final String specification)
{
final Matcher m = FORMAT.matcher(specification);
if (!m.matches()) {
throw new IllegalArgumentException("Invalid specification " + specification);
}
return new BufferedBlockCipherSpec(m.group("alg"), m.group("mode"), m.group("padding"));
}
/**
* Gets a instance of block cipher padding from a padding name string.
*
* @param padding Name of padding algorithm.
*
* @return Block cipher padding instance.
*/
private static BlockCipherPadding getPadding(final String padding)
{
final String name;
final int pIndex = padding.indexOf("Padding");
if (pIndex > -1) {
name = padding.substring(0, pIndex);
} else {
name = padding;
}
final BlockCipherPadding blockCipherPadding;
if ("ISO7816d4".equalsIgnoreCase(name) | "ISO7816".equalsIgnoreCase(name)) {
blockCipherPadding = new ISO7816d4Padding();
} else if ("ISO10126".equalsIgnoreCase(name) || "ISO10126-2".equalsIgnoreCase(name)) {
blockCipherPadding = new ISO10126d2Padding();
} else if ("PKCS7".equalsIgnoreCase(name) || "PKCS5".equalsIgnoreCase(name)) {
blockCipherPadding = new PKCS7Padding();
} else if ("TBC".equalsIgnoreCase(name)) {
blockCipherPadding = new TBCPadding();
} else if ("X923".equalsIgnoreCase(name)) {
blockCipherPadding = new X923Padding();
} else if ("NULL".equalsIgnoreCase(name) || "Zero".equalsIgnoreCase(name) || "None".equalsIgnoreCase(name)) {
blockCipherPadding = new ZeroBytePadding();
} else {
throw new IllegalArgumentException("Invalid padding " + padding);
}
return blockCipherPadding;
}
}