diff --git a/Makefile b/Makefile index d2bd690..cebe1f9 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ LIBS=-lpcre -lcrypto -lm -lpthread CFLAGS=-ggdb -O3 -Wall -OBJS=vanitygen.o oclvanitygen.o pattern.o util.o -PROGS=vanitygen +OBJS=vanitygen.o oclvanitygen.o keyconv.o pattern.o util.o +PROGS=vanitygen keyconv all: $(PROGS) @@ -11,5 +11,8 @@ vanitygen: vanitygen.o pattern.o util.o oclvanitygen: oclvanitygen.o pattern.o util.o $(CC) $^ -o $@ $(CFLAGS) $(LIBS) -lOpenCL +keyconv: keyconv.o util.o + $(CC) $^ -o $@ $(CFLAGS) $(LIBS) + clean: rm -f $(OBJS) $(PROGS) $(TESTS) diff --git a/Makefile.Win32 b/Makefile.Win32 index 59c928d..77b523e 100644 --- a/Makefile.Win32 +++ b/Makefile.Win32 @@ -7,7 +7,7 @@ OPENCL_INCLUDE = /I$(OPENCL_DIR)\include OPENCL_LIBS = $(OPENCL_DIR)\lib\x86\OpenCL.lib CFLAGS = /D_WIN32 /DPTW32_STATIC_LIB /DPCRE_STATIC /I$(OPENSSL_DIR)\include /I$(PTHREADS_DIR) /I$(PCRE_DIR) LIBS = $(OPENSSL_DIR)\lib\libeay32.lib $(PTHREADS_DIR)\pthreadVC2.lib $(PCRE_DIR)\pcre.lib ws2_32.lib -OBJS = vanitygen.obj oclvanitygen.obj pattern.obj util.obj winglue.obj +OBJS = vanitygen.obj oclvanitygen.obj keyconv.obj pattern.obj util.obj winglue.obj all: vanitygen.exe @@ -17,6 +17,9 @@ vanitygen.exe: vanitygen.obj pattern.obj util.obj winglue.obj oclvanitygen.exe: oclvanitygen.obj pattern.obj util.obj winglue.obj link /nologo /out:$@ $** $(LIBS) $(OPENCL_LIBS) +keyconv.exe: keyconv.obj util.obj winglue.obj + link /nologo /out:$@ $** $(LIBS) $(OPENCL_LIBS) + .c.obj: @$(CC) /nologo $(CFLAGS) /c /Tp$< /Fo$@ diff --git a/Makefile.osx b/Makefile.osx index 6ddbee5..31bcc82 100644 --- a/Makefile.osx +++ b/Makefile.osx @@ -1,7 +1,7 @@ LIBS=-lpcre -lcrypto -lm -lpthread CFLAGS=-ggdb -O3 -Wall -OBJS=vanitygen.o oclvanitygen.o pattern.o util.o -PROGS=vanitygen +OBJS=vanitygen.o oclvanitygen.o keyconv.o pattern.o util.o +PROGS=vanitygen keyconv TESTS= all: $(PROGS) @@ -12,5 +12,8 @@ vanitygen: vanitygen.o pattern.o util.o oclvanitygen: oclvanitygen.o pattern.o util.o $(CC) $^ -o $@ $(CFLAGS) $(LIBS) -framework OpenCL +keyconv: keyconv.o util.o + $(CC) $^ -o $@ $(CFLAGS) $(LIBS) + clean: rm -f $(OBJS) $(PROGS) $(TESTS) diff --git a/keyconv.c b/keyconv.c new file mode 100644 index 0000000..fecda35 --- /dev/null +++ b/keyconv.c @@ -0,0 +1,157 @@ +#include +#include +#include +#include + +#include +#include +#include +#include + +#if !defined(_WIN32) +#include +#else +#include "winglue.h" +#endif + +#include "util.h" + +const char *version = "0.17"; + + +static void +usage(const char *progname) +{ + fprintf(stderr, +"Vanitygen keyconv %s\n" +"Usage: %s [-8] [-e|-E ] []\n" +"-8 Output key in PKCS#8 form\n" +"-e Encrypt output key, prompt for password\n" +"-E Encrypt output key with (UNSAFE)\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; + EC_KEY *pkey; + int parameter_group = -1; + int privtype, addrtype; + int pkcs8 = 0; + int pass_prompt = 0; + int opt; + int res; + + while ((opt = getopt(argc, argv, "8E:e")) != -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; + default: + usage(argv[0]); + return 1; + } + } + + if (optind >= argc) { + res = fread(pbuf, 1, sizeof(pbuf) - 1, stdin); + pbuf[res] = '\0'; + key_in = pbuf; + } else { + key_in = argv[optind]; + } + + OpenSSL_add_all_algorithms(); + + pkey = EC_KEY_new_by_curve_name(NID_secp256k1); + + 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 (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 (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, pwbuf); + + if (!res) { + fprintf(stderr, "ERROR: could not password-protect " + "private key\n"); + return 1; + } + + vg_encode_address(pkey, addrtype, pwbuf); + printf("Address: %s\n", pwbuf); + printf("Protkey: %s\n", ecprot); + } + + else { + vg_encode_address(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; +}