/*
 * Ensure that the policy being evaluated is accessible via 
 * SecPolicySearch*(). Not really part of the test, but a handy place
 * to catch this common error before checking in TP changes. 
 */ 
static int verifySecPolicy(
	const CSSM_OID *oid)
{
	SecPolicySearchRef srchRef = NULL;
	OSStatus ortn;
	
	ortn = SecPolicySearchCreate(CSSM_CERT_X_509v3, oid, NULL, &srchRef);
	if(ortn) {
		cssmPerror("SecPolicySearchCreate", ortn);
		return -1;
	}
	SecPolicyRef policyRef = NULL;
	ortn = SecPolicySearchCopyNext(srchRef, &policyRef);
	if(ortn) {
		cssmPerror("SecPolicySearchCopyNext", ortn);
		printf("***The TP policy used in this test is not accessible via SecPolicySearchCopyNext().\n");
		printf("   You probably forgot to add the policy to the theOidList table in PolicyCursor.cpp\n");
		printf("   in the libsecurity_keychain project.\n");
	}
	CFRelease(srchRef);
	if(policyRef) {
		CFRelease(policyRef);
	}
	return ortn;
}
int dbOpenCloseEval(TestParams *testParams)
{
	int ourRtn = 0;
	for(unsigned loop=0; loop<testParams->numLoops; loop++) {
		if(testParams->verbose) {
			printf("dbOpenClose thread %d: loop %d\n", 
				testParams->threadNum, loop);
		}
		else if(!testParams->quiet) {
			printChar(testParams->progressChar);
		}
	
		/* attach to existing DB - don't create */
		CSSM_DB_HANDLE dbHand = cuDbStartupByName(dlHand, (char *)DB_NAME,
			CSSM_FALSE,		// don't create
			testParams->quiet);
		if(dbHand == 0) {
			printf("***dbOpenClose: error attaching to db %s\n", DB_NAME);
			ourRtn = -1;
			break;
		}
		
		CSSM_DL_DB_HANDLE dlDbHand = {dlHand, dbHand};
		CSSM_RETURN crtn = CSSM_DL_DbClose(dlDbHand);
		if(crtn) {
			cssmPerror("CSSM_DL_DbClose", crtn);
			printf("***Error closing %s\n", DB_NAME);
			ourRtn = -1;
			break;
		}
	}
	return ourRtn;
}
/* print a CFData as an X509 Name (i.e., subject or issuer) */
void printCfName(
	CFDataRef nameData,
	OidParser &parser)
{
	SecAsn1CoderRef coder = NULL;
	OSStatus ortn;

	ortn = SecAsn1CoderCreate(&coder);
	if(ortn) {
		cssmPerror("SecAsn1CoderCreate", ortn);
		return;
	}
	/* subsequent errors to errOut: */

	NSS_Name nssName = {NULL};
	unsigned numRdns;

	ortn = SecAsn1Decode(coder, 
		CFDataGetBytePtr(nameData), CFDataGetLength(nameData),
		kSecAsn1NameTemplate,
		&nssName);
	if(ortn) {
		printf("***Error decoding NSS_Name\n");
		goto errOut;
	}	
	numRdns = nssArraySize((const void **)nssName.rdns);
	for(unsigned dex=0; dex<numRdns; dex++) {
		printRdn(nssName.rdns[dex], parser);
	}

errOut:
	if(coder) {
		SecAsn1CoderRelease(coder);
	}
}
Example #4
0
SECURITY_STATUS schan_imp_handshake(schan_imp_session session)
{
    struct mac_session *s = (struct mac_session*)session;
    int status;

    TRACE("(%p/%p)\n", s, s->context);

    status = SSLHandshake(s->context);
    if (status == noErr)
    {
        TRACE("Handshake completed\n");
        return SEC_E_OK;
    }
    else if (status == errSSLWouldBlock)
    {
        TRACE("Continue...\n");
        return SEC_I_CONTINUE_NEEDED;
    }
    else if (errSecErrnoBase <= status && status <= errSecErrnoLimit)
    {
        ERR("Handshake failed: %s\n", strerror(status));
        return SEC_E_INTERNAL_ERROR;
    }
    else
    {
        ERR("Handshake failed: %d\n", status);
        cssmPerror("SSLHandshake", status);
        return SEC_E_INTERNAL_ERROR;
    }

    /* Never reached */
    return SEC_E_OK;
}
/*
 * Assume incoming identity contains a root (e.g., created by
 * certtool) and add that cert to ST's trusted anchors. This
 * enables ST's verify of the incoming chain to succeed without 
 * a kludgy "AllowAnyRoot" specification.
 */
OSStatus addIdentityAsTrustedRoot(
	SSLContextRef 	ctx,
	CFArrayRef		identArray)
{
	CFIndex numItems = CFArrayGetCount(identArray);
	if(numItems == 0) {
		printf("***addIdentityAsTrustedRoot: empty identArray\n");
		return errSecParam;
	}
	
	/* Root should be the last item - could be identity, could be cert */
	CFTypeRef theItem = CFArrayGetValueAtIndex(identArray, numItems - 1);
	if(CFGetTypeID(theItem) == SecIdentityGetTypeID()) {
		/* identity */
		SecCertificateRef certRef;
		OSStatus ortn = SecIdentityCopyCertificate(
			(SecIdentityRef)theItem, &certRef);
		if(ortn) {
			cssmPerror("SecIdentityCopyCertificate", ortn);
			printf("***Error gettting cert from identity\n");
			return ortn;
		}
		ortn = addTrustedSecCert(ctx, certRef, false);
		CFRelease(certRef);
		return ortn;
	}
	else if(CFGetTypeID(theItem) == SecCertificateGetTypeID()) {
		/* certificate */
		return addTrustedSecCert(ctx, (SecCertificateRef)theItem, false);
	}
	else {
		printf("***Bogus item in identity array\n");
		return errSecParam;
	}
}
/* generate key pair, optionally storing the public key in encrypted form */
static int genKeyPair(
	bool pubKeyIsEncrypted,
	SecKeychainRef kcRef,
	SecKeyRef *pubKeyRef,
	SecKeyRef *privKeyRef)
{
	/* gather keygen args */
	CSSM_ALGORITHMS keyAlg = KEY_ALG;
	uint32 keySizeInBits = KEYSIZE;
	CSSM_KEYUSE pubKeyUsage = CSSM_KEYUSE_ANY;
	uint32 pubKeyAttr = CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_EXTRACTABLE | CSSM_KEYATTR_PERMANENT;
	if(pubKeyIsEncrypted) {
		pubKeyAttr |= CSSM_KEYATTR_PUBLIC_KEY_ENCRYPT;
	}
	CSSM_KEYUSE privKeyUsage = CSSM_KEYUSE_ANY;
	uint32 privKeyAttr = CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_EXTRACTABLE |
						 CSSM_KEYATTR_PERMANENT | CSSM_KEYATTR_SENSITIVE;
	
	OSStatus ortn = SecKeyCreatePair(kcRef, keyAlg, keySizeInBits, 0,
		pubKeyUsage, pubKeyAttr,
		privKeyUsage, privKeyAttr,
		NULL,		// default initial access for now 
		pubKeyRef, privKeyRef);
	if(ortn) {
		cssmPerror("SecKeyCreatePair", ortn);
		return 1;
	}
	return 0;
}
static int p12Parse(
	const CSSM_DATA &rawBlob, 
	P12ParseInfo &pinfo,
	unsigned depth)		// print indent depth
{
	NSS_P12_DecodedPFX pfx;
	memset(&pfx, 0, sizeof(pfx));
	if(pinfo.mCoder.decodeItem(rawBlob, NSS_P12_DecodedPFXTemplate, &pfx)) {
		printf("***Error on top-level decode of NSS_P12_DecodedPFX\n");
		return 1;
	}
	doIndent(depth);
	printf("version = %u\n", (unsigned)dataToInt(pfx.version));
	NSS_P7_DecodedContentInfo &dci = pfx.authSafe;

	doIndent(depth);
	printf("contentType = %s\n", oidStr(dci.contentType, pinfo.mParser));
	doIndent(depth);
	printf("type = %s\n", p7ContentInfoTypeStr(dci.type));
	int rtn = 0;
	if(nssCompareCssmData(&dci.contentType, &CSSMOID_PKCS7_Data)) {
		doIndent(depth);
		printf("AuthenticatedSafe Length %u {\n", 
			(unsigned)dci.content.data->Length);
		rtn = authSafeParse(*dci.content.data, pinfo, depth+3);
		doIndent(depth);
		printf("}\n");
	}
	else {
		printf("Not parsing any other content type today.\n");
	}
	if(pfx.macData) {
		doIndent(depth);
		printf("Mac Data {\n");
		p12MacParse(*pfx.macData, pinfo, depth+3);
		doIndent(depth);
		printf("}\n");
		if(pinfo.mPwd.Data == NULL) {
			doIndent(depth);
			printf("=== MAC not verified (no passphrase)===\n");
		}
		else {
			CSSM_RETURN crtn = p12VerifyMac_app(pfx, pinfo.mCspHand, 
				pinfo.mPwd, pinfo.mCoder);
			doIndent(depth);
			if(crtn) {
				cssmPerror("p12VerifyMac", crtn);
				doIndent(depth);
				printf("***MAC verify failure.\n");
			}
			else {
				printf("MAC verifies OK.\n");
			}
		}
	}
	return 0;
}
Example #8
0
/*
 * Given keyFileBase and key type, init a CSSM_KEY from contents of
 * keyFileBase.
 */
static int rt_readKey(
	CSSM_CSP_HANDLE	cspHandle,
	const char 		*keyFileBase,
	CSSM_BOOL		isPub,
	CSSM_ALGORITHMS	alg,
	CSSM_KEY_PTR	key)
{
	char 				fileName[KEY_FILE_NAME_MAX_LEN];
	int 				irtn;
	CSSM_DATA_PTR		keyData = &key->KeyData;
	CSSM_KEYHEADER_PTR	hdr = &key->KeyHeader;
	CSSM_RETURN			crtn;
	CSSM_KEY_SIZE 		keySize;
	
	memset(key, 0, sizeof(CSSM_KEY));
	rtKeyFileName(keyFileBase, isPub, fileName);
	irtn = readFile(fileName, &keyData->Data, (unsigned *)&keyData->Length);
	if(irtn) {
		printf("***error %d reading key file %s\n", irtn, fileName);
		return irtn;
	}
	hdr->HeaderVersion = CSSM_KEYHEADER_VERSION;
	hdr->BlobType = CSSM_KEYBLOB_RAW;
	
	/* Infer format from algorithm and key class */
	switch(alg) {
		case CSSM_ALGID_RSA:
			if(isPub) {
				hdr->Format = CSSM_KEYBLOB_RAW_FORMAT_PKCS1;
			}
			else {
				hdr->Format = CSSM_KEYBLOB_RAW_FORMAT_PKCS8;
			}
			break;
		case CSSM_ALGID_DSA:
			hdr->Format = CSSM_KEYBLOB_RAW_FORMAT_FIPS186;
			break;
		default:
			printf("rt_readKey needs work\n");
			exit(1);
	}
	hdr->AlgorithmId = alg;
	hdr->KeyClass = 
		isPub ? CSSM_KEYCLASS_PUBLIC_KEY : CSSM_KEYCLASS_PRIVATE_KEY;
	hdr->KeyAttr = CSSM_KEYATTR_EXTRACTABLE;
	hdr->KeyUsage = CSSM_KEYUSE_ANY;
	
	/* ask the CSP for key size */
	crtn = CSSM_QueryKeySizeInBits(cspHandle, NULL, key, &keySize);
	if(crtn) {
		cssmPerror("CSSM_QueryKeySizeInBits", crtn);
		return 1;
	}
	hdr->LogicalKeySizeInBits = keySize.LogicalKeySizeInBits;
	return 0;
}
/*
 * No cert- or CDSA-related exceptions thrown by remainder.
 * This is the core initializer: have the CL parse and cache the cert. 
 */
CSSM_RETURN CertParser::initWithData(
	const CSSM_DATA 	&certData)
{
	assert(mClHand != 0);
	CSSM_RETURN crtn = CSSM_CL_CertCache(mClHand, &certData, &mCacheHand);
	#if CP_DEBUG
	if(crtn) {
		cssmPerror("CSSM_CL_CertCache", crtn);
	}
	#endif
	return crtn;
}
Example #10
0
/* convert an OID to a SecPolicyRef */
SecPolicyRef oidToPolicy(
    const CSSM_OID *oid)
{
    OSStatus ortn;
    SecPolicyRef policyRef = NULL;

    ortn = SecPolicyCopy(CSSM_CERT_X_509v3, oid, &policyRef);
    if(ortn) {
        cssmPerror("SecPolicyCopy", ortn);
        return NULL;
    }
    return policyRef;
}
/* Do SecTrustSetUserTrustLegacy() followed by SecTrustGetUserTrust() */
static int doSetVerifyUserTrust(
	SecCertificateRef certRef,
	SecPolicyRef policy,
	SecTrustResultType result)
{
	OSStatus ortn;
	ortn = SecTrustSetUserTrustLegacy(certRef, policy, result);
	if(ortn) {
		cssmPerror("SecTrustSetUserTrustLegacy", ortn);
		return -1;
	}
	return doGetUserTrust(certRef, policy, result);
}
extern int trust_settings_import(int argc, char * const *argv)
{
	extern char *optarg;
	extern int optind;
	OSStatus ortn;
	int arg;
	char *settingsFile = NULL;
	unsigned char *settingsData = NULL;
	size_t settingsLen = 0;
	CFDataRef settings = NULL;
	SecTrustSettingsDomain domain = kSecTrustSettingsDomainUser;
	int rtn;

	if(argc < 2) {
		return 2; /* @@@ Return 2 triggers usage message. */
	}

	optind = 1;
	while ((arg = getopt(argc, argv, "dh")) != -1) {
		switch (arg) {
			case 'd':
				domain = kSecTrustSettingsDomainAdmin;
				break;
			default:
				return 2;
		}
	}
	if(optind != (argc - 1)) {
		/* no args left for settings file */
		return 2;
	}
	settingsFile = argv[optind];
	rtn = readFileSizet(settingsFile, &settingsData, &settingsLen);
	if(rtn) {
		fprintf(stderr, "Error (%d) reading %s.\n", rtn, settingsFile);
		return 1;
	}
	settings = CFDataCreate(NULL, (const UInt8 *)settingsData, settingsLen);
	free(settingsData);
	ortn = SecTrustSettingsImportExternalRepresentation(domain, settings);
	CFRelease(settings);
	if(ortn) {
		cssmPerror("SecTrustSettingsImportExternalRepresentation", ortn);
		rtn = 1;
	}
	else if(!do_quiet) {
		fprintf(stdout, "...Trust Settings imported successfully.\n");
		rtn = 0;
	}
	return rtn;
}
extern int trust_settings_export(int argc, char * const *argv)
{
	extern char *optarg;
	extern int optind;
	OSStatus ortn;
	int arg;
	CFDataRef settings = NULL;
	SecTrustSettingsDomain domain = kSecTrustSettingsDomainUser;
	int rtn;
	char *settingsFile = NULL;
	unsigned len;

	if(argc < 2) {
		return 2; /* @@@ Return 2 triggers usage message. */
	}

	optind = 1;
	while ((arg = getopt(argc, argv, "dsh")) != -1) {
		switch (arg) {
			case 'd':
				domain = kSecTrustSettingsDomainAdmin;
				break;
			case 's':
				domain = kSecTrustSettingsDomainSystem;
				break;
			default:
				return 2;
		}
	}
	if(optind != (argc - 1)) {
		/* no args left for settings file */
		return 2;
	}
	settingsFile = argv[optind];

	ortn = SecTrustSettingsCreateExternalRepresentation(domain, &settings);
	if(ortn) {
		cssmPerror("SecTrustSettingsCreateExternalRepresentation", ortn);
		return 1;
	}
	len = (unsigned) CFDataGetLength(settings);
	rtn = writeFile(settingsFile, CFDataGetBytePtr(settings), len);
	if(rtn) {
		fprintf(stderr, "Error (%d) writing %s.\n", rtn, settingsFile);
	}
	else if(!do_quiet) {
		fprintf(stdout, "...Trust Settings exported successfully.\n");
	}
	CFRelease(settings);
	return rtn;
}
/* do a SecTrustEvaluate, ensure resultType is as specified */
static int doEval(
	CFArrayRef certs,
	SecPolicyRef policy,
	SecTrustResultType expectedResult,
	bool quiet)
{
	OSStatus ortn;
	SecTrustRef trustRef = NULL;
	SecTrustResultType result;
	int ourRtn = 0;

	ortn = SecTrustCreateWithCertificates(certs, policy, &trustRef);
	if(ortn) {
		cssmPerror("SecTrustCreateWithCertificates", ortn);
		return -1;
	}
	ortn = SecTrustEvaluate(trustRef, &result);
	if(ortn) {
		/* shouldn't fail no matter what resultType we expect */
		cssmPerror("SecTrustEvaluate", ortn);
		ourRtn = -1;
		goto errOut;
	}
	if(expectedResult == result) {
		if(!quiet) {
			printf("...got %s as expected\n", secTrustResultStr(result));
		}
	}
	else {
		printf("***Expected %s, got %s\n", secTrustResultStr(expectedResult),
			secTrustResultStr(result));
		ourRtn = -1;
	}
errOut:
	CFRelease(trustRef);
	return ourRtn;
}
/* print cert's label (the one SecCertificate infers) */
OSStatus printCertLabel(
	SecCertificateRef certRef)
{
	OSStatus ortn;
	CFStringRef label;
	
	ortn = SecCertificateInferLabel(certRef, &label);
	if(ortn) {
		cssmPerror("SecCertificateInferLabel", ortn);
		return ortn;
	}
	printCfStr(label);
	CFRelease(label);
	return noErr;
}
/* frees all the fields we fetched */
CertParser::~CertParser()
{
	if(mClHand && mCacheHand) {
		CSSM_RETURN crtn = CSSM_CL_CertAbortCache(mClHand, mCacheHand);
		if(crtn) {
			/* almost certainly a bug */
			printf("Internal Error: CertParser error on free.");
			cssmPerror("CSSM_CL_CertAbortCache", crtn);
		}
	}
	vector<CP_FetchedField *>::iterator iter;
	for(iter=mFetchedFields.begin(); iter!=mFetchedFields.end(); iter++) {
		delete *iter;
	}
}
/* encrypt something with a public key */
static int pubKeyEncrypt(
	SecKeyRef pubKeyRef)
{
	const CSSM_KEY *cssmKey;
	OSStatus ortn;
	CSSM_CSP_HANDLE cspHand;
	
	ortn = SecKeyGetCSSMKey(pubKeyRef, &cssmKey);
	if(ortn) {
		cssmPerror("SecKeyGetCSSMKey", ortn);
		return -1;
	}
	ortn = SecKeyGetCSPHandle(pubKeyRef, &cspHand);
	if(ortn) {
		cssmPerror("SecKeyGetCSPHandle", ortn);
		return -1;
	}
	
	char *ptext = "something to encrypt";
	CSSM_DATA ptextData = {strlen(ptext), (uint8 *)ptext};
	CSSM_DATA ctextData = { 0, NULL };
	CSSM_RETURN crtn;
	
	crtn = cspEncrypt(cspHand, CSSM_ALGID_RSA,
		0, CSSM_PADDING_PKCS1,	// mode/pad
		cssmKey, NULL,
		0, 0,	// effect/rounds
		NULL,	// IV
		&ptextData, &ctextData, CSSM_FALSE);
	if(crtn) {
		return -1;
	}
	/* slighyly hazardous, allocated by CSPDL's allocator */
	free(ctextData.Data);
	return 0;
}
/*
 * Determine if specified SecCertificateRef is a self-signed cert.
 * We do this by comparing the subject and issuerr names; no cryptographic
 * verification is performed.
 *
 * Returns true if the cert appears to be a root. 
 */
static bool isCertRefRoot(
	SecCertificateRef certRef)
{
	bool brtn = false;
#if 0
	/* just search for the two attrs we want */
	UInt32 tags[2] = {kSecSubjectItemAttr, kSecIssuerItemAttr};
	SecKeychainAttributeInfo attrInfo;
	attrInfo.count = 2;
	attrInfo.tag = tags;
	attrInfo.format = NULL;
	SecKeychainAttributeList *attrList = NULL;
	SecKeychainAttribute *attr1 = NULL;
	SecKeychainAttribute *attr2 = NULL;
	
	OSStatus ortn = SecKeychainItemCopyAttributesAndData(
		(SecKeychainItemRef)certRef, 
		&attrInfo,
		NULL,			// itemClass
		&attrList, 
		NULL,			// length - don't need the data
		NULL);			// outData
	if(ortn) {
		cssmPerror("SecKeychainItemCopyAttributesAndData", ortn);
		/* may want to be a bit more robust here, but this should
		 * never happen */
		return false;
	}
	/* subsequent errors to errOut: */
	
	if((attrList == NULL) || (attrList->count != 2)) {
		printf("***Unexpected result fetching label attr\n");
		goto errOut;
	}
	
	/* rootness is just byte-for-byte compare of the two names */ 
	attr1 = &attrList->attr[0];
	attr2 = &attrList->attr[1];
	if(attr1->length == attr2->length) {
		if(memcmp(attr1->data, attr2->data, attr1->length) == 0) {
			brtn = true;
		}
	}
errOut:
	SecKeychainItemFreeAttributesAndData(attrList, NULL);
#endif
	return brtn;
}
Example #19
0
/* app path string to SecTrustedApplicationRef */
SecTrustedApplicationRef appPathToAppRef(
    const char *appPath)
{
    SecTrustedApplicationRef appRef = NULL;
    OSStatus ortn;

    if(appPath == NULL) {
        return NULL;
    }
    ortn = SecTrustedApplicationCreateFromPath(appPath, &appRef);
    if(ortn) {
        cssmPerror("SecTrustedApplicationCreateFromPath", ortn);
        return NULL;
    }
    return appRef;
}
/* Do a SecTrustGetUserTrust(), ensure result is as specified */
static int doGetUserTrust(
	SecCertificateRef certRef,
	SecPolicyRef policy,
	SecTrustResultType expectedResult)
{
	SecTrustResultType foundResult;
	OSStatus ortn = SecTrustGetUserTrust(certRef, policy, &foundResult);
	if(ortn) {
		cssmPerror("SecTrustGetUserTrust", ortn);
		return -1;
	}
	if(foundResult != expectedResult) {
		printf("***Expected current resultType %s; found %s\n",
			secTrustResultStr(expectedResult), secTrustResultStr(foundResult));
		return -1;
	}
	return 0;
}
/*
 * Print subject and/or issuer of a cert.
 */
void printCertName(
    const unsigned char *cert,
    unsigned certLen,
    WhichName whichName)
{
    CSSM_CL_HANDLE clHand = getClHand();
    CSSM_HANDLE cacheHand;
    CSSM_DATA certData = {certLen, (uint8 *)cert};
    CSSM_RETURN crtn;
    bool printSubj = false;
    bool printIssuer = false;
    
    switch(whichName) {
	case NameBoth:
	    printSubj = true;
	    printIssuer = true;
	    break;
	case NameSubject:
	    printSubj = true;
	    break;
	case NameIssuer:
	    printIssuer = true;
	    break;
	default:
	    printf("***BRRZAP! Illegal whichName argument\n");
	    return;
    }
    
    crtn = CSSM_CL_CertCache(clHand, &certData, &cacheHand);
    if(crtn) {
	printf("***Error parsing cert\n");
	cssmPerror("CSSM_CL_CertCache", crtn);
	return;
    }
    
    if(printSubj) {
	printOneCertName(clHand, cacheHand, "Subject", &CSSMOID_X509V1SubjectNameStd);
    }
    if(printIssuer) {
	printOneCertName(clHand, cacheHand, "Issuer", &CSSMOID_X509V1IssuerNameStd);
    }
    CSSM_CL_CertAbortCache(clHand, cacheHand);
    return;
}
int main(int argc, char **argv)
{
	bool quiet = false;
	
	int arg;
	while ((arg = getopt(argc, argv, "qh")) != -1) {
		switch (arg) {
			case 'q':
				quiet = true;
				break;
			case 'h':
				usage(argv);
		}
	}
	
	unsigned numCerts = argc - optind;
	if(numCerts == 0) {
		usage(argv);
	}
	CFMutableArrayRef certArray = CFArrayCreateMutable(NULL, 0, 
		&kCFTypeArrayCallBacks);
	for(int dex=optind; dex<argc; dex++) {
		SecCertificateRef certRef = certFromFile(argv[dex]);
		if(certRef == NULL) {
			exit(1);
		}
		CFArrayAppendValue(certArray, certRef);
		CFRelease(certRef);
	}
	
	OSStatus ortn;
	SecPolicyRef policyRef = NULL;
	ortn = SecPolicyCopy(CSSM_CERT_X_509v3, &CSSMOID_APPLE_TP_SSL, &policyRef);
	if(ortn) {
		cssmPerror("SecPolicyCopy", ortn);
		exit(1);
	}
	
	int ourRtn = doTest(certArray, policyRef, quiet);
	CFRelease(policyRef);
	CFRelease(certArray);
	return ourRtn;
}
static void printOneCertName(
    CSSM_CL_HANDLE clHand,
    CSSM_HANDLE cacheHand,
    const char *title,
    const CSSM_OID *oid)
{
    CSSM_HANDLE resultHand = 0;
    CSSM_DATA_PTR field = NULL;
    uint32 numFields;
    CSSM_RETURN crtn;
    
    crtn = CSSM_CL_CertGetFirstCachedFieldValue(clHand, cacheHand,
	oid, &resultHand, &numFields, &field);
    if(crtn) {
	printf("***Error parsing cert\n");
	cssmPerror("CSSM_CL_CertGetFirstCachedFieldValue", crtn);
	return;
    }
    printName(title, field->Data, field->Length);
    CSSM_CL_FreeFieldValue(clHand, oid, field);
}
Example #24
0
int readCertFile(
    const char *fileName,
    SecCertificateRef *certRef)
{
    unsigned char *cp = NULL;
    unsigned len = 0;
    CSSM_DATA certData;
    OSStatus ortn;
    unsigned char *decoded = NULL;
    unsigned decodedLen = 0;

    if(readFile(fileName, &cp, &len)) {
        printf("***Error reading file %s\n", fileName);
        return -1;
    }
    if(isPem(cp, len)) {
        if(pemDecode(cp, len, &decoded, &decodedLen)) {
            fprintf(stderr, "Error decoding cert file %s\n", fileName);
            return -1;
        }
        certData.Length = decodedLen;
        certData.Data = decoded;
    }
    else {
        certData.Length = len;
        certData.Data = cp;
    }
    ortn = SecCertificateCreateFromData(&certData,
                                        CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_DER, certRef);
    free(cp);
    if(decoded) {
        free(decoded);
    }
    if(ortn) {
        cssmPerror("SecCertificateCreateFromData", ortn);
        return -1;
    }
    return 0;
}
static int do_keychain_import(
	SecKeychainRef		kcRef,
	CFDataRef			inData,
	SecExternalFormat   externFormat,
	SecExternalItemType itemType,
	SecAccessRef		access,
	Boolean				nonExtractable,
	const char			*passphrase,
	const char			*fileName,
	char				**attrNames,
	char				**attrValues,
	unsigned			numExtendedAttributes)
{
	SecKeyImportExportParameters	keyParams;
	OSStatus		ortn;
	CFStringRef		fileStr;
	CFArrayRef		outArray = NULL;
	int				result = 0;
	int				numCerts = 0;
	int				numKeys = 0;
	int				numIdentities = 0;
	int				tryCount = 0;
	CFIndex			dex;
	CFIndex			numItems = 0;
	CFStringRef		passStr = NULL;
	CFStringRef		promptStr = NULL;
	CFStringRef		retryStr = NULL;

	/*
	 * Specify some kind of passphrase in case caller doesn't know this
	 * is a wrapped object
	 */
	memset(&keyParams, 0, sizeof(SecKeyImportExportParameters));
	keyParams.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION;
	if(passphrase != NULL) {
		passStr = CFStringCreateWithCString(NULL, passphrase, kCFStringEncodingASCII);
		keyParams.passphrase = passStr;
	}
	else {
		keyParams.flags = kSecKeySecurePassphrase;
	}
	if(nonExtractable) {
        // explicitly set the key attributes, omitting the CSSM_KEYATTR_EXTRACTABLE bit
        keyParams.keyAttributes = CSSM_KEYATTR_PERMANENT | CSSM_KEYATTR_SENSITIVE;
    }
	keyParams.accessRef = access;

	fileStr = CFStringCreateWithCString(NULL, fileName, kCFStringEncodingUTF8);
	if (fileStr) {
		CFURLRef fileURL = CFURLCreateWithFileSystemPath(NULL, fileStr, kCFURLPOSIXPathStyle, FALSE);
		if (fileURL) {
			CFStringRef nameStr = CFURLCopyLastPathComponent(fileURL);
			if (nameStr) {
				safe_CFRelease(&fileStr);
				fileStr = nameStr;
			}
			safe_CFRelease(&fileURL);
		}
	}
	promptStr = CFStringCreateWithFormat(NULL, NULL, KC_IMPORT_KEY_PASSWORD_MESSAGE, fileStr);
	retryStr = CFStringCreateWithFormat(NULL, NULL, KC_IMPORT_KEY_PASSWORD_RETRYMESSAGE, fileStr);

	while (TRUE)
	{
		keyParams.alertPrompt = (tryCount == 0) ? promptStr : retryStr;

		ortn = SecKeychainItemImport(inData,
									 fileStr,
									 &externFormat,
									 &itemType,
									 0,		/* flags not used (yet) */
									 &keyParams,
									 kcRef,
									 &outArray);

		if(ortn) {
			if (ortn == errSecPkcs12VerifyFailure && ++tryCount < 3) {
				continue;
			}
			sec_perror("SecKeychainItemImport", ortn);
			result = 1;
			goto cleanup;
		}
		break;
	}

	/*
	 * Parse returned items & report to user
	 */
	if(outArray == NULL) {
		sec_error("No keychain items found");
		result = 1;
		goto cleanup;
	}
	numItems = CFArrayGetCount(outArray);
	for(dex=0; dex<numItems; dex++) {
		CFTypeRef item = CFArrayGetValueAtIndex(outArray, dex);
		CFTypeID itemType = CFGetTypeID(item);
		if(itemType == SecIdentityGetTypeID()) {
			numIdentities++;
		}
		else if(itemType == SecCertificateGetTypeID()) {
			numCerts++;
		}
		else if(itemType == SecKeyGetTypeID()) {
			numKeys++;
		}
		else {
			sec_error("Unexpected item type returned from SecKeychainItemImport");
			result = 1;
			goto cleanup;
		}
	}
	if(numIdentities) {
		char *str;
		if(numIdentities > 1) {
			str = "identities";
		}
		else {
			str = "identity";
		}
		fprintf(stdout, "%d %s imported.\n", numIdentities, str);
	}
	if(numKeys) {
		char *str;
		if(numKeys > 1) {
			str = "keys";
		}
		else {
			str = "key";
		}
		fprintf(stdout, "%d %s imported.\n", numKeys, str);
	}
	if(numCerts) {
		char *str;
		if(numCerts > 1) {
			str = "certificates";
		}
		else {
			str = "certificate";
		}
		fprintf(stdout, "%d %s imported.\n", numCerts, str);
	}

	/* optionally apply extended attributes */
	if(numExtendedAttributes) {
		unsigned attrDex;
		for(attrDex=0; attrDex<numExtendedAttributes; attrDex++) {
			CFStringRef attrNameStr = CFStringCreateWithCString(NULL, attrNames[attrDex],
				kCFStringEncodingASCII);
			CFDataRef attrValueData = CFDataCreate(NULL, (const UInt8 *)attrValues[attrDex],
				strlen(attrValues[attrDex]));
			for(dex=0; dex<numItems; dex++) {
				SecKeychainItemRef itemRef =
					(SecKeychainItemRef)CFArrayGetValueAtIndex(outArray, dex);
				ortn = SecKeychainItemSetExtendedAttribute(itemRef, attrNameStr, attrValueData);
				if(ortn) {
					cssmPerror("SecKeychainItemSetExtendedAttribute", ortn);
					result = 1;
					break;
				}
			}	/* for each imported item */
			CFRelease(attrNameStr);
			CFRelease(attrValueData);
			if(result) {
				break;
			}
		}	/* for each extended attribute */
	}

cleanup:
	safe_CFRelease(&fileStr);
	safe_CFRelease(&outArray);
	safe_CFRelease(&passStr);
	safe_CFRelease(&promptStr);
	safe_CFRelease(&retryStr);

	return result;
}
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];
	RingBufferArgs	clientArgs;
	RingBufferArgs	serverArgs;
	bool			abortFlag = false;
	pthread_t		client_thread = NULL;
	int				result;
	OSStatus		ortn;
	unsigned char	sessionTicket[SESSION_TICKET_SIZE];
	int				ourRtn = 0;
	CFArrayRef		idArray = NULL;				/* for SSLSetCertificate */
	CFArrayRef		anchorArray = NULL;			/* trusted roots */
	char			*hostName = NULL;
	
	/* user-spec'd variables */
	char 			*kcName = NULL;
	unsigned 		xferSize = DEFAULT_XFER;
	bool			pauseOnError = false;
	bool			runForever = false;
	bool			skipPAC = false;

	extern int optind;
	extern char *optarg;
	int arg;
	optind = 1;
	while ((arg = getopt(argc, argv, "x:c:k:h:np")) != -1) {
		switch (arg) {
			case 'x':
			{
				unsigned xsize = atoi(optarg);
				if(xsize == 0) {
					runForever = true;
					/* and leave xferSize alone */
				}
				else {
					xferSize = xsize;
				}
				break;
			}
			case 'k':
				kcName = optarg;
				break;
			case 'n':
				skipPAC = true;
				break;
			case 'h':
				/* mainly to test EAP session ticket and ServerName simultaneously */
				hostName = optarg;
				break;
			case 'p':
				pauseOnError = 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 optional server SecIdentity */
	if(kcName) {
		SecKeychainRef	kcRef = NULL;
		SecCertificateRef anchorCert = NULL;
		SecIdentityRef	idRef = NULL;
		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);
		CFRelease(kcRef);
		CFRelease(anchorCert);
	}

	/* set up server side */
	memset(&serverArgs, 0, sizeof(serverArgs));
	serverArgs.xferSize = xferSize;
	serverArgs.xferBuf = serverBuf;
	serverArgs.chunkSize = chunkSize;
	serverArgs.ringWrite = &serverToClientRing;
	serverArgs.ringRead = &clientToServerRing;
	serverArgs.goFlag = &clientArgs.iAmReady;
	serverArgs.abortFlag = &abortFlag;
	serverArgs.pauseOnError = pauseOnError;
	appGetRandomBytes(serverArgs.sharedSecret, SHARED_SECRET_SIZE);
	if(!skipPAC) {
		serverArgs.setMasterSecret = true;
	}
	serverArgs.idArray = idArray;
	serverArgs.trustedRoots = anchorArray;

	/* set up client side */
	memset(&clientArgs, 0, sizeof(clientArgs));
	clientArgs.xferSize = xferSize;
	clientArgs.xferBuf = clientBuf;
	clientArgs.chunkSize = chunkSize;
	clientArgs.ringWrite = &clientToServerRing;
	clientArgs.ringRead = &serverToClientRing;
	clientArgs.goFlag = &serverArgs.iAmReady;
	clientArgs.abortFlag = &abortFlag;
	clientArgs.pauseOnError = pauseOnError;
	memmove(clientArgs.sharedSecret, serverArgs.sharedSecret, SHARED_SECRET_SIZE);
	clientArgs.hostName = hostName;
	
	/* for now set up an easily recognizable ticket */
	for(unsigned dex=0; dex<SESSION_TICKET_SIZE; dex++) {
		sessionTicket[dex] = dex;
	}
	clientArgs.sessionTicket = sessionTicket;
	clientArgs.sessionTicketLen = SESSION_TICKET_SIZE;
	/* client always tries setting the master secret in this test */
	clientArgs.setMasterSecret = true;
	clientArgs.trustedRoots = anchorArray;

	/* fire up client thread */
	result = pthread_create(&client_thread, NULL, 
			rbClientThread, &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 = rbServerThread(&serverArgs);
	
	if(abortFlag) {
		printf("***Test aborted.\n");
		exit(1);
	}
	
	printf("\n");
	
	printf("SSL Protocol Version : %s\n",
		sslGetProtocolVersionString(serverArgs.negotiatedProt));
	printf("SSL Cipher           : %s\n",
		sslGetCipherSuiteString(serverArgs.negotiatedCipher));
		
	if(skipPAC) {
		if(clientArgs.sessionWasResumed) {
			printf("***skipPAC true, but client reported sessionWasResumed\n");
			ourRtn = -1;
		}
		if(serverArgs.sessionWasResumed) {
			printf("***skipPAC true, but server reported sessionWasResumed\n");
			ourRtn = -1;
		}
		if(ourRtn == 0) {
			printf("...PAC session attempted by client; refused by server;\n");
			printf("   Normal session proceeded correctly.\n");
		}
	}
	else {
		if(!clientArgs.sessionWasResumed) {
			printf("***client reported !sessionWasResumed\n");
			ourRtn = -1;
		}
		if(!serverArgs.sessionWasResumed) {
			printf("***server reported !sessionWasResumed\n");
			ourRtn = -1;
		}
		if(memcmp(clientBuf, serverBuf, DEFAULT_CHUNK)) {
			printf("***Data miscompare***\n");
			ourRtn = -1;
		}
		if(ourRtn == 0) {
			printf("...PAC session resumed correctly.\n");
		}
	}
	/* FIXME other stuff? */

	return ourRtn;
}
Example #27
0
int
trusted_cert_dump(int argc, char * const *argv)
{
    CFArrayRef certArray = NULL;
    OSStatus ortn = noErr;
    CFIndex numCerts;
    CFIndex dex;
    CFArrayRef trustSettings;
    int ourRtn = 0;
    SecTrustSettingsDomain domain = kSecTrustSettingsDomainUser;

    extern char *optarg;
    extern int optind;
    int arg;

    optind = 1;
    while ((arg = getopt(argc, argv, "sdh")) != -1) {
        switch (arg) {
        case 's':
            domain = kSecTrustSettingsDomainSystem;
            break;
        case 'd':
            domain = kSecTrustSettingsDomainAdmin;
            break;
        default:
        case 'h':
            return 2; /* @@@ Return 2 triggers usage message. */
        }
    }

    if(optind != argc) {
        return 2; /* @@@ Return 2 triggers usage message. */
    }

    ortn = SecTrustSettingsCopyCertificates(domain, &certArray);
    if(ortn) {
        cssmPerror("SecTrustSettingsCopyCertificates", ortn);
        return 1;
    }
    numCerts = CFArrayGetCount(certArray);
    printf("Number of trusted certs = %ld\n", (long)numCerts);

    for(dex=0; dex<numCerts; dex++) {
        SecCertificateRef certRef =
            (SecCertificateRef)CFArrayGetValueAtIndex(certArray, dex);
        if(CFGetTypeID(certRef) != SecCertificateGetTypeID()) {
            fprintf(stderr, "***Bad CFGetTypeID for cert %ld\n", (long)dex);
            ourRtn = -1;
            break;
        }

        /* always print the cert's label */
        printf("Cert %ld: ", dex);
        printCertLabel(certRef);
        printf("\n");

        /* see if the cert has any usage constraints (it should!) */
        ortn = SecTrustSettingsCopyTrustSettings(certRef, domain, &trustSettings);
        if(ortn) {
            cssmPerror("SecTrustSettingsCopyTrustSettings", ortn);
            ourRtn = -1;
            continue;
        }
        if(displayTrustSettings(trustSettings)) {
            ourRtn = -1;
        }
    }
    CFRelease(certArray);

    return ourRtn;
}
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;
}
/*
 * Log CSSM error.
 */
void cuPrintError(const char *op, CSSM_RETURN err)
{
	cssmPerror(op, err);
}
Example #30
0
/*
 * Display a Trust Settings array as obtained from
 * SecTrustSettingsCopyTrustSettings().
 */
static int displayTrustSettings(
    CFArrayRef	trustSettings)
{
    /* must always be there though it may be empty */
    if(trustSettings == NULL) {
        fprintf(stderr, "***displayTrustSettings: missing trust settings array");
        return -1;
    }
    if(CFGetTypeID(trustSettings) != CFArrayGetTypeID()) {
        fprintf(stderr, "***displayTrustSettings: malformed trust settings array");
        return -1;
    }

    int ourRtn = 0;
    CFIndex numUseConstraints = CFArrayGetCount(trustSettings);
    indentIncr();
    indent();
    printf("Number of trust settings : %ld\n", (long)numUseConstraints);
    OSStatus ortn;
    SecPolicyRef certPolicy;
    SecTrustedApplicationRef certApp;
    CFDictionaryRef ucDict;
    CFStringRef policyStr;
    CFNumberRef cfNum;
    CFIndex ucDex;

    /* grind thru the trust settings dictionaries */
    for(ucDex=0; ucDex<numUseConstraints; ucDex++) {
        indent();
        printf("Trust Setting %ld:\n", (long)ucDex);
        indentIncr();

        ucDict = (CFDictionaryRef)CFArrayGetValueAtIndex(trustSettings, ucDex);
        if(CFGetTypeID(ucDict) != CFDictionaryGetTypeID()) {
            fprintf(stderr, "***displayTrustSettings: malformed usage constraints dictionary");
            ourRtn = -1;
            goto nextAp;
        }

        /* policy - optional */
        certPolicy = (SecPolicyRef)CFDictionaryGetValue(ucDict, kSecTrustSettingsPolicy);
        if(certPolicy != NULL) {
            if(CFGetTypeID(certPolicy) != SecPolicyGetTypeID()) {
                fprintf(stderr, "***displayTrustSettings: malformed certPolicy");
                ourRtn = -1;
                goto nextAp;
            }
            CSSM_OID policyOid;
            ortn = SecPolicyGetOID(certPolicy, &policyOid);
            if(ortn) {
                cssmPerror("SecPolicyGetOID", ortn);
                ourRtn = -1;
                goto nextAp;
            }
            indent();
            printf("Policy OID            : %s\n",
                   oidToOidString(&policyOid));
        }

        /* app - optional  */
        certApp = (SecTrustedApplicationRef)CFDictionaryGetValue(ucDict,
                  kSecTrustSettingsApplication);
        if(certApp != NULL) {
            if(CFGetTypeID(certApp) != SecTrustedApplicationGetTypeID()) {
                fprintf(stderr, "***displayTrustSettings: malformed certApp");
                ourRtn = -1;
                goto nextAp;
            }
            CFDataRef appPath = NULL;
            ortn = SecTrustedApplicationCopyData(certApp, &appPath);
            if(ortn) {
                cssmPerror("SecTrustedApplicationCopyData", ortn);
                ourRtn = -1;
                goto nextAp;
            }
            indent();
            printf("Application           : %s", CFDataGetBytePtr(appPath));
            printf("\n");
            CFRelease(appPath);
        }

        /* policy string */
        policyStr = (CFStringRef)CFDictionaryGetValue(ucDict, kSecTrustSettingsPolicyString);
        if(policyStr != NULL) {
            if(CFGetTypeID(policyStr) != CFStringGetTypeID()) {
                fprintf(stderr, "***displayTrustSettings: malformed policyStr");
                ourRtn = -1;
                goto nextAp;
            }
            indent();
            printf("Policy String         : ");
            printCfStr(policyStr);
            printf("\n");
        }

        /* Allowed error */
        cfNum = (CFNumberRef)CFDictionaryGetValue(ucDict, kSecTrustSettingsAllowedError);
        if(cfNum != NULL) {
            if(CFGetTypeID(cfNum) != CFNumberGetTypeID()) {
                fprintf(stderr, "***displayTrustSettings: malformed allowedError");
                ourRtn = -1;
                goto nextAp;
            }
            indent();
            printf("Allowed Error         : ");
            printCssmErr(cfNum);
            printf("\n");
        }

        /* ResultType */
        cfNum = (CFNumberRef)CFDictionaryGetValue(ucDict, kSecTrustSettingsResult);
        if(cfNum != NULL) {
            if(CFGetTypeID(cfNum) != CFNumberGetTypeID()) {
                fprintf(stderr, "***displayTrustSettings: malformed ResultType");
                ourRtn = -1;
                goto nextAp;
            }
            indent();
            printf("Result Type           : ");
            printResultType(cfNum);
            printf("\n");
        }

        /* key usage */
        cfNum = (CFNumberRef)CFDictionaryGetValue(ucDict, kSecTrustSettingsKeyUsage);
        if(cfNum != NULL) {
            if(CFGetTypeID(cfNum) != CFNumberGetTypeID()) {
                fprintf(stderr, "***displayTrustSettings: malformed keyUsage");
                ourRtn = -1;
                goto nextAp;
            }
            indent();
            printf("Key Usage             : ");
            printKeyUsage(cfNum);
            printf("\n");
        }

nextAp:
        indentDecr();
    }
    indentDecr();
    return ourRtn;
}