/** \ingroup Core_WritePackets \brief Write a One Pass Signature packet \param skey Secret Key to use \param hash_alg Hash Algorithm to use \param sig_type Signature type \param info Write settings \return ops_true if OK; else ops_false */ ops_boolean_t ops_write_one_pass_sig(const ops_secret_key_t* skey, const ops_hash_algorithm_t hash_alg, const ops_sig_type_t sig_type, ops_create_info_t* info) { unsigned char keyid[OPS_KEY_ID_SIZE]; if (debug) fprintf(stderr, "calling ops_keyid in write_one_pass_sig: " "this calls sha1_init\n"); ops_keyid(keyid,&skey->public_key); return ops_write_ptag(OPS_PTAG_CT_ONE_PASS_SIGNATURE, info) && ops_write_length(1+1+1+1+8+1, info) && ops_write_scalar (3, 1, info) // version && ops_write_scalar (sig_type, 1, info) && ops_write_scalar (hash_alg, 1, info) && ops_write_scalar (skey->public_key.algorithm, 1, info) && ops_write(keyid, 8, info) && ops_write_scalar (1, 1, info); }
/** \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; }
int main(int argc,char **argv) { const char *keyfile; const char *plainfile; const char *user_id; const char *hashstr; const char *sigfile; ops_secret_key_t *skey; ops_create_signature_t *sig; ops_hash_algorithm_t alg; int fd; ops_create_info_t *info; unsigned char keyid[OPS_KEY_ID_SIZE]; if(argc != 6) { fprintf(stderr,"%s <secret key file> <user_id> <hash> <plaintext file>" " <signature file>\n",argv[0]); exit(1); } keyfile=argv[1]; user_id=argv[2]; hashstr=argv[3]; plainfile=argv[4]; sigfile=argv[5]; ops_init(); skey=get_secret_key(keyfile); assert(skey); alg=ops_hash_algorithm_from_text(hashstr); if(alg == OPS_HASH_UNKNOWN) { fprintf(stderr,"Unkonwn hash algorithm: %s\n",hashstr); exit(2); } sig=ops_create_signature_new(); ops_signature_start_cleartext_signature(sig,skey,alg,OPS_SIG_BINARY); fd=open(plainfile,O_RDONLY); if(fd < 0) { perror(plainfile); exit(3); } for( ; ; ) { unsigned char buf[8192]; int n; n=read(fd,buf,sizeof buf); if(!n) break; if(n < 0) { perror(plainfile); exit(4); } ops_signature_add_data(sig,buf,n); } close(fd); ops_signature_add_creation_time(sig,time(NULL)); ops_keyid(keyid,&skey->public_key); ops_signature_add_issuer_key_id(sig,keyid); ops_signature_hashed_subpackets_end(sig); fd=open(sigfile,O_CREAT|O_TRUNC|O_WRONLY,0666); if(fd < 0) { perror(sigfile); exit(5); } info=ops_create_info_new(); ops_writer_set_fd(info,fd); ops_write_signature(sig,&skey->public_key,skey,info); ops_secret_key_free(skey); return 0; }