]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
Split pkinit_identity_initialize into two phases
authorNalin Dahyabhai <nalin@redhat.com>
Fri, 28 Jun 2013 21:12:39 +0000 (17:12 -0400)
committerGreg Hudson <ghudson@mit.edu>
Wed, 17 Jul 2013 16:24:20 +0000 (12:24 -0400)
Split part of pkinit_identity_initialize() into a second piece named
pkinit_identity_prompt().  Have each piece pass a new boolean flag to
crypto_load_certs() to indicate if it should defer prompting for a
password/PIN for client identities that require one.  If the flag isn't
set, then crypto_load_certs() should attempt to use a responder-supplied
value, or call the prompter if there isn't one.

ticket: 7680

src/plugins/preauth/pkinit/pkinit.h
src/plugins/preauth/pkinit/pkinit_clnt.c
src/plugins/preauth/pkinit/pkinit_crypto.h
src/plugins/preauth/pkinit/pkinit_crypto_nss.c
src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
src/plugins/preauth/pkinit/pkinit_identity.c
src/plugins/preauth/pkinit/pkinit_srv.c

index 39d4aaaf558f8f96bc6ebe9c1cb73232f0617e7d..b44dfe7b7bed38d2a3dbff8bd01e36203ff18270 100644 (file)
@@ -281,6 +281,16 @@ char * idtype2string(int idtype);
 char * catype2string(int catype);
 
 krb5_error_code pkinit_identity_initialize
+       (krb5_context context,                          /* IN */
+        pkinit_plg_crypto_context plg_cryptoctx,       /* IN */
+        pkinit_req_crypto_context req_cryptoctx,       /* IN */
+        pkinit_identity_opts *idopts,                  /* IN */
+        pkinit_identity_crypto_context id_cryptoctx,   /* IN/OUT */
+        krb5_clpreauth_callbacks cb,                   /* IN/OUT */
+        krb5_clpreauth_rock rock,                      /* IN/OUT */
+        krb5_principal princ);                         /* IN (optional) */
+
+krb5_error_code pkinit_identity_prompt
        (krb5_context context,                          /* IN */
         pkinit_plg_crypto_context plg_cryptoctx,       /* IN */
         pkinit_req_crypto_context req_cryptoctx,       /* IN */
index 5db24dad37e516c472d32c0ad6503917b6f6d146..748b25e52ac23b4d54eb3cc951e9257a6ad88e2d 100644 (file)
@@ -1107,15 +1107,29 @@ pkinit_client_process(krb5_context context, krb5_clpreauth_moddata moddata,
     if (processing_request) {
         pkinit_client_profile(context, plgctx, reqctx, cb, rock,
                               &request->server->realm);
+        retval = pkinit_identity_initialize(context, plgctx->cryptoctx, NULL,
+                                            reqctx->idopts, reqctx->idctx,
+                                            cb, rock, request->client);
+        if (retval) {
+            TRACE_PKINIT_CLIENT_NO_IDENTITY(context);
+            pkiDebug("pkinit_identity_prompt returned %d (%s)\n",
+                     retval, error_message(retval));
+            return retval;
+        }
+        /*
+         * Load identities (again, potentially), prompting, if we can, for
+         * anything for which we didn't get an answer from the responder
+         * callback.
+         */
         pkinit_identity_set_prompter(reqctx->idctx, prompter, prompter_data);
-        retval = pkinit_identity_initialize(context, plgctx->cryptoctx,
-                                            reqctx->cryptoctx, reqctx->idopts,
-                                            reqctx->idctx, cb, rock,
-                                            reqctx->do_identity_matching,
-                                            request->client);
+        retval = pkinit_identity_prompt(context, plgctx->cryptoctx,
+                                        reqctx->cryptoctx, reqctx->idopts,
+                                        reqctx->idctx, cb, rock,
+                                        reqctx->do_identity_matching,
+                                        request->client);
         if (retval) {
             TRACE_PKINIT_CLIENT_NO_IDENTITY(context);
-            pkiDebug("pkinit_identity_initialize returned %d (%s)\n",
+            pkiDebug("pkinit_identity_prompt returned %d (%s)\n",
                      retval, error_message(retval));
             return retval;
         }
index 8b4b62b6d04f10dab03f39e67ddc5d2edb9afe5f..8c2b0063a82593cb6ac1d97bd45857d9fd2cd727 100644 (file)
@@ -433,7 +433,8 @@ krb5_error_code crypto_load_certs
        pkinit_req_crypto_context req_cryptoctx,        /* IN */
        pkinit_identity_opts *idopts,                   /* IN */
        pkinit_identity_crypto_context id_cryptoctx,    /* IN/OUT */
-       krb5_principal princ);                          /* IN */
+       krb5_principal princ,                           /* IN */
+       krb5_boolean defer_id_prompts);                 /* IN */
 
 /*
  * Free up information held from crypto_load_certs()
index 47006ec7e61fc851d6bf1c847aa0773552c0e489..ef0e94d6897d9b074fcfb116e94ee58c97d75c10 100644 (file)
@@ -2890,7 +2890,8 @@ crypto_load_certs(krb5_context context,
                   pkinit_req_crypto_context req_cryptoctx,
                   pkinit_identity_opts *idopts,
                   pkinit_identity_crypto_context id_cryptoctx,
-                  krb5_principal princ)
+                  krb5_principal princ,
+                  krb5_boolean defer_id_prompts)
 {
     SECStatus status;
 
index 29c4f5755b40c67eb27d26812d6349a1cb785788..a780e7122d972f3f865bcf61d131c603da2da4e3 100644 (file)
@@ -4792,7 +4792,8 @@ crypto_load_certs(krb5_context context,
                   pkinit_req_crypto_context req_cryptoctx,
                   pkinit_identity_opts *idopts,
                   pkinit_identity_crypto_context id_cryptoctx,
-                  krb5_principal princ)
+                  krb5_principal princ,
+                  krb5_boolean defer_id_prompts)
 {
     krb5_error_code retval;
 
index 98c0f0083a8d9a3c96bdd8bfaa7d39e0dd66d85d..a53810c5c92da3db24b4415ab1f536565738d86c 100644 (file)
@@ -511,6 +511,11 @@ process_option_ca_crl(krb5_context context,
                                     idtype, catype, residual);
 }
 
+/*
+ * Load any identity information which doesn't require us to ask a controlling
+ * user any questions, and record the names of anything else which would
+ * require us to ask questions.
+ */
 krb5_error_code
 pkinit_identity_initialize(krb5_context context,
                            pkinit_plg_crypto_context plg_cryptoctx,
@@ -519,15 +524,15 @@ pkinit_identity_initialize(krb5_context context,
                            pkinit_identity_crypto_context id_cryptoctx,
                            krb5_clpreauth_callbacks cb,
                            krb5_clpreauth_rock rock,
-                           int do_matching,
                            krb5_principal princ)
 {
     krb5_error_code retval = EINVAL;
-    const char *signer_identity;
     int i;
 
     pkiDebug("%s: %p %p %p\n", __FUNCTION__, context, idopts, id_cryptoctx);
-    if (!(princ && krb5_principal_compare_any_realm (context, princ, krb5_anonymous_principal()))) {
+    if (!(princ &&
+          krb5_principal_compare_any_realm(context, princ,
+                                           krb5_anonymous_principal()))) {
         if (idopts == NULL || id_cryptoctx == NULL)
             goto errout;
 
@@ -561,11 +566,53 @@ pkinit_identity_initialize(krb5_context context,
             goto errout;
 
         retval = crypto_load_certs(context, plg_cryptoctx, req_cryptoctx,
-                                   idopts, id_cryptoctx, princ);
+                                   idopts, id_cryptoctx, princ, TRUE);
+        if (retval)
+            goto errout;
+    } else {
+        /* We're the anonymous principal. */
+        retval = 0;
+    }
+
+errout:
+    return retval;
+}
+
+/*
+ * Load identity information, including that which requires us to ask a
+ * controlling user any questions.  If we have PIN/password values which
+ * correspond to a given identity, use that, otherwise, if one is available,
+ * we'll use the prompter callback.
+ */
+krb5_error_code
+pkinit_identity_prompt(krb5_context context,
+                       pkinit_plg_crypto_context plg_cryptoctx,
+                       pkinit_req_crypto_context req_cryptoctx,
+                       pkinit_identity_opts *idopts,
+                       pkinit_identity_crypto_context id_cryptoctx,
+                       krb5_clpreauth_callbacks cb,
+                       krb5_clpreauth_rock rock,
+                       int do_matching,
+                       krb5_principal princ)
+{
+    krb5_error_code retval = EINVAL;
+    const char *signer_identity;
+    int i;
+
+    pkiDebug("%s: %p %p %p\n", __FUNCTION__, context, idopts, id_cryptoctx);
+    if (!(princ &&
+          krb5_principal_compare_any_realm(context, princ,
+                                           krb5_anonymous_principal()))) {
+        retval = crypto_load_certs(context, plg_cryptoctx, req_cryptoctx,
+                                   idopts, id_cryptoctx, princ, FALSE);
         if (retval)
             goto errout;
 
         if (do_matching) {
+            /*
+             * Try to select exactly one certificate based on matching
+             * criteria.  Typical used for clients.
+             */
             retval = pkinit_cert_matching(context, plg_cryptoctx,
                                           req_cryptoctx, id_cryptoctx, princ);
             if (retval) {
@@ -575,7 +622,10 @@ pkinit_identity_initialize(krb5_context context,
                 goto errout;
             }
         } else {
-            /* Tell crypto code to use the "default" */
+            /*
+             * Tell crypto code to use the "default" identity.  Typically used
+             * for KDCs.
+             */
             retval = crypto_cert_select_default(context, plg_cryptoctx,
                                                 req_cryptoctx, id_cryptoctx);
             if (retval) {
index f3dfb501f24882dbdc2feee541a8ef0aa61c8542..640e835ca87be10d98a290e7a835586f8187a864 100644 (file)
@@ -1299,7 +1299,12 @@ pkinit_server_plugin_init_realm(krb5_context context, const char *realmname,
 
     retval = pkinit_identity_initialize(context, plgctx->cryptoctx, NULL,
                                         plgctx->idopts, plgctx->idctx,
-                                        NULL, NULL, 0, NULL);
+                                        NULL, NULL, NULL);
+    if (retval)
+        goto errout;
+    retval = pkinit_identity_prompt(context, plgctx->cryptoctx, NULL,
+                                    plgctx->idopts, plgctx->idctx,
+                                    NULL, NULL, 0, NULL);
     if (retval)
         goto errout;