View | Details | Raw Unified | Return to bug 3005 | Differences between
and this patch

Collapse All | Expand All

(-)a/digest-openssl.c (+16 lines)
Lines 63-68 const struct ssh_digest digests[] = { Link Here
63
	{ -1,			NULL,		0,	NULL },
63
	{ -1,			NULL,		0,	NULL },
64
};
64
};
65
65
66
const EVP_MD *
67
ssh_digest_to_md(int digest_type)
68
{
69
	switch (digest_type) {
70
	case SSH_DIGEST_SHA1:
71
		return EVP_sha1();
72
	case SSH_DIGEST_SHA256:
73
		return EVP_sha256();
74
	case SSH_DIGEST_SHA384:
75
		return EVP_sha384();
76
	case SSH_DIGEST_SHA512:
77
		return EVP_sha512();
78
	}
79
	return NULL;
80
}
81
66
static const struct ssh_digest *
82
static const struct ssh_digest *
67
ssh_digest_by_alg(int alg)
83
ssh_digest_by_alg(int alg)
68
{
84
{
(-)a/digest.h (+6 lines)
Lines 32-37 Link Here
32
struct sshbuf;
32
struct sshbuf;
33
struct ssh_digest_ctx;
33
struct ssh_digest_ctx;
34
34
35
#ifdef WITH_OPENSSL
36
#include <openssl/evp.h>
37
/* Converts internal digest representation to the OpenSSL one */
38
const EVP_MD *ssh_digest_to_md(int digest_type);
39
#endif
40
35
/* Looks up a digest algorithm by name */
41
/* Looks up a digest algorithm by name */
36
int ssh_digest_alg_by_name(const char *name);
42
int ssh_digest_alg_by_name(const char *name);
37
43
(-)a/ssh-dss.c (-24 / +41 lines)
Lines 52-62 int Link Here
52
ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
52
ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
53
    const u_char *data, size_t datalen, u_int compat)
53
    const u_char *data, size_t datalen, u_int compat)
54
{
54
{
55
	EVP_PKEY *pkey = NULL;
55
	DSA_SIG *sig = NULL;
56
	DSA_SIG *sig = NULL;
56
	const BIGNUM *sig_r, *sig_s;
57
	const BIGNUM *sig_r, *sig_s;
57
	u_char digest[SSH_DIGEST_MAX_LENGTH], sigblob[SIGBLOB_LEN];
58
	u_char sigblob[SIGBLOB_LEN];
58
	size_t rlen, slen, len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
59
	size_t rlen, slen;
60
	int len;
59
	struct sshbuf *b = NULL;
61
	struct sshbuf *b = NULL;
62
	u_char *sigb = NULL;
63
	const u_char *psig = NULL;
60
	int ret = SSH_ERR_INVALID_ARGUMENT;
64
	int ret = SSH_ERR_INVALID_ARGUMENT;
61
65
62
	if (lenp != NULL)
66
	if (lenp != NULL)
Lines 67-83 ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, Link Here
67
	if (key == NULL || key->dsa == NULL ||
71
	if (key == NULL || key->dsa == NULL ||
68
	    sshkey_type_plain(key->type) != KEY_DSA)
72
	    sshkey_type_plain(key->type) != KEY_DSA)
69
		return SSH_ERR_INVALID_ARGUMENT;
73
		return SSH_ERR_INVALID_ARGUMENT;
70
	if (dlen == 0)
71
		return SSH_ERR_INTERNAL_ERROR;
72
74
73
	if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen,
75
	if ((pkey = EVP_PKEY_new()) == NULL ||
74
	    digest, sizeof(digest))) != 0)
76
	    EVP_PKEY_set1_DSA(pkey, key->dsa) != 1)
77
		return SSH_ERR_ALLOC_FAIL;
78
	ret = sshkey_calculate_signature(pkey, SSH_DIGEST_SHA1, &sigb, &len,
79
	    data, datalen);
80
	EVP_PKEY_free(pkey);
81
	if (ret < 0) {
75
		goto out;
82
		goto out;
83
	}
76
84
77
	if ((sig = DSA_do_sign(digest, dlen, key->dsa)) == NULL) {
85
	psig = sigb;
86
	if ((sig = d2i_DSA_SIG(NULL, &psig, len)) == NULL) {
78
		ret = SSH_ERR_LIBCRYPTO_ERROR;
87
		ret = SSH_ERR_LIBCRYPTO_ERROR;
79
		goto out;
88
		goto out;
80
	}
89
	}
90
	free(sigb);
91
	sigb = NULL;
81
92
82
	DSA_SIG_get0(sig, &sig_r, &sig_s);
93
	DSA_SIG_get0(sig, &sig_r, &sig_s);
83
	rlen = BN_num_bytes(sig_r);
94
	rlen = BN_num_bytes(sig_r);
Lines 110-116 ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, Link Here
110
		*lenp = len;
121
		*lenp = len;
111
	ret = 0;
122
	ret = 0;
112
 out:
123
 out:
113
	explicit_bzero(digest, sizeof(digest));
124
	free(sigb);
114
	DSA_SIG_free(sig);
125
	DSA_SIG_free(sig);
115
	sshbuf_free(b);
126
	sshbuf_free(b);
116
	return ret;
127
	return ret;
Lines 121-140 ssh_dss_verify(const struct sshkey *key, Link Here
121
    const u_char *signature, size_t signaturelen,
132
    const u_char *signature, size_t signaturelen,
122
    const u_char *data, size_t datalen, u_int compat)
133
    const u_char *data, size_t datalen, u_int compat)
123
{
134
{
135
	EVP_PKEY *pkey = NULL;
124
	DSA_SIG *sig = NULL;
136
	DSA_SIG *sig = NULL;
125
	BIGNUM *sig_r = NULL, *sig_s = NULL;
137
	BIGNUM *sig_r = NULL, *sig_s = NULL;
126
	u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob = NULL;
138
	u_char *sigblob = NULL;
127
	size_t len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
139
	size_t len, slen;
128
	int ret = SSH_ERR_INTERNAL_ERROR;
140
	int ret = SSH_ERR_INTERNAL_ERROR;
129
	struct sshbuf *b = NULL;
141
	struct sshbuf *b = NULL;
130
	char *ktype = NULL;
142
	char *ktype = NULL;
143
	u_char *sigb = NULL, *psig = NULL;
131
144
132
	if (key == NULL || key->dsa == NULL ||
145
	if (key == NULL || key->dsa == NULL ||
133
	    sshkey_type_plain(key->type) != KEY_DSA ||
146
	    sshkey_type_plain(key->type) != KEY_DSA ||
134
	    signature == NULL || signaturelen == 0)
147
	    signature == NULL || signaturelen == 0)
135
		return SSH_ERR_INVALID_ARGUMENT;
148
		return SSH_ERR_INVALID_ARGUMENT;
136
	if (dlen == 0)
137
		return SSH_ERR_INTERNAL_ERROR;
138
149
139
	/* fetch signature */
150
	/* fetch signature */
140
	if ((b = sshbuf_from(signature, signaturelen)) == NULL)
151
	if ((b = sshbuf_from(signature, signaturelen)) == NULL)
Lines 176-200 ssh_dss_verify(const struct sshkey *key, Link Here
176
	}
187
	}
177
	sig_r = sig_s = NULL; /* transferred */
188
	sig_r = sig_s = NULL; /* transferred */
178
189
179
	/* sha1 the data */
190
	if ((slen = i2d_DSA_SIG(sig, NULL)) == 0) {
180
	if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen,
191
		ret = SSH_ERR_LIBCRYPTO_ERROR;
181
	    digest, sizeof(digest))) != 0)
182
		goto out;
192
		goto out;
183
193
	}
184
	switch (DSA_do_verify(digest, dlen, sig, key->dsa)) {
194
	if ((sigb = malloc(slen)) == NULL) {
185
	case 1:
195
		ret = SSH_ERR_ALLOC_FAIL;
186
		ret = 0;
187
		break;
188
	case 0:
189
		ret = SSH_ERR_SIGNATURE_INVALID;
190
		goto out;
196
		goto out;
191
	default:
197
	}
198
	psig = sigb;
199
	if ((slen = i2d_DSA_SIG(sig, &psig)) == 0) {
192
		ret = SSH_ERR_LIBCRYPTO_ERROR;
200
		ret = SSH_ERR_LIBCRYPTO_ERROR;
193
		goto out;
201
		goto out;
194
	}
202
	}
195
203
204
	if ((pkey = EVP_PKEY_new()) == NULL ||
205
	    EVP_PKEY_set1_DSA(pkey, key->dsa) != 1) {
206
		ret = SSH_ERR_ALLOC_FAIL;
207
		goto out;
208
	}
209
	ret = sshkey_verify_signature(pkey, SSH_DIGEST_SHA1, data, datalen,
210
	    sigb, slen);
211
	EVP_PKEY_free(pkey);
212
196
 out:
213
 out:
197
	explicit_bzero(digest, sizeof(digest));
214
	free(sigb);
198
	DSA_SIG_free(sig);
215
	DSA_SIG_free(sig);
199
	BN_clear_free(sig_r);
216
	BN_clear_free(sig_r);
200
	BN_clear_free(sig_s);
217
	BN_clear_free(sig_s);
(-)a/ssh-ecdsa.c (-27 / +42 lines)
Lines 50-60 int Link Here
50
ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
50
ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
51
    const u_char *data, size_t datalen, u_int compat)
51
    const u_char *data, size_t datalen, u_int compat)
52
{
52
{
53
	EVP_PKEY *pkey = NULL;
53
	ECDSA_SIG *sig = NULL;
54
	ECDSA_SIG *sig = NULL;
55
	unsigned char *sigb = NULL;
56
	const unsigned char *psig;
54
	const BIGNUM *sig_r, *sig_s;
57
	const BIGNUM *sig_r, *sig_s;
55
	int hash_alg;
58
	int hash_alg;
56
	u_char digest[SSH_DIGEST_MAX_LENGTH];
59
	int len;
57
	size_t len, dlen;
58
	struct sshbuf *b = NULL, *bb = NULL;
60
	struct sshbuf *b = NULL, *bb = NULL;
59
	int ret = SSH_ERR_INTERNAL_ERROR;
61
	int ret = SSH_ERR_INTERNAL_ERROR;
60
62
Lines 67-84 ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, Link Here
67
	    sshkey_type_plain(key->type) != KEY_ECDSA)
69
	    sshkey_type_plain(key->type) != KEY_ECDSA)
68
		return SSH_ERR_INVALID_ARGUMENT;
70
		return SSH_ERR_INVALID_ARGUMENT;
69
71
70
	if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1 ||
72
	if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1)
71
	    (dlen = ssh_digest_bytes(hash_alg)) == 0)
72
		return SSH_ERR_INTERNAL_ERROR;
73
		return SSH_ERR_INTERNAL_ERROR;
73
	if ((ret = ssh_digest_memory(hash_alg, data, datalen,
74
74
	    digest, sizeof(digest))) != 0)
75
	if ((pkey = EVP_PKEY_new()) == NULL ||
76
	    EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa) != 1)
77
		return SSH_ERR_ALLOC_FAIL;
78
	ret = sshkey_calculate_signature(pkey, hash_alg, &sigb, &len, data,
79
	    datalen);
80
	EVP_PKEY_free(pkey);
81
	if (ret < 0) {
75
		goto out;
82
		goto out;
83
	}
76
84
77
	if ((sig = ECDSA_do_sign(digest, dlen, key->ecdsa)) == NULL) {
85
	psig = sigb;
86
	if ((sig = d2i_ECDSA_SIG(NULL, &psig, len)) == NULL) {
78
		ret = SSH_ERR_LIBCRYPTO_ERROR;
87
		ret = SSH_ERR_LIBCRYPTO_ERROR;
79
		goto out;
88
		goto out;
80
	}
89
	}
81
82
	if ((bb = sshbuf_new()) == NULL || (b = sshbuf_new()) == NULL) {
90
	if ((bb = sshbuf_new()) == NULL || (b = sshbuf_new()) == NULL) {
83
		ret = SSH_ERR_ALLOC_FAIL;
91
		ret = SSH_ERR_ALLOC_FAIL;
84
		goto out;
92
		goto out;
Lines 102-108 ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, Link Here
102
		*lenp = len;
110
		*lenp = len;
103
	ret = 0;
111
	ret = 0;
104
 out:
112
 out:
105
	explicit_bzero(digest, sizeof(digest));
113
	free(sigb);
106
	sshbuf_free(b);
114
	sshbuf_free(b);
107
	sshbuf_free(bb);
115
	sshbuf_free(bb);
108
	ECDSA_SIG_free(sig);
116
	ECDSA_SIG_free(sig);
Lines 115-136 ssh_ecdsa_verify(const struct sshkey *key, Link Here
115
    const u_char *signature, size_t signaturelen,
123
    const u_char *signature, size_t signaturelen,
116
    const u_char *data, size_t datalen, u_int compat)
124
    const u_char *data, size_t datalen, u_int compat)
117
{
125
{
126
	EVP_PKEY *pkey = NULL;
118
	ECDSA_SIG *sig = NULL;
127
	ECDSA_SIG *sig = NULL;
119
	BIGNUM *sig_r = NULL, *sig_s = NULL;
128
	BIGNUM *sig_r = NULL, *sig_s = NULL;
120
	int hash_alg;
129
	int hash_alg, len;
121
	u_char digest[SSH_DIGEST_MAX_LENGTH];
122
	size_t dlen;
123
	int ret = SSH_ERR_INTERNAL_ERROR;
130
	int ret = SSH_ERR_INTERNAL_ERROR;
124
	struct sshbuf *b = NULL, *sigbuf = NULL;
131
	struct sshbuf *b = NULL, *sigbuf = NULL;
125
	char *ktype = NULL;
132
	char *ktype = NULL;
133
	unsigned char *sigb = NULL, *psig = NULL;
126
134
127
	if (key == NULL || key->ecdsa == NULL ||
135
	if (key == NULL || key->ecdsa == NULL ||
128
	    sshkey_type_plain(key->type) != KEY_ECDSA ||
136
	    sshkey_type_plain(key->type) != KEY_ECDSA ||
129
	    signature == NULL || signaturelen == 0)
137
	    signature == NULL || signaturelen == 0)
130
		return SSH_ERR_INVALID_ARGUMENT;
138
		return SSH_ERR_INVALID_ARGUMENT;
131
139
132
	if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1 ||
140
	if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1)
133
	    (dlen = ssh_digest_bytes(hash_alg)) == 0)
134
		return SSH_ERR_INTERNAL_ERROR;
141
		return SSH_ERR_INTERNAL_ERROR;
135
142
136
	/* fetch signature */
143
	/* fetch signature */
Lines 166-193 ssh_ecdsa_verify(const struct sshkey *key, Link Here
166
	}
173
	}
167
	sig_r = sig_s = NULL; /* transferred */
174
	sig_r = sig_s = NULL; /* transferred */
168
175
169
	if (sshbuf_len(sigbuf) != 0) {
176
	/* Figure out the length */
170
		ret = SSH_ERR_UNEXPECTED_TRAILING_DATA;
177
	if ((len = i2d_ECDSA_SIG(sig, NULL)) == 0) {
178
		ret = SSH_ERR_LIBCRYPTO_ERROR;
179
		goto out;
180
	}
181
	if ((sigb = malloc(len)) == NULL) {
182
		ret = SSH_ERR_ALLOC_FAIL;
171
		goto out;
183
		goto out;
172
	}
184
	}
173
	if ((ret = ssh_digest_memory(hash_alg, data, datalen,
185
	psig = sigb;
174
	    digest, sizeof(digest))) != 0)
186
	if ((len = i2d_ECDSA_SIG(sig, &psig)) == 0) {
187
		ret = SSH_ERR_LIBCRYPTO_ERROR;
175
		goto out;
188
		goto out;
189
	}
176
190
177
	switch (ECDSA_do_verify(digest, dlen, sig, key->ecdsa)) {
191
	if (sshbuf_len(sigbuf) != 0) {
178
	case 1:
192
		ret = SSH_ERR_UNEXPECTED_TRAILING_DATA;
179
		ret = 0;
180
		break;
181
	case 0:
182
		ret = SSH_ERR_SIGNATURE_INVALID;
183
		goto out;
193
		goto out;
184
	default:
194
	}
185
		ret = SSH_ERR_LIBCRYPTO_ERROR;
195
196
	if ((pkey = EVP_PKEY_new()) == NULL ||
197
	    EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa) != 1) {
198
		ret =  SSH_ERR_ALLOC_FAIL;
186
		goto out;
199
		goto out;
187
	}
200
	}
201
	ret = sshkey_verify_signature(pkey, hash_alg, data, datalen, sigb, len);
202
	EVP_PKEY_free(pkey);
188
203
189
 out:
204
 out:
190
	explicit_bzero(digest, sizeof(digest));
205
	free(sigb);
191
	sshbuf_free(sigbuf);
206
	sshbuf_free(sigbuf);
192
	sshbuf_free(b);
207
	sshbuf_free(b);
193
	ECDSA_SIG_free(sig);
208
	ECDSA_SIG_free(sig);
(-)a/ssh-rsa.c (-158 / +35 lines)
Lines 37-43 Link Here
37
37
38
#include "openbsd-compat/openssl-compat.h"
38
#include "openbsd-compat/openssl-compat.h"
39
39
40
static int openssh_RSA_verify(int, u_char *, size_t, u_char *, size_t, RSA *);
40
static int openssh_RSA_verify(int, const u_char *, size_t, u_char *, size_t, EVP_PKEY *);
41
41
42
static const char *
42
static const char *
43
rsa_hash_alg_ident(int hash_alg)
43
rsa_hash_alg_ident(int hash_alg)
Lines 90-110 rsa_hash_id_from_keyname(const char *alg) Link Here
90
	return -1;
90
	return -1;
91
}
91
}
92
92
93
static int
94
rsa_hash_alg_nid(int type)
95
{
96
	switch (type) {
97
	case SSH_DIGEST_SHA1:
98
		return NID_sha1;
99
	case SSH_DIGEST_SHA256:
100
		return NID_sha256;
101
	case SSH_DIGEST_SHA512:
102
		return NID_sha512;
103
	default:
104
		return -1;
105
	}
106
}
107
108
int
93
int
109
ssh_rsa_complete_crt_parameters(struct sshkey *key, const BIGNUM *iqmp)
94
ssh_rsa_complete_crt_parameters(struct sshkey *key, const BIGNUM *iqmp)
110
{
95
{
Lines 164-174 int Link Here
164
ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
149
ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
165
    const u_char *data, size_t datalen, const char *alg_ident)
150
    const u_char *data, size_t datalen, const char *alg_ident)
166
{
151
{
167
	const BIGNUM *rsa_n;
152
	EVP_PKEY *pkey = NULL;
168
	u_char digest[SSH_DIGEST_MAX_LENGTH], *sig = NULL;
153
	u_char *sig = NULL;
169
	size_t slen = 0;
154
	int len, slen = 0;
170
	u_int dlen, len;
155
	int hash_alg, ret = SSH_ERR_INTERNAL_ERROR;
171
	int nid, hash_alg, ret = SSH_ERR_INTERNAL_ERROR;
172
	struct sshbuf *b = NULL;
156
	struct sshbuf *b = NULL;
173
157
174
	if (lenp != NULL)
158
	if (lenp != NULL)
Lines 180-212 ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, Link Here
180
		hash_alg = SSH_DIGEST_SHA1;
164
		hash_alg = SSH_DIGEST_SHA1;
181
	else
165
	else
182
		hash_alg = rsa_hash_id_from_keyname(alg_ident);
166
		hash_alg = rsa_hash_id_from_keyname(alg_ident);
167
183
	if (key == NULL || key->rsa == NULL || hash_alg == -1 ||
168
	if (key == NULL || key->rsa == NULL || hash_alg == -1 ||
184
	    sshkey_type_plain(key->type) != KEY_RSA)
169
	    sshkey_type_plain(key->type) != KEY_RSA)
185
		return SSH_ERR_INVALID_ARGUMENT;
170
		return SSH_ERR_INVALID_ARGUMENT;
186
	RSA_get0_key(key->rsa, &rsa_n, NULL, NULL);
187
	if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
188
		return SSH_ERR_KEY_LENGTH;
189
	slen = RSA_size(key->rsa);
171
	slen = RSA_size(key->rsa);
190
	if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM)
172
	if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE)
191
		return SSH_ERR_INVALID_ARGUMENT;
173
		return SSH_ERR_KEY_LENGTH;
192
193
	/* hash the data */
194
	nid = rsa_hash_alg_nid(hash_alg);
195
	if ((dlen = ssh_digest_bytes(hash_alg)) == 0)
196
		return SSH_ERR_INTERNAL_ERROR;
197
	if ((ret = ssh_digest_memory(hash_alg, data, datalen,
198
	    digest, sizeof(digest))) != 0)
199
		goto out;
200
174
201
	if ((sig = malloc(slen)) == NULL) {
175
	if ((pkey = EVP_PKEY_new()) == NULL ||
202
		ret = SSH_ERR_ALLOC_FAIL;
176
	    EVP_PKEY_set1_RSA(pkey, key->rsa) != 1)
177
		return SSH_ERR_ALLOC_FAIL;
178
	ret = sshkey_calculate_signature(pkey, hash_alg, &sig, &len, data,
179
	    datalen);
180
	EVP_PKEY_free(pkey);
181
	if (ret < 0) {
203
		goto out;
182
		goto out;
204
	}
183
	}
205
184
206
	if (RSA_sign(nid, digest, dlen, sig, &len, key->rsa) != 1) {
207
		ret = SSH_ERR_LIBCRYPTO_ERROR;
208
		goto out;
209
	}
210
	if (len < slen) {
185
	if (len < slen) {
211
		size_t diff = slen - len;
186
		size_t diff = slen - len;
212
		memmove(sig + diff, sig, len);
187
		memmove(sig + diff, sig, len);
Lines 215-220 ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, Link Here
215
		ret = SSH_ERR_INTERNAL_ERROR;
190
		ret = SSH_ERR_INTERNAL_ERROR;
216
		goto out;
191
		goto out;
217
	}
192
	}
193
218
	/* encode signature */
194
	/* encode signature */
219
	if ((b = sshbuf_new()) == NULL) {
195
	if ((b = sshbuf_new()) == NULL) {
220
		ret = SSH_ERR_ALLOC_FAIL;
196
		ret = SSH_ERR_ALLOC_FAIL;
Lines 235-241 ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, Link Here
235
		*lenp = len;
211
		*lenp = len;
236
	ret = 0;
212
	ret = 0;
237
 out:
213
 out:
238
	explicit_bzero(digest, sizeof(digest));
239
	freezero(sig, slen);
214
	freezero(sig, slen);
240
	sshbuf_free(b);
215
	sshbuf_free(b);
241
	return ret;
216
	return ret;
Lines 246-255 ssh_rsa_verify(const struct sshkey *key, Link Here
246
    const u_char *sig, size_t siglen, const u_char *data, size_t datalen,
221
    const u_char *sig, size_t siglen, const u_char *data, size_t datalen,
247
    const char *alg)
222
    const char *alg)
248
{
223
{
249
	const BIGNUM *rsa_n;
224
	EVP_PKEY *pkey = NULL;
250
	char *sigtype = NULL;
225
	char *sigtype = NULL;
251
	int hash_alg, want_alg, ret = SSH_ERR_INTERNAL_ERROR;
226
	int hash_alg, want_alg, ret = SSH_ERR_INTERNAL_ERROR;
252
	size_t len = 0, diff, modlen, dlen;
227
	size_t len = 0, diff, modlen;
253
	struct sshbuf *b = NULL;
228
	struct sshbuf *b = NULL;
254
	u_char digest[SSH_DIGEST_MAX_LENGTH], *osigblob, *sigblob = NULL;
229
	u_char digest[SSH_DIGEST_MAX_LENGTH], *osigblob, *sigblob = NULL;
255
230
Lines 257-264 ssh_rsa_verify(const struct sshkey *key, Link Here
257
	    sshkey_type_plain(key->type) != KEY_RSA ||
232
	    sshkey_type_plain(key->type) != KEY_RSA ||
258
	    sig == NULL || siglen == 0)
233
	    sig == NULL || siglen == 0)
259
		return SSH_ERR_INVALID_ARGUMENT;
234
		return SSH_ERR_INVALID_ARGUMENT;
260
	RSA_get0_key(key->rsa, &rsa_n, NULL, NULL);
235
	if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE)
261
	if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
262
		return SSH_ERR_KEY_LENGTH;
236
		return SSH_ERR_KEY_LENGTH;
263
237
264
	if ((b = sshbuf_from(sig, siglen)) == NULL)
238
	if ((b = sshbuf_from(sig, siglen)) == NULL)
Lines 310-325 ssh_rsa_verify(const struct sshkey *key, Link Here
310
		explicit_bzero(sigblob, diff);
284
		explicit_bzero(sigblob, diff);
311
		len = modlen;
285
		len = modlen;
312
	}
286
	}
313
	if ((dlen = ssh_digest_bytes(hash_alg)) == 0) {
287
314
		ret = SSH_ERR_INTERNAL_ERROR;
288
	if ((pkey = EVP_PKEY_new()) == NULL ||
289
	    EVP_PKEY_set1_RSA(pkey, key->rsa) != 1) {
290
		ret = SSH_ERR_ALLOC_FAIL;
315
		goto out;
291
		goto out;
316
	}
292
	}
317
	if ((ret = ssh_digest_memory(hash_alg, data, datalen,
293
	ret = openssh_RSA_verify(hash_alg, data, datalen, sigblob, len, pkey);
318
	    digest, sizeof(digest))) != 0)
294
	EVP_PKEY_free(pkey);
319
		goto out;
320
295
321
	ret = openssh_RSA_verify(hash_alg, digest, dlen, sigblob, len,
322
	    key->rsa);
323
 out:
296
 out:
324
	freezero(sigblob, len);
297
	freezero(sigblob, len);
325
	free(sigtype);
298
	free(sigtype);
Lines 328-449 ssh_rsa_verify(const struct sshkey *key, Link Here
328
	return ret;
301
	return ret;
329
}
302
}
330
303
331
/*
332
 * See:
333
 * http://www.rsasecurity.com/rsalabs/pkcs/pkcs-1/
334
 * ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.asn
335
 */
336
337
/*
338
 * id-sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
339
 *	oiw(14) secsig(3) algorithms(2) 26 }
340
 */
341
static const u_char id_sha1[] = {
342
	0x30, 0x21, /* type Sequence, length 0x21 (33) */
343
	0x30, 0x09, /* type Sequence, length 0x09 */
344
	0x06, 0x05, /* type OID, length 0x05 */
345
	0x2b, 0x0e, 0x03, 0x02, 0x1a, /* id-sha1 OID */
346
	0x05, 0x00, /* NULL */
347
	0x04, 0x14  /* Octet string, length 0x14 (20), followed by sha1 hash */
348
};
349
350
/*
351
 * See http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html
352
 * id-sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840)
353
 *      organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2)
354
 *      id-sha256(1) }
355
 */
356
static const u_char id_sha256[] = {
357
	0x30, 0x31, /* type Sequence, length 0x31 (49) */
358
	0x30, 0x0d, /* type Sequence, length 0x0d (13) */
359
	0x06, 0x09, /* type OID, length 0x09 */
360
	0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, /* id-sha256 */
361
	0x05, 0x00, /* NULL */
362
	0x04, 0x20  /* Octet string, length 0x20 (32), followed by sha256 hash */
363
};
364
365
/*
366
 * See http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html
367
 * id-sha512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840)
368
 *      organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2)
369
 *      id-sha256(3) }
370
 */
371
static const u_char id_sha512[] = {
372
	0x30, 0x51, /* type Sequence, length 0x51 (81) */
373
	0x30, 0x0d, /* type Sequence, length 0x0d (13) */
374
	0x06, 0x09, /* type OID, length 0x09 */
375
	0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, /* id-sha512 */
376
	0x05, 0x00, /* NULL */
377
	0x04, 0x40  /* Octet string, length 0x40 (64), followed by sha512 hash */
378
};
379
380
static int
304
static int
381
rsa_hash_alg_oid(int hash_alg, const u_char **oidp, size_t *oidlenp)
305
openssh_RSA_verify(int hash_alg, const u_char *data, size_t datalen,
306
    u_char *sigbuf, size_t siglen, EVP_PKEY *pkey)
382
{
307
{
383
	switch (hash_alg) {
308
	size_t rsasize = 0;
384
	case SSH_DIGEST_SHA1:
309
	const RSA *rsa;
385
		*oidp = id_sha1;
310
	int ret;
386
		*oidlenp = sizeof(id_sha1);
387
		break;
388
	case SSH_DIGEST_SHA256:
389
		*oidp = id_sha256;
390
		*oidlenp = sizeof(id_sha256);
391
		break;
392
	case SSH_DIGEST_SHA512:
393
		*oidp = id_sha512;
394
		*oidlenp = sizeof(id_sha512);
395
		break;
396
	default:
397
		return SSH_ERR_INVALID_ARGUMENT;
398
	}
399
	return 0;
400
}
401
311
402
static int
312
	rsa = EVP_PKEY_get0_RSA(pkey);
403
openssh_RSA_verify(int hash_alg, u_char *hash, size_t hashlen,
404
    u_char *sigbuf, size_t siglen, RSA *rsa)
405
{
406
	size_t rsasize = 0, oidlen = 0, hlen = 0;
407
	int ret, len, oidmatch, hashmatch;
408
	const u_char *oid = NULL;
409
	u_char *decrypted = NULL;
410
411
	if ((ret = rsa_hash_alg_oid(hash_alg, &oid, &oidlen)) != 0)
412
		return ret;
413
	ret = SSH_ERR_INTERNAL_ERROR;
414
	hlen = ssh_digest_bytes(hash_alg);
415
	if (hashlen != hlen) {
416
		ret = SSH_ERR_INVALID_ARGUMENT;
417
		goto done;
418
	}
419
	rsasize = RSA_size(rsa);
313
	rsasize = RSA_size(rsa);
420
	if (rsasize <= 0 || rsasize > SSHBUF_MAX_BIGNUM ||
314
	if (rsasize <= 0 || rsasize > SSHBUF_MAX_BIGNUM ||
421
	    siglen == 0 || siglen > rsasize) {
315
	    siglen == 0 || siglen > rsasize) {
422
		ret = SSH_ERR_INVALID_ARGUMENT;
316
		ret = SSH_ERR_INVALID_ARGUMENT;
423
		goto done;
317
		goto done;
424
	}
318
	}
425
	if ((decrypted = malloc(rsasize)) == NULL) {
319
426
		ret = SSH_ERR_ALLOC_FAIL;
320
	ret = sshkey_verify_signature(pkey, hash_alg, data, datalen,
427
		goto done;
321
	    sigbuf, siglen);
428
	}
322
429
	if ((len = RSA_public_decrypt(siglen, sigbuf, decrypted, rsa,
430
	    RSA_PKCS1_PADDING)) < 0) {
431
		ret = SSH_ERR_LIBCRYPTO_ERROR;
432
		goto done;
433
	}
434
	if (len < 0 || (size_t)len != hlen + oidlen) {
435
		ret = SSH_ERR_INVALID_FORMAT;
436
		goto done;
437
	}
438
	oidmatch = timingsafe_bcmp(decrypted, oid, oidlen) == 0;
439
	hashmatch = timingsafe_bcmp(decrypted + oidlen, hash, hlen) == 0;
440
	if (!oidmatch || !hashmatch) {
441
		ret = SSH_ERR_SIGNATURE_INVALID;
442
		goto done;
443
	}
444
	ret = 0;
445
done:
323
done:
446
	freezero(decrypted, rsasize);
447
	return ret;
324
	return ret;
448
}
325
}
449
#endif /* WITH_OPENSSL */
326
#endif /* WITH_OPENSSL */
(-)a/sshkey.c (+77 lines)
Lines 358-363 sshkey_type_plain(int type) Link Here
358
}
358
}
359
359
360
#ifdef WITH_OPENSSL
360
#ifdef WITH_OPENSSL
361
int
362
sshkey_calculate_signature(EVP_PKEY *pkey, int hash_alg, u_char **sigp,
363
    int *lenp, const u_char *data, size_t datalen)
364
{
365
	EVP_MD_CTX *ctx = NULL;
366
	u_char *sig = NULL;
367
	int ret, slen, len;
368
369
	if (sigp == NULL || lenp == NULL) {
370
		return SSH_ERR_INVALID_ARGUMENT;
371
	}
372
373
	slen = EVP_PKEY_size(pkey);
374
	if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM)
375
		return SSH_ERR_INVALID_ARGUMENT;
376
377
	len = slen;
378
	if ((sig = malloc(slen)) == NULL) {
379
		return SSH_ERR_ALLOC_FAIL;
380
	}
381
382
	if ((ctx = EVP_MD_CTX_new()) == NULL) {
383
		ret = SSH_ERR_ALLOC_FAIL;
384
		goto error;
385
	}
386
	if (EVP_SignInit_ex(ctx, ssh_digest_to_md(hash_alg), NULL) <= 0 ||
387
	    EVP_SignUpdate(ctx, data, datalen) <= 0 ||
388
	    EVP_SignFinal(ctx, sig, &len, pkey) <= 0) {
389
		ret = SSH_ERR_LIBCRYPTO_ERROR;
390
		goto error;
391
	}
392
393
	*sigp = sig;
394
	*lenp = len;
395
	/* Now owned by the caller */
396
	sig = NULL;
397
	ret = 0;
398
399
error:
400
	EVP_MD_CTX_free(ctx);
401
	free(sig);
402
	return ret;
403
}
404
405
int
406
sshkey_verify_signature(EVP_PKEY *pkey, int hash_alg, const u_char *data,
407
    size_t datalen, u_char *sigbuf, int siglen)
408
{
409
	EVP_MD_CTX *ctx = NULL;
410
	int ret;
411
412
	if ((ctx = EVP_MD_CTX_new()) == NULL) {
413
		return SSH_ERR_ALLOC_FAIL;
414
	}
415
	if (EVP_VerifyInit_ex(ctx, ssh_digest_to_md(hash_alg), NULL) <= 0 ||
416
	    EVP_VerifyUpdate(ctx, data, datalen) <= 0) {
417
		ret = SSH_ERR_LIBCRYPTO_ERROR;
418
		goto done;
419
	}
420
	ret = EVP_VerifyFinal(ctx, sigbuf, siglen, pkey);
421
	switch (ret) {
422
	case 1:
423
		ret = 0;
424
		break;
425
	case 0:
426
		ret = SSH_ERR_SIGNATURE_INVALID;
427
		break;
428
	default:
429
		ret = SSH_ERR_LIBCRYPTO_ERROR;
430
		break;
431
	}
432
433
done:
434
	EVP_MD_CTX_free(ctx);
435
	return ret;
436
}
437
361
/* XXX: these are really begging for a table-driven approach */
438
/* XXX: these are really begging for a table-driven approach */
362
int
439
int
363
sshkey_curve_name_to_nid(const char *name)
440
sshkey_curve_name_to_nid(const char *name)
(-)a/sshkey.h (+4 lines)
Lines 179-184 const char *sshkey_ssh_name(const struct sshkey *); Link Here
179
const char	*sshkey_ssh_name_plain(const struct sshkey *);
179
const char	*sshkey_ssh_name_plain(const struct sshkey *);
180
int		 sshkey_names_valid2(const char *, int);
180
int		 sshkey_names_valid2(const char *, int);
181
char		*sshkey_alg_list(int, int, int, char);
181
char		*sshkey_alg_list(int, int, int, char);
182
int		 sshkey_calculate_signature(EVP_PKEY*, int, u_char **,
183
    int *, const u_char *, size_t);
184
int		 sshkey_verify_signature(EVP_PKEY *, int, const u_char *,
185
    size_t, u_char *, int);
182
186
183
int	 sshkey_from_blob(const u_char *, size_t, struct sshkey **);
187
int	 sshkey_from_blob(const u_char *, size_t, struct sshkey **);
184
int	 sshkey_fromb(struct sshbuf *, struct sshkey **);
188
int	 sshkey_fromb(struct sshbuf *, struct sshkey **);

Return to bug 3005