예제 #1
0
        public override bool TryCreateSignature(ReadOnlySpan <byte> hash, Span <byte> destination, out int bytesWritten)
#endif
        {
            SafeDsaHandle key = GetKey();
            int           maxSignatureSize = Interop.Crypto.DsaEncodedSignatureSize(key);
            Span <byte>   signDestination  = stackalloc byte[SignatureStackBufSize];

#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS
            if (signatureFormat == DSASignatureFormat.IeeeP1363FixedFieldConcatenation)
#endif
            {
                int fieldSizeBytes     = Interop.Crypto.DsaSignatureFieldSize(key);
                int p1363SignatureSize = 2 * fieldSizeBytes;

                if (destination.Length < p1363SignatureSize)
                {
                    bytesWritten = 0;
                    return(false);
                }

                int fieldSizeBits = fieldSizeBytes * 8;

                ReadOnlySpan <byte> derSignature = SignHash(hash, signDestination, maxSignatureSize, key);
                bytesWritten = AsymmetricAlgorithmHelpers.ConvertDerToIeee1363(derSignature, fieldSizeBits, destination);
                Debug.Assert(bytesWritten == p1363SignatureSize);
                return(true);
            }
#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS
            else if (signatureFormat == DSASignatureFormat.Rfc3279DerSequence)
            {
                if (destination.Length >= maxSignatureSize)
                {
                    signDestination = destination;
                }
                else if (maxSignatureSize > signDestination.Length)
                {
                    Debug.Fail($"Stack-based signDestination is insufficient ({maxSignatureSize} needed)");
                    bytesWritten = 0;
                    return(false);
                }

                ReadOnlySpan <byte> derSignature = SignHash(hash, signDestination, maxSignatureSize, key);

                if (destination == signDestination)
                {
                    bytesWritten = derSignature.Length;
                    return(true);
                }

                return(Helpers.TryCopyToDestination(derSignature, destination, out bytesWritten));
            }
            else
            {
                Debug.Fail($"Missing internal implementation handler for signature format {signatureFormat}");
                throw new CryptographicException(
                          SR.Cryptography_UnknownSignatureFormat,
                          signatureFormat.ToString());
            }
#endif
        }
예제 #2
0
        public override byte[] CreateSignature(byte[] rgbHash)
        {
            if (rgbHash == null)
            {
                throw new ArgumentNullException(nameof(rgbHash));
            }

            SafeDsaHandle key           = _key.Value;
            int           signatureSize = Interop.Crypto.DsaEncodedSignatureSize(key);

            byte[] signature = CryptoPool.Rent(signatureSize);
            try
            {
                bool success = Interop.Crypto.DsaSign(key, rgbHash, new Span <byte>(signature, 0, signatureSize), out signatureSize);
                if (!success)
                {
                    throw Interop.Crypto.CreateOpenSslCryptographicException();
                }

                Debug.Assert(
                    signatureSize <= signature.Length,
                    "DSA_sign reported an unexpected signature size",
                    "DSA_sign reported signatureSize was {0}, when <= {1} was expected",
                    signatureSize,
                    signature.Length);

                int signatureFieldSize = Interop.Crypto.DsaSignatureFieldSize(key) * BitsPerByte;
                return(AsymmetricAlgorithmHelpers.ConvertDerToIeee1363(signature, 0, signatureSize, signatureFieldSize));
            }
            finally
            {
                CryptoPool.Return(signature, signatureSize);
            }
        }
예제 #3
0
            public override byte[] CreateSignature(byte[] rgbHash)
            {
                if (rgbHash == null)
                {
                    throw new ArgumentNullException(nameof(rgbHash));
                }

                SecKeyPair keys = GetKeys();

                if (keys.PrivateKey == null)
                {
                    throw new CryptographicException(SR.Cryptography_CSP_NoPrivateKey);
                }

                byte[] derFormatSignature = Interop.AppleCrypto.GenerateSignature(keys.PrivateKey, rgbHash);

                // Since the AppleCrypto implementation is limited to FIPS 186-2, signature field sizes
                // are always 160 bits / 20 bytes (the size of SHA-1, and the only legal length for Q).
                byte[] ieeeFormatSignature = AsymmetricAlgorithmHelpers.ConvertDerToIeee1363(
                    derFormatSignature,
                    0,
                    derFormatSignature.Length,
                    fieldSizeBits: 160);

                return(ieeeFormatSignature);
            }
예제 #4
0
            public override bool TrySignHash(ReadOnlySpan <byte> source, Span <byte> destination, out int bytesWritten)
            {
                SecKeyPair keys = GetKeys();

                if (keys.PrivateKey == null)
                {
                    throw new CryptographicException(SR.Cryptography_CSP_NoPrivateKey);
                }

                byte[] derFormatSignature  = Interop.AppleCrypto.GenerateSignature(keys.PrivateKey, source);
                byte[] ieeeFormatSignature = AsymmetricAlgorithmHelpers.ConvertDerToIeee1363(
                    derFormatSignature,
                    0,
                    derFormatSignature.Length,
                    KeySize);

                if (ieeeFormatSignature.Length <= destination.Length)
                {
                    new ReadOnlySpan <byte>(ieeeFormatSignature).CopyTo(destination);
                    bytesWritten = ieeeFormatSignature.Length;
                    return(true);
                }
                else
                {
                    bytesWritten = 0;
                    return(false);
                }
            }
예제 #5
0
            public override byte[] SignHash(byte[] hash)
            {
                if (hash == null)
                {
                    throw new ArgumentNullException(nameof(hash));
                }

                SecKeyPair keys = GetKeys();

                if (keys.PrivateKey == null)
                {
                    throw new CryptographicException(SR.Cryptography_CSP_NoPrivateKey);
                }

                byte[] derFormatSignature = Interop.AppleCrypto.CreateSignature(
                    keys.PrivateKey,
                    hash,
                    Interop.AppleCrypto.PAL_HashAlgorithm.Unknown,
                    Interop.AppleCrypto.PAL_SignatureAlgorithm.EC);
                byte[] ieeeFormatSignature = AsymmetricAlgorithmHelpers.ConvertDerToIeee1363(
                    derFormatSignature.AsSpan(0, derFormatSignature.Length),
                    KeySize);

                return(ieeeFormatSignature);
            }
예제 #6
0
        public override bool TrySignHash(ReadOnlySpan <byte> hash, Span <byte> destination, out int bytesWritten)
        {
            ThrowIfDisposed();
            SafeEcKeyHandle key = _key.Value;

            byte[] converted;
            int    signatureLength = Interop.Crypto.EcDsaSize(key);

            byte[] signature = CryptoPool.Rent(signatureLength);
            try
            {
                if (!Interop.Crypto.EcDsaSign(hash, new Span <byte>(signature, 0, signatureLength), ref signatureLength, key))
                {
                    throw Interop.Crypto.CreateOpenSslCryptographicException();
                }

                converted = AsymmetricAlgorithmHelpers.ConvertDerToIeee1363(signature, 0, signatureLength, KeySize);
            }
            finally
            {
                CryptoPool.Return(signature, signatureLength);
            }

            if (converted.Length <= destination.Length)
            {
                new ReadOnlySpan <byte>(converted).CopyTo(destination);
                bytesWritten = converted.Length;
                return(true);
            }
            else
            {
                bytesWritten = 0;
                return(false);
            }
        }
예제 #7
0
            public override byte[] CreateSignature(byte[] rgbHash)
            {
                ArgumentNullException.ThrowIfNull(rgbHash);

                SecKeyPair keys = GetKeys();

                if (keys.PrivateKey == null)
                {
                    throw new CryptographicException(SR.Cryptography_CSP_NoPrivateKey);
                }

                byte[] derFormatSignature = Interop.AppleCrypto.CreateSignature(
                    keys.PrivateKey,
                    rgbHash,
                    Interop.AppleCrypto.PAL_HashAlgorithm.Unknown,
                    Interop.AppleCrypto.PAL_SignatureAlgorithm.DSA);

                // Since the AppleCrypto implementation is limited to FIPS 186-2, signature field sizes
                // are always 160 bits / 20 bytes (the size of SHA-1, and the only legal length for Q).
                byte[] ieeeFormatSignature = AsymmetricAlgorithmHelpers.ConvertDerToIeee1363(
                    derFormatSignature.AsSpan(0, derFormatSignature.Length),
                    fieldSizeBits: SHA1.HashSizeInBits);

                return(ieeeFormatSignature);
            }
예제 #8
0
        public override bool TrySignHash(ReadOnlySpan <byte> hash, Span <byte> destination, out int bytesWritten)
#endif
        {
            ThrowIfDisposed();
            SafeEcKeyHandle key = _key.Value;

            int         signatureLength = Interop.Crypto.EcDsaSize(key);
            Span <byte> signDestination = stackalloc byte[SignatureStackBufSize];

#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS
            if (signatureFormat == DSASignatureFormat.IeeeP1363FixedFieldConcatenation)
            {
#endif
            int encodedSize = 2 * AsymmetricAlgorithmHelpers.BitsToBytes(KeySize);

            if (destination.Length < encodedSize)
            {
                bytesWritten = 0;
                return(false);
            }

            ReadOnlySpan <byte> derSignature = SignHash(hash, signDestination, signatureLength, key);
            bytesWritten = AsymmetricAlgorithmHelpers.ConvertDerToIeee1363(derSignature, KeySize, destination);
            Debug.Assert(bytesWritten == encodedSize);
            return(true);

#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS
        }

        else if (signatureFormat == DSASignatureFormat.Rfc3279DerSequence)
        {
            if (destination.Length >= signatureLength)
            {
                signDestination = destination;
            }
            else if (signatureLength > signDestination.Length)
            {
                Debug.Fail($"Stack-based signDestination is insufficient ({signatureLength} needed)");
                bytesWritten = 0;
                return(false);
            }

            ReadOnlySpan <byte> derSignature = SignHash(hash, signDestination, signatureLength, key);

            if (destination == signDestination)
            {
                bytesWritten = derSignature.Length;
                return(true);
            }

            return(Helpers.TryCopyToDestination(derSignature, destination, out bytesWritten));
        }
        else
        {
            throw new ArgumentOutOfRangeException(nameof(signatureFormat));
        }
#endif
        }
예제 #9
0
            public override byte[] CreateSignature(byte[] rgbHash)
            {
                ArgumentNullException.ThrowIfNull(rgbHash);

                SafeDsaHandle key                = GetKey();
                int           signatureSize      = Interop.AndroidCrypto.DsaEncodedSignatureSize(key);
                int           signatureFieldSize = Interop.AndroidCrypto.DsaSignatureFieldSize(key) * BitsPerByte;
                Span <byte>   signDestination    = stackalloc byte[SignatureStackBufSize];

                ReadOnlySpan <byte> derSignature = SignHash(rgbHash, signDestination, signatureSize, key);

                return(AsymmetricAlgorithmHelpers.ConvertDerToIeee1363(derSignature, signatureFieldSize));
            }
예제 #10
0
            public override byte[] SignHash(byte[] hash)
            {
                ArgumentNullException.ThrowIfNull(hash);

                ThrowIfDisposed();
                SafeEcKeyHandle key             = _key.Value;
                int             signatureLength = Interop.AndroidCrypto.EcDsaSize(key);

                Span <byte>         signDestination = stackalloc byte[SignatureStackBufSize];
                ReadOnlySpan <byte> derSignature    = SignHash(hash, signDestination, signatureLength, key);

                byte[] converted = AsymmetricAlgorithmHelpers.ConvertDerToIeee1363(derSignature, KeySize);
                return(converted);
            }
예제 #11
0
        public override bool TryCreateSignature(ReadOnlySpan <byte> source, Span <byte> destination, out int bytesWritten)
        {
            byte[]        converted;
            SafeDsaHandle key           = _key.Value;
            int           signatureSize = Interop.Crypto.DsaEncodedSignatureSize(key);

            byte[] signature = ArrayPool <byte> .Shared.Rent(signatureSize);

            try
            {
                bool success = Interop.Crypto.DsaSign(key, source, source.Length, new Span <byte>(signature, 0, signatureSize), out signatureSize);
                if (!success)
                {
                    throw Interop.Crypto.CreateOpenSslCryptographicException();
                }

                Debug.Assert(
                    signatureSize <= signature.Length,
                    "DSA_sign reported an unexpected signature size",
                    "DSA_sign reported signatureSize was {0}, when <= {1} was expected",
                    signatureSize,
                    signature.Length);

                int signatureFieldSize = Interop.Crypto.DsaSignatureFieldSize(key) * BitsPerByte;
                converted = AsymmetricAlgorithmHelpers.ConvertDerToIeee1363(signature, 0, signatureSize, signatureFieldSize);
            }
            finally
            {
                Array.Clear(signature, 0, signatureSize);
                ArrayPool <byte> .Shared.Return(signature);
            }

            if (converted.Length <= destination.Length)
            {
                new ReadOnlySpan <byte>(converted).CopyTo(destination);
                bytesWritten = converted.Length;
                return(true);
            }
            else
            {
                bytesWritten = 0;
                return(false);
            }
        }
예제 #12
0
        public override byte[] SignHash(byte[] hash)
        {
            if (hash == null)
            {
                throw new ArgumentNullException(nameof(hash));
            }

            SafeEcKeyHandle key             = _key.Value;
            int             signatureLength = Interop.Crypto.EcDsaSize(key);

            byte[] signature = new byte[signatureLength];
            if (!Interop.Crypto.EcDsaSign(hash, hash.Length, signature, ref signatureLength, key))
            {
                throw Interop.Crypto.CreateOpenSslCryptographicException();
            }

            byte[] converted = AsymmetricAlgorithmHelpers.ConvertDerToIeee1363(signature, 0, signatureLength, KeySize);

            return(converted);
        }