summary refs log tree commit diff
diff options
context:
space:
mode:
authorJeffrey Stedfast <jeff@xamarin.com>2014-12-18 08:53:43 -0500
committerJeffrey Stedfast <jeff@xamarin.com>2014-12-18 08:53:43 -0500
commit8b2f7e6eabdfd1dcb53e409c9f7e85d31a79ce2a (patch)
treeefef9ebef4b7c352b82fc1b81e7a57194bbd55ec
parentAdded BouncyCastle.snk (diff)
parentAdd ECDHE_ECDSA CCM ciphersuites from RFC 7251 (diff)
downloadBouncyCastle.NET-ed25519-8b2f7e6eabdfd1dcb53e409c9f7e85d31a79ce2a.tar.xz
Merge branch 'master' into vs2010
-rw-r--r--crypto/src/asn1/microsoft/MicrosoftObjectIdentifiers.cs27
-rw-r--r--crypto/src/asn1/misc/MiscObjectIdentifiers.cs61
-rw-r--r--crypto/src/bcpg/PublicKeyAlgorithmTags.cs27
-rw-r--r--crypto/src/cms/SignerInformationStore.cs53
-rw-r--r--crypto/src/crypto/paddings/Pkcs7Padding.cs21
-rw-r--r--crypto/src/crypto/tls/AbstractTlsClient.cs44
-rw-r--r--crypto/src/crypto/tls/CipherSuite.cs8
-rw-r--r--crypto/src/crypto/tls/DefaultTlsClient.cs8
-rw-r--r--crypto/src/crypto/tls/DefaultTlsServer.cs8
-rw-r--r--crypto/src/crypto/tls/TlsEccUtilities.cs8
-rw-r--r--crypto/src/crypto/tls/TlsProtocol.cs4
-rw-r--r--crypto/src/crypto/tls/TlsUtilities.cs8
-rw-r--r--crypto/src/openpgp/PgpPublicKey.cs853
13 files changed, 622 insertions, 508 deletions
diff --git a/crypto/src/asn1/microsoft/MicrosoftObjectIdentifiers.cs b/crypto/src/asn1/microsoft/MicrosoftObjectIdentifiers.cs
index b8aba7ee9..bc48c3fa2 100644
--- a/crypto/src/asn1/microsoft/MicrosoftObjectIdentifiers.cs
+++ b/crypto/src/asn1/microsoft/MicrosoftObjectIdentifiers.cs
@@ -2,17 +2,18 @@ using System;
 
 namespace Org.BouncyCastle.Asn1.Microsoft
 {
-	public abstract class MicrosoftObjectIdentifiers
-	{
-		//
-		// Microsoft
-		//       iso(1) identified-organization(3) dod(6) internet(1) private(4) enterprise(1) Microsoft(311)
-		//
-		public static readonly DerObjectIdentifier Microsoft               = new DerObjectIdentifier("1.3.6.1.4.1.311");
-		public static readonly DerObjectIdentifier MicrosoftCertTemplateV1 = new DerObjectIdentifier(Microsoft + ".20.2");
-		public static readonly DerObjectIdentifier MicrosoftCAVersion      = new DerObjectIdentifier(Microsoft + ".21.1");
-		public static readonly DerObjectIdentifier MicrosoftPrevCACertHash = new DerObjectIdentifier(Microsoft + ".21.2");
-		public static readonly DerObjectIdentifier MicrosoftCertTemplateV2 = new DerObjectIdentifier(Microsoft + ".21.7");
-		public static readonly DerObjectIdentifier MicrosoftAppPolicies    = new DerObjectIdentifier(Microsoft + ".21.10");
-	}
+    public abstract class MicrosoftObjectIdentifiers
+    {
+        //
+        // Microsoft
+        //       iso(1) identified-organization(3) dod(6) internet(1) private(4) enterprise(1) Microsoft(311)
+        //
+        public static readonly DerObjectIdentifier Microsoft               = new DerObjectIdentifier("1.3.6.1.4.1.311");
+        public static readonly DerObjectIdentifier MicrosoftCertTemplateV1 = Microsoft.Branch("20.2");
+        public static readonly DerObjectIdentifier MicrosoftCAVersion      = Microsoft.Branch("21.1");
+        public static readonly DerObjectIdentifier MicrosoftPrevCACertHash = Microsoft.Branch("21.2");
+        public static readonly DerObjectIdentifier MicrosoftCrlNextPublish = Microsoft.Branch("21.4");
+        public static readonly DerObjectIdentifier MicrosoftCertTemplateV2 = Microsoft.Branch("21.7");
+        public static readonly DerObjectIdentifier MicrosoftAppPolicies    = Microsoft.Branch("21.10");
+    }
 }
diff --git a/crypto/src/asn1/misc/MiscObjectIdentifiers.cs b/crypto/src/asn1/misc/MiscObjectIdentifiers.cs
index 01004d889..45adce4f7 100644
--- a/crypto/src/asn1/misc/MiscObjectIdentifiers.cs
+++ b/crypto/src/asn1/misc/MiscObjectIdentifiers.cs
@@ -1,5 +1,3 @@
-using Org.BouncyCastle.Asn1;
-
 namespace Org.BouncyCastle.Asn1.Misc
 {
     public abstract class MiscObjectIdentifiers
@@ -9,40 +7,47 @@ namespace Org.BouncyCastle.Asn1.Misc
         //       iso/itu(2) joint-assign(16) us(840) uscompany(1) Netscape(113730) cert-extensions(1) }
         //
         public static readonly DerObjectIdentifier Netscape                = new DerObjectIdentifier("2.16.840.1.113730.1");
-        public static readonly DerObjectIdentifier NetscapeCertType        = new DerObjectIdentifier(Netscape + ".1");
-        public static readonly DerObjectIdentifier NetscapeBaseUrl         = new DerObjectIdentifier(Netscape + ".2");
-        public static readonly DerObjectIdentifier NetscapeRevocationUrl   = new DerObjectIdentifier(Netscape + ".3");
-        public static readonly DerObjectIdentifier NetscapeCARevocationUrl = new DerObjectIdentifier(Netscape + ".4");
-        public static readonly DerObjectIdentifier NetscapeRenewalUrl      = new DerObjectIdentifier(Netscape + ".7");
-        public static readonly DerObjectIdentifier NetscapeCAPolicyUrl     = new DerObjectIdentifier(Netscape + ".8");
-        public static readonly DerObjectIdentifier NetscapeSslServerName   = new DerObjectIdentifier(Netscape + ".12");
-        public static readonly DerObjectIdentifier NetscapeCertComment     = new DerObjectIdentifier(Netscape + ".13");
+        public static readonly DerObjectIdentifier NetscapeCertType        = Netscape.Branch("1");
+        public static readonly DerObjectIdentifier NetscapeBaseUrl         = Netscape.Branch("2");
+        public static readonly DerObjectIdentifier NetscapeRevocationUrl   = Netscape.Branch("3");
+        public static readonly DerObjectIdentifier NetscapeCARevocationUrl = Netscape.Branch("4");
+        public static readonly DerObjectIdentifier NetscapeRenewalUrl      = Netscape.Branch("7");
+        public static readonly DerObjectIdentifier NetscapeCAPolicyUrl     = Netscape.Branch("8");
+        public static readonly DerObjectIdentifier NetscapeSslServerName   = Netscape.Branch("12");
+        public static readonly DerObjectIdentifier NetscapeCertComment     = Netscape.Branch("13");
+
         //
         // Verisign
         //       iso/itu(2) joint-assign(16) us(840) uscompany(1) verisign(113733) cert-extensions(1) }
         //
-        internal const string Verisign = "2.16.840.1.113733.1";
+        public static readonly DerObjectIdentifier Verisign = new DerObjectIdentifier("2.16.840.1.113733.1");
 
-		//
+        //
         // CZAG - country, zip, age, and gender
         //
-        public static readonly DerObjectIdentifier VerisignCzagExtension = new DerObjectIdentifier(Verisign + ".6.3");
+        public static readonly DerObjectIdentifier VerisignCzagExtension          = Verisign.Branch("6.3");
 
-		// D&B D-U-N-S number
-		public static readonly DerObjectIdentifier VerisignDnbDunsNumber = new DerObjectIdentifier(Verisign + ".6.15");
+        public static readonly DerObjectIdentifier VerisignPrivate_6_9            = Verisign.Branch("6.9");
+        public static readonly DerObjectIdentifier VerisignOnSiteJurisdictionHash = Verisign.Branch("6.11");
+        public static readonly DerObjectIdentifier VerisignBitString_6_13         = Verisign.Branch("6.13");
 
-		//
-		// Novell
-		//       iso/itu(2) country(16) us(840) organization(1) novell(113719)
-		//
-		public static readonly string				Novell					= "2.16.840.1.113719";
-		public static readonly DerObjectIdentifier	NovellSecurityAttribs	= new DerObjectIdentifier(Novell + ".1.9.4.1");
+        // D&B D-U-N-S number
+        public static readonly DerObjectIdentifier VerisignDnbDunsNumber          = Verisign.Branch("6.15");
 
-		//
-		// Entrust
-		//       iso(1) member-body(16) us(840) nortelnetworks(113533) entrust(7)
-		//
-		public static readonly string				Entrust					= "1.2.840.113533.7";
-		public static readonly DerObjectIdentifier	EntrustVersionExtension = new DerObjectIdentifier(Entrust + ".65.0");
-	}
+        public static readonly DerObjectIdentifier VerisignIssStrongCrypto        = Verisign.Branch("8.1");
+
+        //
+        // Novell
+        //       iso/itu(2) country(16) us(840) organization(1) novell(113719)
+        //
+        public static readonly string				Novell					= "2.16.840.1.113719";
+        public static readonly DerObjectIdentifier	NovellSecurityAttribs	= new DerObjectIdentifier(Novell + ".1.9.4.1");
+
+        //
+        // Entrust
+        //       iso(1) member-body(16) us(840) nortelnetworks(113533) entrust(7)
+        //
+        public static readonly string				Entrust					= "1.2.840.113533.7";
+        public static readonly DerObjectIdentifier	EntrustVersionExtension = new DerObjectIdentifier(Entrust + ".65.0");
+    }
 }
diff --git a/crypto/src/bcpg/PublicKeyAlgorithmTags.cs b/crypto/src/bcpg/PublicKeyAlgorithmTags.cs
index 85ae548eb..4a6704c14 100644
--- a/crypto/src/bcpg/PublicKeyAlgorithmTags.cs
+++ b/crypto/src/bcpg/PublicKeyAlgorithmTags.cs
@@ -1,6 +1,6 @@
 namespace Org.BouncyCastle.Bcpg
 {
-	/// <remarks>Public Key Algorithm tag numbers.</remarks>
+    /// <remarks>Public Key Algorithm tag numbers.</remarks>
     public enum PublicKeyAlgorithmTag
     {
         RsaGeneral = 1,			// RSA (Encrypt or Sign)
@@ -9,20 +9,21 @@ namespace Org.BouncyCastle.Bcpg
         ElGamalEncrypt = 16,	// Elgamal (Encrypt-Only), see [ELGAMAL]
         Dsa = 17,				// DSA (Digital Signature Standard)
         EC = 18,				// Reserved for Elliptic Curve
+        ECDH = 18,              // Reserved for Elliptic Curve (actual algorithm name)
         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,
-	}
+        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,
+    }
 }
diff --git a/crypto/src/cms/SignerInformationStore.cs b/crypto/src/cms/SignerInformationStore.cs
index bd613843d..27940865d 100644
--- a/crypto/src/cms/SignerInformationStore.cs
+++ b/crypto/src/cms/SignerInformationStore.cs
@@ -8,10 +8,31 @@ namespace Org.BouncyCastle.Cms
 {
     public class SignerInformationStore
     {
-		private readonly IList all; //ArrayList[SignerInformation]
-		private readonly IDictionary table = Platform.CreateHashtable(); // Hashtable[SignerID, ArrayList[SignerInformation]]
+        private readonly IList all; //ArrayList[SignerInformation]
+        private readonly IDictionary table = Platform.CreateHashtable(); // Hashtable[SignerID, ArrayList[SignerInformation]]
 
-		public SignerInformationStore(
+        /**
+         * Create a store containing a single SignerInformation object.
+         *
+         * @param signerInfo the signer information to contain.
+         */
+        public SignerInformationStore(
+            SignerInformation signerInfo)
+        {
+            this.all = Platform.CreateArrayList(1);
+            this.all.Add(signerInfo);
+
+            SignerID sid = signerInfo.SignerID;
+
+            table[sid] = all;
+        }
+
+        /**
+         * Create a store containing a collection of SignerInformation objects.
+         *
+         * @param signerInfos a collection signer information objects to contain.
+         */
+        public SignerInformationStore(
             ICollection signerInfos)
         {
             foreach (SignerInformation signer in signerInfos)
@@ -19,12 +40,12 @@ namespace Org.BouncyCastle.Cms
                 SignerID sid = signer.SignerID;
                 IList list = (IList)table[sid];
 
-				if (list == null)
-				{
-					table[sid] = list = Platform.CreateArrayList(1);
-				}
+                if (list == null)
+                {
+                    table[sid] = list = Platform.CreateArrayList(1);
+                }
 
-				list.Add(signer);
+                list.Add(signer);
             }
 
             this.all = Platform.CreateArrayList(signerInfos);
@@ -40,24 +61,24 @@ namespace Org.BouncyCastle.Cms
         public SignerInformation GetFirstSigner(
             SignerID selector)
         {
-			IList list = (IList) table[selector];
+            IList list = (IList) table[selector];
 
-			return list == null ? null : (SignerInformation) list[0];
+            return list == null ? null : (SignerInformation) list[0];
         }
 
-		/// <summary>The number of signers in the collection.</summary>
-		public int Count
+        /// <summary>The number of signers in the collection.</summary>
+        public int Count
         {
-			get { return all.Count; }
+            get { return all.Count; }
         }
 
-		/// <returns>An ICollection of all signers in the collection</returns>
+        /// <returns>An ICollection of all signers in the collection</returns>
         public ICollection GetSigners()
         {
             return Platform.CreateArrayList(all);
         }
 
-		/**
+        /**
         * Return possible empty collection with signers matching the passed in SignerID
         *
         * @param selector a signer id to select against.
@@ -66,7 +87,7 @@ namespace Org.BouncyCastle.Cms
         public ICollection GetSigners(
             SignerID selector)
         {
-			IList list = (IList) table[selector];
+            IList list = (IList) table[selector];
 
             return list == null ? Platform.CreateArrayList() : Platform.CreateArrayList(list);
         }
diff --git a/crypto/src/crypto/paddings/Pkcs7Padding.cs b/crypto/src/crypto/paddings/Pkcs7Padding.cs
index f3166fd96..11585647a 100644
--- a/crypto/src/crypto/paddings/Pkcs7Padding.cs
+++ b/crypto/src/crypto/paddings/Pkcs7Padding.cs
@@ -9,7 +9,7 @@ namespace Org.BouncyCastle.Crypto.Paddings
     * A padder that adds Pkcs7/Pkcs5 padding to a block.
     */
     public class Pkcs7Padding
-		: IBlockCipherPadding
+        : IBlockCipherPadding
     {
         /**
         * Initialise the padder.
@@ -17,7 +17,7 @@ namespace Org.BouncyCastle.Crypto.Paddings
         * @param random - a SecureRandom if available.
         */
         public void Init(
-			SecureRandom random)
+            SecureRandom random)
         {
             // nothing to do.
         }
@@ -32,7 +32,7 @@ namespace Org.BouncyCastle.Crypto.Paddings
             get { return "PKCS7"; }
         }
 
-		/**
+        /**
         * add the pad bytes to the passed in block, returning the
         * number of bytes added.
         */
@@ -55,21 +55,18 @@ namespace Org.BouncyCastle.Crypto.Paddings
         * return the number of pad bytes present in the block.
         */
         public int PadCount(
-			byte[] input)
+            byte[] input)
         {
-            int count = (int) input[input.Length - 1];
+            byte countAsByte = input[input.Length - 1];
+            int count = countAsByte;
 
-			if (count < 1 || count > input.Length)
-            {
+            if (count < 1 || count > input.Length)
                 throw new InvalidCipherTextException("pad block corrupted");
-            }
 
-			for (int i = 1; i <= count; i++)
+            for (int i = 2; i <= count; i++)
             {
-                if (input[input.Length - i] != count)
-                {
+                if (input[input.Length - i] != countAsByte)
                     throw new InvalidCipherTextException("pad block corrupted");
-                }
             }
 
             return count;
diff --git a/crypto/src/crypto/tls/AbstractTlsClient.cs b/crypto/src/crypto/tls/AbstractTlsClient.cs
index 8b6e85af5..771bc004b 100644
--- a/crypto/src/crypto/tls/AbstractTlsClient.cs
+++ b/crypto/src/crypto/tls/AbstractTlsClient.cs
@@ -30,6 +30,32 @@ namespace Org.BouncyCastle.Crypto.Tls
             this.mCipherFactory = cipherFactory;
         }
 
+        protected virtual bool AllowUnexpectedServerExtension(int extensionType, byte[] extensionData)
+        {
+            switch (extensionType)
+            {
+            case ExtensionType.elliptic_curves:
+                /*
+                 * Exception added based on field reports that some servers do send this, although the
+                 * Supported Elliptic Curves Extension is clearly intended to be client-only. If
+                 * present, we still require that it is a valid EllipticCurveList.
+                 */
+                TlsEccUtilities.ReadSupportedEllipticCurvesExtension(extensionData);
+                return true;
+            default:
+                return false;
+            }
+        }
+
+        protected virtual void CheckForUnexpectedServerExtension(IDictionary serverExtensions, int extensionType)
+        {
+            byte[] extensionData = TlsUtilities.GetExtensionData(serverExtensions, extensionType);
+            if (extensionData != null && !AllowUnexpectedServerExtension(extensionType, extensionData))
+            {
+                throw new TlsFatalAlert(AlertDescription.illegal_parameter);
+            }
+        }
+
         public virtual void Init(TlsClientContext context)
         {
             this.mContext = context;
@@ -187,16 +213,18 @@ namespace Org.BouncyCastle.Crypto.Tls
                 /*
                  * RFC 5246 7.4.1.4.1. Servers MUST NOT send this extension.
                  */
-                if (serverExtensions.Contains(ExtensionType.signature_algorithms))
-                    throw new TlsFatalAlert(AlertDescription.illegal_parameter);
+                CheckForUnexpectedServerExtension(serverExtensions, ExtensionType.signature_algorithms);
 
-                int[] namedCurves = TlsEccUtilities.GetSupportedEllipticCurvesExtension(serverExtensions);
-                if (namedCurves != null)
-                    throw new TlsFatalAlert(AlertDescription.illegal_parameter);
+                CheckForUnexpectedServerExtension(serverExtensions, ExtensionType.elliptic_curves);
 
-                this.mServerECPointFormats = TlsEccUtilities.GetSupportedPointFormatsExtension(serverExtensions);
-                if (this.mServerECPointFormats != null && !TlsEccUtilities.IsEccCipherSuite(this.mSelectedCipherSuite))
-                    throw new TlsFatalAlert(AlertDescription.illegal_parameter);
+                if (TlsEccUtilities.IsEccCipherSuite(this.mSelectedCipherSuite))
+                {
+                    this.mServerECPointFormats = TlsEccUtilities.GetSupportedPointFormatsExtension(serverExtensions);
+                }
+                else
+                {
+                    CheckForUnexpectedServerExtension(serverExtensions, ExtensionType.ec_point_formats);
+                }
             }
         }
 
diff --git a/crypto/src/crypto/tls/CipherSuite.cs b/crypto/src/crypto/tls/CipherSuite.cs
index bff63c6b6..5ec36aee8 100644
--- a/crypto/src/crypto/tls/CipherSuite.cs
+++ b/crypto/src/crypto/tls/CipherSuite.cs
@@ -323,6 +323,14 @@ namespace Org.BouncyCastle.Crypto.Tls
         public const int TLS_PSK_DHE_WITH_AES_256_CCM_8 = 0xC0AB;
 
         /*
+         * RFC 7251
+         */
+        public const int TLS_ECDHE_ECDSA_WITH_AES_128_CCM = 0xC0AC;
+        public const int TLS_ECDHE_ECDSA_WITH_AES_256_CCM = 0xC0AD;
+        public const int TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 = 0xC0AE;
+        public const int TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 = 0xC0AF;
+
+        /*
          * draft-agl-tls-chacha20poly1305-04
          */
         public const int TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCC13;
diff --git a/crypto/src/crypto/tls/DefaultTlsClient.cs b/crypto/src/crypto/tls/DefaultTlsClient.cs
index a2a04a33c..ec98413b7 100644
--- a/crypto/src/crypto/tls/DefaultTlsClient.cs
+++ b/crypto/src/crypto/tls/DefaultTlsClient.cs
@@ -145,9 +145,13 @@ namespace Org.BouncyCastle.Crypto.Tls
             case CipherSuite.TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
             case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
             case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
+            case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM:
+            case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
             case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
             case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
             case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
+            case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM:
+            case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8:
             case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
             case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256:
             case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256:
@@ -258,10 +262,12 @@ namespace Org.BouncyCastle.Crypto.Tls
                 return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_128_CBC, MacAlgorithm.hmac_sha256);
 
             case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM:
+            case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM:
             case CipherSuite.TLS_RSA_WITH_AES_128_CCM:
                 return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_128_CCM, MacAlgorithm.cls_null);
 
             case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM_8:
+            case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
             case CipherSuite.TLS_RSA_WITH_AES_128_CCM_8:
                 return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_128_CCM_8, MacAlgorithm.cls_null);
 
@@ -301,10 +307,12 @@ namespace Org.BouncyCastle.Crypto.Tls
                 return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_CBC, MacAlgorithm.hmac_sha384);
 
             case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM:
+            case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM:
             case CipherSuite.TLS_RSA_WITH_AES_256_CCM:
                 return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_CCM, MacAlgorithm.cls_null);
 
             case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM_8:
+            case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8:
             case CipherSuite.TLS_RSA_WITH_AES_256_CCM_8:
                 return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_CCM_8, MacAlgorithm.cls_null);
 
diff --git a/crypto/src/crypto/tls/DefaultTlsServer.cs b/crypto/src/crypto/tls/DefaultTlsServer.cs
index 017ed0d85..75f6d8d88 100644
--- a/crypto/src/crypto/tls/DefaultTlsServer.cs
+++ b/crypto/src/crypto/tls/DefaultTlsServer.cs
@@ -236,9 +236,13 @@ namespace Org.BouncyCastle.Crypto.Tls
             case CipherSuite.TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
             case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
             case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
+            case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM:
+            case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
             case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
             case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
             case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
+            case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM:
+            case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8:
             case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
             case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256:
             case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256:
@@ -347,10 +351,12 @@ namespace Org.BouncyCastle.Crypto.Tls
                 return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_128_CBC, MacAlgorithm.hmac_sha256);
 
             case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM:
+            case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM:
             case CipherSuite.TLS_RSA_WITH_AES_128_CCM:
                 return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_128_CCM, MacAlgorithm.cls_null);
 
             case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM_8:
+            case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
             case CipherSuite.TLS_RSA_WITH_AES_128_CCM_8:
                 return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_128_CCM_8, MacAlgorithm.cls_null);
 
@@ -390,10 +396,12 @@ namespace Org.BouncyCastle.Crypto.Tls
                 return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_CBC, MacAlgorithm.hmac_sha384);
 
             case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM:
+            case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM:
             case CipherSuite.TLS_RSA_WITH_AES_256_CCM:
                 return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_CCM, MacAlgorithm.cls_null);
 
             case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM_8:
+            case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8:
             case CipherSuite.TLS_RSA_WITH_AES_256_CCM_8:
                 return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_CCM_8, MacAlgorithm.cls_null);
 
diff --git a/crypto/src/crypto/tls/TlsEccUtilities.cs b/crypto/src/crypto/tls/TlsEccUtilities.cs
index 64c3c1593..34f0f57ba 100644
--- a/crypto/src/crypto/tls/TlsEccUtilities.cs
+++ b/crypto/src/crypto/tls/TlsEccUtilities.cs
@@ -246,6 +246,14 @@ namespace Org.BouncyCastle.Crypto.Tls
             case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384:
 
             /*
+             * RFC 7251
+             */
+            case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM:
+            case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
+            case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM:
+            case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8:
+
+            /*
              * draft-agl-tls-chacha20poly1305-04
              */
             case CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:
diff --git a/crypto/src/crypto/tls/TlsProtocol.cs b/crypto/src/crypto/tls/TlsProtocol.cs
index 8ba156952..09838a717 100644
--- a/crypto/src/crypto/tls/TlsProtocol.cs
+++ b/crypto/src/crypto/tls/TlsProtocol.cs
@@ -956,7 +956,11 @@ namespace Org.BouncyCastle.Crypto.Tls
             case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256:
             case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256:
             case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
+            case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM:
+            case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
             case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
+            case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM:
+            case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8:
             case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256:
             case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256:
             case CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:
diff --git a/crypto/src/crypto/tls/TlsUtilities.cs b/crypto/src/crypto/tls/TlsUtilities.cs
index d571e5900..485ecb760 100644
--- a/crypto/src/crypto/tls/TlsUtilities.cs
+++ b/crypto/src/crypto/tls/TlsUtilities.cs
@@ -1252,11 +1252,13 @@ namespace Org.BouncyCastle.Crypto.Tls
 
             case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CCM:
             case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM:
+            case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM:
             case CipherSuite.TLS_PSK_WITH_AES_128_CCM:
             case CipherSuite.TLS_RSA_WITH_AES_128_CCM:
                 return EncryptionAlgorithm.AES_128_CCM;
 
             case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM_8:
+            case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
             case CipherSuite.TLS_PSK_DHE_WITH_AES_128_CCM_8:
             case CipherSuite.TLS_PSK_WITH_AES_128_CCM_8:
             case CipherSuite.TLS_RSA_WITH_AES_128_CCM_8:
@@ -1313,11 +1315,13 @@ namespace Org.BouncyCastle.Crypto.Tls
 
             case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CCM:
             case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM:
+            case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM:
             case CipherSuite.TLS_PSK_WITH_AES_256_CCM:
             case CipherSuite.TLS_RSA_WITH_AES_256_CCM:
                 return EncryptionAlgorithm.AES_256_CCM;
 
             case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM_8:
+            case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8:
             case CipherSuite.TLS_PSK_DHE_WITH_AES_256_CCM_8:
             case CipherSuite.TLS_PSK_WITH_AES_256_CCM_8:
             case CipherSuite.TLS_RSA_WITH_AES_256_CCM_8:
@@ -1554,8 +1558,12 @@ namespace Org.BouncyCastle.Crypto.Tls
             case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384:
             case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384:
             case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
+            case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM:
+            case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
             case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
             case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
+            case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM:
+            case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8:
             case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
             case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256:
             case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256:
diff --git a/crypto/src/openpgp/PgpPublicKey.cs b/crypto/src/openpgp/PgpPublicKey.cs
index b0720146c..c6b2e9e0e 100644
--- a/crypto/src/openpgp/PgpPublicKey.cs
+++ b/crypto/src/openpgp/PgpPublicKey.cs
@@ -11,22 +11,22 @@ using Org.BouncyCastle.Utilities.Collections;
 
 namespace Org.BouncyCastle.Bcpg.OpenPgp
 {
-	/// <remarks>General class to handle a PGP public key object.</remarks>
+    /// <remarks>General class to handle a PGP public key object.</remarks>
     public class PgpPublicKey
     {
-		private static readonly int[] MasterKeyCertificationTypes = new int[]
-		{
-			PgpSignature.PositiveCertification,
-			PgpSignature.CasualCertification,
-			PgpSignature.NoCertification,
-			PgpSignature.DefaultCertification
-		};
-
-		private long				keyId;
+        private static readonly int[] MasterKeyCertificationTypes = new int[]
+        {
+            PgpSignature.PositiveCertification,
+            PgpSignature.CasualCertification,
+            PgpSignature.NoCertification,
+            PgpSignature.DefaultCertification
+        };
+
+        private long				keyId;
         private byte[]				fingerprint;
         private int					keyStrength;
 
-		internal PublicKeyPacket	publicPk;
+        internal PublicKeyPacket	publicPk;
         internal TrustPacket		trustPk;
         internal IList			    keySigs = Platform.CreateArrayList();
         internal IList			    ids = Platform.CreateArrayList();
@@ -34,45 +34,45 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
         internal IList              idSigs = Platform.CreateArrayList();
         internal IList			    subSigs;
 
-		private void Init()
+        private void Init()
         {
             IBcpgKey key = publicPk.Key;
 
-			if (publicPk.Version <= 3)
+            if (publicPk.Version <= 3)
             {
                 RsaPublicBcpgKey rK = (RsaPublicBcpgKey) key;
 
-				this.keyId = rK.Modulus.LongValue;
+                this.keyId = rK.Modulus.LongValue;
 
-				try
+                try
                 {
                     IDigest digest = DigestUtilities.GetDigest("MD5");
 
-					byte[] bytes = rK.Modulus.ToByteArrayUnsigned();
-					digest.BlockUpdate(bytes, 0, bytes.Length);
+                    byte[] bytes = rK.Modulus.ToByteArrayUnsigned();
+                    digest.BlockUpdate(bytes, 0, bytes.Length);
 
-					bytes = rK.PublicExponent.ToByteArrayUnsigned();
-					digest.BlockUpdate(bytes, 0, bytes.Length);
+                    bytes = rK.PublicExponent.ToByteArrayUnsigned();
+                    digest.BlockUpdate(bytes, 0, bytes.Length);
 
-					this.fingerprint = DigestUtilities.DoFinal(digest);
+                    this.fingerprint = DigestUtilities.DoFinal(digest);
                 }
-				//catch (NoSuchAlgorithmException)
-				catch (Exception e)
+                //catch (NoSuchAlgorithmException)
+                catch (Exception e)
                 {
                     throw new IOException("can't find MD5", e);
                 }
 
-				this.keyStrength = rK.Modulus.BitLength;
+                this.keyStrength = rK.Modulus.BitLength;
             }
             else
             {
                 byte[] kBytes = publicPk.GetEncodedContents();
 
-				try
+                try
                 {
                     IDigest digest = DigestUtilities.GetDigest("SHA1");
 
-					digest.Update(0x99);
+                    digest.Update(0x99);
                     digest.Update((byte)(kBytes.Length >> 8));
                     digest.Update((byte)kBytes.Length);
                     digest.BlockUpdate(kBytes, 0, kBytes.Length);
@@ -83,7 +83,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
                     throw new IOException("can't find SHA1", e);
                 }
 
-				this.keyId = (long)(((ulong)fingerprint[fingerprint.Length - 8] << 56)
+                this.keyId = (long)(((ulong)fingerprint[fingerprint.Length - 8] << 56)
                     | ((ulong)fingerprint[fingerprint.Length - 7] << 48)
                     | ((ulong)fingerprint[fingerprint.Length - 6] << 40)
                     | ((ulong)fingerprint[fingerprint.Length - 5] << 32)
@@ -92,7 +92,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
                     | ((ulong)fingerprint[fingerprint.Length - 2] << 8)
                     | (ulong)fingerprint[fingerprint.Length - 1]);
 
-				if (key is RsaPublicBcpgKey)
+                if (key is RsaPublicBcpgKey)
                 {
                     this.keyStrength = ((RsaPublicBcpgKey)key).Modulus.BitLength;
                 }
@@ -107,57 +107,57 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
             }
         }
 
-		/// <summary>
-		/// Create a PgpPublicKey from the passed in lightweight one.
-		/// </summary>
-		/// <remarks>
-		/// Note: the time passed in affects the value of the key's keyId, so you probably only want
-		/// to do this once for a lightweight key, or make sure you keep track of the time you used.
-		/// </remarks>
-		/// <param name="algorithm">Asymmetric algorithm type representing the public key.</param>
-		/// <param name="pubKey">Actual public key to associate.</param>
-		/// <param name="time">Date of creation.</param>
-		/// <exception cref="ArgumentException">If <c>pubKey</c> is not public.</exception>
-		/// <exception cref="PgpException">On key creation problem.</exception>
+        /// <summary>
+        /// Create a PgpPublicKey from the passed in lightweight one.
+        /// </summary>
+        /// <remarks>
+        /// Note: the time passed in affects the value of the key's keyId, so you probably only want
+        /// to do this once for a lightweight key, or make sure you keep track of the time you used.
+        /// </remarks>
+        /// <param name="algorithm">Asymmetric algorithm type representing the public key.</param>
+        /// <param name="pubKey">Actual public key to associate.</param>
+        /// <param name="time">Date of creation.</param>
+        /// <exception cref="ArgumentException">If <c>pubKey</c> is not public.</exception>
+        /// <exception cref="PgpException">On key creation problem.</exception>
         public PgpPublicKey(
             PublicKeyAlgorithmTag	algorithm,
             AsymmetricKeyParameter	pubKey,
             DateTime				time)
         {
-			if (pubKey.IsPrivate)
-				throw new ArgumentException("Expected a public key", "pubKey");
+            if (pubKey.IsPrivate)
+                throw new ArgumentException("Expected a public key", "pubKey");
 
-			IBcpgKey bcpgKey;
+            IBcpgKey bcpgKey;
             if (pubKey is RsaKeyParameters)
             {
                 RsaKeyParameters rK = (RsaKeyParameters) pubKey;
 
-				bcpgKey = new RsaPublicBcpgKey(rK.Modulus, rK.Exponent);
+                bcpgKey = new RsaPublicBcpgKey(rK.Modulus, rK.Exponent);
             }
             else if (pubKey is DsaPublicKeyParameters)
             {
                 DsaPublicKeyParameters dK = (DsaPublicKeyParameters) pubKey;
                 DsaParameters dP = dK.Parameters;
 
-				bcpgKey = new DsaPublicBcpgKey(dP.P, dP.Q, dP.G, dK.Y);
+                bcpgKey = new DsaPublicBcpgKey(dP.P, dP.Q, dP.G, dK.Y);
             }
             else if (pubKey is ElGamalPublicKeyParameters)
             {
                 ElGamalPublicKeyParameters eK = (ElGamalPublicKeyParameters) pubKey;
                 ElGamalParameters eS = eK.Parameters;
 
-				bcpgKey = new ElGamalPublicBcpgKey(eS.P, eS.G, eK.Y);
+                bcpgKey = new ElGamalPublicBcpgKey(eS.P, eS.G, eK.Y);
             }
             else
             {
                 throw new PgpException("unknown key class");
             }
 
-			this.publicPk = new PublicKeyPacket(algorithm, time, bcpgKey);
+            this.publicPk = new PublicKeyPacket(algorithm, time, bcpgKey);
             this.ids = Platform.CreateArrayList();
             this.idSigs = Platform.CreateArrayList();
 
-			try
+            try
             {
                 Init();
             }
@@ -167,7 +167,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
             }
         }
 
-		/// <summary>Constructor for a sub-key.</summary>
+        /// <summary>Constructor for a sub-key.</summary>
         internal PgpPublicKey(
             PublicKeyPacket	publicPk,
             TrustPacket		trustPk,
@@ -177,10 +177,10 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
             this.trustPk = trustPk;
             this.subSigs = sigs;
 
-			Init();
+            Init();
         }
 
-		internal PgpPublicKey(
+        internal PgpPublicKey(
             PgpPublicKey	key,
             TrustPacket		trust,
             IList           subSigs)
@@ -189,19 +189,19 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
             this.trustPk = trust;
             this.subSigs = subSigs;
 
-			this.fingerprint = key.fingerprint;
+            this.fingerprint = key.fingerprint;
             this.keyId = key.keyId;
             this.keyStrength = key.keyStrength;
         }
 
-		/// <summary>Copy constructor.</summary>
-		/// <param name="pubKey">The public key to copy.</param>
+        /// <summary>Copy constructor.</summary>
+        /// <param name="pubKey">The public key to copy.</param>
         internal PgpPublicKey(
             PgpPublicKey pubKey)
         {
             this.publicPk = pubKey.publicPk;
 
-			this.keySigs = Platform.CreateArrayList(pubKey.keySigs);
+            this.keySigs = Platform.CreateArrayList(pubKey.keySigs);
             this.ids = Platform.CreateArrayList(pubKey.ids);
             this.idTrusts = Platform.CreateArrayList(pubKey.idTrusts);
             this.idSigs = Platform.CreateArrayList(pubKey.idSigs.Count);
@@ -210,7 +210,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
                 this.idSigs.Add(Platform.CreateArrayList((IList)pubKey.idSigs[i]));
             }
 
-			if (pubKey.subSigs != null)
+            if (pubKey.subSigs != null)
             {
                 this.subSigs = Platform.CreateArrayList(pubKey.subSigs.Count);
                 for (int i = 0; i != pubKey.subSigs.Count; i++)
@@ -219,12 +219,12 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
                 }
             }
 
-			this.fingerprint = pubKey.fingerprint;
+            this.fingerprint = pubKey.fingerprint;
             this.keyId = pubKey.keyId;
             this.keyStrength = pubKey.keyStrength;
         }
 
-		internal PgpPublicKey(
+        internal PgpPublicKey(
             PublicKeyPacket	publicPk,
             TrustPacket		trustPk,
             IList		    keySigs,
@@ -239,10 +239,10 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
             this.idTrusts = idTrusts;
             this.idSigs = idSigs;
 
-			Init();
+            Init();
         }
 
-		internal PgpPublicKey(
+        internal PgpPublicKey(
             PublicKeyPacket	publicPk,
             IList           ids,
             IList           idSigs)
@@ -253,159 +253,160 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
             Init();
         }
 
-		/// <summary>The version of this key.</summary>
+        /// <summary>The version of this key.</summary>
         public int Version
         {
-			get { return publicPk.Version; }
+            get { return publicPk.Version; }
         }
 
-		/// <summary>The creation time of this key.</summary>
-		public DateTime CreationTime
+        /// <summary>The creation time of this key.</summary>
+        public DateTime CreationTime
         {
-			get { return publicPk.GetTime(); }
+            get { return publicPk.GetTime(); }
         }
 
-		/// <summary>The number of valid days from creation time - zero means no expiry.</summary>
+        /// <summary>The number of valid days from creation time - zero means no expiry.</summary>
         public int ValidDays
         {
-			get
-			{
-				if (publicPk.Version > 3)
-				{
-					return (int)(GetValidSeconds() / (24 * 60 * 60));
-				}
-
-				return publicPk.ValidDays;
-			}
-        }
-
-		/// <summary>Return the trust data associated with the public key, if present.</summary>
-		/// <returns>A byte array with trust data, null otherwise.</returns>
-		public byte[] GetTrustData()
-		{
-			if (trustPk == null)
-			{
-				return null;
-			}
-
-			return trustPk.GetLevelAndTrustAmount();
-		}
-
-		/// <summary>The number of valid seconds from creation time - zero means no expiry.</summary>
-		public long GetValidSeconds()
-        {
-			if (publicPk.Version > 3)
-			{
-				if (IsMasterKey)
-				{
-					for (int i = 0; i != MasterKeyCertificationTypes.Length; i++)
-					{
-						long seconds = GetExpirationTimeFromSig(true, MasterKeyCertificationTypes[i]);
-
-						if (seconds >= 0)
-						{
-							return seconds;
-						}
-					}
-				}
-				else
-				{
-					long seconds = GetExpirationTimeFromSig(false, PgpSignature.SubkeyBinding);
-
-					if (seconds >= 0)
-					{
-						return seconds;
-					}
-				}
-
-				return 0;
-			}
-
-			return (long) publicPk.ValidDays * 24 * 60 * 60;
-        }
-
-		private long GetExpirationTimeFromSig(
-			bool	selfSigned,
-			int		signatureType)
-		{
-			foreach (PgpSignature sig in GetSignaturesOfType(signatureType))
-			{
-				if (!selfSigned || sig.KeyId == KeyId)
-				{
-					PgpSignatureSubpacketVector hashed = sig.GetHashedSubPackets();
-
-					if (hashed != null)
-					{
-						return hashed.GetKeyExpirationTime();
-					}
-
-					return 0;
-				}
-			}
-
-			return -1;
-		}
-
-		/// <summary>The keyId associated with the public key.</summary>
+            get
+            {
+                if (publicPk.Version > 3)
+                {
+                    return (int)(GetValidSeconds() / (24 * 60 * 60));
+                }
+
+                return publicPk.ValidDays;
+            }
+        }
+
+        /// <summary>Return the trust data associated with the public key, if present.</summary>
+        /// <returns>A byte array with trust data, null otherwise.</returns>
+        public byte[] GetTrustData()
+        {
+            if (trustPk == null)
+            {
+                return null;
+            }
+
+            return Arrays.Clone(trustPk.GetLevelAndTrustAmount());
+        }
+
+        /// <summary>The number of valid seconds from creation time - zero means no expiry.</summary>
+        public long GetValidSeconds()
+        {
+            if (publicPk.Version > 3)
+            {
+                if (IsMasterKey)
+                {
+                    for (int i = 0; i != MasterKeyCertificationTypes.Length; i++)
+                    {
+                        long seconds = GetExpirationTimeFromSig(true, MasterKeyCertificationTypes[i]);
+
+                        if (seconds >= 0)
+                        {
+                            return seconds;
+                        }
+                    }
+                }
+                else
+                {
+                    long seconds = GetExpirationTimeFromSig(false, PgpSignature.SubkeyBinding);
+
+                    if (seconds >= 0)
+                    {
+                        return seconds;
+                    }
+                }
+
+                return 0;
+            }
+
+            return (long) publicPk.ValidDays * 24 * 60 * 60;
+        }
+
+        private long GetExpirationTimeFromSig(
+            bool	selfSigned,
+            int		signatureType)
+        {
+            foreach (PgpSignature sig in GetSignaturesOfType(signatureType))
+            {
+                if (!selfSigned || sig.KeyId == KeyId)
+                {
+                    PgpSignatureSubpacketVector hashed = sig.GetHashedSubPackets();
+
+                    if (hashed != null)
+                    {
+                        return hashed.GetKeyExpirationTime();
+                    }
+
+                    return 0;
+                }
+            }
+
+            return -1;
+        }
+
+        /// <summary>The keyId associated with the public key.</summary>
         public long KeyId
         {
             get { return keyId; }
         }
 
-		/// <summary>The fingerprint of the key</summary>
+        /// <summary>The fingerprint of the key</summary>
         public byte[] GetFingerprint()
         {
-			return (byte[]) fingerprint.Clone();
+            return (byte[]) fingerprint.Clone();
         }
 
-		/// <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
+        /// <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
             {
-				switch (publicPk.Algorithm)
-				{
-					case PublicKeyAlgorithmTag.ElGamalEncrypt:
-					case PublicKeyAlgorithmTag.ElGamalGeneral:
-					case PublicKeyAlgorithmTag.RsaEncrypt:
-					case PublicKeyAlgorithmTag.RsaGeneral:
-						return true;
-					default:
-						return false;
-				}
+                switch (publicPk.Algorithm)
+                {
+                    case PublicKeyAlgorithmTag.ECDH:
+                    case PublicKeyAlgorithmTag.ElGamalEncrypt:
+                    case PublicKeyAlgorithmTag.ElGamalGeneral:
+                    case PublicKeyAlgorithmTag.RsaEncrypt:
+                    case PublicKeyAlgorithmTag.RsaGeneral:
+                        return true;
+                    default:
+                        return false;
+                }
             }
         }
 
-		/// <summary>True, if this is a master key.</summary>
+        /// <summary>True, if this is a master key.</summary>
         public bool IsMasterKey
         {
             get { return subSigs == null; }
         }
 
-		/// <summary>The algorithm code associated with the public key.</summary>
+        /// <summary>The algorithm code associated with the public key.</summary>
         public PublicKeyAlgorithmTag Algorithm
         {
-			get { return publicPk.Algorithm; }
+            get { return publicPk.Algorithm; }
         }
 
-		/// <summary>The strength of the key in bits.</summary>
+        /// <summary>The strength of the key in bits.</summary>
         public int BitStrength
         {
             get { return keyStrength; }
         }
 
-		/// <summary>The public key contained in the object.</summary>
-		/// <returns>A lightweight public key.</returns>
-		/// <exception cref="PgpException">If the key algorithm is not recognised.</exception>
+        /// <summary>The public key contained in the object.</summary>
+        /// <returns>A lightweight public key.</returns>
+        /// <exception cref="PgpException">If the key algorithm is not recognised.</exception>
         public AsymmetricKeyParameter GetKey()
         {
             try
@@ -438,50 +439,50 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
             }
         }
 
-		/// <summary>Allows enumeration of any user IDs associated with the key.</summary>
-		/// <returns>An <c>IEnumerable</c> of <c>string</c> objects.</returns>
+        /// <summary>Allows enumeration of any user IDs associated with the key.</summary>
+        /// <returns>An <c>IEnumerable</c> of <c>string</c> objects.</returns>
         public IEnumerable GetUserIds()
         {
             IList temp = Platform.CreateArrayList();
 
-			foreach (object o in ids)
-			{
-				if (o is string)
-				{
-					temp.Add(o);
+            foreach (object o in ids)
+            {
+                if (o is string)
+                {
+                    temp.Add(o);
                 }
             }
 
-			return new EnumerableProxy(temp);
+            return new EnumerableProxy(temp);
         }
 
-		/// <summary>Allows enumeration of any user attribute vectors associated with the key.</summary>
-		/// <returns>An <c>IEnumerable</c> of <c>PgpUserAttributeSubpacketVector</c> objects.</returns>
+        /// <summary>Allows enumeration of any user attribute vectors associated with the key.</summary>
+        /// <returns>An <c>IEnumerable</c> of <c>PgpUserAttributeSubpacketVector</c> objects.</returns>
         public IEnumerable GetUserAttributes()
         {
             IList temp = Platform.CreateArrayList();
 
-			foreach (object o in ids)
-			{
-				if (o is PgpUserAttributeSubpacketVector)
-				{
-					temp.Add(o);
-				}
-			}
+            foreach (object o in ids)
+            {
+                if (o is PgpUserAttributeSubpacketVector)
+                {
+                    temp.Add(o);
+                }
+            }
 
-			return new EnumerableProxy(temp);
+            return new EnumerableProxy(temp);
         }
 
-		/// <summary>Allows enumeration of any signatures associated with the passed in id.</summary>
-		/// <param name="id">The ID to be matched.</param>
-		/// <returns>An <c>IEnumerable</c> of <c>PgpSignature</c> objects.</returns>
+        /// <summary>Allows enumeration of any signatures associated with the passed in id.</summary>
+        /// <param name="id">The ID to be matched.</param>
+        /// <returns>An <c>IEnumerable</c> of <c>PgpSignature</c> objects.</returns>
         public IEnumerable GetSignaturesForId(
             string id)
         {
-			if (id == null)
-				throw new ArgumentNullException("id");
+            if (id == null)
+                throw new ArgumentNullException("id");
 
-			for (int i = 0; i != ids.Count; i++)
+            for (int i = 0; i != ids.Count; i++)
             {
                 if (id.Equals(ids[i]))
                 {
@@ -489,12 +490,12 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
                 }
             }
 
-			return null;
+            return null;
         }
 
-		/// <summary>Allows enumeration of signatures associated with the passed in user attributes.</summary>
-		/// <param name="userAttributes">The vector of user attributes to be matched.</param>
-		/// <returns>An <c>IEnumerable</c> of <c>PgpSignature</c> objects.</returns>
+        /// <summary>Allows enumeration of signatures associated with the passed in user attributes.</summary>
+        /// <param name="userAttributes">The vector of user attributes to be matched.</param>
+        /// <returns>An <c>IEnumerable</c> of <c>PgpSignature</c> objects.</returns>
         public IEnumerable GetSignaturesForUserAttribute(
             PgpUserAttributeSubpacketVector userAttributes)
         {
@@ -506,18 +507,18 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
                 }
             }
 
-			return null;
+            return null;
         }
 
-		/// <summary>Allows enumeration of signatures of the passed in type that are on this key.</summary>
-		/// <param name="signatureType">The type of the signature to be returned.</param>
-		/// <returns>An <c>IEnumerable</c> of <c>PgpSignature</c> objects.</returns>
+        /// <summary>Allows enumeration of signatures of the passed in type that are on this key.</summary>
+        /// <param name="signatureType">The type of the signature to be returned.</param>
+        /// <returns>An <c>IEnumerable</c> of <c>PgpSignature</c> objects.</returns>
         public IEnumerable GetSignaturesOfType(
             int signatureType)
         {
             IList temp = Platform.CreateArrayList();
 
-			foreach (PgpSignature sig in GetSignatures())
+            foreach (PgpSignature sig in GetSignatures())
             {
                 if (sig.SignatureType == signatureType)
                 {
@@ -525,63 +526,79 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
                 }
             }
 
-			return new EnumerableProxy(temp);
+            return new EnumerableProxy(temp);
         }
 
-		/// <summary>Allows enumeration of all signatures/certifications associated with this key.</summary>
-		/// <returns>An <c>IEnumerable</c> with all signatures/certifications.</returns>
+        /// <summary>Allows enumeration of all signatures/certifications associated with this key.</summary>
+        /// <returns>An <c>IEnumerable</c> with all signatures/certifications.</returns>
         public IEnumerable GetSignatures()
         {
-			IList sigs;
-			if (subSigs != null)
-			{
-				sigs = subSigs;
-			}
-			else
-			{
+            IList sigs = subSigs;
+            if (sigs == null)
+            {
                 sigs = Platform.CreateArrayList(keySigs);
 
-				foreach (ICollection extraSigs in idSigs)
-				{
+                foreach (ICollection extraSigs in idSigs)
+                {
                     CollectionUtilities.AddRange(sigs, extraSigs);
-				}
-			}
+                }
+            }
+
+            return new EnumerableProxy(sigs);
+        }
+
+        /**
+         * Return all signatures/certifications directly associated with this key (ie, not to a user id).
+         *
+         * @return an iterator (possibly empty) with all signatures/certifications.
+         */
+        public IEnumerable GetKeySignatures()
+        {
+            IList sigs = subSigs;
+            if (sigs == null)
+            {
+                sigs = Platform.CreateArrayList(keySigs);
+            }
+            return new EnumerableProxy(sigs);
+        }
 
-			return new EnumerableProxy(sigs);
+        public PublicKeyPacket PublicKeyPacket
+        {
+            get { return publicPk; }
         }
 
-		public byte[] GetEncoded()
+        public byte[] GetEncoded()
         {
             MemoryStream bOut = new MemoryStream();
             Encode(bOut);
             return bOut.ToArray();
         }
 
-		public void Encode(
+        public void Encode(
             Stream outStr)
         {
             BcpgOutputStream bcpgOut = BcpgOutputStream.Wrap(outStr);
 
-			bcpgOut.WritePacket(publicPk);
+            bcpgOut.WritePacket(publicPk);
             if (trustPk != null)
             {
                 bcpgOut.WritePacket(trustPk);
             }
 
-			if (subSigs == null)    // not a sub-key
+            if (subSigs == null)    // not a sub-key
             {
-				foreach (PgpSignature keySig in keySigs)
-				{
-					keySig.Encode(bcpgOut);
-				}
+                foreach (PgpSignature keySig in keySigs)
+                {
+                    keySig.Encode(bcpgOut);
+                }
 
-				for (int i = 0; i != ids.Count; i++)
+                for (int i = 0; i != ids.Count; i++)
                 {
                     if (ids[i] is string)
                     {
                         string id = (string) ids[i];
 
-						bcpgOut.WritePacket(new UserIdPacket(id));
+                        bcpgOut.WritePacket(new UserIdPacket(id));
                     }
                     else
                     {
@@ -589,28 +606,28 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
                         bcpgOut.WritePacket(new UserAttributePacket(v.ToSubpacketArray()));
                     }
 
-					if (idTrusts[i] != null)
+                    if (idTrusts[i] != null)
                     {
                         bcpgOut.WritePacket((ContainedPacket)idTrusts[i]);
                     }
 
-					foreach (PgpSignature sig in (IList) idSigs[i])
-					{
-						sig.Encode(bcpgOut);
-					}
+                    foreach (PgpSignature sig in (IList) idSigs[i])
+                    {
+                        sig.Encode(bcpgOut);
+                    }
                 }
             }
             else
             {
-				foreach (PgpSignature subSig in subSigs)
-				{
-					subSig.Encode(bcpgOut);
-				}
+                foreach (PgpSignature subSig in subSigs)
+                {
+                    subSig.Encode(bcpgOut);
+                }
             }
         }
 
-		/// <summary>Check whether this (sub)key has a revocation signature on it.</summary>
-		/// <returns>True, if this (sub)key has been revoked.</returns>
+        /// <summary>Check whether this (sub)key has a revocation signature on it.</summary>
+        /// <returns>True, if this (sub)key has been revoked.</returns>
         public bool IsRevoked()
         {
             int ns = 0;
@@ -638,98 +655,98 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
             return revoked;
         }
 
-		/// <summary>Add a certification for an id to the given public key.</summary>
-		/// <param name="key">The key the certification is to be added to.</param>
-		/// <param name="id">The ID the certification is associated with.</param>
-		/// <param name="certification">The new certification.</param>
-		/// <returns>The re-certified key.</returns>
+        /// <summary>Add a certification for an id to the given public key.</summary>
+        /// <param name="key">The key the certification is to be added to.</param>
+        /// <param name="id">The ID the certification is associated with.</param>
+        /// <param name="certification">The new certification.</param>
+        /// <returns>The re-certified key.</returns>
         public static PgpPublicKey AddCertification(
             PgpPublicKey	key,
             string			id,
             PgpSignature	certification)
         {
-			return AddCert(key, id, certification);
-		}
-
-		/// <summary>Add a certification for the given UserAttributeSubpackets to the given public key.</summary>
-		/// <param name="key">The key the certification is to be added to.</param>
-		/// <param name="userAttributes">The attributes the certification is associated with.</param>
-		/// <param name="certification">The new certification.</param>
-		/// <returns>The re-certified key.</returns>
-		public static PgpPublicKey AddCertification(
-			PgpPublicKey					key,
-			PgpUserAttributeSubpacketVector	userAttributes,
-			PgpSignature					certification)
-		{
-			return AddCert(key, userAttributes, certification);
-		}
-
-		private static PgpPublicKey AddCert(
-			PgpPublicKey	key,
-			object			id,
-			PgpSignature	certification)
-		{
-			PgpPublicKey returnKey = new PgpPublicKey(key);
-			IList sigList = null;
-
-			for (int i = 0; i != returnKey.ids.Count; i++)
-			{
-				if (id.Equals(returnKey.ids[i]))
-				{
-					sigList = (IList) returnKey.idSigs[i];
-				}
-			}
-
-			if (sigList != null)
-			{
-				sigList.Add(certification);
-			}
-			else
-			{
-				sigList = Platform.CreateArrayList();
-				sigList.Add(certification);
-				returnKey.ids.Add(id);
-				returnKey.idTrusts.Add(null);
-				returnKey.idSigs.Add(sigList);
-			}
-
-			return returnKey;
-		}
-
-		/// <summary>
-		/// Remove any certifications associated with a user attribute subpacket on a key.
-		/// </summary>
-		/// <param name="key">The key the certifications are to be removed from.</param>
-		/// <param name="userAttributes">The attributes to be removed.</param>
-		/// <returns>
-		/// The re-certified key, or null if the user attribute subpacket was not found on the key.
-		/// </returns>
-		public static PgpPublicKey RemoveCertification(
-			PgpPublicKey					key,
-			PgpUserAttributeSubpacketVector	userAttributes)
-		{
-			return RemoveCert(key, userAttributes);
-		}
-
-		/// <summary>Remove any certifications associated with a given ID on a key.</summary>
-		/// <param name="key">The key the certifications are to be removed from.</param>
-		/// <param name="id">The ID that is to be removed.</param>
-		/// <returns>The re-certified key, or null if the ID was not found on the key.</returns>
+            return AddCert(key, id, certification);
+        }
+
+        /// <summary>Add a certification for the given UserAttributeSubpackets to the given public key.</summary>
+        /// <param name="key">The key the certification is to be added to.</param>
+        /// <param name="userAttributes">The attributes the certification is associated with.</param>
+        /// <param name="certification">The new certification.</param>
+        /// <returns>The re-certified key.</returns>
+        public static PgpPublicKey AddCertification(
+            PgpPublicKey					key,
+            PgpUserAttributeSubpacketVector	userAttributes,
+            PgpSignature					certification)
+        {
+            return AddCert(key, userAttributes, certification);
+        }
+
+        private static PgpPublicKey AddCert(
+            PgpPublicKey	key,
+            object			id,
+            PgpSignature	certification)
+        {
+            PgpPublicKey returnKey = new PgpPublicKey(key);
+            IList sigList = null;
+
+            for (int i = 0; i != returnKey.ids.Count; i++)
+            {
+                if (id.Equals(returnKey.ids[i]))
+                {
+                    sigList = (IList) returnKey.idSigs[i];
+                }
+            }
+
+            if (sigList != null)
+            {
+                sigList.Add(certification);
+            }
+            else
+            {
+                sigList = Platform.CreateArrayList();
+                sigList.Add(certification);
+                returnKey.ids.Add(id);
+                returnKey.idTrusts.Add(null);
+                returnKey.idSigs.Add(sigList);
+            }
+
+            return returnKey;
+        }
+
+        /// <summary>
+        /// Remove any certifications associated with a user attribute subpacket on a key.
+        /// </summary>
+        /// <param name="key">The key the certifications are to be removed from.</param>
+        /// <param name="userAttributes">The attributes to be removed.</param>
+        /// <returns>
+        /// The re-certified key, or null if the user attribute subpacket was not found on the key.
+        /// </returns>
+        public static PgpPublicKey RemoveCertification(
+            PgpPublicKey					key,
+            PgpUserAttributeSubpacketVector	userAttributes)
+        {
+            return RemoveCert(key, userAttributes);
+        }
+
+        /// <summary>Remove any certifications associated with a given ID on a key.</summary>
+        /// <param name="key">The key the certifications are to be removed from.</param>
+        /// <param name="id">The ID that is to be removed.</param>
+        /// <returns>The re-certified key, or null if the ID was not found on the key.</returns>
         public static PgpPublicKey RemoveCertification(
             PgpPublicKey	key,
             string			id)
         {
-			return RemoveCert(key, id);
-		}
+            return RemoveCert(key, id);
+        }
 
-		private static PgpPublicKey RemoveCert(
-			PgpPublicKey	key,
-			object			id)
-		{
-			PgpPublicKey returnKey = new PgpPublicKey(key);
+        private static PgpPublicKey RemoveCert(
+            PgpPublicKey	key,
+            object			id)
+        {
+            PgpPublicKey returnKey = new PgpPublicKey(key);
             bool found = false;
 
-			for (int i = 0; i < returnKey.ids.Count; i++)
+            for (int i = 0; i < returnKey.ids.Count; i++)
             {
                 if (id.Equals(returnKey.ids[i]))
                 {
@@ -740,64 +757,64 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
                 }
             }
 
-			return found ? returnKey : null;
+            return found ? returnKey : null;
         }
 
-		/// <summary>Remove a certification associated with a given ID on a key.</summary>
-		/// <param name="key">The key the certifications are to be removed from.</param>
-		/// <param name="id">The ID that the certfication is to be removed from.</param>
-		/// <param name="certification">The certfication to be removed.</param>
-		/// <returns>The re-certified key, or null if the certification was not found.</returns>
+        /// <summary>Remove a certification associated with a given ID on a key.</summary>
+        /// <param name="key">The key the certifications are to be removed from.</param>
+        /// <param name="id">The ID that the certfication is to be removed from.</param>
+        /// <param name="certification">The certfication to be removed.</param>
+        /// <returns>The re-certified key, or null if the certification was not found.</returns>
         public static PgpPublicKey RemoveCertification(
             PgpPublicKey	key,
             string			id,
             PgpSignature	certification)
         {
-			return RemoveCert(key, id, certification);
-		}
-
-		/// <summary>Remove a certification associated with a given user attributes on a key.</summary>
-		/// <param name="key">The key the certifications are to be removed from.</param>
-		/// <param name="userAttributes">The user attributes that the certfication is to be removed from.</param>
-		/// <param name="certification">The certification to be removed.</param>
-		/// <returns>The re-certified key, or null if the certification was not found.</returns>
-		public static PgpPublicKey RemoveCertification(
-			PgpPublicKey					key,
-			PgpUserAttributeSubpacketVector	userAttributes,
-			PgpSignature					certification)
-		{
-			return RemoveCert(key, userAttributes, certification);
-		}
-
-		private static PgpPublicKey RemoveCert(
-			PgpPublicKey	key,
-			object			id,
-			PgpSignature	certification)
-		{
-			PgpPublicKey returnKey = new PgpPublicKey(key);
+            return RemoveCert(key, id, certification);
+        }
+
+        /// <summary>Remove a certification associated with a given user attributes on a key.</summary>
+        /// <param name="key">The key the certifications are to be removed from.</param>
+        /// <param name="userAttributes">The user attributes that the certfication is to be removed from.</param>
+        /// <param name="certification">The certification to be removed.</param>
+        /// <returns>The re-certified key, or null if the certification was not found.</returns>
+        public static PgpPublicKey RemoveCertification(
+            PgpPublicKey					key,
+            PgpUserAttributeSubpacketVector	userAttributes,
+            PgpSignature					certification)
+        {
+            return RemoveCert(key, userAttributes, certification);
+        }
+
+        private static PgpPublicKey RemoveCert(
+            PgpPublicKey	key,
+            object			id,
+            PgpSignature	certification)
+        {
+            PgpPublicKey returnKey = new PgpPublicKey(key);
             bool found = false;
 
-			for (int i = 0; i < returnKey.ids.Count; i++)
+            for (int i = 0; i < returnKey.ids.Count; i++)
             {
                 if (id.Equals(returnKey.ids[i]))
                 {
                     IList certs = (IList) returnKey.idSigs[i];
                     found = certs.Contains(certification);
 
-					if (found)
-					{
-						certs.Remove(certification);
-					}
+                    if (found)
+                    {
+                        certs.Remove(certification);
+                    }
                 }
             }
 
-			return found ? returnKey : null;
+            return found ? returnKey : null;
         }
 
-		/// <summary>Add a revocation or some other key certification to a key.</summary>
-		/// <param name="key">The key the revocation is to be added to.</param>
-		/// <param name="certification">The key signature to be added.</param>
-		/// <returns>The new changed public key object.</returns>
+        /// <summary>Add a revocation or some other key certification to a key.</summary>
+        /// <param name="key">The key the revocation is to be added to.</param>
+        /// <param name="certification">The key signature to be added.</param>
+        /// <returns>The new changed public key object.</returns>
         public static PgpPublicKey AddCertification(
             PgpPublicKey	key,
             PgpSignature	certification)
@@ -817,9 +834,9 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
                 }
             }
 
-			PgpPublicKey returnKey = new PgpPublicKey(key);
+            PgpPublicKey returnKey = new PgpPublicKey(key);
 
-			if (returnKey.subSigs != null)
+            if (returnKey.subSigs != null)
             {
                 returnKey.subSigs.Add(certification);
             }
@@ -828,63 +845,63 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
                 returnKey.keySigs.Add(certification);
             }
 
-			return returnKey;
+            return returnKey;
         }
 
-		/// <summary>Remove a certification from the key.</summary>
-		/// <param name="key">The key the certifications are to be removed from.</param>
-		/// <param name="certification">The certfication to be removed.</param>
-		/// <returns>The modified key, null if the certification was not found.</returns>
-		public static PgpPublicKey RemoveCertification(
-			PgpPublicKey	key,
-			PgpSignature	certification)
-		{
-			PgpPublicKey returnKey = new PgpPublicKey(key);
-			IList sigs = returnKey.subSigs != null
-				?	returnKey.subSigs
-				:	returnKey.keySigs;
+        /// <summary>Remove a certification from the key.</summary>
+        /// <param name="key">The key the certifications are to be removed from.</param>
+        /// <param name="certification">The certfication to be removed.</param>
+        /// <returns>The modified key, null if the certification was not found.</returns>
+        public static PgpPublicKey RemoveCertification(
+            PgpPublicKey	key,
+            PgpSignature	certification)
+        {
+            PgpPublicKey returnKey = new PgpPublicKey(key);
+            IList sigs = returnKey.subSigs != null
+                ?	returnKey.subSigs
+                :	returnKey.keySigs;
 
 //			bool found = sigs.Remove(certification);
-			int pos = sigs.IndexOf(certification);
-			bool found = pos >= 0;
-
-			if (found)
-			{
-				sigs.RemoveAt(pos);
-			}
-			else
-			{
-				foreach (String id in key.GetUserIds())
-				{
-					foreach (object sig in key.GetSignaturesForId(id))
-					{
-						// TODO Is this the right type of equality test?
-						if (certification == sig)
-						{
-							found = true;
-							returnKey = PgpPublicKey.RemoveCertification(returnKey, id, certification);
-						}
-					}
-				}
-
-				if (!found)
-				{
-					foreach (PgpUserAttributeSubpacketVector id in key.GetUserAttributes())
-					{
-						foreach (object sig in key.GetSignaturesForUserAttribute(id))
-						{
-							// TODO Is this the right type of equality test?
-							if (certification == sig)
-							{
-								found = true;
-								returnKey = PgpPublicKey.RemoveCertification(returnKey, id, certification);
-							}
-						}
-					}
-				}
-			}
-
-			return returnKey;
-		}
-	}
+            int pos = sigs.IndexOf(certification);
+            bool found = pos >= 0;
+
+            if (found)
+            {
+                sigs.RemoveAt(pos);
+            }
+            else
+            {
+                foreach (String id in key.GetUserIds())
+                {
+                    foreach (object sig in key.GetSignaturesForId(id))
+                    {
+                        // TODO Is this the right type of equality test?
+                        if (certification == sig)
+                        {
+                            found = true;
+                            returnKey = PgpPublicKey.RemoveCertification(returnKey, id, certification);
+                        }
+                    }
+                }
+
+                if (!found)
+                {
+                    foreach (PgpUserAttributeSubpacketVector id in key.GetUserAttributes())
+                    {
+                        foreach (object sig in key.GetSignaturesForUserAttribute(id))
+                        {
+                            // TODO Is this the right type of equality test?
+                            if (certification == sig)
+                            {
+                                found = true;
+                                returnKey = PgpPublicKey.RemoveCertification(returnKey, id, certification);
+                            }
+                        }
+                    }
+                }
+            }
+
+            return returnKey;
+        }
+    }
 }