Nalin Dahyabhai 8220592
commit a8eec52a13ba108b8855aef8cf9dafeb37811d2e
Nalin Dahyabhai 8220592
Author: Nalin Dahyabhai <nalin@redhat.com>
Nalin Dahyabhai 8220592
Date:   Fri Mar 15 12:05:56 2013 -0400
Nalin Dahyabhai 8220592
Nalin Dahyabhai 8220592
    Add PEM password prompter callback in PKINIT
Nalin Dahyabhai 8220592
    
Nalin Dahyabhai 8220592
    Supply a callack to PEM_read_bio_PrivateKey() using the prompter to
Nalin Dahyabhai 8220592
    request a password for encrypted PEM data.  Otherwise OpenSSL will use
Nalin Dahyabhai 8220592
    the controlling terminal.
Nalin Dahyabhai 8220592
    
Nalin Dahyabhai 8220592
    [ghudson@mit.edu: minor style cleanup, commit message]
Nalin Dahyabhai 8220592
    
Nalin Dahyabhai 8220592
    ticket: 7590
Nalin Dahyabhai 8220592
Nalin Dahyabhai 8220592
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
Nalin Dahyabhai 8220592
index 6dbda9b..7186ce8 100644
Nalin Dahyabhai 8220592
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
Nalin Dahyabhai 8220592
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
Nalin Dahyabhai 8220592
@@ -656,11 +656,50 @@ cleanup:
Nalin Dahyabhai 8220592
     return retval;
Nalin Dahyabhai 8220592
 }
Nalin Dahyabhai 8220592
 
Nalin Dahyabhai 8220592
+struct get_key_cb_data {
Nalin Dahyabhai 8220592
+    krb5_context context;
Nalin Dahyabhai 8220592
+    pkinit_identity_crypto_context id_cryptoctx;
Nalin Dahyabhai 8220592
+    char *filename;
Nalin Dahyabhai 8220592
+};
Nalin Dahyabhai 8220592
+
Nalin Dahyabhai 8220592
+static int
Nalin Dahyabhai 8220592
+get_key_cb(char *buf, int size, int rwflag, void *userdata)
Nalin Dahyabhai 8220592
+{
Nalin Dahyabhai 8220592
+    struct get_key_cb_data *data = userdata;
Nalin Dahyabhai 8220592
+    pkinit_identity_crypto_context id_cryptoctx;
Nalin Dahyabhai 8220592
+    krb5_data rdat;
Nalin Dahyabhai 8220592
+    krb5_prompt kprompt;
Nalin Dahyabhai 8220592
+    krb5_prompt_type prompt_type;
Nalin Dahyabhai 8220592
+    krb5_error_code retval;
Nalin Dahyabhai 8220592
+    char *prompt;
Nalin Dahyabhai 8220592
+
Nalin Dahyabhai 8220592
+    if (asprintf(&prompt, "%s %s", _("Pass phrase for"), data->filename) < 0)
Nalin Dahyabhai 8220592
+        return -1;
Nalin Dahyabhai 8220592
+    rdat.data = buf;
Nalin Dahyabhai 8220592
+    rdat.length = size;
Nalin Dahyabhai 8220592
+    kprompt.prompt = prompt;
Nalin Dahyabhai 8220592
+    kprompt.hidden = 1;
Nalin Dahyabhai 8220592
+    kprompt.reply = &rda;;
Nalin Dahyabhai 8220592
+    prompt_type = KRB5_PROMPT_TYPE_PREAUTH;
Nalin Dahyabhai 8220592
+
Nalin Dahyabhai 8220592
+    /* PROMPTER_INVOCATION */
Nalin Dahyabhai 8220592
+    k5int_set_prompt_types(data->context, &prompt_type);
Nalin Dahyabhai 8220592
+    id_cryptoctx = data->id_cryptoctx;
Nalin Dahyabhai 8220592
+    retval = data->id_cryptoctx->prompter(data->context,
Nalin Dahyabhai 8220592
+                                          id_cryptoctx->prompter_data, NULL,
Nalin Dahyabhai 8220592
+                                          NULL, 1, &kprompt);
Nalin Dahyabhai 8220592
+    k5int_set_prompt_types(data->context, 0);
Nalin Dahyabhai 8220592
+    free(prompt);
Nalin Dahyabhai 8220592
+    return retval ? -1 : (int)rdat.length;
Nalin Dahyabhai 8220592
+}
Nalin Dahyabhai 8220592
+
Nalin Dahyabhai 8220592
 static krb5_error_code
Nalin Dahyabhai 8220592
-get_key(char *filename, EVP_PKEY **retkey)
Nalin Dahyabhai 8220592
+get_key(krb5_context context, pkinit_identity_crypto_context id_cryptoctx,
Nalin Dahyabhai 8220592
+        char *filename, EVP_PKEY **retkey)
Nalin Dahyabhai 8220592
 {
Nalin Dahyabhai 8220592
     EVP_PKEY *pkey = NULL;
Nalin Dahyabhai 8220592
     BIO *tmp = NULL;
Nalin Dahyabhai 8220592
+    struct get_key_cb_data cb_data;
Nalin Dahyabhai 8220592
     int code;
Nalin Dahyabhai 8220592
     krb5_error_code retval;
Nalin Dahyabhai 8220592
 
Nalin Dahyabhai 8220592
@@ -676,7 +715,10 @@ get_key(char *filename, EVP_PKEY **retkey)
Nalin Dahyabhai 8220592
         retval = errno;
Nalin Dahyabhai 8220592
         goto cleanup;
Nalin Dahyabhai 8220592
     }
Nalin Dahyabhai 8220592
-    pkey = (EVP_PKEY *) PEM_read_bio_PrivateKey(tmp, NULL, NULL, NULL);
Nalin Dahyabhai 8220592
+    cb_data.context = context;
Nalin Dahyabhai 8220592
+    cb_data.id_cryptoctx = id_cryptoctx;
Nalin Dahyabhai 8220592
+    cb_data.filename = filename;
Nalin Dahyabhai 8220592
+    pkey = PEM_read_bio_PrivateKey(tmp, NULL, get_key_cb, &cb_data);
Nalin Dahyabhai 8220592
     if (pkey == NULL) {
Nalin Dahyabhai 8220592
         retval = EIO;
Nalin Dahyabhai 8220592
         pkiDebug("failed to read private key from %s\n", filename);
Nalin Dahyabhai 8220592
@@ -4333,7 +4375,7 @@ pkinit_load_fs_cert_and_key(krb5_context context,
Nalin Dahyabhai 8220592
         pkiDebug("failed to load user's certificate from '%s'\n", certname);
Nalin Dahyabhai 8220592
         goto cleanup;
Nalin Dahyabhai 8220592
     }
Nalin Dahyabhai 8220592
-    retval = get_key(keyname, &y);
Nalin Dahyabhai 8220592
+    retval = get_key(context, id_cryptoctx, keyname, &y);
Nalin Dahyabhai 8220592
     if (retval != 0 || y == NULL) {
Nalin Dahyabhai 8220592
         pkiDebug("failed to load user's private key from '%s'\n", keyname);
Nalin Dahyabhai 8220592
         goto cleanup;