public CmsRecipientCollection (SubjectIdentifierType recipientIdentifierType, X509Certificate2Collection certificates) : base () 
		{
			foreach (X509Certificate2 x509 in certificates) {
				CmsRecipient p7r = new CmsRecipient (recipientIdentifierType, x509);
				_list.Add (p7r);
			}
		}
        public CmsSigner(SubjectIdentifierType signerIdentifierType, X509Certificate2 certificate)
        {
            switch (signerIdentifierType)
            {
                case SubjectIdentifierType.Unknown:
                    this.SignerIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber;
                    this.IncludeOption = X509IncludeOption.ExcludeRoot;
                    break;

                case SubjectIdentifierType.IssuerAndSerialNumber:
                    this.SignerIdentifierType = signerIdentifierType;
                    this.IncludeOption = X509IncludeOption.ExcludeRoot;
                    break;

                case SubjectIdentifierType.SubjectKeyIdentifier:
                    this.SignerIdentifierType = signerIdentifierType;
                    this.IncludeOption = X509IncludeOption.ExcludeRoot;
                    break;

                case SubjectIdentifierType.NoSignature:
                    this.SignerIdentifierType = signerIdentifierType;
                    this.IncludeOption = X509IncludeOption.None;
                    break;

                default:
                    this.SignerIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber;
                    this.IncludeOption = X509IncludeOption.ExcludeRoot;
                    break;
            }
            this.Certificate = certificate;
            this.DigestAlgorithm = new Oid("1.3.14.3.2.26");
            this.m_signedAttributes = new CryptographicAttributeObjectCollection();
            this.m_unsignedAttributes = new CryptographicAttributeObjectCollection();
            this.m_certificates = new X509Certificate2Collection();
        }
Example #3
0
		public EnvelopedCms (SubjectIdentifierType recipientIdentifierType, ContentInfo contentInfo) 
			: this (contentInfo) 
		{
			_idType = recipientIdentifierType;
			if (_idType == SubjectIdentifierType.SubjectKeyIdentifier)
				_version = 2;
		}
Example #4
0
		// constructor

		public CmsRecipient (X509Certificate2 certificate)
		{
			if (certificate == null)
				throw new ArgumentNullException ("certificate");
			_recipient = SubjectIdentifierType.IssuerAndSerialNumber;
			_certificate = certificate;
		}
Example #5
0
		public CmsSigner (SubjectIdentifierType signerIdentifierType) : this ()
		{
			if (signerIdentifierType == SubjectIdentifierType.Unknown)
				_signer = SubjectIdentifierType.IssuerAndSerialNumber;
			else
				_signer = signerIdentifierType;
		}
        public CmsSigner (SubjectIdentifierType signerIdentifierType, X509Certificate2 certificate) {
            switch (signerIdentifierType) {
            case SubjectIdentifierType.Unknown:
                this.SignerIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber;
                this.IncludeOption = X509IncludeOption.ExcludeRoot;
                break;
            case SubjectIdentifierType.IssuerAndSerialNumber:
                this.SignerIdentifierType = signerIdentifierType;
                this.IncludeOption = X509IncludeOption.ExcludeRoot;
                break;
            case SubjectIdentifierType.SubjectKeyIdentifier:
                this.SignerIdentifierType = signerIdentifierType;
                this.IncludeOption = X509IncludeOption.ExcludeRoot;
                break;
            case SubjectIdentifierType.NoSignature:
                this.SignerIdentifierType = signerIdentifierType;
                this.IncludeOption        = X509IncludeOption.None;
                break;
            default:
                this.SignerIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber;
                this.IncludeOption = X509IncludeOption.ExcludeRoot;
                break;
            }
            this.Certificate = certificate;
            this.DigestAlgorithm = Oid.FromOidValue(CAPI.szOID_OIWSEC_sha1, OidGroup.HashAlgorithm);

            m_signedAttributes = new CryptographicAttributeObjectCollection();
            m_unsignedAttributes = new CryptographicAttributeObjectCollection();
            m_certificates = new X509Certificate2Collection();
        }
        private void Reset(SubjectIdentifierType recipientIdentifierType, X509Certificate2 certificate)
        {
            if (certificate == null)
            {
                throw new ArgumentNullException("certificate");
            }
            switch (recipientIdentifierType)
            {
                case SubjectIdentifierType.Unknown:
                    recipientIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber;
                    break;

                case SubjectIdentifierType.IssuerAndSerialNumber:
                    break;

                case SubjectIdentifierType.SubjectKeyIdentifier:
                    if (!PkcsUtils.CmsSupported())
                    {
                        throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Not_Supported"));
                    }
                    break;

                default:
                    throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Invalid_Subject_Identifier_Type"), recipientIdentifierType.ToString());
            }
            this.m_recipientIdentifierType = recipientIdentifierType;
            this.m_certificate = certificate;
        }
Example #8
0
 internal SubjectIdentifier(CAPI.CRYPTOAPI_BLOB issuer, CAPI.CRYPTOAPI_BLOB serialNumber)
 {
     bool flag = true;
     byte* numPtr = (byte*)(void*)serialNumber.pbData;
     for (uint index = 0U; index < serialNumber.cbData; ++index)
     {
         if ((int)*numPtr++ != 0)
         {
             flag = false;
             break;
         }
     }
     if (flag)
     {
         byte[] numArray = new byte[(IntPtr)issuer.cbData];
         Marshal.Copy(issuer.pbData, numArray, 0, numArray.Length);
         if (string.Compare("CN=Dummy Signer", new X500DistinguishedName(numArray).Name, StringComparison.OrdinalIgnoreCase) == 0)
         {
             this.Reset(SubjectIdentifierType.NoSignature, (object)null);
             return;
         }
     }
     if (flag)
     {
         this.m_type = SubjectIdentifierType.SubjectKeyIdentifier;
         this.m_value = (object)string.Empty;
         uint cbDecodedValue = 0U;
         SafeLocalAllocHandle decodedValue = SafeLocalAllocHandle.InvalidHandle;
         if (!CAPI.DecodeObject(new IntPtr(7L), issuer.pbData, issuer.cbData, out decodedValue, out cbDecodedValue))
             throw new CryptographicException(Marshal.GetLastWin32Error());
         using (decodedValue)
         {
             CAPI.CERT_NAME_INFO certNameInfo = (CAPI.CERT_NAME_INFO)Marshal.PtrToStructure(decodedValue.DangerousGetHandle(), typeof(CAPI.CERT_NAME_INFO));
             for (uint index1 = 0U; index1 < certNameInfo.cRDN; ++index1)
             {
                 CAPI.CERT_RDN certRdn = (CAPI.CERT_RDN)Marshal.PtrToStructure(new IntPtr((long)certNameInfo.rgRDN + (long)index1 * (long)Marshal.SizeOf(typeof(CAPI.CERT_RDN))), typeof(CAPI.CERT_RDN));
                 for (uint index2 = 0U; index2 < certRdn.cRDNAttr; ++index2)
                 {
                     CAPI.CERT_RDN_ATTR certRdnAttr = (CAPI.CERT_RDN_ATTR)Marshal.PtrToStructure(new IntPtr((long)certRdn.rgRDNAttr + (long)index2 * (long)Marshal.SizeOf(typeof(CAPI.CERT_RDN_ATTR))), typeof(CAPI.CERT_RDN_ATTR));
                     if (string.Compare("1.3.6.1.4.1.311.10.7.1", certRdnAttr.pszObjId, StringComparison.OrdinalIgnoreCase) == 0 && (int)certRdnAttr.dwValueType == 2)
                     {
                         byte[] numArray = new byte[(IntPtr)certRdnAttr.Value.cbData];
                         Marshal.Copy(certRdnAttr.Value.pbData, numArray, 0, numArray.Length);
                         this.Reset(SubjectIdentifierType.SubjectKeyIdentifier, (object)X509Utils.EncodeHexString(numArray));
                         return;
                     }
                 }
             }
         }
         throw new CryptographicException(-2146889715);
     }
     else
     {
         CAPI.CERT_ISSUER_SERIAL_NUMBER pIssuerAndSerial;
         pIssuerAndSerial.Issuer = issuer;
         pIssuerAndSerial.SerialNumber = serialNumber;
         this.Reset(SubjectIdentifierType.IssuerAndSerialNumber, (object)PkcsUtils.DecodeIssuerSerial(pIssuerAndSerial));
     }
 }
 public CmsRecipientCollection(SubjectIdentifierType recipientIdentifierType, X509Certificate2Collection certificates)
 {
     this.m_recipients = new ArrayList(certificates.Count);
     for (int i = 0; i < certificates.Count; i++)
     {
         this.m_recipients.Add(new CmsRecipient(recipientIdentifierType, certificates[i]));
     }
 }
Example #10
0
		public CmsRecipientCollection (SubjectIdentifierType recipientIdentifierType, X509Certificate2Collection certificates)
		{
			// no null check, MS throws a NullReferenceException here
			foreach (X509Certificate2 x509 in certificates) {
				CmsRecipient p7r = new CmsRecipient (recipientIdentifierType, x509);
				_list.Add (p7r);
			}
		}
Example #11
0
		// constructors

		public CmsSigner () 
		{
			_signer = SubjectIdentifierType.IssuerAndSerialNumber;
			_digest = new Oid ("1.3.14.3.2.26");
			_options = X509IncludeOption.ExcludeRoot;
			_signed = new CryptographicAttributeObjectCollection ();
			_unsigned = new CryptographicAttributeObjectCollection ();
			_coll = new X509Certificate2Collection ();
		}
Example #12
0
		// only accessible from SignedPkcs7.SignerInfos
		internal SignerInfo (string hashName, X509Certificate2 certificate, SubjectIdentifierType type, object o, int version)
		{
			_digest = new Oid (CryptoConfig.MapNameToOID (hashName));
			_certificate = certificate;
			_counter = new SignerInfoCollection ();
			_signed = new CryptographicAttributeObjectCollection ();
			_unsigned = new CryptographicAttributeObjectCollection ();
			_signer = new SubjectIdentifier (type, o);
			_version = version;
		}
Example #13
0
		public CmsRecipient (SubjectIdentifierType recipientIdentifierType, X509Certificate2 certificate)
		{
			if (certificate == null)
				throw new ArgumentNullException ("certificate");

			if (recipientIdentifierType == SubjectIdentifierType.Unknown)
				_recipient = SubjectIdentifierType.IssuerAndSerialNumber;
			else
				_recipient = recipientIdentifierType;
			_certificate = certificate;
		}
Example #14
0
        public CmsRecipientCollection(SubjectIdentifierType recipientIdentifierType, X509Certificate2Collection certificates)
        {
            if (certificates == null)
                throw new NullReferenceException(); //Desktop compat: this is the wrong exception to throw but it is the compatible one. 

            _recipients = new List<CmsRecipient>(certificates.Count);
            for (int index = 0; index < certificates.Count; index++)
            {
                _recipients.Add(new CmsRecipient(recipientIdentifierType, certificates[index]));
            }
        }
Example #15
0
		/// <summary>
		/// Initializes a new instance of the <see cref="MimeKit.Cryptography.CmsRecipient"/> class.
		/// </summary>
		/// <remarks>
		/// The initial value of the <see cref="EncryptionAlgorithms"/> property will be set to
		/// the Triple-DES encryption algorithm, which should be safe to assume for all modern
		/// S/MIME v3.x client implementations.
		/// </remarks>
		/// <param name="certificate">The recipient's certificate.</param>
		/// <param name="recipientIdentifierType">The recipient identifier type.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <paramref name="certificate"/> is <c>null</c>.
		/// </exception>
		public CmsRecipient (X509Certificate certificate, SubjectIdentifierType recipientIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber)
		{
			if (certificate == null)
				throw new ArgumentNullException (nameof (certificate));

			if (recipientIdentifierType == SubjectIdentifierType.IssuerAndSerialNumber)
				RecipientIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber;
			else
				RecipientIdentifierType = SubjectIdentifierType.SubjectKeyIdentifier;

			EncryptionAlgorithms = new EncryptionAlgorithm[] { EncryptionAlgorithm.TripleDes };
			Certificate = certificate;
		}
Example #16
0
 public EnvelopedCms(SubjectIdentifierType recipientIdentifierType, ContentInfo contentInfo, AlgorithmIdentifier encryptionAlgorithm)
 {
     if (contentInfo == null)
         throw new ArgumentNullException("contentInfo");
     if (contentInfo.Content == null)
         throw new ArgumentNullException("contentInfo.Content");
     if (encryptionAlgorithm == null)
         throw new ArgumentNullException("encryptionAlgorithm");
     this.m_safeCryptMsgHandle = SafeCryptMsgHandle.InvalidHandle;
     this.m_version = recipientIdentifierType == SubjectIdentifierType.SubjectKeyIdentifier ? 2 : 0;
     this.m_recipientIdentifierType = recipientIdentifierType;
     this.m_contentInfo = contentInfo;
     this.m_encryptionAlgorithm = encryptionAlgorithm;
     this.m_encryptionAlgorithm.Parameters = new byte[0];
     this.m_certificates = new X509Certificate2Collection();
     this.m_unprotectedAttributes = new CryptographicAttributeObjectCollection();
 }
Example #17
0
        public SignedCms (SubjectIdentifierType signerIdentifierType, ContentInfo contentInfo, bool detached) {
            if (contentInfo == null)
                throw new ArgumentNullException("contentInfo");

            if (contentInfo.Content == null)
                throw new ArgumentNullException("contentInfo.Content");

            // Reset all states.
            if (signerIdentifierType != SubjectIdentifierType.SubjectKeyIdentifier && 
                signerIdentifierType != SubjectIdentifierType.IssuerAndSerialNumber &&
                signerIdentifierType != SubjectIdentifierType.NoSignature) {
                signerIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber;
            }

            m_safeCryptMsgHandle = SafeCryptMsgHandle.InvalidHandle;
            m_signerIdentifierType =  signerIdentifierType;
            m_version = 0;
            m_contentInfo = contentInfo;
            m_detached = detached;
        }
 public SignedCms(SubjectIdentifierType signerIdentifierType, System.Security.Cryptography.Pkcs.ContentInfo contentInfo, bool detached)
 {
     if (contentInfo == null)
     {
         throw new ArgumentNullException("contentInfo");
     }
     if (contentInfo.Content == null)
     {
         throw new ArgumentNullException("contentInfo.Content");
     }
     if (((signerIdentifierType != SubjectIdentifierType.SubjectKeyIdentifier) && (signerIdentifierType != SubjectIdentifierType.IssuerAndSerialNumber)) && (signerIdentifierType != SubjectIdentifierType.NoSignature))
     {
         signerIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber;
     }
     this.m_safeCryptMsgHandle = System.Security.Cryptography.SafeCryptMsgHandle.InvalidHandle;
     this.m_signerIdentifierType = signerIdentifierType;
     this.m_version = 0;
     this.m_contentInfo = contentInfo;
     this.m_detached = detached;
 }
Example #19
0
        public CmsRecipient(SubjectIdentifierType recipientIdentifierType, X509Certificate2 certificate)
        {
            if (certificate == null)
                throw new ArgumentNullException(nameof(certificate));

            switch (recipientIdentifierType)
            {
                case SubjectIdentifierType.Unknown:
                    recipientIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber;
                    break;
                case SubjectIdentifierType.IssuerAndSerialNumber:
                    break;
                case SubjectIdentifierType.SubjectKeyIdentifier:
                    break;
                default:
                    throw new CryptographicException(SR.Format(SR.Cryptography_Cms_Invalid_Subject_Identifier_Type, recipientIdentifierType));
            }

            RecipientIdentifierType = recipientIdentifierType;
            Certificate = certificate;
        }
Example #20
0
        public SignedCms(SubjectIdentifierType signerIdentifierType, ContentInfo contentInfo, bool detached)
        {
            if (contentInfo == null)
            {
                throw new ArgumentNullException(nameof(contentInfo));
            }
            if (contentInfo.Content == null)
            {
                throw new ArgumentNullException("contentInfo.Content");
            }

            // signerIdentifierType is ignored.
            // In .NET Framework it is used for the signer type of a prompt-for-certificate signer.
            // In .NET Core we don't support prompting.
            //
            // .NET Framework turned any unknown value into IssuerAndSerialNumber, so no exceptions
            // are required, either.

            ContentInfo = contentInfo;
            Detached    = detached;
            Version     = 0;
        }
Example #21
0
        private static void CustomBuild_CertMatch(
            CertLoader loader,
            DateTimeOffset referenceTime,
            SigningCertificateOption v1Option,
            SigningCertificateOption v2Option,
            HashAlgorithmName v2AlgorithmName    = default,
            X509IncludeOption includeOption      = default,
            SubjectIdentifierType identifierType = SubjectIdentifierType.IssuerAndSerialNumber)
        {
            byte[] tokenBytes = BuildCustomToken(
                loader,
                referenceTime,
                v1Option,
                v2Option,
                v2AlgorithmName,
                includeOption,
                identifierType);

            Rfc3161TimestampToken token;

            Assert.True(Rfc3161TimestampToken.TryDecode(tokenBytes, out token, out int bytesRead));

            Assert.Equal(tokenBytes.Length, bytesRead);
            Assert.NotNull(token);

            Assert.Equal(referenceTime, token.TokenInfo.Timestamp);

            using (X509Certificate2 cert = Certificates.ValidLookingTsaCert.GetCertificate())
            {
                Assert.True(
                    token.VerifySignatureForHash(
                        token.TokenInfo.GetMessageHash().Span,
                        token.TokenInfo.HashAlgorithmId,
                        out X509Certificate2 signer,
                        new X509Certificate2Collection(cert)));

                Assert.Equal(cert, signer);
            }
        }
Example #22
0
        internal SubjectIdentifier(SubjectIdentifierType type, object value)
        {
            Debug.Assert(value != null);
#if DEBUG
            switch (type)
            {
            case SubjectIdentifierType.IssuerAndSerialNumber:
                Debug.Assert(value is X509IssuerSerial);
                break;

            case SubjectIdentifierType.SubjectKeyIdentifier:
                Debug.Assert(value is string);
                break;

            default:
                Debug.Fail($"Illegal type passed to SubjectIdentifier: {type}");
                break;
            }
#endif //DEBUG
            Type  = type;
            Value = value;
        }
Example #23
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MimeKit.Cryptography.CmsRecipient"/> class.
        /// </summary>
        /// <remarks>
        /// <para>Creates a new <see cref="CmsRecipient"/>, loading the certificate from the specified stream.</para>
        /// <para>The initial value of the <see cref="EncryptionAlgorithms"/> property will be set to
        /// the Triple-DES encryption algorithm, which should be safe to assume for all modern
        /// S/MIME v3.x client implementations.</para>
        /// </remarks>
        /// <param name="stream">The stream containing the recipient's certificate.</param>
        /// <param name="recipientIdentifierType">The recipient identifier type.</param>
        /// <exception cref="System.ArgumentNullException">
        /// <paramref name="stream"/> is <c>null</c>.
        /// </exception>
        /// <exception cref="System.IO.IOException">
        /// An I/O error occurred.
        /// </exception>
        public CmsRecipient(Stream stream, SubjectIdentifierType recipientIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            if (recipientIdentifierType == SubjectIdentifierType.IssuerAndSerialNumber)
            {
                RecipientIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber;
            }
            else
            {
                RecipientIdentifierType = SubjectIdentifierType.SubjectKeyIdentifier;
            }

            var parser = new X509CertificateParser();

            EncryptionAlgorithms    = new EncryptionAlgorithm[] { EncryptionAlgorithm.TripleDes };
            RecipientIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber;
            Certificate             = parser.ReadCertificate(stream);
        }
Example #24
0
        internal SubjectIdentifier(SubjectIdentifierType type, object value)
        {
            Debug.Assert(value != null);
#if DEBUG
            switch (type)
            {
                case SubjectIdentifierType.IssuerAndSerialNumber:
                    Debug.Assert(value is X509IssuerSerial);
                    break;

                case SubjectIdentifierType.SubjectKeyIdentifier:
                    Debug.Assert(value is string);
                    break;

                default:
                    Debug.Fail($"Illegal type passed to SubjectIdentifier: {type}");
                    break;
            }
#endif //DEBUG
            Type = type;
            Value = value;
        }
        public static SubjectIdentifierOrKey ToSubjectIdentifierOrKey(this CERT_ID certId)
        {
            //
            // SubjectIdentifierOrKey is just a SubjectIdentifier with an (irrelevant here) "key" option thumbtacked onto it so
            // the easiest way is to subcontract the job to SubjectIdentifier.
            //
            SubjectIdentifier     subjectIdentifier     = certId.ToSubjectIdentifier();
            SubjectIdentifierType subjectIdentifierType = subjectIdentifier.Type;

            switch (subjectIdentifierType)
            {
            case SubjectIdentifierType.IssuerAndSerialNumber:
                return(new SubjectIdentifierOrKey(SubjectIdentifierOrKeyType.IssuerAndSerialNumber, subjectIdentifier.Value !));

            case SubjectIdentifierType.SubjectKeyIdentifier:
                return(new SubjectIdentifierOrKey(SubjectIdentifierOrKeyType.SubjectKeyIdentifier, subjectIdentifier.Value !));

            default:
                Debug.Fail("Only the framework can construct SubjectIdentifier's so if we got a bad value here, that's our fault.");
                throw new CryptographicException(SR.Format(SR.Cryptography_Cms_Invalid_Subject_Identifier_Type, subjectIdentifierType));
            }
        }
Example #26
0
        internal void Reset(SubjectIdentifierType type, object value)
        {
            switch (type)
            {
            case SubjectIdentifierType.Unknown:
            case SubjectIdentifierType.NoSignature:
                this.m_type  = type;
                this.m_value = value;
                break;

            case SubjectIdentifierType.IssuerAndSerialNumber:
                if (value.GetType() != typeof(X509IssuerSerial))
                {
                    throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Invalid_Subject_Identifier_Type_Value_Mismatch"), value.GetType().ToString());
                }
                else
                {
                    goto case 0;
                }

            case SubjectIdentifierType.SubjectKeyIdentifier:
                if (!PkcsUtils.CmsSupported())
                {
                    throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Not_Supported"));
                }
                if (value.GetType() != typeof(string))
                {
                    throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Invalid_Subject_Identifier_Type_Value_Mismatch"), value.GetType().ToString());
                }
                else
                {
                    goto case 0;
                }

            default:
                throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Invalid_Subject_Identifier_Type"), ((object)type).ToString());
            }
        }
Example #27
0
        public CmsSigner(SubjectIdentifierType signerIdentifierType, X509Certificate2 certificate)
        {
            switch (signerIdentifierType)
            {
            case SubjectIdentifierType.Unknown:
                this.SignerIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber;
                this.IncludeOption        = X509IncludeOption.ExcludeRoot;
                break;

            case SubjectIdentifierType.IssuerAndSerialNumber:
                this.SignerIdentifierType = signerIdentifierType;
                this.IncludeOption        = X509IncludeOption.ExcludeRoot;
                break;

            case SubjectIdentifierType.SubjectKeyIdentifier:
                this.SignerIdentifierType = signerIdentifierType;
                this.IncludeOption        = X509IncludeOption.ExcludeRoot;
                break;

            case SubjectIdentifierType.NoSignature:
                this.SignerIdentifierType = signerIdentifierType;
                this.IncludeOption        = X509IncludeOption.None;
                break;

            default:
                this.SignerIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber;
                this.IncludeOption        = X509IncludeOption.ExcludeRoot;
                break;
            }
            this.Certificate = certificate;
            string oidValue = LocalAppContextSwitches.CmsUseInsecureHashAlgorithms ? CAPI.szOID_OIWSEC_sha1 : Sha256Oid;

            this.DigestAlgorithm = Oid.FromOidValue(oidValue, OidGroup.HashAlgorithm);

            m_signedAttributes   = new CryptographicAttributeObjectCollection();
            m_unsignedAttributes = new CryptographicAttributeObjectCollection();
            m_certificates       = new X509Certificate2Collection();
        }
Example #28
0
        /// <summary>
        /// Note: Due to its use of X509Certificate2Collection.Find(), this returns a cloned certificate. So the caller should dispose it.
        /// </summary>
        public static X509Certificate2 TryFindMatchingCertificate(this X509Certificate2Collection certs, SubjectIdentifier recipientIdentifier)
        {
            SubjectIdentifierType recipientIdentifierType = recipientIdentifier.Type;

            switch (recipientIdentifierType)
            {
            case SubjectIdentifierType.IssuerAndSerialNumber:
            {
                X509IssuerSerial issuerSerial = (X509IssuerSerial)(recipientIdentifier.Value);

                using (ClonedCertificates matches1 = certs.FindCertificates(X509FindType.FindBySerialNumber, issuerSerial.SerialNumber))
                {
                    using (ClonedCertificates matches2 = matches1.FindCertificates(X509FindType.FindByIssuerDistinguishedName, issuerSerial.IssuerName))
                    {
                        // Desktop compat: We do not complain about multiple matches. Just take the first one and ignore the rest.
                        return(matches2.Any ? matches2.ClaimResult() : null);
                    }
                }
            }

            case SubjectIdentifierType.SubjectKeyIdentifier:
            {
                string ski = (string)(recipientIdentifier.Value);
                using (ClonedCertificates matches = certs.FindCertificates(X509FindType.FindBySubjectKeyIdentifier, ski))
                {
                    // Desktop compat: We do not complain about multiple matches. Just take the first one and ignore the rest.
                    return(matches.Any ? matches.ClaimResult() : null);
                }
            }

            default:
                // RecipientInfo's can only be created by this package so if this an invalid type, it's the package's fault.
                Debug.Fail($"Invalid recipientIdentifier type: {recipientIdentifierType}");
                throw new CryptographicException();
            }
        }
Example #29
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MimeKit.Cryptography.CmsRecipient"/> class.
        /// </summary>
        /// <remarks>
        /// <para>Creates a new <see cref="CmsRecipient"/>, loading the certificate from the specified file.</para>
        /// <para>The initial value of the <see cref="EncryptionAlgorithms"/> property will be set to
        /// the Triple-DES encryption algorithm, which should be safe to assume for all modern
        /// S/MIME v3.x client implementations.</para>
        /// </remarks>
        /// <param name="fileName">The file containing the recipient's certificate.</param>
        /// <param name="recipientIdentifierType">The recipient identifier type.</param>
        /// <exception cref="System.ArgumentNullException">
        /// <paramref name="fileName"/> is <c>null</c>.
        /// </exception>
        /// <exception cref="System.ArgumentException">
        /// <paramref name="fileName"/> is a zero-length string, contains only white space, or
        /// contains one or more invalid characters as defined by
        /// <see cref="System.IO.Path.InvalidPathChars"/>.
        /// </exception>
        /// <exception cref="System.IO.DirectoryNotFoundException">
        /// <paramref name="fileName"/> is an invalid file path.
        /// </exception>
        /// <exception cref="System.IO.FileNotFoundException">
        /// The specified file path could not be found.
        /// </exception>
        /// <exception cref="System.UnauthorizedAccessException">
        /// The user does not have access to read the specified file.
        /// </exception>
        /// <exception cref="System.IO.IOException">
        /// An I/O error occurred.
        /// </exception>
        public CmsRecipient(string fileName, SubjectIdentifierType recipientIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber)
        {
            if (fileName == null)
            {
                throw new ArgumentNullException(nameof(fileName));
            }

            var parser = new X509CertificateParser();

            if (recipientIdentifierType == SubjectIdentifierType.IssuerAndSerialNumber)
            {
                RecipientIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber;
            }
            else
            {
                RecipientIdentifierType = SubjectIdentifierType.SubjectKeyIdentifier;
            }

            EncryptionAlgorithms    = new EncryptionAlgorithm[] { EncryptionAlgorithm.TripleDes };
            RecipientIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber;

            using (var stream = File.OpenRead(fileName))
                Certificate = parser.ReadCertificate(stream);
        }
        private static KeyTransRecipientInfo EncodeKeyTransl(SubjectIdentifierType type = SubjectIdentifierType.IssuerAndSerialNumber)
        {
            ContentInfo  contentInfo = new ContentInfo(new byte[] { 1, 2, 3 });
            EnvelopedCms ecms        = new EnvelopedCms(contentInfo);

            using (X509Certificate2 cert = Certificates.RSAKeyTransfer1.GetCertificate())
            {
                CmsRecipient cmsRecipient = new CmsRecipient(type, cert);
                ecms.Encrypt(cmsRecipient);
            }
            byte[] encodedMessage = ecms.Encode();

            EnvelopedCms ecms2 = new EnvelopedCms();

            ecms2.Decode(encodedMessage);

            RecipientInfoCollection recipients = ecms2.RecipientInfos;

            Assert.Equal(1, recipients.Count);
            RecipientInfo recipientInfo = recipients[0];

            Assert.IsType <KeyTransRecipientInfo>(recipientInfo);
            return((KeyTransRecipientInfo)recipientInfo);
        }
Example #31
0
        private static void CheckSignedEncrypted(byte[] docBytes, SubjectIdentifierType expectedType)
        {
            SignedCms signedCms = new SignedCms();
            signedCms.Decode(docBytes);

            Assert.Equal(Oids.Pkcs7Enveloped, signedCms.ContentInfo.ContentType.Value);

            SignerInfoCollection signers = signedCms.SignerInfos;
            Assert.Equal(1, signers.Count);
            Assert.Equal(expectedType, signers[0].SignerIdentifier.Type);

            // Assert.NotThrows
            signedCms.CheckSignature(true);

            EnvelopedCms envelopedCms = new EnvelopedCms();
            envelopedCms.Decode(signedCms.ContentInfo.Content);

            using (X509Certificate2 cert = Certificates.RSAKeyTransferCapi1.TryGetCertificateWithPrivateKey())
            {
                envelopedCms.Decrypt(new X509Certificate2Collection(cert));
            }

            Assert.Equal("42", envelopedCms.ContentInfo.Content.ByteArrayToHex());
        }
Example #32
0
        public void Decode(byte[] encodedMessage)
        {
            PKCS7.ContentInfo ci = new PKCS7.ContentInfo(encodedMessage);
            if (ci.ContentType != PKCS7.Oid.signedData)
            {
                throw new Exception("");
            }

            PKCS7.SignedData      sd   = new PKCS7.SignedData(ci.Content);
            SubjectIdentifierType type = SubjectIdentifierType.Unknown;
            object o = null;

            X509Certificate2 x509 = null;

            if (sd.SignerInfo.Certificate != null)
            {
                x509 = new X509Certificate2(sd.SignerInfo.Certificate.RawData);
            }
            else if ((sd.SignerInfo.IssuerName != null) && (sd.SignerInfo.SerialNumber != null))
            {
                byte[] serial = sd.SignerInfo.SerialNumber;
                Array.Reverse(serial);                  // ???
                type = SubjectIdentifierType.IssuerAndSerialNumber;
                X509IssuerSerial xis = new X509IssuerSerial();
                xis.IssuerName   = sd.SignerInfo.IssuerName;
                xis.SerialNumber = ToString(serial, true);
                o = xis;
                // TODO: move to a FindCertificate (issuer, serial, collection)
                foreach (Mono.Security.X509.X509Certificate x in sd.Certificates)
                {
                    if (x.IssuerName == sd.SignerInfo.IssuerName)
                    {
                        if (ToString(x.SerialNumber, true) == xis.SerialNumber)
                        {
                            x509 = new X509Certificate2(x.RawData);
                            break;
                        }
                    }
                }
            }
            else if (sd.SignerInfo.SubjectKeyIdentifier != null)
            {
                string ski = ToString(sd.SignerInfo.SubjectKeyIdentifier, false);
                type = SubjectIdentifierType.SubjectKeyIdentifier;
                o    = (object)ski;
                // TODO: move to a FindCertificate (ski, collection)
                foreach (Mono.Security.X509.X509Certificate x in sd.Certificates)
                {
                    if (ToString(GetKeyIdentifier(x), false) == ski)
                    {
                        x509 = new X509Certificate2(x.RawData);
                        break;
                    }
                }
            }

            SignerInfo si = new SignerInfo(sd.SignerInfo.HashName, x509, type, o, sd.SignerInfo.Version);

            // si.AuthenticatedAttributes
            // si.UnauthenticatedAttributes
            _info.Add(si);

            ASN1 content = sd.ContentInfo.Content;
            Oid  oid     = new Oid(sd.ContentInfo.ContentType);

            if (!_detached || _content == null)
            {
                if (content[0] == null)
                {
                    throw new ArgumentException("ContentInfo has no content. Detached signature ?");
                }

                _content = new ContentInfo(oid, content[0].Value);
            }

            foreach (Mono.Security.X509.X509Certificate x in sd.Certificates)
            {
                _certs.Add(new X509Certificate2(x.RawData));
            }

            _version = sd.Version;
        }
        private static void CustomBuild_CertMismatch(
            CertLoader loader,
            DateTimeOffset referenceTime,
            SigningCertificateOption v1Option,
            SigningCertificateOption v2Option,
            HashAlgorithmName v2AlgorithmName    = default,
            X509IncludeOption includeOption      = default,
            SubjectIdentifierType identifierType = SubjectIdentifierType.IssuerAndSerialNumber)
        {
            byte[] tokenBytes = BuildCustomToken(
                loader,
                referenceTime,
                v1Option,
                v2Option,
                v2AlgorithmName,
                includeOption,
                identifierType);

            Rfc3161TimestampToken token;

            bool willParse = includeOption == X509IncludeOption.None;

            if (willParse && identifierType == SubjectIdentifierType.IssuerAndSerialNumber)
            {
                // Because IASN matches against the ESSCertId(V2) directly it will reject the token.

                switch (v1Option)
                {
                case SigningCertificateOption.ValidHashWithInvalidName:
                case SigningCertificateOption.ValidHashWithInvalidSerial:
                case SigningCertificateOption.InvalidHashWithInvalidName:
                case SigningCertificateOption.InvalidHashWithInvalidSerial:
                    willParse = false;
                    break;
                }

                switch (v2Option)
                {
                case SigningCertificateOption.ValidHashWithInvalidName:
                case SigningCertificateOption.ValidHashWithInvalidSerial:
                case SigningCertificateOption.InvalidHashWithInvalidName:
                case SigningCertificateOption.InvalidHashWithInvalidSerial:
                    willParse = false;
                    break;
                }
            }

            if (willParse)
            {
                Assert.True(Rfc3161TimestampToken.TryDecode(tokenBytes, out token, out int bytesRead));
                Assert.NotNull(token);
                Assert.Equal(tokenBytes.Length, bytesRead);

                using (X509Certificate2 cert = loader.GetCertificate())
                {
                    Assert.False(
                        token.VerifySignatureForHash(
                            token.TokenInfo.GetMessageHash().Span,
                            token.TokenInfo.HashAlgorithmId,
                            out X509Certificate2 signer,
                            new X509Certificate2Collection(cert)));

                    Assert.Null(signer);
                }
            }
            else
            {
                Assert.False(Rfc3161TimestampToken.TryDecode(tokenBytes, out token, out int bytesRead));

                Assert.Null(token);
                Assert.Equal(0, bytesRead);
            }
        }
 public CmsSigner (SubjectIdentifierType signerIdentifierType) : this (signerIdentifierType, null) {}
Example #35
0
        //
        // Internal methods.
        //

        internal void Reset (SubjectIdentifierType type, Object value) {
            switch (type) {
            case SubjectIdentifierType.NoSignature:
            case SubjectIdentifierType.Unknown:
                break;
            case SubjectIdentifierType.IssuerAndSerialNumber:
                if (value.GetType() != typeof(X509IssuerSerial)) {
                    throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Invalid_Subject_Identifier_Type_Value_Mismatch"), value.GetType().ToString());
                }
                break;
            case SubjectIdentifierType.SubjectKeyIdentifier:
                if (!PkcsUtils.CmsSupported()) {
                    throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Not_Supported"));
                }
                if (value.GetType() != typeof(string)) {
                    throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Invalid_Subject_Identifier_Type_Value_Mismatch"), value.GetType().ToString());
                }
                break;
            default:
                throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Invalid_Subject_Identifier_Type"), type.ToString());
            }

            m_type = type;
            m_value = value;
        }
Example #36
0
        public static void AddFirstSigner_ECDSA(SubjectIdentifierType identifierType, bool detached, string digestOid)
        {
            ContentInfo contentInfo = new ContentInfo(new byte[] { 9, 8, 7, 6, 5 });
            SignedCms   cms         = new SignedCms(contentInfo, detached);

            using (X509Certificate2 signerCert = Certificates.ECDsaP256Win.TryGetCertificateWithPrivateKey())
            {
                CmsSigner signer = new CmsSigner(identifierType, signerCert);
                signer.IncludeOption   = X509IncludeOption.EndCertOnly;
                signer.DigestAlgorithm = new Oid(digestOid, digestOid);
                cms.ComputeSignature(signer);
            }

            Assert.Single(cms.SignerInfos);
            Assert.Single(cms.Certificates);

            int expectedVersion = identifierType == SubjectIdentifierType.SubjectKeyIdentifier ? 3 : 1;

            Assert.Equal(expectedVersion, cms.Version);

            SignerInfo firstSigner = cms.SignerInfos[0];

            Assert.Equal(identifierType, firstSigner.SignerIdentifier.Type);
            Assert.NotNull(firstSigner.Certificate);
            Assert.NotSame(cms.Certificates[0], firstSigner.Certificate);
            Assert.Equal(cms.Certificates[0], firstSigner.Certificate);

#if netcoreapp
            byte[] signature = firstSigner.GetSignature();
            Assert.NotEmpty(signature);
            // ECDSA PKIX signature format is a DER SEQUENCE.
            Assert.Equal(0x30, signature[0]);

            // ECDSA Oids are all under 1.2.840.10045.4.
            Assert.StartsWith("1.2.840.10045.4.", firstSigner.SignatureAlgorithm.Value);
#endif

            cms.CheckSignature(true);
            byte[] encoded = cms.Encode();

            cms = new SignedCms();
            cms.Decode(encoded);

            Assert.Single(cms.SignerInfos);
            Assert.Single(cms.Certificates);
            Assert.Equal(expectedVersion, cms.Version);
            Assert.Equal(identifierType, cms.SignerInfos[0].SignerIdentifier.Type);
            Assert.Equal(firstSigner.Certificate, cms.SignerInfos[0].Certificate);

#if netcoreapp
            byte[] sig2 = cms.SignerInfos[0].GetSignature();
            Assert.Equal(signature, sig2);
#endif

            if (detached)
            {
                Assert.Throws <CryptographicException>(() => cms.CheckSignature(true));
                cms = new SignedCms(contentInfo, detached);
                cms.Decode(encoded);
            }

            cms.CheckSignature(true);
        }
Example #37
0
 public SignedCms(SubjectIdentifierType signerIdentifierType, ContentInfo content, bool detached)
     : this(content, detached)
 {
     _type = signerIdentifierType;
 }
Example #38
0
		/// <summary>
		/// Initializes a new instance of the <see cref="MimeKit.Cryptography.CmsRecipient"/> class.
		/// </summary>
		/// <remarks>
		/// <para>Creates a new <see cref="CmsRecipient"/>, loading the certificate from the specified file.</para>
		/// <para>The initial value of the <see cref="EncryptionAlgorithms"/> property will be set to
		/// the Triple-DES encryption algorithm, which should be safe to assume for all modern
		/// S/MIME v3.x client implementations.</para>
		/// </remarks>
		/// <param name="fileName">The file containing the recipient's certificate.</param>
		/// <param name="recipientIdentifierType">The recipient identifier type.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <paramref name="fileName"/> is <c>null</c>.
		/// </exception>
		/// <exception cref="System.ArgumentException">
		/// <paramref name="fileName"/> is a zero-length string, contains only white space, or
		/// contains one or more invalid characters as defined by
		/// <see cref="System.IO.Path.InvalidPathChars"/>.
		/// </exception>
		/// <exception cref="System.IO.DirectoryNotFoundException">
		/// <paramref name="fileName"/> is an invalid file path.
		/// </exception>
		/// <exception cref="System.IO.FileNotFoundException">
		/// The specified file path could not be found.
		/// </exception>
		/// <exception cref="System.UnauthorizedAccessException">
		/// The user does not have access to read the specified file.
		/// </exception>
		/// <exception cref="System.IO.IOException">
		/// An I/O error occurred.
		/// </exception>
		public CmsRecipient (string fileName, SubjectIdentifierType recipientIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber)
		{
			if (fileName == null)
				throw new ArgumentNullException (nameof (fileName));

			var parser = new X509CertificateParser ();

			if (recipientIdentifierType == SubjectIdentifierType.IssuerAndSerialNumber)
				RecipientIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber;
			else
				RecipientIdentifierType = SubjectIdentifierType.SubjectKeyIdentifier;

			EncryptionAlgorithms = new EncryptionAlgorithm[] { EncryptionAlgorithm.TripleDes };
			RecipientIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber;

			using (var stream = File.OpenRead (fileName))
				Certificate = parser.ReadCertificate (stream);
		}
Example #39
0
		public CmsSigner (SubjectIdentifierType signerIdentifierType, X509Certificate2 certificate) 
			: this (signerIdentifierType)
		{
			_certificate = certificate;
		}
Example #40
0
 public SignedCms(SubjectIdentifierType signerIdentifierType, ContentInfo contentInfo)
     : this(signerIdentifierType, contentInfo, false)
 {
 }
        private static KeyTransRecipientInfo FixedValueKeyTrans1(SubjectIdentifierType type = SubjectIdentifierType.IssuerAndSerialNumber)
        {
            byte[] encodedMessage;
            switch (type)
            {
                case SubjectIdentifierType.IssuerAndSerialNumber:
                    encodedMessage = s_KeyTransEncodedMessage;
                    break;

                case SubjectIdentifierType.SubjectKeyIdentifier:
                    encodedMessage = s_KeyTransEncodedMessage_Ski;
                    break;

                default:
                    throw new Exception("Bad SubjectIdentifierType.");
            }

            EnvelopedCms ecms = new EnvelopedCms();
            ecms.Decode(encodedMessage);

            RecipientInfoCollection recipients = ecms.RecipientInfos;
            Assert.Equal(1, recipients.Count);
            RecipientInfo recipientInfo = recipients[0];
            Assert.True(recipientInfo is KeyTransRecipientInfo);
            return (KeyTransRecipientInfo)recipientInfo;
        }
        private static KeyTransRecipientInfo EncodeKeyTransl(SubjectIdentifierType type = SubjectIdentifierType.IssuerAndSerialNumber)
        {
            ContentInfo contentInfo = new ContentInfo(new byte[] { 1, 2, 3 });
            EnvelopedCms ecms = new EnvelopedCms(contentInfo);
            using (X509Certificate2 cert = Certificates.RSAKeyTransfer1.GetCertificate())
            {
                CmsRecipient cmsRecipient = new CmsRecipient(type, cert);
                ecms.Encrypt(cmsRecipient);
            }
            byte[] encodedMessage = ecms.Encode();

            EnvelopedCms ecms2 = new EnvelopedCms();
            ecms2.Decode(encodedMessage);

            RecipientInfoCollection recipients = ecms2.RecipientInfos;
            Assert.Equal(1, recipients.Count);
            RecipientInfo recipientInfo = recipients[0];
            Assert.True(recipientInfo is KeyTransRecipientInfo);
            return (KeyTransRecipientInfo)recipientInfo;
        }
Example #43
0
 public SignedCms(SubjectIdentifierType signerIdentifierType) : this()
 {
     _type = signerIdentifierType;
 }
Example #44
0
 public CmsSigner(SubjectIdentifierType signerIdentifierType, X509Certificate2 certificate) : this(signerIdentifierType, certificate, null)
 {
 }
Example #45
0
 public SignedCms(SubjectIdentifierType signerIdentifierType, ContentInfo content)
     : this(content, false)
 {
     _type = signerIdentifierType;
 }
Example #46
0
        /// <summary>
        /// Initialize a new instance of the <see cref="CmsSigner"/> class.
        /// </summary>
        /// <remarks>
        /// <para>The initial value of the <see cref="DigestAlgorithm"/> will be set to
        /// <see cref="DigestAlgorithm.Sha256"/> 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>
        /// <param name="signerIdentifierType">The scheme used for identifying the signer certificate.</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, SubjectIdentifierType signerIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber) : 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));
            }

            if (signerIdentifierType != SubjectIdentifierType.SubjectKeyIdentifier)
            {
                SignerIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber;
            }
            else
            {
                SignerIdentifierType = SubjectIdentifierType.SubjectKeyIdentifier;
            }

            Certificate = CertificateChain[0];
            PrivateKey  = key;
        }
Example #47
0
        public static void AddFirstSigner_DSA(SubjectIdentifierType identifierType, bool detached)
        {
            ContentInfo contentInfo = new ContentInfo(new byte[] { 9, 8, 7, 6, 5 });
            SignedCms   cms         = new SignedCms(contentInfo, detached);

            using (X509Certificate2 signerCert = Certificates.Dsa1024.TryGetCertificateWithPrivateKey())
            {
                CmsSigner signer = new CmsSigner(identifierType, signerCert);
                signer.IncludeOption = X509IncludeOption.EndCertOnly;
                // Best compatibility for DSA is SHA-1 (FIPS 186-2)
                signer.DigestAlgorithm = new Oid(Oids.Sha1, Oids.Sha1);
                cms.ComputeSignature(signer);
            }

            Assert.Single(cms.SignerInfos);
            Assert.Single(cms.Certificates);

            int expectedVersion = identifierType == SubjectIdentifierType.SubjectKeyIdentifier ? 3 : 1;

            Assert.Equal(expectedVersion, cms.Version);

            SignerInfo firstSigner = cms.SignerInfos[0];

            Assert.Equal(identifierType, firstSigner.SignerIdentifier.Type);
            Assert.NotNull(firstSigner.Certificate);
            Assert.NotSame(cms.Certificates[0], firstSigner.Certificate);
            Assert.Equal(cms.Certificates[0], firstSigner.Certificate);

#if netcoreapp
            byte[] signature = firstSigner.GetSignature();
            Assert.NotEmpty(signature);
            // DSA PKIX signature format is a DER SEQUENCE.
            Assert.Equal(0x30, signature[0]);
#endif

            cms.CheckSignature(true);
            byte[] encoded = cms.Encode();

            cms = new SignedCms();
            cms.Decode(encoded);

            Assert.Single(cms.SignerInfos);
            Assert.Single(cms.Certificates);
            Assert.Equal(expectedVersion, cms.Version);
            Assert.Equal(identifierType, cms.SignerInfos[0].SignerIdentifier.Type);
            Assert.Equal(firstSigner.Certificate, cms.SignerInfos[0].Certificate);

#if netcoreapp
            byte[] sig2 = cms.SignerInfos[0].GetSignature();
            Assert.Equal(signature, sig2);
#endif

            if (detached)
            {
                Assert.Throws <CryptographicException>(() => cms.CheckSignature(true));
                cms = new SignedCms(contentInfo, detached);
                cms.Decode(encoded);
            }

            cms.CheckSignature(true);
        }
Example #48
0
        internal unsafe SubjectIdentifier (CAPI.CRYPTOAPI_BLOB issuer, CAPI.CRYPTOAPI_BLOB serialNumber) {
            // If serial number is 0, then it is the special SKI encoding or NoSignature
            bool isSKIorHashOnly = true;
            byte * pb = (byte *) serialNumber.pbData;
            for (uint i = 0; i < serialNumber.cbData; i++) {
                if (*pb++ != (byte) 0) {
                    isSKIorHashOnly = false;
                    break;
                }
            }

            if (isSKIorHashOnly) {
                byte[] issuerBytes = new byte[issuer.cbData];
                Marshal.Copy(issuer.pbData, issuerBytes, 0, issuerBytes.Length);
                X500DistinguishedName dummyName = new X500DistinguishedName(issuerBytes);
                if (String.Compare(CAPI.DummySignerCommonName, dummyName.Name, StringComparison.OrdinalIgnoreCase) == 0) {
                    Reset(SubjectIdentifierType.NoSignature, null);
                    return;
                }
            }

            if (isSKIorHashOnly) {
                // Decode disguised SKI in issuer field (See WinCrypt.h for more info).  Note that some certificates may contain
                // an all-zero serial number but not be encoded with an szOID_KEYID_RDN.  In order to allow use of signatures created
                // using these certificates, we will first try to find the szOID_KEYID_RDN, but if it does not exist, fall back to just
                // decoding the incoming issuer and serial number.
                m_type = SubjectIdentifierType.SubjectKeyIdentifier;
                m_value = String.Empty;

                uint cbCertNameInfo = 0;
                SafeLocalAllocHandle pbCertNameInfo = SafeLocalAllocHandle.InvalidHandle;

                if (CAPI.DecodeObject(new IntPtr(CAPI.X509_NAME),
                                      issuer.pbData,
                                      issuer.cbData,
                                      out pbCertNameInfo,
                                      out cbCertNameInfo)) {
                    using (pbCertNameInfo) {
                        checked {
                            CAPI.CERT_NAME_INFO certNameInfo = (CAPI.CERT_NAME_INFO) Marshal.PtrToStructure(pbCertNameInfo.DangerousGetHandle(), typeof(CAPI.CERT_NAME_INFO));
                            for (uint i = 0; i < certNameInfo.cRDN; i++) {
                                CAPI.CERT_RDN certRdn = (CAPI.CERT_RDN) Marshal.PtrToStructure(new IntPtr((long) certNameInfo.rgRDN + (long) (i * Marshal.SizeOf(typeof(CAPI.CERT_RDN)))), typeof(CAPI.CERT_RDN));

                                for (uint j = 0; j < certRdn.cRDNAttr; j++)
                                {
                                    CAPI.CERT_RDN_ATTR certRdnAttr = (CAPI.CERT_RDN_ATTR)Marshal.PtrToStructure(new IntPtr((long)certRdn.rgRDNAttr + (long)(j * Marshal.SizeOf(typeof(CAPI.CERT_RDN_ATTR)))), typeof(CAPI.CERT_RDN_ATTR));

                                    if (String.Compare(CAPI.szOID_KEYID_RDN, certRdnAttr.pszObjId, StringComparison.OrdinalIgnoreCase) == 0)
                                    {
                                        if (certRdnAttr.dwValueType == CAPI.CERT_RDN_OCTET_STRING)
                                        {
                                            byte[] ski = new byte[certRdnAttr.Value.cbData];
                                            Marshal.Copy(certRdnAttr.Value.pbData, ski, 0, ski.Length);
                                            Reset(SubjectIdentifierType.SubjectKeyIdentifier, X509Utils.EncodeHexString(ski));
                                            return;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            CAPI.CERT_ISSUER_SERIAL_NUMBER IssuerAndSerial;
            IssuerAndSerial.Issuer = issuer;
            IssuerAndSerial.SerialNumber = serialNumber;
            X509IssuerSerial issuerSerial = PkcsUtils.DecodeIssuerSerial(IssuerAndSerial);
            Reset(SubjectIdentifierType.IssuerAndSerialNumber, issuerSerial);
        }
Example #49
0
        public static void EnsureDataIsolation_NewDocument(bool detached)
        {
            byte[]      contentBytes = { 9, 8, 7, 6, 5 };
            ContentInfo contentInfo  = new ContentInfo(contentBytes);
            SignedCms   cms          = new SignedCms(contentInfo, detached);

            SubjectIdentifierType firstType  = SubjectIdentifierType.IssuerAndSerialNumber;
            SubjectIdentifierType secondType = SubjectIdentifierType.SubjectKeyIdentifier;

            using (X509Certificate2 signerCert = Certificates.RSA2048SignatureOnly.TryGetCertificateWithPrivateKey())
            {
                CmsSigner signer = new CmsSigner(firstType, signerCert);
                signer.SignedAttributes.Add(new Pkcs9SigningTime());
                cms.ComputeSignature(signer);
            }

            // CheckSignature doesn't read the public mutable data
            contentInfo.Content[0]       ^= 0xFF;
            contentInfo.ContentType.Value = Oids.Pkcs7Hashed;
            cms.CheckSignature(true);

            using (X509Certificate2 signerCert = Certificates.RSA2048SignatureOnly.TryGetCertificateWithPrivateKey())
            {
                CmsSigner signer = new CmsSigner(secondType, signerCert);
                signer.SignedAttributes.Add(new Pkcs9SigningTime());

                // A second ComputeSignature uses the content value from the first one.
                cms.ComputeSignature(signer);
            }

            // They should have the same content digests.
            AsnEncodedData firstDigest = cms.SignerInfos[0].SignedAttributes
                                         .OfType <CryptographicAttributeObject>().First(cao => cao.Oid.Value == Oids.MessageDigest).Values[0];

            AsnEncodedData secondDigest = cms.SignerInfos[1].SignedAttributes
                                          .OfType <CryptographicAttributeObject>().First(cao => cao.Oid.Value == Oids.MessageDigest).Values[0];

            Assert.Equal(firstDigest.RawData.ByteArrayToHex(), secondDigest.RawData.ByteArrayToHex());

            byte[] encoded = cms.Encode();

            if (detached)
            {
                cms.Decode(encoded);

                // Because Decode leaves ContentInfo alone, and Decode resets the
                // "known" content, this will fail due to the tampered content.
                Assert.Throws <CryptographicException>(() => cms.CheckSignature(true));

                // So put it back.
                cms.ContentInfo.Content[0] ^= 0xFF;
            }

            cms.Decode(encoded);

            if (detached)
            {
                // And break it again.
                cms.ContentInfo.Content[0] ^= 0xFF;
            }

            // Destroy the content that just got decoded.
            encoded.AsSpan().Fill(0x55);
            cms.CheckSignature(true);
        }
Example #50
0
 internal SubjectIdentifier(SubjectIdentifierType type, object value)
 {
     _type  = type;
     _value = value;
 }
Example #51
0
 internal SubjectIdentifier (SubjectIdentifierType type, Object value) {
     Reset(type, value);
 }
        private static byte[] BuildCustomToken(
            CertLoader cert,
            DateTimeOffset timestamp,
            SigningCertificateOption v1Option,
            SigningCertificateOption v2Option,
            HashAlgorithmName v2DigestAlg        = default,
            X509IncludeOption includeOption      = X509IncludeOption.ExcludeRoot,
            SubjectIdentifierType identifierType = SubjectIdentifierType.IssuerAndSerialNumber)
        {
            long accuracyMicroSeconds = (long)(TimeSpan.FromMinutes(1).TotalMilliseconds * 1000);

            byte[] serialNumber = BitConverter.GetBytes(DateTimeOffset.UtcNow.Ticks);
            Array.Reverse(serialNumber);

            Rfc3161TimestampTokenInfo info = new Rfc3161TimestampTokenInfo(
                new Oid("0.0", "0.0"),
                new Oid(Oids.Sha384),
                new byte[384 / 8],
                serialNumber,
                timestamp,
                accuracyMicroSeconds,
                isOrdering: true);

            ContentInfo contentInfo = new ContentInfo(new Oid(Oids.TstInfo, Oids.TstInfo), info.Encode());
            SignedCms   cms         = new SignedCms(contentInfo);

            using (X509Certificate2 tsaCert = cert.TryGetCertificateWithPrivateKey())
            {
                CmsSigner signer = new CmsSigner(identifierType, tsaCert)
                {
                    IncludeOption = includeOption
                };

                if (v1Option != SigningCertificateOption.Omit)
                {
                    ExpandOption(v1Option, out bool validHash, out bool skipIssuerSerial, out bool validName, out bool validSerial);

                    // simple SigningCertificate
                    byte[] signingCertificateV1Bytes =
                        "301A3018301604140000000000000000000000000000000000000000".HexToByteArray();

                    if (validHash)
                    {
                        byte[] hash = SHA1.HashData(tsaCert.RawData);

                        Buffer.BlockCopy(
                            hash,
                            0,
                            signingCertificateV1Bytes,
                            signingCertificateV1Bytes.Length - hash.Length,
                            hash.Length);
                    }

                    if (!skipIssuerSerial)
                    {
                        byte[] footer = BuildIssuerAndSerialNumber(tsaCert, validName, validSerial);

                        signingCertificateV1Bytes[1] += (byte)footer.Length;
                        signingCertificateV1Bytes[3] += (byte)footer.Length;
                        signingCertificateV1Bytes[5] += (byte)footer.Length;

                        Assert.InRange(signingCertificateV1Bytes[1], 0, 127);

                        signingCertificateV1Bytes = signingCertificateV1Bytes.Concat(footer).ToArray();
                    }

                    signer.SignedAttributes.Add(
                        new AsnEncodedData("1.2.840.113549.1.9.16.2.12", signingCertificateV1Bytes));
                }

                if (v2Option != SigningCertificateOption.Omit)
                {
                    byte[] attrBytes;
                    byte[] algBytes = Array.Empty <byte>();
                    byte[] hashBytes;
                    byte[] issuerNameBytes = Array.Empty <byte>();

                    if (v2DigestAlg != default)
                    {
                        switch (v2DigestAlg.Name)
                        {
                        case "MD5":
                            algBytes = "300C06082A864886F70D02050500".HexToByteArray();
                            break;

                        case "SHA1":
                            algBytes = "300906052B0E03021A0500".HexToByteArray();
                            break;

                        case "SHA256":
                            // Invalid under DER, because it's the default.
                            algBytes = "300D06096086480165030402010500".HexToByteArray();
                            break;

                        case "SHA384":
                            algBytes = "300D06096086480165030402020500".HexToByteArray();
                            break;

                        case "SHA512":
                            algBytes = "300D06096086480165030402030500".HexToByteArray();
                            break;

                        default:
                            throw new NotSupportedException(v2DigestAlg.Name);
                        }
                    }
                    else
                    {
                        v2DigestAlg = HashAlgorithmName.SHA256;
                    }

                    hashBytes = tsaCert.GetCertHash(v2DigestAlg);

                    ExpandOption(v2Option, out bool validHash, out bool skipIssuerSerial, out bool validName, out bool validSerial);

                    if (!validHash)
                    {
                        hashBytes[0] ^= 0xFF;
                    }

                    if (!skipIssuerSerial)
                    {
                        issuerNameBytes = BuildIssuerAndSerialNumber(tsaCert, validName, validSerial);
                    }

                    // hashBytes hasn't been wrapped in an OCTET STRING yet, so add 2 more.
                    int payloadSize = algBytes.Length + hashBytes.Length + issuerNameBytes.Length + 2;
                    Assert.InRange(payloadSize, 0, 123);

                    attrBytes = new byte[payloadSize + 6];

                    int index = 0;

                    // SEQUENCE (SigningCertificateV2)
                    attrBytes[index++] = 0x30;
                    attrBytes[index++] = (byte)(payloadSize + 4);

                    // SEQUENCE OF => certs
                    attrBytes[index++] = 0x30;
                    attrBytes[index++] = (byte)(payloadSize + 2);

                    // SEQUENCE (ESSCertIdV2)
                    attrBytes[index++] = 0x30;
                    attrBytes[index++] = (byte)payloadSize;

                    Buffer.BlockCopy(algBytes, 0, attrBytes, index, algBytes.Length);
                    index += algBytes.Length;

                    // OCTET STRING (Hash)
                    attrBytes[index++] = 0x04;
                    attrBytes[index++] = (byte)hashBytes.Length;
                    Buffer.BlockCopy(hashBytes, 0, attrBytes, index, hashBytes.Length);
                    index += hashBytes.Length;

                    Buffer.BlockCopy(issuerNameBytes, 0, attrBytes, index, issuerNameBytes.Length);

                    signer.SignedAttributes.Add(
                        new AsnEncodedData("1.2.840.113549.1.9.16.2.47", attrBytes));
                }

                cms.ComputeSignature(signer);
            }

            return(cms.Encode());
        }
        internal unsafe SubjectIdentifier(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB issuer, System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB serialNumber)
        {
            System.Security.Cryptography.CAPI.CERT_ISSUER_SERIAL_NUMBER cert_issuer_serial_number;
            bool  flag   = true;
            byte *pbData = (byte *)serialNumber.pbData;

            for (uint i = 0; i < serialNumber.cbData; i++)
            {
                pbData++;
                if (pbData[0] != 0)
                {
                    flag = false;
                    break;
                }
            }
            if (flag)
            {
                byte[] destination = new byte[issuer.cbData];
                Marshal.Copy(issuer.pbData, destination, 0, destination.Length);
                X500DistinguishedName name = new X500DistinguishedName(destination);
                if (string.Compare("CN=Dummy Signer", name.Name, StringComparison.OrdinalIgnoreCase) == 0)
                {
                    this.Reset(SubjectIdentifierType.NoSignature, null);
                    return;
                }
            }
            if (flag)
            {
                this.m_type  = SubjectIdentifierType.SubjectKeyIdentifier;
                this.m_value = string.Empty;
                uint cbDecodedValue = 0;
                System.Security.Cryptography.SafeLocalAllocHandle invalidHandle = System.Security.Cryptography.SafeLocalAllocHandle.InvalidHandle;
                if (!System.Security.Cryptography.CAPI.DecodeObject(new IntPtr(7L), issuer.pbData, issuer.cbData, out invalidHandle, out cbDecodedValue))
                {
                    throw new CryptographicException(Marshal.GetLastWin32Error());
                }
                using (invalidHandle)
                {
                    System.Security.Cryptography.CAPI.CERT_NAME_INFO cert_name_info = (System.Security.Cryptography.CAPI.CERT_NAME_INFO)Marshal.PtrToStructure(invalidHandle.DangerousGetHandle(), typeof(System.Security.Cryptography.CAPI.CERT_NAME_INFO));
                    for (uint j = 0; j < cert_name_info.cRDN; j++)
                    {
                        System.Security.Cryptography.CAPI.CERT_RDN cert_rdn = (System.Security.Cryptography.CAPI.CERT_RDN)Marshal.PtrToStructure(new IntPtr(((long)cert_name_info.rgRDN) + (j * Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CERT_RDN)))), typeof(System.Security.Cryptography.CAPI.CERT_RDN));
                        for (uint k = 0; k < cert_rdn.cRDNAttr; k++)
                        {
                            System.Security.Cryptography.CAPI.CERT_RDN_ATTR cert_rdn_attr = (System.Security.Cryptography.CAPI.CERT_RDN_ATTR)Marshal.PtrToStructure(new IntPtr(((long)cert_rdn.rgRDNAttr) + (k * Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CERT_RDN_ATTR)))), typeof(System.Security.Cryptography.CAPI.CERT_RDN_ATTR));
                            if ((string.Compare("1.3.6.1.4.1.311.10.7.1", cert_rdn_attr.pszObjId, StringComparison.OrdinalIgnoreCase) == 0) && (cert_rdn_attr.dwValueType == 2))
                            {
                                byte[] buffer2 = new byte[cert_rdn_attr.Value.cbData];
                                Marshal.Copy(cert_rdn_attr.Value.pbData, buffer2, 0, buffer2.Length);
                                this.Reset(SubjectIdentifierType.SubjectKeyIdentifier, System.Security.Cryptography.X509Certificates.X509Utils.EncodeHexString(buffer2));
                                return;
                            }
                        }
                    }
                }
                throw new CryptographicException(-2146889715);
            }
            cert_issuer_serial_number.Issuer       = issuer;
            cert_issuer_serial_number.SerialNumber = serialNumber;
            X509IssuerSerial serial = PkcsUtils.DecodeIssuerSerial(cert_issuer_serial_number);

            this.Reset(SubjectIdentifierType.IssuerAndSerialNumber, serial);
        }
 public CmsRecipientCollection(SubjectIdentifierType recipientIdentifierType, System.Security.Cryptography.X509Certificates.X509Certificate2Collection certificates)
 {
 }
Example #55
0
 public CmsSigner(SubjectIdentifierType signerIdentifierType)
     : this(signerIdentifierType, null)
 {
 }
Example #56
0
        internal unsafe SubjectIdentifier(CAPI.CRYPTOAPI_BLOB issuer, CAPI.CRYPTOAPI_BLOB serialNumber)
        {
            // If serial number is 0, then it is the special SKI encoding or NoSignature
            bool  isSKIorHashOnly = true;
            byte *pb = (byte *)serialNumber.pbData;

            for (uint i = 0; i < serialNumber.cbData; i++)
            {
                if (*pb++ != (byte)0)
                {
                    isSKIorHashOnly = false;
                    break;
                }
            }

            if (isSKIorHashOnly)
            {
                byte[] issuerBytes = new byte[issuer.cbData];
                Marshal.Copy(issuer.pbData, issuerBytes, 0, issuerBytes.Length);
                X500DistinguishedName dummyName = new X500DistinguishedName(issuerBytes);
                if (String.Compare(CAPI.DummySignerCommonName, dummyName.Name, StringComparison.OrdinalIgnoreCase) == 0)
                {
                    Reset(SubjectIdentifierType.NoSignature, null);
                    return;
                }
            }

            if (isSKIorHashOnly)
            {
                // Decode disguised SKI in issuer field (See WinCrypt.h for more info).  Note that some certificates may contain
                // an all-zero serial number but not be encoded with an szOID_KEYID_RDN.  In order to allow use of signatures created
                // using these certificates, we will first try to find the szOID_KEYID_RDN, but if it does not exist, fall back to just
                // decoding the incoming issuer and serial number.
                m_type  = SubjectIdentifierType.SubjectKeyIdentifier;
                m_value = String.Empty;

                uint cbCertNameInfo = 0;
                SafeLocalAllocHandle pbCertNameInfo = SafeLocalAllocHandle.InvalidHandle;

                if (CAPI.DecodeObject(new IntPtr(CAPI.X509_NAME),
                                      issuer.pbData,
                                      issuer.cbData,
                                      out pbCertNameInfo,
                                      out cbCertNameInfo))
                {
                    using (pbCertNameInfo) {
                        checked {
                            CAPI.CERT_NAME_INFO certNameInfo = (CAPI.CERT_NAME_INFO)Marshal.PtrToStructure(pbCertNameInfo.DangerousGetHandle(), typeof(CAPI.CERT_NAME_INFO));
                            for (uint i = 0; i < certNameInfo.cRDN; i++)
                            {
                                CAPI.CERT_RDN certRdn = (CAPI.CERT_RDN)Marshal.PtrToStructure(new IntPtr((long)certNameInfo.rgRDN + (long)(i * Marshal.SizeOf(typeof(CAPI.CERT_RDN)))), typeof(CAPI.CERT_RDN));

                                for (uint j = 0; j < certRdn.cRDNAttr; j++)
                                {
                                    CAPI.CERT_RDN_ATTR certRdnAttr = (CAPI.CERT_RDN_ATTR)Marshal.PtrToStructure(new IntPtr((long)certRdn.rgRDNAttr + (long)(j * Marshal.SizeOf(typeof(CAPI.CERT_RDN_ATTR)))), typeof(CAPI.CERT_RDN_ATTR));

                                    if (String.Compare(CAPI.szOID_KEYID_RDN, certRdnAttr.pszObjId, StringComparison.OrdinalIgnoreCase) == 0)
                                    {
                                        if (certRdnAttr.dwValueType == CAPI.CERT_RDN_OCTET_STRING)
                                        {
                                            byte[] ski = new byte[certRdnAttr.Value.cbData];
                                            Marshal.Copy(certRdnAttr.Value.pbData, ski, 0, ski.Length);
                                            Reset(SubjectIdentifierType.SubjectKeyIdentifier, X509Utils.EncodeHexString(ski));
                                            return;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            CAPI.CERT_ISSUER_SERIAL_NUMBER IssuerAndSerial;
            IssuerAndSerial.Issuer       = issuer;
            IssuerAndSerial.SerialNumber = serialNumber;
            X509IssuerSerial issuerSerial = PkcsUtils.DecodeIssuerSerial(IssuerAndSerial);

            Reset(SubjectIdentifierType.IssuerAndSerialNumber, issuerSerial);
        }
Example #57
0
        private void TestSimpleDecrypt_RoundTrip(CertLoader certLoader, ContentInfo contentInfo, string algorithmOidValue, SubjectIdentifierType type, ContentInfo expectedContentInfo = null)
        {
            // Deep-copy the contentInfo since the real ContentInfo doesn't do this. This defends against a bad implementation changing
            // our "expectedContentInfo" to match what it produces.
            expectedContentInfo = expectedContentInfo ?? new ContentInfo(new Oid(contentInfo.ContentType), (byte[])(contentInfo.Content.Clone()));

            string certSubjectName;

            byte[] encodedMessage;
            byte[] originalCopy = (byte[])(contentInfo.Content.Clone());
            using (X509Certificate2 certificate = certLoader.GetCertificate())
            {
                certSubjectName = certificate.Subject;
                AlgorithmIdentifier alg          = new AlgorithmIdentifier(new Oid(algorithmOidValue));
                EnvelopedCms        ecms         = new EnvelopedCms(contentInfo, alg);
                CmsRecipient        cmsRecipient = new CmsRecipient(type, certificate);
                ecms.Encrypt(cmsRecipient);
                Assert.Equal(originalCopy.ByteArrayToHex(), ecms.ContentInfo.Content.ByteArrayToHex());
                encodedMessage = ecms.Encode();
            }

            // We don't pass "certificate" down because it's expected that the certificate used for encrypting doesn't have a private key (part of the purpose of this test is
            // to ensure that you don't need the recipient's private key to encrypt.) The decrypt phase will have to locate the matching cert with the private key.
            VerifySimpleDecrypt(encodedMessage, certLoader, expectedContentInfo);
        }
Example #58
0
		/// <summary>
		/// Initializes a new instance of the <see cref="MimeKit.Cryptography.CmsRecipient"/> class.
		/// </summary>
		/// <remarks>
		/// <para>Creates a new <see cref="CmsRecipient"/>, loading the certificate from the specified stream.</para>
		/// <para>The initial value of the <see cref="EncryptionAlgorithms"/> property will be set to
		/// the Triple-DES encryption algorithm, which should be safe to assume for all modern
		/// S/MIME v3.x client implementations.</para>
		/// </remarks>
		/// <param name="stream">The stream containing the recipient's certificate.</param>
		/// <param name="recipientIdentifierType">The recipient identifier type.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <paramref name="stream"/> is <c>null</c>.
		/// </exception>
		/// <exception cref="System.IO.IOException">
		/// An I/O error occurred.
		/// </exception>
		public CmsRecipient (Stream stream, SubjectIdentifierType recipientIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber)
		{
			if (stream == null)
				throw new ArgumentNullException (nameof (stream));

			if (recipientIdentifierType == SubjectIdentifierType.IssuerAndSerialNumber)
				RecipientIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber;
			else
				RecipientIdentifierType = SubjectIdentifierType.SubjectKeyIdentifier;

			var parser = new X509CertificateParser ();

			EncryptionAlgorithms = new EncryptionAlgorithm[] { EncryptionAlgorithm.TripleDes };
			RecipientIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber;
			Certificate = parser.ReadCertificate (stream);
		}
Example #59
0
        public static void AddCounterSigner_ECDSA(SubjectIdentifierType identifierType, string digestOid)
        {
            SignedCms cms = new SignedCms();

            cms.Decode(SignedDocuments.RsaPkcs1OneSignerIssuerAndSerialNumber);
            Assert.Single(cms.Certificates);

            SignerInfo firstSigner = cms.SignerInfos[0];

            Assert.Empty(firstSigner.CounterSignerInfos);
            Assert.Empty(firstSigner.UnsignedAttributes);

            using (X509Certificate2 signerCert = Certificates.ECDsaP256Win.TryGetCertificateWithPrivateKey())
            {
                CmsSigner signer = new CmsSigner(identifierType, signerCert);
                signer.IncludeOption   = X509IncludeOption.EndCertOnly;
                signer.DigestAlgorithm = new Oid(digestOid, digestOid);
                firstSigner.ComputeCounterSignature(signer);
            }

            Assert.Empty(firstSigner.CounterSignerInfos);
            Assert.Empty(firstSigner.UnsignedAttributes);

            SignerInfo firstSigner2 = cms.SignerInfos[0];

            Assert.Single(firstSigner2.CounterSignerInfos);
            Assert.Single(firstSigner2.UnsignedAttributes);

            Assert.Single(cms.SignerInfos);
            Assert.Equal(2, cms.Certificates.Count);

            SignerInfo counterSigner = firstSigner2.CounterSignerInfos[0];

            int expectedVersion = identifierType == SubjectIdentifierType.IssuerAndSerialNumber ? 1 : 3;

            Assert.Equal(expectedVersion, counterSigner.Version);

            // On NetFx there will be two attributes, because Windows emits the
            // content-type attribute even for counter-signers.
            int expectedCount = 1;

#if netfx
            expectedCount = 2;
#endif
            Assert.Equal(expectedCount, counterSigner.SignedAttributes.Count);
            Assert.Equal(Oids.MessageDigest, counterSigner.SignedAttributes[expectedCount - 1].Oid.Value);

            Assert.NotEqual(firstSigner2.Certificate, counterSigner.Certificate);
            Assert.Equal(2, cms.Certificates.Count);

#if netcoreapp
            byte[] signature = counterSigner.GetSignature();
            Assert.NotEmpty(signature);
            // DSA PKIX signature format is a DER SEQUENCE.
            Assert.Equal(0x30, signature[0]);

            // ECDSA Oids are all under 1.2.840.10045.4.
            Assert.StartsWith("1.2.840.10045.4.", counterSigner.SignatureAlgorithm.Value);
#endif

            cms.CheckSignature(true);
            byte[] encoded = cms.Encode();
            cms.Decode(encoded);
            cms.CheckSignature(true);
        }
 internal SubjectIdentifier(SubjectIdentifierType type, object value)
 {
     this.Reset(type, value);
 }