Initial Commit
This commit is contained in:
492
iTechSharp/srcbc/bcpg/ArmoredInputStream.cs
Normal file
492
iTechSharp/srcbc/bcpg/ArmoredInputStream.cs
Normal file
@@ -0,0 +1,492 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
using Org.BouncyCastle.Utilities.IO;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/**
|
||||
* reader for Base64 armored objects - read the headers and then start returning
|
||||
* bytes when the data is reached. An IOException is thrown if the CRC check
|
||||
* fails.
|
||||
*/
|
||||
public class ArmoredInputStream
|
||||
: BaseInputStream
|
||||
{
|
||||
/*
|
||||
* set up the decoding table.
|
||||
*/
|
||||
private readonly static byte[] decodingTable;
|
||||
static ArmoredInputStream()
|
||||
{
|
||||
decodingTable = new byte[128];
|
||||
for (int i = 'A'; i <= 'Z'; i++)
|
||||
{
|
||||
decodingTable[i] = (byte)(i - 'A');
|
||||
}
|
||||
for (int i = 'a'; i <= 'z'; i++)
|
||||
{
|
||||
decodingTable[i] = (byte)(i - 'a' + 26);
|
||||
}
|
||||
for (int i = '0'; i <= '9'; i++)
|
||||
{
|
||||
decodingTable[i] = (byte)(i - '0' + 52);
|
||||
}
|
||||
decodingTable['+'] = 62;
|
||||
decodingTable['/'] = 63;
|
||||
}
|
||||
|
||||
/**
|
||||
* decode the base 64 encoded input data.
|
||||
*
|
||||
* @return the offset the data starts in out.
|
||||
*/
|
||||
private int Decode(
|
||||
int in0,
|
||||
int in1,
|
||||
int in2,
|
||||
int in3,
|
||||
int[] result)
|
||||
{
|
||||
if (in3 < 0)
|
||||
{
|
||||
throw new EndOfStreamException("unexpected end of file in armored stream.");
|
||||
}
|
||||
|
||||
int b1, b2, b3, b4;
|
||||
if (in2 == '=')
|
||||
{
|
||||
b1 = decodingTable[in0] &0xff;
|
||||
b2 = decodingTable[in1] & 0xff;
|
||||
result[2] = ((b1 << 2) | (b2 >> 4)) & 0xff;
|
||||
return 2;
|
||||
}
|
||||
else if (in3 == '=')
|
||||
{
|
||||
b1 = decodingTable[in0];
|
||||
b2 = decodingTable[in1];
|
||||
b3 = decodingTable[in2];
|
||||
result[1] = ((b1 << 2) | (b2 >> 4)) & 0xff;
|
||||
result[2] = ((b2 << 4) | (b3 >> 2)) & 0xff;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
b1 = decodingTable[in0];
|
||||
b2 = decodingTable[in1];
|
||||
b3 = decodingTable[in2];
|
||||
b4 = decodingTable[in3];
|
||||
result[0] = ((b1 << 2) | (b2 >> 4)) & 0xff;
|
||||
result[1] = ((b2 << 4) | (b3 >> 2)) & 0xff;
|
||||
result[2] = ((b3 << 6) | b4) & 0xff;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Stream input;
|
||||
bool start = true;
|
||||
int[] outBuf = new int[3];
|
||||
int bufPtr = 3;
|
||||
Crc24 crc = new Crc24();
|
||||
bool crcFound = false;
|
||||
bool hasHeaders = true;
|
||||
string header = null;
|
||||
bool newLineFound = false;
|
||||
bool clearText = false;
|
||||
bool restart = false;
|
||||
ArrayList headerList= new ArrayList();
|
||||
int lastC = 0;
|
||||
|
||||
/**
|
||||
* Create a stream for reading a PGP armoured message, parsing up to a header
|
||||
* and then reading the data that follows.
|
||||
*
|
||||
* @param input
|
||||
*/
|
||||
public ArmoredInputStream(
|
||||
Stream input)
|
||||
: this(input, true)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an armoured input stream which will assume the data starts
|
||||
* straight away, or parse for headers first depending on the value of
|
||||
* hasHeaders.
|
||||
*
|
||||
* @param input
|
||||
* @param hasHeaders true if headers are to be looked for, false otherwise.
|
||||
*/
|
||||
public ArmoredInputStream(
|
||||
Stream input,
|
||||
bool hasHeaders)
|
||||
{
|
||||
this.input = input;
|
||||
this.hasHeaders = hasHeaders;
|
||||
|
||||
if (hasHeaders)
|
||||
{
|
||||
ParseHeaders();
|
||||
}
|
||||
|
||||
start = false;
|
||||
}
|
||||
|
||||
private bool ParseHeaders()
|
||||
{
|
||||
header = null;
|
||||
|
||||
int c;
|
||||
int last = 0;
|
||||
bool headerFound = false;
|
||||
|
||||
headerList = new ArrayList();
|
||||
|
||||
//
|
||||
// if restart we already have a header
|
||||
//
|
||||
if (restart)
|
||||
{
|
||||
headerFound = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
while ((c = input.ReadByte()) >= 0)
|
||||
{
|
||||
if (c == '-' && (last == 0 || last == '\n' || last == '\r'))
|
||||
{
|
||||
headerFound = true;
|
||||
break;
|
||||
}
|
||||
|
||||
last = c;
|
||||
}
|
||||
}
|
||||
|
||||
if (headerFound)
|
||||
{
|
||||
StringBuilder Buffer = new StringBuilder("-");
|
||||
bool eolReached = false;
|
||||
bool crLf = false;
|
||||
|
||||
if (restart) // we've had to look ahead two '-'
|
||||
{
|
||||
Buffer.Append('-');
|
||||
}
|
||||
|
||||
while ((c = input.ReadByte()) >= 0)
|
||||
{
|
||||
if (last == '\r' && c == '\n')
|
||||
{
|
||||
crLf = true;
|
||||
}
|
||||
if (eolReached && (last != '\r' && c == '\n'))
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (eolReached && c == '\r')
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (c == '\r' || (last != '\r' && c == '\n'))
|
||||
{
|
||||
string line = Buffer.ToString();
|
||||
if (line.Trim().Length < 1)
|
||||
break;
|
||||
headerList.Add(line);
|
||||
Buffer.Length = 0;
|
||||
}
|
||||
|
||||
if (c != '\n' && c != '\r')
|
||||
{
|
||||
Buffer.Append((char)c);
|
||||
eolReached = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (c == '\r' || (last != '\r' && c == '\n'))
|
||||
{
|
||||
eolReached = true;
|
||||
}
|
||||
}
|
||||
|
||||
last = c;
|
||||
}
|
||||
|
||||
if (crLf)
|
||||
{
|
||||
input.ReadByte(); // skip last \n
|
||||
}
|
||||
}
|
||||
|
||||
if (headerList.Count > 0)
|
||||
{
|
||||
header = (string) headerList[0];
|
||||
}
|
||||
|
||||
clearText = "-----BEGIN PGP SIGNED MESSAGE-----".Equals(header);
|
||||
newLineFound = true;
|
||||
|
||||
return headerFound;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if we are inside the clear text section of a PGP
|
||||
* signed message.
|
||||
*/
|
||||
public bool IsClearText()
|
||||
{
|
||||
return clearText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the armor header line (if there is one)
|
||||
* @return the armor header line, null if none present.
|
||||
*/
|
||||
public string GetArmorHeaderLine()
|
||||
{
|
||||
return header;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the armor headers (the lines after the armor header line),
|
||||
* @return an array of armor headers, null if there aren't any.
|
||||
*/
|
||||
public string[] GetArmorHeaders()
|
||||
{
|
||||
if (headerList.Count <= 1)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
string[] hdrs = new string[headerList.Count - 1];
|
||||
for (int i = 0; i != hdrs.Length; i++)
|
||||
{
|
||||
hdrs[i] = (string) headerList[i + 1];
|
||||
}
|
||||
|
||||
return hdrs;
|
||||
}
|
||||
|
||||
private int ReadIgnoreSpace()
|
||||
{
|
||||
int c;
|
||||
do
|
||||
{
|
||||
c = input.ReadByte();
|
||||
}
|
||||
while (c == ' ' || c == '\t');
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
private int ReadIgnoreWhitespace()
|
||||
{
|
||||
int c;
|
||||
do
|
||||
{
|
||||
c = input.ReadByte();
|
||||
}
|
||||
while (c == ' ' || c == '\t' || c == '\r' || c == '\n');
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
private int ReadByteClearText()
|
||||
{
|
||||
int c = input.ReadByte();
|
||||
|
||||
if (c == '\r' || (c == '\n' && lastC != '\r'))
|
||||
{
|
||||
newLineFound = true;
|
||||
}
|
||||
else if (newLineFound && c == '-')
|
||||
{
|
||||
c = input.ReadByte();
|
||||
if (c == '-') // a header, not dash escaped
|
||||
{
|
||||
clearText = false;
|
||||
start = true;
|
||||
restart = true;
|
||||
}
|
||||
else // a space - must be a dash escape
|
||||
{
|
||||
c = input.ReadByte();
|
||||
}
|
||||
newLineFound = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (c != '\n' && lastC != '\r')
|
||||
{
|
||||
newLineFound = false;
|
||||
}
|
||||
}
|
||||
|
||||
lastC = c;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
private int ReadClearText(byte[] buffer, int offset, int count)
|
||||
{
|
||||
int pos = offset;
|
||||
try
|
||||
{
|
||||
int end = offset + count;
|
||||
while (pos < end)
|
||||
{
|
||||
int c = ReadByteClearText();
|
||||
if (c == -1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
buffer[pos++] = (byte) c;
|
||||
}
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
if (pos == offset) throw ioe;
|
||||
}
|
||||
|
||||
return pos - offset;
|
||||
}
|
||||
|
||||
private int DoReadByte()
|
||||
{
|
||||
if (bufPtr > 2 || crcFound)
|
||||
{
|
||||
int c = ReadIgnoreSpace();
|
||||
if (c == '\n' || c == '\r')
|
||||
{
|
||||
c = ReadIgnoreWhitespace();
|
||||
if (c == '=') // crc reached
|
||||
{
|
||||
bufPtr = Decode(ReadIgnoreSpace(), ReadIgnoreSpace(), ReadIgnoreSpace(), ReadIgnoreSpace(), outBuf);
|
||||
|
||||
if (bufPtr != 0)
|
||||
{
|
||||
throw new IOException("no crc found in armored message.");
|
||||
}
|
||||
|
||||
crcFound = true;
|
||||
|
||||
int i = ((outBuf[0] & 0xff) << 16)
|
||||
| ((outBuf[1] & 0xff) << 8)
|
||||
| (outBuf[2] & 0xff);
|
||||
|
||||
if (i != crc.Value)
|
||||
{
|
||||
throw new IOException("crc check failed in armored message.");
|
||||
}
|
||||
|
||||
return ReadByte();
|
||||
}
|
||||
|
||||
if (c == '-') // end of record reached
|
||||
{
|
||||
while ((c = input.ReadByte()) >= 0)
|
||||
{
|
||||
if (c == '\n' || c == '\r')
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!crcFound)
|
||||
{
|
||||
throw new IOException("crc check not found.");
|
||||
}
|
||||
|
||||
crcFound = false;
|
||||
start = true;
|
||||
bufPtr = 3;
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (c < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
bufPtr = Decode(c, ReadIgnoreSpace(), ReadIgnoreSpace(), ReadIgnoreSpace(), outBuf);
|
||||
}
|
||||
|
||||
return outBuf[bufPtr++];
|
||||
}
|
||||
|
||||
public override int ReadByte()
|
||||
{
|
||||
if (start)
|
||||
{
|
||||
if (hasHeaders)
|
||||
{
|
||||
ParseHeaders();
|
||||
}
|
||||
|
||||
crc.Reset();
|
||||
start = false;
|
||||
}
|
||||
|
||||
if (clearText)
|
||||
{
|
||||
return ReadByteClearText();
|
||||
}
|
||||
|
||||
int c = DoReadByte();
|
||||
|
||||
crc.Update(c);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
if (start && count > 0)
|
||||
{
|
||||
if (hasHeaders)
|
||||
{
|
||||
ParseHeaders();
|
||||
}
|
||||
start = false;
|
||||
}
|
||||
|
||||
if (clearText)
|
||||
{
|
||||
return ReadClearText(buffer, offset, count);
|
||||
}
|
||||
|
||||
int pos = offset;
|
||||
try
|
||||
{
|
||||
int end = offset + count;
|
||||
while (pos < end)
|
||||
{
|
||||
int c = DoReadByte();
|
||||
crc.Update(c);
|
||||
if (c == -1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
buffer[pos++] = (byte) c;
|
||||
}
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
if (pos == offset) throw ioe;
|
||||
}
|
||||
|
||||
return pos - offset;
|
||||
}
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
input.Close();
|
||||
base.Close();
|
||||
}
|
||||
}
|
||||
}
|
328
iTechSharp/srcbc/bcpg/ArmoredOutputStream.cs
Normal file
328
iTechSharp/srcbc/bcpg/ArmoredOutputStream.cs
Normal file
@@ -0,0 +1,328 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.Utilities.IO;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/**
|
||||
* Basic output stream.
|
||||
*/
|
||||
public class ArmoredOutputStream
|
||||
: BaseOutputStream
|
||||
{
|
||||
private static readonly byte[] encodingTable =
|
||||
{
|
||||
(byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G',
|
||||
(byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N',
|
||||
(byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U',
|
||||
(byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z',
|
||||
(byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g',
|
||||
(byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n',
|
||||
(byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u',
|
||||
(byte)'v',
|
||||
(byte)'w', (byte)'x', (byte)'y', (byte)'z',
|
||||
(byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6',
|
||||
(byte)'7', (byte)'8', (byte)'9',
|
||||
(byte)'+', (byte)'/'
|
||||
};
|
||||
|
||||
/**
|
||||
* encode the input data producing a base 64 encoded byte array.
|
||||
*/
|
||||
private static void Encode(
|
||||
Stream outStream,
|
||||
int[] data,
|
||||
int len)
|
||||
{
|
||||
Debug.Assert(len > 0);
|
||||
Debug.Assert(len < 4);
|
||||
|
||||
byte[] bs = new byte[4];
|
||||
int d1 = data[0];
|
||||
bs[0] = encodingTable[(d1 >> 2) & 0x3f];
|
||||
|
||||
switch (len)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
bs[1] = encodingTable[(d1 << 4) & 0x3f];
|
||||
bs[2] = (byte)'=';
|
||||
bs[3] = (byte)'=';
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
int d2 = data[1];
|
||||
bs[1] = encodingTable[((d1 << 4) | (d2 >> 4)) & 0x3f];
|
||||
bs[2] = encodingTable[(d2 << 2) & 0x3f];
|
||||
bs[3] = (byte)'=';
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
int d2 = data[1];
|
||||
int d3 = data[2];
|
||||
bs[1] = encodingTable[((d1 << 4) | (d2 >> 4)) & 0x3f];
|
||||
bs[2] = encodingTable[((d2 << 2) | (d3 >> 6)) & 0x3f];
|
||||
bs[3] = encodingTable[d3 & 0x3f];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
outStream.Write(bs, 0, bs.Length);
|
||||
}
|
||||
|
||||
private readonly Stream outStream;
|
||||
private int[] buf = new int[3];
|
||||
private int bufPtr = 0;
|
||||
private Crc24 crc = new Crc24();
|
||||
private int chunkCount = 0;
|
||||
private int lastb;
|
||||
|
||||
private bool start = true;
|
||||
private bool clearText = false;
|
||||
private bool newLine = false;
|
||||
|
||||
private string nl = Platform.NewLine;
|
||||
|
||||
private string type;
|
||||
private string headerStart = "-----BEGIN PGP ";
|
||||
private string headerTail = "-----";
|
||||
private string footerStart = "-----END PGP ";
|
||||
private string footerTail = "-----";
|
||||
|
||||
private string version = "BCPG v1.32";
|
||||
|
||||
private readonly IDictionary headers;
|
||||
|
||||
public ArmoredOutputStream(Stream outStream)
|
||||
{
|
||||
this.outStream = outStream;
|
||||
this.headers = new Hashtable();
|
||||
this.headers["Version"] = version;
|
||||
}
|
||||
|
||||
public ArmoredOutputStream(Stream outStream, IDictionary headers)
|
||||
{
|
||||
this.outStream = outStream;
|
||||
this.headers = new Hashtable(headers);
|
||||
this.headers["Version"] = version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an additional header entry.
|
||||
*
|
||||
* @param name the name of the header entry.
|
||||
* @param v the value of the header entry.
|
||||
*/
|
||||
public void SetHeader(
|
||||
string name,
|
||||
string v)
|
||||
{
|
||||
headers[name] = v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the headers to only contain a Version string.
|
||||
*/
|
||||
public void ResetHeaders()
|
||||
{
|
||||
headers.Clear();
|
||||
headers["Version"] = version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a clear text signed message.
|
||||
* @param hashAlgorithm
|
||||
*/
|
||||
public void BeginClearText(
|
||||
HashAlgorithmTag hashAlgorithm)
|
||||
{
|
||||
string hash;
|
||||
|
||||
switch (hashAlgorithm)
|
||||
{
|
||||
case HashAlgorithmTag.Sha1:
|
||||
hash = "SHA1";
|
||||
break;
|
||||
case HashAlgorithmTag.Sha256:
|
||||
hash = "SHA256";
|
||||
break;
|
||||
case HashAlgorithmTag.Sha384:
|
||||
hash = "SHA384";
|
||||
break;
|
||||
case HashAlgorithmTag.Sha512:
|
||||
hash = "SHA512";
|
||||
break;
|
||||
case HashAlgorithmTag.MD2:
|
||||
hash = "MD2";
|
||||
break;
|
||||
case HashAlgorithmTag.MD5:
|
||||
hash = "MD5";
|
||||
break;
|
||||
case HashAlgorithmTag.RipeMD160:
|
||||
hash = "RIPEMD160";
|
||||
break;
|
||||
default:
|
||||
throw new IOException("unknown hash algorithm tag in beginClearText: " + hashAlgorithm);
|
||||
}
|
||||
|
||||
DoWrite("-----BEGIN PGP SIGNED MESSAGE-----" + nl);
|
||||
DoWrite("Hash: " + hash + nl + nl);
|
||||
|
||||
clearText = true;
|
||||
newLine = true;
|
||||
lastb = 0;
|
||||
}
|
||||
|
||||
public void EndClearText()
|
||||
{
|
||||
clearText = false;
|
||||
}
|
||||
|
||||
public override void WriteByte(
|
||||
byte b)
|
||||
{
|
||||
if (clearText)
|
||||
{
|
||||
outStream.WriteByte(b);
|
||||
|
||||
if (newLine)
|
||||
{
|
||||
if (!(b == '\n' && lastb == '\r'))
|
||||
{
|
||||
newLine = false;
|
||||
}
|
||||
if (b == '-')
|
||||
{
|
||||
outStream.WriteByte((byte)' ');
|
||||
outStream.WriteByte((byte)'-'); // dash escape
|
||||
}
|
||||
}
|
||||
if (b == '\r' || (b == '\n' && lastb != '\r'))
|
||||
{
|
||||
newLine = true;
|
||||
}
|
||||
lastb = b;
|
||||
return;
|
||||
}
|
||||
|
||||
if (start)
|
||||
{
|
||||
bool newPacket = (b & 0x40) != 0;
|
||||
|
||||
int tag;
|
||||
if (newPacket)
|
||||
{
|
||||
tag = b & 0x3f;
|
||||
}
|
||||
else
|
||||
{
|
||||
tag = (b & 0x3f) >> 2;
|
||||
}
|
||||
|
||||
switch ((PacketTag)tag)
|
||||
{
|
||||
case PacketTag.PublicKey:
|
||||
type = "PUBLIC KEY BLOCK";
|
||||
break;
|
||||
case PacketTag.SecretKey:
|
||||
type = "PRIVATE KEY BLOCK";
|
||||
break;
|
||||
case PacketTag.Signature:
|
||||
type = "SIGNATURE";
|
||||
break;
|
||||
default:
|
||||
type = "MESSAGE";
|
||||
break;
|
||||
}
|
||||
|
||||
DoWrite(headerStart + type + headerTail + nl);
|
||||
WriteHeaderEntry("Version", (string) headers["Version"]);
|
||||
|
||||
foreach (DictionaryEntry de in headers)
|
||||
{
|
||||
string k = (string) de.Key;
|
||||
if (k != "Version")
|
||||
{
|
||||
string v = (string) de.Value;
|
||||
WriteHeaderEntry(k, v);
|
||||
}
|
||||
}
|
||||
|
||||
DoWrite(nl);
|
||||
|
||||
start = false;
|
||||
}
|
||||
|
||||
if (bufPtr == 3)
|
||||
{
|
||||
Encode(outStream, buf, bufPtr);
|
||||
bufPtr = 0;
|
||||
if ((++chunkCount & 0xf) == 0)
|
||||
{
|
||||
DoWrite(nl);
|
||||
}
|
||||
}
|
||||
|
||||
crc.Update(b);
|
||||
buf[bufPtr++] = b & 0xff;
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>Note</b>: close does nor close the underlying stream. So it is possible to write
|
||||
* multiple objects using armoring to a single stream.
|
||||
*/
|
||||
public override void Close()
|
||||
{
|
||||
if (type != null)
|
||||
{
|
||||
if (bufPtr > 0)
|
||||
{
|
||||
Encode(outStream, buf, bufPtr);
|
||||
}
|
||||
|
||||
DoWrite(nl + '=');
|
||||
|
||||
int crcV = crc.Value;
|
||||
|
||||
buf[0] = ((crcV >> 16) & 0xff);
|
||||
buf[1] = ((crcV >> 8) & 0xff);
|
||||
buf[2] = (crcV & 0xff);
|
||||
|
||||
Encode(outStream, buf, 3);
|
||||
|
||||
DoWrite(nl);
|
||||
DoWrite(footerStart);
|
||||
DoWrite(type);
|
||||
DoWrite(footerTail);
|
||||
DoWrite(nl);
|
||||
|
||||
outStream.Flush();
|
||||
|
||||
type = null;
|
||||
start = true;
|
||||
base.Close();
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteHeaderEntry(
|
||||
string name,
|
||||
string v)
|
||||
{
|
||||
DoWrite(name + ": " + v + nl);
|
||||
}
|
||||
|
||||
private void DoWrite(
|
||||
string s)
|
||||
{
|
||||
byte[] bs = Encoding.ASCII.GetBytes(s);
|
||||
outStream.Write(bs, 0, bs.Length);
|
||||
}
|
||||
}
|
||||
}
|
355
iTechSharp/srcbc/bcpg/BcpgInputStream.cs
Normal file
355
iTechSharp/srcbc/bcpg/BcpgInputStream.cs
Normal file
@@ -0,0 +1,355 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Utilities.IO;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/// <remarks>Reader for PGP objects.</remarks>
|
||||
public class BcpgInputStream
|
||||
: BaseInputStream
|
||||
{
|
||||
private Stream m_in;
|
||||
private bool next = false;
|
||||
private int nextB;
|
||||
|
||||
internal static BcpgInputStream Wrap(
|
||||
Stream inStr)
|
||||
{
|
||||
if (inStr is BcpgInputStream)
|
||||
{
|
||||
return (BcpgInputStream) inStr;
|
||||
}
|
||||
|
||||
return new BcpgInputStream(inStr);
|
||||
}
|
||||
|
||||
private BcpgInputStream(
|
||||
Stream inputStream)
|
||||
{
|
||||
this.m_in = inputStream;
|
||||
}
|
||||
|
||||
public override int ReadByte()
|
||||
{
|
||||
if (next)
|
||||
{
|
||||
next = false;
|
||||
return nextB;
|
||||
}
|
||||
|
||||
return m_in.ReadByte();
|
||||
}
|
||||
|
||||
public override int Read(
|
||||
byte[] buffer,
|
||||
int offset,
|
||||
int count)
|
||||
{
|
||||
// Strangely, when count == 0, we should still attempt to read a byte
|
||||
// if (count == 0)
|
||||
// return 0;
|
||||
|
||||
if (!next)
|
||||
return m_in.Read(buffer, offset, count);
|
||||
|
||||
// We have next byte waiting, so return it
|
||||
|
||||
if (nextB < 0)
|
||||
return 0; // EndOfStream
|
||||
|
||||
if (buffer == null)
|
||||
throw new ArgumentNullException("buffer");
|
||||
|
||||
buffer[offset] = (byte) nextB;
|
||||
next = false;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
public byte[] ReadAll()
|
||||
{
|
||||
return Streams.ReadAll(this);
|
||||
}
|
||||
|
||||
public void ReadFully(
|
||||
byte[] buffer,
|
||||
int off,
|
||||
int len)
|
||||
{
|
||||
if (Streams.ReadFully(this, buffer, off, len) < len)
|
||||
throw new EndOfStreamException();
|
||||
}
|
||||
|
||||
public void ReadFully(
|
||||
byte[] buffer)
|
||||
{
|
||||
ReadFully(buffer, 0, buffer.Length);
|
||||
}
|
||||
|
||||
/// <summary>Returns the next packet tag in the stream.</summary>
|
||||
public PacketTag NextPacketTag()
|
||||
{
|
||||
if (!next)
|
||||
{
|
||||
try
|
||||
{
|
||||
nextB = m_in.ReadByte();
|
||||
}
|
||||
catch (EndOfStreamException)
|
||||
{
|
||||
nextB = -1;
|
||||
}
|
||||
|
||||
next = true;
|
||||
}
|
||||
|
||||
if (nextB >= 0)
|
||||
{
|
||||
if ((nextB & 0x40) != 0) // new
|
||||
{
|
||||
return (PacketTag)(nextB & 0x3f);
|
||||
}
|
||||
else // old
|
||||
{
|
||||
return (PacketTag)((nextB & 0x3f) >> 2);
|
||||
}
|
||||
}
|
||||
|
||||
return (PacketTag) nextB;
|
||||
}
|
||||
|
||||
public Packet ReadPacket()
|
||||
{
|
||||
int hdr = this.ReadByte();
|
||||
|
||||
if (hdr < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if ((hdr & 0x80) == 0)
|
||||
{
|
||||
throw new IOException("invalid header encountered");
|
||||
}
|
||||
|
||||
bool newPacket = (hdr & 0x40) != 0;
|
||||
PacketTag tag = 0;
|
||||
int bodyLen = 0;
|
||||
bool partial = false;
|
||||
|
||||
if (newPacket)
|
||||
{
|
||||
tag = (PacketTag)(hdr & 0x3f);
|
||||
|
||||
int l = this.ReadByte();
|
||||
|
||||
if (l < 192)
|
||||
{
|
||||
bodyLen = l;
|
||||
}
|
||||
else if (l <= 223)
|
||||
{
|
||||
int b = m_in.ReadByte();
|
||||
bodyLen = ((l - 192) << 8) + (b) + 192;
|
||||
}
|
||||
else if (l == 255)
|
||||
{
|
||||
bodyLen = (m_in.ReadByte() << 24) | (m_in.ReadByte() << 16)
|
||||
| (m_in.ReadByte() << 8) | m_in.ReadByte();
|
||||
}
|
||||
else
|
||||
{
|
||||
partial = true;
|
||||
bodyLen = 1 << (l & 0x1f);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int lengthType = hdr & 0x3;
|
||||
|
||||
tag = (PacketTag)((hdr & 0x3f) >> 2);
|
||||
|
||||
switch (lengthType)
|
||||
{
|
||||
case 0:
|
||||
bodyLen = this.ReadByte();
|
||||
break;
|
||||
case 1:
|
||||
bodyLen = (this.ReadByte() << 8) | this.ReadByte();
|
||||
break;
|
||||
case 2:
|
||||
bodyLen = (this.ReadByte() << 24) | (this.ReadByte() << 16)
|
||||
| (this.ReadByte() << 8) | this.ReadByte();
|
||||
break;
|
||||
case 3:
|
||||
partial = true;
|
||||
break;
|
||||
default:
|
||||
throw new IOException("unknown length type encountered");
|
||||
}
|
||||
}
|
||||
|
||||
BcpgInputStream objStream;
|
||||
if (bodyLen == 0 && partial)
|
||||
{
|
||||
objStream = this;
|
||||
}
|
||||
else
|
||||
{
|
||||
PartialInputStream pis = new PartialInputStream(this, partial, bodyLen);
|
||||
objStream = new BcpgInputStream(pis);
|
||||
}
|
||||
|
||||
switch (tag)
|
||||
{
|
||||
case PacketTag.Reserved:
|
||||
return new InputStreamPacket(objStream);
|
||||
case PacketTag.PublicKeyEncryptedSession:
|
||||
return new PublicKeyEncSessionPacket(objStream);
|
||||
case PacketTag.Signature:
|
||||
return new SignaturePacket(objStream);
|
||||
case PacketTag.SymmetricKeyEncryptedSessionKey:
|
||||
return new SymmetricKeyEncSessionPacket(objStream);
|
||||
case PacketTag.OnePassSignature:
|
||||
return new OnePassSignaturePacket(objStream);
|
||||
case PacketTag.SecretKey:
|
||||
return new SecretKeyPacket(objStream);
|
||||
case PacketTag.PublicKey:
|
||||
return new PublicKeyPacket(objStream);
|
||||
case PacketTag.SecretSubkey:
|
||||
return new SecretSubkeyPacket(objStream);
|
||||
case PacketTag.CompressedData:
|
||||
return new CompressedDataPacket(objStream);
|
||||
case PacketTag.SymmetricKeyEncrypted:
|
||||
return new SymmetricEncDataPacket(objStream);
|
||||
case PacketTag.Marker:
|
||||
return new MarkerPacket(objStream);
|
||||
case PacketTag.LiteralData:
|
||||
return new LiteralDataPacket(objStream);
|
||||
case PacketTag.Trust:
|
||||
return new TrustPacket(objStream);
|
||||
case PacketTag.UserId:
|
||||
return new UserIdPacket(objStream);
|
||||
case PacketTag.UserAttribute:
|
||||
return new UserAttributePacket(objStream);
|
||||
case PacketTag.PublicSubkey:
|
||||
return new PublicSubkeyPacket(objStream);
|
||||
case PacketTag.SymmetricEncryptedIntegrityProtected:
|
||||
return new SymmetricEncIntegrityPacket(objStream);
|
||||
case PacketTag.ModificationDetectionCode:
|
||||
return new ModDetectionCodePacket(objStream);
|
||||
case PacketTag.Experimental1:
|
||||
case PacketTag.Experimental2:
|
||||
case PacketTag.Experimental3:
|
||||
case PacketTag.Experimental4:
|
||||
return new ExperimentalPacket(tag, objStream);
|
||||
default:
|
||||
throw new IOException("unknown packet type encountered: " + tag);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
m_in.Close();
|
||||
base.Close();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A stream that overlays our input stream, allowing the user to only read a segment of it.
|
||||
/// NB: dataLength will be negative if the segment length is in the upper range above 2**31.
|
||||
/// </summary>
|
||||
private class PartialInputStream
|
||||
: BaseInputStream
|
||||
{
|
||||
private BcpgInputStream m_in;
|
||||
private bool partial;
|
||||
private int dataLength;
|
||||
|
||||
internal PartialInputStream(
|
||||
BcpgInputStream bcpgIn,
|
||||
bool partial,
|
||||
int dataLength)
|
||||
{
|
||||
this.m_in = bcpgIn;
|
||||
this.partial = partial;
|
||||
this.dataLength = dataLength;
|
||||
}
|
||||
|
||||
public override int ReadByte()
|
||||
{
|
||||
do
|
||||
{
|
||||
if (dataLength != 0)
|
||||
{
|
||||
int ch = m_in.ReadByte();
|
||||
if (ch < 0)
|
||||
{
|
||||
throw new EndOfStreamException("Premature end of stream in PartialInputStream");
|
||||
}
|
||||
dataLength--;
|
||||
return ch;
|
||||
}
|
||||
}
|
||||
while (partial && ReadPartialDataLength() >= 0);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (dataLength != 0)
|
||||
{
|
||||
int readLen = (dataLength > count || dataLength < 0) ? count : dataLength;
|
||||
int len = m_in.Read(buffer, offset, readLen);
|
||||
if (len < 1)
|
||||
{
|
||||
throw new EndOfStreamException("Premature end of stream in PartialInputStream");
|
||||
}
|
||||
dataLength -= len;
|
||||
return len;
|
||||
}
|
||||
}
|
||||
while (partial && ReadPartialDataLength() >= 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int ReadPartialDataLength()
|
||||
{
|
||||
int l = m_in.ReadByte();
|
||||
|
||||
if (l < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
partial = false;
|
||||
|
||||
if (l < 192)
|
||||
{
|
||||
dataLength = l;
|
||||
}
|
||||
else if (l <= 223)
|
||||
{
|
||||
dataLength = ((l - 192) << 8) + (m_in.ReadByte()) + 192;
|
||||
}
|
||||
else if (l == 255)
|
||||
{
|
||||
dataLength = (m_in.ReadByte() << 24) | (m_in.ReadByte() << 16)
|
||||
| (m_in.ReadByte() << 8) | m_in.ReadByte();
|
||||
}
|
||||
else
|
||||
{
|
||||
partial = true;
|
||||
dataLength = 1 << (l & 0x1f);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
22
iTechSharp/srcbc/bcpg/BcpgObject.cs
Normal file
22
iTechSharp/srcbc/bcpg/BcpgObject.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/// <remarks>Base class for a PGP object.</remarks>
|
||||
public abstract class BcpgObject
|
||||
{
|
||||
public virtual byte[] GetEncoded()
|
||||
{
|
||||
MemoryStream bOut = new MemoryStream();
|
||||
BcpgOutputStream pOut = new BcpgOutputStream(bOut);
|
||||
|
||||
pOut.WriteObject(this);
|
||||
|
||||
return bOut.ToArray();
|
||||
}
|
||||
|
||||
public abstract void Encode(BcpgOutputStream bcpgOut);
|
||||
}
|
||||
}
|
||||
|
390
iTechSharp/srcbc/bcpg/BcpgOutputStream.cs
Normal file
390
iTechSharp/srcbc/bcpg/BcpgOutputStream.cs
Normal file
@@ -0,0 +1,390 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
using Org.BouncyCastle.Utilities.IO;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/// <remarks>Basic output stream.</remarks>
|
||||
public class BcpgOutputStream
|
||||
: BaseOutputStream
|
||||
{
|
||||
internal static BcpgOutputStream Wrap(
|
||||
Stream outStr)
|
||||
{
|
||||
if (outStr is BcpgOutputStream)
|
||||
{
|
||||
return (BcpgOutputStream) outStr;
|
||||
}
|
||||
|
||||
return new BcpgOutputStream(outStr);
|
||||
}
|
||||
|
||||
private Stream outStr;
|
||||
private byte[] partialBuffer;
|
||||
private int partialBufferLength;
|
||||
private int partialPower;
|
||||
private int partialOffset;
|
||||
private const int BufferSizePower = 16; // 2^16 size buffer on long files
|
||||
|
||||
/// <summary>Create a stream representing a general packet.</summary>
|
||||
/// <param name="outStr">Output stream to write to.</param>
|
||||
public BcpgOutputStream(
|
||||
Stream outStr)
|
||||
{
|
||||
if (outStr == null)
|
||||
throw new ArgumentNullException("outStr");
|
||||
|
||||
this.outStr = outStr;
|
||||
}
|
||||
|
||||
/// <summary>Create a stream representing an old style partial object.</summary>
|
||||
/// <param name="outStr">Output stream to write to.</param>
|
||||
/// <param name="tag">The packet tag for the object.</param>
|
||||
public BcpgOutputStream(
|
||||
Stream outStr,
|
||||
PacketTag tag)
|
||||
{
|
||||
if (outStr == null)
|
||||
throw new ArgumentNullException("outStr");
|
||||
|
||||
this.outStr = outStr;
|
||||
this.WriteHeader(tag, true, true, 0);
|
||||
}
|
||||
|
||||
/// <summary>Create a stream representing a general packet.</summary>
|
||||
/// <param name="outStr">Output stream to write to.</param>
|
||||
/// <param name="tag">Packet tag.</param>
|
||||
/// <param name="length">Size of chunks making up the packet.</param>
|
||||
/// <param name="oldFormat">If true, the header is written out in old format.</param>
|
||||
public BcpgOutputStream(
|
||||
Stream outStr,
|
||||
PacketTag tag,
|
||||
long length,
|
||||
bool oldFormat)
|
||||
{
|
||||
if (outStr == null)
|
||||
throw new ArgumentNullException("outStr");
|
||||
|
||||
this.outStr = outStr;
|
||||
|
||||
if (length > 0xFFFFFFFFL)
|
||||
{
|
||||
this.WriteHeader(tag, false, true, 0);
|
||||
this.partialBufferLength = 1 << BufferSizePower;
|
||||
this.partialBuffer = new byte[partialBufferLength];
|
||||
this.partialPower = BufferSizePower;
|
||||
this.partialOffset = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.WriteHeader(tag, oldFormat, false, length);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Create a new style partial input stream buffered into chunks.</summary>
|
||||
/// <param name="outStr">Output stream to write to.</param>
|
||||
/// <param name="tag">Packet tag.</param>
|
||||
/// <param name="length">Size of chunks making up the packet.</param>
|
||||
public BcpgOutputStream(
|
||||
Stream outStr,
|
||||
PacketTag tag,
|
||||
long length)
|
||||
{
|
||||
if (outStr == null)
|
||||
throw new ArgumentNullException("outStr");
|
||||
|
||||
this.outStr = outStr;
|
||||
this.WriteHeader(tag, false, false, length);
|
||||
}
|
||||
|
||||
/// <summary>Create a new style partial input stream buffered into chunks.</summary>
|
||||
/// <param name="outStr">Output stream to write to.</param>
|
||||
/// <param name="tag">Packet tag.</param>
|
||||
/// <param name="buffer">Buffer to use for collecting chunks.</param>
|
||||
public BcpgOutputStream(
|
||||
Stream outStr,
|
||||
PacketTag tag,
|
||||
byte[] buffer)
|
||||
{
|
||||
if (outStr == null)
|
||||
throw new ArgumentNullException("outStr");
|
||||
|
||||
this.outStr = outStr;
|
||||
this.WriteHeader(tag, false, true, 0);
|
||||
|
||||
this.partialBuffer = buffer;
|
||||
|
||||
uint length = (uint) partialBuffer.Length;
|
||||
for (partialPower = 0; length != 1; partialPower++)
|
||||
{
|
||||
length >>= 1;
|
||||
}
|
||||
|
||||
if (partialPower > 30)
|
||||
{
|
||||
throw new IOException("Buffer cannot be greater than 2^30 in length.");
|
||||
}
|
||||
this.partialBufferLength = 1 << partialPower;
|
||||
this.partialOffset = 0;
|
||||
}
|
||||
|
||||
private void WriteNewPacketLength(
|
||||
long bodyLen)
|
||||
{
|
||||
if (bodyLen < 192)
|
||||
{
|
||||
outStr.WriteByte((byte)bodyLen);
|
||||
}
|
||||
else if (bodyLen <= 8383)
|
||||
{
|
||||
bodyLen -= 192;
|
||||
|
||||
outStr.WriteByte((byte)(((bodyLen >> 8) & 0xff) + 192));
|
||||
outStr.WriteByte((byte)bodyLen);
|
||||
}
|
||||
else
|
||||
{
|
||||
outStr.WriteByte(0xff);
|
||||
outStr.WriteByte((byte)(bodyLen >> 24));
|
||||
outStr.WriteByte((byte)(bodyLen >> 16));
|
||||
outStr.WriteByte((byte)(bodyLen >> 8));
|
||||
outStr.WriteByte((byte)bodyLen);
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteHeader(
|
||||
PacketTag tag,
|
||||
bool oldPackets,
|
||||
bool partial,
|
||||
long bodyLen)
|
||||
{
|
||||
int hdr = 0x80;
|
||||
|
||||
if (partialBuffer != null)
|
||||
{
|
||||
PartialFlush(true);
|
||||
partialBuffer = null;
|
||||
}
|
||||
|
||||
if (oldPackets)
|
||||
{
|
||||
hdr |= ((int) tag) << 2;
|
||||
|
||||
if (partial)
|
||||
{
|
||||
this.WriteByte((byte)(hdr | 0x03));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bodyLen <= 0xff)
|
||||
{
|
||||
this.WriteByte((byte) hdr);
|
||||
this.WriteByte((byte)bodyLen);
|
||||
}
|
||||
else if (bodyLen <= 0xffff)
|
||||
{
|
||||
this.WriteByte((byte)(hdr | 0x01));
|
||||
this.WriteByte((byte)(bodyLen >> 8));
|
||||
this.WriteByte((byte)(bodyLen));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.WriteByte((byte)(hdr | 0x02));
|
||||
this.WriteByte((byte)(bodyLen >> 24));
|
||||
this.WriteByte((byte)(bodyLen >> 16));
|
||||
this.WriteByte((byte)(bodyLen >> 8));
|
||||
this.WriteByte((byte)bodyLen);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hdr |= 0x40 | (int) tag;
|
||||
this.WriteByte((byte) hdr);
|
||||
|
||||
if (partial)
|
||||
{
|
||||
partialOffset = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.WriteNewPacketLength(bodyLen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void PartialFlush(
|
||||
bool isLast)
|
||||
{
|
||||
if (isLast)
|
||||
{
|
||||
WriteNewPacketLength(partialOffset);
|
||||
outStr.Write(partialBuffer, 0, partialOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
outStr.WriteByte((byte)(0xE0 | partialPower));
|
||||
outStr.Write(partialBuffer, 0, partialBufferLength);
|
||||
}
|
||||
|
||||
partialOffset = 0;
|
||||
}
|
||||
|
||||
private void WritePartial(
|
||||
byte b)
|
||||
{
|
||||
if (partialOffset == partialBufferLength)
|
||||
{
|
||||
PartialFlush(false);
|
||||
}
|
||||
|
||||
partialBuffer[partialOffset++] = b;
|
||||
}
|
||||
|
||||
private void WritePartial(
|
||||
byte[] buffer,
|
||||
int off,
|
||||
int len)
|
||||
{
|
||||
if (partialOffset == partialBufferLength)
|
||||
{
|
||||
PartialFlush(false);
|
||||
}
|
||||
|
||||
if (len <= (partialBufferLength - partialOffset))
|
||||
{
|
||||
Array.Copy(buffer, off, partialBuffer, partialOffset, len);
|
||||
partialOffset += len;
|
||||
}
|
||||
else
|
||||
{
|
||||
int diff = partialBufferLength - partialOffset;
|
||||
Array.Copy(buffer, off, partialBuffer, partialOffset, diff);
|
||||
off += diff;
|
||||
len -= diff;
|
||||
PartialFlush(false);
|
||||
while (len > partialBufferLength)
|
||||
{
|
||||
Array.Copy(buffer, off, partialBuffer, 0, partialBufferLength);
|
||||
off += partialBufferLength;
|
||||
len -= partialBufferLength;
|
||||
PartialFlush(false);
|
||||
}
|
||||
Array.Copy(buffer, off, partialBuffer, 0, len);
|
||||
partialOffset += len;
|
||||
}
|
||||
}
|
||||
public override void WriteByte(
|
||||
byte value)
|
||||
{
|
||||
if (partialBuffer != null)
|
||||
{
|
||||
WritePartial(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
outStr.WriteByte(value);
|
||||
}
|
||||
}
|
||||
public override void Write(
|
||||
byte[] buffer,
|
||||
int offset,
|
||||
int count)
|
||||
{
|
||||
if (partialBuffer != null)
|
||||
{
|
||||
WritePartial(buffer, offset, count);
|
||||
}
|
||||
else
|
||||
{
|
||||
outStr.Write(buffer, offset, count);
|
||||
}
|
||||
}
|
||||
|
||||
// Additional helper methods to write primitive types
|
||||
internal virtual void WriteShort(
|
||||
short n)
|
||||
{
|
||||
this.Write(
|
||||
(byte)(n >> 8),
|
||||
(byte)n);
|
||||
}
|
||||
internal virtual void WriteInt(
|
||||
int n)
|
||||
{
|
||||
this.Write(
|
||||
(byte)(n >> 24),
|
||||
(byte)(n >> 16),
|
||||
(byte)(n >> 8),
|
||||
(byte)n);
|
||||
}
|
||||
internal virtual void WriteLong(
|
||||
long n)
|
||||
{
|
||||
this.Write(
|
||||
(byte)(n >> 56),
|
||||
(byte)(n >> 48),
|
||||
(byte)(n >> 40),
|
||||
(byte)(n >> 32),
|
||||
(byte)(n >> 24),
|
||||
(byte)(n >> 16),
|
||||
(byte)(n >> 8),
|
||||
(byte)n);
|
||||
}
|
||||
|
||||
public void WritePacket(
|
||||
ContainedPacket p)
|
||||
{
|
||||
p.Encode(this);
|
||||
}
|
||||
|
||||
internal void WritePacket(
|
||||
PacketTag tag,
|
||||
byte[] body,
|
||||
bool oldFormat)
|
||||
{
|
||||
this.WriteHeader(tag, oldFormat, false, body.Length);
|
||||
this.Write(body);
|
||||
}
|
||||
|
||||
public void WriteObject(
|
||||
BcpgObject bcpgObject)
|
||||
{
|
||||
bcpgObject.Encode(this);
|
||||
}
|
||||
|
||||
public void WriteObjects(
|
||||
params BcpgObject[] v)
|
||||
{
|
||||
foreach (BcpgObject o in v)
|
||||
{
|
||||
o.Encode(this);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Flush the underlying stream.</summary>
|
||||
public override void Flush()
|
||||
{
|
||||
outStr.Flush();
|
||||
}
|
||||
|
||||
/// <summary>Finish writing out the current packet without closing the underlying stream.</summary>
|
||||
public void Finish()
|
||||
{
|
||||
if (partialBuffer != null)
|
||||
{
|
||||
PartialFlush(true);
|
||||
partialBuffer = null;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
this.Finish();
|
||||
outStr.Flush();
|
||||
outStr.Close();
|
||||
base.Close();
|
||||
}
|
||||
}
|
||||
}
|
24
iTechSharp/srcbc/bcpg/CompressedDataPacket.cs
Normal file
24
iTechSharp/srcbc/bcpg/CompressedDataPacket.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System.IO;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/// <remarks>Generic compressed data object.</remarks>
|
||||
public class CompressedDataPacket
|
||||
: InputStreamPacket
|
||||
{
|
||||
private readonly CompressionAlgorithmTag algorithm;
|
||||
|
||||
internal CompressedDataPacket(
|
||||
BcpgInputStream bcpgIn)
|
||||
: base(bcpgIn)
|
||||
{
|
||||
this.algorithm = (CompressionAlgorithmTag) bcpgIn.ReadByte();
|
||||
}
|
||||
|
||||
/// <summary>The algorithm tag value.</summary>
|
||||
public CompressionAlgorithmTag Algorithm
|
||||
{
|
||||
get { return algorithm; }
|
||||
}
|
||||
}
|
||||
}
|
11
iTechSharp/srcbc/bcpg/CompressionAlgorithmTags.cs
Normal file
11
iTechSharp/srcbc/bcpg/CompressionAlgorithmTags.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/// <remarks>Basic tags for compression algorithms.</remarks>
|
||||
public enum CompressionAlgorithmTag
|
||||
{
|
||||
Uncompressed = 0, // Uncompressed
|
||||
Zip = 1, // ZIP (RFC 1951)
|
||||
ZLib = 2, // ZLIB (RFC 1950)
|
||||
BZip2 = 3, // BZ2
|
||||
}
|
||||
}
|
22
iTechSharp/srcbc/bcpg/ContainedPacket.cs
Normal file
22
iTechSharp/srcbc/bcpg/ContainedPacket.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/// <remarks>Basic type for a PGP packet.</remarks>
|
||||
public abstract class ContainedPacket
|
||||
: Packet
|
||||
{
|
||||
public byte[] GetEncoded()
|
||||
{
|
||||
MemoryStream bOut = new MemoryStream();
|
||||
BcpgOutputStream pOut = new BcpgOutputStream(bOut);
|
||||
|
||||
pOut.WritePacket(this);
|
||||
|
||||
return bOut.ToArray();
|
||||
}
|
||||
|
||||
public abstract void Encode(BcpgOutputStream bcpgOut);
|
||||
}
|
||||
}
|
46
iTechSharp/srcbc/bcpg/Crc24.cs
Normal file
46
iTechSharp/srcbc/bcpg/Crc24.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
public class Crc24
|
||||
{
|
||||
private const int Crc24Init = 0x0b704ce;
|
||||
private const int Crc24Poly = 0x1864cfb;
|
||||
|
||||
private int crc = Crc24Init;
|
||||
|
||||
public Crc24()
|
||||
{
|
||||
}
|
||||
|
||||
public void Update(
|
||||
int b)
|
||||
{
|
||||
crc ^= b << 16;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
crc <<= 1;
|
||||
if ((crc & 0x1000000) != 0)
|
||||
{
|
||||
crc ^= Crc24Poly;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete("Use 'Value' property instead")]
|
||||
public int GetValue()
|
||||
{
|
||||
return crc;
|
||||
}
|
||||
|
||||
public int Value
|
||||
{
|
||||
get { return crc; }
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
crc = Crc24Init;
|
||||
}
|
||||
}
|
||||
}
|
80
iTechSharp/srcbc/bcpg/DsaPublicBcpgKey.cs
Normal file
80
iTechSharp/srcbc/bcpg/DsaPublicBcpgKey.cs
Normal file
@@ -0,0 +1,80 @@
|
||||
using System;
|
||||
|
||||
using Org.BouncyCastle.Math;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/// <remarks>Base class for a DSA public key.</remarks>
|
||||
public class DsaPublicBcpgKey
|
||||
: BcpgObject, IBcpgKey
|
||||
{
|
||||
private readonly MPInteger p, q, g, y;
|
||||
|
||||
/// <param name="bcpgIn">The stream to read the packet from.</param>
|
||||
public DsaPublicBcpgKey(
|
||||
BcpgInputStream bcpgIn)
|
||||
{
|
||||
this.p = new MPInteger(bcpgIn);
|
||||
this.q = new MPInteger(bcpgIn);
|
||||
this.g = new MPInteger(bcpgIn);
|
||||
this.y = new MPInteger(bcpgIn);
|
||||
}
|
||||
|
||||
public DsaPublicBcpgKey(
|
||||
BigInteger p,
|
||||
BigInteger q,
|
||||
BigInteger g,
|
||||
BigInteger y)
|
||||
{
|
||||
this.p = new MPInteger(p);
|
||||
this.q = new MPInteger(q);
|
||||
this.g = new MPInteger(g);
|
||||
this.y = new MPInteger(y);
|
||||
}
|
||||
|
||||
/// <summary>The format, as a string, always "PGP".</summary>
|
||||
public string Format
|
||||
{
|
||||
get { return "PGP"; }
|
||||
}
|
||||
|
||||
/// <summary>Return the standard PGP encoding of the key.</summary>
|
||||
public override byte[] GetEncoded()
|
||||
{
|
||||
try
|
||||
{
|
||||
return base.GetEncoded();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Encode(
|
||||
BcpgOutputStream bcpgOut)
|
||||
{
|
||||
bcpgOut.WriteObjects(p, q, g, y);
|
||||
}
|
||||
|
||||
public BigInteger G
|
||||
{
|
||||
get { return g.Value; }
|
||||
}
|
||||
|
||||
public BigInteger P
|
||||
{
|
||||
get { return p.Value; }
|
||||
}
|
||||
|
||||
public BigInteger Q
|
||||
{
|
||||
get { return q.Value; }
|
||||
}
|
||||
|
||||
public BigInteger Y
|
||||
{
|
||||
get { return y.Value; }
|
||||
}
|
||||
}
|
||||
}
|
61
iTechSharp/srcbc/bcpg/DsaSecretBcpgKey.cs
Normal file
61
iTechSharp/srcbc/bcpg/DsaSecretBcpgKey.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
|
||||
using Org.BouncyCastle.Math;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/// <remarks>Base class for a DSA secret key.</remarks>
|
||||
public class DsaSecretBcpgKey
|
||||
: BcpgObject, IBcpgKey
|
||||
{
|
||||
internal MPInteger x;
|
||||
|
||||
/**
|
||||
* @param in
|
||||
*/
|
||||
public DsaSecretBcpgKey(
|
||||
BcpgInputStream bcpgIn)
|
||||
{
|
||||
this.x = new MPInteger(bcpgIn);
|
||||
}
|
||||
|
||||
public DsaSecretBcpgKey(
|
||||
BigInteger x)
|
||||
{
|
||||
this.x = new MPInteger(x);
|
||||
}
|
||||
|
||||
/// <summary>The format, as a string, always "PGP".</summary>
|
||||
public string Format
|
||||
{
|
||||
get { return "PGP"; }
|
||||
}
|
||||
|
||||
/// <summary>Return the standard PGP encoding of the key.</summary>
|
||||
public override byte[] GetEncoded()
|
||||
{
|
||||
try
|
||||
{
|
||||
return base.GetEncoded();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Encode(
|
||||
BcpgOutputStream bcpgOut)
|
||||
{
|
||||
bcpgOut.WriteObject(x);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return x
|
||||
*/
|
||||
public BigInteger X
|
||||
{
|
||||
get { return x.Value; }
|
||||
}
|
||||
}
|
||||
}
|
71
iTechSharp/srcbc/bcpg/ElGamalPublicBcpgKey.cs
Normal file
71
iTechSharp/srcbc/bcpg/ElGamalPublicBcpgKey.cs
Normal file
@@ -0,0 +1,71 @@
|
||||
using System;
|
||||
|
||||
using Org.BouncyCastle.Math;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/// <remarks>Base class for an ElGamal public key.</remarks>
|
||||
public class ElGamalPublicBcpgKey
|
||||
: BcpgObject, IBcpgKey
|
||||
{
|
||||
internal MPInteger p, g, y;
|
||||
|
||||
public ElGamalPublicBcpgKey(
|
||||
BcpgInputStream bcpgIn)
|
||||
{
|
||||
this.p = new MPInteger(bcpgIn);
|
||||
this.g = new MPInteger(bcpgIn);
|
||||
this.y = new MPInteger(bcpgIn);
|
||||
}
|
||||
|
||||
public ElGamalPublicBcpgKey(
|
||||
BigInteger p,
|
||||
BigInteger g,
|
||||
BigInteger y)
|
||||
{
|
||||
this.p = new MPInteger(p);
|
||||
this.g = new MPInteger(g);
|
||||
this.y = new MPInteger(y);
|
||||
}
|
||||
|
||||
/// <summary>The format, as a string, always "PGP".</summary>
|
||||
public string Format
|
||||
{
|
||||
get { return "PGP"; }
|
||||
}
|
||||
|
||||
/// <summary>Return the standard PGP encoding of the key.</summary>
|
||||
public override byte[] GetEncoded()
|
||||
{
|
||||
try
|
||||
{
|
||||
return base.GetEncoded();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public BigInteger P
|
||||
{
|
||||
get { return p.Value; }
|
||||
}
|
||||
|
||||
public BigInteger G
|
||||
{
|
||||
get { return g.Value; }
|
||||
}
|
||||
|
||||
public BigInteger Y
|
||||
{
|
||||
get { return y.Value; }
|
||||
}
|
||||
|
||||
public override void Encode(
|
||||
BcpgOutputStream bcpgOut)
|
||||
{
|
||||
bcpgOut.WriteObjects(p, g, y);
|
||||
}
|
||||
}
|
||||
}
|
61
iTechSharp/srcbc/bcpg/ElGamalSecretBcpgKey.cs
Normal file
61
iTechSharp/srcbc/bcpg/ElGamalSecretBcpgKey.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
|
||||
using Org.BouncyCastle.Math;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/// <remarks>Base class for an ElGamal secret key.</remarks>
|
||||
public class ElGamalSecretBcpgKey
|
||||
: BcpgObject, IBcpgKey
|
||||
{
|
||||
internal MPInteger x;
|
||||
|
||||
/**
|
||||
* @param in
|
||||
*/
|
||||
public ElGamalSecretBcpgKey(
|
||||
BcpgInputStream bcpgIn)
|
||||
{
|
||||
this.x = new MPInteger(bcpgIn);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param x
|
||||
*/
|
||||
public ElGamalSecretBcpgKey(
|
||||
BigInteger x)
|
||||
{
|
||||
this.x = new MPInteger(x);
|
||||
}
|
||||
|
||||
/// <summary>The format, as a string, always "PGP".</summary>
|
||||
public string Format
|
||||
{
|
||||
get { return "PGP"; }
|
||||
}
|
||||
|
||||
public BigInteger X
|
||||
{
|
||||
get { return x.Value; }
|
||||
}
|
||||
|
||||
/// <summary>Return the standard PGP encoding of the key.</summary>
|
||||
public override byte[] GetEncoded()
|
||||
{
|
||||
try
|
||||
{
|
||||
return base.GetEncoded();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Encode(
|
||||
BcpgOutputStream bcpgOut)
|
||||
{
|
||||
bcpgOut.WriteObject(x);
|
||||
}
|
||||
}
|
||||
}
|
38
iTechSharp/srcbc/bcpg/ExperimentalPacket.cs
Normal file
38
iTechSharp/srcbc/bcpg/ExperimentalPacket.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/// <remarks>Basic packet for an experimental packet.</remarks>
|
||||
public class ExperimentalPacket
|
||||
: ContainedPacket //, PublicKeyAlgorithmTag
|
||||
{
|
||||
private readonly PacketTag tag;
|
||||
private readonly byte[] contents;
|
||||
|
||||
internal ExperimentalPacket(
|
||||
PacketTag tag,
|
||||
BcpgInputStream bcpgIn)
|
||||
{
|
||||
this.tag = tag;
|
||||
|
||||
this.contents = bcpgIn.ReadAll();
|
||||
}
|
||||
|
||||
public PacketTag Tag
|
||||
{
|
||||
get { return tag; }
|
||||
}
|
||||
|
||||
public byte[] GetContents()
|
||||
{
|
||||
return (byte[]) contents.Clone();
|
||||
}
|
||||
|
||||
public override void Encode(
|
||||
BcpgOutputStream bcpgOut)
|
||||
{
|
||||
bcpgOut.WritePacket(tag, contents, true);
|
||||
}
|
||||
}
|
||||
}
|
19
iTechSharp/srcbc/bcpg/HashAlgorithmTags.cs
Normal file
19
iTechSharp/srcbc/bcpg/HashAlgorithmTags.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/// <remarks>Basic tags for hash algorithms.</remarks>
|
||||
public enum HashAlgorithmTag
|
||||
{
|
||||
MD5 = 1, // MD5
|
||||
Sha1 = 2, // SHA-1
|
||||
RipeMD160 = 3, // RIPE-MD/160
|
||||
DoubleSha = 4, // Reserved for double-width SHA (experimental)
|
||||
MD2 = 5, // MD2
|
||||
Tiger192 = 6, // Reserved for TIGER/192
|
||||
Haval5pass160 = 7, // Reserved for HAVAL (5 pass, 160-bit)
|
||||
|
||||
Sha256 = 8, // SHA-256
|
||||
Sha384 = 9, // SHA-384
|
||||
Sha512 = 10, // SHA-512
|
||||
Sha224 = 11, // SHA-224
|
||||
}
|
||||
}
|
16
iTechSharp/srcbc/bcpg/IBcpgKey.cs
Normal file
16
iTechSharp/srcbc/bcpg/IBcpgKey.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/// <remarks>Base interface for a PGP key.</remarks>
|
||||
public interface IBcpgKey
|
||||
{
|
||||
/// <summary>
|
||||
/// The base format for this key - in the case of the symmetric keys it will generally
|
||||
/// be raw indicating that the key is just a straight byte representation, for an asymmetric
|
||||
/// key the format will be PGP, indicating the key is a string of MPIs encoded in PGP format.
|
||||
/// </summary>
|
||||
/// <returns>"RAW" or "PGP".</returns>
|
||||
string Format { get; }
|
||||
}
|
||||
}
|
20
iTechSharp/srcbc/bcpg/InputStreamPacket.cs
Normal file
20
iTechSharp/srcbc/bcpg/InputStreamPacket.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
public class InputStreamPacket
|
||||
: Packet
|
||||
{
|
||||
private readonly BcpgInputStream bcpgIn;
|
||||
|
||||
public InputStreamPacket(
|
||||
BcpgInputStream bcpgIn)
|
||||
{
|
||||
this.bcpgIn = bcpgIn;
|
||||
}
|
||||
|
||||
/// <summary>Note: you can only read from this once...</summary>
|
||||
public BcpgInputStream GetInputStream()
|
||||
{
|
||||
return bcpgIn;
|
||||
}
|
||||
}
|
||||
}
|
51
iTechSharp/srcbc/bcpg/LiteralDataPacket.cs
Normal file
51
iTechSharp/srcbc/bcpg/LiteralDataPacket.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/// <remarks>Generic literal data packet.</remarks>
|
||||
public class LiteralDataPacket
|
||||
: InputStreamPacket
|
||||
{
|
||||
private int format;
|
||||
private string fileName;
|
||||
private long modDate;
|
||||
|
||||
internal LiteralDataPacket(
|
||||
BcpgInputStream bcpgIn)
|
||||
: base(bcpgIn)
|
||||
{
|
||||
format = bcpgIn.ReadByte();
|
||||
int l = bcpgIn.ReadByte();
|
||||
|
||||
char[] fileNameChars = new char[l];
|
||||
for (int i = 0; i != fileNameChars.Length; i++)
|
||||
{
|
||||
fileNameChars[i] = (char)bcpgIn.ReadByte();
|
||||
}
|
||||
fileName = new string(fileNameChars);
|
||||
|
||||
modDate = (((uint)bcpgIn.ReadByte() << 24)
|
||||
| ((uint)bcpgIn.ReadByte() << 16)
|
||||
| ((uint)bcpgIn.ReadByte() << 8)
|
||||
| (uint)bcpgIn.ReadByte()) * 1000L;
|
||||
}
|
||||
|
||||
/// <summary>The format tag value.</summary>
|
||||
public int Format
|
||||
{
|
||||
get { return format; }
|
||||
}
|
||||
|
||||
/// <summary>The modification time of the file in milli-seconds (since Jan 1, 1970 UTC)</summary>
|
||||
public long ModificationTime
|
||||
{
|
||||
get { return modDate; }
|
||||
}
|
||||
|
||||
public string FileName
|
||||
{
|
||||
get { return fileName; }
|
||||
}
|
||||
}
|
||||
}
|
59
iTechSharp/srcbc/bcpg/MPInteger.cs
Normal file
59
iTechSharp/srcbc/bcpg/MPInteger.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
using Org.BouncyCastle.Math;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/// <remarks>A multiple precision integer</remarks>
|
||||
public class MPInteger
|
||||
: BcpgObject
|
||||
{
|
||||
private readonly BigInteger val;
|
||||
|
||||
public MPInteger(
|
||||
BcpgInputStream bcpgIn)
|
||||
{
|
||||
if (bcpgIn == null)
|
||||
throw new ArgumentNullException("bcpgIn");
|
||||
|
||||
int length = (bcpgIn.ReadByte() << 8) | bcpgIn.ReadByte();
|
||||
byte[] bytes = new byte[(length + 7) / 8];
|
||||
|
||||
bcpgIn.ReadFully(bytes);
|
||||
|
||||
this.val = new BigInteger(1, bytes);
|
||||
}
|
||||
|
||||
public MPInteger(
|
||||
BigInteger val)
|
||||
{
|
||||
if (val == null)
|
||||
throw new ArgumentNullException("val");
|
||||
if (val.SignValue < 0)
|
||||
throw new ArgumentException("Values must be positive", "val");
|
||||
|
||||
this.val = val;
|
||||
}
|
||||
|
||||
public BigInteger Value
|
||||
{
|
||||
get { return val; }
|
||||
}
|
||||
|
||||
public override void Encode(
|
||||
BcpgOutputStream bcpgOut)
|
||||
{
|
||||
bcpgOut.WriteShort((short) val.BitLength);
|
||||
bcpgOut.Write(val.ToByteArrayUnsigned());
|
||||
}
|
||||
|
||||
internal static void Encode(
|
||||
BcpgOutputStream bcpgOut,
|
||||
BigInteger val)
|
||||
{
|
||||
bcpgOut.WriteShort((short) val.BitLength);
|
||||
bcpgOut.Write(val.ToByteArrayUnsigned());
|
||||
}
|
||||
}
|
||||
}
|
24
iTechSharp/srcbc/bcpg/MarkerPacket.cs
Normal file
24
iTechSharp/srcbc/bcpg/MarkerPacket.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System.IO;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/// <remarks>Basic type for a marker packet.</remarks>
|
||||
public class MarkerPacket
|
||||
: ContainedPacket
|
||||
{
|
||||
// "PGP"
|
||||
byte[] marker = { (byte)0x50, (byte)0x47, (byte)0x50 };
|
||||
|
||||
public MarkerPacket(
|
||||
BcpgInputStream bcpgIn)
|
||||
{
|
||||
bcpgIn.ReadFully(marker);
|
||||
}
|
||||
|
||||
public override void Encode(
|
||||
BcpgOutputStream bcpgOut)
|
||||
{
|
||||
bcpgOut.WritePacket(PacketTag.Marker, marker, true);
|
||||
}
|
||||
}
|
||||
}
|
42
iTechSharp/srcbc/bcpg/ModDetectionCodePacket.cs
Normal file
42
iTechSharp/srcbc/bcpg/ModDetectionCodePacket.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/// <remarks>Basic packet for a modification detection code packet.</remarks>
|
||||
public class ModDetectionCodePacket
|
||||
: ContainedPacket
|
||||
{
|
||||
private readonly byte[] digest;
|
||||
|
||||
internal ModDetectionCodePacket(
|
||||
BcpgInputStream bcpgIn)
|
||||
{
|
||||
if (bcpgIn == null)
|
||||
throw new ArgumentNullException("bcpgIn");
|
||||
|
||||
this.digest = new byte[20];
|
||||
bcpgIn.ReadFully(this.digest);
|
||||
}
|
||||
|
||||
public ModDetectionCodePacket(
|
||||
byte[] digest)
|
||||
{
|
||||
if (digest == null)
|
||||
throw new ArgumentNullException("digest");
|
||||
|
||||
this.digest = (byte[]) digest.Clone();
|
||||
}
|
||||
|
||||
public byte[] GetDigest()
|
||||
{
|
||||
return (byte[]) digest.Clone();
|
||||
}
|
||||
|
||||
public override void Encode(
|
||||
BcpgOutputStream bcpgOut)
|
||||
{
|
||||
bcpgOut.WritePacket(PacketTag.ModificationDetectionCode, digest, false);
|
||||
}
|
||||
}
|
||||
}
|
93
iTechSharp/srcbc/bcpg/OnePassSignaturePacket.cs
Normal file
93
iTechSharp/srcbc/bcpg/OnePassSignaturePacket.cs
Normal file
@@ -0,0 +1,93 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/// <remarks>Generic signature object</remarks>
|
||||
public class OnePassSignaturePacket
|
||||
: ContainedPacket
|
||||
{
|
||||
private int version;
|
||||
private int sigType;
|
||||
private HashAlgorithmTag hashAlgorithm;
|
||||
private PublicKeyAlgorithmTag keyAlgorithm;
|
||||
private long keyId;
|
||||
private int nested;
|
||||
|
||||
internal OnePassSignaturePacket(
|
||||
BcpgInputStream bcpgIn)
|
||||
{
|
||||
version = bcpgIn.ReadByte();
|
||||
sigType = bcpgIn.ReadByte();
|
||||
hashAlgorithm = (HashAlgorithmTag) bcpgIn.ReadByte();
|
||||
keyAlgorithm = (PublicKeyAlgorithmTag) bcpgIn.ReadByte();
|
||||
|
||||
keyId |= (long)bcpgIn.ReadByte() << 56;
|
||||
keyId |= (long)bcpgIn.ReadByte() << 48;
|
||||
keyId |= (long)bcpgIn.ReadByte() << 40;
|
||||
keyId |= (long)bcpgIn.ReadByte() << 32;
|
||||
keyId |= (long)bcpgIn.ReadByte() << 24;
|
||||
keyId |= (long)bcpgIn.ReadByte() << 16;
|
||||
keyId |= (long)bcpgIn.ReadByte() << 8;
|
||||
keyId |= (uint)bcpgIn.ReadByte();
|
||||
|
||||
nested = bcpgIn.ReadByte();
|
||||
}
|
||||
|
||||
public OnePassSignaturePacket(
|
||||
int sigType,
|
||||
HashAlgorithmTag hashAlgorithm,
|
||||
PublicKeyAlgorithmTag keyAlgorithm,
|
||||
long keyId,
|
||||
bool isNested)
|
||||
{
|
||||
this.version = 3;
|
||||
this.sigType = sigType;
|
||||
this.hashAlgorithm = hashAlgorithm;
|
||||
this.keyAlgorithm = keyAlgorithm;
|
||||
this.keyId = keyId;
|
||||
this.nested = (isNested) ? 0 : 1;
|
||||
}
|
||||
|
||||
public int SignatureType
|
||||
{
|
||||
get { return sigType; }
|
||||
}
|
||||
|
||||
/// <summary>The encryption algorithm tag.</summary>
|
||||
public PublicKeyAlgorithmTag KeyAlgorithm
|
||||
{
|
||||
get { return keyAlgorithm; }
|
||||
}
|
||||
|
||||
/// <summary>The hash algorithm tag.</summary>
|
||||
public HashAlgorithmTag HashAlgorithm
|
||||
{
|
||||
get { return hashAlgorithm; }
|
||||
}
|
||||
|
||||
public long KeyId
|
||||
{
|
||||
get { return keyId; }
|
||||
}
|
||||
|
||||
public override void Encode(
|
||||
BcpgOutputStream bcpgOut)
|
||||
{
|
||||
MemoryStream bOut = new MemoryStream();
|
||||
BcpgOutputStream pOut = new BcpgOutputStream(bOut);
|
||||
|
||||
pOut.Write(
|
||||
(byte) version,
|
||||
(byte) sigType,
|
||||
(byte) hashAlgorithm,
|
||||
(byte) keyAlgorithm);
|
||||
|
||||
pOut.WriteLong(keyId);
|
||||
|
||||
pOut.WriteByte((byte) nested);
|
||||
|
||||
bcpgOut.WritePacket(PacketTag.OnePassSignature, bOut.ToArray(), true);
|
||||
}
|
||||
}
|
||||
}
|
24
iTechSharp/srcbc/bcpg/OutputStreamPacket.cs
Normal file
24
iTechSharp/srcbc/bcpg/OutputStreamPacket.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
public abstract class OutputStreamPacket
|
||||
{
|
||||
private readonly BcpgOutputStream bcpgOut;
|
||||
|
||||
internal OutputStreamPacket(
|
||||
BcpgOutputStream bcpgOut)
|
||||
{
|
||||
if (bcpgOut == null)
|
||||
throw new ArgumentNullException("bcpgOut");
|
||||
|
||||
this.bcpgOut = bcpgOut;
|
||||
}
|
||||
|
||||
public abstract BcpgOutputStream Open();
|
||||
|
||||
public abstract void Close();
|
||||
}
|
||||
}
|
||||
|
7
iTechSharp/srcbc/bcpg/Packet.cs
Normal file
7
iTechSharp/srcbc/bcpg/Packet.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
public class Packet
|
||||
//: PacketTag
|
||||
{
|
||||
}
|
||||
}
|
30
iTechSharp/srcbc/bcpg/PacketTags.cs
Normal file
30
iTechSharp/srcbc/bcpg/PacketTags.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/// <remarks>Basic PGP packet tag types.</remarks>
|
||||
public enum PacketTag
|
||||
{
|
||||
Reserved = 0, // Reserved - a packet tag must not have this value
|
||||
PublicKeyEncryptedSession = 1, // Public-Key Encrypted Session Key Packet
|
||||
Signature = 2, // Signature Packet
|
||||
SymmetricKeyEncryptedSessionKey = 3, // Symmetric-Key Encrypted Session Key Packet
|
||||
OnePassSignature = 4, // One-Pass Signature Packet
|
||||
SecretKey = 5, // Secret Key Packet
|
||||
PublicKey = 6, // Public Key Packet
|
||||
SecretSubkey = 7, // Secret Subkey Packet
|
||||
CompressedData = 8, // Compressed Data Packet
|
||||
SymmetricKeyEncrypted = 9, // Symmetrically Encrypted Data Packet
|
||||
Marker = 10, // Marker Packet
|
||||
LiteralData = 11, // Literal Data Packet
|
||||
Trust = 12, // Trust Packet
|
||||
UserId = 13, // User ID Packet
|
||||
PublicSubkey = 14, // Public Subkey Packet
|
||||
UserAttribute = 17, // User attribute
|
||||
SymmetricEncryptedIntegrityProtected = 18, // Symmetric encrypted, integrity protected
|
||||
ModificationDetectionCode = 19, // Modification detection code
|
||||
|
||||
Experimental1 = 60, // Private or Experimental Values
|
||||
Experimental2 = 61,
|
||||
Experimental3 = 62,
|
||||
Experimental4 = 63
|
||||
}
|
||||
}
|
28
iTechSharp/srcbc/bcpg/PublicKeyAlgorithmTags.cs
Normal file
28
iTechSharp/srcbc/bcpg/PublicKeyAlgorithmTags.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/// <remarks>Public Key Algorithm tag numbers.</remarks>
|
||||
public enum PublicKeyAlgorithmTag
|
||||
{
|
||||
RsaGeneral = 1, // RSA (Encrypt or Sign)
|
||||
RsaEncrypt = 2, // RSA Encrypt-Only
|
||||
RsaSign = 3, // RSA Sign-Only
|
||||
ElGamalEncrypt = 16, // Elgamal (Encrypt-Only), see [ELGAMAL]
|
||||
Dsa = 17, // DSA (Digital Signature Standard)
|
||||
EC = 18, // Reserved for Elliptic Curve
|
||||
ECDsa = 19, // Reserved for ECDSA
|
||||
ElGamalGeneral = 20, // Elgamal (Encrypt or Sign)
|
||||
DiffieHellman = 21, // Reserved for Diffie-Hellman (X9.42, as defined for IETF-S/MIME)
|
||||
|
||||
Experimental_1 = 100,
|
||||
Experimental_2 = 101,
|
||||
Experimental_3 = 102,
|
||||
Experimental_4 = 103,
|
||||
Experimental_5 = 104,
|
||||
Experimental_6 = 105,
|
||||
Experimental_7 = 106,
|
||||
Experimental_8 = 107,
|
||||
Experimental_9 = 108,
|
||||
Experimental_10 = 109,
|
||||
Experimental_11 = 110,
|
||||
}
|
||||
}
|
103
iTechSharp/srcbc/bcpg/PublicKeyEncSessionPacket.cs
Normal file
103
iTechSharp/srcbc/bcpg/PublicKeyEncSessionPacket.cs
Normal file
@@ -0,0 +1,103 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
using Org.BouncyCastle.Math;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/// <remarks>Basic packet for a PGP public key.</remarks>
|
||||
public class PublicKeyEncSessionPacket
|
||||
: ContainedPacket //, PublicKeyAlgorithmTag
|
||||
{
|
||||
private int version;
|
||||
private long keyId;
|
||||
private PublicKeyAlgorithmTag algorithm;
|
||||
private BigInteger[] data;
|
||||
|
||||
internal PublicKeyEncSessionPacket(
|
||||
BcpgInputStream bcpgIn)
|
||||
{
|
||||
version = bcpgIn.ReadByte();
|
||||
|
||||
keyId |= (long)bcpgIn.ReadByte() << 56;
|
||||
keyId |= (long)bcpgIn.ReadByte() << 48;
|
||||
keyId |= (long)bcpgIn.ReadByte() << 40;
|
||||
keyId |= (long)bcpgIn.ReadByte() << 32;
|
||||
keyId |= (long)bcpgIn.ReadByte() << 24;
|
||||
keyId |= (long)bcpgIn.ReadByte() << 16;
|
||||
keyId |= (long)bcpgIn.ReadByte() << 8;
|
||||
keyId |= (uint)bcpgIn.ReadByte();
|
||||
|
||||
algorithm = (PublicKeyAlgorithmTag) bcpgIn.ReadByte();
|
||||
|
||||
switch ((PublicKeyAlgorithmTag) algorithm)
|
||||
{
|
||||
case PublicKeyAlgorithmTag.RsaEncrypt:
|
||||
case PublicKeyAlgorithmTag.RsaGeneral:
|
||||
data = new BigInteger[]{ new MPInteger(bcpgIn).Value };
|
||||
break;
|
||||
case PublicKeyAlgorithmTag.ElGamalEncrypt:
|
||||
case PublicKeyAlgorithmTag.ElGamalGeneral:
|
||||
data = new BigInteger[]
|
||||
{
|
||||
new MPInteger(bcpgIn).Value,
|
||||
new MPInteger(bcpgIn).Value
|
||||
};
|
||||
break;
|
||||
default:
|
||||
throw new IOException("unknown PGP public key algorithm encountered");
|
||||
}
|
||||
}
|
||||
|
||||
public PublicKeyEncSessionPacket(
|
||||
long keyId,
|
||||
PublicKeyAlgorithmTag algorithm,
|
||||
BigInteger[] data)
|
||||
{
|
||||
this.version = 3;
|
||||
this.keyId = keyId;
|
||||
this.algorithm = algorithm;
|
||||
this.data = (BigInteger[]) data.Clone();
|
||||
}
|
||||
|
||||
public int Version
|
||||
{
|
||||
get { return version; }
|
||||
}
|
||||
|
||||
public long KeyId
|
||||
{
|
||||
get { return keyId; }
|
||||
}
|
||||
|
||||
public PublicKeyAlgorithmTag Algorithm
|
||||
{
|
||||
get { return algorithm; }
|
||||
}
|
||||
|
||||
public BigInteger[] GetEncSessionKey()
|
||||
{
|
||||
return (BigInteger[]) data.Clone();
|
||||
}
|
||||
|
||||
public override void Encode(
|
||||
BcpgOutputStream bcpgOut)
|
||||
{
|
||||
MemoryStream bOut = new MemoryStream();
|
||||
BcpgOutputStream pOut = new BcpgOutputStream(bOut);
|
||||
|
||||
pOut.WriteByte((byte) version);
|
||||
|
||||
pOut.WriteLong(keyId);
|
||||
|
||||
pOut.WriteByte((byte)algorithm);
|
||||
|
||||
for (int i = 0; i != data.Length; i++)
|
||||
{
|
||||
MPInteger.Encode(pOut, data[i]);
|
||||
}
|
||||
|
||||
bcpgOut.WritePacket(PacketTag.PublicKeyEncryptedSession , bOut.ToArray(), true);
|
||||
}
|
||||
}
|
||||
}
|
115
iTechSharp/srcbc/bcpg/PublicKeyPacket.cs
Normal file
115
iTechSharp/srcbc/bcpg/PublicKeyPacket.cs
Normal file
@@ -0,0 +1,115 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
using Org.BouncyCastle.Utilities.Date;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/// <remarks>Basic packet for a PGP public key.</remarks>
|
||||
public class PublicKeyPacket
|
||||
: ContainedPacket //, PublicKeyAlgorithmTag
|
||||
{
|
||||
private int version;
|
||||
private long time;
|
||||
private int validDays;
|
||||
private PublicKeyAlgorithmTag algorithm;
|
||||
private IBcpgKey key;
|
||||
|
||||
internal PublicKeyPacket(
|
||||
BcpgInputStream bcpgIn)
|
||||
{
|
||||
version = bcpgIn.ReadByte();
|
||||
|
||||
time = ((uint)bcpgIn.ReadByte() << 24) | ((uint)bcpgIn.ReadByte() << 16)
|
||||
| ((uint)bcpgIn.ReadByte() << 8) | (uint)bcpgIn.ReadByte();
|
||||
|
||||
if (version <= 3)
|
||||
{
|
||||
validDays = (bcpgIn.ReadByte() << 8) | bcpgIn.ReadByte();
|
||||
}
|
||||
|
||||
algorithm = (PublicKeyAlgorithmTag) bcpgIn.ReadByte();
|
||||
|
||||
switch ((PublicKeyAlgorithmTag) algorithm)
|
||||
{
|
||||
case PublicKeyAlgorithmTag.RsaEncrypt:
|
||||
case PublicKeyAlgorithmTag.RsaGeneral:
|
||||
case PublicKeyAlgorithmTag.RsaSign:
|
||||
key = new RsaPublicBcpgKey(bcpgIn);
|
||||
break;
|
||||
case PublicKeyAlgorithmTag.Dsa:
|
||||
key = new DsaPublicBcpgKey(bcpgIn);
|
||||
break;
|
||||
case PublicKeyAlgorithmTag.ElGamalEncrypt:
|
||||
case PublicKeyAlgorithmTag.ElGamalGeneral:
|
||||
key = new ElGamalPublicBcpgKey(bcpgIn);
|
||||
break;
|
||||
default:
|
||||
throw new IOException("unknown PGP public key algorithm encountered");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Construct a version 4 public key packet.</summary>
|
||||
public PublicKeyPacket(
|
||||
PublicKeyAlgorithmTag algorithm,
|
||||
DateTime time,
|
||||
IBcpgKey key)
|
||||
{
|
||||
this.version = 4;
|
||||
this.time = DateTimeUtilities.DateTimeToUnixMs(time) / 1000L;
|
||||
this.algorithm = algorithm;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public int Version
|
||||
{
|
||||
get { return version; }
|
||||
}
|
||||
|
||||
public PublicKeyAlgorithmTag Algorithm
|
||||
{
|
||||
get { return algorithm; }
|
||||
}
|
||||
|
||||
public int ValidDays
|
||||
{
|
||||
get { return validDays; }
|
||||
}
|
||||
|
||||
public DateTime GetTime()
|
||||
{
|
||||
return DateTimeUtilities.UnixMsToDateTime(time * 1000L);
|
||||
}
|
||||
|
||||
public IBcpgKey Key
|
||||
{
|
||||
get { return key; }
|
||||
}
|
||||
|
||||
public byte[] GetEncodedContents()
|
||||
{
|
||||
MemoryStream bOut = new MemoryStream();
|
||||
BcpgOutputStream pOut = new BcpgOutputStream(bOut);
|
||||
|
||||
pOut.WriteByte((byte) version);
|
||||
pOut.WriteInt((int) time);
|
||||
|
||||
if (version <= 3)
|
||||
{
|
||||
pOut.WriteShort((short) validDays);
|
||||
}
|
||||
|
||||
pOut.WriteByte((byte) algorithm);
|
||||
|
||||
pOut.WriteObject((BcpgObject)key);
|
||||
|
||||
return bOut.ToArray();
|
||||
}
|
||||
|
||||
public override void Encode(
|
||||
BcpgOutputStream bcpgOut)
|
||||
{
|
||||
bcpgOut.WritePacket(PacketTag.PublicKey, GetEncodedContents(), true);
|
||||
}
|
||||
}
|
||||
}
|
30
iTechSharp/srcbc/bcpg/PublicSubkeyPacket.cs
Normal file
30
iTechSharp/srcbc/bcpg/PublicSubkeyPacket.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/// <remarks>Basic packet for a PGP public subkey</remarks>
|
||||
public class PublicSubkeyPacket
|
||||
: PublicKeyPacket
|
||||
{
|
||||
internal PublicSubkeyPacket(
|
||||
BcpgInputStream bcpgIn)
|
||||
: base(bcpgIn)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>Construct a version 4 public subkey packet.</summary>
|
||||
public PublicSubkeyPacket(
|
||||
PublicKeyAlgorithmTag algorithm,
|
||||
DateTime time,
|
||||
IBcpgKey key)
|
||||
: base(algorithm, time, key)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Encode(
|
||||
BcpgOutputStream bcpgOut)
|
||||
{
|
||||
bcpgOut.WritePacket(PacketTag.PublicSubkey, GetEncodedContents(), true);
|
||||
}
|
||||
}
|
||||
}
|
66
iTechSharp/srcbc/bcpg/RsaPublicBcpgKey.cs
Normal file
66
iTechSharp/srcbc/bcpg/RsaPublicBcpgKey.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
using System;
|
||||
|
||||
using Org.BouncyCastle.Math;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/// <remarks>Base class for an RSA public key.</remarks>
|
||||
public class RsaPublicBcpgKey
|
||||
: BcpgObject, IBcpgKey
|
||||
{
|
||||
private readonly MPInteger n, e;
|
||||
|
||||
/// <summary>Construct an RSA public key from the passed in stream.</summary>
|
||||
public RsaPublicBcpgKey(
|
||||
BcpgInputStream bcpgIn)
|
||||
{
|
||||
this.n = new MPInteger(bcpgIn);
|
||||
this.e = new MPInteger(bcpgIn);
|
||||
}
|
||||
|
||||
/// <param name="n">The modulus.</param>
|
||||
/// <param name="e">The public exponent.</param>
|
||||
public RsaPublicBcpgKey(
|
||||
BigInteger n,
|
||||
BigInteger e)
|
||||
{
|
||||
this.n = new MPInteger(n);
|
||||
this.e = new MPInteger(e);
|
||||
}
|
||||
|
||||
public BigInteger PublicExponent
|
||||
{
|
||||
get { return e.Value; }
|
||||
}
|
||||
|
||||
public BigInteger Modulus
|
||||
{
|
||||
get { return n.Value; }
|
||||
}
|
||||
|
||||
/// <summary>The format, as a string, always "PGP".</summary>
|
||||
public string Format
|
||||
{
|
||||
get { return "PGP"; }
|
||||
}
|
||||
|
||||
/// <summary>Return the standard PGP encoding of the key.</summary>
|
||||
public override byte[] GetEncoded()
|
||||
{
|
||||
try
|
||||
{
|
||||
return base.GetEncoded();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Encode(
|
||||
BcpgOutputStream bcpgOut)
|
||||
{
|
||||
bcpgOut.WriteObjects(n, e);
|
||||
}
|
||||
}
|
||||
}
|
114
iTechSharp/srcbc/bcpg/RsaSecretBcpgKey.cs
Normal file
114
iTechSharp/srcbc/bcpg/RsaSecretBcpgKey.cs
Normal file
@@ -0,0 +1,114 @@
|
||||
using System;
|
||||
|
||||
using Org.BouncyCastle.Math;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/// <remarks>Base class for an RSA secret (or priate) key.</remarks>
|
||||
public class RsaSecretBcpgKey
|
||||
: BcpgObject, IBcpgKey
|
||||
{
|
||||
private readonly MPInteger d, p, q, u;
|
||||
private readonly BigInteger expP, expQ, crt;
|
||||
|
||||
public RsaSecretBcpgKey(
|
||||
BcpgInputStream bcpgIn)
|
||||
{
|
||||
this.d = new MPInteger(bcpgIn);
|
||||
this.p = new MPInteger(bcpgIn);
|
||||
this.q = new MPInteger(bcpgIn);
|
||||
this.u = new MPInteger(bcpgIn);
|
||||
|
||||
this.expP = d.Value.Remainder(p.Value.Subtract(BigInteger.One));
|
||||
this.expQ = d.Value.Remainder(q.Value.Subtract(BigInteger.One));
|
||||
this.crt = q.Value.ModInverse(p.Value);
|
||||
}
|
||||
|
||||
public RsaSecretBcpgKey(
|
||||
BigInteger d,
|
||||
BigInteger p,
|
||||
BigInteger q)
|
||||
{
|
||||
// PGP requires (p < q)
|
||||
int cmp = p.CompareTo(q);
|
||||
if (cmp >= 0)
|
||||
{
|
||||
if (cmp == 0)
|
||||
throw new ArgumentException("p and q cannot be equal");
|
||||
|
||||
BigInteger tmp = p;
|
||||
p = q;
|
||||
q = tmp;
|
||||
}
|
||||
|
||||
this.d = new MPInteger(d);
|
||||
this.p = new MPInteger(p);
|
||||
this.q = new MPInteger(q);
|
||||
this.u = new MPInteger(p.ModInverse(q));
|
||||
|
||||
this.expP = d.Remainder(p.Subtract(BigInteger.One));
|
||||
this.expQ = d.Remainder(q.Subtract(BigInteger.One));
|
||||
this.crt = q.ModInverse(p);
|
||||
}
|
||||
|
||||
public BigInteger Modulus
|
||||
{
|
||||
get { return p.Value.Multiply(q.Value); }
|
||||
}
|
||||
|
||||
public BigInteger PrivateExponent
|
||||
{
|
||||
get { return d.Value; }
|
||||
}
|
||||
|
||||
public BigInteger PrimeP
|
||||
{
|
||||
get { return p.Value; }
|
||||
}
|
||||
|
||||
public BigInteger PrimeQ
|
||||
{
|
||||
get { return q.Value; }
|
||||
}
|
||||
|
||||
public BigInteger PrimeExponentP
|
||||
{
|
||||
get { return expP; }
|
||||
}
|
||||
|
||||
public BigInteger PrimeExponentQ
|
||||
{
|
||||
get { return expQ; }
|
||||
}
|
||||
|
||||
public BigInteger CrtCoefficient
|
||||
{
|
||||
get { return crt; }
|
||||
}
|
||||
|
||||
/// <summary>The format, as a string, always "PGP".</summary>
|
||||
public string Format
|
||||
{
|
||||
get { return "PGP"; }
|
||||
}
|
||||
|
||||
/// <summary>Return the standard PGP encoding of the key.</summary>
|
||||
public override byte[] GetEncoded()
|
||||
{
|
||||
try
|
||||
{
|
||||
return base.GetEncoded();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Encode(
|
||||
BcpgOutputStream bcpgOut)
|
||||
{
|
||||
bcpgOut.WriteObjects(d, p, q, u);
|
||||
}
|
||||
}
|
||||
}
|
147
iTechSharp/srcbc/bcpg/S2k.cs
Normal file
147
iTechSharp/srcbc/bcpg/S2k.cs
Normal file
@@ -0,0 +1,147 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.Utilities.IO;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/// <remarks>The string to key specifier class.</remarks>
|
||||
public class S2k
|
||||
: BcpgObject
|
||||
{
|
||||
private const int ExpBias = 6;
|
||||
|
||||
public const int Simple = 0;
|
||||
public const int Salted = 1;
|
||||
public const int SaltedAndIterated = 3;
|
||||
public const int GnuDummyS2K = 101;
|
||||
|
||||
internal int type;
|
||||
internal HashAlgorithmTag algorithm;
|
||||
internal byte[] iv;
|
||||
internal int itCount = -1;
|
||||
internal int protectionMode = -1;
|
||||
|
||||
internal S2k(
|
||||
Stream inStr)
|
||||
{
|
||||
type = inStr.ReadByte();
|
||||
algorithm = (HashAlgorithmTag) inStr.ReadByte();
|
||||
|
||||
//
|
||||
// if this happens we have a dummy-S2k packet.
|
||||
//
|
||||
if (type != GnuDummyS2K)
|
||||
{
|
||||
if (type != 0)
|
||||
{
|
||||
iv = new byte[8];
|
||||
if (Streams.ReadFully(inStr, iv, 0, iv.Length) < iv.Length)
|
||||
throw new EndOfStreamException();
|
||||
|
||||
if (type == 3)
|
||||
{
|
||||
itCount = inStr.ReadByte();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
inStr.ReadByte(); // G
|
||||
inStr.ReadByte(); // N
|
||||
inStr.ReadByte(); // U
|
||||
protectionMode = inStr.ReadByte(); // protection mode
|
||||
}
|
||||
}
|
||||
|
||||
public S2k(
|
||||
HashAlgorithmTag algorithm)
|
||||
{
|
||||
this.type = 0;
|
||||
this.algorithm = algorithm;
|
||||
}
|
||||
|
||||
public S2k(
|
||||
HashAlgorithmTag algorithm,
|
||||
byte[] iv)
|
||||
{
|
||||
this.type = 1;
|
||||
this.algorithm = algorithm;
|
||||
this.iv = iv;
|
||||
}
|
||||
|
||||
public S2k(
|
||||
HashAlgorithmTag algorithm,
|
||||
byte[] iv,
|
||||
int itCount)
|
||||
{
|
||||
this.type = 3;
|
||||
this.algorithm = algorithm;
|
||||
this.iv = iv;
|
||||
this.itCount = itCount;
|
||||
}
|
||||
|
||||
public int Type
|
||||
{
|
||||
get { return type; }
|
||||
}
|
||||
|
||||
/// <summary>The hash algorithm.</summary>
|
||||
public HashAlgorithmTag HashAlgorithm
|
||||
{
|
||||
get { return algorithm; }
|
||||
}
|
||||
|
||||
/// <summary>The IV for the key generation algorithm.</summary>
|
||||
public byte[] GetIV()
|
||||
{
|
||||
return Arrays.Clone(iv);
|
||||
}
|
||||
|
||||
[Obsolete("Use 'IterationCount' property instead")]
|
||||
public long GetIterationCount()
|
||||
{
|
||||
return IterationCount;
|
||||
}
|
||||
|
||||
/// <summary>The iteration count</summary>
|
||||
public long IterationCount
|
||||
{
|
||||
get { return (16 + (itCount & 15)) << ((itCount >> 4) + ExpBias); }
|
||||
}
|
||||
|
||||
/// <summary>The protection mode - only if GnuDummyS2K</summary>
|
||||
public int ProtectionMode
|
||||
{
|
||||
get { return protectionMode; }
|
||||
}
|
||||
|
||||
public override void Encode(
|
||||
BcpgOutputStream bcpgOut)
|
||||
{
|
||||
bcpgOut.WriteByte((byte) type);
|
||||
bcpgOut.WriteByte((byte) algorithm);
|
||||
|
||||
if (type != GnuDummyS2K)
|
||||
{
|
||||
if (type != 0)
|
||||
{
|
||||
bcpgOut.Write(iv);
|
||||
}
|
||||
|
||||
if (type == 3)
|
||||
{
|
||||
bcpgOut.WriteByte((byte) itCount);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bcpgOut.WriteByte((byte) 'G');
|
||||
bcpgOut.WriteByte((byte) 'N');
|
||||
bcpgOut.WriteByte((byte) 'U');
|
||||
bcpgOut.WriteByte((byte) protectionMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
163
iTechSharp/srcbc/bcpg/SecretKeyPacket.cs
Normal file
163
iTechSharp/srcbc/bcpg/SecretKeyPacket.cs
Normal file
@@ -0,0 +1,163 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/// <remarks>Basic packet for a PGP secret key.</remarks>
|
||||
public class SecretKeyPacket
|
||||
: ContainedPacket //, PublicKeyAlgorithmTag
|
||||
{
|
||||
public const int UsageNone = 0x00;
|
||||
public const int UsageChecksum = 0xff;
|
||||
public const int UsageSha1 = 0xfe;
|
||||
|
||||
private PublicKeyPacket pubKeyPacket;
|
||||
private readonly byte[] secKeyData;
|
||||
private int s2kUsage;
|
||||
private SymmetricKeyAlgorithmTag encAlgorithm;
|
||||
private S2k s2k;
|
||||
private byte[] iv;
|
||||
|
||||
internal SecretKeyPacket(
|
||||
BcpgInputStream bcpgIn)
|
||||
{
|
||||
pubKeyPacket = new PublicKeyPacket(bcpgIn);
|
||||
|
||||
s2kUsage = bcpgIn.ReadByte();
|
||||
|
||||
if (s2kUsage == UsageChecksum || s2kUsage == UsageSha1)
|
||||
{
|
||||
encAlgorithm = (SymmetricKeyAlgorithmTag) bcpgIn.ReadByte();
|
||||
s2k = new S2k(bcpgIn);
|
||||
}
|
||||
else
|
||||
{
|
||||
encAlgorithm = (SymmetricKeyAlgorithmTag) s2kUsage;
|
||||
}
|
||||
|
||||
if (!(s2k != null && s2k.Type == S2k.GnuDummyS2K && s2k.ProtectionMode == 0x01))
|
||||
{
|
||||
if (s2kUsage != 0)
|
||||
{
|
||||
if (((int) encAlgorithm) < 7)
|
||||
{
|
||||
iv = new byte[8];
|
||||
}
|
||||
else
|
||||
{
|
||||
iv = new byte[16];
|
||||
}
|
||||
bcpgIn.ReadFully(iv);
|
||||
}
|
||||
}
|
||||
|
||||
secKeyData = bcpgIn.ReadAll();
|
||||
}
|
||||
|
||||
public SecretKeyPacket(
|
||||
PublicKeyPacket pubKeyPacket,
|
||||
SymmetricKeyAlgorithmTag encAlgorithm,
|
||||
S2k s2k,
|
||||
byte[] iv,
|
||||
byte[] secKeyData)
|
||||
{
|
||||
this.pubKeyPacket = pubKeyPacket;
|
||||
this.encAlgorithm = encAlgorithm;
|
||||
|
||||
if (encAlgorithm != SymmetricKeyAlgorithmTag.Null)
|
||||
{
|
||||
this.s2kUsage = UsageChecksum;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.s2kUsage = UsageNone;
|
||||
}
|
||||
|
||||
this.s2k = s2k;
|
||||
this.iv = Arrays.Clone(iv);
|
||||
this.secKeyData = secKeyData;
|
||||
}
|
||||
|
||||
public SecretKeyPacket(
|
||||
PublicKeyPacket pubKeyPacket,
|
||||
SymmetricKeyAlgorithmTag encAlgorithm,
|
||||
int s2kUsage,
|
||||
S2k s2k,
|
||||
byte[] iv,
|
||||
byte[] secKeyData)
|
||||
{
|
||||
this.pubKeyPacket = pubKeyPacket;
|
||||
this.encAlgorithm = encAlgorithm;
|
||||
this.s2kUsage = s2kUsage;
|
||||
this.s2k = s2k;
|
||||
this.iv = Arrays.Clone(iv);
|
||||
this.secKeyData = secKeyData;
|
||||
}
|
||||
|
||||
public SymmetricKeyAlgorithmTag EncAlgorithm
|
||||
{
|
||||
get { return encAlgorithm; }
|
||||
}
|
||||
|
||||
public int S2kUsage
|
||||
{
|
||||
get { return s2kUsage; }
|
||||
}
|
||||
|
||||
public byte[] GetIV()
|
||||
{
|
||||
return Arrays.Clone(iv);
|
||||
}
|
||||
|
||||
public S2k S2k
|
||||
{
|
||||
get { return s2k; }
|
||||
}
|
||||
|
||||
public PublicKeyPacket PublicKeyPacket
|
||||
{
|
||||
get { return pubKeyPacket; }
|
||||
}
|
||||
|
||||
public byte[] GetSecretKeyData()
|
||||
{
|
||||
return secKeyData;
|
||||
}
|
||||
|
||||
public byte[] GetEncodedContents()
|
||||
{
|
||||
MemoryStream bOut = new MemoryStream();
|
||||
BcpgOutputStream pOut = new BcpgOutputStream(bOut);
|
||||
|
||||
pOut.Write(pubKeyPacket.GetEncodedContents());
|
||||
|
||||
pOut.WriteByte((byte) s2kUsage);
|
||||
|
||||
if (s2kUsage == UsageChecksum || s2kUsage == UsageSha1)
|
||||
{
|
||||
pOut.WriteByte((byte) encAlgorithm);
|
||||
pOut.WriteObject(s2k);
|
||||
}
|
||||
|
||||
if (iv != null)
|
||||
{
|
||||
pOut.Write(iv);
|
||||
}
|
||||
|
||||
if (secKeyData != null && secKeyData.Length > 0)
|
||||
{
|
||||
pOut.Write(secKeyData);
|
||||
}
|
||||
|
||||
return bOut.ToArray();
|
||||
}
|
||||
|
||||
public override void Encode(
|
||||
BcpgOutputStream bcpgOut)
|
||||
{
|
||||
bcpgOut.WritePacket(PacketTag.SecretKey, GetEncodedContents(), true);
|
||||
}
|
||||
}
|
||||
}
|
43
iTechSharp/srcbc/bcpg/SecretSubkeyPacket.cs
Normal file
43
iTechSharp/srcbc/bcpg/SecretSubkeyPacket.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/// <remarks>Basic packet for a PGP secret key.</remarks>
|
||||
public class SecretSubkeyPacket
|
||||
: SecretKeyPacket
|
||||
{
|
||||
internal SecretSubkeyPacket(
|
||||
BcpgInputStream bcpgIn)
|
||||
: base(bcpgIn)
|
||||
{
|
||||
}
|
||||
|
||||
public SecretSubkeyPacket(
|
||||
PublicKeyPacket pubKeyPacket,
|
||||
SymmetricKeyAlgorithmTag encAlgorithm,
|
||||
S2k s2k,
|
||||
byte[] iv,
|
||||
byte[] secKeyData)
|
||||
: base(pubKeyPacket, encAlgorithm, s2k, iv, secKeyData)
|
||||
{
|
||||
}
|
||||
|
||||
public SecretSubkeyPacket(
|
||||
PublicKeyPacket pubKeyPacket,
|
||||
SymmetricKeyAlgorithmTag encAlgorithm,
|
||||
int s2kUsage,
|
||||
S2k s2k,
|
||||
byte[] iv,
|
||||
byte[] secKeyData)
|
||||
: base(pubKeyPacket, encAlgorithm, s2kUsage, s2k, iv, secKeyData)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Encode(
|
||||
BcpgOutputStream bcpgOut)
|
||||
{
|
||||
bcpgOut.WritePacket(PacketTag.SecretSubkey, GetEncodedContents(), true);
|
||||
}
|
||||
}
|
||||
}
|
459
iTechSharp/srcbc/bcpg/SignaturePacket.cs
Normal file
459
iTechSharp/srcbc/bcpg/SignaturePacket.cs
Normal file
@@ -0,0 +1,459 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
|
||||
using Org.BouncyCastle.Bcpg.Sig;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.Utilities.Date;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/// <remarks>Generic signature packet.</remarks>
|
||||
public class SignaturePacket
|
||||
: ContainedPacket //, PublicKeyAlgorithmTag
|
||||
{
|
||||
private int version;
|
||||
private int signatureType;
|
||||
private long creationTime;
|
||||
private long keyId;
|
||||
private PublicKeyAlgorithmTag keyAlgorithm;
|
||||
private HashAlgorithmTag hashAlgorithm;
|
||||
private MPInteger[] signature;
|
||||
private byte[] fingerprint;
|
||||
private SignatureSubpacket[] hashedData;
|
||||
private SignatureSubpacket[] unhashedData;
|
||||
private byte[] signatureEncoding;
|
||||
|
||||
internal SignaturePacket(
|
||||
BcpgInputStream bcpgIn)
|
||||
{
|
||||
version = bcpgIn.ReadByte();
|
||||
|
||||
if (version == 3 || version == 2)
|
||||
{
|
||||
// int l =
|
||||
bcpgIn.ReadByte();
|
||||
|
||||
signatureType = bcpgIn.ReadByte();
|
||||
creationTime = (((long)bcpgIn.ReadByte() << 24) | ((long)bcpgIn.ReadByte() << 16)
|
||||
| ((long)bcpgIn.ReadByte() << 8) | (uint)bcpgIn.ReadByte()) * 1000L;
|
||||
|
||||
keyId |= (long)bcpgIn.ReadByte() << 56;
|
||||
keyId |= (long)bcpgIn.ReadByte() << 48;
|
||||
keyId |= (long)bcpgIn.ReadByte() << 40;
|
||||
keyId |= (long)bcpgIn.ReadByte() << 32;
|
||||
keyId |= (long)bcpgIn.ReadByte() << 24;
|
||||
keyId |= (long)bcpgIn.ReadByte() << 16;
|
||||
keyId |= (long)bcpgIn.ReadByte() << 8;
|
||||
keyId |= (uint)bcpgIn.ReadByte();
|
||||
|
||||
keyAlgorithm = (PublicKeyAlgorithmTag) bcpgIn.ReadByte();
|
||||
hashAlgorithm = (HashAlgorithmTag) bcpgIn.ReadByte();
|
||||
}
|
||||
else if (version == 4)
|
||||
{
|
||||
signatureType = bcpgIn.ReadByte();
|
||||
keyAlgorithm = (PublicKeyAlgorithmTag) bcpgIn.ReadByte();
|
||||
hashAlgorithm = (HashAlgorithmTag) bcpgIn.ReadByte();
|
||||
|
||||
int hashedLength = (bcpgIn.ReadByte() << 8) | bcpgIn.ReadByte();
|
||||
byte[] hashed = new byte[hashedLength];
|
||||
|
||||
bcpgIn.ReadFully(hashed);
|
||||
|
||||
//
|
||||
// read the signature sub packet data.
|
||||
//
|
||||
SignatureSubpacketsParser sIn = new SignatureSubpacketsParser(
|
||||
new MemoryStream(hashed, false));
|
||||
|
||||
ArrayList v = new ArrayList();
|
||||
SignatureSubpacket sub;
|
||||
while ((sub = sIn.ReadPacket()) != null)
|
||||
{
|
||||
v.Add(sub);
|
||||
}
|
||||
|
||||
hashedData = new SignatureSubpacket[v.Count];
|
||||
|
||||
for (int i = 0; i != hashedData.Length; i++)
|
||||
{
|
||||
SignatureSubpacket p = (SignatureSubpacket)v[i];
|
||||
if (p is IssuerKeyId)
|
||||
{
|
||||
keyId = ((IssuerKeyId)p).KeyId;
|
||||
}
|
||||
else if (p is SignatureCreationTime)
|
||||
{
|
||||
creationTime = DateTimeUtilities.DateTimeToUnixMs(
|
||||
((SignatureCreationTime)p).GetTime());
|
||||
}
|
||||
|
||||
hashedData[i] = p;
|
||||
}
|
||||
|
||||
int unhashedLength = (bcpgIn.ReadByte() << 8) | bcpgIn.ReadByte();
|
||||
byte[] unhashed = new byte[unhashedLength];
|
||||
|
||||
bcpgIn.ReadFully(unhashed);
|
||||
|
||||
sIn = new SignatureSubpacketsParser(new MemoryStream(unhashed, false));
|
||||
|
||||
v.Clear();
|
||||
|
||||
while ((sub = sIn.ReadPacket()) != null)
|
||||
{
|
||||
v.Add(sub);
|
||||
}
|
||||
|
||||
unhashedData = new SignatureSubpacket[v.Count];
|
||||
|
||||
for (int i = 0; i != unhashedData.Length; i++)
|
||||
{
|
||||
SignatureSubpacket p = (SignatureSubpacket)v[i];
|
||||
if (p is IssuerKeyId)
|
||||
{
|
||||
keyId = ((IssuerKeyId)p).KeyId;
|
||||
}
|
||||
else if (p is SignatureCreationTime)
|
||||
{
|
||||
creationTime = DateTimeUtilities.DateTimeToUnixMs(
|
||||
((SignatureCreationTime)p).GetTime());
|
||||
}
|
||||
|
||||
unhashedData[i] = p;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("unsupported version: " + version);
|
||||
}
|
||||
|
||||
fingerprint = new byte[2];
|
||||
bcpgIn.ReadFully(fingerprint);
|
||||
|
||||
switch (keyAlgorithm)
|
||||
{
|
||||
case PublicKeyAlgorithmTag.RsaGeneral:
|
||||
case PublicKeyAlgorithmTag.RsaSign:
|
||||
MPInteger v = new MPInteger(bcpgIn);
|
||||
signature = new MPInteger[]{ v };
|
||||
break;
|
||||
case PublicKeyAlgorithmTag.Dsa:
|
||||
MPInteger r = new MPInteger(bcpgIn);
|
||||
MPInteger s = new MPInteger(bcpgIn);
|
||||
signature = new MPInteger[]{ r, s };
|
||||
break;
|
||||
case PublicKeyAlgorithmTag.ElGamalEncrypt: // yep, this really does happen sometimes.
|
||||
case PublicKeyAlgorithmTag.ElGamalGeneral:
|
||||
MPInteger p = new MPInteger(bcpgIn);
|
||||
MPInteger g = new MPInteger(bcpgIn);
|
||||
MPInteger y = new MPInteger(bcpgIn);
|
||||
signature = new MPInteger[]{ p, g, y };
|
||||
break;
|
||||
default:
|
||||
if (keyAlgorithm >= PublicKeyAlgorithmTag.Experimental_1 && keyAlgorithm <= PublicKeyAlgorithmTag.Experimental_11)
|
||||
{
|
||||
signature = null;
|
||||
MemoryStream bOut = new MemoryStream();
|
||||
int ch;
|
||||
while ((ch = bcpgIn.ReadByte()) >= 0)
|
||||
{
|
||||
bOut.WriteByte((byte) ch);
|
||||
}
|
||||
signatureEncoding = bOut.ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IOException("unknown signature key algorithm: " + keyAlgorithm);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a version 4 signature packet.
|
||||
*
|
||||
* @param signatureType
|
||||
* @param keyAlgorithm
|
||||
* @param hashAlgorithm
|
||||
* @param hashedData
|
||||
* @param unhashedData
|
||||
* @param fingerprint
|
||||
* @param signature
|
||||
*/
|
||||
public SignaturePacket(
|
||||
int signatureType,
|
||||
long keyId,
|
||||
PublicKeyAlgorithmTag keyAlgorithm,
|
||||
HashAlgorithmTag hashAlgorithm,
|
||||
SignatureSubpacket[] hashedData,
|
||||
SignatureSubpacket[] unhashedData,
|
||||
byte[] fingerprint,
|
||||
MPInteger[] signature)
|
||||
: this(4, signatureType, keyId, keyAlgorithm, hashAlgorithm, hashedData, unhashedData, fingerprint, signature)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a version 2/3 signature packet.
|
||||
*
|
||||
* @param signatureType
|
||||
* @param keyAlgorithm
|
||||
* @param hashAlgorithm
|
||||
* @param fingerprint
|
||||
* @param signature
|
||||
*/
|
||||
public SignaturePacket(
|
||||
int version,
|
||||
int signatureType,
|
||||
long keyId,
|
||||
PublicKeyAlgorithmTag keyAlgorithm,
|
||||
HashAlgorithmTag hashAlgorithm,
|
||||
long creationTime,
|
||||
byte[] fingerprint,
|
||||
MPInteger[] signature)
|
||||
: this(version, signatureType, keyId, keyAlgorithm, hashAlgorithm, null, null, fingerprint, signature)
|
||||
{
|
||||
this.creationTime = creationTime;
|
||||
}
|
||||
|
||||
public SignaturePacket(
|
||||
int version,
|
||||
int signatureType,
|
||||
long keyId,
|
||||
PublicKeyAlgorithmTag keyAlgorithm,
|
||||
HashAlgorithmTag hashAlgorithm,
|
||||
SignatureSubpacket[] hashedData,
|
||||
SignatureSubpacket[] unhashedData,
|
||||
byte[] fingerprint,
|
||||
MPInteger[] signature)
|
||||
{
|
||||
this.version = version;
|
||||
this.signatureType = signatureType;
|
||||
this.keyId = keyId;
|
||||
this.keyAlgorithm = keyAlgorithm;
|
||||
this.hashAlgorithm = hashAlgorithm;
|
||||
this.hashedData = hashedData;
|
||||
this.unhashedData = unhashedData;
|
||||
this.fingerprint = fingerprint;
|
||||
this.signature = signature;
|
||||
}
|
||||
|
||||
public int Version
|
||||
{
|
||||
get { return version; }
|
||||
}
|
||||
|
||||
public int SignatureType
|
||||
{
|
||||
get { return signatureType; }
|
||||
}
|
||||
|
||||
/**
|
||||
* return the keyId
|
||||
* @return the keyId that created the signature.
|
||||
*/
|
||||
public long KeyId
|
||||
{
|
||||
get { return keyId; }
|
||||
}
|
||||
|
||||
/**
|
||||
* return the signature trailer that must be included with the data
|
||||
* to reconstruct the signature
|
||||
*
|
||||
* @return byte[]
|
||||
*/
|
||||
public byte[] GetSignatureTrailer()
|
||||
{
|
||||
byte[] trailer = null;
|
||||
|
||||
if (version == 3)
|
||||
{
|
||||
trailer = new byte[5];
|
||||
|
||||
long time = creationTime / 1000L;
|
||||
|
||||
trailer[0] = (byte)signatureType;
|
||||
trailer[1] = (byte)(time >> 24);
|
||||
trailer[2] = (byte)(time >> 16);
|
||||
trailer[3] = (byte)(time >> 8);
|
||||
trailer[4] = (byte)(time);
|
||||
}
|
||||
else
|
||||
{
|
||||
MemoryStream sOut = new MemoryStream();
|
||||
|
||||
sOut.WriteByte((byte)this.Version);
|
||||
sOut.WriteByte((byte)this.SignatureType);
|
||||
sOut.WriteByte((byte)this.KeyAlgorithm);
|
||||
sOut.WriteByte((byte)this.HashAlgorithm);
|
||||
|
||||
MemoryStream hOut = new MemoryStream();
|
||||
SignatureSubpacket[] hashed = this.GetHashedSubPackets();
|
||||
|
||||
for (int i = 0; i != hashed.Length; i++)
|
||||
{
|
||||
hashed[i].Encode(hOut);
|
||||
}
|
||||
|
||||
byte[] data = hOut.ToArray();
|
||||
|
||||
sOut.WriteByte((byte)(data.Length >> 8));
|
||||
sOut.WriteByte((byte)data.Length);
|
||||
sOut.Write(data, 0, data.Length);
|
||||
|
||||
byte[] hData = sOut.ToArray();
|
||||
|
||||
sOut.WriteByte((byte)this.Version);
|
||||
sOut.WriteByte((byte)0xff);
|
||||
sOut.WriteByte((byte)(hData.Length>> 24));
|
||||
sOut.WriteByte((byte)(hData.Length >> 16));
|
||||
sOut.WriteByte((byte)(hData.Length >> 8));
|
||||
sOut.WriteByte((byte)(hData.Length));
|
||||
|
||||
trailer = sOut.ToArray();
|
||||
}
|
||||
|
||||
return trailer;
|
||||
}
|
||||
|
||||
public PublicKeyAlgorithmTag KeyAlgorithm
|
||||
{
|
||||
get { return keyAlgorithm; }
|
||||
}
|
||||
|
||||
public HashAlgorithmTag HashAlgorithm
|
||||
{
|
||||
get { return hashAlgorithm; }
|
||||
}
|
||||
|
||||
/**
|
||||
* return the signature as a set of integers - note this is normalised to be the
|
||||
* ASN.1 encoding of what appears in the signature packet.
|
||||
*/
|
||||
public MPInteger[] GetSignature()
|
||||
{
|
||||
return signature;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the byte encoding of the signature section.
|
||||
* @return uninterpreted signature bytes.
|
||||
*/
|
||||
public byte[] GetSignatureBytes()
|
||||
{
|
||||
if (signatureEncoding != null)
|
||||
{
|
||||
return (byte[]) signatureEncoding.Clone();
|
||||
}
|
||||
|
||||
MemoryStream bOut = new MemoryStream();
|
||||
BcpgOutputStream bcOut = new BcpgOutputStream(bOut);
|
||||
|
||||
foreach (MPInteger sigObj in signature)
|
||||
{
|
||||
try
|
||||
{
|
||||
bcOut.WriteObject(sigObj);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new Exception("internal error: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
return bOut.ToArray();
|
||||
}
|
||||
|
||||
public SignatureSubpacket[] GetHashedSubPackets()
|
||||
{
|
||||
return hashedData;
|
||||
}
|
||||
|
||||
public SignatureSubpacket[] GetUnhashedSubPackets()
|
||||
{
|
||||
return unhashedData;
|
||||
}
|
||||
|
||||
/// <summary>Return the creation time in milliseconds since 1 Jan., 1970 UTC.</summary>
|
||||
public long CreationTime
|
||||
{
|
||||
get { return creationTime; }
|
||||
}
|
||||
|
||||
public override void Encode(
|
||||
BcpgOutputStream bcpgOut)
|
||||
{
|
||||
MemoryStream bOut = new MemoryStream();
|
||||
BcpgOutputStream pOut = new BcpgOutputStream(bOut);
|
||||
|
||||
pOut.WriteByte((byte) version);
|
||||
|
||||
if (version == 3 || version == 2)
|
||||
{
|
||||
pOut.Write(
|
||||
5, // the length of the next block
|
||||
(byte) signatureType);
|
||||
|
||||
pOut.WriteInt((int)(creationTime / 1000L));
|
||||
|
||||
pOut.WriteLong(keyId);
|
||||
|
||||
pOut.Write(
|
||||
(byte) keyAlgorithm,
|
||||
(byte) hashAlgorithm);
|
||||
}
|
||||
else if (version == 4)
|
||||
{
|
||||
pOut.Write(
|
||||
(byte) signatureType,
|
||||
(byte) keyAlgorithm,
|
||||
(byte) hashAlgorithm);
|
||||
|
||||
EncodeLengthAndData(pOut, GetEncodedSubpackets(hashedData));
|
||||
|
||||
EncodeLengthAndData(pOut, GetEncodedSubpackets(unhashedData));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IOException("unknown version: " + version);
|
||||
}
|
||||
|
||||
pOut.Write(fingerprint);
|
||||
|
||||
if (signature != null)
|
||||
{
|
||||
pOut.WriteObjects(signature);
|
||||
}
|
||||
else
|
||||
{
|
||||
pOut.Write(signatureEncoding);
|
||||
}
|
||||
|
||||
bcpgOut.WritePacket(PacketTag.Signature, bOut.ToArray(), true);
|
||||
}
|
||||
|
||||
private static void EncodeLengthAndData(
|
||||
BcpgOutputStream pOut,
|
||||
byte[] data)
|
||||
{
|
||||
pOut.WriteShort((short) data.Length);
|
||||
pOut.Write(data);
|
||||
}
|
||||
|
||||
private static byte[] GetEncodedSubpackets(
|
||||
SignatureSubpacket[] ps)
|
||||
{
|
||||
MemoryStream sOut = new MemoryStream();
|
||||
|
||||
foreach (SignatureSubpacket p in ps)
|
||||
{
|
||||
p.Encode(sOut);
|
||||
}
|
||||
|
||||
return sOut.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
76
iTechSharp/srcbc/bcpg/SignatureSubpacket.cs
Normal file
76
iTechSharp/srcbc/bcpg/SignatureSubpacket.cs
Normal file
@@ -0,0 +1,76 @@
|
||||
using System.IO;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/// <remarks>Basic type for a PGP Signature sub-packet.</remarks>
|
||||
public class SignatureSubpacket
|
||||
{
|
||||
private readonly SignatureSubpacketTag type;
|
||||
private readonly bool critical;
|
||||
|
||||
internal readonly byte[] data;
|
||||
|
||||
protected internal SignatureSubpacket(
|
||||
SignatureSubpacketTag type,
|
||||
bool critical,
|
||||
byte[] data)
|
||||
{
|
||||
this.type = type;
|
||||
this.critical = critical;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public SignatureSubpacketTag SubpacketType
|
||||
{
|
||||
get { return type; }
|
||||
}
|
||||
|
||||
public bool IsCritical()
|
||||
{
|
||||
return critical;
|
||||
}
|
||||
|
||||
/// <summary>Return the generic data making up the packet.</summary>
|
||||
public byte[] GetData()
|
||||
{
|
||||
return (byte[]) data.Clone();
|
||||
}
|
||||
|
||||
public void Encode(
|
||||
Stream os)
|
||||
{
|
||||
int bodyLen = data.Length + 1;
|
||||
|
||||
if (bodyLen < 192)
|
||||
{
|
||||
os.WriteByte((byte)bodyLen);
|
||||
}
|
||||
else if (bodyLen <= 8383)
|
||||
{
|
||||
bodyLen -= 192;
|
||||
|
||||
os.WriteByte((byte)(((bodyLen >> 8) & 0xff) + 192));
|
||||
os.WriteByte((byte)bodyLen);
|
||||
}
|
||||
else
|
||||
{
|
||||
os.WriteByte(0xff);
|
||||
os.WriteByte((byte)(bodyLen >> 24));
|
||||
os.WriteByte((byte)(bodyLen >> 16));
|
||||
os.WriteByte((byte)(bodyLen >> 8));
|
||||
os.WriteByte((byte)bodyLen);
|
||||
}
|
||||
|
||||
if (critical)
|
||||
{
|
||||
os.WriteByte((byte)(0x80 | (int) type));
|
||||
}
|
||||
else
|
||||
{
|
||||
os.WriteByte((byte) type);
|
||||
}
|
||||
|
||||
os.Write(data, 0, data.Length);
|
||||
}
|
||||
}
|
||||
}
|
30
iTechSharp/srcbc/bcpg/SignatureSubpacketTags.cs
Normal file
30
iTechSharp/srcbc/bcpg/SignatureSubpacketTags.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/**
|
||||
* Basic PGP signature sub-packet tag types.
|
||||
*/
|
||||
public enum SignatureSubpacketTag
|
||||
{
|
||||
CreationTime = 2, // signature creation time
|
||||
ExpireTime = 3, // signature expiration time
|
||||
Exportable = 4, // exportable certification
|
||||
TrustSig = 5, // trust signature
|
||||
RegExp = 6, // regular expression
|
||||
Revocable = 7, // revocable
|
||||
KeyExpireTime = 9, // key expiration time
|
||||
Placeholder = 10, // placeholder for backward compatibility
|
||||
PreferredSymmetricAlgorithms = 11, // preferred symmetric algorithms
|
||||
RevocationKey = 12, // revocation key
|
||||
IssuerKeyId = 16, // issuer key ID
|
||||
NotationData = 20, // notation data
|
||||
PreferredHashAlgorithms = 21, // preferred hash algorithms
|
||||
PreferredCompressionAlgorithms = 22, // preferred compression algorithms
|
||||
KeyServerPreferences = 23, // key server preferences
|
||||
PreferredKeyServer = 24, // preferred key server
|
||||
PrimaryUserId = 25, // primary user id
|
||||
PolicyUrl = 26, // policy URL
|
||||
KeyFlags = 27, // key flags
|
||||
SignerUserId = 28, // signer's user id
|
||||
RevocationReason = 29 // reason for revocation
|
||||
}
|
||||
}
|
88
iTechSharp/srcbc/bcpg/SignatureSubpacketsReader.cs
Normal file
88
iTechSharp/srcbc/bcpg/SignatureSubpacketsReader.cs
Normal file
@@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Bcpg.Sig;
|
||||
using Org.BouncyCastle.Utilities.IO;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/**
|
||||
* reader for signature sub-packets
|
||||
*/
|
||||
public class SignatureSubpacketsParser
|
||||
{
|
||||
private readonly Stream input;
|
||||
|
||||
public SignatureSubpacketsParser(
|
||||
Stream input)
|
||||
{
|
||||
this.input = input;
|
||||
}
|
||||
|
||||
public SignatureSubpacket ReadPacket()
|
||||
{
|
||||
int l = input.ReadByte();
|
||||
if (l < 0)
|
||||
return null;
|
||||
|
||||
int bodyLen = 0;
|
||||
if (l < 192)
|
||||
{
|
||||
bodyLen = l;
|
||||
}
|
||||
else if (l <= 223)
|
||||
{
|
||||
bodyLen = ((l - 192) << 8) + (input.ReadByte()) + 192;
|
||||
}
|
||||
else if (l == 255)
|
||||
{
|
||||
bodyLen = (input.ReadByte() << 24) | (input.ReadByte() << 16)
|
||||
| (input.ReadByte() << 8) | input.ReadByte();
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO Error?
|
||||
}
|
||||
|
||||
int tag = input.ReadByte();
|
||||
if (tag < 0)
|
||||
throw new EndOfStreamException("unexpected EOF reading signature sub packet");
|
||||
|
||||
byte[] data = new byte[bodyLen - 1];
|
||||
if (Streams.ReadFully(input, data) < data.Length)
|
||||
throw new EndOfStreamException();
|
||||
|
||||
bool isCritical = ((tag & 0x80) != 0);
|
||||
SignatureSubpacketTag type = (SignatureSubpacketTag)(tag & 0x7f);
|
||||
switch (type)
|
||||
{
|
||||
case SignatureSubpacketTag.CreationTime:
|
||||
return new SignatureCreationTime(isCritical, data);
|
||||
case SignatureSubpacketTag.KeyExpireTime:
|
||||
return new KeyExpirationTime(isCritical, data);
|
||||
case SignatureSubpacketTag.ExpireTime:
|
||||
return new SignatureExpirationTime(isCritical, data);
|
||||
case SignatureSubpacketTag.Revocable:
|
||||
return new Revocable(isCritical, data);
|
||||
case SignatureSubpacketTag.Exportable:
|
||||
return new Exportable(isCritical, data);
|
||||
case SignatureSubpacketTag.IssuerKeyId:
|
||||
return new IssuerKeyId(isCritical, data);
|
||||
case SignatureSubpacketTag.TrustSig:
|
||||
return new TrustSignature(isCritical, data);
|
||||
case SignatureSubpacketTag.PreferredCompressionAlgorithms:
|
||||
case SignatureSubpacketTag.PreferredHashAlgorithms:
|
||||
case SignatureSubpacketTag.PreferredSymmetricAlgorithms:
|
||||
return new PreferredAlgorithms(type, isCritical, data);
|
||||
case SignatureSubpacketTag.KeyFlags:
|
||||
return new KeyFlags(isCritical, data);
|
||||
case SignatureSubpacketTag.PrimaryUserId:
|
||||
return new PrimaryUserId(isCritical, data);
|
||||
case SignatureSubpacketTag.SignerUserId:
|
||||
return new SignerUserId(isCritical, data);
|
||||
case SignatureSubpacketTag.NotationData:
|
||||
return new NotationData(isCritical, data);
|
||||
}
|
||||
return new SignatureSubpacket(type, isCritical, data);
|
||||
}
|
||||
}
|
||||
}
|
15
iTechSharp/srcbc/bcpg/SymmetricEncDataPacket.cs
Normal file
15
iTechSharp/srcbc/bcpg/SymmetricEncDataPacket.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/// <remarks>Basic type for a symmetric key encrypted packet.</remarks>
|
||||
public class SymmetricEncDataPacket
|
||||
: InputStreamPacket
|
||||
{
|
||||
public SymmetricEncDataPacket(
|
||||
BcpgInputStream bcpgIn)
|
||||
: base(bcpgIn)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
18
iTechSharp/srcbc/bcpg/SymmetricEncIntegrityPacket.cs
Normal file
18
iTechSharp/srcbc/bcpg/SymmetricEncIntegrityPacket.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
public class SymmetricEncIntegrityPacket
|
||||
: InputStreamPacket
|
||||
{
|
||||
internal readonly int version;
|
||||
|
||||
internal SymmetricEncIntegrityPacket(
|
||||
BcpgInputStream bcpgIn)
|
||||
: base(bcpgIn)
|
||||
{
|
||||
version = bcpgIn.ReadByte();
|
||||
}
|
||||
}
|
||||
}
|
20
iTechSharp/srcbc/bcpg/SymmetricKeyAlgorithmTags.cs
Normal file
20
iTechSharp/srcbc/bcpg/SymmetricKeyAlgorithmTags.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/**
|
||||
* Basic tags for symmetric key algorithms
|
||||
*/
|
||||
public enum SymmetricKeyAlgorithmTag
|
||||
{
|
||||
Null = 0, // Plaintext or unencrypted data
|
||||
Idea = 1, // IDEA [IDEA]
|
||||
TripleDes = 2, // Triple-DES (DES-EDE, as per spec -168 bit key derived from 192)
|
||||
Cast5 = 3, // Cast5 (128 bit key, as per RFC 2144)
|
||||
Blowfish = 4, // Blowfish (128 bit key, 16 rounds) [Blowfish]
|
||||
Safer = 5, // Safer-SK128 (13 rounds) [Safer]
|
||||
Des = 6, // Reserved for DES/SK
|
||||
Aes128 = 7, // Reserved for AES with 128-bit key
|
||||
Aes192 = 8, // Reserved for AES with 192-bit key
|
||||
Aes256 = 9, // Reserved for AES with 256-bit key
|
||||
Twofish = 10 // Reserved for Twofish
|
||||
}
|
||||
}
|
91
iTechSharp/srcbc/bcpg/SymmetricKeyEncSessionPacket.cs
Normal file
91
iTechSharp/srcbc/bcpg/SymmetricKeyEncSessionPacket.cs
Normal file
@@ -0,0 +1,91 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/**
|
||||
* Basic type for a symmetric encrypted session key packet
|
||||
*/
|
||||
public class SymmetricKeyEncSessionPacket
|
||||
: ContainedPacket
|
||||
{
|
||||
private int version;
|
||||
private SymmetricKeyAlgorithmTag encAlgorithm;
|
||||
private S2k s2k;
|
||||
private readonly byte[] secKeyData;
|
||||
|
||||
public SymmetricKeyEncSessionPacket(
|
||||
BcpgInputStream bcpgIn)
|
||||
{
|
||||
version = bcpgIn.ReadByte();
|
||||
encAlgorithm = (SymmetricKeyAlgorithmTag) bcpgIn.ReadByte();
|
||||
|
||||
s2k = new S2k(bcpgIn);
|
||||
|
||||
secKeyData = bcpgIn.ReadAll();
|
||||
}
|
||||
|
||||
public SymmetricKeyEncSessionPacket(
|
||||
SymmetricKeyAlgorithmTag encAlgorithm,
|
||||
S2k s2k,
|
||||
byte[] secKeyData)
|
||||
{
|
||||
this.version = 4;
|
||||
this.encAlgorithm = encAlgorithm;
|
||||
this.s2k = s2k;
|
||||
this.secKeyData = secKeyData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public SymmetricKeyAlgorithmTag EncAlgorithm
|
||||
{
|
||||
get { return encAlgorithm; }
|
||||
}
|
||||
|
||||
/**
|
||||
* @return S2k
|
||||
*/
|
||||
public S2k S2k
|
||||
{
|
||||
get { return s2k; }
|
||||
}
|
||||
|
||||
/**
|
||||
* @return byte[]
|
||||
*/
|
||||
public byte[] GetSecKeyData()
|
||||
{
|
||||
return secKeyData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public int Version
|
||||
{
|
||||
get { return version; }
|
||||
}
|
||||
|
||||
public override void Encode(
|
||||
BcpgOutputStream bcpgOut)
|
||||
{
|
||||
MemoryStream bOut = new MemoryStream();
|
||||
BcpgOutputStream pOut = new BcpgOutputStream(bOut);
|
||||
|
||||
pOut.Write(
|
||||
(byte) version,
|
||||
(byte) encAlgorithm);
|
||||
|
||||
pOut.WriteObject(s2k);
|
||||
|
||||
if (secKeyData != null && secKeyData.Length > 0)
|
||||
{
|
||||
pOut.Write(secKeyData);
|
||||
}
|
||||
|
||||
bcpgOut.WritePacket(PacketTag.SymmetricKeyEncryptedSessionKey, bOut.ToArray(), true);
|
||||
}
|
||||
}
|
||||
}
|
43
iTechSharp/srcbc/bcpg/TrustPacket.cs
Normal file
43
iTechSharp/srcbc/bcpg/TrustPacket.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/// <summary>Basic type for a trust packet.</summary>
|
||||
public class TrustPacket
|
||||
: ContainedPacket
|
||||
{
|
||||
private readonly byte[] levelAndTrustAmount;
|
||||
|
||||
public TrustPacket(
|
||||
BcpgInputStream bcpgIn)
|
||||
{
|
||||
MemoryStream bOut = new MemoryStream();
|
||||
|
||||
int ch;
|
||||
while ((ch = bcpgIn.ReadByte()) >= 0)
|
||||
{
|
||||
bOut.WriteByte((byte) ch);
|
||||
}
|
||||
|
||||
levelAndTrustAmount = bOut.ToArray();
|
||||
}
|
||||
|
||||
public TrustPacket(
|
||||
int trustCode)
|
||||
{
|
||||
this.levelAndTrustAmount = new byte[]{ (byte) trustCode };
|
||||
}
|
||||
|
||||
public byte[] GetLevelAndTrustAmount()
|
||||
{
|
||||
return (byte[]) levelAndTrustAmount.Clone();
|
||||
}
|
||||
|
||||
public override void Encode(
|
||||
BcpgOutputStream bcpgOut)
|
||||
{
|
||||
bcpgOut.WritePacket(PacketTag.Trust, levelAndTrustAmount, true);
|
||||
}
|
||||
}
|
||||
}
|
59
iTechSharp/srcbc/bcpg/UserAttributePacket.cs
Normal file
59
iTechSharp/srcbc/bcpg/UserAttributePacket.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/**
|
||||
* Basic type for a user attribute packet.
|
||||
*/
|
||||
public class UserAttributePacket
|
||||
: ContainedPacket
|
||||
{
|
||||
private readonly UserAttributeSubpacket[] subpackets;
|
||||
|
||||
public UserAttributePacket(
|
||||
BcpgInputStream bcpgIn)
|
||||
{
|
||||
UserAttributeSubpacketsParser sIn = new UserAttributeSubpacketsParser(bcpgIn);
|
||||
UserAttributeSubpacket sub;
|
||||
|
||||
ArrayList v = new ArrayList();
|
||||
while ((sub = sIn.ReadPacket()) != null)
|
||||
{
|
||||
v.Add(sub);
|
||||
}
|
||||
|
||||
subpackets = new UserAttributeSubpacket[v.Count];
|
||||
|
||||
for (int i = 0; i != subpackets.Length; i++)
|
||||
{
|
||||
subpackets[i] = (UserAttributeSubpacket)v[i];
|
||||
}
|
||||
}
|
||||
|
||||
public UserAttributePacket(
|
||||
UserAttributeSubpacket[] subpackets)
|
||||
{
|
||||
this.subpackets = subpackets;
|
||||
}
|
||||
|
||||
public UserAttributeSubpacket[] GetSubpackets()
|
||||
{
|
||||
return subpackets;
|
||||
}
|
||||
|
||||
public override void Encode(
|
||||
BcpgOutputStream bcpgOut)
|
||||
{
|
||||
MemoryStream bOut = new MemoryStream();
|
||||
|
||||
for (int i = 0; i != subpackets.Length; i++)
|
||||
{
|
||||
subpackets[i].Encode(bOut);
|
||||
}
|
||||
|
||||
bcpgOut.WritePacket(PacketTag.UserAttribute, bOut.ToArray(), false);
|
||||
}
|
||||
}
|
||||
}
|
86
iTechSharp/srcbc/bcpg/UserAttributeSubpacket.cs
Normal file
86
iTechSharp/srcbc/bcpg/UserAttributeSubpacket.cs
Normal file
@@ -0,0 +1,86 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/**
|
||||
* Basic type for a user attribute sub-packet.
|
||||
*/
|
||||
public class UserAttributeSubpacket
|
||||
{
|
||||
private readonly UserAttributeSubpacketTag type;
|
||||
private readonly byte[] data;
|
||||
|
||||
internal UserAttributeSubpacket(
|
||||
UserAttributeSubpacketTag type,
|
||||
byte[] data)
|
||||
{
|
||||
this.type = type;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public UserAttributeSubpacketTag SubpacketType
|
||||
{
|
||||
get { return type; }
|
||||
}
|
||||
|
||||
/**
|
||||
* return the generic data making up the packet.
|
||||
*/
|
||||
public byte[] GetData()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
public void Encode(
|
||||
Stream os)
|
||||
{
|
||||
int bodyLen = data.Length + 1;
|
||||
|
||||
if (bodyLen < 192)
|
||||
{
|
||||
os.WriteByte((byte)bodyLen);
|
||||
}
|
||||
else if (bodyLen <= 8383)
|
||||
{
|
||||
bodyLen -= 192;
|
||||
|
||||
os.WriteByte((byte)(((bodyLen >> 8) & 0xff) + 192));
|
||||
os.WriteByte((byte)bodyLen);
|
||||
}
|
||||
else
|
||||
{
|
||||
os.WriteByte(0xff);
|
||||
os.WriteByte((byte)(bodyLen >> 24));
|
||||
os.WriteByte((byte)(bodyLen >> 16));
|
||||
os.WriteByte((byte)(bodyLen >> 8));
|
||||
os.WriteByte((byte)bodyLen);
|
||||
}
|
||||
|
||||
os.WriteByte((byte) type);
|
||||
os.Write(data, 0, data.Length);
|
||||
}
|
||||
|
||||
public override bool Equals(
|
||||
object obj)
|
||||
{
|
||||
if (obj == this)
|
||||
return true;
|
||||
|
||||
UserAttributeSubpacket other = obj as UserAttributeSubpacket;
|
||||
|
||||
if (other == null)
|
||||
return false;
|
||||
|
||||
return type == other.type
|
||||
&& Arrays.AreEqual(data, other.data);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return type.GetHashCode() ^ Arrays.GetHashCode(data);
|
||||
}
|
||||
}
|
||||
}
|
10
iTechSharp/srcbc/bcpg/UserAttributeSubpacketTags.cs
Normal file
10
iTechSharp/srcbc/bcpg/UserAttributeSubpacketTags.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/**
|
||||
* Basic PGP user attribute sub-packet tag types.
|
||||
*/
|
||||
public enum UserAttributeSubpacketTag
|
||||
{
|
||||
ImageAttribute = 1
|
||||
}
|
||||
}
|
63
iTechSharp/srcbc/bcpg/UserAttributeSubpacketsReader.cs
Normal file
63
iTechSharp/srcbc/bcpg/UserAttributeSubpacketsReader.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Bcpg.Attr;
|
||||
using Org.BouncyCastle.Utilities.IO;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/**
|
||||
* reader for user attribute sub-packets
|
||||
*/
|
||||
public class UserAttributeSubpacketsParser
|
||||
{
|
||||
private readonly Stream input;
|
||||
|
||||
public UserAttributeSubpacketsParser(
|
||||
Stream input)
|
||||
{
|
||||
this.input = input;
|
||||
}
|
||||
|
||||
public UserAttributeSubpacket ReadPacket()
|
||||
{
|
||||
int l = input.ReadByte();
|
||||
if (l < 0)
|
||||
return null;
|
||||
|
||||
int bodyLen = 0;
|
||||
if (l < 192)
|
||||
{
|
||||
bodyLen = l;
|
||||
}
|
||||
else if (l <= 223)
|
||||
{
|
||||
bodyLen = ((l - 192) << 8) + (input.ReadByte()) + 192;
|
||||
}
|
||||
else if (l == 255)
|
||||
{
|
||||
bodyLen = (input.ReadByte() << 24) | (input.ReadByte() << 16)
|
||||
| (input.ReadByte() << 8) | input.ReadByte();
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO Error?
|
||||
}
|
||||
|
||||
int tag = input.ReadByte();
|
||||
if (tag < 0)
|
||||
throw new EndOfStreamException("unexpected EOF reading user attribute sub packet");
|
||||
|
||||
byte[] data = new byte[bodyLen - 1];
|
||||
if (Streams.ReadFully(input, data) < data.Length)
|
||||
throw new EndOfStreamException();
|
||||
|
||||
UserAttributeSubpacketTag type = (UserAttributeSubpacketTag) tag;
|
||||
switch (type)
|
||||
{
|
||||
case UserAttributeSubpacketTag.ImageAttribute:
|
||||
return new ImageAttrib(data);
|
||||
}
|
||||
return new UserAttributeSubpacket(type, data);
|
||||
}
|
||||
}
|
||||
}
|
37
iTechSharp/srcbc/bcpg/UserIdPacket.cs
Normal file
37
iTechSharp/srcbc/bcpg/UserIdPacket.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg
|
||||
{
|
||||
/**
|
||||
* Basic type for a user ID packet.
|
||||
*/
|
||||
public class UserIdPacket
|
||||
: ContainedPacket
|
||||
{
|
||||
private readonly byte[] idData;
|
||||
|
||||
public UserIdPacket(
|
||||
BcpgInputStream bcpgIn)
|
||||
{
|
||||
this.idData = bcpgIn.ReadAll();
|
||||
}
|
||||
|
||||
public UserIdPacket(
|
||||
string id)
|
||||
{
|
||||
this.idData = Encoding.UTF8.GetBytes(id);
|
||||
}
|
||||
|
||||
public string GetId()
|
||||
{
|
||||
return Encoding.UTF8.GetString(idData, 0, idData.Length);
|
||||
}
|
||||
|
||||
public override void Encode(
|
||||
BcpgOutputStream bcpgOut)
|
||||
{
|
||||
bcpgOut.WritePacket(PacketTag.UserId, idData, true);
|
||||
}
|
||||
}
|
||||
}
|
68
iTechSharp/srcbc/bcpg/attr/ImageAttrib.cs
Normal file
68
iTechSharp/srcbc/bcpg/attr/ImageAttrib.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg.Attr
|
||||
{
|
||||
/// <remarks>Basic type for a image attribute packet.</remarks>
|
||||
public class ImageAttrib
|
||||
: UserAttributeSubpacket
|
||||
{
|
||||
public enum Format : byte
|
||||
{
|
||||
Jpeg = 1
|
||||
}
|
||||
|
||||
private static readonly byte[] Zeroes = new byte[12];
|
||||
|
||||
private int hdrLength;
|
||||
private int _version;
|
||||
private int _encoding;
|
||||
private byte[] imageData;
|
||||
|
||||
public ImageAttrib(
|
||||
byte[] data)
|
||||
: base(UserAttributeSubpacketTag.ImageAttribute, data)
|
||||
{
|
||||
hdrLength = ((data[1] & 0xff) << 8) | (data[0] & 0xff);
|
||||
_version = data[2] & 0xff;
|
||||
_encoding = data[3] & 0xff;
|
||||
|
||||
imageData = new byte[data.Length - hdrLength];
|
||||
Array.Copy(data, hdrLength, imageData, 0, imageData.Length);
|
||||
}
|
||||
|
||||
public ImageAttrib(
|
||||
Format imageType,
|
||||
byte[] imageData)
|
||||
: this(ToByteArray(imageType, imageData))
|
||||
{
|
||||
}
|
||||
|
||||
private static byte[] ToByteArray(
|
||||
Format imageType,
|
||||
byte[] imageData)
|
||||
{
|
||||
MemoryStream bOut = new MemoryStream();
|
||||
bOut.WriteByte(0x10); bOut.WriteByte(0x00); bOut.WriteByte(0x01);
|
||||
bOut.WriteByte((byte) imageType);
|
||||
bOut.Write(Zeroes, 0, Zeroes.Length);
|
||||
bOut.Write(imageData, 0, imageData.Length);
|
||||
return bOut.ToArray();
|
||||
}
|
||||
|
||||
public int Version
|
||||
{
|
||||
get { return _version; }
|
||||
}
|
||||
|
||||
public int Encoding
|
||||
{
|
||||
get { return _encoding; }
|
||||
}
|
||||
|
||||
public byte[] GetImageData()
|
||||
{
|
||||
return imageData;
|
||||
}
|
||||
}
|
||||
}
|
47
iTechSharp/srcbc/bcpg/sig/Exportable.cs
Normal file
47
iTechSharp/srcbc/bcpg/sig/Exportable.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
|
||||
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg.Sig
|
||||
{
|
||||
/**
|
||||
* packet giving signature creation time.
|
||||
*/
|
||||
public class Exportable
|
||||
: SignatureSubpacket
|
||||
{
|
||||
private static byte[] BooleanToByteArray(bool val)
|
||||
{
|
||||
byte[] data = new byte[1];
|
||||
|
||||
if (val)
|
||||
{
|
||||
data[0] = 1;
|
||||
return data;
|
||||
}
|
||||
else
|
||||
{
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
public Exportable(
|
||||
bool critical,
|
||||
byte[] data)
|
||||
: base(SignatureSubpacketTag.Exportable, critical, data)
|
||||
{
|
||||
}
|
||||
|
||||
public Exportable(
|
||||
bool critical,
|
||||
bool isExportable)
|
||||
: base(SignatureSubpacketTag.Exportable, critical, BooleanToByteArray(isExportable))
|
||||
{
|
||||
}
|
||||
|
||||
public bool IsExportable()
|
||||
{
|
||||
return data[0] != 0;
|
||||
}
|
||||
}
|
||||
}
|
61
iTechSharp/srcbc/bcpg/sig/IssuerKeyId.cs
Normal file
61
iTechSharp/srcbc/bcpg/sig/IssuerKeyId.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
|
||||
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg.Sig
|
||||
{
|
||||
/**
|
||||
* packet giving signature creation time.
|
||||
*/
|
||||
public class IssuerKeyId
|
||||
: SignatureSubpacket
|
||||
{
|
||||
protected static byte[] KeyIdToBytes(
|
||||
long keyId)
|
||||
{
|
||||
byte[] data = new byte[8];
|
||||
|
||||
data[0] = (byte)(keyId >> 56);
|
||||
data[1] = (byte)(keyId >> 48);
|
||||
data[2] = (byte)(keyId >> 40);
|
||||
data[3] = (byte)(keyId >> 32);
|
||||
data[4] = (byte)(keyId >> 24);
|
||||
data[5] = (byte)(keyId >> 16);
|
||||
data[6] = (byte)(keyId >> 8);
|
||||
data[7] = (byte)keyId;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public IssuerKeyId(
|
||||
bool critical,
|
||||
byte[] data)
|
||||
: base(SignatureSubpacketTag.IssuerKeyId, critical, data)
|
||||
{
|
||||
}
|
||||
|
||||
public IssuerKeyId(
|
||||
bool critical,
|
||||
long keyId)
|
||||
: base(SignatureSubpacketTag.IssuerKeyId, critical, KeyIdToBytes(keyId))
|
||||
{
|
||||
}
|
||||
|
||||
public long KeyId
|
||||
{
|
||||
get
|
||||
{
|
||||
long keyId = ((long)(data[0] & 0xff) << 56)
|
||||
| ((long)(data[1] & 0xff) << 48)
|
||||
| ((long)(data[2] & 0xff) << 40)
|
||||
| ((long)(data[3] & 0xff) << 32)
|
||||
| ((long)(data[4] & 0xff) << 24)
|
||||
| ((long)(data[5] & 0xff) << 16)
|
||||
| ((long)(data[6] & 0xff) << 8)
|
||||
| ((long)data[7] & 0xff);
|
||||
|
||||
return keyId;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
56
iTechSharp/srcbc/bcpg/sig/KeyExpirationTime.cs
Normal file
56
iTechSharp/srcbc/bcpg/sig/KeyExpirationTime.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
|
||||
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg.Sig
|
||||
{
|
||||
/**
|
||||
* packet giving time after creation at which the key expires.
|
||||
*/
|
||||
public class KeyExpirationTime
|
||||
: SignatureSubpacket
|
||||
{
|
||||
protected static byte[] TimeToBytes(
|
||||
long t)
|
||||
{
|
||||
byte[] data = new byte[4];
|
||||
|
||||
data[0] = (byte)(t >> 24);
|
||||
data[1] = (byte)(t >> 16);
|
||||
data[2] = (byte)(t >> 8);
|
||||
data[3] = (byte)t;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public KeyExpirationTime(
|
||||
bool critical,
|
||||
byte[] data)
|
||||
: base(SignatureSubpacketTag.KeyExpireTime, critical, data)
|
||||
{
|
||||
}
|
||||
|
||||
public KeyExpirationTime(
|
||||
bool critical,
|
||||
long seconds)
|
||||
: base(SignatureSubpacketTag.KeyExpireTime, critical, TimeToBytes(seconds))
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of seconds after creation time a key is valid for.
|
||||
*
|
||||
* @return second count for key validity.
|
||||
*/
|
||||
public long Time
|
||||
{
|
||||
get
|
||||
{
|
||||
long time = ((long)(data[0] & 0xff) << 24) | ((long)(data[1] & 0xff) << 16)
|
||||
| ((long)(data[2] & 0xff) << 8) | ((long)data[3] & 0xff);
|
||||
|
||||
return time;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
36
iTechSharp/srcbc/bcpg/sig/KeyFlags.cs
Normal file
36
iTechSharp/srcbc/bcpg/sig/KeyFlags.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg.Sig
|
||||
{
|
||||
/**
|
||||
* Packet holding the key flag values.
|
||||
*/
|
||||
public class KeyFlags
|
||||
: SignatureSubpacket
|
||||
{
|
||||
private static byte[] IntToByteArray(
|
||||
int v)
|
||||
{
|
||||
return new byte[]{ (byte) v };
|
||||
}
|
||||
|
||||
public KeyFlags(
|
||||
bool critical,
|
||||
byte[] data)
|
||||
: base(SignatureSubpacketTag.KeyFlags, critical, data)
|
||||
{
|
||||
}
|
||||
|
||||
public KeyFlags(
|
||||
bool critical,
|
||||
int flags)
|
||||
: base(SignatureSubpacketTag.KeyFlags, critical, IntToByteArray(flags))
|
||||
{
|
||||
}
|
||||
|
||||
public int Flags
|
||||
{
|
||||
get { return data[0] & 0xff; }
|
||||
}
|
||||
}
|
||||
}
|
101
iTechSharp/srcbc/bcpg/sig/NotationData.cs
Normal file
101
iTechSharp/srcbc/bcpg/sig/NotationData.cs
Normal file
@@ -0,0 +1,101 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg.Sig
|
||||
{
|
||||
/**
|
||||
* Class provided a NotationData object according to
|
||||
* RFC2440, Chapter 5.2.3.15. Notation Data
|
||||
*/
|
||||
public class NotationData
|
||||
: SignatureSubpacket
|
||||
{
|
||||
public const int HeaderFlagLength = 4;
|
||||
public const int HeaderNameLength = 2;
|
||||
public const int HeaderValueLength = 2;
|
||||
|
||||
public NotationData(
|
||||
bool critical,
|
||||
byte[] data)
|
||||
: base(SignatureSubpacketTag.NotationData, critical, data)
|
||||
{
|
||||
}
|
||||
|
||||
public NotationData(
|
||||
bool critical,
|
||||
bool humanReadable,
|
||||
string notationName,
|
||||
string notationValue)
|
||||
: base(SignatureSubpacketTag.NotationData, critical,
|
||||
createData(humanReadable, notationName, notationValue))
|
||||
{
|
||||
}
|
||||
|
||||
private static byte[] createData(
|
||||
bool humanReadable,
|
||||
string notationName,
|
||||
string notationValue)
|
||||
{
|
||||
MemoryStream os = new MemoryStream();
|
||||
|
||||
// (4 octets of flags, 2 octets of name length (M),
|
||||
// 2 octets of value length (N),
|
||||
// M octets of name data,
|
||||
// N octets of value data)
|
||||
|
||||
// flags
|
||||
os.WriteByte(humanReadable ? (byte)0x80 : (byte)0x00);
|
||||
os.WriteByte(0x0);
|
||||
os.WriteByte(0x0);
|
||||
os.WriteByte(0x0);
|
||||
|
||||
byte[] nameData, valueData = null;
|
||||
int nameLength, valueLength;
|
||||
|
||||
nameData = Encoding.UTF8.GetBytes(notationName);
|
||||
nameLength = System.Math.Min(nameData.Length, 0xFF);
|
||||
|
||||
valueData = Encoding.UTF8.GetBytes(notationValue);
|
||||
valueLength = System.Math.Min(valueData.Length, 0xFF);
|
||||
|
||||
// name length
|
||||
os.WriteByte((byte)(nameLength >> 8));
|
||||
os.WriteByte((byte)(nameLength >> 0));
|
||||
|
||||
// value length
|
||||
os.WriteByte((byte)(valueLength >> 8));
|
||||
os.WriteByte((byte)(valueLength >> 0));
|
||||
|
||||
// name
|
||||
os.Write(nameData, 0, nameLength);
|
||||
|
||||
// value
|
||||
os.Write(valueData, 0, valueLength);
|
||||
|
||||
return os.ToArray();
|
||||
}
|
||||
|
||||
public bool IsHumanReadable
|
||||
{
|
||||
get { return data[0] == (byte)0x80; }
|
||||
}
|
||||
|
||||
public string GetNotationName()
|
||||
{
|
||||
int nameLength = ((data[HeaderFlagLength] << 8) + (data[HeaderFlagLength + 1] << 0));
|
||||
int namePos = HeaderFlagLength + HeaderNameLength + HeaderValueLength;
|
||||
|
||||
return Encoding.UTF8.GetString(data, namePos, nameLength);
|
||||
}
|
||||
|
||||
public string GetNotationValue()
|
||||
{
|
||||
int nameLength = ((data[HeaderFlagLength] << 8) + (data[HeaderFlagLength + 1] << 0));
|
||||
int valueLength = ((data[HeaderFlagLength + HeaderNameLength] << 8) + (data[HeaderFlagLength + HeaderNameLength + 1] << 0));
|
||||
int valuePos = HeaderFlagLength + HeaderNameLength + HeaderValueLength + nameLength;
|
||||
|
||||
return Encoding.UTF8.GetString(data, valuePos, valueLength);
|
||||
}
|
||||
}
|
||||
}
|
54
iTechSharp/srcbc/bcpg/sig/PreferredAlgorithms.cs
Normal file
54
iTechSharp/srcbc/bcpg/sig/PreferredAlgorithms.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using System;
|
||||
|
||||
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg.Sig
|
||||
{
|
||||
/**
|
||||
* packet giving signature creation time.
|
||||
*/
|
||||
public class PreferredAlgorithms
|
||||
: SignatureSubpacket
|
||||
{
|
||||
private static byte[] IntToByteArray(
|
||||
int[] v)
|
||||
{
|
||||
byte[] data = new byte[v.Length];
|
||||
|
||||
for (int i = 0; i != v.Length; i++)
|
||||
{
|
||||
data[i] = (byte)v[i];
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public PreferredAlgorithms(
|
||||
SignatureSubpacketTag type,
|
||||
bool critical,
|
||||
byte[] data)
|
||||
: base(type, critical, data)
|
||||
{
|
||||
}
|
||||
|
||||
public PreferredAlgorithms(
|
||||
SignatureSubpacketTag type,
|
||||
bool critical,
|
||||
int[] preferences)
|
||||
: base(type, critical, IntToByteArray(preferences))
|
||||
{
|
||||
}
|
||||
|
||||
public int[] GetPreferences()
|
||||
{
|
||||
int[] v = new int[data.Length];
|
||||
|
||||
for (int i = 0; i != v.Length; i++)
|
||||
{
|
||||
v[i] = data[i] & 0xff;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
}
|
||||
}
|
48
iTechSharp/srcbc/bcpg/sig/PrimaryUserId.cs
Normal file
48
iTechSharp/srcbc/bcpg/sig/PrimaryUserId.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
|
||||
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg.Sig
|
||||
{
|
||||
/**
|
||||
* packet giving whether or not the signature is signed using the primary user ID for the key.
|
||||
*/
|
||||
public class PrimaryUserId
|
||||
: SignatureSubpacket
|
||||
{
|
||||
private static byte[] BooleanToByteArray(
|
||||
bool val)
|
||||
{
|
||||
byte[] data = new byte[1];
|
||||
|
||||
if (val)
|
||||
{
|
||||
data[0] = 1;
|
||||
return data;
|
||||
}
|
||||
else
|
||||
{
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
public PrimaryUserId(
|
||||
bool critical,
|
||||
byte[] data)
|
||||
: base(SignatureSubpacketTag.PrimaryUserId, critical, data)
|
||||
{
|
||||
}
|
||||
|
||||
public PrimaryUserId(
|
||||
bool critical,
|
||||
bool isPrimaryUserId)
|
||||
: base(SignatureSubpacketTag.PrimaryUserId, critical, BooleanToByteArray(isPrimaryUserId))
|
||||
{
|
||||
}
|
||||
|
||||
public bool IsPrimaryUserId()
|
||||
{
|
||||
return data[0] != 0;
|
||||
}
|
||||
}
|
||||
}
|
48
iTechSharp/srcbc/bcpg/sig/Revocable.cs
Normal file
48
iTechSharp/srcbc/bcpg/sig/Revocable.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
|
||||
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg.Sig
|
||||
{
|
||||
/**
|
||||
* packet giving whether or not is revocable.
|
||||
*/
|
||||
public class Revocable
|
||||
: SignatureSubpacket
|
||||
{
|
||||
private static byte[] BooleanToByteArray(
|
||||
bool value)
|
||||
{
|
||||
byte[] data = new byte[1];
|
||||
|
||||
if (value)
|
||||
{
|
||||
data[0] = 1;
|
||||
return data;
|
||||
}
|
||||
else
|
||||
{
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
public Revocable(
|
||||
bool critical,
|
||||
byte[] data)
|
||||
: base(SignatureSubpacketTag.Revocable, critical, data)
|
||||
{
|
||||
}
|
||||
|
||||
public Revocable(
|
||||
bool critical,
|
||||
bool isRevocable)
|
||||
: base(SignatureSubpacketTag.Revocable, critical, BooleanToByteArray(isRevocable))
|
||||
{
|
||||
}
|
||||
|
||||
public bool IsRevocable()
|
||||
{
|
||||
return data[0] != 0;
|
||||
}
|
||||
}
|
||||
}
|
47
iTechSharp/srcbc/bcpg/sig/SignatureCreationTime.cs
Normal file
47
iTechSharp/srcbc/bcpg/sig/SignatureCreationTime.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
|
||||
using Org.BouncyCastle.Utilities.Date;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg.Sig
|
||||
{
|
||||
/**
|
||||
* packet giving signature creation time.
|
||||
*/
|
||||
public class SignatureCreationTime
|
||||
: SignatureSubpacket
|
||||
{
|
||||
protected static byte[] TimeToBytes(
|
||||
DateTime time)
|
||||
{
|
||||
long t = DateTimeUtilities.DateTimeToUnixMs(time) / 1000L;
|
||||
byte[] data = new byte[4];
|
||||
data[0] = (byte)(t >> 24);
|
||||
data[1] = (byte)(t >> 16);
|
||||
data[2] = (byte)(t >> 8);
|
||||
data[3] = (byte)t;
|
||||
return data;
|
||||
}
|
||||
public SignatureCreationTime(
|
||||
bool critical,
|
||||
byte[] data)
|
||||
: base(SignatureSubpacketTag.CreationTime, critical, data)
|
||||
{
|
||||
}
|
||||
public SignatureCreationTime(
|
||||
bool critical,
|
||||
DateTime date)
|
||||
: base(SignatureSubpacketTag.CreationTime, critical, TimeToBytes(date))
|
||||
{
|
||||
}
|
||||
public DateTime GetTime()
|
||||
{
|
||||
long time = (long)(
|
||||
((uint)data[0] << 24)
|
||||
| ((uint)data[1] << 16)
|
||||
| ((uint)data[2] << 8)
|
||||
| ((uint)data[3])
|
||||
);
|
||||
return DateTimeUtilities.UnixMsToDateTime(time * 1000L);
|
||||
}
|
||||
}
|
||||
}
|
54
iTechSharp/srcbc/bcpg/sig/SignatureExpirationTime.cs
Normal file
54
iTechSharp/srcbc/bcpg/sig/SignatureExpirationTime.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using System;
|
||||
|
||||
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg.Sig
|
||||
{
|
||||
/**
|
||||
* packet giving signature expiration time.
|
||||
*/
|
||||
public class SignatureExpirationTime
|
||||
: SignatureSubpacket
|
||||
{
|
||||
protected static byte[] TimeToBytes(
|
||||
long t)
|
||||
{
|
||||
byte[] data = new byte[4];
|
||||
|
||||
data[0] = (byte)(t >> 24);
|
||||
data[1] = (byte)(t >> 16);
|
||||
data[2] = (byte)(t >> 8);
|
||||
data[3] = (byte)t;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public SignatureExpirationTime(
|
||||
bool critical,
|
||||
byte[] data)
|
||||
: base(SignatureSubpacketTag.ExpireTime, critical, data)
|
||||
{
|
||||
}
|
||||
|
||||
public SignatureExpirationTime(
|
||||
bool critical,
|
||||
long seconds)
|
||||
: base(SignatureSubpacketTag.ExpireTime, critical, TimeToBytes(seconds))
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* return time in seconds before signature expires after creation time.
|
||||
*/
|
||||
public long Time
|
||||
{
|
||||
get
|
||||
{
|
||||
long time = ((long)(data[0] & 0xff) << 24) | ((long)(data[1] & 0xff) << 16)
|
||||
| ((long)(data[2] & 0xff) << 8) | ((long)data[3] & 0xff);
|
||||
|
||||
return time;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
52
iTechSharp/srcbc/bcpg/sig/SignerUserId.cs
Normal file
52
iTechSharp/srcbc/bcpg/sig/SignerUserId.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using System;
|
||||
|
||||
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg.Sig
|
||||
{
|
||||
/**
|
||||
* packet giving the User ID of the signer.
|
||||
*/
|
||||
public class SignerUserId
|
||||
: SignatureSubpacket
|
||||
{
|
||||
private static byte[] UserIdToBytes(
|
||||
string id)
|
||||
{
|
||||
byte[] idData = new byte[id.Length];
|
||||
|
||||
for (int i = 0; i != id.Length; i++)
|
||||
{
|
||||
idData[i] = (byte)id[i];
|
||||
}
|
||||
|
||||
return idData;
|
||||
}
|
||||
|
||||
public SignerUserId(
|
||||
bool critical,
|
||||
byte[] data)
|
||||
: base(SignatureSubpacketTag.SignerUserId, critical, data)
|
||||
{
|
||||
}
|
||||
|
||||
public SignerUserId(
|
||||
bool critical,
|
||||
string userId)
|
||||
: base(SignatureSubpacketTag.SignerUserId, critical, UserIdToBytes(userId))
|
||||
{
|
||||
}
|
||||
|
||||
public string GetId()
|
||||
{
|
||||
char[] chars = new char[data.Length];
|
||||
|
||||
for (int i = 0; i != chars.Length; i++)
|
||||
{
|
||||
chars[i] = (char)(data[i] & 0xff);
|
||||
}
|
||||
|
||||
return new string(chars);
|
||||
}
|
||||
}
|
||||
}
|
56
iTechSharp/srcbc/bcpg/sig/TrustSignature.cs
Normal file
56
iTechSharp/srcbc/bcpg/sig/TrustSignature.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
|
||||
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg.Sig
|
||||
{
|
||||
/**
|
||||
* packet giving signature creation time.
|
||||
*/
|
||||
public class TrustSignature
|
||||
: SignatureSubpacket
|
||||
{
|
||||
private static byte[] IntToByteArray(
|
||||
int v1,
|
||||
int v2)
|
||||
{
|
||||
byte[] data = new byte[2];
|
||||
|
||||
data[0] = (byte)v1;
|
||||
data[1] = (byte)v2;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public TrustSignature(
|
||||
bool critical,
|
||||
byte[] data)
|
||||
: base(SignatureSubpacketTag.TrustSig, critical, data)
|
||||
{
|
||||
}
|
||||
|
||||
public TrustSignature(
|
||||
bool critical,
|
||||
int depth,
|
||||
int trustAmount)
|
||||
: base(SignatureSubpacketTag.TrustSig, critical, IntToByteArray(depth, trustAmount))
|
||||
{
|
||||
}
|
||||
|
||||
public int Depth
|
||||
{
|
||||
get
|
||||
{
|
||||
return data[0] & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
public int TrustAmount
|
||||
{
|
||||
get
|
||||
{
|
||||
return data[1] & 0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user