diff --git a/pg/src/main/java/org/bouncycastle/bcpg/ArmoredOutputStream.java b/pg/src/main/java/org/bouncycastle/bcpg/ArmoredOutputStream.java index 9e51fa1233..5233d1a2d5 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/ArmoredOutputStream.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/ArmoredOutputStream.java @@ -6,7 +6,7 @@ import java.util.Hashtable; /** - * Basic output stream. + * Output stream that writes data in ASCII Armored format. */ public class ArmoredOutputStream extends OutputStream @@ -84,7 +84,7 @@ private void encode( boolean start = true; boolean clearText = false; boolean newLine = false; - + String nl = System.getProperty("line.separator"); String type; @@ -94,22 +94,34 @@ private void encode( String footerTail = "-----"; String version = "BCPG v@RELEASE_NAME@"; - + Hashtable headers = new Hashtable(); - + + /** + * Constructs an armored output stream with {@link #resetHeaders() default headers}. + * + * @param out the OutputStream to wrap. + */ public ArmoredOutputStream( OutputStream out) { this.out = out; - + if (nl == null) { nl = "\r\n"; } - + resetHeaders(); } - + + /** + * Constructs an armored output stream with default and custom headers. + * + * @param out the OutputStream to wrap. + * @param headers additional headers that add to or override the {@link #resetHeaders() default + * headers}. + */ public ArmoredOutputStream( OutputStream out, Hashtable headers) @@ -117,18 +129,18 @@ public ArmoredOutputStream( this(out); Enumeration e = headers.keys(); - + while (e.hasMoreElements()) { Object key = e.nextElement(); - + this.headers.put(key, headers.get(key)); } } - + /** * Set an additional header entry. - * + * * @param name the name of the header entry. * @param value the value of the header entry. */ @@ -138,7 +150,7 @@ public void setHeader( { this.headers.put(name, value); } - + /** * Reset the headers to only contain a Version string. */ @@ -147,17 +159,17 @@ public void resetHeaders() headers.clear(); headers.put("Version", version); } - + /** * Start a clear text signed message. * @param hashAlgorithm */ public void beginClearText( - int hashAlgorithm) + int hashAlgorithm) throws IOException { String hash; - + switch (hashAlgorithm) { case HashAlgorithmTags.SHA1: @@ -184,43 +196,43 @@ public void beginClearText( default: throw new IOException("unknown hash algorithm tag in beginClearText: " + hashAlgorithm); } - + String armorHdr = "-----BEGIN PGP SIGNED MESSAGE-----" + nl; String hdrs = "Hash: " + hash + nl + nl; - + for (int i = 0; i != armorHdr.length(); i++) { out.write(armorHdr.charAt(i)); } - + for (int i = 0; i != hdrs.length(); i++) { out.write(hdrs.charAt(i)); } - + clearText = true; newLine = true; lastb = 0; } - + public void endClearText() { clearText = false; } - + private void writeHeaderEntry( String name, - String value) + String value) throws IOException { for (int i = 0; i != name.length(); i++) { out.write(name.charAt(i)); } - + out.write(':'); out.write(' '); - + for (int i = 0; i != value.length(); i++) { out.write(value.charAt(i)); @@ -231,7 +243,7 @@ private void writeHeaderEntry( out.write(nl.charAt(i)); } } - + public void write( int b) throws IOException @@ -259,12 +271,12 @@ public void write( lastb = b; return; } - + if (start) { boolean newPacket = (b & 0x40) != 0; int tag = 0; - + if (newPacket) { tag = b & 0x3f; @@ -288,7 +300,7 @@ public void write( default: type = "MESSAGE"; } - + for (int i = 0; i != headerStart.length(); i++) { out.write(headerStart.charAt(i)); @@ -308,20 +320,20 @@ public void write( { out.write(nl.charAt(i)); } - + writeHeaderEntry("Version", (String)headers.get("Version")); Enumeration e = headers.keys(); while (e.hasMoreElements()) { String key = (String)e.nextElement(); - + if (!key.equals("Version")) { writeHeaderEntry(key, (String)headers.get(key)); } } - + for (int i = 0; i != nl.length(); i++) { out.write(nl.charAt(i)); @@ -346,12 +358,12 @@ public void write( crc.update(b); buf[bufPtr++] = b & 0xff; } - + public void flush() throws IOException { } - + /** * Note: close does nor close the underlying stream. So it is possible to write * multiple objects using armoring to a single stream. @@ -362,48 +374,48 @@ public void close() if (type != null) { encode(out, buf, bufPtr); - + for (int i = 0; i != nl.length(); i++) { out.write(nl.charAt(i)); } out.write('='); - + int crcV = crc.getValue(); - + buf[0] = ((crcV >> 16) & 0xff); buf[1] = ((crcV >> 8) & 0xff); buf[2] = (crcV & 0xff); - + encode(out, buf, 3); - + for (int i = 0; i != nl.length(); i++) { out.write(nl.charAt(i)); } - + for (int i = 0; i != footerStart.length(); i++) { out.write(footerStart.charAt(i)); } - + for (int i = 0; i != type.length(); i++) { out.write(type.charAt(i)); } - + for (int i = 0; i != footerTail.length(); i++) { out.write(footerTail.charAt(i)); } - + for (int i = 0; i != nl.length(); i++) { out.write(nl.charAt(i)); } - + out.flush(); - + type = null; start = true; } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/BCPGInputStream.java b/pg/src/main/java/org/bouncycastle/bcpg/BCPGInputStream.java index 1e2e072350..bc7cb802bd 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/BCPGInputStream.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/BCPGInputStream.java @@ -7,7 +7,7 @@ import org.bouncycastle.util.io.Streams; /** - * reader for PGP objects + * Stream reader for PGP objects */ public class BCPGInputStream extends InputStream implements PacketTags @@ -15,19 +15,19 @@ public class BCPGInputStream InputStream in; boolean next = false; int nextB; - + public BCPGInputStream( InputStream in) { this.in = in; } - + public int available() throws IOException { return in.available(); } - + public int read() throws IOException { @@ -98,11 +98,11 @@ public void readFully( } /** - * returns the next packet tag in the stream. - * - * @return the tag number. - * - * @throws IOException + * Obtains the tag of the next packet in the stream. + * + * @return the {@link PacketTags tag number}. + * + * @throws IOException if an error occurs reading the tag from the stream. */ public int nextPacketTag() throws IOException @@ -117,8 +117,8 @@ public int nextPacketTag() { nextB = -1; } - } - + } + next = true; if (nextB >= 0) @@ -132,20 +132,24 @@ public int nextPacketTag() return ((nextB & 0x3f) >> 2); } } - + return nextB; } + /** + * Reads the next packet from the stream. + * @throws IOException + */ public Packet readPacket() throws IOException { int hdr = this.read(); - + if (hdr < 0) { return null; } - + if ((hdr & 0x80) == 0) { throw new IOException("invalid header encountered"); @@ -155,11 +159,11 @@ public Packet readPacket() int tag = 0; int bodyLen = 0; boolean partial = false; - + if (newPacket) { tag = hdr & 0x3f; - + int l = this.read(); if (l < 192) @@ -185,7 +189,7 @@ else if (l == 255) else { int lengthType = hdr & 0x3; - + tag = (hdr & 0x3f) >> 2; switch (lengthType) @@ -208,7 +212,7 @@ else if (l == 255) } BCPGInputStream objStream; - + if (bodyLen == 0 && partial) { objStream = this; @@ -265,13 +269,13 @@ else if (l == 255) throw new IOException("unknown packet type encountered: " + tag); } } - + public void close() throws IOException { in.close(); } - + /** * a stream that overlays our input stream, allowing the user to only read a segment of it. * @@ -317,12 +321,12 @@ private int loadDataLength() throws IOException { int l = in.read(); - + if (l < 0) { return -1; } - + partial = false; if (l < 192) { @@ -341,10 +345,10 @@ else if (l == 255) partial = true; dataLength = 1 << (l & 0x1f); } - + return dataLength; } - + public int read(byte[] buf, int offset, int len) throws IOException { @@ -366,7 +370,7 @@ public int read(byte[] buf, int offset, int len) return -1; } - + public int read() throws IOException { diff --git a/pg/src/main/java/org/bouncycastle/bcpg/BCPGObject.java b/pg/src/main/java/org/bouncycastle/bcpg/BCPGObject.java index 7b05d8a87b..1018f189d1 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/BCPGObject.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/BCPGObject.java @@ -4,21 +4,21 @@ import java.io.IOException; /** - * base class for a PGP object. + * Base class for a PGP object. */ -public abstract class BCPGObject +public abstract class BCPGObject { - public byte[] getEncoded() + public byte[] getEncoded() throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); BCPGOutputStream pOut = new BCPGOutputStream(bOut); - + pOut.writeObject(this); - + return bOut.toByteArray(); } - + public abstract void encode(BCPGOutputStream out) throws IOException; } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/CompressedDataPacket.java b/pg/src/main/java/org/bouncycastle/bcpg/CompressedDataPacket.java index 0b4005918c..7239d91eec 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/CompressedDataPacket.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/CompressedDataPacket.java @@ -3,26 +3,26 @@ import java.io.IOException; /** - * generic compressed data object. + * A generic compressed data object. */ -public class CompressedDataPacket +public class CompressedDataPacket extends InputStreamPacket { int algorithm; - + CompressedDataPacket( BCPGInputStream in) throws IOException { super(in); - - algorithm = in.read(); + + algorithm = in.read(); } - + /** - * return the algorithm tag value. + * Gets the {@link CompressionAlgorithmTags compression algorithm} used for this packet. * - * @return algorithm tag value. + * @return the compression algorithm tag value. */ public int getAlgorithm() { diff --git a/pg/src/main/java/org/bouncycastle/bcpg/CompressionAlgorithmTags.java b/pg/src/main/java/org/bouncycastle/bcpg/CompressionAlgorithmTags.java index 5b684cf076..0e947d543f 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/CompressionAlgorithmTags.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/CompressionAlgorithmTags.java @@ -3,10 +3,17 @@ /** * Basic tags for compression algorithms */ -public interface CompressionAlgorithmTags +public interface CompressionAlgorithmTags { - public static final int UNCOMPRESSED = 0; // Uncompressed - public static final int ZIP = 1; // ZIP (RFC 1951) - public static final int ZLIB = 2; // ZLIB (RFC 1950) - public static final int BZIP2 = 3; // BZ2 + /** No compression. */ + public static final int UNCOMPRESSED = 0; + + /** ZIP (RFC 1951) compression. Unwrapped DEFLATE. */ + public static final int ZIP = 1; + + /** ZLIB (RFC 1950) compression. DEFLATE with a wrapper for better error detection. */ + public static final int ZLIB = 2; + + /** BZIP2 compression. Better compression than ZIP but much slower to compress and decompress. */ + public static final int BZIP2 = 3; } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/InputStreamPacket.java b/pg/src/main/java/org/bouncycastle/bcpg/InputStreamPacket.java index 411fa475d4..9073a2e8e9 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/InputStreamPacket.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/InputStreamPacket.java @@ -1,23 +1,25 @@ package org.bouncycastle.bcpg; /** - * + * A block of data associated with other packets in a PGP object stream. */ public class InputStreamPacket extends Packet { private BCPGInputStream in; - + public InputStreamPacket( BCPGInputStream in) { this.in = in; } - + /** + * Obtains an input stream to read the contents of the packet. + *
* Note: you can only read from this once... * - * @return the InputStream + * @return the data in this packet. */ public BCPGInputStream getInputStream() { diff --git a/pg/src/main/java/org/bouncycastle/bcpg/LiteralDataPacket.java b/pg/src/main/java/org/bouncycastle/bcpg/LiteralDataPacket.java index b660ce798b..b57c8bdecc 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/LiteralDataPacket.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/LiteralDataPacket.java @@ -2,27 +2,28 @@ import java.io.IOException; +import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Strings; /** - * generic literal data packet. + * Generic literal data packet. */ -public class LiteralDataPacket +public class LiteralDataPacket extends InputStreamPacket { int format; byte[] fileName; long modDate; - + LiteralDataPacket( BCPGInputStream in) throws IOException { super(in); - - format = in.read(); + + format = in.read(); int l = in.read(); - + fileName = new byte[l]; for (int i = 0; i != fileName.length; i++) { @@ -31,11 +32,9 @@ public class LiteralDataPacket modDate = ((long)in.read() << 24) | (in.read() << 16) | (in.read() << 8) | in.read(); } - + /** - * return the format tag value. - * - * @return format tag value. + * Return the format tag of the data packet. */ public int getFormat() { @@ -43,32 +42,26 @@ public int getFormat() } /** - * Return the modification time of the file in milli-seconds. - * - * @return the modification time in millis + * Return the modification time for the file (milliseconds at second level precision). */ public long getModificationTime() { return modDate * 1000L; } - + /** - * @return filename + * Return the file name associated with the data packet. */ public String getFileName() { return Strings.fromUTF8ByteArray(fileName); } + /** + * Return the file name as an uninterpreted byte array. + */ public byte[] getRawFileName() { - byte[] tmp = new byte[fileName.length]; - - for (int i = 0; i != tmp.length; i++) - { - tmp[i] = fileName[i]; - } - - return tmp; + return Arrays.clone(fileName); } } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/S2K.java b/pg/src/main/java/org/bouncycastle/bcpg/S2K.java index 167e7155a2..389814f7a5 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/S2K.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/S2K.java @@ -4,34 +4,44 @@ import java.io.IOException; import java.io.InputStream; + /** - * The string to key specifier class + * Parameter specifier for the PGP string-to-key password based key derivation function. + * + * In iterated mode, S2K takes a single byte iteration count specifier, which is converted to an + * actual iteration count using a formula that grows the iteration count exponentially as the byte + * value increases.0x01 == 1088 iterations, and 0xFF == 65,011,712 iterations.
*/
-public class S2K
+public class S2K
extends BCPGObject
{
private static final int EXPBIAS = 6;
-
+
+ /** Simple key generation. A single non-salted iteration of a hash function */
public static final int SIMPLE = 0;
+ /** Salted key generation. A single iteration of a hash function with a (unique) salt */
public static final int SALTED = 1;
+ /** Salted and iterated key generation. Multiple iterations of a hash function, with a salt */
public static final int SALTED_AND_ITERATED = 3;
+
public static final int GNU_DUMMY_S2K = 101;
-
+
int type;
int algorithm;
byte[] iv;
int itCount = -1;
int protectionMode = -1;
-
+
S2K(
InputStream in)
throws IOException
{
DataInputStream dIn = new DataInputStream(in);
-
+
type = dIn.read();
algorithm = dIn.read();
-
+
//
// if this happens we have a dummy-S2K packet.
//
@@ -56,14 +66,25 @@ public class S2K
protectionMode = dIn.read(); // protection mode
}
}
-
+
+ /**
+ * Constructs a specifier for a {@link #SIMPLE simple} S2K generation.
+ *
+ * @param algorithm the {@link HashAlgorithmTags digest algorithm} to use.
+ */
public S2K(
int algorithm)
{
this.type = 0;
this.algorithm = algorithm;
}
-
+
+ /**
+ * Constructs a specifier for a {@link #SALTED salted} S2K generation.
+ *
+ * @param algorithm the {@link HashAlgorithmTags digest algorithm} to use.
+ * @param iv the salt to apply to input to the key generation.
+ */
public S2K(
int algorithm,
byte[] iv)
@@ -73,6 +94,13 @@ public S2K(
this.iv = iv;
}
+ /**
+ * Constructs a specifier for a {@link #SALTED_AND_ITERATED salted and iterated} S2K generation.
+ *
+ * @param algorithm the {@link HashAlgorithmTags digest algorithm} to iterate.
+ * @param iv the salt to apply to input to the key generation.
+ * @param itCount the single byte iteration count specifier.
+ */
public S2K(
int algorithm,
byte[] iv,
@@ -83,58 +111,61 @@ public S2K(
this.iv = iv;
this.itCount = itCount;
}
-
+
+ /**
+ * Gets the {@link HashAlgorithmTags digest algorithm} specified.
+ */
public int getType()
{
return type;
}
-
+
/**
- * return the hash algorithm for this S2K
+ * Gets the {@link HashAlgorithmTags hash algorithm} for this S2K.
*/
public int getHashAlgorithm()
{
return algorithm;
}
-
+
/**
- * return the iv for the key generation algorithm
+ * Gets the iv/salt to use for the key generation.
*/
public byte[] getIV()
{
return iv;
}
-
+
/**
- * return the iteration count
+ * Gets the actual (expanded) iteration count.
*/
public long getIterationCount()
{
return (16 + (itCount & 15)) << ((itCount >> 4) + EXPBIAS);
}
-
+
/**
- * the protection mode - only if GNU_DUMMY_S2K
+ * Gets the protection mode - only if GNU_DUMMY_S2K
*/
public int getProtectionMode()
{
return protectionMode;
}
-
+
public void encode(
BCPGOutputStream out)
throws IOException
{
out.write(type);
out.write(algorithm);
-
+
if (type != GNU_DUMMY_S2K)
{
if (type != 0)
{
out.write(iv);
}
-
+
if (type == 3)
{
out.write(itCount);
diff --git a/pg/src/main/java/org/bouncycastle/bcpg/SymmetricEncIntegrityPacket.java b/pg/src/main/java/org/bouncycastle/bcpg/SymmetricEncIntegrityPacket.java
index edf6e2adbe..8e8fac6653 100644
--- a/pg/src/main/java/org/bouncycastle/bcpg/SymmetricEncIntegrityPacket.java
+++ b/pg/src/main/java/org/bouncycastle/bcpg/SymmetricEncIntegrityPacket.java
@@ -3,18 +3,19 @@
import java.io.IOException;
/**
+ * A symmetric key encrypted packet with an associated integrity check code.
*/
-public class SymmetricEncIntegrityPacket
+public class SymmetricEncIntegrityPacket
extends InputStreamPacket
-{
+{
int version;
-
+
SymmetricEncIntegrityPacket(
BCPGInputStream in)
throws IOException
{
super(in);
-
+
version = in.read();
}
}
diff --git a/pg/src/main/java/org/bouncycastle/openpgp/PGPCompressedData.java b/pg/src/main/java/org/bouncycastle/openpgp/PGPCompressedData.java
index 4f13a98fb6..a609b5b356 100644
--- a/pg/src/main/java/org/bouncycastle/openpgp/PGPCompressedData.java
+++ b/pg/src/main/java/org/bouncycastle/openpgp/PGPCompressedData.java
@@ -6,52 +6,62 @@
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;
+import org.bouncycastle.apache.bzip2.CBZip2InputStream;
import org.bouncycastle.bcpg.BCPGInputStream;
import org.bouncycastle.bcpg.CompressedDataPacket;
import org.bouncycastle.bcpg.CompressionAlgorithmTags;
-import org.bouncycastle.apache.bzip2.CBZip2InputStream;
+import org.bouncycastle.bcpg.PacketTags;
/**
- * Compressed data objects.
+ * A PGP compressed data object.
*/
-public class PGPCompressedData
+public class PGPCompressedData
implements CompressionAlgorithmTags
{
CompressedDataPacket data;
-
+
+ /**
+ * Construct a compressed data object, reading a single {@link PacketTags#COMPRESSED_DATA}
+ * packet from the stream.
+ *
+ * @param pIn a PGP input stream, with a compressed data packet as the current packet.
+ * @throws IOException if an error occurs reading the packet from the stream.
+ */
public PGPCompressedData(
BCPGInputStream pIn)
throws IOException
{
data = (CompressedDataPacket)pIn.readPacket();
}
-
+
/**
- * Return the algorithm used for compression
- *
- * @return algorithm code
+ * Return the {@link CompressionAlgorithmTags compression algorithm} used for this packet.
+ *
+ * @return the compression algorithm code
*/
public int getAlgorithm()
{
return data.getAlgorithm();
}
-
+
/**
* Return the raw input stream contained in the object.
- *
- * @return InputStream
+ *
+ * Note that this stream is shared with the decompression stream, so consuming the returned
+ * stream will affect decompression.
+ *
+ * @return the raw data in the compressed data packet.
*/
public InputStream getInputStream()
{
return data.getInputStream();
}
-
+
/**
- * Return an uncompressed input stream which allows reading of the
- * compressed data.
- *
- * @return InputStream
- * @throws PGPException
+ * Return an input stream that decompresses and returns data in the compressed packet.
+ *
+ * @return a stream over the uncompressed data.
+ * @throws PGPException if an error occurs constructing the decompression stream.
*/
public InputStream getDataStream()
throws PGPException
@@ -62,9 +72,9 @@ public InputStream getDataStream()
}
if (this.getAlgorithm() == ZIP)
{
- return new InflaterInputStream(this.getInputStream(), new Inflater(true))
+ return new InflaterInputStream(this.getInputStream(), new Inflater(true))
{
- // If the "nowrap" inflater option is used the stream can
+ // If the "nowrap" inflater option is used the stream can
// apparently overread - we override fill() and provide
// an extra byte for the end of the input stream to get
// around this.
@@ -77,16 +87,16 @@ protected void fill() throws IOException
{
throw new EOFException("Unexpected end of ZIP input stream");
}
-
+
len = this.in.read(buf, 0, buf.length);
-
+
if (len == -1)
{
buf[0] = 0;
len = 1;
eof = true;
}
-
+
inf.setInput(buf, 0, len);
}
@@ -97,7 +107,7 @@ protected void fill() throws IOException
{
return new InflaterInputStream(this.getInputStream())
{
- // If the "nowrap" inflater option is used the stream can
+ // If the "nowrap" inflater option is used the stream can
// apparently overread - we override fill() and provide
// an extra byte for the end of the input stream to get
// around this.
@@ -110,9 +120,9 @@ protected void fill() throws IOException
{
throw new EOFException("Unexpected end of ZIP input stream");
}
-
+
len = this.in.read(buf, 0, buf.length);
-
+
if (len == -1)
{
buf[0] = 0;
@@ -137,7 +147,7 @@ protected void fill() throws IOException
throw new PGPException("I/O problem with stream: " + e, e);
}
}
-
+
throw new PGPException("can't recognise compression algorithm: " + this.getAlgorithm());
}
}
diff --git a/pg/src/main/java/org/bouncycastle/openpgp/PGPCompressedDataGenerator.java b/pg/src/main/java/org/bouncycastle/openpgp/PGPCompressedDataGenerator.java
index 4a3ebaf66b..e680a02ad3 100644
--- a/pg/src/main/java/org/bouncycastle/openpgp/PGPCompressedDataGenerator.java
+++ b/pg/src/main/java/org/bouncycastle/openpgp/PGPCompressedDataGenerator.java
@@ -1,19 +1,40 @@
package org.bouncycastle.openpgp;
-import org.bouncycastle.apache.bzip2.CBZip2OutputStream;
-import org.bouncycastle.bcpg.BCPGOutputStream;
-import org.bouncycastle.bcpg.CompressionAlgorithmTags;
-import org.bouncycastle.bcpg.PacketTags;
-
import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;
+import org.bouncycastle.apache.bzip2.CBZip2OutputStream;
+import org.bouncycastle.bcpg.BCPGOutputStream;
+import org.bouncycastle.bcpg.CompressionAlgorithmTags;
+import org.bouncycastle.bcpg.PacketTags;
+
/**
- *class for producing compressed data packets.
+ * Generator for producing compressed data packets.
+ *
+ * A PGPCompressedDataGenerator is used by invoking one of the open functions to create an
+ * OutputStream that raw data can be supplied to for compression:
+ *
+ * - If the length of the data to be written is known in advance, use
+ * {@link #open(OutputStream, long)} to create a packet containing a single compressed object.
+ * - If the length of the data is unknown, use {@link #open(OutputStream, byte[])} to create a
+ * packet consisting of a series of compressed data objects (partials).
+ *
+ *
+ * A PGPCompressedDataGenerator is usually used to wrap the OutputStream
+ * {@link PGPEncryptedDataGenerator#open(OutputStream, byte[]) obtained} from a
+ * {@link PGPEncryptedDataGenerator} (i.e. to compress data prior to encrypting it).
+ *
+ * Raw data is not typically written directly to the OutputStream obtained from a
+ * PGPCompressedDataGenerator. The OutputStream is usually wrapped by a
+ * {@link PGPLiteralDataGenerator}, which encodes the raw data prior to compression.
+ *
+ * Once data for compression has been written to the constructed OutputStream, writing of the object
+ * stream is completed by closing the OutputStream obtained from the open() method, or
+ * equivalently invoking {@link #close()} on this generator.
*/
-public class PGPCompressedDataGenerator
+public class PGPCompressedDataGenerator
implements CompressionAlgorithmTags, StreamGenerator
{
private int algorithm;
@@ -21,13 +42,26 @@ public class PGPCompressedDataGenerator
private OutputStream dOut;
private BCPGOutputStream pkOut;
-
+
+ /**
+ * Construct a new compressed data generator.
+ *
+ * @param algorithm the identifier of the {@link CompressionAlgorithmTags compression algorithm}
+ * to use.
+ */
public PGPCompressedDataGenerator(
int algorithm)
{
this(algorithm, Deflater.DEFAULT_COMPRESSION);
}
-
+
+ /**
+ * Construct a new compressed data generator.
+ *
+ * @param algorithm the identifier of the {@link CompressionAlgorithmTags compression algorithm}
+ * to use.
+ * @param compression the {@link Deflater} compression level to use.
+ */
public PGPCompressedDataGenerator(
int algorithm,
int compression)
@@ -56,17 +90,17 @@ public PGPCompressedDataGenerator(
}
/**
- * Return an OutputStream which will save the data being written to
+ * Return an OutputStream which will save the data being written to
* the compressed object.
*
* The stream created can be closed off by either calling close()
* on the stream or close() on the generator. Closing the returned
* stream does not close off the OutputStream parameter out.
- *
+ *
* @param out underlying OutputStream to be used.
* @return OutputStream
* @throws IOException, IllegalStateException
- */
+ */
public OutputStream open(
OutputStream out)
throws IOException
@@ -82,29 +116,30 @@ public OutputStream open(
return new WrappedGeneratorStream(dOut, this);
}
-
+
/**
- * Return an OutputStream which will compress the data as it is written
- * to it. The stream will be written out in chunks according to the size of the
- * passed in buffer.
+ * Return an OutputStream which will compress the data as it is written to it. The stream will
+ * be written out in chunks (partials) according to the size of the passed in buffer.
*
- * The stream created can be closed off by either calling close()
- * on the stream or close() on the generator. Closing the returned
- * stream does not close off the OutputStream parameter out.
+ * The stream created can be closed off by either calling close() on the stream or close() on
+ * the generator. Closing the returned stream does not close off the OutputStream parameter out.
*
- * Note: if the buffer is not a power of 2 in length only the largest power of 2
- * bytes worth of the buffer will be used.
+ * Note: if the buffer is not a power of 2 in length only the largest power of 2 bytes
+ * worth of the buffer will be used.
*
*
- * Note: using this may break compatibility with RFC 1991 compliant tools. Only recent OpenPGP
- * implementations are capable of accepting these streams.
+ * Note: using this may break compatibility with RFC 1991 compliant tools. Only recent
+ * OpenPGP implementations are capable of accepting these streams.
*
- *
- * @param out underlying OutputStream to be used.
- * @param buffer the buffer to use.
- * @return OutputStream
- * @throws IOException
+ *
+ * @param out the stream to write compressed packets to.
+ * @param buffer a buffer to use to buffer and write partial packets. The returned stream takes
+ * ownership of the buffer and will use it to buffer plaintext data for compression.
+ * @return the output stream to write data to.
+ * @throws IOException if an error occurs writing stream header information to the provider
+ * output stream.
* @throws PGPException
+ * @throws IllegalStateException if this generator already has an open OutputStream.
*/
public OutputStream open(
OutputStream out,
@@ -150,7 +185,7 @@ private void doOpen() throws IOException
/**
* Close the compressed object - this is equivalent to calling close on the stream
* returned by the open() method.
- *
+ *
* @throws IOException
*/
public void close()
diff --git a/pg/src/main/java/org/bouncycastle/openpgp/PGPEncryptedData.java b/pg/src/main/java/org/bouncycastle/openpgp/PGPEncryptedData.java
index cf01ece23a..8b570bc56c 100644
--- a/pg/src/main/java/org/bouncycastle/openpgp/PGPEncryptedData.java
+++ b/pg/src/main/java/org/bouncycastle/openpgp/PGPEncryptedData.java
@@ -8,9 +8,17 @@
import org.bouncycastle.bcpg.InputStreamPacket;
import org.bouncycastle.bcpg.SymmetricEncIntegrityPacket;
import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags;
+import org.bouncycastle.openpgp.operator.PGPDataDecryptor;
+import org.bouncycastle.openpgp.operator.PGPDataDecryptorFactory;
import org.bouncycastle.openpgp.operator.PGPDigestCalculator;
import org.bouncycastle.util.Arrays;
+/**
+ * A PGP encrypted data object.
+ *
+ * Encrypted data packets are decrypted using a {@link PGPDataDecryptor} obtained from a
+ * {@link PGPDataDecryptorFactory}.
+ */
public abstract class PGPEncryptedData
implements SymmetricKeyAlgorithmTags
{
@@ -19,9 +27,9 @@ protected class TruncatedStream extends InputStream
int[] lookAhead = new int[22];
int bufPtr;
InputStream in;
-
+
TruncatedStream(
- InputStream in)
+ InputStream in)
throws IOException
{
for (int i = 0; i != lookAhead.length; i++)
@@ -31,34 +39,34 @@ protected class TruncatedStream extends InputStream
throw new EOFException();
}
}
-
+
bufPtr = 0;
this.in = in;
}
- public int read()
+ public int read()
throws IOException
{
int ch = in.read();
-
+
if (ch >= 0)
{
int c = lookAhead[bufPtr];
-
+
lookAhead[bufPtr] = ch;
bufPtr = (bufPtr + 1) % lookAhead.length;
-
+
return c;
}
-
+
return -1;
}
-
+
int[] getLookAhead()
{
int[] tmp = new int[lookAhead.length];
int count = 0;
-
+
for (int i = bufPtr; i != lookAhead.length; i++)
{
tmp[count++] = lookAhead[i];
@@ -67,11 +75,11 @@ int[] getLookAhead()
{
tmp[count++] = lookAhead[i];
}
-
+
return tmp;
}
}
-
+
InputStreamPacket encData;
InputStream encStream;
TruncatedStream truncStream;
@@ -82,31 +90,41 @@ int[] getLookAhead()
{
this.encData = encData;
}
-
+
/**
* Return the raw input stream for the data stream.
- *
- * @return InputStream
+ *
+ * Note this stream is shared with all other encryption methods in the same
+ * {@link PGPEncryptedDataList} and with any decryption methods in sub-classes, so consuming
+ * this stream will affect decryption.
+ *
+ * @return the encrypted data in this packet.
*/
public InputStream getInputStream()
{
return encData.getInputStream();
}
-
+
/**
- * Return true if the message is integrity protected.
- * @return true if there is a modification detection code package associated with this stream
+ * Checks whether the packet is integrity protected.
+ *
+ * @return true if there is a modification detection code package associated with
+ * this stream
*/
public boolean isIntegrityProtected()
{
return (encData instanceof SymmetricEncIntegrityPacket);
}
-
+
/**
+ * Verifies the integrity of the packet against the modification detection code associated with
+ * it in the stream.
+ *
* Note: This can only be called after the message has been read.
- *
- * @return true if the message verifies, false otherwise.
- * @throws PGPException if the message is not integrity protected.
+ *
+ * @return true if the message verifies, false otherwise.
+ * @throws PGPException if the message is not {@link #isIntegrityProtected() integrity
+ * protected}.
*/
public boolean verify()
throws PGPException, IOException
diff --git a/pg/src/main/java/org/bouncycastle/openpgp/PGPEncryptedDataGenerator.java b/pg/src/main/java/org/bouncycastle/openpgp/PGPEncryptedDataGenerator.java
index 6ae92d13a1..855e9842bf 100644
--- a/pg/src/main/java/org/bouncycastle/openpgp/PGPEncryptedDataGenerator.java
+++ b/pg/src/main/java/org/bouncycastle/openpgp/PGPEncryptedDataGenerator.java
@@ -18,11 +18,30 @@
import org.bouncycastle.util.io.TeeOutputStream;
/**
- * Generator for encrypted objects.
+ * Generator for encrypted objects.
+ *
+ * A PGPEncryptedDataGenerator is used by configuring one or more {@link #methods encryption
+ * methods}, and then invoking one of the open functions to create an OutputStream that raw data can
+ * be supplied to for encryption:
+ *
+ * - If the length of the data to be written is known in advance, use
+ * {@link #open(OutputStream, long)} to create a packet containing a single encrypted object.
+ * - If the length of the data is unknown, use {@link #open(OutputStream, byte[])} to create an
+ * packet consisting of a series of encrypted objects (partials).
+ *
+ *
+ * Raw data is not typically written directly to the OutputStream obtained from a
+ * PGPEncryptedDataGenerator. The OutputStream is usually wrapped by a
+ * {@link PGPLiteralDataGenerator}, and often with a {@link PGPCompressedDataGenerator} between.
+ *
+ * Once plaintext data for encryption has been written to the constructed OutputStream, writing of
+ * the encrypted object stream is completed by closing the OutputStream obtained from the
+ * open() method, or equivalently invoking {@link #close()} on this generator.
*/
public class PGPEncryptedDataGenerator
implements SymmetricKeyAlgorithmTags, StreamGenerator
{
+ // TODO: These seem to belong on the PBE classes. Are they even used now?
/**
* Specifier for SHA-1 S2K PBE generator.
*/
@@ -85,11 +104,11 @@ public PGPEncryptedDataGenerator(PGPDataEncryptorBuilder encryptorBuilder, boole
}
/**
- * Added a key encryption method to be used to encrypt the session data associated
- * with this encrypted data.
- *
- * @param method key encryption method to use.
- */
+ * Add a key encryption method to be used to encrypt the session data associated with this
+ * encrypted data.
+ *
+ * @param method key encryption method to use.
+ */
public void addMethod(PGPKeyEncryptionMethodGenerator method)
{
methods.add(method);
@@ -99,12 +118,12 @@ private void addCheckSum(
byte[] sessionInfo)
{
int check = 0;
-
+
for (int i = 1; i != sessionInfo.length - 2; i++)
{
check += sessionInfo[i] & 0xff;
}
-
+
sessionInfo[sessionInfo.length - 2] = (byte)(check >> 8);
sessionInfo[sessionInfo.length - 1] = (byte)(check);
}
@@ -121,20 +140,26 @@ private byte[] createSessionInfo(
}
/**
- * If buffer is non null stream assumed to be partial, otherwise the
- * length will be used to output a fixed length packet.
+ * Create an OutputStream based on the configured methods.
+ *
+ * If the supplied buffer is non null the stream returned will write a sequence of
+ * partial packets, otherwise the length will be used to output a fixed length packet.
*
- * The stream created can be closed off by either calling close()
- * on the stream or close() on the generator. Closing the returned
- * stream does not close off the OutputStream parameter out.
- *
- * @param out
- * @param length
- * @param buffer
+ * The stream created can be closed off by either calling close() on the stream or close() on
+ * the generator. Closing the returned stream does not close off the OutputStream parameter out.
+ *
+ * @param out the stream to write encrypted packets to.
+ * @param length the length of the data to be encrypted. Ignored if buffer is non
+ * null.
+ * @param buffer a buffer to use to buffer and write partial packets.
* @return the generator's output stream.
- * @throws java.io.IOException
- * @throws PGPException
- * @throws IllegalStateException
+ * @throws IOException if an error occurs writing stream header information to the provider
+ * output stream.
+ * @throws PGPException if an error occurs initialising PGP encryption for the configured
+ * encryption methods.
+ * @throws IllegalStateException if this generator already has an open OutputStream, or no
+ * {@link #addMethod(PGPKeyEncryptionMethodGenerator) encryption methods} are
+ * configured.
*/
private OutputStream open(
OutputStream out,
@@ -160,7 +185,7 @@ private OutputStream open(
rand = dataEncryptorBuilder.getSecureRandom();
if (methods.size() == 1)
- {
+ {
if (methods.get(0) instanceof PBEKeyEncryptionMethodGenerator)
{
@@ -197,7 +222,7 @@ private OutputStream open(
PGPDataEncryptor dataEncryptor = dataEncryptorBuilder.build(key);
digestCalc = dataEncryptor.getIntegrityCalculator();
-
+
if (buffer == null)
{
//
@@ -250,18 +275,23 @@ private OutputStream open(
}
/**
- * Return an outputstream which will encrypt the data as it is written
- * to it.
+ * Create an OutputStream based on the configured methods to write a single encrypted object of
+ * known length.
+ *
*
- * The stream created can be closed off by either calling close()
- * on the stream or close() on the generator. Closing the returned
- * stream does not close off the OutputStream parameter out.
- *
- * @param out
- * @param length
- * @return OutputStream
- * @throws IOException
- * @throws PGPException
+ * The stream created can be closed off by either calling close() on the stream or close() on
+ * the generator. Closing the returned stream does not close off the OutputStream parameter out.
+ *
+ * @param out the stream to write encrypted packets to.
+ * @param length the length of the data to be encrypted.
+ * @return the output stream to write data to for encryption.
+ * @throws IOException if an error occurs writing stream header information to the provider
+ * output stream.
+ * @throws PGPException if an error occurs initialising PGP encryption for the configured
+ * encryption methods.
+ * @throws IllegalStateException if this generator already has an open OutputStream, or no
+ * {@link #addMethod(PGPKeyEncryptionMethodGenerator) encryption methods} are
+ * configured.
*/
public OutputStream open(
OutputStream out,
@@ -270,24 +300,29 @@ public OutputStream open(
{
return this.open(out, length, null);
}
-
+
/**
- * Return an outputstream which will encrypt the data as it is written
- * to it. The stream will be written out in chunks according to the size of the
+ * Create an OutputStream which will encrypt the data as it is written to it. The stream of
+ * encrypted data will be written out in chunks (partial packets) according to the size of the
* passed in buffer.
*
- * The stream created can be closed off by either calling close()
- * on the stream or close() on the generator. Closing the returned
- * stream does not close off the OutputStream parameter out.
+ * The stream created can be closed off by either calling close() on the stream or close() on
+ * the generator. Closing the returned stream does not close off the OutputStream parameter out.
*
- * Note: if the buffer is not a power of 2 in length only the largest power of 2
- * bytes worth of the buffer will be used.
+ * Note: if the buffer is not a power of 2 in length only the largest power of 2 bytes
+ * worth of the buffer will be used.
*
- * @param out
- * @param buffer the buffer to use.
- * @return OutputStream
- * @throws IOException
- * @throws PGPException
+ * @param out the stream to write encrypted packets to.
+ * @param buffer a buffer to use to buffer and write partial packets. The returned stream takes
+ * ownership of the buffer and will use it to buffer plaintext data for encryption.
+ * @return the output stream to write data to for encryption.
+ * @throws IOException if an error occurs writing stream header information to the provider
+ * output stream.
+ * @throws PGPException if an error occurs initialising PGP encryption for the configured
+ * encryption methods.
+ * @throws IllegalStateException if this generator already has an open OutputStream, or no
+ * {@link #addMethod(PGPKeyEncryptionMethodGenerator) encryption methods} are
+ * configured.
*/
public OutputStream open(
OutputStream out,
@@ -296,19 +331,22 @@ public OutputStream open(
{
return this.open(out, 0, buffer);
}
-
+
/**
- * Close off the encrypted object - this is equivalent to calling close on the stream
- * returned by the open() method.
+ * Close off the encrypted object - this is equivalent to calling close on the stream returned
+ * by the open() methods.
*
- * Note: This does not close the underlying output stream, only the stream on top of it created by the open() method.
- * @throws java.io.IOException
+ * Note: This does not close the underlying output stream, only the stream on top of it
+ * created by the open() method.
+ *
+ * @throws IOException if an error occurs writing trailing information (such as integrity check
+ * information) to the underlying stream.
*/
public void close()
throws IOException
{
if (cOut != null)
- {
+ {
if (digestCalc != null)
{
//
diff --git a/pg/src/main/java/org/bouncycastle/openpgp/PGPEncryptedDataList.java b/pg/src/main/java/org/bouncycastle/openpgp/PGPEncryptedDataList.java
index 7fd9c2549a..65c58a67e8 100644
--- a/pg/src/main/java/org/bouncycastle/openpgp/PGPEncryptedDataList.java
+++ b/pg/src/main/java/org/bouncycastle/openpgp/PGPEncryptedDataList.java
@@ -12,13 +12,33 @@
import org.bouncycastle.bcpg.SymmetricKeyEncSessionPacket;
/**
- * A holder for a list of PGP encryption method packets.
+ * A holder for a list of PGP encryption method packets and the encrypted data associated with them.
+ *
+ * This holder supports reading a sequence of the following encryption methods, followed by an
+ * encrypted data packet:
+ *
+ * - {@link PacketTags#SYMMETRIC_KEY_ENC_SESSION} - produces a {@link PGPPBEEncryptedData}
+ * - {@link PacketTags#PUBLIC_KEY_ENC_SESSION} - produces a {@link PGPPublicKeyEncryptedData}
+ *
+ *
+ * All of the objects returned from this holder share a reference to the same encrypted data input
+ * stream, which can only be consumed once.
*/
public class PGPEncryptedDataList
{
List list = new ArrayList();
InputStreamPacket data;
-
+
+ /**
+ * Construct an encrypted data packet holder, reading PGP encrypted method packets and an
+ * encrytped data packet from the stream.
+ *
+ * The next packet in the stream should be one of {@link PacketTags#SYMMETRIC_KEY_ENC_SESSION}
+ * or {@link PacketTags#PUBLIC_KEY_ENC_SESSION}.
+ *
+ * @param pIn the PGP object stream being read.
+ * @throws IOException if an error occurs reading from the PGP input.
+ */
public PGPEncryptedDataList(
BCPGInputStream pIn)
throws IOException
@@ -30,36 +50,47 @@ public PGPEncryptedDataList(
}
data = (InputStreamPacket)pIn.readPacket();
-
+
for (int i = 0; i != list.size(); i++)
{
if (list.get(i) instanceof SymmetricKeyEncSessionPacket)
{
list.set(i, new PGPPBEEncryptedData((SymmetricKeyEncSessionPacket)list.get(i), data));
}
- else
+ else
{
list.set(i, new PGPPublicKeyEncryptedData((PublicKeyEncSessionPacket)list.get(i), data));
}
}
}
-
+
+ /**
+ * Gets the encryption method object at the specified index.
+ *
+ * @param index the encryption method to obtain (0 based).
+ */
public Object get(
int index)
{
return list.get(index);
}
-
+
+ /**
+ * Gets the number of encryption methods in this list.
+ */
public int size()
{
return list.size();
}
-
+
+ /**
+ * Returns true iff there are 0 encryption methods in this list.
+ */
public boolean isEmpty()
{
return list.isEmpty();
}
-
+
/**
* @deprecated misspelt - use getEncryptedDataObjects()
*/
@@ -67,7 +98,11 @@ public Iterator getEncyptedDataObjects()
{
return list.iterator();
}
-
+
+ /**
+ * Returns an iterator over the encryption method objects held in this list, in the order they
+ * appeared in the stream they are read from.
+ */
public Iterator getEncryptedDataObjects()
{
return list.iterator();
diff --git a/pg/src/main/java/org/bouncycastle/openpgp/PGPLiteralData.java b/pg/src/main/java/org/bouncycastle/openpgp/PGPLiteralData.java
index b163b86a64..c90fb1f1b2 100644
--- a/pg/src/main/java/org/bouncycastle/openpgp/PGPLiteralData.java
+++ b/pg/src/main/java/org/bouncycastle/openpgp/PGPLiteralData.java
@@ -8,48 +8,47 @@
import org.bouncycastle.bcpg.LiteralDataPacket;
/**
- * class for processing literal data objects.
+ * A single literal data packet in a PGP object stream.
*/
-public class PGPLiteralData
+public class PGPLiteralData
{
+ /** Format tag for binary literal data */
public static final char BINARY = 'b';
+ /** Format tag for textual literal data */
public static final char TEXT = 't';
+ /** Format tag for UTF-8 encoded textual literal data */
public static final char UTF8 = 'u';
/**
* The special name indicating a "for your eyes only" packet.
*/
public static final String CONSOLE = "_CONSOLE";
-
+
/**
* The special time for a modification time of "now" or
* the present time.
*/
public static final Date NOW = new Date(0L);
-
+
LiteralDataPacket data;
-
+
public PGPLiteralData(
BCPGInputStream pIn)
throws IOException
{
data = (LiteralDataPacket)pIn.readPacket();
}
-
+
/**
- * Return the format of the data stream - BINARY or TEXT.
- *
- * @return int
+ * Return the format of the data packet. One of {@link #BINARY}, {@link #TEXT} or {@link #UTF8}
*/
public int getFormat()
{
return data.getFormat();
}
-
+
/**
- * Return the file name that's associated with the data stream.
- *
- * @return String
+ * Return the file name associated with the data packet.
*/
public String getFileName()
{
@@ -57,7 +56,7 @@ public String getFileName()
}
/**
- * Return the file name as an unintrepreted byte array.
+ * Return the file name as an uninterpreted (UTF-8 encoded) byte array.
*/
public byte[] getRawFileName()
{
@@ -65,29 +64,24 @@ public byte[] getRawFileName()
}
/**
- * Return the modification time for the file.
- *
- * @return the modification time.
+ * Return the modification time for the file (at second level precision).
*/
public Date getModificationTime()
{
return new Date(data.getModificationTime());
}
-
+
/**
- * Return the raw input stream for the data stream.
- *
- * @return InputStream
+ * Return the raw input stream for the data packet.
*/
public InputStream getInputStream()
{
return data.getInputStream();
}
-
+
/**
- * Return the input stream representing the data stream
- *
- * @return InputStream
+ * Return the input stream representing the data stream.
+ * Equivalent to {@link #getInputStream()}.
*/
public InputStream getDataStream()
{
diff --git a/pg/src/main/java/org/bouncycastle/openpgp/PGPLiteralDataGenerator.java b/pg/src/main/java/org/bouncycastle/openpgp/PGPLiteralDataGenerator.java
index d60b535520..1b8da659d1 100644
--- a/pg/src/main/java/org/bouncycastle/openpgp/PGPLiteralDataGenerator.java
+++ b/pg/src/main/java/org/bouncycastle/openpgp/PGPLiteralDataGenerator.java
@@ -10,49 +10,77 @@
import org.bouncycastle.util.Strings;
/**
- * Class for producing literal data packets.
+ * Generator for producing literal data packets.
+ *
+ * A PGPLiteralData is used by invoking one of the open functions to create an OutputStream that raw
+ * data can be supplied to for encoding:
+ *
+ * - If the length of the data to be written is known in advance, use
+ * {@link #open(OutputStream, char, String, long, Date)} to create a packet containing a single
+ * literal data object.
+ * - If the length of the data is unknown, use
+ * {@link #open(OutputStream, char, String, Date, byte[])} to create a packet consisting of a series
+ * of literal data objects (partials).
+ *
+ *
+ * A PGPLiteralDataGenerator is usually used to wrap the OutputStream
+ * {@link PGPEncryptedDataGenerator#open(OutputStream, byte[]) obtained} from a
+ * {@link PGPEncryptedDataGenerator} or a {@link PGPCompressedDataGenerator}.
+ *
+ * Once literal data has been written to the constructed OutputStream, writing of the object stream
+ * is completed by closing the OutputStream obtained from the open() method, or
+ * equivalently invoking {@link #close()} on this generator.
*/
public class PGPLiteralDataGenerator implements StreamGenerator
-{
- public static final char BINARY = PGPLiteralData.BINARY;
+{
+ /** Format tag for binary literal data */
+ public static final char BINARY = PGPLiteralData.BINARY;
+ /** Format tag for textual literal data */
public static final char TEXT = PGPLiteralData.TEXT;
+ /** Format tag for UTF-8 encoded textual literal data */
public static final char UTF8 = PGPLiteralData.UTF8;
-
+
/**
* The special name indicating a "for your eyes only" packet.
*/
+ // TODO: Not used?
public static final String CONSOLE = PGPLiteralData.CONSOLE;
-
+
/**
* The special time for a modification time of "now" or
* the present time.
*/
public static final Date NOW = PGPLiteralData.NOW;
-
+
private BCPGOutputStream pkOut;
private boolean oldFormat = false;
-
+
+ /**
+ * Constructs a generator for literal data objects.
+ */
public PGPLiteralDataGenerator()
- {
+ {
}
-
+
/**
- * Generates literal data objects in the old format, this is
- * important if you need compatability with PGP 2.6.x.
- *
- * @param oldFormat
+ * Constructs a generator for literal data objects, specifying to use new or old (PGP 2.6.x
+ * compatible) format.
+ *
+ * This can be used for compatibility with PGP 2.6.x.
+ *
+ * @param oldFormat true to use PGP 2.6.x compatible format.
*/
public PGPLiteralDataGenerator(
boolean oldFormat)
{
this.oldFormat = oldFormat;
}
-
+
private void writeHeader(
OutputStream out,
char format,
byte[] encName,
- long modificationTime)
+ long modificationTime)
throws IOException
{
out.write(format);
@@ -71,19 +99,18 @@ private void writeHeader(
out.write((byte)(modDate >> 8));
out.write((byte)(modDate));
}
-
+
/**
- * Open a literal data packet, returning a stream to store the data inside
- * the packet.
+ * Open a literal data packet, returning a stream to store the data inside the packet.
*
- * The stream created can be closed off by either calling close()
- * on the stream or close() on the generator. Closing the returned
- * stream does not close off the OutputStream parameter out.
- *
- * @param out the stream we want the packet in
- * @param format the format we are using
- * @param name the name of the "file"
- * @param length the length of the data we will write
+ * The stream created can be closed off by either calling close() on the stream or close() on
+ * the generator. Closing the returned stream does not close off the OutputStream parameter out.
+ *
+ * @param out the underlying output stream to write the literal data packet to.
+ * @param format the format of the literal data that will be written to the output stream (one
+ * of {@link #BINARY}, {@link #TEXT} or {@link #UTF8}).
+ * @param name the name of the "file" to encode in the literal data object.
+ * @param length the length of the data that will be written.
* @param modificationTime the time of last modification we want stored.
*/
public OutputStream open(
@@ -102,30 +129,37 @@ public OutputStream open(
byte[] encName = Strings.toUTF8ByteArray(name);
pkOut = new BCPGOutputStream(out, PacketTags.LITERAL_DATA, length + 2 + encName.length + 4, oldFormat);
-
+
writeHeader(pkOut, format, encName, modificationTime.getTime());
return new WrappedGeneratorStream(pkOut, this);
}
-
+
/**
- * Open a literal data packet, returning a stream to store the data inside
- * the packet as an indefinite length stream. The stream is written out as a
- * series of partial packets with a chunk size determined by the size of the
- * passed in buffer.
+ * Open a literal data packet, returning a stream to store the data inside the packet as an
+ * indefinite length stream. The stream is written out as a series of partial packets with a
+ * chunk size determined by the size of the passed in buffer.
*
- * The stream created can be closed off by either calling close()
- * on the stream or close() on the generator. Closing the returned
- * stream does not close off the OutputStream parameter out.
+ * The stream created can be closed off by either calling close() on the stream or close() on
+ * the generator. Closing the returned stream does not close off the OutputStream parameter out.
+ *
*
- * Note: if the buffer is not a power of 2 in length only the largest power of 2
- * bytes worth of the buffer will be used.
- *
- * @param out the stream we want the packet in
- * @param format the format we are using
- * @param name the name of the "file"
- * @param modificationTime the time of last modification we want stored.
- * @param buffer the buffer to use for collecting data to put into chunks.
+ * Note: if the buffer is not a power of 2 in length only the largest power of 2 bytes
+ * worth of the buffer will be used.
+ *
+ * @param out the underlying output stream to write the literal data packet to.
+ * @param format the format of the literal data that will be written to the output stream (one
+ * of {@link #BINARY}, {@link #TEXT} or {@link #UTF8}).
+ * @param name the name of the "file" to encode in the literal data object.
+ * @param modificationTime the time of last modification we want stored (will be stored to
+ * second level precision).
+ * @param buffer a buffer to use to buffer and write partial packets. The returned stream takes
+ * ownership of the buffer.
+ *
+ * @return the output stream to write data to.
+ * @throws IOException if an error occurs writing stream header information to the provider
+ * output stream.
+ * @throws IllegalStateException if this generator already has an open OutputStream.
*/
public OutputStream open(
OutputStream out,
@@ -148,20 +182,26 @@ public OutputStream open(
return new WrappedGeneratorStream(pkOut, this);
}
-
+
/**
- * Open a literal data packet for the passed in File object, returning
- * an output stream for saving the file contents.
- *
- * The stream created can be closed off by either calling close()
- * on the stream or close() on the generator. Closing the returned
- * stream does not close off the OutputStream parameter out.
- *
- * @param out
- * @param format
- * @param file
- * @return OutputStream
- * @throws IOException
+ * Open a literal data packet for the passed in File object, returning an output stream for
+ * saving the file contents.
+ *
+ * This method configures the generator to store the file contents in a single literal data
+ * packet, taking the filename and modification time from the file, but does not store the
+ * actual file data.
+ *
+ * The stream created can be closed off by either calling close() on the stream or close() on
+ * the generator. Closing the returned stream does not close off the OutputStream parameter out.
+ *
+ * @param out the underlying output stream to write the literal data packet to.
+ * @param format the format of the literal data that will be written to the output stream (one
+ * of {@link #BINARY}, {@link #TEXT} or {@link #UTF8}).
+ * @param file the file to determine the length and filename from.
+ * @return the output stream to write data to.
+ * @throws IOException if an error occurs writing stream header information to the provider
+ * output stream.
+ * @throws IllegalStateException if this generator already has an open OutputStream.
*/
public OutputStream open(
OutputStream out,
@@ -169,24 +209,13 @@ public OutputStream open(
File file)
throws IOException
{
- if (pkOut != null)
- {
- throw new IllegalStateException("generator already in open state");
- }
-
- byte[] encName = Strings.toUTF8ByteArray(file.getName());
-
- pkOut = new BCPGOutputStream(out, PacketTags.LITERAL_DATA, file.length() + 2 + encName.length + 4, oldFormat);
-
- writeHeader(pkOut, format, encName, file.lastModified());
-
- return new WrappedGeneratorStream(pkOut, this);
+ return open(out, format, file.getName(), file.length(), new Date(file.lastModified()));
}
-
+
/**
* Close the literal data packet - this is equivalent to calling close on the stream
* returned by the open() method.
- *
+ *
* @throws IOException
*/
public void close()
diff --git a/pg/src/main/java/org/bouncycastle/openpgp/PGPObjectFactory.java b/pg/src/main/java/org/bouncycastle/openpgp/PGPObjectFactory.java
index bc06d92df9..5d2b90df48 100644
--- a/pg/src/main/java/org/bouncycastle/openpgp/PGPObjectFactory.java
+++ b/pg/src/main/java/org/bouncycastle/openpgp/PGPObjectFactory.java
@@ -8,16 +8,32 @@
import org.bouncycastle.bcpg.BCPGInputStream;
import org.bouncycastle.bcpg.PacketTags;
+import org.bouncycastle.openpgp.bc.BcPGPObjectFactory;
+import org.bouncycastle.openpgp.jcajce.JcaPGPObjectFactory;
import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator;
import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator;
/**
* General class for reading a PGP object stream.
- *
- * Note: if this class finds a PGPPublicKey or a PGPSecretKey it
- * will create a PGPPublicKeyRing, or a PGPSecretKeyRing for each
- * key found. If all you are trying to do is read a key ring file use
- * either PGPPublicKeyRingCollection or PGPSecretKeyRingCollection.
+ *
+ * Note: if this class finds a {@link PGPPublicKey} or a {@link PGPSecretKey} it will create a
+ * {@link PGPPublicKeyRing}, or a {@link PGPSecretKeyRing} for each key found. If all you are trying
+ * to do is read a key ring file use either {@link PGPPublicKeyRingCollection} or
+ * {@link PGPSecretKeyRingCollection}.
+ *
+ * This factory supports reading the following types of objects:
+ *
+ * - {@link PacketTags#SIGNATURE} - produces a {@link PGPSignatureList}
+ * - {@link PacketTags#SECRET_KEY} - produces a {@link PGPSecretKeyRing}
+ * - {@link PacketTags#PUBLIC_KEY} - produces a {@link PGPPublicKeyRing}
+ * - {@link PacketTags#PUBLIC_SUBKEY} - produces a {@link PGPPublicKey}
+ * - {@link PacketTags#COMPRESSED_DATA} - produces a {@link PGPCompressedData}
+ * - {@link PacketTags#LITERAL_DATA} - produces a {@link PGPLiteralData}
+ * - {@link PacketTags#PUBLIC_KEY_ENC_SESSION} - produces a {@link PGPEncryptedDataList}
+ * - {@link PacketTags#SYMMETRIC_KEY_ENC_SESSION} - produces a {@link PGPEncryptedDataList}
+ * - {@link PacketTags#ONE_PASS_SIGNATURE} - produces a {@link PGPOnePassSignatureList}
+ * - {@link PacketTags#MARKER} - produces a {@link PGPMarker}
+ *
*/
public class PGPObjectFactory
{
@@ -25,7 +41,7 @@ public class PGPObjectFactory
private KeyFingerPrintCalculator fingerPrintCalculator;
/**
- * @deprecated use JcaPGPObjectFactory or BcPGPObjectFactory
+ * @deprecated use {@link JcaPGPObjectFactory} or {@link BcPGPObjectFactory}
*/
public PGPObjectFactory(
InputStream in)
@@ -34,10 +50,11 @@ public PGPObjectFactory(
}
/**
- * Create an object factor suitable for reading keys, key rings and key ring collections.
+ * Create an object factory suitable for reading PGP objects such as keys, key rings and key
+ * ring collections, or PGP encrypted data.
*
- * @param in stream to read from
- * @param fingerPrintCalculator calculator to use in key finger print calculations.
+ * @param in stream to read PGP data from.
+ * @param fingerPrintCalculator calculator to use in key finger print calculations.
*/
public PGPObjectFactory(
InputStream in,
@@ -57,10 +74,11 @@ public PGPObjectFactory(
}
/**
- * Create an object factor suitable for reading keys, key rings and key ring collections.
+ * Create an object factory suitable for reading PGP objects such as keys, key rings and key
+ * ring collections, or PGP encrypted data.
*
- * @param bytes stream to read from
- * @param fingerPrintCalculator calculator to use in key finger print calculations.
+ * @param bytes PGP encoded data.
+ * @param fingerPrintCalculator calculator to use in key finger print calculations.
*/
public PGPObjectFactory(
byte[] bytes,
@@ -70,10 +88,10 @@ public PGPObjectFactory(
}
/**
- * Return the next object in the stream, or null if the end is reached.
- *
- * @return Object
- * @throws IOException on a parse error
+ * Return the next object in the stream, or null if the end of stream is reached.
+ *
+ * @return one of the supported objects - see class docs for details.
+ * @throws IOException if an error occurs reading from the wrapped stream or parsing data.
*/
public Object nextObject()
throws IOException
@@ -86,7 +104,7 @@ public Object nextObject()
return null;
case PacketTags.SIGNATURE:
l = new ArrayList();
-
+
while (in.nextPacketTag() == PacketTags.SIGNATURE)
{
try
@@ -98,7 +116,7 @@ public Object nextObject()
throw new IOException("can't create signature object: " + e);
}
}
-
+
return new PGPSignatureList((PGPSignature[])l.toArray(new PGPSignature[l.size()]));
case PacketTags.SECRET_KEY:
try
@@ -129,7 +147,7 @@ public Object nextObject()
return new PGPEncryptedDataList(in);
case PacketTags.ONE_PASS_SIGNATURE:
l = new ArrayList();
-
+
while (in.nextPacketTag() == PacketTags.ONE_PASS_SIGNATURE)
{
try
@@ -141,7 +159,7 @@ public Object nextObject()
throw new IOException("can't create one pass signature object: " + e);
}
}
-
+
return new PGPOnePassSignatureList((PGPOnePassSignature[])l.toArray(new PGPOnePassSignature[l.size()]));
case PacketTags.MARKER:
return new PGPMarker(in);
@@ -151,7 +169,7 @@ public Object nextObject()
case PacketTags.EXPERIMENTAL_4:
return in.readPacket();
}
-
+
throw new IOException("unknown object in stream: " + in.nextPacketTag());
}
}
diff --git a/pg/src/main/java/org/bouncycastle/openpgp/PGPPBEEncryptedData.java b/pg/src/main/java/org/bouncycastle/openpgp/PGPPBEEncryptedData.java
index a24cdc470b..c14ad5487f 100644
--- a/pg/src/main/java/org/bouncycastle/openpgp/PGPPBEEncryptedData.java
+++ b/pg/src/main/java/org/bouncycastle/openpgp/PGPPBEEncryptedData.java
@@ -6,6 +6,7 @@
import org.bouncycastle.bcpg.BCPGInputStream;
import org.bouncycastle.bcpg.InputStreamPacket;
import org.bouncycastle.bcpg.SymmetricEncIntegrityPacket;
+import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags;
import org.bouncycastle.bcpg.SymmetricKeyEncSessionPacket;
import org.bouncycastle.openpgp.operator.PBEDataDecryptorFactory;
import org.bouncycastle.openpgp.operator.PGPDataDecryptor;
@@ -13,36 +14,37 @@
/**
* A password based encryption object.
+ *
+ * PBE encrypted data objects can be {@link #getDataStream(PBEDataDecryptorFactory) decrypted }
+ * using a {@link PBEDataDecryptorFactory}.
*/
public class PGPPBEEncryptedData
extends PGPEncryptedData
{
SymmetricKeyEncSessionPacket keyData;
-
+
+ /**
+ * Construct a PBE encryped data object.
+ *
+ * @param keyData the PBE key data packet associated with the encrypted data in the PGP object
+ * stream.
+ * @param encData the encrypted data.
+ */
PGPPBEEncryptedData(
SymmetricKeyEncSessionPacket keyData,
InputStreamPacket encData)
{
super(encData);
-
+
this.keyData = keyData;
}
-
- /**
- * Return the raw input stream for the data stream.
- *
- * @return InputStream
- */
- public InputStream getInputStream()
- {
- return encData.getInputStream();
- }
- /**
+ /**
* Return the symmetric key algorithm required to decrypt the data protected by this object.
*
- * @param dataDecryptorFactory decryptor factory to use to recover the session data.
- * @return the integer encryption algorithm code.
+ * @param dataDecryptorFactory decryptor factory to use to recover the session data.
+ * @return the identifier of the {@link SymmetricKeyAlgorithmTags encryption algorithm} used to
+ * encrypt this object.
* @throws PGPException if the session data cannot be recovered.
*/
public int getSymmetricAlgorithm(
@@ -55,12 +57,14 @@ public int getSymmetricAlgorithm(
return sessionData[0];
}
- /**
+ /**
* Open an input stream which will provide the decrypted data protected by this object.
- *
- * @param dataDecryptorFactory decryptor factory to use to recover the session data and provide the stream.
- * @return the resulting input stream
- * @throws PGPException if the session data cannot be recovered or the stream cannot be created.
+ *
+ * @param dataDecryptorFactory decryptor factory to use to recover the session data and provide
+ * the stream.
+ * @return the resulting decrypted input stream, probably containing a sequence of PGP data
+ * objects.
+ * @throws PGPException if the session data cannot be recovered or the stream cannot be created.
*/
public InputStream getDataStream(
PBEDataDecryptorFactory dataDecryptorFactory)
diff --git a/pg/src/main/java/org/bouncycastle/openpgp/PGPPublicKeyEncryptedData.java b/pg/src/main/java/org/bouncycastle/openpgp/PGPPublicKeyEncryptedData.java
index 1dde086b44..18e5f6448a 100644
--- a/pg/src/main/java/org/bouncycastle/openpgp/PGPPublicKeyEncryptedData.java
+++ b/pg/src/main/java/org/bouncycastle/openpgp/PGPPublicKeyEncryptedData.java
@@ -17,15 +17,15 @@
*/
public class PGPPublicKeyEncryptedData
extends PGPEncryptedData
-{
+{
PublicKeyEncSessionPacket keyData;
-
+
PGPPublicKeyEncryptedData(
PublicKeyEncSessionPacket keyData,
InputStreamPacket encData)
{
super(encData);
-
+
this.keyData = keyData;
}
@@ -33,19 +33,19 @@ private boolean confirmCheckSum(
byte[] sessionInfo)
{
int check = 0;
-
+
for (int i = 1; i != sessionInfo.length - 2; i++)
{
check += sessionInfo[i] & 0xff;
}
-
+
return (sessionInfo[sessionInfo.length - 2] == (byte)(check >> 8))
&& (sessionInfo[sessionInfo.length - 1] == (byte)(check));
}
-
+
/**
* Return the keyID for the key used to encrypt the data.
- *
+ *
* @return long
*/
public long getKeyID()
@@ -55,9 +55,10 @@ public long getKeyID()
/**
* Return the symmetric key algorithm required to decrypt the data protected by this object.
- *
- * @param dataDecryptorFactory decryptor factory to use to recover the session data.
- * @return the integer encryption algorithm code.
+ *
+ * @param dataDecryptorFactory decryptor factory to use to recover the session data.
+ * @return the identifier of the {@link SymmetricKeyAlgorithmTags encryption algorithm} used to
+ * encrypt this object.
* @throws PGPException if the session data cannot be recovered.
*/
public int getSymmetricAlgorithm(
diff --git a/pg/src/main/java/org/bouncycastle/openpgp/PGPSecretKeyRing.java b/pg/src/main/java/org/bouncycastle/openpgp/PGPSecretKeyRing.java
index 538c47191a..ce356cebe1 100644
--- a/pg/src/main/java/org/bouncycastle/openpgp/PGPSecretKeyRing.java
+++ b/pg/src/main/java/org/bouncycastle/openpgp/PGPSecretKeyRing.java
@@ -24,7 +24,7 @@
* Class to hold a single master secret key and its subkeys.
*
* Often PGP keyring files consist of multiple master keys, if you are trying to process
- * or construct one of these you should use the PGPSecretKeyRingCollection class.
+ * or construct one of these you should use the {@link PGPSecretKeyRingCollection} class.
*/
public class PGPSecretKeyRing
extends PGPKeyRing
diff --git a/pg/src/main/java/org/bouncycastle/openpgp/PGPUtil.java b/pg/src/main/java/org/bouncycastle/openpgp/PGPUtil.java
index 4ea779d755..42e922bfaf 100644
--- a/pg/src/main/java/org/bouncycastle/openpgp/PGPUtil.java
+++ b/pg/src/main/java/org/bouncycastle/openpgp/PGPUtil.java
@@ -6,7 +6,9 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.security.MessageDigest;
import java.security.SecureRandom;
+import java.security.Signature;
import java.util.Date;
import org.bouncycastle.asn1.ASN1InputStream;
@@ -20,7 +22,7 @@
import org.bouncycastle.util.encoders.Base64;
/**
- * Basic utility class
+ * PGP utilities.
*/
public class PGPUtil
implements HashAlgorithmTags
@@ -28,30 +30,30 @@ public class PGPUtil
private static String defProvider = "BC";
/**
- * Return the provider that will be used by factory classes in situations
- * where a provider must be determined on the fly.
- *
- * @return String
+ * Return the JCA/JCE provider that will be used by factory classes in situations where a
+ * provider must be determined on the fly.
+ *
+ * @return the name of the default provider.
*/
public static String getDefaultProvider()
{
+ // TODO: This is unused?
return defProvider;
}
-
+
/**
- * Set the provider to be used by the package when it is necessary to
- * find one on the fly.
- *
- * @param provider
+ * Set the provider to be used by the package when it is necessary to find one on the fly.
+ *
+ * @param provider the name of the JCA/JCE provider to use by default.
*/
public static void setDefaultProvider(
String provider)
{
defProvider = provider;
}
-
+
static MPInteger[] dsaSigToMpi(
- byte[] encoding)
+ byte[] encoding)
throws PGPException
{
ASN1InputStream aIn = new ASN1InputStream(encoding);
@@ -72,13 +74,21 @@ static MPInteger[] dsaSigToMpi(
}
MPInteger[] values = new MPInteger[2];
-
+
values[0] = new MPInteger(i1.getValue());
values[1] = new MPInteger(i2.getValue());
-
+
return values;
}
-
+
+ /**
+ * Translates a PGP {@link HashAlgorithmTags hash algorithm tag} to a JCA {@link MessageDigest}
+ * algorithm name
+ *
+ * @param hashAlgorithm the hash algorithm identifier.
+ * @return the corresponding JCA algorithm name.
+ * @throws PGPException if the hash algorithm is unknown.
+ */
static String getDigestName(
int hashAlgorithm)
throws PGPException
@@ -105,14 +115,23 @@ static String getDigestName(
throw new PGPException("unknown hash algorithm tag in getDigestName: " + hashAlgorithm);
}
}
-
+
+ /**
+ * Translates a PGP {@link PublicKeyAlgorithmTags public key algorithm tag} and a
+ * {@link HashAlgorithmTags hash algorithm tag} to a JCA {@link Signature} algorithm name.
+ *
+ * @param keyAlgorithm they public key algorithm identifier.
+ * @param hashAlgorithm the hash algorithm identifier.
+ * @return the corresponding JCA algorithm name.
+ * @throws PGPException if the public key or hash algorithm is unknown.
+ */
static String getSignatureName(
int keyAlgorithm,
int hashAlgorithm)
throws PGPException
{
String encAlg;
-
+
switch (keyAlgorithm)
{
case PublicKeyAlgorithmTags.RSA_GENERAL:
@@ -133,13 +152,22 @@ static String getSignatureName(
return getDigestName(hashAlgorithm) + "with" + encAlg;
}
+ /**
+ * Generates a random key for a {@link SymmetricKeyAlgorithmTags symmetric encryption algorithm}
+ * .
+ *
+ * @param algorithm the symmetric key algorithm identifier.
+ * @param random a source of random data.
+ * @return a key of the length required by the specified encryption algorithm.
+ * @throws PGPException if the encryption algorithm is unknown.
+ */
public static byte[] makeRandomKey(
int algorithm,
- SecureRandom random)
+ SecureRandom random)
throws PGPException
{
int keySize = 0;
-
+
switch (algorithm)
{
case SymmetricKeyAlgorithmTags.TRIPLE_DES:
@@ -184,22 +212,22 @@ public static byte[] makeRandomKey(
default:
throw new PGPException("unknown symmetric algorithm: " + algorithm);
}
-
+
byte[] keyBytes = new byte[(keySize + 7) / 8];
-
+
random.nextBytes(keyBytes);
-
+
return keyBytes;
}
/**
- * write out the passed in file as a literal data packet.
- *
- * @param out
- * @param fileType the LiteralData type for the file.
- * @param file
- *
- * @throws IOException
+ * Write out the contents of the provided file as a literal data packet.
+ *
+ * @param out the stream to write the literal data to.
+ * @param fileType the {@link PGPLiteralData} type to use for the file data.
+ * @param file the file to write the contents of.
+ *
+ * @throws IOException if an error occurs reading the file or writing to the output stream.
*/
public static void writeFileToLiteralData(
OutputStream out,
@@ -208,19 +236,21 @@ public static void writeFileToLiteralData(
throws IOException
{
PGPLiteralDataGenerator lData = new PGPLiteralDataGenerator();
- OutputStream pOut = lData.open(out, fileType, file.getName(), file.length(), new Date(file.lastModified()));
+ OutputStream pOut = lData.open(out, fileType, file);
pipeFileContents(file, pOut, 4096);
}
-
+
/**
- * write out the passed in file as a literal data packet in partial packet format.
- *
- * @param out
- * @param fileType the LiteralData type for the file.
- * @param file
+ * Write out the contents of the provided file as a literal data packet in partial packet
+ * format.
+ *
+ * @param out the stream to write the literal data to.
+ * @param fileType the {@link PGPLiteralData} type to use for the file data.
+ * @param file the file to write the contents of.
* @param buffer buffer to be used to chunk the file into partial packets.
- *
- * @throws IOException
+ * @see {@link PGPLiteralDataGenerator#open(OutputStream, char, String, Date, byte[])}.
+ *
+ * @throws IOException if an error occurs reading the file or writing to the output stream.
*/
public static void writeFileToLiteralData(
OutputStream out,
@@ -250,41 +280,45 @@ private static void pipeFileContents(File file, OutputStream pOut, int bufSize)
}
private static final int READ_AHEAD = 60;
-
+
private static boolean isPossiblyBase64(
int ch)
{
- return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')
+ return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')
|| (ch >= '0' && ch <= '9') || (ch == '+') || (ch == '/')
|| (ch == '\r') || (ch == '\n');
}
-
+
/**
- * Return either an ArmoredInputStream or a BCPGInputStream based on
- * whether the initial characters of the stream are binary PGP encodings or not.
- *
- * @param in the stream to be wrapped
- * @return a BCPGInputStream
- * @throws IOException
+ * Obtains a stream that can be used to read PGP data from the provided stream.
+ *
+ * If the initial bytes of the underlying stream are binary PGP encodings, then the stream will
+ * be returned directly, otherwise an {@link ArmoredInputStream} is used to wrap the provided
+ * stream and remove ASCII-Armored encoding.
+ *
+ * @param in the stream to be checked and possibly wrapped.
+ * @return a stream that will return PGP binary encoded data.
+ * @throws IOException if an error occurs reading the stream, or initalising the
+ * {@link ArmoredInputStream}.
*/
public static InputStream getDecoderStream(
- InputStream in)
+ InputStream in)
throws IOException
{
if (!in.markSupported())
{
in = new BufferedInputStreamExt(in);
}
-
+
in.mark(READ_AHEAD);
-
+
int ch = in.read();
-
+
if ((ch & 0x80) != 0)
{
in.reset();
-
+
return in;
}
else
@@ -292,34 +326,34 @@ public static InputStream getDecoderStream(
if (!isPossiblyBase64(ch))
{
in.reset();
-
+
return new ArmoredInputStream(in);
}
-
+
byte[] buf = new byte[READ_AHEAD];
int count = 1;
int index = 1;
-
+
buf[0] = (byte)ch;
while (count != READ_AHEAD && (ch = in.read()) >= 0)
{
if (!isPossiblyBase64(ch))
{
in.reset();
-
+
return new ArmoredInputStream(in);
}
-
+
if (ch != '\n' && ch != '\r')
{
buf[index++] = (byte)ch;
}
-
+
count++;
}
-
+
in.reset();
-
+
//
// nothing but new lines, little else, assume regular armoring
//
@@ -327,16 +361,16 @@ public static InputStream getDecoderStream(
{
return new ArmoredInputStream(in);
}
-
+
//
// test our non-blank data
//
byte[] firstBlock = new byte[8];
-
+
System.arraycopy(buf, 0, firstBlock, 0, firstBlock.length);
byte[] decoded = Base64.decode(firstBlock);
-
+
//
// it's a base64 PGP block.
//
@@ -344,11 +378,11 @@ public static InputStream getDecoderStream(
{
return new ArmoredInputStream(in, false);
}
-
+
return new ArmoredInputStream(in);
}
}
-
+
static class BufferedInputStreamExt extends BufferedInputStream
{
BufferedInputStreamExt(InputStream input)
diff --git a/pg/src/main/java/org/bouncycastle/openpgp/StreamGenerator.java b/pg/src/main/java/org/bouncycastle/openpgp/StreamGenerator.java
index 58628d13a8..75e927678e 100644
--- a/pg/src/main/java/org/bouncycastle/openpgp/StreamGenerator.java
+++ b/pg/src/main/java/org/bouncycastle/openpgp/StreamGenerator.java
@@ -2,8 +2,15 @@
import java.io.IOException;
+/**
+ * Callback interface for generators that produce a stream to be informed when the stream has been
+ * closed by the client.
+ */
interface StreamGenerator
{
+ /**
+ * Signal that the stream has been closed.
+ */
void close()
throws IOException;
}
diff --git a/pg/src/main/java/org/bouncycastle/openpgp/bc/BcPGPObjectFactory.java b/pg/src/main/java/org/bouncycastle/openpgp/bc/BcPGPObjectFactory.java
index 2fcde0fa38..7ee93c7309 100644
--- a/pg/src/main/java/org/bouncycastle/openpgp/bc/BcPGPObjectFactory.java
+++ b/pg/src/main/java/org/bouncycastle/openpgp/bc/BcPGPObjectFactory.java
@@ -6,14 +6,28 @@
import org.bouncycastle.openpgp.PGPObjectFactory;
import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator;
+/**
+ * {@link PGPObjectFactory} that uses the Bouncy Castle lightweight API to implement cryptographic
+ * primitives.
+ */
public class BcPGPObjectFactory
extends PGPObjectFactory
{
- public BcPGPObjectFactory(byte[] encoding)
+ /**
+ * Construct an object factory to read PGP objects from encoded data.
+ *
+ * @param encoded the PGP encoded data.
+ */
+ public BcPGPObjectFactory(byte[] encoded)
{
- this(new ByteArrayInputStream(encoding));
+ this(new ByteArrayInputStream(encoded));
}
+ /**
+ * Construct an object factory to read PGP objects from a stream.
+ *
+ * @param in the stream containing PGP encoded objects.
+ */
public BcPGPObjectFactory(InputStream in)
{
super(in, new BcKeyFingerprintCalculator());
diff --git a/pg/src/main/java/org/bouncycastle/openpgp/jcajce/JcaPGPObjectFactory.java b/pg/src/main/java/org/bouncycastle/openpgp/jcajce/JcaPGPObjectFactory.java
index e645973d8e..bff681ab13 100644
--- a/pg/src/main/java/org/bouncycastle/openpgp/jcajce/JcaPGPObjectFactory.java
+++ b/pg/src/main/java/org/bouncycastle/openpgp/jcajce/JcaPGPObjectFactory.java
@@ -6,16 +6,30 @@
import org.bouncycastle.openpgp.PGPObjectFactory;
import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
+/**
+ * {@link PGPObjectFactory} that uses the sources cryptographic primitives from the JCA API.
+ */
public class JcaPGPObjectFactory
extends PGPObjectFactory
{
- public JcaPGPObjectFactory(byte[] encoding)
+ /**
+ * Construct an object factory to read PGP objects from encoded data.
+ *
+ * @param encoded the PGP encoded data.
+ */
+ public JcaPGPObjectFactory(byte[] encoded)
{
- this(new ByteArrayInputStream(encoding));
+ this(new ByteArrayInputStream(encoded));
}
+ /**
+ * Construct an object factory to read PGP objects from a stream.
+ *
+ * @param in the stream containing PGP encoded objects.
+ */
public JcaPGPObjectFactory(InputStream in)
{
+ // FIXME: Convert this to builder style so we can set provider?
super(in, new JcaKeyFingerprintCalculator());
}
}
diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/PBEDataDecryptorFactory.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/PBEDataDecryptorFactory.java
index 05c93e16c9..8538e4f67d 100644
--- a/pg/src/main/java/org/bouncycastle/openpgp/operator/PBEDataDecryptorFactory.java
+++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/PBEDataDecryptorFactory.java
@@ -1,26 +1,57 @@
package org.bouncycastle.openpgp.operator;
import org.bouncycastle.bcpg.S2K;
+import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags;
import org.bouncycastle.openpgp.PGPException;
+/**
+ * A factory for performing PBE decryption operations.
+ */
public abstract class PBEDataDecryptorFactory
implements PGPDataDecryptorFactory
{
private char[] passPhrase;
private PGPDigestCalculatorProvider calculatorProvider;
+ /**
+ * Construct a PBE data decryptor factory.
+ *
+ * @param passPhrase the pass phrase to generate decryption keys with.
+ * @param calculatorProvider the digest to use in key generation.
+ */
protected PBEDataDecryptorFactory(char[] passPhrase, PGPDigestCalculatorProvider calculatorProvider)
{
this.passPhrase = passPhrase;
this.calculatorProvider = calculatorProvider;
}
+ /**
+ * Generates an encryption key using the pass phrase and digest calculator configured for this
+ * factory.
+ *
+ * @param keyAlgorithm the {@link SymmetricKeyAlgorithmTags encryption algorithm} to generate a
+ * key for.
+ * @param s2k the string-to-key specification to use to generate the key.
+ * @return the key bytes for the encryption algorithm, generated using the pass phrase of this
+ * factory.
+ * @throws PGPException if an error occurs generating the key.
+ */
public byte[] makeKeyFromPassPhrase(int keyAlgorithm, S2K s2k)
throws PGPException
{
return PGPUtil.makeKeyFromPassPhrase(calculatorProvider, keyAlgorithm, s2k, passPhrase);
}
+ /**
+ * Decrypts session data from an encrypted data packet.
+ *
+ * @param keyAlgorithm the {@link SymmetricKeyAlgorithmTags encryption algorithm} used to
+ * encrypt the session data.
+ * @param key the key bytes for the encryption algorithm.
+ * @param seckKeyData the encrypted session data to decrypt.
+ * @return the decrypted session data.
+ * @throws PGPException if an error occurs decrypting the session data.
+ */
public abstract byte[] recoverSessionData(int keyAlgorithm, byte[] key, byte[] seckKeyData)
throws PGPException;
}
diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/PBEKeyEncryptionMethodGenerator.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/PBEKeyEncryptionMethodGenerator.java
index 189467dfea..2907439b3a 100644
--- a/pg/src/main/java/org/bouncycastle/openpgp/operator/PBEKeyEncryptionMethodGenerator.java
+++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/PBEKeyEncryptionMethodGenerator.java
@@ -4,9 +4,21 @@
import org.bouncycastle.bcpg.ContainedPacket;
import org.bouncycastle.bcpg.S2K;
+import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags;
import org.bouncycastle.bcpg.SymmetricKeyEncSessionPacket;
import org.bouncycastle.openpgp.PGPException;
+/**
+ * PGP style PBE encryption method.
+ *
+ * A pass phrase is used to generate an encryption key using the PGP {@link S2K string-to-key}
+ * method. This class always uses the {@link S2K#SALTED_AND_ITERATED salted and iterated form of the
+ * S2K algorithm}.
+ *
+ * Note that the iteration count provided to this method is a single byte as described by the
+ * {@link S2K} algorithm, and the actual iteration count ranges exponentially from
+ * 0x01 == 1088 to 0xFF == 65,011,712.
+ */
public abstract class PBEKeyEncryptionMethodGenerator
extends PGPKeyEncryptionMethodGenerator
{
@@ -16,6 +28,13 @@ public abstract class PBEKeyEncryptionMethodGenerator
private SecureRandom random;
private int s2kCount;
+ /**
+ * Construct a PBE key generator using the default iteration count (0x60 == 65536
+ * iterations).
+ *
+ * @param passPhrase the pass phrase to encrypt with.
+ * @param s2kDigestCalculator a digest calculator to use in the string-to-key function.
+ */
protected PBEKeyEncryptionMethodGenerator(
char[] passPhrase,
PGPDigestCalculator s2kDigestCalculator)
@@ -23,6 +42,14 @@ protected PBEKeyEncryptionMethodGenerator(
this(passPhrase, s2kDigestCalculator, 0x60);
}
+ /**
+ * Construct a PBE key generator using a specific iteration level.
+ *
+ * @param passPhrase the pass phrase to encrypt with.
+ * @param s2kDigestCalculator a digest calculator to use in the string-to-key function.
+ * @param s2kCount a single byte {@link S2K} iteration count specifier, which is translated to
+ * an actual iteration count by the S2K class.
+ */
protected PBEKeyEncryptionMethodGenerator(
char[] passPhrase,
PGPDigestCalculator s2kDigestCalculator,
@@ -39,6 +66,13 @@ protected PBEKeyEncryptionMethodGenerator(
this.s2kCount = s2kCount;
}
+ /**
+ * Sets a user defined source of randomness.
+ *
+ * If no SecureRandom is configured, a default SecureRandom will be used.
+ *
+ * @return the current generator.
+ */
public PBEKeyEncryptionMethodGenerator setSecureRandom(SecureRandom random)
{
this.random = random;
@@ -46,6 +80,15 @@ public PBEKeyEncryptionMethodGenerator setSecureRandom(SecureRandom random)
return this;
}
+ /**
+ * Generate a key for a symmetric encryption algorithm using the PBE configuration in this
+ * method.
+ *
+ * @param encAlgorithm the {@link SymmetricKeyAlgorithmTags encryption algorithm} to generate
+ * the key for.
+ * @return the bytes of the generated key.
+ * @throws PGPException if an error occurs performing the string-to-key generation.
+ */
public byte[] getKey(int encAlgorithm)
throws PGPException
{
diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPDataDecryptor.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPDataDecryptor.java
index 7f79640af3..862b342e9a 100644
--- a/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPDataDecryptor.java
+++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPDataDecryptor.java
@@ -2,11 +2,29 @@
import java.io.InputStream;
+/**
+ * A decryptor that wraps a stream of PGP encrypted data to decrypt, and optionally integrity check,
+ * the data.
+ */
public interface PGPDataDecryptor
{
+ /**
+ * Wraps an encrypted data stream with a stream that will return the decrypted data.
+ *
+ * @param in the encrypted data.
+ * @return a decrypting stream.
+ */
InputStream getInputStream(InputStream in);
+ /**
+ * Obtains the block size of the encryption algorithm used in this decryptor.
+ *
+ * @return the block size of the cipher in bytes.
+ */
int getBlockSize();
+ /**
+ * Obtains the digest calculator used to verify the integrity check.
+ */
PGPDigestCalculator getIntegrityCalculator();
}
diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPDataDecryptorFactory.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPDataDecryptorFactory.java
index 87d7891da1..39ac30fd93 100644
--- a/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPDataDecryptorFactory.java
+++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPDataDecryptorFactory.java
@@ -1,9 +1,25 @@
package org.bouncycastle.openpgp.operator;
+import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags;
import org.bouncycastle.openpgp.PGPException;
+/**
+ * Base interface of factories for {@link PGPDataDecryptor}.
+ */
public interface PGPDataDecryptorFactory
{
+ /**
+ * Constructs a data decryptor.
+ *
+ * @param withIntegrityPacket true if the packet to be decrypted has integrity
+ * checking enabled.
+ * @param encAlgorithm the identifier of the {@link SymmetricKeyAlgorithmTags encryption
+ * algorithm} to decrypt with.
+ * @param key the bytes of the key for the cipher.
+ * @return a data decryptor that can decrypt (and verify) streams of encrypted data.
+ * @throws PGPException if an error occurs initialising the decryption and integrity checking
+ * functions.
+ */
public PGPDataDecryptor createDataDecryptor(boolean withIntegrityPacket, int encAlgorithm, byte[] key)
throws PGPException;
}
diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPDataEncryptor.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPDataEncryptor.java
index 20d40a3958..fbd994a002 100644
--- a/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPDataEncryptor.java
+++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPDataEncryptor.java
@@ -2,11 +2,38 @@
import java.io.OutputStream;
+/**
+ * A data encryptor, combining a cipher instance and an optional integrity check calculator.
+ *
+ * {@link PGPDataEncryptor} instances are generally not constructed directly, but obtained from a
+ * {@link PGPDataEncryptorBuilder}.
+ */
public interface PGPDataEncryptor
{
+ /**
+ * Constructs an encrypting output stream that encrypts data using the underlying cipher of this
+ * encryptor.
+ *
+ * The cipher instance in this encryptor is used for all output streams obtained from this
+ * method, so it should only be invoked once.
+ *
+ * @param out the stream to wrap and write encrypted data to.
+ * @return a cipher output stream appropriate to the type of this data encryptor.
+ */
OutputStream getOutputStream(OutputStream out);
+ /**
+ * Obtains the integrity check calculator configured for this encryptor instance.
+ *
+ * @return the integrity check calculator, or null if no integrity checking was
+ * configured.
+ */
PGPDigestCalculator getIntegrityCalculator();
+ /**
+ * Gets the block size of the underlying cipher used by this encryptor.
+ *
+ * @return the block size in bytes.
+ */
int getBlockSize();
}
diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPDataEncryptorBuilder.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPDataEncryptorBuilder.java
index 13f94775fb..91660b01d6 100644
--- a/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPDataEncryptorBuilder.java
+++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPDataEncryptorBuilder.java
@@ -2,14 +2,35 @@
import java.security.SecureRandom;
+import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags;
import org.bouncycastle.openpgp.PGPException;
+/**
+ * A builder for {@link PGPDataEncryptor} instances, which can be used to encrypt data objects.
+ */
public interface PGPDataEncryptorBuilder
{
+ /**
+ * The encryption algorithm used by data encryptors created by this builder.
+ *
+ * @return one of the {@link SymmetricKeyAlgorithmTags symmetric encryption algorithms}.
+ */
int getAlgorithm();
+ /**
+ * Builds a data encryptor using the algorithm configured for this builder.
+ *
+ * @param keyBytes the bytes of the key to use for the cipher.
+ * @return a data encryptor with an initialised cipher.
+ * @throws PGPException if an error occurs initialising the configured encryption.
+ */
PGPDataEncryptor build(byte[] keyBytes)
throws PGPException;
+ /**
+ * Gets the SecureRandom instance used by this builder.
+ * If a SecureRandom has not been explicitly configured, a default {@link SecureRandom} is
+ * constructed and retained by the this builder.
+ */
SecureRandom getSecureRandom();
}
diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPDigestCalculator.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPDigestCalculator.java
index a917a55b60..70efe8a6f1 100644
--- a/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPDigestCalculator.java
+++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPDigestCalculator.java
@@ -2,30 +2,35 @@
import java.io.OutputStream;
+import org.bouncycastle.bcpg.HashAlgorithmTags;
+
+/**
+ * A digest calculator, which consumes a stream of data and computes a digest value over it.
+ */
public interface PGPDigestCalculator
{
/**
- * Return the algorithm number representing the digest implemented by
- * this calculator.
- *
- * @return algorithm number
- */
+ * Return the {@link HashAlgorithmTags algorithm number} representing the digest implemented by
+ * this calculator.
+ *
+ * @return the hash algorithm number
+ */
int getAlgorithm();
/**
- * Returns a stream that will accept data for the purpose of calculating
- * a digest. Use org.bouncycastle.util.io.TeeOutputStream if you want to accumulate
- * the data on the fly as well.
- *
- * @return an OutputStream
- */
+ * Returns a stream that will accept data for the purpose of calculating a digest. Use
+ * org.bouncycastle.util.io.TeeOutputStream if you want to accumulate the data on the fly as
+ * well.
+ *
+ * @return an OutputStream that data to be digested can be written to.
+ */
OutputStream getOutputStream();
/**
- * Return the digest calculated on what has been written to the calculator's output stream.
- *
- * @return a digest.
- */
+ * Return the digest calculated on what has been written to the calculator's output stream.
+ *
+ * @return a digest.
+ */
byte[] getDigest();
/**
diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPDigestCalculatorProvider.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPDigestCalculatorProvider.java
index bbde1ab52f..dcfce65c5b 100644
--- a/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPDigestCalculatorProvider.java
+++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPDigestCalculatorProvider.java
@@ -1,9 +1,21 @@
package org.bouncycastle.openpgp.operator;
+import org.bouncycastle.bcpg.HashAlgorithmTags;
import org.bouncycastle.openpgp.PGPException;
+/**
+ * A factory for digest algorithms.
+ */
public interface PGPDigestCalculatorProvider
{
+ /**
+ * Construct a new instance of a cryptographic digest.
+ *
+ * @param algorithm the identifier of the {@link HashAlgorithmTags digest algorithm} to
+ * instantiate.
+ * @return a digest calculator for the specified algorithm.
+ * @throws PGPException if an error occurs constructing the specified digest.
+ */
PGPDigestCalculator get(int algorithm)
throws PGPException;
}
diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPKeyEncryptionMethodGenerator.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPKeyEncryptionMethodGenerator.java
index 0cffaa53b2..97e703d6db 100644
--- a/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPKeyEncryptionMethodGenerator.java
+++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPKeyEncryptionMethodGenerator.java
@@ -1,10 +1,23 @@
package org.bouncycastle.openpgp.operator;
import org.bouncycastle.bcpg.ContainedPacket;
+import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags;
+import org.bouncycastle.openpgp.PGPEncryptedDataGenerator;
import org.bouncycastle.openpgp.PGPException;
+/**
+ * An encryption method that can be applied to encrypt data in a {@link PGPEncryptedDataGenerator}.
+ */
public abstract class PGPKeyEncryptionMethodGenerator
{
+ /**
+ * Generates a packet encoding the details of this encryption method.
+ *
+ * @param encAlgorithm the {@link SymmetricKeyAlgorithmTags encryption algorithm} being used
+ * @param sessionInfo session data generated by the encrypted data generator.
+ * @return a packet encoding the provided information and the configuration of this instance.
+ * @throws PGPException if an error occurs constructing the packet.
+ */
public abstract ContainedPacket generate(int encAlgorithm, byte[] sessionInfo)
throws PGPException;
}
diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPUtil.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPUtil.java
index 0cbe5d8741..fc9d4c10bb 100644
--- a/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPUtil.java
+++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/PGPUtil.java
@@ -22,6 +22,7 @@ static byte[] makeKeyFromPassPhrase(
char[] passPhrase)
throws PGPException
{
+ // TODO: Never used
String algName = null;
int keySize = 0;
diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPBEDataDecryptorFactory.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPBEDataDecryptorFactory.java
index 81449ebcc0..fdc143b716 100644
--- a/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPBEDataDecryptorFactory.java
+++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPBEDataDecryptorFactory.java
@@ -7,7 +7,8 @@
import org.bouncycastle.openpgp.operator.PGPDataDecryptor;
/**
- * A decryptor factory for handling PBE decryption operations.
+ * A {@link PBEDataDecryptorFactory} for handling PBE decryption operations using the Bouncy Castle
+ * lightweight API to implement cryptographic primitives.
*/
public class BcPBEDataDecryptorFactory
extends PBEDataDecryptorFactory
diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPBEKeyEncryptionMethodGenerator.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPBEKeyEncryptionMethodGenerator.java
index 0a965fe6d6..17aa28cc24 100644
--- a/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPBEKeyEncryptionMethodGenerator.java
+++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPBEKeyEncryptionMethodGenerator.java
@@ -2,6 +2,7 @@
import java.security.SecureRandom;
+import org.bouncycastle.bcpg.S2K;
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.BufferedBlockCipher;
import org.bouncycastle.crypto.InvalidCipherTextException;
@@ -16,10 +17,11 @@ public class BcPBEKeyEncryptionMethodGenerator
extends PBEKeyEncryptionMethodGenerator
{
/**
- * Create a PBE encryption method generator using the provided calculator for key calculation.
+ * Create a PBE encryption method generator using the provided digest and the default S2K count
+ * for key generation.
*
- * @param passPhrase the passphrase to use as the primary source of key material.
- * @param s2kDigestCalculator the digest calculator to use for key calculation.
+ * @param passPhrase the passphrase to use as the primary source of key material.
+ * @param s2kDigestCalculator the digest calculator to use for key calculation.
*/
public BcPBEKeyEncryptionMethodGenerator(char[] passPhrase, PGPDigestCalculator s2kDigestCalculator)
{
@@ -27,9 +29,10 @@ public BcPBEKeyEncryptionMethodGenerator(char[] passPhrase, PGPDigestCalculator
}
/**
- * Create a PBE encryption method generator using the default SHA-1 digest calculator for key calculation.
+ * Create a PBE encryption method generator using the default SHA-1 digest and the default S2K
+ * count for key generation.
*
- * @param passPhrase the passphrase to use as the primary source of key material.
+ * @param passPhrase the passphrase to use as the primary source of key material.
*/
public BcPBEKeyEncryptionMethodGenerator(char[] passPhrase)
{
@@ -37,11 +40,12 @@ public BcPBEKeyEncryptionMethodGenerator(char[] passPhrase)
}
/**
- * Create a PBE encryption method generator using the provided calculator and S2K count for key calculation.
- *
- * @param passPhrase the passphrase to use as the primary source of key material.
- * @param s2kDigestCalculator the digest calculator to use for key calculation.
- * @param s2kCount the S2K count to use.
+ * Create a PBE encryption method generator using the provided calculator and S2K count for key
+ * generation.
+ *
+ * @param passPhrase the passphrase to use as the primary source of key material.
+ * @param s2kDigestCalculator the digest calculator to use for key calculation.
+ * @param s2kCount the single byte {@link S2K} count to use.
*/
public BcPBEKeyEncryptionMethodGenerator(char[] passPhrase, PGPDigestCalculator s2kDigestCalculator, int s2kCount)
{
@@ -49,23 +53,17 @@ public BcPBEKeyEncryptionMethodGenerator(char[] passPhrase, PGPDigestCalculator
}
/**
- * Create a PBE encryption method generator using the default SHA-1 digest calculator and
- * a S2K count other than the default of 0x60 for key calculation.
+ * Create a PBE encryption method generator using the default SHA-1 digest calculator and a S2K
+ * count other than the default for key generation.
*
* @param passPhrase the passphrase to use as the primary source of key material.
- * @param s2kCount the S2K count to use.
+ * @param s2kCount the single byte {@link S2K} count to use.
*/
public BcPBEKeyEncryptionMethodGenerator(char[] passPhrase, int s2kCount)
{
super(passPhrase, new SHA1PGPDigestCalculator(), s2kCount);
}
- /**
- * Provide a user defined source of randomness.
- *
- * @param random the secure random to be used.
- * @return the current generator.
- */
public PBEKeyEncryptionMethodGenerator setSecureRandom(SecureRandom random)
{
super.setSecureRandom(random);
diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPGPDataEncryptorBuilder.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPGPDataEncryptorBuilder.java
index 51fd69d0b8..a47b311121 100644
--- a/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPGPDataEncryptorBuilder.java
+++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/bc/BcPGPDataEncryptorBuilder.java
@@ -3,6 +3,7 @@
import java.io.OutputStream;
import java.security.SecureRandom;
+import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags;
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.BufferedBlockCipher;
import org.bouncycastle.crypto.io.CipherOutputStream;
@@ -11,6 +12,10 @@
import org.bouncycastle.openpgp.operator.PGPDataEncryptorBuilder;
import org.bouncycastle.openpgp.operator.PGPDigestCalculator;
+/**
+ * {@link PGPDataEncryptorBuilder} implementation that uses the Bouncy Castle lightweight API to
+ * implement cryptographic primitives.
+ */
public class BcPGPDataEncryptorBuilder
implements PGPDataEncryptorBuilder
{
@@ -18,6 +23,12 @@ public class BcPGPDataEncryptorBuilder
private boolean withIntegrityPacket;
private int encAlgorithm;
+ /**
+ * Constructs a new data encryptor builder for a specified cipher type.
+ *
+ * @param encAlgorithm one of the {@link SymmetricKeyAlgorithmTags supported symmetric cipher
+ * algorithms}. May not be {@link SymmetricKeyAlgorithmTags#NULL}.
+ */
public BcPGPDataEncryptorBuilder(int encAlgorithm)
{
this.encAlgorithm = encAlgorithm;
@@ -28,11 +39,11 @@ public BcPGPDataEncryptorBuilder(int encAlgorithm)
}
}
- /**
- * Determine whether or not the resulting encrypted data will be protected using an integrity packet.
+ /**
+ * Sets whether or not the resulting encrypted data will be protected using an integrity packet.
*
* @param withIntegrityPacket true if an integrity packet is to be included, false otherwise.
- * @return the current builder.
+ * @return the current builder.
*/
public BcPGPDataEncryptorBuilder setWithIntegrityPacket(boolean withIntegrityPacket)
{
@@ -43,9 +54,11 @@ public BcPGPDataEncryptorBuilder setWithIntegrityPacket(boolean withIntegrityPac
/**
* Provide a user defined source of randomness.
+ *
+ * If no SecureRandom is configured, a default SecureRandom will be used.
*
- * @param random the secure random to be used.
- * @return the current builder.
+ * @param random the secure random to be used.
+ * @return the current builder.
*/
public BcPGPDataEncryptorBuilder setSecureRandom(SecureRandom random)
{
diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcaKeyFingerprintCalculator.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcaKeyFingerprintCalculator.java
index 1bcb92c483..e4fa495ea7 100644
--- a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcaKeyFingerprintCalculator.java
+++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcaKeyFingerprintCalculator.java
@@ -14,6 +14,8 @@
public class JcaKeyFingerprintCalculator
implements KeyFingerPrintCalculator
{
+
+ // FIXME: Convert this to builder style so we can set provider?
public byte[] calculateFingerprint(PublicKeyPacket publicPk)
throws PGPException
{
diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcaPGPDigestCalculatorProviderBuilder.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcaPGPDigestCalculatorProviderBuilder.java
index f743544210..1a8ccef54a 100644
--- a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcaPGPDigestCalculatorProviderBuilder.java
+++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcaPGPDigestCalculatorProviderBuilder.java
@@ -13,14 +13,31 @@
import org.bouncycastle.openpgp.operator.PGPDigestCalculator;
import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider;
+/**
+ * A builder for {@link PGPDigestCalculatorProvider} instances that obtain cryptographic primitives
+ * using the JCA API.
+ *
+ * By default digest calculator providers obtained from this builder will use the default JCA
+ * algorithm lookup mechanisms (i.e. specifying no provider), but a specific provider can be
+ * specified prior to building.
+ */
public class JcaPGPDigestCalculatorProviderBuilder
{
private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper());
+ /**
+ * Default constructor.
+ */
public JcaPGPDigestCalculatorProviderBuilder()
{
}
+ /**
+ * Sets the provider to use to obtain cryptographic primitives.
+ *
+ * @param provider the JCA provider to use.
+ * @return the current builder.
+ */
public JcaPGPDigestCalculatorProviderBuilder setProvider(Provider provider)
{
this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider));
@@ -28,6 +45,12 @@ public JcaPGPDigestCalculatorProviderBuilder setProvider(Provider provider)
return this;
}
+ /**
+ * Sets the provider to use to obtain cryptographic primitives.
+ *
+ * @param providerName the name of the JCA provider to use.
+ * @return the current builder.
+ */
public JcaPGPDigestCalculatorProviderBuilder setProvider(String providerName)
{
this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName));
@@ -35,6 +58,13 @@ public JcaPGPDigestCalculatorProviderBuilder setProvider(String providerName)
return this;
}
+ /**
+ * Constructs a new PGPDigestCalculatorProvider
+ *
+ * @return a PGPDigestCalculatorProvider that will use the JCA algorithm lookup strategy
+ * configured on this builder.
+ * @throws PGPException if an error occurs constructing the digest calculator provider.
+ */
public PGPDigestCalculatorProvider build()
throws PGPException
{
diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePBEDataDecryptorFactoryBuilder.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePBEDataDecryptorFactoryBuilder.java
index cd7118fe3c..d1ef90015b 100644
--- a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePBEDataDecryptorFactoryBuilder.java
+++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePBEDataDecryptorFactoryBuilder.java
@@ -14,6 +14,10 @@
import org.bouncycastle.openpgp.operator.PGPDataDecryptor;
import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider;
+/**
+ * Builder for {@link PBEDataDecryptorFactory} instances that obtain cryptographic primitives using
+ * the JCE API.
+ */
public class JcePBEDataDecryptorFactoryBuilder
{
private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper());
@@ -55,6 +59,12 @@ public JcePBEDataDecryptorFactoryBuilder setProvider(String providerName)
return this;
}
+ /**
+ * Construct a {@link PBEDataDecryptorFactory} to use to decrypt PBE encrypted data.
+ *
+ * @param passPhrase the pass phrase to use to generate keys in the resulting factory.
+ * @return a decryptor factory that can be used to generate PBE keys.
+ */
public PBEDataDecryptorFactory build(char[] passPhrase)
{
return new PBEDataDecryptorFactory(passPhrase, calculatorProvider)
diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePBEKeyEncryptionMethodGenerator.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePBEKeyEncryptionMethodGenerator.java
index 851c0a7965..71429f9643 100644
--- a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePBEKeyEncryptionMethodGenerator.java
+++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePBEKeyEncryptionMethodGenerator.java
@@ -12,6 +12,7 @@
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
+import org.bouncycastle.bcpg.S2K;
import org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
import org.bouncycastle.jcajce.util.ProviderJcaJceHelper;
@@ -28,10 +29,11 @@ public class JcePBEKeyEncryptionMethodGenerator
private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper());
/**
- * Create a PBE encryption method generator using the provided calculator for key calculation.
+ * Create a PBE encryption method generator using the provided digest and the default S2K count
+ * for key generation.
*
- * @param passPhrase the passphrase to use as the primary source of key material.
- * @param s2kDigestCalculator the digest calculator to use for key calculation.
+ * @param passPhrase the passphrase to use as the primary source of key material.
+ * @param s2kDigestCalculator the digest calculator to use for key calculation.
*/
public JcePBEKeyEncryptionMethodGenerator(char[] passPhrase, PGPDigestCalculator s2kDigestCalculator)
{
@@ -39,9 +41,10 @@ public JcePBEKeyEncryptionMethodGenerator(char[] passPhrase, PGPDigestCalculator
}
/**
- * Create a PBE encryption method generator using the default SHA-1 digest calculator for key calculation.
+ * Create a PBE encryption method generator using the default SHA-1 digest and the default S2K
+ * count for key generation.
*
- * @param passPhrase the passphrase to use as the primary source of key material.
+ * @param passPhrase the passphrase to use as the primary source of key material.
*/
public JcePBEKeyEncryptionMethodGenerator(char[] passPhrase)
{
@@ -49,11 +52,12 @@ public JcePBEKeyEncryptionMethodGenerator(char[] passPhrase)
}
/**
- * Create a PBE encryption method generator using the provided calculator and S2K count for key calculation.
+ * Create a PBE encryption method generator using the provided calculator and S2K count for key
+ * generation.
*
- * @param passPhrase the passphrase to use as the primary source of key material.
- * @param s2kDigestCalculator the digest calculator to use for key calculation.
- * @param s2kCount the S2K count to use.
+ * @param passPhrase the passphrase to use as the primary source of key material.
+ * @param s2kDigestCalculator the digest calculator to use for key calculation.
+ * @param s2kCount the single byte {@link S2K} count to use.
*/
public JcePBEKeyEncryptionMethodGenerator(char[] passPhrase, PGPDigestCalculator s2kDigestCalculator, int s2kCount)
{
@@ -61,17 +65,23 @@ public JcePBEKeyEncryptionMethodGenerator(char[] passPhrase, PGPDigestCalculator
}
/**
- * Create a PBE encryption method generator using the default SHA-1 digest calculator and
- * a S2K count other than the default of 0x60 for key calculation
+ * Create a PBE encryption method generator using the default SHA-1 digest calculator and a S2K
+ * count other than the default for key generation.
*
* @param passPhrase the passphrase to use as the primary source of key material.
- * @param s2kCount the S2K count to use.
+ * @param s2kCount the single byte {@link S2K} count to use.
*/
public JcePBEKeyEncryptionMethodGenerator(char[] passPhrase, int s2kCount)
{
super(passPhrase, new SHA1PGPDigestCalculator(), s2kCount);
}
+ /**
+ * Sets the JCE provider to source cryptographic primitives from.
+ *
+ * @param provider the JCE provider to use.
+ * @return the current generator.
+ */
public JcePBEKeyEncryptionMethodGenerator setProvider(Provider provider)
{
this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider));
@@ -79,6 +89,12 @@ public JcePBEKeyEncryptionMethodGenerator setProvider(Provider provider)
return this;
}
+ /**
+ * Sets the JCE provider to source cryptographic primitives from.
+ *
+ * @param providerName the name of the JCE provider to use.
+ * @return the current generator.
+ */
public JcePBEKeyEncryptionMethodGenerator setProvider(String providerName)
{
this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName));
@@ -86,12 +102,6 @@ public JcePBEKeyEncryptionMethodGenerator setProvider(String providerName)
return this;
}
- /**
- * Provide a user defined source of randomness.
- *
- * @param random the secure random to be used.
- * @return the current generator.
- */
public PBEKeyEncryptionMethodGenerator setSecureRandom(SecureRandom random)
{
super.setSecureRandom(random);
diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePGPDataEncryptorBuilder.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePGPDataEncryptorBuilder.java
index ff0380786a..f0c075cef7 100644
--- a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePGPDataEncryptorBuilder.java
+++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcePGPDataEncryptorBuilder.java
@@ -10,6 +10,7 @@
import javax.crypto.CipherOutputStream;
import javax.crypto.spec.IvParameterSpec;
+import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags;
import org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
import org.bouncycastle.jcajce.util.ProviderJcaJceHelper;
@@ -18,6 +19,14 @@
import org.bouncycastle.openpgp.operator.PGPDataEncryptorBuilder;
import org.bouncycastle.openpgp.operator.PGPDigestCalculator;
+/**
+ * {@link PGPDataEncryptorBuilder} implementation that sources cryptographic primitives using the
+ * JCE APIs.
+ *
+ * By default, cryptographic primitives will be loaded using the default JCE load order (i.e.
+ * without specifying a provider).
+ * A specific provider can be specified using one of the {@link #setProvider(String)} methods.
+ */
public class JcePGPDataEncryptorBuilder
implements PGPDataEncryptorBuilder
{
@@ -26,6 +35,12 @@ public class JcePGPDataEncryptorBuilder
private boolean withIntegrityPacket;
private int encAlgorithm;
+ /**
+ * Constructs a new data encryptor builder for a specified cipher type.
+ *
+ * @param encAlgorithm one of the {@link SymmetricKeyAlgorithmTags supported symmetric cipher
+ * algorithms}. May not be {@link SymmetricKeyAlgorithmTags#NULL}.
+ */
public JcePGPDataEncryptorBuilder(int encAlgorithm)
{
this.encAlgorithm = encAlgorithm;
@@ -37,10 +52,10 @@ public JcePGPDataEncryptorBuilder(int encAlgorithm)
}
/**
- * Determine whether or not the resulting encrypted data will be protected using an integrity packet.
+ * Sets whether or not the resulting encrypted data will be protected using an integrity packet.
*
* @param withIntegrityPacket true if an integrity packet is to be included, false otherwise.
- * @return the current builder.
+ * @return the current builder.
*/
public JcePGPDataEncryptorBuilder setWithIntegrityPacket(boolean withIntegrityPacket)
{
@@ -49,6 +64,12 @@ public JcePGPDataEncryptorBuilder setWithIntegrityPacket(boolean withIntegrityPa
return this;
}
+ /**
+ * Sets the JCE provider to source cryptographic primitives from.
+ *
+ * @param provider the JCE provider to use.
+ * @return the current builder.
+ */
public JcePGPDataEncryptorBuilder setProvider(Provider provider)
{
this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider));
@@ -56,6 +77,12 @@ public JcePGPDataEncryptorBuilder setProvider(Provider provider)
return this;
}
+ /**
+ * Sets the JCE provider to source cryptographic primitives from.
+ *
+ * @param providerName the name of the JCE provider to use.
+ * @return the current builder.
+ */
public JcePGPDataEncryptorBuilder setProvider(String providerName)
{
this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName));
@@ -65,9 +92,11 @@ public JcePGPDataEncryptorBuilder setProvider(String providerName)
/**
* Provide a user defined source of randomness.
- *
- * @param random the secure random to be used.
- * @return the current builder.
+ *
+ * If no SecureRandom is configured, a default SecureRandom will be used.
+ *
+ * @param random the secure random to be used.
+ * @return the current builder.
*/
public JcePGPDataEncryptorBuilder setSecureRandom(SecureRandom random)
{
diff --git a/prov/src/main/java/org/bouncycastle/jcajce/util/DefaultJcaJceHelper.java b/prov/src/main/java/org/bouncycastle/jcajce/util/DefaultJcaJceHelper.java
index 4094ba6749..43a97f3084 100644
--- a/prov/src/main/java/org/bouncycastle/jcajce/util/DefaultJcaJceHelper.java
+++ b/prov/src/main/java/org/bouncycastle/jcajce/util/DefaultJcaJceHelper.java
@@ -17,6 +17,10 @@
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKeyFactory;
+/**
+ * {@link JcaJceHelper} that obtains all algorithms using the default JCA/JCE mechanism (i.e.
+ * without specifying a provider).
+ */
public class DefaultJcaJceHelper
implements JcaJceHelper
{
diff --git a/prov/src/main/java/org/bouncycastle/jcajce/util/JcaJceHelper.java b/prov/src/main/java/org/bouncycastle/jcajce/util/JcaJceHelper.java
index 9e8125a2d2..f5da3354a6 100644
--- a/prov/src/main/java/org/bouncycastle/jcajce/util/JcaJceHelper.java
+++ b/prov/src/main/java/org/bouncycastle/jcajce/util/JcaJceHelper.java
@@ -18,6 +18,9 @@
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKeyFactory;
+/**
+ * Factory interface for instantiating JCA/JCE primitives.
+ */
public interface JcaJceHelper
{
Cipher createCipher(
diff --git a/prov/src/main/java/org/bouncycastle/jcajce/util/NamedJcaJceHelper.java b/prov/src/main/java/org/bouncycastle/jcajce/util/NamedJcaJceHelper.java
index 139c8bfde6..ebbfacc1ac 100644
--- a/prov/src/main/java/org/bouncycastle/jcajce/util/NamedJcaJceHelper.java
+++ b/prov/src/main/java/org/bouncycastle/jcajce/util/NamedJcaJceHelper.java
@@ -18,6 +18,9 @@
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKeyFactory;
+/**
+ * {@link JcaJceHelper} that obtains all algorithms using a specific named provider.
+ */
public class NamedJcaJceHelper
implements JcaJceHelper
{
diff --git a/prov/src/main/java/org/bouncycastle/jcajce/util/ProviderJcaJceHelper.java b/prov/src/main/java/org/bouncycastle/jcajce/util/ProviderJcaJceHelper.java
index d10a893411..fad10481eb 100644
--- a/prov/src/main/java/org/bouncycastle/jcajce/util/ProviderJcaJceHelper.java
+++ b/prov/src/main/java/org/bouncycastle/jcajce/util/ProviderJcaJceHelper.java
@@ -18,6 +18,9 @@
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKeyFactory;
+/**
+ * {@link JcaJceHelper} that obtains all algorithms from a specific {@link Provider} instance.
+ */
public class ProviderJcaJceHelper
implements JcaJceHelper
{