#include #include #include #include #include #include #include #include #if !defined(_WIN32) #include #else #include "winglue.h" #endif #include "pattern.h" #include "util.h" const char *version = VANITYGEN_VERSION; static void usage(const char *progname) { fprintf(stderr, "Vanitygen keyconv %s\n" "Usage: %s [-8] [-e|-E ] [-c ] []\n" "-G Generate a key pair and output the full public key\n" "-8 Output key in PKCS#8 form\n" "-e Encrypt output key, prompt for password\n" "-E Encrypt output key with (UNSAFE)\n" "-c Combine private key parts to make complete private key\n" "-v Verbose output\n", version, progname); } int main(int argc, char **argv) { char pwbuf[128]; char ecprot[128]; char pbuf[1024]; const char *key_in; const char *pass_in = NULL; const char *key2_in = NULL; EC_KEY *pkey; int parameter_group = -1; int privtype, addrtype; int pkcs8 = 0; int pass_prompt = 0; int verbose = 0; int generate = 0; int opt; int res; while ((opt = getopt(argc, argv, "8E:ec:vG")) != -1) { switch (opt) { case '8': pkcs8 = 1; break; case 'E': if (pass_prompt) { usage(argv[0]); return 1; } pass_in = optarg; if (!vg_check_password_complexity(pass_in, 1)) fprintf(stderr, "WARNING: Using weak password\n"); break; case 'e': if (pass_in) { usage(argv[0]); return 1; } pass_prompt = 1; break; case 'c': key2_in = optarg; break; case 'v': verbose = 1; break; case 'G': generate = 1; break; default: usage(argv[0]); return 1; } } OpenSSL_add_all_algorithms(); pkey = EC_KEY_new_by_curve_name(NID_secp256k1); if (generate) { unsigned char *pend = (unsigned char *) pbuf; addrtype = 0; privtype = 128; EC_KEY_generate_key(pkey); res = i2o_ECPublicKey(pkey, &pend); fprintf(stderr, "Pubkey (hex): "); dumphex((unsigned char *)pbuf, res); fprintf(stderr, "Privkey (hex): "); dumpbn(EC_KEY_get0_private_key(pkey)); vg_encode_address(EC_KEY_get0_public_key(pkey), EC_KEY_get0_group(pkey), addrtype, ecprot); printf("Address: %s\n", ecprot); vg_encode_privkey(pkey, privtype, ecprot); printf("Privkey: %s\n", ecprot); return 0; } if (optind >= argc) { res = fread(pbuf, 1, sizeof(pbuf) - 1, stdin); pbuf[res] = '\0'; key_in = pbuf; } else { key_in = argv[optind]; } res = vg_decode_privkey_any(pkey, &privtype, key_in, NULL); if (res < 0) { if (EVP_read_pw_string(pwbuf, sizeof(pwbuf), "Enter import password:", 0) || !vg_decode_privkey_any(pkey, &privtype, key_in, pwbuf)) return 1; } if (!res) { fprintf(stderr, "ERROR: Unrecognized key format\n"); return 1; } if (key2_in) { BN_CTX *bnctx; BIGNUM bntmp, bntmp2; EC_KEY *pkey2; pkey2 = EC_KEY_new_by_curve_name(NID_secp256k1); res = vg_decode_privkey_any(pkey2, &privtype, key2_in, NULL); if (res < 0) { if (EVP_read_pw_string(pwbuf, sizeof(pwbuf), "Enter import password:", 0) || !vg_decode_privkey_any(pkey2, &privtype, key2_in, pwbuf)) return 1; } if (!res) { fprintf(stderr, "ERROR: Unrecognized key format\n"); return 1; } BN_init(&bntmp); BN_init(&bntmp2); bnctx = BN_CTX_new(); EC_GROUP_get_order(EC_KEY_get0_group(pkey), &bntmp2, NULL); BN_mod_add(&bntmp, EC_KEY_get0_private_key(pkey), EC_KEY_get0_private_key(pkey2), &bntmp2, bnctx); vg_set_privkey(&bntmp, pkey); EC_KEY_free(pkey2); BN_clear_free(&bntmp); BN_clear_free(&bntmp2); BN_CTX_free(bnctx); } if (pass_prompt) { res = EVP_read_pw_string(pwbuf, sizeof(pwbuf), "Enter password:", 1); if (res) return 1; pass_in = pwbuf; if (!vg_check_password_complexity(pwbuf, 1)) fprintf(stderr, "WARNING: Using weak password\n"); } switch (privtype) { case 128: addrtype = 0; break; case 239: addrtype = 111; break; default: addrtype = 0; break; } if (verbose) { unsigned char *pend = (unsigned char *) pbuf; res = i2o_ECPublicKey(pkey, &pend); fprintf(stderr, "Pubkey (hex): "); dumphex((unsigned char *)pbuf, res); fprintf(stderr, "Privkey (hex): "); dumpbn(EC_KEY_get0_private_key(pkey)); } if (pkcs8) { res = vg_pkcs8_encode_privkey(pbuf, sizeof(pbuf), pkey, pass_in); if (!res) { fprintf(stderr, "ERROR: Could not encode private key\n"); return 1; } printf("%s", pbuf); } else if (pass_in) { res = vg_protect_encode_privkey(ecprot, pkey, privtype, parameter_group, pass_in); if (!res) { fprintf(stderr, "ERROR: could not password-protect " "private key\n"); return 1; } vg_encode_address(EC_KEY_get0_public_key(pkey), EC_KEY_get0_group(pkey), addrtype, pwbuf); printf("Address: %s\n", pwbuf); printf("Protkey: %s\n", ecprot); } else { vg_encode_address(EC_KEY_get0_public_key(pkey), EC_KEY_get0_group(pkey), addrtype, ecprot); printf("Address: %s\n", ecprot); vg_encode_privkey(pkey, privtype, ecprot); printf("Privkey: %s\n", ecprot); } OPENSSL_cleanse(pwbuf, sizeof(pwbuf)); EC_KEY_free(pkey); return 0; }