Jump to navigation

Poupou's Corner of the Web

Looking for perfect security? Try a wireless brick.
Otherwise you may find some unperfect stuff here...


Some extra alpha bits

I just had an interesting bug wrt handling alpha in the System.Drawing.Imaging.ColorMatrix class. The most surprising fact is that running unit tests actually confused me, instead of helping me find the issue (but don't worry I'm still a big fan), because some unit tests (namely System.Drawing.Brushes) were destructive (i.e. the Brushes.* properties were unusable, wrong color, afterward). Eventually running only a subset of the tests (instead of the whole System.Drawing test suite) revealed the treachery.

The fix itself was simple, well once I stopped doubting the code itself and looked at libgdiplus/cairo interaction. One must remember, or (re)learn, that Cairo use pre-multipled alpha for it's ARGB buffers. When fixing such bugs it's clear, very early, that it will require a lot of small changes, compile & test cycles. This makes it a great opportunity to try/time some optimizations on each iteration...

Running the original code, while drawing 32768 times the bitmap using the ColorMatrix, required:
Time: 1:03.5967720 seconds

First I removed an indirection to get matrix values as it also makes the code easier to read and added a check for 100% transparency results. However this last optimization not used in the benchmarked code.
Time: 0:58.8520390 seconds

Then I removed the call to GdipBitmapGetPixel because, despite the removed comment about very little penalty in performance, there is just too many checks that we know, for sure, as valid not to be required in the loops.
Time: 0:54.7671440 seconds

Also I removed the call to GdipBitmapSetPixel for the same (previous) reason and also to avoid computing, again, the pixel memory position (it won't move).
Time: 0:48.3151360 seconds

Finally a few other minor changes, while tracking a memory corruption bug I (of course) introduced during the previous optimizations ;-). Luckily I just don't change much in libgdiplus anymore without running valgrind on the System.Drawing unit tests...
Final time: 0:44.1136470 seconds

So a reduction of about 30%, not so bad for an early (and unplanned) xmas present :-)

12/21/2006 21:23:17 | Comments | Permalink

in chains: The Ugly

and then there's the ugly stuff. Things like having a X500DistinguishedName class able to decode (convert to string) DN using 10 different flags defined in X500DistinguishedNameFlags. Combine flags as you wish, even add String.Compare for case insensitiveness, you can't compare DN with them - it just doesn't deal with whitespaces correctly.

With respect to RFC3280 interoperability, X509Chain never checks for matching (end entity) issuer name versus (ca) subject name, nor can it correctly build a chain that includes self-issued certificates (unless they are the root certificate).

Ugly results (out of 16 sections)

SectionTest CasesRFC3280MS[1]Mono 
4.6.3Verifying Name Constraints11511[2]
4.6.5Verifying Path With Self-Issued Certs814[3]

It's not just Microsoft's fault. X.509, even profiled in RFC3280, is a complex beast. In many ways too complex for what it offer back. A good proof is that SSL/TLS, the most visible use of X.509, works without supporting a lot of it. Anyone remotely interested in this should read, the old but still true, X509 Style Guide by Peter Gutmann. Read it completely (if you're crazy) or just read it's quotes :-)


[1] Tested under Windows XP service pack 2 - YMMV

[2] MS doesn't seems to compare Issuer/Subject names in the chain. The working tests are "valid" test cases.

[3] Mono doesn't support using a different CA to produce CRL. MS has problems building chains with non-root self-issued certificates.

The source code, and unit tests, are now in SVN for C3Y people (like me ;-)

12/7/2006 17:02:37 | Comments | Permalink

in chains: The Bad

While the design of X509Chain itself is good, the rest of the (greatly updated in 2.0) System.Security.Cryptography.X509Certficates namespace still lacks a lot of things. How much ? well more than enough to make it impossible, without rewriting a large amount of code, to write your own X509Chain replacement.

Maybe X509Certificate3, and a few other X509*2 classes, will be better than the previous incarnations ? E.g. X509Certificate in Fx1.0, another X509Certificate in WSE1 (and probably updated in WSE2 and WSE3), X509Certificate2 in Fx2.0... Time will tell, until then be glad that Mono has it's own managed X509Certificate in Mono.Security.dll :-)

Some bad news (for a specific implementation) on RFC3280 compatibility too...

Bad results (out of 16 sections)

SectionTest CasesRFC3280MS[1]Mono 
4.6.4Basic Certificate Revocation Test212021[2]
4.6.6Verifying Basic Constraints171417[3]
4.6.7Key Usage535[4]
4.6.16Private Certificate Extensions212[5]


[1] Tested under Windows XP service pack 2 - YMMV

[2] MS can report RevocationStatusUnknown for a Revoked certificate (if the CRL includes unknown critical extensions)

[3] MS looks for CRL on the self-issued certificate in the chain (it's not the right one to look)

[4] MS doesn't check for the CrlSign key usage (on the CRL's issuer certificate) when validating a CRL

[5] MS report success with certificates containing unknown critical extensions.

and I'm not totally out of bad news...

12/6/2006 16:30:47 | Comments | Permalink

in chains: The Good

Recently I've been buzy completing X.509 support in the 2.0 class libraries. This, somewhat basic, stuff is required to complete S/MIME (Pkcs namespace inside System.Security.dll) and more CardSpace foo.

Right now I'm implementing X509Chain. This is a small class that nicely hides a 129 pages RFC (3280) that references all kind of stuff, like X.500. I've known for a long time that this step was required and would be somewhat frustrating. I wasn't totally wrong ;-)

Now that the subject is introduced, let's start with what's good...

First we have test cases, more a full test suite, thanks to NIST. In 2004 NIST released the Public Key Interoperability Test Suite (PKITS) for Certificate Path Validation (where path == chain). You can download the test data along with a nice, 293 pages, document.

Next we have the design. In the 2.0 framework System.Security.Cryptography.X509Certificates.X509Chain is exposed, i.e. it's not a new feature but it was totally hidden previously (mostly because it resides in, the unmanaged, CryptoAPI) and replaceable, i.e. you can supply an alternative implementation to be used as the default (using CryptoConfig and machine.config).

Other good news is that, for some cases, it seems that MS follows RFC3280. That one is more complex than it looks like because it's not a framework functionality, it's part of CryptoAPI. So every Windows version has an updated CryptoAPI that is (or should be) more RFC3280 compliant than the previous ones (I'm keeping not-good news for another post ;-).

Current results (out of 16 sections)

SectionTest CasesRFC3280MS[1]Mono 
4.6.1Signature Verification666 
4.6.2Validity Period888 

[1] Tested under Windows XP service pack 2 - YMMV

Sadly I may have run out of good news...

12/5/2006 20:53:41 | Comments | Permalink

The views expressed on this website/weblog are mine alone and do not necessarily reflect the views of my employer.