Bugzilla – Attachment 2716 Details for
Bug 2472
Add support to load additional certificates
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch part 2/3
0002-ssh-agent-Add-support-to-load-additional-certificate.patch (text/plain), 6.67 KB, created by
Thomas Jarosch
on 2015-09-26 02:14:04 AEST
(
hide
)
Description:
Patch part 2/3
Filename:
MIME Type:
Creator:
Thomas Jarosch
Created:
2015-09-26 02:14:04 AEST
Size:
6.67 KB
patch
obsolete
>From a32f4e27f66444d2a74d5666a1d0a7a5fd2eccc9 Mon Sep 17 00:00:00 2001 >From: Thomas Jarosch <thomas.jarosch@intra2net.com> >Date: Fri, 25 Sep 2015 17:27:50 +0200 >Subject: [PATCH 2/3] ssh-agent: Add support to load additional certificates > >Add support to load additional certificates >for already loaded privated keys. Useful >if the private key is on a PKCS#11 hardware token. > >The private keys inside ssh-agent are now refcounted >to share the private parts between "Identities". >The reason for this change was that the PKCS#11 code >might have redirected ("wrap") the RSA functions to a hardware token. >We don't want to mess with those internals. > >Signed-off-by: Thomas Jarosch <thomas.jarosch@intra2net.com> >--- > ssh-agent.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++--------- > 1 file changed, 95 insertions(+), 16 deletions(-) > >diff --git a/ssh-agent.c b/ssh-agent.c >index a335ea3..c22b0a3 100644 >--- a/ssh-agent.c >+++ b/ssh-agent.c >@@ -109,9 +109,15 @@ typedef struct { > u_int sockets_alloc = 0; > SocketEntry *sockets = NULL; > >+typedef struct refcountkey { >+ struct sshkey *key; >+ int count; >+} RefcountKey; >+ > typedef struct identity { > TAILQ_ENTRY(identity) next; >- struct sshkey *key; >+ RefcountKey *idkey; >+ RefcountKey *shadowed_key; > char *comment; > char *provider; > time_t death; >@@ -185,16 +191,43 @@ idtab_lookup(int version) > return &idtable[version]; > } > >+static RefcountKey * >+refkey_new(struct sshkey *key) >+{ >+ RefcountKey *ref = xcalloc(1, sizeof(RefcountKey)); >+ >+ ref->key = key; >+ ref->count = 1; >+ >+ return ref; >+} >+ >+static RefcountKey * >+refkey_addref(RefcountKey *refkey) >+{ >+ ++refkey->count; >+ return refkey; >+} >+ >+static void refkey_unref(RefcountKey *refkey) >+{ >+ if (refkey && --refkey->count <= 0) { >+ sshkey_free(refkey->key); >+ free(refkey); >+ } >+} >+ > static void > free_identity(Identity *id) > { >- sshkey_free(id->key); >+ refkey_unref(id->idkey); >+ refkey_unref(id->shadowed_key); > free(id->provider); > free(id->comment); > free(id); > } > >-/* return matching private key for given public key */ >+/* return matching Identity for given public key */ > static Identity * > lookup_identity(struct sshkey *key, int version) > { >@@ -202,7 +235,22 @@ lookup_identity(struct sshkey *key, int version) > > Idtab *tab = idtab_lookup(version); > TAILQ_FOREACH(id, &tab->idlist, next) { >- if (sshkey_equal(key, id->key)) >+ if (sshkey_equal(key, id->idkey->key)) >+ return (id); >+ } >+ return (NULL); >+} >+ >+/* return matching private key for given public key */ >+static Identity * >+lookup_identity_unshadowed_key(struct sshkey *key, int version) >+{ >+ Identity *id; >+ >+ Idtab *tab = idtab_lookup(version); >+ TAILQ_FOREACH(id, &tab->idlist, next) { >+ if (sshkey_equal_public(key, id->idkey->key) && >+ id->shadowed_key == NULL) > return (id); > } > return (NULL); >@@ -215,7 +263,7 @@ confirm_key(Identity *id) > char *p; > int ret = -1; > >- p = sshkey_fingerprint(id->key, fingerprint_hash, SSH_FP_DEFAULT); >+ p = sshkey_fingerprint(id->idkey->key, fingerprint_hash, SSH_FP_DEFAULT); > if (p != NULL && > ask_permission("Allow use of key %s?\nKey fingerprint %s.", > id->comment, p)) >@@ -253,14 +301,14 @@ process_request_identities(SocketEntry *e, int version) > (r = sshbuf_put_u32(msg, tab->nentries)) != 0) > fatal("%s: buffer error: %s", __func__, ssh_err(r)); > TAILQ_FOREACH(id, &tab->idlist, next) { >- if (id->key->type == KEY_RSA1) { >+ if (id->idkey->key->type == KEY_RSA1) { > #ifdef WITH_SSH1 > if ((r = sshbuf_put_u32(msg, >- BN_num_bits(id->key->rsa->n))) != 0 || >+ BN_num_bits(id->idkey->key->rsa->n))) != 0 || > (r = sshbuf_put_bignum1(msg, >- id->key->rsa->e)) != 0 || >+ id->idkey->key->rsa->e)) != 0 || > (r = sshbuf_put_bignum1(msg, >- id->key->rsa->n)) != 0) >+ id->idkey->key->rsa->n)) != 0) > fatal("%s: buffer error: %s", > __func__, ssh_err(r)); > #endif >@@ -268,7 +316,7 @@ process_request_identities(SocketEntry *e, int version) > u_char *blob; > size_t blen; > >- if ((r = sshkey_to_blob(id->key, &blob, &blen)) != 0) { >+ if ((r = sshkey_to_blob(id->idkey->key, &blob, &blen)) != 0) { > error("%s: sshkey_to_blob: %s", __func__, > ssh_err(r)); > continue; >@@ -324,7 +372,7 @@ process_authentication_challenge1(SocketEntry *e) > > id = lookup_identity(key, 1); > if (id != NULL && (!id->confirm || confirm_key(id) == 0)) { >- struct sshkey *private = id->key; >+ struct sshkey *private = id->idkey->key; > /* Decrypt the challenge using the private key. */ > if ((r = rsa_private_decrypt(challenge, challenge, > private->rsa) != 0)) { >@@ -377,7 +425,7 @@ process_sign_request2(SocketEntry *e) > u_int compat = 0, flags; > int r, ok = -1; > struct sshbuf *msg; >- struct sshkey *key; >+ struct sshkey *key, *sign_key; > struct identity *id; > > if ((msg = sshbuf_new()) == NULL) >@@ -400,7 +448,12 @@ process_sign_request2(SocketEntry *e) > verbose("%s: user refused key", __func__); > goto send; > } >- if ((r = sshkey_sign(id->key, &signature, &slen, >+ >+ if (id->shadowed_key) >+ sign_key = id->shadowed_key->key; >+ else >+ sign_key = id->idkey->key; >+ if ((r = sshkey_sign(sign_key, &signature, &slen, > data, dlen, compat)) != 0) { > error("%s: sshkey_sign: %s", __func__, ssh_err(ok)); > goto send; >@@ -640,12 +693,38 @@ process_add_identity(SocketEntry *e, int version) > } > } > >- success = 1; > if (lifetime && !death) > death = monotime() + lifetime; >+ >+ /* handle additional certificates for an existing private key */ >+ if (!sshkey_is_private(k)) { >+ id = lookup_identity_unshadowed_key(k, version); >+ /* ensure we have a private key and this cert is new */ >+ if (id != NULL && lookup_identity(k, version) == NULL) { >+ Identity *certid = xcalloc(1, sizeof(Identity)); >+ certid->idkey = refkey_new(k); >+ certid->shadowed_key = refkey_addref(id->idkey); >+ if (id->provider) >+ certid->provider = xstrdup(id->provider); >+ if (id->comment) >+ certid->comment = xstrdup(id->comment); /* XXX */ >+ certid->death = death; >+ certid->confirm = confirm | id->confirm; >+ >+ TAILQ_INSERT_TAIL(&tab->idlist, certid, next); >+ tab->nentries++; >+ success = 1; >+ } else >+ sshkey_free(k); >+ >+ free(comment); >+ goto send; >+ } >+ >+ success = 1; > if ((id = lookup_identity(k, version)) == NULL) { > id = xcalloc(1, sizeof(Identity)); >- id->key = k; >+ id->idkey = refkey_new(k); > TAILQ_INSERT_TAIL(&tab->idlist, id, next); > /* Increment the number of identities. */ > tab->nentries++; >@@ -771,7 +850,7 @@ process_add_smartcard_key(SocketEntry *e) > tab = idtab_lookup(version); > if (lookup_identity(k, version) == NULL) { > id = xcalloc(1, sizeof(Identity)); >- id->key = k; >+ id->idkey = refkey_new(k); > id->provider = xstrdup(provider); > id->comment = xstrdup(provider); /* XXX */ > id->death = death; >-- >2.4.3 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 2472
:
2715
|
2716
|
2717
|
2933
|
2934
|
3227