Пример #1
0
static VALUE rb_keychain_item_delete(VALUE self){

  SecKeychainItemRef keychainItem=NULL;
  Data_Get_Struct(self, struct OpaqueSecKeychainItemRef, keychainItem);
  OSStatus result = SecKeychainItemDelete(keychainItem);
  CheckOSStatusOrRaise(result);
  return self;
}
static int
do_keychain_delete_internet_password(CFTypeRef keychainOrArray,
	FourCharCode itemCreator,
	FourCharCode itemType,
	const char *kind,
	const char *comment,
	const char *label,
	const char *serverName,
	const char *securityDomain,
	const char *accountName,
	const char *path,
	UInt16 port,
	SecProtocolType protocol,
	SecAuthenticationType authenticationType)
{
	OSStatus result = noErr;
    SecKeychainItemRef itemRef = NULL;
	void *passwordData = NULL;

	itemRef = find_first_internet_password(keychainOrArray,
										   itemCreator,
										   itemType,
										   kind,
										   comment,
										   label,
										   serverName,
										   securityDomain,
										   accountName,
										   path,
										   port,
										   protocol,
										   authenticationType);
	if (!itemRef) {
		result = errSecItemNotFound;
		sec_perror("SecKeychainSearchCopyNext", result);
		goto cleanup;
	}

	print_keychain_item_attributes(stdout, itemRef, FALSE, FALSE, FALSE, FALSE);

	result = SecKeychainItemDelete(itemRef);

	fputs("password has been deleted.\n", stderr);

cleanup:
	if (passwordData)
		SecKeychainItemFreeContent(NULL, passwordData);
	if (itemRef)
		CFRelease(itemRef);

	return result;
}
Пример #3
0
void keychain_clear_password(const char *server, const char *username)
{
	if (!strlen(server) || !strlen(username))
		return;
		
	BADGE_HOSTNAME(server);
	
	SecKeychainItemRef keychainItem = get_password_details(server, username, NULL, 0);
	if (keychainItem)
		SecKeychainItemDelete(keychainItem);
	
	free((void*)server);
}
static OSStatus callbackFunction(SecKeychainEvent keychainEvent,
	SecKeychainCallbackInfo *info, void *context)
{
	assert(keychainEvent == kSecAddEvent && context != NULL);
	assert(info != NULL);
	assert(info->item != NULL);

	checkContent(info->item);
	*((UInt32 *)context) = 1;

	ok_status(SecKeychainItemDelete(info->item), "delete item");
	return 0;
}
Пример #5
0
char *keychain_remove(char *service, char *account) {
    SecKeychainItemRef item;
    OSStatus status = SecKeychainFindGenericPassword(
        NULL,
        strlen(service), service,
        strlen(account), account,
        NULL, NULL,
        &item
    );
    if (status) return get_error(status);

    status = SecKeychainItemDelete(item);
    if (status) return get_error(status);
    return NULL;
}
Пример #6
0
static void delete_internet_password(void)
{
	SecKeychainItemRef item;

	/*
	 * Require at least a protocol and host for removal, which is what git
	 * will give us; if you want to do something more fancy, use the
	 * Keychain manager.
	 */
	if (!protocol || !host)
		return;

	if (SecKeychainFindInternetPassword(KEYCHAIN_ARGS, 0, NULL, &item))
		return;

	SecKeychainItemDelete(item);
}
/* Implementation of OSXKeychain.deleteGenericPassword(). See the Java docs for
 * explanations of the parameters.
 */
JNIEXPORT void JNICALL Java_com_mcdermottroe_apple_OSXKeychain__1deleteGenericPassword(JNIEnv* env, jobject obj, jstring serviceName, jstring accountName) {
	OSStatus status;
	jstring_unpacked service_name;
	jstring_unpacked account_name;
	SecKeychainItemRef itemToDelete;

	/* Query the keychain. */
	status = SecKeychainSetPreferenceDomain(kSecPreferencesDomainUser);
	if (status != errSecSuccess) {
		throw_osxkeychainexception(env, status);
		return;
	}

	/* Unpack the params. */
	jstring_unpack(env, serviceName, &service_name);
	jstring_unpack(env, accountName, &account_name);
	if (service_name.str == NULL || 
	    account_name.str == NULL) {
		jstring_unpacked_free(env, serviceName, &service_name);
		jstring_unpacked_free(env, accountName, &account_name);
		return;
	}
	status = SecKeychainFindGenericPassword(
		NULL,
		service_name.len,
		service_name.str,
		account_name.len,
		account_name.str,
		NULL,
		NULL,
		&itemToDelete
	);
	if (status != errSecSuccess) {
		throw_osxkeychainexception(env, status);
	}
	else {
		status = SecKeychainItemDelete(itemToDelete);
		if (status != errSecSuccess) {
			throw_osxkeychainexception(env, status);
		}
	}

	/* Clean up. */
	jstring_unpacked_free(env, serviceName, &service_name);
	jstring_unpacked_free(env, accountName, &account_name);
}
static int
do_keychain_delete_generic_password(CFTypeRef keychainOrArray,
	FourCharCode itemCreator,
	FourCharCode itemType,
	const char *kind,
	const char *value,
	const char *comment,
	const char *label,
	const char *serviceName,
	const char *accountName)
{
	OSStatus result = noErr;
    SecKeychainItemRef itemRef = NULL;
	void *passwordData = NULL;

	itemRef = find_first_generic_password(keychainOrArray,
										  itemCreator,
										  itemType,
										  kind,
										  value,
										  comment,
										  label,
										  serviceName,
										  accountName);
	if (!itemRef) {
		result = errSecItemNotFound;
		sec_perror("SecKeychainSearchCopyNext", result);
		goto cleanup;
	}

	print_keychain_item_attributes(stdout, itemRef, FALSE, FALSE, FALSE, FALSE);

	result = SecKeychainItemDelete(itemRef);

	fputs("password has been deleted.\n", stderr);

cleanup:
	if (passwordData)
		SecKeychainItemFreeContent(NULL, passwordData);
	if (itemRef)
		CFRelease(itemRef);

	return result;
}
Пример #9
0
int main(int argc, char **argv) {
  if ((argc < 3) || (argc > 4)) {
    printf("Usage: %s <service> <account> [<password>]\n", argv[0]);
    return 1;
  }

  const char *service  = argv[1];
  const char *login    = argv[2];
  const char *password = argc == 4 ? argv[3] : NULL;

  void *buf;
  UInt32 len;
  SecKeychainItemRef item;

  if (password != NULL) {
    if (key_exists_p(service, login, &item) == 0) {
      SecKeychainItemDelete(item);
    }

    OSStatus create_key = SecKeychainAddGenericPassword(
      NULL, strlen(service), service, strlen(login), login, strlen(password),
      password, &item
    );

    if (create_key != 0) {
      fprintf(stderr, "Boxen Keychain Helper: Encountered error code: %d\n", create_key);
      return 1;
    }

  } else {
    OSStatus find_key = SecKeychainFindGenericPassword(
      NULL, strlen(service), service, strlen(login), login, &len, &buf, &item);

    if (find_key != 0) {
      fprintf(stderr, "Boxen Keychain Helper: Encountered error code: %d\n", find_key);
      return 1;
    }

    fwrite(buf, 1, len, stdout);
  }

  return 0;
}
Пример #10
0
bool OsxWallet::deleteCredentials(const QString &realm, const QString &user)
{
    const QByteArray realm_data = realm.toUtf8();
    const QByteArray user_data = user.toUtf8();
    SecKeychainItemRef itemRef = NULL;

    /* check whether the entry exists */
    int rc = SecKeychainFindInternetPassword(keychain,
        realm_data.size(), realm_data.constData(),
        0, NULL,
        user_data.size(), user_data.constData(),
        0, NULL,
        0, kSecProtocolTypeAny, kSecAuthenticationTypeAny,
        0, NULL,
        &itemRef);
    if (rc != errSecSuccess)
        return false;

    rc = SecKeychainItemDelete(itemRef);
    CFRelease(itemRef);

    return (rc == errSecSuccess);
}
OSStatus SecIdentityDeletePreferenceItemWithNameAndKeyUsage(
	CFTypeRef keychainOrArray,
	CFStringRef name,
	int32_t keyUsage)
{
	// when a specific key usage is passed, we'll only match & delete that pref;
	// when a key usage of 0 is passed, all matching prefs should be deleted.
	// maxUsages represents the most matches there could theoretically be, so
	// cut things off at that point if we're still finding items (if they can't
	// be deleted for some reason, we'd never break out of the loop.)

	OSStatus status;
	SecKeychainItemRef item = NULL;
	int count = 0, maxUsages = 12;
	while (++count <= maxUsages &&
			(status = SecIdentityFindPreferenceItemWithNameAndKeyUsage(keychainOrArray, name, keyUsage, &item)) == errSecSuccess) {
		status = SecKeychainItemDelete(item);
		CFRelease(item);
		item = NULL;
	}

	// it's not an error if the item isn't found
	return (status == errSecItemNotFound) ? errSecSuccess : status;
}
Пример #12
0
OSStatus OTMacKeychain::ItemDelete(SecKeychainItemRef itemRef) const
{
    return SecKeychainItemDelete(itemRef);
}
Пример #13
0
static krb5_error_code
get_new_tickets(krb5_context context,
		krb5_principal principal,
		krb5_ccache ccache,
		krb5_deltat ticket_life,
		int interactive)
{
    krb5_error_code ret;
    krb5_get_init_creds_opt *opt;
    krb5_creds cred;
    char passwd[256];
    krb5_deltat start_time = 0;
    krb5_deltat renew = 0;
    const char *renewstr = NULL;
    krb5_enctype *enctype = NULL;
    krb5_ccache tempccache;
    krb5_init_creds_context icc;
    krb5_keytab kt = NULL;
    int will_use_keytab =  (use_keytab || keytab_str);
    krb5_prompter_fct prompter = NULL;
    int need_prompt;

    passwd[0] = '\0';

    if (password_file) {
	FILE *f;

	if (strcasecmp("STDIN", password_file) == 0)
	    f = stdin;
	else
	    f = fopen(password_file, "r");
	if (f == NULL)
	    krb5_errx(context, 1, "Failed to open the password file %s",
		      password_file);

	if (fgets(passwd, sizeof(passwd), f) == NULL)
	    krb5_errx(context, 1,
		      N_("Failed to read password from file %s", ""),
		      password_file);
	if (f != stdin)
	    fclose(f);
	passwd[strcspn(passwd, "\n")] = '\0';
    }

#if defined(__APPLE__) && !defined(__APPLE_TARGET_EMBEDDED__)
    if (passwd[0] == '\0' && !will_use_keytab && home_directory_flag) {
	const char *realm;
	OSStatus osret;
	UInt32 length;
	void *buffer;
	char *name;

	realm = krb5_principal_get_realm(context, principal);

	ret = krb5_unparse_name_flags(context, principal,
				      KRB5_PRINCIPAL_UNPARSE_NO_REALM, &name);
	if (ret)
	    goto nopassword;

	osret = SecKeychainFindGenericPassword(NULL, (UInt32)strlen(realm), realm,
					       (UInt32)strlen(name), name,
					       &length, &buffer, &passwordItem);
	free(name);
	if (osret != noErr)
	    goto nopassword;

	if (length < sizeof(passwd) - 1) {
	    memcpy(passwd, buffer, length);
	    passwd[length] = '\0';
	}
	SecKeychainItemFreeContent(NULL, buffer);
    nopassword:
	do { } while(0);
    }
#endif

    need_prompt = !(pk_user_id || ent_user_id || anonymous_flag || will_use_keytab || passwd[0] != '\0') && interactive;
    if (need_prompt)
	prompter = krb5_prompter_posix;
    else
	prompter = krb5_prompter_print_only;

    memset(&cred, 0, sizeof(cred));

    ret = krb5_get_init_creds_opt_alloc (context, &opt);
    if (ret)
	krb5_err(context, 1, ret, "krb5_get_init_creds_opt_alloc");

    krb5_get_init_creds_opt_set_default_flags(context, "kinit",
	krb5_principal_get_realm(context, principal), opt);

    if(forwardable_flag != -1)
	krb5_get_init_creds_opt_set_forwardable (opt, forwardable_flag);

    if(proxiable_flag != -1)
	krb5_get_init_creds_opt_set_proxiable (opt, proxiable_flag);
    if(anonymous_flag)
	krb5_get_init_creds_opt_set_anonymous (opt, anonymous_flag);
    if (pac_flag != -1)
	krb5_get_init_creds_opt_set_pac_request(context, opt,
						pac_flag ? TRUE : FALSE);
    if (canonicalize_flag)
	krb5_get_init_creds_opt_set_canonicalize(context, opt, TRUE);
    if (pk_enterprise_flag || enterprise_flag || canonicalize_flag || windows_flag)
	krb5_get_init_creds_opt_set_win2k(context, opt, TRUE);
    if (pk_user_id || ent_user_id || anonymous_flag) {
	ret = krb5_get_init_creds_opt_set_pkinit(context, opt,
						 principal,
						 pk_user_id,
						 pk_x509_anchors,
						 NULL,
						 NULL,
						 pk_use_enckey ? 2 : 0 |
						 anonymous_flag ? 4 : 0,
						 interactive ? krb5_prompter_posix : krb5_prompter_print_only,
						 NULL,
						 passwd);
	if (ret)
	    krb5_err(context, 1, ret, "krb5_get_init_creds_opt_set_pkinit");
	if (ent_user_id)
	    krb5_get_init_creds_opt_set_pkinit_user_cert(context, opt, ent_user_id);
    }

    if (addrs_flag != -1)
	krb5_get_init_creds_opt_set_addressless(context, opt,
						addrs_flag ? FALSE : TRUE);

    if (renew_life == NULL && renewable_flag)
	renewstr = "1 month";
    if (renew_life)
	renewstr = renew_life;
    if (renewstr) {
	renew = parse_time (renewstr, "s");
	if (renew < 0)
	    errx (1, "unparsable time: %s", renewstr);

	krb5_get_init_creds_opt_set_renew_life (opt, renew);
    }

    if(ticket_life != 0)
	krb5_get_init_creds_opt_set_tkt_life (opt, ticket_life);

    if(start_str) {
	int tmp = parse_time (start_str, "s");
	if (tmp < 0)
	    errx (1, N_("unparsable time: %s", ""), start_str);

	start_time = tmp;
    }

    if(etype_str.num_strings) {
	int i;

	enctype = malloc(etype_str.num_strings * sizeof(*enctype));
	if(enctype == NULL)
	    errx(1, "out of memory");
	for(i = 0; i < etype_str.num_strings; i++) {
	    ret = krb5_string_to_enctype(context,
					 etype_str.strings[i],
					 &enctype[i]);
	    if(ret)
		krb5_err(context, 1, ret, "unrecognized enctype: %s",
			 etype_str.strings[i]);
	}
	krb5_get_init_creds_opt_set_etype_list(opt, enctype,
					       etype_str.num_strings);
    }

    ret = krb5_init_creds_init(context, principal,
			       prompter, NULL,
			       start_time, opt, &icc);
    if (ret)
	krb5_err (context, 1, ret, "krb5_init_creds_init");

    if (server_str) {
	ret = krb5_init_creds_set_service(context, icc, server_str);
	if (ret)
	    krb5_err (context, 1, ret, "krb5_init_creds_set_service");
    }

    if (kdc_hostname)
	krb5_init_creds_set_kdc_hostname(context, icc, kdc_hostname);

    if (fast_armor_cache_string) {
	krb5_ccache fastid;
	
	ret = krb5_cc_resolve(context, fast_armor_cache_string, &fastid);
	if (ret)
	    krb5_err(context, 1, ret, "krb5_cc_resolve(FAST cache)");
	
	ret = krb5_init_creds_set_fast_ccache(context, icc, fastid);
	if (ret)
	    krb5_err(context, 1, ret, "krb5_init_creds_set_fast_ccache");
    }

    if(will_use_keytab) {
	if(keytab_str)
	    ret = krb5_kt_resolve(context, keytab_str, &kt);
	else
	    ret = krb5_kt_default(context, &kt);
	if (ret)
	    krb5_err (context, 1, ret, "resolving keytab");

	ret = krb5_init_creds_set_keytab(context, icc, kt);
	if (ret)
	    krb5_err (context, 1, ret, "krb5_init_creds_set_keytab");
    }

    if (passwd[0] == '\0' && need_prompt) {
	char *p, *prompt;

	krb5_unparse_name(context, principal, &p);
	asprintf (&prompt, N_("%s's Password: "******""), p);
	free(p);

	if (UI_UTIL_read_pw_string(passwd, sizeof(passwd)-1, prompt, 0)){
	    memset(passwd, 0, sizeof(passwd));
	    errx(1, "failed to read password");
	}
	free (prompt);
    }

    if (passwd[0]) {
	ret = krb5_init_creds_set_password(context, icc, passwd);
	if (ret)
	    krb5_err(context, 1, ret, "krb5_init_creds_set_password");
    }

    ret = krb5_init_creds_get(context, icc);

#ifdef __APPLE__
    /*
     * Save password in Keychain
     */
    if (ret == 0 && keychain_flag && passwordItem == NULL) {
	krb5_error_code ret2;
	const char *realm;
	char *name;

	realm = krb5_principal_get_realm(context, principal);
	ret2 = krb5_unparse_name_flags(context, principal, KRB5_PRINCIPAL_UNPARSE_NO_REALM, &name);
	if (ret2 == 0) {
	    (void)SecKeychainAddGenericPassword(NULL,
						(UInt32)strlen(realm), realm,
						(UInt32)strlen(name), name,
						(UInt32)strlen(passwd), passwd,
						NULL);
	    free(name);
	}
    }
#endif

    memset(passwd, 0, sizeof(passwd));

    switch(ret){
    case 0:
	break;
    case KRB5_LIBOS_PWDINTR: /* don't print anything if it was just C-c:ed */
	exit(1);
    case KRB5KRB_AP_ERR_BAD_INTEGRITY:
    case KRB5KRB_AP_ERR_MODIFIED:
    case KRB5KDC_ERR_PREAUTH_FAILED:
    case KRB5_GET_IN_TKT_LOOP:
#ifdef __APPLE__
	if (passwordItem)
	    SecKeychainItemDelete(passwordItem);
#endif
	krb5_errx(context, 1, N_("Password incorrect", ""));
    case KRB5KRB_AP_ERR_V4_REPLY:
	krb5_errx(context, 1, N_("Looks like a Kerberos 4 reply", ""));
    case KRB5KDC_ERR_KEY_EXPIRED:
	krb5_errx(context, 1, N_("Password expired", ""));
    default:
	krb5_err(context, 1, ret, "krb5_get_init_creds");
    }

    ret = krb5_init_creds_get_creds(context, icc, &cred);
    if (ret)
	krb5_err(context, 1, ret, "krb5_init_creds_get_creds");

    krb5_process_last_request(context, opt, icc);

    ret = krb5_cc_new_unique(context, krb5_cc_get_type(context, ccache),
			     NULL, &tempccache);
    if (ret)
	krb5_err (context, 1, ret, "krb5_cc_new_unique");

    ret = krb5_init_creds_store(context, icc, tempccache);
    if (ret)
	krb5_err(context, 1, ret, "krb5_init_creds_store");

    ret = krb5_init_creds_store_config(context, icc, tempccache);
    if (ret)
	krb5_warn(context, ret, "krb5_init_creds_store_config");

    ret = krb5_init_creds_warn_user(context, icc);
    if (ret)
	krb5_warn(context, ret, "krb5_init_creds_warn_user");

#ifdef __APPLE__
    /*
     * Set for this case, default to * so that all processes can use
     * this cache.
     */
    {
	heim_array_t bundleacl = heim_array_create();
	heim_string_t ace;

	if (bundle_acl_strings.num_strings > 0) {
	    int i;
	    for (i = 0; i < bundle_acl_strings.num_strings; i++) {
		ace = heim_string_create(bundle_acl_strings.strings[i]);
		heim_array_append_value(bundleacl, ace);
		heim_release(ace);
	    }
	} else {
	    ace = heim_string_create("*");
	    heim_array_append_value(bundleacl, ace);
	    heim_release(ace);
	}
	krb5_cc_set_acl(context, tempccache, "kHEIMAttrBundleIdentifierACL", bundleacl);
	heim_release(bundleacl);
    }
#endif

    ret = krb5_cc_move(context, tempccache, ccache);
    if (ret) {
	(void)krb5_cc_destroy(context, tempccache);
	krb5_err (context, 1, ret, "krb5_cc_move");
    }

    if (switch_cache_flags)
	krb5_cc_switch(context, ccache);

    if (ok_as_delegate_flag || windows_flag || use_referrals_flag) {
	unsigned char d = 0;
	krb5_data data;

	if (ok_as_delegate_flag || windows_flag)
	    d |= 1;
	if (use_referrals_flag || windows_flag)
	    d |= 2;

	data.length = 1;
	data.data = &d;

	krb5_cc_set_config(context, ccache, NULL, "realm-config", &data);
    }

    if (enctype)
	free(enctype);

    krb5_init_creds_free(context, icc);
    krb5_get_init_creds_opt_free(context, opt);

    if (kt)
	krb5_kt_close(context, kt);

#ifdef __APPLE__
    if (passwordItem)
	CFRelease(passwordItem);
#endif

    return 0;
}
Пример #14
0
SEXP find_password(SEXP svc, SEXP usr, SEXP new_pwd, SEXP quiet, SEXP del) {
    SEXP res;
    OSStatus status;
    SecKeychainRef kc = NULL; /* default */
    SecKeychainItemRef kci;
    const char *un, *sn;
    char *svc_name;
    void *pwd;
    UInt32 pwd_len = 0;
    int l;
    int silent = Rf_asInteger(quiet) == 1;
    int do_rm = Rf_asInteger(del) == 1;
    int modify = 0;

    if (TYPEOF(svc) != STRSXP || LENGTH(svc) != 1) Rf_error("Invalid service name");

    if (new_pwd != R_NilValue && (TYPEOF(new_pwd) != STRSXP || LENGTH(new_pwd) != 1))
        Rf_error("Invalid password");

    if (new_pwd != R_NilValue || do_rm) modify = 1;

    if (usr == R_NilValue) {
        un = getlogin();
        if (!un) Rf_error("Unable to get current user name via getlogin()");
    } else {
        if (TYPEOF(usr) != STRSXP || LENGTH(usr) != 1)
            Rf_error("Invalid user name (must be a character vector of length one)");
        un = Rf_translateCharUTF8(STRING_ELT(usr, 0));
    }

    sn = Rf_translateCharUTF8(STRING_ELT(svc, 0));
    l = strlen(sn);
    if (l > sizeof(buf) - 16) {
        svc_name = (char*) malloc(l + 16);
        if (!svc_name) Rf_error("Cannot allocate memory for service name");
    } else svc_name = buf;

    /* we are enforcing R.keychain. prefix to avoid abuse to access other system keys */
    strcpy(svc_name, SEC_PREFIX);
    strcat(svc_name, sn);

    status = SecKeychainFindGenericPassword(kc,
                                            strlen(svc_name), svc_name,
                                            strlen(un), un,
                                            &pwd_len, &pwd,
                                            modify ? &kci : NULL);

    if (svc_name != buf) free(svc_name);
    if (silent && status == errSecItemNotFound) return R_NilValue;
    chk_status(status, "find");

    res = PROTECT(Rf_ScalarString(Rf_mkCharLenCE(pwd, pwd_len, CE_UTF8)));
    /* FIXME: we'll leak if the above fails in R */
    SecKeychainItemFreeContent(NULL, pwd);

    if (do_rm) {
        status = SecKeychainItemDelete(kci);
        chk_status(status, "delete");
    } else if (new_pwd != R_NilValue) { /* set a new one */
        const char *np = Rf_translateCharUTF8(STRING_ELT(new_pwd, 0));
        status = SecKeychainItemModifyContent(kci, NULL, strlen(np), np);
        chk_status(status, "modify");
    }

    UNPROTECT(1);
    return res;
}
static int testExtractable(
    SecKeychainRef keychain,
	Boolean extractable,
	Boolean explicit)
{
	OSStatus status;
	SecKeyRef publicKeyRef = NULL;
	SecKeyRef privateKeyRef = NULL;
	CFStringRef label = (extractable) ? CFSTR("test-extractable-YES") : CFSTR("test-extractable-NO");
	Boolean *extractablePtr = (explicit) ? &extractable : NULL;

    status = GenerateRSAKeyPair(keychain,
                                label,
								1024, // size
								extractablePtr,
								&publicKeyRef,
								&privateKeyRef);

	if (status != noErr) {
        //errx(EXIT_FAILURE, "Unable to get key pair (err = %d)", status);
        return status;
	}

	// check that the attributes of the generated private key are what we think they are
	const CSSM_KEY *cssmPrivKey;
	status = SecKeyGetCSSMKey(privateKeyRef, &cssmPrivKey);
    ok_status(status, "%s: SecKeyGetCSSMKey", testName);

	if (status != noErr) {
        //errx(EXIT_FAILURE, "Unable to get CSSM reference key (err = %d)", status);
        return status;
	}
	if (extractable) {
        ok(cssmPrivKey->KeyHeader.KeyAttr & CSSM_KEYATTR_EXTRACTABLE, "%s: check private key marked as extractable (as requested)", testName);
		if (!(cssmPrivKey->KeyHeader.KeyAttr & CSSM_KEYATTR_EXTRACTABLE)) {
            //errx(EXIT_FAILURE, "Oops! the private key was not marked as extractable!");
            return 1;
		}
	}
	else {
        ok(!(cssmPrivKey->KeyHeader.KeyAttr & CSSM_KEYATTR_EXTRACTABLE), "%s: check private key marked as non-extractable (as requested)", testName);
		if (cssmPrivKey->KeyHeader.KeyAttr & CSSM_KEYATTR_EXTRACTABLE) {
            //errx(EXIT_FAILURE, "Oops! the private key was marked as extractable!");
            return 1;
		}
	}

	SecKeyImportExportParameters keyParams;
	memset(&keyParams, 0, sizeof(keyParams));
	keyParams.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION;
	keyParams.passphrase = CFSTR("borken");

	CFDataRef exportedData = NULL;

    status = SecKeychainItemExport(privateKeyRef, kSecFormatWrappedPKCS8, 0, &keyParams, &exportedData);
    if(extractable) {
        ok_status(status, "%s: SecKeychainItemExport (PKCS8) (and we expected it to succeed)", testName);
    } else {
        is(status, errSecDataNotAvailable, "%s: SecKeychainItemExport (PKCS8) (and we expected this to fail with errSecDataNotAvailable)", testName);
    }

    status = SecKeychainItemExport(privateKeyRef, kSecFormatPKCS12, 0, &keyParams, &exportedData);
    if(extractable) {
        ok_status(status, "%s: SecKeychainItemExport(and we expected it to succeed)", testName);
    } else {
        is(status, errSecDataNotAvailable, "%s: SecKeychainItemExport (PKCS12)  (and we expected this to fail with errSecDataNotAvailable)", testName);
    }

	if (status != noErr) {
		if (extractable) {
			//errx(EXIT_FAILURE, "Unable to export extractable key! (err = %d)", status);
            return 1;
		}
		else {
			status = 0; // wasn't extractable, so this is the expected result
		}
	}
	else if (status == noErr && !extractable) {
		//errx(EXIT_FAILURE, "Was able to export non-extractable key! (err = %d)", status);
        return 1;
	}

	status = SecKeychainItemDelete((SecKeychainItemRef)publicKeyRef);
    ok_status(status, "%s: SecKeychainItemDelete", testName);
	if (status != noErr) {
		warnx("Unable to delete created public key from keychain (err = %d)", (int)status);
	}

	status = SecKeychainItemDelete((SecKeychainItemRef)privateKeyRef);
    ok_status(status, "%s: SecKeychainItemDelete", testName);
	if (status != noErr) {
		warnx("Unable to delete created private key from keychain (err = %d)", (int)status);
	}

	CFRelease(publicKeyRef);
	CFRelease(privateKeyRef);

	return 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;
}
Пример #17
0
VALUE destroy_internet_password_for(VALUE self, VALUE data) {
    CHECK_FETCH_HASH_KEY(account)
    CHECK_FETCH_HASH_KEY(protocol)
    CHECK_FETCH_HASH_KEY(server)

    VALUE sym_auth = rb_eval_string(":auth");
    VALUE auth;

    if (!rb_funcall(data, rb_intern("has_key?"), 1, sym_auth)) {
        auth = 0;
    } else {
        auth = rb_funcall(rb_funcall(data, rb_intern("fetch"), 1, sym_auth), rb_intern("to_s"), 0);
        auth = String2FourChar(StringValuePtr(auth));
    }

    VALUE sym_port = rb_eval_string(":port");
    VALUE port;

    if (!rb_funcall(data, rb_intern("has_key?"), 1, sym_port)) {
        port = 0;
    } else {
        port = rb_funcall(rb_funcall(data, rb_intern("fetch"), 1, sym_port), rb_intern("to_i"), 0);
        port = NUM2INT(port);
    }

    VALUE sym_path = rb_eval_string(":path");
    VALUE path;

    if (!rb_funcall(data, rb_intern("has_key?"), 1, sym_path)) {
        path = rb_str_new2("");
    } else {
        path = rb_funcall(rb_funcall(data, rb_intern("fetch"), 1, sym_path), rb_intern("to_s"), 0);
    }

    SecKeychainItemRef itemRef = nil;

    OSStatus status = SecKeychainFindInternetPassword (
                          NULL,                                       // default keychain
                          strlen(StringValuePtr(server)),             // length of serverName
                          StringValuePtr(server),                     // serverName
                          0,                                          // length of domain
                          NULL,                                       // no domain
                          strlen(StringValuePtr(account)),            // length of account name
                          StringValuePtr(account),                    // account name
                          strlen(StringValuePtr(path)),               // length of path
                          StringValuePtr(path),                       // path
                          port,                                       // ignore port
                          String2FourChar(StringValuePtr(protocol)),  // protocol
                          auth,
                          nil,
                          nil,
                          &itemRef
                      );

    if (status != noErr || !itemRef)
        return Qfalse;

    status = SecKeychainItemDelete(itemRef);

    return status == noErr ? Qtrue : Qfalse;
}