/** \ingroup Core_Keys \brief Add selfsigned User ID to key \param keydata Key to which to add user ID \param userid Self-signed User ID to add \return ops_true if OK; else ops_false */ ops_boolean_t ops_add_selfsigned_userid_to_keydata(ops_keydata_t* keydata, ops_user_id_t* userid) { ops_packet_t sigpacket; ops_memory_t* mem_userid=NULL; ops_create_info_t* cinfo_userid=NULL; ops_memory_t* mem_sig=NULL; ops_create_info_t* cinfo_sig=NULL; ops_create_signature_t *sig=NULL; /* * create signature packet for this userid */ // create userid pkt ops_setup_memory_write(&cinfo_userid, &mem_userid, 128); ops_write_struct_user_id(userid, cinfo_userid); // create sig for this pkt sig=ops_create_signature_new(); ops_signature_start_key_signature(sig, &keydata->key.skey.public_key, userid, OPS_CERT_POSITIVE); ops_signature_add_creation_time(sig,time(NULL)); ops_signature_add_issuer_key_id(sig,keydata->key_id); ops_signature_add_primary_user_id(sig, ops_true); ops_signature_hashed_subpackets_end(sig); ops_setup_memory_write(&cinfo_sig, &mem_sig, 128); ops_write_signature(sig,&keydata->key.skey.public_key,&keydata->key.skey, cinfo_sig); // add this packet to keydata sigpacket.length=ops_memory_get_length(mem_sig); sigpacket.raw=ops_memory_get_data(mem_sig); // add userid to keydata ops_add_signed_userid_to_keydata(keydata, userid, &sigpacket); // cleanup ops_create_signature_delete(sig); ops_create_info_delete(cinfo_userid); ops_create_info_delete(cinfo_sig); ops_memory_free(mem_userid); ops_memory_free(mem_sig); return ops_true; }
/** \ingroup Core_Keys \brief Add signature to given key \return ops_true if OK; else ops_false */ ops_boolean_t ops_sign_key(ops_keydata_t* keydata, const unsigned char *signers_key_id,ops_secret_key_t *signers_key) { /* ops_memory_t* mem_userid=NULL; */ ops_create_info_t* cinfo_userid=NULL; ops_memory_t* mem_sig=NULL; ops_create_info_t* cinfo_sig=NULL; ops_create_signature_t *sig=NULL; /* * create signature packet for this userid */ // create sig for this pkt sig=ops_create_signature_new(); ops_signature_start_key_signature(sig, &keydata->key.skey.public_key, &keydata->uids[0], OPS_CERT_GENERIC); ops_signature_add_creation_time(sig,time(NULL)); ops_signature_add_issuer_key_id(sig,signers_key_id); ops_signature_hashed_subpackets_end(sig); ops_setup_memory_write(&cinfo_sig, &mem_sig, 128); ops_write_signature(sig,&signers_key->public_key,signers_key, cinfo_sig); // add this packet to keydata ops_packet_t sigpacket; sigpacket.length=ops_memory_get_length(mem_sig); sigpacket.raw=ops_memory_get_data(mem_sig); // add userid to keydata ops_add_packet_to_keydata(keydata, &sigpacket); // cleanup ops_create_signature_delete(sig); ops_create_info_delete(cinfo_sig); ops_memory_free(mem_sig); return ops_true; }
/** \ingroup HighLevel_KeyGenerate \brief Generates an RSA keypair \param numbits Modulus size \param e Public Exponent \param keydata Pointer to keydata struct to hold new key \return ops_true if key generated successfully; otherwise ops_false \note It is the caller's responsibility to call ops_keydata_free(keydata) */ ops_boolean_t ops_rsa_generate_keypair(const int numbits, const unsigned long e, ops_keydata_t* keydata) { ops_secret_key_t *skey=NULL; RSA *rsa=RSA_new(); BN_CTX *ctx=BN_CTX_new(); BIGNUM *ebn=BN_new(); ops_keydata_init(keydata,OPS_PTAG_CT_SECRET_KEY); skey=ops_get_writable_secret_key_from_data(keydata); // generate the key pair BN_set_word(ebn,e); RSA_generate_key_ex(rsa,numbits,ebn,NULL); // populate ops key from ssl key skey->public_key.version=4; skey->public_key.creation_time=time(NULL); skey->public_key.days_valid=0; skey->public_key.algorithm= OPS_PKA_RSA; skey->public_key.key.rsa.n=BN_dup(rsa->n); skey->public_key.key.rsa.e=BN_dup(rsa->e); skey->s2k_usage=OPS_S2KU_ENCRYPTED_AND_HASHED; skey->s2k_specifier=OPS_S2KS_SALTED; //skey->s2k_specifier=OPS_S2KS_SIMPLE; skey->algorithm=OPS_SA_CAST5; // \todo make param skey->hash_algorithm=OPS_HASH_SHA1; // \todo make param skey->octet_count=0; skey->checksum=0; skey->key.rsa.d=BN_dup(rsa->d); skey->key.rsa.p=BN_dup(rsa->p); skey->key.rsa.q=BN_dup(rsa->q); skey->key.rsa.u=BN_mod_inverse(NULL,rsa->p, rsa->q, ctx); assert(skey->key.rsa.u); BN_CTX_free(ctx); RSA_free(rsa); ops_keyid(keydata->key_id, &keydata->key.skey.public_key); ops_fingerprint(&keydata->fingerprint, &keydata->key.skey.public_key); // Generate checksum ops_create_info_t *cinfo=NULL; ops_memory_t *mem=NULL; ops_setup_memory_write(&cinfo, &mem, 128); ops_push_skey_checksum_writer(cinfo, skey); switch(skey->public_key.algorithm) { // case OPS_PKA_DSA: // return ops_write_mpi(key->key.dsa.x,info); case OPS_PKA_RSA: case OPS_PKA_RSA_ENCRYPT_ONLY: case OPS_PKA_RSA_SIGN_ONLY: if(!ops_write_mpi(skey->key.rsa.d,cinfo) || !ops_write_mpi(skey->key.rsa.p,cinfo) || !ops_write_mpi(skey->key.rsa.q,cinfo) || !ops_write_mpi(skey->key.rsa.u,cinfo)) return ops_false; break; // case OPS_PKA_ELGAMAL: // return ops_write_mpi(key->key.elgamal.x,info); default: assert(0); break; } // close rather than pop, since its the only one on the stack ops_writer_close(cinfo); ops_teardown_memory_write(cinfo, mem); // should now have checksum in skey struct // test if (debug) test_secret_key(skey); return ops_true; }
ops_boolean_t ops_decrypt_memory(const unsigned char *encrypted_memory,int em_length, unsigned char **decrypted_memory,int *out_length, ops_keyring_t* keyring, const ops_boolean_t use_armour, ops_parse_cb_t* cb_get_passphrase) { int fd_in=0; int fd_out=0; char* myfilename=NULL; // ops_parse_info_t *pinfo=NULL; // setup for reading from given input file ops_memory_t *input_mem = ops_memory_new() ; ops_memory_add(input_mem,encrypted_memory,em_length) ; ops_setup_memory_read(&pinfo, input_mem, NULL, callback_write_parsed, ops_false); if (pinfo == NULL) { perror("cannot create memory read"); return ops_false; } // setup memory chunk ops_memory_t *output_mem; ops_setup_memory_write(&pinfo->cbinfo.cinfo, &output_mem,0) ; if (output_mem == NULL) { perror("Cannot create output memory"); ops_teardown_memory_read(pinfo, input_mem); return ops_false; } // \todo check for suffix matching armour param // setup keyring and passphrase callback pinfo->cbinfo.cryptinfo.keyring=keyring; pinfo->cbinfo.cryptinfo.cb_get_passphrase=cb_get_passphrase; // Set up armour/passphrase options if (use_armour) ops_reader_push_dearmour(pinfo); // Do it ops_boolean_t res = ops_parse_and_print_errors(pinfo); // Unsetup if (use_armour) ops_reader_pop_dearmour(pinfo); // copy output memory to supplied buffer. // *out_length = ops_memory_get_length(output_mem) ; *decrypted_memory = ops_mallocz(*out_length) ; memcpy(*decrypted_memory,ops_memory_get_data(output_mem),*out_length) ; ops_decrypt_memory_ABORT: ops_teardown_memory_write(pinfo->cbinfo.cinfo, output_mem); ops_teardown_memory_read(pinfo, input_mem); return res ; }