summaryrefslogtreecommitdiff
path: root/cups/hash.c
diff options
context:
space:
mode:
authorMichael R Sweet <michaelrsweet@gmail.com>2017-11-06 16:19:27 -0500
committerMichael R Sweet <michaelrsweet@gmail.com>2017-11-06 16:28:31 -0500
commit7ec11630684301572cb7d19a95c244c104961a2a (patch)
tree75940c5fb6da6293797bae904c7865433ead08e7 /cups/hash.c
parent054eee9cd0555f836ef9ad87f21d6e6ace1d47f1 (diff)
downloadcups-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.c89
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);
+}