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= &parameter;
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