summaryrefslogtreecommitdiff
path: root/sshconnect2.c
diff options
context:
space:
mode:
Diffstat (limited to 'sshconnect2.c')
-rw-r--r--sshconnect2.c77
1 files changed, 57 insertions, 20 deletions
diff --git a/sshconnect2.c b/sshconnect2.c
index c35a0bd50..5743c2c41 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshconnect2.c,v 1.251 2016/12/04 23:54:02 djm Exp $ */ 1/* $OpenBSD: sshconnect2.c,v 1.255 2017/03/11 23:40:26 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * Copyright (c) 2008 Damien Miller. All rights reserved. 4 * Copyright (c) 2008 Damien Miller. All rights reserved.
@@ -227,8 +227,8 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port)
227#endif 227#endif
228 228
229 if (options.rekey_limit || options.rekey_interval) 229 if (options.rekey_limit || options.rekey_interval)
230 packet_set_rekey_limits((u_int32_t)options.rekey_limit, 230 packet_set_rekey_limits(options.rekey_limit,
231 (time_t)options.rekey_interval); 231 options.rekey_interval);
232 232
233 /* start key exchange */ 233 /* start key exchange */
234 if ((r = kex_setup(active_state, myproposal)) != 0) 234 if ((r = kex_setup(active_state, myproposal)) != 0)
@@ -1057,14 +1057,14 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
1057 Authctxt *authctxt = ctxt; 1057 Authctxt *authctxt = ctxt;
1058 char *info, *lang, *password = NULL, *retype = NULL; 1058 char *info, *lang, *password = NULL, *retype = NULL;
1059 char prompt[150]; 1059 char prompt[150];
1060 const char *host = options.host_key_alias ? options.host_key_alias : 1060 const char *host;
1061 authctxt->host;
1062 1061
1063 debug2("input_userauth_passwd_changereq"); 1062 debug2("input_userauth_passwd_changereq");
1064 1063
1065 if (authctxt == NULL) 1064 if (authctxt == NULL)
1066 fatal("input_userauth_passwd_changereq: " 1065 fatal("input_userauth_passwd_changereq: "
1067 "no authentication context"); 1066 "no authentication context");
1067 host = options.host_key_alias ? options.host_key_alias : authctxt->host;
1068 1068
1069 info = packet_get_string(NULL); 1069 info = packet_get_string(NULL);
1070 lang = packet_get_string(NULL); 1070 lang = packet_get_string(NULL);
@@ -1119,11 +1119,11 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
1119} 1119}
1120 1120
1121static const char * 1121static const char *
1122identity_sign_encode(struct identity *id) 1122key_sign_encode(const struct sshkey *key)
1123{ 1123{
1124 struct ssh *ssh = active_state; 1124 struct ssh *ssh = active_state;
1125 1125
1126 if (id->key->type == KEY_RSA) { 1126 if (key->type == KEY_RSA) {
1127 switch (ssh->kex->rsa_sha2) { 1127 switch (ssh->kex->rsa_sha2) {
1128 case 256: 1128 case 256:
1129 return "rsa-sha2-256"; 1129 return "rsa-sha2-256";
@@ -1131,7 +1131,7 @@ identity_sign_encode(struct identity *id)
1131 return "rsa-sha2-512"; 1131 return "rsa-sha2-512";
1132 } 1132 }
1133 } 1133 }
1134 return key_ssh_name(id->key); 1134 return key_ssh_name(key);
1135} 1135}
1136 1136
1137static int 1137static int
@@ -1140,31 +1140,50 @@ identity_sign(struct identity *id, u_char **sigp, size_t *lenp,
1140{ 1140{
1141 Key *prv; 1141 Key *prv;
1142 int ret; 1142 int ret;
1143 const char *alg;
1144
1145 alg = identity_sign_encode(id);
1146 1143
1147 /* the agent supports this key */ 1144 /* the agent supports this key */
1148 if (id->agent_fd != -1) 1145 if (id->key != NULL && id->agent_fd != -1)
1149 return ssh_agent_sign(id->agent_fd, id->key, sigp, lenp, 1146 return ssh_agent_sign(id->agent_fd, id->key, sigp, lenp,
1150 data, datalen, alg, compat); 1147 data, datalen, key_sign_encode(id->key), compat);
1151 1148
1152 /* 1149 /*
1153 * we have already loaded the private key or 1150 * we have already loaded the private key or
1154 * the private key is stored in external hardware 1151 * the private key is stored in external hardware
1155 */ 1152 */
1156 if (id->isprivate || (id->key->flags & SSHKEY_FLAG_EXT)) 1153 if (id->key != NULL &&
1157 return (sshkey_sign(id->key, sigp, lenp, data, datalen, alg, 1154 (id->isprivate || (id->key->flags & SSHKEY_FLAG_EXT)))
1158 compat)); 1155 return (sshkey_sign(id->key, sigp, lenp, data, datalen,
1156 key_sign_encode(id->key), compat));
1157
1159 /* load the private key from the file */ 1158 /* load the private key from the file */
1160 if ((prv = load_identity_file(id)) == NULL) 1159 if ((prv = load_identity_file(id)) == NULL)
1161 return SSH_ERR_KEY_NOT_FOUND; 1160 return SSH_ERR_KEY_NOT_FOUND;
1162 ret = sshkey_sign(prv, sigp, lenp, data, datalen, alg, compat); 1161 ret = sshkey_sign(prv, sigp, lenp, data, datalen,
1162 key_sign_encode(prv), compat);
1163 sshkey_free(prv); 1163 sshkey_free(prv);
1164 return (ret); 1164 return (ret);
1165} 1165}
1166 1166
1167static int 1167static int
1168id_filename_matches(Identity *id, Identity *private_id)
1169{
1170 const char *suffixes[] = { ".pub", "-cert.pub", NULL };
1171 size_t len = strlen(id->filename), plen = strlen(private_id->filename);
1172 size_t i, slen;
1173
1174 if (strcmp(id->filename, private_id->filename) == 0)
1175 return 1;
1176 for (i = 0; suffixes[i]; i++) {
1177 slen = strlen(suffixes[i]);
1178 if (len > slen && plen == len - slen &&
1179 strcmp(id->filename + (len - slen), suffixes[i]) == 0 &&
1180 memcmp(id->filename, private_id->filename, plen) == 0)
1181 return 1;
1182 }
1183 return 0;
1184}
1185
1186static int
1168sign_and_send_pubkey(Authctxt *authctxt, Identity *id) 1187sign_and_send_pubkey(Authctxt *authctxt, Identity *id)
1169{ 1188{
1170 Buffer b; 1189 Buffer b;
@@ -1206,7 +1225,7 @@ sign_and_send_pubkey(Authctxt *authctxt, Identity *id)
1206 } else { 1225 } else {
1207 buffer_put_cstring(&b, authctxt->method->name); 1226 buffer_put_cstring(&b, authctxt->method->name);
1208 buffer_put_char(&b, have_sig); 1227 buffer_put_char(&b, have_sig);
1209 buffer_put_cstring(&b, identity_sign_encode(id)); 1228 buffer_put_cstring(&b, key_sign_encode(id->key));
1210 } 1229 }
1211 buffer_put_string(&b, blob, bloblen); 1230 buffer_put_string(&b, blob, bloblen);
1212 1231
@@ -1226,6 +1245,24 @@ sign_and_send_pubkey(Authctxt *authctxt, Identity *id)
1226 break; 1245 break;
1227 } 1246 }
1228 } 1247 }
1248 /*
1249 * Exact key matches are preferred, but also allow
1250 * filename matches for non-PKCS#11/agent keys that
1251 * didn't load public keys. This supports the case
1252 * of keeping just a private key file and public
1253 * certificate on disk.
1254 */
1255 if (!matched && !id->isprivate && id->agent_fd == -1 &&
1256 (id->key->flags & SSHKEY_FLAG_EXT) == 0) {
1257 TAILQ_FOREACH(private_id, &authctxt->keys, next) {
1258 if (private_id->key == NULL &&
1259 id_filename_matches(id, private_id)) {
1260 id = private_id;
1261 matched = 1;
1262 break;
1263 }
1264 }
1265 }
1229 if (matched) { 1266 if (matched) {
1230 debug2("%s: using private key \"%s\"%s for " 1267 debug2("%s: using private key \"%s\"%s for "
1231 "certificate", __func__, id->filename, 1268 "certificate", __func__, id->filename,
@@ -1304,7 +1341,7 @@ send_pubkey_test(Authctxt *authctxt, Identity *id)
1304 packet_put_cstring(authctxt->method->name); 1341 packet_put_cstring(authctxt->method->name);
1305 packet_put_char(have_sig); 1342 packet_put_char(have_sig);
1306 if (!(datafellows & SSH_BUG_PKAUTH)) 1343 if (!(datafellows & SSH_BUG_PKAUTH))
1307 packet_put_cstring(identity_sign_encode(id)); 1344 packet_put_cstring(key_sign_encode(id->key));
1308 packet_put_string(blob, bloblen); 1345 packet_put_string(blob, bloblen);
1309 free(blob); 1346 free(blob);
1310 packet_send(); 1347 packet_send();
@@ -1755,7 +1792,7 @@ ssh_keysign(struct sshkey *key, u_char **sigp, size_t *lenp,
1755 if ((b = sshbuf_new()) == NULL) 1792 if ((b = sshbuf_new()) == NULL)
1756 fatal("%s: sshbuf_new failed", __func__); 1793 fatal("%s: sshbuf_new failed", __func__);
1757 /* send # of sock, data to be signed */ 1794 /* send # of sock, data to be signed */
1758 if ((r = sshbuf_put_u32(b, sock) != 0) || 1795 if ((r = sshbuf_put_u32(b, sock)) != 0 ||
1759 (r = sshbuf_put_string(b, data, datalen)) != 0) 1796 (r = sshbuf_put_string(b, data, datalen)) != 0)
1760 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 1797 fatal("%s: buffer error: %s", __func__, ssh_err(r));
1761 if (ssh_msg_send(to[1], version, b) == -1) 1798 if (ssh_msg_send(to[1], version, b) == -1)