Example #1
0
        /// <inheritdoc />
        /// <exception cref="ArgumentNullException"> <paramref name="other" /> is <see langword="null" />. </exception>
        /// <inheritdoc cref="DisposableBase.ThrowIfDisposed"/>
        public async Task <bool> EqualsAsync(IReadOnlySafeString other)
        {
            ThrowIfDisposed();
            if (other == null)
            {
                throw new ArgumentNullException(nameof(other));
            }
            if (other.Length == 0)
            {
                return(Length == 0);
            }
            if (this.GetHashCode() != other.GetHashCode())
            {
                return(false);
            }
            // Caution: Don't check length first and then fall out, since that leaks length info
            var comparisonBit = (uint)Length ^ (uint)other.Length;

            for (var i = 0; i < Length && i < other.Length; i++)
            {
                var ownBytes     = GetAsSafeBytes(i);
                var otherBytes   = other.GetAsSafeBytes(i);
                var areSameBytes = await ownBytes.EqualsAsync(otherBytes)
                                   .ConfigureAwait(false);

                comparisonBit |= (uint)(areSameBytes ? 0 : 1);
            }
            return(comparisonBit == 0);
        }
Example #2
0
        private static Task DecryptAndCopyAsync(IReadOnlySafeString safeString, GCHandle handle)
        {
            var tasks = new Task[safeString.Length];

            for (var i = 0; i < tasks.Length; i++)
            {
                var currentIndex = i;
                tasks[currentIndex] = safeString.RevealDecryptedCharAsync(i)
                                      .ContinueWith(charTask => CopyChar(handle, currentIndex, charTask.Result));
            }
            return(Task.WhenAll(tasks));
        }
Example #3
0
        /// <summary>
        ///     Plain data of the <paramref name="safeString" /> will be available in
        ///     <see cref="String" /> property until this instance is disposed.
        /// </summary>
        /// <param name="safeString">The safe string to decrypt.</param>
        /// <exception cref="ObjectDisposedException"><paramref name="safeString"/> is disposed</exception>
        /// <exception cref="ArgumentNullException"> <paramref name="safeString" /> is <see langword="null" />. </exception>
        /// <exception cref="InvalidOperationException">Already initialized</exception>
        public async Task <IDisposableString> MarshalAsync(IReadOnlySafeString safeString)
        {
            if (safeString == null)
            {
                throw new ArgumentNullException(nameof(safeString));
            }
            if (safeString.IsDisposed)
            {
                throw new ObjectDisposedException(nameof(safeString));
            }
            if (safeString.IsEmpty)
            {
                return(new DisposableString(string.Empty, default));
            }
            var str    = new string('\0', safeString.Length);
            var handle = PinString(str);

            await DecryptAndCopyAsync(safeString, handle).ConfigureAwait(false);

            return(new DisposableString(str, handle));
        }
Example #4
0
 /// <summary>
 /// Indicates whether the specified <see cref="ISafeString"/> is null or an empty string ("").
 /// </summary>
 /// <param name="safeString">The string to test.</param>
 /// <returns><see langword="true" /> if the value parameter is <see langword="null" /> or an empty string (""); otherwise, <see langword="false" />.</returns>
 public static bool IsNullOrEmpty(IReadOnlySafeString safeString)
 => safeString == null || safeString.IsEmpty;