adium 5304:ed9b7110d6f5: Using a function from Apple sample code...

commits at adium.im commits at adium.im
Sun Feb 10 05:54:03 UTC 2013


details:	http://hg.adium.im/adium/rev/ed9b7110d6f5
revision:	5304:ed9b7110d6f5
branch:		(none)
author:		Evan Schoenberg
date:		Sat Feb 09 23:53:56 2013 -0600

Using a function from Apple sample code, only enable cdsa ciphers that are supported on the local system

diffs (256 lines):

diff -r 960732c325a6 -r ed9b7110d6f5 Plugins/Purple Service/libpurple_extensions/ssl-cdsa.c
--- a/Plugins/Purple Service/libpurple_extensions/ssl-cdsa.c	Tue Feb 05 09:07:46 2013 -0600
+++ b/Plugins/Purple Service/libpurple_extensions/ssl-cdsa.c	Sat Feb 09 23:53:56 2013 -0600
@@ -50,6 +50,8 @@
 
 #define PURPLE_SSL_CDSA_BUGGY_TLS_WORKAROUND "ssl_cdsa_buggy_tls_workaround"
 
+static OSStatus ssl_cdsa_set_enabled_ciphers(SSLContextRef ctx, const SSLCipherSuite *ciphers);
+
 /*
  * query_cert_chain - callback for letting the user review the certificate before accepting it
  *
@@ -361,7 +363,7 @@
     /*
      * Disable ciphers that confuse some servers
      */
-    SSLCipherSuite ciphers[27] = {
+    SSLCipherSuite ciphers[28] = {
         TLS_RSA_WITH_AES_128_CBC_SHA,
         SSL_RSA_WITH_RC4_128_SHA,
         SSL_RSA_WITH_RC4_128_MD5,
@@ -389,8 +391,10 @@
         SSL_DH_anon_EXPORT_WITH_RC4_40_MD5,
         SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA,
         SSL_RSA_WITH_NULL_MD5,
+        SSL_NO_SUCH_CIPHERSUITE
     };
-    err = (OSStatus)SSLSetEnabledCiphers(cdsa_data->ssl_ctx, ciphers, sizeof(ciphers) / sizeof(SSLCipherSuite));
+    
+    err = ssl_cdsa_set_enabled_ciphers(cdsa_data->ssl_ctx, ciphers);
     if (err != noErr) {
         purple_debug_error("cdsa", "SSLSetEnabledCiphers failed\n");
         if (gsc->error_cb != NULL)
@@ -687,3 +691,222 @@
 }
 
 PURPLE_INIT_PLUGIN(ssl_cdsa, init_plugin, info)
+
+
+#pragma mark -
+
+/*
+ Method: ssl_cdsa_set_enabled_ciphers
+ Source: SSLExample/sslViewer.cpp
+ Contains:   SSL viewer tool, SecureTransport / OS X version.
+ 
+ Copyright:  © Copyright 2002 Apple Computer, Inc. All rights reserved.
+ 
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple Computer, Inc.
+ ("Apple") in consideration of your agreement to the following terms, and your
+ use, installation, modification or redistribution of this Apple software
+ constitutes acceptance of these terms.  If you do not agree with these terms,
+ please do not use, install, modify or redistribute this Apple software.
+ 
+ In consideration of your agreement to abide by the following terms, and subject
+ to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
+ copyrights in this original Apple software (the "Apple Software"), to use,
+ reproduce, modify and redistribute the Apple Software, with or without
+ modifications, in source and/or binary forms; provided that if you redistribute
+ the Apple Software in its entirety and without modifications, you must retain
+ this notice and the following text and disclaimers in all such redistributions of
+ the Apple Software.  Neither the name, trademarks, service marks or logos of
+ Apple Computer, Inc. may be used to endorse or promote products derived from the
+ Apple Software without specific prior written permission from Apple.  Except as
+ expressly stated in this notice, no other rights or licenses, express or implied,
+ are granted by Apple herein, including but not limited to any patent rights that
+ may be infringed by your derivative works or by other works in which the Apple
+ Software may be incorporated.
+ 
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE MAKES NO
+ WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+ WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+ COMBINATION WITH YOUR PRODUCTS.
+ 
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
+ OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
+ (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Return string representation of SecureTransport-related OSStatus.
+ */
+static const char *ssl_cdsa_sslGetSSLErrString(OSStatus err)
+{
+	static char noErrStr[20];
+    
+	switch(err) {
+		case noErr:                         return "noErr";
+            /*
+		case memFullErr:                    return "memFullErr";
+		case paramErr:                      return "paramErr";
+		case unimpErr:                      return "unimpErr";
+		case ioErr:                         return "ioErr";
+		case badReqErr:                     return "badReqErr";
+             */
+            /* SSL errors */
+		case errSSLProtocol:                return "errSSLProtocol";
+		case errSSLNegotiation:             return "errSSLNegotiation";
+		case errSSLFatalAlert:              return "errSSLFatalAlert";
+		case errSSLWouldBlock:              return "errSSLWouldBlock";
+		case errSSLSessionNotFound:         return "errSSLSessionNotFound";
+		case errSSLClosedGraceful:          return "errSSLClosedGraceful";
+		case errSSLClosedAbort:             return "errSSLClosedAbort";
+		case errSSLXCertChainInvalid:       return "errSSLXCertChainInvalid";
+		case errSSLBadCert:                 return "errSSLBadCert";
+		case errSSLCrypto:                  return "errSSLCrypto";
+		case errSSLInternal:                return "errSSLInternal";
+		case errSSLModuleAttach:            return "errSSLModuleAttach";
+		case errSSLUnknownRootCert:         return "errSSLUnknownRootCert";
+		case errSSLNoRootCert:              return "errSSLNoRootCert";
+		case errSSLCertExpired:             return "errSSLCertExpired";
+		case errSSLCertNotYetValid:         return "errSSLCertNotYetValid";
+		case errSSLClosedNoNotify:          return "errSSLClosedNoNotify";
+		case errSSLBufferOverflow:          return "errSSLBufferOverflow";
+		case errSSLBadCipherSuite:          return "errSSLBadCipherSuite";
+            /* TLS/Panther addenda */
+		case errSSLPeerUnexpectedMsg:       return "errSSLPeerUnexpectedMsg";
+		case errSSLPeerBadRecordMac:        return "errSSLPeerBadRecordMac";
+		case errSSLPeerDecryptionFail:      return "errSSLPeerDecryptionFail";
+		case errSSLPeerRecordOverflow:      return "errSSLPeerRecordOverflow";
+		case errSSLPeerDecompressFail:      return "errSSLPeerDecompressFail";
+		case errSSLPeerHandshakeFail:       return "errSSLPeerHandshakeFail";
+		case errSSLPeerBadCert:             return "errSSLPeerBadCert";
+		case errSSLPeerUnsupportedCert:     return "errSSLPeerUnsupportedCert";
+		case errSSLPeerCertRevoked:         return "errSSLPeerCertRevoked";
+		case errSSLPeerCertExpired:         return "errSSLPeerCertExpired";
+		case errSSLPeerCertUnknown:         return "errSSLPeerCertUnknown";
+		case errSSLIllegalParam:            return "errSSLIllegalParam";
+		case errSSLPeerUnknownCA:           return "errSSLPeerUnknownCA";
+		case errSSLPeerAccessDenied:        return "errSSLPeerAccessDenied";
+		case errSSLPeerDecodeError:         return "errSSLPeerDecodeError";
+		case errSSLPeerDecryptError:        return "errSSLPeerDecryptError";
+		case errSSLPeerExportRestriction:   return "errSSLPeerExportRestriction";
+		case errSSLPeerProtocolVersion:     return "errSSLPeerProtocolVersion";
+		case errSSLPeerInsufficientSecurity:return "errSSLPeerInsufficientSecurity";
+		case errSSLPeerInternalError:       return "errSSLPeerInternalError";
+		case errSSLPeerUserCancelled:       return "errSSLPeerUserCancelled";
+		case errSSLPeerNoRenegotiation:     return "errSSLPeerNoRenegotiation";
+		case errSSLHostNameMismatch:        return "errSSLHostNameMismatch";
+		case errSSLConnectionRefused:       return "errSSLConnectionRefused";
+		case errSSLDecryptionFail:          return "errSSLDecryptionFail";
+		case errSSLBadRecordMac:            return "errSSLBadRecordMac";
+		case errSSLRecordOverflow:          return "errSSLRecordOverflow";
+		case errSSLBadConfiguration:        return "errSSLBadConfiguration";
+            
+            /* some from the Sec layer */
+		case errSecNotAvailable:            return "errSecNotAvailable";
+		case errSecDuplicateItem:           return "errSecDuplicateItem";
+		case errSecItemNotFound:            return "errSecItemNotFound";
+#if TARGET_OS_MAC
+		case errSecReadOnly:                return "errSecReadOnly";
+		case errSecAuthFailed:              return "errSecAuthFailed";
+		case errSecNoSuchKeychain:          return "errSecNoSuchKeychain";
+		case errSecInvalidKeychain:         return "errSecInvalidKeychain";
+		case errSecNoSuchAttr:              return "errSecNoSuchAttr";
+		case errSecInvalidItemRef:          return "errSecInvalidItemRef";
+		case errSecInvalidSearchRef:        return "errSecInvalidSearchRef";
+		case errSecNoSuchClass:             return "errSecNoSuchClass";
+		case errSecNoDefaultKeychain:       return "errSecNoDefaultKeychain";
+		case errSecWrongSecVersion:         return "errSecWrongSecVersion";
+		case errSecInvalidTrustSettings:    return "errSecInvalidTrustSettings";
+		case errSecNoTrustSettings:         return "errSecNoTrustSettings";
+#endif
+		default:
+#if 0
+			if (err < (CSSM_BASE_ERROR +
+                       (CSSM_ERRORCODE_MODULE_EXTENT * 8)))
+			{
+				/* assume CSSM error */
+				return cssmErrToStr(err);
+			}
+			else
+#endif
+			{
+				sprintf(noErrStr, "Unknown (%d)", (unsigned)err);
+				return noErrStr;
+			}
+	}
+}
+
+static void ssl_cdsa_printSslErrStr(
+                    const char 	*op,
+                    OSStatus 	err)
+{
+	purple_debug_error("cdsa", "%s: %s\n", op, ssl_cdsa_sslGetSSLErrString(err));
+}
+
+/*
+ * Given an SSLContextRef and an array of SSLCipherSuites, terminated by
+ * SSL_NO_SUCH_CIPHERSUITE, select those SSLCipherSuites which the library
+ * supports and do a SSLSetEnabledCiphers() specifying those.
+ */
+static OSStatus ssl_cdsa_set_enabled_ciphers(SSLContextRef ctx, const SSLCipherSuite *ciphers)
+{
+    size_t numSupported;
+    OSStatus ortn;
+    SSLCipherSuite *supported = NULL;
+    SSLCipherSuite *enabled = NULL;
+    unsigned enabledDex = 0;    // index into enabled
+    unsigned supportedDex = 0;  // index into supported
+    unsigned inDex = 0;         // index into ciphers
+    
+    /* first get all the supported ciphers */
+    ortn = SSLGetNumberSupportedCiphers(ctx, &numSupported);
+    if(ortn != noErr) {
+        ssl_cdsa_printSslErrStr("SSLGetNumberSupportedCiphers", ortn);
+        return ortn;
+    }
+    supported = (SSLCipherSuite *)malloc(numSupported * sizeof(SSLCipherSuite));
+    ortn = SSLGetSupportedCiphers(ctx, supported, &numSupported);
+    if(ortn != noErr) {
+        ssl_cdsa_printSslErrStr("SSLGetSupportedCiphers", ortn);
+        return ortn;
+    }
+    
+    /*
+     * Malloc an array we'll use for SSLGetEnabledCiphers - this will  be
+     * bigger than the number of suites we actually specify
+     */
+    enabled = (SSLCipherSuite *)malloc(numSupported * sizeof(SSLCipherSuite));
+    
+    /*
+     * For each valid suite in ciphers, see if it's in the list of
+     * supported ciphers. If it is, add it to the list of ciphers to be
+     * enabled.
+     */
+    for(inDex=0; ciphers[inDex] != SSL_NO_SUCH_CIPHERSUITE; inDex++) {
+        bool isSupported = false;
+        
+        for(supportedDex=0; supportedDex<numSupported; supportedDex++) {
+            if(ciphers[inDex] == supported[supportedDex]) {
+                enabled[enabledDex++] = ciphers[inDex];
+                isSupported = true;
+                break;
+            }
+        }
+
+        if (!isSupported)
+            purple_debug_info("cdsa", "cipher %i not supported; disabled.", ciphers[inDex]);
+    }
+    
+    /* send it on down. */
+    ortn = SSLSetEnabledCiphers(ctx, enabled, enabledDex);
+    if(ortn != noErr) {
+        ssl_cdsa_printSslErrStr("SSLSetEnabledCiphers", ortn);
+    }
+    free(enabled);
+    free(supported);
+    return ortn;
+}
+




More information about the commits mailing list