Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / ManagedLibraries / Security / System / Security / Cryptography / DataProtection.cs / 1305376 / DataProtection.cs
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// [....]
//
//
// DataProtection.cs
//
// 01/25/2003
//
namespace System.Security.Cryptography
{
using Microsoft.Win32;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.ConstrainedExecution;
using System.Security.Permissions;
using System.Globalization;
public enum DataProtectionScope {
CurrentUser = 0x00,
LocalMachine = 0x01
}
public enum MemoryProtectionScope {
SameProcess = 0x00,
CrossProcess = 0x01,
SameLogon = 0x02
}
[System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
public static class ProtectedData {
[SecuritySafeCritical]
public static byte[] Protect (byte[] userData,
byte[] optionalEntropy,
DataProtectionScope scope) {
if (userData == null)
throw new ArgumentNullException("userData");
if (Environment.OSVersion.Platform == PlatformID.Win32Windows)
throw new NotSupportedException(SecurityResources.GetResourceString("NotSupported_PlatformRequiresNT"));
GCHandle pbDataIn = new GCHandle();
GCHandle pOptionalEntropy = new GCHandle();
CAPI.CRYPTOAPI_BLOB blob = new CAPI.CRYPTOAPI_BLOB();
RuntimeHelpers.PrepareConstrainedRegions();
try {
pbDataIn = GCHandle.Alloc(userData, GCHandleType.Pinned);
CAPI.CRYPTOAPI_BLOB dataIn = new CAPI.CRYPTOAPI_BLOB();
dataIn.cbData = (uint) userData.Length;
dataIn.pbData = pbDataIn.AddrOfPinnedObject();
CAPI.CRYPTOAPI_BLOB entropy = new CAPI.CRYPTOAPI_BLOB();
if (optionalEntropy != null) {
pOptionalEntropy = GCHandle.Alloc(optionalEntropy, GCHandleType.Pinned);
entropy.cbData = (uint) optionalEntropy.Length;
entropy.pbData = pOptionalEntropy.AddrOfPinnedObject();
}
uint dwFlags = CAPI.CRYPTPROTECT_UI_FORBIDDEN;
if (scope == DataProtectionScope.LocalMachine)
dwFlags |= CAPI.CRYPTPROTECT_LOCAL_MACHINE;
unsafe {
if (!CAPI.CryptProtectData(new IntPtr(&dataIn),
String.Empty,
new IntPtr(&entropy),
IntPtr.Zero,
IntPtr.Zero,
dwFlags,
new IntPtr(&blob))) {
int lastWin32Error = Marshal.GetLastWin32Error();
// One of the most common reasons that DPAPI operations fail is that the user
// profile is not loaded (for instance in the case of impersonation or running in a
// service. In those cases, throw an exception that provides more specific details
// about what happened.
if (CAPI.ErrorMayBeCausedByUnloadedProfile(lastWin32Error)) {
throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_DpApi_ProfileMayNotBeLoaded"));
}
else {
throw new CryptographicException(lastWin32Error);
}
}
}
// In some cases, the API would fail due to OOM but simply return a null pointer.
if (blob.pbData == IntPtr.Zero)
throw new OutOfMemoryException();
byte[] encryptedData = new byte[(int) blob.cbData];
Marshal.Copy(blob.pbData, encryptedData, 0, encryptedData.Length);
return encryptedData;
}
catch (EntryPointNotFoundException) {
throw new NotSupportedException(SecurityResources.GetResourceString("NotSupported_PlatformRequiresNT"));
}
finally {
if (pbDataIn.IsAllocated)
pbDataIn.Free();
if (pOptionalEntropy.IsAllocated)
pOptionalEntropy.Free();
if (blob.pbData != IntPtr.Zero) {
CAPI.CAPISafe.ZeroMemory(blob.pbData, blob.cbData);
CAPI.CAPISafe.LocalFree(blob.pbData);
}
}
}
[SecuritySafeCritical]
public static byte[] Unprotect (byte[] encryptedData,
byte[] optionalEntropy,
DataProtectionScope scope) {
if (encryptedData == null)
throw new ArgumentNullException("encryptedData");
if (Environment.OSVersion.Platform == PlatformID.Win32Windows)
throw new NotSupportedException(SecurityResources.GetResourceString("NotSupported_PlatformRequiresNT"));
GCHandle pbDataIn = new GCHandle();
GCHandle pOptionalEntropy = new GCHandle();
CAPI.CRYPTOAPI_BLOB userData = new CAPI.CRYPTOAPI_BLOB();
RuntimeHelpers.PrepareConstrainedRegions();
try {
pbDataIn = GCHandle.Alloc(encryptedData, GCHandleType.Pinned);
CAPI.CRYPTOAPI_BLOB dataIn = new CAPI.CRYPTOAPI_BLOB();
dataIn.cbData = (uint) encryptedData.Length;
dataIn.pbData = pbDataIn.AddrOfPinnedObject();
CAPI.CRYPTOAPI_BLOB entropy = new CAPI.CRYPTOAPI_BLOB();
if (optionalEntropy != null) {
pOptionalEntropy = GCHandle.Alloc(optionalEntropy, GCHandleType.Pinned);
entropy.cbData = (uint) optionalEntropy.Length;
entropy.pbData = pOptionalEntropy.AddrOfPinnedObject();
}
uint dwFlags = CAPI.CRYPTPROTECT_UI_FORBIDDEN;
if (scope == DataProtectionScope.LocalMachine)
dwFlags |= CAPI.CRYPTPROTECT_LOCAL_MACHINE;
unsafe {
if (!CAPI.CryptUnprotectData(new IntPtr(&dataIn),
IntPtr.Zero,
new IntPtr(&entropy),
IntPtr.Zero,
IntPtr.Zero,
dwFlags,
new IntPtr(&userData)))
throw new CryptographicException(Marshal.GetLastWin32Error());
}
// In some cases, the API would fail due to OOM but simply return a null pointer.
if (userData.pbData == IntPtr.Zero)
throw new OutOfMemoryException();
byte[] data = new byte[(int) userData.cbData];
Marshal.Copy(userData.pbData, data, 0, data.Length);
return data;
}
catch (EntryPointNotFoundException) {
throw new NotSupportedException(SecurityResources.GetResourceString("NotSupported_PlatformRequiresNT"));
}
finally {
if (pbDataIn.IsAllocated)
pbDataIn.Free();
if (pOptionalEntropy.IsAllocated)
pOptionalEntropy.Free();
if (userData.pbData != IntPtr.Zero) {
CAPI.CAPISafe.ZeroMemory(userData.pbData, userData.cbData);
CAPI.CAPISafe.LocalFree(userData.pbData);
}
}
}
}
[System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
public static class ProtectedMemory {
[SecuritySafeCritical]
public static void Protect (byte[] userData,
MemoryProtectionScope scope) {
if (userData == null)
throw new ArgumentNullException("userData");
if (Environment.OSVersion.Platform == PlatformID.Win32Windows)
throw new NotSupportedException(SecurityResources.GetResourceString("NotSupported_PlatformRequiresNT"));
VerifyScope(scope);
// The RtlEncryptMemory and RtlDecryptMemory functions are available on WinXP and publicly published
// in the ntsecapi.h header file as of Windows Server 2003.
// The Rtl functions accept data in 8 byte increments, but we don't want applications to be able to make use of this,
// or else they're liable to break when the user upgrades.
if ((userData.Length == 0) || (userData.Length % CAPI.CRYPTPROTECTMEMORY_BLOCK_SIZE != 0))
throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_DpApi_InvalidMemoryLength"));
uint dwFlags = (uint) scope;
try {
// RtlEncryptMemory return an NTSTATUS
int status = CAPI.SystemFunction040(userData,
(uint) userData.Length,
dwFlags);
if (status < 0) // non-negative numbers indicate success
throw new CryptographicException(CAPI.CAPISafe.LsaNtStatusToWinError(status));
}
catch (EntryPointNotFoundException) {
throw new NotSupportedException(SecurityResources.GetResourceString("NotSupported_PlatformRequiresNT"));
}
}
[SecuritySafeCritical]
public static void Unprotect (byte[] encryptedData,
MemoryProtectionScope scope) {
if (encryptedData == null)
throw new ArgumentNullException("encryptedData");
if (Environment.OSVersion.Platform == PlatformID.Win32Windows)
throw new NotSupportedException(SecurityResources.GetResourceString("NotSupported_PlatformRequiresNT"));
VerifyScope(scope);
// The RtlEncryptMemory and RtlDecryptMemory functions are available on WinXP and publicly published
// in the ntsecapi.h header file as of Windows Server 2003.
// The Rtl functions accept data in 8 byte increments, but we don't want applications to be able to make use of this,
// or else they're liable to break when the user upgrades.
if ((encryptedData.Length == 0) || (encryptedData.Length % CAPI.CRYPTPROTECTMEMORY_BLOCK_SIZE != 0))
throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_DpApi_InvalidMemoryLength"));
uint dwFlags = (uint) scope;
try {
// RtlDecryptMemory return an NTSTATUS
int status = CAPI.SystemFunction041(encryptedData,
(uint) encryptedData.Length,
dwFlags);
if (status < 0) // non-negative numbers indicate success
throw new CryptographicException(CAPI.CAPISafe.LsaNtStatusToWinError(status));
}
catch (EntryPointNotFoundException) {
throw new NotSupportedException(SecurityResources.GetResourceString("NotSupported_PlatformRequiresNT"));
}
}
private static void VerifyScope (MemoryProtectionScope scope) {
if ((scope != MemoryProtectionScope.SameProcess) && (scope != MemoryProtectionScope.CrossProcess) &&
(scope != MemoryProtectionScope.SameLogon))
throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, SecurityResources.GetResourceString("Arg_EnumIllegalVal"), (int) scope));
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- BuildProvider.cs
- MaskedTextBoxDesignerActionList.cs
- GeneralTransform3DCollection.cs
- ResourceAttributes.cs
- DesignerSerializerAttribute.cs
- CreateUserWizard.cs
- ProjectedWrapper.cs
- BitmapPalette.cs
- RealizationDrawingContextWalker.cs
- XhtmlStyleClass.cs
- EntityCommandExecutionException.cs
- FunctionMappingTranslator.cs
- UTF7Encoding.cs
- WebPartConnectionsCancelVerb.cs
- Transactions.cs
- SoapFault.cs
- DragDropHelper.cs
- AdRotator.cs
- XamlTypeMapper.cs
- FieldAccessException.cs
- SelectionProcessor.cs
- TypeElement.cs
- MSAAWinEventWrap.cs
- ContentType.cs
- RijndaelManaged.cs
- NetworkStream.cs
- FilteredSchemaElementLookUpTable.cs
- AmbientValueAttribute.cs
- AttributeQuery.cs
- CharacterHit.cs
- RTLAwareMessageBox.cs
- AnimationException.cs
- counter.cs
- ExitEventArgs.cs
- QilChoice.cs
- SettingsPropertyCollection.cs
- XPathArrayIterator.cs
- PropertyTab.cs
- WebPartEditorCancelVerb.cs
- SmtpSpecifiedPickupDirectoryElement.cs
- ProtectedProviderSettings.cs
- CrossSiteScriptingValidation.cs
- SelectedCellsChangedEventArgs.cs
- HotCommands.cs
- WinEventQueueItem.cs
- PatternMatcher.cs
- OleStrCAMarshaler.cs
- BitmapCacheBrush.cs
- WebServiceHostFactory.cs
- MultiAsyncResult.cs
- DependencySource.cs
- StaticResourceExtension.cs
- documentsequencetextcontainer.cs
- XmlSignatureProperties.cs
- PrimaryKeyTypeConverter.cs
- QilNode.cs
- ValidationEventArgs.cs
- MsmqBindingElementBase.cs
- XhtmlTextWriter.cs
- XmlSchemaComplexContentRestriction.cs
- NotFiniteNumberException.cs
- BulletedListEventArgs.cs
- CodePropertyReferenceExpression.cs
- SignatureDescription.cs
- XmlSubtreeReader.cs
- X509CertificateClaimSet.cs
- LayoutEvent.cs
- TextTreeInsertUndoUnit.cs
- TextSchema.cs
- IIS7WorkerRequest.cs
- DateRangeEvent.cs
- DataGridItem.cs
- GeneralTransform3DCollection.cs
- CollaborationHelperFunctions.cs
- TabRenderer.cs
- ActiveXHost.cs
- DivideByZeroException.cs
- TaskForm.cs
- BasicDesignerLoader.cs
- BindingSource.cs
- TransformerTypeCollection.cs
- DataRowComparer.cs
- CompilerErrorCollection.cs
- XmlSiteMapProvider.cs
- SafeArrayTypeMismatchException.cs
- SrgsElement.cs
- XPathAncestorIterator.cs
- DebugHandleTracker.cs
- BufferAllocator.cs
- VirtualPath.cs
- DefaultMemberAttribute.cs
- ContentDisposition.cs
- ImageKeyConverter.cs
- PresentationSource.cs
- StateMachineWorkflowDesigner.cs
- SessionPageStatePersister.cs
- OracleRowUpdatedEventArgs.cs
- SqlDataSourceView.cs
- basecomparevalidator.cs
- OdbcEnvironment.cs