diff options
| author | Will Fiveash <will.fiveash@oracle.com> | 2010-07-28 17:47:31 -0500 |
|---|---|---|
| committer | Will Fiveash <will.fiveash@oracle.com> | 2010-07-28 17:47:31 -0500 |
| commit | 488060a6285c53d78d4e5360e7db00d6d544d960 (patch) | |
| tree | 8f11bd03cfd23c63d3c454da46c69335bac6b854 /usr/src/lib/krb5/plugins/preauth | |
| parent | 700f2bdf63820e30238ab3d63d8f6b61d731ff54 (diff) | |
| download | illumos-joyent-488060a6285c53d78d4e5360e7db00d6d544d960.tar.gz | |
6929628 pkinit preauth plugin needs interface so caller can provide PIN
Diffstat (limited to 'usr/src/lib/krb5/plugins/preauth')
5 files changed, 87 insertions, 23 deletions
diff --git a/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit.h b/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit.h index 9ae77a2a5f..3614c618bf 100644 --- a/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit.h +++ b/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit.h @@ -28,6 +28,10 @@ * SUCH DAMAGES. */ +/* + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + */ + #ifndef _PKINIT_H #define _PKINIT_H @@ -196,6 +200,7 @@ typedef struct _pkinit_identity_opts { char *token_label; char *cert_id_string; char *cert_label; + char *PIN; /* Solaris Kerberos */ #endif } pkinit_identity_opts; diff --git a/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_clnt.c b/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_clnt.c index 296d051708..c06a66dc8c 100644 --- a/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_clnt.c +++ b/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_clnt.c @@ -28,6 +28,10 @@ * SUCH DAMAGES. */ +/* + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + */ + #include <stdio.h> #include <stdlib.h> #include <errno.h> @@ -1472,6 +1476,11 @@ handle_gic_opt(krb5_context context, pkiDebug("Setting flag to use RSA_PROTOCOL\n"); plgctx->opts->dh_or_rsa = RSA_PROTOCOL; } + } else if (strcmp(attr, "PIN") == 0) { + /* Solaris Kerberos: handle our PIN attr */ + plgctx->idopts->PIN = strdup(value); + if (plgctx->idopts->PIN == NULL) + return ENOMEM; } return 0; } diff --git a/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto_openssl.c index b22675eaab..d73efc201a 100644 --- a/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto_openssl.c +++ b/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto_openssl.c @@ -769,6 +769,7 @@ pkinit_init_pkcs11(pkinit_identity_crypto_context ctx) ctx->slotid = PK_NOSLOT; ctx->token_label = NULL; ctx->cert_label = NULL; + ctx->PIN = NULL; ctx->session = CK_INVALID_HANDLE; ctx->p11 = NULL; ctx->p11flags = 0; /* Solaris Kerberos */ @@ -811,6 +812,10 @@ pkinit_fini_pkcs11(pkinit_identity_crypto_context ctx) free(ctx->cert_id); if (ctx->cert_label != NULL) free(ctx->cert_label); + if (ctx->PIN != NULL) { + (void) memset(ctx->PIN, 0, strlen(ctx->PIN)); + free(ctx->PIN); + } #endif } @@ -3363,6 +3368,10 @@ pkinit_C_UnloadModule(void *handle) return CKR_OK; } +/* + * Solaris Kerberos: this function was changed to support a PIN being passed + * in. If that is the case the user will not be prompted for their PIN. + */ static krb5_error_code pkinit_login(krb5_context context, pkinit_identity_crypto_context id_cryptoctx, @@ -3378,6 +3387,15 @@ pkinit_login(krb5_context context, if (tip->flags & CKF_PROTECTED_AUTHENTICATION_PATH) { rdat.data = NULL; rdat.length = 0; + } else if (id_cryptoctx->PIN != NULL) { + if ((rdat.data = strdup(id_cryptoctx->PIN)) == NULL) + return (ENOMEM); + /* + * Don't include NULL string terminator in length calculation as this + * PIN is passed to the C_Login function and only the text chars should + * be considered to be the PIN. + */ + rdat.length = strlen(id_cryptoctx->PIN); } else { unsigned char *lastnonwspc, *iterp; /* Solaris Kerberos - trim token label */ int count; @@ -3409,8 +3427,12 @@ pkinit_login(krb5_context context, (void) strlcat(prompt, gettext(" (Warning: PIN final try)"), prompt_len); else if (tip->flags & CKF_USER_PIN_COUNT_LOW) (void) strlcat(prompt, gettext(" (Warning: PIN count low)"), prompt_len); - rdat.data = (char *)malloc(tip->ulMaxPinLen + 2); + rdat.data = malloc(tip->ulMaxPinLen + 2); rdat.length = tip->ulMaxPinLen + 1; + /* + * Note that the prompter function will set rdat.length such that the + * NULL terminator is not included + */ kprompt.prompt = prompt; kprompt.hidden = 1; @@ -3421,7 +3443,7 @@ pkinit_login(krb5_context context, k5int_set_prompt_types(context, &prompt_type); r = (*id_cryptoctx->prompter)(context, id_cryptoctx->prompter_data, NULL, NULL, 1, &kprompt); - k5int_set_prompt_types(context, 0); + k5int_set_prompt_types(context, NULL); free(prompt); } @@ -3441,8 +3463,10 @@ pkinit_login(krb5_context context, id_cryptoctx->p11flags |= C_LOGIN_DONE; } } - if (rdat.data) + if (rdat.data) { + (void) memset(rdat.data, 0, rdat.length); free(rdat.data); + } return r; } @@ -4105,27 +4129,33 @@ pkinit_get_certs_pkcs12(krb5_context context, pkiDebug("Initial PKCS12_parse with no password failed\n"); - (void) memset(prompt_reply, '\0', sizeof(prompt_reply)); - rdat.data = prompt_reply; - rdat.length = sizeof(prompt_reply); - - r = snprintf(prompt_string, sizeof(prompt_string), "%s %s", - prompt_prefix, idopts->cert_filename); - if (r >= sizeof(prompt_string)) { - pkiDebug("Prompt string, '%s %s', is too long!\n", - prompt_prefix, idopts->cert_filename); - goto cleanup; + if (id_cryptoctx->PIN != NULL) { + /* Solaris Kerberos: use PIN if set */ + rdat.data = id_cryptoctx->PIN; + /* note rdat.length isn't needed in this case */ + } else { + (void) memset(prompt_reply, '\0', sizeof(prompt_reply)); + rdat.data = prompt_reply; + rdat.length = sizeof(prompt_reply); + + r = snprintf(prompt_string, sizeof(prompt_string), "%s %s", + prompt_prefix, idopts->cert_filename); + if (r >= sizeof(prompt_string)) { + pkiDebug("Prompt string, '%s %s', is too long!\n", + prompt_prefix, idopts->cert_filename); + goto cleanup; + } + kprompt.prompt = prompt_string; + kprompt.hidden = 1; + kprompt.reply = &rdat; + prompt_type = KRB5_PROMPT_TYPE_PREAUTH; + + /* PROMPTER_INVOCATION */ + k5int_set_prompt_types(context, &prompt_type); + r = (*id_cryptoctx->prompter)(context, id_cryptoctx->prompter_data, + NULL, NULL, 1, &kprompt); + k5int_set_prompt_types(context, NULL); } - kprompt.prompt = prompt_string; - kprompt.hidden = 1; - kprompt.reply = &rdat; - prompt_type = KRB5_PROMPT_TYPE_PREAUTH; - - /* PROMPTER_INVOCATION */ - k5int_set_prompt_types(context, &prompt_type); - r = (*id_cryptoctx->prompter)(context, id_cryptoctx->prompter_data, - NULL, NULL, 1, &kprompt); - k5int_set_prompt_types(context, 0); ret = PKCS12_parse(p12, rdat.data, &y, &x, NULL); if (ret == 0) { @@ -4389,6 +4419,11 @@ pkinit_get_certs_pkcs11(krb5_context context, if (id_cryptoctx->cert_label == NULL) return ENOMEM; } + if (idopts->PIN != NULL) { + id_cryptoctx->PIN = strdup(idopts->PIN); + if (id_cryptoctx->PIN == NULL) + return ENOMEM; + } /* Convert the ascii cert_id string into a binary blob */ /* * Solaris Kerberos: diff --git a/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto_openssl.h b/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto_openssl.h index 289c3d060a..1eb60263ec 100644 --- a/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto_openssl.h +++ b/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto_openssl.h @@ -80,6 +80,7 @@ struct _pkinit_identity_crypto_context { CK_SLOT_ID slotid; char *token_label; char *cert_label; + char *PIN; /* Solaris Kerberos: */ /* These are crypto-specific */ void *p11_module; CK_SESSION_HANDLE session; diff --git a/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_identity.c b/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_identity.c index e4a6470523..7656b8eb4e 100644 --- a/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_identity.c +++ b/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_identity.c @@ -28,6 +28,10 @@ * SUCH DAMAGES. */ +/* + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + */ + #include <errno.h> #include <string.h> #include <stdio.h> @@ -136,6 +140,7 @@ pkinit_init_identity_opts(pkinit_identity_opts **idopts) opts->token_label = NULL; opts->cert_id_string = NULL; opts->cert_label = NULL; + opts->PIN = NULL; #endif *idopts = opts; @@ -219,6 +224,11 @@ pkinit_dup_identity_opts(pkinit_identity_opts *src_opts, if (newopts->cert_label == NULL) goto cleanup; } + if (src_opts->PIN != NULL) { + newopts->PIN = strdup(src_opts->PIN); + if (newopts->PIN == NULL) + goto cleanup; + } #endif @@ -255,6 +265,10 @@ pkinit_fini_identity_opts(pkinit_identity_opts *idopts) free(idopts->cert_id_string); if (idopts->cert_label != NULL) free(idopts->cert_label); + if (idopts->PIN != NULL) { + (void) memset(idopts->PIN, 0, strlen(idopts->PIN)); + free(idopts->PIN); + } #endif free(idopts); } |
