Exemplo n.º 1
0
        public AlgorithmIdentifier find(AlgorithmIdentifier sigAlgId)
        {
            AlgorithmIdentifier digAlgId;

            if (sigAlgId.Algorithm.Equals(PkcsObjectIdentifiers.IdRsassaPss))
            {
                digAlgId = RsassaPssParameters.GetInstance(sigAlgId.Parameters).HashAlgorithm;
            }
            else
            {
                digAlgId = new AlgorithmIdentifier((DerObjectIdentifier)digestOids[sigAlgId.Algorithm], DerNull.Instance);
            }

            return(digAlgId);
        }
Exemplo n.º 2
0
        internal static string GetSignatureName(
            AlgorithmIdentifier sigAlgId)
        {
            Asn1Encodable asn1Params = sigAlgId.Parameters;

            if (asn1Params != null && !(asn1Params is Asn1Null))
            {
                if (sigAlgId.ObjectID.Equals(PkcsObjectIdentifiers.IdRsassaPss))
                {
                    RsassaPssParameters rsaParams = RsassaPssParameters.GetInstance(asn1Params);
                    return(GetDigestAlgName(rsaParams.HashAlgorithm.ObjectID) + "withRSAandMGF1");
                }
            }

            return(sigAlgId.ObjectID.Id);
        }
Exemplo n.º 3
0
        internal static string GetSignatureName(AlgorithmIdentifier sigAlgId)
        {
            Asn1Encodable parameters = sigAlgId.Parameters;

            if ((parameters != null) && !derNull.Equals(parameters))
            {
                if (sigAlgId.Algorithm.Equals(PkcsObjectIdentifiers.IdRsassaPss))
                {
                    return(GetDigestAlgName(RsassaPssParameters.GetInstance(parameters).HashAlgorithm.Algorithm) + "withRSAandMGF1");
                }
                if (sigAlgId.Algorithm.Equals(X9ObjectIdentifiers.ECDsaWithSha2))
                {
                    return(GetDigestAlgName((DerObjectIdentifier)Asn1Sequence.GetInstance(parameters)[0]) + "withECDSA");
                }
            }
            return(sigAlgId.Algorithm.Id);
        }
Exemplo n.º 4
0
        internal static string GetSignatureName(AlgorithmIdentifier sigAlgId)
        {
            Asn1Encodable parameters = sigAlgId.Parameters;

            if (parameters != null && !X509SignatureUtilities.derNull.Equals(parameters))
            {
                if (sigAlgId.ObjectID.Equals(PkcsObjectIdentifiers.IdRsassaPss))
                {
                    RsassaPssParameters instance = RsassaPssParameters.GetInstance(parameters);
                    return(X509SignatureUtilities.GetDigestAlgName(instance.HashAlgorithm.ObjectID) + "withRSAandMGF1");
                }
                if (sigAlgId.ObjectID.Equals(X9ObjectIdentifiers.ECDsaWithSha2))
                {
                    Asn1Sequence instance2 = Asn1Sequence.GetInstance(parameters);
                    return(X509SignatureUtilities.GetDigestAlgName((DerObjectIdentifier)instance2[0]) + "withECDSA");
                }
            }
            return(sigAlgId.ObjectID.Id);
        }
        public IVerifierFactory <AlgorithmIdentifier> CreateVerifierFactory(AlgorithmIdentifier signatureAlgorithmID, AlgorithmIdentifier digestAlgorithmID)
        {
            IVerifierFactory <IParameters <Algorithm> > baseVerifier;

            AsymmetricRsaPublicKey rsaKey = publicKey as AsymmetricRsaPublicKey;

            if (rsaKey != null)
            {
                IVerifierFactoryService verifierService = CryptoServicesRegistrar.CreateService(rsaKey);

                if (signatureAlgorithmID.Algorithm.Equals(PkcsObjectIdentifiers.IdRsassaPss))
                {
                    FipsRsa.PssSignatureParameters pssParams = FipsRsa.Pss;
                    RsassaPssParameters            sigParams = RsassaPssParameters.GetInstance(signatureAlgorithmID.Parameters);

                    pssParams = pssParams.WithDigest((FipsDigestAlgorithm)Utils.digestTable[sigParams.HashAlgorithm.Algorithm]);
                    AlgorithmIdentifier mgfDigAlg = AlgorithmIdentifier.GetInstance(AlgorithmIdentifier.GetInstance(sigParams.MaskGenAlgorithm).Parameters);
                    pssParams = pssParams.WithMgfDigest((FipsDigestAlgorithm)Utils.digestTable[mgfDigAlg.Algorithm]);

                    pssParams = pssParams.WithSaltLength(sigParams.SaltLength.Value.IntValue);

                    return(CreateVerifierFactory(signatureAlgorithmID, verifierService.CreateVerifierFactory(pssParams), certificate));
                }
                else if (PkixVerifierFactoryProvider.pkcs1Table.Contains(signatureAlgorithmID.Algorithm))
                {
                    FipsRsa.SignatureParameters rsaParams = FipsRsa.Pkcs1v15.WithDigest((FipsDigestAlgorithm)PkixVerifierFactoryProvider.pkcs1Table[signatureAlgorithmID.Algorithm]);

                    return(CreateVerifierFactory(signatureAlgorithmID, verifierService.CreateVerifierFactory(rsaParams), certificate));
                }
                else if (signatureAlgorithmID.Algorithm.Equals(PkcsObjectIdentifiers.RsaEncryption))
                {
                    FipsRsa.SignatureParameters rsaParams = FipsRsa.Pkcs1v15.WithDigest((FipsDigestAlgorithm)Utils.digestTable[digestAlgorithmID.Algorithm]);

                    return(CreateVerifierFactory(signatureAlgorithmID, verifierService.CreateVerifierFactory(rsaParams), certificate));
                }
            }

            throw new ArgumentException("cannot match signature algorithm: " + signatureAlgorithmID.Algorithm);
        }
Exemplo n.º 6
0
        internal static string GetSignatureName(AlgorithmIdentifier sigAlgId)
        {
            Asn1Encodable parameters = sigAlgId.Parameters;

            if (parameters != null && !derNull.Equals(parameters))
            {
                if (sigAlgId.Algorithm.Equals(PkcsObjectIdentifiers.IdRsassaPss))
                {
                    RsassaPssParameters rsaParams = RsassaPssParameters.GetInstance(parameters);

                    return GetDigestAlgName(rsaParams.HashAlgorithm.Algorithm) + "withRSAandMGF1";
                }
                if (sigAlgId.Algorithm.Equals(X9ObjectIdentifiers.ECDsaWithSha2))
                {
                    Asn1Sequence ecDsaParams = Asn1Sequence.GetInstance(parameters);

                    return GetDigestAlgName((DerObjectIdentifier)ecDsaParams[0]) + "withECDSA";
                }
            }

            return sigAlgId.Algorithm.Id;
        }
Exemplo n.º 7
0
        private bool DoVerify(AsymmetricKeyParameter key)
        {
            string              digestAlgName  = SignerInformation.Helper.GetDigestAlgName(this.DigestAlgOid);
            IDigest             digestInstance = SignerInformation.Helper.GetDigestInstance(digestAlgName);
            DerObjectIdentifier objectID       = this.encryptionAlgorithm.ObjectID;
            Asn1Encodable       parameters     = this.encryptionAlgorithm.Parameters;
            ISigner             signer;

            if (objectID.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.ObjectID.Equals(this.digestAlgorithm.ObjectID))
                    {
                        throw new CmsException("RSASSA-PSS signature parameters specified incorrect hash algorithm");
                    }
                    if (!instance.MaskGenAlgorithm.ObjectID.Equals(PkcsObjectIdentifiers.IdMgf1))
                    {
                        throw new CmsException("RSASSA-PSS signature parameters specified unknown MGF");
                    }
                    IDigest digest   = DigestUtilities.GetDigest(instance.HashAlgorithm.ObjectID);
                    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);
                    goto IL_142;
                }
                catch (Exception e)
                {
                    throw new CmsException("failed to set RSASSA-PSS signature parameters", e);
                }
            }
            string algorithm = digestAlgName + "with" + SignerInformation.Helper.GetEncryptionAlgName(this.EncryptionAlgOid);

            signer = SignerInformation.Helper.GetSignatureInstance(algorithm);
            try
            {
IL_142:
                if (this.digestCalculator != null)
                {
                    this.resultDigest = this.digestCalculator.GetDigest();
                }
                else
                {
                    if (this.content != null)
                    {
                        this.content.Write(new DigOutputStream(digestInstance));
                    }
                    else if (this.signedAttributeSet == null)
                    {
                        throw new CmsException("data not encapsulated in signature - use detached constructor.");
                    }
                    this.resultDigest = DigestUtilities.DoFinal(digestInstance);
                }
            }
            catch (IOException e2)
            {
                throw new CmsException("can't process mime object to create signature.", e2);
            }
            Asn1Object singleValuedSignedAttribute = this.GetSingleValuedSignedAttribute(CmsAttributes.ContentType, "content-type");

            if (singleValuedSignedAttribute == null)
            {
                if (!this.isCounterSignature && this.signedAttributeSet != null)
                {
                    throw new CmsException("The content-type attribute type MUST be present whenever signed attributes are present in signed-data");
                }
            }
            else
            {
                if (this.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(this.contentType))
                {
                    throw new CmsException("content-type attribute value does not match eContentType");
                }
            }
            Asn1Object singleValuedSignedAttribute2 = this.GetSingleValuedSignedAttribute(CmsAttributes.MessageDigest, "message-digest");

            if (singleValuedSignedAttribute2 == null)
            {
                if (this.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(this.resultDigest, asn1OctetString.GetOctets()))
                {
                    throw new CmsException("message-digest attribute value does not match calculated value");
                }
            }
            Org.BouncyCastle.Asn1.Cms.AttributeTable signedAttributes = this.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 = this.UnsignedAttributes;
            if (unsignedAttributes != null)
            {
                foreach (Org.BouncyCastle.Asn1.Cms.Attribute attribute in unsignedAttributes.GetAll(CmsAttributes.CounterSignature))
                {
                    if (attribute.AttrValues.Count < 1)
                    {
                        throw new CmsException("A countersignature attribute MUST contain at least one AttributeValue");
                    }
                }
            }
            bool result;

            try
            {
                signer.Init(false, key);
                if (this.signedAttributeSet == null)
                {
                    if (this.digestCalculator != null)
                    {
                        result = this.VerifyDigest(this.resultDigest, key, this.GetSignature());
                        return(result);
                    }
                    if (this.content != null)
                    {
                        this.content.Write(new SigOutputStream(signer));
                    }
                }
                else
                {
                    byte[] encodedSignedAttributes = this.GetEncodedSignedAttributes();
                    signer.BlockUpdate(encodedSignedAttributes, 0, encodedSignedAttributes.Length);
                }
                result = signer.VerifySignature(this.GetSignature());
            }
            catch (InvalidKeyException e3)
            {
                throw new CmsException("key not appropriate to signature in message.", e3);
            }
            catch (IOException e4)
            {
                throw new CmsException("can't process mime object to create signature.", e4);
            }
            catch (SignatureException ex)
            {
                throw new CmsException("invalid signature format in message: " + ex.Message, ex);
            }
            return(result);
        }
Exemplo n.º 8
0
        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);
            }
        }
Exemplo n.º 9
0
        /// <summary>
        /// Return a verifier factory that produces verifiers conforming to algorithmDetails.
        /// </summary>
        /// <param name="algorithmDetails">The configuration parameters for verifiers produced by the resulting factory.</param>
        /// <returns>A new verifier factory.</returns>
        public IVerifierFactory <AlgorithmIdentifier> CreateVerifierFactory(AlgorithmIdentifier algorithmDetails)
        {
            AsymmetricRsaPublicKey rsaKey = publicKey as AsymmetricRsaPublicKey;

            if (rsaKey != null)
            {
                IVerifierFactoryService verifierService = CryptoServicesRegistrar.CreateService(rsaKey);

                if (algorithmDetails.Algorithm.Equals(PkcsObjectIdentifiers.IdRsassaPss))
                {
                    FipsRsa.PssSignatureParameters pssParams = FipsRsa.Pss;
                    RsassaPssParameters            sigParams = RsassaPssParameters.GetInstance(algorithmDetails.Parameters);

                    pssParams = pssParams.WithDigest((FipsDigestAlgorithm)Utils.digestTable[sigParams.HashAlgorithm.Algorithm]);
                    AlgorithmIdentifier mgfDigAlg = AlgorithmIdentifier.GetInstance(AlgorithmIdentifier.GetInstance(sigParams.MaskGenAlgorithm).Parameters);
                    pssParams = pssParams.WithMgfDigest((FipsDigestAlgorithm)Utils.digestTable[mgfDigAlg.Algorithm]);

                    pssParams = pssParams.WithSaltLength(sigParams.SaltLength.Value.IntValue);

                    return(CreateVerifierFactory(algorithmDetails, verifierService.CreateVerifierFactory(pssParams), certificate));
                }
                else if (pkcs1Table.Contains(algorithmDetails.Algorithm))
                {
                    FipsRsa.SignatureParameters rsaParams = FipsRsa.Pkcs1v15.WithDigest((FipsDigestAlgorithm)pkcs1Table[algorithmDetails.Algorithm]);

                    return(CreateVerifierFactory(algorithmDetails, verifierService.CreateVerifierFactory(rsaParams), certificate));
                }
            }

            AsymmetricDsaPublicKey dsaKey = publicKey as AsymmetricDsaPublicKey;

            if (dsaKey != null)
            {
                IVerifierFactoryService verifierService = CryptoServicesRegistrar.CreateService(dsaKey);

                FipsDsa.SignatureParameters sigParams = (FipsDsa.SignatureParameters)dsaTable[algorithmDetails.Algorithm];

                return(CreateVerifierFactory(algorithmDetails, verifierService.CreateVerifierFactory(sigParams), certificate));
            }

            AsymmetricECPublicKey ecdsaKey = publicKey as AsymmetricECPublicKey;

            if (ecdsaKey != null)
            {
                IVerifierFactoryService verifierService = CryptoServicesRegistrar.CreateService(ecdsaKey);

                FipsEC.SignatureParameters sigParams = (FipsEC.SignatureParameters)ecdsaTable[algorithmDetails.Algorithm];

                return(CreateVerifierFactory(algorithmDetails, verifierService.CreateVerifierFactory(sigParams), certificate));
            }

            AsymmetricSphincsPublicKey sphincsKey = publicKey as AsymmetricSphincsPublicKey;

            if (sphincsKey != null)
            {
                IVerifierFactoryService verifierService = CryptoServicesRegistrar.CreateService(sphincsKey);
                if (algorithmDetails.Algorithm.Equals(BCObjectIdentifiers.sphincs256_with_SHA512))
                {
                    return(CreateVerifierFactory(algorithmDetails, verifierService.CreateVerifierFactory(Sphincs.Sphincs256), certificate));
                }
                else
                {
                    return(CreateVerifierFactory(algorithmDetails, verifierService.CreateVerifierFactory(Sphincs.Sphincs256.WithDigest(FipsShs.Sha3_512)), certificate));
                }
            }

            throw new ArgumentException("cannot match signature algorithm");
        }
Exemplo n.º 10
0
        private bool DoVerify(
            AsymmetricKeyParameter key)
        {
            string  digestName = Helper.GetDigestAlgName(this.DigestAlgOid);
            IDigest digest     = Helper.GetDigestInstance(digestName);

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

            if (sigAlgOid.Equals(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)

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

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

                    IDigest pssDigest    = DigestUtilities.GetDigest(pss.HashAlgorithm.Algorithm);
                    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);

                //sig = Helper.GetSignatureInstance(this.EncryptionAlgOid);
                //sig = SignerUtilities.GetSigner(sigAlgOid);
            }

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

                AttributeTable unsignedAttrTable = this.UnsignedAttributes;
                if (unsignedAttrTable != null)
                {
                    foreach (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);
            }
        }