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.
8296341Sdelphij *
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).
15296341Sdelphij *
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.
22296341Sdelphij *
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 :-).
37296341Sdelphij * 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)"
40296341Sdelphij *
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.
52296341Sdelphij *
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 */
68296341Sdelphij#define SSL_SIG_LENGTH  36
6959191Skris
70109998Smarkmint RSA_sign(int type, const unsigned char *m, unsigned int m_len,
71296341Sdelphij             unsigned char *sigret, unsigned int *siglen, RSA *rsa)
72296341Sdelphij{
73296341Sdelphij    X509_SIG sig;
74296341Sdelphij    ASN1_TYPE parameter;
75296341Sdelphij    int i, j, ret = 1;
76296341Sdelphij    unsigned char *p, *tmps = NULL;
77296341Sdelphij    const unsigned char *s = NULL;
78296341Sdelphij    X509_ALGOR algor;
79296341Sdelphij    ASN1_OCTET_STRING digest;
80238405Sjkim#ifdef OPENSSL_FIPS
81296341Sdelphij    if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD)
82296341Sdelphij        && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) {
83296341Sdelphij        RSAerr(RSA_F_RSA_SIGN, RSA_R_NON_FIPS_RSA_METHOD);
84296341Sdelphij        return 0;
85296341Sdelphij    }
86238405Sjkim#endif
87296341Sdelphij    if ((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_sign) {
88296341Sdelphij        return rsa->meth->rsa_sign(type, m, m_len, sigret, siglen, rsa);
89296341Sdelphij    }
90296341Sdelphij    /* Special case: SSL signature, just check the length */
91296341Sdelphij    if (type == NID_md5_sha1) {
92296341Sdelphij        if (m_len != SSL_SIG_LENGTH) {
93296341Sdelphij            RSAerr(RSA_F_RSA_SIGN, RSA_R_INVALID_MESSAGE_LENGTH);
94296341Sdelphij            return (0);
95296341Sdelphij        }
96296341Sdelphij        i = SSL_SIG_LENGTH;
97296341Sdelphij        s = m;
98296341Sdelphij    } else {
99296341Sdelphij        sig.algor = &algor;
100296341Sdelphij        sig.algor->algorithm = OBJ_nid2obj(type);
101296341Sdelphij        if (sig.algor->algorithm == NULL) {
102296341Sdelphij            RSAerr(RSA_F_RSA_SIGN, RSA_R_UNKNOWN_ALGORITHM_TYPE);
103296341Sdelphij            return (0);
104296341Sdelphij        }
105296341Sdelphij        if (sig.algor->algorithm->length == 0) {
106296341Sdelphij            RSAerr(RSA_F_RSA_SIGN,
107296341Sdelphij                   RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD);
108296341Sdelphij            return (0);
109296341Sdelphij        }
110296341Sdelphij        parameter.type = V_ASN1_NULL;
111296341Sdelphij        parameter.value.ptr = NULL;
112296341Sdelphij        sig.algor->parameter = &parameter;
11356083Skris
114296341Sdelphij        sig.digest = &digest;
115296341Sdelphij        sig.digest->data = (unsigned char *)m; /* TMP UGLY CAST */
116296341Sdelphij        sig.digest->length = m_len;
11756083Skris
118296341Sdelphij        i = i2d_X509_SIG(&sig, NULL);
119296341Sdelphij    }
120296341Sdelphij    j = RSA_size(rsa);
121296341Sdelphij    if (i > (j - RSA_PKCS1_PADDING_SIZE)) {
122296341Sdelphij        RSAerr(RSA_F_RSA_SIGN, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY);
123296341Sdelphij        return (0);
124296341Sdelphij    }
125296341Sdelphij    if (type != NID_md5_sha1) {
126296341Sdelphij        tmps = (unsigned char *)OPENSSL_malloc((unsigned int)j + 1);
127296341Sdelphij        if (tmps == NULL) {
128296341Sdelphij            RSAerr(RSA_F_RSA_SIGN, ERR_R_MALLOC_FAILURE);
129296341Sdelphij            return (0);
130296341Sdelphij        }
131296341Sdelphij        p = tmps;
132296341Sdelphij        i2d_X509_SIG(&sig, &p);
133296341Sdelphij        s = tmps;
134296341Sdelphij    }
135296341Sdelphij    i = RSA_private_encrypt(i, s, sigret, rsa, RSA_PKCS1_PADDING);
136296341Sdelphij    if (i <= 0)
137296341Sdelphij        ret = 0;
138296341Sdelphij    else
139296341Sdelphij        *siglen = i;
14056083Skris
141296341Sdelphij    if (type != NID_md5_sha1) {
142296341Sdelphij        OPENSSL_cleanse(tmps, (unsigned int)j + 1);
143296341Sdelphij        OPENSSL_free(tmps);
144296341Sdelphij    }
145296341Sdelphij    return (ret);
146296341Sdelphij}
14756083Skris
148273399Sdelphij/*
149273399Sdelphij * Check DigestInfo structure does not contain extraneous data by reencoding
150296341Sdelphij * using DER and checking encoding against original.
151273399Sdelphij */
152296341Sdelphijstatic int rsa_check_digestinfo(X509_SIG *sig, const unsigned char *dinfo,
153296341Sdelphij                                int dinfolen)
154296341Sdelphij{
155296341Sdelphij    unsigned char *der = NULL;
156296341Sdelphij    int derlen;
157296341Sdelphij    int ret = 0;
158296341Sdelphij    derlen = i2d_X509_SIG(sig, &der);
159296341Sdelphij    if (derlen <= 0)
160296341Sdelphij        return 0;
161296341Sdelphij    if (derlen == dinfolen && !memcmp(dinfo, der, derlen))
162296341Sdelphij        ret = 1;
163296341Sdelphij    OPENSSL_cleanse(der, derlen);
164296341Sdelphij    OPENSSL_free(der);
165296341Sdelphij    return ret;
166296341Sdelphij}
167273399Sdelphij
168238405Sjkimint int_rsa_verify(int dtype, const unsigned char *m,
169296341Sdelphij                   unsigned int m_len,
170296341Sdelphij                   unsigned char *rm, size_t *prm_len,
171296341Sdelphij                   const unsigned char *sigbuf, size_t siglen, RSA *rsa)
172296341Sdelphij{
173296341Sdelphij    int i, ret = 0, sigtype;
174296341Sdelphij    unsigned char *s;
175296341Sdelphij    X509_SIG *sig = NULL;
17656083Skris
177238405Sjkim#ifdef OPENSSL_FIPS
178296341Sdelphij    if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD)
179296341Sdelphij        && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) {
180296341Sdelphij        RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_NON_FIPS_RSA_METHOD);
181296341Sdelphij        return 0;
182296341Sdelphij    }
183238405Sjkim#endif
184238405Sjkim
185296341Sdelphij    if (siglen != (unsigned int)RSA_size(rsa)) {
186296341Sdelphij        RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_WRONG_SIGNATURE_LENGTH);
187296341Sdelphij        return (0);
188296341Sdelphij    }
18956083Skris
190296341Sdelphij    if ((dtype == NID_md5_sha1) && rm) {
191296341Sdelphij        i = RSA_public_decrypt((int)siglen,
192296341Sdelphij                               sigbuf, rm, rsa, RSA_PKCS1_PADDING);
193296341Sdelphij        if (i <= 0)
194296341Sdelphij            return 0;
195296341Sdelphij        *prm_len = i;
196296341Sdelphij        return 1;
197296341Sdelphij    }
19859191Skris
199296341Sdelphij    s = (unsigned char *)OPENSSL_malloc((unsigned int)siglen);
200296341Sdelphij    if (s == NULL) {
201296341Sdelphij        RSAerr(RSA_F_INT_RSA_VERIFY, ERR_R_MALLOC_FAILURE);
202296341Sdelphij        goto err;
203296341Sdelphij    }
204296341Sdelphij    if ((dtype == NID_md5_sha1) && (m_len != SSL_SIG_LENGTH)) {
205296341Sdelphij        RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_MESSAGE_LENGTH);
206296341Sdelphij        goto err;
207296341Sdelphij    }
208296341Sdelphij    i = RSA_public_decrypt((int)siglen, sigbuf, s, rsa, RSA_PKCS1_PADDING);
209238405Sjkim
210296341Sdelphij    if (i <= 0)
211296341Sdelphij        goto err;
212296341Sdelphij    /*
213296341Sdelphij     * Oddball MDC2 case: signature can be OCTET STRING. check for correct
214296341Sdelphij     * tag and length octets.
215296341Sdelphij     */
216296341Sdelphij    if (dtype == NID_mdc2 && i == 18 && s[0] == 0x04 && s[1] == 0x10) {
217296341Sdelphij        if (rm) {
218296341Sdelphij            memcpy(rm, s + 2, 16);
219296341Sdelphij            *prm_len = 16;
220296341Sdelphij            ret = 1;
221296341Sdelphij        } else if (memcmp(m, s + 2, 16))
222296341Sdelphij            RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
223296341Sdelphij        else
224296341Sdelphij            ret = 1;
225296341Sdelphij    }
22656083Skris
227296341Sdelphij    /* Special case: SSL signature */
228296341Sdelphij    if (dtype == NID_md5_sha1) {
229296341Sdelphij        if ((i != SSL_SIG_LENGTH) || memcmp(s, m, SSL_SIG_LENGTH))
230296341Sdelphij            RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
231296341Sdelphij        else
232296341Sdelphij            ret = 1;
233296341Sdelphij    } else {
234296341Sdelphij        const unsigned char *p = s;
235296341Sdelphij        sig = d2i_X509_SIG(NULL, &p, (long)i);
23656083Skris
237296341Sdelphij        if (sig == NULL)
238296341Sdelphij            goto err;
239162207Ssimon
240296341Sdelphij        /* Excess data can be used to create forgeries */
241296341Sdelphij        if (p != s + i || !rsa_check_digestinfo(sig, s, i)) {
242296341Sdelphij            RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
243296341Sdelphij            goto err;
244296341Sdelphij        }
245162207Ssimon
246296341Sdelphij        /*
247296341Sdelphij         * Parameters to the signature algorithm can also be used to create
248296341Sdelphij         * forgeries
249296341Sdelphij         */
250296341Sdelphij        if (sig->algor->parameter
251296341Sdelphij            && ASN1_TYPE_get(sig->algor->parameter) != V_ASN1_NULL) {
252296341Sdelphij            RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
253296341Sdelphij            goto err;
254296341Sdelphij        }
255162207Ssimon
256296341Sdelphij        sigtype = OBJ_obj2nid(sig->algor->algorithm);
25756083Skris
258296341Sdelphij#ifdef RSA_DEBUG
259296341Sdelphij        /* put a backward compatibility flag in EAY */
260296341Sdelphij        fprintf(stderr, "in(%s) expect(%s)\n", OBJ_nid2ln(sigtype),
261296341Sdelphij                OBJ_nid2ln(dtype));
262296341Sdelphij#endif
263296341Sdelphij        if (sigtype != dtype) {
264296341Sdelphij            if (((dtype == NID_md5) &&
265296341Sdelphij                 (sigtype == NID_md5WithRSAEncryption)) ||
266296341Sdelphij                ((dtype == NID_md2) &&
267296341Sdelphij                 (sigtype == NID_md2WithRSAEncryption))) {
268296341Sdelphij                /* ok, we will let it through */
269109998Smarkm#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16)
270296341Sdelphij                fprintf(stderr,
271296341Sdelphij                        "signature has problems, re-make with post SSLeay045\n");
272109998Smarkm#endif
273296341Sdelphij            } else {
274296341Sdelphij                RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_ALGORITHM_MISMATCH);
275296341Sdelphij                goto err;
276296341Sdelphij            }
277296341Sdelphij        }
278296341Sdelphij        if (rm) {
279296341Sdelphij            const EVP_MD *md;
280296341Sdelphij            md = EVP_get_digestbynid(dtype);
281296341Sdelphij            if (md && (EVP_MD_size(md) != sig->digest->length))
282296341Sdelphij                RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_DIGEST_LENGTH);
283296341Sdelphij            else {
284296341Sdelphij                memcpy(rm, sig->digest->data, sig->digest->length);
285296341Sdelphij                *prm_len = sig->digest->length;
286296341Sdelphij                ret = 1;
287296341Sdelphij            }
288296341Sdelphij        } else if (((unsigned int)sig->digest->length != m_len) ||
289296341Sdelphij                   (memcmp(m, sig->digest->data, m_len) != 0)) {
290296341Sdelphij            RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
291296341Sdelphij        } else
292296341Sdelphij            ret = 1;
293296341Sdelphij    }
294296341Sdelphij err:
295296341Sdelphij    if (sig != NULL)
296296341Sdelphij        X509_SIG_free(sig);
297296341Sdelphij    if (s != NULL) {
298296341Sdelphij        OPENSSL_cleanse(s, (unsigned int)siglen);
299296341Sdelphij        OPENSSL_free(s);
300296341Sdelphij    }
301296341Sdelphij    return (ret);
302296341Sdelphij}
30356083Skris
304238405Sjkimint RSA_verify(int dtype, const unsigned char *m, unsigned int m_len,
305296341Sdelphij               const unsigned char *sigbuf, unsigned int siglen, RSA *rsa)
306296341Sdelphij{
307238405Sjkim
308296341Sdelphij    if ((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_verify) {
309296341Sdelphij        return rsa->meth->rsa_verify(dtype, m, m_len, sigbuf, siglen, rsa);
310296341Sdelphij    }
311238405Sjkim
312296341Sdelphij    return int_rsa_verify(dtype, m, m_len, NULL, NULL, sigbuf, siglen, rsa);
313296341Sdelphij}
314