rsa_sign.c revision 280297
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.
8280297Sjkim *
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).
15280297Sjkim *
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.
22280297Sjkim *
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 :-).
37280297Sjkim * 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)"
40280297Sjkim *
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.
52280297Sjkim *
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 */
68280297Sjkim#define SSL_SIG_LENGTH  36
6959191Skris
70109998Smarkmint RSA_sign(int type, const unsigned char *m, unsigned int m_len,
71280297Sjkim             unsigned char *sigret, unsigned int *siglen, RSA *rsa)
72280297Sjkim{
73280297Sjkim    X509_SIG sig;
74280297Sjkim    ASN1_TYPE parameter;
75280297Sjkim    int i, j, ret = 1;
76280297Sjkim    unsigned char *p, *tmps = NULL;
77280297Sjkim    const unsigned char *s = NULL;
78280297Sjkim    X509_ALGOR algor;
79280297Sjkim    ASN1_OCTET_STRING digest;
80238405Sjkim#ifdef OPENSSL_FIPS
81280297Sjkim    if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD)
82280297Sjkim        && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) {
83280297Sjkim        RSAerr(RSA_F_RSA_SIGN, RSA_R_NON_FIPS_RSA_METHOD);
84280297Sjkim        return 0;
85280297Sjkim    }
86238405Sjkim#endif
87280297Sjkim    if ((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_sign) {
88280297Sjkim        return rsa->meth->rsa_sign(type, m, m_len, sigret, siglen, rsa);
89280297Sjkim    }
90280297Sjkim    /* Special case: SSL signature, just check the length */
91280297Sjkim    if (type == NID_md5_sha1) {
92280297Sjkim        if (m_len != SSL_SIG_LENGTH) {
93280297Sjkim            RSAerr(RSA_F_RSA_SIGN, RSA_R_INVALID_MESSAGE_LENGTH);
94280297Sjkim            return (0);
95280297Sjkim        }
96280297Sjkim        i = SSL_SIG_LENGTH;
97280297Sjkim        s = m;
98280297Sjkim    } else {
99280297Sjkim        sig.algor = &algor;
100280297Sjkim        sig.algor->algorithm = OBJ_nid2obj(type);
101280297Sjkim        if (sig.algor->algorithm == NULL) {
102280297Sjkim            RSAerr(RSA_F_RSA_SIGN, RSA_R_UNKNOWN_ALGORITHM_TYPE);
103280297Sjkim            return (0);
104280297Sjkim        }
105280297Sjkim        if (sig.algor->algorithm->length == 0) {
106280297Sjkim            RSAerr(RSA_F_RSA_SIGN,
107280297Sjkim                   RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD);
108280297Sjkim            return (0);
109280297Sjkim        }
110280297Sjkim        parameter.type = V_ASN1_NULL;
111280297Sjkim        parameter.value.ptr = NULL;
112280297Sjkim        sig.algor->parameter = &parameter;
11356083Skris
114280297Sjkim        sig.digest = &digest;
115280297Sjkim        sig.digest->data = (unsigned char *)m; /* TMP UGLY CAST */
116280297Sjkim        sig.digest->length = m_len;
11756083Skris
118280297Sjkim        i = i2d_X509_SIG(&sig, NULL);
119280297Sjkim    }
120280297Sjkim    j = RSA_size(rsa);
121280297Sjkim    if (i > (j - RSA_PKCS1_PADDING_SIZE)) {
122280297Sjkim        RSAerr(RSA_F_RSA_SIGN, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY);
123280297Sjkim        return (0);
124280297Sjkim    }
125280297Sjkim    if (type != NID_md5_sha1) {
126280297Sjkim        tmps = (unsigned char *)OPENSSL_malloc((unsigned int)j + 1);
127280297Sjkim        if (tmps == NULL) {
128280297Sjkim            RSAerr(RSA_F_RSA_SIGN, ERR_R_MALLOC_FAILURE);
129280297Sjkim            return (0);
130280297Sjkim        }
131280297Sjkim        p = tmps;
132280297Sjkim        i2d_X509_SIG(&sig, &p);
133280297Sjkim        s = tmps;
134280297Sjkim    }
135280297Sjkim    i = RSA_private_encrypt(i, s, sigret, rsa, RSA_PKCS1_PADDING);
136280297Sjkim    if (i <= 0)
137280297Sjkim        ret = 0;
138280297Sjkim    else
139280297Sjkim        *siglen = i;
14056083Skris
141280297Sjkim    if (type != NID_md5_sha1) {
142280297Sjkim        OPENSSL_cleanse(tmps, (unsigned int)j + 1);
143280297Sjkim        OPENSSL_free(tmps);
144280297Sjkim    }
145280297Sjkim    return (ret);
146280297Sjkim}
14756083Skris
148273144Sjkim/*
149273144Sjkim * Check DigestInfo structure does not contain extraneous data by reencoding
150280297Sjkim * using DER and checking encoding against original.
151273144Sjkim */
152280297Sjkimstatic int rsa_check_digestinfo(X509_SIG *sig, const unsigned char *dinfo,
153280297Sjkim                                int dinfolen)
154280297Sjkim{
155280297Sjkim    unsigned char *der = NULL;
156280297Sjkim    int derlen;
157280297Sjkim    int ret = 0;
158280297Sjkim    derlen = i2d_X509_SIG(sig, &der);
159280297Sjkim    if (derlen <= 0)
160280297Sjkim        return 0;
161280297Sjkim    if (derlen == dinfolen && !memcmp(dinfo, der, derlen))
162280297Sjkim        ret = 1;
163280297Sjkim    OPENSSL_cleanse(der, derlen);
164280297Sjkim    OPENSSL_free(der);
165280297Sjkim    return ret;
166280297Sjkim}
167273144Sjkim
168238405Sjkimint int_rsa_verify(int dtype, const unsigned char *m,
169280297Sjkim                   unsigned int m_len,
170280297Sjkim                   unsigned char *rm, size_t *prm_len,
171280297Sjkim                   const unsigned char *sigbuf, size_t siglen, RSA *rsa)
172280297Sjkim{
173280297Sjkim    int i, ret = 0, sigtype;
174280297Sjkim    unsigned char *s;
175280297Sjkim    X509_SIG *sig = NULL;
17656083Skris
177238405Sjkim#ifdef OPENSSL_FIPS
178280297Sjkim    if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD)
179280297Sjkim        && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) {
180280297Sjkim        RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_NON_FIPS_RSA_METHOD);
181280297Sjkim        return 0;
182280297Sjkim    }
183238405Sjkim#endif
184238405Sjkim
185280297Sjkim    if (siglen != (unsigned int)RSA_size(rsa)) {
186280297Sjkim        RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_WRONG_SIGNATURE_LENGTH);
187280297Sjkim        return (0);
188280297Sjkim    }
18956083Skris
190280297Sjkim    if ((dtype == NID_md5_sha1) && rm) {
191280297Sjkim        i = RSA_public_decrypt((int)siglen,
192280297Sjkim                               sigbuf, rm, rsa, RSA_PKCS1_PADDING);
193280297Sjkim        if (i <= 0)
194280297Sjkim            return 0;
195280297Sjkim        *prm_len = i;
196280297Sjkim        return 1;
197280297Sjkim    }
19859191Skris
199280297Sjkim    s = (unsigned char *)OPENSSL_malloc((unsigned int)siglen);
200280297Sjkim    if (s == NULL) {
201280297Sjkim        RSAerr(RSA_F_INT_RSA_VERIFY, ERR_R_MALLOC_FAILURE);
202280297Sjkim        goto err;
203280297Sjkim    }
204280297Sjkim    if ((dtype == NID_md5_sha1) && (m_len != SSL_SIG_LENGTH)) {
205280297Sjkim        RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_MESSAGE_LENGTH);
206280297Sjkim        goto err;
207280297Sjkim    }
208280297Sjkim    i = RSA_public_decrypt((int)siglen, sigbuf, s, rsa, RSA_PKCS1_PADDING);
209238405Sjkim
210280297Sjkim    if (i <= 0)
211280297Sjkim        goto err;
212280297Sjkim    /*
213280297Sjkim     * Oddball MDC2 case: signature can be OCTET STRING. check for correct
214280297Sjkim     * tag and length octets.
215280297Sjkim     */
216280297Sjkim    if (dtype == NID_mdc2 && i == 18 && s[0] == 0x04 && s[1] == 0x10) {
217280297Sjkim        if (rm) {
218280297Sjkim            memcpy(rm, s + 2, 16);
219280297Sjkim            *prm_len = 16;
220280297Sjkim            ret = 1;
221280297Sjkim        } else if (memcmp(m, s + 2, 16))
222280297Sjkim            RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
223280297Sjkim        else
224280297Sjkim            ret = 1;
225280297Sjkim    }
22656083Skris
227280297Sjkim    /* Special case: SSL signature */
228280297Sjkim    if (dtype == NID_md5_sha1) {
229280297Sjkim        if ((i != SSL_SIG_LENGTH) || memcmp(s, m, SSL_SIG_LENGTH))
230280297Sjkim            RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
231280297Sjkim        else
232280297Sjkim            ret = 1;
233280297Sjkim    } else {
234280297Sjkim        const unsigned char *p = s;
235280297Sjkim        sig = d2i_X509_SIG(NULL, &p, (long)i);
23656083Skris
237280297Sjkim        if (sig == NULL)
238280297Sjkim            goto err;
239162207Ssimon
240280297Sjkim        /* Excess data can be used to create forgeries */
241280297Sjkim        if (p != s + i || !rsa_check_digestinfo(sig, s, i)) {
242280297Sjkim            RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
243280297Sjkim            goto err;
244280297Sjkim        }
245162207Ssimon
246280297Sjkim        /*
247280297Sjkim         * Parameters to the signature algorithm can also be used to create
248280297Sjkim         * forgeries
249280297Sjkim         */
250280297Sjkim        if (sig->algor->parameter
251280297Sjkim            && ASN1_TYPE_get(sig->algor->parameter) != V_ASN1_NULL) {
252280297Sjkim            RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
253280297Sjkim            goto err;
254280297Sjkim        }
255162207Ssimon
256280297Sjkim        sigtype = OBJ_obj2nid(sig->algor->algorithm);
25756083Skris
258280297Sjkim#ifdef RSA_DEBUG
259280297Sjkim        /* put a backward compatibility flag in EAY */
260280297Sjkim        fprintf(stderr, "in(%s) expect(%s)\n", OBJ_nid2ln(sigtype),
261280297Sjkim                OBJ_nid2ln(dtype));
262280297Sjkim#endif
263280297Sjkim        if (sigtype != dtype) {
264280297Sjkim            if (((dtype == NID_md5) &&
265280297Sjkim                 (sigtype == NID_md5WithRSAEncryption)) ||
266280297Sjkim                ((dtype == NID_md2) &&
267280297Sjkim                 (sigtype == NID_md2WithRSAEncryption))) {
268280297Sjkim                /* ok, we will let it through */
269109998Smarkm#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16)
270280297Sjkim                fprintf(stderr,
271280297Sjkim                        "signature has problems, re-make with post SSLeay045\n");
272109998Smarkm#endif
273280297Sjkim            } else {
274280297Sjkim                RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_ALGORITHM_MISMATCH);
275280297Sjkim                goto err;
276280297Sjkim            }
277280297Sjkim        }
278280297Sjkim        if (rm) {
279280297Sjkim            const EVP_MD *md;
280280297Sjkim            md = EVP_get_digestbynid(dtype);
281280297Sjkim            if (md && (EVP_MD_size(md) != sig->digest->length))
282280297Sjkim                RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_DIGEST_LENGTH);
283280297Sjkim            else {
284280297Sjkim                memcpy(rm, sig->digest->data, sig->digest->length);
285280297Sjkim                *prm_len = sig->digest->length;
286280297Sjkim                ret = 1;
287280297Sjkim            }
288280297Sjkim        } else if (((unsigned int)sig->digest->length != m_len) ||
289280297Sjkim                   (memcmp(m, sig->digest->data, m_len) != 0)) {
290280297Sjkim            RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
291280297Sjkim        } else
292280297Sjkim            ret = 1;
293280297Sjkim    }
294280297Sjkim err:
295280297Sjkim    if (sig != NULL)
296280297Sjkim        X509_SIG_free(sig);
297280297Sjkim    if (s != NULL) {
298280297Sjkim        OPENSSL_cleanse(s, (unsigned int)siglen);
299280297Sjkim        OPENSSL_free(s);
300280297Sjkim    }
301280297Sjkim    return (ret);
302280297Sjkim}
30356083Skris
304238405Sjkimint RSA_verify(int dtype, const unsigned char *m, unsigned int m_len,
305280297Sjkim               const unsigned char *sigbuf, unsigned int siglen, RSA *rsa)
306280297Sjkim{
307238405Sjkim
308280297Sjkim    if ((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_verify) {
309280297Sjkim        return rsa->meth->rsa_verify(dtype, m, m_len, sigbuf, siglen, rsa);
310280297Sjkim    }
311238405Sjkim
312280297Sjkim    return int_rsa_verify(dtype, m, m_len, NULL, NULL, sigbuf, siglen, rsa);
313280297Sjkim}
314