org.bouncycastle.bcpg.OnePassSignaturePacket Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bcpg-jdk14 Show documentation
Show all versions of bcpg-jdk14 Show documentation
The Bouncy Castle Java API for handling the OpenPGP protocol. This jar contains the OpenPGP API for JDK 1.4. The APIs can be used in conjunction with a JCE/JCA provider such as the one provided with the Bouncy Castle Cryptography APIs.
The newest version!
package org.bouncycastle.bcpg;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.io.Streams;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
/**
* One-Pass-Signature packet.
* OPS packets are used to enable verification of signed messages in one-pass by providing necessary metadata
* about the signed data up front, so the consumer can start processing the signed data without needing
* to process the signature packet at the end of the data stream first.
*
* There are two versions of this packet currently defined.
* Version 3 OPS packets are used with {@link SignaturePacket SignaturePackets} of version 3 and 4.
* Version 6 OPS packets are used with {@link SignaturePacket SignaturePackets} of version 6.
* It is not clear to me, which version of the OPS packet is intended to be used with version 5 signatures.
*
* @see
* Definition of version 3 OPS packets in RFC4880
* @see
* Definition of version 3 and 6 OPS packets in RFC9580
* @see
* Definition of version 3 and 6 OPS packets in librepgp
*/
public class OnePassSignaturePacket
extends ContainedPacket
{
public static final int VERSION_3 = 3;
public static final int VERSION_6 = 6;
private final int version;
private final int sigType;
private final int hashAlgorithm;
private final int keyAlgorithm;
private final long keyID;
private final byte[] fingerprint;
private final byte[] salt;
private final int isContaining;
/**
* Parse a {@link OnePassSignaturePacket} from an OpenPGP packet input stream.
* @param in OpenPGP packet input stream
* @throws IOException when the end of stream is prematurely reached, or when the packet is malformed
*/
OnePassSignaturePacket(
BCPGInputStream in)
throws IOException
{
this(in, false);
}
OnePassSignaturePacket(
BCPGInputStream in,
boolean newPacketFormat)
throws IOException
{
super(ONE_PASS_SIGNATURE, newPacketFormat);
version = in.read();
sigType = in.read();
hashAlgorithm = in.read();
keyAlgorithm = in.read();
if (version == VERSION_3)
{
keyID = StreamUtil.readKeyID(in);
fingerprint = null;
salt = null;
}
else if (version == VERSION_6)
{
int saltLen = in.read();
if (saltLen < 0)
{
throw new IOException("Version 6 OPS packet has invalid salt length.");
}
salt = new byte[saltLen];
in.readFully(salt);
fingerprint = new byte[32];
in.readFully(fingerprint);
keyID = FingerprintUtil.keyIdFromV6Fingerprint(fingerprint);
}
else
{
Streams.drain(in);
throw new UnsupportedPacketVersionException("Unsupported OnePassSignature packet version encountered: " + version);
}
isContaining = in.read();
}
/**
* Create a version 3 {@link OnePassSignaturePacket}.
* Version 3 OPS packets are used with version 3 and version 4 {@link SignaturePacket SignaturePackets}.
*
* To create an OPS packet for use with a version 6 {@link SignaturePacket},
* see {@link OnePassSignaturePacket#OnePassSignaturePacket(int, int, int, byte[], byte[], boolean)}.
*
* @param sigType signature type
* @param hashAlgorithm hash algorithm tag
* @param keyAlgorithm public key algorithm tag
* @param keyID id of the signing key
* @param isNested if false, there is another OPS packet after this one, which applies to the same data.
* it true, the corresponding signature is calculated also over succeeding additional OPS packets.
*/
public OnePassSignaturePacket(
int sigType,
int hashAlgorithm,
int keyAlgorithm,
long keyID,
boolean isNested)
{
super(ONE_PASS_SIGNATURE);
this.version = VERSION_3;
this.sigType = sigType;
this.hashAlgorithm = hashAlgorithm;
this.keyAlgorithm = keyAlgorithm;
this.keyID = keyID;
this.fingerprint = null;
this.salt = null;
this.isContaining = (isNested) ? 0 : 1;
}
/**
* Create a version 6 {@link OnePassSignaturePacket}.
*
* @param sigType signature type
* @param hashAlgorithm hash algorithm tag
* @param keyAlgorithm public key algorithm tag
* @param salt random salt. The length of this array depends on the hash algorithm in use.
* @param fingerprint 32 octet fingerprint of the (v6) signing key
* @param isNested if false, there is another OPS packet after this one, which applies to the same data.
* it true, the corresponding signature is calculated also over succeeding additional OPS packets.
*/
public OnePassSignaturePacket(
int sigType,
int hashAlgorithm,
int keyAlgorithm,
byte[] salt,
byte[] fingerprint,
boolean isNested)
{
super(ONE_PASS_SIGNATURE);
this.version = VERSION_6;
this.sigType = sigType;
this.hashAlgorithm = hashAlgorithm;
this.keyAlgorithm = keyAlgorithm;
this.salt = salt;
this.fingerprint = fingerprint;
this.isContaining = (isNested) ? 0 : 1;
keyID = FingerprintUtil.keyIdFromV6Fingerprint(fingerprint);
}
/**
* Return the packet version.
* @return version
*/
public int getVersion()
{
return version;
}
/**
* Return the signature type.
* @return the signature type
*/
public int getSignatureType()
{
return sigType;
}
/**
* Return the ID of the public key encryption algorithm.
* @return public key algorithm tag
*/
public int getKeyAlgorithm()
{
return keyAlgorithm;
}
/**
* Return the algorithm ID of the hash algorithm.
* @return hash algorithm tag
*/
public int getHashAlgorithm()
{
return hashAlgorithm;
}
/**
* Return the key-id of the signing key.
* @return key id
*/
public long getKeyID()
{
return keyID;
}
/**
* Return the version 6 fingerprint of the issuer.
* Only for version 6 packets.
* @return 32 bytes issuer fingerprint
*/
public byte[] getFingerprint()
{
return Arrays.clone(fingerprint);
}
/**
* Return the salt used in the signature.
* Only for version 6 packets.
* @return salt
*/
public byte[] getSalt()
{
return Arrays.clone(salt);
}
/**
* Return true, if the signature contains any signatures that follow.
* A bracketing OPS is followed by additional OPS packets and is calculated over all the data between itself
* and its corresponding signature (it is an attestation for encapsulated signatures).
*
* @return true if encapsulating, false otherwise
*/
public boolean isContaining()
{
return isContaining == 1;
}
/**
* Encode the contents of this packet into the given packet output stream.
*
* @param out OpenPGP packet output stream
*/
public void encode(
BCPGOutputStream out)
throws IOException
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
BCPGOutputStream pOut = new BCPGOutputStream(bOut);
pOut.write(version);
pOut.write(sigType);
pOut.write(hashAlgorithm);
pOut.write(keyAlgorithm);
if (version == VERSION_3)
{
StreamUtil.writeKeyID(pOut, keyID);
}
else if (version == VERSION_6)
{
pOut.write(salt.length);
pOut.write(salt);
pOut.write(fingerprint);
}
pOut.write(isContaining);
pOut.close();
out.writePacket(hasNewPacketFormat(), ONE_PASS_SIGNATURE, bOut.toByteArray());
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy