Beispiel #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
        }
Beispiel #2
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
        }
Beispiel #3
0
 protected virtual bool TryHashData(
     ReadOnlySpan <byte> data,
     Span <byte> destination,
     HashAlgorithmName hashAlgorithm,
     out int bytesWritten)
 {
     byte[] hash = HashSpanToArray(data, hashAlgorithm);
     return(Helpers.TryCopyToDestination(hash, destination, out bytesWritten));
 }
Beispiel #4
0
        /// <summary>
        ///   Attempts to create the ECDSA signature for the specified hash value in the indicated format
        ///   into the provided buffer.
        /// </summary>
        /// <param name="hash">The hash value to sign.</param>
        /// <param name="destination">The buffer to receive the signature.</param>
        /// <param name="signatureFormat">The encoding format to use for the signature.</param>
        /// <param name="bytesWritten">
        ///   When this method returns, contains a value that indicates the number of bytes written to
        ///   <paramref name="destination"/>. This parameter is treated as uninitialized.
        /// </param>
        /// <returns>
        ///   <see langword="true"/> if <paramref name="destination"/> is big enough to receive the signature;
        ///   otherwise, <see langword="false"/>.
        /// </returns>
        /// <exception cref="CryptographicException">
        ///   An error occurred in the signing operation.
        /// </exception>
        protected virtual bool TrySignHashCore(
            ReadOnlySpan <byte> hash,
            Span <byte> destination,
            DSASignatureFormat signatureFormat,
            out int bytesWritten)
        {
            // This method is expected to be overridden with better implementation

            // The only available implementation here is abstract method, use it
            byte[] result    = SignHash(hash.ToArray());
            byte[] converted = AsymmetricAlgorithmHelpers.ConvertFromIeeeP1363Signature(result, signatureFormat);
            return(Helpers.TryCopyToDestination(converted, destination, out bytesWritten));
        }
Beispiel #5
0
        /// <summary>
        ///   Attempts to create the DSA signature for the specified hash value in the indicated format
        ///   into the provided buffer.
        /// </summary>
        /// <param name="hash">The hash value to sign.</param>
        /// <param name="destination">The buffer to receive the signature.</param>
        /// <param name="signatureFormat">The encoding format to use for the signature.</param>
        /// <param name="bytesWritten">
        ///   When this method returns, contains a value that indicates the number of bytes written to
        ///   <paramref name="destination"/>. This parameter is treated as uninitialized.
        /// </param>
        /// <returns>
        ///   <see langword="true"/> if <paramref name="destination"/> is big enough to receive the signature;
        ///   otherwise, <see langword="false"/>.
        /// </returns>
        /// <exception cref="CryptographicException">
        ///   An error occurred in the signing operation.
        /// </exception>
        protected virtual bool TryCreateSignatureCore(
            ReadOnlySpan <byte> hash,
            Span <byte> destination,
            DSASignatureFormat signatureFormat,
            out int bytesWritten)
        {
            // This method is expected to be overriden with better implementation

            // The only available implementation here is abstract method, use it
            byte[] sig = CreateSignature(hash.ToArray());

            if (signatureFormat != DSASignatureFormat.IeeeP1363FixedFieldConcatenation)
            {
                sig = AsymmetricAlgorithmHelpers.ConvertFromIeeeP1363Signature(sig, signatureFormat);
            }

            return(Helpers.TryCopyToDestination(sig, destination, out bytesWritten));
        }