Beispiel #1
0
        /// <summary>
        /// Verifies the signature over data or a digest.
        /// The data will be hashed internall by the method using hash algorithm from
        /// the signing scheme digest computed from the specified data buffer.
        /// The signing scheme is retrieved from the signature. The verification key
        /// shall have either compatible or null scheme.
        /// </summary>
        /// <param name="data">Byte buffer containing either digest or data to check against the signature</param>
        /// <param name="dataIsDigest">Specifies the type of 'data' parameter contents</param>
        /// <param name="signature">The signature</param>
        /// <returns>True if the verification succeeds.</returns>
        private bool VerifySignature(byte[] data, bool dataIsDigest, ISignatureUnion sig)
        {
#if TSS_USE_BCRYPT
            Debug.Assert(Key != UIntPtr.Zero);
#endif
            TpmAlgId sigScheme = sig.GetUnionSelector();
            TpmAlgId sigHash   = CryptoLib.SchemeHash(sig);

            var rsaParams = PublicParms.parameters as RsaParms;
            if (rsaParams != null)
            {
#if !TSS_USE_BCRYPT
                Debug.Assert(RsaProvider != null);
#endif
                var      s         = sig as SignatureRsa;
                TpmAlgId keyScheme = rsaParams.scheme.GetUnionSelector();

                if (keyScheme != TpmAlgId.Null && keyScheme != sigScheme)
                {
                    Globs.Throw <ArgumentException>("Key scheme and signature scheme do not match");
                    return(false);
                }

                byte[] digest = dataIsDigest ? data : CryptoLib.HashData(sigHash, data);

                if (sigScheme == TpmAlgId.Rsassa)
                {
#if TSS_USE_BCRYPT
                    return(Key.VerifySignature(digest, s.sig, sigHash, true));
#else
                    return(RsaProvider.VerifyHash(digest, CryptoLib.GetHashName(sigHash), s.sig));
#endif
                }
                if (sigScheme == TpmAlgId.Rsapss)
                {
#if true
                    Globs.Throw <ArgumentException>("VerifySignature(): PSS scheme is not supported");
                    return(false);
#else
#if TSS_USE_BCRYPT
                    return(BCryptInterface.VerifySignature(KeyHandle, digest, sig.sig, sigHash, false));
#else
                    var rr = new RawRsa(RsaProvider.ExportParameters(false), RsaProvider.KeySize);
                    return(rr.PssVerify(digest, sig.sig, sigHash));
#endif
#endif // false
                }
                Globs.Throw <ArgumentException>("VerifySignature(): Unrecognized scheme");
                return(false);
            }

            var eccParams = PublicParms.parameters as EccParms;
            if (eccParams != null)
            {
                if (eccParams.scheme.GetUnionSelector() != TpmAlgId.Ecdsa)
                {
                    Globs.Throw <ArgumentException>("Unsupported ECC sig scheme");
                    return(false);
                }
                TpmAlgId keyScheme = eccParams.scheme.GetUnionSelector();

                if (keyScheme != TpmAlgId.Null && keyScheme != sigScheme)
                {
                    Globs.Throw <ArgumentException>("Key scheme and signature scheme do not match");
                    return(false);
                }

                var    s       = sig as SignatureEcdsa;
                byte[] digest  = dataIsDigest ? data : CryptoLib.HashData(sigHash, data);
                byte[] sigBlob = Globs.Concatenate(s.signatureR, s.signatureS);
#if TSS_USE_BCRYPT
                return(Key.VerifySignature(digest, sigBlob));
#elif !__MonoCS__
                Debug.Assert(EcdsaProvider != null);
                EcdsaProvider.HashAlgorithm = GetCngAlgorithm(sigHash);
                return(EcdsaProvider.VerifyHash(digest, sigBlob));
#endif // !TSS_USE_BCRYPT && !__MonoCS__
            }

            // Should never be here
            Globs.Throw("VerifySignature: Unrecognized asymmetric algorithm");
            return(false);
        } // VerifySignature()
Beispiel #2
0
        /// <summary>
        /// Sign using a non-default hash algorithm.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="sigHash"></param>
        /// <returns></returns>
        public ISignatureUnion SignData(byte[] data, TpmAlgId sigHash)
        {
#if TSS_USE_BCRYPT
            Debug.Assert(Key != UIntPtr.Zero);
#endif
            var rsaParams = PublicParms.parameters as RsaParms;
            if (rsaParams != null)
            {
#if !TSS_USE_BCRYPT
                Debug.Assert(RsaProvider != null);
#endif
                TpmAlgId sigScheme = rsaParams.scheme.GetUnionSelector();

                switch (sigScheme)
                {
                case TpmAlgId.Rsassa:
                {
                    if (sigHash == TpmAlgId.Null)
                    {
                        sigHash = (rsaParams.scheme as SigSchemeRsassa).hashAlg;
                    }
                    byte[] digest = CryptoLib.HashData(sigHash, data);
#if TSS_USE_BCRYPT
                    byte[] sig = Key.SignHash(digest, BcryptScheme.Rsassa, sigHash);
#else
                    byte[] sig = RsaProvider.SignData(data, CryptoLib.GetHashName(sigHash));
#endif
                    return(new SignatureRsassa(sigHash, sig));
                }

                case TpmAlgId.Rsapss:
                {
#if true
                    Globs.Throw <ArgumentException>("SignData(): PSS scheme is not supported");
                    return(null);
#else
                    if (sigHash == TpmAlgId.Null)
                    {
                        sigHash = (rsaParams.scheme as SigSchemeRsapss).hashAlg;
                    }
#if TSS_USE_BCRYPT
                    byte[] sig = BCryptInterface.SignHash(KeyHandle, digest, sigHash, false);
#else
                    var    rr  = new RawRsa(RsaProvider.ExportParameters(false), RsaProvider.KeySize);
                    byte[] sig = rr.PssSign(digest, sigHash);
#endif
                    return(new SignatureRsapss(sigHash, sig));
#endif // false
                }
                }
                Globs.Throw <ArgumentException>("Unsupported signature scheme");
                return(null);
            }

            var eccParms = PublicParms.parameters as EccParms;
            if (eccParms != null)
            {
                if (eccParms.scheme.GetUnionSelector() != TpmAlgId.Ecdsa)
                {
                    Globs.Throw <ArgumentException>("Unsupported ECC sig scheme");
                    return(null);
                }
                if (sigHash == TpmAlgId.Null)
                {
                    sigHash = (eccParms.scheme as SigSchemeEcdsa).hashAlg;
                }
                byte[] digest = CryptoLib.HashData(sigHash, data);
#if TSS_USE_BCRYPT
                //throw new NotImplementedException("ECC signing with BCrypt is not implemented");
                byte[] sig = Key.SignHash(digest, BcryptScheme.Ecdsa, sigHash);
                int    len = sig.Length / 2;
                return(new SignatureEcdsa(sigHash, Globs.CopyData(sig, 0, len), Globs.CopyData(sig, len, len)));
#elif !__MonoCS__
                Debug.Assert(EcdsaProvider != null);
                EcdsaProvider.HashAlgorithm = GetCngAlgorithm(sigHash);
                byte[] sig = EcdsaProvider.SignData(data);

                int fragLen = sig.Length / 2;
                var r       = Globs.CopyData(sig, 0, fragLen);
                var s       = Globs.CopyData(sig, fragLen, fragLen);
                return(new SignatureEcdsa(sigHash, r, s));
#endif // !TSS_USE_BCRYPT && !__MonoCS__
            }

            // Should never be here
            Globs.Throw("VerifySignature: Unrecognized asymmetric algorithm");
            return(null);
        } // SignData()