State Street Gang
.NET, straight up

Sysinternals File Share

May 30, 2008 16:37 by will

Just a quick note... If you don't use Sysinternals tools, you must not be programming anything important.  Its the be-all, end-all of windoze troubleshooting tools. 

But sometimes getting those tools where you need them is inconvenient.  For instance, say you need to use Process Monitor to figure out why your ASP.NET website is bombing out during the compilation phase on a production server.  The error logs won't help you; all you get is a FNF without the filename that wasn't found in the error message (thanks, framework guys!).

You're connected to the server over an RDP.  How do you get procmon on the server?  You can Google the addy for Sysinternals and then click through a few pages to download it.  Of course, you'll have to specifically allow every page you have to click through due to the extended security on the 2k3 box.  Or you might find port 80 is blocked completely by the client's corporate firewall. 

You could then try to copy it over the RDP... OOPS!  You forgot to set up disk and desktop sharing.  Or maybe you're bandwidth to the server is a 1/2 inch diameter pipe due to some stringent QoS settings.

Well, the Sysinternals guys just made it a whole lot easier.  They set up a network share on the internets.

\\live.sysinternals.com\tools

You can open it up in any Explorer window like any other network share, as long as you can get to the internet.  You can download the apps directly by copying them, or just run them over the share.  For example, open a cmd window and run Filemon directly:

\\live.sysinternals.com\tools\filemon.exe

Its just that bad-ass.

kick it on DotNetKicks.com
Tags:
Categories: Debug | Tips
Actions: E-mail | Permalink | Comments (8) | Comment RSSRSS comment feed

Safest Way to Get the Cache Object

May 20, 2008 11:23 by will

This is one of those "I keep forgetting this so I'd better put it in a blog post" blog posts. 

We've all seen this:

object bar = HttpContext.Current.Cache["foo"];

And we've all had null reference exceptions thrown because of it.  Usually, we duct tape it back together with the pitiful:

if (HttpContext.Current == null)
    throw new InvalidOperationException
        ("Lol you're screwed");
object bar = HttpContext.Current.Cache["foo"];

Or we add on more logic to return a non-offensive result that is incorrect, but since there is no current context (usually happens when the web server is recycling), what do we care? 

There is a better way.  One where you will always get the cache, and it will never be null:

object bar = HttpRuntime.Cache["foo"];

No matter what's going on, the HttpRuntime's cache property will never be null.  And it's the same object as that in HttpContext.Current.  If you don't believe me, just slap the following in any ASP.NET page:

Assert.IsTrue(object.Equals(HttpContext.Current.Cache,HttpRuntime.Cache);

Tags:
Categories: ASP.NET | Tips
Actions: E-mail | Permalink | Comments (1) | Comment RSSRSS comment feed

WiX 3.0 Hates Subfolders in VS 2008 Projects

May 19, 2008 16:07 by will

First time using the WiX install project in VS 2008 for me, and its been interesting.  I like it over all, but I do miss the automation of the standard Visual Studio installer project.

I did run into an aggravating issue that I managed to figure out a solution for.  I present it here for your edification.

E_FAIL == Epic Fail?

After working hard at getting my WiX project to successfully install a simple website, I was feeling pretty good about it.  But the next time I loaded up Visual Studio and opened my solution, I got the following error:

Error HRESULT E_FAIL has been returned from a call to a COM component.

That was helpful.  After Ok-ing the dialog away, I saw that my WiX project was grayed out and marked unavailable.  Super.  I tried a number of different things:

More...

Tags:
Categories: Tips | WPF
Actions: E-mail | Permalink | Comments (3) | Comment RSSRSS comment feed

A .NET Cryptography Primer, Part Four

May 7, 2008 13:35 by Will

(You can find the previous parts here:  part 1 (background), part 2 (hashes), and part 3 (Symmetric encryption))

Background

This last part in this primer series covers asymmetric encryption, also known as public/private key encryption.  A "public" key, freely distributed, is paired with a "private" key, which is kept secret.  The public key is used to encrypt messages that, without massive computational power, only the paired private key can decrypt.  This is only secure one way--from public key to private key--so two-way encrypted communications usually involve both sender and receiver exchanging public keys in order to encrypt transmissions both ways.

Shared secret (symmetric) encryption is vulnerable to eavesdroppers, decompilers and those with sufficient computational power, each of whom have a relatively simple path to discovering what that secret is.  If that shared secret is sniffed as it is transmitted over the network, or recovered from source code, or cracked using a rainbow table, your data is now open to everyone.  Asymmetric cryptography allows for the easy storage and transmission of the public key without fear of it falling into the wrong hands, as determining the private key is practically impossible.  I'm no expert, but I believe if you started to brute-force crack a 4096 bit key today, you'd finish roughly five seconds after the universe collapses back into a singularity.

Another common use for asymmetric algorithms is to generate signatures.  This is useful for ensuring that data transmitted in cleartext isn't tampered with.  For a given message, you can use your private key to generate a signature.  This is transmitted in cleartext along with the message.  On the receiving end, you can use the public key to verify that the signature was generated by the private key and that it matches the set of bytes.  This ensures that the message is from a trusted source (the owner of the private key) and that the message hasn't been tampered with in a "man in the middle" style attack. 

Implementations

There are two different types of asymmetric algorithms available to .NET coders.  They are RSA and DSA (Digital Signature Algorithm).  Without going into details, the algorithms are essentially the same.  The difference is that DSA can only be used to generate signatures and is legal to export, whereas RSA can be used to perform encryption as well and cannot be legally exported to some countries.  Of course, that is a huge over-generalization; if you're interested in learning more you can always Google it.  For my examples, I'll be using RSA as it can do both and is more commonly used.

Like other cryptographic algorithms in the .NET framework, the RSA implementation is implemented as a provider, the RSACryptoServiceProvider, which extends an abstract base class for all algorithms of this type:  System.Security.Cryptography.RSA.  By using the static Create() method on this base class, you can get the default or a specifically named implementation of the provider.  In my examples I'll be new-ing up instances, as the constructor for the RSACryptoServiceProvider takes a CspParameters object that can be used to configure the provider.  For more information on the different types of RSA CSPs available for Microsoft developers and how to specify which to use, go here.

A word or two thousand about Key Containers

The security of asymmetric algorithms depends on the private key remaining private.  Imagine a software product that uses RSA signatures for a license key.  You compile the public key into the software and use it to verify licenses.  The company generates these a license by taking the "Licensed to" information from a user and generating a signature.  If the private key is stolen or lost, every boxed copy of the software is now trash.  The source code has to be recompiled with a new public key.  And the next software update will require users to re-register their copies of the software.  This is commonly known as "a nightmare."

Unlike shared secret keys (aka passwords), public/private key pairs are complex structures that cannot be memorized.  Because of this, Microsoft stores these keys in what is called a "Key Container".  This is implemented as a file on the hard drive and is secured by ACLs.  Key Containers can be scoped to the machine (look in Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\ MachineKeys) or to the user (Documents and Settings\[USER ACCOUNT]\Application Data\Microsoft\Crypto\RSA).  Machine level keys are accessible by the system and those with configured access rights (by default the principal that created them).  User-scoped containers are, oddly enough, accessible by the system, the user that created them, AND administrators.  Because of this, they can optionally be encrypted with a password.  Another important aspect about user-scoped key containers is that they are stored within the user's profile, which means they are lost when the user account is deleted.  You can have more than one key container of either type, each being identified by its name.

User-scoped Key Containers

User scoped key containers, by default, are only available to the system, admins, and the user that created them.  You can also configure the provider to allow users to apply a password to the container to make them more secure.  I'll be using the machine store for simplicity later, but to scope the container to the user is simple:

// create a configuration object for the provider
CspParameters parms = new CspParameters();
// set the flag to use a user protected key
parms.Flags = CspProviderFlags.UseUserProtectedKey;
// name the key container 
parms.KeyContainerName = "foo";
// Instantiate the provider
RSACryptoServiceProvider rsa 
    = new RSACryptoServiceProvider(parms);

The provider creates a new public/private key pair for you the first time you try to do something that requires it (encrypt, sign, export).  When a new key is created, a dialog is presented to the user that allows the user to set the security level of the key container to high and apply a password to it.  The user can set the security level to High to password protect the key pair.

Initial dialog Set Security Level dialog Create Password Dialog

From this point on, any operation that attempts to access this key will result in a dialog being shown requesting the user's password:

Enter Password Dialog

I'll refrain from the obvious statement of how this could easily be spoofed by a malicious application on the user's system.  If you are thinking about using this as an additional security layer, I'd suggest looking into using the KeyPassword property of the CspParameters object to set this password from within your application's UI.

Creating the RSA Provider

This method shows how to create the default implementation of the RSA crypto provider that uses the machine key store.  If containerName is new, a new key pair is created prior to using or accessing it.  Every example from here on will use this method to create the provider.

private RSACryptoServiceProvider CreateRSA(
    string containerName)
{
    CspParameters parms = new CspParameters();
    parms.KeyContainerName = containerName;
    RSACryptoServiceProvider rsa = 
        new RSACryptoServiceProvider(parms);
    return rsa;
}

Deleting a key from a Key Container

Deleting a key from a key container is a little tricky, as the actual deletion takes place in the set method of the PersistKeyInCsp property, which isn't intuitive.

private void DeleteKeyInContainer
    (string containerName)
{
    // get a provider configured to the container
    RSACryptoServiceProvider rcsp = 
        CreateRSA(containerName);
    // Deletes the key entry from the container
    rcsp.PersistKeyInCsp = false;
    // clears the key from the provider
    rcsp.Clear();
}

Importing and exporting keys

Key pairs can be imported and exported from a key container.  A key pair is actually a complex structure containing the different components the algorithm needs.  This can be exported as a blob (compatible with unmanaged implementations), as an XML string, and as a strut (RSAParameters):

private void ExportImportKeys(string containerName)
{
    // get a provider configured to the container
    RSACryptoServiceProvider rcsp = 
        CreateRSA(containerName);
    // export the key pair 3 different ways
    byte[] keyBlob = rcsp.ExportCspBlob(true);
    string keyXml = rcsp.ToXmlString(true);
    RSAParameters keyParms = 
        rcsp.ExportParameters(true);
    // and import them back in
    rcsp.ImportCspBlob(keyBlob);
    rcsp.FromXmlString(keyXml);
    rcsp.ImportParameters(keyParms);
}

In these export methods, you must pass in a boolean that indicates whether you wish to export the private key as well as the public key (true to export both).  Note that when you bring a private key out of the Key Container you are greatly reducing the security of your application.  If you intend to distribute the public key, you will have to call one of these methods passing in false.  You do not have to use a different import method when importing a public key. 

Encryption and decryption

Remember, you must encrypt with the public key, and decrypt with the private key.  This seems a little backwards, but it is how the algorithm works.  The following code creates an encryptor and decryptor pointing to different key containers (I use a randomly generated Guid for the name).  The public key is extracted from the decryptor and loaded into the encryptor, and a byte array is encrypted and decrypted.  The code after the CollectionAssert demonstrates that a public key cannot be used to decrypt.

// create an encryptor and decryptor
RSACryptoServiceProvider decryptor = 
    CreateRSA(Guid.NewGuid().ToString());
RSACryptoServiceProvider encryptor = 
    CreateRSA(Guid.NewGuid().ToString());
 
// Export the public key from the decryptor
string key = decryptor.ToXmlString(false);
 
// Load the public key into the encryptor
encryptor.FromXmlString(key);
 
byte[] expected = new byte[] { 1, 2, 3 };
 
// encrypt with the public key
byte[] encrypted = encryptor.Encrypt(
    expected, true);
 
// decrypt with the private key
byte[] decrypted = decryptor.Decrypt(
    encrypted, true);
 
CollectionAssert.AreEqual(expected,decrypted);
 
// the following will fail
encryptor.Decrypt(encrypted, true);

Creating and Verifying Signatures

A signature is a cryptographic hash created by a private key that can be verified by its public key.  The public key can be compiled into code and be used to verify signatures that are generated by, say, a trusted employee at your company.  The following code demonstrates generating a signature and verifying it.  The private key is used to generate the signature and the public key is used to verify it.  The last line demonstrates that the public key cannot be used to generate a new license for the tampered data.

RSACryptoServiceProvider signer = 
    CreateRSA(Guid.NewGuid().ToString());
RSACryptoServiceProvider verifier = 
    CreateRSA(Guid.NewGuid().ToString());
 
// Export the public key from the signer
string publicKey = signer.ToXmlString(false);
 
// Load the public key into the verifier
verifier.FromXmlString(publicKey);
 
byte[] rawData = new byte[] { 1, 2, 3 };
 
// encrypt with the public key
byte[] signature = signer.SignData(
    rawData, "SHA1");
 
bool untampered = verifier.VerifyData(
    rawData, "SHA1", signature);
 
// Tamper!
rawData[2] = 4;
 
bool tampered = verifier.VerifyData(
    rawData, "SHA1", signature);
 
Assert.IsTrue(untampered);
Assert.IsFalse(tampered);
 
// the following will fail
signature = verifier.SignData(
    rawData, "SHA1");

Summary

Asymmetric cryptography is used to encrypt and sign data without having to rely on an insecure shared secret.  Key pairs are stored in a Key Container (a file on the hard drive) that can be scoped to the machine or to a specific user.  User-scoped containers can be secured using a password.  The public key is used to encrypt data and verify signatures.  The private key is used to decrypt data and generate signatures

Whew!  That was a long one.  I've learned a bunch writing these four parts, including how much more I don't know about the process.  I would have liked to go into more details about some of the aspects of cryptography on the .NET platform, but the more I say the more I risk being wrong. 

Most likely, if you're reading this, you care about security.  Don't just stop here; if you need cryptography in your program, you need to keep learning.  If you use it and you don't thoroughly understand it, you're probably doing it wrong.  And this is one area where you have to do it right.

kick it on DotNetKicks.com
Tags:
Categories: Cryptography | Security | Tips
Actions: E-mail | Permalink | Comments (4) | Comment RSSRSS comment feed

Scroll Selected Text Into View in WPF

May 2, 2008 17:08 by Will

(Illness and work has been kicking my ass for the past couple weeks; I'm posting a quick how-to so my parents don't worry.  I'll be finishing up the crypto series next week, I swear!)

I've been doing lots of work in WPF over the last few weeks, getting familiar with xaml for a major project at work (xaml templating and XPS documents, cool stuff).  Getting to re-know standard windows forms controls in their new WPF flavors has been interesting.  Every once in awhile you come on an issue that takes a while to figure out.

One of those I just encountered was getting the WPF version of the TextBox to scroll a particular chunk of text into view.  Here's the scenario:

  • Text is pasted into a multiline TextBox without wrapping that overflows the available visual space
  • Both horizontal and vertical scrollbars appear
  • In code, a word is selected.  That word happens to be outside the visible area of the TextBox.

In this situation, the question becomes how to scroll this selected text into view via code so the user can see the selected text.

The standard methods don't work.  The obvious methods for scrolling (I'll skip them for brevity's sake) only scroll the TextBox vertically, or take a value that cannot easily and reliably be determined from the available information. 

The solution is to use the BringIntoView method.  The problem is that this method is designed to communicate to an owning ScrollView in order to tell it to scroll.  If you call this on the TextBox and the TextBox is using an internal ScrollView, the method fails to work.

You must turn off your TextBox' scrolling and place the TextBox into a ScrollView.  Here's the xaml:

<Border
  DockPanel.Dock="Top"
  BorderBrush="Gray"
  BorderThickness="1">
  <ScrollViewer
   VerticalScrollBarVisibility="Auto"
   HorizontalScrollBarVisibility="Auto">
    <TextBox
     BorderThickness="0"
     Name="_inputString"
     AcceptsReturn="True"
     TextWrapping="NoWrap"
     GotMouseCapture="TextBox_GotFocus"
     Text="{Binding Path=InputString, 
        UpdateSourceTrigger=PropertyChanged}">
    </TextBox>
  </ScrollViewer>
</Border>

Notice the Border; the ScrollView doesn't display a border, so you have to create one and turn off the TextBox' so it doesn't look weird.  Here's the codebehind:

_inputString.Select(m.Index, m.Length);
Rect start = _inputString
  .GetRectFromCharacterIndex(m.Index, true);
Rect end = _inputString
  .GetRectFromCharacterIndex
    (m.Index + m.Length, true);
_inputString.BringIntoView(Rect.Union(start, end));
_inputString.Focus();

The m object in this case is actually a Regex Match object and _inputString is the TextBox; the code is from a databound wpf regex tool I'm working on.  I can select text using the start index of the text and the length of the selection.

The BringIntoView method takes a Rect struct.  The GetRectFromCharacterIndex method returns a Rect that covers an individual character of the text; we want to bring the whole selection into view so we need the union of the Rect from the first and last characters of the selection.

Its a little sloppy.  I haven't done much testing on this; guaranteed that if the first character Rect is on line 278 and the last is on line 279 something odd might happen, but it does work.

Update

Adding this to the scrolling code allows you to scroll to the first half of the text if the selection contains a newline:

if (_inputString.SelectedText.Contains(Environment.NewLine))
{
    string selected = _inputString.SelectedText;
    int length = selected.IndexOf(Environment.NewLine);
    end = _inputString.GetRectFromCharacterIndex
        (m.Index + length, true);
}
else
{
    end = _inputString.GetRectFromCharacterIndex
        (m.Index + m.Length, true);
}
kick it on DotNetKicks.com
Tags:
Categories: Tips | WPF
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed