> -----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