1 package org.bouncycastle.openpgp.operator.bc; 2 3 import java.io.OutputStream; 4 import java.security.SecureRandom; 5 6 import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; 7 import org.bouncycastle.crypto.BlockCipher; 8 import org.bouncycastle.crypto.BufferedBlockCipher; 9 import org.bouncycastle.crypto.io.CipherOutputStream; 10 import org.bouncycastle.openpgp.PGPException; 11 import org.bouncycastle.openpgp.operator.PGPDataEncryptor; 12 import org.bouncycastle.openpgp.operator.PGPDataEncryptorBuilder; 13 import org.bouncycastle.openpgp.operator.PGPDigestCalculator; 14 15 /** 16 * {@link PGPDataEncryptorBuilder} implementation that uses the Bouncy Castle lightweight API to 17 * implement cryptographic primitives. 18 */ 19 public class BcPGPDataEncryptorBuilder 20 implements PGPDataEncryptorBuilder 21 { 22 private SecureRandom random; 23 private boolean withIntegrityPacket; 24 private int encAlgorithm; 25 26 /** 27 * Constructs a new data encryptor builder for a specified cipher type. 28 * 29 * @param encAlgorithm one of the {@link SymmetricKeyAlgorithmTags supported symmetric cipher 30 * algorithms}. May not be {@link SymmetricKeyAlgorithmTags#NULL}. 31 */ BcPGPDataEncryptorBuilder(int encAlgorithm)32 public BcPGPDataEncryptorBuilder(int encAlgorithm) 33 { 34 this.encAlgorithm = encAlgorithm; 35 36 if (encAlgorithm == 0) 37 { 38 throw new IllegalArgumentException("null cipher specified"); 39 } 40 } 41 42 /** 43 * Sets whether or not the resulting encrypted data will be protected using an integrity packet. 44 * 45 * @param withIntegrityPacket true if an integrity packet is to be included, false otherwise. 46 * @return the current builder. 47 */ setWithIntegrityPacket(boolean withIntegrityPacket)48 public BcPGPDataEncryptorBuilder setWithIntegrityPacket(boolean withIntegrityPacket) 49 { 50 this.withIntegrityPacket = withIntegrityPacket; 51 52 return this; 53 } 54 55 /** 56 * Provide a user defined source of randomness. 57 * <p> 58 * If no SecureRandom is configured, a default SecureRandom will be used. 59 * </p> 60 * @param random the secure random to be used. 61 * @return the current builder. 62 */ setSecureRandom(SecureRandom random)63 public BcPGPDataEncryptorBuilder setSecureRandom(SecureRandom random) 64 { 65 this.random = random; 66 67 return this; 68 } 69 getAlgorithm()70 public int getAlgorithm() 71 { 72 return encAlgorithm; 73 } 74 getSecureRandom()75 public SecureRandom getSecureRandom() 76 { 77 if (random == null) 78 { 79 random = new SecureRandom(); 80 } 81 82 return random; 83 } 84 build(byte[] keyBytes)85 public PGPDataEncryptor build(byte[] keyBytes) 86 throws PGPException 87 { 88 return new MyPGPDataEncryptor(keyBytes); 89 } 90 91 private class MyPGPDataEncryptor 92 implements PGPDataEncryptor 93 { 94 private final BufferedBlockCipher c; 95 MyPGPDataEncryptor(byte[] keyBytes)96 MyPGPDataEncryptor(byte[] keyBytes) 97 throws PGPException 98 { 99 BlockCipher engine = BcImplProvider.createBlockCipher(encAlgorithm); 100 101 try 102 { 103 c = BcUtil.createStreamCipher(true, engine, withIntegrityPacket, keyBytes); 104 } 105 catch (IllegalArgumentException e) 106 { 107 throw new PGPException("invalid parameters: " + e.getMessage(), e); 108 } 109 } 110 getOutputStream(OutputStream out)111 public OutputStream getOutputStream(OutputStream out) 112 { 113 return new CipherOutputStream(out, c); 114 } 115 getIntegrityCalculator()116 public PGPDigestCalculator getIntegrityCalculator() 117 { 118 if (withIntegrityPacket) 119 { 120 return new SHA1PGPDigestCalculator(); 121 } 122 123 return null; 124 } 125 getBlockSize()126 public int getBlockSize() 127 { 128 return c.getBlockSize(); 129 } 130 } 131 } 132