예제 #1
0
STATIC SecTrustedApplicationRef
create_trusted_app_from_bundle_resource(CFStringRef bundle_path,
					CFStringRef resource_path)
{
    CFBundleRef			bundle;
    CFURLRef			bundle_url;
    CFURLRef			eapolclient_url = NULL;
    char			path[MAXPATHLEN];
    Boolean			success = FALSE;
    SecTrustedApplicationRef	trusted_app = NULL;

    bundle_url = CFURLCreateWithFileSystemPath(NULL,
					       bundle_path,
					       kCFURLPOSIXPathStyle, FALSE);
    if (bundle_url == NULL) {
	goto done;
    }
    bundle = CFBundleCreate(NULL, bundle_url);
    CFRelease(bundle_url);
    if (bundle == NULL) {
	goto done;
    }
    eapolclient_url 
	= CFBundleCopyResourceURL(bundle, CFSTR(keapolclientPath),
				  NULL, NULL);
    CFRelease(bundle);
    if (eapolclient_url == NULL) {
	goto done;
    }
    success = CFURLGetFileSystemRepresentation(eapolclient_url,
					       TRUE,
					       (UInt8 *)path, sizeof(path));
    CFRelease(eapolclient_url);
    if (success) {
	OSStatus	status;

	status = SecTrustedApplicationCreateFromPath(path,
						     &trusted_app);
	if (status != noErr) {
	    fprintf(stderr,
		    "SecTrustedApplicationCreateFromPath(%s) failed, %d\n",
		    path, (int)status);
	}
    }

 done:
    return (trusted_app);
}
예제 #2
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;
}
int
keychain_import(int argc, char * const *argv)
{
	int ch, result = 0;

	char *inFile = NULL;
	char *kcName = NULL;
	SecKeychainRef kcRef = NULL;
	SecExternalFormat externFormat = kSecFormatUnknown;
	SecExternalItemType itemType = kSecItemTypeUnknown;
	Boolean wrapped = FALSE;
	Boolean nonExtractable = FALSE;
	const char *passphrase = NULL;
	unsigned char *inFileData = NULL;
	unsigned inFileLen = 0;
	CFDataRef inData = NULL;
	unsigned numExtendedAttributes = 0;
	char **attrNames = NULL;
	char **attrValues = NULL;
	Boolean access_specified = FALSE;
	Boolean always_allow = FALSE;
	SecAccessRef access = NULL;
	CFMutableArrayRef trusted_list = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);

	if(argc < 2) {
		result = 2; /* @@@ Return 2 triggers usage message. */
		goto cleanup;
	}
	inFile = argv[1];
	if((argc == 2) && (inFile[0] == '-')) {
		result = 2;
		goto cleanup;
	}
	optind = 2;

    while ((ch = getopt(argc, argv, "k:t:f:P:wxa:hAT:")) != -1)
	{
		switch  (ch)
		{
		case 'k':
			kcName = optarg;
			break;
		case 't':
			if(!strcmp("pub", optarg)) {
				itemType = kSecItemTypePublicKey;
			}
			else if(!strcmp("priv", optarg)) {
				itemType = kSecItemTypePrivateKey;
			}
			else if(!strcmp("session", optarg)) {
				itemType = kSecItemTypeSessionKey;
			}
			else if(!strcmp("cert", optarg)) {
				itemType = kSecItemTypeCertificate;
			}
			else if(!strcmp("agg", optarg)) {
				itemType = kSecItemTypeAggregate;
			}
			else {
				result = 2; /* @@@ Return 2 triggers usage message. */
				goto cleanup;
			}
			break;
		case 'f':
			if(!strcmp("openssl", optarg)) {
				externFormat = kSecFormatOpenSSL;
			}
			else if(!strcmp("openssh1", optarg)) {
				externFormat = kSecFormatSSH;
			}
			else if(!strcmp("openssh2", optarg)) {
				externFormat = kSecFormatSSHv2;
			}
			else if(!strcmp("bsafe", optarg)) {
				externFormat = kSecFormatBSAFE;
			}
			else if(!strcmp("raw", optarg)) {
				externFormat = kSecFormatRawKey;
			}
			else if(!strcmp("pkcs7", optarg)) {
				externFormat = kSecFormatPKCS7;
			}
			else if(!strcmp("pkcs8", optarg)) {
				externFormat = kSecFormatWrappedPKCS8;
			}
			else if(!strcmp("pkcs12", optarg)) {
				externFormat = kSecFormatPKCS12;
			}
			else if(!strcmp("netscape", optarg)) {
				externFormat = kSecFormatNetscapeCertSequence;
			}
			else if(!strcmp("x509", optarg)) {
				externFormat = kSecFormatX509Cert;
			}
			else if(!strcmp("pemseq", optarg)) {
				externFormat = kSecFormatPEMSequence;
			}
			else {
				result = 2; /* @@@ Return 2 triggers usage message. */
				goto cleanup;
			}
			break;
		case 'w':
			wrapped = TRUE;
			break;
		case 'x':
			nonExtractable = TRUE;
			break;
		case 'P':
			passphrase = optarg;
			break;
		case 'a':
			/* this takes an additional argument */
			if(optind > (argc - 1)) {
				result = 2; /* @@@ Return 2 triggers usage message. */
				goto cleanup;
			}
			attrNames  = (char **)realloc(attrNames, numExtendedAttributes * sizeof(char *));
			attrValues = (char **)realloc(attrValues, numExtendedAttributes * sizeof(char *));
			attrNames[numExtendedAttributes]  = optarg;
			attrValues[numExtendedAttributes] = argv[optind];
			numExtendedAttributes++;
			optind++;
			break;
		case 'A':
			always_allow = TRUE;
			access_specified = TRUE;
			break;
		case 'T':
			if (optarg[0])
			{
				SecTrustedApplicationRef app = NULL;
				OSStatus status = noErr;
				/* check whether the argument specifies an application group */
				const char *groupPrefix = "group://";
				size_t prefixLen = strlen(groupPrefix);
				if (strlen(optarg) > prefixLen && !memcmp(optarg, groupPrefix, prefixLen)) {
					const char *groupName = &optarg[prefixLen];
					if ((status = SecTrustedApplicationCreateApplicationGroup(groupName, NULL, &app)) != noErr) {
						sec_error("SecTrustedApplicationCreateApplicationGroup %s: %s", optarg, sec_errstr(status));
					}
				} else {
					if ((status = SecTrustedApplicationCreateFromPath(optarg, &app)) != noErr) {
						sec_error("SecTrustedApplicationCreateFromPath %s: %s", optarg, sec_errstr(status));
					}
				}

				if (status) {
					result = 1;
					goto cleanup;
				}

				CFArrayAppendValue(trusted_list, app);
				CFRelease(app);
			}
			access_specified = TRUE;
			break;
		case '?':
		default:
			result = 2; /* @@@ Return 2 triggers usage message. */
			goto cleanup;
		}
	}

	if(wrapped) {
		switch(externFormat) {
			case kSecFormatOpenSSL:
			case kSecFormatUnknown:		// i.e., use default
				externFormat = kSecFormatWrappedOpenSSL;
				break;
			case kSecFormatSSH:
				externFormat = kSecFormatWrappedSSH;
				break;
			case kSecFormatSSHv2:
				/* there is no wrappedSSHv2 */
				externFormat = kSecFormatWrappedOpenSSL;
				break;
			case kSecFormatWrappedPKCS8:
				/* proceed */
				break;
			default:
				fprintf(stderr, "Don't know how to wrap in specified format/type\n");
				result = 2; /* @@@ Return 2 triggers usage message. */
				goto cleanup;
		}
	}

	if(kcName) {
		kcRef = keychain_open(kcName);
		if(kcRef == NULL) {
			return 1;
		}
	}
	if(readFile(inFile, &inFileData, &inFileLen)) {
		sec_error("Error reading infile %s: %s", inFile, strerror(errno));
		result = 1;
		goto cleanup;
	}
	inData = CFDataCreate(NULL, inFileData, inFileLen);
	if(inData == NULL) {
		result = 1;
		goto cleanup;
	}
	free(inFileData);

	if(access_specified)
	{
		char *accessName = NULL;
		CFStringRef fileStr = CFStringCreateWithCString(NULL, inFile, kCFStringEncodingUTF8);
		if (fileStr) {
			CFURLRef fileURL = CFURLCreateWithFileSystemPath(NULL, fileStr, kCFURLPOSIXPathStyle, FALSE);
			if (fileURL) {
				CFStringRef nameStr = CFURLCopyLastPathComponent(fileURL);
				if (nameStr) {
					CFIndex nameLen = CFStringGetLength(nameStr);
					CFIndex bufLen = 1 + CFStringGetMaximumSizeForEncoding(nameLen, kCFStringEncodingUTF8);
					accessName = (char *)malloc(bufLen);
					if (!CFStringGetCString(nameStr, accessName, bufLen-1, kCFStringEncodingUTF8))
						accessName[0]=0;
					nameLen = strlen(accessName);
					char *p = &accessName[nameLen]; // initially points to terminating null
					while (--nameLen > 0) {
						if (*p == '.') { // strip extension, if any
							*p = '\0';
							break;
						}
						p--;
					}
					safe_CFRelease(&nameStr);
				}
				safe_CFRelease(&fileURL);
			}
			safe_CFRelease(&fileStr);
		}

		result = create_access(accessName, always_allow, trusted_list, &access);

		if (accessName) {
			free(accessName);
		}
		if (result != 0) {
			goto cleanup;
		}
	}

	result = do_keychain_import(kcRef, inData, externFormat, itemType, access,
								nonExtractable, passphrase, inFile, attrNames,
								attrValues, numExtendedAttributes);

cleanup:
	safe_CFRelease(&trusted_list);
	safe_CFRelease(&access);
	safe_CFRelease(&kcRef);
	safe_CFRelease(&inData);

	return result;
}
예제 #4
0
STATIC CFArrayRef
copy_trusted_applications(bool eapolclient_only)
{
    CFMutableArrayRef		array;
    SecTrustedApplicationRef	trusted_app;
    OSStatus			status;

    array = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);

    /* eapolclient */
    trusted_app
	= create_trusted_app_from_bundle_resource(CFSTR(kEAPOLControllerPath),
						  CFSTR(keapolclientPath));
    if (trusted_app != NULL) {
	CFArrayAppendValue(array, trusted_app);
	CFRelease(trusted_app);
    }

    /* AirPort Application Group */
    status 
	= SecTrustedApplicationCreateApplicationGroup(kAirPortApplicationGroup,
						      NULL, &trusted_app);
    if (status != noErr) {
	fprintf(stderr,
		"SecTrustedApplicationCreateApplicationGroup("
		kAirPortApplicationGroup ") failed, %d\n",
		(int)status);
    }
    else {
	CFArrayAppendValue(array, trusted_app);
	CFRelease(trusted_app);
    }
    if (eapolclient_only) {
	goto done;
    }

    /* this executable */
    status = SecTrustedApplicationCreateFromPath(NULL, &trusted_app);
    if (status != noErr) {
	fprintf(stderr,
		"SecTrustedApplicationCreateFromPath(NULL) failed, %d\n",
		(int)status);
    }
    else {
	CFArrayAppendValue(array, trusted_app);
	CFRelease(trusted_app);
    }

    /* SystemUIServer */
    status = SecTrustedApplicationCreateFromPath(kSystemUIServerPath, 
						 &trusted_app);
    if (status != noErr) {
	fprintf(stderr,
		"SecTrustedApplicationCreateFromPath(%s) failed, %d\n",
		kSystemUIServerPath,
		(int)status);
    }
    else {
	CFArrayAppendValue(array, trusted_app);
	CFRelease(trusted_app);
    }

 done:
    if (CFArrayGetCount(array) == 0) {
	my_CFRelease(&array);
    }
    return (array);
}
OSStatus SecAccessCreateWithTrustedApplications(CFStringRef trustedApplicationsPListPath, CFStringRef accessLabel, Boolean allowAny, SecAccessRef* returnedAccess)
{
	OSStatus err = errSecSuccess;
	SecAccessRef accessToReturn=nil;
	CFMutableArrayRef trustedApplications=nil;

	if (!allowAny) // use default access ("confirm access")
	{
		// make an exception list of applications you want to trust,
		// which are allowed to access the item without requiring user confirmation
		SecTrustedApplicationRef myself=NULL, someOther=NULL;
        CFArrayRef trustedAppListFromBundle=NULL;

        trustedApplications=CFArrayCreateMutable(kCFAllocatorDefault,0,&kCFTypeArrayCallBacks);
        err = SecTrustedApplicationCreateFromPath(NULL, &myself);
        if (!err)
            CFArrayAppendValue(trustedApplications,myself);

		CFURLRef url = CFURLCreateWithFileSystemPath(NULL, trustedApplicationsPListPath, kCFURLPOSIXPathStyle, 0);
		CFStringRef leafStr = NULL;
		leafStr = CFURLCopyLastPathComponent(url);

		CFURLRef bndlPathURL = NULL;
		bndlPathURL = CFURLCreateCopyDeletingLastPathComponent(NULL, url);
		CFStringRef bndlPath = NULL;
		bndlPath = CFURLCopyFileSystemPath(bndlPathURL, kCFURLPOSIXPathStyle);
        trustedAppListFromBundle=copyTrustedAppListFromBundle(bndlPath, leafStr);
		if ( leafStr )
			CFRelease(leafStr);
		if ( bndlPath )
			CFRelease(bndlPath);
		if ( url )
			CFRelease(url);
		if ( bndlPathURL )
			CFRelease(bndlPathURL);
        if (trustedAppListFromBundle)
        {
            CFIndex ix,top;
            char buffer[MAXPATHLEN];
            top = CFArrayGetCount(trustedAppListFromBundle);
            for (ix=0;ix<top;ix++)
            {
                CFStringRef filename = (CFStringRef)CFArrayGetValueAtIndex(trustedAppListFromBundle,ix);
                CFIndex stringLength = CFStringGetLength(filename);
                CFIndex usedBufLen;

                if (stringLength != CFStringGetBytes(filename,CFRangeMake(0,stringLength),kCFStringEncodingUTF8,0,
                    false,(UInt8 *)&buffer,MAXPATHLEN, &usedBufLen))
                    break;
                buffer[usedBufLen] = 0;
				//
				// Support specification of trusted applications by either
				// a full pathname or a code requirement string.
				//
				if (buffer[0]=='/')
				{
					err = SecTrustedApplicationCreateFromPath(buffer,&someOther);
				}
				else
				{
					char *buf = NULL;
					CFStringRef reqStr = filename;
					CFArrayRef descArray = CFStringCreateArrayBySeparatingStrings(NULL, reqStr, CFSTR("\""));
					if (descArray && (CFArrayGetCount(descArray) > 1))
					{
						CFStringRef descStr = (CFStringRef) CFArrayGetValueAtIndex(descArray, 1);
						if (descStr)
							buf = CFStringToCString(descStr);
					}
					SecRequirementRef reqRef = NULL;
					err = SecRequirementCreateWithString(reqStr, kSecCSDefaultFlags, &reqRef);
					if (!err)
						err = SecTrustedApplicationCreateFromRequirement((const char *)buf, reqRef, &someOther);
					if (buf)
						free(buf);
					CFReleaseSafe(reqRef);
					CFReleaseSafe(descArray);
				}
                if (!err)
                    CFArrayAppendValue(trustedApplications,someOther);

				if (someOther)
					CFReleaseNull(someOther);
            }
            CFRelease(trustedAppListFromBundle);
        }
	}

	err = SecAccessCreate((CFStringRef)accessLabel, (CFArrayRef)trustedApplications, &accessToReturn);
    if (!err)
	{
		if (allowAny) // change access to be wide-open for decryption ("always allow access")
		{
			// get the access control list for decryption operations
			CFArrayRef aclList=nil;
			err = SecAccessCopySelectedACLList(accessToReturn, CSSM_ACL_AUTHORIZATION_DECRYPT, &aclList);
			if (!err)
			{
				// get the first entry in the access control list
				SecACLRef aclRef=(SecACLRef)CFArrayGetValueAtIndex(aclList, 0);
				CFArrayRef appList=nil;
				CFStringRef promptDescription=nil;
				CSSM_ACL_KEYCHAIN_PROMPT_SELECTOR promptSelector;
				err = SecACLCopySimpleContents(aclRef, &appList, &promptDescription, &promptSelector);

				// modify the default ACL to not require the passphrase, and have a nil application list
				promptSelector.flags &= ~CSSM_ACL_KEYCHAIN_PROMPT_REQUIRE_PASSPHRASE;
				err = SecACLSetSimpleContents(aclRef, NULL, promptDescription, &promptSelector);

				if (appList) CFRelease(appList);
				if (promptDescription) CFRelease(promptDescription);
			}
		}
	}
	*returnedAccess = accessToReturn;
	return err;
}