GetDigestInstance() private méthode

private GetDigestInstance ( string algorithm ) : IDigest
algorithm string
Résultat IDigest
Exemple #1
0
 public CmsSignedDataParser(CmsTypedStream signedContent, Stream sigData)
     : base(sigData)
 {
     //IL_0130: Expected O, but got Unknown
     try
     {
         _signedContent = signedContent;
         _signedData    = SignedDataParser.GetInstance(contentInfo.GetContent(16));
         _digests       = Platform.CreateHashtable();
         _digestOids    = new HashSet();
         Asn1SetParser    digestAlgorithms = _signedData.GetDigestAlgorithms();
         IAsn1Convertible asn1Convertible;
         while ((asn1Convertible = digestAlgorithms.ReadObject()) != null)
         {
             AlgorithmIdentifier instance = AlgorithmIdentifier.GetInstance(asn1Convertible.ToAsn1Object());
             try
             {
                 string id            = instance.Algorithm.Id;
                 string digestAlgName = Helper.GetDigestAlgName(id);
                 if (!_digests.Contains((object)digestAlgName))
                 {
                     _digests.set_Item((object)digestAlgName, (object)Helper.GetDigestInstance(digestAlgName));
                     _digestOids.Add(id);
                 }
             }
             catch (SecurityUtilityException)
             {
             }
         }
         ContentInfoParser     encapContentInfo      = _signedData.GetEncapContentInfo();
         Asn1OctetStringParser asn1OctetStringParser = (Asn1OctetStringParser)encapContentInfo.GetContent(4);
         if (asn1OctetStringParser != null)
         {
             CmsTypedStream cmsTypedStream = new CmsTypedStream(encapContentInfo.ContentType.Id, asn1OctetStringParser.GetOctetStream());
             if (_signedContent == null)
             {
                 _signedContent = cmsTypedStream;
             }
             else
             {
                 cmsTypedStream.Drain();
             }
         }
         _signedContentType = ((_signedContent == null) ? encapContentInfo.ContentType : new DerObjectIdentifier(_signedContent.ContentType));
     }
     catch (IOException val)
     {
         IOException val2 = val;
         throw new CmsException("io exception: " + ((global::System.Exception)(object) val2).get_Message(), (global::System.Exception)(object) val2);
     }
 }
        private void ConfigureDigest(string digestOid)
        {
            //IL_0035: Unknown result type (might be due to invalid IL or missing references)
            RegisterDigestOid(digestOid);
            string  digestAlgName = Helper.GetDigestAlgName(digestOid);
            IDigest digest        = (IDigest)_messageDigests.get_Item((object)digestAlgName);

            if (digest == null)
            {
                if (_messageDigestsLocked)
                {
                    throw new InvalidOperationException("Cannot configure new digests after the data stream is opened");
                }
                digest = Helper.GetDigestInstance(digestAlgName);
                _messageDigests.set_Item((object)digestAlgName, (object)digest);
            }
        }
Exemple #3
0
        /**
         * base constructor
         *
         * @param signedContent the content that was signed.
         * @param sigData the signature object.
         */
        public CmsSignedDataParser(
            CmsTypedStream signedContent,
            Stream sigData)
            : base(sigData)
        {
            try
            {
                this._signedContent = signedContent;
                this._signedData    = SignedDataParser.GetInstance(this.contentInfo.GetContent(Asn1Tags.Sequence));
                this._digests       = Platform.CreateHashtable();
                this._digestOids    = new HashSet();

                Asn1SetParser    digAlgs = _signedData.GetDigestAlgorithms();
                IAsn1Convertible o;

                while ((o = digAlgs.ReadObject()) != null)
                {
                    AlgorithmIdentifier id = AlgorithmIdentifier.GetInstance(o.ToAsn1Object());

                    try
                    {
                        string digestOid  = id.ObjectID.Id;
                        string digestName = Helper.GetDigestAlgName(digestOid);

                        if (!this._digests.Contains(digestName))
                        {
                            this._digests[digestName] = Helper.GetDigestInstance(digestName);
                            this._digestOids.Add(digestOid);
                        }
                    }
                    catch (SecurityUtilityException)
                    {
                        // TODO Should do something other than ignore it
                    }
                }

                //
                // If the message is simply a certificate chain message GetContent() may return null.
                //
                ContentInfoParser     cont = _signedData.GetEncapContentInfo();
                Asn1OctetStringParser octs = (Asn1OctetStringParser)
                                             cont.GetContent(Asn1Tags.OctetString);

                if (octs != null)
                {
                    CmsTypedStream ctStr = new CmsTypedStream(
                        cont.ContentType.Id, octs.GetOctetStream());

                    if (_signedContent == null)
                    {
                        this._signedContent = ctStr;
                    }
                    else
                    {
                        //
                        // content passed in, need to read past empty encapsulated content info object if present
                        //
                        ctStr.Drain();
                    }
                }

                _signedContentType = _signedContent == null
                                        ?       cont.ContentType
                                        :       new DerObjectIdentifier(_signedContent.ContentType);
            }
            catch (IOException e)
            {
                throw new CmsException("io exception: " + e.Message, e);
            }

            if (_digests.Count < 1)
            {
                throw new CmsException("no digests could be created for message.");
            }
        }
Exemple #4
0
        private bool DoVerify(
            AsymmetricKeyParameter key)
        {
            string  digestName = Helper.GetDigestAlgName(this.DigestAlgOid);
            IDigest digest     = Helper.GetDigestInstance(digestName);

            DerObjectIdentifier sigAlgOid = this.encryptionAlgorithm.ObjectID;
            Asn1Encodable       sigParams = this.encryptionAlgorithm.Parameters;
            ISigner             sig;

            if (sigAlgOid.Equals(Asn1.Pkcs.PkcsObjectIdentifiers.IdRsassaPss))
            {
                // RFC 4056 2.2
                // When the id-RSASSA-PSS algorithm identifier is used for a signature,
                // the AlgorithmIdentifier parameters field MUST contain RSASSA-PSS-params.
                if (sigParams == null)
                {
                    throw new CmsException("RSASSA-PSS signature must specify algorithm parameters");
                }

                try
                {
                    // TODO Provide abstract configuration mechanism
                    // (via alternate SignerUtilities.GetSigner method taking ASN.1 params)

                    Asn1.Pkcs.RsassaPssParameters pss = Asn1.Pkcs.RsassaPssParameters.GetInstance(
                        sigParams.ToAsn1Object());

                    if (!pss.HashAlgorithm.ObjectID.Equals(this.digestAlgorithm.ObjectID))
                    {
                        throw new CmsException("RSASSA-PSS signature parameters specified incorrect hash algorithm");
                    }
                    if (!pss.MaskGenAlgorithm.ObjectID.Equals(Asn1.Pkcs.PkcsObjectIdentifiers.IdMgf1))
                    {
                        throw new CmsException("RSASSA-PSS signature parameters specified unknown MGF");
                    }

                    IDigest pssDigest    = DigestUtilities.GetDigest(pss.HashAlgorithm.ObjectID);
                    int     saltLength   = pss.SaltLength.Value.IntValue;
                    byte    trailerField = (byte)pss.TrailerField.Value.IntValue;

                    // RFC 4055 3.1
                    // The value MUST be 1, which represents the trailer field with hexadecimal value 0xBC
                    if (trailerField != 1)
                    {
                        throw new CmsException("RSASSA-PSS signature parameters must have trailerField of 1");
                    }

                    sig = new PssSigner(new RsaBlindedEngine(), pssDigest, saltLength);
                }
                catch (Exception e)
                {
                    throw new CmsException("failed to set RSASSA-PSS signature parameters", e);
                }
            }
            else
            {
                // TODO Probably too strong a check at the moment
//				if (sigParams != null)
//					throw new CmsException("unrecognised signature parameters provided");

                string signatureName = digestName + "with" + Helper.GetEncryptionAlgName(this.EncryptionAlgOid);

                sig = Helper.GetSignatureInstance(signatureName);
            }

            try
            {
                if (digestCalculator != null)
                {
                    resultDigest = digestCalculator.GetDigest();
                }
                else
                {
                    if (content != null)
                    {
                        content.Write(new DigOutputStream(digest));
                    }
                    else if (signedAttributeSet == null)
                    {
                        // TODO Get rid of this exception and just treat content==null as empty not missing?
                        throw new CmsException("data not encapsulated in signature - use detached constructor.");
                    }

                    resultDigest = DigestUtilities.DoFinal(digest);
                }
            }
            catch (IOException e)
            {
                throw new CmsException("can't process mime object to create signature.", e);
            }

            // RFC 3852 11.1 Check the content-type attribute is correct
            {
                Asn1Object validContentType = GetSingleValuedSignedAttribute(
                    CmsAttributes.ContentType, "content-type");
                if (validContentType == null)
                {
                    if (!isCounterSignature && signedAttributeSet != null)
                    {
                        throw new CmsException("The content-type attribute type MUST be present whenever signed attributes are present in signed-data");
                    }
                }
                else
                {
                    if (isCounterSignature)
                    {
                        throw new CmsException("[For counter signatures,] the signedAttributes field MUST NOT contain a content-type attribute");
                    }

                    if (!(validContentType is DerObjectIdentifier))
                    {
                        throw new CmsException("content-type attribute value not of ASN.1 type 'OBJECT IDENTIFIER'");
                    }

                    DerObjectIdentifier signedContentType = (DerObjectIdentifier)validContentType;

                    if (!signedContentType.Equals(contentType))
                    {
                        throw new CmsException("content-type attribute value does not match eContentType");
                    }
                }
            }

            // RFC 3852 11.2 Check the message-digest attribute is correct
            {
                Asn1Object validMessageDigest = GetSingleValuedSignedAttribute(
                    CmsAttributes.MessageDigest, "message-digest");
                if (validMessageDigest == null)
                {
                    if (signedAttributeSet != null)
                    {
                        throw new CmsException("the message-digest signed attribute type MUST be present when there are any signed attributes present");
                    }
                }
                else
                {
                    if (!(validMessageDigest is Asn1OctetString))
                    {
                        throw new CmsException("message-digest attribute value not of ASN.1 type 'OCTET STRING'");
                    }

                    Asn1OctetString signedMessageDigest = (Asn1OctetString)validMessageDigest;

                    if (!Arrays.AreEqual(resultDigest, signedMessageDigest.GetOctets()))
                    {
                        throw new CmsException("message-digest attribute value does not match calculated value");
                    }
                }
            }

            // RFC 3852 11.4 Validate countersignature attribute(s)
            {
                Asn1.Cms.AttributeTable signedAttrTable = this.SignedAttributes;
                if (signedAttrTable != null &&
                    signedAttrTable.GetAll(CmsAttributes.CounterSignature).Count > 0)
                {
                    throw new CmsException("A countersignature attribute MUST NOT be a signed attribute");
                }

                Asn1.Cms.AttributeTable unsignedAttrTable = this.UnsignedAttributes;
                if (unsignedAttrTable != null)
                {
                    foreach (Asn1.Cms.Attribute csAttr in unsignedAttrTable.GetAll(CmsAttributes.CounterSignature))
                    {
                        if (csAttr.AttrValues.Count < 1)
                        {
                            throw new CmsException("A countersignature attribute MUST contain at least one AttributeValue");
                        }

                        // Note: We don't recursively validate the countersignature value
                    }
                }
            }

            try
            {
                sig.Init(false, key);

                if (signedAttributeSet == null)
                {
                    if (digestCalculator != null)
                    {
                        // need to decrypt signature and check message bytes
                        return(VerifyDigest(resultDigest, key, this.GetSignature()));
                    }
                    else if (content != null)
                    {
                        // TODO Use raw signature of the hash value instead
                        content.Write(new SigOutputStream(sig));
                    }
                }
                else
                {
                    byte[] tmp = this.GetEncodedSignedAttributes();
                    sig.BlockUpdate(tmp, 0, tmp.Length);
                }

                return(sig.VerifySignature(this.GetSignature()));
            }
            catch (InvalidKeyException e)
            {
                throw new CmsException("key not appropriate to signature in message.", e);
            }
            catch (IOException e)
            {
                throw new CmsException("can't process mime object to create signature.", e);
            }
            catch (SignatureException e)
            {
                throw new CmsException("invalid signature format in message: " + e.Message, e);
            }
        }
Exemple #5
0
        private bool DoVerify(
            AsymmetricKeyParameter key,
            Asn1.Cms.AttributeTable signedAttrTable)
        {
            string  digestName = Helper.GetDigestAlgName(this.DigestAlgOid);
            IDigest digest     = Helper.GetDigestInstance(digestName);

            DerObjectIdentifier sigAlgOid = this.encryptionAlgorithm.ObjectID;
            Asn1Encodable       sigParams = this.encryptionAlgorithm.Parameters;
            ISigner             sig;

            if (sigAlgOid.Equals(Asn1.Pkcs.PkcsObjectIdentifiers.IdRsassaPss))
            {
                // RFC 4056 2.2
                // When the id-RSASSA-PSS algorithm identifier is used for a signature,
                // the AlgorithmIdentifier parameters field MUST contain RSASSA-PSS-params.
                if (sigParams == null)
                {
                    throw new CmsException("RSASSA-PSS signature must specify algorithm parameters");
                }

                try
                {
                    // TODO Provide abstract configuration mechanism

                    Asn1.Pkcs.RsassaPssParameters pss = Asn1.Pkcs.RsassaPssParameters.GetInstance(
                        sigParams.ToAsn1Object());

                    if (!pss.HashAlgorithm.ObjectID.Equals(this.digestAlgorithm.ObjectID))
                    {
                        throw new CmsException("RSASSA-PSS signature parameters specified incorrect hash algorithm");
                    }
                    if (!pss.MaskGenAlgorithm.ObjectID.Equals(Asn1.Pkcs.PkcsObjectIdentifiers.IdMgf1))
                    {
                        throw new CmsException("RSASSA-PSS signature parameters specified unknown MGF");
                    }

                    IDigest pssDigest    = DigestUtilities.GetDigest(pss.HashAlgorithm.ObjectID);
                    int     saltLength   = pss.SaltLength.Value.IntValue;
                    byte    trailerField = (byte)pss.TrailerField.Value.IntValue;

                    // RFC 4055 3.1
                    // The value MUST be 1, which represents the trailer field with hexadecimal value 0xBC
                    if (trailerField != 1)
                    {
                        throw new CmsException("RSASSA-PSS signature parameters must have trailerField of 1");
                    }

                    sig = new PssSigner(new RsaBlindedEngine(), pssDigest, saltLength);
                }
                catch (Exception e)
                {
                    throw new CmsException("failed to set RSASSA-PSS signature parameters", e);
                }
            }
            else
            {
                // TODO Probably too strong a check at the moment
//				if (sigParams != null)
//					throw new CmsException("unrecognised signature parameters provided");

                string signatureName = digestName + "with" + Helper.GetEncryptionAlgName(this.EncryptionAlgOid);

                sig = Helper.GetSignatureInstance(signatureName);
            }

            try
            {
                sig.Init(false, key);

                if (signedAttributes == null)
                {
                    if (content != null)
                    {
                        content.Write(new CmsSignedDataGenerator.SigOutputStream(sig));
                        content.Write(new CmsSignedDataGenerator.DigOutputStream(digest));

                        resultDigest = DigestUtilities.DoFinal(digest);
                    }
                    else
                    {
                        resultDigest = digestCalculator.GetDigest();

                        // need to decrypt signature and check message bytes
                        return(VerifyDigest(resultDigest, key, this.GetSignature()));
                    }
                }
                else
                {
                    byte[] hash;
                    if (content != null)
                    {
                        content.Write(
                            new CmsSignedDataGenerator.DigOutputStream(digest));

                        hash = DigestUtilities.DoFinal(digest);
                    }
                    else if (digestCalculator != null)
                    {
                        hash = digestCalculator.GetDigest();
                    }
                    else
                    {
                        hash = null;
                    }

                    resultDigest = hash;

                    Asn1.Cms.Attribute dig  = signedAttrTable[Asn1.Cms.CmsAttributes.MessageDigest];
                    Asn1.Cms.Attribute type = signedAttrTable[Asn1.Cms.CmsAttributes.ContentType];

                    if (dig == null)
                    {
                        throw new SignatureException("no hash for content found in signed attributes");
                    }

                    if (type == null && !contentType.Equals(CmsAttributes.CounterSignature))
                    {
                        throw new SignatureException("no content type id found in signed attributes");
                    }

                    Asn1Object hashObj = dig.AttrValues[0].ToAsn1Object();

                    if (hashObj is Asn1OctetString)
                    {
                        byte[] signedHash = ((Asn1OctetString)hashObj).GetOctets();

                        if (!Arrays.AreEqual(hash, signedHash))
                        {
                            throw new SignatureException("content hash found in signed attributes different");
                        }
                    }
                    else if (hashObj is DerNull)
                    {
                        if (hash != null)
                        {
                            throw new SignatureException("NULL hash found in signed attributes when one expected");
                        }
                    }

                    if (type != null)
                    {
                        DerObjectIdentifier typeOID = (DerObjectIdentifier)type.AttrValues[0];

                        if (!typeOID.Equals(contentType))
                        {
                            throw new SignatureException("contentType in signed attributes different");
                        }
                    }

                    byte[] tmp = this.GetEncodedSignedAttributes();
                    sig.BlockUpdate(tmp, 0, tmp.Length);
                }

                return(sig.VerifySignature(this.GetSignature()));
            }
            catch (InvalidKeyException e)
            {
                throw new CmsException(
                          "key not appropriate to signature in message.", e);
            }
            catch (IOException e)
            {
                throw new CmsException(
                          "can't process mime object to create signature.", e);
            }
            catch (SignatureException e)
            {
                throw new CmsException(
                          "invalid signature format in message: " + e.Message, e);
            }
        }
        private bool DoVerify(AsymmetricKeyParameter key)
        {
            //IL_019b: Expected O, but got Unknown
            //IL_03a0: Expected O, but got Unknown
            string              digestAlgName  = Helper.GetDigestAlgName(DigestAlgOid);
            IDigest             digestInstance = Helper.GetDigestInstance(digestAlgName);
            DerObjectIdentifier algorithm      = encryptionAlgorithm.Algorithm;
            Asn1Encodable       parameters     = encryptionAlgorithm.Parameters;
            ISigner             signer;

            if (algorithm.Equals(PkcsObjectIdentifiers.IdRsassaPss))
            {
                if (parameters == null)
                {
                    throw new CmsException("RSASSA-PSS signature must specify algorithm parameters");
                }
                try
                {
                    RsassaPssParameters instance = RsassaPssParameters.GetInstance(parameters.ToAsn1Object());
                    if (!instance.HashAlgorithm.Algorithm.Equals(digestAlgorithm.Algorithm))
                    {
                        throw new CmsException("RSASSA-PSS signature parameters specified incorrect hash algorithm");
                    }
                    if (!instance.MaskGenAlgorithm.Algorithm.Equals(PkcsObjectIdentifiers.IdMgf1))
                    {
                        throw new CmsException("RSASSA-PSS signature parameters specified unknown MGF");
                    }
                    IDigest digest   = DigestUtilities.GetDigest(instance.HashAlgorithm.Algorithm);
                    int     intValue = instance.SaltLength.Value.IntValue;
                    byte    b        = (byte)instance.TrailerField.Value.IntValue;
                    if (b != 1)
                    {
                        throw new CmsException("RSASSA-PSS signature parameters must have trailerField of 1");
                    }
                    signer = new PssSigner(new RsaBlindedEngine(), digest, intValue);
                }
                catch (global::System.Exception e)
                {
                    throw new CmsException("failed to set RSASSA-PSS signature parameters", e);
                }
            }
            else
            {
                string algorithm2 = digestAlgName + "with" + Helper.GetEncryptionAlgName(EncryptionAlgOid);
                signer = Helper.GetSignatureInstance(algorithm2);
            }
            try
            {
                if (digestCalculator != null)
                {
                    resultDigest = digestCalculator.GetDigest();
                }
                else
                {
                    if (content != null)
                    {
                        content.Write((Stream)(object)new DigOutputStream(digestInstance));
                    }
                    else if (signedAttributeSet == null)
                    {
                        throw new CmsException("data not encapsulated in signature - use detached constructor.");
                    }
                    resultDigest = DigestUtilities.DoFinal(digestInstance);
                }
            }
            catch (IOException val)
            {
                IOException e2 = val;
                throw new CmsException("can't process mime object to create signature.", (global::System.Exception)(object) e2);
            }
            Asn1Object singleValuedSignedAttribute = GetSingleValuedSignedAttribute(CmsAttributes.ContentType, "content-type");

            if (singleValuedSignedAttribute == null)
            {
                if (!isCounterSignature && signedAttributeSet != null)
                {
                    throw new CmsException("The content-type attribute type MUST be present whenever signed attributes are present in signed-data");
                }
            }
            else
            {
                if (isCounterSignature)
                {
                    throw new CmsException("[For counter signatures,] the signedAttributes field MUST NOT contain a content-type attribute");
                }
                if (!(singleValuedSignedAttribute is DerObjectIdentifier))
                {
                    throw new CmsException("content-type attribute value not of ASN.1 type 'OBJECT IDENTIFIER'");
                }
                DerObjectIdentifier derObjectIdentifier = (DerObjectIdentifier)singleValuedSignedAttribute;
                if (!derObjectIdentifier.Equals(contentType))
                {
                    throw new CmsException("content-type attribute value does not match eContentType");
                }
            }
            Asn1Object singleValuedSignedAttribute2 = GetSingleValuedSignedAttribute(CmsAttributes.MessageDigest, "message-digest");

            if (singleValuedSignedAttribute2 == null)
            {
                if (signedAttributeSet != null)
                {
                    throw new CmsException("the message-digest signed attribute type MUST be present when there are any signed attributes present");
                }
            }
            else
            {
                if (!(singleValuedSignedAttribute2 is Asn1OctetString))
                {
                    throw new CmsException("message-digest attribute value not of ASN.1 type 'OCTET STRING'");
                }
                Asn1OctetString asn1OctetString = (Asn1OctetString)singleValuedSignedAttribute2;
                if (!Arrays.AreEqual(resultDigest, asn1OctetString.GetOctets()))
                {
                    throw new CmsException("message-digest attribute value does not match calculated value");
                }
            }
            Org.BouncyCastle.Asn1.Cms.AttributeTable signedAttributes = SignedAttributes;
            if (signedAttributes != null && signedAttributes.GetAll(CmsAttributes.CounterSignature).Count > 0)
            {
                throw new CmsException("A countersignature attribute MUST NOT be a signed attribute");
            }
            Org.BouncyCastle.Asn1.Cms.AttributeTable unsignedAttributes = UnsignedAttributes;
            if (unsignedAttributes != null)
            {
                {
                    global::System.Collections.IEnumerator enumerator = unsignedAttributes.GetAll(CmsAttributes.CounterSignature).GetEnumerator();
                    try
                    {
                        while (enumerator.MoveNext())
                        {
                            Attribute attribute = (Attribute)enumerator.get_Current();
                            if (attribute.AttrValues.Count < 1)
                            {
                                throw new CmsException("A countersignature attribute MUST contain at least one AttributeValue");
                            }
                        }
                    }
                    finally
                    {
                        global::System.IDisposable disposable = enumerator as global::System.IDisposable;
                        if (disposable != null)
                        {
                            disposable.Dispose();
                        }
                    }
                }
            }
            try
            {
                signer.Init(forSigning: false, key);
                if (signedAttributeSet == null)
                {
                    if (digestCalculator != null)
                    {
                        return(VerifyDigest(resultDigest, key, GetSignature()));
                    }
                    if (content != null)
                    {
                        content.Write((Stream)(object)new SigOutputStream(signer));
                    }
                }
                else
                {
                    byte[] encodedSignedAttributes = GetEncodedSignedAttributes();
                    signer.BlockUpdate(encodedSignedAttributes, 0, encodedSignedAttributes.Length);
                }
                return(signer.VerifySignature(GetSignature()));
            }
            catch (InvalidKeyException e3)
            {
                throw new CmsException("key not appropriate to signature in message.", e3);
            }
            catch (IOException val2)
            {
                IOException e4 = val2;
                throw new CmsException("can't process mime object to create signature.", (global::System.Exception)(object) e4);
            }
            catch (SignatureException ex)
            {
                throw new CmsException("invalid signature format in message: " + ((global::System.Exception)ex).get_Message(), ex);
            }
        }
Exemple #7
0
        private bool DoVerify(
            AsymmetricKeyParameter key,
            Asn1.Cms.AttributeTable signedAttrTable)
        {
            string digestName    = Helper.GetDigestAlgName(this.DigestAlgOid);
            string signatureName = digestName + "with"
                                   + Helper.GetEncryptionAlgName(this.EncryptionAlgOid);
            ISigner sig    = Helper.GetSignatureInstance(signatureName);
            IDigest digest = Helper.GetDigestInstance(digestName);

            try
            {
                sig.Init(false, key);

                if (signedAttributes == null)
                {
                    if (content != null)
                    {
                        content.Write(new CmsSignedDataGenerator.SigOutputStream(sig));
                        content.Write(new CmsSignedDataGenerator.DigOutputStream(digest));

                        _resultDigest = DigestUtilities.DoFinal(digest);
                    }
                    else
                    {
                        _resultDigest = _digest;

                        // need to decrypt signature and check message bytes
                        return(VerifyDigest(_digest, key, this.GetSignature()));
                    }
                }
                else
                {
                    byte[] hash;
                    if (content != null)
                    {
                        content.Write(
                            new CmsSignedDataGenerator.DigOutputStream(digest));

                        hash = DigestUtilities.DoFinal(digest);
                    }
                    else
                    {
                        hash = _digest;
                    }

                    _resultDigest = hash;

                    Asn1.Cms.Attribute dig  = signedAttrTable[Asn1.Cms.CmsAttributes.MessageDigest];
                    Asn1.Cms.Attribute type = signedAttrTable[Asn1.Cms.CmsAttributes.ContentType];

                    if (dig == null)
                    {
                        throw new SignatureException("no hash for content found in signed attributes");
                    }

                    if (type == null)
                    {
                        throw new SignatureException("no content type id found in signed attributes");
                    }

                    Asn1Object hashObj = dig.AttrValues[0].ToAsn1Object();

                    if (hashObj is Asn1OctetString)
                    {
                        byte[] signedHash = ((Asn1OctetString)hashObj).GetOctets();

                        if (!Arrays.AreEqual(hash, signedHash))
                        {
                            throw new SignatureException("content hash found in signed attributes different");
                        }
                    }
                    else if (hashObj is DerNull)
                    {
                        if (hash != null)
                        {
                            throw new SignatureException("NULL hash found in signed attributes when one expected");
                        }
                    }

                    DerObjectIdentifier typeOID = (DerObjectIdentifier)type.AttrValues[0];

                    if (!typeOID.Equals(contentType))
                    {
                        throw new SignatureException("contentType in signed attributes different");
                    }

                    {
                        byte[] tmp = this.GetEncodedSignedAttributes();
                        sig.BlockUpdate(tmp, 0, tmp.Length);
                    }
                }

                return(sig.VerifySignature(this.GetSignature()));
            }
            catch (InvalidKeyException e)
            {
                throw new CmsException(
                          "key not appropriate to signature in message.", e);
            }
            catch (IOException e)
            {
                throw new CmsException(
                          "can't process mime object to create signature.", e);
            }
            catch (SignatureException e)
            {
                throw new CmsException(
                          "invalid signature format in message: " + e.Message, e);
            }
        }