diff options
Diffstat (limited to 'pg/src/main/jdk1.1/org/spongycastle/openpgp/operator/jcajce')
-rw-r--r-- | pg/src/main/jdk1.1/org/spongycastle/openpgp/operator/jcajce/JcaPGPContentSignerBuilder.java | 142 | ||||
-rw-r--r-- | pg/src/main/jdk1.1/org/spongycastle/openpgp/operator/jcajce/OperatorHelper.java | 220 |
2 files changed, 362 insertions, 0 deletions
diff --git a/pg/src/main/jdk1.1/org/spongycastle/openpgp/operator/jcajce/JcaPGPContentSignerBuilder.java b/pg/src/main/jdk1.1/org/spongycastle/openpgp/operator/jcajce/JcaPGPContentSignerBuilder.java new file mode 100644 index 00000000..a5dc297d --- /dev/null +++ b/pg/src/main/jdk1.1/org/spongycastle/openpgp/operator/jcajce/JcaPGPContentSignerBuilder.java @@ -0,0 +1,142 @@ +package org.spongycastle.openpgp.operator.jcajce; + +import java.io.OutputStream; +import java.security.InvalidKeyException; +import java.security.Provider; +import java.security.SecureRandom; +import java.security.Signature; +import java.security.SignatureException; + +import org.spongycastle.jcajce.util.DefaultJcaJceHelper; +import org.spongycastle.jcajce.util.NamedJcaJceHelper; +import org.spongycastle.jcajce.util.ProviderJcaJceHelper; +import org.spongycastle.openpgp.PGPException; +import org.spongycastle.openpgp.PGPPrivateKey; +import org.spongycastle.openpgp.operator.PGPContentSigner; +import org.spongycastle.openpgp.operator.PGPContentSignerBuilder; +import org.spongycastle.openpgp.operator.PGPDigestCalculator; +import org.spongycastle.util.io.TeeOutputStream; + +public class JcaPGPContentSignerBuilder + implements PGPContentSignerBuilder +{ + private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); + private JcaPGPDigestCalculatorProviderBuilder digestCalculatorProviderBuilder = new JcaPGPDigestCalculatorProviderBuilder(); + private JcaPGPKeyConverter keyConverter = new JcaPGPKeyConverter(); + private int hashAlgorithm; + private SecureRandom random; + private int keyAlgorithm; + + public JcaPGPContentSignerBuilder(int keyAlgorithm, int hashAlgorithm) + { + this.keyAlgorithm = keyAlgorithm; + this.hashAlgorithm = hashAlgorithm; + } + + public JcaPGPContentSignerBuilder setSecureRandom(SecureRandom random) + { + this.random = random; + + return this; + } + + public JcaPGPContentSignerBuilder setProvider(Provider provider) + { + this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider)); + keyConverter.setProvider(provider); + digestCalculatorProviderBuilder.setProvider(provider); + + return this; + } + + public JcaPGPContentSignerBuilder setProvider(String providerName) + { + this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName)); + keyConverter.setProvider(providerName); + digestCalculatorProviderBuilder.setProvider(providerName); + + return this; + } + + public JcaPGPContentSignerBuilder setDigestProvider(Provider provider) + { + digestCalculatorProviderBuilder.setProvider(provider); + + return this; + } + + public JcaPGPContentSignerBuilder setDigestProvider(String providerName) + { + digestCalculatorProviderBuilder.setProvider(providerName); + + return this; + } + + public PGPContentSigner build(final int signatureType, final PGPPrivateKey privateKey) + throws PGPException + { + final PGPDigestCalculator digestCalculator = digestCalculatorProviderBuilder.build().get(hashAlgorithm); + final Signature signature = helper.createSignature(keyAlgorithm, hashAlgorithm); + + try + { + if (random != null) + { + signature.initSign(keyConverter.getPrivateKey(privateKey)); + } + else + { + signature.initSign(keyConverter.getPrivateKey(privateKey)); + } + } + catch (InvalidKeyException e) + { + throw new PGPException("invalid key.", e); + } + + return new PGPContentSigner() + { + public int getType() + { + return signatureType; + } + + public int getHashAlgorithm() + { + return hashAlgorithm; + } + + public int getKeyAlgorithm() + { + return keyAlgorithm; + } + + public long getKeyID() + { + return privateKey.getKeyID(); + } + + public OutputStream getOutputStream() + { + return new TeeOutputStream(new SignatureOutputStream(signature), digestCalculator.getOutputStream()); + } + + public byte[] getSignature() + { + try + { + return signature.sign(); + } + catch (SignatureException e) + { // TODO: need a specific runtime exception for PGP operators. + throw new IllegalStateException("unable to create signature"); + } + } + + public byte[] getDigest() + { + return digestCalculator.getDigest(); + } + }; + } +} diff --git a/pg/src/main/jdk1.1/org/spongycastle/openpgp/operator/jcajce/OperatorHelper.java b/pg/src/main/jdk1.1/org/spongycastle/openpgp/operator/jcajce/OperatorHelper.java new file mode 100644 index 00000000..dc20e0c3 --- /dev/null +++ b/pg/src/main/jdk1.1/org/spongycastle/openpgp/operator/jcajce/OperatorHelper.java @@ -0,0 +1,220 @@ +package org.spongycastle.openpgp.operator.jcajce; + +import java.io.InputStream; +import java.security.GeneralSecurityException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.KeyFactory; +import java.security.MessageDigest; +import java.security.Signature; + +import javax.crypto.Cipher; +import javax.crypto.CipherInputStream; +import javax.crypto.SecretKey; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +import org.spongycastle.bcpg.PublicKeyAlgorithmTags; +import org.spongycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.spongycastle.jcajce.util.JcaJceHelper; +import org.spongycastle.openpgp.PGPException; +import org.spongycastle.openpgp.PGPPublicKey; +import org.spongycastle.openpgp.operator.PGPDataDecryptor; +import org.spongycastle.openpgp.operator.PGPDigestCalculator; + +class OperatorHelper +{ + private JcaJceHelper helper; + + OperatorHelper(JcaJceHelper helper) + { + this.helper = helper; + } + + MessageDigest createDigest(int algorithm) + throws GeneralSecurityException, PGPException + { + MessageDigest dig; + + try + { + dig = helper.createDigest(PGPUtil.getDigestName(algorithm)); + } + catch (NoSuchAlgorithmException e) + { + throw new PGPException("cannot find provider: " + e.getMessage(), e); + } + catch (NoSuchProviderException e) + { + throw new PGPException("cannot find provider: " + e.getMessage(), e); + } + + return dig; + } + + KeyFactory createKeyFactory(String algorithm) + throws GeneralSecurityException, PGPException + { + try + { + return helper.createKeyFactory(algorithm); + } + catch (NoSuchAlgorithmException e) + { + throw new PGPException("cannot find provider: " + e.getMessage(), e); + } + catch (NoSuchProviderException e) + { + throw new PGPException("cannot find provider: " + e.getMessage(), e); + } + } + + PGPDataDecryptor createDataDecryptor(boolean withIntegrityPacket, int encAlgorithm, byte[] key) + throws PGPException + { + try + { + SecretKey secretKey = new SecretKeySpec(key, PGPUtil.getSymmetricCipherName(encAlgorithm)); + + final Cipher c = createStreamCipher(encAlgorithm, withIntegrityPacket); + + byte[] iv = new byte[c.getBlockSize()]; + + c.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(iv)); + + return new PGPDataDecryptor() + { + public InputStream getInputStream(InputStream in) + { + return new CipherInputStream(in, c); + } + + public int getBlockSize() + { + return c.getBlockSize(); + } + + public PGPDigestCalculator getIntegrityCalculator() + { + return new SHA1PGPDigestCalculator(); + } + }; + } + catch (PGPException e) + { + throw e; + } + catch (Exception e) + { + throw new PGPException("Exception creating cipher", e); + } + } + + Cipher createStreamCipher(int encAlgorithm, boolean withIntegrityPacket) + throws PGPException + { + String mode = (withIntegrityPacket) + ? "CFB" + : "OpenPGPCFB"; + + String cName = PGPUtil.getSymmetricCipherName(encAlgorithm) + + "/" + mode + "/NoPadding"; + + return createCipher(cName); + } + + Cipher createCipher(String cipherName) + throws PGPException + { + try + { + return helper.createCipher(cipherName); + } + catch (Exception e) + { + throw new PGPException("cannot create cipher: " + e.getMessage(), e); + } + } + + Cipher createPublicKeyCipher(int encAlgorithm) + throws PGPException + { + switch (encAlgorithm) + { + case PGPPublicKey.RSA_ENCRYPT: + case PGPPublicKey.RSA_GENERAL: + return createCipher("RSA/ECB/PKCS1Padding"); + case PGPPublicKey.ELGAMAL_ENCRYPT: + case PGPPublicKey.ELGAMAL_GENERAL: + return createCipher("ElGamal/ECB/PKCS1Padding"); + case PGPPublicKey.DSA: + throw new PGPException("Can't use DSA for encryption."); + case PGPPublicKey.ECDSA: + throw new PGPException("Can't use ECDSA for encryption."); + default: + throw new PGPException("unknown asymmetric algorithm: " + encAlgorithm); + } + } + + Cipher createKeyWrapper(int encAlgorithm) + throws PGPException + { + try + { + switch (encAlgorithm) + { + case SymmetricKeyAlgorithmTags.AES_128: + case SymmetricKeyAlgorithmTags.AES_192: + case SymmetricKeyAlgorithmTags.AES_256: + return helper.createCipher("AESWrap"); + default: + throw new PGPException("unknown wrap algorithm: " + encAlgorithm); + } + } + catch (Exception e) + { + throw new PGPException("cannot create cipher: " + e.getMessage(), e); + } + } + + private Signature createSignature(String cipherName) + throws PGPException + { + try + { + return helper.createSignature(cipherName); + } + catch (Exception e) + { + throw new PGPException("cannot create signature: " + e.getMessage(), e); + } + } + + public Signature createSignature(int keyAlgorithm, int hashAlgorithm) + throws PGPException + { + String encAlg; + + switch (keyAlgorithm) + { + case PublicKeyAlgorithmTags.RSA_GENERAL: + case PublicKeyAlgorithmTags.RSA_SIGN: + encAlg = "RSA"; + break; + case PublicKeyAlgorithmTags.DSA: + encAlg = "DSA"; + break; + case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT: // in some malformed cases. + case PublicKeyAlgorithmTags.ELGAMAL_GENERAL: + encAlg = "ElGamal"; + break; + case PublicKeyAlgorithmTags.ECDSA: + encAlg = "ECDSA"; + break; + default: + throw new PGPException("unknown algorithm tag in signature:" + keyAlgorithm); + } + + return createSignature(PGPUtil.getDigestName(hashAlgorithm) + "with" + encAlg); + } +} |