/src/openssl111/crypto/rsa/rsa_sign.c
| Line | Count | Source (jump to first uncovered line) | 
| 1 |  | /* | 
| 2 |  |  * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. | 
| 3 |  |  * | 
| 4 |  |  * Licensed under the OpenSSL license (the "License").  You may not use | 
| 5 |  |  * this file except in compliance with the License.  You can obtain a copy | 
| 6 |  |  * in the file LICENSE in the source distribution or at | 
| 7 |  |  * https://www.openssl.org/source/license.html | 
| 8 |  |  */ | 
| 9 |  |  | 
| 10 |  | #include <stdio.h> | 
| 11 |  | #include "internal/cryptlib.h" | 
| 12 |  | #include <openssl/bn.h> | 
| 13 |  | #include <openssl/rsa.h> | 
| 14 |  | #include <openssl/objects.h> | 
| 15 |  | #include <openssl/x509.h> | 
| 16 |  | #include "crypto/x509.h" | 
| 17 |  | #include "rsa_local.h" | 
| 18 |  |  | 
| 19 |  | /* Size of an SSL signature: MD5+SHA1 */ | 
| 20 | 0 | #define SSL_SIG_LENGTH  36 | 
| 21 |  |  | 
| 22 |  | /* | 
| 23 |  |  * encode_pkcs1 encodes a DigestInfo prefix of hash |type| and digest |m|, as | 
| 24 |  |  * described in EMSA-PKCS1-v1_5-ENCODE, RFC 3447 section 9.2 step 2. This | 
| 25 |  |  * encodes the DigestInfo (T and tLen) but does not add the padding. | 
| 26 |  |  * | 
| 27 |  |  * On success, it returns one and sets |*out| to a newly allocated buffer | 
| 28 |  |  * containing the result and |*out_len| to its length. The caller must free | 
| 29 |  |  * |*out| with |OPENSSL_free|. Otherwise, it returns zero. | 
| 30 |  |  */ | 
| 31 |  | static int encode_pkcs1(unsigned char **out, int *out_len, int type, | 
| 32 |  |                         const unsigned char *m, unsigned int m_len) | 
| 33 | 0 | { | 
| 34 | 0 |     X509_SIG sig; | 
| 35 | 0 |     X509_ALGOR algor; | 
| 36 | 0 |     ASN1_TYPE parameter; | 
| 37 | 0 |     ASN1_OCTET_STRING digest; | 
| 38 | 0 |     uint8_t *der = NULL; | 
| 39 | 0 |     int len; | 
| 40 |  | 
 | 
| 41 | 0 |     sig.algor = &algor; | 
| 42 | 0 |     sig.algor->algorithm = OBJ_nid2obj(type); | 
| 43 | 0 |     if (sig.algor->algorithm == NULL) { | 
| 44 | 0 |         RSAerr(RSA_F_ENCODE_PKCS1, RSA_R_UNKNOWN_ALGORITHM_TYPE); | 
| 45 | 0 |         return 0; | 
| 46 | 0 |     } | 
| 47 | 0 |     if (OBJ_length(sig.algor->algorithm) == 0) { | 
| 48 | 0 |         RSAerr(RSA_F_ENCODE_PKCS1, | 
| 49 | 0 |                RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD); | 
| 50 | 0 |         return 0; | 
| 51 | 0 |     } | 
| 52 | 0 |     parameter.type = V_ASN1_NULL; | 
| 53 | 0 |     parameter.value.ptr = NULL; | 
| 54 | 0 |     sig.algor->parameter = ¶meter; | 
| 55 |  | 
 | 
| 56 | 0 |     sig.digest = &digest; | 
| 57 | 0 |     sig.digest->data = (unsigned char *)m; | 
| 58 | 0 |     sig.digest->length = m_len; | 
| 59 |  | 
 | 
| 60 | 0 |     len = i2d_X509_SIG(&sig, &der); | 
| 61 | 0 |     if (len < 0) | 
| 62 | 0 |         return 0; | 
| 63 |  |  | 
| 64 | 0 |     *out = der; | 
| 65 | 0 |     *out_len = len; | 
| 66 | 0 |     return 1; | 
| 67 | 0 | } | 
| 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 | 0 | { | 
| 72 | 0 |     int encrypt_len, encoded_len = 0, ret = 0; | 
| 73 | 0 |     unsigned char *tmps = NULL; | 
| 74 | 0 |     const unsigned char *encoded = NULL; | 
| 75 |  | 
 | 
| 76 | 0 |     if (rsa->meth->rsa_sign) { | 
| 77 | 0 |         return rsa->meth->rsa_sign(type, m, m_len, sigret, siglen, rsa); | 
| 78 | 0 |     } | 
| 79 |  |  | 
| 80 |  |     /* Compute the encoded digest. */ | 
| 81 | 0 |     if (type == NID_md5_sha1) { | 
| 82 |  |         /* | 
| 83 |  |          * NID_md5_sha1 corresponds to the MD5/SHA1 combination in TLS 1.1 and | 
| 84 |  |          * earlier. It has no DigestInfo wrapper but otherwise is | 
| 85 |  |          * RSASSA-PKCS1-v1_5. | 
| 86 |  |          */ | 
| 87 | 0 |         if (m_len != SSL_SIG_LENGTH) { | 
| 88 | 0 |             RSAerr(RSA_F_RSA_SIGN, RSA_R_INVALID_MESSAGE_LENGTH); | 
| 89 | 0 |             return 0; | 
| 90 | 0 |         } | 
| 91 | 0 |         encoded_len = SSL_SIG_LENGTH; | 
| 92 | 0 |         encoded = m; | 
| 93 | 0 |     } else { | 
| 94 | 0 |         if (!encode_pkcs1(&tmps, &encoded_len, type, m, m_len)) | 
| 95 | 0 |             goto err; | 
| 96 | 0 |         encoded = tmps; | 
| 97 | 0 |     } | 
| 98 |  |  | 
| 99 | 0 |     if (encoded_len > RSA_size(rsa) - RSA_PKCS1_PADDING_SIZE) { | 
| 100 | 0 |         RSAerr(RSA_F_RSA_SIGN, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); | 
| 101 | 0 |         goto err; | 
| 102 | 0 |     } | 
| 103 | 0 |     encrypt_len = RSA_private_encrypt(encoded_len, encoded, sigret, rsa, | 
| 104 | 0 |                                       RSA_PKCS1_PADDING); | 
| 105 | 0 |     if (encrypt_len <= 0) | 
| 106 | 0 |         goto err; | 
| 107 |  |  | 
| 108 | 0 |     *siglen = encrypt_len; | 
| 109 | 0 |     ret = 1; | 
| 110 |  | 
 | 
| 111 | 0 | err: | 
| 112 | 0 |     OPENSSL_clear_free(tmps, (size_t)encoded_len); | 
| 113 | 0 |     return ret; | 
| 114 | 0 | } | 
| 115 |  |  | 
| 116 |  | /* | 
| 117 |  |  * int_rsa_verify verifies an RSA signature in |sigbuf| using |rsa|. It may be | 
| 118 |  |  * called in two modes. If |rm| is NULL, it verifies the signature for digest | 
| 119 |  |  * |m|. Otherwise, it recovers the digest from the signature, writing the digest | 
| 120 |  |  * to |rm| and the length to |*prm_len|. |type| is the NID of the digest | 
| 121 |  |  * algorithm to use. It returns one on successful verification and zero | 
| 122 |  |  * otherwise. | 
| 123 |  |  */ | 
| 124 |  | int int_rsa_verify(int type, const unsigned char *m, unsigned int m_len, | 
| 125 |  |                    unsigned char *rm, size_t *prm_len, | 
| 126 |  |                    const unsigned char *sigbuf, size_t siglen, RSA *rsa) | 
| 127 | 0 | { | 
| 128 | 0 |     int decrypt_len, ret = 0, encoded_len = 0; | 
| 129 | 0 |     unsigned char *decrypt_buf = NULL, *encoded = NULL; | 
| 130 |  | 
 | 
| 131 | 0 |     if (siglen != (size_t)RSA_size(rsa)) { | 
| 132 | 0 |         RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_WRONG_SIGNATURE_LENGTH); | 
| 133 | 0 |         return 0; | 
| 134 | 0 |     } | 
| 135 |  |  | 
| 136 |  |     /* Recover the encoded digest. */ | 
| 137 | 0 |     decrypt_buf = OPENSSL_malloc(siglen); | 
| 138 | 0 |     if (decrypt_buf == NULL) { | 
| 139 | 0 |         RSAerr(RSA_F_INT_RSA_VERIFY, ERR_R_MALLOC_FAILURE); | 
| 140 | 0 |         goto err; | 
| 141 | 0 |     } | 
| 142 |  |  | 
| 143 | 0 |     decrypt_len = RSA_public_decrypt((int)siglen, sigbuf, decrypt_buf, rsa, | 
| 144 | 0 |                                      RSA_PKCS1_PADDING); | 
| 145 | 0 |     if (decrypt_len <= 0) | 
| 146 | 0 |         goto err; | 
| 147 |  |  | 
| 148 | 0 |     if (type == NID_md5_sha1) { | 
| 149 |  |         /* | 
| 150 |  |          * NID_md5_sha1 corresponds to the MD5/SHA1 combination in TLS 1.1 and | 
| 151 |  |          * earlier. It has no DigestInfo wrapper but otherwise is | 
| 152 |  |          * RSASSA-PKCS1-v1_5. | 
| 153 |  |          */ | 
| 154 | 0 |         if (decrypt_len != SSL_SIG_LENGTH) { | 
| 155 | 0 |             RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); | 
| 156 | 0 |             goto err; | 
| 157 | 0 |         } | 
| 158 |  |  | 
| 159 | 0 |         if (rm != NULL) { | 
| 160 | 0 |             memcpy(rm, decrypt_buf, SSL_SIG_LENGTH); | 
| 161 | 0 |             *prm_len = SSL_SIG_LENGTH; | 
| 162 | 0 |         } else { | 
| 163 | 0 |             if (m_len != SSL_SIG_LENGTH) { | 
| 164 | 0 |                 RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_MESSAGE_LENGTH); | 
| 165 | 0 |                 goto err; | 
| 166 | 0 |             } | 
| 167 |  |  | 
| 168 | 0 |             if (memcmp(decrypt_buf, m, SSL_SIG_LENGTH) != 0) { | 
| 169 | 0 |                 RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); | 
| 170 | 0 |                 goto err; | 
| 171 | 0 |             } | 
| 172 | 0 |         } | 
| 173 | 0 |     } else if (type == NID_mdc2 && decrypt_len == 2 + 16 | 
| 174 | 0 |                && decrypt_buf[0] == 0x04 && decrypt_buf[1] == 0x10) { | 
| 175 |  |         /* | 
| 176 |  |          * Oddball MDC2 case: signature can be OCTET STRING. check for correct | 
| 177 |  |          * tag and length octets. | 
| 178 |  |          */ | 
| 179 | 0 |         if (rm != NULL) { | 
| 180 | 0 |             memcpy(rm, decrypt_buf + 2, 16); | 
| 181 | 0 |             *prm_len = 16; | 
| 182 | 0 |         } else { | 
| 183 | 0 |             if (m_len != 16) { | 
| 184 | 0 |                 RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_MESSAGE_LENGTH); | 
| 185 | 0 |                 goto err; | 
| 186 | 0 |             } | 
| 187 |  |  | 
| 188 | 0 |             if (memcmp(m, decrypt_buf + 2, 16) != 0) { | 
| 189 | 0 |                 RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); | 
| 190 | 0 |                 goto err; | 
| 191 | 0 |             } | 
| 192 | 0 |         } | 
| 193 | 0 |     } else { | 
| 194 |  |         /* | 
| 195 |  |          * If recovering the digest, extract a digest-sized output from the end | 
| 196 |  |          * of |decrypt_buf| for |encode_pkcs1|, then compare the decryption | 
| 197 |  |          * output as in a standard verification. | 
| 198 |  |          */ | 
| 199 | 0 |         if (rm != NULL) { | 
| 200 | 0 |             const EVP_MD *md = EVP_get_digestbynid(type); | 
| 201 | 0 |             if (md == NULL) { | 
| 202 | 0 |                 RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_UNKNOWN_ALGORITHM_TYPE); | 
| 203 | 0 |                 goto err; | 
| 204 | 0 |             } | 
| 205 |  |  | 
| 206 | 0 |             m_len = EVP_MD_size(md); | 
| 207 | 0 |             if (m_len > (size_t)decrypt_len) { | 
| 208 | 0 |                 RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_DIGEST_LENGTH); | 
| 209 | 0 |                 goto err; | 
| 210 | 0 |             } | 
| 211 | 0 |             m = decrypt_buf + decrypt_len - m_len; | 
| 212 | 0 |         } | 
| 213 |  |  | 
| 214 |  |         /* Construct the encoded digest and ensure it matches. */ | 
| 215 | 0 |         if (!encode_pkcs1(&encoded, &encoded_len, type, m, m_len)) | 
| 216 | 0 |             goto err; | 
| 217 |  |  | 
| 218 | 0 |         if (encoded_len != decrypt_len | 
| 219 | 0 |             || memcmp(encoded, decrypt_buf, encoded_len) != 0) { | 
| 220 | 0 |             RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); | 
| 221 | 0 |             goto err; | 
| 222 | 0 |         } | 
| 223 |  |  | 
| 224 |  |         /* Output the recovered digest. */ | 
| 225 | 0 |         if (rm != NULL) { | 
| 226 | 0 |             memcpy(rm, m, m_len); | 
| 227 | 0 |             *prm_len = m_len; | 
| 228 | 0 |         } | 
| 229 | 0 |     } | 
| 230 |  |  | 
| 231 | 0 |     ret = 1; | 
| 232 |  | 
 | 
| 233 | 0 | err: | 
| 234 | 0 |     OPENSSL_clear_free(encoded, (size_t)encoded_len); | 
| 235 | 0 |     OPENSSL_clear_free(decrypt_buf, siglen); | 
| 236 | 0 |     return ret; | 
| 237 | 0 | } | 
| 238 |  |  | 
| 239 |  | int RSA_verify(int type, const unsigned char *m, unsigned int m_len, | 
| 240 |  |                const unsigned char *sigbuf, unsigned int siglen, RSA *rsa) | 
| 241 | 0 | { | 
| 242 |  | 
 | 
| 243 | 0 |     if (rsa->meth->rsa_verify) { | 
| 244 | 0 |         return rsa->meth->rsa_verify(type, m, m_len, sigbuf, siglen, rsa); | 
| 245 | 0 |     } | 
| 246 |  |  | 
| 247 | 0 |     return int_rsa_verify(type, m, m_len, NULL, NULL, sigbuf, siglen, rsa); | 
| 248 | 0 | } |