static GString *purple_fbapi_construct_request_vargs(PurpleAccount *account, const char *method, va_list args) { GTree *params; const char *api_key, *api_secret; const char *key, *value; char call_id[21]; char *signature; GString *body; /* Read all paramters into a sorted tree */ params = g_tree_new((GCompareFunc)strcmp); while ((key = va_arg(args, const char *)) != NULL) { value = va_arg(args, const char *); g_tree_insert(params, (char *)key, (char *)value); /* If we have a session_key then we need a call_id */ if (g_str_equal(key, "session_key")) { struct timeval tv; if (gettimeofday(&tv, NULL) != 0) { time_t now; purple_debug_error("fbapi", "Error calling gettimeofday(): %s\n", g_strerror(errno)); now = time(NULL); strftime(call_id, sizeof(call_id), "%s000000", localtime(&now)); } else { char tmp[22]; strftime(tmp, sizeof(tmp), "%s", localtime(&tv.tv_sec)); sprintf(call_id, "%s%06lu", tmp, (long unsigned int)tv.tv_usec); } g_tree_insert(params, "call_id", call_id); } } api_key = purple_account_get_string(account, "fb_api_key", PURPLE_FBAPI_KEY); api_secret = purple_account_get_string(account, "fb_api_secret", API_SECRET); /* Add the method and api_key parameters to the list */ g_tree_insert(params, "method", (char *)method); g_tree_insert(params, "api_key", (char *)api_key); /* Add the signature parameter to the list */ signature = generate_signature((char *)api_secret, params); g_tree_insert(params, "sig", signature); /* Construct the body of the HTTP POST request */ body = g_string_new(NULL); g_tree_foreach(params, append_params_to_body, body); g_tree_destroy(params); g_free(signature); return body; }
// Add a signature at the end of every <file_info> element, // int add_signatures(char* xml, R_RSA_PRIVATE_KEY& key) { char* p = xml, *q1, *q2, buf[BLOB_SIZE], buf2[BLOB_SIZE]; char signature_hex[BLOB_SIZE]; char signature_xml[BLOB_SIZE]; char signed_xml[1024]; int retval, len; while (1) { q1 = strstr(p, "<file_info>\n"); if (!q1) break; q2 = strstr(q1, "</file_info>"); if (!q2) { fprintf(stderr, "add_signatures: malformed XML: %s\n", xml); return ERR_XML_PARSE; } q1 += strlen("<file_info>\n"); len = q2 - q1; memcpy(buf, q1, len); buf[len] = 0; char name[1024]; if (!parse_str(buf, "<name>", name, sizeof(name))) { fprintf(stderr, "add_signatures: missing name: %s", buf); return ERR_XML_PARSE; } double max_nbytes; if (!parse_double(buf, "<max_nbytes>", max_nbytes)) { fprintf(stderr, "add_signatures: missing max_nbytes: %s", buf); return ERR_XML_PARSE; } sprintf(signed_xml, "<name>%s</name><max_nbytes>%.0f</max_nbytes>", name, max_nbytes ); retval = generate_signature(signed_xml, signature_hex, key); sprintf(signature_xml, "<xml_signature>\n%s</xml_signature>\n", signature_hex ); if (retval) return retval; strcpy(buf2, q2); strcpy(q1, buf); strcat(q1, signature_xml); strcat(q1, buf2); p = q1; } return 0; }
void fill_session_url(CMStringA &buf, CMStringA &token, CMStringA &secret, time_t &hosttime, const char *password, bool encryption) { /* AIM_SESSION_URL?query_string?sig_sha256=signature */ CMStringA query_string; query_string.Format("a=%s&distId=%s&f=xml&k=%s&ts=%llu&useTLS=%d", token, AIM_DEFAULT_DISTID, AIM_DEFAULT_CLIENT_KEY, hosttime, (int)encryption); BYTE session_key[MIR_SHA256_HASH_SIZE], signature[MIR_SHA256_HASH_SIZE]; mir_hmac_sha256(session_key, (BYTE*)password, mir_strlen(password), (BYTE*)secret.GetString(), secret.GetLength()); ptrA szKey(mir_base64_encode(session_key, sizeof(session_key))); generate_signature(signature, "GET", AIM_SESSION_URL, query_string, szKey); ptrA szEncoded(mir_base64_encode(signature, sizeof(signature))); buf.Format("%s?%s&sig_sha256=%s", AIM_SESSION_URL, query_string, (char*)szEncoded); }
static void send_start_oscar_session(OscarData *od, const char *token, const char *session_key, time_t hosttime) { char *query_string, *signature, *url; PurpleAccount *account; gboolean use_tls; account = purple_connection_get_account(od->gc); use_tls = purple_account_get_bool(account, "use_ssl", OSCAR_DEFAULT_USE_SSL); /* * Construct the GET parameters. 0x00000611 is the distid given to * us by AOL for use as the default libpurple distid. */ query_string = g_strdup_printf("a=%s" "&distId=%d" "&f=xml" "&k=%s" "&ts=%" PURPLE_TIME_T_MODIFIER "&useTLS=%d", purple_url_encode(token), oscar_get_ui_info_int(od->icq ? "prpl-icq-distid" : "prpl-aim-distid", 0x00000611), get_client_key(od), hosttime, use_tls); signature = generate_signature("GET", URL_START_OSCAR_SESSION, query_string, session_key); url = g_strdup_printf(URL_START_OSCAR_SESSION "?%s&sig_sha256=%s", query_string, signature); g_free(query_string); g_free(signature); /* Make the request */ od->url_data = purple_util_fetch_url_request_len_with_account(account, url, TRUE, NULL, FALSE, NULL, FALSE, -1, start_oscar_session_cb, od); g_free(url); }
static void send_start_oscar_session(OscarData *od, const char *token, const char *session_key, time_t hosttime) { char *query_string, *signature, *url; gboolean use_tls = purple_account_get_bool(purple_connection_get_account(od->gc), "use_ssl", OSCAR_DEFAULT_USE_SSL); /* Construct the GET parameters */ query_string = g_strdup_printf("a=%s" "&f=xml" "&k=%s" "&ts=%" PURPLE_TIME_T_MODIFIER "&useTLS=%d", purple_url_encode(token), get_client_key(od), hosttime, use_tls); signature = generate_signature("GET", URL_START_OSCAR_SESSION, query_string, session_key); url = g_strdup_printf(URL_START_OSCAR_SESSION "?%s&sig_sha256=%s", query_string, signature); g_free(query_string); g_free(signature); /* Make the request */ od->url_data = purple_util_fetch_url(url, TRUE, NULL, FALSE, start_oscar_session_cb, od); g_free(url); }
int main(int argc, char** argv) { R_RSA_PUBLIC_KEY public_key; R_RSA_PRIVATE_KEY private_key; int i, n, retval; bool is_valid; DATA_BLOCK signature, in, out; unsigned char signature_buf[256], buf[256], buf2[256]; FILE *f, *fpriv, *fpub; char cbuf[256]; RSA rsa_key; RSA *rsa_key_; BIO *bio_out=NULL; BIO *bio_err=NULL; char *certpath; bool b2o=false; // boinc key to openssl key ? bool kpriv=false; // private key ? if (argc == 1) { usage(); exit(1); } if (!strcmp(argv[1], "-genkey")) { if (argc < 5) { usage(); exit(1); } printf("creating keys in %s and %s\n", argv[3], argv[4]); n = atoi(argv[2]); srand(random_int()); RSA* rp = RSA_generate_key(n, 65537, 0, 0); openssl_to_keys(rp, n, private_key, public_key); fpriv = fopen(argv[3], "w"); if (!fpriv) die("fopen"); fpub = fopen(argv[4], "w"); if (!fpub) die("fopen"); print_key_hex(fpriv, (KEY*)&private_key, sizeof(private_key)); print_key_hex(fpub, (KEY*)&public_key, sizeof(public_key)); } else if (!strcmp(argv[1], "-sign")) { if (argc < 4) { usage(); exit(1); } fpriv = fopen(argv[3], "r"); if (!fpriv) die("fopen"); retval = scan_key_hex(fpriv, (KEY*)&private_key, sizeof(private_key)); if (retval) die("scan_key_hex\n"); signature.data = signature_buf; signature.len = 256; retval = sign_file(argv[2], private_key, signature); print_hex_data(stdout, signature); } else if (!strcmp(argv[1], "-sign_string")) { if (argc < 4) { usage(); exit(1); } fpriv = fopen(argv[3], "r"); if (!fpriv) die("fopen"); retval = scan_key_hex(fpriv, (KEY*)&private_key, sizeof(private_key)); if (retval) die("scan_key_hex\n"); generate_signature(argv[2], cbuf, private_key); puts(cbuf); } else if (!strcmp(argv[1], "-verify")) { if (argc < 5) { usage(); exit(1); } fpub = fopen(argv[4], "r"); if (!fpub) die("fopen"); retval = scan_key_hex(fpub, (KEY*)&public_key, sizeof(public_key)); if (retval) die("read_public_key"); f = fopen(argv[3], "r"); signature.data = signature_buf; signature.len = 256; retval = scan_hex_data(f, signature); if (retval) die("scan_hex_data"); retval = verify_file(argv[2], public_key, signature, is_valid); if (retval) die("verify_file"); if (is_valid) { printf("file is valid\n"); } else { printf("file is invalid\n"); return 1; } } else if (!strcmp(argv[1], "-test_crypt")) { if (argc < 4) { usage(); exit(1); } fpriv = fopen(argv[2], "r"); if (!fpriv) die("fopen"); retval = scan_key_hex(fpriv, (KEY*)&private_key, sizeof(private_key)); if (retval) die("scan_key_hex\n"); fpub = fopen(argv[3], "r"); if (!fpub) die("fopen"); retval = scan_key_hex(fpub, (KEY*)&public_key, sizeof(public_key)); if (retval) die("read_public_key"); strcpy((char*)buf2, "encryption test successful"); in.data = buf2; in.len = strlen((char*)in.data); out.data = buf; encrypt_private(private_key, in, out); in = out; out.data = buf2; decrypt_public(public_key, in, out); printf("out: %s\n", out.data); } else if (!strcmp(argv[1], "-cert_verify")) { if (argc < 6) die("usage: crypt_prog -cert_verify file signature_file certificate_dir ca_dir \n"); f = fopen(argv[3], "r"); signature.data = signature_buf; signature.len = 256; retval = scan_hex_data(f, signature); if (retval) die("cannot scan_hex_data"); certpath = check_validity(argv[4], argv[2], signature.data, argv[5]); if (certpath == NULL) { die("signature cannot be verfied.\n\n"); } else { printf("siganture verified using certificate '%s'.\n\n", certpath); free(certpath); } // this converts, but an executable signed with sign_executable, // and signature converted to OpenSSL format cannot be verified with // OpenSSL } else if (!strcmp(argv[1], "-convsig")) { if (argc < 5) { usage(); exit(1); } if (strcmp(argv[2], "b2o") == 0) { b2o = true; } else if (strcmp(argv[2], "o2b") == 0) { b2o = false; } else { die("either 'o2b' or 'b2o' must be defined for -convsig\n"); } if (b2o) { f = fopen(argv[3], "r"); signature.data = signature_buf; signature.len = 256; retval = scan_hex_data(f, signature); fclose(f); f = fopen(argv[4], "w+"); print_raw_data(f, signature); fclose(f); } else { f = fopen(argv[3], "r"); signature.data = signature_buf; signature.len = 256; retval = scan_raw_data(f, signature); fclose(f); f = fopen(argv[4], "w+"); print_hex_data(f, signature); fclose(f); } } else if (!strcmp(argv[1], "-convkey")) { if (argc < 6) { usage(); exit(1); } if (strcmp(argv[2], "b2o") == 0) { b2o = true; } else if (strcmp(argv[2], "o2b") == 0) { b2o = false; } else { die("either 'o2b' or 'b2o' must be defined for -convkey\n"); } if (strcmp(argv[3], "pub") == 0) { kpriv = false; } else if (strcmp(argv[3], "priv") == 0) { kpriv = true; } else { die("either 'pub' or 'priv' must be defined for -convkey\n"); } OpenSSL_add_all_algorithms(); ERR_load_crypto_strings(); ENGINE_load_builtin_engines(); if (bio_err == NULL) { bio_err = BIO_new_fp(stdout, BIO_NOCLOSE); } //enc=EVP_get_cipherbyname("des"); //if (enc == NULL) // die("could not get cypher.\n"); // no encription yet. bio_out=BIO_new(BIO_s_file()); if (BIO_write_filename(bio_out,argv[5]) <= 0) { perror(argv[5]); die("could not create output file.\n"); } if (b2o) { rsa_key_ = RSA_new(); if (kpriv) { fpriv = fopen(argv[4], "r"); if (!fpriv) { die("fopen"); } scan_key_hex(fpriv, (KEY*)&private_key, sizeof(private_key)); fclose(fpriv); private_to_openssl(private_key, &rsa_key); //i = PEM_write_bio_RSAPrivateKey(bio_out, &rsa_key, // enc, NULL, 0, pass_cb, NULL); // no encryption yet. //i = PEM_write_bio_RSAPrivateKey(bio_out, &rsa_key, // NULL, NULL, 0, pass_cb, NULL); fpriv = fopen(argv[5], "w+"); PEM_write_RSAPrivateKey(fpriv, &rsa_key, NULL, NULL, 0, 0, NULL); fclose(fpriv); //if (i == 0) { // ERR_print_errors(bio_err); // die("could not write key file.\n"); //} } else { fpub = fopen(argv[4], "r"); if (!fpub) { die("fopen"); } scan_key_hex(fpub, (KEY*)&public_key, sizeof(public_key)); fclose(fpub); fpub = fopen(argv[5], "w+"); if (!fpub) { die("fopen"); } public_to_openssl(public_key, rsa_key_); i = PEM_write_RSA_PUBKEY(fpub, rsa_key_); if (i == 0) { ERR_print_errors(bio_err); die("could not write key file.\n"); } fclose(fpub); } } else { // o2b rsa_key_ = (RSA *)calloc(1, sizeof(RSA)); memset(rsa_key_, 0, sizeof(RSA)); if (rsa_key_ == NULL) { die("could not allocate memory for RSA structure.\n"); } if (kpriv) { fpriv = fopen (argv[4], "r"); rsa_key_ = PEM_read_RSAPrivateKey(fpriv, NULL, NULL, NULL); fclose(fpriv); if (rsa_key_ == NULL) { ERR_print_errors(bio_err); die("could not load private key.\n"); } openssl_to_private(rsa_key_, &private_key); fpriv = fopen(argv[5], "w"); if (!fpriv) { die("fopen"); } print_key_hex(fpriv, (KEY*)&private_key, sizeof(private_key)); } else { fpub = fopen (argv[4], "r"); rsa_key_ = PEM_read_RSA_PUBKEY(fpub, NULL, NULL, NULL); fclose(fpub); if (rsa_key_ == NULL) { ERR_print_errors(bio_err); die("could not load public key.\n"); } openssl_to_keys(rsa_key_, 1024, private_key, public_key); //openssl_to_public(rsa_key_, &public_key); public_to_openssl(public_key, rsa_key_); // fpub = fopen(argv[5], "w"); if (!fpub) { die("fopen"); } print_key_hex(fpub, (KEY*)&public_key, sizeof(public_key)); } } } else { usage(); exit(1); } return 0; }
int main(int argc, char *argv[]) { int rc; pesign_context ctx, *ctxp = &ctx; int list = 0; int remove = 0; char *digest_name = "sha256"; poptContext optCon; struct poptOption options[] = { {NULL, '\0', POPT_ARG_INTL_DOMAIN, "pesign" }, {"in", 'i', POPT_ARG_STRING, &ctx.infile, 0, "specify input file", "<infile>"}, {"out", 'o', POPT_ARG_STRING, &ctx.outfile, 0, "specify output file", "<outfile>" }, {"certficate", 'c', POPT_ARG_STRING, &ctx.cms_ctx.certname, 0, "specify certificate nickname", "<certificate nickname>" }, {"privkey", 'p', POPT_ARG_STRING, &ctx.privkeyfile, 0, "specify private key file", "<privkey>" }, {"force", 'f', POPT_ARG_VAL, &ctx.force, 1, "force overwriting of output file", NULL }, {"nogaps", 'n', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &ctx.hashgaps, 0, "skip gaps between sections when signing", NULL }, {"sign", 's', POPT_ARG_VAL, &ctx.sign, 1, "create a new signature", NULL }, {"hash", 'h', POPT_ARG_VAL, &ctx.hash, 1, "hash binary", NULL }, {"digest_type", 'd', POPT_ARG_STRING|POPT_ARGFLAG_SHOW_DEFAULT, &digest_name, 0, "digest type to use for pe hash" }, {"import-signature", 'm', POPT_ARG_STRING|POPT_ARGFLAG_DOC_HIDDEN, &ctx.insig, 0,"import signature from file", "<insig>" }, {"signature-number", 'u', POPT_ARG_INT, &ctx.signum, -1, "specify which signature to operate on","<sig-number>"}, {"list-signatures", 'l', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &list, 1, "list signatures", NULL }, {"show-signature", 'S', POPT_ARG_VAL, &list, 1, "show signature", NULL }, {"remove-signature", 'r', POPT_ARG_VAL, &remove, 1, "remove signature" }, {"export-signature", 'e', POPT_ARG_STRING|POPT_ARGFLAG_DOC_HIDDEN, &ctx.outsig, 0,"export signature to file", "<outsig>" }, {"export-pubkey", 'K', POPT_ARG_STRING, &ctx.outkey, 0, "export pubkey to file", "<outkey>" }, {"export-cert", 'C', POPT_ARG_STRING, &ctx.outcert, 0, "export signing cert to file", "<outcert>" }, {"ascii-armor", 'a', POPT_ARG_VAL, &ctx.ascii, 1, "use ascii armoring", NULL }, POPT_AUTOALIAS POPT_AUTOHELP POPT_TABLEEND }; rc = pesign_context_init(ctxp); if (rc < 0) { fprintf(stderr, "Could not initialize context: %m\n"); exit(1); } optCon = poptGetContext("pesign", argc, (const char **)argv, options,0); while ((rc = poptGetNextOpt(optCon)) > 0) ; if (rc < -1) { fprintf(stderr, "pesign: Invalid argument: %s: %s\n", poptBadOption(optCon, 0), poptStrerror(rc)); exit(1); } if (poptPeekArg(optCon)) { fprintf(stderr, "pesign: Invalid Argument: \"%s\"\n", poptPeekArg(optCon)); exit(1); } poptFreeContext(optCon); rc = set_digest_parameters(&ctx.cms_ctx, digest_name); int is_help = strcmp(digest_name, "help") ? 0 : 1; if (rc < 0) { if (!is_help) { fprintf(stderr, "Digest \"%s\" not found.\n", digest_name); } exit(!is_help); } int action = 0; if (ctx.insig) action |= IMPORT_SIGNATURE; if (ctx.outkey) action |= EXPORT_PUBKEY; if (ctx.outcert) action |= EXPORT_CERT; if (ctx.outsig) action |= EXPORT_SIGNATURE; if (remove != 0) action |= REMOVE_SIGNATURE; if (list != 0) action |= LIST_SIGNATURES; if (ctx.sign) { action |= GENERATE_SIGNATURE; if (!(action & EXPORT_SIGNATURE)) action |= IMPORT_SIGNATURE; } if (ctx.hash) action |= GENERATE_DIGEST|PRINT_DIGEST; SECItem newsig; switch (action) { case NO_FLAGS: fprintf(stderr, "pesign: Nothing to do.\n"); exit(0); break; /* add a signature from a file */ case IMPORT_SIGNATURE: check_inputs(ctxp); open_input(ctxp); open_output(ctxp); close_input(ctxp); open_sig_input(ctxp); import_signature(ctxp); close_sig_input(ctxp); close_output(ctxp); break; case EXPORT_PUBKEY: rc = find_certificate(&ctx.cms_ctx); if (rc < 0) { fprintf(stderr, "pesign: Could not find " "certificate %s\n", ctx.cms_ctx.certname); exit(1); } open_pubkey_output(ctxp); export_pubkey(ctxp); break; case EXPORT_CERT: rc = find_certificate(&ctx.cms_ctx); if (rc < 0) { fprintf(stderr, "pesign: Could not find " "certificate %s\n", ctx.cms_ctx.certname); exit(1); } open_cert_output(ctxp); export_cert(ctxp); break; /* find a signature in the binary and save it to a file */ case EXPORT_SIGNATURE: open_input(ctxp); open_sig_output(ctxp); if (ctx.signum > ctx.cms_ctx.num_signatures) { fprintf(stderr, "Invalid signature number.\n"); exit(1); } SECItem *sig = ctx.cms_ctx.signatures[ctx.signum]; export_signature(ctxp, sig); close_input(ctxp); close_sig_output(ctxp); break; /* remove a signature from the binary */ case REMOVE_SIGNATURE: check_inputs(ctxp); open_input(ctxp); open_output(ctxp); close_input(ctxp); if (ctx.signum > ctx.cms_ctx.num_signatures) { fprintf(stderr, "Invalid signature number.\n"); exit(1); } remove_signature(&ctx); close_output(ctxp); break; /* list signatures in the binary */ case LIST_SIGNATURES: open_input(ctxp); list_signatures(ctxp); break; case GENERATE_DIGEST|PRINT_DIGEST: open_input(ctxp); generate_digest(ctxp, ctx.inpe); print_digest(ctxp); break; /* generate a signature and save it in a separate file */ case EXPORT_SIGNATURE|GENERATE_SIGNATURE: rc = find_certificate(&ctx.cms_ctx); if (rc < 0) { fprintf(stderr, "pesign: Could not find " "certificate %s\n", ctx.cms_ctx.certname); exit(1); } open_input(ctxp); open_sig_output(ctxp); generate_digest(ctxp, ctx.inpe); generate_signature(ctxp, &newsig); export_signature(ctxp, &newsig); break; /* generate a signature and embed it in the binary */ case IMPORT_SIGNATURE|GENERATE_SIGNATURE: check_inputs(ctxp); rc = find_certificate(&ctx.cms_ctx); if (rc < 0) { fprintf(stderr, "pesign: Could not find " "certificate %s\n", ctx.cms_ctx.certname); exit(1); } open_input(ctxp); open_output(ctxp); close_input(ctxp); generate_digest(ctxp, ctx.outpe); generate_signature(ctxp, &newsig); insert_signature(ctxp, &newsig); close_output(ctxp); break; default: fprintf(stderr, "Incompatible flags (0x%08x): ", action); for (int i = 1; i < FLAG_LIST_END; i <<= 1) { if (action & i) print_flag_name(stderr, i); } fprintf(stderr, "\n"); exit(1); } pesign_context_fini(&ctx); return (rc < 0); }
int main(int argc, char *argv[]) { int rc; pesign_context *ctxp; int list = 0; int remove = 0; int daemon = 0; int fork = 1; int padding = 0; int need_db = 0; char *digest_name = "sha256"; char *tokenname = "NSS Certificate DB"; char *origtoken = tokenname; char *certname = NULL; char *certdir = "/etc/pki/pesign"; char *signum = NULL; rc = pesign_context_new(&ctxp); if (rc < 0) { fprintf(stderr, "Could not initialize context: %m\n"); exit(1); } poptContext optCon; struct poptOption options[] = { {NULL, '\0', POPT_ARG_INTL_DOMAIN, "pesign" }, {"in", 'i', POPT_ARG_STRING, &ctxp->infile, 0, "specify input file", "<infile>"}, {"out", 'o', POPT_ARG_STRING, &ctxp->outfile, 0, "specify output file", "<outfile>" }, {"certficate", 'c', POPT_ARG_STRING, &certname, 0, "specify certificate nickname", "<certificate nickname>" }, {"certdir", 'n', POPT_ARG_STRING|POPT_ARGFLAG_SHOW_DEFAULT, &certdir, 0, "specify nss certificate database directory", "<certificate directory path>" }, {"force", 'f', POPT_ARG_VAL, &ctxp->force, 1, "force overwriting of output file", NULL }, {"sign", 's', POPT_ARG_VAL, &ctxp->sign, 1, "create a new signature", NULL }, {"hash", 'h', POPT_ARG_VAL, &ctxp->hash, 1, "hash binary", NULL }, {"digest_type", 'd', POPT_ARG_STRING|POPT_ARGFLAG_SHOW_DEFAULT, &digest_name, 0, "digest type to use for pe hash" }, {"import-signed-certificate", 'm', POPT_ARG_STRING|POPT_ARGFLAG_DOC_HIDDEN, &ctxp->insig, 0,"import signature from file", "<insig>" }, {"export-signed-attributes", 'E', POPT_ARG_STRING|POPT_ARGFLAG_DOC_HIDDEN, &ctxp->outsattrs, 0, "export signed attributes to file", "<signed_attributes_file>" }, {"import-signed-attributes", 'I', POPT_ARG_STRING|POPT_ARGFLAG_DOC_HIDDEN, &ctxp->insattrs, 0, "import signed attributes from file", "<signed_attributes_file>" }, {"import-raw-signature", 'R', POPT_ARG_STRING|POPT_ARGFLAG_DOC_HIDDEN, &ctxp->rawsig, 0, "import raw signature from file", "<inraw>" }, {"signature-number", 'u', POPT_ARG_STRING, &signum, 0, "specify which signature to operate on","<sig-number>"}, {"list-signatures", 'l', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &list, 1, "list signatures", NULL }, {"nss-token", 't', POPT_ARG_STRING|POPT_ARGFLAG_SHOW_DEFAULT, &tokenname, 0, "NSS token holding signing key" }, {"show-signature", 'S', POPT_ARG_VAL, &list, 1, "show signature", NULL }, {"remove-signature", 'r', POPT_ARG_VAL, &remove, 1, "remove signature" }, {"export-signature", 'e', POPT_ARG_STRING|POPT_ARGFLAG_DOC_HIDDEN, &ctxp->outsig, 0, "export signature to file", "<outsig>" }, {"export-pubkey", 'K', POPT_ARG_STRING, &ctxp->outkey, 0, "export pubkey to file", "<outkey>" }, {"export-cert", 'C', POPT_ARG_STRING, &ctxp->outcert, 0, "export signing cert to file", "<outcert>" }, {"ascii-armor", 'a', POPT_ARG_VAL, &ctxp->ascii, 1, "use ascii armoring", NULL }, {"daemonize", 'D', POPT_ARG_VAL, &daemon, 1, "run as a daemon process", NULL }, {"nofork", 'N', POPT_ARG_VAL, &fork, 0, "don't fork when daemonizing", NULL }, {"verbose", 'v', POPT_ARG_VAL, &ctxp->verbose, 1, "be very verbose", NULL }, {"padding", 'P', POPT_ARG_VAL, &padding, 1, "pad data section", NULL }, POPT_AUTOALIAS POPT_AUTOHELP POPT_TABLEEND }; optCon = poptGetContext("pesign", argc, (const char **)argv, options,0); rc = poptReadDefaultConfig(optCon, 0); if (rc < 0 && !(rc == POPT_ERROR_ERRNO && errno == ENOENT)) { fprintf(stderr, "pesign: poptReadDefaultConfig failed: %s\n", poptStrerror(rc)); exit(1); } while ((rc = poptGetNextOpt(optCon)) > 0) ; if (rc < -1) { fprintf(stderr, "pesign: Invalid argument: %s: %s\n", poptBadOption(optCon, 0), poptStrerror(rc)); exit(1); } if (poptPeekArg(optCon)) { fprintf(stderr, "pesign: Invalid Argument: \"%s\"\n", poptPeekArg(optCon)); exit(1); } poptFreeContext(optCon); if (signum) { errno = 0; ctxp->signum = strtol(signum, NULL, 0); if (errno != 0) { fprintf(stderr, "invalid signature number: %m\n"); exit(1); } } int action = 0; if (daemon) action |= DAEMONIZE; if (ctxp->rawsig) { action |= IMPORT_RAW_SIGNATURE; need_db = 1; } if (ctxp->insattrs) action |= IMPORT_SATTRS; if (ctxp->outsattrs) action |= EXPORT_SATTRS; if (ctxp->insig) action |= IMPORT_SIGNATURE; if (ctxp->outkey) { action |= EXPORT_PUBKEY; need_db = 1; } if (ctxp->outcert) { action |= EXPORT_CERT; need_db = 1; } if (ctxp->outsig) action |= EXPORT_SIGNATURE; if (remove != 0) action |= REMOVE_SIGNATURE; if (list != 0) action |= LIST_SIGNATURES; if (ctxp->sign) { action |= GENERATE_SIGNATURE; if (!(action & EXPORT_SIGNATURE)) action |= IMPORT_SIGNATURE; need_db = 1; } if (ctxp->hash) action |= GENERATE_DIGEST|PRINT_DIGEST; if (!daemon) { SECStatus status; if (need_db) status = NSS_Init(certdir); else status = NSS_NoDB_Init(NULL); if (status != SECSuccess) { fprintf(stderr, "Could not initialize nss: %s\n", PORT_ErrorToString(PORT_GetError())); exit(1); } status = register_oids(ctxp->cms_ctx); if (status != SECSuccess) { fprintf(stderr, "Could not register OIDs\n"); exit(1); } } rc = set_digest_parameters(ctxp->cms_ctx, digest_name); int is_help = strcmp(digest_name, "help") ? 0 : 1; if (rc < 0) { if (!is_help) { fprintf(stderr, "Digest \"%s\" not found.\n", digest_name); } exit(!is_help); } ctxp->cms_ctx->tokenname = tokenname ? PORT_ArenaStrdup(ctxp->cms_ctx->arena, tokenname) : NULL; if (tokenname && !ctxp->cms_ctx->tokenname) { fprintf(stderr, "could not allocate token name: %s\n", PORT_ErrorToString(PORT_GetError())); exit(1); } if (tokenname != origtoken) free(tokenname); ctxp->cms_ctx->certname = certname ? PORT_ArenaStrdup(ctxp->cms_ctx->arena, certname) : NULL; if (certname && !ctxp->cms_ctx->certname) { fprintf(stderr, "could not allocate certificate name: %s\n", PORT_ErrorToString(PORT_GetError())); exit(1); } if (certname) free(certname); if (ctxp->sign) { if (!ctxp->cms_ctx->certname) { fprintf(stderr, "pesign: signing requested but no " "certificate nickname provided\n"); exit(1); } } ssize_t sigspace = 0; switch (action) { case NO_FLAGS: fprintf(stderr, "pesign: Nothing to do.\n"); exit(0); break; /* in this case we have the actual binary signature and the * signing cert, but not the pkcs7ish certificate that goes * with it. */ case IMPORT_RAW_SIGNATURE|IMPORT_SATTRS: check_inputs(ctxp); rc = find_certificate(ctxp->cms_ctx, 0); if (rc < 0) { fprintf(stderr, "pesign: Could not find " "certificate %s\n", ctxp->cms_ctx->certname); exit(1); } open_rawsig_input(ctxp); open_sattr_input(ctxp); import_raw_signature(ctxp); close_sattr_input(ctxp); close_rawsig_input(ctxp); open_input(ctxp); open_output(ctxp); close_input(ctxp); generate_digest(ctxp->cms_ctx, ctxp->outpe, 1); sigspace = calculate_signature_space(ctxp->cms_ctx, ctxp->outpe); allocate_signature_space(ctxp->outpe, sigspace); generate_signature(ctxp->cms_ctx); insert_signature(ctxp->cms_ctx, ctxp->signum); close_output(ctxp); break; case EXPORT_SATTRS: open_input(ctxp); open_sattr_output(ctxp); generate_digest(ctxp->cms_ctx, ctxp->inpe, 1); generate_sattr_blob(ctxp); close_sattr_output(ctxp); close_input(ctxp); break; /* add a signature from a file */ case IMPORT_SIGNATURE: check_inputs(ctxp); if (ctxp->signum > ctxp->cms_ctx->num_signatures + 1) { fprintf(stderr, "Invalid signature number.\n"); exit(1); } open_input(ctxp); open_output(ctxp); close_input(ctxp); open_sig_input(ctxp); parse_signature(ctxp); sigspace = get_sigspace_extend_amount(ctxp->cms_ctx, ctxp->outpe, &ctxp->cms_ctx->newsig); allocate_signature_space(ctxp->outpe, sigspace); check_signature_space(ctxp); insert_signature(ctxp->cms_ctx, ctxp->signum); close_sig_input(ctxp); close_output(ctxp); break; case EXPORT_PUBKEY: rc = find_certificate(ctxp->cms_ctx, 1); if (rc < 0) { fprintf(stderr, "pesign: Could not find " "certificate %s\n", ctxp->cms_ctx->certname); exit(1); } open_pubkey_output(ctxp); export_pubkey(ctxp); break; case EXPORT_CERT: rc = find_certificate(ctxp->cms_ctx, 0); if (rc < 0) { fprintf(stderr, "pesign: Could not find " "certificate %s\n", ctxp->cms_ctx->certname); exit(1); } open_cert_output(ctxp); export_cert(ctxp); break; /* find a signature in the binary and save it to a file */ case EXPORT_SIGNATURE: open_input(ctxp); open_sig_output(ctxp); if (ctxp->signum > ctxp->cms_ctx->num_signatures) { fprintf(stderr, "Invalid signature number.\n"); exit(1); } if (ctxp->signum < 0) ctxp->signum = 0; if (ctxp->signum >= ctxp->cms_ctx->num_signatures) { fprintf(stderr, "No valid signature #%d.\n", ctxp->signum); exit(1); } memcpy(&ctxp->cms_ctx->newsig, ctxp->cms_ctx->signatures[ctxp->signum], sizeof (ctxp->cms_ctx->newsig)); export_signature(ctxp->cms_ctx, ctxp->outsigfd, ctxp->ascii); close_input(ctxp); close_sig_output(ctxp); memset(&ctxp->cms_ctx->newsig, '\0', sizeof (ctxp->cms_ctx->newsig)); break; /* remove a signature from the binary */ case REMOVE_SIGNATURE: check_inputs(ctxp); open_input(ctxp); open_output(ctxp); close_input(ctxp); if (ctxp->signum < 0 || ctxp->signum >= ctxp->cms_ctx->num_signatures) { fprintf(stderr, "Invalid signature number %d. " "Must be between 0 and %d.\n", ctxp->signum, ctxp->cms_ctx->num_signatures - 1); exit(1); } remove_signature(ctxp); close_output(ctxp); break; /* list signatures in the binary */ case LIST_SIGNATURES: open_input(ctxp); list_signatures(ctxp); break; case GENERATE_DIGEST|PRINT_DIGEST: open_input(ctxp); generate_digest(ctxp->cms_ctx, ctxp->inpe, padding); print_digest(ctxp); break; /* generate a signature and save it in a separate file */ case EXPORT_SIGNATURE|GENERATE_SIGNATURE: rc = find_certificate(ctxp->cms_ctx, 1); if (rc < 0) { fprintf(stderr, "pesign: Could not find " "certificate %s\n", ctxp->cms_ctx->certname); exit(1); } open_input(ctxp); open_sig_output(ctxp); generate_digest(ctxp->cms_ctx, ctxp->inpe, 1); generate_signature(ctxp->cms_ctx); export_signature(ctxp->cms_ctx, ctxp->outsigfd, ctxp->ascii); break; /* generate a signature and embed it in the binary */ case IMPORT_SIGNATURE|GENERATE_SIGNATURE: check_inputs(ctxp); rc = find_certificate(ctxp->cms_ctx, 1); if (rc < 0) { fprintf(stderr, "pesign: Could not find " "certificate %s\n", ctxp->cms_ctx->certname); exit(1); } if (ctxp->signum > ctxp->cms_ctx->num_signatures + 1) { fprintf(stderr, "Invalid signature number.\n"); exit(1); } open_input(ctxp); open_output(ctxp); close_input(ctxp); generate_digest(ctxp->cms_ctx, ctxp->outpe, 1); sigspace = calculate_signature_space(ctxp->cms_ctx, ctxp->outpe); allocate_signature_space(ctxp->outpe, sigspace); generate_digest(ctxp->cms_ctx, ctxp->outpe, 1); generate_signature(ctxp->cms_ctx); insert_signature(ctxp->cms_ctx, ctxp->signum); close_output(ctxp); break; case DAEMONIZE: rc = daemonize(ctxp->cms_ctx, certdir, fork); break; default: fprintf(stderr, "Incompatible flags (0x%08x): ", action); for (int i = 1; i < FLAG_LIST_END; i <<= 1) { if (action & i) print_flag_name(stderr, i); } fprintf(stderr, "\n"); exit(1); } pesign_context_free(ctxp); if (!daemon) { SECStatus status = NSS_Shutdown(); if (status != SECSuccess) { fprintf(stderr, "could not shut down NSS: %s", PORT_ErrorToString(PORT_GetError())); exit(1); } } return (rc < 0); }