diff options
Diffstat (limited to 'sshconnect2.c')
-rw-r--r-- | sshconnect2.c | 345 |
1 files changed, 216 insertions, 129 deletions
diff --git a/sshconnect2.c b/sshconnect2.c index d8ae6eb3a..920376408 100644 --- a/sshconnect2.c +++ b/sshconnect2.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshconnect2.c,v 1.271 2018/06/26 02:02:36 djm Exp $ */ | 1 | /* $OpenBSD: sshconnect2.c,v 1.272 2018/07/03 11:39:54 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. |
@@ -315,7 +315,7 @@ int input_gssapi_errtok(int, u_int32_t, struct ssh *); | |||
315 | 315 | ||
316 | void userauth(Authctxt *, char *); | 316 | void userauth(Authctxt *, char *); |
317 | 317 | ||
318 | static int sign_and_send_pubkey(Authctxt *, Identity *); | 318 | static int sign_and_send_pubkey(struct ssh *ssh, Authctxt *, Identity *); |
319 | static void pubkey_prepare(Authctxt *); | 319 | static void pubkey_prepare(Authctxt *); |
320 | static void pubkey_cleanup(Authctxt *); | 320 | static void pubkey_cleanup(Authctxt *); |
321 | static void pubkey_reset(Authctxt *); | 321 | static void pubkey_reset(Authctxt *); |
@@ -619,7 +619,7 @@ input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh) | |||
619 | */ | 619 | */ |
620 | TAILQ_FOREACH_REVERSE(id, &authctxt->keys, idlist, next) { | 620 | TAILQ_FOREACH_REVERSE(id, &authctxt->keys, idlist, next) { |
621 | if (key_equal(key, id->key)) { | 621 | if (key_equal(key, id->key)) { |
622 | sent = sign_and_send_pubkey(authctxt, id); | 622 | sent = sign_and_send_pubkey(ssh, authctxt, id); |
623 | break; | 623 | break; |
624 | } | 624 | } |
625 | } | 625 | } |
@@ -986,73 +986,80 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, struct ssh *ssh) | |||
986 | return 0; | 986 | return 0; |
987 | } | 987 | } |
988 | 988 | ||
989 | static const char * | ||
990 | key_sign_encode(const struct sshkey *key) | ||
991 | { | ||
992 | struct ssh *ssh = active_state; | ||
993 | |||
994 | if (key->type == KEY_RSA) { | ||
995 | switch (ssh->kex->rsa_sha2) { | ||
996 | case 256: | ||
997 | return "rsa-sha2-256"; | ||
998 | case 512: | ||
999 | return "rsa-sha2-512"; | ||
1000 | } | ||
1001 | } | ||
1002 | return key_ssh_name(key); | ||
1003 | } | ||
1004 | |||
1005 | /* | 989 | /* |
1006 | * Some agents will return ssh-rsa signatures when asked to make a | 990 | * Select an algorithm for publickey signatures. |
1007 | * rsa-sha2-* signature. Check what they actually gave back and warn the | 991 | * Returns algorithm (caller must free) or NULL if no mutual algorithm found. |
1008 | * user if the agent has returned an unexpected type. | 992 | * |
993 | * Call with ssh==NULL to ignore server-sig-algs extension list and | ||
994 | * only attempt with the key's base signature type. | ||
1009 | */ | 995 | */ |
1010 | static int | 996 | static char * |
1011 | check_sigtype(const struct sshkey *key, const u_char *sig, size_t len) | 997 | key_sig_algorithm(struct ssh *ssh, const struct sshkey *key) |
1012 | { | 998 | { |
1013 | int r; | 999 | char *allowed, *oallowed, *cp, *alg = NULL; |
1014 | char *sigtype = NULL; | ||
1015 | const char *alg = key_sign_encode(key); | ||
1016 | 1000 | ||
1017 | if (sshkey_is_cert(key)) | 1001 | /* |
1018 | return 0; | 1002 | * The signature algorithm will only differ from the key algorithm |
1019 | if ((r = sshkey_sigtype(sig, len, &sigtype)) != 0) | 1003 | * for RSA keys/certs and when the server advertises support for |
1020 | return r; | 1004 | * newer (SHA2) algorithms. |
1021 | if (strcmp(sigtype, alg) != 0) { | 1005 | */ |
1022 | logit("warning: agent returned different signature type %s " | 1006 | if (ssh == NULL || ssh->kex->server_sig_algs == NULL || |
1023 | "(expected %s)", sigtype, alg); | 1007 | (key->type != KEY_RSA && key->type != KEY_RSA_CERT)) { |
1024 | } | 1008 | /* Filter base key signature alg against our configuration */ |
1025 | free(sigtype); | 1009 | return match_list(key_ssh_name(key), |
1026 | /* Incorrect signature types aren't an error ... yet */ | 1010 | options.pubkey_key_types, NULL); |
1027 | return 0; | 1011 | } |
1012 | |||
1013 | /* | ||
1014 | * For RSA keys/certs, since these might have a different sig type: | ||
1015 | * find the first entry in PubkeyAcceptedKeyTypes of the right type | ||
1016 | * that also appears in the supported signature algorithms list from | ||
1017 | * the server. | ||
1018 | */ | ||
1019 | oallowed = allowed = xstrdup(options.pubkey_key_types); | ||
1020 | while ((cp = strsep(&allowed, ",")) != NULL) { | ||
1021 | if (sshkey_type_from_name(cp) != key->type) | ||
1022 | continue; | ||
1023 | alg = match_list(cp, ssh->kex->server_sig_algs, NULL); | ||
1024 | if (alg != NULL) | ||
1025 | break; | ||
1026 | } | ||
1027 | free(oallowed); | ||
1028 | return alg; | ||
1028 | } | 1029 | } |
1029 | 1030 | ||
1030 | static int | 1031 | static int |
1031 | identity_sign(struct identity *id, u_char **sigp, size_t *lenp, | 1032 | identity_sign(struct identity *id, u_char **sigp, size_t *lenp, |
1032 | const u_char *data, size_t datalen, u_int compat) | 1033 | const u_char *data, size_t datalen, u_int compat, const char *alg) |
1033 | { | 1034 | { |
1034 | struct sshkey *prv; | 1035 | struct sshkey *prv; |
1035 | int r; | 1036 | int r; |
1036 | 1037 | ||
1037 | /* the agent supports this key */ | 1038 | /* The agent supports this key. */ |
1038 | if (id->key != NULL && id->agent_fd != -1) { | 1039 | if (id->key != NULL && id->agent_fd != -1) { |
1039 | if ((r = ssh_agent_sign(id->agent_fd, id->key, sigp, lenp, | 1040 | return ssh_agent_sign(id->agent_fd, id->key, sigp, lenp, |
1040 | data, datalen, key_sign_encode(id->key), compat)) != 0 || | 1041 | data, datalen, alg, compat); |
1041 | (r = check_sigtype(id->key, *sigp, *lenp)) != 0) | ||
1042 | return r; | ||
1043 | return 0; | ||
1044 | } | 1042 | } |
1045 | 1043 | ||
1046 | /* | 1044 | /* |
1047 | * we have already loaded the private key or | 1045 | * We have already loaded the private key or the private key is |
1048 | * the private key is stored in external hardware | 1046 | * stored in external hardware. |
1049 | */ | 1047 | */ |
1050 | if (id->key != NULL && | 1048 | if (id->key != NULL && |
1051 | (id->isprivate || (id->key->flags & SSHKEY_FLAG_EXT))) | 1049 | (id->isprivate || (id->key->flags & SSHKEY_FLAG_EXT))) { |
1052 | return (sshkey_sign(id->key, sigp, lenp, data, datalen, | 1050 | if ((r = sshkey_sign(id->key, sigp, lenp, data, datalen, |
1053 | key_sign_encode(id->key), compat)); | 1051 | alg, compat)) != 0) |
1052 | return r; | ||
1053 | /* | ||
1054 | * PKCS#11 tokens may not support all signature algorithms, | ||
1055 | * so check what we get back. | ||
1056 | */ | ||
1057 | if ((r = sshkey_check_sigtype(*sigp, *lenp, alg)) != 0) | ||
1058 | return r; | ||
1059 | return 0; | ||
1060 | } | ||
1054 | 1061 | ||
1055 | /* load the private key from the file */ | 1062 | /* Load the private key from the file. */ |
1056 | if ((prv = load_identity_file(id)) == NULL) | 1063 | if ((prv = load_identity_file(id)) == NULL) |
1057 | return SSH_ERR_KEY_NOT_FOUND; | 1064 | return SSH_ERR_KEY_NOT_FOUND; |
1058 | if (id->key != NULL && !sshkey_equal_public(prv, id->key)) { | 1065 | if (id->key != NULL && !sshkey_equal_public(prv, id->key)) { |
@@ -1060,8 +1067,7 @@ identity_sign(struct identity *id, u_char **sigp, size_t *lenp, | |||
1060 | __func__, id->filename); | 1067 | __func__, id->filename); |
1061 | return SSH_ERR_KEY_NOT_FOUND; | 1068 | return SSH_ERR_KEY_NOT_FOUND; |
1062 | } | 1069 | } |
1063 | r = sshkey_sign(prv, sigp, lenp, data, datalen, | 1070 | r = sshkey_sign(prv, sigp, lenp, data, datalen, alg, compat); |
1064 | key_sign_encode(prv), compat); | ||
1065 | sshkey_free(prv); | 1071 | sshkey_free(prv); |
1066 | return r; | 1072 | return r; |
1067 | } | 1073 | } |
@@ -1086,57 +1092,35 @@ id_filename_matches(Identity *id, Identity *private_id) | |||
1086 | } | 1092 | } |
1087 | 1093 | ||
1088 | static int | 1094 | static int |
1089 | sign_and_send_pubkey(Authctxt *authctxt, Identity *id) | 1095 | sign_and_send_pubkey(struct ssh *ssh, Authctxt *authctxt, Identity *id) |
1090 | { | 1096 | { |
1091 | Buffer b; | 1097 | struct sshbuf *b = NULL; |
1092 | Identity *private_id; | 1098 | Identity *private_id, *sign_id = NULL; |
1093 | u_char *blob, *signature; | 1099 | u_char *signature = NULL; |
1094 | size_t slen; | 1100 | size_t slen = 0, skip = 0; |
1095 | u_int bloblen, skip = 0; | 1101 | int r, fallback_sigtype, sent = 0; |
1096 | int matched, ret = -1, have_sig = 1; | 1102 | char *alg = NULL, *fp = NULL; |
1097 | char *fp; | 1103 | const char *loc = ""; |
1098 | 1104 | ||
1099 | if ((fp = sshkey_fingerprint(id->key, options.fingerprint_hash, | 1105 | if ((fp = sshkey_fingerprint(id->key, options.fingerprint_hash, |
1100 | SSH_FP_DEFAULT)) == NULL) | 1106 | SSH_FP_DEFAULT)) == NULL) |
1101 | return 0; | 1107 | return 0; |
1102 | debug3("%s: %s %s", __func__, key_type(id->key), fp); | ||
1103 | free(fp); | ||
1104 | 1108 | ||
1105 | if (key_to_blob(id->key, &blob, &bloblen) == 0) { | 1109 | debug3("%s: %s %s", __func__, sshkey_type(id->key), fp); |
1106 | /* we cannot handle this key */ | ||
1107 | debug3("sign_and_send_pubkey: cannot handle key"); | ||
1108 | return 0; | ||
1109 | } | ||
1110 | /* data to be signed */ | ||
1111 | buffer_init(&b); | ||
1112 | if (datafellows & SSH_OLD_SESSIONID) { | ||
1113 | buffer_append(&b, session_id2, session_id2_len); | ||
1114 | skip = session_id2_len; | ||
1115 | } else { | ||
1116 | buffer_put_string(&b, session_id2, session_id2_len); | ||
1117 | skip = buffer_len(&b); | ||
1118 | } | ||
1119 | buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); | ||
1120 | buffer_put_cstring(&b, authctxt->server_user); | ||
1121 | buffer_put_cstring(&b, authctxt->service); | ||
1122 | buffer_put_cstring(&b, authctxt->method->name); | ||
1123 | buffer_put_char(&b, have_sig); | ||
1124 | buffer_put_cstring(&b, key_sign_encode(id->key)); | ||
1125 | buffer_put_string(&b, blob, bloblen); | ||
1126 | 1110 | ||
1127 | /* | 1111 | /* |
1128 | * If the key is an certificate, try to find a matching private key | 1112 | * If the key is an certificate, try to find a matching private key |
1129 | * and use it to complete the signature. | 1113 | * and use it to complete the signature. |
1130 | * If no such private key exists, fall back to trying the certificate | 1114 | * If no such private key exists, fall back to trying the certificate |
1131 | * key itself in case it has a private half already loaded. | 1115 | * key itself in case it has a private half already loaded. |
1116 | * This will try to set sign_id to the private key that will perform | ||
1117 | * the signature. | ||
1132 | */ | 1118 | */ |
1133 | if (key_is_cert(id->key)) { | 1119 | if (sshkey_is_cert(id->key)) { |
1134 | matched = 0; | ||
1135 | TAILQ_FOREACH(private_id, &authctxt->keys, next) { | 1120 | TAILQ_FOREACH(private_id, &authctxt->keys, next) { |
1136 | if (sshkey_equal_public(id->key, private_id->key) && | 1121 | if (sshkey_equal_public(id->key, private_id->key) && |
1137 | id->key->type != private_id->key->type) { | 1122 | id->key->type != private_id->key->type) { |
1138 | id = private_id; | 1123 | sign_id = private_id; |
1139 | matched = 1; | ||
1140 | break; | 1124 | break; |
1141 | } | 1125 | } |
1142 | } | 1126 | } |
@@ -1147,18 +1131,18 @@ sign_and_send_pubkey(Authctxt *authctxt, Identity *id) | |||
1147 | * of keeping just a private key file and public | 1131 | * of keeping just a private key file and public |
1148 | * certificate on disk. | 1132 | * certificate on disk. |
1149 | */ | 1133 | */ |
1150 | if (!matched && !id->isprivate && id->agent_fd == -1 && | 1134 | if (sign_id == NULL && |
1135 | !id->isprivate && id->agent_fd == -1 && | ||
1151 | (id->key->flags & SSHKEY_FLAG_EXT) == 0) { | 1136 | (id->key->flags & SSHKEY_FLAG_EXT) == 0) { |
1152 | TAILQ_FOREACH(private_id, &authctxt->keys, next) { | 1137 | TAILQ_FOREACH(private_id, &authctxt->keys, next) { |
1153 | if (private_id->key == NULL && | 1138 | if (private_id->key == NULL && |
1154 | id_filename_matches(id, private_id)) { | 1139 | id_filename_matches(id, private_id)) { |
1155 | id = private_id; | 1140 | sign_id = private_id; |
1156 | matched = 1; | ||
1157 | break; | 1141 | break; |
1158 | } | 1142 | } |
1159 | } | 1143 | } |
1160 | } | 1144 | } |
1161 | if (matched) { | 1145 | if (sign_id != NULL) { |
1162 | debug2("%s: using private key \"%s\"%s for " | 1146 | debug2("%s: using private key \"%s\"%s for " |
1163 | "certificate", __func__, id->filename, | 1147 | "certificate", __func__, id->filename, |
1164 | id->agent_fd != -1 ? " from agent" : ""); | 1148 | id->agent_fd != -1 ? " from agent" : ""); |
@@ -1168,51 +1152,121 @@ sign_and_send_pubkey(Authctxt *authctxt, Identity *id) | |||
1168 | } | 1152 | } |
1169 | } | 1153 | } |
1170 | 1154 | ||
1171 | /* generate signature */ | 1155 | /* |
1172 | ret = identity_sign(id, &signature, &slen, | 1156 | * If the above didn't select another identity to do the signing |
1173 | buffer_ptr(&b), buffer_len(&b), datafellows); | 1157 | * then default to the one we started with. |
1174 | if (ret != 0) { | 1158 | */ |
1175 | if (ret != SSH_ERR_KEY_NOT_FOUND) | 1159 | if (sign_id == NULL) |
1176 | error("%s: signing failed: %s", __func__, ssh_err(ret)); | 1160 | sign_id = id; |
1177 | free(blob); | 1161 | |
1178 | buffer_free(&b); | 1162 | /* assemble and sign data */ |
1179 | return 0; | 1163 | for (fallback_sigtype = 0; fallback_sigtype <= 1; fallback_sigtype++) { |
1164 | free(alg); | ||
1165 | slen = 0; | ||
1166 | signature = NULL; | ||
1167 | if ((alg = key_sig_algorithm(fallback_sigtype ? NULL : ssh, | ||
1168 | id->key)) == NULL) { | ||
1169 | error("%s: no mutual signature supported", __func__); | ||
1170 | goto out; | ||
1171 | } | ||
1172 | debug3("%s: signing using %s", __func__, alg); | ||
1173 | |||
1174 | sshbuf_free(b); | ||
1175 | if ((b = sshbuf_new()) == NULL) | ||
1176 | fatal("%s: sshbuf_new failed", __func__); | ||
1177 | if (datafellows & SSH_OLD_SESSIONID) { | ||
1178 | if ((r = sshbuf_put(b, session_id2, | ||
1179 | session_id2_len)) != 0) { | ||
1180 | fatal("%s: sshbuf_put: %s", | ||
1181 | __func__, ssh_err(r)); | ||
1182 | } | ||
1183 | } else { | ||
1184 | if ((r = sshbuf_put_string(b, session_id2, | ||
1185 | session_id2_len)) != 0) { | ||
1186 | fatal("%s: sshbuf_put_string: %s", | ||
1187 | __func__, ssh_err(r)); | ||
1188 | } | ||
1189 | } | ||
1190 | skip = buffer_len(b); | ||
1191 | if ((r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 || | ||
1192 | (r = sshbuf_put_cstring(b, authctxt->server_user)) != 0 || | ||
1193 | (r = sshbuf_put_cstring(b, authctxt->service)) != 0 || | ||
1194 | (r = sshbuf_put_cstring(b, authctxt->method->name)) != 0 || | ||
1195 | (r = sshbuf_put_u8(b, 1)) != 0 || | ||
1196 | (r = sshbuf_put_cstring(b, alg)) != 0 || | ||
1197 | (r = sshkey_puts(id->key, b)) != 0) { | ||
1198 | fatal("%s: assemble signed data: %s", | ||
1199 | __func__, ssh_err(r)); | ||
1200 | } | ||
1201 | |||
1202 | /* generate signature */ | ||
1203 | r = identity_sign(sign_id, &signature, &slen, | ||
1204 | sshbuf_ptr(b), sshbuf_len(b), datafellows, alg); | ||
1205 | if (r == 0) | ||
1206 | break; | ||
1207 | else if (r == SSH_ERR_KEY_NOT_FOUND) | ||
1208 | goto out; /* soft failure */ | ||
1209 | else if (r == SSH_ERR_SIGN_ALG_UNSUPPORTED && | ||
1210 | !fallback_sigtype) { | ||
1211 | if (sign_id->agent_fd != -1) | ||
1212 | loc = "agent "; | ||
1213 | else if ((sign_id->key->flags & SSHKEY_FLAG_EXT) != 0) | ||
1214 | loc = "token "; | ||
1215 | logit("%skey %s %s returned incorrect signature type", | ||
1216 | loc, sshkey_type(id->key), fp); | ||
1217 | continue; | ||
1218 | } | ||
1219 | error("%s: signing failed: %s", __func__, ssh_err(r)); | ||
1220 | goto out; | ||
1180 | } | 1221 | } |
1181 | #ifdef DEBUG_PK | 1222 | if (slen == 0 || signature == NULL) /* shouldn't happen */ |
1182 | buffer_dump(&b); | 1223 | fatal("%s: no signature", __func__); |
1183 | #endif | ||
1184 | free(blob); | ||
1185 | 1224 | ||
1186 | /* append signature */ | 1225 | /* append signature */ |
1187 | buffer_put_string(&b, signature, slen); | 1226 | if ((r = sshbuf_put_string(b, signature, slen)) != 0) |
1188 | free(signature); | 1227 | fatal("%s: append signature: %s", __func__, ssh_err(r)); |
1189 | 1228 | ||
1229 | #ifdef DEBUG_PK | ||
1230 | sshbuf_dump(b, stderr); | ||
1231 | #endif | ||
1190 | /* skip session id and packet type */ | 1232 | /* skip session id and packet type */ |
1191 | if (buffer_len(&b) < skip + 1) | 1233 | if ((r = sshbuf_consume(b, skip + 1)) != 0) |
1192 | fatal("userauth_pubkey: internal error"); | 1234 | fatal("%s: consume: %s", __func__, ssh_err(r)); |
1193 | buffer_consume(&b, skip + 1); | ||
1194 | 1235 | ||
1195 | /* put remaining data from buffer into packet */ | 1236 | /* put remaining data from buffer into packet */ |
1196 | packet_start(SSH2_MSG_USERAUTH_REQUEST); | 1237 | if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 || |
1197 | packet_put_raw(buffer_ptr(&b), buffer_len(&b)); | 1238 | (r = sshpkt_putb(ssh, b)) != 0 || |
1198 | buffer_free(&b); | 1239 | (r = sshpkt_send(ssh)) != 0) |
1199 | packet_send(); | 1240 | fatal("%s: enqueue request: %s", __func__, ssh_err(r)); |
1200 | 1241 | ||
1201 | return 1; | 1242 | /* success */ |
1243 | sent = 1; | ||
1244 | |||
1245 | out: | ||
1246 | free(fp); | ||
1247 | free(alg); | ||
1248 | sshbuf_free(b); | ||
1249 | freezero(signature, slen); | ||
1250 | return sent; | ||
1202 | } | 1251 | } |
1203 | 1252 | ||
1204 | static int | 1253 | static int |
1205 | send_pubkey_test(Authctxt *authctxt, Identity *id) | 1254 | send_pubkey_test(struct ssh *ssh, Authctxt *authctxt, Identity *id) |
1206 | { | 1255 | { |
1207 | u_char *blob; | 1256 | u_char *blob = NULL; |
1208 | u_int bloblen, have_sig = 0; | 1257 | u_int bloblen, have_sig = 0; |
1258 | char *alg = NULL; | ||
1259 | int sent = 0; | ||
1209 | 1260 | ||
1210 | debug3("send_pubkey_test"); | 1261 | if ((alg = key_sig_algorithm(ssh, id->key)) == NULL) { |
1262 | debug("%s: no mutual signature algorithm", __func__); | ||
1263 | goto out; | ||
1264 | } | ||
1211 | 1265 | ||
1212 | if (key_to_blob(id->key, &blob, &bloblen) == 0) { | 1266 | if (key_to_blob(id->key, &blob, &bloblen) == 0) { |
1213 | /* we cannot handle this key */ | 1267 | /* we cannot handle this key */ |
1214 | debug3("send_pubkey_test: cannot handle key"); | 1268 | debug3("%s: cannot handle key", __func__); |
1215 | return 0; | 1269 | goto out; |
1216 | } | 1270 | } |
1217 | /* register callback for USERAUTH_PK_OK message */ | 1271 | /* register callback for USERAUTH_PK_OK message */ |
1218 | dispatch_set(SSH2_MSG_USERAUTH_PK_OK, &input_userauth_pk_ok); | 1272 | dispatch_set(SSH2_MSG_USERAUTH_PK_OK, &input_userauth_pk_ok); |
@@ -1222,11 +1276,15 @@ send_pubkey_test(Authctxt *authctxt, Identity *id) | |||
1222 | packet_put_cstring(authctxt->service); | 1276 | packet_put_cstring(authctxt->service); |
1223 | packet_put_cstring(authctxt->method->name); | 1277 | packet_put_cstring(authctxt->method->name); |
1224 | packet_put_char(have_sig); | 1278 | packet_put_char(have_sig); |
1225 | packet_put_cstring(key_sign_encode(id->key)); | 1279 | packet_put_cstring(alg); |
1226 | packet_put_string(blob, bloblen); | 1280 | packet_put_string(blob, bloblen); |
1227 | free(blob); | ||
1228 | packet_send(); | 1281 | packet_send(); |
1229 | return 1; | 1282 | /* success */ |
1283 | sent = 1; | ||
1284 | out: | ||
1285 | free(alg); | ||
1286 | free(blob); | ||
1287 | return sent; | ||
1230 | } | 1288 | } |
1231 | 1289 | ||
1232 | static struct sshkey * | 1290 | static struct sshkey * |
@@ -1295,6 +1353,36 @@ load_identity_file(Identity *id) | |||
1295 | return private; | 1353 | return private; |
1296 | } | 1354 | } |
1297 | 1355 | ||
1356 | static int | ||
1357 | key_type_allowed_by_config(struct sshkey *key) | ||
1358 | { | ||
1359 | if (match_pattern_list(sshkey_ssh_name(key), | ||
1360 | options.pubkey_key_types, 0) == 1) | ||
1361 | return 1; | ||
1362 | |||
1363 | /* RSA keys/certs might be allowed by alternate signature types */ | ||
1364 | switch (key->type) { | ||
1365 | case KEY_RSA: | ||
1366 | if (match_pattern_list("rsa-sha2-512", | ||
1367 | options.pubkey_key_types, 0) == 1) | ||
1368 | return 1; | ||
1369 | if (match_pattern_list("rsa-sha2-256", | ||
1370 | options.pubkey_key_types, 0) == 1) | ||
1371 | return 1; | ||
1372 | break; | ||
1373 | case KEY_RSA_CERT: | ||
1374 | if (match_pattern_list("rsa-sha2-512-cert-v01@openssh.com", | ||
1375 | options.pubkey_key_types, 0) == 1) | ||
1376 | return 1; | ||
1377 | if (match_pattern_list("rsa-sha2-256-cert-v01@openssh.com", | ||
1378 | options.pubkey_key_types, 0) == 1) | ||
1379 | return 1; | ||
1380 | break; | ||
1381 | } | ||
1382 | return 0; | ||
1383 | } | ||
1384 | |||
1385 | |||
1298 | /* | 1386 | /* |
1299 | * try keys in the following order: | 1387 | * try keys in the following order: |
1300 | * 1. certificates listed in the config file | 1388 | * 1. certificates listed in the config file |
@@ -1419,9 +1507,7 @@ pubkey_prepare(Authctxt *authctxt) | |||
1419 | } | 1507 | } |
1420 | /* finally, filter by PubkeyAcceptedKeyTypes */ | 1508 | /* finally, filter by PubkeyAcceptedKeyTypes */ |
1421 | TAILQ_FOREACH_SAFE(id, preferred, next, id2) { | 1509 | TAILQ_FOREACH_SAFE(id, preferred, next, id2) { |
1422 | if (id->key != NULL && | 1510 | if (id->key != NULL && !key_type_allowed_by_config(key)) { |
1423 | match_pattern_list(sshkey_ssh_name(id->key), | ||
1424 | options.pubkey_key_types, 0) != 1) { | ||
1425 | debug("Skipping %s key %s - " | 1511 | debug("Skipping %s key %s - " |
1426 | "not in PubkeyAcceptedKeyTypes", | 1512 | "not in PubkeyAcceptedKeyTypes", |
1427 | sshkey_ssh_name(id->key), id->filename); | 1513 | sshkey_ssh_name(id->key), id->filename); |
@@ -1479,6 +1565,7 @@ try_identity(Identity *id) | |||
1479 | int | 1565 | int |
1480 | userauth_pubkey(Authctxt *authctxt) | 1566 | userauth_pubkey(Authctxt *authctxt) |
1481 | { | 1567 | { |
1568 | struct ssh *ssh = active_state; /* XXX */ | ||
1482 | Identity *id; | 1569 | Identity *id; |
1483 | int sent = 0; | 1570 | int sent = 0; |
1484 | char *fp; | 1571 | char *fp; |
@@ -1506,7 +1593,7 @@ userauth_pubkey(Authctxt *authctxt) | |||
1506 | debug("Offering public key: %s %s %s", | 1593 | debug("Offering public key: %s %s %s", |
1507 | sshkey_type(id->key), fp, id->filename); | 1594 | sshkey_type(id->key), fp, id->filename); |
1508 | free(fp); | 1595 | free(fp); |
1509 | sent = send_pubkey_test(authctxt, id); | 1596 | sent = send_pubkey_test(ssh, authctxt, id); |
1510 | } | 1597 | } |
1511 | } else { | 1598 | } else { |
1512 | debug("Trying private key: %s", id->filename); | 1599 | debug("Trying private key: %s", id->filename); |
@@ -1514,7 +1601,7 @@ userauth_pubkey(Authctxt *authctxt) | |||
1514 | if (id->key != NULL) { | 1601 | if (id->key != NULL) { |
1515 | if (try_identity(id)) { | 1602 | if (try_identity(id)) { |
1516 | id->isprivate = 1; | 1603 | id->isprivate = 1; |
1517 | sent = sign_and_send_pubkey( | 1604 | sent = sign_and_send_pubkey(ssh, |
1518 | authctxt, id); | 1605 | authctxt, id); |
1519 | } | 1606 | } |
1520 | key_free(id->key); | 1607 | key_free(id->key); |
@@ -1735,7 +1822,7 @@ ssh_keysign(struct sshkey *key, u_char **sigp, size_t *lenp, | |||
1735 | int | 1822 | int |
1736 | userauth_hostbased(Authctxt *authctxt) | 1823 | userauth_hostbased(Authctxt *authctxt) |
1737 | { | 1824 | { |
1738 | struct ssh *ssh = active_state; | 1825 | struct ssh *ssh = active_state; /* XXX */ |
1739 | struct sshkey *private = NULL; | 1826 | struct sshkey *private = NULL; |
1740 | struct sshbuf *b = NULL; | 1827 | struct sshbuf *b = NULL; |
1741 | u_char *sig = NULL, *keyblob = NULL; | 1828 | u_char *sig = NULL, *keyblob = NULL; |