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."); }
/// <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)))); } }
/// <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; }
/// <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; }
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)); }
/// <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; }
/// <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; }
/// <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; }
/// <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; }