mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 05:43:48 -07:00
Merge branch 'master' into allin
update 201114
This commit is contained in:
commit
79e1159eaf
56 changed files with 713 additions and 1114 deletions
|
@ -27,7 +27,7 @@ LD = g++
|
||||||
SH = sh
|
SH = sh
|
||||||
BASH = bash
|
BASH = bash
|
||||||
PERL = perl
|
PERL = perl
|
||||||
CCC =foo
|
SWIG = swig
|
||||||
CC_VERSION = $(shell $(CC) -dumpversion 2>/dev/null|sed 's/\..*//')
|
CC_VERSION = $(shell $(CC) -dumpversion 2>/dev/null|sed 's/\..*//')
|
||||||
CC_VERSION := $(or $(strip $(CC_VERSION)),0)
|
CC_VERSION := $(or $(strip $(CC_VERSION)),0)
|
||||||
|
|
||||||
|
|
|
@ -1301,7 +1301,7 @@ void SimulateIso14443aTag(uint8_t tagType, uint8_t flags, uint8_t *data) {
|
||||||
// We need to listen to the high-frequency, peak-detected path.
|
// We need to listen to the high-frequency, peak-detected path.
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN);
|
||||||
|
|
||||||
iso14a_set_timeout(201400); // 106 * 19ms default
|
iso14a_set_timeout(201400); // 106 * 19ms default *100?
|
||||||
|
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
|
@ -2903,9 +2903,11 @@ void ReaderIso14443a(PacketCommandNG *c) {
|
||||||
goto OUT;
|
goto OUT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
uint32_t save_iso14a_timeout = 0;
|
||||||
if ((param & ISO14A_SET_TIMEOUT))
|
if ((param & ISO14A_SET_TIMEOUT)) {
|
||||||
|
save_iso14a_timeout = iso14a_get_timeout();
|
||||||
iso14a_set_timeout(timeout);
|
iso14a_set_timeout(timeout);
|
||||||
|
}
|
||||||
|
|
||||||
if ((param & ISO14A_APDU)) {
|
if ((param & ISO14A_APDU)) {
|
||||||
uint8_t res;
|
uint8_t res;
|
||||||
|
@ -2969,6 +2971,10 @@ void ReaderIso14443a(PacketCommandNG *c) {
|
||||||
if ((param & ISO14A_REQUEST_TRIGGER))
|
if ((param & ISO14A_REQUEST_TRIGGER))
|
||||||
iso14a_set_trigger(false);
|
iso14a_set_trigger(false);
|
||||||
|
|
||||||
|
if ((param & ISO14A_SET_TIMEOUT)) {
|
||||||
|
iso14a_set_timeout(save_iso14a_timeout);
|
||||||
|
}
|
||||||
|
|
||||||
if ((param & ISO14A_NO_DISCONNECT))
|
if ((param & ISO14A_NO_DISCONNECT))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -188,7 +188,6 @@ set (TARGET_SOURCES
|
||||||
${PM3_ROOT}/client/src/emv/crypto.c
|
${PM3_ROOT}/client/src/emv/crypto.c
|
||||||
${PM3_ROOT}/client/src/emv/crypto_polarssl.c
|
${PM3_ROOT}/client/src/emv/crypto_polarssl.c
|
||||||
${PM3_ROOT}/client/src/emv/dol.c
|
${PM3_ROOT}/client/src/emv/dol.c
|
||||||
${PM3_ROOT}/client/src/emv/dump.c
|
|
||||||
${PM3_ROOT}/client/src/emv/emv_pk.c
|
${PM3_ROOT}/client/src/emv/emv_pk.c
|
||||||
${PM3_ROOT}/client/src/emv/emv_pki.c
|
${PM3_ROOT}/client/src/emv/emv_pki.c
|
||||||
${PM3_ROOT}/client/src/emv/emv_pki_priv.c
|
${PM3_ROOT}/client/src/emv/emv_pki_priv.c
|
||||||
|
@ -426,7 +425,7 @@ if (SKIPPYTHON EQUAL 1)
|
||||||
else (SKIPPYTHON EQUAL 1)
|
else (SKIPPYTHON EQUAL 1)
|
||||||
if (PYTHON3EMBED_FOUND)
|
if (PYTHON3EMBED_FOUND)
|
||||||
message(STATUS "Python3 library: Python3 embed found, enabled")
|
message(STATUS "Python3 library: Python3 embed found, enabled")
|
||||||
elseif (PYTHON_FOUND)
|
elseif (PYTHON3_FOUND)
|
||||||
message(STATUS "Python3 library: Python3 found, enabled")
|
message(STATUS "Python3 library: Python3 found, enabled")
|
||||||
else (PYTHON3EMBED_FOUND)
|
else (PYTHON3EMBED_FOUND)
|
||||||
message(STATUS "Python3 library: Python3 not found, disabled")
|
message(STATUS "Python3 library: Python3 not found, disabled")
|
||||||
|
@ -456,6 +455,28 @@ else (SKIPWHEREAMISYSTEM EQUAL 1)
|
||||||
message(STATUS "Whereami library: system library not found, using local library")
|
message(STATUS "Whereami library: system library not found, using local library")
|
||||||
endif (WHEREAMI_FOUND)
|
endif (WHEREAMI_FOUND)
|
||||||
endif (SKIPWHEREAMISYSTEM EQUAL 1)
|
endif (SKIPWHEREAMISYSTEM EQUAL 1)
|
||||||
|
|
||||||
|
# Lua SWIG
|
||||||
|
if (EXISTS ${PM3_ROOT}/client/src/pm3_luawrap.c)
|
||||||
|
set (TARGET_SOURCES
|
||||||
|
${PM3_ROOT}/client/src/pm3_luawrap.c
|
||||||
|
${TARGET_SOURCES})
|
||||||
|
add_definitions(-DHAVE_LUA_SWIG)
|
||||||
|
message(STATUS "Lua SWIG: wrapper found")
|
||||||
|
endif (EXISTS ${PM3_ROOT}/client/src/pm3_luawrap.c)
|
||||||
|
|
||||||
|
# Python SWIG
|
||||||
|
if (NOT SKIPPYTHON EQUAL 1)
|
||||||
|
if (PYTHON3EMBED_FOUND OR PYTHON3_FOUND)
|
||||||
|
if (EXISTS ${PM3_ROOT}/client/src/pm3_pywrap.c)
|
||||||
|
set (TARGET_SOURCES
|
||||||
|
${PM3_ROOT}/client/src/pm3_pywrap.c
|
||||||
|
${TARGET_SOURCES})
|
||||||
|
add_definitions(-DHAVE_PYTHON_SWIG)
|
||||||
|
message(STATUS "Python SWIG: wrapper found")
|
||||||
|
endif (EXISTS ${PM3_ROOT}/client/src/pm3_pywrap.c)
|
||||||
|
endif (PYTHON3EMBED_FOUND OR PYTHON3_FOUND)
|
||||||
|
endif (NOT SKIPPYTHON EQUAL 1)
|
||||||
message(STATUS "===================================================================")
|
message(STATUS "===================================================================")
|
||||||
|
|
||||||
add_executable(proxmark3
|
add_executable(proxmark3
|
||||||
|
|
|
@ -285,6 +285,19 @@ ifneq ($(SKIPREADLINE),1)
|
||||||
READLINE_FOUND = 1
|
READLINE_FOUND = 1
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
########
|
||||||
|
# SWIG #
|
||||||
|
########
|
||||||
|
|
||||||
|
ifneq ("$(wildcard src/pm3_luawrap.c)","")
|
||||||
|
SWIG_LUA_FOUND = 1
|
||||||
|
endif
|
||||||
|
ifeq ($(PYTHON_FOUND),1)
|
||||||
|
ifneq ("$(wildcard src/pm3_pywrap.c)","")
|
||||||
|
SWIG_PYTHON_FOUND = 1
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
#######################################################################################################
|
#######################################################################################################
|
||||||
CFLAGS ?= $(DEFCFLAGS)
|
CFLAGS ?= $(DEFCFLAGS)
|
||||||
# We cannot just use CFLAGS+=... because it has impact on sub-makes if CFLAGS is defined in env:
|
# We cannot just use CFLAGS+=... because it has impact on sub-makes if CFLAGS is defined in env:
|
||||||
|
@ -315,6 +328,12 @@ ifeq ($(PYTHON_FOUND),1)
|
||||||
PM3CFLAGS += -DHAVE_PYTHON
|
PM3CFLAGS += -DHAVE_PYTHON
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(SWIG_LUA_FOUND),1)
|
||||||
|
PM3CFLAGS += -DHAVE_LUA_SWIG
|
||||||
|
endif
|
||||||
|
ifeq ($(SWIG_PYTHON_FOUND),1)
|
||||||
|
PM3CFLAGS += -DHAVE_PYTHON_SWIG
|
||||||
|
endif
|
||||||
|
|
||||||
CXXFLAGS ?= -Wall -Werror -O3
|
CXXFLAGS ?= -Wall -Werror -O3
|
||||||
PM3CXXFLAGS = $(CXXFLAGS)
|
PM3CXXFLAGS = $(CXXFLAGS)
|
||||||
|
@ -414,6 +433,13 @@ else
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(SWIG_LUA_FOUND),1)
|
||||||
|
$(info Lua SWIG: wrapper found)
|
||||||
|
endif
|
||||||
|
ifeq ($(SWIG_PYTHON_FOUND),1)
|
||||||
|
$(info Python SWIG: wrapper found)
|
||||||
|
endif
|
||||||
|
|
||||||
$(info compiler version: $(shell $(CC) --version|head -n 1))
|
$(info compiler version: $(shell $(CC) --version|head -n 1))
|
||||||
$(info ===================================================================)
|
$(info ===================================================================)
|
||||||
|
|
||||||
|
@ -506,7 +532,6 @@ SRCS = aiddesfire.c \
|
||||||
emv/crypto.c\
|
emv/crypto.c\
|
||||||
emv/crypto_polarssl.c\
|
emv/crypto_polarssl.c\
|
||||||
emv/dol.c \
|
emv/dol.c \
|
||||||
emv/dump.c \
|
|
||||||
emv/emv_pk.c\
|
emv/emv_pk.c\
|
||||||
emv/emv_pki.c\
|
emv/emv_pki.c\
|
||||||
emv/emv_pki_priv.c\
|
emv/emv_pki_priv.c\
|
||||||
|
@ -573,6 +598,16 @@ SRCS += bucketsort.c \
|
||||||
parity.c \
|
parity.c \
|
||||||
util_posix.c
|
util_posix.c
|
||||||
|
|
||||||
|
# swig
|
||||||
|
|
||||||
|
SWIGSRCS =
|
||||||
|
ifeq ($(SWIG_LUA_FOUND),1)
|
||||||
|
SWIGSRCS += pm3_luawrap.c
|
||||||
|
endif
|
||||||
|
ifeq ($(SWIG_PYTHON_FOUND),1)
|
||||||
|
SWIGSRCS += pm3_pywrap.c
|
||||||
|
endif
|
||||||
|
|
||||||
# gui
|
# gui
|
||||||
ifeq ($(QT_FOUND),1)
|
ifeq ($(QT_FOUND),1)
|
||||||
CXXSRCS = proxgui.cpp proxguiqt.cpp proxguiqt.moc.cpp
|
CXXSRCS = proxgui.cpp proxguiqt.cpp proxguiqt.moc.cpp
|
||||||
|
@ -586,6 +621,7 @@ ifeq ($(platform),Darwin)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
OBJS = $(SRCS:%.c=$(OBJDIR)/%.o)
|
OBJS = $(SRCS:%.c=$(OBJDIR)/%.o)
|
||||||
|
OBJS += $(SWIGSRCS:%.c=$(OBJDIR)/%.o)
|
||||||
OBJS += $(CXXSRCS:%.cpp=$(OBJDIR)/%.o)
|
OBJS += $(CXXSRCS:%.cpp=$(OBJDIR)/%.o)
|
||||||
OBJS += $(OBJCSRCS:%.m=$(OBJDIR)/%.o)
|
OBJS += $(OBJCSRCS:%.m=$(OBJDIR)/%.o)
|
||||||
|
|
||||||
|
@ -650,6 +686,7 @@ endif
|
||||||
ifneq (,$(INSTALLSHARE))
|
ifneq (,$(INSTALLSHARE))
|
||||||
$(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH)
|
$(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH)
|
||||||
$(Q)$(CP) $(INSTALLSHARE) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH)
|
$(Q)$(CP) $(INSTALLSHARE) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH)
|
||||||
|
$(Q)$(CP) src/pm3.py $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH)/pyscripts
|
||||||
endif
|
endif
|
||||||
@true
|
@true
|
||||||
|
|
||||||
|
@ -712,6 +749,18 @@ ifneq ($(WHEREAMI_FOUND),1)
|
||||||
$(Q)$(MAKE) --no-print-directory -C $(WHEREAMILIBPATH) all
|
$(Q)$(MAKE) --no-print-directory -C $(WHEREAMILIBPATH) all
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
########
|
||||||
|
# SWIG #
|
||||||
|
########
|
||||||
|
|
||||||
|
src/pm3_luawrap.c: pm3.i
|
||||||
|
$(info [=] GEN $@)
|
||||||
|
$(Q)$(SWIG) -lua -o $@ $<
|
||||||
|
|
||||||
|
src/pm3_pywrap.c: pm3.i
|
||||||
|
$(info [=] GEN $@)
|
||||||
|
$(Q)$(SWIG) -python -o $@ $<
|
||||||
|
|
||||||
########
|
########
|
||||||
# misc #
|
# misc #
|
||||||
########
|
########
|
||||||
|
@ -726,6 +775,14 @@ src/version.c: default_version.c
|
||||||
# easy printing of MAKE VARIABLES
|
# easy printing of MAKE VARIABLES
|
||||||
print-%: ; @echo $* = $($*)
|
print-%: ; @echo $* = $($*)
|
||||||
|
|
||||||
|
# SWIG files emit a number of warnings, we've to ignore them
|
||||||
|
%wrap.o: %wrap.c
|
||||||
|
$(OBJDIR)/%wrap.o : %wrap.c $(OBJDIR)/%.d
|
||||||
|
$(info [-] CC $<)
|
||||||
|
$(Q)$(MKDIR) $(dir $@)
|
||||||
|
$(Q)$(CC) $(DEPFLAGS) $(PM3CFLAGS) -Wno-missing-prototypes -Wno-missing-declarations -Wno-missing-field-initializers -c -o $@ $<
|
||||||
|
$(Q)$(POSTCOMPILE)
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(OBJDIR)/%.o : %.c $(OBJDIR)/%.d
|
$(OBJDIR)/%.o : %.c $(OBJDIR)/%.d
|
||||||
$(info [-] CC $<)
|
$(info [-] CC $<)
|
||||||
|
@ -748,6 +805,7 @@ $(OBJDIR)/%.o : %.m $(OBJDIR)/%.d
|
||||||
$(Q)$(POSTCOMPILE)
|
$(Q)$(POSTCOMPILE)
|
||||||
|
|
||||||
DEPENDENCY_FILES = $(patsubst %.c, $(OBJDIR)/%.d, $(SRCS)) \
|
DEPENDENCY_FILES = $(patsubst %.c, $(OBJDIR)/%.d, $(SRCS)) \
|
||||||
|
$(patsubst %wrap.c, $(OBJDIR)/%.d, $(SWIGSRCS)) \
|
||||||
$(patsubst %.cpp, $(OBJDIR)/%.d, $(CXXSRCS)) \
|
$(patsubst %.cpp, $(OBJDIR)/%.d, $(CXXSRCS)) \
|
||||||
$(patsubst %.m, $(OBJDIR)/%.d, $(OBJCSRCS))
|
$(patsubst %.m, $(OBJDIR)/%.d, $(OBJCSRCS))
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,6 @@ add_library(pm3rrg_rdv4 SHARED
|
||||||
${PM3_ROOT}/client/src/emv/crypto.c
|
${PM3_ROOT}/client/src/emv/crypto.c
|
||||||
${PM3_ROOT}/client/src/emv/crypto_polarssl.c
|
${PM3_ROOT}/client/src/emv/crypto_polarssl.c
|
||||||
${PM3_ROOT}/client/src/emv/dol.c
|
${PM3_ROOT}/client/src/emv/dol.c
|
||||||
${PM3_ROOT}/client/src/emv/dump.c
|
|
||||||
${PM3_ROOT}/client/src/emv/emv_pk.c
|
${PM3_ROOT}/client/src/emv/emv_pk.c
|
||||||
${PM3_ROOT}/client/src/emv/emv_pki.c
|
${PM3_ROOT}/client/src/emv/emv_pki.c
|
||||||
${PM3_ROOT}/client/src/emv/emv_pki_priv.c
|
${PM3_ROOT}/client/src/emv/emv_pki_priv.c
|
||||||
|
|
|
@ -35,8 +35,7 @@
|
||||||
int CLIParserInit(CLIParserContext **ctx, const char *vprogramName, const char *vprogramHint, const char *vprogramHelp) {
|
int CLIParserInit(CLIParserContext **ctx, const char *vprogramName, const char *vprogramHint, const char *vprogramHelp) {
|
||||||
*ctx = malloc(sizeof(CLIParserContext));
|
*ctx = malloc(sizeof(CLIParserContext));
|
||||||
if (!*ctx) {
|
if (!*ctx) {
|
||||||
printf("ERROR: Insufficient memory\n");
|
PrintAndLogEx(ERR, "ERROR: Insufficient memory\n");
|
||||||
fflush(stdout);
|
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
(*ctx)->argtable = NULL;
|
(*ctx)->argtable = NULL;
|
||||||
|
@ -220,16 +219,15 @@ int CLIParamHexToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int
|
||||||
res = param_gethex_to_eol((char *)tmpstr, 0, data, maxdatalen, datalen);
|
res = param_gethex_to_eol((char *)tmpstr, 0, data, maxdatalen, datalen);
|
||||||
switch (res) {
|
switch (res) {
|
||||||
case 1:
|
case 1:
|
||||||
printf("Parameter error: Invalid HEX value\n");
|
PrintAndLogEx(ERR, "Parameter error: Invalid HEX value\n");
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
printf("Parameter error: parameter too large\n");
|
PrintAndLogEx(ERR, "Parameter error: parameter too large\n");
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
printf("Parameter error: Hex string must have EVEN number of digits\n");
|
PrintAndLogEx(ERR, "Parameter error: Hex string must have EVEN number of digits\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fflush(stdout);
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,8 +244,7 @@ int CLIParamStrToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int
|
||||||
int len = strlen(argstr->sval[i]);
|
int len = strlen(argstr->sval[i]);
|
||||||
|
|
||||||
if (len > ((sizeof(tmpstr) / 2) - ibuf)) {
|
if (len > ((sizeof(tmpstr) / 2) - ibuf)) {
|
||||||
printf("Parameter error: string too long (%i chars), expect MAX %zu chars\n", len + ibuf, (sizeof(tmpstr) / 2));
|
PrintAndLogEx(ERR, "Parameter error: string too long (%i chars), expect MAX %zu chars\n", len + ibuf, (sizeof(tmpstr) / 2));
|
||||||
fflush(stdout);
|
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,8 +260,7 @@ int CLIParamStrToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (ibuf > maxdatalen) {
|
if (ibuf > maxdatalen) {
|
||||||
printf("Parameter error: string too long (%i chars), expected MAX %i chars\n", ibuf, maxdatalen);
|
PrintAndLogEx(ERR, "Parameter error: string too long (%i chars), expected MAX %i chars\n", ibuf, maxdatalen);
|
||||||
fflush(stdout);
|
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
build/
|
|
|
@ -1,4 +1,5 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
swig -lua -o ../src/pm3_luawrap.c ../src/pm3.i
|
cd ..
|
||||||
swig -python -o ../src/pm3_pywrap.c ../src/pm3.i
|
make src/pm3_luawrap.c
|
||||||
|
make src/pm3_pywrap.c
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
cd ..
|
||||||
rm -rf build
|
rm -rf build
|
||||||
mkdir build
|
mkdir build
|
||||||
(
|
(
|
||||||
|
@ -7,4 +8,3 @@ mkdir build
|
||||||
cmake ..
|
cmake ..
|
||||||
make -j
|
make -j
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
cd ..
|
||||||
(
|
(
|
||||||
cd build
|
cd build
|
||||||
make -j
|
make -j
|
4
client/experimental_client_with_swig/01make_client_makefile.sh
Executable file
4
client/experimental_client_with_swig/01make_client_makefile.sh
Executable file
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
make -j
|
|
@ -1,3 +1,3 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
build/proxmark3 /dev/ttyACM0 -c "script run testembedded.lua"
|
../../pm3 -c "script run testembedded.lua"
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
#/usr/local/lib/python3/dist-packages/pm3.py
|
../../pm3 -c "script run testembedded.py"
|
||||||
#/usr/lib/python3/dist-packages/pm3.py
|
|
||||||
|
|
||||||
# need access to pm3.py
|
|
||||||
PYTHONPATH=../src build/proxmark3 /dev/ttyACM0 -c "script run testembedded.py"
|
|
||||||
|
|
3
client/experimental_client_with_swig/02b_run_test_py_grabber.sh
Executable file
3
client/experimental_client_with_swig/02b_run_test_py_grabber.sh
Executable file
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
../../pm3 -c "script run testembedded_grab.py" -i
|
|
@ -1,573 +0,0 @@
|
||||||
# Usage:
|
|
||||||
# mkdir build
|
|
||||||
# cd build
|
|
||||||
# cmake .. (see below for options)
|
|
||||||
# make (VERBOSE=1 if needed)
|
|
||||||
#
|
|
||||||
# MINGW:
|
|
||||||
# On ProxSpace 3.4:
|
|
||||||
# cmake -G"MSYS Makefiles" ..
|
|
||||||
# On Proxspace 3.3 or less, you need to install cmake:
|
|
||||||
# pacman -S mingw-w64-x86_64-cmake
|
|
||||||
# /mingw64/bin/cmake -G"MSYS Makefiles" ..
|
|
||||||
#
|
|
||||||
# Android cross-compilation: (ANDROID_ABI=arm64-v8a for a 64b version)
|
|
||||||
# cmake \
|
|
||||||
# -DCMAKE_TOOLCHAIN_FILE=<path-to-your-android-ndk>/build/cmake/android.toolchain.cmake \
|
|
||||||
# -DANDROID_ABI=armeabi-v7a \
|
|
||||||
# -DANDROID_NATIVE_API_LEVEL=android-19 \
|
|
||||||
# -DSKIPBT=1 -DSKIPPYTHON=1 -DSKIPPTHREAD=1 ..
|
|
||||||
|
|
||||||
message(STATUS "CMake ${CMAKE_VERSION}")
|
|
||||||
cmake_minimum_required(VERSION 3.10)
|
|
||||||
project(proxmark3)
|
|
||||||
SET (PM3_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../..)
|
|
||||||
|
|
||||||
if(CMAKE_VERSION VERSION_LESS "3.7.0")
|
|
||||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
find_package(PkgConfig)
|
|
||||||
|
|
||||||
if (NOT SKIPQT EQUAL 1)
|
|
||||||
if(APPLE AND EXISTS /usr/local/opt/qt5)
|
|
||||||
# Homebrew installs Qt5 (up to at least 5.11.0) in
|
|
||||||
# /usr/local/qt5. Ensure that it can be found by CMake
|
|
||||||
# since it is not in the default /usr/local prefix.
|
|
||||||
# Add it to PATHS so that it doesn't override the
|
|
||||||
# CMAKE_PREFIX_PATH environment variable.
|
|
||||||
# QT_FIND_PACKAGE_OPTIONS should be passed to find_package,
|
|
||||||
# e.g. find_package(Qt5Core ${QT_FIND_PACKAGE_OPTIONS})
|
|
||||||
list(APPEND QT_FIND_PACKAGE_OPTIONS PATHS /usr/local/opt/qt5)
|
|
||||||
endif(APPLE AND EXISTS /usr/local/opt/qt5)
|
|
||||||
set(QT_PACKAGELIST
|
|
||||||
Qt5Core
|
|
||||||
Qt5Widgets
|
|
||||||
Qt5Gui
|
|
||||||
)
|
|
||||||
set(Qt5_FOUND ON)
|
|
||||||
foreach(_qt_package IN LISTS QT_PACKAGELIST)
|
|
||||||
find_package(${_qt_package} QUIET ${QT_FIND_PACKAGE_OPTIONS})
|
|
||||||
set(Qt5_LIBRARIES ${${_qt_package}_LIBRARIES} ${Qt5_LIBRARIES})
|
|
||||||
if(NOT ${_qt_package}_FOUND)
|
|
||||||
set(Qt5_FOUND OFF)
|
|
||||||
endif(NOT ${_qt_package}_FOUND)
|
|
||||||
endforeach()
|
|
||||||
endif (NOT SKIPQT EQUAL 1)
|
|
||||||
|
|
||||||
if (NOT SKIPBT EQUAL 1)
|
|
||||||
pkg_search_module(BLUEZ QUIET bluez)
|
|
||||||
endif (NOT SKIPBT EQUAL 1)
|
|
||||||
|
|
||||||
if (NOT SKIPPYTHON EQUAL 1)
|
|
||||||
pkg_search_module(PYTHON3 QUIET python3)
|
|
||||||
pkg_search_module(PYTHON3EMBED QUIET python3-embed)
|
|
||||||
endif (NOT SKIPPYTHON EQUAL 1)
|
|
||||||
|
|
||||||
# If cross-compiled, we need to init source and build.
|
|
||||||
if (CMAKE_TOOLCHAIN_FILE)
|
|
||||||
set(CFLAGS_EXTERNAL_LIB "CFLAGS=--target=${CMAKE_C_COMPILER_TARGET} -w")
|
|
||||||
set(EMBED_READLINE ON)
|
|
||||||
set(EMBED_BZIP2 ON)
|
|
||||||
endif (CMAKE_TOOLCHAIN_FILE)
|
|
||||||
|
|
||||||
if (EMBED_READLINE OR EMBED_BZIP2)
|
|
||||||
include(ExternalProject)
|
|
||||||
endif (EMBED_READLINE OR EMBED_BZIP2)
|
|
||||||
|
|
||||||
if (NOT SKIPREADLINE EQUAL 1)
|
|
||||||
if (APPLE)
|
|
||||||
find_path(READLINE_INCLUDE_DIRS readline/readline.h /usr/local/opt/readline/include /opt/local/include /opt/include /usr/local/include /usr/include NO_DEFAULT_PATH)
|
|
||||||
find_library(READLINE_LIBRARIES readline /usr/local/opt/readline/lib /opt/local/lib /opt/lib /usr/local/lib /usr/lib NO_DEFAULT_PATH)
|
|
||||||
endif (APPLE)
|
|
||||||
if (EMBED_READLINE)
|
|
||||||
ExternalProject_Add(ncurses
|
|
||||||
URL http://ftp.gnu.org/pub/gnu/ncurses/ncurses-6.0.tar.gz
|
|
||||||
PREFIX deps/ncurses
|
|
||||||
DOWNLOAD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/ncurses
|
|
||||||
CONFIGURE_COMMAND ./configure CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} LD=${CMAKE_C_COMPILER} AR=${CMAKE_AR} RANLIB=${CMAKE_RANLIB} ${CFLAGS_EXTERNAL_LIB} --host=arm --disable-database --with-fallbacks=ansi-generic,ansi-mini,color_xterm,dtterm,dumb,Eterm,Eterm-256color,Eterm-88color,eterm-color,gnome,gnome-256color,guru,hurd,iTerm.app,konsole,konsole-16color,konsole-256color,konsole-base,konsole-linux,konsole-solaris,konsole-vt100,kterm,kterm-color,linux,linux-16color,linux-basic,mac,mlterm,mlterm-256color,mrxvt,mrxvt-256color,mterm,mterm-ansi,mvterm,nsterm,nsterm-16color,nsterm-256color,pty,putty,putty-256color,putty-vt100,rxvt,rxvt-16color,rxvt-256color,rxvt-88color,rxvt-basic,rxvt-color,screen,screen-16color,screen-256color,simpleterm,st-16color,st-256color,st52,st52-color,stv52,tt,tt52,unknown,vt100,vt102,vte,vte-256color,xterm,xterm-16color,xterm-256color,xterm-88color,xterm-basic,xterm-bold,xterm-color,xterm-utf8,xterm-vt220,xterm-vt52,xterm1,xtermc,xtermm --enable-termcap --without-ada --without-debug --without-dlsym --without-gpm --without-develop --without-tests --without-cxx-binding --with-termlib
|
|
||||||
BUILD_IN_SOURCE ON
|
|
||||||
BUILD_COMMAND make libs
|
|
||||||
INSTALL_COMMAND ""
|
|
||||||
LOG_DOWNLOAD ON
|
|
||||||
)
|
|
||||||
ExternalProject_Add_StepTargets(ncurses configure build install)
|
|
||||||
|
|
||||||
ExternalProject_Add(readline
|
|
||||||
URL ftp://ftp.gnu.org/gnu/readline/readline-7.0.tar.gz
|
|
||||||
PREFIX deps/readline
|
|
||||||
DOWNLOAD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/readline
|
|
||||||
CONFIGURE_COMMAND ./configure CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} LD=${CMAKE_C_COMPILER} AR=${CMAKE_AR} RANLIB=${CMAKE_RANLIB} ${CFLAGS_EXTERNAL_LIB} --host=arm --enable-static
|
|
||||||
BUILD_IN_SOURCE ON
|
|
||||||
BUILD_COMMAND make
|
|
||||||
INSTALL_COMMAND ""
|
|
||||||
LOG_DOWNLOAD ON
|
|
||||||
)
|
|
||||||
ExternalProject_Add_StepTargets(readline configure build install)
|
|
||||||
set(READLINE_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR}/deps/readline/src/)
|
|
||||||
set(READLINE_LIBRARIES ${CMAKE_CURRENT_BINARY_DIR}/deps/readline/src/readline/libreadline.a ${CMAKE_CURRENT_BINARY_DIR}/deps/ncurses/src/ncurses/lib/libtinfo.a)
|
|
||||||
else (EMBED_READLINE)
|
|
||||||
find_path(READLINE_INCLUDE_DIRS readline/readline.h)
|
|
||||||
find_library(READLINE_LIBRARIES readline)
|
|
||||||
endif (EMBED_READLINE)
|
|
||||||
if (READLINE_INCLUDE_DIRS AND READLINE_LIBRARIES)
|
|
||||||
set(READLINE_FOUND ON)
|
|
||||||
endif (READLINE_INCLUDE_DIRS AND READLINE_LIBRARIES)
|
|
||||||
endif (NOT SKIPREADLINE EQUAL 1)
|
|
||||||
|
|
||||||
if (NOT SKIPJANSSONSYSTEM EQUAL 1)
|
|
||||||
pkg_check_modules(PC_JANSSON QUIET jansson)
|
|
||||||
find_path(JANSSON_INCLUDE_DIRS
|
|
||||||
NAMES jansson.h
|
|
||||||
HINTS ${PC_JANSSON_INCLUDEDIR} ${PC_JANSSON_INCLUDE_DIRS})
|
|
||||||
find_library(JANSSON_LIBRARIES
|
|
||||||
NAMES jansson libjansson
|
|
||||||
HINTS ${PC_JANSSON_LIBDIR} ${PC_JANSSON_LIBRARY_DIRS})
|
|
||||||
if (JANSSON_INCLUDE_DIRS AND JANSSON_LIBRARIES)
|
|
||||||
set(JANSSON_FOUND ON)
|
|
||||||
endif (JANSSON_INCLUDE_DIRS AND JANSSON_LIBRARIES)
|
|
||||||
endif (NOT SKIPJANSSONSYSTEM EQUAL 1)
|
|
||||||
|
|
||||||
if(EMBED_BZIP2)
|
|
||||||
set(BZIP2_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/deps/bzip2/src/bzip2)
|
|
||||||
ExternalProject_Add(bzip2
|
|
||||||
GIT_REPOSITORY https://android.googlesource.com/platform/external/bzip2
|
|
||||||
GIT_TAG platform-tools-30.0.2
|
|
||||||
PREFIX deps/bzip2
|
|
||||||
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/bzip2
|
|
||||||
CONFIGURE_COMMAND mkdir -p ${BZIP2_BUILD_DIR} && git archive --format tar HEAD | tar -C ${BZIP2_BUILD_DIR} -x
|
|
||||||
BUILD_IN_SOURCE ON
|
|
||||||
BUILD_COMMAND make -C ${BZIP2_BUILD_DIR} -j4 CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} LD=${CMAKE_C_COMPILER} AR=${CMAKE_AR} RANLIB=${CMAKE_RANLIB} ${CFLAGS_EXTERNAL_LIB} libbz2.a
|
|
||||||
INSTALL_COMMAND ""
|
|
||||||
LOG_DOWNLOAD ON
|
|
||||||
)
|
|
||||||
ExternalProject_Add_StepTargets(bzip2 configure build install)
|
|
||||||
set(BZIP2_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR}/deps/bzip2/src/bzip2)
|
|
||||||
set(BZIP2_LIBRARIES ${CMAKE_CURRENT_BINARY_DIR}/deps/bzip2/src/bzip2/libbz2.a)
|
|
||||||
set(BZIP2_FOUND ON)
|
|
||||||
else(EMBED_BZIP2)
|
|
||||||
find_package (BZip2 REQUIRED)
|
|
||||||
endif(EMBED_BZIP2)
|
|
||||||
|
|
||||||
if (NOT SKIPWHEREAMISYSTEM EQUAL 1)
|
|
||||||
find_path(WHEREAMI_INCLUDE_DIRS whereami.h)
|
|
||||||
find_library(WHEREAMI_LIBRARIES whereami)
|
|
||||||
if (WHEREAMI_INCLUDE_DIRS AND WHEREAMI_LIBRARIES)
|
|
||||||
set(WHEREAMI_FOUND ON)
|
|
||||||
endif (WHEREAMI_INCLUDE_DIRS AND WHEREAMI_LIBRARIES)
|
|
||||||
endif (NOT SKIPWHEREAMISYSTEM EQUAL 1)
|
|
||||||
|
|
||||||
add_subdirectory(${PM3_ROOT}/client/deps deps)
|
|
||||||
|
|
||||||
set (TARGET_SOURCES
|
|
||||||
${PM3_ROOT}/common/commonutil.c
|
|
||||||
${PM3_ROOT}/common/util_posix.c
|
|
||||||
${PM3_ROOT}/common/parity.c
|
|
||||||
${PM3_ROOT}/common/bucketsort.c
|
|
||||||
${PM3_ROOT}/common/crapto1/crapto1.c
|
|
||||||
${PM3_ROOT}/common/crapto1/crypto1.c
|
|
||||||
${PM3_ROOT}/common/crc.c
|
|
||||||
${PM3_ROOT}/common/crc16.c
|
|
||||||
${PM3_ROOT}/common/crc32.c
|
|
||||||
${PM3_ROOT}/common/crc64.c
|
|
||||||
${PM3_ROOT}/common/lfdemod.c
|
|
||||||
${PM3_ROOT}/common/legic_prng.c
|
|
||||||
${PM3_ROOT}/common/iso15693tools.c
|
|
||||||
${PM3_ROOT}/common/cardhelper.c
|
|
||||||
${PM3_ROOT}/common/generator.c
|
|
||||||
${PM3_ROOT}/client/src/crypto/asn1dump.c
|
|
||||||
${PM3_ROOT}/client/src/crypto/asn1utils.c
|
|
||||||
${PM3_ROOT}/client/src/crypto/libpcrypto.c
|
|
||||||
${PM3_ROOT}/client/src/emv/test/cda_test.c
|
|
||||||
${PM3_ROOT}/client/src/emv/test/crypto_test.c
|
|
||||||
${PM3_ROOT}/client/src/emv/test/cryptotest.c
|
|
||||||
${PM3_ROOT}/client/src/emv/test/dda_test.c
|
|
||||||
${PM3_ROOT}/client/src/emv/test/sda_test.c
|
|
||||||
${PM3_ROOT}/client/src/emv/apduinfo.c
|
|
||||||
${PM3_ROOT}/client/src/emv/cmdemv.c
|
|
||||||
${PM3_ROOT}/client/src/emv/crypto.c
|
|
||||||
${PM3_ROOT}/client/src/emv/crypto_polarssl.c
|
|
||||||
${PM3_ROOT}/client/src/emv/dol.c
|
|
||||||
${PM3_ROOT}/client/src/emv/dump.c
|
|
||||||
${PM3_ROOT}/client/src/emv/emv_pk.c
|
|
||||||
${PM3_ROOT}/client/src/emv/emv_pki.c
|
|
||||||
${PM3_ROOT}/client/src/emv/emv_pki_priv.c
|
|
||||||
${PM3_ROOT}/client/src/emv/emv_roca.c
|
|
||||||
${PM3_ROOT}/client/src/emv/emv_tags.c
|
|
||||||
${PM3_ROOT}/client/src/emv/emvcore.c
|
|
||||||
${PM3_ROOT}/client/src/emv/emvjson.c
|
|
||||||
${PM3_ROOT}/client/src/emv/tlv.c
|
|
||||||
${PM3_ROOT}/client/src/fido/additional_ca.c
|
|
||||||
${PM3_ROOT}/client/src/fido/cbortools.c
|
|
||||||
${PM3_ROOT}/client/src/fido/cose.c
|
|
||||||
${PM3_ROOT}/client/src/fido/fidocore.c
|
|
||||||
${PM3_ROOT}/client/src/loclass/cipher.c
|
|
||||||
${PM3_ROOT}/client/src/loclass/cipherutils.c
|
|
||||||
${PM3_ROOT}/client/src/loclass/elite_crack.c
|
|
||||||
${PM3_ROOT}/client/src/loclass/hash1_brute.c
|
|
||||||
${PM3_ROOT}/client/src/loclass/ikeys.c
|
|
||||||
${PM3_ROOT}/client/src/mifare/mad.c
|
|
||||||
${PM3_ROOT}/client/src/mifare/mfkey.c
|
|
||||||
${PM3_ROOT}/client/src/mifare/mifare4.c
|
|
||||||
${PM3_ROOT}/client/src/mifare/mifaredefault.c
|
|
||||||
${PM3_ROOT}/client/src/mifare/mifarehost.c
|
|
||||||
${PM3_ROOT}/client/src/mifare/ndef.c
|
|
||||||
${PM3_ROOT}/client/src/mifare/desfire_crypto.c
|
|
||||||
${PM3_ROOT}/client/src/uart/uart_posix.c
|
|
||||||
${PM3_ROOT}/client/src/uart/uart_win32.c
|
|
||||||
${PM3_ROOT}/client/src/ui/overlays.ui
|
|
||||||
${PM3_ROOT}/client/src/aiddesfire.c
|
|
||||||
${PM3_ROOT}/client/src/aidsearch.c
|
|
||||||
${PM3_ROOT}/client/src/cmdanalyse.c
|
|
||||||
${PM3_ROOT}/client/src/cmdcrc.c
|
|
||||||
${PM3_ROOT}/client/src/cmddata.c
|
|
||||||
${PM3_ROOT}/client/src/cmdflashmem.c
|
|
||||||
${PM3_ROOT}/client/src/cmdflashmemspiffs.c
|
|
||||||
${PM3_ROOT}/client/src/cmdhf.c
|
|
||||||
${PM3_ROOT}/client/src/cmdhf14a.c
|
|
||||||
${PM3_ROOT}/client/src/cmdhf14b.c
|
|
||||||
${PM3_ROOT}/client/src/cmdhf15.c
|
|
||||||
${PM3_ROOT}/client/src/cmdhfcryptorf.c
|
|
||||||
${PM3_ROOT}/client/src/cmdhfepa.c
|
|
||||||
${PM3_ROOT}/client/src/cmdhffelica.c
|
|
||||||
${PM3_ROOT}/client/src/cmdhffido.c
|
|
||||||
${PM3_ROOT}/client/src/cmdhficlass.c
|
|
||||||
${PM3_ROOT}/client/src/cmdhflegic.c
|
|
||||||
${PM3_ROOT}/client/src/cmdhflist.c
|
|
||||||
${PM3_ROOT}/client/src/cmdhflto.c
|
|
||||||
${PM3_ROOT}/client/src/cmdhfmf.c
|
|
||||||
${PM3_ROOT}/client/src/cmdhfmfdes.c
|
|
||||||
${PM3_ROOT}/client/src/cmdhfmfhard.c
|
|
||||||
${PM3_ROOT}/client/src/cmdhfmfp.c
|
|
||||||
${PM3_ROOT}/client/src/cmdhfmfu.c
|
|
||||||
${PM3_ROOT}/client/src/cmdhfst.c
|
|
||||||
${PM3_ROOT}/client/src/cmdhfthinfilm.c
|
|
||||||
${PM3_ROOT}/client/src/cmdhftopaz.c
|
|
||||||
${PM3_ROOT}/client/src/cmdhfwaveshare.c
|
|
||||||
${PM3_ROOT}/client/src/cmdhw.c
|
|
||||||
${PM3_ROOT}/client/src/cmdlf.c
|
|
||||||
${PM3_ROOT}/client/src/cmdlfawid.c
|
|
||||||
${PM3_ROOT}/client/src/cmdlfcotag.c
|
|
||||||
${PM3_ROOT}/client/src/cmdlfdestron.c
|
|
||||||
${PM3_ROOT}/client/src/cmdlfem4x.c
|
|
||||||
${PM3_ROOT}/client/src/cmdlfem4x05.c
|
|
||||||
${PM3_ROOT}/client/src/cmdlfem4x50.c
|
|
||||||
${PM3_ROOT}/client/src/cmdlffdxb.c
|
|
||||||
${PM3_ROOT}/client/src/cmdlfgallagher.c
|
|
||||||
${PM3_ROOT}/client/src/cmdlfguard.c
|
|
||||||
${PM3_ROOT}/client/src/cmdlfhid.c
|
|
||||||
${PM3_ROOT}/client/src/cmdlfhitag.c
|
|
||||||
${PM3_ROOT}/client/src/cmdlfidteck.c
|
|
||||||
${PM3_ROOT}/client/src/cmdlfindala.c
|
|
||||||
${PM3_ROOT}/client/src/cmdlfio.c
|
|
||||||
${PM3_ROOT}/client/src/cmdlfjablotron.c
|
|
||||||
${PM3_ROOT}/client/src/cmdlfkeri.c
|
|
||||||
${PM3_ROOT}/client/src/cmdlfmotorola.c
|
|
||||||
${PM3_ROOT}/client/src/cmdlfnedap.c
|
|
||||||
${PM3_ROOT}/client/src/cmdlfnexwatch.c
|
|
||||||
${PM3_ROOT}/client/src/cmdlfnoralsy.c
|
|
||||||
${PM3_ROOT}/client/src/cmdlfpac.c
|
|
||||||
${PM3_ROOT}/client/src/cmdlfparadox.c
|
|
||||||
${PM3_ROOT}/client/src/cmdlfpcf7931.c
|
|
||||||
${PM3_ROOT}/client/src/cmdlfpresco.c
|
|
||||||
${PM3_ROOT}/client/src/cmdlfpyramid.c
|
|
||||||
${PM3_ROOT}/client/src/cmdlfsecurakey.c
|
|
||||||
${PM3_ROOT}/client/src/cmdlft55xx.c
|
|
||||||
${PM3_ROOT}/client/src/cmdlfti.c
|
|
||||||
${PM3_ROOT}/client/src/cmdlfviking.c
|
|
||||||
${PM3_ROOT}/client/src/cmdlfvisa2000.c
|
|
||||||
${PM3_ROOT}/client/src/cmdmain.c
|
|
||||||
${PM3_ROOT}/client/src/cmdparser.c
|
|
||||||
${PM3_ROOT}/client/src/cmdscript.c
|
|
||||||
${PM3_ROOT}/client/src/cmdsmartcard.c
|
|
||||||
${PM3_ROOT}/client/src/cmdtrace.c
|
|
||||||
${PM3_ROOT}/client/src/cmdusart.c
|
|
||||||
${PM3_ROOT}/client/src/cmdwiegand.c
|
|
||||||
${PM3_ROOT}/client/src/comms.c
|
|
||||||
${PM3_ROOT}/client/src/fileutils.c
|
|
||||||
${PM3_ROOT}/client/src/flash.c
|
|
||||||
${PM3_ROOT}/client/src/graph.c
|
|
||||||
${PM3_ROOT}/client/src/jansson_path.c
|
|
||||||
${PM3_ROOT}/client/src/preferences.c
|
|
||||||
${PM3_ROOT}/client/src/pm3.c
|
|
||||||
${PM3_ROOT}/client/src/pm3_binlib.c
|
|
||||||
${PM3_ROOT}/client/src/pm3_bitlib.c
|
|
||||||
${PM3_ROOT}/client/src/prng.c
|
|
||||||
${PM3_ROOT}/client/src/scandir.c
|
|
||||||
${PM3_ROOT}/client/src/scripting.c
|
|
||||||
${PM3_ROOT}/client/src/tea.c
|
|
||||||
${PM3_ROOT}/client/src/ui.c
|
|
||||||
${PM3_ROOT}/client/src/util.c
|
|
||||||
${PM3_ROOT}/client/src/wiegand_formats.c
|
|
||||||
${PM3_ROOT}/client/src/wiegand_formatutils.c
|
|
||||||
${CMAKE_BINARY_DIR}/version.c
|
|
||||||
)
|
|
||||||
|
|
||||||
add_custom_command(
|
|
||||||
OUTPUT ${CMAKE_BINARY_DIR}/version.c
|
|
||||||
COMMAND sh ${PM3_ROOT}/tools/mkversion.sh > ${CMAKE_BINARY_DIR}/version.c || perl ${PM3_ROOT}/tools/mkversion.pl > ${CMAKE_BINARY_DIR}/version.c || ${CMAKE_COMMAND} -E copy ${PM3_ROOT}/common/default_version.c ${CMAKE_BINARY_DIR}/version.c
|
|
||||||
DEPENDS ${PM3_ROOT}/common/default_version.c
|
|
||||||
)
|
|
||||||
|
|
||||||
set(ADDITIONAL_SRC "")
|
|
||||||
set(ADDITIONAL_LNK "")
|
|
||||||
set(ADDITIONAL_DIRS "")
|
|
||||||
set(ADDITIONAL_LNKDIRS "")
|
|
||||||
set(X86_CPUS x86 x86_64 i686)
|
|
||||||
|
|
||||||
message(STATUS "CMAKE_SYSTEM_PROCESSOR := ${CMAKE_SYSTEM_PROCESSOR}")
|
|
||||||
|
|
||||||
if (APPLE)
|
|
||||||
message(STATUS "Apple device detected.")
|
|
||||||
set(ADDITIONAL_SRC ${PM3_ROOT}/client/src/util_darwin.h ${PM3_ROOT}/client/src/util_darwin.m ${ADDITIONAL_SRC})
|
|
||||||
set(ADDITIONAL_LNK "-framework Foundation" "-framework AppKit")
|
|
||||||
endif (APPLE)
|
|
||||||
|
|
||||||
if ((NOT SKIPQT EQUAL 1) AND (Qt5_FOUND))
|
|
||||||
set(CMAKE_AUTOMOC ON)
|
|
||||||
set(CMAKE_AUTORCC ON)
|
|
||||||
set(CMAKE_AUTOUIC ON)
|
|
||||||
set (TARGET_SOURCES
|
|
||||||
${PM3_ROOT}/client/src/proxgui.cpp
|
|
||||||
${PM3_ROOT}/client/src/proxguiqt.cpp
|
|
||||||
${TARGET_SOURCES})
|
|
||||||
|
|
||||||
add_definitions("-DHAVE_GUI")
|
|
||||||
set(ADDITIONAL_LNK ${Qt5_LIBRARIES} ${ADDITIONAL_LNK})
|
|
||||||
else ((NOT SKIPQT EQUAL 1) AND (Qt5_FOUND))
|
|
||||||
set(TARGET_SOURCES
|
|
||||||
${PM3_ROOT}/client/src/guidummy.cpp
|
|
||||||
${TARGET_SOURCES})
|
|
||||||
endif ((NOT SKIPQT EQUAL 1) AND (Qt5_FOUND))
|
|
||||||
|
|
||||||
if (NOT SKIPBT EQUAL 1)
|
|
||||||
if (BLUEZ_FOUND)
|
|
||||||
add_definitions("-DHAVE_BLUEZ")
|
|
||||||
set(ADDITIONAL_LNK ${BLUEZ_LIBRARIES} ${ADDITIONAL_LNK})
|
|
||||||
endif (BLUEZ_FOUND)
|
|
||||||
endif(NOT SKIPBT EQUAL 1)
|
|
||||||
|
|
||||||
if (JANSSON_FOUND)
|
|
||||||
set(ADDITIONAL_DIRS ${JANSSON_INCLUDE_DIRS} ${ADDITIONAL_DIRS})
|
|
||||||
set(ADDITIONAL_LNK ${JANSSON_LIBRARIES} ${ADDITIONAL_LNK})
|
|
||||||
endif (JANSSON_FOUND)
|
|
||||||
|
|
||||||
if (NOT SKIPPYTHON EQUAL 1)
|
|
||||||
if (PYTHON3EMBED_FOUND)
|
|
||||||
add_definitions(-DHAVE_PYTHON)
|
|
||||||
set(ADDITIONAL_DIRS ${PYTHON3EMBED_INCLUDE_DIRS} ${ADDITIONAL_DIRS})
|
|
||||||
set(ADDITIONAL_LNK ${PYTHON3EMBED_LIBRARIES} ${ADDITIONAL_LNK})
|
|
||||||
set(ADDITIONAL_LNKDIRS ${PYTHON3EMBED_LIBRARY_DIRS} ${ADDITIONAL_LNKDIRS})
|
|
||||||
elseif (PYTHON3_FOUND)
|
|
||||||
add_definitions(-DHAVE_PYTHON)
|
|
||||||
set(ADDITIONAL_DIRS ${PYTHON3_INCLUDE_DIRS} ${ADDITIONAL_DIRS})
|
|
||||||
set(ADDITIONAL_LNK ${PYTHON3_LIBRARIES} ${ADDITIONAL_LNK})
|
|
||||||
set(ADDITIONAL_LNKDIRS ${PYTHON3_LIBRARY_DIRS} ${ADDITIONAL_LNKDIRS})
|
|
||||||
endif (PYTHON3EMBED_FOUND)
|
|
||||||
endif (NOT SKIPPYTHON EQUAL 1)
|
|
||||||
|
|
||||||
if (NOT SKIPREADLINE EQUAL 1)
|
|
||||||
if (READLINE_FOUND)
|
|
||||||
add_definitions("-DHAVE_READLINE")
|
|
||||||
set(ADDITIONAL_DIRS ${READLINE_INCLUDE_DIRS} ${ADDITIONAL_DIRS})
|
|
||||||
set(ADDITIONAL_LNK ${READLINE_LIBRARIES} ${ADDITIONAL_LNK})
|
|
||||||
endif (READLINE_FOUND)
|
|
||||||
endif(NOT SKIPREADLINE EQUAL 1)
|
|
||||||
|
|
||||||
if (BZIP2_FOUND)
|
|
||||||
set(ADDITIONAL_DIRS ${BZIP2_INCLUDE_DIRS} ${ADDITIONAL_DIRS})
|
|
||||||
set(ADDITIONAL_LNK ${BZIP2_LIBRARIES} ${ADDITIONAL_LNK})
|
|
||||||
endif (BZIP2_FOUND)
|
|
||||||
|
|
||||||
if (WHEREAMI_FOUND)
|
|
||||||
set(ADDITIONAL_DIRS ${WHEREAMI_INCLUDE_DIRS} ${ADDITIONAL_DIRS})
|
|
||||||
set(ADDITIONAL_LNK ${WHEREAMI_LIBRARIES} ${ADDITIONAL_LNK})
|
|
||||||
endif (WHEREAMI_FOUND)
|
|
||||||
|
|
||||||
message(STATUS "===================================================================")
|
|
||||||
if (SKIPQT EQUAL 1)
|
|
||||||
message(STATUS "GUI support: skipped")
|
|
||||||
else (SKIPQT EQUAL 1)
|
|
||||||
if (Qt5_FOUND)
|
|
||||||
message(STATUS "GUI support: QT5 found, enabled")
|
|
||||||
else (Qt5_FOUND)
|
|
||||||
message(STATUS "GUI support: QT5 not found, disabled")
|
|
||||||
endif (Qt5_FOUND)
|
|
||||||
endif (SKIPQT EQUAL 1)
|
|
||||||
|
|
||||||
if (SKIPBT EQUAL 1)
|
|
||||||
message(STATUS "native BT support: skipped")
|
|
||||||
else (SKIPBT EQUAL 1)
|
|
||||||
if (BLUEZ_FOUND)
|
|
||||||
message(STATUS "native BT support: Bluez found, enabled")
|
|
||||||
else (BLUEZ_FOUND)
|
|
||||||
message(STATUS "native BT support: Bluez not found, disabled")
|
|
||||||
endif (BLUEZ_FOUND)
|
|
||||||
endif(SKIPBT EQUAL 1)
|
|
||||||
|
|
||||||
if (EMBED_BZIP2)
|
|
||||||
message(STATUS "Bzip2 library: embedded")
|
|
||||||
else (EMBED_BZIP2)
|
|
||||||
message(STATUS "Bzip2 library: system library found")
|
|
||||||
endif (EMBED_BZIP2)
|
|
||||||
|
|
||||||
if (SKIPJANSSONSYSTEM EQUAL 1)
|
|
||||||
message(STATUS "Jansson library: local library forced")
|
|
||||||
else (SKIPJANSSONSYSTEM EQUAL 1)
|
|
||||||
if (JANSSON_FOUND)
|
|
||||||
message(STATUS "Jansson library: system library found")
|
|
||||||
else (JANSSON_FOUND)
|
|
||||||
message(STATUS "Jansson library: system library not found, using local library")
|
|
||||||
endif (JANSSON_FOUND)
|
|
||||||
endif (SKIPJANSSONSYSTEM EQUAL 1)
|
|
||||||
|
|
||||||
if (SKIPPYTHON EQUAL 1)
|
|
||||||
message(STATUS "Python3 library: skipped")
|
|
||||||
else (SKIPPYTHON EQUAL 1)
|
|
||||||
if (PYTHON3EMBED_FOUND)
|
|
||||||
message(STATUS "Python3 library: Python3 embed found, enabled")
|
|
||||||
elseif (PYTHON_FOUND)
|
|
||||||
message(STATUS "Python3 library: Python3 found, enabled")
|
|
||||||
else (PYTHON3EMBED_FOUND)
|
|
||||||
message(STATUS "Python3 library: Python3 not found, disabled")
|
|
||||||
endif (PYTHON3EMBED_FOUND)
|
|
||||||
endif(SKIPPYTHON EQUAL 1)
|
|
||||||
|
|
||||||
if (SKIPREADLINE EQUAL 1)
|
|
||||||
message(STATUS "Readline library: skipped")
|
|
||||||
else (SKIPREADLINE EQUAL 1)
|
|
||||||
if (READLINE_FOUND)
|
|
||||||
if (EMBED_READLINE)
|
|
||||||
message(STATUS "Readline library: embedded")
|
|
||||||
else (EMBED_READLINE)
|
|
||||||
message(STATUS "Readline library: system library found")
|
|
||||||
endif (EMBED_READLINE)
|
|
||||||
else (READLINE_FOUND)
|
|
||||||
message(STATUS "Readline library: Readline not found, disabled")
|
|
||||||
endif (READLINE_FOUND)
|
|
||||||
endif(SKIPREADLINE EQUAL 1)
|
|
||||||
|
|
||||||
if (SKIPWHEREAMISYSTEM EQUAL 1)
|
|
||||||
message(STATUS "Whereami library: local library forced")
|
|
||||||
else (SKIPWHEREAMISYSTEM EQUAL 1)
|
|
||||||
if (WHEREAMI_FOUND)
|
|
||||||
message(STATUS "Whereami library: system library found")
|
|
||||||
else (WHEREAMI_FOUND)
|
|
||||||
message(STATUS "Whereami library: system library not found, using local library")
|
|
||||||
endif (WHEREAMI_FOUND)
|
|
||||||
endif (SKIPWHEREAMISYSTEM EQUAL 1)
|
|
||||||
message(STATUS "===================================================================")
|
|
||||||
|
|
||||||
# Lua SWIG
|
|
||||||
if (EXISTS ${PM3_ROOT}/client/src/pm3_luawrap.c)
|
|
||||||
set (TARGET_SOURCES
|
|
||||||
${PM3_ROOT}/client/src/pm3_luawrap.c
|
|
||||||
${TARGET_SOURCES})
|
|
||||||
add_definitions(-DHAVE_LUA_SWIG)
|
|
||||||
message("Lua SWIG wrapper found")
|
|
||||||
endif (EXISTS ${PM3_ROOT}/client/src/pm3_luawrap.c)
|
|
||||||
|
|
||||||
# Python SWIG
|
|
||||||
if (NOT SKIPPYTHON EQUAL 1)
|
|
||||||
if (PYTHON3EMBED_FOUND OR PYTHON3_FOUND)
|
|
||||||
if (EXISTS ${PM3_ROOT}/client/src/pm3_pywrap.c)
|
|
||||||
set (TARGET_SOURCES
|
|
||||||
${PM3_ROOT}/client/src/pm3_pywrap.c
|
|
||||||
${TARGET_SOURCES})
|
|
||||||
add_definitions(-DHAVE_PYTHON_SWIG)
|
|
||||||
message("Python SWIG wrapper found")
|
|
||||||
endif (EXISTS ${PM3_ROOT}/client/src/pm3_pywrap.c)
|
|
||||||
endif (PYTHON3EMBED_FOUND OR PYTHON3_FOUND)
|
|
||||||
endif (NOT SKIPPYTHON EQUAL 1)
|
|
||||||
|
|
||||||
add_executable(proxmark3
|
|
||||||
${PM3_ROOT}/client/src/proxmark3.c
|
|
||||||
${TARGET_SOURCES}
|
|
||||||
${ADDITIONAL_SRC}
|
|
||||||
)
|
|
||||||
|
|
||||||
target_compile_options(proxmark3 PUBLIC -Wall -Werror -O3)
|
|
||||||
if (EMBED_READLINE)
|
|
||||||
if (NOT SKIPREADLINE EQUAL 1)
|
|
||||||
add_dependencies(proxmark3 ncurses readline)
|
|
||||||
endif (NOT SKIPREADLINE EQUAL 1)
|
|
||||||
endif (EMBED_READLINE)
|
|
||||||
if (EMBED_BZIP2)
|
|
||||||
add_dependencies(proxmark3 bzip2)
|
|
||||||
endif (EMBED_BZIP2)
|
|
||||||
|
|
||||||
if (MINGW)
|
|
||||||
# Mingw uses by default Microsoft printf, we want the GNU printf (e.g. for %z)
|
|
||||||
# and setting _ISOC99_SOURCE sets internally __USE_MINGW_ANSI_STDIO=1
|
|
||||||
# FTR __USE_MINGW_ANSI_STDIO seems deprecated in Mingw32
|
|
||||||
# but not Mingw64 https://fr.osdn.net/projects/mingw/lists/archive/users/2019-January/000199.html
|
|
||||||
target_compile_definitions(proxmark3 PRIVATE _ISOC99_SOURCE)
|
|
||||||
|
|
||||||
set(CMAKE_C_FLAGS "-mno-ms-bitfields -fexec-charset=cp850 ${CMAKE_C_FLAGS}")
|
|
||||||
set(CMAKE_CXX_FLAGS "-mno-ms-bitfields -fexec-charset=cp850 ${CMAKE_CXX_FLAGS}")
|
|
||||||
endif (MINGW)
|
|
||||||
|
|
||||||
target_include_directories(proxmark3 PRIVATE
|
|
||||||
${PM3_ROOT}/common
|
|
||||||
${PM3_ROOT}/common_fpga
|
|
||||||
${PM3_ROOT}/include
|
|
||||||
${PM3_ROOT}/client/src
|
|
||||||
${PM3_ROOT}/client/include
|
|
||||||
${ADDITIONAL_DIRS}
|
|
||||||
)
|
|
||||||
|
|
||||||
if (NOT APPLE)
|
|
||||||
# required for Raspberry Pi, but breaks with clang (OSX). Need to be at the end of the linker line.
|
|
||||||
set(ADDITIONAL_LNK ${ADDITIONAL_LNK} -Wl,--as-needed -latomic -Wl,--no-as-needed)
|
|
||||||
endif (NOT APPLE)
|
|
||||||
|
|
||||||
if (NOT JANSSON_FOUND)
|
|
||||||
set(ADDITIONAL_LNK pm3rrg_rdv4_jansson ${ADDITIONAL_LNK})
|
|
||||||
endif (NOT JANSSON_FOUND)
|
|
||||||
if (NOT WHEREAMI_FOUND)
|
|
||||||
set(ADDITIONAL_LNK pm3rrg_rdv4_whereami ${ADDITIONAL_LNK})
|
|
||||||
endif (NOT WHEREAMI_FOUND)
|
|
||||||
|
|
||||||
target_link_libraries(proxmark3 PRIVATE
|
|
||||||
m
|
|
||||||
pm3rrg_rdv4_mbedtls
|
|
||||||
pm3rrg_rdv4_cliparser
|
|
||||||
pm3rrg_rdv4_lua
|
|
||||||
pm3rrg_rdv4_tinycbor
|
|
||||||
pm3rrg_rdv4_amiibo
|
|
||||||
pm3rrg_rdv4_reveng
|
|
||||||
pm3rrg_rdv4_hardnested
|
|
||||||
${ADDITIONAL_LNK})
|
|
||||||
|
|
||||||
if (NOT SKIPPTHREAD EQUAL 1)
|
|
||||||
target_link_libraries(proxmark3 PRIVATE pthread)
|
|
||||||
endif (NOT SKIPPTHREAD EQUAL 1)
|
|
||||||
|
|
||||||
if (NOT SKIPPYTHON EQUAL 1)
|
|
||||||
# OSX have a hard time compiling python3 dependency with older cmake.
|
|
||||||
if (PYTHON3EMBED_FOUND OR PYTHON3_FOUND)
|
|
||||||
if (NOT CMAKE_VERSION VERSION_LESS 3.13)
|
|
||||||
target_link_directories(proxmark3 PRIVATE ${ADDITIONAL_LNKDIRS})
|
|
||||||
elseif (APPLE)
|
|
||||||
message( SEND_ERROR "Your CMAKE version is too old for Apple platform, please update to a version >=3.13" )
|
|
||||||
endif (NOT CMAKE_VERSION VERSION_LESS 3.13)
|
|
||||||
endif (PYTHON3EMBED_FOUND OR PYTHON3_FOUND)
|
|
||||||
endif (NOT SKIPPYTHON EQUAL 1)
|
|
||||||
|
|
||||||
install(TARGETS proxmark3 DESTINATION "bin")
|
|
||||||
install(DIRECTORY cmdscripts lualibs luascripts pyscripts resources dictionaries DESTINATION "share/proxmark3")
|
|
||||||
|
|
||||||
add_custom_command(OUTPUT lualibs/pm3_cmd.lua
|
|
||||||
COMMAND "awk -f pm3_cmd_h2lua.awk ../include/pm3_cmd.h > lualibs/pm3_cmd.lua"
|
|
||||||
COMMENT "Creating lualibs/pm3_cmd.lua"
|
|
||||||
)
|
|
||||||
|
|
||||||
add_custom_command(OUTPUT lualibs/mfc_default_keys.lua
|
|
||||||
COMMAND "awk -f default_keys_dic2lua.awk mfc_default_keys.dic > lualibs/mfc_default_keys.lua"
|
|
||||||
COMMENT "Creating lualibs/mfc_default_keys.lua"
|
|
||||||
)
|
|
||||||
|
|
||||||
#"make package" will trigger this
|
|
||||||
SET(CPACK_GENERATOR "DEB")
|
|
||||||
SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "Iceman")
|
|
||||||
INCLUDE(CPack)
|
|
78
client/experimental_client_with_swig/output_grabber.py
Executable file
78
client/experimental_client_with_swig/output_grabber.py
Executable file
|
@ -0,0 +1,78 @@
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import threading
|
||||||
|
import time
|
||||||
|
|
||||||
|
# From https://stackoverflow.com/a/29834357
|
||||||
|
class OutputGrabber(object):
|
||||||
|
"""
|
||||||
|
Class used to grab standard output or another stream.
|
||||||
|
"""
|
||||||
|
escape_char = "\b"
|
||||||
|
|
||||||
|
def __init__(self, stream=None, threaded=False):
|
||||||
|
self.origstream = stream
|
||||||
|
self.threaded = threaded
|
||||||
|
if self.origstream is None:
|
||||||
|
self.origstream = sys.stdout
|
||||||
|
self.origstreamfd = self.origstream.fileno()
|
||||||
|
self.capturedtext = ""
|
||||||
|
# Create a pipe so the stream can be captured:
|
||||||
|
self.pipe_out, self.pipe_in = os.pipe()
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
self.start()
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, type, value, traceback):
|
||||||
|
self.stop()
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
"""
|
||||||
|
Start capturing the stream data.
|
||||||
|
"""
|
||||||
|
self.capturedtext = ""
|
||||||
|
# Save a copy of the stream:
|
||||||
|
self.streamfd = os.dup(self.origstreamfd)
|
||||||
|
# Replace the original stream with our write pipe:
|
||||||
|
os.dup2(self.pipe_in, self.origstreamfd)
|
||||||
|
if self.threaded:
|
||||||
|
# Start thread that will read the stream:
|
||||||
|
self.workerThread = threading.Thread(target=self.readOutput)
|
||||||
|
self.workerThread.start()
|
||||||
|
# Make sure that the thread is running and os.read() has executed:
|
||||||
|
time.sleep(0.01)
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
"""
|
||||||
|
Stop capturing the stream data and save the text in `capturedtext`.
|
||||||
|
"""
|
||||||
|
# Print the escape character to make the readOutput method stop:
|
||||||
|
self.origstream.write(self.escape_char)
|
||||||
|
# Flush the stream to make sure all our data goes in before
|
||||||
|
# the escape character:
|
||||||
|
self.origstream.flush()
|
||||||
|
if self.threaded:
|
||||||
|
# wait until the thread finishes so we are sure that
|
||||||
|
# we have until the last character:
|
||||||
|
self.workerThread.join()
|
||||||
|
else:
|
||||||
|
self.readOutput()
|
||||||
|
# Close the pipe:
|
||||||
|
os.close(self.pipe_in)
|
||||||
|
os.close(self.pipe_out)
|
||||||
|
# Restore the original stream:
|
||||||
|
os.dup2(self.streamfd, self.origstreamfd)
|
||||||
|
# Close the duplicate stream:
|
||||||
|
os.close(self.streamfd)
|
||||||
|
|
||||||
|
def readOutput(self):
|
||||||
|
"""
|
||||||
|
Read the stream data (one byte at a time)
|
||||||
|
and save the text in `capturedtext`.
|
||||||
|
"""
|
||||||
|
while True:
|
||||||
|
char = os.read(self.pipe_out,1).decode(self.origstream.encoding)
|
||||||
|
if not char or self.escape_char in char:
|
||||||
|
break
|
||||||
|
self.capturedtext += char
|
13
client/experimental_client_with_swig/testembedded_grab.py
Executable file
13
client/experimental_client_with_swig/testembedded_grab.py
Executable file
|
@ -0,0 +1,13 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import pm3
|
||||||
|
from output_grabber import OutputGrabber
|
||||||
|
|
||||||
|
out = OutputGrabber()
|
||||||
|
p=pm3.pm3()
|
||||||
|
print("Device:", p.name)
|
||||||
|
with out:
|
||||||
|
p.console("hw status")
|
||||||
|
for line in out.capturedtext.split('\n'):
|
||||||
|
if "Unique ID" in line:
|
||||||
|
print(line)
|
|
@ -1,4 +1,5 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
swig -lua -o ../src/pm3_luawrap.c ../src/pm3.i
|
cd ..
|
||||||
swig -python -o ../src/pm3_pywrap.c ../src/pm3.i
|
make src/pm3_luawrap.c
|
||||||
|
make src/pm3_pywrap.c
|
||||||
|
|
|
@ -188,7 +188,6 @@ set (TARGET_SOURCES
|
||||||
${PM3_ROOT}/client/src/emv/crypto.c
|
${PM3_ROOT}/client/src/emv/crypto.c
|
||||||
${PM3_ROOT}/client/src/emv/crypto_polarssl.c
|
${PM3_ROOT}/client/src/emv/crypto_polarssl.c
|
||||||
${PM3_ROOT}/client/src/emv/dol.c
|
${PM3_ROOT}/client/src/emv/dol.c
|
||||||
${PM3_ROOT}/client/src/emv/dump.c
|
|
||||||
${PM3_ROOT}/client/src/emv/emv_pk.c
|
${PM3_ROOT}/client/src/emv/emv_pk.c
|
||||||
${PM3_ROOT}/client/src/emv/emv_pki.c
|
${PM3_ROOT}/client/src/emv/emv_pki.c
|
||||||
${PM3_ROOT}/client/src/emv/emv_pki_priv.c
|
${PM3_ROOT}/client/src/emv/emv_pki_priv.c
|
||||||
|
@ -456,7 +455,6 @@ else (SKIPWHEREAMISYSTEM EQUAL 1)
|
||||||
message(STATUS "Whereami library: system library not found, using local library")
|
message(STATUS "Whereami library: system library not found, using local library")
|
||||||
endif (WHEREAMI_FOUND)
|
endif (WHEREAMI_FOUND)
|
||||||
endif (SKIPWHEREAMISYSTEM EQUAL 1)
|
endif (SKIPWHEREAMISYSTEM EQUAL 1)
|
||||||
message(STATUS "===================================================================")
|
|
||||||
|
|
||||||
# Lua SWIG
|
# Lua SWIG
|
||||||
if (EXISTS ${PM3_ROOT}/client/src/pm3_luawrap.c)
|
if (EXISTS ${PM3_ROOT}/client/src/pm3_luawrap.c)
|
||||||
|
@ -464,7 +462,7 @@ if (EXISTS ${PM3_ROOT}/client/src/pm3_luawrap.c)
|
||||||
${PM3_ROOT}/client/src/pm3_luawrap.c
|
${PM3_ROOT}/client/src/pm3_luawrap.c
|
||||||
${TARGET_SOURCES})
|
${TARGET_SOURCES})
|
||||||
add_definitions(-DHAVE_LUA_SWIG)
|
add_definitions(-DHAVE_LUA_SWIG)
|
||||||
message("Lua SWIG wrapper found")
|
message(STATUS "Lua SWIG: wrapper found")
|
||||||
endif (EXISTS ${PM3_ROOT}/client/src/pm3_luawrap.c)
|
endif (EXISTS ${PM3_ROOT}/client/src/pm3_luawrap.c)
|
||||||
|
|
||||||
# Python SWIG
|
# Python SWIG
|
||||||
|
@ -475,10 +473,11 @@ if (NOT SKIPPYTHON EQUAL 1)
|
||||||
${PM3_ROOT}/client/src/pm3_pywrap.c
|
${PM3_ROOT}/client/src/pm3_pywrap.c
|
||||||
${TARGET_SOURCES})
|
${TARGET_SOURCES})
|
||||||
add_definitions(-DHAVE_PYTHON_SWIG)
|
add_definitions(-DHAVE_PYTHON_SWIG)
|
||||||
message("Python SWIG wrapper found")
|
message(STATUS "Python SWIG: wrapper found")
|
||||||
endif (EXISTS ${PM3_ROOT}/client/src/pm3_pywrap.c)
|
endif (EXISTS ${PM3_ROOT}/client/src/pm3_pywrap.c)
|
||||||
endif (PYTHON3EMBED_FOUND OR PYTHON3_FOUND)
|
endif (PYTHON3EMBED_FOUND OR PYTHON3_FOUND)
|
||||||
endif (NOT SKIPPYTHON EQUAL 1)
|
endif (NOT SKIPPYTHON EQUAL 1)
|
||||||
|
message(STATUS "===================================================================")
|
||||||
|
|
||||||
add_library(pm3rrg_rdv4 SHARED
|
add_library(pm3rrg_rdv4 SHARED
|
||||||
${PM3_ROOT}/client/src/proxmark3.c
|
${PM3_ROOT}/client/src/proxmark3.c
|
||||||
|
|
3
client/experimental_lib/example_py/02run_test_grab_interactive.sh
Executable file
3
client/experimental_lib/example_py/02run_test_grab_interactive.sh
Executable file
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
PYTHONPATH=../../src ipython3 -i ./test_grab.py
|
78
client/experimental_lib/example_py/output_grabber.py
Executable file
78
client/experimental_lib/example_py/output_grabber.py
Executable file
|
@ -0,0 +1,78 @@
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import threading
|
||||||
|
import time
|
||||||
|
|
||||||
|
# From https://stackoverflow.com/a/29834357
|
||||||
|
class OutputGrabber(object):
|
||||||
|
"""
|
||||||
|
Class used to grab standard output or another stream.
|
||||||
|
"""
|
||||||
|
escape_char = "\b"
|
||||||
|
|
||||||
|
def __init__(self, stream=None, threaded=False):
|
||||||
|
self.origstream = stream
|
||||||
|
self.threaded = threaded
|
||||||
|
if self.origstream is None:
|
||||||
|
self.origstream = sys.stdout
|
||||||
|
self.origstreamfd = self.origstream.fileno()
|
||||||
|
self.capturedtext = ""
|
||||||
|
# Create a pipe so the stream can be captured:
|
||||||
|
self.pipe_out, self.pipe_in = os.pipe()
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
self.start()
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, type, value, traceback):
|
||||||
|
self.stop()
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
"""
|
||||||
|
Start capturing the stream data.
|
||||||
|
"""
|
||||||
|
self.capturedtext = ""
|
||||||
|
# Save a copy of the stream:
|
||||||
|
self.streamfd = os.dup(self.origstreamfd)
|
||||||
|
# Replace the original stream with our write pipe:
|
||||||
|
os.dup2(self.pipe_in, self.origstreamfd)
|
||||||
|
if self.threaded:
|
||||||
|
# Start thread that will read the stream:
|
||||||
|
self.workerThread = threading.Thread(target=self.readOutput)
|
||||||
|
self.workerThread.start()
|
||||||
|
# Make sure that the thread is running and os.read() has executed:
|
||||||
|
time.sleep(0.01)
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
"""
|
||||||
|
Stop capturing the stream data and save the text in `capturedtext`.
|
||||||
|
"""
|
||||||
|
# Print the escape character to make the readOutput method stop:
|
||||||
|
self.origstream.write(self.escape_char)
|
||||||
|
# Flush the stream to make sure all our data goes in before
|
||||||
|
# the escape character:
|
||||||
|
self.origstream.flush()
|
||||||
|
if self.threaded:
|
||||||
|
# wait until the thread finishes so we are sure that
|
||||||
|
# we have until the last character:
|
||||||
|
self.workerThread.join()
|
||||||
|
else:
|
||||||
|
self.readOutput()
|
||||||
|
# Close the pipe:
|
||||||
|
os.close(self.pipe_in)
|
||||||
|
os.close(self.pipe_out)
|
||||||
|
# Restore the original stream:
|
||||||
|
os.dup2(self.streamfd, self.origstreamfd)
|
||||||
|
# Close the duplicate stream:
|
||||||
|
os.close(self.streamfd)
|
||||||
|
|
||||||
|
def readOutput(self):
|
||||||
|
"""
|
||||||
|
Read the stream data (one byte at a time)
|
||||||
|
and save the text in `capturedtext`.
|
||||||
|
"""
|
||||||
|
while True:
|
||||||
|
char = os.read(self.pipe_out,1).decode(self.origstream.encoding)
|
||||||
|
if not char or self.escape_char in char:
|
||||||
|
break
|
||||||
|
self.capturedtext += char
|
13
client/experimental_lib/example_py/test_grab.py
Executable file
13
client/experimental_lib/example_py/test_grab.py
Executable file
|
@ -0,0 +1,13 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import pm3
|
||||||
|
from output_grabber import OutputGrabber
|
||||||
|
|
||||||
|
out = OutputGrabber()
|
||||||
|
p=pm3.pm3("/dev/ttyACM1")
|
||||||
|
print("Device:", p.name)
|
||||||
|
with out:
|
||||||
|
p.console("hw status")
|
||||||
|
for line in out.capturedtext.split('\n'):
|
||||||
|
if "Unique ID" in line:
|
||||||
|
print(line)
|
|
@ -68,10 +68,11 @@ end
|
||||||
|
|
||||||
_errorcodes.tostring = function(command)
|
_errorcodes.tostring = function(command)
|
||||||
if(type(command) == 'string') then
|
if(type(command) == 'string') then
|
||||||
return ("%s (%d)"):format(_reverse_lookup[command] or "ERROR UNDEFINED!", command)
|
return ("%s (%s)"):format(_reverse_lookup[command] or "ERROR UNDEFINED!", command)
|
||||||
end
|
end
|
||||||
if(type(command) == 'number') then
|
if(type(command) == 'number') then
|
||||||
return ("%s (%d)"):format(_reverse_lookup[ tostring(command)] or "ERROR UNDEFINED!", command)
|
local hx = ("%04X"):format(command)
|
||||||
|
return ("%s (0x%s)"):format(_reverse_lookup[hx] or "ERROR UNDEFINED!", hx)
|
||||||
end
|
end
|
||||||
return ("Error, numeric or string argument expected, got : %s"):format(tostring(command))
|
return ("Error, numeric or string argument expected, got : %s"):format(tostring(command))
|
||||||
end
|
end
|
||||||
|
|
|
@ -29,12 +29,11 @@
|
||||||
#include "aidsearch.h"
|
#include "aidsearch.h"
|
||||||
#include "cmdhf.h" // handle HF plot
|
#include "cmdhf.h" // handle HF plot
|
||||||
#include "protocols.h" // MAGIC_GEN_1A
|
#include "protocols.h" // MAGIC_GEN_1A
|
||||||
#include "emv/dump.h" // dump_buffer
|
|
||||||
|
|
||||||
bool APDUInFramingEnable = true;
|
bool APDUInFramingEnable = true;
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
static int waitCmd(uint8_t iSelect, uint32_t timeout);
|
static int waitCmd(bool i_select, uint32_t timeout);
|
||||||
|
|
||||||
static const manufactureName manufactureMapping[] = {
|
static const manufactureName manufactureMapping[] = {
|
||||||
// ID, "Vendor Country"
|
// ID, "Vendor Country"
|
||||||
|
@ -246,20 +245,7 @@ static int usage_hf_14a_sniff(void) {
|
||||||
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a sniff c r"));
|
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a sniff c r"));
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
static int usage_hf_14a_raw(void) {
|
|
||||||
PrintAndLogEx(NORMAL, "Usage: hf 14a raw [-h] [-r] [-c] [-k] [-a] [-T] [-t] <milliseconds> [-b] <number of bits> <0A 0B 0C ... hex>");
|
|
||||||
PrintAndLogEx(NORMAL, " -h this help");
|
|
||||||
PrintAndLogEx(NORMAL, " -r do not read response");
|
|
||||||
PrintAndLogEx(NORMAL, " -c calculate and append CRC");
|
|
||||||
PrintAndLogEx(NORMAL, " -k keep signal field ON after receive");
|
|
||||||
PrintAndLogEx(NORMAL, " -a active signal field ON without select");
|
|
||||||
PrintAndLogEx(NORMAL, " -s active signal field ON with select");
|
|
||||||
PrintAndLogEx(NORMAL, " -b number of bits to send. Useful for send partial byte");
|
|
||||||
PrintAndLogEx(NORMAL, " -t timeout in ms");
|
|
||||||
PrintAndLogEx(NORMAL, " -T use Topaz protocol to send command");
|
|
||||||
PrintAndLogEx(NORMAL, " -3 ISO14443-3 select only (skip RATS)");
|
|
||||||
return PM3_SUCCESS;
|
|
||||||
}
|
|
||||||
static int usage_hf_14a_reader(void) {
|
static int usage_hf_14a_reader(void) {
|
||||||
PrintAndLogEx(NORMAL, "Usage: hf 14a reader [k|s|x] [3]");
|
PrintAndLogEx(NORMAL, "Usage: hf 14a reader [k|s|x] [3]");
|
||||||
PrintAndLogEx(NORMAL, " k keep the field active after command executed");
|
PrintAndLogEx(NORMAL, " k keep the field active after command executed");
|
||||||
|
@ -1118,14 +1104,14 @@ static int CmdHF14AAPDU(const char *Cmd) {
|
||||||
CLIParserInit(&ctx, "hf 14a apdu",
|
CLIParserInit(&ctx, "hf 14a apdu",
|
||||||
"Sends an ISO 7816-4 APDU via ISO 14443-4 block transmission protocol (T=CL). works with all apdu types from ISO 7816-4:2013",
|
"Sends an ISO 7816-4 APDU via ISO 14443-4 block transmission protocol (T=CL). works with all apdu types from ISO 7816-4:2013",
|
||||||
"hf 14a apdu -st 00A404000E325041592E5359532E444446303100\n"
|
"hf 14a apdu -st 00A404000E325041592E5359532E444446303100\n"
|
||||||
"hf 14a apdu -sd 00A404000E325041592E5359532E444446303100 -> decode apdu\n"
|
"hf 14a apdu -sd 00A404000E325041592E5359532E444446303100 -> decode apdu\n"
|
||||||
"hf 14a apdu -sm 00A40400 325041592E5359532E4444463031 -l 256 -> encode standard apdu\n"
|
"hf 14a apdu -sm 00A40400 325041592E5359532E4444463031 -l 256 -> encode standard apdu\n"
|
||||||
"hf 14a apdu -sm 00A40400 325041592E5359532E4444463031 -el 65536 -> encode extended apdu\n");
|
"hf 14a apdu -sm 00A40400 325041592E5359532E4444463031 -el 65536 -> encode extended apdu\n");
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
arg_lit0("s", "select", "activate field and select card"),
|
arg_lit0("s", "select", "activate field and select card"),
|
||||||
arg_lit0("k", "keep", "leave the signal field ON after receive response"),
|
arg_lit0("k", "keep", "keep signal field ON after receive"),
|
||||||
arg_lit0("t", "tlv", "executes TLV decoder if it possible"),
|
arg_lit0("t", "tlv", "executes TLV decoder if it possible"),
|
||||||
arg_lit0("d", "decapdu", "decode apdu request if it possible"),
|
arg_lit0("d", "decapdu", "decode apdu request if it possible"),
|
||||||
arg_str0("m", "make", "<head (CLA INS P1 P2) hex>", "make apdu with head from this field and data from data field. Must be 4 bytes length: <CLA INS P1 P2>"),
|
arg_str0("m", "make", "<head (CLA INS P1 P2) hex>", "make apdu with head from this field and data from data field. Must be 4 bytes length: <CLA INS P1 P2>"),
|
||||||
|
@ -1225,97 +1211,54 @@ static int CmdHF14AAPDU(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int CmdHF14ACmdRaw(const char *Cmd) {
|
static int CmdHF14ACmdRaw(const char *Cmd) {
|
||||||
bool reply = 1;
|
|
||||||
bool crc = false;
|
CLIParserContext *ctx;
|
||||||
bool keep_field_on = false;
|
CLIParserInit(&ctx, "hf 14a raw",
|
||||||
bool active = false;
|
"Sends an raw bytes over ISO14443a. With option to use TOPAZ 14a mode.",
|
||||||
bool active_select = false;
|
"hf 14a raw -sc 3000 -> select, crc, where 3000 == 'read block 00'\n"
|
||||||
bool no_rats = false;
|
"hf 14a raw -ak -b 7 40 -> send 7 bit byte 0x40\n"
|
||||||
uint16_t numbits = 0;
|
);
|
||||||
bool bTimeout = false;
|
|
||||||
uint32_t timeout = 0;
|
void *argtable[] = {
|
||||||
bool topazmode = false;
|
arg_param_begin,
|
||||||
char buf[5] = "";
|
arg_lit0("a", NULL, "active signal field ON without select"),
|
||||||
int i = 0;
|
arg_int0("b", NULL, "<dec>", "number of bits to send. Useful for send partial byte"),
|
||||||
|
arg_lit0("c", NULL, "calculate and append CRC"),
|
||||||
|
arg_lit0("k", NULL, "keep signal field ON after receive"),
|
||||||
|
arg_lit0("3", NULL, "ISO14443-3 select only (skip RATS)"),
|
||||||
|
arg_lit0("r", NULL, "do not read response"),
|
||||||
|
arg_lit0("s", NULL, "active signal field ON with select"),
|
||||||
|
arg_int0("t", "timeout", "<ms>", "timeout in milliseconds"),
|
||||||
|
arg_lit0(NULL, "topaz", "use Topaz protocol to send command"),
|
||||||
|
arg_strx1(NULL, NULL, "<hex>", "raw bytes to send"),
|
||||||
|
arg_param_end
|
||||||
|
};
|
||||||
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
|
||||||
|
|
||||||
|
bool active = arg_get_lit(ctx, 1);
|
||||||
|
uint16_t numbits = (uint16_t)arg_get_int_def(ctx, 2, 0);
|
||||||
|
bool crc = arg_get_lit(ctx, 3);
|
||||||
|
bool keep_field_on = arg_get_lit(ctx, 4);
|
||||||
|
bool no_rats = arg_get_lit(ctx, 5);
|
||||||
|
bool reply = (arg_get_lit(ctx, 6) == false);
|
||||||
|
bool active_select = arg_get_lit(ctx, 7);
|
||||||
|
uint32_t timeout = (uint32_t)arg_get_int_def(ctx, 8, 0);
|
||||||
|
bool topazmode = arg_get_lit(ctx, 9);
|
||||||
|
|
||||||
|
int datalen = 0;
|
||||||
uint8_t data[PM3_CMD_DATA_SIZE];
|
uint8_t data[PM3_CMD_DATA_SIZE];
|
||||||
uint16_t datalen = 0;
|
CLIGetHexWithReturn(ctx, 10, data, &datalen);
|
||||||
uint32_t temp;
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
if (strlen(Cmd) < 2) return usage_hf_14a_raw();
|
bool bTimeout = (timeout) ? true : false;
|
||||||
|
|
||||||
// strip
|
// ensure we can add 2byte crc to input data
|
||||||
while (*Cmd == ' ' || *Cmd == '\t') Cmd++;
|
if (datalen >= sizeof(data) + 2) {
|
||||||
|
if (crc) {
|
||||||
while (Cmd[i] != '\0') {
|
PrintAndLogEx(FAILED, "Buffer is full, we can't add CRC to your data");
|
||||||
if (Cmd[i] == ' ' || Cmd[i] == '\t') { i++; continue; }
|
return PM3_EINVARG;
|
||||||
if (Cmd[i] == '-') {
|
|
||||||
switch (Cmd[i + 1]) {
|
|
||||||
case 'H':
|
|
||||||
case 'h':
|
|
||||||
return usage_hf_14a_raw();
|
|
||||||
case 'r':
|
|
||||||
reply = false;
|
|
||||||
break;
|
|
||||||
case 'c':
|
|
||||||
crc = true;
|
|
||||||
break;
|
|
||||||
case 'k':
|
|
||||||
keep_field_on = true;
|
|
||||||
break;
|
|
||||||
case 'a':
|
|
||||||
active = true;
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
active_select = true;
|
|
||||||
break;
|
|
||||||
case 'b':
|
|
||||||
sscanf(Cmd + i + 2, "%u", &temp);
|
|
||||||
numbits = temp & 0xFFFF;
|
|
||||||
i += 3;
|
|
||||||
while (Cmd[i] != ' ' && Cmd[i] != '\0') { i++; }
|
|
||||||
i -= 2;
|
|
||||||
break;
|
|
||||||
case 't':
|
|
||||||
bTimeout = true;
|
|
||||||
sscanf(Cmd + i + 2, "%u", &temp);
|
|
||||||
timeout = temp;
|
|
||||||
i += 3;
|
|
||||||
while (Cmd[i] != ' ' && Cmd[i] != '\0') { i++; }
|
|
||||||
i -= 2;
|
|
||||||
break;
|
|
||||||
case 'T':
|
|
||||||
topazmode = true;
|
|
||||||
break;
|
|
||||||
case '3':
|
|
||||||
no_rats = true;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return usage_hf_14a_raw();
|
|
||||||
}
|
|
||||||
i += 2;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
if ((Cmd[i] >= '0' && Cmd[i] <= '9') ||
|
|
||||||
(Cmd[i] >= 'a' && Cmd[i] <= 'f') ||
|
|
||||||
(Cmd[i] >= 'A' && Cmd[i] <= 'F')) {
|
|
||||||
buf[strlen(buf) + 1] = 0;
|
|
||||||
buf[strlen(buf)] = Cmd[i];
|
|
||||||
i++;
|
|
||||||
|
|
||||||
if (strlen(buf) >= 2) {
|
|
||||||
sscanf(buf, "%x", &temp);
|
|
||||||
data[datalen] = (uint8_t)(temp & 0xff);
|
|
||||||
*buf = 0;
|
|
||||||
if (++datalen >= sizeof(data)) {
|
|
||||||
if (crc)
|
|
||||||
PrintAndLogEx(FAILED, "Buffer is full, we can't add CRC to your data");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
PrintAndLogEx(FAILED, "Invalid char on input");
|
|
||||||
return PM3_ESOFT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (crc && datalen > 0 && datalen < sizeof(data) - 2) {
|
if (crc && datalen > 0 && datalen < sizeof(data) - 2) {
|
||||||
|
@ -1371,19 +1314,19 @@ static int CmdHF14ACmdRaw(const char *Cmd) {
|
||||||
if (reply) {
|
if (reply) {
|
||||||
int res = 0;
|
int res = 0;
|
||||||
if (active_select)
|
if (active_select)
|
||||||
res = waitCmd(1, timeout);
|
res = waitCmd(true, timeout);
|
||||||
if (!res && datalen > 0)
|
if (res == PM3_SUCCESS && datalen > 0)
|
||||||
waitCmd(0, timeout);
|
waitCmd(false, timeout);
|
||||||
}
|
}
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int waitCmd(uint8_t iSelect, uint32_t timeout) {
|
static int waitCmd(bool i_select, uint32_t timeout) {
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
|
|
||||||
if (WaitForResponseTimeout(CMD_ACK, &resp, timeout + 1500)) {
|
if (WaitForResponseTimeout(CMD_ACK, &resp, timeout + 1500)) {
|
||||||
uint16_t len = (resp.oldarg[0] & 0xFFFF);
|
uint16_t len = (resp.oldarg[0] & 0xFFFF);
|
||||||
if (iSelect) {
|
if (i_select) {
|
||||||
len = (resp.oldarg[1] & 0xFFFF);
|
len = (resp.oldarg[1] & 0xFFFF);
|
||||||
if (len) {
|
if (len) {
|
||||||
PrintAndLogEx(SUCCESS, "Card selected. UID[%u]:", len);
|
PrintAndLogEx(SUCCESS, "Card selected. UID[%u]:", len);
|
||||||
|
@ -1395,28 +1338,30 @@ static int waitCmd(uint8_t iSelect, uint32_t timeout) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!len)
|
if (!len)
|
||||||
return 1;
|
return PM3_ESOFT;
|
||||||
|
|
||||||
uint8_t *data = resp.data.asBytes;
|
uint8_t *data = resp.data.asBytes;
|
||||||
|
|
||||||
if (iSelect == 0 && len >= 3) {
|
if (i_select == false && len >= 3) {
|
||||||
bool crc = check_crc(CRC_14443_A, data, len);
|
bool crc = check_crc(CRC_14443_A, data, len);
|
||||||
|
|
||||||
|
char s[16];
|
||||||
|
sprintf(s,
|
||||||
|
(crc) ? _GREEN_("%02X %02X") : _RED_("%02X %02X"),
|
||||||
|
data[len - 2],
|
||||||
|
data[len - 1]
|
||||||
|
);
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, "%s[%02X %02X] %s",
|
PrintAndLogEx(SUCCESS, "%s[ %s ]", sprint_hex(data, len - 2), s);
|
||||||
sprint_hex(data, len - 2),
|
|
||||||
data[len - 2],
|
|
||||||
data[len - 1],
|
|
||||||
(crc) ? _GREEN_("ok") : _RED_("fail")
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(SUCCESS, "%s", sprint_hex(data, len));
|
PrintAndLogEx(SUCCESS, "%s", sprint_hex(data, len));
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
||||||
return 3;
|
return PM3_ETIMEOUT;
|
||||||
}
|
}
|
||||||
return 0;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int CmdHF14AAntiFuzz(const char *Cmd) {
|
static int CmdHF14AAntiFuzz(const char *Cmd) {
|
||||||
|
|
|
@ -1326,7 +1326,7 @@ static int CmdHF15Dump(const char *Cmd) {
|
||||||
if (fileNameLen < 1) {
|
if (fileNameLen < 1) {
|
||||||
PrintAndLogEx(INFO, "Using UID as filename");
|
PrintAndLogEx(INFO, "Using UID as filename");
|
||||||
fptr += sprintf(fptr, "hf-15-");
|
fptr += sprintf(fptr, "hf-15-");
|
||||||
FillFileNameByUID(fptr, uid, "-dump", sizeof(uid));
|
FillFileNameByUID(fptr, SwapEndian64(uid, sizeof(uid), 8), "-dump", sizeof(uid));
|
||||||
}
|
}
|
||||||
// detect blocksize from card :)
|
// detect blocksize from card :)
|
||||||
|
|
||||||
|
|
|
@ -19,9 +19,7 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#include "cmdhffido.h"
|
#include "cmdhffido.h"
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "cmdparser.h" // command_t
|
#include "cmdparser.h" // command_t
|
||||||
#include "commonutil.h"
|
#include "commonutil.h"
|
||||||
#include "comms.h"
|
#include "comms.h"
|
||||||
|
@ -33,10 +31,10 @@
|
||||||
#include "crypto/libpcrypto.h"
|
#include "crypto/libpcrypto.h"
|
||||||
#include "fido/cbortools.h"
|
#include "fido/cbortools.h"
|
||||||
#include "fido/fidocore.h"
|
#include "fido/fidocore.h"
|
||||||
#include "emv/dump.h"
|
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "cmdhf14a.h"
|
#include "cmdhf14a.h"
|
||||||
#include "cmdtrace.h"
|
#include "cmdtrace.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
|
@ -88,7 +86,7 @@ static int cmd_hf_fido_info(const char *cmd) {
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(INFO, "FIDO authenticator detected (not standard U2F).");
|
PrintAndLogEx(INFO, "FIDO authenticator detected (not standard U2F).");
|
||||||
PrintAndLogEx(INFO, "Non U2F authenticator version:");
|
PrintAndLogEx(INFO, "Non U2F authenticator version:");
|
||||||
dump_buffer((const unsigned char *)buf, len, NULL, 0);
|
print_buffer((const unsigned char *)buf, len, 1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(INFO, "FIDO U2F authenticator detected. Version: %.*s", (int)len, buf);
|
PrintAndLogEx(INFO, "FIDO U2F authenticator detected. Version: %.*s", (int)len, buf);
|
||||||
|
@ -296,7 +294,7 @@ static int cmd_hf_fido_register(const char *cmd) {
|
||||||
|
|
||||||
if (verbose2) {
|
if (verbose2) {
|
||||||
PrintAndLogEx(INFO, "------------ " _CYAN_("data") " ----------------------");
|
PrintAndLogEx(INFO, "------------ " _CYAN_("data") " ----------------------");
|
||||||
dump_buffer((const unsigned char *)buf, len, NULL, 0);
|
print_buffer((const unsigned char *)buf, len, 1);
|
||||||
PrintAndLogEx(INFO, "-------------" _CYAN_("data") " ----------------------");
|
PrintAndLogEx(INFO, "-------------" _CYAN_("data") " ----------------------");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,7 +340,7 @@ static int cmd_hf_fido_register(const char *cmd) {
|
||||||
uint8_t rval[300] = {0};
|
uint8_t rval[300] = {0};
|
||||||
uint8_t sval[300] = {0};
|
uint8_t sval[300] = {0};
|
||||||
res = ecdsa_asn1_get_signature(&buf[hashp], len - hashp, rval, sval);
|
res = ecdsa_asn1_get_signature(&buf[hashp], len - hashp, rval, sval);
|
||||||
if (!res) {
|
if (res == PM3_SUCCESS) {
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
PrintAndLogEx(INFO, " r: %s", sprint_hex(rval, 32));
|
PrintAndLogEx(INFO, " r: %s", sprint_hex(rval, 32));
|
||||||
PrintAndLogEx(INFO, " s: %s", sprint_hex(sval, 32));
|
PrintAndLogEx(INFO, " s: %s", sprint_hex(sval, 32));
|
||||||
|
@ -585,7 +583,7 @@ static int cmd_hf_fido_authenticate(const char *cmd) {
|
||||||
uint8_t rval[300] = {0};
|
uint8_t rval[300] = {0};
|
||||||
uint8_t sval[300] = {0};
|
uint8_t sval[300] = {0};
|
||||||
res = ecdsa_asn1_get_signature(&buf[5], len - 5, rval, sval);
|
res = ecdsa_asn1_get_signature(&buf[5], len - 5, rval, sval);
|
||||||
if (!res) {
|
if (res == PM3_SUCCESS) {
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
PrintAndLogEx(INFO, " r: %s", sprint_hex(rval, 32));
|
PrintAndLogEx(INFO, " r: %s", sprint_hex(rval, 32));
|
||||||
PrintAndLogEx(INFO, " s: %s", sprint_hex(sval, 32));
|
PrintAndLogEx(INFO, " s: %s", sprint_hex(sval, 32));
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
#include "comms.h" // clearCommandBuffer
|
#include "comms.h" // clearCommandBuffer
|
||||||
#include "fileutils.h"
|
#include "fileutils.h"
|
||||||
#include "cmdtrace.h"
|
#include "cmdtrace.h"
|
||||||
#include "emv/dump.h"
|
|
||||||
#include "mifare/mifaredefault.h" // mifare default key array
|
#include "mifare/mifaredefault.h" // mifare default key array
|
||||||
#include "cliparser.h" // argtable
|
#include "cliparser.h" // argtable
|
||||||
#include "hardnested_bf_core.h" // SetSIMDInstr
|
#include "hardnested_bf_core.h" // SetSIMDInstr
|
||||||
|
@ -5095,7 +5094,7 @@ static int CmdHFMFNDEF(const char *Cmd) {
|
||||||
if (verbose2) {
|
if (verbose2) {
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(INFO, "--- " _CYAN_("MFC NDEF raw") " ----------------");
|
PrintAndLogEx(INFO, "--- " _CYAN_("MFC NDEF raw") " ----------------");
|
||||||
dump_buffer(data, datalen, stdout, 1);
|
print_buffer(data, datalen, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
NDEFDecodeAndPrint(data, datalen, verbose);
|
NDEFDecodeAndPrint(data, datalen, verbose);
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include "mifare/mad.h"
|
#include "mifare/mad.h"
|
||||||
#include "generator.h"
|
#include "generator.h"
|
||||||
#include "aiddesfire.h"
|
#include "aiddesfire.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
#define MAX_KEY_LEN 24
|
#define MAX_KEY_LEN 24
|
||||||
#define MAX_KEYS_LIST_LEN 1024
|
#define MAX_KEYS_LIST_LEN 1024
|
||||||
|
@ -728,7 +729,6 @@ static int mfdes_get_info(mfdes_info_res_t *info) {
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rpayload) {
|
static int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rpayload) {
|
||||||
// 3 different way to authenticate AUTH (CRC16) , AUTH_ISO (CRC32) , AUTH_AES (CRC32)
|
// 3 different way to authenticate AUTH (CRC16) , AUTH_ISO (CRC32) , AUTH_AES (CRC32)
|
||||||
// 4 different crypto arg1 DES, 3DES, 3K3DES, AES
|
// 4 different crypto arg1 DES, 3DES, 3K3DES, AES
|
||||||
|
@ -777,9 +777,7 @@ static int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rp
|
||||||
|
|
||||||
if (payload->kdfAlgo == MFDES_KDF_ALGO_AN10922) {
|
if (payload->kdfAlgo == MFDES_KDF_ALGO_AN10922) {
|
||||||
mifare_kdf_an10922(key, payload->kdfInput, payload->kdfInputLen);
|
mifare_kdf_an10922(key, payload->kdfInput, payload->kdfInputLen);
|
||||||
if (g_debugMode) {
|
PrintAndLogEx(DEBUG, " Derrived key: " _GREEN_("%s"), sprint_hex(key->data, key_block_size(key)));
|
||||||
PrintAndLogEx(INFO, " Derrived key: " _GREEN_("%s"), sprint_hex(key->data, key_block_size(key)));
|
|
||||||
}
|
|
||||||
} else if (payload->kdfAlgo == MFDES_KDF_ALGO_GALLAGHER) {
|
} else if (payload->kdfAlgo == MFDES_KDF_ALGO_GALLAGHER) {
|
||||||
// We will overrite any provided KDF input since a gallagher specific KDF was requested.
|
// We will overrite any provided KDF input since a gallagher specific KDF was requested.
|
||||||
payload->kdfInputLen = 11;
|
payload->kdfInputLen = 11;
|
||||||
|
@ -789,11 +787,9 @@ static int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rp
|
||||||
}
|
}
|
||||||
|
|
||||||
mifare_kdf_an10922(key, payload->kdfInput, payload->kdfInputLen);
|
mifare_kdf_an10922(key, payload->kdfInput, payload->kdfInputLen);
|
||||||
|
PrintAndLogEx(DEBUG, " KDF Input: " _YELLOW_("%s"), sprint_hex(payload->kdfInput, payload->kdfInputLen));
|
||||||
|
PrintAndLogEx(DEBUG, " Derrived key: " _GREEN_("%s"), sprint_hex(key->data, key_block_size(key)));
|
||||||
|
|
||||||
if (g_debugMode) {
|
|
||||||
PrintAndLogEx(INFO, " KDF Input: " _YELLOW_("%s"), sprint_hex(payload->kdfInput, payload->kdfInputLen));
|
|
||||||
PrintAndLogEx(INFO, " Derrived key: " _GREEN_("%s"), sprint_hex(key->data, key_block_size(key)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t subcommand = MFDES_AUTHENTICATE;
|
uint8_t subcommand = MFDES_AUTHENTICATE;
|
||||||
|
@ -866,8 +862,8 @@ static int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rp
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_debugMode > 1) {
|
if (g_debugMode > 1) {
|
||||||
PrintAndLogEx(INFO, "encRndB: %s", sprint_hex(encRndB, 8));
|
PrintAndLogEx(DEBUG, "encRndB: %s", sprint_hex(encRndB, 8));
|
||||||
PrintAndLogEx(INFO, "RndB: %s", sprint_hex(RndB, 8));
|
PrintAndLogEx(DEBUG, "RndB: %s", sprint_hex(RndB, 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
// - Rotate RndB by 8 bits
|
// - Rotate RndB by 8 bits
|
||||||
|
@ -893,24 +889,24 @@ static int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rp
|
||||||
memcpy(tmp, RndA, rndlen);
|
memcpy(tmp, RndA, rndlen);
|
||||||
memcpy(tmp + rndlen, rotRndB, rndlen);
|
memcpy(tmp + rndlen, rotRndB, rndlen);
|
||||||
if (g_debugMode > 1) {
|
if (g_debugMode > 1) {
|
||||||
PrintAndLogEx(INFO, "rotRndB: %s", sprint_hex(rotRndB, rndlen));
|
PrintAndLogEx(DEBUG, "rotRndB: %s", sprint_hex(rotRndB, rndlen));
|
||||||
PrintAndLogEx(INFO, "Both: %s", sprint_hex(tmp, 16));
|
PrintAndLogEx(DEBUG, "Both: %s", sprint_hex(tmp, 16));
|
||||||
}
|
}
|
||||||
tdes_nxp_send(tmp, both, 16, key->data, IV, 2);
|
tdes_nxp_send(tmp, both, 16, key->data, IV, 2);
|
||||||
if (g_debugMode > 1) {
|
if (g_debugMode > 1) {
|
||||||
PrintAndLogEx(INFO, "EncBoth: %s", sprint_hex(both, 16));
|
PrintAndLogEx(DEBUG, "EncBoth: %s", sprint_hex(both, 16));
|
||||||
}
|
}
|
||||||
} else if (payload->algo == MFDES_ALGO_3K3DES) {
|
} else if (payload->algo == MFDES_ALGO_3K3DES) {
|
||||||
uint8_t tmp[32] = {0x00};
|
uint8_t tmp[32] = {0x00};
|
||||||
memcpy(tmp, RndA, rndlen);
|
memcpy(tmp, RndA, rndlen);
|
||||||
memcpy(tmp + rndlen, rotRndB, rndlen);
|
memcpy(tmp + rndlen, rotRndB, rndlen);
|
||||||
if (g_debugMode > 1) {
|
if (g_debugMode > 1) {
|
||||||
PrintAndLogEx(INFO, "rotRndB: %s", sprint_hex(rotRndB, rndlen));
|
PrintAndLogEx(DEBUG, "rotRndB: %s", sprint_hex(rotRndB, rndlen));
|
||||||
PrintAndLogEx(INFO, "Both3k3: %s", sprint_hex(tmp, 32));
|
PrintAndLogEx(DEBUG, "Both3k3: %s", sprint_hex(tmp, 32));
|
||||||
}
|
}
|
||||||
tdes_nxp_send(tmp, both, 32, key->data, IV, 3);
|
tdes_nxp_send(tmp, both, 32, key->data, IV, 3);
|
||||||
if (g_debugMode > 1) {
|
if (g_debugMode > 1) {
|
||||||
PrintAndLogEx(INFO, "EncBoth: %s", sprint_hex(both, 32));
|
PrintAndLogEx(DEBUG, "EncBoth: %s", sprint_hex(both, 32));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (payload->mode == MFDES_AUTH_AES) {
|
} else if (payload->mode == MFDES_AUTH_AES) {
|
||||||
|
@ -918,8 +914,8 @@ static int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rp
|
||||||
memcpy(tmp, RndA, rndlen);
|
memcpy(tmp, RndA, rndlen);
|
||||||
memcpy(tmp + rndlen, rotRndB, rndlen);
|
memcpy(tmp + rndlen, rotRndB, rndlen);
|
||||||
if (g_debugMode > 1) {
|
if (g_debugMode > 1) {
|
||||||
PrintAndLogEx(INFO, "rotRndB: %s", sprint_hex(rotRndB, rndlen));
|
PrintAndLogEx(DEBUG, "rotRndB: %s", sprint_hex(rotRndB, rndlen));
|
||||||
PrintAndLogEx(INFO, "Both3k3: %s", sprint_hex(tmp, 32));
|
PrintAndLogEx(DEBUG, "Both3k3: %s", sprint_hex(tmp, 32));
|
||||||
}
|
}
|
||||||
if (payload->algo == MFDES_ALGO_AES) {
|
if (payload->algo == MFDES_ALGO_AES) {
|
||||||
if (mbedtls_aes_setkey_enc(&ctx, key->data, 128) != 0) {
|
if (mbedtls_aes_setkey_enc(&ctx, key->data, 128) != 0) {
|
||||||
|
@ -927,7 +923,7 @@ static int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rp
|
||||||
}
|
}
|
||||||
mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT, 32, IV, tmp, both);
|
mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT, 32, IV, tmp, both);
|
||||||
if (g_debugMode > 1) {
|
if (g_debugMode > 1) {
|
||||||
PrintAndLogEx(INFO, "EncBoth: %s", sprint_hex(both, 32));
|
PrintAndLogEx(DEBUG, "EncBoth: %s", sprint_hex(both, 32));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -996,8 +992,8 @@ static int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rp
|
||||||
for (uint32_t x = 0; x < rndlen; x++) {
|
for (uint32_t x = 0; x < rndlen; x++) {
|
||||||
if (RndA[x] != encRndA[x]) {
|
if (RndA[x] != encRndA[x]) {
|
||||||
if (g_debugMode > 1) {
|
if (g_debugMode > 1) {
|
||||||
PrintAndLogEx(INFO, "Expected_RndA : %s", sprint_hex(RndA, rndlen));
|
PrintAndLogEx(DEBUG, "Expected_RndA : %s", sprint_hex(RndA, rndlen));
|
||||||
PrintAndLogEx(INFO, "Generated_RndA : %s", sprint_hex(encRndA, rndlen));
|
PrintAndLogEx(DEBUG, "Generated_RndA : %s", sprint_hex(encRndA, rndlen));
|
||||||
}
|
}
|
||||||
return 11;
|
return 11;
|
||||||
}
|
}
|
||||||
|
@ -4769,7 +4765,7 @@ static int CmdHF14aDesNDEF(const char *Cmd) {
|
||||||
if (verbose2) {
|
if (verbose2) {
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(INFO, "--- " _CYAN_("DESFire NDEF raw") " ----------------");
|
PrintAndLogEx(INFO, "--- " _CYAN_("DESFire NDEF raw") " ----------------");
|
||||||
dump_buffer(data, datalen, stdout, 1);
|
print_buffer(data, datalen, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLogEx(HINT, "Try " _YELLOW_("`hf mfdes ndef -vv`") " for more details");
|
PrintAndLogEx(HINT, "Try " _YELLOW_("`hf mfdes ndef -vv`") " for more details");
|
||||||
|
|
|
@ -15,12 +15,12 @@
|
||||||
#include "commonutil.h" // ARRAYLEN
|
#include "commonutil.h" // ARRAYLEN
|
||||||
#include "comms.h"
|
#include "comms.h"
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
|
#include "util.h"
|
||||||
#include "cmdhf14a.h"
|
#include "cmdhf14a.h"
|
||||||
#include "mifare/mifare4.h"
|
#include "mifare/mifare4.h"
|
||||||
#include "mifare/mad.h"
|
#include "mifare/mad.h"
|
||||||
#include "mifare/ndef.h"
|
#include "mifare/ndef.h"
|
||||||
#include "cliparser.h"
|
#include "cliparser.h"
|
||||||
#include "emv/dump.h"
|
|
||||||
#include "mifare/mifaredefault.h"
|
#include "mifare/mifaredefault.h"
|
||||||
#include "util_posix.h"
|
#include "util_posix.h"
|
||||||
#include "fileutils.h"
|
#include "fileutils.h"
|
||||||
|
@ -1551,7 +1551,7 @@ static int CmdHFMFPNDEF(const char *Cmd) {
|
||||||
if (verbose2) {
|
if (verbose2) {
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(INFO, "--- " _CYAN_("MF Plus NDEF raw") " ----------------");
|
PrintAndLogEx(INFO, "--- " _CYAN_("MF Plus NDEF raw") " ----------------");
|
||||||
dump_buffer(data, datalen, stdout, 1);
|
print_buffer(data, datalen, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
NDEFDecodeAndPrint(data, datalen, verbose);
|
NDEFDecodeAndPrint(data, datalen, verbose);
|
||||||
|
|
|
@ -83,9 +83,9 @@ static model_t models[] = {
|
||||||
{"2.9 inch e-paper", 16, 296, 128},
|
{"2.9 inch e-paper", 16, 296, 128},
|
||||||
{"4.2 inch e-paper", 100, 400, 300}, // tested
|
{"4.2 inch e-paper", 100, 400, 300}, // tested
|
||||||
{"7.5 inch e-paper", 120, 800, 480},
|
{"7.5 inch e-paper", 120, 800, 480},
|
||||||
{"2.7 inch e-paper", 121, 276, 176},
|
{"2.7 inch e-paper", 121, 176, 276}, // tested
|
||||||
{"2.13 inch e-paper B (with red)", 106, 212, 104},
|
{"2.13 inch e-paper B (with red)", 106, 104, 212}, // tested
|
||||||
{"1.54 inch e-paper B (with red)", 100, 200, 200},
|
{"1.54 inch e-paper B (with red)", 100, 200, 200}, // tested
|
||||||
{"7.5 inch e-paper HD", 120, 880, 528},
|
{"7.5 inch e-paper HD", 120, 880, 528},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -563,7 +563,6 @@ static int transceive_blocking(uint8_t *txBuf, uint16_t txBufLen, uint8_t *rxBuf
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_DISCONNECT, txBufLen, 0, txBuf, txBufLen);
|
SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_DISCONNECT, txBufLen, 0, txBuf, txBufLen);
|
||||||
rxBuf[0] = 1;
|
rxBuf[0] = 1;
|
||||||
|
|
||||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
|
if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
|
||||||
if (resp.oldarg[0] > rxBufLen) {
|
if (resp.oldarg[0] > rxBufLen) {
|
||||||
PrintAndLogEx(WARNING, "Received %"PRIu64 " bytes, rxBuf too small (%u)", resp.oldarg[0], rxBufLen);
|
PrintAndLogEx(WARNING, "Received %"PRIu64 " bytes, rxBuf too small (%u)", resp.oldarg[0], rxBufLen);
|
||||||
|
@ -856,7 +855,7 @@ static int start_drawing(uint8_t model_nr, uint8_t *black, uint8_t *red) {
|
||||||
} else if (model_nr == M2in13B) { //2.13inch B
|
} else if (model_nr == M2in13B) { //2.13inch B
|
||||||
for (i = 0; i < 26; i++) {
|
for (i = 0; i < 26; i++) {
|
||||||
read_black(i, step8, model_nr, black);
|
read_black(i, step8, model_nr, black);
|
||||||
ret = transceive_blocking(step8, 109, rx, 20, actrxlen, true); // cd 08
|
ret = transceive_blocking(step8, 109, rx, 20, actrxlen, false); // cd 08
|
||||||
if (ret != PM3_SUCCESS) {
|
if (ret != PM3_SUCCESS) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -920,7 +919,7 @@ static int start_drawing(uint8_t model_nr, uint8_t *black, uint8_t *red) {
|
||||||
for (i = 0; i < 26; i++) {
|
for (i = 0; i < 26; i++) {
|
||||||
read_red(i, step13, model_nr, red);
|
read_red(i, step13, model_nr, red);
|
||||||
//memset(&step13[3], 0xfE, 106);
|
//memset(&step13[3], 0xfE, 106);
|
||||||
ret = transceive_blocking(step13, 109, rx, 20, actrxlen, true);
|
ret = transceive_blocking(step13, 109, rx, 20, actrxlen, false);
|
||||||
if (ret != PM3_SUCCESS) {
|
if (ret != PM3_SUCCESS) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1882,7 +1882,8 @@ uint32_t static em4x05_Sniff_GetBlock(char *bits, bool fwd) {
|
||||||
if (parity != (bits[35] - '0'))
|
if (parity != (bits[35] - '0'))
|
||||||
parityerror = true;
|
parityerror = true;
|
||||||
|
|
||||||
if (parityerror) printf("parity error : ");
|
if (parityerror)
|
||||||
|
PrintAndLogEx(ERR, "parity error : ");
|
||||||
|
|
||||||
if (!fwd) {
|
if (!fwd) {
|
||||||
uint32_t t1 = value;
|
uint32_t t1 = value;
|
||||||
|
@ -1997,10 +1998,10 @@ int CmdEM4x05Sniff(const char *Cmd) {
|
||||||
((strncmp(bits, "01010", 5) == 0) && (bitidx == 50))) {
|
((strncmp(bits, "01010", 5) == 0) && (bitidx == 50))) {
|
||||||
memmove(bits, &bits[1], bitidx - 1);
|
memmove(bits, &bits[1], bitidx - 1);
|
||||||
bitidx--;
|
bitidx--;
|
||||||
printf("Trim leading 0\n");
|
PrintAndLogEx(INFO, "Trim leading 0");
|
||||||
}
|
}
|
||||||
bits[bitidx] = 0;
|
bits[bitidx] = 0;
|
||||||
// printf ("==> %s\n",bits);
|
|
||||||
// logon
|
// logon
|
||||||
if ((strncmp(bits, "0011", 4) == 0) && (bitidx == 49)) {
|
if ((strncmp(bits, "0011", 4) == 0) && (bitidx == 49)) {
|
||||||
haveData = true;
|
haveData = true;
|
||||||
|
@ -2017,8 +2018,9 @@ int CmdEM4x05Sniff(const char *Cmd) {
|
||||||
sprintf(cmdText, "Write");
|
sprintf(cmdText, "Write");
|
||||||
tmpValue = (bits[4] - '0') + ((bits[5] - '0') << 1) + ((bits[6] - '0') << 2) + ((bits[7] - '0') << 3);
|
tmpValue = (bits[4] - '0') + ((bits[5] - '0') << 1) + ((bits[6] - '0') << 2) + ((bits[7] - '0') << 3);
|
||||||
sprintf(blkAddr, "%d", tmpValue);
|
sprintf(blkAddr, "%d", tmpValue);
|
||||||
if (tmpValue == 2)
|
if (tmpValue == 2) {
|
||||||
pwd = true;
|
pwd = true;
|
||||||
|
}
|
||||||
tmpValue = em4x05_Sniff_GetBlock(&bits[11], fwd);
|
tmpValue = em4x05_Sniff_GetBlock(&bits[11], fwd);
|
||||||
sprintf(dataText, "%08X", tmpValue);
|
sprintf(dataText, "%08X", tmpValue);
|
||||||
}
|
}
|
||||||
|
@ -2057,8 +2059,9 @@ int CmdEM4x05Sniff(const char *Cmd) {
|
||||||
} else {
|
} else {
|
||||||
i = (CycleWidth - ZeroWidth) / 28;
|
i = (CycleWidth - ZeroWidth) / 28;
|
||||||
bits[bitidx++] = '0';
|
bits[bitidx++] = '0';
|
||||||
for (int ii = 0; ii < i; ii++)
|
for (int ii = 0; ii < i; ii++) {
|
||||||
bits[bitidx++] = '1';
|
bits[bitidx++] = '1';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2068,15 +2071,14 @@ int CmdEM4x05Sniff(const char *Cmd) {
|
||||||
// Print results
|
// Print results
|
||||||
if (haveData) { //&& (minWidth > 1) && (maxWidth > minWidth)){
|
if (haveData) { //&& (minWidth > 1) && (maxWidth > minWidth)){
|
||||||
if (pwd)
|
if (pwd)
|
||||||
PrintAndLogEx(SUCCESS, "%6zu | %-10s | "_YELLOW_("%8s")" | "_YELLOW_("%3s")" | %s", pktOffset, cmdText, dataText, blkAddr, bits);
|
PrintAndLogEx(SUCCESS, "%6zu | %-10s | " _YELLOW_("%8s")" | " _YELLOW_("%3s")" | %s", pktOffset, cmdText, dataText, blkAddr, bits);
|
||||||
else
|
else
|
||||||
PrintAndLogEx(SUCCESS, "%6zu | %-10s | "_GREEN_("%8s")" | "_GREEN_("%3s")" | %s", pktOffset, cmdText, dataText, blkAddr, bits);
|
PrintAndLogEx(SUCCESS, "%6zu | %-10s | " _GREEN_("%8s")" | " _GREEN_("%3s")" | %s", pktOffset, cmdText, dataText, blkAddr, bits);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// footer
|
// footer
|
||||||
PrintAndLogEx(SUCCESS, "---------------------------------------------------------------------------------------------------");
|
PrintAndLogEx(SUCCESS, "---------------------------------------------------------------------------------------------------");
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
#include "comms.h" // getfromdevice
|
#include "comms.h" // getfromdevice
|
||||||
#include "emv/emvcore.h" // decodeTVL
|
#include "emv/emvcore.h" // decodeTVL
|
||||||
#include "crypto/libpcrypto.h" // sha512hash
|
#include "crypto/libpcrypto.h" // sha512hash
|
||||||
#include "emv/dump.h"
|
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
|
#include "util.h"
|
||||||
#include "fileutils.h"
|
#include "fileutils.h"
|
||||||
#include "crc16.h" // crc
|
#include "crc16.h" // crc
|
||||||
|
|
||||||
|
@ -316,7 +316,7 @@ static void PrintATR(uint8_t *atr, size_t atrlen) {
|
||||||
|
|
||||||
if (K > 1) {
|
if (K > 1) {
|
||||||
PrintAndLogEx(INFO, "\tHistorical bytes");
|
PrintAndLogEx(INFO, "\tHistorical bytes");
|
||||||
dump_buffer(&atr[2 + T1len + TD1len + TDilen], K, NULL, 1);
|
print_buffer(&atr[2 + T1len + TD1len + TDilen], K, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,23 +15,17 @@
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <jansson.h>
|
#include <jansson.h>
|
||||||
#include <mbedtls/asn1.h>
|
#include <mbedtls/asn1.h>
|
||||||
#include <mbedtls/oid.h>
|
#include <mbedtls/oid.h>
|
||||||
#include "emv/emv_tags.h"
|
#include "emv/emv_tags.h"
|
||||||
#include "emv/dump.h"
|
|
||||||
#include "emv/emvjson.h"
|
#include "emv/emvjson.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "proxmark3.h"
|
#include "proxmark3.h"
|
||||||
#include "fileutils.h"
|
#include "fileutils.h"
|
||||||
#include "pm3_cmd.h"
|
#include "pm3_cmd.h"
|
||||||
|
|
||||||
#ifndef PRINT_INDENT
|
|
||||||
# define PRINT_INDENT(level) {for (int myi = 0; myi < (level); myi++) fprintf(f, " ");}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
enum asn1_tag_t {
|
enum asn1_tag_t {
|
||||||
ASN1_TAG_GENERIC,
|
ASN1_TAG_GENERIC,
|
||||||
ASN1_TAG_BOOLEAN,
|
ASN1_TAG_BOOLEAN,
|
||||||
|
@ -109,65 +103,62 @@ static const struct asn1_tag *asn1_get_tag(const struct tlv *tlv) {
|
||||||
return tag ? tag : &asn1_tags[0];
|
return tag ? tag : &asn1_tags[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void asn1_tag_dump_str_time(const struct tlv *tlv, const struct asn1_tag *tag, FILE *f, int level, bool longyear, bool *needdump) {
|
static void asn1_tag_dump_str_time(const struct tlv *tlv, const struct asn1_tag *tag, int level, bool longyear, bool *needdump) {
|
||||||
int len = tlv->len;
|
int len = tlv->len;
|
||||||
*needdump = false;
|
*needdump = false;
|
||||||
|
|
||||||
int startindx = longyear ? 4 : 2;
|
int startindx = longyear ? 4 : 2;
|
||||||
|
|
||||||
if (len > 4) {
|
if (len > 4) {
|
||||||
fprintf(f, "\tvalue: '");
|
PrintAndLogEx(NORMAL, " value: '" NOLF);
|
||||||
while (true) {
|
while (true) {
|
||||||
// year
|
// year
|
||||||
if (!longyear)
|
if (longyear == false)
|
||||||
fprintf(f, "20");
|
PrintAndLogEx(NORMAL, "20" NOLF);
|
||||||
fwrite(tlv->value, 1, longyear ? 4 : 2, f);
|
|
||||||
fprintf(f, "-");
|
PrintAndLogEx(NORMAL, "%s-" NOLF, sprint_hex(tlv->value, startindx) );
|
||||||
|
|
||||||
if (len < startindx + 2)
|
if (len < startindx + 2)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// month
|
// month
|
||||||
fwrite(&tlv->value[startindx], 1, 2, f);
|
PrintAndLogEx(NORMAL, "%02x%02x-" NOLF, tlv->value[startindx], tlv->value[startindx + 1]);
|
||||||
fprintf(f, "-");
|
|
||||||
if (len < startindx + 4)
|
if (len < startindx + 4)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// day
|
// day
|
||||||
fwrite(&tlv->value[startindx + 2], 1, 2, f);
|
PrintAndLogEx(NORMAL, "%02x%02x " NOLF, tlv->value[startindx + 2], tlv->value[startindx + 3]);
|
||||||
fprintf(f, " ");
|
|
||||||
if (len < startindx + 6)
|
if (len < startindx + 6)
|
||||||
break;
|
break;
|
||||||
// hour
|
// hour
|
||||||
fwrite(&tlv->value[startindx + 4], 1, 2, f);
|
PrintAndLogEx(NORMAL, "%02x%02x:" NOLF, tlv->value[startindx + 4], tlv->value[startindx + 5]);
|
||||||
fprintf(f, ":");
|
|
||||||
if (len < startindx + 8)
|
if (len < startindx + 8)
|
||||||
break;
|
break;
|
||||||
// min
|
// min
|
||||||
fwrite(&tlv->value[startindx + 6], 1, 2, f);
|
PrintAndLogEx(NORMAL, "%02x%02x:" NOLF, tlv->value[startindx + 6], tlv->value[startindx + 7]);
|
||||||
fprintf(f, ":");
|
|
||||||
if (len < startindx + 10)
|
if (len < startindx + 10)
|
||||||
break;
|
break;
|
||||||
// sec
|
// sec
|
||||||
fwrite(&tlv->value[startindx + 8], 1, 2, f);
|
PrintAndLogEx(NORMAL, "%02x%02x" NOLF, tlv->value[startindx + 8], tlv->value[startindx + 9]);
|
||||||
if (len < startindx + 11)
|
if (len < startindx + 11)
|
||||||
break;
|
break;
|
||||||
// time zone
|
// time zone
|
||||||
fprintf(f, " zone: %.*s", len - 10 - (longyear ? 4 : 2), &tlv->value[startindx + 10]);
|
PrintAndLogEx(NORMAL, " zone: %.*s" NOLF, len - 10 - (longyear ? 4 : 2), &tlv->value[startindx + 10]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fprintf(f, "'\n");
|
PrintAndLogEx(NORMAL, "'");
|
||||||
} else {
|
} else {
|
||||||
fprintf(f, "\n");
|
PrintAndLogEx(NORMAL, "");
|
||||||
*needdump = true;
|
*needdump = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void asn1_tag_dump_string(const struct tlv *tlv, const struct asn1_tag *tag, FILE *f, int level) {
|
static void asn1_tag_dump_string(const struct tlv *tlv, const struct asn1_tag *tag, int level) {
|
||||||
fprintf(f, "\tvalue: '");
|
PrintAndLogEx(NORMAL, " value: '" NOLF);
|
||||||
fwrite(tlv->value, 1, tlv->len, f);
|
PrintAndLogEx(NORMAL, "%s'", sprint_hex(tlv->value, tlv->len));
|
||||||
fprintf(f, "'\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void asn1_tag_dump_octet_string(const struct tlv *tlv, const struct asn1_tag *tag, FILE *f, int level, bool *needdump) {
|
static void asn1_tag_dump_octet_string(const struct tlv *tlv, const struct asn1_tag *tag, int level, bool *needdump) {
|
||||||
*needdump = false;
|
*needdump = false;
|
||||||
for (size_t i = 0; i < tlv->len; i++)
|
for (size_t i = 0; i < tlv->len; i++)
|
||||||
if (!isspace(tlv->value[i]) && !isprint(tlv->value[i])) {
|
if (!isspace(tlv->value[i]) && !isprint(tlv->value[i])) {
|
||||||
|
@ -176,10 +167,10 @@ static void asn1_tag_dump_octet_string(const struct tlv *tlv, const struct asn1_
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*needdump) {
|
if (*needdump) {
|
||||||
fprintf(f, "'\n");
|
PrintAndLogEx(NORMAL, "'");
|
||||||
} else {
|
} else {
|
||||||
fprintf(f, "\t\t");
|
PrintAndLogEx(NORMAL, " " NOLF);
|
||||||
asn1_tag_dump_string(tlv, tag, f, level);
|
asn1_tag_dump_string(tlv, tag, level);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,25 +204,26 @@ static unsigned long asn1_value_integer(const struct tlv *tlv, unsigned start, u
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void asn1_tag_dump_boolean(const struct tlv *tlv, const struct asn1_tag *tag, FILE *f, int level) {
|
static void asn1_tag_dump_boolean(const struct tlv *tlv, const struct asn1_tag *tag, int level) {
|
||||||
PRINT_INDENT(level);
|
PrintAndLogEx(NORMAL, "%*s" NOLF, (level * 4), " ");
|
||||||
if (tlv->len > 0) {
|
if (tlv->len > 0) {
|
||||||
fprintf(f, "\tvalue: %s\n", tlv->value[0] ? "true" : "false");
|
PrintAndLogEx(NORMAL, " value: %s", tlv->value[0] ? "true" : "false");
|
||||||
} else {
|
} else {
|
||||||
fprintf(f, "n/a\n");
|
PrintAndLogEx(NORMAL, "n/a");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void asn1_tag_dump_integer(const struct tlv *tlv, const struct asn1_tag *tag, FILE *f, int level) {
|
static void asn1_tag_dump_integer(const struct tlv *tlv, const struct asn1_tag *tag, int level) {
|
||||||
PRINT_INDENT(level);
|
PrintAndLogEx(NORMAL, "%*s" NOLF, (level * 4), " ");
|
||||||
if (tlv->len == 4) {
|
if (tlv->len == 4) {
|
||||||
int32_t val = 0;
|
int32_t val = 0;
|
||||||
for (size_t i = 0; i < tlv->len; i++)
|
for (size_t i = 0; i < tlv->len; i++) {
|
||||||
val = (val << 8) + tlv->value[i];
|
val = (val << 8) + tlv->value[i];
|
||||||
fprintf(f, "\tvalue4b: %d\n", val);
|
}
|
||||||
|
PrintAndLogEx(NORMAL, " value4b: %d", val);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fprintf(f, "\tvalue: %lu\n", asn1_value_integer(tlv, 0, tlv->len * 2));
|
PrintAndLogEx(NORMAL, " value: %lu", asn1_value_integer(tlv, 0, tlv->len * 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *asn1_oid_description(const char *oid, bool with_group_desc) {
|
static char *asn1_oid_description(const char *oid, bool with_group_desc) {
|
||||||
|
@ -277,77 +269,77 @@ error:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void asn1_tag_dump_object_id(const struct tlv *tlv, const struct asn1_tag *tag, FILE *f, int level) {
|
static void asn1_tag_dump_object_id(const struct tlv *tlv, const struct asn1_tag *tag, int level) {
|
||||||
PRINT_INDENT(level);
|
|
||||||
mbedtls_asn1_buf asn1_buf;
|
mbedtls_asn1_buf asn1_buf;
|
||||||
asn1_buf.len = tlv->len;
|
asn1_buf.len = tlv->len;
|
||||||
asn1_buf.p = (uint8_t *)tlv->value;
|
asn1_buf.p = (uint8_t *)tlv->value;
|
||||||
char pstr[300];
|
char pstr[300];
|
||||||
mbedtls_oid_get_numeric_string(pstr, sizeof(pstr), &asn1_buf);
|
mbedtls_oid_get_numeric_string(pstr, sizeof(pstr), &asn1_buf);
|
||||||
fprintf(f, " %s", pstr);
|
|
||||||
|
PrintAndLogEx(INFO, "%*s %s" NOLF, (level * 4), " ", pstr);
|
||||||
|
|
||||||
char *jsondesc = asn1_oid_description(pstr, true);
|
char *jsondesc = asn1_oid_description(pstr, true);
|
||||||
if (jsondesc) {
|
if (jsondesc) {
|
||||||
fprintf(f, " - %s", jsondesc);
|
PrintAndLogEx(NORMAL, " - %s" NOLF, jsondesc);
|
||||||
} else {
|
} else {
|
||||||
const char *ppstr;
|
const char *ppstr;
|
||||||
mbedtls_oid_get_attr_short_name(&asn1_buf, &ppstr);
|
mbedtls_oid_get_attr_short_name(&asn1_buf, &ppstr);
|
||||||
if (ppstr && strnlen(ppstr, 1)) {
|
if (ppstr && strnlen(ppstr, 1)) {
|
||||||
fprintf(f, " (%s)\n", ppstr);
|
PrintAndLogEx(NORMAL, " (%s)", ppstr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mbedtls_oid_get_sig_alg_desc(&asn1_buf, &ppstr);
|
mbedtls_oid_get_sig_alg_desc(&asn1_buf, &ppstr);
|
||||||
if (ppstr && strnlen(ppstr, 1)) {
|
if (ppstr && strnlen(ppstr, 1)) {
|
||||||
fprintf(f, " (%s)\n", ppstr);
|
PrintAndLogEx(NORMAL, " (%s)", ppstr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mbedtls_oid_get_extended_key_usage(&asn1_buf, &ppstr);
|
mbedtls_oid_get_extended_key_usage(&asn1_buf, &ppstr);
|
||||||
if (ppstr && strnlen(ppstr, 1)) {
|
if (ppstr && strnlen(ppstr, 1)) {
|
||||||
fprintf(f, " (%s)\n", ppstr);
|
PrintAndLogEx(NORMAL, " (%s)", ppstr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fprintf(f, "\n");
|
PrintAndLogEx(NORMAL, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool asn1_tag_dump(const struct tlv *tlv, FILE *f, int level, bool *candump) {
|
bool asn1_tag_dump(const struct tlv *tlv, int level, bool *candump) {
|
||||||
if (!tlv) {
|
if (tlv == NULL) {
|
||||||
fprintf(f, "NULL\n");
|
PrintAndLogEx(FAILED, "NULL\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct asn1_tag *tag = asn1_get_tag(tlv);
|
const struct asn1_tag *tag = asn1_get_tag(tlv);
|
||||||
|
|
||||||
PRINT_INDENT(level);
|
PrintAndLogEx(INFO, "%*s--%2x[%02zx] '%s':" NOLF, (level * 4), " ", tlv->tag, tlv->len, tag->name);
|
||||||
fprintf(f, "--%2x[%02zx] '%s':", tlv->tag, tlv->len, tag->name);
|
|
||||||
|
|
||||||
switch (tag->type) {
|
switch (tag->type) {
|
||||||
case ASN1_TAG_GENERIC:
|
case ASN1_TAG_GENERIC:
|
||||||
fprintf(f, "\n");
|
PrintAndLogEx(NORMAL, "");
|
||||||
break;
|
break;
|
||||||
case ASN1_TAG_STRING:
|
case ASN1_TAG_STRING:
|
||||||
asn1_tag_dump_string(tlv, tag, f, level);
|
asn1_tag_dump_string(tlv, tag, level);
|
||||||
*candump = false;
|
*candump = false;
|
||||||
break;
|
break;
|
||||||
case ASN1_TAG_OCTET_STRING:
|
case ASN1_TAG_OCTET_STRING:
|
||||||
asn1_tag_dump_octet_string(tlv, tag, f, level, candump);
|
asn1_tag_dump_octet_string(tlv, tag, level, candump);
|
||||||
break;
|
break;
|
||||||
case ASN1_TAG_BOOLEAN:
|
case ASN1_TAG_BOOLEAN:
|
||||||
asn1_tag_dump_boolean(tlv, tag, f, level);
|
asn1_tag_dump_boolean(tlv, tag, level);
|
||||||
*candump = false;
|
*candump = false;
|
||||||
break;
|
break;
|
||||||
case ASN1_TAG_INTEGER:
|
case ASN1_TAG_INTEGER:
|
||||||
asn1_tag_dump_integer(tlv, tag, f, level);
|
asn1_tag_dump_integer(tlv, tag, level);
|
||||||
*candump = false;
|
*candump = false;
|
||||||
break;
|
break;
|
||||||
case ASN1_TAG_UTC_TIME:
|
case ASN1_TAG_UTC_TIME:
|
||||||
asn1_tag_dump_str_time(tlv, tag, f, level, false, candump);
|
asn1_tag_dump_str_time(tlv, tag, level, false, candump);
|
||||||
break;
|
break;
|
||||||
case ASN1_TAG_STR_TIME:
|
case ASN1_TAG_STR_TIME:
|
||||||
asn1_tag_dump_str_time(tlv, tag, f, level, true, candump);
|
asn1_tag_dump_str_time(tlv, tag, level, true, candump);
|
||||||
break;
|
break;
|
||||||
case ASN1_TAG_OBJECT_ID:
|
case ASN1_TAG_OBJECT_ID:
|
||||||
asn1_tag_dump_object_id(tlv, tag, f, level);
|
asn1_tag_dump_object_id(tlv, tag, level);
|
||||||
*candump = false;
|
*candump = false;
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,9 +13,8 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include "emv/tlv.h"
|
#include "emv/tlv.h"
|
||||||
|
|
||||||
bool asn1_tag_dump(const struct tlv *tlv, FILE *f, int level, bool *candump);
|
bool asn1_tag_dump(const struct tlv *tlv, int level, bool *candump);
|
||||||
|
|
||||||
#endif /* asn1utils.h */
|
#endif /* asn1utils.h */
|
||||||
|
|
|
@ -12,19 +12,16 @@
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <mbedtls/asn1.h>
|
#include <mbedtls/asn1.h>
|
||||||
|
|
||||||
#include "ui.h" // Print...
|
#include "ui.h" // Print...
|
||||||
|
|
||||||
#include "emv/tlv.h"
|
#include "emv/tlv.h"
|
||||||
#include "emv/dump.h"
|
|
||||||
#include "asn1dump.h"
|
#include "asn1dump.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
int ecdsa_asn1_get_signature(uint8_t *signature, size_t signaturelen, uint8_t *rval, uint8_t *sval) {
|
int ecdsa_asn1_get_signature(uint8_t *signature, size_t signaturelen, uint8_t *rval, uint8_t *sval) {
|
||||||
if (!signature || !signaturelen || !rval || !sval)
|
if (!signature || !signaturelen || !rval || !sval)
|
||||||
return 1;
|
return PM3_EINVARG;
|
||||||
|
|
||||||
int res = 0;
|
int res = PM3_SUCCESS;
|
||||||
unsigned char *p = signature;
|
unsigned char *p = signature;
|
||||||
const unsigned char *end = p + signaturelen;
|
const unsigned char *end = p + signaturelen;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
@ -57,7 +54,7 @@ int ecdsa_asn1_get_signature(uint8_t *signature, size_t signaturelen, uint8_t *r
|
||||||
|
|
||||||
// check size
|
// check size
|
||||||
if (end != p)
|
if (end != p)
|
||||||
return 2;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
|
@ -66,9 +63,9 @@ exit:
|
||||||
|
|
||||||
static void print_cb(void *data, const struct tlv *tlv, int level, bool is_leaf) {
|
static void print_cb(void *data, const struct tlv *tlv, int level, bool is_leaf) {
|
||||||
bool candump = true;
|
bool candump = true;
|
||||||
asn1_tag_dump(tlv, stdout, level, &candump);
|
asn1_tag_dump(tlv, level, &candump);
|
||||||
if (is_leaf && candump) {
|
if (is_leaf && candump) {
|
||||||
dump_buffer(tlv->value, tlv->len, stdout, level);
|
print_buffer(tlv->value, tlv->len, level);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,10 +77,10 @@ int asn1_print(uint8_t *asn1buf, size_t asn1buflen, const char *indent) {
|
||||||
tlvdb_free(t);
|
tlvdb_free(t);
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(ERR, "Can't parse data as TLV tree");
|
PrintAndLogEx(ERR, "Can't parse data as TLV tree");
|
||||||
return 1;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -418,7 +418,7 @@ int ecdsa_nist_test(bool verbose) {
|
||||||
// make signature
|
// make signature
|
||||||
res = ecdsa_signature_create_test(curveid, T_PRIVATE_KEY, T_Q_X, T_Q_Y, T_K, input, length, signature, &siglen);
|
res = ecdsa_signature_create_test(curveid, T_PRIVATE_KEY, T_Q_X, T_Q_Y, T_K, input, length, signature, &siglen);
|
||||||
// PrintAndLogEx(INFO, "res: %x signature[%x]: %s", (res < 0)? -res : res, siglen, sprint_hex(signature, siglen));
|
// PrintAndLogEx(INFO, "res: %x signature[%x]: %s", (res < 0)? -res : res, siglen, sprint_hex(signature, siglen));
|
||||||
if (res)
|
if (res != PM3_SUCCESS)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
// check vectors
|
// check vectors
|
||||||
|
@ -483,7 +483,7 @@ int ecdsa_nist_test(bool verbose) {
|
||||||
if (verbose)
|
if (verbose)
|
||||||
PrintAndLogEx(NORMAL, _GREEN_("passed\n"));
|
PrintAndLogEx(NORMAL, _GREEN_("passed\n"));
|
||||||
|
|
||||||
return 0;
|
return PM3_SUCCESS;
|
||||||
exit:
|
exit:
|
||||||
if (verbose)
|
if (verbose)
|
||||||
PrintAndLogEx(NORMAL, _RED_("failed\n"));
|
PrintAndLogEx(NORMAL, _RED_("failed\n"));
|
||||||
|
|
|
@ -1153,7 +1153,7 @@ static int CmdEMVExec(const char *Cmd) {
|
||||||
// 9F27: Cryptogram Information Data (CID)
|
// 9F27: Cryptogram Information Data (CID)
|
||||||
const struct tlv *CID = tlvdb_get(tlvRoot, 0x9F27, NULL);
|
const struct tlv *CID = tlvdb_get(tlvRoot, 0x9F27, NULL);
|
||||||
if (CID) {
|
if (CID) {
|
||||||
emv_tag_dump(CID, stdout, 0);
|
emv_tag_dump(CID, 1);
|
||||||
PrintAndLogEx(NORMAL, "------------------------------");
|
PrintAndLogEx(NORMAL, "------------------------------");
|
||||||
if (CID->len > 0) {
|
if (CID->len > 0) {
|
||||||
switch (CID->value[0] & EMVAC_AC_MASK) {
|
switch (CID->value[0] & EMVAC_AC_MASK) {
|
||||||
|
@ -1356,10 +1356,10 @@ static int CmdEMVExec(const char *Cmd) {
|
||||||
// here must be AC2, but we dont make external authenticate (
|
// here must be AC2, but we dont make external authenticate (
|
||||||
/* // AC2
|
/* // AC2
|
||||||
PRINT_INDENT(level);
|
PRINT_INDENT(level);
|
||||||
if ((CID & EMVAC_AC2_MASK) == EMVAC_AAC2) fprintf(f, "\tAC2: AAC (Transaction declined)\n");
|
if ((CID & EMVAC_AC2_MASK) == EMVAC_AAC2) PrintAndLogEx(NORMAL, "\tAC2: AAC (Transaction declined)");
|
||||||
if ((CID & EMVAC_AC2_MASK) == EMVAC_TC2) fprintf(f, "\tAC2: TC (Transaction approved)\n");
|
if ((CID & EMVAC_AC2_MASK) == EMVAC_TC2) PrintAndLogEx(NORMAL, "\tAC2: TC (Transaction approved)");
|
||||||
if ((CID & EMVAC_AC2_MASK) == EMVAC_ARQC2) fprintf(f, "\tAC2: not requested (ARQC)\n");
|
if ((CID & EMVAC_AC2_MASK) == EMVAC_ARQC2) PrintAndLogEx(NORMAL, "\tAC2: not requested (ARQC)");
|
||||||
if ((CID & EMVAC_AC2_MASK) == EMVAC_AC2_MASK) fprintf(f, "\tAC2: RFU\n");
|
if ((CID & EMVAC_AC2_MASK) == EMVAC_AC2_MASK) PrintAndLogEx(NORMAL, "\tAC2: RFU");
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,47 +0,0 @@
|
||||||
/*
|
|
||||||
* libopenemv - a library to work with EMV family of smart cards
|
|
||||||
* Copyright (C) 2015 Dmitry Eremin-Solenikov
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "dump.h"
|
|
||||||
|
|
||||||
#ifndef PRINT_INDENT
|
|
||||||
# define PRINT_INDENT(level) {for (int myi = 0; myi < (level); myi++) fprintf(f, " ");}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void dump_buffer(const unsigned char *ptr, size_t len, FILE *f, int level) {
|
|
||||||
int j;
|
|
||||||
|
|
||||||
if (!f)
|
|
||||||
f = stdout;
|
|
||||||
|
|
||||||
for (int i = 0; i < len; i += 16) {
|
|
||||||
PRINT_INDENT(level);
|
|
||||||
fprintf(f, "\t%02x:", i);
|
|
||||||
for (j = 0; j < 16; j++) {
|
|
||||||
if (i + j < len)
|
|
||||||
fprintf(f, " %02hhx", ptr[i + j]);
|
|
||||||
else
|
|
||||||
fprintf(f, " ");
|
|
||||||
}
|
|
||||||
fprintf(f, " |");
|
|
||||||
for (j = 0; j < 16 && i + j < len; j++) {
|
|
||||||
fprintf(f, "%c", (ptr[i + j] >= 0x20 && ptr[i + j] < 0x7f) ? ptr[i + j] : '.');
|
|
||||||
}
|
|
||||||
fprintf(f, "\n");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
/*
|
|
||||||
* libopenemv - a library to work with EMV family of smart cards
|
|
||||||
* Copyright (C) 2015 Dmitry Eremin-Solenikov
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef DUMP_H
|
|
||||||
#define DUMP_H
|
|
||||||
|
|
||||||
#include "common.h"
|
|
||||||
|
|
||||||
#include <stdio.h> // FILE
|
|
||||||
|
|
||||||
void dump_buffer(const unsigned char *ptr, size_t len, FILE *f, int level);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -24,7 +24,6 @@
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
#include "crypto.h"
|
#include "crypto.h"
|
||||||
#include "dump.h"
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
|
|
||||||
|
@ -73,7 +72,7 @@ static unsigned char *emv_pki_decode_message(const struct emv_pk *enc_pk,
|
||||||
|
|
||||||
/* if (true){
|
/* if (true){
|
||||||
PrintAndLogEx(SUCCESS, "Recovered data:\n");
|
PrintAndLogEx(SUCCESS, "Recovered data:\n");
|
||||||
dump_buffer(data, data_len, stdout, 0);
|
print_buffer(data, data_len, 1);
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
if (data[data_len - 1] != 0xbc || data[0] != 0x6a || data[1] != msgtype) {
|
if (data[data_len - 1] != 0xbc || data[0] != 0x6a || data[1] != msgtype) {
|
||||||
|
@ -200,7 +199,7 @@ static struct emv_pk *emv_pki_decode_key_ex(const struct emv_pk *enc_pk,
|
||||||
|
|
||||||
if (showData) {
|
if (showData) {
|
||||||
PrintAndLogEx(SUCCESS, "Recovered data:");
|
PrintAndLogEx(SUCCESS, "Recovered data:");
|
||||||
dump_buffer(data, data_len, stdout, 0);
|
print_buffer(data, data_len, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Perform the rest of checks here */
|
/* Perform the rest of checks here */
|
||||||
|
@ -375,7 +374,7 @@ struct tlvdb *emv_pki_recover_dac_ex(const struct emv_pk *enc_pk, const struct t
|
||||||
|
|
||||||
if (showData) {
|
if (showData) {
|
||||||
PrintAndLogEx(SUCCESS, "Recovered data:");
|
PrintAndLogEx(SUCCESS, "Recovered data:");
|
||||||
dump_buffer(data, data_len, stdout, 0);
|
print_buffer(data, data_len, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct tlvdb *dac_db = tlvdb_fixed(0x9f45, 2, data + 3);
|
struct tlvdb *dac_db = tlvdb_fixed(0x9f45, 2, data + 3);
|
||||||
|
@ -409,7 +408,7 @@ struct tlvdb *emv_pki_recover_idn_ex(const struct emv_pk *enc_pk, const struct t
|
||||||
|
|
||||||
if (showData) {
|
if (showData) {
|
||||||
PrintAndLogEx(SUCCESS, "Recovered data:");
|
PrintAndLogEx(SUCCESS, "Recovered data:");
|
||||||
dump_buffer(data, data_len, stdout, 0);
|
print_buffer(data, data_len, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t idn_len = data[4];
|
size_t idn_len = data[4];
|
||||||
|
@ -445,7 +444,7 @@ struct tlvdb *emv_pki_recover_atc_ex(const struct emv_pk *enc_pk, const struct t
|
||||||
|
|
||||||
if (showData) {
|
if (showData) {
|
||||||
PrintAndLogEx(SUCCESS, "Recovered data:");
|
PrintAndLogEx(SUCCESS, "Recovered data:");
|
||||||
dump_buffer(data, data_len, stdout, 0);
|
print_buffer(data, data_len, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t idn_len = data[4];
|
size_t idn_len = data[4];
|
||||||
|
@ -511,7 +510,7 @@ struct tlvdb *emv_pki_perform_cda_ex(const struct emv_pk *enc_pk, const struct t
|
||||||
|
|
||||||
if (showData) {
|
if (showData) {
|
||||||
PrintAndLogEx(SUCCESS, "Recovered data:");
|
PrintAndLogEx(SUCCESS, "Recovered data:");
|
||||||
dump_buffer(data, data_len, stdout, 0);
|
print_buffer(data, data_len, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data[3] < 30 || data[3] > data_len - 4) {
|
if (data[3] < 30 || data[3] > data_len - 4) {
|
||||||
|
|
|
@ -18,15 +18,10 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "emv_tags.h"
|
#include "emv_tags.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "commonutil.h"
|
#include "commonutil.h"
|
||||||
|
#include "ui.h"
|
||||||
#ifndef PRINT_INDENT
|
|
||||||
# define PRINT_INDENT(level) {for (int myi = 0; myi < (level); myi++) fprintf(f, " ");}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
enum emv_tag_t {
|
enum emv_tag_t {
|
||||||
EMV_TAG_GENERIC,
|
EMV_TAG_GENERIC,
|
||||||
|
@ -455,19 +450,21 @@ static const char *bitstrings[] = {
|
||||||
"1.......",
|
"1.......",
|
||||||
};
|
};
|
||||||
|
|
||||||
static void emv_tag_dump_bitmask(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) {
|
static void emv_tag_dump_bitmask(const struct tlv *tlv, const struct emv_tag *tag, int level) {
|
||||||
const struct emv_tag_bit *bits = tag->data;
|
const struct emv_tag_bit *bits = tag->data;
|
||||||
unsigned bit, byte;
|
unsigned bit, byte;
|
||||||
|
|
||||||
for (byte = 1; byte <= tlv->len; byte ++) {
|
for (byte = 1; byte <= tlv->len; byte ++) {
|
||||||
unsigned char val = tlv->value[byte - 1];
|
unsigned char val = tlv->value[byte - 1];
|
||||||
PRINT_INDENT(level);
|
PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " ");
|
||||||
fprintf(f, "\tByte %u (%02x)\n", byte, val);
|
PrintAndLogEx(NORMAL, " Byte %u (%02x)", byte, val);
|
||||||
for (bit = 8; bit > 0; bit--, val <<= 1) {
|
for (bit = 8; bit > 0; bit--, val <<= 1) {
|
||||||
if (val & 0x80) {
|
if (val & 0x80) {
|
||||||
PRINT_INDENT(level);
|
PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " ");
|
||||||
fprintf(f, "\t\t%s - '%s'\n", bitstrings[bit - 1],
|
PrintAndLogEx(NORMAL, " %s - '%s'",
|
||||||
bits->bit == EMV_BIT(byte, bit) ? bits->name : "Unknown");
|
bitstrings[bit - 1],
|
||||||
|
(bits->bit == EMV_BIT(byte, bit)) ? bits->name : "Unknown"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (bits->bit == EMV_BIT(byte, bit))
|
if (bits->bit == EMV_BIT(byte, bit))
|
||||||
bits ++;
|
bits ++;
|
||||||
|
@ -475,7 +472,7 @@ static void emv_tag_dump_bitmask(const struct tlv *tlv, const struct emv_tag *ta
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void emv_tag_dump_dol(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) {
|
static void emv_tag_dump_dol(const struct tlv *tlv, const struct emv_tag *tag, int level) {
|
||||||
const unsigned char *buf = tlv->value;
|
const unsigned char *buf = tlv->value;
|
||||||
size_t left = tlv->len;
|
size_t left = tlv->len;
|
||||||
|
|
||||||
|
@ -484,22 +481,20 @@ static void emv_tag_dump_dol(const struct tlv *tlv, const struct emv_tag *tag, F
|
||||||
const struct emv_tag *doltag;
|
const struct emv_tag *doltag;
|
||||||
|
|
||||||
if (!tlv_parse_tl(&buf, &left, &doltlv)) {
|
if (!tlv_parse_tl(&buf, &left, &doltlv)) {
|
||||||
PRINT_INDENT(level);
|
PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " ");
|
||||||
fprintf(f, "Invalid Tag-Len\n");
|
PrintAndLogEx(NORMAL, "Invalid Tag-Len");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
doltag = emv_get_tag(&doltlv);
|
doltag = emv_get_tag(&doltlv);
|
||||||
|
|
||||||
PRINT_INDENT(level);
|
PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " ");
|
||||||
fprintf(f, "\tTag %4x len %02zx ('%s')\n", doltlv.tag, doltlv.len, doltag->name);
|
PrintAndLogEx(NORMAL, " Tag %4x len %02zx ('%s')", doltlv.tag, doltlv.len, doltag->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void emv_tag_dump_string(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) {
|
static void emv_tag_dump_string(const struct tlv *tlv, const struct emv_tag *tag, int level) {
|
||||||
fprintf(f, "\tString value '");
|
PrintAndLogEx(NORMAL, " String value '%s'", sprint_hex_inrow(tlv->value, tlv->len));
|
||||||
fwrite(tlv->value, 1, tlv->len, f);
|
|
||||||
fprintf(f, "'\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned long emv_value_numeric(const struct tlv *tlv, unsigned start, unsigned end) {
|
static unsigned long emv_value_numeric(const struct tlv *tlv, unsigned start, unsigned end) {
|
||||||
|
@ -532,17 +527,18 @@ static unsigned long emv_value_numeric(const struct tlv *tlv, unsigned start, un
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void emv_tag_dump_numeric(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) {
|
static void emv_tag_dump_numeric(const struct tlv *tlv, const struct emv_tag *tag, int level) {
|
||||||
PRINT_INDENT(level);
|
PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " ");
|
||||||
fprintf(f, "\tNumeric value %lu\n", emv_value_numeric(tlv, 0, tlv->len * 2));
|
PrintAndLogEx(NORMAL, " Numeric value %lu", emv_value_numeric(tlv, 0, tlv->len * 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void emv_tag_dump_yymmdd(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) {
|
static void emv_tag_dump_yymmdd(const struct tlv *tlv, const struct emv_tag *tag, int level) {
|
||||||
PRINT_INDENT(level);
|
PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " ");
|
||||||
fprintf(f, "\tDate: 20%02lu.%lu.%lu\n",
|
PrintAndLogEx(NORMAL, " Date: 20%02lu.%lu.%lu",
|
||||||
emv_value_numeric(tlv, 0, 2),
|
emv_value_numeric(tlv, 0, 2),
|
||||||
emv_value_numeric(tlv, 2, 4),
|
emv_value_numeric(tlv, 2, 4),
|
||||||
emv_value_numeric(tlv, 4, 6));
|
emv_value_numeric(tlv, 4, 6)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t emv_get_binary(const unsigned char *S) {
|
static uint32_t emv_get_binary(const unsigned char *S) {
|
||||||
|
@ -550,44 +546,44 @@ static uint32_t emv_get_binary(const unsigned char *S) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://github.com/binaryfoo/emv-bertlv/blob/master/src/main/resources/fields/visa-cvr.txt
|
// https://github.com/binaryfoo/emv-bertlv/blob/master/src/main/resources/fields/visa-cvr.txt
|
||||||
static void emv_tag_dump_cvr(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) {
|
static void emv_tag_dump_cvr(const struct tlv *tlv, const struct emv_tag *tag, int level) {
|
||||||
if (!tlv || tlv->len < 1) {
|
if (tlv == NULL || tlv->len < 1) {
|
||||||
PRINT_INDENT(level);
|
PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " ");
|
||||||
fprintf(f, "\tINVALID!\n");
|
PrintAndLogEx(NORMAL, " INVALID length!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tlv->len != tlv->value[0] + 1) {
|
if (tlv->len != tlv->value[0] + 1) {
|
||||||
PRINT_INDENT(level);
|
PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " ");
|
||||||
fprintf(f, "\tINVALID length!\n");
|
PrintAndLogEx(NORMAL, " INVALID length!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tlv->len >= 2) {
|
if (tlv->len >= 2) {
|
||||||
// AC1
|
// AC1
|
||||||
PRINT_INDENT(level);
|
PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " ");
|
||||||
if ((tlv->value[1] & 0xC0) == 0x00) fprintf(f, "\tAC1: AAC (Transaction declined)\n");
|
if ((tlv->value[1] & 0xC0) == 0x00) PrintAndLogEx(NORMAL, " AC1: AAC (Transaction declined)");
|
||||||
if ((tlv->value[1] & 0xC0) == 0x40) fprintf(f, "\tAC1: TC (Transaction approved)\n");
|
if ((tlv->value[1] & 0xC0) == 0x40) PrintAndLogEx(NORMAL, " AC1: TC (Transaction approved)");
|
||||||
if ((tlv->value[1] & 0xC0) == 0x80) fprintf(f, "\tAC1: ARQC (Online authorisation requested)\n");
|
if ((tlv->value[1] & 0xC0) == 0x80) PrintAndLogEx(NORMAL, " AC1: ARQC (Online authorisation requested)");
|
||||||
if ((tlv->value[1] & 0xC0) == 0xC0) fprintf(f, "\tAC1: RFU\n");
|
if ((tlv->value[1] & 0xC0) == 0xC0) PrintAndLogEx(NORMAL, " AC1: RFU");
|
||||||
// AC2
|
// AC2
|
||||||
PRINT_INDENT(level);
|
PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " ");
|
||||||
if ((tlv->value[1] & 0x30) == 0x00) fprintf(f, "\tAC2: AAC (Transaction declined)\n");
|
if ((tlv->value[1] & 0x30) == 0x00) PrintAndLogEx(NORMAL, " AC2: AAC (Transaction declined)");
|
||||||
if ((tlv->value[1] & 0x30) == 0x10) fprintf(f, "\tAC2: TC (Transaction approved)\n");
|
if ((tlv->value[1] & 0x30) == 0x10) PrintAndLogEx(NORMAL, " AC2: TC (Transaction approved)");
|
||||||
if ((tlv->value[1] & 0x30) == 0x20) fprintf(f, "\tAC2: not requested (ARQC)\n");
|
if ((tlv->value[1] & 0x30) == 0x20) PrintAndLogEx(NORMAL, " AC2: not requested (ARQC)");
|
||||||
if ((tlv->value[1] & 0x30) == 0x30) fprintf(f, "\tAC2: RFU\n");
|
if ((tlv->value[1] & 0x30) == 0x30) PrintAndLogEx(NORMAL, " AC2: RFU");
|
||||||
}
|
}
|
||||||
if (tlv->len >= 3 && (tlv->value[2] >> 4)) {
|
if (tlv->len >= 3 && (tlv->value[2] >> 4)) {
|
||||||
PRINT_INDENT(level);
|
PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " ");
|
||||||
fprintf(f, "\tPIN try: %x\n", tlv->value[2] >> 4);
|
PrintAndLogEx(NORMAL, " PIN try: %x", tlv->value[2] >> 4);
|
||||||
}
|
}
|
||||||
if (tlv->len >= 4 && (tlv->value[3] & 0x0F)) {
|
if (tlv->len >= 4 && (tlv->value[3] & 0x0F)) {
|
||||||
PRINT_INDENT(level);
|
PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " ");
|
||||||
fprintf(f, "\tIssuer discretionary bits: %x\n", tlv->value[3] & 0x0F);
|
PrintAndLogEx(NORMAL, " Issuer discretionary bits: %x", tlv->value[3] & 0x0F);
|
||||||
}
|
}
|
||||||
if (tlv->len >= 5 && (tlv->value[4] >> 4)) {
|
if (tlv->len >= 5 && (tlv->value[4] >> 4)) {
|
||||||
PRINT_INDENT(level);
|
PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " ");
|
||||||
fprintf(f, "\tSuccessfully processed issuer script commands: %x\n", tlv->value[4] >> 4);
|
PrintAndLogEx(NORMAL, " Successfully processed issuer script commands: %x", tlv->value[4] >> 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
// mask 0F 0F F0 0F
|
// mask 0F 0F F0 0F
|
||||||
|
@ -610,68 +606,73 @@ static void emv_tag_dump_cvr(const struct tlv *tlv, const struct emv_tag *tag, F
|
||||||
};
|
};
|
||||||
|
|
||||||
if (data[0] || data[1] || data[2] || data[3])
|
if (data[0] || data[1] || data[2] || data[3])
|
||||||
emv_tag_dump_bitmask(&bit_tlv, &bit_tag, f, level);
|
emv_tag_dump_bitmask(&bit_tlv, &bit_tag, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
// EMV Book 3
|
// EMV Book 3
|
||||||
static void emv_tag_dump_cid(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) {
|
static void emv_tag_dump_cid(const struct tlv *tlv, const struct emv_tag *tag, int level) {
|
||||||
if (!tlv || tlv->len < 1) {
|
if (tlv == NULL || tlv->len < 1) {
|
||||||
PRINT_INDENT(level);
|
PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " ");
|
||||||
fprintf(f, "\tINVALID!\n");
|
PrintAndLogEx(NORMAL, " INVALID!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRINT_INDENT(level);
|
PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " ");
|
||||||
if ((tlv->value[0] & EMVAC_AC_MASK) == EMVAC_AAC) fprintf(f, "\tAC1: AAC (Transaction declined)\n");
|
|
||||||
if ((tlv->value[0] & EMVAC_AC_MASK) == EMVAC_TC) fprintf(f, "\tAC1: TC (Transaction approved)\n");
|
if ((tlv->value[0] & EMVAC_AC_MASK) == EMVAC_AAC)
|
||||||
if ((tlv->value[0] & EMVAC_AC_MASK) == EMVAC_ARQC) fprintf(f, "\tAC1: ARQC (Online authorisation requested)\n");
|
PrintAndLogEx(NORMAL, " AC1: AAC (Transaction declined)");
|
||||||
if ((tlv->value[0] & EMVAC_AC_MASK) == EMVAC_AC_MASK) fprintf(f, "\tAC1: RFU\n");
|
if ((tlv->value[0] & EMVAC_AC_MASK) == EMVAC_TC)
|
||||||
|
PrintAndLogEx(NORMAL, " AC1: TC (Transaction approved)");
|
||||||
|
if ((tlv->value[0] & EMVAC_AC_MASK) == EMVAC_ARQC)
|
||||||
|
PrintAndLogEx(NORMAL, " AC1: ARQC (Online authorisation requested)");
|
||||||
|
if ((tlv->value[0] & EMVAC_AC_MASK) == EMVAC_AC_MASK)
|
||||||
|
PrintAndLogEx(NORMAL, " AC1: RFU");
|
||||||
|
|
||||||
if (tlv->value[0] & EMVCID_ADVICE) {
|
if (tlv->value[0] & EMVCID_ADVICE) {
|
||||||
PRINT_INDENT(level);
|
PrintAndLogEx(NORMAL, "%*s" NOLF, (level * 4), " ");
|
||||||
fprintf(f, "\tAdvice required!\n");
|
PrintAndLogEx(NORMAL, " Advice required!");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tlv->value[0] & EMVCID_REASON_MASK) {
|
if (tlv->value[0] & EMVCID_REASON_MASK) {
|
||||||
PRINT_INDENT(level);
|
PrintAndLogEx(NORMAL, "%*s" NOLF, (level * 4), " ");
|
||||||
fprintf(f, "\tReason/advice/referral code: ");
|
PrintAndLogEx(NORMAL, " Reason/advice/referral code: " NOLF);
|
||||||
switch ((tlv->value[0] & EMVCID_REASON_MASK)) {
|
switch ((tlv->value[0] & EMVCID_REASON_MASK)) {
|
||||||
case 0:
|
case 0:
|
||||||
fprintf(f, "No information given\n");
|
PrintAndLogEx(NORMAL, "No information given");
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
fprintf(f, "Service not allowed\n");
|
PrintAndLogEx(NORMAL, "Service not allowed");
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
fprintf(f, "PIN Try Limit exceeded\n");
|
PrintAndLogEx(NORMAL, "PIN Try Limit exceeded");
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
fprintf(f, "Issuer authentication failed\n");
|
PrintAndLogEx(NORMAL, "Issuer authentication failed");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(f, "\tRFU: %2x\n", (tlv->value[0] & EMVCID_REASON_MASK));
|
PrintAndLogEx(NORMAL, " RFU: %2x", (tlv->value[0] & EMVCID_REASON_MASK));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void emv_tag_dump_cvm_list(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) {
|
static void emv_tag_dump_cvm_list(const struct tlv *tlv, const struct emv_tag *tag, int level) {
|
||||||
uint32_t X, Y;
|
uint32_t X, Y;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (tlv->len < 10 || tlv->len % 2) {
|
if (tlv->len < 10 || tlv->len % 2) {
|
||||||
PRINT_INDENT(level);
|
PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " ");
|
||||||
fprintf(f, "\tINVALID!\n");
|
PrintAndLogEx(NORMAL, " INVALID!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
X = emv_get_binary(tlv->value);
|
X = emv_get_binary(tlv->value);
|
||||||
Y = emv_get_binary(tlv->value + 4);
|
Y = emv_get_binary(tlv->value + 4);
|
||||||
|
|
||||||
PRINT_INDENT(level);
|
PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " ");
|
||||||
fprintf(f, "\tX: %u\n", X);
|
PrintAndLogEx(NORMAL, " X: %u", X);
|
||||||
PRINT_INDENT(level);
|
PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " ");
|
||||||
fprintf(f, "\tY: %u\n", Y);
|
PrintAndLogEx(NORMAL, " Y: %u", Y);
|
||||||
|
|
||||||
for (i = 8; i < tlv->len; i += 2) {
|
for (i = 8; i < tlv->len; i += 2) {
|
||||||
const char *method;
|
const char *method;
|
||||||
|
@ -746,73 +747,76 @@ static void emv_tag_dump_cvm_list(const struct tlv *tlv, const struct emv_tag *t
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRINT_INDENT(level);
|
PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " ");
|
||||||
fprintf(f, "\t%02x %02x: '%s' '%s' and '%s' if this CVM is unsuccessful\n",
|
PrintAndLogEx(NORMAL, " %02x %02x: '%s' '%s' and '%s' if this CVM is unsuccessful",
|
||||||
tlv->value[i], tlv->value[i + 1],
|
tlv->value[i],
|
||||||
method, condition, (tlv->value[i] & 0x40) ? "continue" : "fail");
|
tlv->value[i + 1],
|
||||||
|
method,
|
||||||
|
condition,
|
||||||
|
(tlv->value[i] & 0x40) ? "continue" : "fail"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void emv_tag_dump_afl(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) {
|
static void emv_tag_dump_afl(const struct tlv *tlv, const struct emv_tag *tag, int level) {
|
||||||
if (tlv->len < 4 || tlv->len % 4) {
|
if (tlv->len < 4 || tlv->len % 4) {
|
||||||
PRINT_INDENT(level);
|
PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " ");
|
||||||
fprintf(f, "\tINVALID!\n");
|
PrintAndLogEx(NORMAL, " INVALID!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < tlv->len / 4; i++) {
|
for (int i = 0; i < tlv->len / 4; i++) {
|
||||||
PRINT_INDENT(level);
|
PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " ");
|
||||||
fprintf(f, "SFI[%02x] start:%02x end:%02x offline:%02x\n", tlv->value[i * 4 + 0] >> 3, tlv->value[i * 4 + 1], tlv->value[i * 4 + 2], tlv->value[i * 4 + 3]);
|
PrintAndLogEx(NORMAL, "SFI[%02x] start:%02x end:%02x offline:%02x", tlv->value[i * 4 + 0] >> 3, tlv->value[i * 4 + 1], tlv->value[i * 4 + 2], tlv->value[i * 4 + 3]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emv_tag_dump(const struct tlv *tlv, FILE *f, int level) {
|
bool emv_tag_dump(const struct tlv *tlv, int level) {
|
||||||
if (!tlv) {
|
if (tlv == NULL) {
|
||||||
fprintf(f, "NULL\n");
|
PrintAndLogEx(FAILED, "NULL");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct emv_tag *tag = emv_get_tag(tlv);
|
const struct emv_tag *tag = emv_get_tag(tlv);
|
||||||
|
|
||||||
PRINT_INDENT(level);
|
PrintAndLogEx(INFO, "%*s--%2x[%02zx] '%s':" NOLF, (level * 4), " ", tlv->tag, tlv->len, tag->name);
|
||||||
fprintf(f, "--%2x[%02zx] '%s':", tlv->tag, tlv->len, tag->name);
|
|
||||||
|
|
||||||
switch (tag->type) {
|
switch (tag->type) {
|
||||||
case EMV_TAG_GENERIC:
|
case EMV_TAG_GENERIC:
|
||||||
fprintf(f, "\n");
|
PrintAndLogEx(NORMAL, "");
|
||||||
break;
|
break;
|
||||||
case EMV_TAG_BITMASK:
|
case EMV_TAG_BITMASK:
|
||||||
fprintf(f, "\n");
|
PrintAndLogEx(NORMAL, "");
|
||||||
emv_tag_dump_bitmask(tlv, tag, f, level);
|
emv_tag_dump_bitmask(tlv, tag, level);
|
||||||
break;
|
break;
|
||||||
case EMV_TAG_DOL:
|
case EMV_TAG_DOL:
|
||||||
fprintf(f, "\n");
|
PrintAndLogEx(NORMAL, "");
|
||||||
emv_tag_dump_dol(tlv, tag, f, level);
|
emv_tag_dump_dol(tlv, tag, level);
|
||||||
break;
|
break;
|
||||||
case EMV_TAG_CVM_LIST:
|
case EMV_TAG_CVM_LIST:
|
||||||
fprintf(f, "\n");
|
PrintAndLogEx(NORMAL, "");
|
||||||
emv_tag_dump_cvm_list(tlv, tag, f, level);
|
emv_tag_dump_cvm_list(tlv, tag, level);
|
||||||
break;
|
break;
|
||||||
case EMV_TAG_AFL:
|
case EMV_TAG_AFL:
|
||||||
fprintf(f, "\n");
|
PrintAndLogEx(NORMAL, "");
|
||||||
emv_tag_dump_afl(tlv, tag, f, level);
|
emv_tag_dump_afl(tlv, tag, level);
|
||||||
break;
|
break;
|
||||||
case EMV_TAG_STRING:
|
case EMV_TAG_STRING:
|
||||||
emv_tag_dump_string(tlv, tag, f, level);
|
emv_tag_dump_string(tlv, tag, level);
|
||||||
break;
|
break;
|
||||||
case EMV_TAG_NUMERIC:
|
case EMV_TAG_NUMERIC:
|
||||||
emv_tag_dump_numeric(tlv, tag, f, level);
|
emv_tag_dump_numeric(tlv, tag, level);
|
||||||
break;
|
break;
|
||||||
case EMV_TAG_YYMMDD:
|
case EMV_TAG_YYMMDD:
|
||||||
emv_tag_dump_yymmdd(tlv, tag, f, level);
|
emv_tag_dump_yymmdd(tlv, tag, level);
|
||||||
break;
|
break;
|
||||||
case EMV_TAG_CVR:
|
case EMV_TAG_CVR:
|
||||||
fprintf(f, "\n");
|
PrintAndLogEx(NORMAL, "");
|
||||||
emv_tag_dump_cvr(tlv, tag, f, level);
|
emv_tag_dump_cvr(tlv, tag, level);
|
||||||
break;
|
break;
|
||||||
case EMV_TAG_CID:
|
case EMV_TAG_CID:
|
||||||
fprintf(f, "\n");
|
PrintAndLogEx(NORMAL, "");
|
||||||
emv_tag_dump_cid(tlv, tag, f, level);
|
emv_tag_dump_cid(tlv, tag, level);
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
#define TAGS_H
|
#define TAGS_H
|
||||||
|
|
||||||
#include "tlv.h"
|
#include "tlv.h"
|
||||||
#include <stdio.h> // FILE
|
|
||||||
|
|
||||||
// AC
|
// AC
|
||||||
# define EMVAC_AC_MASK 0xC0
|
# define EMVAC_AC_MASK 0xC0
|
||||||
|
@ -34,7 +33,7 @@
|
||||||
# define EMVCID_ADVICE 0x08
|
# define EMVCID_ADVICE 0x08
|
||||||
# define EMVCID_REASON_MASK 0x07
|
# define EMVCID_REASON_MASK 0x07
|
||||||
|
|
||||||
bool emv_tag_dump(const struct tlv *tlv, FILE *f, int level);
|
bool emv_tag_dump(const struct tlv *tlv, int level);
|
||||||
const char *emv_get_tag_name(const struct tlv *tlv);
|
const char *emv_get_tag_name(const struct tlv *tlv);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "cmdhf14a.h"
|
#include "cmdhf14a.h"
|
||||||
#include "dol.h"
|
#include "dol.h"
|
||||||
#include "dump.h"
|
|
||||||
#include "emv_tags.h"
|
#include "emv_tags.h"
|
||||||
#include "emvjson.h"
|
#include "emvjson.h"
|
||||||
#include "util_posix.h"
|
#include "util_posix.h"
|
||||||
|
@ -158,9 +157,9 @@ enum CardPSVendor GetCardPSVendor(uint8_t *AID, size_t AIDlen) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_cb(void *data, const struct tlv *tlv, int level, bool is_leaf) {
|
static void print_cb(void *data, const struct tlv *tlv, int level, bool is_leaf) {
|
||||||
emv_tag_dump(tlv, stdout, level);
|
emv_tag_dump(tlv, level);
|
||||||
if (is_leaf) {
|
if (is_leaf) {
|
||||||
dump_buffer(tlv->value, tlv->len, stdout, level);
|
print_buffer(tlv->value, tlv->len, level);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -805,6 +804,7 @@ int trDDA(EMVCommandChannel channel, bool decodeTLV, struct tlvdb *tlv) {
|
||||||
emv_pk_free(pk);
|
emv_pk_free(pk);
|
||||||
emv_pk_free(issuer_pk);
|
emv_pk_free(issuer_pk);
|
||||||
emv_pk_free(icc_pk);
|
emv_pk_free(icc_pk);
|
||||||
|
atc_db = NULL;
|
||||||
return 9;
|
return 9;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -23,10 +23,10 @@
|
||||||
|
|
||||||
#include "../emv_pk.h"
|
#include "../emv_pk.h"
|
||||||
#include "../crypto.h"
|
#include "../crypto.h"
|
||||||
#include "../dump.h"
|
|
||||||
#include "../tlv.h"
|
#include "../tlv.h"
|
||||||
#include "../emv_pki.h"
|
#include "../emv_pki.h"
|
||||||
#include "ui.h" // printandlog
|
#include "ui.h" // printandlog
|
||||||
|
#include "util.h" // print_buffer
|
||||||
|
|
||||||
struct emv_pk c_mchip_05 = {
|
struct emv_pk c_mchip_05 = {
|
||||||
.rid = { 0xa0, 0x00, 0x00, 0x00, 0x04, },
|
.rid = { 0xa0, 0x00, 0x00, 0x00, 0x04, },
|
||||||
|
@ -172,7 +172,7 @@ static int cda_test_raw(bool verbose) {
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
PrintAndLogEx(INFO, "issuer cert:");
|
PrintAndLogEx(INFO, "issuer cert:");
|
||||||
dump_buffer(ipk_data, ipk_data_len, stdout, 0);
|
print_buffer(ipk_data, ipk_data_len, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ipk_pk_len = ipk_data[13];
|
size_t ipk_pk_len = ipk_data[13];
|
||||||
|
@ -202,7 +202,7 @@ static int cda_test_raw(bool verbose) {
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
PrintAndLogEx(INFO, "crypto hash:");
|
PrintAndLogEx(INFO, "crypto hash:");
|
||||||
dump_buffer(h, 20, stdout, 0);
|
print_buffer(h, 20, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (memcmp(ipk_data + ipk_data_len - 21, h, 20)) {
|
if (memcmp(ipk_data + ipk_data_len - 21, h, 20)) {
|
||||||
|
@ -231,7 +231,7 @@ static int cda_test_raw(bool verbose) {
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
PrintAndLogEx(INFO, "icc cert:");
|
PrintAndLogEx(INFO, "icc cert:");
|
||||||
dump_buffer(iccpk_data, iccpk_data_len, stdout, 0);
|
print_buffer(iccpk_data, iccpk_data_len, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t iccpk_pk_len = iccpk_data[19];
|
size_t iccpk_pk_len = iccpk_data[19];
|
||||||
|
@ -260,7 +260,7 @@ static int cda_test_raw(bool verbose) {
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
PrintAndLogEx(INFO, "crypto hash1.1:");
|
PrintAndLogEx(INFO, "crypto hash1.1:");
|
||||||
dump_buffer(h, 20, stdout, 0);
|
print_buffer(h, 20, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (memcmp(iccpk_data + iccpk_data_len - 21, h, 20)) {
|
if (memcmp(iccpk_data + iccpk_data_len - 21, h, 20)) {
|
||||||
|
@ -287,7 +287,7 @@ static int cda_test_raw(bool verbose) {
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
PrintAndLogEx(INFO, "SDAD:");
|
PrintAndLogEx(INFO, "SDAD:");
|
||||||
dump_buffer(sdad, sdad_len, stdout, 0);
|
print_buffer(sdad, sdad_len, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ch = crypto_hash_open(HASH_SHA_1);
|
ch = crypto_hash_open(HASH_SHA_1);
|
||||||
|
@ -308,7 +308,7 @@ static int cda_test_raw(bool verbose) {
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
PrintAndLogEx(INFO, "crypto hash2:");
|
PrintAndLogEx(INFO, "crypto hash2:");
|
||||||
dump_buffer(h2, 20, stdout, 0);
|
print_buffer(h2, 20, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
crypto_hash_close(ch);
|
crypto_hash_close(ch);
|
||||||
|
@ -331,7 +331,7 @@ static int cda_test_raw(bool verbose) {
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
PrintAndLogEx(INFO, "crypto hash2.1:");
|
PrintAndLogEx(INFO, "crypto hash2.1:");
|
||||||
dump_buffer(h, 20, stdout, 0);
|
print_buffer(h, 20, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (memcmp(sdad + 5 + 8 + 1 + 8, h, 20)) {
|
if (memcmp(sdad + 5 + 8 + 1 + 8, h, 20)) {
|
||||||
|
@ -408,7 +408,7 @@ static int cda_test_pk(bool verbose) {
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
PrintAndLogEx(INFO, "IDN:");
|
PrintAndLogEx(INFO, "IDN:");
|
||||||
dump_buffer(idn->value, idn->len, stdout, 0);
|
print_buffer(idn->value, idn->len, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
tlvdb_free(idndb);
|
tlvdb_free(idndb);
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
|
|
||||||
#include "commonutil.h" // ARRAYLEN
|
#include "commonutil.h" // ARRAYLEN
|
||||||
#include "../crypto.h"
|
#include "../crypto.h"
|
||||||
#include "../dump.h"
|
|
||||||
#include "util_posix.h"
|
#include "util_posix.h"
|
||||||
#include "ui.h" // printandlog
|
#include "ui.h" // printandlog
|
||||||
|
|
||||||
|
|
|
@ -23,11 +23,10 @@
|
||||||
#include "dda_test.h"
|
#include "dda_test.h"
|
||||||
#include "../emv_pk.h"
|
#include "../emv_pk.h"
|
||||||
#include "../crypto.h"
|
#include "../crypto.h"
|
||||||
#include "../dump.h"
|
|
||||||
#include "../tlv.h"
|
#include "../tlv.h"
|
||||||
#include "../emv_pki.h"
|
#include "../emv_pki.h"
|
||||||
#include "ui.h" // printandlog
|
#include "ui.h" // printandlog
|
||||||
|
#include "util.h" // print_buffer
|
||||||
|
|
||||||
struct emv_pk mchip_05 = {
|
struct emv_pk mchip_05 = {
|
||||||
.rid = { 0xa0, 0x00, 0x00, 0x00, 0x04, },
|
.rid = { 0xa0, 0x00, 0x00, 0x00, 0x04, },
|
||||||
|
@ -161,7 +160,7 @@ static int dda_test_raw(bool verbose) {
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
PrintAndLogEx(INFO, "issuer cert:");
|
PrintAndLogEx(INFO, "issuer cert:");
|
||||||
dump_buffer(ipk_data, ipk_data_len, stdout, 0);
|
print_buffer(ipk_data, ipk_data_len, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ipk_pk_len = ipk_data[13];
|
size_t ipk_pk_len = ipk_data[13];
|
||||||
|
@ -191,7 +190,7 @@ static int dda_test_raw(bool verbose) {
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
PrintAndLogEx(INFO, "crypto hash:");
|
PrintAndLogEx(INFO, "crypto hash:");
|
||||||
dump_buffer(h, 20, stdout, 0);
|
print_buffer(h, 20, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (memcmp(ipk_data + ipk_data_len - 21, h, 20)) {
|
if (memcmp(ipk_data + ipk_data_len - 21, h, 20)) {
|
||||||
|
@ -220,7 +219,7 @@ static int dda_test_raw(bool verbose) {
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
PrintAndLogEx(INFO, "icc cert:");
|
PrintAndLogEx(INFO, "icc cert:");
|
||||||
dump_buffer(iccpk_data, iccpk_data_len, stdout, 0);
|
print_buffer(iccpk_data, iccpk_data_len, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t iccpk_pk_len = iccpk_data[19];
|
size_t iccpk_pk_len = iccpk_data[19];
|
||||||
|
@ -249,7 +248,7 @@ static int dda_test_raw(bool verbose) {
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
PrintAndLogEx(INFO, "crypto hash1.1:");
|
PrintAndLogEx(INFO, "crypto hash1.1:");
|
||||||
dump_buffer(h, 20, stdout, 0);
|
print_buffer(h, 20, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (memcmp(iccpk_data + iccpk_data_len - 21, h, 20)) {
|
if (memcmp(iccpk_data + iccpk_data_len - 21, h, 20)) {
|
||||||
|
@ -276,7 +275,7 @@ static int dda_test_raw(bool verbose) {
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
PrintAndLogEx(INFO, "sdad:");
|
PrintAndLogEx(INFO, "sdad:");
|
||||||
dump_buffer(sdad, sdad_len, stdout, 0);
|
print_buffer(sdad, sdad_len, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ch = crypto_hash_open(HASH_SHA_1);
|
ch = crypto_hash_open(HASH_SHA_1);
|
||||||
|
@ -297,7 +296,7 @@ static int dda_test_raw(bool verbose) {
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
PrintAndLogEx(INFO, "crypto hash2:");
|
PrintAndLogEx(INFO, "crypto hash2:");
|
||||||
dump_buffer(h2, 20, stdout, 0);
|
print_buffer(h2, 20, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
crypto_hash_close(ch);
|
crypto_hash_close(ch);
|
||||||
|
@ -356,7 +355,7 @@ static int dda_test_pk(bool verbose) {
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
PrintAndLogEx(INFO, "IDN:");
|
PrintAndLogEx(INFO, "IDN:");
|
||||||
dump_buffer(idn->value, idn->len, stdout, 0);
|
print_buffer(idn->value, idn->len, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
tlvdb_free(idndb);
|
tlvdb_free(idndb);
|
||||||
|
|
|
@ -23,10 +23,10 @@
|
||||||
|
|
||||||
#include "../emv_pk.h"
|
#include "../emv_pk.h"
|
||||||
#include "../crypto.h"
|
#include "../crypto.h"
|
||||||
#include "../dump.h"
|
|
||||||
#include "../tlv.h"
|
#include "../tlv.h"
|
||||||
#include "../emv_pki.h"
|
#include "../emv_pki.h"
|
||||||
#include "ui.h" // printandlog
|
#include "ui.h" // printandlog
|
||||||
|
#include "util.h" // print_buffer
|
||||||
#include "sda_test.h"
|
#include "sda_test.h"
|
||||||
|
|
||||||
struct emv_pk vsdc_01 = {
|
struct emv_pk vsdc_01 = {
|
||||||
|
@ -122,7 +122,7 @@ static int sda_test_raw(bool verbose) {
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
PrintAndLogEx(INFO, "issuer cert:");
|
PrintAndLogEx(INFO, "issuer cert:");
|
||||||
dump_buffer(ipk_data, ipk_data_len, stdout, 0);
|
print_buffer(ipk_data, ipk_data_len, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ipk_pk_len = ipk_data[13];
|
size_t ipk_pk_len = ipk_data[13];
|
||||||
|
@ -152,7 +152,7 @@ static int sda_test_raw(bool verbose) {
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
PrintAndLogEx(INFO, "crypto hash:");
|
PrintAndLogEx(INFO, "crypto hash:");
|
||||||
dump_buffer(h, 20, stdout, 0);
|
print_buffer(h, 20, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (memcmp(ipk_data + ipk_data_len - 21, h, 20)) {
|
if (memcmp(ipk_data + ipk_data_len - 21, h, 20)) {
|
||||||
|
@ -179,7 +179,7 @@ static int sda_test_raw(bool verbose) {
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
PrintAndLogEx(INFO, "ssad:");
|
PrintAndLogEx(INFO, "ssad:");
|
||||||
dump_buffer(ssad, ssad_len, stdout, 0);
|
print_buffer(ssad, ssad_len, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ch = crypto_hash_open(HASH_SHA_1);
|
ch = crypto_hash_open(HASH_SHA_1);
|
||||||
|
@ -200,7 +200,7 @@ static int sda_test_raw(bool verbose) {
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
PrintAndLogEx(INFO, "crypto hash2:");
|
PrintAndLogEx(INFO, "crypto hash2:");
|
||||||
dump_buffer(h2, 20, stdout, 0);
|
print_buffer(h2, 20, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
crypto_hash_close(ch);
|
crypto_hash_close(ch);
|
||||||
|
@ -245,7 +245,7 @@ static int sda_test_pk(bool verbose) {
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
PrintAndLogEx(INFO, "dac:");
|
PrintAndLogEx(INFO, "dac:");
|
||||||
dump_buffer(dac->value, dac->len, stdout, 0);
|
print_buffer(dac->value, dac->len, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
tlvdb_free(dacdb);
|
tlvdb_free(dacdb);
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
#include "crypto/libpcrypto.h"
|
#include "crypto/libpcrypto.h"
|
||||||
#include "additional_ca.h"
|
#include "additional_ca.h"
|
||||||
#include "cose.h"
|
#include "cose.h"
|
||||||
#include "emv/dump.h"
|
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
@ -364,7 +363,7 @@ static int FIDO2CheckSignature(json_t *root, uint8_t *publickey, uint8_t *sign,
|
||||||
uint8_t sval[300] = {0};
|
uint8_t sval[300] = {0};
|
||||||
|
|
||||||
int res = ecdsa_asn1_get_signature(sign, signLen, rval, sval);
|
int res = ecdsa_asn1_get_signature(sign, signLen, rval, sval);
|
||||||
if (!res) {
|
if (res == PM3_SUCCESS) {
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
PrintAndLogEx(INFO, " r: %s", sprint_hex(rval, 32));
|
PrintAndLogEx(INFO, " r: %s", sprint_hex(rval, 32));
|
||||||
PrintAndLogEx(INFO, " s: %s", sprint_hex(sval, 32));
|
PrintAndLogEx(INFO, " s: %s", sprint_hex(sval, 32));
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
|
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "util.h" // sprint_hex...
|
#include "util.h" // sprint_hex...
|
||||||
#include "emv/dump.h"
|
|
||||||
#include "crypto/asn1utils.h"
|
#include "crypto/asn1utils.h"
|
||||||
#include "pm3_cmd.h"
|
#include "pm3_cmd.h"
|
||||||
|
|
||||||
|
@ -181,7 +180,7 @@ static int ndefDecodeSig1(uint8_t *sig, size_t siglen) {
|
||||||
uint8_t rval[300] = {0};
|
uint8_t rval[300] = {0};
|
||||||
uint8_t sval[300] = {0};
|
uint8_t sval[300] = {0};
|
||||||
int res = ecdsa_asn1_get_signature(&sig[indx], intsiglen, rval, sval);
|
int res = ecdsa_asn1_get_signature(&sig[indx], intsiglen, rval, sval);
|
||||||
if (!res) {
|
if (res == PM3_SUCCESS) {
|
||||||
PrintAndLogEx(SUCCESS, "\t\tr: %s", sprint_hex(rval + 32 - slen, slen));
|
PrintAndLogEx(SUCCESS, "\t\tr: %s", sprint_hex(rval + 32 - slen, slen));
|
||||||
PrintAndLogEx(SUCCESS, "\t\ts: %s", sprint_hex(sval + 32 - slen, slen));
|
PrintAndLogEx(SUCCESS, "\t\ts: %s", sprint_hex(sval + 32 - slen, slen));
|
||||||
}
|
}
|
||||||
|
@ -375,15 +374,15 @@ static int ndefRecordDecodeAndPrint(uint8_t *ndefRecord, size_t ndefRecordLen) {
|
||||||
|
|
||||||
if (NDEFHeader.TypeLen) {
|
if (NDEFHeader.TypeLen) {
|
||||||
PrintAndLogEx(INFO, "Type data:");
|
PrintAndLogEx(INFO, "Type data:");
|
||||||
dump_buffer(NDEFHeader.Type, NDEFHeader.TypeLen, stdout, 1);
|
print_buffer(NDEFHeader.Type, NDEFHeader.TypeLen, 1);
|
||||||
}
|
}
|
||||||
if (NDEFHeader.IDLen) {
|
if (NDEFHeader.IDLen) {
|
||||||
PrintAndLogEx(INFO, "ID data:");
|
PrintAndLogEx(INFO, "ID data:");
|
||||||
dump_buffer(NDEFHeader.ID, NDEFHeader.IDLen, stdout, 1);
|
print_buffer(NDEFHeader.ID, NDEFHeader.IDLen, 1);
|
||||||
}
|
}
|
||||||
if (NDEFHeader.PayloadLen) {
|
if (NDEFHeader.PayloadLen) {
|
||||||
PrintAndLogEx(INFO, "Payload data:");
|
PrintAndLogEx(INFO, "Payload data:");
|
||||||
dump_buffer(NDEFHeader.Payload, NDEFHeader.PayloadLen, stdout, 1);
|
print_buffer(NDEFHeader.Payload, NDEFHeader.PayloadLen, 1);
|
||||||
if (NDEFHeader.TypeLen)
|
if (NDEFHeader.TypeLen)
|
||||||
ndefDecodePayload(&NDEFHeader);
|
ndefDecodePayload(&NDEFHeader);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,22 +11,22 @@
|
||||||
typedef struct {
|
typedef struct {
|
||||||
%extend {
|
%extend {
|
||||||
pm3() {
|
pm3() {
|
||||||
printf("SWIG pm3 constructor, get current pm3\n");
|
// printf("SWIG pm3 constructor, get current pm3\n");
|
||||||
pm3_device * p = pm3_get_current_dev();
|
pm3_device * p = pm3_get_current_dev();
|
||||||
p->script_embedded = 1;
|
p->script_embedded = 1;
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
pm3(char *port) {
|
pm3(char *port) {
|
||||||
printf("SWIG pm3 constructor with port, open pm3\n");
|
// printf("SWIG pm3 constructor with port, open pm3\n");
|
||||||
pm3_device * p = pm3_open(port);
|
pm3_device * p = pm3_open(port);
|
||||||
p->script_embedded = 0;
|
p->script_embedded = 0;
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
~pm3() {
|
~pm3() {
|
||||||
if ($self->script_embedded) {
|
if ($self->script_embedded) {
|
||||||
printf("SWIG pm3 destructor, nothing to do\n");
|
// printf("SWIG pm3 destructor, nothing to do\n");
|
||||||
} else {
|
} else {
|
||||||
printf("SWIG pm3 destructor, close pm3\n");
|
// printf("SWIG pm3 destructor, close pm3\n");
|
||||||
pm3_close($self);
|
pm3_close($self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2687,7 +2687,7 @@ static swig_module_info swig_module = {swig_types, 1, 0, 0, 0, 0};
|
||||||
#include "comms.h"
|
#include "comms.h"
|
||||||
|
|
||||||
SWIGINTERN pm3 *new_pm3__SWIG_0(void){
|
SWIGINTERN pm3 *new_pm3__SWIG_0(void){
|
||||||
printf("SWIG pm3 constructor, get current pm3\n");
|
// printf("SWIG pm3 constructor, get current pm3\n");
|
||||||
pm3_device * p = pm3_get_current_dev();
|
pm3_device * p = pm3_get_current_dev();
|
||||||
p->script_embedded = 1;
|
p->script_embedded = 1;
|
||||||
return p;
|
return p;
|
||||||
|
@ -2701,16 +2701,16 @@ SWIGINTERN int SWIG_lua_isnilstring(lua_State *L, int idx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
SWIGINTERN pm3 *new_pm3__SWIG_1(char *port){
|
SWIGINTERN pm3 *new_pm3__SWIG_1(char *port){
|
||||||
printf("SWIG pm3 constructor with port, open pm3\n");
|
// printf("SWIG pm3 constructor with port, open pm3\n");
|
||||||
pm3_device * p = pm3_open(port);
|
pm3_device * p = pm3_open(port);
|
||||||
p->script_embedded = 0;
|
p->script_embedded = 0;
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
SWIGINTERN void delete_pm3(pm3 *self){
|
SWIGINTERN void delete_pm3(pm3 *self){
|
||||||
if (self->script_embedded) {
|
if (self->script_embedded) {
|
||||||
printf("SWIG pm3 destructor, nothing to do\n");
|
// printf("SWIG pm3 destructor, nothing to do\n");
|
||||||
} else {
|
} else {
|
||||||
printf("SWIG pm3 destructor, close pm3\n");
|
// printf("SWIG pm3 destructor, close pm3\n");
|
||||||
pm3_close(self);
|
pm3_close(self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2672,7 +2672,7 @@ static swig_module_info swig_module = {swig_types, 2, 0, 0, 0, 0};
|
||||||
#include "comms.h"
|
#include "comms.h"
|
||||||
|
|
||||||
SWIGINTERN pm3 *new_pm3__SWIG_0(void){
|
SWIGINTERN pm3 *new_pm3__SWIG_0(void){
|
||||||
printf("SWIG pm3 constructor, get current pm3\n");
|
// printf("SWIG pm3 constructor, get current pm3\n");
|
||||||
pm3_device * p = pm3_get_current_dev();
|
pm3_device * p = pm3_get_current_dev();
|
||||||
p->script_embedded = 1;
|
p->script_embedded = 1;
|
||||||
return p;
|
return p;
|
||||||
|
@ -2801,16 +2801,16 @@ SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc)
|
||||||
|
|
||||||
|
|
||||||
SWIGINTERN pm3 *new_pm3__SWIG_1(char *port){
|
SWIGINTERN pm3 *new_pm3__SWIG_1(char *port){
|
||||||
printf("SWIG pm3 constructor with port, open pm3\n");
|
// printf("SWIG pm3 constructor with port, open pm3\n");
|
||||||
pm3_device * p = pm3_open(port);
|
pm3_device * p = pm3_open(port);
|
||||||
p->script_embedded = 0;
|
p->script_embedded = 0;
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
SWIGINTERN void delete_pm3(pm3 *self){
|
SWIGINTERN void delete_pm3(pm3 *self){
|
||||||
if (self->script_embedded) {
|
if (self->script_embedded) {
|
||||||
printf("SWIG pm3 destructor, nothing to do\n");
|
// printf("SWIG pm3 destructor, nothing to do\n");
|
||||||
} else {
|
} else {
|
||||||
printf("SWIG pm3 destructor, close pm3\n");
|
// printf("SWIG pm3 destructor, close pm3\n");
|
||||||
pm3_close(self);
|
pm3_close(self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -898,7 +898,7 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
// execute pm3 command file
|
// execute pm3 command file
|
||||||
if (strcmp(argv[i], "-s") == 0 || strcmp(argv[i], "--script-file") == 0) {
|
if (strcmp(argv[i], "-s") == 0 || strcmp(argv[i], "--script-file") == 0) {
|
||||||
if (i + 1 == argc) {
|
if (i + 1 == argc || strlen(argv[i + 1]) == 0) {
|
||||||
PrintAndLogEx(ERR, _RED_("ERROR:") " missing script file specification after -s\n");
|
PrintAndLogEx(ERR, _RED_("ERROR:") " missing script file specification after -s\n");
|
||||||
show_help(false, exec_name);
|
show_help(false, exec_name);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -910,7 +910,7 @@ int main(int argc, char *argv[]) {
|
||||||
// execute lua script
|
// execute lua script
|
||||||
if (strcmp(argv[i], "-l") == 0 || strcmp(argv[i], "--lua") == 0) {
|
if (strcmp(argv[i], "-l") == 0 || strcmp(argv[i], "--lua") == 0) {
|
||||||
addLuaExec = true;
|
addLuaExec = true;
|
||||||
if (i + 1 == argc) {
|
if (i + 1 == argc || strlen(argv[i + 1]) == 0) {
|
||||||
PrintAndLogEx(ERR, _RED_("ERROR:") " missing lua script specification after -l\n");
|
PrintAndLogEx(ERR, _RED_("ERROR:") " missing lua script specification after -l\n");
|
||||||
show_help(false, exec_name);
|
show_help(false, exec_name);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -200,6 +200,52 @@ void print_hex_break(const uint8_t *data, const size_t len, uint8_t breaks) {
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void print_buffer(const uint8_t *data, const size_t len, int level) {
|
||||||
|
|
||||||
|
if (len < 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
char buf[UTIL_BUFFER_SIZE_SPRINT + 3];
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < len; i += 16) {
|
||||||
|
|
||||||
|
// (16 * 3) + (16) + + 1
|
||||||
|
memset(buf, 0, sizeof(buf));
|
||||||
|
sprintf(buf, "%*s%02x: ", (level * 4), " ", i);
|
||||||
|
|
||||||
|
hex_to_buffer((uint8_t *)(buf + strlen(buf)), data + i, 16, (sizeof(buf) - strlen(buf) - 1), 0, 1, true);
|
||||||
|
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "| %s", sprint_ascii(data + i, 16));
|
||||||
|
PrintAndLogEx(INFO, "%s", buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
// the last odd bytes
|
||||||
|
uint8_t mod = len % 16;
|
||||||
|
|
||||||
|
if (mod) {
|
||||||
|
memset(buf, 0, sizeof(buf));
|
||||||
|
sprintf(buf, "%*s%02x: ", (level * 4), " ", i);
|
||||||
|
hex_to_buffer((uint8_t *)(buf + strlen(buf)), data + i, mod, (sizeof(buf) - strlen(buf) - 1), 0, 1, true);
|
||||||
|
|
||||||
|
// add the spaces...
|
||||||
|
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%*s", ((16 - mod) * 3) , " ");
|
||||||
|
|
||||||
|
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "| %s", sprint_ascii(data + i, mod));
|
||||||
|
PrintAndLogEx(INFO, "%s", buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_blocks(uint32_t *data, size_t len) {
|
||||||
|
PrintAndLogEx(SUCCESS, "Blk | Data ");
|
||||||
|
PrintAndLogEx(SUCCESS, "----+------------");
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
PrintAndLogEx(ERR, "..empty data");
|
||||||
|
} else {
|
||||||
|
for (uint8_t i = 0; i < len; i++)
|
||||||
|
PrintAndLogEx(SUCCESS, " %02d | %08X", i, data[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
char *sprint_hex(const uint8_t *data, const size_t len) {
|
char *sprint_hex(const uint8_t *data, const size_t len) {
|
||||||
static char buf[UTIL_BUFFER_SIZE_SPRINT - 3] = {0};
|
static char buf[UTIL_BUFFER_SIZE_SPRINT - 3] = {0};
|
||||||
hex_to_buffer((uint8_t *)buf, data, len, sizeof(buf) - 1, 0, 1, true);
|
hex_to_buffer((uint8_t *)buf, data, len, sizeof(buf) - 1, 0, 1, true);
|
||||||
|
@ -344,18 +390,6 @@ char *sprint_ascii(const uint8_t *data, const size_t len) {
|
||||||
return sprint_ascii_ex(data, len, 0);
|
return sprint_ascii_ex(data, len, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_blocks(uint32_t *data, size_t len) {
|
|
||||||
PrintAndLogEx(SUCCESS, "Blk | Data ");
|
|
||||||
PrintAndLogEx(SUCCESS, "----+------------");
|
|
||||||
|
|
||||||
if (!data) {
|
|
||||||
PrintAndLogEx(ERR, "..empty data");
|
|
||||||
} else {
|
|
||||||
for (uint8_t i = 0; i < len; i++)
|
|
||||||
PrintAndLogEx(SUCCESS, " %02d | %08X", i, data[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int hex_to_bytes(const char *hexValue, uint8_t *bytesValue, size_t maxBytesValueLen) {
|
int hex_to_bytes(const char *hexValue, uint8_t *bytesValue, size_t maxBytesValueLen) {
|
||||||
char buf[4] = {0};
|
char buf[4] = {0};
|
||||||
int indx = 0;
|
int indx = 0;
|
||||||
|
|
|
@ -50,6 +50,7 @@ char *sprint_hex_ascii(const uint8_t *data, const size_t len);
|
||||||
char *sprint_ascii(const uint8_t *data, const size_t len);
|
char *sprint_ascii(const uint8_t *data, const size_t len);
|
||||||
char *sprint_ascii_ex(const uint8_t *data, const size_t len, const size_t min_str_len);
|
char *sprint_ascii_ex(const uint8_t *data, const size_t len, const size_t min_str_len);
|
||||||
|
|
||||||
|
void print_buffer(const uint8_t *data, const size_t len, int level);
|
||||||
void print_blocks(uint32_t *data, size_t len);
|
void print_blocks(uint32_t *data, size_t len);
|
||||||
|
|
||||||
int hex_to_bytes(const char *hexValue, uint8_t *bytesValue, size_t maxBytesValueLen);
|
int hex_to_bytes(const char *hexValue, uint8_t *bytesValue, size_t maxBytesValueLen);
|
||||||
|
|
22
pm3
22
pm3
|
@ -11,22 +11,36 @@ FINDBTRFCOMM=true
|
||||||
FINDBTDIRECT=true
|
FINDBTDIRECT=true
|
||||||
|
|
||||||
PM3PATH=$(dirname "$0")
|
PM3PATH=$(dirname "$0")
|
||||||
|
EVALENV=""
|
||||||
FULLIMAGE="fullimage.elf"
|
FULLIMAGE="fullimage.elf"
|
||||||
BOOTIMAGE="bootrom.elf"
|
BOOTIMAGE="bootrom.elf"
|
||||||
# try pm3 dirs in current repo workdir
|
# try pm3 dirs in current repo workdir
|
||||||
if [ -d "$PM3PATH/client/" ]; then
|
if [ -d "$PM3PATH/client/" ]; then
|
||||||
CLIENT="$PM3PATH/client/proxmark3"
|
if [ -x "$PM3PATH/client/proxmark3" ]; then
|
||||||
|
CLIENT="$PM3PATH/client/proxmark3"
|
||||||
|
elif [ -x "$PM3PATH/client/build/proxmark3" ]; then
|
||||||
|
CLIENT="$PM3PATH/client/build/proxmark3"
|
||||||
|
else
|
||||||
|
echo >&2 "[!!] In devel workdir but no executable found, did you compile it?"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
# Devel mode: point to workdir pm3.py module
|
||||||
|
EVALENV+=" PYTHONPATH=$PM3PATH/client/src"
|
||||||
# try install dir
|
# try install dir
|
||||||
elif [ -x "$PM3PATH/proxmark3" ]; then
|
elif [ -x "$PM3PATH/proxmark3" ]; then
|
||||||
CLIENT="$PM3PATH/proxmark3"
|
CLIENT="$PM3PATH/proxmark3"
|
||||||
|
EVALENV+=" PYTHONPATH=$PM3PATH/../share/proxmark3/pyscripts/"
|
||||||
|
# or /usr/[local/]lib/python3/dist-packages/pm3.py ?
|
||||||
else
|
else
|
||||||
# hope it's installed somehow, still not sure where fw images are...
|
# hope it's installed somehow, still not sure where fw images and pm3.py are...
|
||||||
CLIENT="proxmark3"
|
CLIENT="proxmark3"
|
||||||
fi
|
fi
|
||||||
EVALENV=""
|
|
||||||
# LeakSanitizer suppressions
|
# LeakSanitizer suppressions
|
||||||
if [ -e .lsan_suppressions ]; then
|
if [ -e .lsan_suppressions ]; then
|
||||||
EVALENV="export LSAN_OPTIONS=suppressions=.lsan_suppressions"
|
EVALENV+=" LSAN_OPTIONS=suppressions=.lsan_suppressions"
|
||||||
|
fi
|
||||||
|
if [ "$EVALENV" != "" ]; then
|
||||||
|
EVALENV="export $EVALENV"
|
||||||
fi
|
fi
|
||||||
PM3LIST=()
|
PM3LIST=()
|
||||||
SHOWLIST=false
|
SHOWLIST=false
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue