#include "includes.h"#include <openssl/rsa.h>#include <openssl/md5.h>#include "rsa.h"#include "packet.h"#include "xmalloc.h"#include "ssh1.h"#include "uidswap.h"#include "match.h"#include "auth-options.h"#include "pathnames.h"#include "log.h"#include "servconf.h"#include "auth.h"#include "hostfile.h"#include "monitor_wrap.h"#include "ssh.h"#include "misc.h"Go to the source code of this file.
Functions | |
| RCSID ("$OpenBSD: auth-rsa.c,v 1.63 2005/06/17 02:44:32 djm Exp $") | |
| BIGNUM * | auth_rsa_generate_challenge (Key *key) |
| int | auth_rsa_verify_response (Key *key, BIGNUM *challenge, u_char response[16]) |
| int | auth_rsa_challenge_dialog (Key *key) |
| int | auth_rsa_key_allowed (struct passwd *pw, BIGNUM *client_n, Key **rkey) |
| int | auth_rsa (Authctxt *authctxt, BIGNUM *client_n) |
Variables | |
| ServerOptions | options |
| u_char | session_id [16] |
|
||||||||||||
|
Definition at line 287 of file auth-rsa.c. References auth_clear_options(), auth_rsa_challenge_dialog(), auth_rsa_key_allowed(), key_fingerprint(), key_free(), key_type(), packet_send_debug(), PRIVSEP, Authctxt::pw, SSH_FP_HEX, SSH_FP_MD5, Authctxt::valid, verbose(), and xfree(). Referenced by auth1_process_rsa(). 00288 { 00289 Key *key; 00290 char *fp; 00291 struct passwd *pw = authctxt->pw; 00292 00293 /* no user given */ 00294 if (!authctxt->valid) 00295 return 0; 00296 00297 if (!PRIVSEP(auth_rsa_key_allowed(pw, client_n, &key))) { 00298 auth_clear_options(); 00299 return (0); 00300 } 00301 00302 /* Perform the challenge-response dialog for this key. */ 00303 if (!auth_rsa_challenge_dialog(key)) { 00304 /* Wrong response. */ 00305 verbose("Wrong response to RSA authentication challenge."); 00306 packet_send_debug("Wrong response to RSA authentication challenge."); 00307 /* 00308 * Break out of the loop. Otherwise we might send 00309 * another challenge and break the protocol. 00310 */ 00311 key_free(key); 00312 return (0); 00313 } 00314 /* 00315 * Correct response. The client has been successfully 00316 * authenticated. Note that we have not yet processed the 00317 * options; this will be reset if the options cause the 00318 * authentication to be rejected. 00319 */ 00320 fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); 00321 verbose("Found matching %s key: %s", 00322 key_type(key), fp); 00323 xfree(fp); 00324 key_free(key); 00325 00326 packet_send_debug("RSA authentication accepted."); 00327 return (1); 00328 }
|
|
|
Definition at line 116 of file auth-rsa.c. References auth_rsa_generate_challenge(), auth_rsa_verify_response(), fatal(), packet_check_eom, packet_get_char(), packet_put_bignum(), packet_read_expect(), packet_send(), packet_start(), packet_write_wait(), PRIVSEP, response(), Key::rsa, rsa_public_encrypt(), SSH_CMSG_AUTH_RSA_RESPONSE, and SSH_SMSG_AUTH_RSA_CHALLENGE. Referenced by auth_rhosts_rsa(), and auth_rsa(). 00117 { 00118 BIGNUM *challenge, *encrypted_challenge; 00119 u_char response[16]; 00120 int i, success; 00121 00122 if ((encrypted_challenge = BN_new()) == NULL) 00123 fatal("auth_rsa_challenge_dialog: BN_new() failed"); 00124 00125 challenge = PRIVSEP(auth_rsa_generate_challenge(key)); 00126 00127 /* Encrypt the challenge with the public key. */ 00128 rsa_public_encrypt(encrypted_challenge, challenge, key->rsa); 00129 00130 /* Send the encrypted challenge to the client. */ 00131 packet_start(SSH_SMSG_AUTH_RSA_CHALLENGE); 00132 packet_put_bignum(encrypted_challenge); 00133 packet_send(); 00134 BN_clear_free(encrypted_challenge); 00135 packet_write_wait(); 00136 00137 /* Wait for a response. */ 00138 packet_read_expect(SSH_CMSG_AUTH_RSA_RESPONSE); 00139 for (i = 0; i < 16; i++) 00140 response[i] = packet_get_char(); 00141 packet_check_eom(); 00142 00143 success = PRIVSEP(auth_rsa_verify_response(key, challenge, response)); 00144 BN_clear_free(challenge); 00145 return (success); 00146 }
|
|
|
Definition at line 58 of file auth-rsa.c. References fatal(), and Key::rsa. Referenced by auth_rsa_challenge_dialog(), and mm_answer_rsa_challenge(). 00059 { 00060 BIGNUM *challenge; 00061 BN_CTX *ctx; 00062 00063 if ((challenge = BN_new()) == NULL) 00064 fatal("auth_rsa_generate_challenge: BN_new() failed"); 00065 /* Generate a random challenge. */ 00066 BN_rand(challenge, 256, 0, 0); 00067 if ((ctx = BN_CTX_new()) == NULL) 00068 fatal("auth_rsa_generate_challenge: BN_CTX_new() failed"); 00069 BN_mod(challenge, challenge, key->rsa->n, ctx); 00070 BN_CTX_free(ctx); 00071 00072 return challenge; 00073 }
|
|
||||||||||||||||
|
Definition at line 154 of file auth-rsa.c. References auth_parse_options(), authorized_keys_file(), bits, debug(), file, hostfile_read_key(), key_free(), key_new(), KEY_RSA1, logit(), read_keyfile_line(), restore_uid(), secure_filename(), SSH_MAX_PUBKEY_BYTES, ServerOptions::strict_modes, temporarily_use_uid(), and xfree(). Referenced by auth_rsa(), and mm_answer_rsa_keyallowed(). 00155 { 00156 char line[SSH_MAX_PUBKEY_BYTES], *file; 00157 int allowed = 0; 00158 u_int bits; 00159 FILE *f; 00160 u_long linenum = 0; 00161 struct stat st; 00162 Key *key; 00163 00164 /* Temporarily use the user's uid. */ 00165 temporarily_use_uid(pw); 00166 00167 /* The authorized keys. */ 00168 file = authorized_keys_file(pw); 00169 debug("trying public RSA key file %s", file); 00170 00171 /* Fail quietly if file does not exist */ 00172 if (stat(file, &st) < 0) { 00173 /* Restore the privileged uid. */ 00174 restore_uid(); 00175 xfree(file); 00176 return (0); 00177 } 00178 /* Open the file containing the authorized keys. */ 00179 f = fopen(file, "r"); 00180 if (!f) { 00181 /* Restore the privileged uid. */ 00182 restore_uid(); 00183 xfree(file); 00184 return (0); 00185 } 00186 if (options.strict_modes && 00187 secure_filename(f, file, pw, line, sizeof(line)) != 0) { 00188 xfree(file); 00189 fclose(f); 00190 logit("Authentication refused: %s", line); 00191 restore_uid(); 00192 return (0); 00193 } 00194 00195 /* Flag indicating whether the key is allowed. */ 00196 allowed = 0; 00197 00198 key = key_new(KEY_RSA1); 00199 00200 /* 00201 * Go though the accepted keys, looking for the current key. If 00202 * found, perform a challenge-response dialog to verify that the 00203 * user really has the corresponding private key. 00204 */ 00205 while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) { 00206 char *cp; 00207 char *key_options; 00208 int keybits; 00209 00210 /* Skip leading whitespace, empty and comment lines. */ 00211 for (cp = line; *cp == ' ' || *cp == '\t'; cp++) 00212 ; 00213 if (!*cp || *cp == '\n' || *cp == '#') 00214 continue; 00215 00216 /* 00217 * Check if there are options for this key, and if so, 00218 * save their starting address and skip the option part 00219 * for now. If there are no options, set the starting 00220 * address to NULL. 00221 */ 00222 if (*cp < '0' || *cp > '9') { 00223 int quoted = 0; 00224 key_options = cp; 00225 for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) { 00226 if (*cp == '\\' && cp[1] == '"') 00227 cp++; /* Skip both */ 00228 else if (*cp == '"') 00229 quoted = !quoted; 00230 } 00231 } else 00232 key_options = NULL; 00233 00234 /* Parse the key from the line. */ 00235 if (hostfile_read_key(&cp, &bits, key) == 0) { 00236 debug("%.100s, line %lu: non ssh1 key syntax", 00237 file, linenum); 00238 continue; 00239 } 00240 /* cp now points to the comment part. */ 00241 00242 /* Check if the we have found the desired key (identified by its modulus). */ 00243 if (BN_cmp(key->rsa->n, client_n) != 0) 00244 continue; 00245 00246 /* check the real bits */ 00247 keybits = BN_num_bits(key->rsa->n); 00248 if (keybits < 0 || bits != (u_int)keybits) 00249 logit("Warning: %s, line %lu: keysize mismatch: " 00250 "actual %d vs. announced %d.", 00251 file, linenum, BN_num_bits(key->rsa->n), bits); 00252 00253 /* We have found the desired key. */ 00254 /* 00255 * If our options do not allow this key to be used, 00256 * do not send challenge. 00257 */ 00258 if (!auth_parse_options(pw, key_options, file, linenum)) 00259 continue; 00260 00261 /* break out, this key is allowed */ 00262 allowed = 1; 00263 break; 00264 } 00265 00266 /* Restore the privileged uid. */ 00267 restore_uid(); 00268 00269 /* Close the file. */ 00270 xfree(file); 00271 fclose(f); 00272 00273 /* return key if allowed */ 00274 if (allowed && rkey != NULL) 00275 *rkey = key; 00276 else 00277 key_free(key); 00278 return (allowed); 00279 }
|
|
||||||||||||||||
|
Definition at line 76 of file auth-rsa.c. References error(), fatal(), Key::rsa, session_id, and SSH_RSA_MINIMUM_MODULUS_SIZE. Referenced by auth_rsa_challenge_dialog(), and mm_answer_rsa_response(). 00077 { 00078 u_char buf[32], mdbuf[16]; 00079 MD5_CTX md; 00080 int len; 00081 00082 /* don't allow short keys */ 00083 if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { 00084 error("auth_rsa_verify_response: RSA modulus too small: %d < minimum %d bits", 00085 BN_num_bits(key->rsa->n), SSH_RSA_MINIMUM_MODULUS_SIZE); 00086 return (0); 00087 } 00088 00089 /* The response is MD5 of decrypted challenge plus session id. */ 00090 len = BN_num_bytes(challenge); 00091 if (len <= 0 || len > 32) 00092 fatal("auth_rsa_verify_response: bad challenge length %d", len); 00093 memset(buf, 0, 32); 00094 BN_bn2bin(challenge, buf + 32 - len); 00095 MD5_Init(&md); 00096 MD5_Update(&md, buf, 32); 00097 MD5_Update(&md, session_id, 16); 00098 MD5_Final(mdbuf, &md); 00099 00100 /* Verify that the response is the original challenge. */ 00101 if (memcmp(response, mdbuf, 16) != 0) { 00102 /* Wrong answer. */ 00103 return (0); 00104 } 00105 /* Correct answer. */ 00106 return (1); 00107 }
|
|
||||||||||||
|
|
|
|
|
|
|
Definition at line 41 of file sshconnect1.c. Referenced by auth_rsa_verify_response(), do_ssh1_kex(), mm_answer_sessid(), process_authentication_challenge1(), respond_to_rsa_challenge(), ssh_kex(), and try_agent_authentication(). |