Weblog
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)
| Section | Test Cases | RFC3280 | MS[1] | Mono | |
| 4.6.3 | Verifying Name Constraints | 11 | 5 | 11 | [2] |
| 4.6.5 | Verifying Path With Self-Issued Certs | 8 | 1 | 4 | [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 :-)
Notes
[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)
| Section | Test Cases | RFC3280 | MS[1] | Mono | |
| 4.6.4 | Basic Certificate Revocation Test | 21 | 20 | 21 | [2] |
| 4.6.6 | Verifying Basic Constraints | 17 | 14 | 17 | [3] |
| 4.6.7 | Key Usage | 5 | 3 | 5 | [4] |
| 4.6.16 | Private Certificate Extensions | 2 | 1 | 2 | [5] |
Notes
[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)
| Section | Test Cases | RFC3280 | MS[1] | Mono | |
| 4.6.1 | Signature Verification | 6 | 6 | 6 | |
| 4.6.2 | Validity Period | 8 | 8 | 8 |
Notes
[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.
