Ejemplo n.º 1
0
        /// <summary>
        /// Creates a new Secret from another secret object.
        /// </summary>
        public Secret(ISecret secret)
        {
            if (secret == null)
            {
                throw new ArgumentNullException(nameof(secret));
            }

            Secret other = secret as Secret;

            if (other != null)
            {
                // Fast-track: simple deep copy scenario.
                this._localAllocHandle = other._localAllocHandle.Duplicate();
                this._plaintextLength  = other._plaintextLength;
            }
            else
            {
                // Copy the secret to a temporary managed buffer, then protect the buffer.
                // We pin the temp buffer and zero it out when we're finished to limit exposure of the secret.
                byte[] tempPlaintextBuffer = new byte[secret.Length];
                fixed(byte *pbTempPlaintextBuffer = tempPlaintextBuffer)
                {
                    try
                    {
                        secret.WriteSecretIntoBuffer(new ArraySegment <byte>(tempPlaintextBuffer));
                        _localAllocHandle = Protect(pbTempPlaintextBuffer, (uint)tempPlaintextBuffer.Length);
                        _plaintextLength  = (uint)tempPlaintextBuffer.Length;
                    }
                    finally
                    {
                        UnsafeBufferUtil.SecureZeroMemory(pbTempPlaintextBuffer, tempPlaintextBuffer.Length);
                    }
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Creates a new Secret from the provided input value, where the input value
        /// is specified as an array segment.
        /// </summary>
        public Secret(ArraySegment <byte> value)
        {
            value.Validate();

            _localAllocHandle = Protect(value);
            _plaintextLength  = (uint)value.Count;
        }
Ejemplo n.º 3
0
    public SecureLocalAllocHandle Duplicate()
    {
        SecureLocalAllocHandle duplicateHandle = Allocate(_cb);

        UnsafeBufferUtil.BlockCopy(from: this, to: duplicateHandle, length: _cb);
        return(duplicateHandle);
    }
Ejemplo n.º 4
0
        private static SecureLocalAllocHandle Protect(byte *pbPlaintext, uint cbPlaintext)
        {
            // If we're not running on a platform that supports CryptProtectMemory,
            // shove the plaintext directly into a LocalAlloc handle. Ideally we'd
            // mark this memory page as non-pageable, but this is fraught with peril.
            if (!OSVersionUtil.IsWindows())
            {
                SecureLocalAllocHandle handle = SecureLocalAllocHandle.Allocate((IntPtr) checked ((int)cbPlaintext));
                UnsafeBufferUtil.BlockCopy(from: pbPlaintext, to: handle, byteCount: cbPlaintext);
                return(handle);
            }

            // We need to make sure we're a multiple of CRYPTPROTECTMEMORY_BLOCK_SIZE.
            uint numTotalBytesToAllocate = cbPlaintext;
            uint numBytesPaddingRequired = CRYPTPROTECTMEMORY_BLOCK_SIZE - (numTotalBytesToAllocate % CRYPTPROTECTMEMORY_BLOCK_SIZE);

            if (numBytesPaddingRequired == CRYPTPROTECTMEMORY_BLOCK_SIZE)
            {
                numBytesPaddingRequired = 0; // we're already a proper multiple of the block size
            }
            checked { numTotalBytesToAllocate += numBytesPaddingRequired; }
            CryptoUtil.Assert(numTotalBytesToAllocate % CRYPTPROTECTMEMORY_BLOCK_SIZE == 0, "numTotalBytesToAllocate % CRYPTPROTECTMEMORY_BLOCK_SIZE == 0");

            // Allocate and copy plaintext data; padding is uninitialized / undefined.
            SecureLocalAllocHandle encryptedMemoryHandle = SecureLocalAllocHandle.Allocate((IntPtr)numTotalBytesToAllocate);

            UnsafeBufferUtil.BlockCopy(from: pbPlaintext, to: encryptedMemoryHandle, byteCount: cbPlaintext);

            // Finally, CryptProtectMemory the whole mess.
            if (numTotalBytesToAllocate != 0)
            {
                MemoryProtection.CryptProtectMemory(encryptedMemoryHandle, byteCount: numTotalBytesToAllocate);
            }
            return(encryptedMemoryHandle);
        }
Ejemplo n.º 5
0
    /// <summary>
    /// Allocates some amount of memory using LocalAlloc.
    /// </summary>
    public static SecureLocalAllocHandle Allocate(IntPtr cb)
    {
        SecureLocalAllocHandle newHandle = new SecureLocalAllocHandle(cb);

        newHandle.AllocateImpl(cb);
        return(newHandle);
    }
        public ProtectedMemoryBlob(ArraySegment <byte> plaintext)
        {
            plaintext.Validate();

            _localAllocHandle = Protect(plaintext);
            _plaintextLength  = (uint)plaintext.Count;
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Creates a new Secret from the provided input value, where the input value
        /// is specified as a pointer to unmanaged memory.
        /// </summary>
        public Secret(byte *secret, int secretLength)
        {
            if (secret == null)
            {
                throw new ArgumentNullException(nameof(secret));
            }
            if (secretLength < 0)
            {
                throw Error.Common_ValueMustBeNonNegative(nameof(secretLength));
            }

            _localAllocHandle = Protect(secret, (uint)secretLength);
            _plaintextLength  = (uint)secretLength;
        }
        public ProtectedMemoryBlob(byte *plaintext, int plaintextLength)
        {
            if (plaintext == null)
            {
                throw new ArgumentNullException("plaintext");
            }
            if (plaintextLength < 0)
            {
                throw new ArgumentOutOfRangeException("plaintextLength");
            }

            _localAllocHandle = Protect(plaintext, (uint)plaintextLength);
            _plaintextLength  = (uint)plaintextLength;
        }
Ejemplo n.º 9
0
    public void Duplicate_Copies_Data()
    {
        // Arrange
        const string expected      = "xyz";
        int          cbExpected    = expected.Length * sizeof(char);
        var          controlHandle = SecureLocalAllocHandle.Allocate((IntPtr)cbExpected);

        for (int i = 0; i < expected.Length; i++)
        {
            ((char *)controlHandle.DangerousGetHandle())[i] = expected[i];
        }

        // Act
        var duplicateHandle = controlHandle.Duplicate();

        // Assert
        Assert.Equal(expected, new string((char *)duplicateHandle.DangerousGetHandle(), 0, expected.Length)); // contents the same data
        Assert.NotEqual(controlHandle.DangerousGetHandle(), duplicateHandle.DangerousGetHandle());            // shouldn't just point to the same memory location
    }
Ejemplo n.º 10
0
 private static LocalAllocHandle LocalAlloc(int cb)
 {
     return(SecureLocalAllocHandle.Allocate((IntPtr)cb));
 }