BouncyCastle update.

git-svn-id: svn://svn.code.sf.net/p/itextsharp/code/trunk@11 820d3149-562b-4f88-9aa4-a8e61a3485cf
master
psoares33 2008-08-11 22:44:58 +00:00
parent c4e9a9ce5f
commit 4141622d84
38 changed files with 1432 additions and 707 deletions

View File

@ -4357,6 +4357,11 @@
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "srcbc\cms\PKCS5Scheme2UTF8PBEKey.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "srcbc\cms\RecipientId.cs"
SubType = "Code"
@ -6022,6 +6027,11 @@
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "srcbc\pkcs\PKCS12StoreBuilder.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "srcbc\pkcs\PrivateKeyInfoFactory.cs"
SubType = "Code"

View File

@ -1,7 +1,9 @@
using System;
using System.Collections;
using System.Globalization;
using System.Text;
using Org.BouncyCastle.Utilities.Net;
using NetUtils = Org.BouncyCastle.Utilities.Net;
namespace Org.BouncyCastle.Asn1.X509
{
@ -95,7 +97,7 @@ namespace Org.BouncyCastle.Asn1.X509
}
/**
* Create a GeneralName for the given tag from the passed in String.
* Create a GeneralName for the given tag from the passed in string.
* <p>
* This constructor can handle:
* <ul>
@ -139,10 +141,11 @@ namespace Org.BouncyCastle.Asn1.X509
}
else if (tag == IPAddress)
{
if (!Org.BouncyCastle.Utilities.Net.IPAddress.IsValid(name))
byte[] enc = toGeneralNameEncoding(name);
if (enc == null)
throw new ArgumentException("IP Address is invalid", "name");
this.obj = new DerOctetString(Encoding.UTF8.GetBytes(name));
this.obj = new DerOctetString(enc);
}
else
{
@ -231,10 +234,173 @@ namespace Org.BouncyCastle.Asn1.X509
return buf.ToString();
}
private byte[] toGeneralNameEncoding(
string ip)
{
if (NetUtils.IPAddress.IsValidIPv6WithNetmask(ip) || NetUtils.IPAddress.IsValidIPv6(ip))
{
int slashIndex = ip.IndexOf('/');
if (slashIndex < 0)
{
byte[] addr = new byte[16];
int[] parsedIp = parseIPv6(ip);
copyInts(parsedIp, addr, 0);
return addr;
}
else
{
byte[] addr = new byte[32];
int[] parsedIp = parseIPv6(ip.Substring(0, slashIndex));
copyInts(parsedIp, addr, 0);
string mask = ip.Substring(slashIndex + 1);
if (mask.IndexOf(':') > 0)
{
parsedIp = parseIPv6(mask);
}
else
{
parsedIp = parseMask(mask);
}
copyInts(parsedIp, addr, 16);
return addr;
}
}
else if (NetUtils.IPAddress.IsValidIPv4WithNetmask(ip) || NetUtils.IPAddress.IsValidIPv4(ip))
{
int slashIndex = ip.IndexOf('/');
if (slashIndex < 0)
{
byte[] addr = new byte[4];
parseIPv4(ip, addr, 0);
return addr;
}
else
{
byte[] addr = new byte[8];
parseIPv4(ip.Substring(0, slashIndex), addr, 0);
string mask = ip.Substring(slashIndex + 1);
if (mask.IndexOf('.') > 0)
{
parseIPv4(mask, addr, 4);
}
else
{
parseIPv4Mask(mask, addr, 4);
}
return addr;
}
}
return null;
}
private void parseIPv4Mask(string mask, byte[] addr, int offset)
{
int maskVal = Int32.Parse(mask);
for (int i = 0; i != maskVal; i++)
{
addr[(i / 8) + offset] |= (byte)(1 << (i % 8));
}
}
private void parseIPv4(string ip, byte[] addr, int offset)
{
foreach (string token in ip.Split('.', '/'))
{
addr[offset++] = (byte)Int32.Parse(token);
}
}
private int[] parseMask(string mask)
{
int[] res = new int[8];
int maskVal = Int32.Parse(mask);
for (int i = 0; i != maskVal; i++)
{
res[i / 16] |= 1 << (i % 16);
}
return res;
}
private void copyInts(int[] parsedIp, byte[] addr, int offSet)
{
for (int i = 0; i != parsedIp.Length; i++)
{
addr[(i * 2) + offSet] = (byte)(parsedIp[i] >> 8);
addr[(i * 2 + 1) + offSet] = (byte)parsedIp[i];
}
}
private int[] parseIPv6(string ip)
{
if (ip.StartsWith("::"))
{
ip = ip.Substring(1);
}
else if (ip.EndsWith("::"))
{
ip = ip.Substring(0, ip.Length - 1);
}
IEnumerator sEnum = ip.Split(':').GetEnumerator();
int index = 0;
int[] val = new int[8];
int doubleColon = -1;
while (sEnum.MoveNext())
{
string e = (string) sEnum.Current;
if (e.Length == 0)
{
doubleColon = index;
val[index++] = 0;
}
else
{
if (e.IndexOf('.') < 0)
{
val[index++] = Int32.Parse(e, NumberStyles.AllowHexSpecifier);
}
else
{
string[] tokens = e.Split('.');
val[index++] = (Int32.Parse(tokens[0]) << 8) | Int32.Parse(tokens[1]);
val[index++] = (Int32.Parse(tokens[2]) << 8) | Int32.Parse(tokens[3]);
}
}
}
if (index != val.Length)
{
Array.Copy(val, doubleColon, val, val.Length - (index - doubleColon), index - doubleColon);
for (int i = doubleColon; i != val.Length - (index - doubleColon); i++)
{
val[i] = 0;
}
}
return val;
}
public override Asn1Object ToAsn1Object()
{
// Explicitly tagged if DirectoryName
return new DerTaggedObject(tag == 4, tag, obj);
return new DerTaggedObject(tag == DirectoryName, tag, obj);
}
}
}

View File

@ -988,9 +988,7 @@ namespace Org.BouncyCastle.Asn1.X509
bool reverse,
Hashtable oidSymbols)
{
StringBuilder buf = new StringBuilder();
ArrayList components = new ArrayList();
bool first = true;
StringBuilder ava = null;
@ -1015,33 +1013,18 @@ namespace Org.BouncyCastle.Asn1.X509
if (reverse)
{
for (int i = components.Count - 1; i >= 0; i--)
{
if (first)
{
first = false;
}
else
{
buf.Append(',');
}
buf.Append(components[i].ToString());
}
components.Reverse();
}
else
{
for (int i = 0; i < components.Count; i++)
{
if (first)
{
first = false;
}
else
{
buf.Append(',');
}
StringBuilder buf = new StringBuilder();
if (components.Count > 0)
{
buf.Append(components[0].ToString());
for (int i = 1; i < components.Count; ++i)
{
buf.Append(',');
buf.Append(components[i].ToString());
}
}

View File

@ -23,7 +23,14 @@ namespace Org.BouncyCastle.Bcpg
internal SecretKeyPacket(
BcpgInputStream bcpgIn)
{
pubKeyPacket = new PublicKeyPacket(bcpgIn);
if (this is SecretSubkeyPacket)
{
pubKeyPacket = new PublicSubkeyPacket(bcpgIn);
}
else
{
pubKeyPacket = new PublicKeyPacket(bcpgIn);
}
s2kUsage = bcpgIn.ReadByte();

View File

@ -1,5 +1,7 @@
using System;
using Org.BouncyCastle.Math;
namespace Org.BouncyCastle.Bcpg.Sig
{
/**
@ -8,11 +10,33 @@ namespace Org.BouncyCastle.Bcpg.Sig
public class KeyFlags
: SignatureSubpacket
{
public const int CertifyOther = 0x01;
public const int SignData = 0x02;
public const int EncryptComms = 0x04;
public const int EncryptStorage = 0x08;
public const int Split = 0x10;
public const int Authentication = 0x20;
public const int Shared = 0x80;
private static byte[] IntToByteArray(
int v)
{
return new byte[]{ (byte) v };
}
byte[] tmp = new byte[4];
int size = 0;
for (int i = 0; i != 4; i++)
{
tmp[i] = (byte)(v >> (i * 8));
if (tmp[i] != 0)
{
size = i;
}
}
byte[] data = new byte[size + 1];
Array.Copy(tmp, 0, data, 0, data.Length);
return data;
}
public KeyFlags(
bool critical,
@ -28,9 +52,23 @@ namespace Org.BouncyCastle.Bcpg.Sig
{
}
/// <summary>
/// Return the flag values contained in the first 4 octets (note: at the moment
/// the standard only uses the first one).
/// </summary>
public int Flags
{
get { return data[0] & 0xff; }
get
{
int flags = 0;
for (int i = 0; i != data.Length; i++)
{
flags |= (data[i] & 0xff) << (i * 8);
}
return flags;
}
}
}
}

View File

@ -244,17 +244,21 @@ namespace Org.BouncyCastle.Cms
return crlStore;
}
/**
* Return the a string representation of the OID associated with the
* encapsulated content info structure carried in the signed data.
*
* @return the OID for the content type.
*/
[Obsolete("Use 'SignedContentType' property instead.")]
public string SignedContentTypeOid
{
get { return signedData.EncapContentInfo.ContentType.Id; }
}
/// <summary>
/// Return the <c>DerObjectIdentifier</c> associated with the encapsulated
/// content info structure carried in the signed data.
/// </summary>
public DerObjectIdentifier SignedContentType
{
get { return signedData.EncapContentInfo.ContentType; }
}
public CmsProcessable SignedContent
{
get { return signedContent; }

View File

@ -220,9 +220,10 @@ namespace Org.BouncyCastle.Cms
public void AddSigners(
SignerInformationStore signerStore)
{
foreach (object o in signerStore.GetSigners())
foreach (SignerInformation o in signerStore.GetSigners())
{
_signers.Add(o);
AddSignerCallback(o);
}
}
@ -236,5 +237,10 @@ namespace Org.BouncyCastle.Cms
{
return new Hashtable(_digests);
}
internal virtual void AddSignerCallback(
SignerInformation si)
{
}
}
}

View File

@ -6,6 +6,9 @@ using Org.BouncyCastle.Crypto.Parameters;
namespace Org.BouncyCastle.Cms
{
/// <summary>
/// PKCS5 scheme-2 - password converted to bytes assuming ASCII.
/// </summary>
public class Pkcs5Scheme2PbeKey
: CmsPbeKey
{

View File

@ -0,0 +1,38 @@
using System;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
namespace Org.BouncyCastle.Cms
{
/**
* PKCS5 scheme-2 - password converted to bytes using UTF-8.
*/
public class Pkcs5Scheme2Utf8PbeKey
: CmsPbeKey
{
public Pkcs5Scheme2Utf8PbeKey(
string password,
byte[] salt,
int iterationCount)
: base(password, salt, iterationCount)
{
}
internal override KeyParameter GetEncoded(
string algorithmOid)
{
Pkcs5S2ParametersGenerator gen = new Pkcs5S2ParametersGenerator();
gen.Init(
PbeParametersGenerator.Pkcs5PasswordToUtf8Bytes(this.Password),
this.Salt,
this.IterationCount);
return (KeyParameter) gen.GenerateDerivedParameters(
algorithmOid,
CmsEnvelopedHelper.Instance.GetKeySize(algorithmOid));
}
}
}

View File

@ -31,6 +31,20 @@ namespace Org.BouncyCastle.Cms
this._rid = new RecipientID();
}
/**
* return the object identifier for the key derivation algorithm, or null
* if there is none present.
*
* @return OID for key derivation algorithm, if present.
*/
public virtual AlgorithmIdentifier KeyDerivationAlgorithm
{
get
{
return _info.KeyDerivationAlgorithm;
}
}
/**
* decrypt the content and return an input stream.
*/

View File

@ -136,6 +136,25 @@ namespace Org.BouncyCastle.Crypto
return Encoding.ASCII.GetBytes(password);
}
/**
* converts a password to a byte array according to the scheme in
* PKCS5 (UTF-8, no padding)
*
* @param password a character array reqpresenting the password.
* @return a byte array representing the password.
*/
public static byte[] Pkcs5PasswordToUtf8Bytes(
char[] password)
{
return Encoding.UTF8.GetBytes(password);
}
public static byte[] Pkcs5PasswordToUtf8Bytes(
string password)
{
return Encoding.UTF8.GetBytes(password);
}
/**
* converts a password to a byte array according to the scheme in
* Pkcs12 (unicode, big endian, 2 zero pad bytes at the end).

View File

@ -14,6 +14,7 @@ namespace Org.BouncyCastle.Crypto.Encodings
{
private byte[] defHash;
private IDigest hash;
private IDigest mgf1Hash;
private IAsymmetricBlockCipher engine;
private SecureRandom random;
@ -36,9 +37,19 @@ namespace Org.BouncyCastle.Crypto.Encodings
IAsymmetricBlockCipher cipher,
IDigest hash,
byte[] encodingParams)
: this(cipher, hash, hash, encodingParams)
{
}
public OaepEncoding(
IAsymmetricBlockCipher cipher,
IDigest hash,
IDigest mgf1Hash,
byte[] encodingParams)
{
this.engine = cipher;
this.hash = hash;
this.mgf1Hash = mgf1Hash;
this.defHash = new byte[hash.GetDigestSize()];
if (encodingParams != null)
@ -191,7 +202,7 @@ namespace Org.BouncyCastle.Crypto.Encodings
int inLen)
{
byte[] data = engine.ProcessBlock(inBytes, inOff, inLen);
byte[] block = null;
byte[] block;
//
// as we may have zeros in our leading bytes for the block we produced
@ -298,7 +309,7 @@ namespace Org.BouncyCastle.Crypto.Encodings
int length)
{
byte[] mask = new byte[length];
byte[] hashBuf = new byte[defHash.Length];
byte[] hashBuf = new byte[mgf1Hash.GetDigestSize()];
byte[] C = new byte[4];
int counter = 0;
@ -308,23 +319,23 @@ namespace Org.BouncyCastle.Crypto.Encodings
{
ItoOSP(counter, C);
hash.BlockUpdate(Z, zOff, zLen);
hash.BlockUpdate(C, 0, C.Length);
hash.DoFinal(hashBuf, 0);
mgf1Hash.BlockUpdate(Z, zOff, zLen);
mgf1Hash.BlockUpdate(C, 0, C.Length);
mgf1Hash.DoFinal(hashBuf, 0);
Array.Copy(hashBuf, 0, mask, counter * defHash.Length, defHash.Length);
Array.Copy(hashBuf, 0, mask, counter * hashBuf.Length, hashBuf.Length);
}
while (++counter < (length / defHash.Length));
while (++counter < (length / hashBuf.Length));
if ((counter * defHash.Length) < length)
if ((counter * hashBuf.Length) < length)
{
ItoOSP(counter, C);
hash.BlockUpdate(Z, zOff, zLen);
hash.BlockUpdate(C, 0, C.Length);
hash.DoFinal(hashBuf, 0);
mgf1Hash.BlockUpdate(Z, zOff, zLen);
mgf1Hash.BlockUpdate(C, 0, C.Length);
mgf1Hash.DoFinal(hashBuf, 0);
Array.Copy(hashBuf, 0, mask, counter * defHash.Length, mask.Length - (counter * defHash.Length));
Array.Copy(hashBuf, 0, mask, counter * hashBuf.Length, mask.Length - (counter * hashBuf.Length));
}
return mask;

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,5 @@
#if INCLUDE_IDEA
using System;
using Org.BouncyCastle.Crypto.Parameters;
@ -15,7 +17,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* It can be found at ftp://ftp.funet.fi/pub/crypt/cryptography/symmetric/idea/
* </p>
* <p>
* Note: This algorithm is patented in the USA, Japan, and Europe including
* Note 1: This algorithm is patented in the USA, Japan, and Europe including
* at least Austria, France, Germany, Italy, Netherlands, Spain, Sweden, Switzerland
* and the United Kingdom. Non-commercial use is free, however any commercial
* products are liable for royalties. Please see
@ -23,6 +25,10 @@ namespace Org.BouncyCastle.Crypto.Engines
* further details. This announcement has been included at the request of
* the patent holders.
* </p>
* <p>
* Note 2: Due to the requests concerning the above, this algorithm is now only
* included in the extended assembly. It is not included in the default distributions.
* </p>
*/
public class IdeaEngine
: IBlockCipher
@ -331,3 +337,5 @@ namespace Org.BouncyCastle.Crypto.Engines
}
}
}
#endif

View File

@ -14,15 +14,15 @@ namespace Org.BouncyCastle.Crypto.Engines
rounds = 32,
block_size = 8,
key_size = 16,
delta = unchecked((int) 0x9E3779B9),
d_sum = unchecked((int) 0xC6EF3720); // sum on decrypt
delta = unchecked((int) 0x9E3779B9);
/*
* the expanded key array of 4 subkeys
*/
private int[] _S = new int[4];
private bool _initialised;
private bool _forEncryption;
private uint[] _S = new uint[4],
_sum0 = new uint[32],
_sum1 = new uint[32];
private bool _initialised, _forEncryption;
/**
* Create an instance of the TEA encryption algorithm
@ -106,10 +106,18 @@ namespace Org.BouncyCastle.Crypto.Engines
private void setKey(
byte[] key)
{
_S[0] = bytesToInt(key, 0);
_S[1] = bytesToInt(key, 4);
_S[2] = bytesToInt(key, 8);
_S[3] = bytesToInt(key, 12);
int i, j;
for (i = j = 0; i < 4; i++,j+=4)
{
_S[i] = bytesToUint(key, j);
}
for (i = j = 0; i < rounds; i++)
{
_sum0[i] = ((uint)j + _S[j & 3]);
j += delta;
_sum1[i] = ((uint)j + _S[j >> 11 & 3]);
}
}
private int encryptBlock(
@ -119,20 +127,17 @@ namespace Org.BouncyCastle.Crypto.Engines
int outOff)
{
// Pack bytes into integers
int v0 = bytesToInt(inBytes, inOff);
int v1 = bytesToInt(inBytes, inOff + 4);
uint v0 = bytesToUint(inBytes, inOff);
uint v1 = bytesToUint(inBytes, inOff + 4);
int sum = 0;
for (int i = 0; i != rounds; i++)
for (int i = 0; i < rounds; i++)
{
v0 += ((v1 << 4 ^ (int)((uint)v1 >> 5)) + v1) ^ (sum + _S[sum & 3]);
sum += delta;
v1 += ((v0 << 4 ^ (int)((uint)v0 >> 5)) + v0) ^ (sum + _S[(int)((uint)sum >> 11) & 3]);
v0 += ((v1 << 4 ^ v1 >> 5) + v1) ^ _sum0[i];
v1 += ((v0 << 4 ^ v0 >> 5) + v0) ^ _sum1[i];
}
unpackInt(v0, outBytes, outOff);
unpackInt(v1, outBytes, outOff + 4);
unpackUint(v0, outBytes, outOff);
unpackUint(v1, outBytes, outOff + 4);
return block_size;
}
@ -144,42 +149,35 @@ namespace Org.BouncyCastle.Crypto.Engines
int outOff)
{
// Pack bytes into integers
int v0 = bytesToInt(inBytes, inOff);
int v1 = bytesToInt(inBytes, inOff + 4);
uint v0 = bytesToUint(inBytes, inOff);
uint v1 = bytesToUint(inBytes, inOff + 4);
int sum = d_sum;
for (int i = 0; i != rounds; i++)
for (int i = rounds-1; i >= 0; i--)
{
v1 -= ((v0 << 4 ^ (int)((uint)v0 >> 5)) + v0) ^ (sum + _S[(int)((uint)sum >> 11) & 3]);
sum -= delta;
v0 -= ((v1 << 4 ^ (int)((uint)v1 >> 5)) + v1) ^ (sum + _S[sum & 3]);
v1 -= ((v0 << 4 ^ v0 >> 5) + v0) ^ _sum1[i];
v0 -= ((v1 << 4 ^ v1 >> 5) + v1) ^ _sum0[i];
}
unpackInt(v0, outBytes, outOff);
unpackInt(v1, outBytes, outOff + 4);
unpackUint(v0, outBytes, outOff);
unpackUint(v1, outBytes, outOff + 4);
return block_size;
}
private int bytesToInt(byte[] b, int inOff)
private uint bytesToUint(byte[] b, int inOff)
{
return ((b[inOff++]) << 24) |
((b[inOff++] & 255) << 16) |
((b[inOff++] & 255) << 8) |
((b[inOff] & 255));
return ((uint)b[inOff++] << 24)
| ((uint)b[inOff++] << 16)
| ((uint)b[inOff++] << 8)
| ((uint)b[inOff]);
}
private void unpackInt(
int v,
byte[] b,
int outOff)
private void unpackUint(uint v, byte[] b, int outOff)
{
uint uv = (uint) v;
b[outOff++] = (byte)(uv >> 24);
b[outOff++] = (byte)(uv >> 16);
b[outOff++] = (byte)(uv >> 8);
b[outOff ] = (byte)uv;
b[outOff++] = (byte)(v >> 24);
b[outOff++] = (byte)(v >> 16);
b[outOff++] = (byte)(v >> 8);
b[outOff] = (byte)v;
}
}
}

View File

@ -19,7 +19,6 @@ namespace Org.BouncyCastle.Crypto.Modes
private byte[] IV;
private byte[] FR;
private byte[] FRE;
private byte[] tmp;
private readonly IBlockCipher cipher;
private readonly int blockSize;
@ -42,7 +41,6 @@ namespace Org.BouncyCastle.Crypto.Modes
this.IV = new byte[blockSize];
this.FR = new byte[blockSize];
this.FRE = new byte[blockSize];
this.tmp = new byte[blockSize];
}
/**
@ -208,10 +206,8 @@ namespace Org.BouncyCastle.Crypto.Modes
for (int n = 2; n < blockSize; n++)
{
outBytes[outOff + n] = EncryptByte(input[inOff + n], n - 2);
FR[n - 2] = outBytes[outOff + n] = EncryptByte(input[inOff + n], n - 2);
}
Array.Copy(outBytes, outOff + 2, FR, 0, blockSize - 2);
}
else if (count == 0)
{
@ -219,12 +215,10 @@ namespace Org.BouncyCastle.Crypto.Modes
for (int n = 0; n < blockSize; n++)
{
outBytes[outOff + n] = EncryptByte(input[inOff + n], n);
FR[n] = outBytes[outOff + n] = EncryptByte(input[inOff + n], n);
}
Array.Copy(outBytes, outOff, FR, 0, blockSize);
count += blockSize;
count += blockSize;
}
else if (count == blockSize)
{
@ -243,12 +237,10 @@ namespace Org.BouncyCastle.Crypto.Modes
for (int n = 2; n < blockSize; n++)
{
outBytes[outOff + n] = EncryptByte(input[inOff + n], n - 2);
FR[n - 2] = outBytes[outOff + n] = EncryptByte(input[inOff + n], n - 2);
}
Array.Copy(outBytes, outOff + 2, FR, 0, blockSize - 2);
count += blockSize;
count += blockSize;
}
return blockSize;
@ -284,22 +276,22 @@ namespace Org.BouncyCastle.Crypto.Modes
if (count > blockSize)
{
// copy in buffer so that this mode works if in and out are the same
Array.Copy(input, inOff, tmp, 0, blockSize);
byte inVal = input[inOff];
FR[blockSize - 2] = inVal;
outBytes[outOff] = EncryptByte(inVal, blockSize - 2);
outBytes[outOff] = EncryptByte(tmp[0], blockSize - 2);
outBytes[outOff + 1] = EncryptByte(tmp[1], blockSize - 1);
Array.Copy(tmp, 0, FR, blockSize - 2, 2);
inVal = input[inOff + 1];
FR[blockSize - 1] = inVal;
outBytes[outOff + 1] = EncryptByte(inVal, blockSize - 1);
cipher.ProcessBlock(FR, 0, FRE, 0);
for (int n = 2; n < blockSize; n++)
{
outBytes[outOff + n] = EncryptByte(tmp[n], n - 2);
}
Array.Copy(tmp, 2, FR, 0, blockSize - 2);
inVal = input[inOff + n];
FR[n - 2] = inVal;
outBytes[outOff + n] = EncryptByte(inVal, n - 2);
}
}
else if (count == 0)
{
@ -315,24 +307,25 @@ namespace Org.BouncyCastle.Crypto.Modes
}
else if (count == blockSize)
{
Array.Copy(input, inOff, tmp, 0, blockSize);
cipher.ProcessBlock(FR, 0, FRE, 0);
outBytes[outOff] = EncryptByte(tmp[0], 0);
outBytes[outOff + 1] = EncryptByte(tmp[1], 1);
byte inVal1 = input[inOff];
byte inVal2 = input[inOff + 1];
outBytes[outOff ] = EncryptByte(inVal1, 0);
outBytes[outOff + 1] = EncryptByte(inVal2, 1);
Array.Copy(FR, 2, FR, 0, blockSize - 2);
FR[blockSize - 2] = tmp[0];
FR[blockSize - 1] = tmp[1];
FR[blockSize - 2] = inVal1;
FR[blockSize - 1] = inVal2;
cipher.ProcessBlock(FR, 0, FRE, 0);
for (int n = 2; n < blockSize; n++)
{
FR[n - 2] = input[inOff + n];
outBytes[outOff + n] = EncryptByte(input[inOff + n], n - 2);
byte inVal = input[inOff + n];
FR[n - 2] = inVal;
outBytes[outOff + n] = EncryptByte(inVal, n - 2);
}
count += blockSize;

View File

@ -11,6 +11,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
{
public const char Binary = 'b';
public const char Text = 't';
public const char Utf8 = 'u';
/// <summary>The special name indicating a "for your eyes only" packet.</summary>
public const string Console = "_CONSOLE";

View File

@ -358,9 +358,16 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
return (byte[]) fingerprint.Clone();
}
/// <summary>True, if this key is marked as suitable for encryption</summary>
/// <returns>True, if this key is marked as suitable for using for encryption.</returns>
/// <summary>
/// Check if this key has an algorithm type that makes it suitable to use for encryption.
/// </summary>
/// <remarks>
/// Note: with version 4 keys KeyFlags subpackets should also be considered when present for
/// determining the preferred use of the key.
/// </remarks>
/// <returns>
/// <c>true</c> if this key algorithm is suitable for encryption.
/// </returns>
public bool IsEncryptionKey
{
get

View File

@ -165,7 +165,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
}
/// <summary>Return the public key ring which contains the key referred to by keyId</summary>
/// <param name="keyId">The ID of the public key</param>
/// <param name="keyId">key ID to match against</param>
public PgpPublicKeyRing GetPublicKeyRing(
long keyId)
{
@ -187,6 +187,16 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
return null;
}
/// <summary>
/// Return true if a key matching the passed in key ID is present, false otherwise.
/// </summary>
/// <param name="keyID">key ID to look for.</param>
public bool Contains(
long keyID)
{
return GetPublicKey(keyID) != null;
}
public byte[] GetEncoded()
{
MemoryStream bOut = new MemoryStream();

View File

@ -279,8 +279,17 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
{
}
/// <summary>True, if this key is marked as suitable for signature generation.</summary>
public bool IsSigningKey
/// <summary>
/// Check if this key has an algorithm type that makes it suitable to use for signing.
/// </summary>
/// <remarks>
/// Note: with version 4 keys KeyFlags subpackets should also be considered when present for
/// determining the preferred use of the key.
/// </remarks>
/// <returns>
/// <c>true</c> if this key algorithm is suitable for use with signing.
/// </returns>
public bool IsSigningKey
{
get
{

View File

@ -189,7 +189,17 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
return null;
}
public byte[] GetEncoded()
/// <summary>
/// Return true if a key matching the passed in key ID is present, false otherwise.
/// </summary>
/// <param name="keyID">key ID to look for.</param>
public bool Contains(
long keyID)
{
return GetSecretKey(keyID) != null;
}
public byte[] GetEncoded()
{
MemoryStream bOut = new MemoryStream();

View File

@ -322,6 +322,18 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
return sigPck.GetSignatureTrailer();
}
/// <summary>
/// Return true if the signature has either hashed or unhashed subpackets.
/// </summary>
public bool HasSubpackets
{
get
{
return sigPck.GetHashedSubPackets() != null
|| sigPck.GetUnhashedSubPackets() != null;
}
}
public PgpSignatureSubpacketVector GetHashedSubPackets()
{
return createSubpacketVector(sigPck.GetHashedSubPackets());

View File

@ -30,6 +30,18 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
return null;
}
/**
* Return true if a particular subpacket type exists.
*
* @param type type to look for.
* @return true if present, false otherwise.
*/
public bool HasSubpacket(
SignatureSubpacketTag type)
{
return GetSubpacket(type) != null;
}
/**
* Return all signature subpackets of the passed in type.
* @param type subpacket type code
@ -147,6 +159,19 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
return p == null ? null : ((SignerUserId) p).GetId();
}
public bool IsPrimaryUserId()
{
PrimaryUserId primaryId = (PrimaryUserId)
this.GetSubpacket(SignatureSubpacketTag.PrimaryUserId);
if (primaryId != null)
{
return primaryId.IsPrimaryUserId();
}
return false;
}
public SignatureSubpacketTag[] GetCriticalTags()
{
int count = 0;

View File

@ -28,5 +28,20 @@ namespace Org.BouncyCastle.Pkcs
{
get { return this.key; }
}
}
public override bool Equals(object obj)
{
AsymmetricKeyEntry other = obj as AsymmetricKeyEntry;
if (other == null)
return false;
return key.Equals(other.key);
}
public override int GetHashCode()
{
return ~key.GetHashCode();
}
}
}

View File

@ -0,0 +1,34 @@
using System;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Pkcs;
namespace Org.BouncyCastle.Pkcs
{
public class Pkcs12StoreBuilder
{
private DerObjectIdentifier keyAlgorithm = PkcsObjectIdentifiers.PbeWithShaAnd3KeyTripleDesCbc;
private DerObjectIdentifier certAlgorithm = PkcsObjectIdentifiers.PbewithShaAnd40BitRC2Cbc;
public Pkcs12StoreBuilder()
{
}
public Pkcs12Store Build()
{
return new Pkcs12Store(keyAlgorithm, certAlgorithm);
}
public Pkcs12StoreBuilder SetCertAlgorithm(DerObjectIdentifier certAlgorithm)
{
this.certAlgorithm = certAlgorithm;
return this;
}
public Pkcs12StoreBuilder SetKeyAlgorithm(DerObjectIdentifier keyAlgorithm)
{
this.keyAlgorithm = keyAlgorithm;
return this;
}
}
}

View File

@ -25,11 +25,11 @@ namespace Org.BouncyCastle.Pkcs
private readonly IgnoresCaseHashtable certs = new IgnoresCaseHashtable();
private readonly Hashtable chainCerts = new Hashtable();
private readonly Hashtable keyCerts = new Hashtable();
private readonly DerObjectIdentifier keyAlgorithm;
private readonly DerObjectIdentifier certAlgorithm;
private static readonly DerObjectIdentifier keyAlgorithm = PkcsObjectIdentifiers.PbeWithShaAnd3KeyTripleDesCbc;
private static readonly DerObjectIdentifier CertAlgorithm = PkcsObjectIdentifiers.PbewithShaAnd40BitRC2Cbc;
private int MinIterations = 1024;
private int saltSize = 20;
private const int MinIterations = 1024;
private const int SaltSize = 20;
private static SubjectKeyIdentifier CreateSubjectKeyID(
AsymmetricKeyParameter pubKey)
@ -79,13 +79,35 @@ namespace Org.BouncyCastle.Pkcs
}
}
internal Pkcs12Store(
DerObjectIdentifier keyAlgorithm,
DerObjectIdentifier certAlgorithm)
{
this.keyAlgorithm = keyAlgorithm;
this.certAlgorithm = certAlgorithm;
}
// TODO Consider making obsolete
// [Obsolete("User 'Pkcs12StoreBuilder' instead")]
public Pkcs12Store()
: this(PkcsObjectIdentifiers.PbeWithShaAnd3KeyTripleDesCbc,
PkcsObjectIdentifiers.PbewithShaAnd40BitRC2Cbc)
{
}
// TODO Consider making obsolete
// [Obsolete("User 'Pkcs12StoreBuilder' and 'Load' method instead")]
public Pkcs12Store(
Stream input,
char[] password)
: this()
{
Load(input, password);
}
public void Load(
Stream input,
char[] password)
{
if (input == null)
throw new ArgumentNullException("input");
@ -126,6 +148,9 @@ namespace Org.BouncyCastle.Pkcs
}
}
keys.Clear();
localIds.Clear();
ArrayList chain = new ArrayList();
if (info.ContentType.Equals(PkcsObjectIdentifiers.Data))
@ -372,9 +397,9 @@ namespace Org.BouncyCastle.Pkcs
}
}
certs = new IgnoresCaseHashtable();
chainCerts = new Hashtable();
keyCerts = new Hashtable();
certs.Clear();
chainCerts.Clear();
keyCerts.Clear();
foreach (SafeBag b in chain)
{
@ -781,7 +806,7 @@ namespace Org.BouncyCastle.Pkcs
Asn1EncodableVector keyS = new Asn1EncodableVector();
foreach (string name in keys.Keys)
{
byte[] kSalt = new byte[saltSize];
byte[] kSalt = new byte[SaltSize];
random.NextBytes(kSalt);
AsymmetricKeyEntry privKey = (AsymmetricKeyEntry) keys[name];
@ -843,13 +868,13 @@ namespace Org.BouncyCastle.Pkcs
//
// certificate processing
//
byte[] cSalt = new byte[saltSize];
byte[] cSalt = new byte[SaltSize];
random.NextBytes(cSalt);
Asn1EncodableVector certSeq = new Asn1EncodableVector();
Pkcs12PbeParams cParams = new Pkcs12PbeParams(cSalt, MinIterations);
AlgorithmIdentifier cAlgId = new AlgorithmIdentifier(CertAlgorithm, cParams.ToAsn1Object());
AlgorithmIdentifier cAlgId = new AlgorithmIdentifier(certAlgorithm, cParams.ToAsn1Object());
ISet doneCerts = new HashSet();
foreach (string name in keys.Keys)
@ -924,6 +949,13 @@ namespace Org.BouncyCastle.Pkcs
foreach (string oid in cert.BagAttributeKeys)
{
// a certificate not immediately linked to a key doesn't require
// a localKeyID and will confuse some PKCS12 implementations.
//
// If we find one, we'll prune it out.
if (oid.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID.Id))
continue;
Asn1Encodable entry = cert[oid];
// NB: Ignore any existing FriendlyName
@ -971,6 +1003,13 @@ namespace Org.BouncyCastle.Pkcs
foreach (string oid in cert.BagAttributeKeys)
{
// a certificate not immediately linked to a key doesn't require
// a localKeyID and will confuse some PKCS12 implementations.
//
// If we find one, we'll prune it out.
if (oid.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID.Id))
continue;
fName.Add(
new DerSequence(
new DerObjectIdentifier(oid),
@ -1068,6 +1107,12 @@ namespace Org.BouncyCastle.Pkcs
private readonly Hashtable orig = new Hashtable();
private readonly Hashtable keys = new Hashtable();
public void Clear()
{
orig.Clear();
keys.Clear();
}
public IEnumerator GetEnumerator()
{
return orig.GetEnumerator();

View File

@ -28,5 +28,20 @@ namespace Org.BouncyCastle.Pkcs
{
get { return this.cert; }
}
}
public override bool Equals(object obj)
{
X509CertificateEntry other = obj as X509CertificateEntry;
if (other == null)
return false;
return cert.Equals(other.cert);
}
public override int GetHashCode()
{
return ~cert.GetHashCode();
}
}
}

View File

@ -289,9 +289,11 @@ namespace Org.BouncyCastle.Security
case "HC256":
streamCipher = new HC256Engine();
break;
#if INCLUDE_IDEA
case "IDEA":
blockCipher = new IdeaEngine();
break;
#endif
case "NOEKEON":
blockCipher = new NoekeonEngine();
break;
@ -396,18 +398,23 @@ namespace Org.BouncyCastle.Security
asymBlockCipher = new OaepEncoding(asymBlockCipher, new MD5Digest());
break;
case "OAEPWITHSHA1ANDMGF1PADDING":
case "OAEPWITHSHA-1ANDMGF1PADDING":
asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha1Digest());
break;
case "OAEPWITHSHA224ANDMGF1PADDING":
case "OAEPWITHSHA-224ANDMGF1PADDING":
asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha224Digest());
break;
case "OAEPWITHSHA256ANDMGF1PADDING":
case "OAEPWITHSHA-256ANDMGF1PADDING":
asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha256Digest());
break;
case "OAEPWITHSHA384ANDMGF1PADDING":
case "OAEPWITHSHA-384ANDMGF1PADDING":
asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha384Digest());
break;
case "OAEPWITHSHA512ANDMGF1PADDING":
case "OAEPWITHSHA-512ANDMGF1PADDING":
asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha512Digest());
break;
case "PKCS1":

View File

@ -168,6 +168,7 @@ namespace Org.BouncyCastle.Security
{
return new CfbBlockCipherMac(new SkipjackEngine());
}
#if INCLUDE_IDEA
if (mechanism == "IDEAMAC")
{
return new CbcBlockCipherMac(new IdeaEngine());
@ -176,6 +177,7 @@ namespace Org.BouncyCastle.Security
{
return new CfbBlockCipherMac(new IdeaEngine());
}
#endif
if (mechanism == "RC2MAC")
{
return new CbcBlockCipherMac(new RC2Engine());

View File

@ -146,11 +146,19 @@ namespace Org.BouncyCastle.Tsp
throw new TspValidationException("response for different message imprint algorithm.");
}
if (tok.SignedAttributes[PkcsObjectIdentifiers.IdAASigningCertificate] == null)
Asn1.Cms.Attribute scV1 = tok.SignedAttributes[PkcsObjectIdentifiers.IdAASigningCertificate];
Asn1.Cms.Attribute scV2 = tok.SignedAttributes[PkcsObjectIdentifiers.IdAASigningCertificateV2];
if (scV1 == null && scV2 == null)
{
throw new TspValidationException("no signing certificate attribute present.");
}
if (scV1 != null && scV2 != null)
{
throw new TspValidationException("conflicting signing certificate attributes present.");
}
if (request.ReqPolicy != null && !request.ReqPolicy.Equals(tstInfo.Policy))
{
throw new TspValidationException("TSA policy wrong for request.");

View File

@ -37,7 +37,7 @@ namespace Org.BouncyCastle.Tsp
{
this.tsToken = signedData;
if (!this.tsToken.SignedContentTypeOid.Equals(PkcsObjectIdentifiers.IdCTTstInfo.Id))
if (!this.tsToken.SignedContentType.Equals(PkcsObjectIdentifiers.IdCTTstInfo))
{
throw new TspValidationException("ContentInfo object not for a time stamp.");
}

View File

@ -1,4 +1,5 @@
using System;
using System.Text;
namespace Org.BouncyCastle.Utilities
{
@ -30,5 +31,23 @@ namespace Org.BouncyCastle.Utilities
}
return bs;
}
public static string FromUtf8ByteArray(
byte[] bytes)
{
return Encoding.UTF8.GetString(bytes, 0, bytes.Length);
}
public static byte[] ToUtf8ByteArray(
string s)
{
return Encoding.UTF8.GetBytes(s);
}
public static byte[] ToUtf8ByteArray(
char[] cs)
{
return Encoding.UTF8.GetBytes(cs);
}
}
}

View File

@ -25,6 +25,19 @@ namespace Org.BouncyCastle.Utilities.Collections
impl[o] = null;
}
public void AddAll(IEnumerable e)
{
foreach (object o in e)
{
Add(o);
}
}
public void Clear()
{
impl.Clear();
}
public bool Contains(object o)
{
return impl.ContainsKey(o);
@ -45,6 +58,11 @@ namespace Org.BouncyCastle.Utilities.Collections
return impl.Keys.GetEnumerator();
}
public bool IsEmpty
{
get { return impl.Count == 0; }
}
public bool IsSynchronized
{
get { return impl.IsSynchronized; }
@ -55,6 +73,14 @@ namespace Org.BouncyCastle.Utilities.Collections
impl.Remove(o);
}
public void RemoveAll(IEnumerable e)
{
foreach (object o in e)
{
Remove(o);
}
}
public object SyncRoot
{
get { return impl.SyncRoot; }

View File

@ -7,7 +7,11 @@ namespace Org.BouncyCastle.Utilities.Collections
: ICollection
{
void Add(object o);
void AddAll(IEnumerable e);
void Clear();
bool Contains(object o);
bool IsEmpty { get; }
void Remove(object o);
void RemoveAll(IEnumerable e);
}
}

View File

@ -1,4 +1,5 @@
using System;
using System.Globalization;
using Org.BouncyCastle.Math;
@ -7,12 +8,12 @@ namespace Org.BouncyCastle.Utilities.Net
public class IPAddress
{
/**
* Validate the given IPv4 or IPv6 address.
*
* @param address the IP address as a string.
*
* @return true if a valid address, false otherwise
*/
* Validate the given IPv4 or IPv6 address.
*
* @param address the IP address as a string.
*
* @return true if a valid address, false otherwise
*/
public static bool IsValid(
string address)
{
@ -20,21 +21,44 @@ namespace Org.BouncyCastle.Utilities.Net
}
/**
* Validate the given IPv4 address.
*
* @param address the IP address as a string.
*
* @return true if a valid IPv4 address, false otherwise
*/
private static bool IsValidIPv4(
* Validate the given IPv4 or IPv6 address and netmask.
*
* @param address the IP address as a string.
*
* @return true if a valid address with netmask, false otherwise
*/
public static bool IsValidWithNetMask(
string address)
{
return IsValidIPv4WithNetmask(address) || IsValidIPv6WithNetmask(address);
}
/**
* Validate the given IPv4 address.
*
* @param address the IP address as a string.
*
* @return true if a valid IPv4 address, false otherwise
*/
public static bool IsValidIPv4(
string address)
{
try
{
return unsafeIsValidIPv4(address);
}
catch (FormatException) {}
catch (OverflowException) {}
return false;
}
private static bool unsafeIsValidIPv4(
string address)
{
if (address.Length == 0)
return false;
BigInteger octet;
int octets = 0;
string temp = address + ".";
int pos;
@ -45,68 +69,129 @@ namespace Org.BouncyCastle.Utilities.Net
if (octets == 4)
return false;
try
{
octet = new BigInteger(temp.Substring(start, pos - start));
}
catch (FormatException)
{
return false;
}
string octetStr = temp.Substring(start, pos - start);
int octet = Int32.Parse(octetStr);
if (octet.SignValue < 0 || octet.BitLength > 8)
return false;
start = pos + 1;
++octets;
}
return octets == 4;
}
/**
* Validate the given IPv6 address.
*
* @param address the IP address as a string.
*
* @return true if a valid IPv4 address, false otherwise
*/
private static bool IsValidIPv6(
string address)
{
if (address.Length == 0)
return false;
BigInteger octet;
int octets = 0;
string temp = address + ":";
int pos;
int start = 0;
while (start < temp.Length
&& (pos = temp.IndexOf(':', start)) > start)
{
if (octets == 8)
return false;
try
{
octet = new BigInteger(temp.Substring(start, pos - start), 16);
}
catch (FormatException)
{
return false;
}
if (octet.SignValue < 0 || octet.BitLength > 16)
if (octet < 0 || octet > 255)
return false;
start = pos + 1;
octets++;
}
return octets == 8;
return octets == 4;
}
public static bool IsValidIPv4WithNetmask(
string address)
{
int index = address.IndexOf("/");
string mask = address.Substring(index + 1);
return (index > 0) && IsValidIPv4(address.Substring(0, index))
&& (IsValidIPv4(mask) || IsMaskValue(mask, 32));
}
public static bool IsValidIPv6WithNetmask(
string address)
{
int index = address.IndexOf("/");
string mask = address.Substring(index + 1);
return (index > 0) && (IsValidIPv6(address.Substring(0, index))
&& (IsValidIPv6(mask) || IsMaskValue(mask, 128)));
}
private static bool IsMaskValue(
string component,
int size)
{
int val = Int32.Parse(component);
try
{
return val >= 0 && val <= size;
}
catch (FormatException) {}
catch (OverflowException) {}
return false;
}
/**
* Validate the given IPv6 address.
*
* @param address the IP address as a string.
*
* @return true if a valid IPv4 address, false otherwise
*/
public static bool IsValidIPv6(
string address)
{
try
{
return unsafeIsValidIPv6(address);
}
catch (FormatException) {}
catch (OverflowException) {}
return false;
}
private static bool unsafeIsValidIPv6(
string address)
{
if (address.Length == 0)
{
return false;
}
int octets = 0;
string temp = address + ":";
bool doubleColonFound = false;
int pos;
int start = 0;
while (start < temp.Length
&& (pos = temp.IndexOf(':', start)) >= start)
{
if (octets == 8)
{
return false;
}
if (start != pos)
{
string value = temp.Substring(start, pos - start);
if (pos == (temp.Length - 1) && value.IndexOf('.') > 0)
{
if (!IsValidIPv4(value))
{
return false;
}
octets++; // add an extra one as address covers 2 words.
}
else
{
string octetStr = temp.Substring(start, pos - start);
int octet = Int32.Parse(octetStr, NumberStyles.AllowHexSpecifier);
if (octet < 0 || octet > 0xffff)
return false;
}
}
else
{
if (pos != 1 && pos != temp.Length - 1 && doubleColonFound)
{
return false;
}
doubleColonFound = true;
}
start = pos + 1;
octets++;
}
return octets == 8 || doubleColonFound;
}
}
}

View File

@ -10,13 +10,13 @@ namespace Org.BouncyCastle.X509
/// <summary>
/// Get all critical extension values, by oid
/// </summary>
/// <returns>IDictionary with DerObjectIdentifier keys and Asn1OctetString values</returns>
/// <returns>IDictionary with string (OID) keys and Asn1OctetString values</returns>
ISet GetCriticalExtensionOids();
/// <summary>
/// Get all non-critical extension values, by oid
/// </summary>
/// <returns>IDictionary with DerObjectIdentifier keys and Asn1OctetString values</returns>
/// <returns>IDictionary with string (OID) keys and Asn1OctetString values</returns>
ISet GetNonCriticalExtensionOids();
[Obsolete("Use version taking a DerObjectIdentifier instead")]

View File

@ -246,20 +246,14 @@ namespace Org.BouncyCastle.X509
byte[] sig = this.GetSignature();
buf.Append(" Signature: ").Append(
Encoding.ASCII.GetString(Hex.Encode(sig, 0, 20))).Append(nl);
buf.Append(" Signature: ");
buf.Append(AsHexString(sig, 0, 20)).Append(nl);
for (int i = 20; i < sig.Length; i += 20)
{
if (i < sig.Length - 20)
{
buf.Append(" ").Append(
Encoding.ASCII.GetString(Hex.Encode(sig, i, 20))).Append(nl);
}
else
{
buf.Append(" ").Append(
Encoding.ASCII.GetString(Hex.Encode(sig, i, sig.Length - i))).Append(nl);
}
int count = System.Math.Min(20, sig.Length - i);
buf.Append(" ");
buf.Append(AsHexString(sig, i, count)).Append(nl);
}
X509Extensions extensions = c.TbsCertList.Extensions;
@ -405,5 +399,14 @@ namespace Org.BouncyCastle.X509
return isIndirect;
}
}
private static string AsHexString(
byte[] bytes,
int index,
int count)
{
byte[] hex = Hex.Encode(bytes, index, count);
return Encoding.ASCII.GetString(hex, 0, hex.Length);
}
}
}