summaryrefslogtreecommitdiff
path: root/sshconnect2.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2015-09-24 06:15:11 +0000
committerDamien Miller <djm@mindrot.org>2015-10-06 12:21:54 +1100
commit4e44a79a07d4b88b6a4e5e8c1bed5f58c841b1b8 (patch)
tree7ef647dabf413a83da2f0c26917a8e0b5e1d2145 /sshconnect2.c
parente3cbb06ade83c72b640a53728d362bbefa0008e2 (diff)
upstream commit
add ssh_config CertificateFile option to explicitly list a certificate; patch from Meghana Bhat on bz#2436; ok markus@ Upstream-ID: 58648ec53c510b41c1f46d8fe293aadc87229ab8
Diffstat (limited to 'sshconnect2.c')
-rw-r--r--sshconnect2.c61
1 files changed, 52 insertions, 9 deletions
diff --git a/sshconnect2.c b/sshconnect2.c
index 775103185..e82188392 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshconnect2.c,v 1.226 2015/07/30 00:01:34 djm Exp $ */ 1/* $OpenBSD: sshconnect2.c,v 1.227 2015/09/24 06:15:11 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.
@@ -1001,18 +1001,17 @@ static int
1001sign_and_send_pubkey(Authctxt *authctxt, Identity *id) 1001sign_and_send_pubkey(Authctxt *authctxt, Identity *id)
1002{ 1002{
1003 Buffer b; 1003 Buffer b;
1004 Identity *private_id;
1004 u_char *blob, *signature; 1005 u_char *blob, *signature;
1005 u_int bloblen;
1006 size_t slen; 1006 size_t slen;
1007 u_int skip = 0; 1007 u_int bloblen, skip = 0;
1008 int ret = -1; 1008 int matched, ret = -1, have_sig = 1;
1009 int have_sig = 1;
1010 char *fp; 1009 char *fp;
1011 1010
1012 if ((fp = sshkey_fingerprint(id->key, options.fingerprint_hash, 1011 if ((fp = sshkey_fingerprint(id->key, options.fingerprint_hash,
1013 SSH_FP_DEFAULT)) == NULL) 1012 SSH_FP_DEFAULT)) == NULL)
1014 return 0; 1013 return 0;
1015 debug3("sign_and_send_pubkey: %s %s", key_type(id->key), fp); 1014 debug3("%s: %s %s", __func__, key_type(id->key), fp);
1016 free(fp); 1015 free(fp);
1017 1016
1018 if (key_to_blob(id->key, &blob, &bloblen) == 0) { 1017 if (key_to_blob(id->key, &blob, &bloblen) == 0) {
@@ -1044,6 +1043,36 @@ sign_and_send_pubkey(Authctxt *authctxt, Identity *id)
1044 } 1043 }
1045 buffer_put_string(&b, blob, bloblen); 1044 buffer_put_string(&b, blob, bloblen);
1046 1045
1046 /*
1047 * If the key is an certificate, try to find a matching private key
1048 * and use it to complete the signature.
1049 * If no such private key exists, return failure and continue with
1050 * other methods of authentication.
1051 */
1052 if (key_is_cert(id->key)) {
1053 matched = 0;
1054 TAILQ_FOREACH(private_id, &authctxt->keys, next) {
1055 if (sshkey_equal_public(id->key, private_id->key) &&
1056 id->key->type != private_id->key->type) {
1057 id = private_id;
1058 matched = 1;
1059 break;
1060 }
1061 }
1062 if (matched) {
1063 debug2("%s: using private key \"%s\"%s for "
1064 "certificate", __func__, id->filename,
1065 id->agent_fd != -1 ? " from agent" : "");
1066 } else {
1067 /* XXX maybe verbose/error? */
1068 debug("%s: no private key for certificate "
1069 "\"%s\"", __func__, id->filename);
1070 free(blob);
1071 buffer_free(&b);
1072 return 0;
1073 }
1074 }
1075
1047 /* generate signature */ 1076 /* generate signature */
1048 ret = identity_sign(id, &signature, &slen, 1077 ret = identity_sign(id, &signature, &slen,
1049 buffer_ptr(&b), buffer_len(&b), datafellows); 1078 buffer_ptr(&b), buffer_len(&b), datafellows);
@@ -1180,9 +1209,11 @@ load_identity_file(char *filename, int userprovided)
1180 1209
1181/* 1210/*
1182 * try keys in the following order: 1211 * try keys in the following order:
1183 * 1. agent keys that are found in the config file 1212 * 1. certificates listed in the config file
1184 * 2. other agent keys 1213 * 2. other input certificates
1185 * 3. keys that are only listed in the config file 1214 * 3. agent keys that are found in the config file
1215 * 4. other agent keys
1216 * 5. keys that are only listed in the config file
1186 */ 1217 */
1187static void 1218static void
1188pubkey_prepare(Authctxt *authctxt) 1219pubkey_prepare(Authctxt *authctxt)
@@ -1236,6 +1267,18 @@ pubkey_prepare(Authctxt *authctxt)
1236 free(id); 1267 free(id);
1237 } 1268 }
1238 } 1269 }
1270 /* list of certificates specified by user */
1271 for (i = 0; i < options.num_certificate_files; i++) {
1272 key = options.certificates[i];
1273 if (!key_is_cert(key) || key->cert == NULL ||
1274 key->cert->type != SSH2_CERT_TYPE_USER)
1275 continue;
1276 id = xcalloc(1, sizeof(*id));
1277 id->key = key;
1278 id->filename = xstrdup(options.certificate_files[i]);
1279 id->userprovided = options.certificate_file_userprovided[i];
1280 TAILQ_INSERT_TAIL(preferred, id, next);
1281 }
1239 /* list of keys supported by the agent */ 1282 /* list of keys supported by the agent */
1240 if ((r = ssh_get_authentication_socket(&agent_fd)) != 0) { 1283 if ((r = ssh_get_authentication_socket(&agent_fd)) != 0) {
1241 if (r != SSH_ERR_AGENT_NOT_PRESENT) 1284 if (r != SSH_ERR_AGENT_NOT_PRESENT)