org.bouncycastle.openpgp.PGPV3SignatureGenerator Maven / Gradle / Ivy
package org.bouncycastle.openpgp;
import java.io.ByteArrayOutputStream;
import java.math.BigInteger;
import java.security.*;
import java.util.Date;
import org.bouncycastle.bcpg.MPInteger;
import org.bouncycastle.bcpg.OnePassSignaturePacket;
import org.bouncycastle.bcpg.PublicKeyAlgorithmTags;
import org.bouncycastle.bcpg.SignaturePacket;
/**
* Generator for old style PGP V3 Signatures.
*/
public class PGPV3SignatureGenerator
{
private int keyAlgorithm;
private int hashAlgorithm;
private PGPPrivateKey privKey;
private Signature sig;
private MessageDigest dig;
private int signatureType;
private byte lastb;
/**
* Create a generator for the passed in keyAlgorithm and hashAlgorithm codes.
*
* @param keyAlgorithm
* @param hashAlgorithm
* @param provider
* @throws NoSuchAlgorithmException
* @throws NoSuchProviderException
* @throws PGPException
*/
public PGPV3SignatureGenerator(
int keyAlgorithm,
int hashAlgorithm,
String provider)
throws NoSuchAlgorithmException, NoSuchProviderException, PGPException
{
this(keyAlgorithm, hashAlgorithm, PGPUtil.getProvider(provider));
}
public PGPV3SignatureGenerator(
int keyAlgorithm,
int hashAlgorithm,
Provider provider)
throws NoSuchAlgorithmException, PGPException
{
this.keyAlgorithm = keyAlgorithm;
this.hashAlgorithm = hashAlgorithm;
dig = PGPUtil.getDigestInstance(PGPUtil.getDigestName(hashAlgorithm), provider);
sig = Signature.getInstance(PGPUtil.getSignatureName(keyAlgorithm, hashAlgorithm), provider);
}
/**
* Initialise the generator for signing.
*
* @param signatureType
* @param key
* @throws PGPException
*/
public void initSign(
int signatureType,
PGPPrivateKey key)
throws PGPException
{
initSign(signatureType, key, null);
}
/**
* Initialise the generator for signing.
*
* @param signatureType
* @param key
* @param random
* @throws PGPException
*/
public void initSign(
int signatureType,
PGPPrivateKey key,
SecureRandom random)
throws PGPException
{
this.privKey = key;
this.signatureType = signatureType;
try
{
if (random == null)
{
sig.initSign(key.getKey());
}
else
{
sig.initSign(key.getKey(), random);
}
}
catch (InvalidKeyException e)
{
throw new PGPException("invalid key.", e);
}
dig.reset();
lastb = 0;
}
public void update(
byte b)
throws SignatureException
{
if (signatureType == PGPSignature.CANONICAL_TEXT_DOCUMENT)
{
if (b == '\r')
{
sig.update((byte)'\r');
sig.update((byte)'\n');
dig.update((byte)'\r');
dig.update((byte)'\n');
}
else if (b == '\n')
{
if (lastb != '\r')
{
sig.update((byte)'\r');
sig.update((byte)'\n');
dig.update((byte)'\r');
dig.update((byte)'\n');
}
}
else
{
sig.update(b);
dig.update(b);
}
lastb = b;
}
else
{
sig.update(b);
dig.update(b);
}
}
public void update(
byte[] b)
throws SignatureException
{
this.update(b, 0, b.length);
}
public void update(
byte[] b,
int off,
int len)
throws SignatureException
{
if (signatureType == PGPSignature.CANONICAL_TEXT_DOCUMENT)
{
int finish = off + len;
for (int i = off; i != finish; i++)
{
this.update(b[i]);
}
}
else
{
sig.update(b, off, len);
dig.update(b, off, len);
}
}
/**
* Return the one pass header associated with the current signature.
*
* @param isNested
* @return PGPOnePassSignature
* @throws PGPException
*/
public PGPOnePassSignature generateOnePassVersion(
boolean isNested)
throws PGPException
{
return new PGPOnePassSignature(new OnePassSignaturePacket(signatureType, hashAlgorithm, keyAlgorithm, privKey.getKeyID(), isNested));
}
/**
* Return a V3 signature object containing the current signature state.
*
* @return PGPSignature
* @throws PGPException
* @throws SignatureException
*/
public PGPSignature generate()
throws PGPException, SignatureException
{
long creationTime = new Date().getTime() / 1000;
ByteArrayOutputStream sOut = new ByteArrayOutputStream();
sOut.write(signatureType);
sOut.write((byte)(creationTime >> 24));
sOut.write((byte)(creationTime >> 16));
sOut.write((byte)(creationTime >> 8));
sOut.write((byte)creationTime);
byte[] hData = sOut.toByteArray();
sig.update(hData);
dig.update(hData);
MPInteger[] sigValues;
if (keyAlgorithm == PublicKeyAlgorithmTags.RSA_SIGN
|| keyAlgorithm == PublicKeyAlgorithmTags.RSA_GENERAL)
// an RSA signature
{
sigValues = new MPInteger[1];
sigValues[0] = new MPInteger(new BigInteger(1, sig.sign()));
}
else
{
sigValues = PGPUtil.dsaSigToMpi(sig.sign());
}
byte[] digest = dig.digest();
byte[] fingerPrint = new byte[2];
fingerPrint[0] = digest[0];
fingerPrint[1] = digest[1];
return new PGPSignature(new SignaturePacket(3, signatureType, privKey.getKeyID(), keyAlgorithm, hashAlgorithm, creationTime * 1000, fingerPrint, sigValues));
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy