Jan 15, 2013

Https explained

(http://www.moserware.com/2009/06/first-few-milliseconds-of-https.html)

The First Few Milliseconds of an HTTPS Connection

Convinced from spending hours reading rave reviews, Bob eagerly clicked "Proceed to Checkout" for his gallon of Tuscan Whole Milk and...
Whoa! What just happened?

In the 220 milliseconds that flew by, a lot of interesting stuff happened to make Firefox change the address bar color and put a lock in the lower right corner. With the help of Wireshark, my favorite network tool, and a slightly modified debug build of Firefox, we can see exactly what's going on.
By agreement of RFC 2818, Firefox knew that "https" meant it should connect to port 443 at Amazon.com:

Most people associate HTTPS with SSL (Secure Sockets Layer) which was created by Netscape in the mid 90's. This is becoming less true over time. As Netscape lost market share, SSL's maintenance moved to the Internet Engineering Task Force (IETF). The first post-Netscape version was re-branded as Transport Layer Security (TLS) 1.0 which was released in January 1999. It's rare to see true "SSL" traffic given that TLS has been around for 10 years.

Client Hello

TLS wraps all traffic in "records" of different types. We see that the first byte out of our browser is the hex byte 0x16 = 22 which means that this is a "handshake" record:

The next two bytes are 0x0301 which indicate that this is a version 3.1 record which shows that TLS 1.0 is essentially SSL 3.1.
The handshake record is broken out into several messages. The first is our "Client Hello" message (0x01). There are a few important things here:

  • Random:


    There are four bytes representing the current Coordinated Universal Time (UTC) in the Unix epoch format, which is the number of seconds since January 1, 1970. In this case, 0x4a2f07ca. It's followed by 28 random bytes. This will be used later on.
  • Session ID:


    Here it's empty/null. If we had previously connected to Amazon.com a few seconds ago, we could potentially resume a session and avoid a full handshake.
  • Cipher Suites:


    This is a list of all of the encryption algorithms that the browser is willing to support. Its top pick is a very strong choice of "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA" followed by 33 others that it's willing to accept. Don't worry if none of that makes sense. We'll find out later that Amazon doesn't pick our first choice anyway.
  • server_name extension:


    This is a way to tell Amazon.com that our browser is trying to reach https://www.amazon.com/. This is really convenient because our TLS handshake occurs long before any HTTP traffic. HTTP has a "Host" header which allows a cost-cutting Internet hosting companies to pile hundreds of websites onto a single IP address. SSL has traditionally required a different IP for each site, but this extension allows the server to respond with the appropriate certificate that the browser is looking for. If nothing else, this extension should allow an extra week or so of IPv4 addresses.

Server Hello

Amazon.com replies with a handshake record that's a massive two packets in size (2,551 bytes). The record has version bytes of 0x0301 meaning that Amazon agreed to our request to use TLS 1.0. This record has three sub-messages with some interesting data:
  1. "Server Hello" Message (2):

    • We get the server's four byte time Unix epoch time representation and its 28 random bytes that will be used later.
    • A 32 byte session ID in case we want to reconnect without a big handshake.
    • Of the 34 cipher suites we offered, Amazon picked "TLS_RSA_WITH_RC4_128_MD5" (0x0004). This means that it will use the "RSA" public key algorithm to verify certificate signatures and exchange keys, the RC4 encryption algorithm to encrypt data, and the MD5 hash function to verify the contents of messages. We'll cover these in depth later on. I personally think Amazon had selfish reasons for choosing this cipher suite. Of the ones on the list, it was the one that was least CPU intensive to use so that Amazon could crowd more connections onto each of their servers. A much less likely possibility is that they wanted to pay special tribute to Ron Rivest, who created all three of these algorithms.
  2. Certificate Message (11):


    • This message takes a whopping 2,464 bytes and is the certificate that the client can use to validate Amazon's. It isn't anything fancy. You can view most of its contents in your browser:

  3. "Server Hello Done" Message (14):


    • This is a zero byte message that tells the client that it's done with the "Hello" process and indicate that the server won't be asking the client for a certificate.

Checking out the Certificate

The browser has to figure out if it should trust Amazon.com. In this case, it's using certificates. It looks at Amazon's certificate and sees that the current time is between the "not before" time of August 26th, 2008 and before the "not after" time of August 27, 2009. It also checks to make sure that the certificate's public key is authorized for exchanging secret keys.
Why should we trust this certificate?
Attached to the certificate is a "signature" that is just a really long number in big-endian format:

Anyone could have sent us these bytes. Why should we trust this signature? To answer that question, need to make a speedy detour into mathemagic land:

Interlude: A Short, Not Too Scary, Guide to RSA

People sometimes wonder if math has any relevance to programming. Certificates give a very practical example of applied math. Amazon's certificate tells us that we should use the RSA algorithm to check the signature. RSA was created in the 1970's by MIT professors Ron *R*ivest, Adi *S*hamir, and Len *A*dleman who found a clever way to combine ideas spanning 2000 years of math development to come up with a beautifully simple algorithm:
You pick two huge prime numbers "p" and "q." Multiply them to get "n = p*q." Next, you pick a small public exponent "e" which is the "encryption exponent" and a specially crafted inverse of "e" called "d" as the "decryption exponent." You then make "n" and "e" public and keep "d" as secret as you possibly can and then throw away "p" and "q" (or keep them as secret as "d"). It's really important to remember that "e" and "d" are inverses of each other.
Now, if you have some message, you just need to interpret its bytes as a number "M." If you want to "encrypt" a message to create a "ciphertext", you'd calculate:
C ≡ Me (mod n)
This means that you multiply "M" by itself "e" times. The "mod n" means that we only take the remainder (e.g. "modulus") when dividing by "n." For example, 11 AM + 3 hours ≡ 2 (PM) (mod 12 hours). The recipient knows "d" which allows them to invert the message to recover the original message:
Cd ≡ (Me)d ≡ Me*d ≡ M1 ≡ M (mod n)
Just as interesting is that the person with "d" can "sign" a document by raising a message "M" to the "d" exponent:
Md ≡ S (mod n)
This works because "signer" makes public "S", "M", "e", and "n." Anyone can verify the signature "S" with a simple calculation:
Se ≡ (Md)e ≡ Md*e ≡ Me*d ≡ M1 ≡ M (mod n)
Public key cryptography algorithms like RSA are often called "asymmetric" algorithms because the encryption key (in our case, "e") is not equal to (e.g. "symmetric" with) the decryption key "d". Reducing everything "mod n" makes it impossible to use the easy techniques that we're used to such as normal logarithms. The magic of RSA works because you can calculate/encrypt C ≡ Me (mod n) very quickly, but it is really hard to calculate/decrypt Cd ≡ M (mod n) without knowing "d." As we saw earlier, "d" is derived from factoring "n" back to its "p" and "q", which is a tough problem.

Verifying Signatures

The big thing to keep in mind with RSA in the real world is that all of the numbers involved have to be big to make things really hard to break using the best algorithms that we have. How big? Amazon.com's certificate was "signed" by "VeriSign Class 3 Secure Server CA." From the certificate, we see that this VeriSign modulus "n" is 2048 bits long which has this 617 digit base-10 representation:
1890572922 9464742433 9498401781 6528521078 8629616064 3051642608 4317020197 7241822595 6075980039 8371048211 4887504542 4200635317 0422636532 2091550579 0341204005 1169453804 7325464426 0479594122 4167270607 6731441028 3698615569 9947933786 3789783838 5829991518 1037601365 0218058341 7944190228 0926880299 3425241541 4300090021 1055372661 2125414429 9349272172 5333752665 6605550620 5558450610 3253786958 8361121949 2417723618 5199653627 5260212221 0847786057 9342235500 9443918198 9038906234 1550747726 8041766919 1500918876 1961879460 3091993360 6376719337 6644159792 1249204891 7079005527 7689341573 9395596650 5484628101 0469658502 1566385762 0175231997 6268718746 7514321
(Good luck trying to find "p" and "q" from this "n" - if you could, you could generate real-looking VeriSign certificates.)
VeriSign's "e" is 2^16 + 1 = 65537. Of course, they keep their "d" value secret, probably on a safe hardware device protected by retinal scanners and armed guards. Before signing, VeriSign checked the validity of the contents that Amazon.com claimed on its certificate using a real-world "handshake" that involved looking at several of their business documents. Once VeriSign was satisfied with the documents, they used the SHA-1 hash algorithm to get a hash value of the certificate that had all the claims. In Wireshark, the full certificate shows up as the "signedCertificate" part:

It's sort of a misnomer since it actually means that those are the bytes that the signer is going to sign and not the bytes that already include a signature.
The actual signature, "S", is simply called "encrypted" in Wireshark. If we raise "S" to VeriSign's public "e" exponent of 65537 and then take the remainder when divided by the modulus "n", we get this "decrypted" signature hex value:

0001FFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFF00302130 0906052B0E03021A 05000414C19F8786 871775C60EFE0542 E4C2167C830539DB
Per the PKCS #1 v1.5 standard, the first byte is "00" and it "ensures that the encryption block, [when] converted to an integer, is less than the modulus." The second byte of "01" indicates that this is a private key operation (e.g. it's a signature). This is followed by a lot of "FF" bytes that are used to pad the result to make sure that it's big enough. The padding is terminated by a "00" byte. It's followed by "30 21 30 09 06 05 2B 0E 03 02 1A 05 00 04 14" which is the PKCS #1 v2.1 way of specifying the SHA-1 hash algorithm. The last 20 bytes are SHA-1 hash digest of the bytes in "signedCertificate."
Since the decrypted value is properly formatted and the last bytes are the same hash value that we can calculate independently, we can assume that whoever knew "VeriSign Class 3 Secure Server CA"'s private key "signed" it. We implicitly trust that only VeriSign knows the private key "d."
We can repeat the process to verify that "VeriSign Class 3 Secure Server CA"'s certificate was signed by VeriSign's "Class 3 Public Primary Certification Authority."
But why should we trust that? There are no more levels on the trust chain.

The top "VeriSign Class 3 Public Primary Certification Authority" was signed by itself. This certificate has been built into Mozilla products as an implicitly trusted good certificate since version 1.4 of certdata.txt in the Network Security Services (NSS) library. It was checked-in on September 6, 2000 by Netscape's Robert Relyea with the following comment:

"Make the framework compile with the rest of NSS. Include a 'live' certdata.txt with those certs we have permission to push to open source (additional certs will be added as we get permission from the owners)."
This decision has had a relatively long impact since the certificate has a validity range of January 28, 1996 - August 1, 2028.
As Ken Thompson explained so well in his "Reflections on Trusting Trust", you ultimately have to implicitly trust somebody. There is no way around this problem. In this case, we're implicitly trusting that Robert Relyea made a good choice. We also hope that Mozilla's built-in certificate policy is reasonable for the other built-in certificates.
One thing to keep in mind here is that all these certificates and signatures were simply used to form a trust chain. On the public Internet, VeriSign's root certificate is implicitly trusted by Firefox long before you go to any website. In a company, you can create your own root certificate authority (CA) that you can install on everyone's machine.
Alternatively, you can get around having to pay companies like VeriSign and avoid certificate trust chains altogether. Certificates are used to establish trust by using a trusted third-party (in this case, VeriSign). If you have a secure means of sharing a secret "key", such as whispering a long password into someone's ear, then you can use that pre-shared key (PSK) to establish trust. There are extensions to TLS to allow this, such as TLS-PSK, and my personal favorite, TLS with Secure Remote Password (SRP) extensions. Unfortunately, these extensions aren't nearly as widely deployed and supported, so they're usually not practical. Additionally, these alternatives impose a burden that we have to have some other secure means of communicating the secret that's more cumbersome than what we're trying to establish with TLS (otherwise, why wouldn't we use that for everything?).
One final check that we need to do is to verify that the host name on the certificate is what we expected. Nelson Bolyard's comment in the SSL_AuthCertificate function explains why:
/* cert is OK. This is the client side of an SSL connection.
 * Now check the name field in the cert against the desired hostname.
 * NB: This is our only defense against Man-In-The-Middle (MITM) attacks! */
This check helps prevent against a man-in-the-middle attack because we are implicitly trusting that the people on the certificate trust chain wouldn't do something bad, like sign a certificate claiming to be from Amazon.com unless it actually was Amazon.com. If an attacker is able to modify your DNS server by using a technique like DNS cache poisoning, you might be fooled into thinking you're at a trusted site (like Amazon.com) because the address bar will look normal. This last check implicitly trusts certificate authorities to stop these bad things from happening.

Pre-Master Secret

We've verified some claims about Amazon.com and know its public encryption exponent "e" and modulus "n." Anyone listening in on the traffic can know this as well (as evidenced because we are using Wireshark captures). Now we need to create a random secret key that an eavesdropper/attacker can't figure out. This isn't as easy as it sounds. In 1996, researchers figured out that Netscape Navigator 1.1 was using only three sources to seed their pseudo-random number generator (PRNG). The sources were: the time of day, the process id, and the parent process id. As the researchers showed, these "random" sources aren't that random and were relatively easy to figure out.
Since everything else was derived from these three "random" sources, it was possible to "break" the SSL "security" in 25 seconds on a 1996 era machine. If you still don't believe that finding randomness is hard, just ask the Debian OpenSSL maintainers. If you mess it up, all the security built on top of it is suspect.
On Windows, random numbers used for cryptographic purposes are generated by calling the CryptGenRandom function that hashes bits sampled from over 125 sources. Firefox uses this function along with some bits derived from its own function to seed its pseudo-random number generator.
The 48 byte "pre-master secret" random value that's generated isn't used directly, but it's very important to keep it secret since a lot of things are derived from it. Not surprisingly, Firefox makes it hard to find out this value. I had to compile a debug version and set the SSLDEBUGFILE and SSLTRACE environment variables to see it.
In this particular session, the pre-master secret showed up in the SSLDEBUGFILE as:
4456: SSL[131491792]: Pre-Master Secret [Len: 48]
03 01 bb 7b 08 98 a7 49 de e8 e9 b8 91 52 ec 81 ...{...I.....R..
4c c2 39 7b f6 ba 1c 0a b1 95 50 29 be 02 ad e6 L.9{......P)....
ad 6e 11 3f 20 c4 66 f0 64 22 57 7e e1 06 7a 3b .n.? .f.d"W~..z;
Note that it's not completely random. The first two bytes are, by convention, the TLS version (03 01).

Trading Secrets

We now need to get this secret value over to Amazon.com. By Amazon's wishes of "TLS_RSA_WITH_RC4_128_MD5", we will use RSA to do this. You could make your input message equal to just the 48 byte pre-master secret, but the Public Key Cryptography Standard (PKCS) #1, version 1.5 RFC tells us that we should pad these bytes with random data to make the input equal to exactly the size of the modulus (1024 bits/128 bytes). This makes it harder for an attacker to determine our pre-master secret. It also gives us one last chance to protect ourselves in case we did something really bone-headed, like reusing the same secret. If we reused the key, the eavesdropper would likely see a different value placed on the network due to the random padding.
Again, Firefox makes it hard to see these random values. I had to insert debugging statements into the padding function to see what was going on:
wrapperHandle = fopen("plaintextpadding.txt", "a");
fprintf(wrapperHandle, "PLAINTEXT = ");
for(i = 0; i < modulusLen; i++)
{
    fprintf(wrapperHandle, "%02X ", block[i]);
}
fprintf(wrapperHandle, "\r\n");
fclose(wrapperHandle);
In this session, the full padded value was:
00 02 12 A3 EA B1 65 D6 81 6C 13 14 13 62 10 53 23 B3 96 85 FF 24 FA CC 46 11 21 24 A4 81 EA 30 63 95 D4 DC BF 9C CC D0 2E DD 5A A6 41 6A 4E 82 65 7D 70 7D 50 09 17 CD 10 55 97 B9 C1 A1 84 F2 A9 AB EA 7D F4 CC 54 E4 64 6E 3A E5 91 A0 06 00 03 01 BB 7B 08 98 A7 49 DE E8 E9 B8 91 52 EC 81 4C C2 39 7B F6 BA 1C 0A B1 95 50 29 BE 02 AD E6 AD 6E 11 3F 20 C4 66 F0 64 22 57 7E E1 06 7A 3B
Firefox took this value and calculated "C ≡ Me (mod n)" to get the value we see in the "Client Key Exchange" record:

Finally, Firefox sent out one last unencrypted message, a "Change Cipher Spec" record:

This is Firefox's way of telling Amazon that it's going to start using the agreed upon secret to encrypt its next message.

Deriving the Master Secret

If we've done everything correctly, both sides (and only those sides) now know the 48 byte (256 bit) pre-master secret. There's a slight trust issue here from Amazon's perspective: the pre-master secret just has bits that were generated by the client, they don't take anything into account from the server or anything we said earlier. We'll fix that be computing the "master secret." Per the spec, this is done by calculating:
master_secret = PRF(pre_master_secret, "master secret", ClientHello.random + ServerHello.random)
The "pre_master_secret" is the secret value we sent earlier. The "master secret" is simply a string whose ASCII bytes (e.g. "6d 61 73 74 65 72 ...") are used. We then concatenate the random values that were sent in the ClientHello and ServerHello (from Amazon) messages that we saw at the beginning.
The PRF is the "Pseudo-Random Function" that's also defined in the spec and is quite clever. It combines the secret, the ASCII label, and the seed data we give it by using the keyed-Hash Message Authentication Code (HMAC) versions of both MD5 and SHA-1 hash functions. Half of the input is sent to each hash function. It's clever because it is quite resistant to attack, even in the face of weaknesses in MD5 and SHA-1. This process can feedback on itself and iterate forever to generate as many bytes as we need.
Following this procedure, we obtain a 48 byte "master secret" of
4C AF 20 30 8F 4C AA C5 66 4A 02 90 F2 AC 10 00 39 DB 1D E0 1F CB E0 E0 9D D7 E6 BE 62 A4 6C 18 06 AD 79 21 DB 82 1D 53 84 DB 35 A7 1F C1 01 19

Generating Lots of Keys

Now that both sides have a "master secrets", the spec shows us how we can derive all the needed session keys we need using the PRF to create a "key block" where we will pull data from:
key_block = PRF(SecurityParameters.master_secret, "key expansion", SecurityParameters.server_random + SecurityParameters.client_random);
The bytes from "key_block" are used to populate the following:
client_write_MAC_secret[SecurityParameters.hash_size]
server_write_MAC_secret[SecurityParameters.hash_size]
client_write_key[SecurityParameters.key_material_length]
server_write_key[SecurityParameters.key_material_length]
client_write_IV[SecurityParameters.IV_size]
server_write_IV[SecurityParameters.IV_size]
Since we're using a stream cipher instead of a block cipher like the Advanced Encryption Standard (AES), we don't need the Initialization Vectors (IVs). Therefore, we just need two Message Authentication Code (MAC) keys for each side that are 16 bytes (128 bits) each since the specified MD5 hash digest size is 16 bytes. In addition, the RC4 cipher uses a 16 byte (128 bit) key that both sides will need as well. All told, we need 2*16 + 2*16 = 64 bytes from the key block.
Running the PRF, we get these values:
client_write_MAC_secret = 80 B8 F6 09 51 74 EA DB 29 28 EF 6F 9A B8 81 B0
server_write_MAC_secret = 67 7C 96 7B 70 C5 BC 62 9D 1D 1F 4A A6 79 81 61
client_write_key = 32 13 2C DD 1B 39 36 40 84 4A DE E5 6C 52 46 72
server_write_key = 58 36 C4 0D 8C 7C 74 DA 6D B7 34 0A 91 B6 8F A7

Prepare to be Encrypted!

The last handshake message the client sends out is the "Finished message." This is a clever message that proves that no one tampered with the handshake and it proves that we know the key. The client takes all bytes from all handshake messages and puts them into a "handshake_messages" buffer. We then calculate 12 bytes of "verify_data" using the pseudo-random function (PRF) with our master key, the label "client finished", and an MD5 and SHA-1 hash of "handshake_messages":
verify_data = PRF(master_secret, "client finished", MD5(handshake_messages) + SHA-1(handshake_messages)) [12]
We take the result and add a record header byte "0x14" to indicate "finished" and length bytes "00 00 0c" to indicate that we're sending 12 bytes of verify data. Then, like all future encrypted messages, we need to make sure the decrypted contents haven't been tampered with. Since our cipher suite in use is TLS_RSA_WITH_RC4_128_MD5, this means we use the MD5 hash function.
Some people get paranoid when they hear MD5 because it has some weaknesses. I certainly don't advocate using it as-is. However, TLS is smart in that it doesn't use MD5 directly, but rather the HMAC version of it. This means that instead of using MD5(m) directly, we calculate:
HMAC_MD5(Key, m) = MD5((Key ⊕ opad) ++ MD5((Key ⊕ ipad) ++ m)
(The ⊕ means XOR, ++ means concatenate, "opad" is the bytes "5c 5c ... 5c", and "ipad" is the bytes "36 36 ... 36").
In particular, we calculate:
HMAC_MD5(client_write_MAC_secret, seq_num + TLSCompressed.type + TLSCompressed.version + TLSCompressed.length + TLSCompressed.fragment));
As you can see, we include a sequence number ("seq_num") along with attributes of the plaintext message (here it's called "TLSCompressed"). The sequence number foils attackers who might try to take a previously encrypted message and insert it midstream. If this occurred, the sequence numbers would definitely be different than what we expected. This also protects us from an attacker dropping a message.
All that's left is to encrypt these bytes.

RC4 Encryption

Our negotiated cipher suite was TLS_RSA_WITH_RC4_128_MD5. This tells us that we need to use Ron's Code #4 (RC4) to encrypt the traffic. Ron Rivest developed the RC4 algorithm to generate random bytes based on a 256 byte key. The algorithm is so simple you can actually memorize it in a few minutes.
RC4 begins by creating a 256-byte "S" byte array and populating it with 0 to 255. You then iterate over the array by mixing in bytes from the key. You do this to create a state machine that is used to generate "random" bytes. To generate a random byte, we shuffle around the "S" array.
Put graphically, it looks like this:

To encrypt a byte, we xor this pseudo-random byte with the byte we want to encrypt. Remember that xor'ing a bit with 1 causes it to flip. Since we're generating random numbers, on average the xor will flip half of the bits. This random bit flipping is effectively how we encrypt data. As you can see, it's not very complicated and thus it runs quickly. I think that's why Amazon chose it.
Recall that we have a "client_write_key" and a "server_write_key." The means we need to create two RC4 instances: one to encrypt what our browser sends and the other to decrypt what the server sent us.
The first few random bytes out of the "client_write" RC4 instance are "7E 20 7A 4D FE FB 78 A7 33 ..." If we xor these bytes with the unencrypted header and verify message bytes of "14 00 00 0C 98 F0 AE CB C4 ...", we'll get what appears in the encrypted portion that we can see in Wireshark:

The server does almost the same thing. It sends out a "Change Cipher Spec" and then a "Finished Message" that includes all handshake messages, including the decrypted version of the client's "Finished Message." Consequently, this proves to the client that the server was able to successfully decrypt our message.

Welcome to the Application Layer!

Now, 220 milliseconds after we started, we're finally ready for the application layer. We can now send normal HTTP traffic that'll be encrypted by the TLS layer with the RC4 write instance and decrypt traffic with the server RC4 write instance. In addition, the TLS layer will check each record for tampering by computing the HMAC_MD5 hash of the contents.
At this point, the handshake is over. Our TLS record's content type is now 23 (0x17). Encrypted traffic begins with "17 03 01" which indicate the record type and TLS version. These bytes are followed by our encrypted size, which includes the HMAC hash.
Encrypting the plaintext of:
GET /gp/cart/view.html/ref=pd_luc_mri HTTP/1.1
Host: www.amazon.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.10) Gecko/2009060911 Minefield/3.0.10 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
...
will give us the bytes we see on the wire:

The only other interesting fact is that the sequence number increases on each record, it's now 1 (and the next record will be 2, etc).
The server does the same type of thing on its side using the server_write_key. We see its response, including the tell-tale application data header:

Decrypting this gives us:

HTTP/1.1 200 OK
Date: Wed, 10 Jun 2009 01:09:30 GMT
Server: Server
...
Cneonction: close
Transfer-Encoding: chunked
which is a normal HTTP reply that includes a non-descriptive "Server: Server" header and a misspelled "Cneonction: close" header coming from Amazon's load balancers.
TLS is just below the application layer. The HTTP server software can act as if it's sending unencrypted traffic. The only change is that it writes to a library that does all the encryption. OpenSSL is a popular open-source library for TLS.
The connection will stay open while both sides send and receive encrypted data until either side sends out a "closure alert" message and then closes the connection. If we reconnect shortly after disconnecting, we can re-use the negotiated keys (if the server still has them cached) without using public key operations, otherwise we do a completely new full handshake.
It's important to realize that application data records can be anything. The only reason "HTTPS" is special is because the web is so popular. There are lots of other TCP/IP based protocols that ride on top of TLS. For example, TLS is used by FTPS and secure extensions to SMTP. It's certainly better to use TLS than inventing your own solution. Additionally, you'll benefit from a protocol that has withstood careful security analysis.

... And We're Done!

The very readable TLS RFC covers many more details that were missed here. We covered just one single path in our observation of the 220 millisecond dance between Firefox and Amazon's server. Quite a bit of the process was affected by the TLS_RSA_WITH_RC4_128_MD5 Cipher Suite selection that Amazon made with its ServerHello message. It's a reasonable choice that slightly favors speed over security.
As we saw, if someone could secretly factor Amazon's "n" modulus into its respective "p" and "q", they could effectively decrypt all "secure" traffic until Amazon changes their certificate. Amazon counter-balances this concern this with a short one year duration certificate:

One of the cipher suites that was offered was "TLS_DHE_RSA_WITH_AES_256_CBC_SHA" which uses the Diffie-Hellman key exchange that has a nice property of "forward secrecy." This means that if someone cracked the mathematics of the key exchange, they'd be no better off to decrypt another session. One downside to this algorithm is that it requires more math with big numbers, and thus is a little more computationally taxing on a busy server. The "Advanced Encryption Standard" (AES) algorithm was present in many of the suites that we offered. It's different than RC4 in that it works on 16 byte "blocks" at a time rather than a single byte. Since its key can be up to 256 bits, many consider this to be more secure than RC4.
In just 220 milliseconds, two endpoints on the Internet came together, provided enough credentials to trust each other, set up encryption algorithms, and started to send encrypted traffic.
And to think, all of this just so Bob can buy milk.

Application-wide action filters in ASP.NET MVC

(http://blog.maartenballiauw.be/post/2009/06/24/Application-wide-action-filters-in-ASPNET-MVC.aspx)


 Ever had a team of developers using your ASP.NET MVC framework? Chances are you have implemented some action filters (i.e. for logging) which should be applied on all controllers in the application. Two ways to do this: kindly ask your developers to add a [Logging] attribute to the controllers they write, or kindly ask to inherit from SomeCustomControllerWithActionsInPlace.
If you have been in this situation, monday mornings, afternoons, tuesdays and other weekdays are in fact days where some developers will forget to do one of the above. This means no logging! Or any other action filters that are executed due to a developer that has not been fed with enough coffee… Wouldn’t it be nice to have a central repository where you can register application-wide action filters? That’s exactly what we are going to do in this blog post.
Note: you can in fact use a dependency injection strategy for this as well, see Jeremy Skinner’s blog.
Download the example code: MvcGlobalActionFilter.zip (24.38 kb)

 
 

The idea

Well, all things have to start with an idea, otherwise there’s nothing much left to do. What we’ll be doing in our solution to global action filters is the following:
  1. Create a IGlobalFilter interface which global action filters have to implement. You can discuss about this, but I think it’s darn handy to add some convenience methods like ShouldBeInvoked() where you can abstract away some checks before the filter is actually invoked.
  2. Create some IGlobalActionFilter, IGlobalResultFilter, IGlobalAuthorizationFilter, IGlobalExceptionFilter interfaces, just for convenience to the developer that is creating the global filters. You’ll see the use of this later on.
  3. Create a GlobalFilterActionInvoker, a piece of logic that is set on each controller so the controller knows how to call its own action methods. We’ll use this one to inject our lists of global filters.
  4. Create a GlobalFilterControllerFactory. I’m not happy with this, but we need it to set the GlobalFilterActionInvoker instance on each controller when it is created.

IGlobalFilter, IGlobalActionFilter, …

Not going to spend too much time on these. Actually, these interfaces are just descriptors for our implementation so it knows what type of filter is specified and if it should be invoked. Here’s a bunch of code. No comments.

public interface IGlobalFilter { bool ShouldBeInvoked(ControllerContext controllerContext); } public interface IGlobalAuthorizationFilter : IGlobalFilter, IAuthorizationFilter public interface IGlobalActionFilter : IGlobalFilter, IActionFilter { } public interface IGlobalResultFilter : IGlobalFilter, IResultFilter { } public interface IGlobalExceptionFilter : IGlobalFilter, IExceptionFilter { }
And yes, I did suppress some Static Code Analysis rules for this :-)

GlobalFilterActionInvoker

The GlobalFilterActionInvoker will take care of registering the global filters and making sure each filter is actually invoked on every controller and action method in our ASP.NET MVC application. Here’s a start for our class:

public class GlobalFilterActionInvoker : ControllerActionInvoker { protected FilterInfo globalFilters; public GlobalFilterActionInvoker() { globalFilters = new FilterInfo(); } public GlobalFilterActionInvoker(FilterInfo filters) { globalFilters = filters; } public GlobalFilterActionInvoker(List filters) : this(new FilterInfo()) { foreach (var filter in filters) RegisterGlobalFilter(filter); } public FilterInfo Filters { get { return globalFilters; } } // - more code - }
We’re providing some utility constructors that take a list of global filters and add it to the internal FilterInfo instance (which is an ASP.NET MVC class we can leverage in here). RegisterGlobalFilter() will do the magic of adding filters to the right collection in the FilterInfo instance.

public void RegisterGlobalFilter(IGlobalFilter filter) { if (filter is IGlobalAuthorizationFilter) globalFilters.AuthorizationFilters.Add((IGlobalAuthorizationFilter)filter); if (filter is IGlobalActionFilter) globalFilters.ActionFilters.Add((IGlobalActionFilter)filter); if (filter is IGlobalResultFilter) globalFilters.ResultFilters.Add((IGlobalResultFilter)filter); if (filter is IGlobalExceptionFilter) globalFilters.ExceptionFilters.Add((IGlobalExceptionFilter)filter); }
One override left in our implementation: ControllerActionInvoker, the class we are inheriting from, provides a method named GetFilters(), which is used to get the filters for a specific controller context. Ideal one to override:

protected override FilterInfo GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor) { FilterInfo definedFilters = base.GetFilters(controllerContext, actionDescriptor); foreach (var filter in Filters.AuthorizationFilters) { IGlobalFilter globalFilter = filter as IGlobalFilter; if (globalFilter == null || (globalFilter != null && globalFilter.ShouldBeInvoked(controllerContext))) { definedFilters.AuthorizationFilters.Add(filter); } } // - same for action filters - // - same for result filters - // - same for exception filters - return definedFilters; }
Basically, we are querying our IGlobalFilter if it should be invoked for the given controller context. If so, we add it to the FilterInfo object that is required by the ControllerActionInvoker base class. Piece of cake!

GlobalFilterControllerFactory

I’m not happy having to create this one, but we need it to set the GlobalFilterActionInvoker instance on each controller that is created. Otherwise, there is no way to specify our global filters on a controller or action method… Here’s the class:

public class GlobalFilterControllerFactory : DefaultControllerFactory { protected GlobalFilterActionInvoker actionInvoker; public GlobalFilterControllerFactory(GlobalFilterActionInvoker invoker) { actionInvoker = invoker; } public override IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName) { IController controller = base.CreateController(requestContext, controllerName); Controller controllerInstance = controller as Controller; if (controllerInstance != null) { controllerInstance.ActionInvoker = actionInvoker; } return controller; } }
What we do here is let the DefaultControllerFactory create a controller. Next, we simply set the controller’s ActionInvoker property to our GlobalFilterActionInvoker .

Plumbing it all together!

To plumb things together, add some code in your Global.asax.cs class, under Application_Start:
protected void Application_Start() { RegisterRoutes(RouteTable.Routes); ControllerBuilder.Current.SetControllerFactory( new GlobalFilterControllerFactory( new GlobalFilterActionInvoker( new List { new SampleGlobalTitleFilter() } ) ) ); }
We are now setting the controller factory for our application to GlobalFilterControllerFactory, handing it a GlobalFilterActionInvoker which specifies one global action filter: SampleGlobalTitleFilter.

Sidenote: SampleGlobalTitleFilter

As a sidenote, I created a sample result filter named SampleGlobalTitleFilter, which is defined as a global filter that always appends a string (“ – Sample Application”) to the page title. Here’s the code for that one:

public class SampleGlobalTitleFilter : IGlobalResultFilter { public bool ShouldBeInvoked(System.Web.Mvc.ControllerContext controllerContext) { return true; } public void OnResultExecuted(System.Web.Mvc.ResultExecutedContext filterContext) { return; } public void OnResultExecuting(System.Web.Mvc.ResultExecutingContext filterContext) { if (filterContext.Controller.ViewData["PageTitle"] == null) filterContext.Controller.ViewData["PageTitle"] = ""; string pageTitle = filterContext.Controller.ViewData["PageTitle"].ToString(); if (!string.IsNullOrEmpty(pageTitle)) pageTitle += " - "; pageTitle += "Sample Application"; filterContext.Controller.ViewData["PageTitle"] = pageTitle; } }

Conclusion

Download the sample code: MvcGlobalActionFilter.zip (24.38 kb)
There is no need for my developers to specify SampleGlobalTitleFilter on each controller they write. There is no need for my developers to use the ControllerWithTitleFilter base class. People can come in and even develop software without drinking 2 liters of coffee! Really, development should not be hard for your developers. Make sure all application-wide infrastructure is there and our people are ready to go. And I’m really loving ASP.NET MVC’s extensibility on that part!

 

Security transparency in CLR 2.0 (.NET 2.0, .NET3.0, .NET 3.5) and in CLR 4.0 (.NET 4.0)

David DeWinter has an excellent series of post on different topics security in both CLR 2.0 and CLR 4.0

Transparency Can Reduce Your Security Footprint – #1
Using Transparency in CLR 2.0 – #2
Transparent Code Behavior in CLR 2.0 – #3
What’s New With Security in .NET 4? – #4
Opting Out of Security Changes in .NET 4 – #5
The AllowPartiallyTrustedCallersAttribute (APTCA) – #6

How to Host a Partial Trust Sandbox – #7
Conditional APTCA in .NET 4 – #8
Hosting Conditional APTCA Assemblies – #9
An Introduction to Security Transparency in .NET 4 – #10
Type Transparency in .NET 4 – #11
Partial Trust, APTCA, and Security Transparency – #12
Transparency and Implicit Static Constructors – #13
Determining the Security Rules for Your Assemblies – #14
The SecurityRulesAttribute – #15
Mixing Level 1 and Level 2 Transparency Rules – #16
How to Build APIs with Transparency in Mind – #17
Asserting for Permissions in .NET 4 – #18

A nice and informative JQuery tutorial

Learning resources for Entity Framework 4.0 new features

(http://bogdanbrinzarea.wordpress.com/2009/08/05/learning-resources-for-entity-framework-4-0-new-features/)

New features

http://blogs.msdn.com/adonet/archive/2009/05/21/updated-entity-framework-documentation-for-beta1.aspx
http://blogs.msdn.com/adonet/archive/2009/06/22/announcing-entity-framework-feature-ctp-1.aspx
http://blog.tonysneed.com/?p=161
http://www.develop.com/entityframework4

SQL improvements

http://blogs.msdn.com/adonet/archive/2009/08/05/improvements-to-the-generated-sql-in-net-4-0-beta1.aspx
http://thedatafarm.com/blog/data-access/important-entity-framework-query-improvements-for-net-4-0/

POCO Objects

http://msdn.microsoft.com/en-us/magazine/ee236639.aspx
http://blogs.msdn.com/adonet/archive/2009/05/11/sneak-preview-persistence-ignorance-and-poco-in-entity-framework-4-0.aspx
http://blogs.msdn.com/adonet/archive/2009/05/21/poco-in-the-entity-framework-part-1-the-experience.aspx
http://blogs.msdn.com/adonet/archive/2009/05/28/poco-in-the-entity-framework-part-2-complex-types-deferred-loading-and-explicit-loading.aspx
http://blogs.msdn.com/adonet/archive/2009/06/10/poco-in-the-entity-framework-part-3-change-tracking-with-poco.aspx
http://mosesofegypt.net/post/Entity-Framework-4-Persistence-Ignorance-First-Look.aspx

Deferred Loading and Explicit Loading

http://blogs.msdn.com/adonet/archive/2009/05/12/sneak-preview-deferred-loading-in-entity-framework-4-0.aspx
http://blogs.msdn.com/adonet/archive/2009/05/28/poco-in-the-entity-framework-part-2-complex-types-deferred-loading-and-explicit-loading.aspx
http://thedatafarm.com/blog/data-access/a-look-at-lazy-loading-in-ef4/
http://www.simonsegal.net/blog/2009/07/27/entity-framework-40-improvements/
http://www.simonsegal.net/blog/2009/07/29/entity-framework-40-and-fetching-strategies/

Functions in LINQ to Entities

http://thedatafarm.com/blog/data-access/checking-out-one-of-the-new-stored-procedure-features-in-ef4/
http://blogs.microsoft.co.il/blogs/gilf/archive/2009/05/23/calling-database-functions-in-linq-to-entities-in-entity-framework-4.aspx
Tip 30 – How to use a custom database function

Model Defined Functions

http://blogs.msdn.com/adonet/archive/2009/05/14/sneak-preview-model-defined-functions.aspx
http://blogs.microsoft.co.il/blogs/gilf/archive/2009/05/23/calling-database-functions-in-linq-to-entities-in-entity-framework-4.aspx
http://thedatafarm.com/blog/data-access/ef4-model-defined-functions-level-1-amp-2/

EDM Designer

http://msdn.microsoft.com/en-us/library/dd456821(VS.100).aspx

Model-First Support

http://msdn.microsoft.com/en-us/magazine/ee236639.aspx
http://blogs.msdn.com/adonet/archive/2009/05/12/sneak-preview-model-first-in-the-entity-framework-4-0.aspx
http://blogs.microsoft.co.il/blogs/gilf/archive/2009/05/23/model-first-in-entity-framework-4.aspx
http://channel9.msdn.com/shows/10-4/10-4-Episode-15-Model-First-Development-with-the-Entity-Framework-40/
http://thedatafarm.com/blog/data-access/ef4-ndash-new-properties-for-entity-properties/

Code Only Support

http://blogs.msdn.com/efdesign/archive/2009/06/10/code-only.aspx
http://blogs.msdn.com/adonet/archive/2009/06/22/feature-ctp-walkthrough-code-only-for-entity-framework.aspx
http://blogs.msdn.com/efdesign/archive/2009/08/03/code-only-enhancements.aspx
http://blogs.msdn.com/alexj/archive/2009/08/12/tip-32-how-to-create-a-database-from-ssdl-ef-4-only.aspx

Complex Type Support

http://blogs.microsoft.co.il/blogs/gilf/archive/2009/05/22/complex-type-support-in-the-edm-designer-in-entity-framework-4.aspx
http://blogs.msdn.com/adonet/archive/2009/05/28/poco-in-the-entity-framework-part-2-complex-types-deferred-loading-and-explicit-loading.aspx
http://thedatafarm.com/blog/data-access/a-big-step-for-stored-procedures-in-ef4/
http://thedatafarm.com/blog/data-access/complex-types-in-the-edm-designer-in-ef4-and-a-look-at-updating-complex-types-in-code/

Table splitting

http://thedatafarm.com/blog/data-access/ef-table-splitting-ndash-the-opposite-of-entity-splitting/

Testability

http://blogs.msdn.com/adonet/archive/2009/05/18/sneak-preview-entity-framework-4-0-testability-improvements.aspx

Design patterns

http://msdn.microsoft.com/en-us/magazine/ee236639.aspx
http://blog.keithpatton.com/2009/05/30/Entity+Framework+POCO+Repository+Using+Visual+Studio+2010+Net+40+Beta+1.aspx
http://blogs.msdn.com/adonet/archive/2009/06/16/using-repository-and-unit-of-work-patterns-with-entity-framework-4-0.aspx
http://thedatafarm.com/blog/data-access/another-clever-pattern-for-dealingi-wtih-ef-change-tracking-across-processes/

Events

http://romiller.com/Home/tabid/36/EntryID/51/Default.aspx

Architecture

http://blogs.msdn.com/adonet/archive/2009/05/14/sneak-preview-n-tier-development-with-entity-framework-4-0.aspx
http://msdn.microsoft.com/en-us/magazine/ee321569.aspx

Self tracking entities

http://blogs.msdn.com/adonet/archive/2009/05/14/sneak-preview-n-tier-development-with-entity-framework-4-0.aspx
http://msdn.microsoft.com/en-us/magazine/ee321569.aspx
http://blogs.msdn.com/efdesign/archive/2009/03/24/self-tracking-entities-in-the-entity-framework.aspx
http://blogs.msdn.com/adonet/archive/2009/06/10/poco-in-the-entity-framework-part-3-change-tracking-with-poco.aspx
http://blogs.msdn.com/adonet/archive/2009/06/22/feature-ctp-walkthrough-self-tracking-entities-for-entity-framework.aspx
http://weblogs.asp.net/gunnarpeipman/archive/2009/07/11/entity-framework-4-0-how-to-use-pocos.aspx

POCO T4 templates

http://msdn.microsoft.com/en-us/magazine/ee236639.aspx
http://thedatafarm.com/blog/data-access/ef-why-work-with-objectstateentries-instead-of-the-objects-directly/
http://thedatafarm.com/blog/data-access/customizing-edm-code-gen-in-ef4/
http://thedatafarm.com/blog/data-access/small-ef4-wpf-bug-that-bit-me-in-the-butt-during-my-vtdotnet-presentation/
 http://blogs.msdn.com/adonet/archive/2009/05/19/sneak-peek-using-code-generation-templates-with-the-entity-framework-4-0.aspx
http://blogs.msdn.com/adonet/archive/2009/05/21/poco-in-the-entity-framework-part-1-the-experience.aspx
http://blogs.msdn.com/adonet/archive/2009/06/22/feature-ctp-walkthrough-poco-templates-for-entity-framework.aspx
http://msmvps.com/blogs/matthieu/archive/2009/06/26/poco-t4.aspx
http://blogs.msdn.com/adonet/archive/2009/07/22/customizing-t4-templates.aspx

Validation

http://blogs.msdn.com/alexj/archive/2009/07/20/tip-27-how-to-implement-beforesave-validation.aspx

EDM designer

http://thedatafarm.com/blog/data-access/more-designer-improvements-deleting-entities-from-the-model-and-from-the-store-schema/

Foreign keys

http://blogs.msdn.com/efdesign/archive/2009/03/16/foreign-keys-in-the-entity-framework.aspx

Pluralization

http://blogs.msdn.com/efdesign/archive/2008/12/02/pluralization.aspx
http://blogs.msdn.com/adonet/archive/2009/05/20/sneak-preview-pluralization-in-entity-framework-4-0.aspx
http://blogs.microsoft.co.il/blogs/gilf/archive/2009/05/22/pluralize-or-singularize-generated-object-names-checkbox-in-entity-framework-4.aspx

Tips

Tip 32 – How to create a database from SSDL – EF 4 only
Tip 31 – How to compose L2O and L2E queries
Tip 30 – How to use a custom database function
Tip 29 – How to avoid LazyLoad or Load() reader issues
Tip 28 – How to implement an Eager Loading strategy
Tip 27 – How to Implement BeforeSave Validation
Tip 26 – How to avoid database queries using Stub Entities
Tip 25 – How to get Entities by key the easy way
Tip 24 – How to get the ObjectContext from an Entity
Tip 23 – How to fake Enums in EF 4
Tip 22 – How to make Include really Include
Tip 21 – How to use the Single() operator – EF 4.0 only
Tip 20 – How to deal with Fixed Length Keys
Tip 19 – How to use Optimistic Concurrency with the Entity Framework
Tip 18 – How to decide on a lifetime for your ObjectContext
Tip 17 – How to do one step updates with AttachAsModified(..)
Tip 16 – How to mimic .NET 4.0’s ObjectSet today
Tip 15 – How to avoid loading unnecessary Properties
Tip 14 – How to cache Entity Framework Reference Data
Tip 13 – How to Attach an Entity the easy way
Tip 12 – How to choose an Inheritance Strategy
Tip 11 – How to avoid Relationship Span
Tip 10 – How to understand Entity Framework jargon
Tip 9 – How to delete an object without retrieving it
Tip 8 – How to write ‘WHERE IN’ style queries using LINQ to Entities
Tip 7 – How to fake Foreign Key Properties in .NET 3.5 SP1
Tip 6 – How and when to use eager loading
Tip 5 – How to restrict the types returned from an EF Query
Tip 4 – Conceptual Schema Definition Language Rules
Tip 3 – How to get started with T4
Tip 2 – Entity Framework Books
Tip 1 – How to sort Relationships in the Entity Framework

Learning resources for ASP.NET 4.0 WebForms new features

(http://bogdanbrinzarea.wordpress.com/2009/08/06/learning-resources-for-asp-net-4-0-webforms-new-features/)


General

http://videos.visitmix.com/MIX09/T46F
http://channel9.msdn.com/shows/The+Knowledge+Chamber/Stephen-Walther-New-Features-of-ASPNET-40/
http://blogs.msdn.com/publicsector/archive/2009/03/25/devdinnerondemand-what-s-new-in-asp-net-4-0.aspx
http://blogs.msdn.com/scothu/archive/2009/03/23/asp-net-4-0-and-visual-studio-2010-development-overview-dynamic-data.aspx
http://www.asp.net/learn/whitepapers/aspnet40/
http://haacked.com/archive/2008/11/13/future-of-aspnet.aspx

WebForms

http://blogs.msdn.com/mikeormond/archive/2009/05/06/asp-net-4-0-webforms-enhancements.aspx
http://channel9.msdn.com/shows/10-4/10-4-Episode-3-ASPNET-WebForms-40/
http://mostlylucid.net/archive/2009/01/01/asp.net-4.0-webforms-podcast-is-now-up.aspx
http://blogs.msdn.com/mikeormond/archive/2009/04/16/visual-studio-2010-enhancements-for-asp-net.aspx
http://mostlylucid.net/archive/2009/01/29/1313.aspx

Client ID

http://mostlylucid.net/archive/2008/11/03/way-too-much-information-on-control-ids-and-asp.net-4.0.aspx
http://blog.osbornm.com/archive/2009/01/06/asp.net-4.0-clientid-overview-again.aspx

ViewState

http://weblogs.asp.net/despos/archive/2009/06/13/asp-net-4-0-more-control-on-viewstate-management.aspx
http://mostlylucid.net/archive/2009/01/28/1312.aspx

Data Controls

http://blogs.msdn.com/mikeormond/archive/2009/06/29/asp-net-4-0-enhancements-to-data-controls.aspx
http://csharpbits.notaclue.net/2009/03/cascading-or-dependant-field-templates.html

Routing

http://mostlylucid.net/archive/2009/05/19/1322.aspx
http://mostlylucid.net/archive/2009/01/25/asp.net-4.0-webform-routing-quick-rsquon-dirty-version.aspx
http://haacked.com/archive/2009/01/25/routing-for-web-forms-in-asp.net-4.0.aspx

Dynamic Images

http://www.hanselman.com/blog/ASPNETFuturesGeneratingDynamicImagesWithHttpHandlersGetsEasier.aspx
http://blogs.msdn.com/scothu/archive/2008/08/21/image-generation-is-released-to-codeplex.aspx
http://davidhayden.com/blog/dave/archive/2008/08/27/ASPNETImageGenerationGenerateImagesGetImagesDatabaseTransformImages.aspx
http://www.codeplex.com/aspnet/Release/ProjectReleases.aspx?ReleaseId=16449

Control Adapters

http://mostlylucid.net/archive/2009/04/27/1319.aspx

Testing

http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=28536

Ways to improve garbage collection performance for windows apps

 

Improve garbage collection performance (Windows Store apps using C#/VB) (Windows)

(http://msdn.microsoft.com/en-us/library/windows/apps/hh994643.aspx)

Windows Store apps written in C# and Visual Basic get automatic memory management from the .NET garbage collector. This section summarizes the behavior and performance best practices for the .NET garbage collector in Windows Store apps. For more info on how the .NET garbage collector works and tools for debugging and analyzing garbage collector performance, see Garbage collection.
The garbage collector determines when to run by balancing the memory consumption of the managed heap with the amount of work a garbage collection needs to do. One of the ways the garbage collector does this is by dividing the heap into generations and collecting only part of the heap most of the time. There are three generations in the managed heap:
  • Generation 0. This generation contains newly allocated objects unless they are 85,000 bytes or larger, in which case they are part of the large object heap. The large object heap is collected with generation 2 collections. Generation 0 collections are the most frequently occurring type of collection and clean up short-lived objects such as local variables.
  • Generation 1. This generation contains objects that have survived generation 0 collections. It serves as a buffer between generation 0 and generation 2. Generation 1 collections occur less frequently than generation 0 collections and clean up temporary objects that were active during previous generation 0 collections. A generation 1 collection also collects generation 0.
  • Generation 2. This generation contains long-lived objects that have survived generation 0 and generation 1 collections. Generation 2 collections are the least frequent and collect the entire managed heap, including the large object heap which contains objects that are 85,000 bytes or larger.
You can measure the performance of the garbage collector in 2 aspects: the amount of time it takes to do the garbage collection and the memory consumption of the managed heap. As mentioned earlier, the garbage collector strives for the best balance between the two. If you have a small app with a heap size that’s less than 100MB, focus on reducing memory consumption. If you have an app with a managed heap that’s larger than 100M, focus on reducing the garbage collection time only. You can help the .NET garbage collector achieve better performance by following the tips we look at next.

Reduce memory consumption 

Remove references

A reference to an object in your app prevents that object, and all of the objects it references, from being collected. The .NET just-in-time (JIT) compiler does a good job of detecting when a variable is no longer in use so objects held onto by that variable will be eligible for collection. But in some cases it may not be obvious that some objects have a reference to other objects because part of the object graph might be owned by libraries your app uses. To learn about the tools and techniques to find out which objects survive a garbage collection, see Garbage collection and performance.

Induce a garbage collection if it’s useful

Induce a garbage collection only after you have measured your app's performance and have determined that inducing a collection will improve its performance.
You can induce a garbage collection of a generation by calling GC.Collect(n), where n is the generation you want to collect (0, 1, or 2). We recommend that you don't force a garbage collection in your app because the garbage collector uses many heuristics to determine the best time to perform a collection, and forcing a collection is in many cases an unnecessary use of the CPU. But if you know that you have a large number of objects in your app that are suddenly no longer used and you want to return this memory to the system, then it may be appropriate to force a garbage collection. For example, you can induce a collection at the end of a loading sequence in a game to free up memory before gameplay starts.
To avoid accidently inducing too many garbage collections, you can set the GCCollectionMode to Optimized. This instructs the garbage collector to start a collection only if it determines that the collection would be productive enough to be justified.

Reduce garbage collection time

Follow the best practices here only after you've analyzed your app and observed large garbage collection times that you want to reduce. There are 2 aspects of garbage collection-related pause times: the time it takes to run a single garbage collection pass, and the total time your app spends doing garbage collections. The amount of time it takes to do a collection depends on how much live data the collector has to analyze. Generation 0 and generation 1 are bounded in size, but generation 2 continues to grow as more long-lived objects are active in your app. This means that the collection times for generation 0 and generation 1 are bounded, while generation 2 collections have the potential of taking a longer amount of time. How often garbage collections run depends mostly on how much memory you allocate, because a garbage collection frees up memory to satisfy allocation requests.
The garbage collector occasionally pauses your app to perform work, but doesn't necessarily pause your app the entire time it is doing a collection. Pause times are usually not user-perceivable in your app, especially for generation 0 and generation 1 collections. The Background garbage collection feature of the .NET garbage collector allows Generation 2 collections to be performed concurrently while your app is running and will only pause your app for short periods of time. But it is not always possible to do a Generation 2 collection as a background collection. In that case, the pause can be user-perceivable if you have a large enough heap (more than 100MB).
Frequent garbage collections can contribute to increased CPU (and therefore power) consumption, longer loading times, or decreased frame rates in your application. Below are some techniques you can use to reduce garbage collection time and collection-related pauses in your managed Windows Store app.

Reduce memory allocations

If you don’t allocate any objects then the garbage collector doesn’t run unless there is a low memory condition in the system. Reducing the amount of memory you allocate directly translates to less frequent garbage collections.
If in some sections of your app pauses are completely undesirable, then you can pre-allocate the necessary objects beforehand during a less performance-critical time. For example, a game might allocate all of the objects needed for gameplay during the loading screen of a level and not make any allocations during gameplay. This avoids pauses while the user is playing the game and can result in a higher and more consistent frame rate.

Reduce generation 2 collections by avoiding objects with a medium-length lifetime

Generational garbage collections perform best when you have really short-lived and/or really long-lived objects in your app. Short lived objects are collected in the cheaper generation 0 and generation 1 collections, and objects that are long-lived get promoted to generation 2, which is collected infrequently. Long-lived objects are those that are in use for the entire duration of your app, or during a significant period of your app, such as during a specific page or game level.
If you frequently create objects that have a temporary lifetime but live long enough to be promoted to generation 2, then more of the expensive generation 2 collections happen. You may be able to reduce generation 2 collections by recycling existing objects or throwing away objects more quickly.
A common example of objects with medium-term lifetime is objects that are used for displaying items in a list that a user scrolls through. If objects are created when items in the list are scrolled into view, and are no longer referenced as items in the list are scrolled out of view, then your app typically has a large number of generation 2 collections. In situations like this you can pre-allocate and reuse a set of objects for the data that is actively shown to the user, and use short-lived objects to load info as items in the list come into view.

Reduce generation 2 collections by avoiding large-sized objects with short lifetimes

As mentioned previously, any object that is 85,000 bytes or larger is allocated on the large object heap (LOH) and gets collected as part of generation 2. If you have temporary variables, such as buffers, that are greater than 85,000 bytes, then a generation 2 collection cleans them up. Limiting temporary variables to less than 85,000 bytes reduces the number of generation 2 collections in your app. One common technique is to create a buffer pool and reuse objects from the pool to avoid large temporary allocations.

Avoid reference-rich objects

The garbage collector determines which objects are live by following references between objects, starting from roots in your app. For more info, see What happens during a garbage collection. If an object contains many references, then there is more work for the garbage collector to do. A common technique (especially with large objects) is to convert reference rich objects into objects with no references (e.g., instead of storing a reference, store an index). Of course this technique works only when it is logically possible to do so.
Replacing object references with indexes can be a disruptive and complicated change to your app and is most effective for large objects with a large number of references. Do this only if you are noticing large garbage collection times in your app related to reference-heavy objects.

 

Changes to the Garbage collection

Changes made in .Net 4.0:

(http://geekswithblogs.net/sdorman/archive/2008/11/07/clr-4.0-garbage-collection-changes.aspx) 

The .NET garbage collector is one of the areas of the .NET Framework that is extremely important and probably one of the least understood. There are a lot of articles written about it and there have been very few changes since .NET 1.0 was first released. (There have been changes with almost each release, but they have been relatively minor.)
With .NET 4.0, however, there are some fairly substantial changes to the GC that will have some interesting performance implications (in a good way).
For a quick review, the GC in .NET is a generational garbage collector with 3 generations. Generation 0 and 1 collections are very fast since the segment (called the ephemeral segment) is small while Generation 2 collections can be relatively slow.
The GC in .NET also has two modes of operation: Server and Workstation. In Server GC, the algorithm maximizes the overall throughput but all managed code must be paused while it runs. In CLR 4, you can now subscribe to an event to be notified before a Generation 2 or Large Object Heap collection.

public static void Main(string[] args)
{
  try
  {
    // Register for a set of notifications.
    // Parameters require tuning. First is 
    // for Gen2, second, Large Object Heap 
    GC.RegisterForFullGCNotification(10, 10);

    // Start a thread using WaitForFullGCProc
    Thread thWaitForFullGC = new Thread(new ThreadStart(WaitForFullGCProc));
    thWaitForFullGC.Start();
  }

  catch (InvalidOperationException invalidOp)
  {
    Console.WriteLine("GC Notifications are not supported while concurrent GC is enabled.\n” + invalidOp.Message);
  }
}

public static void WaitForFullGCProc()
{
    while (true)
    {
    // Wait for a notification
    GCNotificationStatus s = GC.WaitForFullGCApproach();

    if (s == GCNotificationStatus.Succeeded)
    {
      // This call will direct new traffic
      // away from machine; wait for old
      // traffic to finish; then call
      // GC.Collect()
      OnFullGCApproachNotify();
    }
    
    // Wait for a notification of completion
    s = GC.WaitForFullGCComplete();
    if (s == GCNotificationStatus.Succeeded)
    {
      OnFullGCCompleteEndNotify();
    }
}



The changes in the server GC will probably only affect a small number of applications. However, the changes to the workstation GC (which is the default mode) will affect almost all .NET applications.
In all .NET Framework versions from 3.5SP1 and earlier, workstation GC used a concurrent collection method. This means that the GC can do most, but not all, of a Generation 2 collection without pausing managed code. It can’t, however, do a Generation 0 and Generation 1 collection at the same time as a Generation 2 collection.
CLR 4.0 changes that to support background collection, which can do a Generation 0 and Generation 1 collection at the same time as a Generation 2 collection. This means that now only unusual circumstances should lead to long latency times.

http://geekswithblogs.net/images/geekswithblogs_net/sdorman/WindowsLiveWriter/NET4.0GarbageCollectionChanges_C830/image_2.png

 These charts are from some performance testing done by Microsoft and presented during PDC which shows how the new background collection algorithm should greatly reduce the latency times.



Background Garbage Collection in CLR 4.0

Concurrent GC is being replaced by Background GC in CLR 4.0
Concurrent GC is the mode of the GC that you use in desktop applications for example.  The goal of the concurrent GC is to minimize pause time, and it does so by allowing you to still allocate while a GC is in progress (hence the concurrent part).
Concurrent GC is only available in workstation mode. 
In server mode (which is what you use in ASP.NET for example when you have multiple processors/cores), simplified all managed calls are paused while in a GC, which means that you can’t allocate anything.  This means that the process pauses slightly while in a GC but on the other hand what you loose in pause time, you gain in throughput as GCs are made by x number of GC threads concurrently, where x is #procs*#cores.
In concurrent GC you were allowed to allocate while in a GC, but you are not allowed to start another GC while in a GC. This in turn means that the maximum you are allowed to allocate while in a GC is whatever space you have left on one segment (currently 16 MB in workstation mode) minus anything that is already allocated there).
The difference in Background mode is that you are allowed to start a new GC (gen 0+1) while in a full background GC, and this allows you to even create a new segment to allocate in if necessary.  In short, the blocking that could occur before when you allocated all you could in one segment won’t happen anymore.

Background GC’s will be available in the Silverlight CLR as well
The CoreCLR uses the same GC as the regular CLR, so this means that Silverlight apps benefit from this as well…

As Server mode does not use concurrent GC this will not be available in Server GC
Having this in server mode would be incredibly cool as GCs can get pretty hefty, especially in 64 bit apps with very large heaps, but as Maoni mentions in the video and in the post, this work for the concurrent GC lays the foundation for the same work being done in the Server GC. Because of the complexities involved in doing this in Server GC though this is not included in v4.0.
If you do have a lot of latency due to heavy pause times during full garbage collections, there is a feature that was introduced in 3.5 SP1 that allows you to be notified when a full GC is about to occur.  You can then redirect to another server in a cluster for example while the GC occurs.     

I just want to mention that this not being in the Server GC does not mean that you should switch your server apps (asp.net etc.) to use workstation with concurrent,  Server GC is optimized for these scenarios and should still be used there.


Changes made in .Net 4.5:

(http://blogs.msdn.com/b/dotnet/archive/2011/10/04/large-object-heap-improvements-in-net-4-5.aspx)


Garbage collection is one of premiere features of the .NET managed coding platform. As the platform has become more capable, we’re seeing developers allocate more and more large objects. Since large objects are managed differently than small objects, we’ve heard a lot of feedback requesting improvement. Today’s post is by Surupa Biswas and Maoni Stephens from the garbage collection feature team. -- Brandon
The CLR manages two different heaps for allocation, the small object heap (SOH) and the large object heap (LOH). Any allocation greater than or equal to 85,000 bytes goes on the LOH. Copying large objects has a performance penalty, so the LOH is not compacted unlike the SOH. Another defining characteristic is that the LOH is only collected during a generation 2 collection. Together, these have the built-in assumption that large object allocations are infrequent.
Because the LOH is not compacted, memory management is more like a traditional allocator. The CLR keeps a free list of available blocks of memory. When allocating a large object, the runtime first looks at the free list to see if it will satisfy the allocation request. When the GC discovers adjacent objects that died, it combines the space they used into one free block which can be used for allocation. Because a lot of interaction with the free list takes place at the time of allocation, there are tradeoffs between speed and optimal placement of memory blocks.
A condition known as fragmentation can occur when nothing on the free list can be used. This can result in an out-of-memory exception despite the fact that collectively there is enough free memory. For developers who work with a lot of large objects, this error condition may be familiar. We’ve received a lot of feedback requesting for a solution to LOH fragmentation.

A Better LOH Allocator

In .NET 4.5, we made two improvements to the large object heap. First, we significantly improved the way the runtime manages the free list, thereby making more effective use of fragments. Now the memory allocator will revisit the memory fragments that earlier allocation couldn’t use. Second, when in server GC mode, the runtime balances LOH allocations between each heap. Prior to .NET 4.5, we only balanced the SOH. We’ve observed substantial improvements in some of our LOH allocation benchmarks as a result of both changes.
We’re also starting to collect telemetry about how the LOH is used. We’re tracking how often out-of-memory conditions in managed applications are due to LOH fragmentation. We’ll use this data to measure and improve memory management of real-world applications.
We still recommend some traditional techniques are for getting the best performance from the LOH. Many large objects are quite similar in nature, which creates the opportunity for object pooling. Frequently, types allocated on the LOH are byte-buffers that are filled by third-party libraries or devices. Rather than allocating and freeing the buffer, an object pool would let you reuse a previously-allocated buffer. Since fewer allocations and collections take place on the LOH, fragmentation is less likely to occur and the program’s performance is likely to improve.