146 lines
2.6 KiB
C#
146 lines
2.6 KiB
C#
using System;
|
|
using System.IO;
|
|
using Org.BouncyCastle.Crypto;
|
|
using Org.BouncyCastle.Security;
|
|
|
|
namespace Org.BouncyCastle.Bcpg.OpenPgp;
|
|
|
|
public class PgpOnePassSignature
|
|
{
|
|
private OnePassSignaturePacket sigPack;
|
|
|
|
private int signatureType;
|
|
|
|
private ISigner sig;
|
|
|
|
private byte lastb;
|
|
|
|
public long KeyId => sigPack.KeyId;
|
|
|
|
public int SignatureType => sigPack.SignatureType;
|
|
|
|
public HashAlgorithmTag HashAlgorithm => sigPack.HashAlgorithm;
|
|
|
|
public PublicKeyAlgorithmTag KeyAlgorithm => sigPack.KeyAlgorithm;
|
|
|
|
internal PgpOnePassSignature(BcpgInputStream bcpgInput)
|
|
: this((OnePassSignaturePacket)bcpgInput.ReadPacket())
|
|
{
|
|
}
|
|
|
|
internal PgpOnePassSignature(OnePassSignaturePacket sigPack)
|
|
{
|
|
this.sigPack = sigPack;
|
|
signatureType = sigPack.SignatureType;
|
|
}
|
|
|
|
public void InitVerify(PgpPublicKey pubKey)
|
|
{
|
|
lastb = 0;
|
|
try
|
|
{
|
|
sig = SignerUtilities.GetSigner(PgpUtilities.GetSignatureName(sigPack.KeyAlgorithm, sigPack.HashAlgorithm));
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
throw new PgpException("can't set up signature object.", exception);
|
|
}
|
|
try
|
|
{
|
|
sig.Init(forSigning: false, pubKey.GetKey());
|
|
}
|
|
catch (InvalidKeyException exception2)
|
|
{
|
|
throw new PgpException("invalid key.", exception2);
|
|
}
|
|
}
|
|
|
|
public void Update(byte b)
|
|
{
|
|
if (signatureType == 1)
|
|
{
|
|
doCanonicalUpdateByte(b);
|
|
}
|
|
else
|
|
{
|
|
sig.Update(b);
|
|
}
|
|
}
|
|
|
|
private void doCanonicalUpdateByte(byte b)
|
|
{
|
|
switch (b)
|
|
{
|
|
case 13:
|
|
doUpdateCRLF();
|
|
break;
|
|
case 10:
|
|
if (lastb != 13)
|
|
{
|
|
doUpdateCRLF();
|
|
}
|
|
break;
|
|
default:
|
|
sig.Update(b);
|
|
break;
|
|
}
|
|
lastb = b;
|
|
}
|
|
|
|
private void doUpdateCRLF()
|
|
{
|
|
sig.Update(13);
|
|
sig.Update(10);
|
|
}
|
|
|
|
public void Update(byte[] bytes)
|
|
{
|
|
if (signatureType == 1)
|
|
{
|
|
for (int i = 0; i != bytes.Length; i++)
|
|
{
|
|
doCanonicalUpdateByte(bytes[i]);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
sig.BlockUpdate(bytes, 0, bytes.Length);
|
|
}
|
|
}
|
|
|
|
public void Update(byte[] bytes, int off, int length)
|
|
{
|
|
if (signatureType == 1)
|
|
{
|
|
int num = off + length;
|
|
for (int i = off; i != num; i++)
|
|
{
|
|
doCanonicalUpdateByte(bytes[i]);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
sig.BlockUpdate(bytes, off, length);
|
|
}
|
|
}
|
|
|
|
public bool Verify(PgpSignature pgpSig)
|
|
{
|
|
byte[] signatureTrailer = pgpSig.GetSignatureTrailer();
|
|
sig.BlockUpdate(signatureTrailer, 0, signatureTrailer.Length);
|
|
return sig.VerifySignature(pgpSig.GetSignature());
|
|
}
|
|
|
|
public byte[] GetEncoded()
|
|
{
|
|
MemoryStream memoryStream = new MemoryStream();
|
|
Encode(memoryStream);
|
|
return memoryStream.ToArray();
|
|
}
|
|
|
|
public void Encode(Stream outStr)
|
|
{
|
|
BcpgOutputStream.Wrap(outStr).WritePacket(sigPack);
|
|
}
|
|
}
|