The struct krb5_context_data field can be passed to plugins
which might not be aware of the new structure layout. To
reduce the risk of data corruption, fields must never be
removed, modified or reordered. Old unused fields are marked
deprecated and new fields are appended to the end of the structure.
This change moves two fields that were added to master which
are not present in Heimdal 7.x:
fe43be8558 added config_include_depth.
5b39bd7c1d added no_ticket_store.
Change-Id: I28b157e128732324972c99b246a93a828bc077c1
Some versions of gcc can't follow the logic in the encryption path
of the _krb5_evp_encrypt_iov_cts code, and believe that it is
possible for the lastpos structure to be used uninitialised.
This isn't actually possible. On entry to the loop, remaining is
guaranteed to be both greater than, and a multiple of blocksize.
In order to exit the loop, remaining must be set to 0. If
cursor.current.length >= remaining, then we set remaining to 0 and
also set lastpos. Otherwise, we calculate the number of whole blocks
in the current iovec, which must be less than remaining, and subtract
that from remaining. Remaining must still be a multiple of and greater
than or equal to blocksize. If remaining == blocksize, we set lastpos,
and set remaining to 0. Otherwise we consume a single block, and go
around again. All of the paths which may set remaining to 0 also
set lastpos, so lastpos must be populated when the loop terminates.
Coverity has a similiar misconception, albeit with ivec2, which is
mistaken for the same reasons.
When we have an underlying iovec encryption function, use iovecs for
checksum-then-encrypt alogrithms in decrypt_iov_ivec, rather than
coalescing iovecs into a single memory buffer.
Add a verify operation for this checksum. If a verify operation isn't
defined, then the verify_checksum code has to dynamically allocate and
free a block of memory for the computed checksum, which can be a
significant overhead when performing bulk data encryption.
Add iovec routines for both padded CBC, and CTS EVP based encryption.
These routines go to great lengths to minimise the number of times
we call EVP_Cipher. With some EVP implementations (such as OpenSSL's
AES-NI) there is a significant entrance and exit overhead from this
routine, due to the use of SIMD vectors for the ivec.
Add a encrypt_iov function pointer to all of our encryption types
which can be used to implement an iovec based encryption routine.
Modify krb5_encrypt_iov so that it calls the iovec based routine
if it is available.
Use the iovec checksum routines in krb5_encrypt_iov_ivec. This
still marshalls all of the iovecs together to perform the encryption
operation, but this change halves the amount of time spent on
data marshalling in this function.
When we decide we need to zero the padding iovec, do so with 0, not
with the length that we've determined.
This had no effect because we zero the padding properly later, but it
should be fixed, so that things still work when the later memset() goes
away.
So that we can eventually use iovec hashes with encrypt, as well
as sign operations, add CRYPTO_TYPE_HEADER and CRYPTO_TYPE_PADDING
to the list of iovecs which will be hashed.
Creating and destroying an EVP_CTX_MD structure with every hash
operation is very expensive. Speed things up by caching one within
the krb5_crypto structure. krb5_crypto can already only be safely
used by one thread at a time - adding a message digest context here
shouldn't introduce any further threading risks.
Users of the stashed context must be careful to ensure that they
call no other hash functions whilst they are in the middle of using
the context.
Instead of flattening the iovecs passed into
krb5_verify_checksum_iov, create a new internal verify_checksum_iov
function which passes iovecs down onto the individual ->verify or
->checksum functions.
_krb5_find_enctype is a moderately expensive operation, as it
does a linear search of the enctype lists. Avoid calling it
in _key_schedule when we already have a key schedule in place.
This change makes the most common check the first in the function.
Rather than flattening the iovecs supplied to
krb5_create_checksum_iov into a malloc()'d memory block, refactor
the function so that they can be passed straight through to the
backend hash functions.
Modify the signature of the checksum operation in the
krb5_checksum_type structure so that it processes iovecs rather than
solid blocks of data.
Update all of the implementations of these functions for all of the
checksum types that we support so that they process iovecs, either
by iterating through the iovec in each function, or by calling
_krb5_evp_digest_iov or _krb5_evp_hmac_iov()
Update callers of these functions so that they turn their single blocks
of data into a single iovec of the correct type before calling checksum
Add a function which will perform an HMAC over a set of iovecs,
using the hcrypto provided HMAC functions.
Join contiguous iovecs together before passing them to the hash
function so we make as few calls into the hash as possible.
depending what's available when you compile for iOS it's possible to
be __APPLE__ and not have CF; actually test for it instead of blythely
assuming it can be used
This allows the optimized checksum->verify() function to be used.
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
(cherry picked from Samba commit fb318ab0203297019c5e47c6bef4a9abfdeea8a5)
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
(cherry picked from Samba commit 05cc099499ef3a07d140981ef82937c842a3ffef)
This reverts commit ccb63bb0aa, which was
unnecessary and broke tests/kdc/check-kadmin (and other things).
host->port happens to be an unsigned short, so that promotion to an integer in
the snprintf() call is safe in that the promoted value will still be
non-negative, and no larger than an unsigned short's maximum value. We're
still assuming that 7 bytes is sufficient to hold the text representation of
that maximum value, which indeed it is, assuming sizeof(unsigned short) == 2
and CHAR_BIT == 8, which are fair assumptions here. A better patch, if we
needed it, would be to just make portstr[] an array of 11 char, or perhaps make
it a VLA (but we can't yet use VLAs, I don't think, because of older Windows
systems that must be supported still).
The default client principal for krb5_set_password, if the
principal argument were NULL, was krb5_get_default_principal. But
krb5_set_password requires credentials for the password change service
be passed in, and those credentials are already associated with a
client principal that's much more likely to be the correct choice for
a default. Use that principal instead of krb5_get_default_principal.
If the hostname was already set, a typo in a test meant we were not
freeing it. While we're at it, handle the unlikely possibility that
the existing pointer is passed as the new value.
In _krb5_extract_ticket() the KDC-REP service name must be obtained from
encrypted version stored in 'enc_part' instead of the unencrypted version
stored in 'ticket'. Use of the unecrypted version provides an
opportunity for successful server impersonation and other attacks.
Identified by Jeffrey Altman, Viktor Duchovni and Nico Williams.
Change-Id: I45ef61e8a46e0f6588d64b5bd572a24c7432547c
Unlike the ccache, we can't lock less because of the way in which keytab
entries are removed: by negating their length. Also unlike ccaches, we
hold locks across the entirety of keytab iteration.
Use stdio. Don't lock to read -- we only ever rename new ccaches into
place, or overwrite endtimes to delete entries, or overwrite part of the
realm name of cc config entries.
Dropping locks around ccache iterator stepping strongly implied that we
don't expect truncation, that we only expect appends (and the
overwriting done to delete entries).
Don't unlock -- let close(2) do it, thus making fewer system calls.
The ASN.1 functions copy_Realm(), copy_PrincipalName() and
copy_EncryptionKey() can fail. Check the return and perform error
handling as appropriate.
Change-Id: I2b3629d19db96eb41d1cd554cef1dca99745e753