static int
kc_rsa_private_decrypt(int flen, const unsigned char *from, unsigned char *to,
		       RSA * rsa, int padding)
{
    struct kc_rsa *kc = RSA_get_app_data(rsa);

    CSSM_RETURN cret;
    OSStatus ret;
    const CSSM_ACCESS_CREDENTIALS *creds;
    SecKeyRef privKeyRef = kc->pkey;
    CSSM_CSP_HANDLE cspHandle;
    const CSSM_KEY *cssmKey;
    CSSM_CC_HANDLE handle = 0;
    CSSM_DATA out, in, rem;
    int fret = 0;
    CSSM_SIZE outlen = 0;
    char remdata[1024];

    if (padding != RSA_PKCS1_PADDING)
	return -1;

    cret = SecKeyGetCSSMKey(privKeyRef, &cssmKey);
    if(cret) heim_abort("SecKeyGetCSSMKey failed: %d", (int)cret);

    cret = SecKeyGetCSPHandle(privKeyRef, &cspHandle);
    if(cret) heim_abort("SecKeyGetCSPHandle failed: %d", (int)cret);

    ret = SecKeyGetCredentials(privKeyRef, CSSM_ACL_AUTHORIZATION_DECRYPT,
			       kSecCredentialTypeNoUI, &creds);
    if(ret) heim_abort("SecKeyGetCredentials failed: %d", (int)ret);

    ret = CSSM_CSP_CreateAsymmetricContext (cspHandle,
					    CSSM_ALGID_RSA,
					    creds,
					    cssmKey,
					    CSSM_PADDING_PKCS1,
					    &handle);
    if(ret) heim_abort("CSSM_CSP_CreateAsymmetricContext failed: %d", (int)ret);

    in.Data = (uint8 *)from;
    in.Length = flen;

    out.Data = (uint8 *)to;
    out.Length = kc->keysize;

    rem.Data = (uint8 *)remdata;
    rem.Length = sizeof(remdata);

    cret = CSSM_DecryptData(handle, &in, 1, &out, 1, &outlen, &rem);
    if(cret) {
	/* cssmErrorString(cret); */
	fret = -1;
    } else
	fret = (int)out.Length;

    if(handle)
	CSSM_DeleteContext(handle);

    return fret;
}
static int
kc_rsa_private_encrypt(int flen,
		       const unsigned char *from,
		       unsigned char *to,
		       RSA *rsa,
		       int padding)
{
    struct kc_rsa *kc = RSA_get_app_data(rsa);

    CSSM_RETURN cret;
    OSStatus ret;
    const CSSM_ACCESS_CREDENTIALS *creds;
    SecKeyRef privKeyRef = kc->pkey;
    CSSM_CSP_HANDLE cspHandle;
    const CSSM_KEY *cssmKey;
    CSSM_CC_HANDLE sigHandle = 0;
    CSSM_DATA sig, in;
    int fret = 0;

    if (padding != RSA_PKCS1_PADDING)
	return -1;

    cret = SecKeyGetCSSMKey(privKeyRef, &cssmKey);
    if(cret) heim_abort("SecKeyGetCSSMKey failed: %d", cret);

    cret = SecKeyGetCSPHandle(privKeyRef, &cspHandle);
    if(cret) heim_abort("SecKeyGetCSPHandle failed: %d", cret);

    ret = SecKeyGetCredentials(privKeyRef, CSSM_ACL_AUTHORIZATION_SIGN,
			       kSecCredentialTypeNoUI, &creds);
    if(ret) heim_abort("SecKeyGetCredentials failed: %d", (int)ret);

    ret = CSSM_CSP_CreateSignatureContext(cspHandle, CSSM_ALGID_RSA,
					  creds, cssmKey, &sigHandle);
    if(ret) heim_abort("CSSM_CSP_CreateSignatureContext failed: %d", (int)ret);

    in.Data = (uint8 *)from;
    in.Length = flen;

    sig.Data = (uint8 *)to;
    sig.Length = kc->keysize;

    cret = CSSM_SignData(sigHandle, &in, 1, CSSM_ALGID_NONE, &sig);
    if(cret) {
	/* cssmErrorString(cret); */
	fret = -1;
    } else
	fret = (int)sig.Length;

    if(sigHandle)
	CSSM_DeleteContext(sigHandle);

    return fret;
}
Esempio n. 3
0
File: db.c Progetto: InvLim/heimdal
/** heim_db_register
 * @brief Registers a DB type for use with heim_db_create().
 *
 * @param dbtype Name of DB type
 * @param data   Private data argument to the dbtype's openf method
 * @param plugin Structure with DB type methods (function pointers)
 *
 * Backends that provide begin/commit/rollback methods must provide ACID
 * semantics.
 *
 * The registered DB type will have ACID semantics for backends that do
 * not provide begin/commit/rollback methods but do provide lock/unlock
 * and rdjournal/wrjournal methods (using a replay log journalling
 * scheme).
 *
 * If the registered DB type does not natively provide read vs. write
 * transaction isolation but does provide a lock method then the DB will
 * provide read/write transaction isolation.
 *
 * @return ENOMEM on failure, else 0.
 *
 * @addtogroup heimbase
 */
int
heim_db_register(const char *dbtype,
		 void *data,
		 struct heim_db_type *plugin)
{
    heim_dict_t plugins;
    heim_string_t s;
    db_plugin plug, plug2;
    int ret = 0;

    if ((plugin->beginf != NULL && plugin->commitf == NULL) ||
	(plugin->beginf != NULL && plugin->rollbackf == NULL) ||
	(plugin->lockf != NULL && plugin->unlockf == NULL) ||
	plugin->copyf == NULL)
	heim_abort("Invalid DB plugin; make sure methods are paired");

    /* Initialize */
    plugins = heim_dict_create(11);
    if (plugins == NULL)
	return ENOMEM;
    heim_base_once_f(&db_plugin_init_once, plugins, db_init_plugins_once);
    heim_release(plugins);
    heim_assert(db_plugins != NULL, "heim_db plugin table initialized");

    s = heim_string_create(dbtype);
    if (s == NULL)
	return ENOMEM;

    plug = heim_alloc(sizeof (*plug), "db_plug", plugin_dealloc);
    if (plug == NULL) {
	heim_release(s);
	return ENOMEM;
    }

    plug->name = heim_retain(s);
    plug->openf = plugin->openf;
    plug->clonef = plugin->clonef;
    plug->closef = plugin->closef;
    plug->lockf = plugin->lockf;
    plug->unlockf = plugin->unlockf;
    plug->syncf = plugin->syncf;
    plug->beginf = plugin->beginf;
    plug->commitf = plugin->commitf;
    plug->rollbackf = plugin->rollbackf;
    plug->copyf = plugin->copyf;
    plug->setf = plugin->setf;
    plug->delf = plugin->delf;
    plug->iterf = plugin->iterf;
    plug->data = data;

    HEIMDAL_MUTEX_lock(&db_type_mutex);
    plug2 = heim_dict_get_value(db_plugins, s);
    if (plug2 == NULL)
	ret = heim_dict_set_value(db_plugins, s, plug);
    HEIMDAL_MUTEX_unlock(&db_type_mutex);
    heim_release(plug);
    heim_release(s);

    return ret;
}
Esempio n. 4
0
krb5_error_code
hdb_print_entry(krb5_context context, HDB *db, hdb_entry_ex *entry,
                void *data)
{
    struct hdb_print_entry_arg *parg = data;
    krb5_error_code ret;
    krb5_storage *sp;

    fflush(parg->out);
    sp = krb5_storage_from_fd(fileno(parg->out));
    if (sp == NULL) {
	krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
	return ENOMEM;
    }

    switch (parg->fmt) {
    case HDB_DUMP_HEIMDAL:
        ret = entry2string_int(context, sp, &entry->entry);
        break;
    case HDB_DUMP_MIT:
        ret = entry2mit_string_int(context, sp, &entry->entry);
        break;
    default:
        heim_abort("Only two dump formats supported: Heimdal and MIT");
    }
    if (ret) {
	krb5_storage_free(sp);
	return ret;
    }

    krb5_storage_write(sp, "\n", 1);
    krb5_storage_free(sp);
    return 0;
}
Esempio n. 5
0
heim_string_t
heim_error_copy_string(heim_error_t error)
{
    if (heim_get_tid(error) != HEIM_TID_ERROR) {
	if (heim_get_tid(error) == heim_number_get_type_id())
	    return __heim_string_constant(strerror(heim_number_get_int((heim_number_t)error)));
	heim_abort("invalid heim_error_t");
    }
    /* XXX concat all strings */
    return heim_retain(error->msg);
}
Esempio n. 6
0
int
heim_error_get_code(heim_error_t error)
{
    if (error == NULL)
	return -1;
    if (heim_get_tid(error) != HEIM_TID_ERROR) {
	if (heim_get_tid(error) == heim_number_get_type_id())
	    return heim_number_get_int((heim_number_t)error);
	heim_abort("invalid heim_error_t");
    }
    return error->error_code;
}
Esempio n. 7
0
File: db.c Progetto: InvLim/heimdal
/**
 * Open a transaction on the given db.
 *
 * @param db    Open DB handle
 * @param error Output error object
 *
 * @return 0 on success, system error otherwise
 *
 * @addtogroup heimbase
 */
int
heim_db_begin(heim_db_t db, int read_only, heim_error_t *error)
{
    int ret;

    if (heim_get_tid(db) != HEIM_TID_DB)
	return EINVAL;

    if (db->in_transaction && (read_only || !db->ro_tx || (!read_only && !db->ro_tx)))
	heim_abort("DB already in transaction");

    if (db->plug->setf == NULL || db->plug->delf == NULL)
	return EINVAL;

    if (db->plug->beginf) {
	ret = db->plug->beginf(db->db_data, read_only, error);
    } else if (!db->in_transaction) {
	/* Try to emulate transactions */

	if (db->plug->lockf == NULL)
	    return EINVAL; /* can't lock? -> no transactions */

	/* Assume unlock provides sync/durability */
	ret = db->plug->lockf(db->db_data, read_only, error);
	if (ret)
	    return ret;

	ret = db_replay_log(db, error);
	if (ret) {
	    ret = db->plug->unlockf(db->db_data, error);
	    return ret;
	}

	db->set_keys = heim_dict_create(11);
	if (db->set_keys == NULL)
	    return ENOMEM;
	db->del_keys = heim_dict_create(11);
	if (db->del_keys == NULL) {
	    heim_release(db->set_keys);
	    db->set_keys = NULL;
	    return ENOMEM;
	}
    } else {
	heim_assert(read_only == 0, "Internal error");
	ret = db->plug->lockf(db->db_data, 0, error);
	if (ret)
	    return ret;
    }
    db->in_transaction = 1;
    db->ro_tx = !!read_only;
    return 0;
}
Esempio n. 8
0
heim_error_t
heim_error_append(heim_error_t top, heim_error_t append)
{
    if (heim_get_tid(top) != HEIM_TID_ERROR) {
	if (heim_get_tid(top) == heim_number_get_type_id())
	    return top;
	heim_abort("invalid heim_error_t");
    }
    if (top->next)
	heim_release(top->next);
    top->next = heim_retain(append);
    return top;
}
Esempio n. 9
0
File: db.c Progetto: InvLim/heimdal
/**
 * Clone (duplicate) an open DB handle.
 *
 * This is useful for multi-threaded applications.  Applications must
 * synchronize access to any given DB handle.
 *
 * Returns EBUSY if there is an open transaction for the input db.
 *
 * @param db      Open DB handle
 * @param error   Output error object
 *
 * @return a DB handle
 *
 * @addtogroup heimbase
 */
heim_db_t
heim_db_clone(heim_db_t db, heim_error_t *error)
{
    heim_db_t result;
    int ret;

    if (heim_get_tid(db) != HEIM_TID_DB)
	heim_abort("Expected a database");
    if (db->in_transaction)
	heim_abort("DB handle is busy");

    if (db->plug->clonef == NULL) {
	return heim_db_create(heim_string_get_utf8(db->dbtype),
			      heim_string_get_utf8(db->dbname),
			      db->options, error);
    }

    result = _heim_alloc_object(&db_object, sizeof(*result));
    if (result == NULL) {
	if (error)
	    *error = heim_error_create_enomem();
	return NULL;
    }

    result->set_keys = NULL;
    result->del_keys = NULL;
    ret = db->plug->clonef(db->db_data, &result->db_data, error);
    if (ret) {
	heim_release(result);
	if (error && !*error)
	    *error = heim_error_create(ENOENT,
				       N_("Could not re-open DB while cloning", ""));
	return NULL;
    }
    db->db_data = NULL;
    return result;
}
static int
kc_rsa_sign(int type, const unsigned char *from, unsigned int flen,
	    unsigned char *to, unsigned int *tlen, const RSA *rsa)
{
    struct kc_rsa *kc = RSA_get_app_data(rk_UNCONST(rsa));

    CSSM_RETURN cret;
    OSStatus ret;
    const CSSM_ACCESS_CREDENTIALS *creds;
    SecKeyRef privKeyRef = kc->pkey;
    CSSM_CSP_HANDLE cspHandle;
    const CSSM_KEY *cssmKey;
    CSSM_CC_HANDLE sigHandle = 0;
    CSSM_DATA sig, in;
    int fret = 0;
    CSSM_ALGORITHMS stype;

    if (type == NID_md5) {
	stype = CSSM_ALGID_MD5;
    } else if (type == NID_sha1) {
	stype = CSSM_ALGID_SHA1;
    } else if (type == NID_sha256) {
	stype = CSSM_ALGID_SHA256;
    } else if (type == NID_sha384) {
	stype = CSSM_ALGID_SHA384;
    } else if (type == NID_sha512) {
	stype = CSSM_ALGID_SHA512;
    } else
	return -1;

    cret = SecKeyGetCSSMKey(privKeyRef, &cssmKey);
    if(cret) heim_abort("SecKeyGetCSSMKey failed: %d", cret);

    cret = SecKeyGetCSPHandle(privKeyRef, &cspHandle);
    if(cret) heim_abort("SecKeyGetCSPHandle failed: %d", cret);

    ret = SecKeyGetCredentials(privKeyRef, CSSM_ACL_AUTHORIZATION_SIGN,
			       kSecCredentialTypeNoUI, &creds);
    if(ret) heim_abort("SecKeyGetCredentials failed: %d", (int)ret);

    ret = CSSM_CSP_CreateSignatureContext(cspHandle, CSSM_ALGID_RSA,
					  creds, cssmKey, &sigHandle);
    if(ret) heim_abort("CSSM_CSP_CreateSignatureContext failed: %d", (int)ret);

    in.Data = (uint8 *)from;
    in.Length = flen;

    sig.Data = (uint8 *)to;
    sig.Length = kc->keysize;

    cret = CSSM_SignData(sigHandle, &in, 1, stype, &sig);
    if(cret) {
	/* cssmErrorString(cret); */
	fret = -1;
    } else {
	fret = 1;
	*tlen = (unsigned int)sig.Length;
    }

    if(sigHandle)
	CSSM_DeleteContext(sigHandle);

    return fret;
}