X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Frsa%2Frsa_sign.c;h=0be4ec7fb01f08b04e2e6558fc5a9df80d4c8a7a;hp=2a440901de3ee94f76b93ffe0e843a25a50fd222;hb=b7056b641418327cc82112cab236785e57a0b61b;hpb=f2a253e0ddd23c9a7601276f37b536fff53f3f8f diff --git a/crypto/rsa/rsa_sign.c b/crypto/rsa/rsa_sign.c index 2a440901de..0be4ec7fb0 100644 --- a/crypto/rsa/rsa_sign.c +++ b/crypto/rsa/rsa_sign.c @@ -62,7 +62,7 @@ #include #include #include -#include +#include "rsa_locl.h" /* Size of an SSL signature: MD5+SHA1 */ #define SSL_SIG_LENGTH 36 @@ -77,10 +77,11 @@ int RSA_sign(int type, const unsigned char *m, unsigned int m_len, const unsigned char *s = NULL; X509_ALGOR algor; ASN1_OCTET_STRING digest; - if((rsa->flags & RSA_FLAG_SIGN_VER) - && ENGINE_get_RSA(rsa->engine)->rsa_sign) - return ENGINE_get_RSA(rsa->engine)->rsa_sign(type, - m, m_len, sigret, siglen, rsa); + if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_sign) + { + return rsa->meth->rsa_sign(type, m, m_len, + sigret, siglen, rsa); + } /* Special case: SSL signature, just check the length */ if(type == NID_md5_sha1) { if(m_len != SSL_SIG_LENGTH) { @@ -113,7 +114,7 @@ int RSA_sign(int type, const unsigned char *m, unsigned int m_len, i=i2d_X509_SIG(&sig,NULL); } j=RSA_size(rsa); - if ((i-RSA_PKCS1_PADDING) > j) + if (i > (j-RSA_PKCS1_PADDING_SIZE)) { RSAerr(RSA_F_RSA_SIGN,RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); return(0); @@ -136,39 +137,47 @@ int RSA_sign(int type, const unsigned char *m, unsigned int m_len, *siglen=i; if(type != NID_md5_sha1) { - memset(tmps,0,(unsigned int)j+1); + OPENSSL_cleanse(tmps,(unsigned int)j+1); OPENSSL_free(tmps); } return(ret); } -int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len, - 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, size_t *prm_len, + const unsigned char *sigbuf, size_t siglen, + RSA *rsa) { int i,ret=0,sigtype; - unsigned char *p,*s; + unsigned char *s; X509_SIG *sig=NULL; if (siglen != (unsigned int)RSA_size(rsa)) { - RSAerr(RSA_F_RSA_VERIFY,RSA_R_WRONG_SIGNATURE_LENGTH); + RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_WRONG_SIGNATURE_LENGTH); return(0); } - if((rsa->flags & RSA_FLAG_SIGN_VER) - && ENGINE_get_RSA(rsa->engine)->rsa_verify) - return ENGINE_get_RSA(rsa->engine)->rsa_verify(dtype, - m, m_len, sigbuf, siglen, rsa); + if((dtype == NID_md5_sha1) && rm) + { + i = RSA_public_decrypt((int)siglen, + sigbuf,rm,rsa,RSA_PKCS1_PADDING); + if (i <= 0) + return 0; + *prm_len = i; + return 1; + } s=(unsigned char *)OPENSSL_malloc((unsigned int)siglen); if (s == NULL) { - RSAerr(RSA_F_RSA_VERIFY,ERR_R_MALLOC_FAILURE); + RSAerr(RSA_F_INT_RSA_VERIFY,ERR_R_MALLOC_FAILURE); goto err; } if((dtype == NID_md5_sha1) && (m_len != SSL_SIG_LENGTH) ) { - RSAerr(RSA_F_RSA_VERIFY,RSA_R_INVALID_MESSAGE_LENGTH); - return(0); + RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_INVALID_MESSAGE_LENGTH); + goto err; } i=RSA_public_decrypt((int)siglen,sigbuf,s,rsa,RSA_PKCS1_PADDING); @@ -177,13 +186,30 @@ int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len, /* Special case: SSL signature */ if(dtype == NID_md5_sha1) { if((i != SSL_SIG_LENGTH) || memcmp(s, m, SSL_SIG_LENGTH)) - RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE); + RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE); else ret = 1; } else { - p=s; + const unsigned char *p=s; 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_INT_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_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE); + goto err; + } + sigtype=OBJ_obj2nid(sig->algor->algorithm); @@ -206,23 +232,54 @@ int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len, } else { - RSAerr(RSA_F_RSA_VERIFY, + RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_ALGORITHM_MISMATCH); goto err; } } - if ( ((unsigned int)sig->digest->length != m_len) || + if (rm) + { + const EVP_MD *md; + md = EVP_get_digestbynid(dtype); + if (md && (EVP_MD_size(md) != sig->digest->length)) + RSAerr(RSA_F_INT_RSA_VERIFY, + RSA_R_INVALID_DIGEST_LENGTH); + else + { + memcpy(rm, sig->digest->data, + sig->digest->length); + *prm_len = sig->digest->length; + ret = 1; + } + } + else if (((unsigned int)sig->digest->length != m_len) || (memcmp(m,sig->digest->data,m_len) != 0)) { - RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE); + RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE); } else ret=1; } err: if (sig != NULL) X509_SIG_free(sig); - memset(s,0,(unsigned int)siglen); - OPENSSL_free(s); + if (s != NULL) + { + OPENSSL_cleanse(s,(unsigned int)siglen); + OPENSSL_free(s); + } return(ret); } +int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len, + const unsigned char *sigbuf, unsigned int siglen, + RSA *rsa) + { + + if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_verify) + { + return rsa->meth->rsa_verify(dtype, m, m_len, + sigbuf, siglen, rsa); + } + + return int_rsa_verify(dtype, m, m_len, NULL, NULL, sigbuf, siglen, rsa); + }