/** \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 1 if OK; else 0 */ unsigned pgp_add_selfsigned_userid(pgp_key_t *key, uint8_t *userid) { pgp_create_sig_t *sig; pgp_subpacket_t sigpacket; pgp_memory_t *mem_userid = NULL; pgp_output_t *useridoutput = NULL; pgp_memory_t *mem_sig = NULL; pgp_output_t *sigoutput = NULL; /* * create signature packet for this userid */ /* create userid pkt */ pgp_setup_memory_write(&useridoutput, &mem_userid, 128); pgp_write_struct_userid(useridoutput, userid); /* create sig for this pkt */ sig = pgp_create_sig_new(); pgp_sig_start_key_sig(sig, &key->key.seckey.pubkey, userid, PGP_CERT_POSITIVE); pgp_add_time(sig, (int64_t)time(NULL), "birth"); pgp_add_issuer_keyid(sig, key->sigid); pgp_add_primary_userid(sig, 1); pgp_end_hashed_subpkts(sig); pgp_setup_memory_write(&sigoutput, &mem_sig, 128); pgp_write_sig(sigoutput, sig, &key->key.seckey.pubkey, &key->key.seckey); /* add this packet to key */ sigpacket.length = pgp_mem_len(mem_sig); sigpacket.raw = pgp_mem_data(mem_sig); /* add userid to key */ (void) pgp_add_userid(key, userid); (void) pgp_add_subpacket(key, &sigpacket); /* cleanup */ pgp_create_sig_delete(sig); pgp_output_delete(useridoutput); pgp_output_delete(sigoutput); pgp_memory_free(mem_userid); pgp_memory_free(mem_sig); return 1; }
/** \ingroup HighLevel_Sign \brief Sign a file \param inname Input filename \param outname Output filename. If NULL, a name is constructed from the input filename. \param seckey Secret Key to use for signing \param armored Write armoured text, if set. \param overwrite May overwrite existing file, if set. \return 1 if OK; else 0; */ unsigned pgp_sign_file(pgp_io_t *io, const char *inname, const char *outname, const pgp_seckey_t *seckey, const char *hashname, const int64_t from, const uint64_t duration, const unsigned armored, const unsigned cleartext, const unsigned overwrite) { pgp_create_sig_t *sig; pgp_sig_type_t sig_type; pgp_hash_alg_t hash_alg; pgp_memory_t *infile; pgp_output_t *output; pgp_hash_t *hash; unsigned ret; uint8_t keyid[PGP_KEY_ID_SIZE]; int fd_out; sig = NULL; sig_type = PGP_SIG_BINARY; infile = NULL; output = NULL; hash = NULL; fd_out = 0; /* find the hash algorithm */ hash_alg = pgp_str_to_hash_alg(hashname); if (hash_alg == PGP_HASH_UNKNOWN) { (void) fprintf(io->errs, "pgp_sign_file: unknown hash algorithm: \"%s\"\n", hashname); return 0; } /* read input file into buf */ infile = pgp_memory_new(); if (!pgp_mem_readfile(infile, inname)) { return 0; } /* setup output file */ fd_out = open_output_file(&output, inname, outname, (armored) ? "asc" : "gpg", overwrite); if (fd_out < 0) { pgp_memory_free(infile); return 0; } /* set up signature */ sig = pgp_create_sig_new(); if (!sig) { pgp_memory_free(infile); pgp_teardown_file_write(output, fd_out); return 0; } pgp_start_sig(sig, seckey, hash_alg, sig_type); if (cleartext) { if (pgp_writer_push_clearsigned(output, sig) != 1) { return 0; } /* Do the signing */ pgp_write(output, pgp_mem_data(infile), (unsigned)pgp_mem_len(infile)); pgp_memory_free(infile); /* add signature with subpackets: */ /* - creation time */ /* - key id */ ret = pgp_writer_use_armored_sig(output) && pgp_add_time(sig, (int64_t)from, "birth") && pgp_add_time(sig, (int64_t)duration, "expiration"); if (ret == 0) { pgp_teardown_file_write(output, fd_out); return 0; } pgp_keyid(keyid, PGP_KEY_ID_SIZE, &seckey->pubkey, hash_alg); ret = pgp_add_issuer_keyid(sig, keyid) && pgp_end_hashed_subpkts(sig) && pgp_write_sig(output, sig, &seckey->pubkey, seckey); pgp_teardown_file_write(output, fd_out); if (ret == 0) { PGP_ERROR_1(&output->errors, PGP_E_W, "%s", "Cannot sign file as cleartext"); } } else { /* set armoured/not armoured here */ if (armored) { pgp_writer_push_armor_msg(output); } /* write one_pass_sig */ pgp_write_one_pass_sig(output, seckey, hash_alg, sig_type); /* hash file contents */ hash = pgp_sig_get_hash(sig); hash->add(hash, pgp_mem_data(infile), (unsigned)pgp_mem_len(infile)); #if 1 /* output file contents as Literal Data packet */ pgp_write_litdata(output, pgp_mem_data(infile), (const int)pgp_mem_len(infile), PGP_LDT_BINARY); #else /* XXX - agc - sync with writer.c 1094 for ops_writez */ pgp_setup_memory_write(&litoutput, &litmem, bufsz); pgp_setup_memory_write(&zoutput, &zmem, bufsz); pgp_write_litdata(litoutput, pgp_mem_data(pgp_mem_data(infile), (const int)pgp_mem_len(infile), PGP_LDT_BINARY); pgp_writez(zoutput, pgp_mem_data(litmem), pgp_mem_len(litmem)); #endif /* add creation time to signature */ pgp_add_time(sig, (int64_t)from, "birth"); pgp_add_time(sig, (int64_t)duration, "expiration"); /* add key id to signature */ pgp_keyid(keyid, PGP_KEY_ID_SIZE, &seckey->pubkey, hash_alg); pgp_add_issuer_keyid(sig, keyid); pgp_end_hashed_subpkts(sig); pgp_write_sig(output, sig, &seckey->pubkey, seckey); /* tidy up */ pgp_teardown_file_write(output, fd_out); pgp_create_sig_delete(sig); pgp_memory_free(infile); ret = 1; } return ret; }
/* sign a file, and put the signature in a separate file */ int pgp_sign_detached(pgp_io_t *io, const char *f, char *sigfile, pgp_seckey_t *seckey, const char *hash, const int64_t from, const uint64_t duration, const unsigned armored, const unsigned overwrite) { pgp_create_sig_t *sig; pgp_hash_alg_t hash_alg; pgp_output_t *output; pgp_memory_t *mem; uint8_t keyid[PGP_KEY_ID_SIZE]; int fd; /* find out which hash algorithm to use */ hash_alg = pgp_str_to_hash_alg(hash); if (hash_alg == PGP_HASH_UNKNOWN) { (void) fprintf(io->errs,"Unknown hash algorithm: %s\n", hash); return 0; } /* setup output file */ fd = open_output_file(&output, f, sigfile, (armored) ? "asc" : "sig", overwrite); if (fd < 0) { (void) fprintf(io->errs,"Can't open output file: %s\n", f); return 0; } /* create a new signature */ sig = pgp_create_sig_new(); pgp_start_sig(sig, seckey, hash_alg, PGP_SIG_BINARY); /* read the contents of 'f', and add that to the signature */ mem = pgp_memory_new(); if (!pgp_mem_readfile(mem, f)) { pgp_teardown_file_write(output, fd); return 0; } /* set armoured/not armoured here */ if (armored) { pgp_writer_push_armor_msg(output); } pgp_sig_add_data(sig, pgp_mem_data(mem), pgp_mem_len(mem)); pgp_memory_free(mem); /* calculate the signature */ pgp_add_time(sig, from, "birth"); pgp_add_time(sig, (int64_t)duration, "expiration"); pgp_keyid(keyid, sizeof(keyid), &seckey->pubkey, hash_alg); pgp_add_issuer_keyid(sig, keyid); pgp_end_hashed_subpkts(sig); pgp_write_sig(output, sig, &seckey->pubkey, seckey); pgp_teardown_file_write(output, fd); pgp_seckey_free(seckey); return 1; }
/** \ingroup HighLevel_Sign \brief Signs a buffer \param input Input text to be signed \param input_len Length of input text \param sig_type Signature type \param seckey Secret Key \param armored Write armoured text, if set \return New pgp_memory_t struct containing signed text \note It is the caller's responsibility to call pgp_memory_free(me) */ pgp_memory_t * pgp_sign_buf(pgp_io_t *io, const void *input, const size_t insize, const pgp_seckey_t *seckey, const int64_t from, const uint64_t duration, const char *hashname, const unsigned armored, const unsigned cleartext) { pgp_litdata_enum ld_type; pgp_create_sig_t *sig; pgp_sig_type_t sig_type; pgp_hash_alg_t hash_alg; pgp_output_t *output; pgp_memory_t *mem; uint8_t keyid[PGP_KEY_ID_SIZE]; pgp_hash_t *hash; unsigned ret; sig = NULL; sig_type = PGP_SIG_BINARY; output = NULL; mem = pgp_memory_new(); hash = NULL; ret = 0; hash_alg = pgp_str_to_hash_alg(hashname); if (hash_alg == PGP_HASH_UNKNOWN) { (void) fprintf(io->errs, "pgp_sign_buf: unknown hash algorithm: \"%s\"\n", hashname); return NULL; } /* setup literal data packet type */ ld_type = (cleartext) ? PGP_LDT_TEXT : PGP_LDT_BINARY; if (input == NULL) { (void) fprintf(io->errs, "pgp_sign_buf: null input\n"); return NULL; } /* set up signature */ if ((sig = pgp_create_sig_new()) == NULL) { return NULL; } pgp_start_sig(sig, seckey, hash_alg, sig_type); /* setup writer */ pgp_setup_memory_write(&output, &mem, insize); if (cleartext) { /* Do the signing */ /* add signature with subpackets: */ /* - creation time */ /* - key id */ ret = pgp_writer_push_clearsigned(output, sig) && pgp_write(output, input, (unsigned)insize) && pgp_writer_use_armored_sig(output) && pgp_add_time(sig, from, "birth") && pgp_add_time(sig, (int64_t)duration, "expiration"); if (ret == 0) { return NULL; } pgp_output_delete(output); } else { /* set armoured/not armoured here */ if (armored) { pgp_writer_push_armor_msg(output); } if (pgp_get_debug_level(__FILE__)) { fprintf(io->errs, "** Writing out one pass sig\n"); } /* write one_pass_sig */ pgp_write_one_pass_sig(output, seckey, hash_alg, sig_type); /* hash memory */ hash = pgp_sig_get_hash(sig); hash->add(hash, input, (unsigned)insize); /* output file contents as Literal Data packet */ if (pgp_get_debug_level(__FILE__)) { (void) fprintf(stderr, "** Writing out data now\n"); } pgp_write_litdata(output, input, (const int)insize, ld_type); if (pgp_get_debug_level(__FILE__)) { fprintf(stderr, "** After Writing out data now\n"); } /* add creation time to signature */ pgp_add_time(sig, from, "birth"); pgp_add_time(sig, (int64_t)duration, "expiration"); /* add key id to signature */ pgp_keyid(keyid, PGP_KEY_ID_SIZE, &seckey->pubkey, hash_alg); pgp_add_issuer_keyid(sig, keyid); pgp_end_hashed_subpkts(sig); /* write out sig */ pgp_write_sig(output, sig, &seckey->pubkey, seckey); /* tidy up */ pgp_writer_close(output); pgp_create_sig_delete(sig); } return mem; }