I've checked again and again. There really is no need to expand a to
authorRichard Levitte <levitte@openssl.org>
Thu, 16 Nov 2000 21:35:41 +0000 (21:35 +0000)
committerRichard Levitte <levitte@openssl.org>
Thu, 16 Nov 2000 21:35:41 +0000 (21:35 +0000)
4 times it's size when bn_sqr_recursive() won't look farther than the
original length.  Thereby, constification is no longer a problem.

crypto/bn/bn_sqr.c
ssl/kssl.c [new file with mode: 0644]
ssl/kssl.h [new file with mode: 0644]

index 4789f13..bbff1ad 100644 (file)
@@ -69,7 +69,7 @@ int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
        BIGNUM *tmp,*rr,*free_a = NULL;
 
 #ifdef BN_COUNT
-printf("BN_sqr %d * %d\n",a->top,a->top);
+       fprintf(stderr,"BN_sqr %d * %d\n",a->top,a->top);
 #endif
        bn_check_top(a);
 
@@ -124,10 +124,7 @@ printf("BN_sqr %d * %d\n",a->top,a->top);
                        k=j+j;
                        if (al == j)
                                {
-                               BIGNUM *tmp_bn = free_a;
-                               if ((a = free_a = bn_dup_expand(a,k*2)) == NULL) goto err;
                                if (bn_wexpand(tmp,k*2) == NULL) goto err;
-                               if (tmp_bn) BN_free(tmp_bn);
                                bn_sqr_recursive(rr->d,a->d,al,tmp->d);
                                }
                        else
@@ -153,10 +150,11 @@ printf("BN_sqr %d * %d\n",a->top,a->top);
        }
 
 /* tmp must have 2*n words */
-void bn_sqr_normal(BN_ULONG *r, BN_ULONG *a, int n, BN_ULONG *tmp)
+void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp)
        {
        int i,j,max;
-       BN_ULONG *ap,*rp;
+       const BN_ULONG *ap;
+       BN_ULONG *rp;
 
        max=n*2;
        ap=a;
@@ -200,14 +198,14 @@ void bn_sqr_normal(BN_ULONG *r, BN_ULONG *a, int n, BN_ULONG *tmp)
  * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0])
  * a[1]*b[1]
  */
-void bn_sqr_recursive(BN_ULONG *r, BN_ULONG *a, int n2, BN_ULONG *t)
+void bn_sqr_recursive(BN_ULONG *r, const BN_ULONG *a, int n2, BN_ULONG *t)
        {
        int n=n2/2;
        int zero,c1;
        BN_ULONG ln,lo,*p;
 
 #ifdef BN_COUNT
-printf(" bn_sqr_recursive %d * %d\n",n2,n2);
+       fprintf(stderr," bn_sqr_recursive %d * %d\n",n2,n2);
 #endif
        if (n2 == 4)
                {
diff --git a/ssl/kssl.c b/ssl/kssl.c
new file mode 100644 (file)
index 0000000..8d72beb
--- /dev/null
@@ -0,0 +1,582 @@
+/* ssl/kssl.c -*- mode: C; c-file-style: "eay" -*- */
+/* Written by Vern Staats <staatsvr@asc.hpc.mil> for the OpenSSL project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+/*     ssl/kssl.c  --  Routines to support (& debug) Kerberos5 auth for openssl
+**
+**     19990701        VRS     Started.
+*/
+
+#ifndef NO_KRB5
+#include <string.h>
+#include <openssl/ssl.h>
+
+char
+*kstring(char *string)
+        {
+        static char    *null = "[NULL]";
+
+       return ((string == NULL)? null: string);
+        }
+
+#define        MAXKNUM 255
+char
+*knumber(int len, krb5_octet *contents)
+        {
+       static char     buf[MAXKNUM+1];
+       int             i;
+
+       BIO_snprintf(buf, MAXKNUM, "[%d] ", len);
+
+       for (i=0; i < len  &&  MAXKNUM > strlen(buf)+3; i++)
+                {
+                BIO_snprintf(&buf[strlen(buf)], 3, "%02x", contents[i]);
+                }
+
+       return (buf);
+}
+
+
+/*     Set kssl_err error info when reason text is a simple string
+**             kssl_err = struct { int reason; char text[KSSL_ERR_MAX+1]; }
+*/
+void
+kssl_err_set(KSSL_ERR *kssl_err, int reason, char *text)
+        {
+       if (kssl_err == NULL)  return;
+
+       kssl_err->reason = reason;
+       BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, text);
+       return;
+        }
+
+
+/*     Display contents of krb5_data struct, for debugging
+*/
+void
+print_krb5_data(char *label, krb5_data *kdata)
+        {
+       int     i;
+
+       printf("%s[%d] ", label, kdata->length);
+       for (i=0; i < kdata->length; i++)
+                {
+               if (isprint((int) kdata->data[i]))
+                        printf(        "%c ",  kdata->data[i]);
+               else
+                        printf(        "%02x", kdata->data[i]);
+               }
+       printf("\n");
+        }
+
+
+/*     Display contents of krb5_authdata struct, for debugging
+*/
+void
+print_krb5_authdata(char *label, krb5_authdata **adata)
+        {
+       if (adata == NULL)
+                {
+               printf("%s, authdata==0\n", label);
+               return;
+               }
+       printf("%s [%p]\n", label, adata);
+#if 0
+       {
+        int    i;
+       printf("%s[at%d:%d] ", label, adata->ad_type, adata->length);
+       for (i=0; i < adata->length; i++)
+                {
+                printf((isprint(adata->contents[i]))? "%c ": "%02x",
+                        adata->contents[i]);
+               }
+       printf("\n");
+       }
+#endif
+}
+
+
+/*     Display contents of krb5_keyblock struct, for debugging
+*/
+void
+print_krb5_keyblock(char *label, krb5_keyblock *keyblk)
+        {
+       int     i;
+
+       if (keyblk == NULL)
+                {
+               printf("%s, keyblk==0\n", label);
+               return;
+               }
+       printf("%s\n\t[et%d:%d]: ", label, keyblk->enctype, keyblk->length);
+       for (i=0; i < keyblk->length; i++)
+                {
+               printf("%02x",keyblk->contents[i]);
+               }
+       printf("\n");
+        }
+
+
+/*     Given krb5 service (typically "kssl") and hostname in kssl_ctx,
+**     Create Kerberos AP_REQ message for SSL Client.
+**
+**     19990628        VRS     Started.
+*/
+krb5_error_code
+kssl_cget_tkt( /* UPDATE */    KSSL_CTX *kssl_ctx,
+                /* OUT    */   krb5_data *krb5_app_req, KSSL_ERR *kssl_err)
+{
+       krb5_error_code         krb5rc = KRB5KRB_ERR_GENERIC;
+       krb5_context            krb5context = NULL;
+       krb5_auth_context       krb5auth_context = NULL;
+       krb5_ccache             krb5ccdef = NULL;
+       krb5_creds              krb5creds, *krb5credsp = NULL;
+       krb5_data               krb5in_data;
+
+       kssl_err_set(kssl_err, 0, "");
+       memset((char *)&krb5creds, 0, sizeof(krb5creds));
+
+       if (!kssl_ctx)
+                {
+               kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
+                        "No kssl_ctx defined.\n");
+               goto err;
+               }
+       else if (!kssl_ctx->service_host)
+                {
+               kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
+                        "kssl_ctx service_host undefined.\n");
+               goto err;
+               }
+
+       if ((krb5rc = krb5_init_context(&krb5context)) != 0)
+                {
+               BIO_snprintf(kssl_err->text,KSSL_ERR_MAX,
+                        "krb5_init_context() fails: %d\n", krb5rc);
+               kssl_err->reason = SSL_R_KRB5_C_INIT;
+               goto err;
+               }
+
+       if ((krb5rc = krb5_sname_to_principal(krb5context,
+                kssl_ctx->service_host,
+                (kssl_ctx->service_name)? kssl_ctx->service_name: KRB5SVC,
+                KRB5_NT_SRV_HST, &krb5creds.server)) != 0)
+                {
+               BIO_snprintf(kssl_err->text,KSSL_ERR_MAX,
+                        "krb5_sname_to_principal() fails for %s/%s\n",
+                        kssl_ctx->service_host,
+                        (kssl_ctx->service_name)? kssl_ctx->service_name: KRB5SVC);
+               kssl_err->reason = SSL_R_KRB5_C_INIT;
+               goto err;
+               }
+
+       if ((krb5rc = krb5_cc_default(krb5context, &krb5ccdef)) != 0)
+                {
+               kssl_err_set(kssl_err, SSL_R_KRB5_C_CC_PRINC,
+                        "krb5_cc_default fails.\n");
+               goto err;
+               }
+
+       if ((krb5rc = krb5_cc_get_principal(krb5context, krb5ccdef,
+                &krb5creds.client)) != 0)
+                {
+               kssl_err_set(kssl_err, SSL_R_KRB5_C_CC_PRINC,
+                        "krb5_cc_get_principal() fails.\n");
+               goto err;
+               }
+
+       if ((krb5rc = krb5_get_credentials(krb5context, 0, krb5ccdef,
+                &krb5creds, &krb5credsp)) != 0)
+                {
+               kssl_err_set(kssl_err, SSL_R_KRB5_C_GET_CRED,
+                        "krb5_get_credentials() fails.\n");
+               goto err;
+               }
+
+       krb5in_data.data = NULL;
+       krb5in_data.length = 0;
+
+       krb5rc = KRB5KRB_ERR_GENERIC;
+       /*      caller should free data of krb5_app_req  */
+        if ((krb5rc = krb5_mk_req_extended(krb5context, &krb5auth_context,
+                0, &krb5in_data, krb5credsp, krb5_app_req)) != 0)
+                {
+               kssl_err_set(kssl_err, SSL_R_KRB5_C_MK_REQ,
+                        "krb5_mk_req_extended() fails.\n");
+               goto err;
+               }
+       else if (kssl_ctx_setkey(kssl_ctx, &krb5credsp->keyblock))
+                {
+               kssl_err_set(kssl_err, SSL_R_KRB5_C_INIT,
+                        "kssl_ctx_setkey() fails.\n");
+               }
+       else    krb5rc = 0;
+
+ err:
+#ifdef KSSL_DEBUG
+       kssl_ctx_show(kssl_ctx);
+#endif /* KSSL_DEBUG */
+
+       if (krb5creds.client)   krb5_free_principal(krb5context, krb5creds.client);
+       if (krb5creds.server)   krb5_free_principal(krb5context, krb5creds.server);
+       if (krb5auth_context)   krb5_auth_con_free(krb5context, krb5auth_context);
+       if (krb5context)        krb5_free_context(krb5context);
+       return (krb5rc);
+}
+
+
+/*     Given krb5 service name in KSSL_CTX *kssl_ctx (typically "kssl"),
+**             and krb5 AP_REQ message & message length,
+**     Return Kerberos session key and client principle
+**             to SSL Server in KSSL_CTX *kssl_ctx.
+**
+**     19990702        VRS     Started.
+*/
+krb5_error_code
+kssl_sget_tkt( /* UPDATE */    KSSL_CTX *kssl_ctx,
+               /* IN     */    char *msg, int msglen,
+               /* OUT    */    KSSL_ERR *kssl_err  )
+        {
+        krb5_error_code                        krb5rc = KRB5KRB_ERR_GENERIC;
+        static krb5_context            krb5context = NULL;
+       static krb5_auth_context        krb5auth_context = NULL;
+       krb5_ticket                     *krb5ticket = NULL;
+       krb5_keytab                     krb5keytab = NULL;
+       krb5_principal                  krb5server;
+       krb5_data                       krb5in_data;
+       krb5_flags                      ap_option;
+
+       kssl_err_set(kssl_err, 0, "");
+
+       if (!kssl_ctx)
+                {
+               kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, "No kssl_ctx defined.\n");
+               goto err;
+               }
+
+#ifdef KSSL_DEBUG
+       printf("in kssl_sget_tkt(%s)\n", kstring(kssl_ctx->service_name));
+#endif /* KSSL_DEBUG */
+
+       if (!krb5context  &&  (krb5rc = krb5_init_context(&krb5context)))
+                {
+               kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
+                        "krb5_init_context() fails.\n");
+               goto err;
+               }
+       if (krb5auth_context  &&
+               (krb5rc = krb5_auth_con_free(krb5context, krb5auth_context)))
+                {
+               kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
+                        "krb5_auth_con_free() fails.\n");
+               goto err;
+               }
+       else  krb5auth_context = NULL;
+       if (!krb5auth_context  &&
+               (krb5rc = krb5_auth_con_init(krb5context, &krb5auth_context)))
+                {
+               kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
+                        "krb5_auth_con_init() fails.\n");
+               goto err;
+               }
+
+       if ((krb5rc = krb5_sname_to_principal(krb5context, NULL,
+                (kssl_ctx->service_name)? kssl_ctx->service_name: KRB5SVC,
+                KRB5_NT_SRV_HST, &krb5server)) != 0)
+                {
+               kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
+                        "krb5_sname_to_principal() fails.\n");
+               goto err;
+               }
+
+       if (kssl_ctx->keytab_file  &&
+               ((krb5rc = krb5_kt_resolve(krb5context, kssl_ctx->keytab_file,
+                        &krb5keytab))))
+                {
+               kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, "krb5_kt_resolve() fails.\n");
+               goto err;
+               }
+       /*      kssl_ctx->keytab_file == NULL ==> use Kerberos default /etc/krb5.keytab
+       */
+
+       /*      Actual Kerberos5 krb5_recvauth() has initial conversation here
+       **      o       check KRB5_SENDAUTH_BADAUTHVERS unless KRB5_RECVAUTH_SKIP_VERSION
+       **      o       check KRB5_SENDAUTH_BADAPPLVERS
+       **      o       send "0" msg if all OK
+       */
+
+       krb5in_data.data = msg;
+       krb5in_data.length = msglen;
+       if ((krb5rc = krb5_rd_req(krb5context, &krb5auth_context, &krb5in_data,
+                krb5server, krb5keytab, &ap_option, &krb5ticket))
+                != 0)
+                {
+               BIO_snprintf(kssl_err->text, KSSL_ERR_MAX,
+                        "krb5_rd_req() fails with %x.\n", krb5rc);
+               kssl_err->reason = SSL_R_KRB5_S_RD_REQ;
+               goto err;
+               }
+
+       krb5rc = KRB5_NO_TKT_SUPPLIED;
+       if (!krb5ticket  ||     !krb5ticket->enc_part2  ||
+                !krb5ticket->enc_part2->client  ||
+                !krb5ticket->enc_part2->client->data  ||
+                !krb5ticket->enc_part2->session)
+                {
+                kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET,
+                        "bad ticket from krb5_rd_req.\n");
+               }
+       else if (kssl_ctx_setprinc(kssl_ctx, KSSL_CLIENT,
+                &krb5ticket->enc_part2->client->realm,
+                krb5ticket->enc_part2->client->data))
+                {
+               kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET,
+                        "kssl_ctx_setprinc() fails.\n");
+               }
+       else if (kssl_ctx_setkey(kssl_ctx, krb5ticket->enc_part2->session))
+                {
+               kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET,
+                        "kssl_ctx_setkey() fails.\n");
+               }
+       else    krb5rc = 0;
+
+ err:
+#ifdef KSSL_DEBUG
+       kssl_ctx_show(kssl_ctx);
+#endif /* KSSL_DEBUG */
+
+       if (krb5ticket)         krb5_free_ticket(krb5context, krb5ticket);
+       if (krb5server)         krb5_free_principal(krb5context, krb5server);
+       return (krb5rc);
+        }
+
+
+/*     Allocate & return a new kssl_ctx struct.
+*/
+KSSL_CTX       *
+kssl_ctx_new(void)
+        {
+       return ((KSSL_CTX *) calloc(1, sizeof(KSSL_CTX)));
+        }
+
+
+/*     Frees a kssl_ctx struct and any allocated memory it holds.
+**     Returns NULL.
+*/
+KSSL_CTX       *
+kssl_ctx_free(KSSL_CTX *kssl_ctx)
+        {
+       if (kssl_ctx == NULL)  return kssl_ctx;
+
+       if (kssl_ctx->key)              memset(kssl_ctx->key, 0, kssl_ctx->length);
+       if (kssl_ctx->key)              free(kssl_ctx->key);
+       if (kssl_ctx->client_princ)     free(kssl_ctx->client_princ);
+       if (kssl_ctx->service_host)     free(kssl_ctx->service_host);
+       if (kssl_ctx->service_name)     free(kssl_ctx->service_name);
+       if (kssl_ctx->keytab_file)      free(kssl_ctx->keytab_file);
+
+       free(kssl_ctx);
+       return (KSSL_CTX *) NULL;
+        }
+
+
+/*     Given a (krb5_data *) entity (and optional realm),
+**     set the plain (char *) client_princ or service_host member
+**     of the kssl_ctx struct.
+*/
+krb5_error_code
+kssl_ctx_setprinc(KSSL_CTX *kssl_ctx, int which,
+        krb5_data *realm, krb5_data *entity)
+        {
+       char    **princ;
+       int     length;
+
+       if (kssl_ctx == NULL  ||  entity == NULL)  return KSSL_CTX_ERR;
+
+       switch (which)
+                {
+        case KSSL_CLIENT:      princ = &kssl_ctx->client_princ;        break;
+        case KSSL_SERVER:      princ = &kssl_ctx->service_host;        break;
+        default:               return KSSL_CTX_ERR;                    break;
+               }
+       if (*princ)  free(*princ);
+
+       length = entity->length + ((realm)? realm->length + 2: 1);
+       if ((*princ = calloc(1, length)) == NULL)       return KSSL_CTX_ERR;
+       else
+                {
+               strncpy(*princ, entity->data, entity->length);
+               if (realm)
+                        {
+                       strcat (*princ, "@");
+                       (void) strncat(*princ, realm->data, realm->length);
+                       }
+               }
+
+       return KSSL_CTX_OK;
+        }
+
+
+/*     Set one of the plain (char *) string members of the kssl_ctx struct.
+**     Default values should be:
+**             which == KSSL_SERVICE   =>      "kssl" (KRB5SVC)
+**             which == KSSL_KEYTAB    =>      "/etc/krb5.keytab.kssl" (KRB5KEYTAB)
+*/
+krb5_error_code
+kssl_ctx_setstring(KSSL_CTX *kssl_ctx, int which, char *text)
+        {
+       char    **string;
+
+       if (!kssl_ctx)  return KSSL_CTX_ERR;
+
+       switch (which)
+                {
+        case KSSL_SERVICE:     string = &kssl_ctx->service_name;       break;
+        case KSSL_SERVER:      string = &kssl_ctx->service_host;       break;
+        case KSSL_CLIENT:      string = &kssl_ctx->client_princ;       break;
+        case KSSL_KEYTAB:      string = &kssl_ctx->keytab_file;        break;
+        default:               return KSSL_CTX_ERR;                    break;
+               }
+       if (*string)  free(*string);
+
+       if (!text)
+                {
+               *string = '\0';
+               return KSSL_CTX_OK;
+               }
+
+       if ((*string = calloc(1, strlen(text) + 1)) == NULL)  return KSSL_CTX_ERR;
+       else    strcpy(*string, text);
+
+       return KSSL_CTX_OK;
+        }
+
+
+/*     Copy the Kerberos session key from a (krb5_keyblock *) to a kssl_ctx
+**     struct.  Clear kssl_ctx->key if Kerberos session key is NULL.
+*/
+krb5_error_code
+kssl_ctx_setkey(KSSL_CTX *kssl_ctx, krb5_keyblock *session)
+        {
+       if (!kssl_ctx)  return KSSL_CTX_ERR;
+
+       if (kssl_ctx->key)
+                {
+               memset(kssl_ctx->key, 0, kssl_ctx->length);
+               free(kssl_ctx->key);
+               }
+
+       if (session)
+                {
+               kssl_ctx->enctype = session->enctype;
+               kssl_ctx->length  = session->length;
+               }
+       else
+                {
+               kssl_ctx->enctype = ENCTYPE_UNKNOWN;
+               kssl_ctx->length  = 0;
+               return KSSL_CTX_OK;
+               }
+
+       if ((kssl_ctx->key =
+                (krb5_octet FAR *) calloc(1, kssl_ctx->length)) == NULL)
+                {
+               kssl_ctx->length  = 0;
+               return KSSL_CTX_ERR;
+               }
+       else    memcpy(kssl_ctx->key, session->contents, session->length);
+
+       return KSSL_CTX_OK;
+        }
+
+
+/*     Display contents of kssl_ctx struct
+*/
+void
+kssl_ctx_show(KSSL_CTX *kssl_ctx)
+        {
+       int     i;
+
+       printf("kssl_ctx: ");
+       if (kssl_ctx == NULL)
+                {
+               printf("NULL\n");
+               return;
+               }
+       else    printf("%p\n", kssl_ctx);
+
+       printf("\tservice:\t%s\n",
+                (kssl_ctx->service_name)? kssl_ctx->service_name: "NULL");
+       printf("\tclient:\t%s\n",
+                (kssl_ctx->client_princ)? kssl_ctx->client_princ: "NULL");
+       printf("\tserver:\t%s\n",
+                (kssl_ctx->service_host)? kssl_ctx->service_host: "NULL");
+       printf("\tkeytab:\t%s\n",
+                (kssl_ctx->keytab_file)? kssl_ctx->keytab_file: "NULL");
+       printf("\tkey [%d:%d]:\t",
+                kssl_ctx->enctype, kssl_ctx->length);
+
+       for (i=0; i < kssl_ctx->length  &&  kssl_ctx->key; i++)
+                {
+               printf("%02x", kssl_ctx->key[i]);
+               }
+       printf("\n");
+       return;
+        }
+
+#endif /* NO_KRB5      */
+
diff --git a/ssl/kssl.h b/ssl/kssl.h
new file mode 100644 (file)
index 0000000..d10ad77
--- /dev/null
@@ -0,0 +1,151 @@
+/* ssl/kssl.h -*- mode: C; c-file-style: "eay" -*- */
+/* Written by Vern Staats <staatsvr@asc.hpc.mil> for the OpenSSL project 2000.
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/*
+**     19990701        VRS     Started.
+*/
+
+#ifndef        KSSL_H
+#define        KSSL_H
+
+#ifndef NO_KRB5
+
+#include <stdio.h>
+#include <ctype.h>
+#include <krb5.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/*     Uncomment this to debug kssl problems or
+**     to trace usage of the Kerberos session key
+**
+**     #define         KSSL_DEBUG
+*/
+
+#ifndef        KRB5SVC
+#define KRB5SVC        "host"
+#endif
+
+#ifndef        KRB5KEYTAB
+#define KRB5KEYTAB     "/etc/krb5.keytab"
+#endif
+
+
+#define        KSSL_ERR_MAX    255
+typedef struct kssl_err_st  {
+       int  reason;
+       char text[KSSL_ERR_MAX+1];
+       } KSSL_ERR;
+
+
+/*     Context for passing
+**             (1) Kerberos session key to SSL, and
+**             (2)     Config data between application and SSL lib
+*/
+typedef struct kssl_ctx_st
+        {
+                                /*     used by:    disposition:            */
+       char *service_name;     /*      C,S         default ok (kssl)       */
+       char *service_host;     /*      C           input, REQUIRED         */
+       char *client_princ;     /*      S           output from krb5 ticket */
+       char *keytab_file;      /*      S           NULL (/etc/krb5.keytab) */
+       krb5_enctype enctype;
+       int length;
+       krb5_octet FAR *key;
+       } KSSL_CTX;
+
+#define        KSSL_CLIENT     1
+#define KSSL_SERVER    2
+#define        KSSL_SERVICE    3
+#define        KSSL_KEYTAB     4
+
+#define KSSL_CTX_OK    0
+#define KSSL_CTX_ERR   1
+#define KSSL_NOMEM     2
+
+
+void print_krb5_data(char *label, krb5_data *kdata);
+void print_krb5_authdata(char *label, krb5_authdata **adata);
+void print_krb5_keyblock(char *label, krb5_keyblock *keyblk);
+
+char *kstring(char *string);
+char *knumber(int len, krb5_octet *contents);
+
+
+void kssl_err_set(KSSL_ERR *kssl_err, int reason, char *text);
+
+KSSL_CTX *kssl_ctx_new(void);
+KSSL_CTX *kssl_ctx_free(KSSL_CTX *kssl_ctx);
+void kssl_ctx_show(KSSL_CTX *kssl_ctx);
+krb5_error_code kssl_ctx_setkey(KSSL_CTX *kssl_ctx, krb5_keyblock *session);
+krb5_error_code kssl_ctx_setstring(KSSL_CTX *kssl_ctx, int which, char *text);
+krb5_error_code kssl_ctx_setprinc(KSSL_CTX *kssl_ctx, int which,
+        krb5_data *realm, krb5_data *entity);
+
+krb5_error_code        kssl_cget_tkt(KSSL_CTX *kssl_ctx,  krb5_data *ap_req,
+        KSSL_ERR *kssl_err);
+krb5_error_code        kssl_sget_tkt(KSSL_CTX *kssl_ctx,  char *msg, int msglen,
+        KSSL_ERR *kssl_err);
+
+#ifdef  __cplusplus
+}
+#endif
+#endif /* NO_KRB5      */
+#endif /* KSSL_H       */