diff options
Diffstat (limited to 'ssh-rsa.c')
-rw-r--r-- | ssh-rsa.c | 49 |
1 files changed, 36 insertions, 13 deletions
@@ -35,6 +35,8 @@ | |||
35 | #include "digest.h" | 35 | #include "digest.h" |
36 | #include "log.h" | 36 | #include "log.h" |
37 | 37 | ||
38 | #include "openbsd-compat/openssl-compat.h" | ||
39 | |||
38 | static int openssh_RSA_verify(int, u_char *, size_t, u_char *, size_t, RSA *); | 40 | static int openssh_RSA_verify(int, u_char *, size_t, u_char *, size_t, RSA *); |
39 | 41 | ||
40 | static const char * | 42 | static const char * |
@@ -104,38 +106,55 @@ rsa_hash_alg_nid(int type) | |||
104 | } | 106 | } |
105 | 107 | ||
106 | int | 108 | int |
107 | ssh_rsa_generate_additional_parameters(struct sshkey *key) | 109 | ssh_rsa_complete_crt_parameters(struct sshkey *key, const BIGNUM *iqmp) |
108 | { | 110 | { |
109 | BIGNUM *aux = NULL; | 111 | const BIGNUM *rsa_p, *rsa_q, *rsa_d; |
112 | BIGNUM *aux = NULL, *d_consttime = NULL; | ||
113 | BIGNUM *rsa_dmq1 = NULL, *rsa_dmp1 = NULL, *rsa_iqmp = NULL; | ||
110 | BN_CTX *ctx = NULL; | 114 | BN_CTX *ctx = NULL; |
111 | BIGNUM d; | ||
112 | int r; | 115 | int r; |
113 | 116 | ||
114 | if (key == NULL || key->rsa == NULL || | 117 | if (key == NULL || key->rsa == NULL || |
115 | sshkey_type_plain(key->type) != KEY_RSA) | 118 | sshkey_type_plain(key->type) != KEY_RSA) |
116 | return SSH_ERR_INVALID_ARGUMENT; | 119 | return SSH_ERR_INVALID_ARGUMENT; |
117 | 120 | ||
121 | RSA_get0_key(key->rsa, NULL, NULL, &rsa_d); | ||
122 | RSA_get0_factors(key->rsa, &rsa_p, &rsa_q); | ||
123 | |||
118 | if ((ctx = BN_CTX_new()) == NULL) | 124 | if ((ctx = BN_CTX_new()) == NULL) |
119 | return SSH_ERR_ALLOC_FAIL; | 125 | return SSH_ERR_ALLOC_FAIL; |
120 | if ((aux = BN_new()) == NULL) { | 126 | if ((aux = BN_new()) == NULL || |
127 | (rsa_dmq1 = BN_new()) == NULL || | ||
128 | (rsa_dmp1 = BN_new()) == NULL) | ||
129 | return SSH_ERR_ALLOC_FAIL; | ||
130 | if ((d_consttime = BN_dup(rsa_d)) == NULL || | ||
131 | (rsa_iqmp = BN_dup(iqmp)) == NULL) { | ||
121 | r = SSH_ERR_ALLOC_FAIL; | 132 | r = SSH_ERR_ALLOC_FAIL; |
122 | goto out; | 133 | goto out; |
123 | } | 134 | } |
124 | BN_set_flags(aux, BN_FLG_CONSTTIME); | 135 | BN_set_flags(aux, BN_FLG_CONSTTIME); |
136 | BN_set_flags(d_consttime, BN_FLG_CONSTTIME); | ||
125 | 137 | ||
126 | BN_init(&d); | 138 | if ((BN_sub(aux, rsa_q, BN_value_one()) == 0) || |
127 | BN_with_flags(&d, key->rsa->d, BN_FLG_CONSTTIME); | 139 | (BN_mod(rsa_dmq1, d_consttime, aux, ctx) == 0) || |
128 | 140 | (BN_sub(aux, rsa_p, BN_value_one()) == 0) || | |
129 | if ((BN_sub(aux, key->rsa->q, BN_value_one()) == 0) || | 141 | (BN_mod(rsa_dmp1, d_consttime, aux, ctx) == 0)) { |
130 | (BN_mod(key->rsa->dmq1, &d, aux, ctx) == 0) || | 142 | r = SSH_ERR_LIBCRYPTO_ERROR; |
131 | (BN_sub(aux, key->rsa->p, BN_value_one()) == 0) || | 143 | goto out; |
132 | (BN_mod(key->rsa->dmp1, &d, aux, ctx) == 0)) { | 144 | } |
145 | if (!RSA_set0_crt_params(key->rsa, rsa_dmp1, rsa_dmq1, rsa_iqmp)) { | ||
133 | r = SSH_ERR_LIBCRYPTO_ERROR; | 146 | r = SSH_ERR_LIBCRYPTO_ERROR; |
134 | goto out; | 147 | goto out; |
135 | } | 148 | } |
149 | rsa_dmp1 = rsa_dmq1 = rsa_iqmp = NULL; /* transferred */ | ||
150 | /* success */ | ||
136 | r = 0; | 151 | r = 0; |
137 | out: | 152 | out: |
138 | BN_clear_free(aux); | 153 | BN_clear_free(aux); |
154 | BN_clear_free(d_consttime); | ||
155 | BN_clear_free(rsa_dmp1); | ||
156 | BN_clear_free(rsa_dmq1); | ||
157 | BN_clear_free(rsa_iqmp); | ||
139 | BN_CTX_free(ctx); | 158 | BN_CTX_free(ctx); |
140 | return r; | 159 | return r; |
141 | } | 160 | } |
@@ -145,6 +164,7 @@ int | |||
145 | ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, | 164 | ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, |
146 | const u_char *data, size_t datalen, const char *alg_ident) | 165 | const u_char *data, size_t datalen, const char *alg_ident) |
147 | { | 166 | { |
167 | const BIGNUM *rsa_n; | ||
148 | u_char digest[SSH_DIGEST_MAX_LENGTH], *sig = NULL; | 168 | u_char digest[SSH_DIGEST_MAX_LENGTH], *sig = NULL; |
149 | size_t slen = 0; | 169 | size_t slen = 0; |
150 | u_int dlen, len; | 170 | u_int dlen, len; |
@@ -163,7 +183,8 @@ ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, | |||
163 | if (key == NULL || key->rsa == NULL || hash_alg == -1 || | 183 | if (key == NULL || key->rsa == NULL || hash_alg == -1 || |
164 | sshkey_type_plain(key->type) != KEY_RSA) | 184 | sshkey_type_plain(key->type) != KEY_RSA) |
165 | return SSH_ERR_INVALID_ARGUMENT; | 185 | return SSH_ERR_INVALID_ARGUMENT; |
166 | if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) | 186 | RSA_get0_key(key->rsa, &rsa_n, NULL, NULL); |
187 | if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE) | ||
167 | return SSH_ERR_KEY_LENGTH; | 188 | return SSH_ERR_KEY_LENGTH; |
168 | slen = RSA_size(key->rsa); | 189 | slen = RSA_size(key->rsa); |
169 | if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM) | 190 | if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM) |
@@ -225,6 +246,7 @@ ssh_rsa_verify(const struct sshkey *key, | |||
225 | const u_char *sig, size_t siglen, const u_char *data, size_t datalen, | 246 | const u_char *sig, size_t siglen, const u_char *data, size_t datalen, |
226 | const char *alg) | 247 | const char *alg) |
227 | { | 248 | { |
249 | const BIGNUM *rsa_n; | ||
228 | char *sigtype = NULL; | 250 | char *sigtype = NULL; |
229 | int hash_alg, want_alg, ret = SSH_ERR_INTERNAL_ERROR; | 251 | int hash_alg, want_alg, ret = SSH_ERR_INTERNAL_ERROR; |
230 | size_t len = 0, diff, modlen, dlen; | 252 | size_t len = 0, diff, modlen, dlen; |
@@ -235,7 +257,8 @@ ssh_rsa_verify(const struct sshkey *key, | |||
235 | sshkey_type_plain(key->type) != KEY_RSA || | 257 | sshkey_type_plain(key->type) != KEY_RSA || |
236 | sig == NULL || siglen == 0) | 258 | sig == NULL || siglen == 0) |
237 | return SSH_ERR_INVALID_ARGUMENT; | 259 | return SSH_ERR_INVALID_ARGUMENT; |
238 | if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) | 260 | RSA_get0_key(key->rsa, &rsa_n, NULL, NULL); |
261 | if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE) | ||
239 | return SSH_ERR_KEY_LENGTH; | 262 | return SSH_ERR_KEY_LENGTH; |
240 | 263 | ||
241 | if ((b = sshbuf_from(sig, siglen)) == NULL) | 264 | if ((b = sshbuf_from(sig, siglen)) == NULL) |