On Wed, Jul 16, 2008, Arnaud Ebalard wrote: > Hi, > > This is a resend [1], please redirect me if I am off-topic. > > while modifying some IKE code to use OpenSSL in order to have RSA > signature done by engines (support via opensc on Linux, more > specifically eGate and eToken PRO devices), I encountered the following > issue. > > RSA_sign() has a 'type' argument that describes the hash that was used > for generating the data. It is used to add digest info before padding > and private key encryption occur to complete the signature. There is a > specific case in the code, namely for SSL which does not use a digest > info but a fixed length 36 bytes hash value (concatenation of md5 and > sha1 hashes). > > IKEv1 has the same kind of requirement. RFC 2409 has the following in > Section 5.1: > > Since the hash algorithm used is already known there is no need to > encode its OID into the signature. In addition, there is no binding > between the OIDs used for RSA signatures in PKCS #1 and those used in > this document. Therefore, RSA signatures MUST be encoded as a private > key encryption in PKCS #1 format and not as a signature in PKCS #1 > format (which includes the OID of the hash algorithm). DSS signatures > MUST be encoded as r followed by s. > > Note that I cannot call RSA_private_encrypt() as a workaround because > the devices do not support it (even if on tokens, I have added specific > keys that allow decryption) and it does not seem the expected way to do > it. > > At the moment, I am using NID_md5_sha1 type for RSA_sign() and have > temporarily deactivated the length check (36 bytes) in libp11 code but > this is also a temporary workaround. What would be the correct way to > handle that issue? Initially, I wanted to add a new NID_IKE_digest type > that would make RSA_sign() behave like with NID_md5_sha1 but with a > relaxed check on the length. Because the removal of the length check > basically provides access to private key encryption via signature > primitive, I thought I should ask before. >
Well RSA_private_encrypt() despite its name is a signing operation. There is a PKCS#11 equivalent (C_Sign and the CKM_RSA_PKCS mechanism) though some tokens don't support it fully but emulate it in such a way that it only works for a fixed range of digests. If a token supports it but the PKCS#11 ENGINE has no equivalent that's an ENGINE implementation issue. If the actual token doesn't fully support an RSA_private_encrypt() equivalent then you are SOL. Using RSA_sign() with NID_md5_sha1 had the problem that the length is incorrect which is why you need to disable the length check. This has some security implications: for example the well publicised exponent 3 issue. Steve. -- Dr Stephen N. Henson. Email, S/MIME and PGP keys: see homepage OpenSSL project core developer and freelance consultant. Homepage: http://www.drh-consultancy.demon.co.uk ______________________________________________________________________ OpenSSL Project http://www.openssl.org Development Mailing List [email protected] Automated List Manager [EMAIL PROTECTED]
