[Vm-dev] [commit][3416] Integrate Marcel Taeumel & Tobias Pape' s v2 SSL plugin changes.

commits at squeakvm.org commits at squeakvm.org
Thu Jul 30 01:51:21 UTC 2015


Revision: 3416
Author:   eliot
Date:     2015-07-29 18:51:21 -0700 (Wed, 29 Jul 2015)
Log Message:
-----------
Integrate Marcel Taeumel & Tobias Pape's v2 SSL plugin changes.

M    SqueakSSL/sqWin32SSL.c

Modified Paths:
--------------
    trunk/platforms/win32/plugins/SqueakSSL/sqWin32SSL.c

Modified: trunk/platforms/win32/plugins/SqueakSSL/sqWin32SSL.c
===================================================================
--- trunk/platforms/win32/plugins/SqueakSSL/sqWin32SSL.c	2015-07-30 01:46:49 UTC (rev 3415)
+++ trunk/platforms/win32/plugins/SqueakSSL/sqWin32SSL.c	2015-07-30 01:51:21 UTC (rev 3416)
@@ -1,4 +1,16 @@
-/* sqWin32SSL.c: SqueakSSL implementation for Windows */
+/****************************************************************************
+*   PROJECT: SqueakSSL implementation for Windows
+*   FILE:    sqWin32SSL.c
+*   CONTENT: SSL platform functions
+*
+*   AUTHORS:  Andreas Raab (ar)
+*
+*             Marcel Taeumel (mt)
+*               Hasso Plattner Institute, Postdam, Germany
+*             Tobias Pape (topa)
+*               Hasso Plattner Institute, Postdam, Germany
+*****************************************************************************/
+
 #include <windows.h>
 #include <errno.h>
 #include <malloc.h>
@@ -18,6 +30,7 @@
 
 	char *certName;
 	char *peerName;
+	char *serverName;
 
 	CredHandle sslCred;
 	CtxtHandle sslCtxt;
@@ -126,7 +139,7 @@
 	char  bFriendlyName[MAX_NAME_SIZE];
 
 	if(certName) {
-		hStore = CertOpenSystemStore(0, "MY");
+		hStore = CertOpenSystemStore(0, L"MY");
 		if(!hStore) {
 			if(ssl->loglevel) printf("sqSetupCert: CertOpenSystemStore failed\n");
 			return 0;
@@ -199,7 +212,9 @@
 	PCERT_NAME_INFO certInfo = NULL;
 	PCERT_RDN_ATTR certAttr = NULL;
 	DWORD dwSize = 0;
-	char tmpBuf[1024];
+	int cbPeerName = 0;
+	LPTSTR tmpBuf = NULL;
+	DWORD cchTmpBuf = 0;
 
 	if(ssl->peerName) {
 		free(ssl->peerName);
@@ -214,32 +229,21 @@
 		return 0;
 	}
 
-	/* Figure out the size of the blob */
-	if(!CryptDecodeObject(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_NAME,
-		certHandle->pCertInfo->Subject.pbData,
-		certHandle->pCertInfo->Subject.cbData,
-		0, NULL, &dwSize)) {
-			if(ssl->loglevel) printf("sqExtractPeerName: CryptDecodeObject failed\n");
-			return 0;
-	}
-	
-	/* Get the contents */
-	certInfo = alloca(dwSize);
-	if(!CryptDecodeObject(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_NAME, 
-		certHandle->pCertInfo->Subject.pbData,
-		certHandle->pCertInfo->Subject.cbData,
-		0, certInfo, &dwSize)) {
-			if(ssl->loglevel) printf("sqExtractPeerName: CryptDecodeObject failed\n");
-			return 0;
-	}
+	/* Extract CN from certificate */
+	cchTmpBuf = CertGetNameString(certHandle, CERT_NAME_ATTR_TYPE, 0, szOID_COMMON_NAME, NULL, 0);
+	tmpBuf = (LPTSTR)alloca(cchTmpBuf * sizeof(TCHAR));
+	CertGetNameString(certHandle, CERT_NAME_ATTR_TYPE, 0, szOID_COMMON_NAME, tmpBuf, cchTmpBuf);
 
-	/* Fetch the CN from the cert */
-	certAttr = CertFindRDNAttr(szOID_COMMON_NAME, certInfo);
-	if(certAttr == NULL) return 0;
-
-	/* Translate from RDN to string */
-	if(CertRDNValueToStr(CERT_RDN_PRINTABLE_STRING, &certAttr->Value, tmpBuf, sizeof(tmpBuf)) == 0) return 0;
+#ifdef _UNICODE
+	/* Convert wide to UTF8 */
+	cbPeerName = WideCharToMultiByte(CP_UTF8, 0, tmpBuf, -1, NULL, 0, NULL, NULL);
+	if (cbPeerName == 0) return 0;
+	ssl->peerName = calloc(1, cbPeerName);
+	WideCharToMultiByte(CP_UTF8, 0, tmpBuf, -1, ssl->peerName, cbPeerName, NULL, NULL);
+#else
 	ssl->peerName = _strdup(tmpBuf);
+#endif
+	
 	if(ssl->loglevel) printf("sqExtractPeerName: Peer name is %s\n", ssl->peerName);
 
 	CertFreeCertificateContext(certHandle);
@@ -401,6 +405,7 @@
 
 	if(ssl->certName) free(ssl->certName);
 	if(ssl->peerName) free(ssl->peerName);
+	if(ssl->serverName) free(ssl->serverName);
 	if(ssl->dataBuf) free(ssl->dataBuf);
 
 	free(ssl);
@@ -423,6 +428,8 @@
 	SCHANNEL_CRED sc_cred = { 0 };
 	ULONG sslFlags, retFlags;
 	sqSSL *ssl = sslFromHandle(handle);
+	LPTSTR serverName = NULL;
+	int ccServerName = 0;
 
 	/* Verify state of session */
 	if(ssl == NULL || (ssl->state != SQSSL_UNUSED && ssl->state != SQSSL_CONNECTING)) {
@@ -433,9 +440,10 @@
 		/* 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->dataBuf) return SQSSL_OUT_OF_MEMORY;
 	}
-	if(ssl->loglevel) printf("sqConnectSSL: input token %d bytes\n", srcLen);
+	if(ssl->loglevel) 
+		printf("sqConnectSSL: input token %d bytes\n", srcLen);
 	memcpy(ssl->dataBuf + ssl->dataLen, srcBuf, srcLen);
 	ssl->dataLen += srcLen;
 
@@ -470,18 +478,32 @@
 
 	if(ssl->loglevel) printf("sqConnectSSL: Input to InitSecCtxt is %d bytes\n", ssl->dataLen);
 
+#ifdef _UNICODE
+	if(ssl->serverName) {
+		ccServerName = MultiByteToWideChar(CP_UTF8, 0, ssl->serverName, -1, NULL, 0);
+		if (ccServerName == 0) {
+			return SQSSL_GENERIC_ERROR;
+		}
+		serverName = (LPTSTR)alloca(ccServerName * sizeof(TCHAR));
+		if (MultiByteToWideChar(CP_UTF8, 0, ssl->serverName, -1, serverName, ccServerName) == 0) {
+			return SQSSL_GENERIC_ERROR;
+		}
+	}
+#else
+	if(ssl->serverName) serverName = ssl->serverName;
+#endif
+
 	if(ssl->state == SQSSL_UNUSED) {
 		ssl->state = SQSSL_CONNECTING;
 
-		if(!sqSetupCert(ssl, ssl->certName, 0)) 
-			/* FIXME. We need a different error code here. */
+		if (!sqSetupCert(ssl, ssl->certName, 0)) {
 			return SQSSL_GENERIC_ERROR;
-
-		ret = InitializeSecurityContext(&ssl->sslCred, NULL, NULL,
+		}
+		ret = InitializeSecurityContext(&ssl->sslCred, NULL, serverName,
 										sslFlags, 0, 0, NULL, 0, &ssl->sslCtxt,
 										&ssl->sbdOut, &retFlags, NULL);
 	} else {
-		ret = InitializeSecurityContext(&ssl->sslCred, &ssl->sslCtxt, NULL,
+		ret = InitializeSecurityContext(&ssl->sslCred, &ssl->sslCtxt, serverName,
 										sslFlags, 0, 0, &ssl->sbdIn, 0, NULL,
 										&ssl->sbdOut, &retFlags, NULL);
 	}
@@ -516,11 +538,11 @@
 					memmove(ssl->dataBuf, ssl->dataBuf + (ssl->dataLen - extra), extra);
 					ssl->dataLen = extra;
 				} else ssl->dataLen = 0;
-
+				
 				/* Don't return zero (SQSSL_OK) when more data is needed */
 				return count ? count : SQSSL_NEED_MORE_DATA;
 			default:
-				if(ssl->loglevel) printf("Unexpected return code %d\n", ret);
+				if(ssl->loglevel) printf("Unexpected return code %lu\n", (unsigned long)ret);
 				return SQSSL_GENERIC_ERROR;
 		}
 	}
@@ -799,6 +821,7 @@
 	switch(propID) {
 		case SQSSL_PROP_PEERNAME:  return ssl->peerName;
 		case SQSSL_PROP_CERTNAME:  return ssl->certName;
+		case SQSSL_PROP_SERVERNAME: return ssl->serverName;
 		default:
 			if(ssl->loglevel) printf("sqGetStringPropertySSL: Unknown property ID %d\n", propID);
 			return NULL;
@@ -838,7 +861,7 @@
 	if(!pfxStore) return 0;
 
 	/* And copy the certificates to MY store */
-	myStore = CertOpenSystemStore(0, "MY");
+	myStore = CertOpenSystemStore(0, L"MY");
 	pContext = NULL;
 	while(pContext = CertEnumCertificatesInStore(pfxStore, pContext)) {
 		CertAddCertificateContextToStore(myStore, pContext, CERT_STORE_ADD_REPLACE_EXISTING, NULL);
@@ -865,16 +888,27 @@
 	if(propLen) {
 	  property = calloc(1, propLen+1);
 	  memcpy(property, propName, propLen);
+	  property[propLen] = '\0';
 	};
 
-	if(ssl->loglevel) printf("sqSetStringPropertySSL(%d): %s\n", propID, property);
+	if(ssl->loglevel) printf("sqSetStringPropertySSL(%d): %s\n", propID, property ? property : "(null)");
 
 	switch(propID) {
-		case SQSSL_PROP_CERTNAME: ssl->certName = property; break;
+		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;
 		/* Platform specific: Adds a .PFX file to MY certificate store w/o password.
 		   Useful for installing the default test certificate in SqueakSSL. */
-		case 10001: return sqAddPfxCertToStore(propName, propLen, NULL, 0);
-		default: 
+		case 10001:
+			if(property) free(property);
+			return sqAddPfxCertToStore(propName, propLen, NULL, 0);
+		default:
+			if(property) free(property);
 			if(ssl->loglevel) printf("sqSetStringPropertySSL: Unknown property ID %d\n", propID);
 			return 0;
 	}
@@ -894,7 +928,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);
@@ -911,6 +945,7 @@
 	Returns: Non-zero if successful.
 */
 sqInt sqSetIntPropertySSL(sqInt handle, sqInt propID, sqInt propValue) {
+
 	sqSSL *ssl = sslFromHandle(handle);
 	if(ssl == NULL) return 0;
 
@@ -920,5 +955,5 @@
 			if(ssl->loglevel) printf("sqSetIntPropertySSL: Unknown property ID %d\n", propID);
 			return 0;
 	}
-	return 0;
+	return 1;
 }



More information about the Vm-dev mailing list