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; }
/** 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; }
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; }
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); }
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; }
/** * 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; }
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; }
/** * 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; }