]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - cups/hash.c
Fix typos in snprintf/vsnprintf emulation code.
[thirdparty/cups.git] / cups / hash.c
index 1d7b0dbad2c0203227f21b55095545437a5e4ecc..061486076ca405978b33941838f0d0c40e1088f4 100644 (file)
@@ -1,17 +1,10 @@
 /*
- * "$Id$"
- *
  * Hashing function for CUPS.
  *
- * Copyright 2015 by Apple Inc.
- *
- * These coded instructions, statements, and computer programs are the
- * property of Apple Inc. and are protected by Federal copyright
- * law.  Distribution and use rights are outlined in the file "LICENSE.txt"
- * which should have been included with this file.  If this file is
- * file is missing or damaged, see the license at "http://www.cups.org/".
+ * Copyright © 2015-2019 by Apple Inc.
  *
- * This file is subject to the Apple OS-Developed Software exception.
+ * Licensed under Apache License v2.0.  See the file "LICENSE" for more
+ * information.
  */
 
 /*
 #include "cups-private.h"
 #ifdef __APPLE__
 #  include <CommonCrypto/CommonDigest.h>
+#elif defined(HAVE_GNUTLS)
+#  include <gnutls/crypto.h>
+#else
+#  include "md5-internal.h"
 #endif /* __APPLE__ */
 
 
@@ -36,7 +33,7 @@
  *
  * The returned hash is binary data.
  *
- * @since CUPS 2.2@
+ * @since CUPS 2.2/macOS 10.12@
  */
 
 ssize_t                                        /* O - Size of hash or -1 on error */
@@ -53,7 +50,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...
@@ -70,7 +84,7 @@ cupsHashData(const char    *algorithm,        /* I - Algorithm name */
 
     return (CC_SHA1_DIGEST_LENGTH);
   }
-  else if (strcmp(algorithm, "sha2-224"))
+  else if (!strcmp(algorithm, "sha2-224"))
   {
     CC_SHA256_CTX      ctx;            /* SHA-224 context */
 
@@ -83,7 +97,7 @@ cupsHashData(const char    *algorithm,        /* I - Algorithm name */
 
     return (CC_SHA224_DIGEST_LENGTH);
   }
-  else if (strcmp(algorithm, "sha2-256"))
+  else if (!strcmp(algorithm, "sha2-256"))
   {
     CC_SHA256_CTX      ctx;            /* SHA-256 context */
 
@@ -96,7 +110,7 @@ cupsHashData(const char    *algorithm,       /* I - Algorithm name */
 
     return (CC_SHA256_DIGEST_LENGTH);
   }
-  else if (strcmp(algorithm, "sha2-384"))
+  else if (!strcmp(algorithm, "sha2-384"))
   {
     CC_SHA512_CTX      ctx;            /* SHA-384 context */
 
@@ -109,7 +123,7 @@ cupsHashData(const char    *algorithm,      /* I - Algorithm name */
 
     return (CC_SHA384_DIGEST_LENGTH);
   }
-  else if (strcmp(algorithm, "sha2-512"))
+  else if (!strcmp(algorithm, "sha2-512"))
   {
     CC_SHA512_CTX      ctx;            /* SHA-512 context */
 
@@ -122,7 +136,7 @@ cupsHashData(const char    *algorithm,      /* I - Algorithm name */
 
     return (CC_SHA512_DIGEST_LENGTH);
   }
-  else if (strcmp(algorithm, "sha2-512_224"))
+  else if (!strcmp(algorithm, "sha2-512_224"))
   {
     CC_SHA512_CTX      ctx;            /* SHA-512 context */
     unsigned char      temp[CC_SHA512_DIGEST_LENGTH];
@@ -143,7 +157,7 @@ cupsHashData(const char    *algorithm,      /* I - Algorithm name */
 
     return (CC_SHA224_DIGEST_LENGTH);
   }
-  else if (strcmp(algorithm, "sha2-512_256"))
+  else if (!strcmp(algorithm, "sha2-512_256"))
   {
     CC_SHA512_CTX      ctx;            /* SHA-512 context */
     unsigned char      temp[CC_SHA512_DIGEST_LENGTH];
@@ -171,22 +185,24 @@ 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"))
+  else if (!strcmp(algorithm, "sha2-224"))
     alg = GNUTLS_DIG_SHA224;
-  else if (strcmp(algorithm, "sha2-256"))
+  else if (!strcmp(algorithm, "sha2-256"))
     alg = GNUTLS_DIG_SHA256;
-  else if (strcmp(algorithm, "sha2-384"))
+  else if (!strcmp(algorithm, "sha2-384"))
     alg = GNUTLS_DIG_SHA384;
-  else if (strcmp(algorithm, "sha2-512"))
+  else if (!strcmp(algorithm, "sha2-512"))
     alg = GNUTLS_DIG_SHA512;
-  else if (strcmp(algorithm, "sha2-512_224"))
+  else if (!strcmp(algorithm, "sha2-512_224"))
   {
     alg      = GNUTLS_DIG_SHA512;
     tempsize = 28;
   }
-  else if (strcmp(algorithm, "sha2-512_256"))
+  else if (!strcmp(algorithm, "sha2-512_256"))
   {
     alg      = GNUTLS_DIG_SHA512;
     tempsize = 32;
@@ -206,7 +222,7 @@ cupsHashData(const char    *algorithm,      /* I - Algorithm name */
       gnutls_hash_fast(alg, data, datalen, temp);
       memcpy(hash, temp, tempsize);
 
-      return (tempsize);
+      return ((ssize_t)tempsize);
     }
 
     if (hashsize < gnutls_hash_get_len(alg))
@@ -214,15 +230,25 @@ cupsHashData(const char    *algorithm,    /* I - Algorithm name */
 
     gnutls_hash_fast(alg, data, datalen, hash);
 
-    return (gnutls_hash_get_len(alg));
+    return ((ssize_t)gnutls_hash_get_len(alg));
   }
 
 #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__ */
 
@@ -246,5 +272,50 @@ cupsHashData(const char    *algorithm,     /* I - Algorithm name */
 
 
 /*
- * End of "$Id$".
+ * 'cupsHashString()' - Format a hash value as a hexadecimal string.
+ *
+ * The passed buffer must be at least 2 * hashsize + 1 characters in length.
+ *
+ * @since CUPS 2.2.7@
  */
+
+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);
+}