include com_err.h for error_message()
[mech_eap.git] / mech_eap / util.h
index dfd2f44..4c1c142 100644 (file)
@@ -142,6 +142,17 @@ bufferEqualString(const gss_buffer_t b1, const char *s)
 }
 
 /* util_cksum.c */
+enum gss_eap_token_type {
+    TOK_TYPE_NONE                    = 0x0000,  /* no token */
+    TOK_TYPE_MIC                     = 0x0404,  /* RFC 4121 MIC token */
+    TOK_TYPE_WRAP                    = 0x0504,  /* RFC 4121 wrap token */
+    TOK_TYPE_EXPORT_NAME             = 0x0401,  /* RFC 2743 exported name */
+    TOK_TYPE_EXPORT_NAME_COMPOSITE   = 0x0402,  /* exported composite name */
+    TOK_TYPE_DELETE_CONTEXT          = 0x0405,  /* RFC 2743 delete context */
+    TOK_TYPE_INITIATOR_CONTEXT       = 0x0601,  /* initiator-sent context token */
+    TOK_TYPE_ACCEPTOR_CONTEXT        = 0x0602,  /* acceptor-sent context token */
+};
+
 int
 gssEapSign(krb5_context context,
            krb5_cksumtype type,
@@ -153,7 +164,8 @@ gssEapSign(krb5_context context,
 #endif
            krb5_keyusage sign_usage,
            gss_iov_buffer_desc *iov,
-           int iov_count);
+           int iov_count,
+           enum gss_eap_token_type toktype);
 
 int
 gssEapVerify(krb5_context context,
@@ -167,6 +179,7 @@ gssEapVerify(krb5_context context,
              krb5_keyusage sign_usage,
              gss_iov_buffer_desc *iov,
              int iov_count,
+             enum gss_eap_token_type toktype,
              int *valid);
 
 #if 0
@@ -179,17 +192,6 @@ gssEapEncodeGssChannelBindings(OM_uint32 *minor,
 /* util_context.c */
 #define EAP_EXPORT_CONTEXT_V1           1
 
-enum gss_eap_token_type {
-    TOK_TYPE_NONE                    = 0x0000,  /* no token */
-    TOK_TYPE_MIC                     = 0x0404,  /* RFC 4121 MIC token */
-    TOK_TYPE_WRAP                    = 0x0504,  /* RFC 4121 wrap token */
-    TOK_TYPE_EXPORT_NAME             = 0x0401,  /* RFC 2743 exported name */
-    TOK_TYPE_EXPORT_NAME_COMPOSITE   = 0x0402,  /* exported composite name */
-    TOK_TYPE_DELETE_CONTEXT          = 0x0405,  /* RFC 2743 delete context */
-    TOK_TYPE_INITIATOR_CONTEXT       = 0x0601,  /* initiator-sent context token */
-    TOK_TYPE_ACCEPTOR_CONTEXT        = 0x0602,  /* acceptor-sent context token */
-};
-
 /* inner token types and flags */
 #define ITOK_TYPE_NONE                  0x00000000
 #define ITOK_TYPE_CONTEXT_ERR           0x00000001 /* critical */
@@ -272,6 +274,12 @@ gssEapSetCredPassword(OM_uint32 *minor,
                       const gss_buffer_t password);
 
 OM_uint32
+gssEapSetCredClientCertificate(OM_uint32 *minor,
+                               gss_cred_id_t cred,
+                               const gss_buffer_t clientCert,
+                               const gss_buffer_t privateKey);
+
+OM_uint32
 gssEapSetCredService(OM_uint32 *minor,
                      gss_cred_id_t cred,
                      const gss_name_t target);
@@ -323,6 +331,11 @@ gssEapLocateIov(gss_iov_buffer_desc *iov,
                 int iov_count,
                 OM_uint32 type);
 
+gss_iov_buffer_t
+gssEapLocateHeaderIov(gss_iov_buffer_desc *iov,
+                      int iov_count,
+                      enum gss_eap_token_type toktype);
+
 void
 gssEapIovMessageLength(gss_iov_buffer_desc *iov,
                        int iov_count,
@@ -403,6 +416,8 @@ gssEapDeriveRfc3961Key(OM_uint32 *minor,
 #define KRB_PRINC_TYPE(princ)   (krb5_princ_type(NULL, (princ)))
 #define KRB_PRINC_NAME(princ)   (krb5_princ_name(NULL, (princ)))
 #define KRB_PRINC_REALM(princ)  (krb5_princ_realm(NULL, (princ)))
+#define KRB_PRINC_COMPONENT(princ, component) \
+        (krb5_princ_component(NULL, (princ), (component)))
 
 #define KRB_KT_ENT_KEYBLOCK(e)  (&(e)->key)
 #define KRB_KT_ENT_FREE(c, e)   krb5_free_keytab_entry_contents((c), (e))
@@ -799,13 +814,20 @@ verifyTokenHeader(OM_uint32 *minor,
                   enum gss_eap_token_type *ret_tok_type);
 
 /* Helper macros */
-
 #ifndef GSSEAP_MALLOC
+#if _WIN32
+#include <gssapi/gssapi_alloc.h>
+#define GSSEAP_MALLOC                   gssalloc_malloc
+#define GSSEAP_CALLOC                   gssalloc_calloc
+#define GSSEAP_FREE                     gssalloc_free
+#define GSSEAP_REALLOC                  gssalloc_realloc
+#else
 #define GSSEAP_CALLOC                   calloc
 #define GSSEAP_MALLOC                   malloc
 #define GSSEAP_FREE                     free
 #define GSSEAP_REALLOC                  realloc
-#endif
+#endif /* _WIN32 */
+#endif /* !GSSEAP_MALLOC */
 
 #ifndef GSSAPI_CALLCONV
 #define GSSAPI_CALLCONV                 KRB5_CALLCONV
@@ -997,13 +1019,58 @@ static inline void
 krbPrincComponentToGssBuffer(krb5_principal krbPrinc,
                              int index, gss_buffer_t buffer)
 {
+    if (KRB_PRINC_LENGTH(krbPrinc) <= index) {
+        buffer->value = NULL;
+        buffer->length = 0;
+    } else {
 #ifdef HAVE_HEIMDAL_VERSION
-    buffer->value = (void *)KRB_PRINC_NAME(krbPrinc)[index];
-    buffer->length = strlen((char *)buffer->value);
+        buffer->value = (void *)KRB_PRINC_NAME(krbPrinc)[index];
+        buffer->length = strlen((char *)buffer->value);
 #else
-    buffer->value = (void *)krb5_princ_component(NULL, krbPrinc, index)->data;
-    buffer->length = krb5_princ_component(NULL, krbPrinc, index)->length;
+        buffer->value = (void *)krb5_princ_component(NULL, krbPrinc, index)->data;
+        buffer->length = krb5_princ_component(NULL, krbPrinc, index)->length;
 #endif /* HAVE_HEIMDAL_VERSION */
+    }
+}
+
+static inline krb5_error_code
+krbPrincUnparseServiceSpecifics(krb5_context krbContext, krb5_principal krbPrinc,
+                                gss_buffer_t nameBuf)
+{
+    krb5_error_code result = 0;
+    if (KRB_PRINC_LENGTH(krbPrinc) > 2) {
+        /* Acceptor-Service-Specific */
+        krb5_principal_data ssiPrinc = *krbPrinc;
+        char *ssi;
+
+        KRB_PRINC_LENGTH(&ssiPrinc) -= 2;
+        KRB_PRINC_NAME(&ssiPrinc) += 2;
+
+        result = krb5_unparse_name_flags(krbContext, &ssiPrinc,
+                                         KRB5_PRINCIPAL_UNPARSE_NO_REALM, &ssi);
+        if (result != 0)
+            return result;
+
+        nameBuf->value = ssi;
+        nameBuf->length = strlen(ssi);
+    } else {
+        nameBuf->value = NULL;
+        nameBuf->length = 0;
+    }
+
+    return result;
+}
+
+static inline void
+krbFreeUnparsedName(krb5_context krbContext, gss_buffer_t nameBuf)
+{
+#ifdef HAVE_HEIMDAL_VERSION
+    krb5_xfree((char *) nameBuf->value);
+#else
+    krb5_free_unparsed_name(krbContext, (char *)(nameBuf->value));
+#endif
+    nameBuf->value = NULL;
+    nameBuf->length = 0;
 }
 
 static inline void