156083Skris/* crypto/rsa/rsa_sign.c */ 256083Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 356083Skris * All rights reserved. 456083Skris * 556083Skris * This package is an SSL implementation written 656083Skris * by Eric Young (eay@cryptsoft.com). 756083Skris * The implementation was written so as to conform with Netscapes SSL. 856083Skris * 956083Skris * This library is free for commercial and non-commercial use as long as 1056083Skris * the following conditions are aheared to. The following conditions 1156083Skris * apply to all code found in this distribution, be it the RC4, RSA, 1256083Skris * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1356083Skris * included with this distribution is covered by the same copyright terms 1456083Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com). 1556083Skris * 1656083Skris * Copyright remains Eric Young's, and as such any Copyright notices in 1756083Skris * the code are not to be removed. 1856083Skris * If this package is used in a product, Eric Young should be given attribution 1956083Skris * as the author of the parts of the library used. 2056083Skris * This can be in the form of a textual message at program startup or 2156083Skris * in documentation (online or textual) provided with the package. 2256083Skris * 2356083Skris * Redistribution and use in source and binary forms, with or without 2456083Skris * modification, are permitted provided that the following conditions 2556083Skris * are met: 2656083Skris * 1. Redistributions of source code must retain the copyright 2756083Skris * notice, this list of conditions and the following disclaimer. 2856083Skris * 2. Redistributions in binary form must reproduce the above copyright 2956083Skris * notice, this list of conditions and the following disclaimer in the 3056083Skris * documentation and/or other materials provided with the distribution. 3156083Skris * 3. All advertising materials mentioning features or use of this software 3256083Skris * must display the following acknowledgement: 3356083Skris * "This product includes cryptographic software written by 3456083Skris * Eric Young (eay@cryptsoft.com)" 3556083Skris * The word 'cryptographic' can be left out if the rouines from the library 3656083Skris * being used are not cryptographic related :-). 3756083Skris * 4. If you include any Windows specific code (or a derivative thereof) from 3856083Skris * the apps directory (application code) you must include an acknowledgement: 3956083Skris * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 4056083Skris * 4156083Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4256083Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4356083Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4456083Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4556083Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4656083Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4756083Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4856083Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4956083Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5056083Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5156083Skris * SUCH DAMAGE. 5256083Skris * 5356083Skris * The licence and distribution terms for any publically available version or 5456083Skris * derivative of this code cannot be changed. i.e. this code cannot simply be 5556083Skris * copied and put under another distribution licence 5656083Skris * [including the GNU Public Licence.] 5756083Skris */ 5856083Skris 5956083Skris#include <stdio.h> 6056083Skris#include "cryptlib.h" 6156083Skris#include <openssl/bn.h> 6256083Skris#include <openssl/rsa.h> 6356083Skris#include <openssl/objects.h> 6456083Skris#include <openssl/x509.h> 65238405Sjkim#include "rsa_locl.h" 6656083Skris 6759191Skris/* Size of an SSL signature: MD5+SHA1 */ 6859191Skris#define SSL_SIG_LENGTH 36 6959191Skris 70109998Smarkmint RSA_sign(int type, const unsigned char *m, unsigned int m_len, 7156083Skris unsigned char *sigret, unsigned int *siglen, RSA *rsa) 7256083Skris { 7356083Skris X509_SIG sig; 7456083Skris ASN1_TYPE parameter; 7556083Skris int i,j,ret=1; 76109998Smarkm unsigned char *p, *tmps = NULL; 77109998Smarkm const unsigned char *s = NULL; 7856083Skris X509_ALGOR algor; 7956083Skris ASN1_OCTET_STRING digest; 80238405Sjkim#ifdef OPENSSL_FIPS 81238405Sjkim if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) 82238405Sjkim && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) 83238405Sjkim { 84238405Sjkim RSAerr(RSA_F_RSA_SIGN, RSA_R_NON_FIPS_RSA_METHOD); 85238405Sjkim return 0; 86238405Sjkim } 87238405Sjkim#endif 88120631Snectar if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_sign) 89120631Snectar { 90120631Snectar return rsa->meth->rsa_sign(type, m, m_len, 91120631Snectar sigret, siglen, rsa); 92120631Snectar } 9359191Skris /* Special case: SSL signature, just check the length */ 9459191Skris if(type == NID_md5_sha1) { 9559191Skris if(m_len != SSL_SIG_LENGTH) { 9659191Skris RSAerr(RSA_F_RSA_SIGN,RSA_R_INVALID_MESSAGE_LENGTH); 9759191Skris return(0); 9856083Skris } 9959191Skris i = SSL_SIG_LENGTH; 10059191Skris s = m; 10159191Skris } else { 10259191Skris sig.algor= &algor; 10359191Skris sig.algor->algorithm=OBJ_nid2obj(type); 10459191Skris if (sig.algor->algorithm == NULL) 10559191Skris { 10659191Skris RSAerr(RSA_F_RSA_SIGN,RSA_R_UNKNOWN_ALGORITHM_TYPE); 10759191Skris return(0); 10859191Skris } 10959191Skris if (sig.algor->algorithm->length == 0) 11059191Skris { 11159191Skris RSAerr(RSA_F_RSA_SIGN,RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD); 11259191Skris return(0); 11359191Skris } 11459191Skris parameter.type=V_ASN1_NULL; 11559191Skris parameter.value.ptr=NULL; 11659191Skris sig.algor->parameter= ¶meter; 11756083Skris 11859191Skris sig.digest= &digest; 119109998Smarkm sig.digest->data=(unsigned char *)m; /* TMP UGLY CAST */ 12059191Skris sig.digest->length=m_len; 12156083Skris 12259191Skris i=i2d_X509_SIG(&sig,NULL); 12359191Skris } 12456083Skris j=RSA_size(rsa); 125109998Smarkm if (i > (j-RSA_PKCS1_PADDING_SIZE)) 12656083Skris { 12756083Skris RSAerr(RSA_F_RSA_SIGN,RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); 12856083Skris return(0); 12956083Skris } 13059191Skris if(type != NID_md5_sha1) { 131109998Smarkm tmps=(unsigned char *)OPENSSL_malloc((unsigned int)j+1); 132109998Smarkm if (tmps == NULL) 13359191Skris { 13459191Skris RSAerr(RSA_F_RSA_SIGN,ERR_R_MALLOC_FAILURE); 13559191Skris return(0); 13659191Skris } 137109998Smarkm p=tmps; 13859191Skris i2d_X509_SIG(&sig,&p); 139109998Smarkm s=tmps; 14059191Skris } 14156083Skris i=RSA_private_encrypt(i,s,sigret,rsa,RSA_PKCS1_PADDING); 14256083Skris if (i <= 0) 14356083Skris ret=0; 14456083Skris else 14556083Skris *siglen=i; 14656083Skris 14759191Skris if(type != NID_md5_sha1) { 148109998Smarkm OPENSSL_cleanse(tmps,(unsigned int)j+1); 149109998Smarkm OPENSSL_free(tmps); 15059191Skris } 15156083Skris return(ret); 15256083Skris } 15356083Skris 154279264Sdelphij/* 155279264Sdelphij * Check DigestInfo structure does not contain extraneous data by reencoding 156279264Sdelphij * using DER and checking encoding against original. 157279264Sdelphij */ 158279264Sdelphijstatic int rsa_check_digestinfo(X509_SIG *sig, const unsigned char *dinfo, int dinfolen) 159279264Sdelphij { 160279264Sdelphij unsigned char *der = NULL; 161279264Sdelphij int derlen; 162279264Sdelphij int ret = 0; 163279264Sdelphij derlen = i2d_X509_SIG(sig, &der); 164279264Sdelphij if (derlen <= 0) 165279264Sdelphij return 0; 166279264Sdelphij if (derlen == dinfolen && !memcmp(dinfo, der, derlen)) 167279264Sdelphij ret = 1; 168279264Sdelphij OPENSSL_cleanse(der, derlen); 169279264Sdelphij OPENSSL_free(der); 170279264Sdelphij return ret; 171279264Sdelphij } 172279264Sdelphij 173238405Sjkimint int_rsa_verify(int dtype, const unsigned char *m, 174238405Sjkim unsigned int m_len, 175238405Sjkim unsigned char *rm, size_t *prm_len, 176238405Sjkim const unsigned char *sigbuf, size_t siglen, 177238405Sjkim RSA *rsa) 17856083Skris { 17956083Skris int i,ret=0,sigtype; 180160814Ssimon unsigned char *s; 18156083Skris X509_SIG *sig=NULL; 18256083Skris 183238405Sjkim#ifdef OPENSSL_FIPS 184238405Sjkim if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) 185238405Sjkim && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) 186238405Sjkim { 187238405Sjkim RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_NON_FIPS_RSA_METHOD); 188238405Sjkim return 0; 189238405Sjkim } 190238405Sjkim#endif 191238405Sjkim 19256083Skris if (siglen != (unsigned int)RSA_size(rsa)) 19356083Skris { 194238405Sjkim RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_WRONG_SIGNATURE_LENGTH); 19556083Skris return(0); 19656083Skris } 19756083Skris 198238405Sjkim if((dtype == NID_md5_sha1) && rm) 199120631Snectar { 200238405Sjkim i = RSA_public_decrypt((int)siglen, 201238405Sjkim sigbuf,rm,rsa,RSA_PKCS1_PADDING); 202238405Sjkim if (i <= 0) 203238405Sjkim return 0; 204238405Sjkim *prm_len = i; 205238405Sjkim return 1; 206120631Snectar } 20759191Skris 20868651Skris s=(unsigned char *)OPENSSL_malloc((unsigned int)siglen); 20956083Skris if (s == NULL) 21056083Skris { 211238405Sjkim RSAerr(RSA_F_INT_RSA_VERIFY,ERR_R_MALLOC_FAILURE); 21256083Skris goto err; 21356083Skris } 214238405Sjkim if((dtype == NID_md5_sha1) && (m_len != SSL_SIG_LENGTH) ) { 215238405Sjkim RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_INVALID_MESSAGE_LENGTH); 216238405Sjkim goto err; 217238405Sjkim } 218238405Sjkim i=RSA_public_decrypt((int)siglen,sigbuf,s,rsa,RSA_PKCS1_PADDING); 219238405Sjkim 220238405Sjkim if (i <= 0) goto err; 221238405Sjkim /* Oddball MDC2 case: signature can be OCTET STRING. 222238405Sjkim * check for correct tag and length octets. 223238405Sjkim */ 224238405Sjkim if (dtype == NID_mdc2 && i == 18 && s[0] == 0x04 && s[1] == 0x10) 225194206Ssimon { 226238405Sjkim if (rm) 227194206Ssimon { 228238405Sjkim memcpy(rm, s + 2, 16); 229238405Sjkim *prm_len = 16; 230238405Sjkim ret = 1; 231194206Ssimon } 232238405Sjkim else if(memcmp(m, s + 2, 16)) 233238405Sjkim RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE); 234238405Sjkim else 235238405Sjkim ret = 1; 236194206Ssimon } 23756083Skris 23859191Skris /* Special case: SSL signature */ 23959191Skris if(dtype == NID_md5_sha1) { 24059191Skris if((i != SSL_SIG_LENGTH) || memcmp(s, m, SSL_SIG_LENGTH)) 241238405Sjkim RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE); 24259191Skris else ret = 1; 24359191Skris } else { 244160814Ssimon const unsigned char *p=s; 24559191Skris sig=d2i_X509_SIG(NULL,&p,(long)i); 24656083Skris 24759191Skris if (sig == NULL) goto err; 248162207Ssimon 249162207Ssimon /* Excess data can be used to create forgeries */ 250279264Sdelphij if(p != s+i || !rsa_check_digestinfo(sig, s, i)) 251162207Ssimon { 252238405Sjkim RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE); 253162207Ssimon goto err; 254162207Ssimon } 255162207Ssimon 256162207Ssimon /* Parameters to the signature algorithm can also be used to 257162207Ssimon create forgeries */ 258162207Ssimon if(sig->algor->parameter 259162914Ssimon && ASN1_TYPE_get(sig->algor->parameter) != V_ASN1_NULL) 260162207Ssimon { 261238405Sjkim RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE); 262162207Ssimon goto err; 263162207Ssimon } 264162207Ssimon 26559191Skris sigtype=OBJ_obj2nid(sig->algor->algorithm); 26656083Skris 26756083Skris 26859191Skris #ifdef RSA_DEBUG 26959191Skris /* put a backward compatibility flag in EAY */ 27059191Skris fprintf(stderr,"in(%s) expect(%s)\n",OBJ_nid2ln(sigtype), 27159191Skris OBJ_nid2ln(dtype)); 27259191Skris #endif 27359191Skris if (sigtype != dtype) 27456083Skris { 27559191Skris if (((dtype == NID_md5) && 27659191Skris (sigtype == NID_md5WithRSAEncryption)) || 27759191Skris ((dtype == NID_md2) && 27859191Skris (sigtype == NID_md2WithRSAEncryption))) 27959191Skris { 28059191Skris /* ok, we will let it through */ 281109998Smarkm#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16) 28259191Skris fprintf(stderr,"signature has problems, re-make with post SSLeay045\n"); 283109998Smarkm#endif 28459191Skris } 28559191Skris else 28659191Skris { 287238405Sjkim RSAerr(RSA_F_INT_RSA_VERIFY, 28859191Skris RSA_R_ALGORITHM_MISMATCH); 28959191Skris goto err; 29059191Skris } 29156083Skris } 292238405Sjkim if (rm) 293238405Sjkim { 294238405Sjkim const EVP_MD *md; 295238405Sjkim md = EVP_get_digestbynid(dtype); 296238405Sjkim if (md && (EVP_MD_size(md) != sig->digest->length)) 297238405Sjkim RSAerr(RSA_F_INT_RSA_VERIFY, 298238405Sjkim RSA_R_INVALID_DIGEST_LENGTH); 299238405Sjkim else 300238405Sjkim { 301238405Sjkim memcpy(rm, sig->digest->data, 302238405Sjkim sig->digest->length); 303238405Sjkim *prm_len = sig->digest->length; 304238405Sjkim ret = 1; 305238405Sjkim } 306238405Sjkim } 307238405Sjkim else if (((unsigned int)sig->digest->length != m_len) || 30859191Skris (memcmp(m,sig->digest->data,m_len) != 0)) 30956083Skris { 310238405Sjkim RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE); 31156083Skris } 31259191Skris else 31359191Skris ret=1; 31459191Skris } 31556083Skriserr: 31656083Skris if (sig != NULL) X509_SIG_free(sig); 317160814Ssimon if (s != NULL) 318160814Ssimon { 319160814Ssimon OPENSSL_cleanse(s,(unsigned int)siglen); 320160814Ssimon OPENSSL_free(s); 321160814Ssimon } 32256083Skris return(ret); 32356083Skris } 32456083Skris 325238405Sjkimint RSA_verify(int dtype, const unsigned char *m, unsigned int m_len, 326238405Sjkim const unsigned char *sigbuf, unsigned int siglen, 327238405Sjkim RSA *rsa) 328238405Sjkim { 329238405Sjkim 330238405Sjkim if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_verify) 331238405Sjkim { 332238405Sjkim return rsa->meth->rsa_verify(dtype, m, m_len, 333238405Sjkim sigbuf, siglen, rsa); 334238405Sjkim } 335238405Sjkim 336238405Sjkim return int_rsa_verify(dtype, m, m_len, NULL, NULL, sigbuf, siglen, rsa); 337238405Sjkim } 338