[xmlsec] xmlsec-mscrypto code review (patch #3)
Aleksey Sanin
aleksey@aleksey.com
Sun, 21 Sep 2003 22:29:23 -0700
This is a multi-part message in MIME format.
--------------080208010709090501050509
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
Attached (and commited) is the last patch for src/mscrtypto/x509.c and
src/mscrtypto/x509vfy.c. I feel that I would need to do one more pass in
a week or so because there were too many changes on the first pass.
Meantime, I am going to think about hex<->dec conversion code.
Wouter, I would appreciate if you can take a look at my comments for
all 3 patches. There are few things that need clarification (see item 2)
bellow as an example).
And thanks for all your work! I can confirm that writing good code with
MS Crypto API is a hard job!
Aleksey
My comments
-----------------------------------------------------------------------------------------------------------------------------------------------------------
1) Fixed the problem with "check" in Windows Makefile and relative
paths in some tests
(raw x509 cert test, for example)
xmlSecMSCryptoX509StoreVerify() :
The function did check only one thing: there is a certificate that is
signed by another
one in the chain. IMHO, it's just a *BIG* security hole because the code
did not check
that cert is actually trusted (not ention that chains with more than two
certs should be
supported).
I re-wrote the code and now it does right thing. However, it still has a
couple problems:
- Currently the only "trusted" certs are ones loaded to xmlsec
directly (for
example, using xmlsec command line utility "--trusted" option). This
means that
code does not accept trusted certs in MS Crypto store as such. There
are some functions
that allow to check against trusted certs in MS Crypto store. But
MSDN says that
these functions are not available in Windows 95/98/Me and partially
not available
in NT 4.0 and Windows 2000. Anyone interested in more details feel
free to search
for "Certificate Chain Verification Functions" article in MSDN. For
me, it sounds
like it would be possible to use these new functions but I think it
would be good
to have a runtime version check:
- if it's old Windows then use current code;
- if it's new Windows with new functions then use some new code.
If you are interested in this functionality, feel free to contribute
- Curerntly the cert chain construction/verification function is
recursive. It's
not too difficult to use a loop instead but I don't think this is
important too
much. If you do then feel free to submit a patch
2) xmlSecMSCryptoKeyDataX509AdoptCert():
What is the reason why you duplicate cert passed to the function? I
removed this dup call
but it might be wrong.
3) xmlSecMSCryptoKeyDataX509GetCert():
ctx->hMemCert might not be intialized. I changed code to always create
this certs store
in the initialization function.
--------------080208010709090501050509
Content-Type: application/gzip;
name="mscrypto3.diff.gz"
Content-Transfer-Encoding: base64
Content-Disposition: inline;
filename="mscrypto3.diff.gz"
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
Nop++RetDmlanJoAAA==
--------------080208010709090501050509--