diff options
author | Michael R Sweet <michaelrsweet@gmail.com> | 2017-11-06 16:19:27 -0500 |
---|---|---|
committer | Michael R Sweet <michaelrsweet@gmail.com> | 2017-11-06 16:28:31 -0500 |
commit | 7ec11630684301572cb7d19a95c244c104961a2a (patch) | |
tree | 75940c5fb6da6293797bae904c7865433ead08e7 /cups/hash.c | |
parent | 054eee9cd0555f836ef9ad87f21d6e6ace1d47f1 (diff) | |
download | cups-7ec11630684301572cb7d19a95c244c104961a2a.tar.gz |
Support the latest HTTP Digest authentication specification (Issue #4862)
Also deprecates all httpMD5* functions.
- cgi-bin/var.c: Use cupsHashData to compute SID hash.
- cups/auth.c: Rewrite WWW-Authenticate parser to support multiple auth schemes
and the new RFC 7616 version of HTTP Digest.
- cups/cups.h: Add cupsHashString function to get a hex version of a hash.
- cups/hash.c: Add MD5 support.
- cups/http.c: Track WWW-Authenticate in a long string, concatenate new set
values.
- cups/http.h: Deprecate httpMD5* and recommend cupsDoAuth and cupsHash*.
- cups/http-private.h: Pull MD5 stuff, nonce_count is unsigned, track
WWW-Authenticate header as a potentially long string.
- cups/http-support.c: Use cupsHashData to compute UUID hash.
- cups/md5.c: Comment everything out if we have an OS-supplied MD5 hash
function.
- cups/md5passwd.c: Use cupsHash* functions.
- cups/tls-*.c: Use cupsHash* functions.
- cups/versioning.h: Add CUPS_API_2_3 definition.
- scheduler/client.c: Update WWW-Authenticate header to include AuthRef,
Local, and PeerCred schemes with parameters as needed.
Diffstat (limited to 'cups/hash.c')
-rw-r--r-- | cups/hash.c | 89 |
1 files changed, 84 insertions, 5 deletions
diff --git a/cups/hash.c b/cups/hash.c index ede546167..aa6aca310 100644 --- a/cups/hash.c +++ b/cups/hash.c @@ -1,7 +1,7 @@ /* * Hashing function for CUPS. * - * Copyright 2015-2016 by Apple Inc. + * Copyright 2015-2017 by Apple Inc. * * These coded instructions, statements, and computer programs are the * property of Apple Inc. and are protected by Federal copyright @@ -21,6 +21,8 @@ # include <CommonCrypto/CommonDigest.h> #elif defined(HAVE_GNUTLS) # include <gnutls/crypto.h> +#else +# include "md5-private.h" #endif /* __APPLE__ */ @@ -53,7 +55,24 @@ cupsHashData(const char *algorithm, /* I - Algorithm name */ } #ifdef __APPLE__ - if (!strcmp(algorithm, "sha")) + if (!strcmp(algorithm, "md5")) + { + /* + * MD5 (deprecated but widely used...) + */ + + CC_MD5_CTX ctx; /* MD5 context */ + + if (hashsize < CC_MD5_DIGEST_LENGTH) + goto too_small; + + CC_MD5_Init(&ctx); + CC_MD5_Update(&ctx, data, (CC_LONG)datalen); + CC_MD5_Final(hash, &ctx); + + return (CC_MD5_DIGEST_LENGTH); + } + else if (!strcmp(algorithm, "sha")) { /* * SHA-1... @@ -171,7 +190,9 @@ cupsHashData(const char *algorithm, /* I - Algorithm name */ unsigned char temp[64]; /* Temporary hash buffer */ size_t tempsize = 0; /* Truncate to this size? */ - if (!strcmp(algorithm, "sha")) + if (!strcmp(algorithm, "md5")) + alg = GNUTLS_DIG_MD5; + else if (!strcmp(algorithm, "sha")) alg = GNUTLS_DIG_SHA1; else if (!strcmp(algorithm, "sha2-224")) alg = GNUTLS_DIG_SHA224; @@ -219,10 +240,20 @@ cupsHashData(const char *algorithm, /* I - Algorithm name */ #else /* - * No hash support without CommonCrypto or GNU TLS... + * No hash support beyond MD5 without CommonCrypto or GNU TLS... */ - if (hashsize < 64) + if (!strcmp(algorithm, "md5")) + { + _cups_md5_state_t state; /* MD5 state info */ + + _cupsMD5Init(&state); + _cupsMD5Append(&state, data, datalen); + _cupsMD5Finish(&state, hash); + + return (16); + } + else if (hashsize < 64) goto too_small; #endif /* __APPLE__ */ @@ -243,3 +274,51 @@ cupsHashData(const char *algorithm, /* I - Algorithm name */ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Hash buffer too small."), 1); return (-1); } + + +/* + * 'cupsHashString()' - Format a hash value as a hexadecimal string. + * + * The passed buffer must be at least 2 * hashsize + 1 characters in length. + */ + +const char * /* O - Formatted string */ +cupsHashString( + const unsigned char *hash, /* I - Hash */ + size_t hashsize, /* I - Size of hash */ + char *buffer, /* I - String buffer */ + size_t bufsize) /* I - Size of string buffer */ +{ + char *bufptr = buffer; /* Pointer into buffer */ + static const char *hex = "0123456789abcdef"; + /* Hex characters (lowercase!) */ + + + /* + * Range check input... + */ + + if (!hash || hashsize < 1 || !buffer || bufsize < (2 * hashsize + 1)) + { + if (buffer) + *buffer = '\0'; + return (NULL); + } + + /* + * Loop until we've converted the whole hash... + */ + + while (hashsize > 0) + { + *bufptr++ = hex[*hash >> 4]; + *bufptr++ = hex[*hash & 15]; + + hash ++; + hashsize --; + } + + *bufptr = '\0'; + + return (buffer); +} |