]> CyberLeo.Net >> Repos - FreeBSD/releng/9.3.git/blob - crypto/openssl/crypto/rsa/rsa_sign.c
Fix multiple OpenSSL vulnerabilities.
[FreeBSD/releng/9.3.git] / crypto / openssl / crypto / rsa / rsa_sign.c
1 /* crypto/rsa/rsa_sign.c */
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3  * All rights reserved.
4  *
5  * This package is an SSL implementation written
6  * by Eric Young (eay@cryptsoft.com).
7  * The implementation was written so as to conform with Netscapes SSL.
8  *
9  * This library is free for commercial and non-commercial use as long as
10  * the following conditions are aheared to.  The following conditions
11  * apply to all code found in this distribution, be it the RC4, RSA,
12  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13  * included with this distribution is covered by the same copyright terms
14  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15  *
16  * Copyright remains Eric Young's, and as such any Copyright notices in
17  * the code are not to be removed.
18  * If this package is used in a product, Eric Young should be given attribution
19  * as the author of the parts of the library used.
20  * This can be in the form of a textual message at program startup or
21  * in documentation (online or textual) provided with the package.
22  *
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  * 1. Redistributions of source code must retain the copyright
27  *    notice, this list of conditions and the following disclaimer.
28  * 2. Redistributions in binary form must reproduce the above copyright
29  *    notice, this list of conditions and the following disclaimer in the
30  *    documentation and/or other materials provided with the distribution.
31  * 3. All advertising materials mentioning features or use of this software
32  *    must display the following acknowledgement:
33  *    "This product includes cryptographic software written by
34  *     Eric Young (eay@cryptsoft.com)"
35  *    The word 'cryptographic' can be left out if the rouines from the library
36  *    being used are not cryptographic related :-).
37  * 4. If you include any Windows specific code (or a derivative thereof) from
38  *    the apps directory (application code) you must include an acknowledgement:
39  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40  *
41  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  *
53  * The licence and distribution terms for any publically available version or
54  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55  * copied and put under another distribution licence
56  * [including the GNU Public Licence.]
57  */
58
59 #include <stdio.h>
60 #include "cryptlib.h"
61 #include <openssl/bn.h>
62 #include <openssl/rsa.h>
63 #include <openssl/objects.h>
64 #include <openssl/x509.h>
65
66 /* Size of an SSL signature: MD5+SHA1 */
67 #define SSL_SIG_LENGTH  36
68
69 int RSA_sign(int type, const unsigned char *m, unsigned int m_len,
70              unsigned char *sigret, unsigned int *siglen, RSA *rsa)
71 {
72     X509_SIG sig;
73     ASN1_TYPE parameter;
74     int i, j, ret = 1;
75     unsigned char *p, *tmps = NULL;
76     const unsigned char *s = NULL;
77     X509_ALGOR algor;
78     ASN1_OCTET_STRING digest;
79     if ((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_sign) {
80         return rsa->meth->rsa_sign(type, m, m_len, sigret, siglen, rsa);
81     }
82     /* Special case: SSL signature, just check the length */
83     if (type == NID_md5_sha1) {
84         if (m_len != SSL_SIG_LENGTH) {
85             RSAerr(RSA_F_RSA_SIGN, RSA_R_INVALID_MESSAGE_LENGTH);
86             return (0);
87         }
88         i = SSL_SIG_LENGTH;
89         s = m;
90     } else {
91         /* NB: in FIPS mode block anything that isn't a TLS signature */
92 #ifdef OPENSSL_FIPS
93         if (FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) {
94             RSAerr(RSA_F_RSA_SIGN, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
95             return 0;
96         }
97 #endif
98         sig.algor = &algor;
99         sig.algor->algorithm = OBJ_nid2obj(type);
100         if (sig.algor->algorithm == NULL) {
101             RSAerr(RSA_F_RSA_SIGN, RSA_R_UNKNOWN_ALGORITHM_TYPE);
102             return (0);
103         }
104         if (sig.algor->algorithm->length == 0) {
105             RSAerr(RSA_F_RSA_SIGN,
106                    RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD);
107             return (0);
108         }
109         parameter.type = V_ASN1_NULL;
110         parameter.value.ptr = NULL;
111         sig.algor->parameter = &parameter;
112
113         sig.digest = &digest;
114         sig.digest->data = (unsigned char *)m; /* TMP UGLY CAST */
115         sig.digest->length = m_len;
116
117         i = i2d_X509_SIG(&sig, NULL);
118     }
119     j = RSA_size(rsa);
120     if (i > (j - RSA_PKCS1_PADDING_SIZE)) {
121         RSAerr(RSA_F_RSA_SIGN, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY);
122         return (0);
123     }
124     if (type != NID_md5_sha1) {
125         tmps = (unsigned char *)OPENSSL_malloc((unsigned int)j + 1);
126         if (tmps == NULL) {
127             RSAerr(RSA_F_RSA_SIGN, ERR_R_MALLOC_FAILURE);
128             return (0);
129         }
130         p = tmps;
131         i2d_X509_SIG(&sig, &p);
132         s = tmps;
133     }
134 #ifdef OPENSSL_FIPS
135     /* Bypass algorithm blocking: this is allowed if we get this far */
136     i = rsa->meth->rsa_priv_enc(i, s, sigret, rsa, RSA_PKCS1_PADDING);
137 #else
138     i = RSA_private_encrypt(i, s, sigret, rsa, RSA_PKCS1_PADDING);
139 #endif
140     if (i <= 0)
141         ret = 0;
142     else
143         *siglen = i;
144
145     if (type != NID_md5_sha1) {
146         OPENSSL_cleanse(tmps, (unsigned int)j + 1);
147         OPENSSL_free(tmps);
148     }
149     return (ret);
150 }
151
152 /*
153  * Check DigestInfo structure does not contain extraneous data by reencoding
154  * using DER and checking encoding against original.
155  */
156 static int rsa_check_digestinfo(X509_SIG *sig, const unsigned char *dinfo,
157                                 int dinfolen)
158 {
159     unsigned char *der = NULL;
160     int derlen;
161     int ret = 0;
162     derlen = i2d_X509_SIG(sig, &der);
163     if (derlen <= 0)
164         return 0;
165     if (derlen == dinfolen && !memcmp(dinfo, der, derlen))
166         ret = 1;
167     OPENSSL_cleanse(der, derlen);
168     OPENSSL_free(der);
169     return ret;
170 }
171
172 int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len,
173                unsigned char *sigbuf, unsigned int siglen, RSA *rsa)
174 {
175     int i, ret = 0, sigtype;
176     unsigned char *s;
177     X509_SIG *sig = NULL;
178
179     if (siglen != (unsigned int)RSA_size(rsa)) {
180         RSAerr(RSA_F_RSA_VERIFY, RSA_R_WRONG_SIGNATURE_LENGTH);
181         return (0);
182     }
183
184     if ((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_verify) {
185         return rsa->meth->rsa_verify(dtype, m, m_len, sigbuf, siglen, rsa);
186     }
187
188     s = (unsigned char *)OPENSSL_malloc((unsigned int)siglen);
189     if (s == NULL) {
190         RSAerr(RSA_F_RSA_VERIFY, ERR_R_MALLOC_FAILURE);
191         goto err;
192     }
193     if (dtype == NID_md5_sha1) {
194         if (m_len != SSL_SIG_LENGTH) {
195             RSAerr(RSA_F_RSA_VERIFY, RSA_R_INVALID_MESSAGE_LENGTH);
196             goto err;
197         }
198     }
199     /* NB: in FIPS mode block anything that isn't a TLS signature */
200 #ifdef OPENSSL_FIPS
201     else if (FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) {
202         RSAerr(RSA_F_RSA_VERIFY, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
203         return 0;
204     }
205     /* Bypass algorithm blocking: this is allowed */
206     i = rsa->meth->rsa_pub_dec((int)siglen, sigbuf, s, rsa,
207                                RSA_PKCS1_PADDING);
208 #else
209     i = RSA_public_decrypt((int)siglen, sigbuf, s, rsa, RSA_PKCS1_PADDING);
210 #endif
211
212     if (i <= 0)
213         goto err;
214
215     /* Special case: SSL signature */
216     if (dtype == NID_md5_sha1) {
217         if ((i != SSL_SIG_LENGTH) || memcmp(s, m, SSL_SIG_LENGTH))
218             RSAerr(RSA_F_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
219         else
220             ret = 1;
221     } else {
222         const unsigned char *p = s;
223         sig = d2i_X509_SIG(NULL, &p, (long)i);
224
225         if (sig == NULL)
226             goto err;
227
228         /* Excess data can be used to create forgeries */
229         if (p != s + i || !rsa_check_digestinfo(sig, s, i)) {
230             RSAerr(RSA_F_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
231             goto err;
232         }
233
234         /*
235          * Parameters to the signature algorithm can also be used to create
236          * forgeries
237          */
238         if (sig->algor->parameter
239             && ASN1_TYPE_get(sig->algor->parameter) != V_ASN1_NULL) {
240             RSAerr(RSA_F_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
241             goto err;
242         }
243
244         sigtype = OBJ_obj2nid(sig->algor->algorithm);
245
246 #ifdef RSA_DEBUG
247         /* put a backward compatibility flag in EAY */
248         fprintf(stderr, "in(%s) expect(%s)\n", OBJ_nid2ln(sigtype),
249                 OBJ_nid2ln(dtype));
250 #endif
251         if (sigtype != dtype) {
252             if (((dtype == NID_md5) &&
253                  (sigtype == NID_md5WithRSAEncryption)) ||
254                 ((dtype == NID_md2) &&
255                  (sigtype == NID_md2WithRSAEncryption))) {
256                 /* ok, we will let it through */
257 #if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16)
258                 fprintf(stderr,
259                         "signature has problems, re-make with post SSLeay045\n");
260 #endif
261             } else {
262                 RSAerr(RSA_F_RSA_VERIFY, RSA_R_ALGORITHM_MISMATCH);
263                 goto err;
264             }
265         }
266         if (((unsigned int)sig->digest->length != m_len) ||
267             (memcmp(m, sig->digest->data, m_len) != 0)) {
268             RSAerr(RSA_F_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
269         } else
270             ret = 1;
271     }
272  err:
273     if (sig != NULL)
274         X509_SIG_free(sig);
275     if (s != NULL) {
276         OPENSSL_cleanse(s, (unsigned int)siglen);
277         OPENSSL_free(s);
278     }
279     return (ret);
280 }