/// <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 SecureLocalAllocHandle Duplicate() { SecureLocalAllocHandle duplicateHandle = Allocate(_cb); UnsafeBufferUtil.BlockCopy(from: this, to: duplicateHandle, length: _cb); return(duplicateHandle); }
/// <summary> /// Creates a new Secret from another secret object. /// </summary> public Secret([NotNull] ISecret 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); } } } }
/// <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; }
/// <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 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 }
/// <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; }