summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libcrypto/rsa/rsa_sign.c268
1 files changed, 148 insertions, 120 deletions
diff --git a/src/lib/libcrypto/rsa/rsa_sign.c b/src/lib/libcrypto/rsa/rsa_sign.c
index 6e9e869f0a..2383259dda 100644
--- a/src/lib/libcrypto/rsa/rsa_sign.c
+++ b/src/lib/libcrypto/rsa/rsa_sign.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: rsa_sign.c,v 1.29 2017/05/02 03:59:45 deraadt Exp $ */ 1/* $OpenBSD: rsa_sign.c,v 1.30 2018/07/23 17:37:17 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -70,168 +70,196 @@
70/* Size of an SSL signature: MD5+SHA1 */ 70/* Size of an SSL signature: MD5+SHA1 */
71#define SSL_SIG_LENGTH 36 71#define SSL_SIG_LENGTH 36
72 72
73int 73static int encode_pkcs1(unsigned char **, int *, int , const unsigned char *,
74RSA_sign(int type, const unsigned char *m, unsigned int m_len, 74 unsigned int);
75 unsigned char *sigret, unsigned int *siglen, RSA *rsa) 75
76/*
77 * encode_pkcs1 encodes a DigestInfo prefix of hash `type' and digest `m', as
78 * described in EMSA-PKCS-v1_5-ENCODE, RFC 8017 section 9. step 2. This
79 * encodes the DigestInfo (T and tLen) but does not add the padding.
80 *
81 * On success, it returns one and sets `*out' to a newly allocated buffer
82 * containing the result and `*out_len' to its length. Freeing `*out' is
83 * the caller's responsibility. Failure is indicated by zero.
84 */
85static int
86encode_pkcs1(unsigned char **out, int *out_len, int type,
87 const unsigned char *m, unsigned int m_len)
76{ 88{
77 X509_SIG sig; 89 X509_SIG sig;
78 ASN1_TYPE parameter;
79 int i, j, ret = 1;
80 unsigned char *p, *tmps = NULL;
81 const unsigned char *s = NULL;
82 X509_ALGOR algor; 90 X509_ALGOR algor;
91 ASN1_TYPE parameter;
83 ASN1_OCTET_STRING digest; 92 ASN1_OCTET_STRING digest;
93 uint8_t *der = NULL;
94 int len;
95
96 sig.algor = &algor;
97 if ((sig.algor->algorithm = OBJ_nid2obj(type)) == NULL) {
98 RSAerror(RSA_R_UNKNOWN_ALGORITHM_TYPE);
99 return 0;
100 }
101 if (sig.algor->algorithm->length == 0) {
102 RSAerror(
103 RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD);
104 return 0;
105 }
106 parameter.type = V_ASN1_NULL;
107 parameter.value.ptr = NULL;
108 sig.algor->parameter = &parameter;
109
110 sig.digest = &digest;
111 sig.digest->data = (unsigned char*)m; /* TMP UGLY CAST */
112 sig.digest->length = m_len;
84 113
85 if ((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_sign) 114 if ((len = i2d_X509_SIG(&sig, &der)) < 0)
115 return 0;
116
117 *out = der;
118 *out_len = len;
119
120 return 1;
121}
122
123int
124RSA_sign(int type, const unsigned char *m, unsigned int m_len,
125 unsigned char *sigret, unsigned int *siglen, RSA *rsa)
126{
127 const unsigned char *encoded = NULL;
128 unsigned char *tmps = NULL;
129 int encrypt_len, encoded_len = 0, ret = 0;
130
131 if ((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_sign != NULL)
86 return rsa->meth->rsa_sign(type, m, m_len, sigret, siglen, rsa); 132 return rsa->meth->rsa_sign(type, m, m_len, sigret, siglen, rsa);
87 133
88 /* Special case: SSL signature, just check the length */ 134 /* Compute the encoded digest. */
89 if (type == NID_md5_sha1) { 135 if (type == NID_md5_sha1) {
136 /*
137 * NID_md5_sha1 corresponds to the MD5/SHA1 combination in
138 * TLS 1.1 and earlier. It has no DigestInfo wrapper but
139 * otherwise is RSASSA-PKCS-v1.5.
140 */
90 if (m_len != SSL_SIG_LENGTH) { 141 if (m_len != SSL_SIG_LENGTH) {
91 RSAerror(RSA_R_INVALID_MESSAGE_LENGTH); 142 RSAerror(RSA_R_INVALID_DIGEST_LENGTH);
92 return 0; 143 return 0;
93 } 144 }
94 i = SSL_SIG_LENGTH; 145 encoded_len = SSL_SIG_LENGTH;
95 s = m; 146 encoded = m;
96 } else { 147 } else {
97 sig.algor = &algor; 148 if (!encode_pkcs1(&tmps, &encoded_len, type, m, m_len))
98 sig.algor->algorithm = OBJ_nid2obj(type); 149 goto err;
99 if (sig.algor->algorithm == NULL) { 150 encoded = tmps;
100 RSAerror(RSA_R_UNKNOWN_ALGORITHM_TYPE);
101 return 0;
102 }
103 if (sig.algor->algorithm->length == 0) {
104 RSAerror(RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD);
105 return 0;
106 }
107 parameter.type = V_ASN1_NULL;
108 parameter.value.ptr = NULL;
109 sig.algor->parameter = &parameter;
110
111 sig.digest = &digest;
112 sig.digest->data = (unsigned char *)m; /* TMP UGLY CAST */
113 sig.digest->length = m_len;
114
115 i = i2d_X509_SIG(&sig, NULL);
116 } 151 }
117 j = RSA_size(rsa); 152 if (encoded_len > RSA_size(rsa) - RSA_PKCS1_PADDING_SIZE) {
118 if (i > j - RSA_PKCS1_PADDING_SIZE) {
119 RSAerror(RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); 153 RSAerror(RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY);
120 return 0; 154 goto err;
121 }
122 if (type != NID_md5_sha1) {
123 tmps = malloc(j + 1);
124 if (tmps == NULL) {
125 RSAerror(ERR_R_MALLOC_FAILURE);
126 return 0;
127 }
128 p = tmps;
129 i2d_X509_SIG(&sig, &p);
130 s = tmps;
131 } 155 }
132 i = RSA_private_encrypt(i, s, sigret, rsa, RSA_PKCS1_PADDING); 156 if ((encrypt_len = RSA_private_encrypt(encoded_len, encoded, sigret,
133 if (i <= 0) 157 rsa, RSA_PKCS1_PADDING)) <= 0)
134 ret = 0; 158 goto err;
135 else 159
136 *siglen = i; 160 *siglen = encrypt_len;
137 161 ret = 1;
138 if (type != NID_md5_sha1) 162
139 freezero(tmps, (unsigned int)j + 1); 163 err:
164 freezero(tmps, (size_t)encoded_len);
140 return (ret); 165 return (ret);
141} 166}
142 167
168/*
169 * int_rsa_verify verifies an RSA signature in `sigbuf' using `rsa'. It may be
170 * called in two modes. If `rm' is NULL, it verifies the signature for the
171 * digest `m'. Otherwise, it recovers the digest from the signature, writing the
172 * digest to `rm' and the length to `*prm_len'. `type' is the NID of the digest
173 * algorithm to use. It returns one on successful verification and zero
174 * otherwise.
175 */
143int 176int
144int_rsa_verify(int dtype, const unsigned char *m, unsigned int m_len, 177int_rsa_verify(int type, const unsigned char *m, unsigned int m_len,
145 unsigned char *rm, size_t *prm_len, const unsigned char *sigbuf, 178 unsigned char *rm, size_t *prm_len, const unsigned char *sigbuf,
146 size_t siglen, RSA *rsa) 179 size_t siglen, RSA *rsa)
147{ 180{
148 int i, ret = 0, sigtype; 181 unsigned char *decrypt_buf, *encoded = NULL;
149 unsigned char *s; 182 int decrypt_len, encoded_len = 0, ret = 0;
150 X509_SIG *sig = NULL;
151 183
152 if (siglen != (unsigned int)RSA_size(rsa)) { 184 if (siglen != (size_t)RSA_size(rsa)) {
153 RSAerror(RSA_R_WRONG_SIGNATURE_LENGTH); 185 RSAerror(RSA_R_WRONG_SIGNATURE_LENGTH);
154 return 0; 186 return 0;
155 } 187 }
156 188
157 if ((dtype == NID_md5_sha1) && rm) { 189 /* Recover the encoded digest. */
158 i = RSA_public_decrypt((int)siglen, sigbuf, rm, rsa, 190 if ((decrypt_buf = malloc(siglen)) == NULL) {
159 RSA_PKCS1_PADDING);
160 if (i <= 0)
161 return 0;
162 *prm_len = i;
163 return 1;
164 }
165
166 s = malloc(siglen);
167 if (s == NULL) {
168 RSAerror(ERR_R_MALLOC_FAILURE); 191 RSAerror(ERR_R_MALLOC_FAILURE);
169 goto err; 192 goto err;
170 } 193 }
171 if (dtype == NID_md5_sha1 && m_len != SSL_SIG_LENGTH) { 194 if ((decrypt_len = RSA_public_decrypt((int)siglen, sigbuf, decrypt_buf,
172 RSAerror(RSA_R_INVALID_MESSAGE_LENGTH); 195 rsa, RSA_PKCS1_PADDING)) <= 0)
173 goto err;
174 }
175 i = RSA_public_decrypt((int)siglen, sigbuf, s, rsa, RSA_PKCS1_PADDING);
176
177 if (i <= 0)
178 goto err; 196 goto err;
197
198 if (type == NID_md5_sha1) {
199 /*
200 * NID_md5_sha1 corresponds to the MD5/SHA1 combination in
201 * TLS 1.1 and earlier. It has no DigestInfo wrapper but
202 * otherwise is RSASSA-PKCS1-v1_5.
203 */
204 if (decrypt_len != SSL_SIG_LENGTH) {
205 RSAerror(RSA_R_INVALID_DIGEST_LENGTH);
206 goto err;
207 }
179 208
180 /* Special case: SSL signature */ 209 if (rm != NULL) {
181 if (dtype == NID_md5_sha1) { 210 memcpy(rm, decrypt_buf, SSL_SIG_LENGTH);
182 if (i != SSL_SIG_LENGTH || memcmp(s, m, SSL_SIG_LENGTH)) 211 *prm_len = SSL_SIG_LENGTH;
183 RSAerror(RSA_R_BAD_SIGNATURE); 212 } else {
184 else 213 if (m_len != SSL_SIG_LENGTH) {
185 ret = 1; 214 RSAerror(RSA_R_INVALID_MESSAGE_LENGTH);
215 goto err;
216 }
217 if (memcmp(decrypt_buf, m, SSL_SIG_LENGTH) != 0) {
218 RSAerror(RSA_R_BAD_SIGNATURE);
219 goto err;
220 }
221 }
186 } else { 222 } else {
187 const unsigned char *p = s; 223 /*
224 * If recovering the digest, extract a digest-sized output from
225 * the end of `decrypt_buf' for `encode_pkcs1', then compare the
226 * decryption output as in a standard verification.
227 */
228 if (rm != NULL) {
229 const EVP_MD *md;
188 230
189 sig = d2i_X509_SIG(NULL, &p, (long)i); 231 if ((md = EVP_get_digestbynid(type)) == NULL) {
232 RSAerror(RSA_R_UNKNOWN_ALGORITHM_TYPE);
233 goto err;
234 }
235 if ((m_len = EVP_MD_size(md)) > (size_t)decrypt_len) {
236 RSAerror(RSA_R_INVALID_DIGEST_LENGTH);
237 goto err;
238 }
239 m = decrypt_buf + decrypt_len - m_len;
240 }
190 241
191 if (sig == NULL) 242 /* Construct the encoded digest and ensure it matches */
243 if (!encode_pkcs1(&encoded, &encoded_len, type, m, m_len))
192 goto err; 244 goto err;
193 245
194 /* Excess data can be used to create forgeries */ 246 if (encoded_len != decrypt_len ||
195 if (p != s + i) { 247 memcmp(encoded, decrypt_buf, encoded_len) != 0) {
196 RSAerror(RSA_R_BAD_SIGNATURE); 248 RSAerror(RSA_R_BAD_SIGNATURE);
197 goto err; 249 goto err;
198 } 250 }
199 251
200 /* Parameters to the signature algorithm can also be used to 252 /* Output the recovered digest. */
201 create forgeries */ 253 if (rm != NULL) {
202 if (sig->algor->parameter && 254 memcpy(rm, m, m_len);
203 ASN1_TYPE_get(sig->algor->parameter) != V_ASN1_NULL) { 255 *prm_len = m_len;
204 RSAerror(RSA_R_BAD_SIGNATURE);
205 goto err;
206 } 256 }
207
208 sigtype = OBJ_obj2nid(sig->algor->algorithm);
209
210 if (sigtype != dtype) {
211 RSAerror(RSA_R_ALGORITHM_MISMATCH);
212 goto err;
213 }
214 if (rm) {
215 const EVP_MD *md;
216
217 md = EVP_get_digestbynid(dtype);
218 if (md && (EVP_MD_size(md) != sig->digest->length))
219 RSAerror(RSA_R_INVALID_DIGEST_LENGTH);
220 else {
221 memcpy(rm, sig->digest->data,
222 sig->digest->length);
223 *prm_len = sig->digest->length;
224 ret = 1;
225 }
226 } else if ((unsigned int)sig->digest->length != m_len ||
227 memcmp(m, sig->digest->data, m_len) != 0) {
228 RSAerror(RSA_R_BAD_SIGNATURE);
229 } else
230 ret = 1;
231 } 257 }
232err: 258
233 X509_SIG_free(sig); 259 ret = 1;
234 freezero(s, (unsigned int)siglen); 260 err:
261 freezero(encoded, (size_t)encoded_len);
262 freezero(decrypt_buf, siglen);
235 return ret; 263 return ret;
236} 264}
237 265