> -----Original Message-----
> Sent: Friday, November 26, 2010 3:16 PM
> To: mozilla's crypto code discussion list
> Subject: Certificate login in Firefox - how does it work?
> 
> Hello,
> I am developing a PKCS#11 module and currently I am having problems
> getting the certificate login working in Firefox.
> I load a page, click on login button and then Firefox starts
> communicating with my PKCS#11 module (the page wants its users to log
> in using their certificates). It lets me select a certificate from a
> list - well, I only have one so I select it and continue. Then, after
> some more communication, C_Sign is performed. However, this fails
> because I have no way of dealing with the data Firefox sends to my
> PKCS#11 module (the data to sign using the C_Sign function).
> Signing works properly in Thunderbird since it sends DER-encoded data
> (hash algorithm OID and the hash itself) and dealing with that is
> fairly straightforward.
> However, Firefox sends some seemingly-random 36-byte data. If I use the
> same algorithm as for Thunderbird (doesn't matter if SHA1 or MD5), the
> page fails to load and says "ssl_error_decrypt_error_alert". I don't
> know what should my PKCS#11 module provide for the page to accept it
> correctly and continue.
> Just FYI, there is a C# .NET program on the other end and trying
> SignData or SignHash to compute the value to return proved
> unsuccessful.
> Please, could anybody enlighten this issue to me?

Please see the TLS 1.0 RFC, Section 7.4.8. Certificate Verify [1] (or later, 
but TLS 1.0 is appropriate for the current release of NSS)

The handshake of a TLS 1.0 client using an RSA key is the concatenation of the 
SHA-1 and MD-5 hashes of the handshake messages exchanged since the Client 
Hello. If you're mapping this to CryptoAPI types (since you mentioned C#, I'm 
presuming some Windows & CryptoAPI familiarity), this is CALG_SSL3_SHAMD5 [2]. 
The 36 bytes comes from the size of MD5 (16 bytes) and SHA-1 (20 bytes). For 
other key types (eg: DSA, ECC), and depending on whether you're acting as a 
server or a client, the signature data may differ, see the appropriate RFCs 
(ie: [3])

The actual call is made as part of ssl3_SignHashes, assuming you're using SSL 
3.0/TLS 1.0. If you're using SSL 2.0, you've got more problems than hash 
signing. The implementation of this method is at [4].

While I've not spent time hacking with PCKS#11, my understanding is that the 
C_Sign function should be treating the input as raw/opaque, dictated by the 
mechanism that was used to initialize. If you're relying on the input being in 
a particular format, you need to ensure that format is specified in the 
underlying PKCS#11 specification for that mechanism, otherwise it sounds like 
you're making assumptions that shouldn't be made.

For SSL/TLS signatures, and for RSA keys, the mechanism passed is CKM_RSA_PKCS 
[5]. According to the PKCS#11 specification, this mechanism corresponds to 
computing the raw RSA signature over data, *excluding* computing the message 
digest or DigestInfo structure [6]. In CryptoAPI terms, this is the option 
CRYPT_NOHASHOID [7]. For what it's worth, I'm not aware of this flag being 
exposed by the .NET implementation, eg: 
System.Security.Cryptography.RSACryptoServiceProvider's SignHash. You'll likely 
need to do some marshalling to the native APIs if you're using C#.

And to save you a bit of trouble/pain: for CryptoAPI, you cannot simply sign 
raw data - you can only sign previously hashed data. I understand this to mean 
that you cannot write a pure PKCS#11 -> CryptoAPI mapper, whether .NET or at 
the raw Win32 level, because the CryptoAPI specifically forbids signing raw 
data of arbitrary length, while PKCS#11 permits it [7]. Your best bet, and a 
common approach for the specific case of TLS client authentication, is to 
combine CryptCreateHash/CryptSetHashParam(HP_HASHVAL)/CryptSignHash. Discussing 
that solution is veering off the topic from this list, but with that above 
information and some targeted searching, you should find a number of 
discussions on this approach. 

Hope that helps.

[1] http://www.ietf.org/rfc/rfc2246.txt
[2] http://msdn.microsoft.com/en-us/library/aa379865(VS.85).aspx
[3] http://www.ietf.org/rfc/rfc4492.txt
[4] http://mxr.mozilla.org/security/source/security/nss/lib/ssl/ssl3con.c#845
[5] 
http://mxr.mozilla.org/security/source/security/nss/lib/pk11wrap/pk11mech.c#1859
[6] ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-11/v2-20/pkcs-11v2-20.pdf , Section 
12.1.6.
[7] http://msdn.microsoft.com/en-us/library/aa380280(VS.85).aspx 



-- 
dev-tech-crypto mailing list
dev-tech-crypto@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-tech-crypto

Reply via email to