Пример #1
0
        public void TestAddRemoveRange()
        {
            var certificates = new List <X509Certificate> ();
            var chain        = new X509CertificateChain();

            foreach (var authority in CertificateAuthorities)
            {
                var certificate = SecureMimeTestsBase.LoadCertificate(GetTestDataPath(authority));

                certificates.Add(certificate);
            }

            Assert.Throws <ArgumentNullException> (() => chain.AddRange(null));

            chain.AddRange(certificates);

            Assert.AreEqual(CertificateAuthorities.Length, chain.Count, "Unexpected number of certificates after AddRange.");

            int index = 0;

            foreach (var certificate in chain)
            {
                Assert.AreEqual(certificates[index++], certificate, "GetEnumerator");
            }

            index = 0;
            foreach (X509Certificate certificate in ((IEnumerable)chain))
            {
                Assert.AreEqual(certificates[index++], certificate, "GetEnumerator");
            }

            Assert.Throws <ArgumentNullException> (() => chain.RemoveRange(null));

            chain.RemoveRange(certificates);

            Assert.AreEqual(0, chain.Count, "Unexpected number of certificates after RemoveRange.");
        }
Пример #2
0
        /// <summary>
        /// Validates the given certificate.
        /// </summary>
        /// <param name="certificate">X.509 Certificate to validate.</param>
        /// <exception cref="ArgumentNullException">The input parameter 'certificate' is null.</exception>
        /// <exception cref="SecurityTokenValidationException">X.509 Certificate validation failed.</exception>
        public override void Validate(X509Certificate2 certificate)
        {
            if (certificate == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("certificate");
            }

            X509CertificateChain chain = new X509CertificateChain(this.useMachineContext, (uint)this.chainPolicyOID);

            if (this.chainPolicy != null)
            {
                chain.ChainPolicy = this.chainPolicy;
            }

            if (!chain.Build(certificate))
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                          new SecurityTokenValidationException(
                              SR.GetString(
                                  SR.ID4070,
                                  X509Util.GetCertificateId(certificate),
                                  GetChainStatusInformation(chain.ChainStatus))));
            }
        }
Пример #3
0
		/// <summary>
		/// Initializes a new instance of the <see cref="MimeKit.Cryptography.CmsSigner"/> class.
		/// </summary>
		/// <remarks>
		/// <para>The initial value of the <see cref="DigestAlgorithm"/> will be set to
		/// <see cref="MimeKit.Cryptography.DigestAlgorithm.Sha1"/> and both the
		/// <see cref="SignedAttributes"/> and <see cref="UnsignedAttributes"/> properties
		/// will be initialized to empty tables.</para>
		/// </remarks>
		/// <param name="chain">The chain of certificates starting with the signer's certificate back to the root.</param>
		/// <param name="key">The signer's private key.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <para><paramref name="chain"/> is <c>null</c>.</para>
		/// <para>-or-</para>
		/// <para><paramref name="key"/> is <c>null</c>.</para>
		/// </exception>
		/// <exception cref="System.ArgumentException">
		/// <para><paramref name="chain"/> did not contain any certificates.</para>
		/// <para>-or-</para>
		/// <para>The certificate cannot be used for signing.</para>
		/// <para>-or-</para>
		/// <para><paramref name="key"/> is not a private key.</para>
		/// </exception>
		public CmsSigner (IEnumerable<X509Certificate> chain, AsymmetricKeyParameter key) : this ()
		{
			if (chain == null)
				throw new ArgumentNullException (nameof (chain));

			if (key == null)
				throw new ArgumentNullException (nameof (key));

			CertificateChain = new X509CertificateChain (chain);

			if (CertificateChain.Count == 0)
				throw new ArgumentException ("The certificate chain was empty.", nameof (chain));

			CheckCertificateCanBeUsedForSigning (CertificateChain[0]);

			if (!key.IsPrivate)
				throw new ArgumentException ("The key must be a private key.", nameof (key));

			Certificate = CertificateChain[0];
			PrivateKey = key;
		}
Пример #4
0
		/// <summary>
		/// Initializes a new instance of the <see cref="MimeKit.Cryptography.CmsSigner"/> class.
		/// </summary>
		/// <remarks>
		/// <para>The initial value of the <see cref="MimeKit.Cryptography.DigestAlgorithm"/> will
		/// be set to <see cref="MimeKit.Cryptography.DigestAlgorithm.Sha1"/> and both the
		/// <see cref="SignedAttributes"/> and <see cref="UnsignedAttributes"/> properties will be
		/// initialized to empty tables.</para>
		/// </remarks>
		/// <param name="certificate">The signer's certificate.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <paramref name="certificate"/> is <c>null</c>.
		/// </exception>
		/// <exception cref="System.ArgumentException">
		/// <paramref name="certificate"/> cannot be used for signing.
		/// </exception>
		public CmsSigner (X509Certificate2 certificate) : this ()
		{
			if (certificate == null)
				throw new ArgumentNullException (nameof (certificate));

			if (!certificate.HasPrivateKey)
				throw new ArgumentException ("The certificate does not contain a private key.", nameof (certificate));

			var cert = DotNetUtilities.FromX509Certificate (certificate);
			var key = DotNetUtilities.GetKeyPair (certificate.PrivateKey);

			CheckCertificateCanBeUsedForSigning (cert);

			CertificateChain = new X509CertificateChain ();
			CertificateChain.Add (cert);
			Certificate = cert;
			PrivateKey = key.Private;
		}
Пример #5
0
		void LoadPkcs12 (Stream stream, string password)
		{
			var pkcs12 = new Pkcs12Store (stream, password.ToCharArray ());

			foreach (string alias in pkcs12.Aliases) {
				if (!pkcs12.IsKeyEntry (alias))
					continue;

				var chain = pkcs12.GetCertificateChain (alias);
				var key = pkcs12.GetKey (alias);

				if (!key.Key.IsPrivate || chain.Length == 0)
					continue;

				var flags = chain[0].Certificate.GetKeyUsageFlags ();

				if (flags != X509KeyUsageFlags.None && (flags & SecureMimeContext.DigitalSignatureKeyUsageFlags) == 0)
					continue;

				CheckCertificateCanBeUsedForSigning (chain[0].Certificate);

				CertificateChain = new X509CertificateChain ();
				Certificate = chain[0].Certificate;
				PrivateKey = key.Key;

				foreach (var entry in chain)
					CertificateChain.Add (entry.Certificate);

				break;
			}

			if (PrivateKey == null)
				throw new ArgumentException ("The stream did not contain a private key.", nameof (stream));
		}
Пример #6
0
		/// <summary>
		/// Initializes a new instance of the <see cref="MimeKit.Cryptography.CmsSigner"/> class.
		/// </summary>
		/// <remarks>
		/// <para>The initial value of the <see cref="MimeKit.Cryptography.DigestAlgorithm"/> will
		/// be set to <see cref="MimeKit.Cryptography.DigestAlgorithm.Sha1"/> and both the
		/// <see cref="SignedAttributes"/> and <see cref="UnsignedAttributes"/> properties will be
		/// initialized to empty tables.</para>
		/// </remarks>
		/// <param name="certificate">The signer's certificate.</param>
		/// <param name="key">The signer's private key.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <para><paramref name="certificate"/> is <c>null</c>.</para>
		/// <para>-or-</para>
		/// <para><paramref name="key"/> is <c>null</c>.</para>
		/// </exception>
		/// <exception cref="System.ArgumentException">
		/// <para><paramref name="certificate"/> cannot be used for signing.</para>
		/// <para>-or-</para>
		/// <para><paramref name="key"/> is not a private key.</para>
		/// </exception>
		public CmsSigner (X509Certificate certificate, AsymmetricKeyParameter key) : this ()
		{
			if (certificate == null)
				throw new ArgumentNullException (nameof (certificate));

			CheckCertificateCanBeUsedForSigning (certificate);

			if (key == null)
				throw new ArgumentNullException (nameof (key));

			if (!key.IsPrivate)
				throw new ArgumentException ("The key must be a private key.", nameof (key));

			CertificateChain = new X509CertificateChain ();
			CertificateChain.Add (certificate);
			Certificate = certificate;
			PrivateKey = key;
		}
Пример #7
0
		/// <summary>
		/// Initializes a new instance of the <see cref="MimeKit.Cryptography.CmsSigner"/> class.
		/// </summary>
		/// <remarks>
		/// <para>The initial value of the <see cref="DigestAlgorithm"/> will be set to
		/// <see cref="MimeKit.Cryptography.DigestAlgorithm.Sha1"/> and both the
		/// <see cref="SignedAttributes"/> and <see cref="UnsignedAttributes"/> properties
		/// will be initialized to empty tables.</para>
		/// </remarks>
		/// <param name="chain">The chain of certificates starting with the signer's certificate back to the root.</param>
		/// <param name="key">The signer's private key.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <para><paramref name="chain"/> is <c>null</c>.</para>
		/// <para>-or-</para>
		/// <para><paramref name="key"/> is <c>null</c>.</para>
		/// </exception>
		/// <exception cref="System.ArgumentException">
		/// <para><paramref name="chain"/> did not contain any certificates.</para>
		/// <para>-or-</para>
		/// <para>The certificate cannot be used for signing.</para>
		/// <para>-or-</para>
		/// <para><paramref name="key"/> is not a private key.</para>
		/// </exception>
		public CmsSigner (IEnumerable<X509CertificateEntry> chain, AsymmetricKeyParameter key) : this ()
		{
			if (chain == null)
				throw new ArgumentNullException ("chain");

			if (key == null)
				throw new ArgumentNullException ("key");

			CertificateChain = new X509CertificateChain ();
			foreach (var entry in chain) {
				CertificateChain.Add (entry.Certificate);
				if (Certificate == null)
					Certificate = entry.Certificate;
			}

			if (CertificateChain.Count == 0)
				throw new ArgumentException ("The certificate chain was empty.", "chain");

			CheckCertificateCanBeUsedForSigning (Certificate);

			if (!key.IsPrivate)
				throw new ArgumentException ("The key must be a private key.", "key");

			PrivateKey = key;
		}
Пример #8
0
		/// <summary>
		/// Initializes a new instance of the <see cref="MimeKit.Cryptography.CmsSigner"/> class.
		/// </summary>
		/// <remarks>
		/// <para>The initial value of the <see cref="DigestAlgorithm"/> will be set to
		/// <see cref="MimeKit.Cryptography.DigestAlgorithm.Sha1"/> and both the
		/// <see cref="SignedAttributes"/> and <see cref="UnsignedAttributes"/> properties
		/// will be initialized to empty tables.</para>
		/// </remarks>
		/// <param name="chain">The chain of certificates starting with the signer's certificate back to the root.</param>
		/// <param name="key">The signer's private key.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <para><paramref name="chain"/> is <c>null</c>.</para>
		/// <para>-or-</para>
		/// <para><paramref name="key"/> is <c>null</c>.</para>
		/// </exception>
		/// <exception cref="System.ArgumentException">
		/// <para><paramref name="chain"/> did not contain any certificates.</para>
		/// <para>-or-</para>
		/// <para>The certificate cannot be used for signing.</para>
		/// <para>-or-</para>
		/// <para><paramref name="key"/> is not a private key.</para>
		/// </exception>
		public CmsSigner (IEnumerable<X509CertificateEntry> chain, AsymmetricKeyParameter key) : this ()
		{
			if (chain == null)
				throw new ArgumentNullException ("chain");

			if (key == null)
				throw new ArgumentNullException ("key");

			CertificateChain = new X509CertificateChain ();
			foreach (var entry in chain) {
				CertificateChain.Add (entry.Certificate);
				if (Certificate == null)
					Certificate = entry.Certificate;
			}

			if (CertificateChain.Count == 0)
				throw new ArgumentException ("The certificate chain was empty.", "chain");

			var flags = Certificate.GetKeyUsageFlags ();
			if (flags != X509KeyUsageFlags.None && (flags & X509KeyUsageFlags.DigitalSignature) == 0)
				throw new ArgumentException ("The certificate cannot be used for signing.");

			if (!key.IsPrivate)
				throw new ArgumentException ("The key must be a private key.", "key");

			PrivateKey = key;
		}
Пример #9
0
		/// <summary>
		/// Initializes a new instance of the <see cref="MimeKit.Cryptography.CmsSigner"/> class.
		/// </summary>
		/// <remarks>
		/// <para>The initial value of the <see cref="MimeKit.Cryptography.DigestAlgorithm"/> will
		/// be set to <see cref="MimeKit.Cryptography.DigestAlgorithm.Sha1"/> and both the
		/// <see cref="SignedAttributes"/> and <see cref="UnsignedAttributes"/> properties will be
		/// initialized to empty tables.</para>
		/// </remarks>
		/// <param name="certificate">The signer's certificate.</param>
		/// <param name="key">The signer's private key.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <para><paramref name="certificate"/> is <c>null</c>.</para>
		/// <para>-or-</para>
		/// <para><paramref name="key"/> is <c>null</c>.</para>
		/// </exception>
		/// <exception cref="System.ArgumentException">
		/// <para><paramref name="certificate"/> cannot be used for signing.</para>
		/// <para>-or-</para>
		/// <para><paramref name="key"/> is not a private key.</para>
		/// </exception>
		public CmsSigner (X509Certificate certificate, AsymmetricKeyParameter key) : this ()
		{
			if (certificate == null)
				throw new ArgumentNullException ("certificate");

			var flags = certificate.GetKeyUsageFlags ();
			if (flags != X509KeyUsageFlags.None && (flags & X509KeyUsageFlags.DigitalSignature) == 0)
				throw new ArgumentException ("The certificate cannot be used for signing.", "certificate");

			if (key == null)
				throw new ArgumentNullException ("key");

			if (!key.IsPrivate)
				throw new ArgumentException ("The key must be a private key.", "key");

			CertificateChain = new X509CertificateChain ();
			CertificateChain.Add (certificate);
			Certificate = certificate;
			PrivateKey = key;
		}