diff --git a/lib/krb5/crypto.c b/lib/krb5/crypto.c index edbb812c9..45cdd1e69 100644 --- a/lib/krb5/crypto.c +++ b/lib/krb5/crypto.c @@ -3204,6 +3204,108 @@ decrypt_internal_special(krb5_context context, return 0; } +typedef struct krb5_crypto_iov { + unsigned int flags; +#define KRB5_CRYPTO_TYPE_EMPTY 0 /* ignored */ +#define KRB5_CRYPTO_TYPE_SIGNATURE 1 /* OUT krb5_crypto_length_signature */ +#define KRB5_CRYPTO_TYPE_DATA 2 /* IN and OUT */ +#define KRB5_CRYPTO_TYPE_SIGN_ONLY 3 /* IN */ +#define KRB5_CRYPTO_TYPE_PADDING 4 /* OUT krb5_crypto_length_padding */ + krb5_data data; +} krb5_crypto_iov; + +/** + * Inline encrypt a kerberos message + * + * @param context Kerberos context + * @param crypto Kerberos crypto context + * @param usage Key usage for this buffer + * @param data array of buffers to process + * @param num_data length of array + * @param ivec initial cbc/cts vector + * + * @return Return an error code or 0. + * @ingroup krb5_crypto + * + * Kerberos encrypted data look like this: + * + * 1. KRB5_CRYPTO_TYPE_SIGNATURE + * 2. array KRB5_CRYPTO_TYPE_DATA and KRB5_CRYPTO_TYPE_SIGN_ONLY in + * any order, however the receiver have to aware of the + * order. KRB5_CRYPTO_TYPE_SIGN_ONLY is commonly used headers and + * trailers. + * 3. KRB5_CRYPTO_TYPE_PADDING (0 for cfx and rc4, 8 for des types) + */ + +krb5_error_code KRB5_LIB_FUNCTION +krb5_encrypt_iov_ivec(krb5_context context, + krb5_crypto crypto, + unsigned usage, + krb5_crypto_iov **data, + size_t num_data, + void *ivec) +{ + krb5_clear_error_string(context); + return KRB5_CRYPTO_INTERNAL; +} + +krb5_error_code KRB5_LIB_FUNCTION +krb5_crypto_length_signature(krb5_crypto crypto, size_t len) +{ + krb5_clear_error_string(context); + return KRB5_CRYPTO_INTERNAL; +} + +krb5_error_code KRB5_LIB_FUNCTION +krb5_crypto_length_padding(krb5_crypto crypto, size_t len) +{ + krb5_clear_error_string(context); + return KRB5_CRYPTO_INTERNAL; +} + +krb5_error_code KRB5_LIB_FUNCTION +krb5_encrypt_ivec_new(krb5_context context, + krb5_crypto crypto, + unsigned usage, + const void *data, + size_t len, + krb5_data *result, + void *ivec) +{ + krb5_crypto_iov iov[3]; + krb5_error_code ret; + size_t total_len; + + total_len = + krb5_crypto_signature_length(crypto, len) + len + + krb5_crypto_padding_length(crypto, len); + + ret = krb5_data_alloc(result, total_len); + if (ret) { + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); + return ret; + } + + iov[0].flags = KRB5_CRYPTO_TYPE_SIGNATURE; + iov[0].data.length = krb5_crypto_length_signature(crypto, len); + iov[0].data.data = result->data; + + iov[1].flags = KRB5_CRYPTO_TYPE_DATA; + iov[1].data.length = len; + iov[1].data.data = ((char *)result->data) + iov[0].data.length; + memcpy(iov[0].data.data, data); + + iov[2].flags = KRB5_CRYPTO_TYPE_PADDING; + iov[2].data.length = krb5_crypto_length_padding(crypto, len); + iov[2].data.data = ((char *)result->data) + iov[0].data.length + len; + + ret = krb5_encrypt_iov_ivec(context, crypto, usage, + &iov, sizeof(iov)/sizeof(iov[0]), ivec); + if (ret) + krb5_data_free(result); + return ret; +} + krb5_error_code KRB5_LIB_FUNCTION krb5_encrypt_ivec(krb5_context context,