DarwinSSL: allow using NTLM authentication
authorNick Zitzmann <nick@chronosnet.com>
Wed, 27 Jun 2012 09:57:31 +0000 (11:57 +0200)
committerYang Tse <yangsita@gmail.com>
Wed, 27 Jun 2012 09:57:31 +0000 (11:57 +0200)
Allow NTLM authentication when building using SecureTransport (Darwin) for SSL.

This uses CommonCrypto, a cryptography library that ships with all versions of
iOS and Mac OS X. It's like OpenSSL's libcrypto, except that it's missing a few
less-common cyphers and doesn't have a big number data structure.

configure.ac
lib/curl_darwinssl.c
lib/curl_darwinssl.h
lib/curl_ntlm_core.c
lib/setup.h

index 3c792cd..da9f75e 100644 (file)
@@ -3279,7 +3279,8 @@ if test "x$USE_WINDOWS_SSPI" = "x1"; then
 fi
 if test "x$CURL_DISABLE_HTTP" != "x1"; then
   if test "x$USE_SSLEAY" = "x1" -o "x$USE_WINDOWS_SSPI" = "x1" \
-      -o "x$GNUTLS_ENABLED" = "x1" -o "x$NSS_ENABLED" = "x1"; then
+      -o "x$GNUTLS_ENABLED" = "x1" -o "x$NSS_ENABLED" = "x1" \
+      -o "x$DARWINSSL_ENABLED" = "x1"; then
     SUPPORT_FEATURES="$SUPPORT_FEATURES NTLM"
     if test "x$NTLM_WB_ENABLED" = "x1"; then
       SUPPORT_FEATURES="$SUPPORT_FEATURES NTLM_WB"
index 627117d..b98e068 100644 (file)
@@ -21,8 +21,8 @@
  ***************************************************************************/
 
 /*
- * Source file for all SecureTransport-specific code for the TLS/SSL layer.
- * No code but sslgen.c should ever call or use these functions.
+ * Source file for all iOS and Mac OS X SecureTransport-specific code for the
+ * TLS/SSL layer. No code but sslgen.c should ever call or use these functions.
  */
 
 #include "setup.h"
@@ -38,6 +38,7 @@
 #include <Security/Security.h>
 #include <Security/SecureTransport.h>
 #include <CoreFoundation/CoreFoundation.h>
+#include <CommonCrypto/CommonDigest.h>
 #include "urldata.h"
 #include "sendf.h"
 #include "inet_pton.h"
@@ -606,6 +607,23 @@ bool Curl_darwinssl_data_pending(const struct connectdata *conn,
     return false;
 }
 
+void Curl_darwinssl_random(struct SessionHandle *data,
+                           unsigned char *entropy,
+                           size_t length)
+{
+  (void)data;
+  arc4random_buf(entropy, length);
+}
+
+void Curl_darwinssl_md5sum(unsigned char *tmp, /* input */
+                           size_t tmplen,
+                           unsigned char *md5sum, /* output */
+                           size_t md5len)
+{
+  (void)md5len;
+  (void)CC_MD5(tmp, tmplen, md5sum);
+}
+
 static ssize_t darwinssl_send(struct connectdata *conn,
                               int sockindex,
                               const void *mem,
index 6c4f328..53053ed 100644 (file)
@@ -43,6 +43,14 @@ int Curl_darwinssl_check_cxn(struct connectdata *conn);
 bool Curl_darwinssl_data_pending(const struct connectdata *conn,
                                  int connindex);
 
+void Curl_darwinssl_random(struct SessionHandle *data,
+                           unsigned char *entropy,
+                           size_t length);
+void Curl_darwinssl_md5sum(unsigned char *tmp, /* input */
+                           size_t tmplen,
+                           unsigned char *md5sum, /* output */
+                           size_t md5len);
+
 /* API setup for SecureTransport */
 #define curlssl_init() (1)
 #define curlssl_cleanup() Curl_nop_stmt
@@ -58,6 +66,8 @@ bool Curl_darwinssl_data_pending(const struct connectdata *conn,
 #define curlssl_version Curl_darwinssl_version
 #define curlssl_check_cxn Curl_darwinssl_check_cxn
 #define curlssl_data_pending(x,y) Curl_darwinssl_data_pending(x, y)
+#define curlssl_random(x,y,z) Curl_darwinssl_random(x,y,z)
+#define curlssl_md5sum(a,b,c,d) Curl_darwinssl_md5sum(a,b,c,d)
 
 #endif /* USE_DARWINSSL */
 #endif /* HEADER_CURL_DARWINSSL_H */
index 6d1fb80..6b7d9fc 100644 (file)
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
 #  include "curl_md4.h"
 #  define MD5_DIGEST_LENGTH MD5_LENGTH
 
+#elif defined(USE_DARWINSSL)
+
+#  include <CommonCrypto/CommonCryptor.h>
+#  include <CommonCrypto/CommonDigest.h>
+
 #else
 #  error "Can't compile NTLM support without a crypto library."
 #endif
@@ -221,7 +226,23 @@ fail:
   return rv;
 }
 
-#endif /* defined(USE_NSS) */
+#elif defined(USE_DARWINSSL)
+
+static bool encrypt_des(const unsigned char *in, unsigned char *out,
+                        const unsigned char *key_56)
+{
+  char key[8];
+  size_t out_len;
+  CCCryptorStatus err;
+
+  extend_key_56_to_64(key_56, key);
+  err = CCCrypt(kCCEncrypt, kCCAlgorithmDES, kCCOptionECBMode, key,
+                kCCKeySizeDES, NULL, in, 8 /* inbuflen */, out,
+                8 /* outbuflen */, &out_len);
+  return err == kCCSuccess;
+}
+
+#endif /* defined(USE_DARWINSSL) */
 
 #endif /* defined(USE_SSLEAY) */
 
@@ -273,7 +294,7 @@ void Curl_ntlm_core_lm_resp(const unsigned char *keys,
   setup_des_key(keys + 14, &des);
   gcry_cipher_encrypt(des, results + 16, 8, plaintext, 8);
   gcry_cipher_close(des);
-#elif defined(USE_NSS)
+#elif defined(USE_NSS) || defined(USE_DARWINSSL)
   encrypt_des(plaintext, results, keys);
   encrypt_des(plaintext, results + 8, keys + 7);
   encrypt_des(plaintext, results + 16, keys + 14);
@@ -336,7 +357,7 @@ void Curl_ntlm_core_mk_lm_hash(struct SessionHandle *data,
     setup_des_key(pw + 7, &des);
     gcry_cipher_encrypt(des, lmbuffer + 8, 8, magic, 8);
     gcry_cipher_close(des);
-#elif defined(USE_NSS)
+#elif defined(USE_NSS) || defined(USE_DARWINSSL)
     encrypt_des(magic, lmbuffer, pw);
     encrypt_des(magic, lmbuffer + 8, pw + 7);
 #endif
@@ -399,6 +420,8 @@ CURLcode Curl_ntlm_core_mk_nt_hash(struct SessionHandle *data,
     gcry_md_close(MD4pw);
 #elif defined(USE_NSS)
     Curl_md4it(ntbuffer, pw, 2 * len);
+#elif defined(USE_DARWINSSL)
+    (void)CC_MD4(pw, 2 * len, ntbuffer);
 #endif
 
     memset(ntbuffer + 16, 0, 21 - 16);
index a2d0b28..42a0a81 100644 (file)
@@ -593,7 +593,7 @@ int netware_init(void);
 /* Single point where USE_NTLM definition might be done */
 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_NTLM)
 #if defined(USE_SSLEAY) || defined(USE_WINDOWS_SSPI) || \
-   defined(USE_GNUTLS) || defined(USE_NSS)
+    defined(USE_GNUTLS) || defined(USE_NSS) || defined(USE_DARWINSSL)
 #define USE_NTLM
 #endif
 #endif