Tuukka Norri avatar Tuukka Norri committed a16f3e9

libpq changes and stubs for certificate verification
- Added some code to the libpq patch to make it work as intended.
- Wrote stubs for creating a Security framework certificate, policies and trust objects.

Comments (0)

Files changed (9)

Framework/Framework.xcodeproj/project.pbxproj

 		5303239E088061EA0024E7EF /* PGTSConnectionQueries.m in Sources */ = {isa = PBXBuildFile; fileRef = 53BA4FDC08804EA000BFAFB5 /* PGTSConnectionQueries.m */; };
 		530323C5088062270024E7EF /* NDRunLoopMessenger.h in Headers */ = {isa = PBXBuildFile; fileRef = 530323C3088062270024E7EF /* NDRunLoopMessenger.h */; };
 		530323C6088062270024E7EF /* NDRunLoopMessenger.m in Sources */ = {isa = PBXBuildFile; fileRef = 530323C4088062270024E7EF /* NDRunLoopMessenger.m */; };
+		531266140B68E28100637EDA /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 531266130B68E28100637EDA /* Security.framework */; };
+		5312665D0B68F23C00637EDA /* PGTSSertificateVerificationDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 5312665B0B68F23C00637EDA /* PGTSSertificateVerificationDelegate.h */; };
+		5312665E0B68F23C00637EDA /* PGTSSertificateVerificationDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5312665C0B68F23C00637EDA /* PGTSSertificateVerificationDelegate.m */; };
 		531746A7095C07E00098D3D5 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0867D69BFE84028FC02AAC07 /* Foundation.framework */; };
 		53298DE00B3307A800DE7CC8 /* PGTSRoleDescription.h in Headers */ = {isa = PBXBuildFile; fileRef = 53298DDE0B3307A800DE7CC8 /* PGTSRoleDescription.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		53298DE10B3307A800DE7CC8 /* PGTSRoleDescription.m in Sources */ = {isa = PBXBuildFile; fileRef = 53298DDF0B3307A800DE7CC8 /* PGTSRoleDescription.m */; };
 			isa = PBXContainerItemProxy;
 			containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
 			proxyType = 1;
-			remoteGlobalIDString = 53DBE6EA0B661CE800C3D20A /* PostgreSQL-8.2.1 */;
+			remoteGlobalIDString = 53DBE6EA0B661CE800C3D20A;
 			remoteInfo = "PostgreSQL-8.2.1";
 		};
 		53F524D50A51A28900E7DDC4 /* PBXContainerItemProxy */ = {
 		530323C3088062270024E7EF /* NDRunLoopMessenger.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = NDRunLoopMessenger.h; path = Contrib/NDRunLoopMessenger.h; sourceTree = "<group>"; };
 		530323C4088062270024E7EF /* NDRunLoopMessenger.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; name = NDRunLoopMessenger.m; path = Contrib/NDRunLoopMessenger.m; sourceTree = "<group>"; };
 		5304E3FC09575374004D0C0F /* TSDataTypes.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = TSDataTypes.xcodeproj; path = ../Dependencies/TSDataTypes/TSDataTypes.xcodeproj; sourceTree = SOURCE_ROOT; };
+		531266130B68E28100637EDA /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = /System/Library/Frameworks/Security.framework; sourceTree = "<absolute>"; };
+		5312665B0B68F23C00637EDA /* PGTSSertificateVerificationDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PGTSSertificateVerificationDelegate.h; path = Sources/PGTSSertificateVerificationDelegate.h; sourceTree = "<group>"; };
+		5312665C0B68F23C00637EDA /* PGTSSertificateVerificationDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PGTSSertificateVerificationDelegate.m; path = Sources/PGTSSertificateVerificationDelegate.m; sourceTree = "<group>"; };
 		5325EAD70A1B2EF600FEA842 /* postgresql */ = {isa = PBXFileReference; lastKnownFileType = folder; name = postgresql; path = "PGTS-PostgreSQL/postgresql"; sourceTree = BUILT_PRODUCTS_DIR; };
 		53298DDE0B3307A800DE7CC8 /* PGTSRoleDescription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PGTSRoleDescription.h; path = Sources/PGTSRoleDescription.h; sourceTree = "<group>"; };
 		53298DDF0B3307A800DE7CC8 /* PGTSRoleDescription.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PGTSRoleDescription.m; path = Sources/PGTSRoleDescription.m; sourceTree = "<group>"; };
 				53E11A100A7919CE00D0107C /* ExceptionHandling.framework in Frameworks */,
 				53594D1C0B13711300378707 /* libpq.a in Frameworks */,
 				53D0441D0B4C1E0300DB9308 /* libLog4Cocoa.a in Frameworks */,
+				531266140B68E28100637EDA /* Security.framework in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 				534CFECB095DCCDC00BF3440 /* Kerberos.framework */,
 				53A422880981B84C003C3A24 /* libcrypto.dylib */,
 				53F4F5100A370F16004913AF /* libssl.dylib */,
+				531266130B68E28100637EDA /* Security.framework */,
 			);
 			name = "Linked Frameworks";
 			sourceTree = "<group>";
 				53BA4FDB08804EA000BFAFB5 /* PGTSAdditions.m */,
 				536B892D0A518E4A00379C00 /* PGTSExceptions.h */,
 				536B892E0A518E4A00379C00 /* PGTSExceptions.m */,
+				5312665B0B68F23C00637EDA /* PGTSSertificateVerificationDelegate.h */,
+				5312665C0B68F23C00637EDA /* PGTSSertificateVerificationDelegate.m */,
 			);
 			name = Other;
 			sourceTree = "<group>";
 				53298DE00B3307A800DE7CC8 /* PGTSRoleDescription.h in Headers */,
 				53298DF20B330B6F00DE7CC8 /* PGTSAbstractObjectDescription.h in Headers */,
 				53298E0F0B330EFB00DE7CC8 /* PGTSACLItem.h in Headers */,
+				5312665D0B68F23C00637EDA /* PGTSSertificateVerificationDelegate.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			shellScript = "my_build_dir=\"$BUILT_PRODUCTS_DIR\"/PGTS-PostgreSQL\nversion=\"8.2.1\"\npostgresql_source_file=\"postgresql-base-${version}.tar.bz2\"\npostgresql_root=\"${my_build_dir}/postgresql-${version}\"\n\nfunction extract\n{\n    # Extract the sources\n    if [ ! -d \"$postgresql_root\" ]\n    then\n        if [ -e \"$postgresql_root\" ]\n        then\n            echo \"A file named ${postgresql_root} exists and is not a folder. Exiting.\"\n            exit 1\n        fi\n        gnutar -jxf \"$postgresql_source_file\" -C \"$my_build_dir\"\n\t   patch -p0 -d \"$my_build_dir\" < \"$SRCROOT\"/libpq.patch\n    fi\n}\n\nfunction build\n{\n    ptype=`uname -p`\n    my_host=\n    my_target=\"$1\"\n    if [ -z \"$my_target\" ]\n    then\n        my_target=\"$ptype\"\n    fi\n\n\tunset CC\n\tunset CPP\n\tunset CFLAGS\n\tunset CPPFLAGS\n\tunset CXXFLAGS\n\tunset LDFLAGS\n\n    if [ \"powerpc\" = \"$my_target\" ]\n    then\n        export CFLAGS=\"-arch ppc\"\n        export CPPFLAGS=\"-isystem=/Developer/SDKs/MacOSX10.4u.sdk\"\n        export LDFLAGS=\"-Wl,-syslibroot,/Developer/SDKs/MacOSX10.4u.sdk\"\n\n        if [ \"i386\" = \"$ptype\" ]\n        then\n            my_host=\"--host=powerpc-apple-darwin8.6.0\"\n        fi\n    elif [ \"i386\" = \"$my_target\" ]\n    then\n        export CFLAGS=\"-arch i386\"\n        export CPPFLAGS=\"-isystem=/Developer/SDKs/MacOSX10.4u.sdk\"\n        export LDFLAGS=\"-Wl,-syslibroot,/Developer/SDKs/MacOSX10.4u.sdk\"\n\n        if [ \"powerpc\" = \"$ptype\" ]\n        then\n            my_host=\"--host=i386-apple-darwin8.6.0\"\n        fi\n    else\n        echo \"Unsupported architecture $my_target\"\n        exit 1\n    fi\n\n    pushd \"$postgresql_root\"\n\tmake distclean 2> /dev/null\n\techo \"Configure options: $my_host --with-bonjour --disable-shared \\\n    \t--without-zlib --without-readline --prefix=$my_build_dir/$my_target\"\n    ./configure $my_host --with-bonjour --disable-shared \\\n    \t--without-zlib --without-readline --prefix=$my_build_dir/\"$my_target\"\n    make clean 2> /dev/null\n\n    mkdir -p ../\"$my_target\"\n\n\t## PG 8.2 doesn't like to be built piece by piece.\n\tmake -j 4 2> /dev/null\n\n    for x in src/include src/interfaces/libpq src/bin/psql\n    do\n        pushd \"$x\"\n        make install\n        popd\n    done\n    \n    popd\n}\n\nif [ ! -e \"$my_build_dir\"/universal/lib/libpq.a ] || \\\n   [ ! -e \"$my_build_dir\"/universal/bin/psql ] ||\n   [ ! -e \"$my_build_dir\"/postgresql ]\nthen\n\tmkdir -p \"$my_build_dir\"\n\tpushd \"$SRCROOT\"/Contrib/PostgreSQL\n\textract\n\n\tif [ ! -e \"$my_build_dir\"/powerpc/lib/libpq.a ] || [ ! -e \"$my_build_dir\"/powerpc/bin/psql ]\n\tthen\n\t    build powerpc\n\tfi\n\n\tif [ ! -e \"$my_build_dir\"/i386/lib/libpq.a ] || [ ! -e \"$my_build_dir\"/i386/bin/psql ]\n\tthen\n\t    build i386\n\tfi\n\n\tmkdir -p \"$my_build_dir\"/universal/bin\n\tmkdir -p \"$my_build_dir\"/universal/lib\n\tfor file in lib/libpq.a bin/psql\n\tdo\n\t    lipo -create -output \"$my_build_dir\"/universal/\"$file\" \\\n\t\t\t\"$my_build_dir\"/i386/\"$file\" \\\n\t\t\t\"$my_build_dir\"/powerpc/\"$file\"\n\tdone\n\tcp -R \"$my_build_dir\"/powerpc/include \"$my_build_dir\"/postgresql\n\t\"$postgresql_root\"/configure --version | head -n 1 > \"$my_build_dir\"/VERSION\n\n\tpopd\nfi\nexit 0\n";
+			shellScript = "my_build_dir=\"$BUILT_PRODUCTS_DIR\"/PGTS-PostgreSQL\nversion=\"8.2.1\"\npostgresql_source_file=\"postgresql-base-${version}.tar.bz2\"\npostgresql_root=\"${my_build_dir}/postgresql-${version}\"\n\nfunction extract\n{\n    # Extract the sources\n    if [ ! -d \"$postgresql_root\" ]\n    then\n        if [ -e \"$postgresql_root\" ]\n        then\n            echo \"A file named ${postgresql_root} exists and is not a folder. Exiting.\"\n            exit 1\n        fi\n        gnutar -jxf \"$postgresql_source_file\" -C \"$my_build_dir\"\n\t   patch -p0 -d \"$my_build_dir\" < \"$SRCROOT\"/libpq.patch\n    fi\n}\n\nfunction build\n{\n    ptype=`uname -p`\n    my_host=\n    my_target=\"$1\"\n    if [ -z \"$my_target\" ]\n    then\n        my_target=\"$ptype\"\n    fi\n\n\tunset CC\n\tunset CPP\n\tunset CFLAGS\n\tunset CPPFLAGS\n\tunset CXXFLAGS\n\tunset LDFLAGS\n\n    if [ \"powerpc\" = \"$my_target\" ]\n    then\n        export CFLAGS=\"-arch ppc\"\n        export CPPFLAGS=\"-isystem=/Developer/SDKs/MacOSX10.4u.sdk\"\n        export LDFLAGS=\"-Wl,-syslibroot,/Developer/SDKs/MacOSX10.4u.sdk\"\n\n        if [ \"i386\" = \"$ptype\" ]\n        then\n            my_host=\"--host=powerpc-apple-darwin8.6.0\"\n        fi\n    elif [ \"i386\" = \"$my_target\" ]\n    then\n        export CFLAGS=\"-arch i386\"\n        export CPPFLAGS=\"-isystem=/Developer/SDKs/MacOSX10.4u.sdk\"\n        export LDFLAGS=\"-Wl,-syslibroot,/Developer/SDKs/MacOSX10.4u.sdk\"\n\n        if [ \"powerpc\" = \"$ptype\" ]\n        then\n            my_host=\"--host=i386-apple-darwin8.6.0\"\n        fi\n    else\n        echo \"Unsupported architecture $my_target\"\n        exit 1\n    fi\n\n    pushd \"$postgresql_root\"\n    make distclean 2> /dev/null\n\n    if [ \"Debug\" = \"$BUILD_STYLE\" ]\n    then\n        echo \"Configure options: $my_host --with-bonjour --disable-shared \\\n        --without-zlib --without-readline --with-openssl --enable-debug \\ \n        --prefix=$my_build_dir/$my_target\"\n        ./configure $my_host --with-bonjour --disable-shared --enable-debug \\\n        --without-zlib --without-readline --with-openssl \\\n        --prefix=$my_build_dir/\"$my_target\"\n    else\n        echo \"Configure options: $my_host --with-bonjour --disable-shared \\\n        --without-zlib --without-readline --with-openssl \\ \n        --prefix=$my_build_dir/$my_target\"\n        ./configure $my_host --with-bonjour --disable-shared \\\n        --without-zlib --without-readline --with-openssl \\\n        --prefix=$my_build_dir/\"$my_target\"\n    fi\n\n    make clean 2> /dev/null\n\n    mkdir -p ../\"$my_target\"\n\n\t## PG 8.2 doesn't like to be built piece by piece.\n\tmake -j 4 2> /dev/null\n\n    for x in src/include src/interfaces/libpq src/bin/psql\n    do\n        pushd \"$x\"\n        make install\n        popd\n    done\n    \n    popd\n}\n\nif [ ! -e \"$my_build_dir\"/universal/lib/libpq.a ] || \\\n   [ ! -e \"$my_build_dir\"/universal/bin/psql ] ||\n   [ ! -e \"$my_build_dir\"/postgresql ]\nthen\n\tmkdir -p \"$my_build_dir\"\n\tpushd \"$SRCROOT\"/Contrib/PostgreSQL\n\textract\n\n\tif [ ! -e \"$my_build_dir\"/powerpc/lib/libpq.a ] || [ ! -e \"$my_build_dir\"/powerpc/bin/psql ]\n\tthen\n\t    build powerpc\n\tfi\n\n\tif [ ! -e \"$my_build_dir\"/i386/lib/libpq.a ] || [ ! -e \"$my_build_dir\"/i386/bin/psql ]\n\tthen\n\t    build i386\n\tfi\n\n\tmkdir -p \"$my_build_dir\"/universal/bin\n\tmkdir -p \"$my_build_dir\"/universal/lib\n\tfor file in lib/libpq.a bin/psql\n\tdo\n\t    lipo -create -output \"$my_build_dir\"/universal/\"$file\" \\\n\t\t\t\"$my_build_dir\"/i386/\"$file\" \\\n\t\t\t\"$my_build_dir\"/powerpc/\"$file\"\n\tdone\n\tcp -R \"$my_build_dir\"/powerpc/include \"$my_build_dir\"/postgresql\n\t\"$postgresql_root\"/configure --version | head -n 1 > \"$my_build_dir\"/VERSION\n\n\tpopd\nfi\nexit 0\n";
 		};
 		53E70DBE09824820001785B2 /* Framework Symlink */ = {
 			isa = PBXShellScriptBuildPhase;
 				53298DE10B3307A800DE7CC8 /* PGTSRoleDescription.m in Sources */,
 				53298DF30B330B6F00DE7CC8 /* PGTSAbstractObjectDescription.m in Sources */,
 				53298E100B330EFB00DE7CC8 /* PGTSACLItem.m in Sources */,
+				5312665E0B68F23C00637EDA /* PGTSSertificateVerificationDelegate.m in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

Framework/Sources/PGTSConnection.h

     volatile BOOL threadRunning;
     volatile BOOL failedToSendQuery;
     volatile BOOL messageDelegateAfterConnecting;
+	volatile BOOL sslSetUp;
 }
 
 + (PGTSConnection *) connection;

Framework/Sources/PGTSConnectionPrivate.m

 #import <sys/time.h>
 #import <unistd.h>
 #import <openssl/ssl.h>
+#import <Log4Cocoa/Log4Cocoa.h>
+#import "postgresql/libpq-fe.h"
 #import "TSRunloopMessenger.h"
 #import "PGTSConnectionPrivate.h"
 #import "PGTSConstants.h"
 #import "PGTSConnectionDelegate.h"
 #import "PGTSConnectionPool.h"
 #import "PGTSExceptions.h"
-#import <Log4Cocoa/Log4Cocoa.h>
+#import "PGTSFunctions.h"
 
 
+static int sslConnectionExIndex = -1;
+
+extern int PGTSVerifySSLSertificate (int preverify_ok, X509_STORE_CTX* x509_ctx);
+
 static NSNotification* 
 PGTSExtractPgNotification (id anObject, PGnotify* pgNotification)
 {
     return notification;
 }
 
+int
+PGTSSSLConnectionExIndex ()
+{
+	if (-1 == sslConnectionExIndex)
+		sslConnectionExIndex = SSL_get_ex_new_index (0, NULL, NULL, NULL, NULL);
+	return sslConnectionExIndex;
+}
 
 @interface NSObject (PGTSKeyValueObserving)
 + (BOOL) automaticallyNotifiesObserversForKey: (NSString *) key;
         log4Error (@"Unable to get connection socket from libpq");
     else
     {
+		sslSetUp = NO;
         if (YES == reset)
         {
             [socket closeFile];
             FD_SET (bsdSocket, &mask);
             selectStatus = 0;
             pollingStatus = pollFunction (connection);
-            
+
+#ifdef USE_SSL
+			if (NO == sslSetUp && CONNECTION_SSL_CONTINUE == PQstatus (connection))
+			{
+				sslSetUp = YES;
+				SSL* ssl = PQgetssl (connection);
+				NSAssert (NULL != ssl, @"Expected ssl struct not to be NULL.");
+				SSL_set_verify (ssl, SSL_VERIFY_PEER, &PGTSVerifySSLSertificate);
+				SSL_set_ex_data (ssl, PGTSSSLConnectionExIndex(), self);
+			}
+#endif
+			
             switch (pollingStatus)
             {
                 case PGRES_POLLING_OK:
                     break;
                     
                 case PGRES_POLLING_WRITING:
-                default:
-#ifdef USE_SSL
-					if (CONNECTION_SSL_CONTINUE == PQstatus (conn))
-					{
-						SSL* ssl = PQgetSSL (conn);
-						NSAssert (NULL != ssl, @"Expected ssl struct not to be NULL.");
-						SSL_set_verify (ssl, SSL_VERIFY_PEER, &PGTSVerifySSLCertificate);
-						//We have this hack since the cert callback cannot have a void* argument.
-						//SSL_get_ex_new_index probably doesn't help here since the index might change across SSL structures.
-						SSL_set_msg_callback_arg (ssl, self);
-					}
-#endif
-					
+                default:					
                     selectStatus = select (bsdSocket + 1, NULL, &mask, NULL, &ltimeout);
                     break;
             } //switch

Framework/Sources/PGTSFunctions.h

 extern void PGTSNoticeProcessor (void* sender, const char* message);
 extern NSString* PGTSModificationName (unichar type);
 extern NSString* PGTSLockOperation (unichar type);
-extern int PGTSVerifySSLSertificate (int preverify_ok, void* x509_ctx);
+extern int PGTSSSLConnectionExIndex ();

Framework/Sources/PGTSFunctions.m

 #import <Foundation/Foundation.h>
 #import <openssl/x509.h>
 #import <openssl/ssl.h>
+#import <Security/Security.h>
 #import "postgresql/libpq-fe.h"
 #import "PGTSFunctions.h"
 #import "PGTSConstants.h"
                 }
                 option++;
             }
-            kPGTSConnectionDictionaryKeys = [keys copy];            
+            kPGTSConnectionDictionaryKeys = [keys copy];
+			
+			//sslmode is disable by default??
+			[(NSMutableDictionary *) kPGTSDefaultConnectionDictionary setObject: @"prefer" forKey: @"sslmode"];
         }
         [pool release];
     }
     return lockOperation;
 }
 
+
+inline CSSM_CERT_TYPE
+x509Version (X509* x509Cert)
+{
+	CSSM_CERT_TYPE rval = CSSM_CERT_X_509v3;
+	switch (X509_get_version (x509Cert))
+	{
+		case 1:
+			rval = CSSM_CERT_X_509v1;
+			break;
+		case 2:
+			rval = CSSM_CERT_X_509v2;
+			break;
+		case 3:
+		default:
+			break;
+	}
+	return rval;
+}
+
+inline SecCertificateRef
+SecCertificateFromX509 (X509* opensslCert, BIO* bioOutput)
+{
+	SecCertificateRef cert = NULL;
+	if (i2d_X509_bio (bioOutput, opensslCert))
+	{
+		BUF_MEM* bioBuffer = NULL;
+		BIO_get_mem_ptr (bioOutput, &bioBuffer);
+		
+		OSStatus status = SecCertificateCreateFromData ((void *) bioBuffer->data, x509Version (opensslCert), CSSM_CERT_ENCODING_DER, &cert);
+		status = noErr;
+	}
+	return cert;
+}
+
+/**
+ * \internal
+ * Verify an X.509 certificate.
+ * Get the X.509 certificate from OpenSSL, encode it in DER format and let Security framework parse it again.
+ * This way, we can use the Keychain to verify the certificate, since a CA trusted by the OS or the user
+ * might have signed it or the user could have stored the certificate earlier. The preverification result
+ * is ignored because it rejects certificates from CAs unknown to OpenSSL. 
+ */
 int
 PGTSVerifySSLSertificate (int preverify_ok, void* x509_ctx)
 {
-    SSL* ssl = X509_STORE_CTX_get_ex_data ((X509_STORE_CTX *) x509_ctx, SSL_get_ex_data_X509_STORE_CTX_idx ());
-	PGTSConnection* connection = ssl->msg_callback_arg;
-	connection = nil;
 	return preverify_ok;
+#if 0 
+	int rval = 0;
+	SSL* ssl = X509_STORE_CTX_get_ex_data ((X509_STORE_CTX *) x509_ctx, SSL_get_ex_data_X509_STORE_CTX_idx ());
+	PGTSConnection* connection = SSL_get_ex_data (ssl, PGTSSSLConnectionExIndex ());
+	
+	//FIXME: move these into the delegate object and make the API such that X509 structure can also be used
+	//when verifying.
+	BIO* bioOutput = BIO_new (BIO_s_mem ());
+	
+	int count = M_sk_num (x509_ctx->untrusted);
+	NSMutableArray* certs = [NSMutableArray arrayWithCapacity: count + 1];
+	SecCertificateRef serverCert = CertificateFromX509 (x509_ctx->cert, bioOutput);
+	[certs addObject: serverCert];
+	
+	for (int i = 0; i < count; i++)
+	{
+		BIO_reset (bioOutput);
+		SecCertificateRef chainCert = CertificateFromX509 (M_sk_value (x509_ctx->untrusted, i));
+		[certs addObject: chainCert];
+	}
+	
+	SecTrustRef trust = NULL;
+	OSStatus status = SecTrustCreateWithCertificates (certs,<#CFTypeRef policies#>, &trust);
+
+	BIO_free (bioOutput);
+	return rval;
+#endif
 }

Framework/Sources/PGTSSertificateVerificationDelegate.h

+//
+// PGTSSertificateVerificationDelegate.h
+// BaseTen
+//
+// Copyright (C) 2006 Marko Karppinen & Co. LLC.
+//
+// Before using this software, please review the available licensing options
+// by visiting http://www.karppinen.fi/baseten/licensing/ or by contacting
+// us at sales@karppinen.fi. Without an additional license, this software
+// may be distributed only in compliance with the GNU General Public License.
+//
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License, version 2.0,
+// as published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+// $Id$
+//
+
+#import <Foundation/Foundation.h>
+
+@interface PGTSSertificateVerificationDelegate : NSObject 
+{
+	NSMutableArray* mPolicies;
+}
+
+@end

Framework/Sources/PGTSSertificateVerificationDelegate.m

+//
+// PGTSSertificateVerificationDelegate.m
+// BaseTen
+//
+// Copyright (C) 2006 Marko Karppinen & Co. LLC.
+//
+// Before using this software, please review the available licensing options
+// by visiting http://www.karppinen.fi/baseten/licensing/ or by contacting
+// us at sales@karppinen.fi. Without an additional license, this software
+// may be distributed only in compliance with the GNU General Public License.
+//
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License, version 2.0,
+// as published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+// $Id: PGTSFunctions.m 101 2007-01-23 16:25:46Z tuukka.norri@karppinen.fi $
+//
+
+#import "PGTSSertificateVerificationDelegate.h"
+#import <Security/Security.h>
+
+
+@implementation PGTSSertificateVerificationDelegate
+
+- (id) init
+{
+	return nil;
+}
+
+- (void) dealloc
+{
+	[mPolicies release];
+	[super dealloc];
+}
+
+/*
+ * To verify a certificate, we need to
+ * create a trust. To create a trust, we need to find search policies. To find search policies, we need to create
+ * a search criteria. To create a search criteria, we need to give the criteria creation function some constants.
+ */
+- (NSArray *) policies
+{
+	if (nil == mPolicies)
+	{
+		//FIXME: this doesn't compile :(
+#if 0
+		OSStatus status = noErr;
+	
+		mPolicies = [[NSMutableArray alloc] init];
+		int i = 0;
+		CSSM_OID currentOid;
+		CSSM_OID* oids = {CSSMOID_APPLE_TP_SSL, CSSMOID_APPLE_TP_REVOCATION_CRL, NULL};
+		while (NULL != (currentOid = oids [i]))
+		{
+			SecPolicySearchRef criteria = NULL;
+			SecPolicyRef policy = NULL;
+			status = SecPolicySearchCreate (CSSM_CERT_X_509v3, currentOid, NULL, &criteria);
+			while (noErr == SecPolicySearchCopyNext (criteria, &policy))
+			{
+				[policies addObject: policy];
+				CFRelease (policy);
+			}
+			CFRelease (criteria);
+		}
+#endif
+	}
+	return mPolicies;
+}
+
+@end

Framework/libpq.patch

 
 diff -urN postgresql-8.2.1/src/interfaces/libpq/fe-connect.c postgresql-8.2.1-tsnorri/src/interfaces/libpq/fe-connect.c
 --- postgresql-8.2.1/src/interfaces/libpq/fe-connect.c	2006-11-21 18:28:00.000000000 +0200
-+++ postgresql-8.2.1-tsnorri/src/interfaces/libpq/fe-connect.c	2007-01-23 16:26:52.000000000 +0200
-@@ -1305,13 +1305,17 @@
++++ postgresql-8.2.1-tsnorri/src/interfaces/libpq/fe-connect.c	2007-01-25 11:52:27.000000000 +0200
+@@ -998,6 +998,7 @@
+ 
+ 			/* Special cases: proceed without waiting. */
+ 		case CONNECTION_SSL_STARTUP:
++        case CONNECTION_SSL_CONTINUE:
+ 		case CONNECTION_NEEDED:
+ 			break;
+ 
+@@ -1305,13 +1306,17 @@
  		case CONNECTION_SSL_STARTUP:
  			{
  #ifdef USE_SSL
  				{
  					/*
  					 * We use pqReadData here since it has the logic to
-@@ -1344,6 +1348,9 @@
+@@ -1344,6 +1349,9 @@
  						/* Do one-time setup; this creates conn->ssl */
  						if (pqsecure_initialize(conn) == -1)
  							goto error_return;
 +
 +                        conn->status = CONNECTION_SSL_CONTINUE;
-+                        return PGRES_POLLING_WRITING; //Is this correct?
++                        return pqsecure_prepare_client (conn);
  					}
  					else if (SSLok == 'N')
  					{
-@@ -1390,10 +1397,18 @@
+@@ -1390,10 +1398,18 @@
  					}
  				}
  
  				if (pollres == PGRES_POLLING_OK)
  				{
  					/* SSL handshake done, ready to send startup packet */
+diff -urN postgresql-8.2.1/src/interfaces/libpq/fe-secure.c postgresql-8.2.1-tsnorri/src/interfaces/libpq/fe-secure.c
+--- postgresql-8.2.1/src/interfaces/libpq/fe-secure.c	2006-10-06 20:14:01.000000000 +0300
++++ postgresql-8.2.1-tsnorri/src/interfaces/libpq/fe-secure.c	2007-01-25 11:21:24.000000000 +0200
+@@ -193,10 +193,10 @@
+ }
+ 
+ /*
+- *	Attempt to negotiate secure session.
++ *  Set conn->ssl.
+  */
+ PostgresPollingStatusType
+-pqsecure_open_client(PGconn *conn)
++pqsecure_prepare_client(PGconn *conn)
+ {
+ #ifdef USE_SSL
+ 	/* First time through? */
+@@ -221,7 +221,21 @@
+ 		 * detect whether client_cert_cb() has stored a message.
+ 		 */
+ 		resetPQExpBuffer(&conn->errorMessage);
+-	}
++    }
++    return PGRES_POLLING_WRITING; //Is this correct?
++#else
++	/* shouldn't get here */
++	return PGRES_POLLING_FAILED;
++#endif
++}
++
++/*
++ *	Attempt to negotiate secure session.
++ */
++PostgresPollingStatusType
++pqsecure_open_client(PGconn *conn)
++{
++#ifdef USE_SSL
+ 	/* Begin or continue the actual handshake */
+ 	return open_client_SSL(conn);
+ #else
 diff -urN postgresql-8.2.1/src/interfaces/libpq/libpq-fe.h postgresql-8.2.1-tsnorri/src/interfaces/libpq/libpq-fe.h
 --- postgresql-8.2.1/src/interfaces/libpq/libpq-fe.h	2006-10-04 03:30:13.000000000 +0300
 +++ postgresql-8.2.1-tsnorri/src/interfaces/libpq/libpq-fe.h	2007-01-23 16:36:58.000000000 +0200
  } ConnStatusType;
  
  typedef enum
+diff -urN postgresql-8.2.1/src/interfaces/libpq/libpq-int.h postgresql-8.2.1-tsnorri/src/interfaces/libpq/libpq-int.h
+--- postgresql-8.2.1/src/interfaces/libpq/libpq-int.h	2006-10-04 03:30:13.000000000 +0300
++++ postgresql-8.2.1-tsnorri/src/interfaces/libpq/libpq-int.h	2007-01-25 11:33:41.000000000 +0200
+@@ -485,6 +485,7 @@
+ 
+ extern int	pqsecure_initialize(PGconn *);
+ extern void pqsecure_destroy(void);
++extern PostgresPollingStatusType pqsecure_prepare_client(PGconn *);
+ extern PostgresPollingStatusType pqsecure_open_client(PGconn *);
+ extern void pqsecure_close(PGconn *);
+ extern ssize_t pqsecure_read(PGconn *, void *ptr, size_t len);
+

Framework/xcconfig/basic.xcconfig

 INFOPLIST_FILE = Info.plist
 GCC_PREFIX_HEADER = Sources/PGTS_Prefix.pch
 DSTROOT = /
-OTHER_CFLAGS = -DPGTS_SCHEMA_NAME=\"baseten\"
+OTHER_CFLAGS = -DPGTS_SCHEMA_NAME=\"baseten\" -DUSE_SSL
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.