コード例 #1
0
OSStatus SecKeychainItemSetAccessWithPassword(SecKeychainItemRef itemRef, SecAccessRef accessRef, UInt32 passwordLength, const void * password)
{
    BEGIN_SECKCITEMAPI

    OSStatus result;

    // try to unlock the keychain with this password first
    SecKeychainRef kc = NULL;
    result = SecKeychainItemCopyKeychain(__itemImplRef, &kc);
    if(!result) {
        SecKeychainUnlock(kc, passwordLength, password, true);
        if(kc) {
            CFRelease(kc);
        }
    }

    // Create some credentials with this password
    CssmAutoData data(Allocator::standard(), password, passwordLength);
    AclFactory::PassphraseUnlockCredentials cred(data, Allocator::standard());

    Access::required(accessRef)->editAccess(*aclBearer(reinterpret_cast<CFTypeRef>(__itemImplRef)), true, cred.getAccessCredentials());
    ItemImpl::required(itemRef)->postItemEvent (kSecUpdateEvent);

    END_SECKCITEMAPI
}
コード例 #2
0
ファイル: TokenIDHelper.cpp プロジェクト: Proteas/codesign
int unlockToken(const char *password)
{
	OSStatus status = noErr;
	if (!password)
		return paramErr;

	CFArrayRef searchList = NULL;

	status = SecKeychainCopyDomainSearchList(kSecPreferencesDomainDynamic, &searchList);
	if (status)
		return status;
		
	CFIndex count = searchList ? CFArrayGetCount(searchList) : 0;
	if (count)
	{
		SecKeychainRef keychainRef = (SecKeychainRef)CFArrayGetValueAtIndex(searchList, 0);	// only first dynamic keychain!
		status = SecKeychainUnlock(keychainRef, (UInt32)strlen(password), password, 1);
		if (keychainRef)
			CFRelease(keychainRef);
	}
	else
		status = errSecNoSuchKeychain;
	if (searchList)
		CFRelease(searchList);
	return status;
}
コード例 #3
0
ファイル: keychain.c プロジェクト: fcheung/keychain_c
static VALUE rb_keychain_unlock(int argc, VALUE *argv, VALUE self){
  SecKeychainRef keychain=NULL;
  Data_Get_Struct(self, struct OpaqueSecKeychainRef, keychain);

  VALUE password;
  rb_scan_args(argc, argv, "01", &password);

  OSStatus result = noErr;
  if(password){
    StringValue(password);
    password = rb_str_export_to_enc(password, rb_utf8_encoding());

    result = SecKeychainUnlock(keychain, (UInt32)RSTRING_LEN(password), (UInt8*)RSTRING_PTR(password), true);
  }else{
    result = SecKeychainUnlock(keychain,0,NULL,false);
  }

  CheckOSStatusOrRaise(result);

  return Qnil;
}
コード例 #4
0
ファイル: keychain_crack.c プロジェクト: kholia/thesis
int main(void)
{
	OSStatus err;
	char passphrase[128];

	/* attack default keychain */
	SecKeychainRef keychain = NULL;

	/* argv[1] contains target keychain's name */
	while(fgets(passphrase, 128, stdin) != NULL) {
		err = SecKeychainUnlock(keychain,
				strlen(password), password, TRUE);
		if (!err) {
			printf ("Password Found : %s\n", password);
			exit(0);
		}
	}
}
コード例 #5
0
int main(int argc, char **argv)
{
	bool verbose = false;
	
	int arg;
	while ((arg = getopt(argc, argv, "vh")) != -1) {
		switch (arg) {
			case 'v':
				verbose = true;
				break;
			case 'h':
				usage(argv);
		}
	}
	if(optind != argc) {
		usage(argv);
	}
	
	printNoDialog();
	
	/* initial setup */
	verboseDisp(verbose, "deleting keychain");
	unlink(KEYCHAIN_NAME);
	
	verboseDisp(verbose, "creating keychain");
	SecKeychainRef kcRef = NULL;
	OSStatus ortn = SecKeychainCreate(KEYCHAIN_NAME, 
		strlen(KEYCHAIN_PWD), KEYCHAIN_PWD,
		false, NULL, &kcRef);
	if(ortn) {
		cssmPerror("SecKeychainCreate", ortn);
		exit(1);
	}

	/* 
	 * 1. Generate key pair with cleartext public key.
	 *    Ensure we can use the public key when keychain is locked with no
	 *    user interaction.  
	 */
	 
	/* generate key pair, cleartext public key */
	verboseDisp(verbose, "creating key pair, cleartext public key");
	SecKeyRef pubKeyRef = NULL;
	SecKeyRef privKeyRef = NULL;
	if(genKeyPair(false, kcRef, &pubKeyRef, &privKeyRef)) {
		exit(1);
	}
	
	/* Use generated cleartext public key with locked keychain */
	verboseDisp(verbose, "locking keychain, exporting public key");
	SecKeychainLock(kcRef);
	CFDataRef exportData = NULL;
	ortn = SecKeychainItemExport(pubKeyRef, kSecFormatOpenSSL, 0, NULL, &exportData);
	if(ortn) {
		cssmPerror("SecKeychainCreate", ortn);
		exit(1);
	}
	CFRelease(exportData);
	
	verboseDisp(verbose, "locking keychain, encrypting with public key");
	SecKeychainLock(kcRef);
	if(pubKeyEncrypt(pubKeyRef)) {
		exit(1);
	}

	/* reset */
	verboseDisp(verbose, "deleting keys");
	ortn = SecKeychainItemDelete((SecKeychainItemRef)pubKeyRef);
	if(ortn) {
		cssmPerror("SecKeychainItemDelete", ortn);
		exit(1);
	}
	ortn = SecKeychainItemDelete((SecKeychainItemRef)privKeyRef);
	if(ortn) {
		cssmPerror("SecKeychainItemDelete", ortn);
		exit(1);
	}
	CFRelease(pubKeyRef);
	CFRelease(privKeyRef);

	/* 
	 * 2. Generate key pair with encrypted public key.
	 *    Ensure that user interaction is required when we use the public key 
	 *    when keychain is locked.
	 */

	verboseDisp(verbose, "programmatically unlocking keychain");
	ortn = SecKeychainUnlock(kcRef, strlen(KEYCHAIN_PWD), KEYCHAIN_PWD, TRUE);
	if(ortn) {
		cssmPerror("SecKeychainItemDelete", ortn);
		exit(1);
	}
	
	/* generate key pair, encrypted public key */
	verboseDisp(verbose, "creating key pair, encrypted public key");
	if(genKeyPair(true, kcRef, &pubKeyRef, &privKeyRef)) {
		exit(1);
	}

	/* Use generated encrypted public key with locked keychain */
	verboseDisp(verbose, "locking keychain, exporting public key");
	SecKeychainLock(kcRef);
	printExpectDialog();
	ortn = SecKeychainItemExport(pubKeyRef, kSecFormatOpenSSL, 0, NULL, &exportData);
	if(ortn) {
		cssmPerror("SecKeychainCreate", ortn);
		exit(1);
	}
	/* we'll use that exported blob later to test import */
	if(!didGetDialog()) {
		exit(1);
	}
	
	verboseDisp(verbose, "locking keychain, encrypting with public key");
	SecKeychainLock(kcRef);
	printExpectDialog();
	if(pubKeyEncrypt(pubKeyRef)) {
		exit(1);
	}
	if(!didGetDialog()) {
		exit(1);
	}

	/* reset */
	printNoDialog();
	verboseDisp(verbose, "locking keychain");
	SecKeychainLock(kcRef);
	verboseDisp(verbose, "deleting keys");
	ortn = SecKeychainItemDelete((SecKeychainItemRef)pubKeyRef);
	if(ortn) {
		cssmPerror("SecKeychainItemDelete", ortn);
		exit(1);
	}
	ortn = SecKeychainItemDelete((SecKeychainItemRef)privKeyRef);
	if(ortn) {
		cssmPerror("SecKeychainItemDelete", ortn);
		exit(1);
	}
	CFRelease(pubKeyRef);
	CFRelease(privKeyRef);

	/* 
	 * 3. Import public key, storing in cleartext. Ensure that the import
	 *    doesn't require unlock, and ensure we can use the public key 
	 *    when keychain is locked with no user interaction.  
	 */

	printNoDialog();
	verboseDisp(verbose, "locking keychain");
	SecKeychainLock(kcRef);

	/* import public key - default is in the clear */
	verboseDisp(verbose, "importing public key, store in the clear (default)");
	CFArrayRef outArray = NULL;
	SecExternalFormat format = kSecFormatOpenSSL;
	SecExternalItemType type = kSecItemTypePublicKey;
	ortn = SecKeychainItemImport(exportData, 
		NULL, &format, &type,
		0, NULL,
		kcRef, &outArray);
	if(ortn) {
		cssmPerror("SecKeychainItemImport", ortn);
		exit(1);
	}
	CFRelease(exportData);
	if(CFArrayGetCount(outArray) != 1) {
		printf("***Unexpected outArray size (%ld) after import\n",
			(long)CFArrayGetCount(outArray));
		exit(1);
	}
	pubKeyRef = (SecKeyRef)CFArrayGetValueAtIndex(outArray, 0);
	if(CFGetTypeID(pubKeyRef) != SecKeyGetTypeID()) {
		printf("***Unexpected item type after import\n");
		exit(1);
	}
	
	/* Use imported cleartext public key with locked keychain */
	verboseDisp(verbose, "locking keychain, exporting public key");
	SecKeychainLock(kcRef);
	exportData = NULL;
	ortn = SecKeychainItemExport(pubKeyRef, kSecFormatOpenSSL, 0, NULL, &exportData);
	if(ortn) {
		cssmPerror("SecKeychainItemExport", ortn);
		exit(1);
	}
	/* we'll use exportData again */
	
	verboseDisp(verbose, "locking keychain, encrypting with public key");
	SecKeychainLock(kcRef);
	if(pubKeyEncrypt(pubKeyRef)) {
		exit(1);
	}

	/* reset */
	verboseDisp(verbose, "deleting key");
	ortn = SecKeychainItemDelete((SecKeychainItemRef)pubKeyRef);
	if(ortn) {
		cssmPerror("SecKeychainItemDelete", ortn);
		exit(1);
	}
	CFRelease(pubKeyRef);
	
	/* 
	 * Import public key, storing in encrypted form.
	 * Ensure that user interaction is required when we use the public key 
	 * when keychain is locked.
	 */

	/* import public key, encrypted in the keychain */
	SecKeyImportExportParameters impExpParams;
	memset(&impExpParams, 0, sizeof(impExpParams));
	impExpParams.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION;
	impExpParams.keyAttributes = CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_EXTRACTABLE | 
								 CSSM_KEYATTR_PERMANENT | CSSM_KEYATTR_PUBLIC_KEY_ENCRYPT;
	verboseDisp(verbose, "importing public key, store encrypted");
	printExpectDialog();
	outArray = NULL;
	format = kSecFormatOpenSSL;
	type = kSecItemTypePublicKey;
	ortn = SecKeychainItemImport(exportData, 
		NULL, &format, &type,
		0, &impExpParams,
		kcRef, &outArray);
	if(ortn) {
		cssmPerror("SecKeychainItemImport", ortn);
		exit(1);
	}
	if(!didGetDialog()) {
		exit(1);
	}
	CFRelease(exportData);
	if(CFArrayGetCount(outArray) != 1) {
		printf("***Unexpected outArray size (%ld) after import\n",
			(long)CFArrayGetCount(outArray));
		exit(1);
	}
	pubKeyRef = (SecKeyRef)CFArrayGetValueAtIndex(outArray, 0);
	if(CFGetTypeID(pubKeyRef) != SecKeyGetTypeID()) {
		printf("***Unexpected item type after import\n");
		exit(1);
	}
					
	/* Use imported encrypted public key with locked keychain */
	verboseDisp(verbose, "locking keychain, exporting public key");
	SecKeychainLock(kcRef);
	printExpectDialog();
	ortn = SecKeychainItemExport(pubKeyRef, kSecFormatOpenSSL, 0, NULL, &exportData);
	if(ortn) {
		cssmPerror("SecKeychainItemExport", ortn);
		exit(1);
	}
	if(!didGetDialog()) {
		exit(1);
	}
	CFRelease(exportData);
	
	verboseDisp(verbose, "locking keychain, encrypting with public key");
	SecKeychainLock(kcRef);
	printExpectDialog();
	if(pubKeyEncrypt(pubKeyRef)) {
		exit(1);
	}
	if(!didGetDialog()) {
		exit(1);
	}

	SecKeychainDelete(kcRef);
	printf("...test succeeded.\n");
	return 0;
}
コード例 #6
0
int main(int argc, char **argv)
{   
    OSStatus            err;
	int					arg;
	char				fullFileBase[100];
	SSLProtocol			negVersion;
	SSLCipherSuite		negCipher;
	Boolean				sessionWasResumed;
	unsigned char		sessionID[MAX_SESSION_ID_LENGTH];
	size_t				sessionIDLength;
	CFArrayRef			peerCerts = NULL;		
	char				*argp;
	otSocket			listenSock;
	CFArrayRef			serverCerts = nil;		// required
	CFArrayRef			encryptCerts = nil;		// optional
	SecKeychainRef		serverKc = nil;
	SecKeychainRef		encryptKc = nil;
	int 				loopNum;
	int					errCount = 0;
	SSLClientCertificateState certState;		// obtained from sslServe

	/* user-spec'd parameters */
	unsigned short		portNum = DEFAULT_PORT;
	bool			allowExpired = false;
	bool			allowAnyRoot = false;
	char				*fileBase = NULL;
	bool			displayCerts = false;
	char				cipherRestrict = '\0';
	SSLProtocol			attemptProt = kTLSProtocol1;
	bool			protXOnly = false;	// kSSLProtocol3Only, 
												//    kTLSProtocol1Only
	char				*acceptedProts = NULL;	// "23t" ==> SSLSetProtocolVersionEnabled
	bool			quiet = false;
	bool			resumableEnable = true;
	bool			pause = false;
	char				*keyChainName = NULL;
	char				*encryptKeyChainName = NULL;
	int					loops = 1;
	SSLAuthenticate		authenticate = kNeverAuthenticate;
	bool			nonBlocking = false;
	bool			allowExpiredRoot = false;
	bool			disableCertVerify = false;
	char				*anchorFile = NULL;
	bool			replaceAnchors = false;
	bool			vfyCertState = false;
	SSLClientCertificateState expectCertState = kSSLClientCertNone;
	char				*password = NULL;
	char				*dhParamsFile = NULL;
	unsigned char		*dhParams = NULL;
	unsigned			dhParamsLen = 0;
	bool			doIdSearch = false;
	bool			completeCertChain = false;
	uint32_t				sessionCacheTimeout = 0;
	bool			disableAnonCiphers = false;
	CFMutableArrayRef	acceptableDNList = NULL;

	for(arg=1; arg<argc; arg++) {
		argp = argv[arg];
		switch(argp[0]) {
			case 'P':
				portNum = atoi(&argp[2]);
				break;
			case 'k':
				keyChainName = &argp[2];
				break;
			case 'y':
				encryptKeyChainName = &argp[2];
				break;
			case 'e':
				allowExpired = true;
				break;
			case 'E':
				allowExpiredRoot = true;
				break;
			case 'x':
				disableCertVerify = true;
				break;
			case 'a':
				if(++arg == argc)  {
					/* requires another arg */
					usage(argv);
				}
				anchorFile = argv[arg];
				break;
			case 'A':
				if(++arg == argc)  {
					/* requires another arg */
					usage(argv);
				}
				anchorFile = argv[arg];
				replaceAnchors = true;
				break;
			case 'T':
				if(argp[1] != '=') {
					usage(argv);
				}
				vfyCertState = true;
				switch(argp[2]) {
					case 'n':
						expectCertState = kSSLClientCertNone;
						break;
					case 'r':
						expectCertState = kSSLClientCertRequested;
						break;
					case 's':
						expectCertState = kSSLClientCertSent;
						break;
					case 'j':
						expectCertState = kSSLClientCertRejected;
						break;
					default:
						usage(argv);
				}
				break;
			case 'r':
				allowAnyRoot = true;
				break;
			case 'd':
				break;
			case 'c':
				displayCerts = true;
				break;
			case 'f':
				fileBase = &argp[2];
				break;
			case 'C':
				cipherRestrict = argp[2];
				break;
			case '2':
				attemptProt = kSSLProtocol2;
				break;
			case '3':
				attemptProt = kSSLProtocol3;
				break;
			case 't':
				attemptProt = kTLSProtocol1;
				break;
			case 'o':
				protXOnly = true;
				break;
			case 'g':
				if(argp[1] != '=') {
					usage(argv);
				}
				acceptedProts = &argp[2];
				break;
			case 'R':
				resumableEnable = false;
				break;
			case 'b':
				nonBlocking = true;
				break;
			case 'u':
				if(argp[1] != '=') {
					usage(argv);
				}
				switch(argp[2]) {
					case 'a': authenticate = kAlwaysAuthenticate; break;
					case 'n': authenticate = kNeverAuthenticate; break;
					case 't': authenticate = kTryAuthenticate; break;
					default: usage(argv);
				}
				break;
			case 'D':
				if(++arg == argc)  {
					/* requires another arg */
					usage(argv);
				}
				dhParamsFile = argv[arg];
				break;
			case 'z':
				password = &argp[2];
				break;
			case 'H':
				doIdSearch = true;
				break;
			case 'M':
				completeCertChain = true;
				break;
			case 'i':
				sessionCacheTimeout = atoi(&argp[2]);
				break;
			case '4':
				disableAnonCiphers = true;
				break;
			case 'p':
				pause = true;
				break;
			case 'q':
				quiet = true;
				break;
#if 0
			case 'U':
				if(++arg == argc)  {
					/* requires another arg */
					usage(argv);
				}
				if(cspReadFile(argv[arg], &caCert, &caCertLen)) {
					printf("***Error reading file %s. Aborting.\n", argv[arg]);
					exit(1);
				}
				if(acceptableDNList == NULL) {
					acceptableDNList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
				}
				certData.Data = caCert;
				certData.Length = caCertLen;
				ortn = SecCertificateCreateFromData(&certData,
													CSSM_CERT_X_509v3,
													CSSM_CERT_ENCODING_DER,
													&secCert);
				if(ortn) {
					cssmPerror("SecCertificateCreateFromData", ortn);
					exit(1);
				}
				CFArrayAppendValue(acceptableDNList, secCert);
				CFRelease(secCert);
				break;
#endif
			case 'l':
				if(argp[1] == '\0') {
					/* no loop count --> loop forever */
					loops = 0;
					break;
				}
				else if(argp[1] != '=') {
					usage(argv);
				}
				loops = atoi(&argp[2]);
				break;
			default:
				usage(argv);
		}
	}

#if NO_SERVER
# if DEBUG
    securityd_init(NULL);
# endif
#endif

	/* get server cert and optional encryption cert as CFArrayRef */
	if(keyChainName) {
		serverCerts = getSslCerts(keyChainName, false, completeCertChain, 
			anchorFile, &serverKc);
		if(serverCerts == nil) {
			exit(1);
		}
	}
	else 
#if 0
    if(doIdSearch) {
		OSStatus ortn = sslIdentityPicker(NULL, anchorFile, true, NULL, &serverCerts);
		if(ortn) {
			printf("***IdentitySearch failure; aborting.\n");
			exit(1);
		}
	}
	if(password) {
		OSStatus ortn = SecKeychainUnlock(serverKc, strlen(password), password, true);
		if(ortn) {
			printf("SecKeychainUnlock returned %d\n", (int)ortn);
			/* oh well */
		}
	}
	if(encryptKeyChainName) {
		encryptCerts = getSslCerts(encryptKeyChainName, true, completeCertChain,
			anchorFile, &encryptKc);
		if(encryptCerts == nil) {
			exit(1);
		}
	}
#else
    (void) doIdSearch;
    (void) encryptKeyChainName;
#endif
	if(protXOnly) {
		switch(attemptProt) {
			case kTLSProtocol1:
				attemptProt = kTLSProtocol1Only;
				break;
			case kSSLProtocol3:
				attemptProt = kSSLProtocol3Only;
				break;
			default:
				break;
		}
	}
#if 0
	if(dhParamsFile) {
		int r = cspReadFile(dhParamsFile, &dhParams, &dhParamsLen);
		if(r) {
			printf("***Error reading diffie-hellman params from %s; aborting\n",
				dhParamsFile);
		}
	}
#else
    (void) dhParamsFile;
#endif

	/* one-time only server port setup */
	err = ListenForClients(portNum, nonBlocking, &listenSock);
	if(err) {
    	printf("ListenForClients returned %d; aborting\n", (int)err);
		exit(1);
	}

	for(loopNum=1; ; loopNum++) {
		err = sslServe(listenSock,
			portNum,
			attemptProt,
			acceptedProts,
			serverCerts,
			password,
			encryptCerts,
			allowExpired,
			allowAnyRoot,
			allowExpiredRoot,
			disableCertVerify,
			anchorFile,
			replaceAnchors,
			cipherRestrict,
			authenticate,
			dhParams,
			dhParamsLen,
			acceptableDNList,
			resumableEnable,
			sessionCacheTimeout,
			disableAnonCiphers,
			quiet,
			pause,
			&negVersion,
			&negCipher,
			&certState,
			&sessionWasResumed,
			sessionID,
			&sessionIDLength,
			&peerCerts,
			argv);
		if(err) {
			errCount++;
		}
		if(!quiet) {
			SSLProtocol tryProt = attemptProt;
			showSSLResult(tryProt,
				acceptedProts,
				err, 
				negVersion, 
				negCipher, 
				sessionWasResumed,
				sessionID,
				sessionIDLength,
				peerCerts,
				displayCerts,
				certState,
				fileBase ? fullFileBase : NULL);
		}
		errCount += verifyClientCertState(vfyCertState, expectCertState, 
			certState);
		freePeerCerts(peerCerts);
		if(loops && (loopNum == loops)) {
			break;
		}
	};
	
	endpointShutdown(listenSock);

	if(serverKc) {
		CFRelease(serverKc);
	}
	if(encryptKc) {
		CFRelease(encryptKc);
	}
    return errCount;

}
コード例 #7
0
/*
 * params->lock is held for us by runSession() - we use it as a semapahore by
 * unlocking it when we've created a port to listen on. 
 * This is generally run from a thread via sslRunSession() and 
 * sslServerThread() in sslAppUtils.cpp. 
 */
OSStatus sslAppServe(
	SslAppTestParams	*params)
{
	otSocket			listenSock = 0;
	otSocket			acceptSock = 0;
    PeerSpec            peerId;
    OSStatus            ortn;
    SSLContextRef       ctx = NULL;
	SecKeychainRef		serverKc = nil;
	CFArrayRef			serverCerts = nil;
	
	sslThrDebug("Server", "starting");
    params->negVersion = kSSLProtocolUnknown;
    params->negCipher = SSL_NULL_WITH_NULL_NULL;
	params->ortn = noHardwareErr;
    
	/* set up a socket on which to listen */
	for(unsigned retry=0; retry<BIND_RETRIES; retry++) {
		ortn = ListenForClients(params->port, params->nonBlocking,
			&listenSock);
		switch(ortn) {
			case errSecSuccess:
				break;
			case errSecOpWr:
				/* port already in use - try another */
				params->port++;
				if(params->verbose || THREADING_DEBUG) {
					printf("...retrying ListenForClients at port %d\n",
						params->port);
				}
				break;
			default:
				break;
		}
		if(ortn != errSecOpWr) {
			break;
		}
	}
	
	/* let main thread know a socket is ready */
	if(pthread_mutex_lock(&params->pthreadMutex)) {
		printf("***Error acquiring server lock; aborting.\n");
		return -1;
	}
	params->serverReady = true;
	if(pthread_cond_broadcast(&params->pthreadCond)) {
		printf("***Error waking main thread; aborting.\n");
		return -1;
	}
	if(pthread_mutex_unlock(&params->pthreadMutex)) {
		printf("***Error acquiring server lock; aborting.\n");
		return -1;
	}

	if(ortn) {
		printf("ListenForClients returned %d; aborting\n", (int)ortn);
		return ortn;
	}

	/* wait for a connection */
	if(params->verbose) {
		printf("Waiting for client connection...");
		fflush(stdout);
	}
	ortn = AcceptClientConnection(listenSock, &acceptSock, &peerId);
    if(ortn) {
    	printf("AcceptClientConnection returned %d; aborting\n", (int)ortn);
    	return ortn;
    }

	/* 
	 * Set up a SecureTransport session.
	 */
	ortn = SSLNewContext(true, &ctx);
	if(ortn) {
		printSslErrStr("SSLNewContext", ortn);
		goto cleanup;
	} 
	ortn = SSLSetIOFuncs(ctx, SocketRead, SocketWrite);
	if(ortn) {
		printSslErrStr("SSLSetIOFuncs", ortn);
		goto cleanup;
	} 
	ortn = SSLSetConnection(ctx, (SSLConnectionRef)acceptSock);
	if(ortn) {
		printSslErrStr("SSLSetConnection", ortn);
		goto cleanup;
	}
	
	if(params->anchorFile) {
		ortn = sslAddTrustedRoot(ctx, params->anchorFile, 
			params->replaceAnchors);
		if(ortn) {
			goto cleanup;
		}
	}
	if(params->myCertKcName != NULL) {
		/* if not, better be trying anonymous diff-hellman... :-) */
		serverCerts = getSslCerts(params->myCertKcName, false, false, NULL,
			&serverKc);
		if(serverCerts == nil) {
			exit(1);
		}
		if(params->password) {
			ortn = SecKeychainUnlock(serverKc, strlen(params->password), 
					(void *)params->password, true);
			if(ortn) {
				printf("SecKeychainUnlock returned %d\n", (int)ortn);
				/* oh well */
			}
		}
		if(params->idIsTrustedRoot) {
			/* assume this is a root we want to implicitly trust */
			ortn = addIdentityAsTrustedRoot(ctx, serverCerts);
			if(ortn) {
				goto cleanup;
			}
		}
		ortn = SSLSetCertificate(ctx, serverCerts);
		if(ortn) {
			printSslErrStr("SSLSetCertificate", ortn);
			goto cleanup;
		}
	}
	
	if(params->disableCertVerify) {
		ortn = SSLSetEnableCertVerify(ctx, false);
		if(ortn) {
			printSslErrStr("SSLSetEnableCertVerify", ortn);
			goto cleanup;
		}
	}
	ortn = sslSetProtocols(ctx, params->acceptedProts, params->tryVersion);
	if(ortn) {
		goto cleanup;
	}
	if(params->resumeEnable) {
		ortn = SSLSetPeerID(ctx, &peerId, sizeof(PeerSpec));
		if(ortn) {
			printSslErrStr("SSLSetPeerID", ortn);
			goto cleanup;
		}
	}
	if(params->ciphers != NULL) {
		ortn = sslSetEnabledCiphers(ctx, params->ciphers);
		if(ortn) {
			goto cleanup;
		}
	}
	if(params->authenticate != kNeverAuthenticate) {
		ortn = SSLSetClientSideAuthenticate(ctx, params->authenticate);
		if(ortn) {
			printSslErrStr("SSLSetClientSideAuthenticate", ortn);
			goto cleanup;
		}
	}
	if(params->dhParams) {
		#if JAGUAR_BUILD
		printf("***Diffie-Hellman not supported in this config.\n");
		#else
		ortn = SSLSetDiffieHellmanParams(ctx, params->dhParams, 
			params->dhParamsLen);
		if(ortn) {
			printSslErrStr("SSLSetDiffieHellmanParams", ortn);
			goto cleanup;
		}
		#endif
	}

	/* Perform SSL/TLS handshake */
    do {   
		ortn = SSLHandshake(ctx);
	    if((ortn == errSSLWouldBlock) && !params->silent) {
	    	/* keep UI responsive */ 
	    	sslOutputDot();
	    }
    } while (ortn == errSSLWouldBlock);
	
	SSLGetClientCertificateState(ctx, &params->certState);
	SSLGetNegotiatedCipher(ctx, &params->negCipher);
	SSLGetNegotiatedProtocolVersion(ctx, &params->negVersion);
	
	if(params->verbose) {
		printf("\n");
	}
	if(ortn) {
		goto cleanup;
	}

	/* wait for one complete line */
	char readBuf[READBUF_LEN];
	size_t length;
	while(ortn == errSecSuccess) {
	    length = READBUF_LEN;
	    ortn = SSLRead(ctx, readBuf, length, &length);
	    if (ortn == errSSLWouldBlock) {
			/* keep trying */
	        ortn = errSecSuccess;
			continue;
	    }
	    if(length == 0) {
			/* keep trying */
			continue;
	    }
	    
	    /* poor person's line completion scan */
	    for(unsigned i=0; i<length; i++) {
	    	if((readBuf[i] == '\n') || (readBuf[i] == '\r')) {
	    		goto serverResp;
	    	}
	    }
	}
	
serverResp:
	/* send out canned response */
	ortn = SSLWrite(ctx, SERVER_MESSAGE, strlen(SERVER_MESSAGE), &length);
	if(ortn) {
		printSslErrStr("SSLWrite", ortn);
	}

cleanup:
	/*
	 * always do close, even on error - to flush outgoing write queue 
	 */
	if(ctx) {
		OSStatus cerr = SSLClose(ctx);
		if(ortn == errSecSuccess) {
			ortn = cerr;
		}
	}
	if(acceptSock) {
		while(!params->clientDone && !params->serverAbort) {
			usleep(100);
		}
		endpointShutdown(acceptSock);
	}
	if(listenSock) {
		endpointShutdown(listenSock);
	}
	if(ctx) {
	    SSLDisposeContext(ctx);  
	}    
	params->ortn = ortn;
	sslThrDebug("Server", "done");
	return ortn;
}
コード例 #8
0
int main(int argc, char **argv)
{
	RingBuffer		serverToClientRing;
	RingBuffer		clientToServerRing;
	unsigned		numBufs = DEFAULT_NUM_BUFS;
	unsigned		bufSize = DEFAULT_BUF_SIZE;
	unsigned		chunkSize = DEFAULT_CHUNK;
	unsigned char	clientBuf[DEFAULT_CHUNK];
	unsigned char	serverBuf[DEFAULT_CHUNK];
	CFArrayRef		idArray;					/* for SSLSetCertificate */
	CFArrayRef		anchorArray;				/* trusted roots */
	SslRingBufferArgs clientArgs;
	SslRingBufferArgs serverArgs;
	SecKeychainRef	kcRef = NULL;
	SecCertificateRef anchorCert = NULL;
	SecIdentityRef	idRef = NULL;
	bool			abortFlag = false;
	pthread_t		client_thread = NULL;
	int				result;
	bool			diffieHellman = true;		/* FIXME needs work */
	OSStatus		ortn;
	
	/* user-spec'd variables */
	char 			*kcName = DEFAULT_KC;
	unsigned 		xferSize = DEFAULT_XFER;
	SSLCipherSuite 	cipherSuite = TLS_RSA_WITH_AES_128_CBC_SHA;
	SSLProtocol 	prot = kTLSProtocol1;
	char 			password[200];
	bool 			clientAuthEnable = false;
	bool			pauseOnError = false;
	bool			runForever = false;
	bool			mallocPause = false;
	
	password[0] = 0;

	extern int optind;
	extern char *optarg;
	int arg;
	optind = 1;
	while ((arg = getopt(argc, argv, "k:x:c:v:w:aBpm")) != -1) {
		switch (arg) {
			case 'k':
				kcName = optarg;
				break;
			case 'x':
			{
				unsigned xsize = atoi(optarg);
				if(xsize == 0) {
					runForever = true;
					/* and leave xferSize alone */
				}
				else {
					xferSize = xsize;
				}
				break;
			}
			case 'c':
				switch(optarg[0]) {
					case 'a':
						cipherSuite = TLS_RSA_WITH_AES_128_CBC_SHA;
						break;
					case 'r':
						cipherSuite = SSL_RSA_WITH_RC4_128_SHA;
						break;
					case 'd':
						cipherSuite = SSL_RSA_WITH_DES_CBC_SHA;
						break;
					case 'D':
						cipherSuite = SSL_RSA_WITH_3DES_EDE_CBC_SHA;
						break;
					case 'h':
						cipherSuite = SSL_DH_anon_WITH_RC4_128_MD5;
						diffieHellman = true;
						break;
					case 'H':
						cipherSuite = SSL_DHE_DSS_WITH_DES_CBC_SHA;
						diffieHellman = true;
						break;
					case 'A':
						cipherSuite = TLS_RSA_WITH_AES_256_CBC_SHA;
						break;
					default:
						usage(argv);
				}
				break;
			case 'v':
				switch(optarg[0]) {
					case 't':
						prot = kTLSProtocol1;
						break;
					case '2':
						prot = kSSLProtocol2;
						break;
					case '3':
						prot = kSSLProtocol3;
						break;
					default:
						usage(argv);
				}
				break;
			case 'w':
				strcpy(password, optarg);
				break;
			case 'a':
				clientAuthEnable = true;
				break;
			case 'p':
				pauseOnError = true;
				break;
			case 'm':
				mallocPause = true;
				break;
			default:
				usage(argv);
		}
	}
	if(optind != argc) {
		usage(argv);
	}
	
	/* set up ring buffers */
	ringBufSetup(&serverToClientRing, "serveToClient", numBufs, bufSize);
	ringBufSetup(&clientToServerRing, "clientToServe", numBufs, bufSize);
	
	/* get server SecIdentity */
	idArray = getSslCerts(kcName, 
		CSSM_FALSE,		/* encryptOnly */
		CSSM_FALSE,		/* completeCertChain */
		NULL,			/* anchorFile */
		&kcRef);
	if(idArray == NULL) {
		printf("***Can't get signing cert from %s\n", kcName);
		exit(1);
	}
	idRef = (SecIdentityRef)CFArrayGetValueAtIndex(idArray, 0);
	ortn = SecIdentityCopyCertificate(idRef, &anchorCert);
	if(ortn) {
		cssmPerror("SecIdentityCopyCertificate", ortn);
		exit(1);
	}
	anchorArray = CFArrayCreate(NULL, (const void **)&anchorCert,
			1, &kCFTypeArrayCallBacks);

	/* unlock keychain? */
	if(password[0]) {
		ortn = SecKeychainUnlock(kcRef, strlen(password), password, true);
		if(ortn) {
			cssmPerror("SecKeychainUnlock", ortn);
			/* oh well */
		}
	}
	CFRelease(kcRef);

	if(mallocPause) {
		fpurge(stdin);
		printf("Pausing for MallocDebug setup. CR to proceed: ");
		getchar();
	}
	
	/* set up server side */
	memset(&serverArgs, 0, sizeof(serverArgs));
	serverArgs.idArray = idArray;
	serverArgs.trustedRoots = anchorArray;
	serverArgs.xferSize = xferSize;
	serverArgs.xferBuf = serverBuf;
	serverArgs.chunkSize = chunkSize;
	serverArgs.runForever = runForever;
	serverArgs.cipherSuite = cipherSuite;
	serverArgs.prot = prot;
	serverArgs.ringWrite = &serverToClientRing;
	serverArgs.ringRead = &clientToServerRing;
	serverArgs.goFlag = &clientArgs.iAmReady;
	serverArgs.abortFlag = &abortFlag;
	serverArgs.pauseOnError = pauseOnError;

	/* set up client side */
	memset(&clientArgs, 0, sizeof(clientArgs));
	clientArgs.idArray = NULL;		/* until we do client auth */
	clientArgs.trustedRoots = anchorArray;
	clientArgs.xferSize = xferSize;
	clientArgs.xferBuf = clientBuf;
	clientArgs.chunkSize = chunkSize;
	clientArgs.runForever = runForever;
	clientArgs.cipherSuite = cipherSuite;
	clientArgs.prot = prot;
	clientArgs.ringWrite = &clientToServerRing;
	clientArgs.ringRead = &serverToClientRing;
	clientArgs.goFlag = &serverArgs.iAmReady;
	clientArgs.abortFlag = &abortFlag;
	clientArgs.pauseOnError = pauseOnError;
	
	/* fire up client thread */
	result = pthread_create(&client_thread, NULL, 
			sslRbClientThread, &clientArgs);
	if(result) {
		printf("***pthread_create returned %d, aborting\n", result);
		exit(1);
	}
	
	/* 
	 * And the server pseudo thread. This returns when all data has been transferred. 
	 */
	ortn = sslRbServerThread(&serverArgs);
	
	if(abortFlag) {
		printf("***Test aborted.\n");
		exit(1);
	}
	
	printf("\n");

	if(mallocPause) {
		fpurge(stdin);
		printf("End of test. Pausing for MallocDebug analysis. CR to proceed: ");
		getchar();
	}
	
	printf("SSL Protocol Version : %s\n",
		sslGetProtocolVersionString(serverArgs.negotiatedProt));
	printf("SSL Cipher           : %s\n",
		sslGetCipherSuiteString(serverArgs.negotiatedCipher));
		
	printf("SSL Handshake        : %f s\n", 
		serverArgs.startData - serverArgs.startHandshake);
	printf("Data Transfer        : %u bytes in %f s\n", (unsigned)xferSize, 
		serverArgs.endData - serverArgs.startHandshake);
	printf("                     : %.1f Kbytes/s\n", 
			xferSize / (serverArgs.endData - serverArgs.startHandshake) / 1024.0);
	return 0;
}
コード例 #9
0
int main(int argc, char **argv)
{
	/* user-spec'd variables */
	const char 		*kcName = DEFAULT_KC;
	unsigned 		xferSize = XFERSIZE_DEF;
	int 			port = PORT_DEF;
	const char 		*hostName = HOST_DEF;
	SSLCipherSuite 	cipherSuite = TLS_RSA_WITH_AES_128_CBC_SHA;
	SSLProtocol 	prot = kTLSProtocol1Only;
	char 			password[200];
	bool 			clientAuthEnable = false;
	bool 			isServer = false;
	unsigned 		bufSize = BUFSIZE;
	bool			diffieHellman = false;
	int				nonBlocking = 0;
	
	if(argc < 2) {
		usage(argv);
	}
	password[0] = 0;
	switch(argv[1][0]) {
		case 's':
			isServer = true;
			break;
		case 'c':
			isServer = false;
			break;
		default:
			usage(argv);
	}
	
	extern int optind;
	extern char *optarg;
	int arg;
	optind = 2;
	while ((arg = getopt(argc, argv, "h:p:k:x:c:v:w:b:aB")) != -1) {
		switch (arg) {
			case 'h':
				hostName = optarg;
				break;
			case 'p':
				port = atoi(optarg);
				break;
			case 'k':
				kcName = optarg;
				break;
			case 'x':
				xferSize = atoi(optarg);
				break;
			case 'c':
				if(!isServer) {
					printf("***Specify cipherSuite on server side.\n");
					exit(1);
				}
				switch(optarg[0]) {
					case 'r':
						cipherSuite = SSL_RSA_WITH_RC4_128_SHA;
						break;
					case 'd':
						cipherSuite = SSL_RSA_WITH_DES_CBC_SHA;
						break;
					case 'D':
						cipherSuite = SSL_RSA_WITH_3DES_EDE_CBC_SHA;
						break;
					case 'h':
						cipherSuite = SSL_DH_anon_WITH_RC4_128_MD5;
						diffieHellman = true;
						break;
					case 'H':
						cipherSuite = SSL_DHE_DSS_WITH_DES_CBC_SHA;
						diffieHellman = true;
						break;
					case 'A':
						cipherSuite = TLS_RSA_WITH_AES_256_CBC_SHA;
						break;
					default:
						usage(argv);
				}
				break;
			case 'v':
				if(!isServer) {
					printf("***Specify protocol on server side.\n");
					exit(1);
				}
				switch(optarg[0]) {
					case 't':
						prot = kTLSProtocol1Only;
						break;
					case '2':
						prot = kSSLProtocol2;
						break;
					case '3':
						prot = kSSLProtocol3Only;
						break;
					default:
						usage(argv);
				}
				break;
			case 'w':
				strcpy(password, optarg);
				break;
			case 'b':
				bufSize = atoi(optarg);
				break;
			case 'a':
				clientAuthEnable = true;
				break;
			case 'B':
				nonBlocking = 1;
				break;
			default:
				usage(argv);
		}
	}
	
	/* per-transfer buffer - make it random for server */
	char *buf = (char *)malloc(bufSize);
	if(isServer) {
		Security::DevRandomGenerator rng;
		rng.random(buf, bufSize);
	}
	
	/* gather Diffie-Hellman params from cwd */
	unsigned char *dhParams = NULL;
	unsigned dhParamsLen = 0;
	if(diffieHellman && isServer) {
		if(readFile(DH_PARAM_FILE, &dhParams, &dhParamsLen)) {
			printf("***Error reading Diffie-Hellman Params. Prepare to "
				"wait for a minute during SSL handshake.\n");
		}
	}
	
	/*
	 * Open keychain; both sides use the same one.
	 */
	OSStatus ortn;
	SecKeychainRef certKc = NULL;
	CFAbsoluteTime kcOpenStart = CFAbsoluteTimeGetCurrent();
	ortn = SecKeychainOpen(kcName, &certKc);
	if(ortn) {
		printf("Error opening keychain %s (%d); aborting.\n",
			kcName, (int)ortn);
		exit(1);
	}
	if(password[0]) {
		ortn = SecKeychainUnlock(certKc, strlen(password), password, true);
		if(ortn) {
			printf("SecKeychainUnlock returned %d\n", (int)ortn);
			/* oh well */
		}
	}
	CFAbsoluteTime kcOpenEnd = CFAbsoluteTimeGetCurrent();
	
	otSocket peerSock = 0;
	otSocket listenSock = 0;			// for server only
    PeerSpec peerId;
	
	if(isServer) {
		printf("...listening for client connection on port %d\n", port);
		ortn = ListenForClients(port, nonBlocking, &listenSock);
		if(ortn) {
			printf("...error establishing a listen socket. Aborting.\n");
			exit(1);
		}
		ortn = AcceptClientConnection(listenSock, &peerSock, &peerId);
		if(ortn) {
			printf("...error listening for connection. Aborting.\n");
			exit(1);
		}
	}
	else {
		printf("...connecting to host %s at port %d\n", hostName, port);
		ortn = MakeServerConnection(hostName, port, nonBlocking, &peerSock,
			&peerId);
		if(ortn) {
			printf("...error connecting to server %s. Aborting.\n",
				hostName);
			exit(1);
		}
	}

	/* start timing SSL setup */
	CFAbsoluteTime setupStart = CFAbsoluteTimeGetCurrent();

	SSLContextRef ctx;
	ortn = SSLNewContext(isServer, &ctx);
	if(ortn) {
		printSslErrStr("SSLNewContext", ortn);
		exit(1);
	} 
	ortn = SSLSetIOFuncs(ctx, SocketRead, SocketWrite);
	if(ortn) {
		printSslErrStr("SSLSetIOFuncs", ortn);
		exit(1);
	} 
	ortn = SSLSetConnection(ctx, (SSLConnectionRef)peerSock);
	if(ortn) {
		printSslErrStr("SSLSetConnection", ortn);
		exit(1);
	}
	ortn = SSLSetPeerDomainName(ctx, hostName, strlen(hostName) + 1);
	if(ortn) {
		printSslErrStr("SSLSetPeerDomainName", ortn);
		exit(1);
	}	
	
	/*
	 * Server/client specific setup.
	 *
	 * Client uses the same keychain as server, but it uses it for 
	 * sslAddTrustedRoots() instead of getSslCerts() and 
	 * SSLSetCertificate().
	 */
	CFArrayRef myCerts = NULL;
	if(clientAuthEnable || isServer) {
		myCerts = sslKcRefToCertArray(certKc, CSSM_FALSE, CSSM_FALSE, NULL, NULL);
		if(myCerts == NULL) {
			exit(1);
		}
		ortn = addIdentityAsTrustedRoot(ctx, myCerts);
		if(ortn) {
			exit(1);
		}
		ortn = SSLSetCertificate(ctx, myCerts);
		if(ortn) {
			printSslErrStr("SSLSetCertificate", ortn);
			exit(1);
		}
	}
	if(isServer) {
		SSLAuthenticate auth;
		if(clientAuthEnable) {
			auth = kAlwaysAuthenticate;
		}
		else {
			auth = kNeverAuthenticate;
		}
		ortn = SSLSetClientSideAuthenticate(ctx, auth);
		if(ortn) {
			printSslErrStr("SSLSetClientSideAuthenticate", ortn);
			exit(1);
		}
		ortn = SSLSetEnabledCiphers(ctx, &cipherSuite, 1);
		if(ortn) {
			printSslErrStr("SSLSetEnabledCiphers", ortn);
			exit(1);
		}
		ortn = SSLSetProtocolVersion(ctx, prot);
		if(ortn) {
			printSslErrStr("SSLSetProtocolVersion", ortn);
			exit(1);
		}
		if(dhParams != NULL) {
			ortn = SSLSetDiffieHellmanParams(ctx, dhParams, dhParamsLen);
			if(ortn) {
				printSslErrStr("SSLSetDiffieHellmanParams", ortn);
				exit(1);
			}
		}
	}
	else {
		/* client setup */
		if(!clientAuthEnable) {
			/* We're not presenting a cert; trust the server certs */
			bool foundOne;
			ortn = sslAddTrustedRoots(ctx, certKc, &foundOne);
			if(ortn) {
				printSslErrStr("sslAddTrustedRoots", ortn);
				exit(1);
			}
		}
	}
	
	/*
	 * Context setup complete. Start timing handshake.
	 */
	CFAbsoluteTime hshakeStart = CFAbsoluteTimeGetCurrent();
    do {   
		ortn = SSLHandshake(ctx);
    } while (ortn == errSSLWouldBlock);
	if(ortn) {
		printSslErrStr("SSLHandshake", ortn);
		exit(1);
	}
	CFAbsoluteTime hshakeEnd = CFAbsoluteTimeGetCurrent();
	
	/* snag these before data xfer possibly shuts down connection */
	SSLProtocol	negVersion;
	SSLCipherSuite negCipher;
	SSLClientCertificateState certState;		// RETURNED

	SSLGetNegotiatedCipher(ctx, &negCipher);
	SSLGetNegotiatedProtocolVersion(ctx, &negVersion);
	SSLGetClientCertificateState(ctx, &certState);
	
	/* server sends xferSize bytes to client and shuts down */
	size_t bytesMoved;
	
	CFAbsoluteTime dataStart = CFAbsoluteTimeGetCurrent();
	size_t totalMoved = 0;
	if(isServer) {
		size_t bytesToGo = xferSize;
		bool done = false;
		do {
			size_t thisMove = bufSize;
			if(thisMove > bytesToGo) {
				thisMove = bytesToGo;
			}
			ortn = SSLWrite(ctx, buf, thisMove, &bytesMoved);
			switch(ortn) {
				case noErr:
				case errSSLWouldBlock:
					break;
				default:
					done = true;
					break;
			}
			bytesToGo -= bytesMoved;
			totalMoved += bytesMoved;
			if(bytesToGo == 0) {
				done = true;
			}
		} while(!done);
		if(ortn != noErr) {
			printSslErrStr("SSLWrite", ortn);
			exit(1);
		}
	}
	else {
		/* client reads until error or errSSLClosedGraceful */
		bool done = false;
		do {
			ortn = SSLRead(ctx, buf, bufSize, &bytesMoved);
			switch(ortn) {
				case errSSLClosedGraceful:
					done = true;
					break;
				case noErr:
				case errSSLWouldBlock:
					break;
				default:
					done = true;
					break;
			}
			totalMoved += bytesMoved;
		} while(!done);
		if(ortn != errSSLClosedGraceful) {
			printSslErrStr("SSLRead", ortn);
			exit(1);
		}
	}
	
	/* shut down channel */
	ortn = SSLClose(ctx);
	if(ortn) {
		printSslErrStr("SSLCLose", ortn);
		exit(1);
	}
	CFAbsoluteTime dataEnd = CFAbsoluteTimeGetCurrent();

	/* how'd we do? */
	printf("SSL version          : %s\n", 
		sslGetProtocolVersionString(negVersion));
	printf("CipherSuite          : %s\n",
		sslGetCipherSuiteString(negCipher));
	printf("Client Cert State    : %s\n",
			sslGetClientCertStateString(certState));

	if(password[0]) {
		printf("keychain open/unlock : ");
	}
	else {
		printf("keychain open        : ");
	}
	printf("%f s\n", kcOpenEnd - kcOpenStart);
	printf("SSLContext setup     : %f s\n", hshakeStart - setupStart);
	printf("SSL Handshake        : %f s\n", hshakeEnd - hshakeStart);
	printf("Data Transfer        : %u bytes in %f s\n", (unsigned)totalMoved, 
		dataEnd - dataStart);
	printf("                     : %.1f Kbytes/s\n", 
			totalMoved / (dataEnd - dataStart) / 1024.0);
	return 0;
}
コード例 #10
0
ファイル: main.c プロジェクト: pnc/splitring
int main(int argc, char * const argv[]) {
  int verbose = 0;
  int dryRun = 0;
  int version = 0;
  char *toKeychainPath = NULL;

  struct option longopts[] = {
    { "dry-run",      no_argument,         &dryRun,     1   },
    { "to-keychain",  required_argument,   NULL,        'k' },
    { "verbose",      no_argument,         &verbose,    1   },
    { "version",      no_argument,         &version,       1   },
    { NULL,           0,                   NULL,        0   }
  };

  int ch;
  while ((ch = getopt_long(argc, argv, "dk:v", longopts, NULL)) != -1) {
    switch (ch) {
      case 'k':
        toKeychainPath = optarg;
        break;
      case 'd':
        dryRun = 1;
        break;
      case 'v':
        verbose = 1;
        break;
      case 0:
        // Handle long-only options
        break;
      default:
        SRPrintUsage();
        exit(EX_USAGE);
    }
  }
  argc -= optind;
  argv += optind;

  if (version) {
    fprintf(stderr, "splitring 1.1\nCopyright (C) 2013 Phil Calvin\n");
    exit(0);
  }

  if (!argc) {
    SRPrintUsage();
    exit(EX_USAGE);
  }

  CFMutableArrayRef keychains = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);

  // Iterate the passed keychain paths, opening each one
  for (int i = 0; i < argc; i++) {
    char* path = realpath(argv[i], NULL);
    if (path) {
      SecKeychainRef keychain = SROpenKeychain(path);
      CFArrayAppendValue(keychains, keychain);
      CFRelease(keychain);
      free(path);
    } else {
      fprintf(stderr, "Unable to find keychain: %s\n", argv[i]);
    }
  }

  // Unlock each of the keychains
  for (int i = 0; i < CFArrayGetCount(keychains); i++) {
    SecKeychainRef keychain = (SecKeychainRef)CFArrayGetValueAtIndex(keychains, i);
    // Unlock it; might not need to do this
    if (verbose) {
      UInt32 bufferSize = 4096;
      char keychainPath[bufferSize];
      SecKeychainGetPath(keychain, &bufferSize, keychainPath);
      fprintf(stderr, "Unlocking keychain at path: %s\n", keychainPath);
    }
    OSStatus status = SecKeychainUnlock(keychain, 0, NULL, FALSE);
    SRHandleError(status, true);
  }

  SecKeychainRef targetKeychain = NULL;
  if (toKeychainPath) {
    // Convert this to a canonical path
    char* canonicalPath = realpath(toKeychainPath, NULL);
    if (canonicalPath) {
      // Import to the specified keychain
      targetKeychain = SROpenKeychain(canonicalPath);
      free(canonicalPath);
    } else {
      fprintf(stderr, "Unable to find keychain: %s\n", toKeychainPath);
      exit(EX_IOERR);
    }
  } else {
    // Import to the default keychain if one wasn't specified
    OSStatus status = SecKeychainCopyDefault(&targetKeychain);
    SRHandleError(status, true);
    status = SecKeychainUnlock(targetKeychain, 0, NULL, FALSE);
    SRHandleError(status, true);
  }

  // Search for all items
  CFMutableArrayRef classes = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
  CFArrayAppendValue(classes, kSecClassGenericPassword);
  CFArrayAppendValue(classes, kSecClassInternetPassword);
  //CFArrayAppendValue(classes, kSecClassCertificate);
  //CFArrayAppendValue(classes, kSecClassIdentity);
  //CFArrayAppendValue(classes, kSecClassKey);

  CFArrayRef items = SRCopyItems(keychains, classes);

  if (verbose) {
    UInt32 bufferSize = 4096;
    char defaultKeychainPath[bufferSize];
    SecKeychainGetPath(targetKeychain, &bufferSize, defaultKeychainPath);
    fprintf(stderr, "Importing %li items to keychain at path: %s\n",
            CFArrayGetCount(items),
            defaultKeychainPath);
  }

  SRCopyItemsToKeychain(items, targetKeychain, verbose, dryRun);

  CFRelease(items);
  CFRelease(targetKeychain);
  CFRelease(keychains);
  return 0;
}
コード例 #11
0
static void tests(void)
{
	char *home = getenv("HOME");
	char kcname1[256], kcname2[256];
	SecKeychainStatus status1, status2;

	if (!home || strlen(home) > 200)
		plan_skip_all("home too big");

	sprintf(kcname1, "%s/kctests/kc1/kc1", home);
	SecKeychainRef kc1 = NULL, kc2 = NULL;
    kc1 = createNewKeychainAt(kcname1, "test");

	ok_status(SecKeychainGetStatus(kc1, &status1), "get kc1 status");
	is(status1, kSecUnlockStateStatus|kSecReadPermStatus|kSecWritePermStatus,
		"status unlocked readable writable");
	ok_status(SecKeychainLock(kc1), "SecKeychainLock kc1");
	ok_status(SecKeychainGetStatus(kc1, &status1), "get kc1 status");
	TODO: {
		todo("<rdar://problem/2668794> KeychainImpl::status() returns "
			"incorrect status (always writable?)");

		is(status1, kSecReadPermStatus|kSecWritePermStatus,
			"status (locked) readable writable");
	}

	/* Make keychain non writable. */
	char kcdir1[256];
	sprintf(kcdir1, "%s/kctests/kc1", home);
	ok_unix(chmod(kcdir1, 0555), "chmod kcdir1 0555");

	ok_status(SecKeychainGetStatus(kc1, &status1), "get kc1 status");
	is(status1, kSecReadPermStatus, "status (locked) readable");
	ok_status(SecKeychainUnlock(kc1, 4, "test", TRUE), "SecKeychainLock kc1");
	ok_status(SecKeychainGetStatus(kc1, &status1), "get kc1 status");
	TODO: {
		todo("<rdar://problem/2668794> KeychainImpl::status() returns "
			"incorrect status (always writable?)");

		is(status1, kSecUnlockStateStatus|kSecReadPermStatus,
			"status unlocked readable");
	}

	/* Reopen the keychain. */
	CFRelease(kc1);
	ok_status(SecKeychainOpen(kcname1, &kc1), "SecKeychainOpen kc1");

	ok_status(SecKeychainGetStatus(kc1, &status1), "get kc1 status");
	TODO: {
		todo("<rdar://problem/2668794> KeychainImpl::status() returns "
			"incorrect status (always writable?)");

		is(status1, kSecUnlockStateStatus|kSecReadPermStatus,
			"status unlocked readable");
	}

	sprintf(kcname2, "%s/kctests/kc2/kc2", home);
    kc2 = createNewKeychainAt(kcname2, "test");
	ok_unix(chmod(kcname2, 0444), "chmod kc2 0444");
	ok_status(SecKeychainGetStatus(kc2, &status2), "get kc2 status");
	is(status2, kSecUnlockStateStatus|kSecReadPermStatus|kSecWritePermStatus,
		"status unlocked readable writable");

	/* Reopen the keychain. */
	CFRelease(kc2);
	ok_status(SecKeychainOpen(kcname2, &kc2), "SecKeychainOpen kc2");

	ok_status(SecKeychainGetStatus(kc2, &status2), "get kc2 status");
	is(status2, kSecUnlockStateStatus|kSecReadPermStatus|kSecWritePermStatus,
		"status unlocked readable writable");

	/* Restore dir to writable so cleanup code will work ok. */
	ok_unix(chmod(kcdir1, 0755), "chmod kcdir1 0755");
    ok_status(SecKeychainDelete(kc1), "%s: SecKeychainDelete", testName);
	CFRelease(kc1);
    ok_status(SecKeychainDelete(kc2), "%s: SecKeychainDelete", testName);
	CFRelease(kc2);

	bool testWithFreshlyCreatedKeychain = true;
	SecKeychainRef keychain = createNewKeychain("test", "test");
	ok_status(SecKeychainLock(keychain), "SecKeychainLock");

	do {
		SecKeychainStatus keychainStatus = 0;
		is_status(SecKeychainUnlock(keychain, 0, NULL, true), -25293, "SecKeychainUnlock with NULL password (incorrect)");
		ok_status(SecKeychainGetStatus(keychain, &keychainStatus), "SecKeychainGetStatus");
		is( (keychainStatus & kSecUnlockStateStatus), 0, "Check it's not unlocked");

		keychainStatus = 0;
		ok_status(SecKeychainUnlock(keychain, strlen("test"), "test", true), "SecKeychainUnlock with correct password");
		ok_status(SecKeychainGetStatus(keychain, &keychainStatus), "SecKeychainGetStatus");
		is( (keychainStatus & kSecUnlockStateStatus), kSecUnlockStateStatus, "Check it's unlocked");
		
		ok_status(SecKeychainLock(keychain), "SecKeychainLock");

		if (testWithFreshlyCreatedKeychain)
		{
        CFRelease(keychain);
			testWithFreshlyCreatedKeychain = false;
			ok_status(SecKeychainOpen("test", &keychain), "SecKeychainOpen");
		}
        else {
			testWithFreshlyCreatedKeychain = true;

            ok_status(SecKeychainDelete(keychain), "%s: SecKeychainDelete", testName);
            CFReleaseNull(keychain);
        }
		
	}
	while(!testWithFreshlyCreatedKeychain);

}
コード例 #12
0
/* relies on SSLSetProtocolVersionEnabled */
OSStatus sslAppClient(
	SslAppTestParams	*params)
{
    PeerSpec            peerId;
	otSocket			sock = 0;
    OSStatus            ortn;
    SSLContextRef       ctx = NULL;
	SecKeychainRef		clientKc = nil;
	CFArrayRef			clientCerts = nil;
	
	sslThrDebug("Client", "starting");
    params->negVersion = kSSLProtocolUnknown;
    params->negCipher  = SSL_NULL_WITH_NULL_NULL;
    params->ortn       = noHardwareErr;
	
	/* first make sure requested server is there */
	ortn = MakeServerConnection(params->hostName, params->port,
		params->nonBlocking, &sock, &peerId);
    if(ortn) {
    	printf("MakeServerConnection returned %d; aborting\n", (int)ortn);
    	return ortn;
    }
	
	/* 
	 * Set up a SecureTransport session.
	 */
	ortn = SSLNewContext(false, &ctx);
	if(ortn) {
		printSslErrStr("SSLNewContext", ortn);
		goto cleanup;
	} 
	ortn = SSLSetIOFuncs(ctx, SocketRead, SocketWrite);
	if(ortn) {
		printSslErrStr("SSLSetIOFuncs", ortn);
		goto cleanup;
	} 
	ortn = SSLSetConnection(ctx, (SSLConnectionRef)sock);
	if(ortn) {
		printSslErrStr("SSLSetConnection", ortn);
		goto cleanup;
	}
	if(!params->skipHostNameCheck) {
		ortn = SSLSetPeerDomainName(ctx, params->hostName, 
			strlen(params->hostName));
		if(ortn) {
			printSslErrStr("SSLSetPeerDomainName", ortn);
			goto cleanup;
		}
	}
	
	/* remainder of setup is optional */
	if(params->anchorFile) {
		ortn = sslAddTrustedRoot(ctx, params->anchorFile, params->replaceAnchors);
		if(ortn) {
			goto cleanup;
		}
	}
	ortn = sslSetProtocols(ctx, params->acceptedProts, params->tryVersion);
	if(ortn) {
		goto cleanup;
	}
	if(params->resumeEnable) {
		ortn = SSLSetPeerID(ctx, &peerId, sizeof(PeerSpec));
		if(ortn) {
			printSslErrStr("SSLSetPeerID", ortn);
			goto cleanup;
		}
	}
	if(params->disableCertVerify) {
		ortn = SSLSetEnableCertVerify(ctx, false);
		if(ortn) {
			printSslErrStr("SSLSetEnableCertVerify", ortn);
			goto cleanup;
		}
	}
	if(params->ciphers != NULL) {
		ortn = sslSetEnabledCiphers(ctx, params->ciphers);
		if(ortn) {
			goto cleanup;
		}
	}
	if(params->myCertKcName) {
		clientCerts = getSslCerts(params->myCertKcName, false, false, NULL, &clientKc);
		if(clientCerts == nil) {
			exit(1);
		}
		if(params->password) {
			ortn = SecKeychainUnlock(clientKc, strlen(params->password), 
					(void *)params->password, true);
			if(ortn) {
				printf("SecKeychainUnlock returned %d\n", (int)ortn);
				/* oh well */
			}
		}
		if(params->idIsTrustedRoot) {
			/* assume this is a root we want to implicitly trust */
			ortn = addIdentityAsTrustedRoot(ctx, clientCerts);
			if(ortn) {
				goto cleanup;
			}
		}
		ortn = SSLSetCertificate(ctx, clientCerts);
		if(ortn) {
			printSslErrStr("SSLSetCertificate", ortn);
			goto cleanup;
		}
	}
    do {
		ortn = SSLHandshake(ctx);
	    if((ortn == errSSLWouldBlock) && !params->silent) {
	    	/* keep UI responsive */ 
	    	sslOutputDot();
	    }
    } while (ortn == errSSLWouldBlock);
	
	SSLGetClientCertificateState(ctx, &params->certState);
	SSLGetNegotiatedCipher(ctx, &params->negCipher);
	SSLGetNegotiatedProtocolVersion(ctx, &params->negVersion);
	
	if(ortn != errSecSuccess) {
		goto cleanup;
	}

	/* send a GET msg */
	size_t actLen;
	ortn = SSLWrite(ctx, CLIENT_GETMSG, strlen(CLIENT_GETMSG), &actLen);
	if(ortn) {
		printSslErrStr("SSLWrite", ortn);
		goto cleanup;
	}
	
	#if KEEP_CONNECTED
	
	/*
	 * Consume any server data and wait for server to disconnect
	 */
	char readBuf[READBUF_LEN];
    do {
		ortn = SSLRead(ctx, readBuf, READBUF_LEN, &actLen);
    } while (ortn == errSSLWouldBlock);
	
    /* convert normal "shutdown" into zero err rtn */
	if(ortn == errSSLClosedGraceful) {
		ortn = errSecSuccess;
	}
	#endif	/* KEEP_CONNECTED */
	
cleanup:
	if(ctx) {
		OSStatus cerr = SSLClose(ctx);
		if(ortn == errSecSuccess) {
			ortn = cerr;
		}
	}
	if(sock) {
		endpointShutdown(sock);
	}
	if(ctx) {
	    SSLDisposeContext(ctx);  
	}    
	params->ortn = ortn;
	sslThrDebug("Client", "done");
	return ortn;
}