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
87337982Sjkim    if ((rsa->meth->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;
221291719Sjkim        } else if (memcmp(m, s + 2, 16)) {
222280297Sjkim            RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
223291719Sjkim        } else {
224280297Sjkim            ret = 1;
225291719Sjkim        }
226291719Sjkim    } else if (dtype == NID_md5_sha1) {
227291719Sjkim        /* Special case: SSL signature */
228280297Sjkim        if ((i != SSL_SIG_LENGTH) || memcmp(s, m, SSL_SIG_LENGTH))
229280297Sjkim            RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
230280297Sjkim        else
231280297Sjkim            ret = 1;
232280297Sjkim    } else {
233280297Sjkim        const unsigned char *p = s;
234280297Sjkim        sig = d2i_X509_SIG(NULL, &p, (long)i);
23556083Skris
236280297Sjkim        if (sig == NULL)
237280297Sjkim            goto err;
238162207Ssimon
239280297Sjkim        /* Excess data can be used to create forgeries */
240280297Sjkim        if (p != s + i || !rsa_check_digestinfo(sig, s, i)) {
241280297Sjkim            RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
242280297Sjkim            goto err;
243280297Sjkim        }
244162207Ssimon
245280297Sjkim        /*
246280297Sjkim         * Parameters to the signature algorithm can also be used to create
247280297Sjkim         * forgeries
248280297Sjkim         */
249280297Sjkim        if (sig->algor->parameter
250280297Sjkim            && ASN1_TYPE_get(sig->algor->parameter) != V_ASN1_NULL) {
251280297Sjkim            RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
252280297Sjkim            goto err;
253280297Sjkim        }
254162207Ssimon
255280297Sjkim        sigtype = OBJ_obj2nid(sig->algor->algorithm);
25656083Skris
257280297Sjkim#ifdef RSA_DEBUG
258280297Sjkim        /* put a backward compatibility flag in EAY */
259280297Sjkim        fprintf(stderr, "in(%s) expect(%s)\n", OBJ_nid2ln(sigtype),
260280297Sjkim                OBJ_nid2ln(dtype));
261280297Sjkim#endif
262280297Sjkim        if (sigtype != dtype) {
263290207Sjkim            RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_ALGORITHM_MISMATCH);
264290207Sjkim            goto err;
265280297Sjkim        }
266280297Sjkim        if (rm) {
267280297Sjkim            const EVP_MD *md;
268280297Sjkim            md = EVP_get_digestbynid(dtype);
269280297Sjkim            if (md && (EVP_MD_size(md) != sig->digest->length))
270280297Sjkim                RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_DIGEST_LENGTH);
271280297Sjkim            else {
272280297Sjkim                memcpy(rm, sig->digest->data, sig->digest->length);
273280297Sjkim                *prm_len = sig->digest->length;
274280297Sjkim                ret = 1;
275280297Sjkim            }
276280297Sjkim        } else if (((unsigned int)sig->digest->length != m_len) ||
277280297Sjkim                   (memcmp(m, sig->digest->data, m_len) != 0)) {
278280297Sjkim            RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
279280297Sjkim        } else
280280297Sjkim            ret = 1;
281280297Sjkim    }
282280297Sjkim err:
283280297Sjkim    if (sig != NULL)
284280297Sjkim        X509_SIG_free(sig);
285280297Sjkim    if (s != NULL) {
286280297Sjkim        OPENSSL_cleanse(s, (unsigned int)siglen);
287280297Sjkim        OPENSSL_free(s);
288280297Sjkim    }
289280297Sjkim    return (ret);
290280297Sjkim}
29156083Skris
292238405Sjkimint RSA_verify(int dtype, const unsigned char *m, unsigned int m_len,
293280297Sjkim               const unsigned char *sigbuf, unsigned int siglen, RSA *rsa)
294280297Sjkim{
295238405Sjkim
296337982Sjkim    if ((rsa->meth->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_verify) {
297280297Sjkim        return rsa->meth->rsa_verify(dtype, m, m_len, sigbuf, siglen, rsa);
298280297Sjkim    }
299238405Sjkim
300280297Sjkim    return int_rsa_verify(dtype, m, m_len, NULL, NULL, sigbuf, siglen, rsa);
301280297Sjkim}
302