Heimdal portability fixes (except for reauth)
[mech_eap.orig] / util_crypt.c
index 00a3cb1..9841c9d 100644 (file)
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
+/*
+ * Message protection services: cryptography helpers.
+ */
+
 #include "gssapiP_eap.h"
 
 /*
  */
 static krb5_error_code
 mapIov(krb5_context context, int dce_style, size_t ec, size_t rrc,
-       krb5_enctype enctype, gss_iov_buffer_desc *iov,
+#ifdef HAVE_HEIMDAL_VERSION
+       krb5_crypto crypto,
+#else
+       krb5_keyblock *crypto,
+#endif
+       gss_iov_buffer_desc *iov,
        int iov_count, krb5_crypto_iov **pkiov,
        size_t *pkiov_count)
 {
@@ -95,7 +104,7 @@ mapIov(krb5_context context, int dce_style, size_t ec, size_t rrc,
     int i = 0, j;
     size_t kiov_count;
     krb5_crypto_iov *kiov;
-    unsigned int k5_headerlen = 0, k5_trailerlen = 0;
+    size_t k5_headerlen = 0, k5_trailerlen = 0;
     size_t gss_headerlen, gss_trailerlen;
     krb5_error_code code;
 
@@ -108,13 +117,11 @@ mapIov(krb5_context context, int dce_style, size_t ec, size_t rrc,
     trailer = gssEapLocateIov(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER);
     assert(trailer == NULL || rrc == 0);
 
-    code = krb5_c_crypto_length(context, enctype, KRB5_CRYPTO_TYPE_HEADER,
-                                &k5_headerlen);
+    code = krbCryptoLength(context, crypto, KRB5_CRYPTO_TYPE_HEADER, &k5_headerlen);
     if (code != 0)
         return code;
 
-    code = krb5_c_crypto_length(context, enctype, KRB5_CRYPTO_TYPE_TRAILER,
-                                &k5_trailerlen);
+    code = krbCryptoLength(context, crypto, KRB5_CRYPTO_TYPE_TRAILER, &k5_trailerlen);
     if (code != 0)
         return code;
 
@@ -194,89 +201,83 @@ mapIov(krb5_context context, int dce_style, size_t ec, size_t rrc,
 }
 
 int
-gssEapEncrypt(krb5_context context, int dce_style, size_t ec,
-              size_t rrc, krb5_keyblock *key, int usage, krb5_pointer iv,
-              gss_iov_buffer_desc *iov, int iov_count)
+gssEapEncrypt(krb5_context context,
+              int dce_style,
+              size_t ec,
+              size_t rrc,
+#ifdef HAVE_HEIMDAL_VERSION
+              krb5_crypto crypto,
+#else
+              krb5_keyblock *crypto,
+#endif
+              int usage,
+              gss_iov_buffer_desc *iov,
+              int iov_count)
 {
     krb5_error_code code;
-    size_t blocksize;
-    krb5_data ivd, *pivd;
     size_t kiov_count;
-    krb5_crypto_iov *kiov;
+    krb5_crypto_iov *kiov = NULL;
 
-    if (iv) {
-        code = krb5_c_block_size(context, KRB_KEYTYPE(key), &blocksize);
-        if (code)
-            return(code);
-
-        ivd.length = blocksize;
-        ivd.data = GSSEAP_MALLOC(ivd.length);
-        if (ivd.data == NULL)
-            return ENOMEM;
-        memcpy(ivd.data, iv, ivd.length);
-        pivd = &ivd;
-    } else {
-        pivd = NULL;
-    }
+    code = mapIov(context, dce_style, ec, rrc, crypto,
+                  iov, iov_count, &kiov, &kiov_count);
+    if (code != 0)
+        goto cleanup;
 
-    code = mapIov(context, dce_style, ec, rrc,
-                  KRB_KEYTYPE(key), iov, iov_count,
-                  &kiov, &kiov_count);
-    if (code == 0) {
-        code = krb5_c_encrypt_iov(context, key, usage, pivd, kiov, kiov_count);
-        GSSEAP_FREE(kiov);
-    }
+#ifdef HAVE_HEIMDAL_VERSION
+    code = krb5_encrypt_iov_ivec(context, crypto, usage, kiov, kiov_count, NULL);
+#else
+    code = krb5_c_encrypt_iov(context, crypto, usage, NULL, kiov, kiov_count);
+#endif
+    if (code != 0)
+        goto cleanup;
 
-    if (pivd != NULL)
-        GSSEAP_FREE(pivd->data);
+cleanup:
+    if (kiov != NULL)
+        GSSEAP_FREE(kiov);
 
     return code;
 }
 
 int
-gssEapDecrypt(krb5_context context, int dce_style, size_t ec,
-              size_t rrc, krb5_keyblock *key, int usage, krb5_pointer iv,
-              gss_iov_buffer_desc *iov, int iov_count)
+gssEapDecrypt(krb5_context context,
+              int dce_style,
+              size_t ec,
+              size_t rrc,
+#ifdef HAVE_HEIMDAL_VERSION
+              krb5_crypto crypto,
+#else
+              krb5_keyblock *crypto,
+#endif
+              int usage,
+              gss_iov_buffer_desc *iov,
+              int iov_count)
 {
     krb5_error_code code;
-    size_t blocksize;
-    krb5_data ivd, *pivd;
     size_t kiov_count;
     krb5_crypto_iov *kiov;
 
-    if (iv) {
-        code = krb5_c_block_size(context, KRB_KEYTYPE(key), &blocksize);
-        if (code)
-            return(code);
-
-        ivd.length = blocksize;
-        ivd.data = GSSEAP_MALLOC(ivd.length);
-        if (ivd.data == NULL)
-            return ENOMEM;
-        memcpy(ivd.data, iv, ivd.length);
-        pivd = &ivd;
-    } else {
-        pivd = NULL;
-    }
+    code = mapIov(context, dce_style, ec, rrc, crypto,
+                  iov, iov_count, &kiov, &kiov_count);
+    if (code != 0)
+        goto cleanup;
 
-    code = mapIov(context, dce_style, ec, rrc,
-                  KRB_KEYTYPE(key), iov, iov_count,
-                  &kiov, &kiov_count);
-    if (code == 0) {
-        code = krb5_c_decrypt_iov(context, key, usage, pivd, kiov, kiov_count);
-        GSSEAP_FREE(kiov);
-    }
+#ifdef HAVE_HEIMDAL_VERSION
+    code = krb5_decrypt_iov_ivec(context, crypto, usage, kiov, kiov_count, NULL);
+#else
+    code = krb5_c_decrypt_iov(context, crypto, usage, NULL, kiov, kiov_count);
+#endif
 
-    if (pivd != NULL)
-        GSSEAP_FREE(pivd->data);
+cleanup:
+    if (kiov != NULL)
+        GSSEAP_FREE(kiov);
 
     return code;
 }
 
-krb5_cryptotype
+int
 gssEapMapCryptoFlag(OM_uint32 type)
 {
-    krb5_cryptotype ktype;
+    int ktype;
 
     switch (GSS_IOV_BUFFER_TYPE(type)) {
     case GSS_IOV_BUFFER_TYPE_DATA:
@@ -316,7 +317,7 @@ gssEapLocateIov(gss_iov_buffer_desc *iov, int iov_count, OM_uint32 type)
 }
 
 void
-gssEapIovMessageLnegth(gss_iov_buffer_desc *iov,
+gssEapIovMessageLength(gss_iov_buffer_desc *iov,
                        int iov_count,
                        size_t *data_length_p,
                        size_t *assoc_data_length_p)
@@ -394,79 +395,3 @@ gssEapAllocIov(gss_iov_buffer_t iov, size_t size)
 
     return 0;
 }
-
-static char
-keyDerivationConstant[] = "rfc4121-gss-eap";
-
-OM_uint32
-gssEapDeriveRFC3961Key(OM_uint32 *minor,
-                       gss_buffer_t msk,
-                       krb5_enctype enctype,
-                       krb5_keyblock *pKey)
-{
-    krb5_context context;
-    krb5_data data, prf;
-    krb5_keyblock kd;
-    krb5_error_code code;
-    size_t keybytes, keylength, prflength;
-
-    memset(pKey, 0, sizeof(*pKey));
-
-    GSSEAP_KRB_INIT(&context);
-
-    kd.contents = NULL;
-    prf.data = NULL;
-    KRB_KEYTYPE(&kd) = enctype;
-
-    code = krb5_c_keylengths(context, enctype, &keybytes, &keylength);
-    if (code != 0)
-        goto cleanup;
-
-    data.length = msk->length;
-    data.data = (char *)msk->value;
-
-    kd.contents = GSSEAP_MALLOC(keylength);
-    if (kd.contents == NULL) {
-        code = ENOMEM;
-        goto cleanup;
-    }
-    kd.length = keylength;
-
-    code = krb5_c_random_to_key(context, enctype, &data, &kd);
-    if (code != 0)
-        goto cleanup;
-
-    data.length = sizeof(keyDerivationConstant) - 1;
-    data.data = keyDerivationConstant;
-
-    code = krb5_c_prf_length(context, enctype, &prflength);
-    if (code != 0)
-        goto cleanup;
-
-    prf.length = prflength;
-    prf.data = GSSEAP_MALLOC(prflength);
-    if (data.data == NULL) {
-        code = ENOMEM;
-        goto cleanup;
-    }
-
-    code = krb5_c_prf(context, &kd, &data, &prf);
-    if (code != 0)
-        goto cleanup;
-
-    code = krb5_c_random_to_key(context, enctype, &prf, &kd);
-    if (code != 0)
-        goto cleanup;
-
-    *pKey = kd;
-
-cleanup:
-    if (code != 0) {
-        GSSEAP_FREE(kd.contents);
-    }
-
-    GSSEAP_FREE(prf.data);
-
-    *minor = code;
-    return (*minor == 0) ? GSS_S_COMPLETE : GSS_S_FAILURE;
-}