[Vm-dev] [commit][3417] Integrate Marcel Taeumel & Tobias Pape'
s v2 SSL plugin changes.
commits at squeakvm.org
commits at squeakvm.org
Thu Jul 30 01:55:26 UTC 2015
Revision: 3417
Author: eliot
Date: 2015-07-29 18:55:26 -0700 (Wed, 29 Jul 2015)
Log Message:
-----------
Integrate Marcel Taeumel & Tobias Pape's v2 SSL plugin changes.
Modified Paths:
--------------
branches/Cog/platforms/Mac OS/plugins/SqueakSSL/sqMacSSL.c
branches/Cog/platforms/unix/plugins/SqueakSSL/sqUnixOpenSSL.c
Added Paths:
-----------
branches/Cog/platforms/Mac OS/plugins/SqueakSSL/Info.plist
branches/Cog/platforms/unix/plugins/SqueakSSL/config.cmake
Property Changed:
----------------
branches/Cog/platforms/Cross/vm/sqSCCSVersion.h
Property changes on: branches/Cog/platforms/Cross/vm/sqSCCSVersion.h
___________________________________________________________________
Modified: checkindate
- Mon Jul 20 23:17:35 PDT 2015
+ Wed Jul 29 18:55:18 PDT 2015
Added: branches/Cog/platforms/Mac OS/plugins/SqueakSSL/Info.plist
===================================================================
--- branches/Cog/platforms/Mac OS/plugins/SqueakSSL/Info.plist (rev 0)
+++ branches/Cog/platforms/Mac OS/plugins/SqueakSSL/Info.plist 2015-07-30 01:55:26 UTC (rev 3417)
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>SqueakSSL</string>
+ <key>CFBundleIconFile</key>
+ <string></string>
+ <key>CFBundleIdentifier</key>
+ <string>org.squeak.SqueakSSL</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>BNDL</string>
+ <key>CFBundleSignature</key>
+ <string>FAST</string>
+ <key>CFBundleVersion</key>
+ <string>1.0</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CSResourcesFileMapped</key>
+ <true/>
+</dict>
+</plist>
Modified: branches/Cog/platforms/Mac OS/plugins/SqueakSSL/sqMacSSL.c
===================================================================
--- branches/Cog/platforms/Mac OS/plugins/SqueakSSL/sqMacSSL.c 2015-07-30 01:51:21 UTC (rev 3416)
+++ branches/Cog/platforms/Mac OS/plugins/SqueakSSL/sqMacSSL.c 2015-07-30 01:55:26 UTC (rev 3417)
@@ -1,479 +1,683 @@
-/* sqMacSSL.c: SqueakSSL implementation based on Mac OSX Security Services */
+/****************************************************************************
+ * PROJECT: SqueakSSL implementation for Mac OS X
+ * FILE: sqMac2SSL.c
+ * CONTENT: SSL platform functions
+ *
+ * AUTHORS: Andreas Raab (ar)
+ *
+ * Tobias Pape (topa)
+ * Hasso Plattner Institute, Postdam, Germany
+ *****************************************************************************/
#include "sq.h"
#include "SqueakSSL.h"
+#include <string.h>
+#include <stdarg.h>
-#include <Security/Security.h>
-#include <Security/SecCertificate.h>
+#import <Security/Security.h>
typedef struct sqSSL {
- int state;
- int certFlags;
- int loglevel;
+ int state;
+ int certFlags;
+ int loglevel;
- char *certName;
- char *peerName;
+ char* certName;
+ char* peerName;
+ char* serverName;
-
- SSLContextRef ctx;
- CFArrayRef certs;
+ SSLContextRef ctx;
+ CFArrayRef certs;
- /* internal data buffer */
- char *dataBuf;
- int dataLen;
- int dataMax;
-
- /* external data buffer */
- char *outBuf;
- int outLen;
- int outMax;
+ /* internal data buffer */
+ char* dataBuf;
+ int dataLen;
+ int dataMax;
+
+ /* external data buffer */
+ char* outBuf;
+ int outLen;
+ int outMax;
} sqSSL;
-static sqSSL **handleBuf = NULL;
+/********************************************************************/
+#pragma mark Global State
+/********************************************************************/
+
+static sqSSL** handleBuf = NULL;
static sqInt handleMax = 0;
+// Max lengh of a Certificate common name or DNS Host name
+#define CN_MAX 255
+
/********************************************************************/
+#pragma mark Forward Declarations
/********************************************************************/
+
+static int printf_status(OSStatus status, const char* restrict format, ...);
+static OSStatus sqExtractPeerName(sqSSL* ssl);
+static sqSSL* sqSSLFromHandle(sqInt handle);
+OSStatus sqSetupSSL(sqSSL* ssl, int isServer);
+
+OSStatus SqueakSSLRead(SSLConnectionRef connection, void* data,
+ size_t* dataLength);
+
+OSStatus SqueakSSLWrite(SSLConnectionRef connection, const void* data,
+ size_t* dataLength);
+
+
/********************************************************************/
+#pragma mark -
+#pragma mark Internal Helper
+/********************************************************************/
-/* SqueakSSLRead: Custom read function for Secure Transport */
-OSStatus SqueakSSLRead(SSLConnectionRef connection, void *data,
- size_t *dataLength) {
- sqSSL *ssl = (sqSSL*) connection;
- size_t sz = *dataLength;
+static int printf_status(OSStatus status, const char* restrict format, ...)
+{
+ int ret = 0;
+ va_list args;
+ va_start(args, format);
+ CFErrorRef _e = CFErrorCreate(NULL, kCFErrorDomainOSStatus, status, NULL);
+ CFStringRef _sdesc = CFErrorCopyDescription(_e);
+ CFStringRef _sreas = CFErrorCopyFailureReason(_e);
+ CFStringRef _sreco = CFErrorCopyRecoverySuggestion(_e);
+ ret += vprintf(format, args);
+ ret += printf("Status (%d): %s (%s): %s\n",
+ (int)status,
+ CFStringGetCStringPtr(_sdesc, kCFStringEncodingUTF8),
+ CFStringGetCStringPtr(_sreas, kCFStringEncodingUTF8),
+ CFStringGetCStringPtr(_sreco, kCFStringEncodingUTF8));
+ CFRelease(_sreco);
+ CFRelease(_sreas);
+ CFRelease(_sdesc);
+ CFRelease(_e);
+ va_end(args);
+ return ret;
+}
- if(ssl->loglevel)
- printf("SqueakSSLRead: Requesting %d bytes, having %d bytes\n",
- (int)sz, ssl->dataLen);
- if(ssl->dataLen < sz) sz = ssl->dataLen;
- memcpy(data, ssl->dataBuf, sz);
- /* Did we have enough data? */
- if(sz == *dataLength) {
- /* Adjust read buffer */
- memmove(ssl->dataBuf, ssl->dataBuf+sz, ssl->dataLen - sz);
- ssl->dataLen -= sz;
- *dataLength = sz;
- return noErr;
- }
- ssl->dataLen = 0;
- *dataLength = sz;
- return errSSLWouldBlock;
+/* By convention, the sqSSL object is named ssl and has its logLevel >= 0 */
+#define logprintf if (ssl->loglevel) printf
+#define logprintf_status if (ssl->loglevel) printf_status
+
+/* sqSSLFromHandle: Maps a handle to an SSL */
+static sqSSL* sqSSLFromHandle(sqInt handle)
+{
+ return handle < handleMax ? handleBuf[handle] : NULL;
}
-/* SqueakSSLRead: Custom write function for Secure Transport */
-OSStatus SqueakSSLWrite(SSLConnectionRef connection, const void *data,
- size_t *dataLength) {
- sqSSL *ssl = (sqSSL*) connection;
- size_t sz = ssl->outMax - ssl->outLen;
-
- if(ssl->loglevel)
- printf("SqueakSSLWrite: Writing %d bytes, having %d free\n",
- (int)*dataLength, (int)sz);
- if(sz == 0) {
- *dataLength = 0;
- return errSSLWouldBlock;
- }
- if(*dataLength < sz) sz = *dataLength;
- memcpy(ssl->outBuf + ssl->outLen, data, sz);
- ssl->outLen += sz;
- *dataLength = sz;
- return noErr;
+/* sqSetupSSL: Common SSL setup task */
+OSStatus sqSetupSSL(sqSSL* ssl, int isServer)
+{
+ OSStatus status = noErr;
+
+ logprintf("sqSetupSSL: Setting up new context\n");
+ /* Create the new context */
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
+ ssl->ctx = SSLCreateContext(NULL,
+ isServer ? kSSLServerSide : kSSLClientSide,
+ kSSLStreamType);
+#else
+ status = SSLNewContext(isServer, &ssl->ctx);
+ if (status != noErr) {
+ logprintf_status(status, "SSLNewContext failed");
+ return status;
+ }
+#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
+
+ /* Set the connection ref */
+ status = SSLSetConnection(ssl->ctx, ssl);
+ if (status != noErr) {
+ logprintf_status(status, "SSLSetConnection failed");
+ return status;
+ }
+
+ /* Set up the read/write functions */
+ status = SSLSetIOFuncs(ssl->ctx, SqueakSSLRead, SqueakSSLWrite);
+ if (status != noErr) {
+ logprintf_status(status, "SSLSetIOFuncs failed");
+ return status;
+ }
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
+ /* At least TLS 1 */
+ status = SSLSetProtocolVersionMin(ssl->ctx, kTLSProtocol1);
+#else
+ /* Prefer TLS 1 */
+ status = SSLSetProtocolVersionEnabled(ssl->ctx, kTLSProtocol1, true);
+#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
+ if (status != noErr) {
+ logprintf_status(status, "SSLSetProtocolVersion{Min,Enabled} failed");
+ return status;
+ }
+
+
+ /* Disable cert verification since we do that ourselves */
+ status = SSLSetEnableCertVerify(ssl->ctx, false);
+ if (status != noErr) {
+ logprintf_status(status, "SSLSetEnableCertVerify failed");
+ return status;
+ }
+
+ if (ssl->serverName) {
+ /* Try for SNI */
+#if !(MAC_OS_X_VERSION_MAX_ALLOWED >= 1070)
+ status = SSLSetPeerDomainName(ssl->ctx, ssl->serverName,
+ strlen(ssl->serverName));
+#else
+ status = SSLSetPeerDomainName(ssl->ctx, ssl->serverName,
+ strnlen(ssl->serverName, CN_MAX - 1));
+#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
+ if (status != noErr) {
+ logprintf_status(status, "SSLSetPeerDomainName failed");
+ return status;
+ }
+ }
+
+ return status;
}
+/* sqExtractPeerName: Extract a copy of the first common name from the
+ certificate obtained in a handshake
+ */
+static OSStatus sqExtractPeerName(sqSSL* ssl)
+{
+ OSStatus status = noErr;
+ if (CFArrayGetCount(ssl->certs) <= 0) {
+ // No cert -> no peer name available
+ return status;
+ }
+
+ char peerName[CN_MAX + 1];
+ CFStringRef cfName = NULL;
+ SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(ssl->certs, 0);
+ status = SecCertificateCopyCommonName(cert, &cfName);
+ if (status == noErr) {
+ CFStringGetCString(cfName, peerName, sizeof(peerName), kCFStringEncodingUTF8);
+#if !(MAC_OS_X_VERSION_MAX_ALLOWED >= 1070)
+ ssl->peerName = strdup(peerName);
+#else
+ ssl->peerName = strndup(peerName, CN_MAX);
+#endif
+ CFRelease(cfName);
+ }
+ return status;
+}
+
+
+#pragma mark -
+#pragma mark Callbacks
+
/********************************************************************/
/********************************************************************/
/********************************************************************/
-/* sslFromHandle: Maps a handle to an SSL */
-static sqSSL *sslFromHandle(sqInt handle) {
- return handle < handleMax ? handleBuf[handle] : NULL;
-}
+/* SqueakSSLRead: Custom read function for Secure Transport */
+OSStatus SqueakSSLRead(SSLConnectionRef connection, void* data,
+ size_t* dataLength)
+{
+ sqSSL* ssl = (sqSSL*)connection;
+ size_t sz = *dataLength;
-/* sqSetupSSL: Common SSL setup task */
+ logprintf("SqueakSSLRead: Requesting %d bytes, having %d bytes\n",
+ (int)sz, ssl->dataLen);
-int sqSetupSSL(sqSSL *ssl, int isServer) {
- OSStatus status;
+ if (ssl->dataLen < sz) {
+ sz = ssl->dataLen;
+ }
+ memcpy(data, ssl->dataBuf, sz);
- if(ssl->loglevel) printf("sqSetupSSL: Setting up new context\n");
- /* Create the new context */
- status = SSLNewContext(isServer, &ssl->ctx);
- if(status) {
- if(ssl->loglevel) printf("SSLNewContext failed: code = %d\n", (int)status);
- return 0;
- }
- /* Set the connection ref */
- status = SSLSetConnection(ssl->ctx, ssl);
- if(status) {
- if(ssl->loglevel) printf("SSLSetConnection failed: code = %d\n", (int)status);
- return 0;
- }
-
- /* Set up the read/write functions */
- status = SSLSetIOFuncs(ssl->ctx,SqueakSSLRead, SqueakSSLWrite);
- if(status) {
- if(ssl->loglevel) printf("SSLSetIOFuncs failed: code = %d\n", (int)status);
- return 0;
- }
+ /* Did we have enough data? */
+ if (sz == *dataLength) {
+ /* Adjust read buffer */
+ memmove(ssl->dataBuf, ssl->dataBuf+sz, ssl->dataLen - sz);
+ ssl->dataLen -= sz;
+ *dataLength = sz;
+ return noErr;
+ }
- /* Enable desired protocols */
- status = SSLSetProtocolVersionEnabled(ssl->ctx, kSSLProtocol2, false);
- if(status) {
- if(ssl->loglevel) printf("SSLSetProtocolVersionEnabled failed: code = %d\n", (int)status);
- return 0;
- }
+ ssl->dataLen = 0;
+ *dataLength = sz;
+ return errSSLWouldBlock;
+}
- status = SSLSetProtocolVersionEnabled(ssl->ctx, kSSLProtocol3, true);
- if(status) {
- if(ssl->loglevel) printf("SSLSetProtocolVersionEnabled failed: code = %d\n", (int)status);
- return 0;
- }
+/* SqueakSSLRead: Custom write function for Secure Transport */
+OSStatus SqueakSSLWrite(SSLConnectionRef connection, const void* data,
+ size_t* dataLength)
+{
+ sqSSL* ssl = (sqSSL*)connection;
+ size_t sz = ssl->outMax - ssl->outLen;
- status = SSLSetProtocolVersionEnabled(ssl->ctx, kTLSProtocol1, true);
- if(status) {
- if(ssl->loglevel) printf("SSLSetProtocolVersionEnabled failed: code = %d\n", (int)status);
- return 0;
- }
- /* Disable cert verification since we do that ourselves */
- status = SSLSetEnableCertVerify(ssl->ctx, false);
- if(status) {
- if(ssl->loglevel) printf("SSLSetEnableCertVerify failed: code = %d\n", (int)status);
- return 0;
- }
+ logprintf("SqueakSSLWrite: Writing %d bytes, having %d free\n",
+ (int)*dataLength, (int)sz);
+ if (sz == 0) {
+ *dataLength = 0;
+ return errSSLWouldBlock;
+ }
- return 1;
+ if (*dataLength < sz) {
+ sz = *dataLength;
+ }
+ memcpy(ssl->outBuf + ssl->outLen, data, sz);
+ ssl->outLen += sz;
+ *dataLength = sz;
+ return noErr;
}
/********************************************************************/
+#pragma mark -
+#pragma mark Plugin Interface
/********************************************************************/
-/********************************************************************/
/* sqCreateSSL: Creates a new SSL instance.
- Arguments: None.
- Returns: SSL handle.
+ Arguments: None.
+ Returns: SSL handle.
*/
-sqInt sqCreateSSL(void) {
- sqInt handle = 0;
- sqSSL *ssl = NULL;
+sqInt sqCreateSSL(void)
+{
+ sqInt handle = 0;
+ sqSSL* ssl = NULL;
- ssl = calloc(1, sizeof(sqSSL));
- ssl->loglevel = 0;
+ ssl = calloc(1, sizeof(sqSSL));
+ ssl->loglevel = 0;
- /* Find a free handle */
- for(handle = 1; handle < handleMax; handle++)
- if(handleBuf[handle] == NULL) break;
+ /* Find a free handle */
+ for (handle = 1; handle < handleMax; handle++) {
+ if (handleBuf[handle] == NULL) {
+ break;
+ }
+ }
- if(handle >= handleMax) {
- int i, delta = 100;
- /* Resize the handle buffer */
- handleBuf = realloc(handleBuf, (handleMax+delta)*sizeof(void*));
- for(i = handleMax; i < handleMax+delta; i++)
- handleBuf[i] = NULL;
- handleMax += delta;
- }
- handleBuf[handle] = ssl;
- return handle;
+ if (handle >= handleMax) {
+ int delta = 100;
+ /* Resize the handle buffer */
+ handleBuf = (sqSSL**)realloc(handleBuf,
+ (handleMax + delta) * sizeof(sqSSL*));
+ for (int i = handleMax; i < handleMax + delta; i++) {
+ handleBuf[i] = NULL;
+ }
+ handleMax += delta;
+ }
+ handleBuf[handle] = ssl;
+ return handle;
}
/* sqDestroySSL: Destroys an SSL instance.
- Arguments:
- handle - the SSL handle
- Returns: Non-zero if successful.
+ Arguments:
+ handle - the SSL handle
+ Returns: Non-zero if successful.
*/
-sqInt sqDestroySSL(sqInt handle) {
- sqSSL *ssl = sslFromHandle(handle);
- if(ssl == NULL) return 0;
+sqInt sqDestroySSL(sqInt handle)
+{
+ sqSSL* ssl = sqSSLFromHandle(handle);
+ if (ssl == NULL) {
+ return 0;
+ }
- if(ssl->certName) free(ssl->certName);
- if(ssl->peerName) free(ssl->peerName);
+ if (ssl->ctx) {
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
+ CFRelease(ssl->ctx);
+#else
+ SSLDisposeContext(ssl->ctx);
+#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
+ }
- free(ssl);
- handleBuf[handle] = NULL;
- return 1;
+ if (ssl->certName) {
+ free(ssl->certName);
+ }
+ if (ssl->peerName) {
+ free(ssl->peerName);
+ }
+ if (ssl->serverName) {
+ free(ssl->serverName);
+ }
+
+ free(ssl);
+ handleBuf[handle] = NULL;
+ return 1;
}
/* sqConnectSSL: Start/continue an SSL client handshake.
- Arguments:
- handle - the SSL handle
- srcBuf - the input token sent by the remote peer
- srcLen - the size of the input token
- dstBuf - the output buffer for a new token
- dstLen - the size of the output buffer
- Returns: The size of the output token or an error code.
+ Arguments:
+ handle - the SSL handle
+ srcBuf - the input token sent by the remote peer
+ srcLen - the size of the input token
+ dstBuf - the output buffer for a new token
+ dstLen - the size of the output buffer
+ Returns: The size of the output token or an error code.
*/
-sqInt sqConnectSSL(sqInt handle, char* srcBuf, sqInt srcLen, char *dstBuf, sqInt dstLen) {
- OSStatus status;
- sqSSL *ssl = sslFromHandle(handle);
+sqInt sqConnectSSL(sqInt handle, char* srcBuf, sqInt srcLen, char* dstBuf,
+ sqInt dstLen)
+{
+ OSStatus status;
+ sqSSL* ssl = sqSSLFromHandle(handle);
- if(ssl->loglevel) printf("sqConnectSSL: %x\n", (int)ssl);
+ logprintf("sqConnectSSL: %x\n", (int)ssl);
- /* Verify state of session */
- if(ssl == NULL || (ssl->state != SQSSL_UNUSED && ssl->state != SQSSL_CONNECTING)) {
- return SQSSL_INVALID_STATE;
- }
+ /* Verify state of session */
+ if (ssl == NULL
+ || (ssl->state != SQSSL_UNUSED && ssl->state != SQSSL_CONNECTING)) {
+ return SQSSL_INVALID_STATE;
+ }
- /* Set up the output buffer */
- ssl->outBuf = dstBuf;
- ssl->outLen = 0;
- ssl->outMax = dstLen;
+ /* Set up the output buffer */
+ ssl->outBuf = dstBuf;
+ ssl->outLen = 0;
+ ssl->outMax = dstLen;
- if(ssl->dataLen + srcLen > ssl->dataMax) {
- /* resize the data buffer */
- ssl->dataMax += (srcLen < 4096) ? (4096) : (srcLen+1024);
- ssl->dataBuf = realloc(ssl->dataBuf, ssl->dataMax);
- if(!ssl->dataBuf) return SQSSL_OUT_OF_MEMORY;
- }
- if(ssl->loglevel) printf("sqConnectSSL: input token %d bytes\n", srcLen);
- memcpy(ssl->dataBuf + ssl->dataLen, srcBuf, srcLen);
- ssl->dataLen += srcLen;
+ if (ssl->dataLen + srcLen > ssl->dataMax) {
+ /* resize the data buffer */
+ ssl->dataMax += (srcLen < 4096) ? (4096) : (srcLen + 1024);
+ ssl->dataBuf = realloc(ssl->dataBuf, ssl->dataMax);
+ if (!ssl->dataBuf) {
+ return SQSSL_OUT_OF_MEMORY;
+ }
+ }
+ logprintf("sqConnectSSL: input token %d bytes\n", srcLen);
+ memcpy(ssl->dataBuf + ssl->dataLen, srcBuf, srcLen);
+ ssl->dataLen += srcLen;
- /* Establish initial connection */
- if(ssl->state == SQSSL_UNUSED) {
- ssl->state = SQSSL_CONNECTING;
- if(ssl->loglevel) printf("sqConnectSSL: Setting up SSL\n");
- if(!sqSetupSSL(ssl, 0)) return SQSSL_GENERIC_ERROR;
- }
+ /* Establish initial connection */
+ if (ssl->state == SQSSL_UNUSED) {
+ ssl->state = SQSSL_CONNECTING;
+ logprintf("sqConnectSSL: Setting up SSL\n");
+ status = sqSetupSSL(ssl, 0);
+ if (status != noErr) {
+ return SQSSL_GENERIC_ERROR;
+ }
+ }
- status = SSLHandshake(ssl->ctx);
- if(status == errSSLWouldBlock) {
- /* Return token to caller */
- if(ssl->loglevel) printf("sqConnectSSL: Produced %d token bytes\n", ssl->outLen);
- return ssl->outLen ? ssl->outLen : SQSSL_NEED_MORE_DATA;
- }
- if(status != noErr) {
- if(ssl->loglevel) printf("sqConnectSSL: SSLHandshake returned %d\n", (int)status);
- return SQSSL_GENERIC_ERROR;
- }
- /* We are connected. Verify the cert. */
- ssl->state = SQSSL_CONNECTED;
- ssl->certFlags = -1;
+ status = SSLHandshake(ssl->ctx);
+ if (status == errSSLWouldBlock) {
+ /* Return token to caller */
+ logprintf("sqConnectSSL: Produced %d token bytes\n", ssl->outLen);
+ return ssl->outLen ? ssl->outLen : SQSSL_NEED_MORE_DATA;
+ }
+ if (status != noErr) {
+ logprintf_status(status, "sqConnectSSL: SSLHandshake");
+ return SQSSL_GENERIC_ERROR;
+ }
+ /* We are connected. Verify the cert. */
+ ssl->state = SQSSL_CONNECTED;
+ ssl->certFlags = -1;
- /* Extract the peer name from the cert */
- status = SSLCopyPeerCertificates(ssl->ctx, &ssl->certs);
- if(status == noErr) {
- if(CFArrayGetCount(ssl->certs) > 0) {
- char peerName[256];
- CFStringRef cfName;
- SecCertificateRef cert = (SecCertificateRef) CFArrayGetValueAtIndex(ssl->certs, 0);
- status = SecCertificateCopyCommonName(cert, &cfName);
- if(status == noErr) {
- CFStringGetCString(cfName, peerName, sizeof(peerName), kCFStringEncodingUTF8);
- ssl->peerName = strdup(peerName);
- CFRelease(cfName);
- }
- }
- }
- return 0;
+ /* Extract the peer name from the cert */
+ status = SSLCopyPeerCertificates(ssl->ctx, &ssl->certs);
+ if (status == noErr) {
+ sqExtractPeerName(ssl);
+ }
+ return SQSSL_OK;
}
/* sqAcceptSSL: Start/continue an SSL server handshake.
- Arguments:
- handle - the SSL handle
- srcBuf - the input token sent by the remote peer
- srcLen - the size of the input token
- dstBuf - the output buffer for a new token
- dstLen - the size of the output buffer
- Returns: The size of the output token or an error code.
+ Arguments:
+ handle - the SSL handle
+ srcBuf - the input token sent by the remote peer
+ srcLen - the size of the input token
+ dstBuf - the output buffer for a new token
+ dstLen - the size of the output buffer
+ Returns: The size of the output token or an error code.
*/
-sqInt sqAcceptSSL(sqInt handle, char* srcBuf, sqInt srcLen, char *dstBuf, sqInt dstLen) {
- OSStatus status;
- sqSSL *ssl = sslFromHandle(handle);
+sqInt sqAcceptSSL(sqInt handle, char* srcBuf, sqInt srcLen, char* dstBuf,
+ sqInt dstLen)
+{
+ OSStatus status = noErr;
+ sqSSL* ssl = sqSSLFromHandle(handle);
- /* Verify state of session */
- if(ssl == NULL || (ssl->state != SQSSL_UNUSED && ssl->state != SQSSL_ACCEPTING)) {
- return SQSSL_INVALID_STATE;
- }
+ /* Verify state of session */
+ if (ssl == NULL
+ || (ssl->state != SQSSL_UNUSED && ssl->state != SQSSL_ACCEPTING)) {
+ return SQSSL_INVALID_STATE;
+ }
- /* Set up the output buffer */
- ssl->outBuf = dstBuf;
- ssl->outLen = 0;
- ssl->outMax = dstLen;
-
- if(ssl->dataLen + srcLen > ssl->dataMax) {
- /* resize the data buffer */
- ssl->dataMax += (srcLen < 4096) ? (4096) : (srcLen+1024);
- ssl->dataBuf = realloc(ssl->dataBuf, ssl->dataMax);
- if(!ssl->dataBuf) return SQSSL_OUT_OF_MEMORY;
- }
- if(ssl->loglevel) printf("sqConnectSSL: input token %d bytes\n", srcLen);
- memcpy(ssl->dataBuf + ssl->dataLen, srcBuf, srcLen);
- ssl->dataLen += srcLen;
-
- /* Establish initial connection */
- if(ssl->state == SQSSL_UNUSED) {
- ssl->state = SQSSL_ACCEPTING;
- if(ssl->loglevel) printf("sqAcceptSSL: Setting up SSL\n");
- if(!sqSetupSSL(ssl, 1)) return SQSSL_GENERIC_ERROR;
- if(ssl->loglevel) printf("sqAcceptSSL: setting accept state\n");
- }
+ /* Set up the output buffer */
+ ssl->outBuf = dstBuf;
+ ssl->outLen = 0;
+ ssl->outMax = dstLen;
- status = SSLHandshake(ssl->ctx);
- if(status == errSSLWouldBlock) {
- /* Return token to caller */
- return ssl->outLen ? ssl->outLen : SQSSL_NEED_MORE_DATA;
- }
- if(status != noErr) {
- if(ssl->loglevel) printf("sqConnectSSL: SSLHandshake returned %d\n", (int)status);
- return SQSSL_GENERIC_ERROR;
- }
- /* We are connected. Verify the cert. */
- ssl->state = SQSSL_CONNECTED;
- return 0;
+ if (ssl->dataLen + srcLen > ssl->dataMax) {
+ /* resize the data buffer */
+ ssl->dataMax += (srcLen < 4096) ? (4096) : (srcLen + 1024);
+ ssl->dataBuf = realloc(ssl->dataBuf, ssl->dataMax);
+ if (!ssl->dataBuf) {
+ return SQSSL_OUT_OF_MEMORY;
+ }
+ }
+ logprintf("sqConnectSSL: input token %d bytes\n", srcLen);
+ memcpy(ssl->dataBuf + ssl->dataLen, srcBuf, srcLen);
+ ssl->dataLen += srcLen;
+
+ /* Establish initial connection */
+ if (ssl->state == SQSSL_UNUSED) {
+ ssl->state = SQSSL_ACCEPTING;
+ logprintf("sqAcceptSSL: Setting up SSL\n");
+ status = sqSetupSSL(ssl, 1);
+ if (status != noErr) {
+ return SQSSL_GENERIC_ERROR;
+ }
+ logprintf("sqAcceptSSL: setting accept state\n");
+ }
+
+ status = SSLHandshake(ssl->ctx);
+ if (status == errSSLWouldBlock) {
+ /* Return token to caller */
+ return ssl->outLen ? ssl->outLen : SQSSL_NEED_MORE_DATA;
+ }
+ if (status != noErr) {
+ logprintf("sqConnectSSL: SSLHandshake returned %d\n", (int)status);
+ return SQSSL_GENERIC_ERROR;
+ }
+ /* We are connected. Verify the cert. */
+ ssl->state = SQSSL_CONNECTED;
+ return SQSSL_OK;
}
/* sqEncryptSSL: Encrypt data for SSL transmission.
- Arguments:
- handle - the SSL handle
- srcBuf - the unencrypted input data
- srcLen - the size of the input data
- dstBuf - the output buffer for the encrypted contents
- dstLen - the size of the output buffer
- Returns: The size of the output generated or an error code.
+ Arguments:
+ handle - the SSL handle
+ srcBuf - the unencrypted input data
+ srcLen - the size of the input data
+ dstBuf - the output buffer for the encrypted contents
+ dstLen - the size of the output buffer
+ Returns: The size of the output generated or an error code.
*/
-sqInt sqEncryptSSL(sqInt handle, char* srcBuf, sqInt srcLen, char *dstBuf, sqInt dstLen) {
- size_t nbytes;
- OSStatus status;
- sqSSL *ssl = sslFromHandle(handle);
+sqInt sqEncryptSSL(sqInt handle, char* srcBuf, sqInt srcLen, char* dstBuf,
+ sqInt dstLen)
+{
+ size_t nbytes = 0;
+ OSStatus status = noErr;
+ sqSSL* ssl = sqSSLFromHandle(handle);
- if(ssl == NULL || ssl->state != SQSSL_CONNECTED) return SQSSL_INVALID_STATE;
+ if (ssl == NULL || ssl->state != SQSSL_CONNECTED) {
+ return SQSSL_INVALID_STATE;
+ }
- /* Set up the output buffer */
- ssl->outBuf = dstBuf;
- ssl->outLen = 0;
- ssl->outMax = dstLen;
-
- if(ssl->loglevel) printf("sqEncryptSSL: Encrypting %d bytes\n", srcLen);
+ /* Set up the output buffer */
+ ssl->outBuf = dstBuf;
+ ssl->outLen = 0;
+ ssl->outMax = dstLen;
- status = SSLWrite(ssl->ctx, srcBuf, srcLen, &nbytes);
- if(nbytes != srcLen) return SQSSL_GENERIC_ERROR;
- if(status == errSSLWouldBlock || status == noErr) return ssl->outLen;
- if(ssl->loglevel) printf("sqDecryptSSL: SSLWrite returned %d\n", (int)status);
- return SQSSL_GENERIC_ERROR;
+ logprintf("sqEncryptSSL: Encrypting %d bytes\n", srcLen);
+
+ status = SSLWrite(ssl->ctx, srcBuf, srcLen, &nbytes);
+ if (nbytes != srcLen) {
+ return SQSSL_GENERIC_ERROR;
+ }
+ if (status == errSSLWouldBlock || status == noErr
+ || status == errSSLClosedGraceful) {
+ return ssl->outLen;
+ }
+ logprintf_status(status, "sqDecryptSSL: SSLWrite");
+ return SQSSL_GENERIC_ERROR;
}
/* sqDecryptSSL: Decrypt data for SSL transmission.
- Arguments:
- handle - the SSL handle
- srcBuf - the encrypted input data
- srcLen - the size of the input data
- dstBuf - the output buffer for the decrypted contents
- dstLen - the size of the output buffer
- Returns: The size of the output generated or an error code.
+ Arguments:
+ handle - the SSL handle
+ srcBuf - the encrypted input data
+ srcLen - the size of the input data
+ dstBuf - the output buffer for the decrypted contents
+ dstLen - the size of the output buffer
+ Returns: The size of the output generated or an error code.
*/
-sqInt sqDecryptSSL(sqInt handle, char* srcBuf, sqInt srcLen, char *dstBuf, sqInt dstLen) {
- size_t nbytes = 0;
- OSStatus status;
- sqSSL *ssl = sslFromHandle(handle);
+sqInt sqDecryptSSL(sqInt handle, char* srcBuf, sqInt srcLen, char* dstBuf,
+ sqInt dstLen)
+{
+ size_t nbytes = 0;
+ OSStatus status = noErr;
+ sqSSL* ssl = sqSSLFromHandle(handle);
- if(ssl == NULL || ssl->state != SQSSL_CONNECTED) return SQSSL_INVALID_STATE;
+ if (ssl == NULL || ssl->state != SQSSL_CONNECTED) {
+ return SQSSL_INVALID_STATE;
+ }
- if(ssl->dataLen + srcLen > ssl->dataMax) {
- /* resize the read buffer */
- ssl->dataMax += (srcLen < 4096) ? (4096) : (srcLen+1024);
- ssl->dataBuf = realloc(ssl->dataBuf, ssl->dataMax);
- if(!ssl->dataBuf) return SQSSL_OUT_OF_MEMORY;
- }
- if(ssl->loglevel) printf("sqDecryptSSL: Input data %d bytes\n", srcLen);
- memcpy(ssl->dataBuf + ssl->dataLen, srcBuf, srcLen);
- ssl->dataLen += srcLen;
-
- if(ssl->loglevel) printf("sqDecryptSSL: Decrypting %d bytes\n", ssl->dataLen);
+ if (ssl->dataLen + srcLen > ssl->dataMax) {
+ /* resize the read buffer */
+ ssl->dataMax += (srcLen < 4096) ? (4096) : (srcLen + 1024);
+ ssl->dataBuf = realloc(ssl->dataBuf, ssl->dataMax);
+ if (!ssl->dataBuf) {
+ return SQSSL_OUT_OF_MEMORY;
+ }
+ }
+ logprintf("sqDecryptSSL: Input data %d bytes\n", srcLen);
+ memcpy(ssl->dataBuf + ssl->dataLen, srcBuf, srcLen);
+ ssl->dataLen += srcLen;
- status = SSLRead(ssl->ctx, dstBuf, dstLen, &nbytes);
- if(status == errSSLWouldBlock || status == noErr) return nbytes;
- if(ssl->loglevel) printf("sqDecryptSSL: SSLRead returned %d\n", (int)status);
- return SQSSL_GENERIC_ERROR;
+ logprintf("sqDecryptSSL: Decrypting %d bytes\n", ssl->dataLen);
+
+ status = SSLRead(ssl->ctx, dstBuf, dstLen, &nbytes);
+ if (status == errSSLWouldBlock || status == noErr
+ || status == errSSLClosedGraceful) {
+ return nbytes;
+ }
+ logprintf_status(status, "sqDecryptSSL: SSLRead");
+ return SQSSL_GENERIC_ERROR;
}
/* sqGetStringPropertySSL: Retrieve a string property from SSL.
- Arguments:
- handle - the ssl handle
- propID - the property id to retrieve
- Returns: The string value of the property.
+ Arguments:
+ handle - the ssl handle
+ propID - the property id to retrieve
+ Returns: The string value of the property.
*/
-char* sqGetStringPropertySSL(sqInt handle, int propID) {
- sqSSL *ssl = sslFromHandle(handle);
+char* sqGetStringPropertySSL(sqInt handle, int propID)
+{
+ sqSSL* ssl = sqSSLFromHandle(handle);
- if(ssl == NULL) return NULL;
- switch(propID) {
- case SQSSL_PROP_PEERNAME: return ssl->peerName;
- case SQSSL_PROP_CERTNAME: return ssl->certName;
- default:
- if(ssl->loglevel) printf("sqGetStringPropertySSL: Unknown property ID %d\n", propID);
- return NULL;
- }
- return NULL;
+ if (ssl == NULL) {
+ return NULL;
+ }
+
+ switch (propID) {
+ case SQSSL_PROP_PEERNAME: return ssl->peerName;
+ case SQSSL_PROP_CERTNAME: return ssl->certName;
+ case SQSSL_PROP_SERVERNAME: return ssl->serverName;
+ default:
+ logprintf("sqGetStringPropertySSL: Unknown property ID %d\n", propID);
+ return NULL;
+ }
+ return NULL;
}
/* sqSetStringPropertySSL: Set a string property in SSL.
- Arguments:
- handle - the ssl handle
- propID - the property id to retrieve
- propName - the property string
- propLen - the length of the property string
- Returns: Non-zero if successful.
+ Arguments:
+ handle - the ssl handle
+ propID - the property id to retrieve
+ propName - the property string
+ propLen - the length of the property string
+ Returns: Non-zero if successful.
*/
-sqInt sqSetStringPropertySSL(sqInt handle, int propID, char *propName, sqInt propLen) {
- sqSSL *ssl = sslFromHandle(handle);
- char *property = NULL;
+sqInt sqSetStringPropertySSL(sqInt handle, int propID, char* propName,
+ sqInt propLen)
+{
+ sqSSL* ssl = sqSSLFromHandle(handle);
+ char* property = NULL;
- if(ssl == NULL) return 0;
+ if (ssl == NULL) return 0;
- if(propLen) {
- property = calloc(1, propLen+1);
- memcpy(property, propName, propLen);
- };
+ if (propLen) {
+ property = malloc(propLen + 1);
+ memcpy(property, propName, propLen);
+ property[propLen] = '\0';
+ }
- if(ssl->loglevel) printf("sqSetStringPropertySSL(%d): %s\n", propID, property);
+ logprintf("sqSetStringPropertySSL(%d): %s\n",
+ propID, property ? property : "(null)");
- switch(propID) {
- case SQSSL_PROP_CERTNAME: ssl->certName = property; break;
- default:
- if(ssl->loglevel) printf("sqSetStringPropertySSL: Unknown property ID %d\n", propID);
- return 0;
- }
- return 1;
+ switch(propID) {
+ case SQSSL_PROP_CERTNAME:
+ if (ssl->certName) {
+ free(ssl->certName);
+ }
+ ssl->certName = property;
+ break;
+ case SQSSL_PROP_SERVERNAME:
+ if (ssl->serverName) {
+ free(ssl->serverName);
+ }
+ ssl->serverName = property;
+ break;
+ default:
+ if (property) {
+ free(property);
+ }
+ logprintf("sqSetStringPropertySSL: Unknown property ID %d\n", propID);
+ return 0;
+ }
+ return 1;
}
/* sqGetIntPropertySSL: Retrieve an integer property from SSL.
- Arguments:
- handle - the ssl handle
- propID - the property id to retrieve
- Returns: The integer value of the property.
+ Arguments:
+ handle - the ssl handle
+ propID - the property id to retrieve
+ Returns: The integer value of the property.
*/
-int sqGetIntPropertySSL(sqInt handle, int propID) {
- sqSSL *ssl = sslFromHandle(handle);
+int sqGetIntPropertySSL(sqInt handle, int propID)
+{
+ sqSSL* ssl = sqSSLFromHandle(handle);
- if(ssl == NULL) return 0;
- switch(propID) {
- case SQSSL_PROP_SSLSTATE: return ssl->state;
- case SQSSL_PROP_CERTSTATE: return ssl->certFlags;
- case SQSSL_PROP_VERSION: return 1;
- case SQSSL_PROP_LOGLEVEL: return ssl->loglevel;
- default:
- if(ssl->loglevel) printf("sqGetIntPropertySSL: Unknown property ID %d\n", propID);
- return 0;
- }
- return 0;
+ if (ssl == NULL) {
+ return 0;
+ }
+
+ switch(propID) {
+ case SQSSL_PROP_SSLSTATE: return ssl->state;
+ case SQSSL_PROP_CERTSTATE: return ssl->certFlags;
+ case SQSSL_PROP_VERSION: return SQSSL_VERSION;
+ case SQSSL_PROP_LOGLEVEL: return ssl->loglevel;
+ default:
+ logprintf("sqGetIntPropertySSL: Unknown property ID %d\n", propID);
+ return 0;
+ }
+ return 0;
}
/* sqSetIntPropertySSL: Set an integer property in SSL.
- Arguments:
- handle - the ssl handle
- propID - the property id to retrieve
- propValue - the property value
- Returns: Non-zero if successful.
+ Arguments:
+ handle - the ssl handle
+ propID - the property id to retrieve
+ propValue - the property value
+ Returns: Non-zero if successful.
*/
-sqInt sqSetIntPropertySSL(sqInt handle, sqInt propID, sqInt propValue) {
- sqSSL *ssl = sslFromHandle(handle);
- if(ssl == NULL) return 0;
+sqInt sqSetIntPropertySSL(sqInt handle, sqInt propID, sqInt propValue)
+{
+ sqSSL* ssl = sqSSLFromHandle(handle);
+ if (ssl == NULL) {
+ return 0;
+ }
- switch(propID) {
- case SQSSL_PROP_LOGLEVEL: ssl->loglevel = propValue; break;
- default:
- if(ssl->loglevel) printf("sqSetIntPropertySSL: Unknown property ID %d\n", propID);
- return 0;
- }
- return 1;
+ switch(propID) {
+ case SQSSL_PROP_SSLSTATE: // falltrough
+ case SQSSL_PROP_CERTSTATE: // falltrough
+ case SQSSL_PROP_VERSION:
+ logprintf("sqSetIntPropertySSL: property is readonly %d\n", propID);
+ break;
+ case SQSSL_PROP_LOGLEVEL:
+ ssl->loglevel = propValue;
+ break;
+ default:
+ logprintf("sqSetIntPropertySSL: Unknown property ID %d\n", propID);
+ return 0;
+ }
+ return 1;
}
Added: branches/Cog/platforms/unix/plugins/SqueakSSL/config.cmake
===================================================================
--- branches/Cog/platforms/unix/plugins/SqueakSSL/config.cmake (rev 0)
+++ branches/Cog/platforms/unix/plugins/SqueakSSL/config.cmake 2015-07-30 01:55:26 UTC (rev 3417)
@@ -0,0 +1 @@
+PLUGIN_REQUIRE_PACKAGE (OPENSSL openssl)
Modified: branches/Cog/platforms/unix/plugins/SqueakSSL/sqUnixOpenSSL.c
===================================================================
--- branches/Cog/platforms/unix/plugins/SqueakSSL/sqUnixOpenSSL.c 2015-07-30 01:51:21 UTC (rev 3416)
+++ branches/Cog/platforms/unix/plugins/SqueakSSL/sqUnixOpenSSL.c 2015-07-30 01:55:26 UTC (rev 3417)
@@ -37,7 +37,7 @@
sqInt sqCopyBioSSL(sqSSL *ssl, BIO *bio, char *dstBuf, sqInt dstLen) {
int nbytes = BIO_ctrl_pending(bio);
- if(ssl->loglevel) printf("sqCopyBioSSL: %d bytes pending; buffer size %d\n",
+ if(ssl->loglevel) printf("sqCopyBioSSL: %d bytes pending; buffer size %ld\n",
nbytes, dstLen);
if(nbytes > dstLen) return -1;
return BIO_read(bio, dstBuf, dstLen);
@@ -439,7 +439,7 @@
switch(propID) {
case SQSSL_PROP_SSLSTATE: return ssl->state;
case SQSSL_PROP_CERTSTATE: return ssl->certFlags;
- case SQSSL_PROP_VERSION: return 1;
+ case SQSSL_PROP_VERSION: return SQSSL_VERSION;
case SQSSL_PROP_LOGLEVEL: return ssl->loglevel;
default:
if(ssl->loglevel) printf("sqGetIntPropertySSL: Unknown property ID %d\n", propID);
@@ -462,7 +462,7 @@
switch(propID) {
case SQSSL_PROP_LOGLEVEL: ssl->loglevel = propValue; break;
default:
- if(ssl->loglevel) printf("sqSetIntPropertySSL: Unknown property ID %d\n", propID);
+ if(ssl->loglevel) printf("sqSetIntPropertySSL: Unknown property ID %ld\n", propID);
return 0;
}
return 1;
More information about the Vm-dev
mailing list