Avoid PKCS #1 v1.5 signature attack discovered by Daniel Bleichenbacher
[openssl.git] / crypto / rsa / rsa_sign.c
index 7dae5c84157e12ab0633cad8021923187b2a1f96..e1b1714210f122d2fc9d84a3daa00d2d80721cce 100644 (file)
@@ -62,6 +62,7 @@
 #include <openssl/rsa.h>
 #include <openssl/objects.h>
 #include <openssl/x509.h>
 #include <openssl/rsa.h>
 #include <openssl/objects.h>
 #include <openssl/x509.h>
+#include "rsa_locl.h"
 
 /* Size of an SSL signature: MD5+SHA1 */
 #define SSL_SIG_LENGTH 36
 
 /* Size of an SSL signature: MD5+SHA1 */
 #define SSL_SIG_LENGTH 36
@@ -142,10 +143,11 @@ int RSA_sign(int type, const unsigned char *m, unsigned int m_len,
        return(ret);
        }
 
        return(ret);
        }
 
-int int_rsa_verify(int dtype, const unsigned char *m, unsigned int m_len,
-               unsigned char *rm, unsigned int *prm_len,
-               const unsigned char *sigbuf, unsigned int siglen,
-               RSA *rsa)
+int int_rsa_verify(int dtype, const unsigned char *m,
+                         unsigned int m_len,
+                         unsigned char *rm, unsigned int *prm_len,
+                         const unsigned char *sigbuf, unsigned int siglen,
+                         RSA *rsa)
        {
        int i,ret=0,sigtype;
        unsigned char *s;
        {
        int i,ret=0,sigtype;
        unsigned char *s;
@@ -191,6 +193,23 @@ int int_rsa_verify(int dtype, const unsigned char *m, unsigned int m_len,
                sig=d2i_X509_SIG(NULL,&p,(long)i);
 
                if (sig == NULL) goto err;
                sig=d2i_X509_SIG(NULL,&p,(long)i);
 
                if (sig == NULL) goto err;
+
+               /* Excess data can be used to create forgeries */
+               if(p != s+i)
+                       {
+                       RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
+                       goto err;
+                       }
+
+               /* Parameters to the signature algorithm can also be used to
+                  create forgeries */
+               if(sig->algor->parameter
+                  && ASN1_TYPE_get(sig->algor->parameter) != V_ASN1_NULL)
+                       {
+                       RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
+                       goto err;
+                       }
+
                sigtype=OBJ_obj2nid(sig->algor->algorithm);
 
 
                sigtype=OBJ_obj2nid(sig->algor->algorithm);