Merge branch 'master' into attestation2
This commit is contained in:
@@ -73,6 +73,10 @@ tool/tests/parse_name
|
|||||||
tool/tests/parse_name.log
|
tool/tests/parse_name.log
|
||||||
tool/tests/parse_name.o
|
tool/tests/parse_name.o
|
||||||
tool/tests/parse_name.trs
|
tool/tests/parse_name.trs
|
||||||
|
tool/tests/test_inout
|
||||||
|
tool/tests/test_inout.log
|
||||||
|
tool/tests/test_inout.o
|
||||||
|
tool/tests/test_inout.trs
|
||||||
coverage/
|
coverage/
|
||||||
lib/error.gcno
|
lib/error.gcno
|
||||||
lib/version.gcno
|
lib/version.gcno
|
||||||
|
|||||||
+2
-1
@@ -31,7 +31,8 @@ ACLOCAL_AMFLAGS = -I m4
|
|||||||
|
|
||||||
EXTRA_DIST = windows.mk mac.mk tool/tests/basic.sh tools/fasc.pl
|
EXTRA_DIST = windows.mk mac.mk tool/tests/basic.sh tools/fasc.pl
|
||||||
|
|
||||||
EXTRA_DIST += doc/Certificate_Authority.adoc doc/OS_X_code_signing.adoc doc/SSH_with_PIV_and_PKCS11.adoc doc/Windows_certificate.adoc doc/YKCS11_release_notes.adoc doc/YubiKey_PIV_introduction.adoc
|
EXTRA_DIST += doc/Android_code_signing.adoc doc/Certificate_Authority.adoc doc/OS_X_code_signing.adoc doc/SSH_with_PIV_and_PKCS11.adoc doc/Windows_certificate.adoc doc/YKCS11_release_notes.adoc doc/YubiKey_PIV_introduction.adoc
|
||||||
|
|
||||||
|
|
||||||
if ENABLE_COV
|
if ENABLE_COV
|
||||||
cov-reset:
|
cov-reset:
|
||||||
|
|||||||
@@ -1,6 +1,49 @@
|
|||||||
yubico-piv-tool NEWS -- History of user-visible changes. -*- outline -*-
|
yubico-piv-tool NEWS -- History of user-visible changes. -*- outline -*-
|
||||||
|
|
||||||
* Version 1.1.3 (unreleased)
|
* Version 1.3.1 (unreleased)
|
||||||
|
|
||||||
|
* Version 1.3.0 (released 2016-02-19)
|
||||||
|
|
||||||
|
** Fixed extraction of RSA modulus and exponent for pkcs11.
|
||||||
|
|
||||||
|
** Implemented C_SetPIN for pkcs11.
|
||||||
|
|
||||||
|
** Add generic write and read object actions for the tool.
|
||||||
|
Supports hex/binary/base64 formats
|
||||||
|
|
||||||
|
** Add ykpiv_change_pin(), ykpiv_change_puk() and ykpiv_unblock_pin()
|
||||||
|
|
||||||
|
** Print CCC with status action.
|
||||||
|
|
||||||
|
** Address bugs with pkcs11 on windows.
|
||||||
|
|
||||||
|
** Add --valid-days and --serial to tool for selfsign-certificate action.
|
||||||
|
|
||||||
|
** Ask for password for pkcs12 if none is given.
|
||||||
|
|
||||||
|
* Version 1.2.2 (released 2015-12-08)
|
||||||
|
|
||||||
|
** Fix old buffer overflow in change-pin functionality.
|
||||||
|
|
||||||
|
* Version 1.2.1 (released 2015-12-08)
|
||||||
|
|
||||||
|
** Fix issue with big certificates and status.
|
||||||
|
|
||||||
|
* Version 1.2.0 (released 2015-12-07)
|
||||||
|
|
||||||
|
** On OSX use @loader_path instead of @executable_path for ykcs11.
|
||||||
|
|
||||||
|
** Add ykpiv_import_private_key to libykpiv.
|
||||||
|
|
||||||
|
** Raise buffer sizes to support bigger objects.
|
||||||
|
|
||||||
|
** Change behavior of action status, only list populated slots.
|
||||||
|
|
||||||
|
** Add retired keys to ykcs11.
|
||||||
|
|
||||||
|
** In ykcs11 support login with non null terminated pin.
|
||||||
|
|
||||||
|
** Add a new action set-ccc to yubico-piv-tool to set the CCC.
|
||||||
|
|
||||||
* Version 1.1.2 (released 2015-11-13)
|
* Version 1.1.2 (released 2015-11-13)
|
||||||
|
|
||||||
|
|||||||
+21
-7
@@ -26,7 +26,7 @@
|
|||||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
|
||||||
AC_INIT([yubico-piv-tool], [1.1.3])
|
AC_INIT([yubico-piv-tool], [1.3.1])
|
||||||
AC_CONFIG_AUX_DIR([build-aux])
|
AC_CONFIG_AUX_DIR([build-aux])
|
||||||
AC_CONFIG_MACRO_DIR([m4])
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
|
|
||||||
@@ -34,9 +34,9 @@ AC_CONFIG_MACRO_DIR([m4])
|
|||||||
# Interfaces changed/added/removed: CURRENT++ REVISION=0
|
# Interfaces changed/added/removed: CURRENT++ REVISION=0
|
||||||
# Interfaces added: AGE++
|
# Interfaces added: AGE++
|
||||||
# Interfaces removed: AGE=0
|
# Interfaces removed: AGE=0
|
||||||
AC_SUBST([LT_CURRENT], 2)
|
AC_SUBST([LT_CURRENT], 4)
|
||||||
AC_SUBST([LT_REVISION], 1)
|
AC_SUBST([LT_REVISION], 1)
|
||||||
AC_SUBST([LT_AGE], 1)
|
AC_SUBST([LT_AGE], 3)
|
||||||
|
|
||||||
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
|
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
|
||||||
AM_SILENT_RULES([yes])
|
AM_SILENT_RULES([yes])
|
||||||
@@ -52,8 +52,6 @@ PKG_PROG_PKG_CONFIG
|
|||||||
|
|
||||||
PKG_CHECK_MODULES(OPENSSL, libcrypto)
|
PKG_CHECK_MODULES(OPENSSL, libcrypto)
|
||||||
|
|
||||||
#PKG_CHECK_MODULES([LIBNSPR], [nspr], [], [])
|
|
||||||
|
|
||||||
gl_LD_VERSION_SCRIPT
|
gl_LD_VERSION_SCRIPT
|
||||||
gl_VALGRIND_TESTS
|
gl_VALGRIND_TESTS
|
||||||
|
|
||||||
@@ -190,10 +188,24 @@ AC_ARG_ENABLE([ykcs11-debug],
|
|||||||
|
|
||||||
AS_IF([test "x$enable_ykcs11_debug" != xno],
|
AS_IF([test "x$enable_ykcs11_debug" != xno],
|
||||||
[AC_DEFINE([YKCS11_DBG], [1], [Regular debug flag])
|
[AC_DEFINE([YKCS11_DBG], [1], [Regular debug flag])
|
||||||
AC_DEFINE([YKCS11_DINOUT], [1], [Function accessed/left debug flag])],
|
AC_DEFINE([YKCS11_DINOUT], [1], [Function accessed/left debug flag])
|
||||||
|
ykcs11_debug="ENABLED"],
|
||||||
[true],
|
[true],
|
||||||
[AC_DEFINE([YKCS11_DBG], [0], [Regular debug flag])
|
[AC_DEFINE([YKCS11_DBG], [0], [Regular debug flag])
|
||||||
AC_DEFINE([YKCS11_DINOUT], [0], [Function accessed/left debug flag])])
|
AC_DEFINE([YKCS11_DINOUT], [0], [Function accessed/left debug flag])
|
||||||
|
ykcs11_debug="DISABLED"])
|
||||||
|
|
||||||
|
AC_ARG_ENABLE([hardware-tests],
|
||||||
|
[AS_HELP_STRING([--enable-hardware-tests],
|
||||||
|
[enables tests that require a YubiKey to be plugged in])],
|
||||||
|
[enable_hardware_tests="$enableval"],
|
||||||
|
[enable_hardware_tests="no"])
|
||||||
|
|
||||||
|
AS_IF([test "x$enable_hardware_tests" != xno],
|
||||||
|
[AC_DEFINE([HW_TESTS], [1], [Flag for hardware tests])
|
||||||
|
hw_tests="ENABLED"],
|
||||||
|
[true],
|
||||||
|
[hw_tests="DISABLED"])
|
||||||
|
|
||||||
AC_SUBST(YKPIV_VERSION_MAJOR, `echo $PACKAGE_VERSION | sed 's/\(.*\)\..*\..*/\1/g'`)
|
AC_SUBST(YKPIV_VERSION_MAJOR, `echo $PACKAGE_VERSION | sed 's/\(.*\)\..*\..*/\1/g'`)
|
||||||
AC_SUBST(YKPIV_VERSION_MINOR, `echo $PACKAGE_VERSION | sed 's/.*\.\(.*\)\..*/\1/g'`)
|
AC_SUBST(YKPIV_VERSION_MINOR, `echo $PACKAGE_VERSION | sed 's/.*\.\(.*\)\..*/\1/g'`)
|
||||||
@@ -238,4 +250,6 @@ AC_MSG_NOTICE([summary of build options:
|
|||||||
Mac PCSC
|
Mac PCSC
|
||||||
LIBS: ${PCSC_MACOSX_LIBS}
|
LIBS: ${PCSC_MACOSX_LIBS}
|
||||||
|
|
||||||
|
YKCS11 debug: ${ykcs11_debug}
|
||||||
|
Hardware tests: ${hw_tests}
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
Load and use Android code signing certificate
|
||||||
|
---------------------------------------------
|
||||||
|
|
||||||
|
This is a step-by-step guide on how to load and use an android code signing
|
||||||
|
key and certificate.
|
||||||
|
|
||||||
|
Prerequisites
|
||||||
|
-------------
|
||||||
|
|
||||||
|
* a YubiKey with the PIV application
|
||||||
|
* the yubico-piv-tool software
|
||||||
|
* the OpenSC software
|
||||||
|
* jarsigner and keytool from the JDK (OpenJDK 8 used here)
|
||||||
|
|
||||||
|
Steps
|
||||||
|
-----
|
||||||
|
|
||||||
|
1. Import the key and cert, do one of the below:
|
||||||
|
a. Import the key and cert (PEM format) in slot 9a:
|
||||||
|
+
|
||||||
|
----
|
||||||
|
$ yubico-piv-tool -s 9a -a import-key -i key.pem
|
||||||
|
$ yubico-piv-tool -s 9a -a import-certificate -i cert.pem
|
||||||
|
----
|
||||||
|
|
||||||
|
b. Import the key and cert (PKCS12 format) in slot 9a:
|
||||||
|
+
|
||||||
|
----
|
||||||
|
$ yubico-piv-tool -s 9a -a import-key -a import-cert -i key.p12 -K PKCS12
|
||||||
|
----
|
||||||
|
|
||||||
|
2. Create a java pkcs11 configuration file:
|
||||||
|
+
|
||||||
|
----
|
||||||
|
cat > /tmp/pkcs11_java.cfg
|
||||||
|
name = OpenSC-PKCS11
|
||||||
|
description = SunPKCS11 via OpenSC
|
||||||
|
library = /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so
|
||||||
|
slotListIndex = 1
|
||||||
|
----
|
||||||
|
|
||||||
|
3. Check that keytool can see the key:
|
||||||
|
+
|
||||||
|
----
|
||||||
|
$ keytool -providerClass sun.security.pkcs11.SunPKCS11 -providerArg /tmp/pkcs11_java.cfg \
|
||||||
|
-keystore NONE -storetype PKCS11 -list
|
||||||
|
Enter keystore password:
|
||||||
|
|
||||||
|
Keystore type: PKCS11
|
||||||
|
Keystore provider: SunPKCS11-OpenSC-PKCS11
|
||||||
|
|
||||||
|
Your keystore contains 1 entry
|
||||||
|
|
||||||
|
Certificate for PIV Authentication, PrivateKeyEntry,
|
||||||
|
Certificate fingerprint (SHA1): 26:D7:CB:71:6D:42:3C:AB:58:69:E0:9D:F0:16:DF:84:7E:1C:5A:9A
|
||||||
|
----
|
||||||
|
+
|
||||||
|
Password here is the PIN of the key (default 123456).
|
||||||
|
|
||||||
|
4. Sign the apk with jarsigner:
|
||||||
|
+
|
||||||
|
----
|
||||||
|
$ jarsigner -providerClass sun.security.pkcs11.SunPKCS11 -providerArg /tmp/pkcs11_java.cfg \
|
||||||
|
-keystore NONE -storetype PKCS11 app.apk "Certificate for PIV Authentication"
|
||||||
|
Enter Passphrase for keystore:
|
||||||
|
jar signed.
|
||||||
|
----
|
||||||
|
|
||||||
|
5. Verify the signature with jarsigner:
|
||||||
|
+
|
||||||
|
----
|
||||||
|
$ jarsigner -verify app.apk
|
||||||
|
----
|
||||||
@@ -48,9 +48,6 @@
|
|||||||
struct ykpiv_state {
|
struct ykpiv_state {
|
||||||
SCARDCONTEXT context;
|
SCARDCONTEXT context;
|
||||||
SCARDHANDLE card;
|
SCARDHANDLE card;
|
||||||
unsigned long n_readers;
|
|
||||||
char readers[MAX_READERS][READER_LEN];
|
|
||||||
unsigned long tot_readers_len;
|
|
||||||
int verbose;
|
int verbose;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+185
-2
@@ -258,7 +258,7 @@ ykpiv_rc ykpiv_transfer_data(ykpiv_state *state, const unsigned char *templ,
|
|||||||
rc = SCardBeginTransaction(state->card);
|
rc = SCardBeginTransaction(state->card);
|
||||||
if(rc != SCARD_S_SUCCESS) {
|
if(rc != SCARD_S_SUCCESS) {
|
||||||
if(state->verbose) {
|
if(state->verbose) {
|
||||||
fprintf(stderr, "error: Failed to being pcsc transaction, rc=%08lx\n", rc);
|
fprintf(stderr, "error: Failed to begin pcsc transaction, rc=%08lx\n", rc);
|
||||||
}
|
}
|
||||||
return YKPIV_PCSC_ERROR;
|
return YKPIV_PCSC_ERROR;
|
||||||
}
|
}
|
||||||
@@ -716,6 +716,68 @@ ykpiv_rc ykpiv_verify(ykpiv_state *state, const char *pin, int *tries) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define CHREF_ACT_CHANGE_PIN 0
|
||||||
|
#define CHREF_ACT_UNBLOCK_PIN 1
|
||||||
|
#define CHREF_ACT_CHANGE_PUK 2
|
||||||
|
|
||||||
|
static ykpiv_rc _change_pin_internal(ykpiv_state *state, int action, const char * current_pin, size_t current_pin_len, const char * new_pin, size_t new_pin_len, int *tries) {
|
||||||
|
int sw;
|
||||||
|
unsigned char templ[] = {0, YKPIV_INS_CHANGE_REFERENCE, 0, 0x80};
|
||||||
|
unsigned char indata[0x10];
|
||||||
|
unsigned char data[0xff];
|
||||||
|
unsigned long recv_len = sizeof(data);
|
||||||
|
ykpiv_rc res;
|
||||||
|
if (current_pin_len > 8) {
|
||||||
|
return YKPIV_SIZE_ERROR;
|
||||||
|
}
|
||||||
|
if (new_pin_len > 8) {
|
||||||
|
return YKPIV_SIZE_ERROR;
|
||||||
|
}
|
||||||
|
if(action == CHREF_ACT_UNBLOCK_PIN) {
|
||||||
|
templ[1] = YKPIV_INS_RESET_RETRY;
|
||||||
|
}
|
||||||
|
else if(action == CHREF_ACT_CHANGE_PUK) {
|
||||||
|
templ[3] = 0x81;
|
||||||
|
}
|
||||||
|
memcpy(indata, current_pin, current_pin_len);
|
||||||
|
if(current_pin_len < 8) {
|
||||||
|
memset(indata + current_pin_len, 0xff, 8 - current_pin_len);
|
||||||
|
}
|
||||||
|
memcpy(indata + 8, new_pin, new_pin_len);
|
||||||
|
if(new_pin_len < 8) {
|
||||||
|
memset(indata + 8 + new_pin_len, 0xff, 8 - new_pin_len);
|
||||||
|
}
|
||||||
|
res = ykpiv_transfer_data(state, templ, indata, sizeof(indata), data, &recv_len, &sw);
|
||||||
|
if(res != YKPIV_OK) {
|
||||||
|
return res;
|
||||||
|
} else if(sw != 0x9000) {
|
||||||
|
if((sw >> 8) == 0x63) {
|
||||||
|
*tries = sw & 0xf;
|
||||||
|
return YKPIV_WRONG_PIN;
|
||||||
|
} else if(sw == 0x6983) {
|
||||||
|
return YKPIV_PIN_LOCKED;
|
||||||
|
} else {
|
||||||
|
if(state->verbose) {
|
||||||
|
fprintf(stderr, "Failed changing pin, token response code: %x.\n", sw);
|
||||||
|
}
|
||||||
|
return YKPIV_GENERIC_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return YKPIV_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ykpiv_rc ykpiv_change_pin(ykpiv_state *state, const char * current_pin, size_t current_pin_len, const char * new_pin, size_t new_pin_len, int *tries) {
|
||||||
|
return _change_pin_internal(state, CHREF_ACT_CHANGE_PIN, current_pin, current_pin_len, new_pin, new_pin_len, tries);
|
||||||
|
}
|
||||||
|
|
||||||
|
ykpiv_rc ykpiv_change_puk(ykpiv_state *state, const char * current_puk, size_t current_puk_len, const char * new_puk, size_t new_puk_len, int *tries) {
|
||||||
|
return _change_pin_internal(state, CHREF_ACT_CHANGE_PUK, current_puk, current_puk_len, new_puk, new_puk_len, tries);
|
||||||
|
}
|
||||||
|
|
||||||
|
ykpiv_rc ykpiv_unblock_pin(ykpiv_state *state, const char * puk, size_t puk_len, const char * new_pin, size_t new_pin_len, int *tries) {
|
||||||
|
return _change_pin_internal(state, CHREF_ACT_CHANGE_PUK, puk, puk_len, new_pin, new_pin_len, tries);
|
||||||
|
}
|
||||||
|
|
||||||
ykpiv_rc ykpiv_fetch_object(ykpiv_state *state, int object_id,
|
ykpiv_rc ykpiv_fetch_object(ykpiv_state *state, int object_id,
|
||||||
unsigned char *data, unsigned long *len) {
|
unsigned char *data, unsigned long *len) {
|
||||||
int sw;
|
int sw;
|
||||||
@@ -751,7 +813,7 @@ ykpiv_rc ykpiv_fetch_object(ykpiv_state *state, int object_id,
|
|||||||
ykpiv_rc ykpiv_save_object(ykpiv_state *state, int object_id,
|
ykpiv_rc ykpiv_save_object(ykpiv_state *state, int object_id,
|
||||||
unsigned char *indata, size_t len) {
|
unsigned char *indata, size_t len) {
|
||||||
|
|
||||||
unsigned char data[2048];
|
unsigned char data[3072];
|
||||||
unsigned char *dataptr = data;
|
unsigned char *dataptr = data;
|
||||||
unsigned char templ[] = {0, YKPIV_INS_PUT_DATA, 0x3f, 0xff};
|
unsigned char templ[] = {0, YKPIV_INS_PUT_DATA, 0x3f, 0xff};
|
||||||
int sw;
|
int sw;
|
||||||
@@ -781,3 +843,124 @@ ykpiv_rc ykpiv_save_object(ykpiv_state *state, int object_id,
|
|||||||
return YKPIV_GENERIC_ERROR;
|
return YKPIV_GENERIC_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ykpiv_rc ykpiv_import_private_key(ykpiv_state *state, const unsigned char key, unsigned char algorithm,
|
||||||
|
const unsigned char *p, size_t p_len,
|
||||||
|
const unsigned char *q, size_t q_len,
|
||||||
|
const unsigned char *dp, size_t dp_len,
|
||||||
|
const unsigned char *dq, size_t dq_len,
|
||||||
|
const unsigned char *qinv, size_t qinv_len,
|
||||||
|
const unsigned char *ec_data, unsigned char ec_data_len,
|
||||||
|
const unsigned char pin_policy, const unsigned char touch_policy) {
|
||||||
|
|
||||||
|
unsigned char key_data[1024];
|
||||||
|
unsigned char *in_ptr = key_data;
|
||||||
|
unsigned char templ[] = {0, YKPIV_INS_IMPORT_KEY, algorithm, key};
|
||||||
|
unsigned char data[256];
|
||||||
|
unsigned long recv_len = sizeof(data);
|
||||||
|
unsigned elem_len;
|
||||||
|
int sw;
|
||||||
|
const unsigned char *params[5];
|
||||||
|
size_t lens[5];
|
||||||
|
size_t padding;
|
||||||
|
unsigned char n_params;
|
||||||
|
int i;
|
||||||
|
int param_tag;
|
||||||
|
|
||||||
|
if (state == NULL)
|
||||||
|
return YKPIV_GENERIC_ERROR;
|
||||||
|
|
||||||
|
if (key == YKPIV_KEY_CARDMGM ||
|
||||||
|
key < YKPIV_KEY_RETIRED1 ||
|
||||||
|
(key > YKPIV_KEY_RETIRED20 && key < YKPIV_KEY_AUTHENTICATION) ||
|
||||||
|
key > YKPIV_KEY_CARDAUTH) {
|
||||||
|
return YKPIV_KEY_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pin_policy != YKPIV_PINPOLICY_DEFAULT &&
|
||||||
|
pin_policy != YKPIV_PINPOLICY_NEVER &&
|
||||||
|
pin_policy != YKPIV_PINPOLICY_ONCE &&
|
||||||
|
pin_policy != YKPIV_PINPOLICY_ALWAYS)
|
||||||
|
return YKPIV_GENERIC_ERROR;
|
||||||
|
|
||||||
|
if (touch_policy != YKPIV_TOUCHPOLICY_DEFAULT &&
|
||||||
|
touch_policy != YKPIV_TOUCHPOLICY_NEVER &&
|
||||||
|
touch_policy != YKPIV_TOUCHPOLICY_ALWAYS)
|
||||||
|
return YKPIV_GENERIC_ERROR;
|
||||||
|
|
||||||
|
if (algorithm == YKPIV_ALGO_RSA1024 || algorithm == YKPIV_ALGO_RSA2048) {
|
||||||
|
|
||||||
|
if (algorithm == YKPIV_ALGO_RSA1024)
|
||||||
|
elem_len = 64;
|
||||||
|
if (algorithm == YKPIV_ALGO_RSA2048)
|
||||||
|
elem_len = 128;
|
||||||
|
|
||||||
|
if (p == NULL || q == NULL || dp == NULL ||
|
||||||
|
dq == NULL || qinv == NULL)
|
||||||
|
return YKPIV_GENERIC_ERROR;
|
||||||
|
|
||||||
|
params[0] = p;
|
||||||
|
lens[0] = p_len;
|
||||||
|
params[1] = q;
|
||||||
|
lens[1] = q_len;
|
||||||
|
params[2] = dp;
|
||||||
|
lens[2] = dp_len;
|
||||||
|
params[3] = dq;
|
||||||
|
lens[3] = dq_len;
|
||||||
|
params[4] = qinv;
|
||||||
|
lens[4] = qinv_len;
|
||||||
|
param_tag = 0x01;
|
||||||
|
|
||||||
|
n_params = 5;
|
||||||
|
}
|
||||||
|
else if (algorithm == YKPIV_ALGO_ECCP256 || algorithm == YKPIV_ALGO_ECCP384) {
|
||||||
|
if (algorithm == YKPIV_ALGO_ECCP256)
|
||||||
|
elem_len = 32;
|
||||||
|
if (algorithm == YKPIV_ALGO_ECCP384)
|
||||||
|
elem_len = 48;
|
||||||
|
|
||||||
|
if (ec_data == NULL)
|
||||||
|
return YKPIV_GENERIC_ERROR;
|
||||||
|
|
||||||
|
params[0] = ec_data;
|
||||||
|
lens[0] = ec_data_len;
|
||||||
|
param_tag = 0x06;
|
||||||
|
n_params = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return YKPIV_ALGORITHM_ERROR;
|
||||||
|
|
||||||
|
for (i = 0; i < n_params; i++) {
|
||||||
|
*in_ptr++ = param_tag + i;
|
||||||
|
in_ptr += set_length(in_ptr, elem_len);
|
||||||
|
padding = elem_len - lens[i];
|
||||||
|
memset(in_ptr, 0, padding);
|
||||||
|
in_ptr += padding;
|
||||||
|
memcpy(in_ptr, params[i], lens[i]);
|
||||||
|
in_ptr += lens[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pin_policy != YKPIV_PINPOLICY_DEFAULT) {
|
||||||
|
*in_ptr++ = YKPIV_PINPOLICY_TAG;
|
||||||
|
*in_ptr++ = 0x01;
|
||||||
|
*in_ptr++ = pin_policy;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (touch_policy != YKPIV_TOUCHPOLICY_DEFAULT) {
|
||||||
|
*in_ptr++ = YKPIV_TOUCHPOLICY_TAG;
|
||||||
|
*in_ptr++ = 0x01;
|
||||||
|
*in_ptr++ = touch_policy;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ykpiv_transfer_data(state, templ, key_data, in_ptr - key_data, data, &recv_len, &sw) != YKPIV_OK)
|
||||||
|
return YKPIV_GENERIC_ERROR;
|
||||||
|
|
||||||
|
if (sw == 0x6982)
|
||||||
|
return YKPIV_AUTHENTICATION_ERROR;
|
||||||
|
|
||||||
|
if (sw != 0x9000)
|
||||||
|
return YKPIV_GENERIC_ERROR;
|
||||||
|
|
||||||
|
return YKPIV_OK;
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
+40
@@ -57,6 +57,7 @@ extern "C"
|
|||||||
YKPIV_WRONG_PIN = -10,
|
YKPIV_WRONG_PIN = -10,
|
||||||
YKPIV_INVALID_OBJECT = -11,
|
YKPIV_INVALID_OBJECT = -11,
|
||||||
YKPIV_ALGORITHM_ERROR = -12,
|
YKPIV_ALGORITHM_ERROR = -12,
|
||||||
|
YKPIV_PIN_LOCKED = -13,
|
||||||
} ykpiv_rc;
|
} ykpiv_rc;
|
||||||
|
|
||||||
const char *ykpiv_strerror(ykpiv_rc err);
|
const char *ykpiv_strerror(ykpiv_rc err);
|
||||||
@@ -85,12 +86,29 @@ extern "C"
|
|||||||
unsigned char algorithm, unsigned char key);
|
unsigned char algorithm, unsigned char key);
|
||||||
ykpiv_rc ykpiv_get_version(ykpiv_state *state, char *version, size_t len);
|
ykpiv_rc ykpiv_get_version(ykpiv_state *state, char *version, size_t len);
|
||||||
ykpiv_rc ykpiv_verify(ykpiv_state *state, const char *pin, int *tries);
|
ykpiv_rc ykpiv_verify(ykpiv_state *state, const char *pin, int *tries);
|
||||||
|
ykpiv_rc ykpiv_change_pin(ykpiv_state *state, const char * current_pin, size_t current_pin_len,
|
||||||
|
const char * new_pin, size_t new_pin_len,
|
||||||
|
int *tries);
|
||||||
|
ykpiv_rc ykpiv_change_puk(ykpiv_state *state, const char * current_puk, size_t current_puk_len,
|
||||||
|
const char * new_puk, size_t new_puk_len,
|
||||||
|
int *tries);
|
||||||
|
ykpiv_rc ykpiv_unblock_pin(ykpiv_state *state, const char * puk, size_t puk_len,
|
||||||
|
const char * new_pin, size_t new_pin_len,
|
||||||
|
int *tries);
|
||||||
ykpiv_rc ykpiv_fetch_object(ykpiv_state *state, int object_id,
|
ykpiv_rc ykpiv_fetch_object(ykpiv_state *state, int object_id,
|
||||||
unsigned char *data, unsigned long *len);
|
unsigned char *data, unsigned long *len);
|
||||||
ykpiv_rc ykpiv_set_mgmkey2(ykpiv_state *state, const unsigned char *new_key,
|
ykpiv_rc ykpiv_set_mgmkey2(ykpiv_state *state, const unsigned char *new_key,
|
||||||
const unsigned char touch);
|
const unsigned char touch);
|
||||||
ykpiv_rc ykpiv_save_object(ykpiv_state *state, int object_id,
|
ykpiv_rc ykpiv_save_object(ykpiv_state *state, int object_id,
|
||||||
unsigned char *indata, size_t len);
|
unsigned char *indata, size_t len);
|
||||||
|
ykpiv_rc ykpiv_import_private_key(ykpiv_state *state, const unsigned char key, unsigned char algorithm,
|
||||||
|
const unsigned char *p, size_t p_len,
|
||||||
|
const unsigned char *q, size_t q_len,
|
||||||
|
const unsigned char *dp, size_t dp_len,
|
||||||
|
const unsigned char *dq, size_t dq_len,
|
||||||
|
const unsigned char *qinv, size_t qinv_len,
|
||||||
|
const unsigned char *ec_data, unsigned char ec_data_len,
|
||||||
|
const unsigned char pin_policy, const unsigned char touch_policy);
|
||||||
|
|
||||||
#define YKPIV_ALGO_3DES 0x03
|
#define YKPIV_ALGO_3DES 0x03
|
||||||
#define YKPIV_ALGO_RSA1024 0x06
|
#define YKPIV_ALGO_RSA1024 0x06
|
||||||
@@ -103,6 +121,26 @@ extern "C"
|
|||||||
#define YKPIV_KEY_SIGNATURE 0x9c
|
#define YKPIV_KEY_SIGNATURE 0x9c
|
||||||
#define YKPIV_KEY_KEYMGM 0x9d
|
#define YKPIV_KEY_KEYMGM 0x9d
|
||||||
#define YKPIV_KEY_CARDAUTH 0x9e
|
#define YKPIV_KEY_CARDAUTH 0x9e
|
||||||
|
#define YKPIV_KEY_RETIRED1 0x82
|
||||||
|
#define YKPIV_KEY_RETIRED2 0x83
|
||||||
|
#define YKPIV_KEY_RETIRED3 0x84
|
||||||
|
#define YKPIV_KEY_RETIRED4 0x85
|
||||||
|
#define YKPIV_KEY_RETIRED5 0x86
|
||||||
|
#define YKPIV_KEY_RETIRED6 0x87
|
||||||
|
#define YKPIV_KEY_RETIRED7 0x88
|
||||||
|
#define YKPIV_KEY_RETIRED8 0x89
|
||||||
|
#define YKPIV_KEY_RETIRED9 0x8a
|
||||||
|
#define YKPIV_KEY_RETIRED10 0x8b
|
||||||
|
#define YKPIV_KEY_RETIRED11 0x8c
|
||||||
|
#define YKPIV_KEY_RETIRED12 0x8d
|
||||||
|
#define YKPIV_KEY_RETIRED13 0x8e
|
||||||
|
#define YKPIV_KEY_RETIRED14 0x8f
|
||||||
|
#define YKPIV_KEY_RETIRED15 0x90
|
||||||
|
#define YKPIV_KEY_RETIRED16 0x91
|
||||||
|
#define YKPIV_KEY_RETIRED17 0x92
|
||||||
|
#define YKPIV_KEY_RETIRED18 0x93
|
||||||
|
#define YKPIV_KEY_RETIRED19 0x94
|
||||||
|
#define YKPIV_KEY_RETIRED20 0x95
|
||||||
|
|
||||||
#define YKPIV_OBJ_CAPABILITY 0x5fc107
|
#define YKPIV_OBJ_CAPABILITY 0x5fc107
|
||||||
#define YKPIV_OBJ_CHUID 0x5fc102
|
#define YKPIV_OBJ_CHUID 0x5fc102
|
||||||
@@ -158,11 +196,13 @@ extern "C"
|
|||||||
#define YKPIV_INS_ATTEST 0xf9
|
#define YKPIV_INS_ATTEST 0xf9
|
||||||
|
|
||||||
#define YKPIV_PINPOLICY_TAG 0xaa
|
#define YKPIV_PINPOLICY_TAG 0xaa
|
||||||
|
#define YKPIV_PINPOLICY_DEFAULT 0
|
||||||
#define YKPIV_PINPOLICY_NEVER 1
|
#define YKPIV_PINPOLICY_NEVER 1
|
||||||
#define YKPIV_PINPOLICY_ONCE 2
|
#define YKPIV_PINPOLICY_ONCE 2
|
||||||
#define YKPIV_PINPOLICY_ALWAYS 3
|
#define YKPIV_PINPOLICY_ALWAYS 3
|
||||||
|
|
||||||
#define YKPIV_TOUCHPOLICY_TAG 0xab
|
#define YKPIV_TOUCHPOLICY_TAG 0xab
|
||||||
|
#define YKPIV_TOUCHPOLICY_DEFAULT 0
|
||||||
#define YKPIV_TOUCHPOLICY_NEVER 1
|
#define YKPIV_TOUCHPOLICY_NEVER 1
|
||||||
#define YKPIV_TOUCHPOLICY_ALWAYS 2
|
#define YKPIV_TOUCHPOLICY_ALWAYS 2
|
||||||
|
|
||||||
|
|||||||
+15
-1
@@ -60,4 +60,18 @@ YKPIV_1.1.0
|
|||||||
global:
|
global:
|
||||||
ykpiv_set_mgmkey2;
|
ykpiv_set_mgmkey2;
|
||||||
ykpiv_list_readers;
|
ykpiv_list_readers;
|
||||||
} YKPIV_0.1.0;
|
} YKPIV_0.2.0;
|
||||||
|
|
||||||
|
YKPIV_1.2.0
|
||||||
|
{
|
||||||
|
global:
|
||||||
|
ykpiv_import_private_key;
|
||||||
|
} YKPIV_1.1.0;
|
||||||
|
|
||||||
|
YKPIV_1.3.0
|
||||||
|
{
|
||||||
|
global:
|
||||||
|
ykpiv_change_pin;
|
||||||
|
ykpiv_change_puk;
|
||||||
|
ykpiv_unblock_pin;
|
||||||
|
} YKPIV_1.2.0;
|
||||||
|
|||||||
@@ -26,7 +26,8 @@
|
|||||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
PACKAGE=yubico-piv-tool
|
PACKAGE=yubico-piv-tool
|
||||||
OPENSSLVERSION=1.0.1p
|
OPENSSLVERSION=1.0.1r
|
||||||
|
CFLAGS="-mmacosx-version-min=10.6"
|
||||||
|
|
||||||
all: usage mac
|
all: usage mac
|
||||||
|
|
||||||
@@ -47,7 +48,7 @@ doit:
|
|||||||
curl -L -O "https://www.openssl.org/source/openssl-$(OPENSSLVERSION).tar.gz" && \
|
curl -L -O "https://www.openssl.org/source/openssl-$(OPENSSLVERSION).tar.gz" && \
|
||||||
tar xfz openssl-$(OPENSSLVERSION).tar.gz && \
|
tar xfz openssl-$(OPENSSLVERSION).tar.gz && \
|
||||||
cd openssl-$(OPENSSLVERSION) && \
|
cd openssl-$(OPENSSLVERSION) && \
|
||||||
./Configure darwin64-x86_64-cc shared no-ssl2 no-ssl3 no-engines --prefix=$(PWD)/tmp/root && \
|
./Configure darwin64-x86_64-cc shared no-ssl2 no-ssl3 no-engines --prefix=$(PWD)/tmp/root $(CFLAGS) && \
|
||||||
make all install_sw && \
|
make all install_sw && \
|
||||||
cp LICENSE $(PWD)/tmp$(ARCH)/root/licenses/openssl.txt && \
|
cp LICENSE $(PWD)/tmp$(ARCH)/root/licenses/openssl.txt && \
|
||||||
rm -rf $(PWD)/tmp/root/ssl/ && \
|
rm -rf $(PWD)/tmp/root/ssl/ && \
|
||||||
@@ -60,16 +61,16 @@ doit:
|
|||||||
cp ../$(PACKAGE)-$(VERSION).tar.gz . && \
|
cp ../$(PACKAGE)-$(VERSION).tar.gz . && \
|
||||||
tar xfz $(PACKAGE)-$(VERSION).tar.gz && \
|
tar xfz $(PACKAGE)-$(VERSION).tar.gz && \
|
||||||
cd $(PACKAGE)-$(VERSION)/ && \
|
cd $(PACKAGE)-$(VERSION)/ && \
|
||||||
PKG_CONFIG_PATH=$(PWD)/tmp/root/lib/pkgconfig ./configure --prefix=$(PWD)/tmp/root && \
|
CFLAGS=$(CFLAGS) PKG_CONFIG_PATH=$(PWD)/tmp/root/lib/pkgconfig ./configure --prefix=$(PWD)/tmp/root && \
|
||||||
make install $(CHECK) && \
|
make install $(CHECK) && \
|
||||||
chmod u+w $(PWD)/tmp/root/lib/libcrypto.1.0.0.dylib && \
|
chmod u+w $(PWD)/tmp/root/lib/libcrypto.1.0.0.dylib && \
|
||||||
install_name_tool -id @executable_path/../lib/libcrypto.1.0.0.dylib $(PWD)/tmp/root/lib/libcrypto.1.0.0.dylib && \
|
install_name_tool -id @loader_path/libcrypto.1.0.0.dylib $(PWD)/tmp/root/lib/libcrypto.1.0.0.dylib && \
|
||||||
install_name_tool -id @executable_path/../lib/libykpiv.1.dylib $(PWD)/tmp/root/lib/libykpiv.1.dylib && \
|
install_name_tool -id @loader_path/libykpiv.1.dylib $(PWD)/tmp/root/lib/libykpiv.1.dylib && \
|
||||||
install_name_tool -id @executable_path/../lib/libykcs11.1.dylib $(PWD)/tmp/root/lib/libykcs11.1.dylib && \
|
install_name_tool -id @loader_path/libykcs11.1.dylib $(PWD)/tmp/root/lib/libykcs11.1.dylib && \
|
||||||
install_name_tool -change $(PWD)/tmp/root/lib/libcrypto.1.0.0.dylib @executable_path/../lib/libcrypto.1.0.0.dylib $(PWD)/tmp/root/lib/libykpiv.1.dylib && \
|
install_name_tool -change $(PWD)/tmp/root/lib/libcrypto.1.0.0.dylib @loader_path/libcrypto.1.0.0.dylib $(PWD)/tmp/root/lib/libykpiv.1.dylib && \
|
||||||
install_name_tool -change $(PWD)/tmp/root/lib/libcrypto.1.0.0.dylib @executable_path/../lib/libcrypto.1.0.0.dylib $(PWD)/tmp/root/lib/libykcs11.1.dylib && \
|
install_name_tool -change $(PWD)/tmp/root/lib/libcrypto.1.0.0.dylib @loader_path/libcrypto.1.0.0.dylib $(PWD)/tmp/root/lib/libykcs11.1.dylib && \
|
||||||
install_name_tool -change $(PWD)/tmp/root/lib/libcrypto.1.0.0.dylib @executable_path/../lib/libcrypto.1.0.0.dylib $(PWD)/tmp/root/bin/yubico-piv-tool && \
|
install_name_tool -change $(PWD)/tmp/root/lib/libcrypto.1.0.0.dylib @executable_path/../lib/libcrypto.1.0.0.dylib $(PWD)/tmp/root/bin/yubico-piv-tool && \
|
||||||
install_name_tool -change $(PWD)/tmp/root/lib/libykpiv.1.dylib @executable_path/../lib/libykpiv.1.dylib $(PWD)/tmp/root/lib/libykcs11.1.dylib && \
|
install_name_tool -change $(PWD)/tmp/root/lib/libykpiv.1.dylib @loader_path/libykpiv.1.dylib $(PWD)/tmp/root/lib/libykcs11.1.dylib && \
|
||||||
install_name_tool -change $(PWD)/tmp/root/lib/libykpiv.1.dylib @executable_path/../lib/libykpiv.1.dylib $(PWD)/tmp/root/bin/yubico-piv-tool ; \
|
install_name_tool -change $(PWD)/tmp/root/lib/libykpiv.1.dylib @executable_path/../lib/libykpiv.1.dylib $(PWD)/tmp/root/bin/yubico-piv-tool ; \
|
||||||
if otool -L $(PWD)/tmp/root/lib/*.dylib $(PWD)/tmp/root/bin/* | grep '$(PWD)/tmp/root' | grep -q compatibility; then \
|
if otool -L $(PWD)/tmp/root/lib/*.dylib $(PWD)/tmp/root/bin/* | grep '$(PWD)/tmp/root' | grep -q compatibility; then \
|
||||||
echo "something is incorrectly linked!"; \
|
echo "something is incorrectly linked!"; \
|
||||||
|
|||||||
+4
-5
@@ -33,7 +33,7 @@ AM_CPPFLAGS += -I$(top_srcdir)/lib -I$(top_builddir)/lib
|
|||||||
|
|
||||||
bin_PROGRAMS = yubico-piv-tool
|
bin_PROGRAMS = yubico-piv-tool
|
||||||
yubico_piv_tool_SOURCES = yubico-piv-tool.c yubico-piv-tool.h2m
|
yubico_piv_tool_SOURCES = yubico-piv-tool.c yubico-piv-tool.h2m
|
||||||
yubico_piv_tool_LDADD = $(OPENSSL_LIBS) ../lib/libykpiv.la
|
yubico_piv_tool_LDADD = $(OPENSSL_LIBS) $(top_builddir)/lib/libykpiv.la
|
||||||
yubico_piv_tool_LDADD += libpiv_cmd.la libpiv_util.la
|
yubico_piv_tool_LDADD += libpiv_cmd.la libpiv_util.la
|
||||||
|
|
||||||
noinst_LTLIBRARIES = libpiv_cmd.la libpiv_util.la
|
noinst_LTLIBRARIES = libpiv_cmd.la libpiv_util.la
|
||||||
@@ -41,9 +41,9 @@ libpiv_cmd_la_SOURCES = cmdline.ggo cmdline.c cmdline.h
|
|||||||
libpiv_cmd_la_CFLAGS =
|
libpiv_cmd_la_CFLAGS =
|
||||||
|
|
||||||
libpiv_util_la_SOURCES = util.c util.h
|
libpiv_util_la_SOURCES = util.c util.h
|
||||||
libpiv_util_la_LIBADD = $(OPENSSL_LIBS)
|
libpiv_util_la_LIBADD = $(top_builddir)/lib/libykpiv.la $(OPENSSL_LIBS)
|
||||||
|
|
||||||
cmdline.c cmdline.h: cmdline.ggo Makefile.am
|
cmdline.c cmdline.h: cmdline.ggo Makefile.am $(top_srcdir)/configure.ac
|
||||||
$(GENGETOPT) --input $^
|
$(GENGETOPT) --input $^
|
||||||
|
|
||||||
BUILT_SOURCES = cmdline.c cmdline.h
|
BUILT_SOURCES = cmdline.c cmdline.h
|
||||||
@@ -54,8 +54,7 @@ MAINTAINERCLEANFILES = $(BUILT_SOURCES)
|
|||||||
dist_man_MANS = yubico-piv-tool.1
|
dist_man_MANS = yubico-piv-tool.1
|
||||||
MAINTAINERCLEANFILES += $(dist_man_MANS)
|
MAINTAINERCLEANFILES += $(dist_man_MANS)
|
||||||
|
|
||||||
yubico-piv-tool.1: $(yubico_piv_tool_SOURCES) \
|
yubico-piv-tool.1: $(yubico_piv_tool_SOURCES) $(libpiv_cmd_la_SOURCES)
|
||||||
$(top_srcdir)/configure.ac
|
|
||||||
$(HELP2MAN) --no-info \
|
$(HELP2MAN) --no-info \
|
||||||
--name="Yubico PIV tool" \
|
--name="Yubico PIV tool" \
|
||||||
--include=$(srcdir)/yubico-piv-tool.h2m \
|
--include=$(srcdir)/yubico-piv-tool.h2m \
|
||||||
|
|||||||
+6
-1
@@ -32,7 +32,8 @@ option "action" a "Action to take" values="version","generate","set-mgm-key",
|
|||||||
"reset","pin-retries","import-key","import-certificate","set-chuid",
|
"reset","pin-retries","import-key","import-certificate","set-chuid",
|
||||||
"request-certificate","verify-pin","change-pin","change-puk","unblock-pin",
|
"request-certificate","verify-pin","change-pin","change-puk","unblock-pin",
|
||||||
"selfsign-certificate","delete-certificate","read-certificate","status",
|
"selfsign-certificate","delete-certificate","read-certificate","status",
|
||||||
"test-signature","test-decipher","list-readers","attest" enum multiple
|
"test-signature","test-decipher","list-readers","set-ccc","write-object",
|
||||||
|
"read-object","attest" enum multiple
|
||||||
text "
|
text "
|
||||||
Multiple actions may be given at once and will be executed in order
|
Multiple actions may be given at once and will be executed in order
|
||||||
for example --action=verify-pin --action=request-certificate\n"
|
for example --action=verify-pin --action=request-certificate\n"
|
||||||
@@ -56,8 +57,12 @@ option "subject" S "The subject to use for certificate request" string optional
|
|||||||
text "
|
text "
|
||||||
The subject must be written as:
|
The subject must be written as:
|
||||||
/CN=host.example.com/OU=test/O=example.com/\n"
|
/CN=host.example.com/OU=test/O=example.com/\n"
|
||||||
|
option "serial" - "Serial number of the self-signed certificate" int optional default="1"
|
||||||
|
option "valid-days" - "Time (in days) until the self-signed certificate expires" int optional default="365"
|
||||||
option "pin" P "Pin/puk code for verification" string optional
|
option "pin" P "Pin/puk code for verification" string optional
|
||||||
option "new-pin" N "New pin/puk code for changing" string optional dependon="pin"
|
option "new-pin" N "New pin/puk code for changing" string optional dependon="pin"
|
||||||
option "pin-policy" - "Set pin policy for action generate or import-key" values="never","once","always" enum optional
|
option "pin-policy" - "Set pin policy for action generate or import-key" values="never","once","always" enum optional
|
||||||
option "touch-policy" - "Set touch policy for action generate, import-key or set-mgm-key" values="never","always" enum optional
|
option "touch-policy" - "Set touch policy for action generate, import-key or set-mgm-key" values="never","always" enum optional
|
||||||
|
option "id" - "Id of object for write/read object" int optional
|
||||||
|
option "format" f "Format of data for write/read object" values="hex","base64","binary" enum optional default="hex"
|
||||||
option "sign" - "Sign data" flag off hidden
|
option "sign" - "Sign data" flag off hidden
|
||||||
|
|||||||
@@ -37,8 +37,9 @@ AM_CPPFLAGS += $(OPENSSL_CFLAGS)
|
|||||||
AM_LDFLAGS = -no-install
|
AM_LDFLAGS = -no-install
|
||||||
|
|
||||||
parse_name_LDADD = ../libpiv_util.la $(OPENSSL_LIBS)
|
parse_name_LDADD = ../libpiv_util.la $(OPENSSL_LIBS)
|
||||||
|
test_inout_LDADD = ../libpiv_util.la
|
||||||
|
|
||||||
check_PROGRAMS = parse_name
|
check_PROGRAMS = parse_name test_inout
|
||||||
TESTS = basic.sh $(check_PROGRAMS)
|
TESTS = basic.sh $(check_PROGRAMS)
|
||||||
|
|
||||||
if ENABLE_COV
|
if ENABLE_COV
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2015 Yubico AB
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define pipe(fds) _pipe(fds,4096, 0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void test_inout(enum enum_format format) {
|
||||||
|
const unsigned char buf[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
|
||||||
|
unsigned char buf2[sizeof(buf)];
|
||||||
|
int pipefd[2];
|
||||||
|
FILE *tmp1, *tmp2;
|
||||||
|
|
||||||
|
assert(pipe(pipefd) == 0);
|
||||||
|
tmp1 = fdopen(pipefd[1], "w");
|
||||||
|
dump_data(buf, sizeof(buf), tmp1, false, format);
|
||||||
|
fclose(tmp1);
|
||||||
|
tmp2 = fdopen(pipefd[0], "r");
|
||||||
|
read_data(buf2, sizeof(buf2), tmp2, format);
|
||||||
|
assert(memcmp(buf, buf2, sizeof(buf)) == 0);
|
||||||
|
fclose(tmp2);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
test_inout(format_arg_base64);
|
||||||
|
test_inout(format_arg_hex);
|
||||||
|
test_inout(format_arg_binary);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
+143
-14
@@ -148,12 +148,80 @@ parse_err:
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dump_hex(const unsigned char *buf, unsigned int len, FILE *output, bool space) {
|
size_t read_data(unsigned char *buf, size_t len, FILE* input, enum enum_format format) {
|
||||||
unsigned int i;
|
char raw_buf[3072 * 2];
|
||||||
for (i = 0; i < len; i++) {
|
size_t raw_len = sizeof(raw_buf);
|
||||||
fprintf(output, "%02x%s", buf[i], space == true ? " " : "");
|
raw_len = fread(raw_buf, 1, raw_len, input);
|
||||||
|
switch(format) {
|
||||||
|
case format_arg_hex:
|
||||||
|
if(raw_buf[raw_len - 1] == '\n') {
|
||||||
|
raw_len -= 1;
|
||||||
|
}
|
||||||
|
if(ykpiv_hex_decode(raw_buf, raw_len, buf, &len) != YKPIV_OK) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
case format_arg_base64:
|
||||||
|
{
|
||||||
|
int read;
|
||||||
|
BIO *b64 = BIO_new(BIO_f_base64());
|
||||||
|
BIO *bio = BIO_new_mem_buf(raw_buf, raw_len);
|
||||||
|
BIO_push(b64, bio);
|
||||||
|
read = BIO_read(b64, buf, len);
|
||||||
|
BIO_free_all(b64);
|
||||||
|
if(read <= 0) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return (size_t)read;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case format_arg_binary:
|
||||||
|
if(raw_len > len) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
memcpy(buf, raw_buf, raw_len);
|
||||||
|
return raw_len;
|
||||||
|
case format__NULL:
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dump_data(const unsigned char *buf, unsigned int len, FILE *output, bool space, enum enum_format format) {
|
||||||
|
switch(format) {
|
||||||
|
case format_arg_hex:
|
||||||
|
{
|
||||||
|
char tmp[3072 * 3 + 1];
|
||||||
|
unsigned int i;
|
||||||
|
unsigned int step = 2;
|
||||||
|
if(space) step += 1;
|
||||||
|
if(len > 3072) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
sprintf(tmp + i * step, "%02x%s", buf[i], space == true ? " " : "");
|
||||||
|
}
|
||||||
|
fprintf(output, "%s\n", tmp);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
case format_arg_base64:
|
||||||
|
{
|
||||||
|
BIO *b64 = BIO_new(BIO_f_base64());
|
||||||
|
BIO *bio = BIO_new_fp(output, BIO_NOCLOSE);
|
||||||
|
BIO_push(b64, bio);
|
||||||
|
BIO_write(b64, buf, (int)len);
|
||||||
|
BIO_flush(b64);
|
||||||
|
BIO_free_all(b64);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
case format_arg_binary:
|
||||||
|
fwrite(buf, 1, len, output);
|
||||||
|
return;
|
||||||
|
case format__NULL:
|
||||||
|
default:
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
fprintf(output, "\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_length(const unsigned char *buffer, int *len) {
|
int get_length(const unsigned char *buffer, int *len) {
|
||||||
@@ -276,33 +344,94 @@ int key_to_object_id(int key) {
|
|||||||
int object;
|
int object;
|
||||||
|
|
||||||
switch(key) {
|
switch(key) {
|
||||||
case 0x9a:
|
case YKPIV_KEY_AUTHENTICATION:
|
||||||
object = YKPIV_OBJ_AUTHENTICATION;
|
object = YKPIV_OBJ_AUTHENTICATION;
|
||||||
break;
|
break;
|
||||||
case 0x9c:
|
case YKPIV_KEY_CARDMGM:
|
||||||
object = YKPIV_OBJ_SIGNATURE;
|
object = YKPIV_OBJ_SIGNATURE;
|
||||||
break;
|
break;
|
||||||
case 0x9d:
|
case YKPIV_KEY_KEYMGM:
|
||||||
object = YKPIV_OBJ_KEY_MANAGEMENT;
|
object = YKPIV_OBJ_KEY_MANAGEMENT;
|
||||||
break;
|
break;
|
||||||
case 0x9e:
|
case YKPIV_KEY_CARDAUTH:
|
||||||
object = YKPIV_OBJ_CARD_AUTH;
|
object = YKPIV_OBJ_CARD_AUTH;
|
||||||
break;
|
break;
|
||||||
|
case YKPIV_KEY_RETIRED1:
|
||||||
|
object = YKPIV_OBJ_RETIRED1;
|
||||||
|
break;
|
||||||
|
case YKPIV_KEY_RETIRED2:
|
||||||
|
object = YKPIV_OBJ_RETIRED2;
|
||||||
|
break;
|
||||||
|
case YKPIV_KEY_RETIRED3:
|
||||||
|
object = YKPIV_OBJ_RETIRED3;
|
||||||
|
break;
|
||||||
|
case YKPIV_KEY_RETIRED4:
|
||||||
|
object = YKPIV_OBJ_RETIRED4;
|
||||||
|
break;
|
||||||
|
case YKPIV_KEY_RETIRED5:
|
||||||
|
object = YKPIV_OBJ_RETIRED5;
|
||||||
|
break;
|
||||||
|
case YKPIV_KEY_RETIRED6:
|
||||||
|
object = YKPIV_OBJ_RETIRED6;
|
||||||
|
break;
|
||||||
|
case YKPIV_KEY_RETIRED7:
|
||||||
|
object = YKPIV_OBJ_RETIRED7;
|
||||||
|
break;
|
||||||
|
case YKPIV_KEY_RETIRED8:
|
||||||
|
object = YKPIV_OBJ_RETIRED8;
|
||||||
|
break;
|
||||||
|
case YKPIV_KEY_RETIRED9:
|
||||||
|
object = YKPIV_OBJ_RETIRED9;
|
||||||
|
break;
|
||||||
|
case YKPIV_KEY_RETIRED10:
|
||||||
|
object = YKPIV_OBJ_RETIRED10;
|
||||||
|
break;
|
||||||
|
case YKPIV_KEY_RETIRED11:
|
||||||
|
object = YKPIV_OBJ_RETIRED11;
|
||||||
|
break;
|
||||||
|
case YKPIV_KEY_RETIRED12:
|
||||||
|
object = YKPIV_OBJ_RETIRED12;
|
||||||
|
break;
|
||||||
|
case YKPIV_KEY_RETIRED13:
|
||||||
|
object = YKPIV_OBJ_RETIRED13;
|
||||||
|
break;
|
||||||
|
case YKPIV_KEY_RETIRED14:
|
||||||
|
object = YKPIV_OBJ_RETIRED14;
|
||||||
|
break;
|
||||||
|
case YKPIV_KEY_RETIRED15:
|
||||||
|
object = YKPIV_OBJ_RETIRED15;
|
||||||
|
break;
|
||||||
|
case YKPIV_KEY_RETIRED16:
|
||||||
|
object = YKPIV_OBJ_RETIRED16;
|
||||||
|
break;
|
||||||
|
case YKPIV_KEY_RETIRED17:
|
||||||
|
object = YKPIV_OBJ_RETIRED17;
|
||||||
|
break;
|
||||||
|
case YKPIV_KEY_RETIRED18:
|
||||||
|
object = YKPIV_OBJ_RETIRED18;
|
||||||
|
break;
|
||||||
|
case YKPIV_KEY_RETIRED19:
|
||||||
|
object = YKPIV_OBJ_RETIRED19;
|
||||||
|
break;
|
||||||
|
case YKPIV_KEY_RETIRED20:
|
||||||
|
object = YKPIV_OBJ_RETIRED20;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
object = 0;
|
object = 0;
|
||||||
}
|
}
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool set_component_with_len(unsigned char **in_ptr, const BIGNUM *bn, int element_len) {
|
bool set_component(unsigned char *in_ptr, const BIGNUM *bn, int element_len) {
|
||||||
int real_len = BN_num_bytes(bn);
|
int real_len = BN_num_bytes(bn);
|
||||||
*in_ptr += set_length(*in_ptr, element_len);
|
|
||||||
if(real_len > element_len) {
|
if(real_len > element_len) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
memset(*in_ptr, 0, (size_t)(element_len - real_len));
|
memset(in_ptr, 0, (size_t)(element_len - real_len));
|
||||||
*in_ptr += element_len - real_len;
|
in_ptr += element_len - real_len;
|
||||||
*in_ptr += BN_bn2bin(bn, *in_ptr);
|
BN_bn2bin(bn, in_ptr);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-2
@@ -31,6 +31,8 @@
|
|||||||
#ifndef YUBICO_PIV_TOOL_INTERNAL_H
|
#ifndef YUBICO_PIV_TOOL_INTERNAL_H
|
||||||
#define YUBICO_PIV_TOOL_INTERNAL_H
|
#define YUBICO_PIV_TOOL_INTERNAL_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include <openssl/x509.h>
|
#include <openssl/x509.h>
|
||||||
|
|
||||||
#include "cmdline.h"
|
#include "cmdline.h"
|
||||||
@@ -38,7 +40,8 @@
|
|||||||
#define INPUT 1
|
#define INPUT 1
|
||||||
#define OUTPUT 2
|
#define OUTPUT 2
|
||||||
|
|
||||||
void dump_hex(unsigned const char*, unsigned int, FILE*, bool);
|
size_t read_data(unsigned char*, size_t, FILE*, enum enum_format);
|
||||||
|
void dump_data(unsigned const char*, unsigned int, FILE*, bool, enum enum_format);
|
||||||
int set_length(unsigned char*, int);
|
int set_length(unsigned char*, int);
|
||||||
int get_length(const unsigned char*, int*);
|
int get_length(const unsigned char*, int*);
|
||||||
X509_NAME *parse_name(const char*);
|
X509_NAME *parse_name(const char*);
|
||||||
@@ -46,7 +49,7 @@ unsigned char get_algorithm(EVP_PKEY*);
|
|||||||
FILE *open_file(const char*, int);
|
FILE *open_file(const char*, int);
|
||||||
int get_object_id(enum enum_slot slot);
|
int get_object_id(enum enum_slot slot);
|
||||||
int key_to_object_id(int key);
|
int key_to_object_id(int key);
|
||||||
bool set_component_with_len(unsigned char**, const BIGNUM*, int);
|
bool set_component(unsigned char *in_ptr, const BIGNUM *bn, int element_len);
|
||||||
bool prepare_rsa_signature(const unsigned char*, unsigned int, unsigned char*,
|
bool prepare_rsa_signature(const unsigned char*, unsigned int, unsigned char*,
|
||||||
unsigned int*, int);
|
unsigned int*, int);
|
||||||
bool read_pw(const char*, char*, size_t, int);
|
bool read_pw(const char*, char*, size_t, int);
|
||||||
|
|||||||
+304
-153
@@ -63,6 +63,17 @@ unsigned const char chuid_tmpl[] = {
|
|||||||
};
|
};
|
||||||
#define CHUID_GUID_OFFS 29
|
#define CHUID_GUID_OFFS 29
|
||||||
|
|
||||||
|
unsigned const char ccc_tmpl[] = {
|
||||||
|
0xf0, 0x15, 0xa0, 0x00, 0x00, 0x01, 0x16, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x01, 0x21,
|
||||||
|
0xf2, 0x01, 0x21, 0xf3, 0x00, 0xf4, 0x01, 0x00, 0xf5, 0x01, 0x10, 0xf6, 0x00,
|
||||||
|
0xf7, 0x00, 0xfa, 0x00, 0xfb, 0x00, 0xfc, 0x00, 0xfd, 0x00, 0xfe, 0x00
|
||||||
|
};
|
||||||
|
#define CCC_ID_OFFS 9
|
||||||
|
|
||||||
|
#define CHUID 0
|
||||||
|
#define CCC 1
|
||||||
|
|
||||||
#define MAX_OID_LEN 19
|
#define MAX_OID_LEN 19
|
||||||
|
|
||||||
#define KEY_LEN 24
|
#define KEY_LEN 24
|
||||||
@@ -71,7 +82,7 @@ static void print_version(ykpiv_state *state, const char *output_file_name) {
|
|||||||
char version[7];
|
char version[7];
|
||||||
FILE *output_file = open_file(output_file_name, OUTPUT);
|
FILE *output_file = open_file(output_file_name, OUTPUT);
|
||||||
if(!output_file) {
|
if(!output_file) {
|
||||||
fprintf(stderr, "Failed opening output_file_name\n");
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ykpiv_get_version(state, version, sizeof(version)) == YKPIV_OK) {
|
if(ykpiv_get_version(state, version, sizeof(version)) == YKPIV_OK) {
|
||||||
@@ -324,6 +335,7 @@ static bool import_key(ykpiv_state *state, enum enum_key_format key_format,
|
|||||||
PKCS12 *p12 = NULL;
|
PKCS12 *p12 = NULL;
|
||||||
X509 *cert = NULL;
|
X509 *cert = NULL;
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
ykpiv_rc rc = YKPIV_GENERIC_ERROR;
|
||||||
|
|
||||||
sscanf(slot, "%2x", &key);
|
sscanf(slot, "%2x", &key);
|
||||||
|
|
||||||
@@ -360,119 +372,123 @@ static bool import_key(ykpiv_state *state, enum enum_key_format key_format,
|
|||||||
|
|
||||||
{
|
{
|
||||||
unsigned char algorithm = get_algorithm(private_key);
|
unsigned char algorithm = get_algorithm(private_key);
|
||||||
|
unsigned char pp = YKPIV_PINPOLICY_DEFAULT;
|
||||||
|
unsigned char tp = YKPIV_TOUCHPOLICY_DEFAULT;
|
||||||
|
|
||||||
if(algorithm == 0) {
|
if(algorithm == 0) {
|
||||||
goto import_out;
|
goto import_out;
|
||||||
}
|
}
|
||||||
{
|
|
||||||
unsigned char data[0xff];
|
if(pin_policy != pin_policy__NULL) {
|
||||||
unsigned long recv_len = sizeof(data);
|
pp = get_pin_policy(pin_policy);
|
||||||
unsigned char in_data[1024];
|
}
|
||||||
unsigned char *in_ptr = in_data;
|
|
||||||
unsigned char templ[] = {0, YKPIV_INS_IMPORT_KEY, algorithm, key};
|
if(touch_policy != touch_policy__NULL) {
|
||||||
int sw;
|
tp = get_touch_policy(touch_policy);
|
||||||
|
}
|
||||||
|
|
||||||
if(YKPIV_IS_RSA(algorithm)) {
|
if(YKPIV_IS_RSA(algorithm)) {
|
||||||
RSA *rsa_private_key = EVP_PKEY_get1_RSA(private_key);
|
RSA *rsa_private_key = EVP_PKEY_get1_RSA(private_key);
|
||||||
unsigned char e[4];
|
unsigned char e[4];
|
||||||
unsigned char *e_ptr = e;
|
unsigned char p[128];
|
||||||
|
unsigned char q[128];
|
||||||
|
unsigned char dmp1[128];
|
||||||
|
unsigned char dmq1[128];
|
||||||
|
unsigned char iqmp[128];
|
||||||
|
|
||||||
int element_len = 128;
|
int element_len = 128;
|
||||||
if(algorithm == YKPIV_ALGO_RSA1024) {
|
if(algorithm == YKPIV_ALGO_RSA1024) {
|
||||||
element_len = 64;
|
element_len = 64;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((set_component_with_len(&e_ptr, rsa_private_key->e, 3) == false) ||
|
if((set_component(e, rsa_private_key->e, 3) == false) ||
|
||||||
!(e[1] == 0x01 && e[2] == 0x00 && e[3] == 0x01)) {
|
!(e[0] == 0x01 && e[1] == 0x00 && e[2] == 0x01)) {
|
||||||
fprintf(stderr, "Invalid public exponent for import (only 0x10001 supported)\n");
|
fprintf(stderr, "Invalid public exponent for import (only 0x10001 supported)\n");
|
||||||
goto import_out;
|
goto import_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
*in_ptr++ = 0x01;
|
if(set_component(p, rsa_private_key->p, element_len) == false) {
|
||||||
if(set_component_with_len(&in_ptr, rsa_private_key->p, element_len) == false) {
|
|
||||||
fprintf(stderr, "Failed setting p component.\n");
|
fprintf(stderr, "Failed setting p component.\n");
|
||||||
goto import_out;
|
goto import_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
*in_ptr++ = 0x02;
|
if(set_component(q, rsa_private_key->q, element_len) == false) {
|
||||||
if(set_component_with_len(&in_ptr, rsa_private_key->q, element_len) == false) {
|
|
||||||
fprintf(stderr, "Failed setting q component.\n");
|
fprintf(stderr, "Failed setting q component.\n");
|
||||||
goto import_out;
|
goto import_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
*in_ptr++ = 0x03;
|
if(set_component(dmp1, rsa_private_key->dmp1, element_len) == false) {
|
||||||
if(set_component_with_len(&in_ptr, rsa_private_key->dmp1, element_len) == false) {
|
|
||||||
fprintf(stderr, "Failed setting dmp1 component.\n");
|
fprintf(stderr, "Failed setting dmp1 component.\n");
|
||||||
goto import_out;
|
goto import_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
*in_ptr++ = 0x04;
|
if(set_component(dmq1, rsa_private_key->dmq1, element_len) == false) {
|
||||||
if(set_component_with_len(&in_ptr, rsa_private_key->dmq1, element_len) == false) {
|
|
||||||
fprintf(stderr, "Failed setting dmq1 component.\n");
|
fprintf(stderr, "Failed setting dmq1 component.\n");
|
||||||
goto import_out;
|
goto import_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
*in_ptr++ = 0x05;
|
if(set_component(iqmp, rsa_private_key->iqmp, element_len) == false) {
|
||||||
if(set_component_with_len(&in_ptr, rsa_private_key->iqmp, element_len) == false) {
|
|
||||||
fprintf(stderr, "Failed setting iqmp component.\n");
|
fprintf(stderr, "Failed setting iqmp component.\n");
|
||||||
goto import_out;
|
goto import_out;
|
||||||
}
|
}
|
||||||
} else if(YKPIV_IS_EC(algorithm)) {
|
|
||||||
|
rc = ykpiv_import_private_key(state, key, algorithm,
|
||||||
|
p, element_len,
|
||||||
|
q, element_len,
|
||||||
|
dmp1, element_len,
|
||||||
|
dmq1, element_len,
|
||||||
|
iqmp, element_len,
|
||||||
|
NULL, 0,
|
||||||
|
pp, tp);
|
||||||
|
}
|
||||||
|
else if(YKPIV_IS_EC(algorithm)) {
|
||||||
EC_KEY *ec = EVP_PKEY_get1_EC_KEY(private_key);
|
EC_KEY *ec = EVP_PKEY_get1_EC_KEY(private_key);
|
||||||
const BIGNUM *s = EC_KEY_get0_private_key(ec);
|
const BIGNUM *s = EC_KEY_get0_private_key(ec);
|
||||||
int element_len = 32;
|
unsigned char s_ptr[48];
|
||||||
|
|
||||||
|
int element_len = 32;
|
||||||
if(algorithm == YKPIV_ALGO_ECCP384) {
|
if(algorithm == YKPIV_ALGO_ECCP384) {
|
||||||
element_len = 48;
|
element_len = 48;
|
||||||
}
|
}
|
||||||
|
|
||||||
*in_ptr++ = 0x06;
|
if(set_component(s_ptr, s, element_len) == false) {
|
||||||
if(set_component_with_len(&in_ptr, s, element_len) == false) {
|
|
||||||
fprintf(stderr, "Failed setting ec private key.\n");
|
fprintf(stderr, "Failed setting ec private key.\n");
|
||||||
goto import_out;
|
goto import_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rc = ykpiv_import_private_key(state, key, algorithm,
|
||||||
|
NULL, 0,
|
||||||
|
NULL, 0,
|
||||||
|
NULL, 0,
|
||||||
|
NULL, 0,
|
||||||
|
NULL, 0,
|
||||||
|
s_ptr, element_len,
|
||||||
|
pp, tp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pin_policy != pin_policy__NULL) {
|
|
||||||
*in_ptr++ = YKPIV_PINPOLICY_TAG;
|
|
||||||
*in_ptr++ = 1;
|
|
||||||
*in_ptr++ = get_pin_policy(pin_policy);
|
|
||||||
}
|
|
||||||
if(touch_policy != touch_policy__NULL) {
|
|
||||||
*in_ptr++ = YKPIV_TOUCHPOLICY_TAG;
|
|
||||||
*in_ptr++ = 1;
|
|
||||||
*in_ptr++ = get_touch_policy(touch_policy);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ykpiv_transfer_data(state, templ, in_data, in_ptr - in_data, data,
|
|
||||||
&recv_len, &sw) != YKPIV_OK) {
|
|
||||||
return false;
|
|
||||||
} else if(sw == 0x6a80) {
|
|
||||||
fprintf(stderr, "Failed import.");
|
|
||||||
if(pin_policy != pin_policy__NULL) {
|
|
||||||
fprintf(stderr, "Maybe pin-policy is not supported on this key?\n");
|
|
||||||
} else if(touch_policy != touch_policy__NULL) {
|
|
||||||
fprintf(stderr, "Maybe touch-policy is not supported on this key?\n");
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "Maybe algorithm is not supported on this key?\n");
|
|
||||||
}
|
|
||||||
} else if(sw != 0x9000) {
|
|
||||||
fprintf(stderr, "Failed import command with code %x.\n", sw);
|
|
||||||
} else {
|
|
||||||
ret = true;
|
ret = true;
|
||||||
|
if(rc != YKPIV_OK) {
|
||||||
|
ret = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
import_out:
|
import_out:
|
||||||
if(private_key) {
|
if(private_key) {
|
||||||
EVP_PKEY_free(private_key);
|
EVP_PKEY_free(private_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(p12) {
|
if(p12) {
|
||||||
PKCS12_free(p12);
|
PKCS12_free(p12);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(cert) {
|
if(cert) {
|
||||||
X509_free(cert);
|
X509_free(cert);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(input_file != stdin) {
|
if(input_file != stdin) {
|
||||||
fclose(input_file);
|
fclose(input_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -536,15 +552,16 @@ static bool import_cert(ykpiv_state *state, enum enum_key_format cert_format,
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
unsigned char certdata[2100];
|
unsigned char certdata[3072];
|
||||||
unsigned char *certptr = certdata;
|
unsigned char *certptr = certdata;
|
||||||
int object = get_object_id(slot);
|
int object = get_object_id(slot);
|
||||||
ykpiv_rc res;
|
ykpiv_rc res;
|
||||||
|
|
||||||
if(cert_len > 2048) {
|
if(4 + cert_len + 5 > 3072) { /* 4 is prefix size, 5 is postfix size */
|
||||||
fprintf(stderr, "Certificate to large, maximum 2048 bytes (was %d bytes).\n", cert_len);
|
fprintf(stderr, "Certificate is to large to fit in buffer.\n");
|
||||||
goto import_cert_out;
|
goto import_cert_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
*certptr++ = 0x70;
|
*certptr++ = 0x70;
|
||||||
certptr += set_length(certptr, cert_len);
|
certptr += set_length(certptr, cert_len);
|
||||||
if (compress) {
|
if (compress) {
|
||||||
@@ -587,20 +604,36 @@ import_cert_out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool set_chuid(ykpiv_state *state, int verbose) {
|
static bool set_dataobject(ykpiv_state *state, int verbose, int type) {
|
||||||
unsigned char chuid[sizeof(chuid_tmpl)];
|
unsigned char obj[1024];
|
||||||
ykpiv_rc res;
|
ykpiv_rc res;
|
||||||
|
size_t offs, rand_len, len;
|
||||||
|
const unsigned char *tmpl;
|
||||||
|
int id;
|
||||||
|
|
||||||
memcpy(chuid, chuid_tmpl, sizeof(chuid));
|
if(type == CHUID) {
|
||||||
if(RAND_pseudo_bytes(chuid + CHUID_GUID_OFFS, 0x10) == -1) {
|
offs = CHUID_GUID_OFFS;
|
||||||
|
len = sizeof(chuid_tmpl);
|
||||||
|
rand_len = 0x10;
|
||||||
|
tmpl = chuid_tmpl;
|
||||||
|
id = YKPIV_OBJ_CHUID;
|
||||||
|
} else {
|
||||||
|
offs = CCC_ID_OFFS;
|
||||||
|
rand_len = 0xe;
|
||||||
|
len = sizeof(ccc_tmpl);
|
||||||
|
tmpl = ccc_tmpl;
|
||||||
|
id = YKPIV_OBJ_CAPABILITY;
|
||||||
|
}
|
||||||
|
memcpy(obj, tmpl, len);
|
||||||
|
if(RAND_pseudo_bytes(obj + offs, rand_len) == -1) {
|
||||||
fprintf(stderr, "error: no randomness.\n");
|
fprintf(stderr, "error: no randomness.\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(verbose) {
|
if(verbose) {
|
||||||
fprintf(stderr, "Setting the CHUID to: ");
|
fprintf(stderr, "Setting the %s to: ", type == CHUID ? "CHUID" : "CCC");
|
||||||
dump_hex(chuid, sizeof(chuid), stderr, true);
|
dump_data(obj, len, stderr, true, format_arg_hex);
|
||||||
}
|
}
|
||||||
if((res = ykpiv_save_object(state, YKPIV_OBJ_CHUID, chuid, sizeof(chuid))) != YKPIV_OK) {
|
if((res = ykpiv_save_object(state, id, obj, len)) != YKPIV_OK) {
|
||||||
fprintf(stderr, "Failed communicating with device: %s\n", ykpiv_strerror(res));
|
fprintf(stderr, "Failed communicating with device: %s\n", ykpiv_strerror(res));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -748,7 +781,7 @@ request_out:
|
|||||||
|
|
||||||
static bool selfsign_certificate(ykpiv_state *state, enum enum_key_format key_format,
|
static bool selfsign_certificate(ykpiv_state *state, enum enum_key_format key_format,
|
||||||
const char *input_file_name, const char *slot, char *subject, enum enum_hash hash,
|
const char *input_file_name, const char *slot, char *subject, enum enum_hash hash,
|
||||||
const char *output_file_name) {
|
int serial, int validDays, const char *output_file_name) {
|
||||||
FILE *input_file = NULL;
|
FILE *input_file = NULL;
|
||||||
FILE *output_file = NULL;
|
FILE *output_file = NULL;
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
@@ -814,7 +847,7 @@ static bool selfsign_certificate(ykpiv_state *state, enum enum_key_format key_fo
|
|||||||
fprintf(stderr, "Failed to set the certificate public key.\n");
|
fprintf(stderr, "Failed to set the certificate public key.\n");
|
||||||
goto selfsign_out;
|
goto selfsign_out;
|
||||||
}
|
}
|
||||||
if(!ASN1_INTEGER_set(X509_get_serialNumber(x509), 1)) {
|
if(!ASN1_INTEGER_set(X509_get_serialNumber(x509), serial)) {
|
||||||
fprintf(stderr, "Failed to set certificate serial.\n");
|
fprintf(stderr, "Failed to set certificate serial.\n");
|
||||||
goto selfsign_out;
|
goto selfsign_out;
|
||||||
}
|
}
|
||||||
@@ -822,7 +855,7 @@ static bool selfsign_certificate(ykpiv_state *state, enum enum_key_format key_fo
|
|||||||
fprintf(stderr, "Failed to set certificate notBefore.\n");
|
fprintf(stderr, "Failed to set certificate notBefore.\n");
|
||||||
goto selfsign_out;
|
goto selfsign_out;
|
||||||
}
|
}
|
||||||
if(!X509_gmtime_adj(X509_get_notAfter(x509), 31536000L)) {
|
if(!X509_gmtime_adj(X509_get_notAfter(x509), 60L * 60L * 24L * validDays)) {
|
||||||
fprintf(stderr, "Failed to set certificate notAfter.\n");
|
fprintf(stderr, "Failed to set certificate notAfter.\n");
|
||||||
goto selfsign_out;
|
goto selfsign_out;
|
||||||
}
|
}
|
||||||
@@ -936,17 +969,16 @@ static bool verify_pin(ykpiv_state *state, const char *pin) {
|
|||||||
* since they're very similar in what data they use. */
|
* since they're very similar in what data they use. */
|
||||||
static bool change_pin(ykpiv_state *state, enum enum_action action, const char *pin,
|
static bool change_pin(ykpiv_state *state, enum enum_action action, const char *pin,
|
||||||
const char *new_pin) {
|
const char *new_pin) {
|
||||||
unsigned char templ[] = {0, YKPIV_INS_CHANGE_REFERENCE, 0, 0x80};
|
|
||||||
unsigned char indata[0x10];
|
|
||||||
unsigned char data[0xff];
|
|
||||||
unsigned long recv_len = sizeof(data);
|
|
||||||
char pinbuf[9] = {0};
|
char pinbuf[9] = {0};
|
||||||
char new_pinbuf[9] = {0};
|
char new_pinbuf[9] = {0};
|
||||||
const char *name = action == action_arg_changeMINUS_pin ? "pin" : "puk";
|
const char *name = action == action_arg_changeMINUS_pin ? "pin" : "puk";
|
||||||
const char *new_name = action == action_arg_changeMINUS_puk ? "new puk" : "new pin";
|
const char *new_name = action == action_arg_changeMINUS_puk ? "new puk" : "new pin";
|
||||||
int sw;
|
int (*op)(ykpiv_state *state, const char * puk, size_t puk_len,
|
||||||
|
const char * new_pin, size_t new_pin_len, int *tries) = ykpiv_change_pin;
|
||||||
size_t pin_len;
|
size_t pin_len;
|
||||||
size_t new_len;
|
size_t new_len;
|
||||||
|
int tries;
|
||||||
|
ykpiv_rc res;
|
||||||
|
|
||||||
if(!pin) {
|
if(!pin) {
|
||||||
if (!read_pw(name, pinbuf, sizeof(pinbuf), false)) {
|
if (!read_pw(name, pinbuf, sizeof(pinbuf), false)) {
|
||||||
@@ -969,38 +1001,33 @@ static bool change_pin(ykpiv_state *state, enum enum_action action, const char *
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(action == action_arg_unblockMINUS_pin) {
|
if(action == action_arg_unblockMINUS_pin) {
|
||||||
templ[1] = YKPIV_INS_RESET_RETRY;
|
op = ykpiv_unblock_pin;
|
||||||
}
|
}
|
||||||
else if(action == action_arg_changeMINUS_puk) {
|
else if(action == action_arg_changeMINUS_puk) {
|
||||||
templ[3] = 0x81;
|
op = ykpiv_change_puk;
|
||||||
}
|
}
|
||||||
memcpy(indata, pin, pin_len);
|
res = op(state, pin, pin_len, new_pin, new_len, &tries);
|
||||||
if(pin_len < 8) {
|
switch (res) {
|
||||||
memset(indata + pin_len, 0xff, 8 - pin_len);
|
case YKPIV_OK:
|
||||||
}
|
return true;
|
||||||
memcpy(indata + 8, new_pin, new_len);
|
|
||||||
if(new_len < 8) {
|
case YKPIV_WRONG_PIN:
|
||||||
memset(indata + 8 + new_len, 0xff, 16 - new_len);
|
|
||||||
}
|
|
||||||
if(ykpiv_transfer_data(state, templ, indata, sizeof(indata), data, &recv_len, &sw) != YKPIV_OK) {
|
|
||||||
return false;
|
|
||||||
} else if(sw != 0x9000) {
|
|
||||||
if((sw >> 8) == 0x63) {
|
|
||||||
int tries = sw & 0xf;
|
|
||||||
fprintf(stderr, "Failed verifying %s code, now %d tries left before blocked.\n",
|
fprintf(stderr, "Failed verifying %s code, now %d tries left before blocked.\n",
|
||||||
name, tries);
|
name, tries);
|
||||||
} else if(sw == 0x6983) {
|
return false;
|
||||||
|
|
||||||
|
case YKPIV_PIN_LOCKED:
|
||||||
if(action == action_arg_changeMINUS_pin) {
|
if(action == action_arg_changeMINUS_pin) {
|
||||||
fprintf(stderr, "The pin code is blocked, use the unblock-pin action to unblock it.\n");
|
fprintf(stderr, "The pin code is blocked, use the unblock-pin action to unblock it.\n");
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "The puk code is blocked, you will have to reinitialize the application.\n");
|
fprintf(stderr, "The puk code is blocked, you will have to reinitialize the application.\n");
|
||||||
}
|
}
|
||||||
} else {
|
return false;
|
||||||
fprintf(stderr, "Failed changing/unblocking code, error: %x\n", sw);
|
|
||||||
}
|
default:
|
||||||
|
fprintf(stderr, "Failed changing/unblocking code, error: %x\n", res);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool delete_certificate(ykpiv_state *state, enum enum_slot slot) {
|
static bool delete_certificate(ykpiv_state *state, enum enum_slot slot) {
|
||||||
@@ -1019,7 +1046,7 @@ static bool read_certificate(ykpiv_state *state, enum enum_slot slot,
|
|||||||
enum enum_key_format key_format, const char *output_file_name) {
|
enum enum_key_format key_format, const char *output_file_name) {
|
||||||
FILE *output_file;
|
FILE *output_file;
|
||||||
int object = get_object_id(slot);
|
int object = get_object_id(slot);
|
||||||
unsigned char data[2048];
|
unsigned char data[3072];
|
||||||
const unsigned char *ptr = data;
|
const unsigned char *ptr = data;
|
||||||
unsigned long len = sizeof(data);
|
unsigned long len = sizeof(data);
|
||||||
int cert_len;
|
int cert_len;
|
||||||
@@ -1100,6 +1127,9 @@ static bool sign_file(ykpiv_state *state, const char *input, const char *output,
|
|||||||
|
|
||||||
output_file = open_file(output, OUTPUT);
|
output_file = open_file(output, OUTPUT);
|
||||||
if(!output_file) {
|
if(!output_file) {
|
||||||
|
if(input_file && input_file != stdin) {
|
||||||
|
fclose(input_file);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1127,7 +1157,7 @@ static bool sign_file(ykpiv_state *state, const char *input, const char *output,
|
|||||||
|
|
||||||
if(verbosity) {
|
if(verbosity) {
|
||||||
fprintf(stderr, "file hashed as: ");
|
fprintf(stderr, "file hashed as: ");
|
||||||
dump_hex(hashed, hash_len, stderr, true);
|
dump_data(hashed, hash_len, stderr, true, format_arg_hex);
|
||||||
}
|
}
|
||||||
EVP_MD_CTX_destroy(mdctx);
|
EVP_MD_CTX_destroy(mdctx);
|
||||||
}
|
}
|
||||||
@@ -1146,7 +1176,7 @@ static bool sign_file(ykpiv_state *state, const char *input, const char *output,
|
|||||||
|
|
||||||
if(verbosity) {
|
if(verbosity) {
|
||||||
fprintf(stderr, "file signed as: ");
|
fprintf(stderr, "file signed as: ");
|
||||||
dump_hex(buf, len, stderr, true);
|
dump_data(buf, len, stderr, true, format_arg_hex);
|
||||||
}
|
}
|
||||||
fwrite(buf, 1, len, output_file);
|
fwrite(buf, 1, len, output_file);
|
||||||
ret = true;
|
ret = true;
|
||||||
@@ -1167,7 +1197,8 @@ out:
|
|||||||
static void print_cert_info(ykpiv_state *state, enum enum_slot slot, const EVP_MD *md,
|
static void print_cert_info(ykpiv_state *state, enum enum_slot slot, const EVP_MD *md,
|
||||||
FILE *output) {
|
FILE *output) {
|
||||||
int object = get_object_id(slot);
|
int object = get_object_id(slot);
|
||||||
unsigned char data[2048];
|
int slot_name;
|
||||||
|
unsigned char data[3072];
|
||||||
const unsigned char *ptr = data;
|
const unsigned char *ptr = data;
|
||||||
unsigned long len = sizeof(data);
|
unsigned long len = sizeof(data);
|
||||||
int cert_len;
|
int cert_len;
|
||||||
@@ -1176,10 +1207,18 @@ static void print_cert_info(ykpiv_state *state, enum enum_slot slot, const EVP_M
|
|||||||
BIO *bio = NULL;
|
BIO *bio = NULL;
|
||||||
|
|
||||||
if(ykpiv_fetch_object(state, object, data, &len) != YKPIV_OK) {
|
if(ykpiv_fetch_object(state, object, data, &len) != YKPIV_OK) {
|
||||||
fprintf(output, "No data available.\n");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (slot == slot_arg_9a)
|
||||||
|
slot_name = 0x9a;
|
||||||
|
else if (slot >= slot_arg_9c && slot <= slot_arg_9e)
|
||||||
|
slot_name = 0x9b + slot;
|
||||||
|
else
|
||||||
|
slot_name = 0x82 + (slot - slot_arg_82);
|
||||||
|
|
||||||
|
fprintf(output, "Slot %x:\t", slot_name);
|
||||||
|
|
||||||
if(*ptr++ == 0x70) {
|
if(*ptr++ == 0x70) {
|
||||||
unsigned int md_len = sizeof(data);
|
unsigned int md_len = sizeof(data);
|
||||||
ASN1_TIME *not_before, *not_after;
|
ASN1_TIME *not_before, *not_after;
|
||||||
@@ -1237,7 +1276,7 @@ static void print_cert_info(ykpiv_state *state, enum enum_slot slot, const EVP_M
|
|||||||
fprintf(output, "\n");
|
fprintf(output, "\n");
|
||||||
X509_digest(x509, md, data, &md_len);
|
X509_digest(x509, md, data, &md_len);
|
||||||
fprintf(output, "\tFingerprint:\t");
|
fprintf(output, "\tFingerprint:\t");
|
||||||
dump_hex(data, md_len, output, false);
|
dump_data(data, md_len, output, false, format_arg_hex);
|
||||||
|
|
||||||
bio = BIO_new_fp(output, BIO_NOCLOSE | BIO_FP_TEXT);
|
bio = BIO_new_fp(output, BIO_NOCLOSE | BIO_FP_TEXT);
|
||||||
not_before = X509_get_notBefore(x509);
|
not_before = X509_get_notBefore(x509);
|
||||||
@@ -1266,10 +1305,12 @@ cert_out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool status(ykpiv_state *state, enum enum_hash hash,
|
static bool status(ykpiv_state *state, enum enum_hash hash,
|
||||||
|
enum enum_slot slot,
|
||||||
const char *output_file_name) {
|
const char *output_file_name) {
|
||||||
const EVP_MD *md;
|
const EVP_MD *md;
|
||||||
unsigned char chuid[2048];
|
unsigned char buf[3072];
|
||||||
long unsigned len = sizeof(chuid);
|
long unsigned len = sizeof(buf);
|
||||||
|
int i;
|
||||||
FILE *output_file = open_file(output_file_name, OUTPUT);
|
FILE *output_file = open_file(output_file_name, OUTPUT);
|
||||||
if(!output_file) {
|
if(!output_file) {
|
||||||
return false;
|
return false;
|
||||||
@@ -1281,20 +1322,26 @@ static bool status(ykpiv_state *state, enum enum_hash hash,
|
|||||||
}
|
}
|
||||||
|
|
||||||
fprintf(output_file, "CHUID:\t");
|
fprintf(output_file, "CHUID:\t");
|
||||||
if(ykpiv_fetch_object(state, YKPIV_OBJ_CHUID, chuid, &len) != YKPIV_OK) {
|
if(ykpiv_fetch_object(state, YKPIV_OBJ_CHUID, buf, &len) != YKPIV_OK) {
|
||||||
fprintf(output_file, "No data available\n");
|
fprintf(output_file, "No data available\n");
|
||||||
} else {
|
} else {
|
||||||
dump_hex(chuid, len, output_file, false);
|
dump_data(buf, len, output_file, false, format_arg_hex);
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(output_file, "Slot 9a:\t");
|
len = sizeof(buf);
|
||||||
print_cert_info(state, slot_arg_9a, md, output_file);
|
fprintf(output_file, "CCC:\t");
|
||||||
fprintf(output_file, "Slot 9c:\t");
|
if(ykpiv_fetch_object(state, YKPIV_OBJ_CAPABILITY, buf, &len) != YKPIV_OK) {
|
||||||
print_cert_info(state, slot_arg_9c, md, output_file);
|
fprintf(output_file, "No data available\n");
|
||||||
fprintf(output_file, "Slot 9d:\t");
|
} else {
|
||||||
print_cert_info(state, slot_arg_9d, md, output_file);
|
dump_data(buf, len, output_file, false, format_arg_hex);
|
||||||
fprintf(output_file, "Slot 9e:\t");
|
}
|
||||||
print_cert_info(state, slot_arg_9e, md, output_file);
|
|
||||||
|
if (slot == slot__NULL)
|
||||||
|
for (i = 0; i < 24; i++) {
|
||||||
|
print_cert_info(state, i, md, output_file);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
print_cert_info(state, slot, md, output_file);
|
||||||
|
|
||||||
{
|
{
|
||||||
int tries;
|
int tries;
|
||||||
@@ -1360,7 +1407,7 @@ static bool test_signature(ykpiv_state *state, enum enum_slot slot,
|
|||||||
EVP_DigestFinal_ex(mdctx, data, &data_len);
|
EVP_DigestFinal_ex(mdctx, data, &data_len);
|
||||||
if(verbose) {
|
if(verbose) {
|
||||||
fprintf(stderr, "Test data hashes as: ");
|
fprintf(stderr, "Test data hashes as: ");
|
||||||
dump_hex(data, data_len, stderr, true);
|
dump_data(data, data_len, stderr, true, format_arg_hex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1516,9 +1563,9 @@ static bool test_decipher(ykpiv_state *state, enum enum_slot slot,
|
|||||||
if(len == sizeof(secret)) {
|
if(len == sizeof(secret)) {
|
||||||
if(verbose) {
|
if(verbose) {
|
||||||
fprintf(stderr, "Generated nonce: ");
|
fprintf(stderr, "Generated nonce: ");
|
||||||
dump_hex(secret, sizeof(secret), stderr, true);
|
dump_data(secret, sizeof(secret), stderr, true, format_arg_hex);
|
||||||
fprintf(stderr, "Decrypted nonce: ");
|
fprintf(stderr, "Decrypted nonce: ");
|
||||||
dump_hex(secret2, sizeof(secret2), stderr, true);
|
dump_data(secret2, sizeof(secret2), stderr, true, format_arg_hex);
|
||||||
}
|
}
|
||||||
if(memcmp(secret, secret2, sizeof(secret)) == 0) {
|
if(memcmp(secret, secret2, sizeof(secret)) == 0) {
|
||||||
fprintf(stderr, "Successfully performed RSA decryption!\n");
|
fprintf(stderr, "Successfully performed RSA decryption!\n");
|
||||||
@@ -1558,9 +1605,9 @@ static bool test_decipher(ykpiv_state *state, enum enum_slot slot,
|
|||||||
}
|
}
|
||||||
if(verbose) {
|
if(verbose) {
|
||||||
fprintf(stderr, "ECDH host generated: ");
|
fprintf(stderr, "ECDH host generated: ");
|
||||||
dump_hex(secret, len, stderr, true);
|
dump_data(secret, len, stderr, true, format_arg_hex);
|
||||||
fprintf(stderr, "ECDH card generated: ");
|
fprintf(stderr, "ECDH card generated: ");
|
||||||
dump_hex(secret2, len, stderr, true);
|
dump_data(secret2, len, stderr, true, format_arg_hex);
|
||||||
}
|
}
|
||||||
if(memcmp(secret, secret2, key_len) == 0) {
|
if(memcmp(secret, secret2, key_len) == 0) {
|
||||||
fprintf(stderr, "Successfully performed ECDH exchange with card.\n");
|
fprintf(stderr, "Successfully performed ECDH exchange with card.\n");
|
||||||
@@ -1618,11 +1665,6 @@ static bool attest(ykpiv_state *state, const char *slot,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
output_file = open_file(output_file_name, OUTPUT);
|
|
||||||
if(!output_file) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ykpiv_transfer_data(state, templ, NULL, 0, data, &len, &sw) != YKPIV_OK) {
|
if(ykpiv_transfer_data(state, templ, NULL, 0, data, &len, &sw) != YKPIV_OK) {
|
||||||
fprintf(stderr, "Failed to communicate.\n");
|
fprintf(stderr, "Failed to communicate.\n");
|
||||||
goto attest_out;
|
goto attest_out;
|
||||||
@@ -1660,7 +1702,73 @@ attest_out:
|
|||||||
if(x509) {
|
if(x509) {
|
||||||
X509_free(x509);
|
X509_free(x509);
|
||||||
}
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool write_object(ykpiv_state *state, int id,
|
||||||
|
const char *input_file_name, int verbosity, enum enum_format format) {
|
||||||
|
bool ret = false;
|
||||||
|
FILE *input_file = NULL;
|
||||||
|
unsigned char data[3072];
|
||||||
|
size_t len = sizeof(data);
|
||||||
|
ykpiv_rc res;
|
||||||
|
|
||||||
|
input_file = open_file(input_file_name, INPUT);
|
||||||
|
if(!input_file) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isatty(fileno(input_file))) {
|
||||||
|
fprintf(stderr, "Please paste the data...\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
len = read_data(data, len, input_file, format);
|
||||||
|
if(len == 0) {
|
||||||
|
fprintf(stderr, "Failed reading data\n");
|
||||||
|
goto write_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(verbosity) {
|
||||||
|
fprintf(stderr, "Writing %lu bytes of data to object %x.\n", len, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if((res = ykpiv_save_object(state, id, data, len)) != YKPIV_OK) {
|
||||||
|
fprintf(stderr, "Failed writing data to device: %s\n", ykpiv_strerror(res));
|
||||||
|
} else {
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
write_out:
|
||||||
|
if(input_file != stdin) {
|
||||||
|
fclose(input_file);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool read_object(ykpiv_state *state, int id, const char *output_file_name,
|
||||||
|
enum enum_format format) {
|
||||||
|
FILE *output_file = NULL;
|
||||||
|
unsigned char data[3072];
|
||||||
|
unsigned long len = sizeof(data);
|
||||||
|
bool ret = false;
|
||||||
|
|
||||||
|
output_file = open_file(output_file_name, OUTPUT);
|
||||||
|
if(!output_file) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ykpiv_fetch_object(state, id, data, &len) != YKPIV_OK) {
|
||||||
|
fprintf(stderr, "Failed fetching object.\n");
|
||||||
|
goto read_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
dump_data(data, len, output_file, false, format);
|
||||||
|
ret = true;
|
||||||
|
|
||||||
|
read_out:
|
||||||
|
if(output_file != stdout) {
|
||||||
|
fclose(output_file);
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1671,12 +1779,16 @@ int main(int argc, char *argv[]) {
|
|||||||
enum enum_action action;
|
enum enum_action action;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
int ret = EXIT_SUCCESS;
|
int ret = EXIT_SUCCESS;
|
||||||
|
bool authed = false;
|
||||||
|
char pwbuf[128];
|
||||||
|
char *password;
|
||||||
|
|
||||||
if(cmdline_parser(argc, argv, &args_info) != 0) {
|
if(cmdline_parser(argc, argv, &args_info) != 0) {
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
verbosity = args_info.verbose_arg + (int)args_info.verbose_given;
|
verbosity = args_info.verbose_arg + (int)args_info.verbose_given;
|
||||||
|
password = args_info.password_arg;
|
||||||
|
|
||||||
for(i = 0; i < args_info.action_given; i++) {
|
for(i = 0; i < args_info.action_given; i++) {
|
||||||
action = *(args_info.action_arg + i);
|
action = *(args_info.action_arg + i);
|
||||||
@@ -1709,12 +1821,21 @@ int main(int argc, char *argv[]) {
|
|||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case action_arg_writeMINUS_object:
|
||||||
|
case action_arg_readMINUS_object:
|
||||||
|
if(!args_info.id_given) {
|
||||||
|
fprintf(stderr, "The '%s' action needs the --id argument.\n",
|
||||||
|
cmdline_parser_action_values[action]);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case action_arg_changeMINUS_pin:
|
case action_arg_changeMINUS_pin:
|
||||||
case action_arg_changeMINUS_puk:
|
case action_arg_changeMINUS_puk:
|
||||||
case action_arg_unblockMINUS_pin:
|
case action_arg_unblockMINUS_pin:
|
||||||
case action_arg_verifyMINUS_pin:
|
case action_arg_verifyMINUS_pin:
|
||||||
case action_arg_setMINUS_mgmMINUS_key:
|
case action_arg_setMINUS_mgmMINUS_key:
|
||||||
case action_arg_setMINUS_chuid:
|
case action_arg_setMINUS_chuid:
|
||||||
|
case action_arg_setMINUS_ccc:
|
||||||
case action_arg_version:
|
case action_arg_version:
|
||||||
case action_arg_reset:
|
case action_arg_reset:
|
||||||
case action_arg_status:
|
case action_arg_status:
|
||||||
@@ -1736,47 +1857,35 @@ int main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for(i = 0; i < args_info.action_given; i++) {
|
for(i = 0; i < args_info.action_given; i++) {
|
||||||
bool needs_auth = false;
|
|
||||||
action = *(args_info.action_arg + i);
|
action = *(args_info.action_arg + i);
|
||||||
switch(action) {
|
switch(action) {
|
||||||
|
case action_arg_importMINUS_key:
|
||||||
|
case action_arg_importMINUS_certificate:
|
||||||
|
if(args_info.key_format_arg == key_format_arg_PKCS12 && !password) {
|
||||||
|
if(verbosity) {
|
||||||
|
fprintf(stderr, "Asking for password since '%s' needs it.\n", cmdline_parser_action_values[action]);
|
||||||
|
}
|
||||||
|
if(!read_pw("Password", pwbuf, sizeof(pwbuf), false)) {
|
||||||
|
fprintf(stderr, "Failed to get password.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
password = pwbuf;
|
||||||
|
}
|
||||||
case action_arg_generate:
|
case action_arg_generate:
|
||||||
case action_arg_setMINUS_mgmMINUS_key:
|
case action_arg_setMINUS_mgmMINUS_key:
|
||||||
case action_arg_pinMINUS_retries:
|
case action_arg_pinMINUS_retries:
|
||||||
case action_arg_importMINUS_key:
|
|
||||||
case action_arg_importMINUS_certificate:
|
|
||||||
case action_arg_setMINUS_chuid:
|
case action_arg_setMINUS_chuid:
|
||||||
|
case action_arg_setMINUS_ccc:
|
||||||
case action_arg_deleteMINUS_certificate:
|
case action_arg_deleteMINUS_certificate:
|
||||||
if(verbosity) {
|
case action_arg_writeMINUS_object:
|
||||||
fprintf(stderr, "Authenticating since action '%s' needs that.\n", cmdline_parser_action_values[action]);
|
if(!authed) {
|
||||||
}
|
|
||||||
needs_auth = true;
|
|
||||||
break;
|
|
||||||
case action_arg_version:
|
|
||||||
case action_arg_reset:
|
|
||||||
case action_arg_requestMINUS_certificate:
|
|
||||||
case action_arg_verifyMINUS_pin:
|
|
||||||
case action_arg_changeMINUS_pin:
|
|
||||||
case action_arg_changeMINUS_puk:
|
|
||||||
case action_arg_unblockMINUS_pin:
|
|
||||||
case action_arg_selfsignMINUS_certificate:
|
|
||||||
case action_arg_readMINUS_certificate:
|
|
||||||
case action_arg_status:
|
|
||||||
case action_arg_testMINUS_signature:
|
|
||||||
case action_arg_testMINUS_decipher:
|
|
||||||
case action_arg_listMINUS_readers:
|
|
||||||
case action_arg_attest:
|
|
||||||
case action__NULL:
|
|
||||||
default:
|
|
||||||
if(verbosity) {
|
|
||||||
fprintf(stderr, "Action '%s' does not need authentication.\n", cmdline_parser_action_values[action]);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(needs_auth) {
|
|
||||||
unsigned char key[KEY_LEN];
|
unsigned char key[KEY_LEN];
|
||||||
size_t key_len = sizeof(key);
|
size_t key_len = sizeof(key);
|
||||||
char keybuf[KEY_LEN*2+1];
|
char keybuf[KEY_LEN*2+1];
|
||||||
char *key_ptr = args_info.key_arg;
|
char *key_ptr = args_info.key_arg;
|
||||||
|
if(verbosity) {
|
||||||
|
fprintf(stderr, "Authenticating since action '%s' needs that.\n", cmdline_parser_action_values[action]);
|
||||||
|
}
|
||||||
if(args_info.key_given && args_info.key_orig == NULL) {
|
if(args_info.key_given && args_info.key_orig == NULL) {
|
||||||
if(!read_pw("management key", keybuf, sizeof(keybuf), false)) {
|
if(!read_pw("management key", keybuf, sizeof(keybuf), false)) {
|
||||||
fprintf(stderr, "Failed to read management key from stdin,\n");
|
fprintf(stderr, "Failed to read management key from stdin,\n");
|
||||||
@@ -1796,13 +1905,41 @@ int main(int argc, char *argv[]) {
|
|||||||
if(verbosity) {
|
if(verbosity) {
|
||||||
fprintf(stderr, "Successful application authentication.\n");
|
fprintf(stderr, "Successful application authentication.\n");
|
||||||
}
|
}
|
||||||
|
authed = true;
|
||||||
|
} else {
|
||||||
|
if(verbosity) {
|
||||||
|
fprintf(stderr, "Skipping authentication for '%s' since it's already done.\n", cmdline_parser_action_values[action]);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
case action_arg_version:
|
||||||
|
case action_arg_reset:
|
||||||
|
case action_arg_requestMINUS_certificate:
|
||||||
|
case action_arg_verifyMINUS_pin:
|
||||||
|
case action_arg_changeMINUS_pin:
|
||||||
|
case action_arg_changeMINUS_puk:
|
||||||
|
case action_arg_unblockMINUS_pin:
|
||||||
|
case action_arg_selfsignMINUS_certificate:
|
||||||
|
case action_arg_readMINUS_certificate:
|
||||||
|
case action_arg_status:
|
||||||
|
case action_arg_testMINUS_signature:
|
||||||
|
case action_arg_testMINUS_decipher:
|
||||||
|
case action_arg_listMINUS_readers:
|
||||||
|
case action_arg_attest:
|
||||||
|
case action_arg_readMINUS_object:
|
||||||
|
case action__NULL:
|
||||||
|
default:
|
||||||
|
if(verbosity) {
|
||||||
|
fprintf(stderr, "Action '%s' does not need authentication.\n", cmdline_parser_action_values[action]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* openssl setup.. */
|
/* openssl setup.. */
|
||||||
OpenSSL_add_all_algorithms();
|
OpenSSL_add_all_algorithms();
|
||||||
|
|
||||||
|
|
||||||
for(i = 0; i < args_info.action_given; i++) {
|
for(i = 0; i < args_info.action_given; i++) {
|
||||||
char new_keybuf[KEY_LEN*2+1] = {0};
|
char new_keybuf[KEY_LEN*2+1] = {0};
|
||||||
char *new_mgm_key = args_info.new_key_arg;
|
char *new_mgm_key = args_info.new_key_arg;
|
||||||
@@ -1871,25 +2008,27 @@ int main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case action_arg_importMINUS_key:
|
case action_arg_importMINUS_key:
|
||||||
if(import_key(state, args_info.key_format_arg, args_info.input_arg, args_info.slot_orig, args_info.password_arg,
|
if(import_key(state, args_info.key_format_arg, args_info.input_arg, args_info.slot_orig, password,
|
||||||
args_info.pin_policy_arg, args_info.touch_policy_arg) == false) {
|
args_info.pin_policy_arg, args_info.touch_policy_arg) == false) {
|
||||||
|
fprintf(stderr, "Unable to import private key\n");
|
||||||
ret = EXIT_FAILURE;
|
ret = EXIT_FAILURE;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Successfully imported a new private key.\n");
|
fprintf(stderr, "Successfully imported a new private key.\n");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case action_arg_importMINUS_certificate:
|
case action_arg_importMINUS_certificate:
|
||||||
if(import_cert(state, args_info.key_format_arg, args_info.input_arg, args_info.slot_arg, args_info.password_arg) == false) {
|
if(import_cert(state, args_info.key_format_arg, args_info.input_arg, args_info.slot_arg, password) == false) {
|
||||||
ret = EXIT_FAILURE;
|
ret = EXIT_FAILURE;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Successfully imported a new certificate.\n");
|
fprintf(stderr, "Successfully imported a new certificate.\n");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case action_arg_setMINUS_ccc:
|
||||||
case action_arg_setMINUS_chuid:
|
case action_arg_setMINUS_chuid:
|
||||||
if(set_chuid(state, verbosity) == false) {
|
if(set_dataobject(state, verbosity, action == action_arg_setMINUS_chuid ? CHUID : CCC) == false) {
|
||||||
ret = EXIT_FAILURE;
|
ret = EXIT_FAILURE;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Successfully set new CHUID.\n");
|
fprintf(stderr, "Successfully set new %s.\n", action == action_arg_setMINUS_chuid ? "CHUID" : "CCC");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case action_arg_requestMINUS_certificate:
|
case action_arg_requestMINUS_certificate:
|
||||||
@@ -1925,6 +2064,7 @@ int main(int argc, char *argv[]) {
|
|||||||
case action_arg_selfsignMINUS_certificate:
|
case action_arg_selfsignMINUS_certificate:
|
||||||
if(selfsign_certificate(state, args_info.key_format_arg, args_info.input_arg,
|
if(selfsign_certificate(state, args_info.key_format_arg, args_info.input_arg,
|
||||||
args_info.slot_orig, args_info.subject_arg, args_info.hash_arg,
|
args_info.slot_orig, args_info.subject_arg, args_info.hash_arg,
|
||||||
|
args_info.serial_arg, args_info.valid_days_arg,
|
||||||
args_info.output_arg) == false) {
|
args_info.output_arg) == false) {
|
||||||
ret = EXIT_FAILURE;
|
ret = EXIT_FAILURE;
|
||||||
} else {
|
} else {
|
||||||
@@ -1943,7 +2083,7 @@ int main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case action_arg_status:
|
case action_arg_status:
|
||||||
if(status(state, args_info.hash_arg, args_info.output_arg) == false) {
|
if(status(state, args_info.hash_arg, args_info.slot_arg, args_info.output_arg) == false) {
|
||||||
ret = EXIT_FAILURE;
|
ret = EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -1963,6 +2103,17 @@ int main(int argc, char *argv[]) {
|
|||||||
if(list_readers(state) == false) {
|
if(list_readers(state) == false) {
|
||||||
ret = EXIT_FAILURE;
|
ret = EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
case action_arg_writeMINUS_object:
|
||||||
|
if(write_object(state, args_info.id_arg, args_info.input_arg, verbosity,
|
||||||
|
args_info.format_arg) == false) {
|
||||||
|
ret = EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case action_arg_readMINUS_object:
|
||||||
|
if(read_object(state, args_info.id_arg, args_info.output_arg,
|
||||||
|
args_info.format_arg) == false) {
|
||||||
|
ret = EXIT_FAILURE;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case action_arg_attest:
|
case action_arg_attest:
|
||||||
if(attest(state, args_info.slot_orig, args_info.key_format_arg,
|
if(attest(state, args_info.slot_orig, args_info.key_format_arg,
|
||||||
|
|||||||
+2
-5
@@ -26,7 +26,7 @@
|
|||||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
PACKAGE=yubico-piv-tool
|
PACKAGE=yubico-piv-tool
|
||||||
OPENSSLVERSION=1.0.1p
|
OPENSSLVERSION=1.0.1r
|
||||||
|
|
||||||
all: usage 32bit 64bit
|
all: usage 32bit 64bit
|
||||||
|
|
||||||
@@ -53,17 +53,14 @@ doit:
|
|||||||
rm -rf $(PWD)/tmp$(ARCH)/root/ssl/ && \
|
rm -rf $(PWD)/tmp$(ARCH)/root/ssl/ && \
|
||||||
rm $(PWD)/tmp$(ARCH)/root/bin/openssl.exe && \
|
rm $(PWD)/tmp$(ARCH)/root/bin/openssl.exe && \
|
||||||
rm $(PWD)/tmp$(ARCH)/root/bin/c_rehash && \
|
rm $(PWD)/tmp$(ARCH)/root/bin/c_rehash && \
|
||||||
rm $(PWD)/tmp$(ARCH)/root/bin/ssleay32.dll && \
|
|
||||||
rm -rf $(PWD)/tmp$(ARCH)/root/lib/engines/ && \
|
rm -rf $(PWD)/tmp$(ARCH)/root/lib/engines/ && \
|
||||||
rm -rf $(PWD)/tmp$(ARCH)/root/lib/libssl* && \
|
|
||||||
rm $(PWD)/tmp$(ARCH)/root/lib/pkgconfig/libssl.pc && \
|
|
||||||
rm $(PWD)/tmp$(ARCH)/root/lib/pkgconfig/openssl.pc && \
|
|
||||||
cd .. && \
|
cd .. && \
|
||||||
cp ../$(PACKAGE)-$(VERSION).tar.gz . && \
|
cp ../$(PACKAGE)-$(VERSION).tar.gz . && \
|
||||||
tar xfa $(PACKAGE)-$(VERSION).tar.gz && \
|
tar xfa $(PACKAGE)-$(VERSION).tar.gz && \
|
||||||
cd $(PACKAGE)-$(VERSION)/ && \
|
cd $(PACKAGE)-$(VERSION)/ && \
|
||||||
CC=$(HOST)-gcc PKG_CONFIG_PATH=$(PWD)/tmp$(ARCH)/root/lib/pkgconfig lt_cv_deplibs_check_method=pass_all ./configure --host=$(HOST) --build=x86_64-unknown-linux-gnu --prefix=$(PWD)/tmp$(ARCH)/root LDFLAGS=-L$(PWD)/tmp$(ARCH)/root/lib CPPFLAGS=-I$(PWD)/tmp$(ARCH)/root/include && \
|
CC=$(HOST)-gcc PKG_CONFIG_PATH=$(PWD)/tmp$(ARCH)/root/lib/pkgconfig lt_cv_deplibs_check_method=pass_all ./configure --host=$(HOST) --build=x86_64-unknown-linux-gnu --prefix=$(PWD)/tmp$(ARCH)/root LDFLAGS=-L$(PWD)/tmp$(ARCH)/root/lib CPPFLAGS=-I$(PWD)/tmp$(ARCH)/root/include && \
|
||||||
make install $(CHECK) && \
|
make install $(CHECK) && \
|
||||||
|
rm -rf $(PWD)/tmp$(ARCH)/root/lib/pkgconfig/ && \
|
||||||
cp COPYING $(PWD)/tmp$(ARCH)/root/licenses/$(PACKAGE).txt && \
|
cp COPYING $(PWD)/tmp$(ARCH)/root/licenses/$(PACKAGE).txt && \
|
||||||
cd .. && \
|
cd .. && \
|
||||||
cd root && \
|
cd root && \
|
||||||
|
|||||||
+90
-55
@@ -8,9 +8,29 @@
|
|||||||
// TODO: this is mostly from OpenSC, how to give credit?
|
// TODO: this is mostly from OpenSC, how to give credit?
|
||||||
typedef enum {
|
typedef enum {
|
||||||
PIV_DATA_OBJ_X509_PIV_AUTH = 0, // PIV authentication
|
PIV_DATA_OBJ_X509_PIV_AUTH = 0, // PIV authentication
|
||||||
PIV_DATA_OBJ_X509_CARD_AUTH, // Certificate for card authentication
|
PIV_DATA_OBJ_X509_CARD_AUTH, // Card authentication
|
||||||
PIV_DATA_OBJ_X509_DS, // Certificate for digital signature
|
PIV_DATA_OBJ_X509_DS, // Digital signature
|
||||||
PIV_DATA_OBJ_X509_KM, // Certificate for key management
|
PIV_DATA_OBJ_X509_KM, // Key management
|
||||||
|
PIV_DATA_OBJ_X509_RETIRED1, // Retired key 1
|
||||||
|
PIV_DATA_OBJ_X509_RETIRED2, // Retired key 2
|
||||||
|
PIV_DATA_OBJ_X509_RETIRED3, // Retired key 3
|
||||||
|
PIV_DATA_OBJ_X509_RETIRED4, // Retired key 4
|
||||||
|
PIV_DATA_OBJ_X509_RETIRED5, // Retired key 5
|
||||||
|
PIV_DATA_OBJ_X509_RETIRED6, // Retired key 6
|
||||||
|
PIV_DATA_OBJ_X509_RETIRED7, // Retired key 7
|
||||||
|
PIV_DATA_OBJ_X509_RETIRED8, // Retired key 8
|
||||||
|
PIV_DATA_OBJ_X509_RETIRED9, // Retired key 9
|
||||||
|
PIV_DATA_OBJ_X509_RETIRED10, // Retired key 10
|
||||||
|
PIV_DATA_OBJ_X509_RETIRED11, // Retired key 11
|
||||||
|
PIV_DATA_OBJ_X509_RETIRED12, // Retired key 12
|
||||||
|
PIV_DATA_OBJ_X509_RETIRED13, // Retired key 13
|
||||||
|
PIV_DATA_OBJ_X509_RETIRED14, // Retired key 14
|
||||||
|
PIV_DATA_OBJ_X509_RETIRED15, // Retired key 15
|
||||||
|
PIV_DATA_OBJ_X509_RETIRED16, // Retired key 16
|
||||||
|
PIV_DATA_OBJ_X509_RETIRED17, // Retired key 17
|
||||||
|
PIV_DATA_OBJ_X509_RETIRED18, // Retired key 18
|
||||||
|
PIV_DATA_OBJ_X509_RETIRED19, // Retired key 19
|
||||||
|
PIV_DATA_OBJ_X509_RETIRED20, // Retired key 20
|
||||||
PIV_DATA_OBJ_CCC, // Card capability container
|
PIV_DATA_OBJ_CCC, // Card capability container
|
||||||
PIV_DATA_OBJ_CHUI, // Cardholder unique id
|
PIV_DATA_OBJ_CHUI, // Cardholder unique id
|
||||||
PIV_DATA_OBJ_CHF, // Cardholder fingerprints
|
PIV_DATA_OBJ_CHF, // Cardholder fingerprints
|
||||||
@@ -19,73 +39,88 @@ typedef enum {
|
|||||||
PIV_DATA_OBJ_PI, // Cardholder printed information
|
PIV_DATA_OBJ_PI, // Cardholder printed information
|
||||||
PIV_DATA_OBJ_DISCOVERY, // Discovery object
|
PIV_DATA_OBJ_DISCOVERY, // Discovery object
|
||||||
PIV_DATA_OBJ_HISTORY, // History object
|
PIV_DATA_OBJ_HISTORY, // History object
|
||||||
PIV_DATA_OBJ_RETIRED_X509_1, // Retired certificate for KM 1
|
|
||||||
PIV_DATA_OBJ_RETIRED_X509_2, // Retired certificate for KM 2
|
|
||||||
PIV_DATA_OBJ_RETIRED_X509_3, // Retired certificate for KM 3
|
|
||||||
PIV_DATA_OBJ_RETIRED_X509_4, // Retired certificate for KM 4
|
|
||||||
PIV_DATA_OBJ_RETIRED_X509_5, // Retired certificate for KM 5
|
|
||||||
PIV_DATA_OBJ_RETIRED_X509_6, // Retired certificate for KM 6
|
|
||||||
PIV_DATA_OBJ_RETIRED_X509_7, // Retired certificate for KM 7
|
|
||||||
PIV_DATA_OBJ_RETIRED_X509_8, // Retired certificate for KM 8
|
|
||||||
PIV_DATA_OBJ_RETIRED_X509_9, // Retired certificate for KM 9
|
|
||||||
PIV_DATA_OBJ_RETIRED_X509_10, // Retired certificate for KM 10
|
|
||||||
PIV_DATA_OBJ_RETIRED_X509_11, // Retired certificate for KM 11
|
|
||||||
PIV_DATA_OBJ_RETIRED_X509_12, // Retired certificate for KM 12
|
|
||||||
PIV_DATA_OBJ_RETIRED_X509_13, // Retired certificate for KM 13
|
|
||||||
PIV_DATA_OBJ_RETIRED_X509_14, // Retired certificate for KM 14
|
|
||||||
PIV_DATA_OBJ_RETIRED_X509_15, // Retired certificate for KM 15
|
|
||||||
PIV_DATA_OBJ_RETIRED_X509_16, // Retired certificate for KM 16
|
|
||||||
PIV_DATA_OBJ_RETIRED_X509_17, // Retired certificate for KM 17
|
|
||||||
PIV_DATA_OBJ_RETIRED_X509_18, // Retired certificate for KM 18
|
|
||||||
PIV_DATA_OBJ_RETIRED_X509_19, // Retired certificate for KM 19
|
|
||||||
PIV_DATA_OBJ_RETIRED_X509_20, // Retired certificate for KM 20
|
|
||||||
PIV_DATA_OBJ_IRIS_IMAGE, // Cardholder iris images
|
PIV_DATA_OBJ_IRIS_IMAGE, // Cardholder iris images
|
||||||
PIV_DATA_OBJ_BITGT, // Biometric information templates group template
|
PIV_DATA_OBJ_BITGT, // Biometric information templates group template
|
||||||
PIV_DATA_OBJ_SM_SIGNER, // Secure messaging signer
|
PIV_DATA_OBJ_SM_SIGNER, // Secure messaging signer
|
||||||
PIV_DATA_OBJ_PC_REF_DATA, // Pairing code reference data
|
PIV_DATA_OBJ_PC_REF_DATA, // Pairing code reference data
|
||||||
/* PIV_DATA_OBJ_9B03, // NON-STANDARD TODO: remove?
|
|
||||||
PIV_DATA_OBJ_9A06, // NON-STANDARD
|
|
||||||
PIV_DATA_OBJ_9C06, // NON-STANDARD
|
|
||||||
PIV_DATA_OBJ_9D06, // NON-STANDARD
|
|
||||||
PIV_DATA_OBJ_9E06, // NON-STANDARD
|
|
||||||
PIV_DATA_OBJ_8206, // NON-STANDARD
|
|
||||||
PIV_DATA_OBJ_8306, // NON-STANDARD
|
|
||||||
PIV_DATA_OBJ_8406, // NON-STANDARD
|
|
||||||
PIV_DATA_OBJ_8506, // NON-STANDARD
|
|
||||||
PIV_DATA_OBJ_8606, // NON-STANDARD
|
|
||||||
PIV_DATA_OBJ_8706, // NON-STANDARD
|
|
||||||
PIV_DATA_OBJ_8806, // NON-STANDARD
|
|
||||||
PIV_DATA_OBJ_8906, // NON-STANDARD
|
|
||||||
PIV_DATA_OBJ_8A06, // NON-STANDARD
|
|
||||||
PIV_DATA_OBJ_8B06, // NON-STANDARD
|
|
||||||
PIV_DATA_OBJ_8C06, // NON-STANDARD
|
|
||||||
PIV_DATA_OBJ_8D06, // NON-STANDARD
|
|
||||||
PIV_DATA_OBJ_8E06, // NON-STANDARD
|
|
||||||
PIV_DATA_OBJ_8F06, // NON-STANDARD
|
|
||||||
PIV_DATA_OBJ_9006, // NON-STANDARD
|
|
||||||
PIV_DATA_OBJ_9106, // NON-STANDARD
|
|
||||||
PIV_DATA_OBJ_9206, // NON-STANDARD
|
|
||||||
PIV_DATA_OBJ_9306, // NON-STANDARD
|
|
||||||
PIV_DATA_OBJ_9406, // NON-STANDARD
|
|
||||||
PIV_DATA_OBJ_9506, // NON-STANDARD*/
|
|
||||||
PIV_DATA_OBJ_LAST,
|
PIV_DATA_OBJ_LAST,
|
||||||
|
|
||||||
PIV_CERT_OBJ_X509_PIV_AUTH, // PIV authentication
|
PIV_CERT_OBJ_X509_PIV_AUTH, // Certificate for PIV authentication
|
||||||
PIV_CERT_OBJ_X509_CARD_AUTH, // Certificate for card authentication
|
PIV_CERT_OBJ_X509_CARD_AUTH, // Certificate for card authentication
|
||||||
PIV_CERT_OBJ_X509_DS, // Certificate for digital signature
|
PIV_CERT_OBJ_X509_DS, // Certificate for digital signature
|
||||||
PIV_CERT_OBJ_X509_KM, // Certificate for key management
|
PIV_CERT_OBJ_X509_KM, // Certificate for key management
|
||||||
|
PIV_CERT_OBJ_X509_RETIRED1, // Certificate for retired key 1
|
||||||
|
PIV_CERT_OBJ_X509_RETIRED2, // Certificate for retired key 2
|
||||||
|
PIV_CERT_OBJ_X509_RETIRED3, // Certificate for retired key 3
|
||||||
|
PIV_CERT_OBJ_X509_RETIRED4, // Certificate for retired key 4
|
||||||
|
PIV_CERT_OBJ_X509_RETIRED5, // Certificate for retired key 5
|
||||||
|
PIV_CERT_OBJ_X509_RETIRED6, // Certificate for retired key 6
|
||||||
|
PIV_CERT_OBJ_X509_RETIRED7, // Certificate for retired key 7
|
||||||
|
PIV_CERT_OBJ_X509_RETIRED8, // Certificate for retired key 8
|
||||||
|
PIV_CERT_OBJ_X509_RETIRED9, // Certificate for retired key 9
|
||||||
|
PIV_CERT_OBJ_X509_RETIRED10, // Certificate for retired key 10
|
||||||
|
PIV_CERT_OBJ_X509_RETIRED11, // Certificate for retired key 11
|
||||||
|
PIV_CERT_OBJ_X509_RETIRED12, // Certificate for retired key 12
|
||||||
|
PIV_CERT_OBJ_X509_RETIRED13, // Certificate for retired key 13
|
||||||
|
PIV_CERT_OBJ_X509_RETIRED14, // Certificate for retired key 14
|
||||||
|
PIV_CERT_OBJ_X509_RETIRED15, // Certificate for retired key 15
|
||||||
|
PIV_CERT_OBJ_X509_RETIRED16, // Certificate for retired key 16
|
||||||
|
PIV_CERT_OBJ_X509_RETIRED17, // Certificate for retired key 17
|
||||||
|
PIV_CERT_OBJ_X509_RETIRED18, // Certificate for retired key 18
|
||||||
|
PIV_CERT_OBJ_X509_RETIRED19, // Certificate for retired key 19
|
||||||
|
PIV_CERT_OBJ_X509_RETIRED20, // Certificate for retired key 20
|
||||||
PIV_CERT_OBJ_LAST,
|
PIV_CERT_OBJ_LAST,
|
||||||
|
|
||||||
PIV_PVTK_OBJ_PIV_AUTH, // Private key for PIV authentication
|
PIV_PVTK_OBJ_PIV_AUTH, // Private key for PIV authentication
|
||||||
PIV_PVTK_OBJ_CARD_AUTH, // Private Key for card authentication
|
PIV_PVTK_OBJ_CARD_AUTH, // Private key for card authentication
|
||||||
PIV_PVTK_OBJ_DS, // Private Key for digital signature
|
PIV_PVTK_OBJ_DS, // Private key for digital signature
|
||||||
PIV_PVTK_OBJ_KM, // Private Key for key management
|
PIV_PVTK_OBJ_KM, // Private key for key management
|
||||||
|
PIV_PVTK_OBJ_RETIRED1, // Private key for retired key 1
|
||||||
|
PIV_PVTK_OBJ_RETIRED2, // Private key for retired key 2
|
||||||
|
PIV_PVTK_OBJ_RETIRED3, // Private key for retired key 3
|
||||||
|
PIV_PVTK_OBJ_RETIRED4, // Private key for retired key 4
|
||||||
|
PIV_PVTK_OBJ_RETIRED5, // Private key for retired key 5
|
||||||
|
PIV_PVTK_OBJ_RETIRED6, // Private key for retired key 6
|
||||||
|
PIV_PVTK_OBJ_RETIRED7, // Private key for retired key 7
|
||||||
|
PIV_PVTK_OBJ_RETIRED8, // Private key for retired key 8
|
||||||
|
PIV_PVTK_OBJ_RETIRED9, // Private key for retired key 9
|
||||||
|
PIV_PVTK_OBJ_RETIRED10, // Private key for retired key 10
|
||||||
|
PIV_PVTK_OBJ_RETIRED11, // Private key for retired key 11
|
||||||
|
PIV_PVTK_OBJ_RETIRED12, // Private key for retired key 12
|
||||||
|
PIV_PVTK_OBJ_RETIRED13, // Private key for retired key 13
|
||||||
|
PIV_PVTK_OBJ_RETIRED14, // Private key for retired key 14
|
||||||
|
PIV_PVTK_OBJ_RETIRED15, // Private key for retired key 15
|
||||||
|
PIV_PVTK_OBJ_RETIRED16, // Private key for retired key 16
|
||||||
|
PIV_PVTK_OBJ_RETIRED17, // Private key for retired key 17
|
||||||
|
PIV_PVTK_OBJ_RETIRED18, // Private key for retired key 18
|
||||||
|
PIV_PVTK_OBJ_RETIRED19, // Private key for retired key 19
|
||||||
|
PIV_PVTK_OBJ_RETIRED20, // Private key for retired key 20
|
||||||
PIV_PVTK_OBJ_LAST,
|
PIV_PVTK_OBJ_LAST,
|
||||||
|
|
||||||
PIV_PUBK_OBJ_PIV_AUTH, // Public key for PIV authentication
|
PIV_PUBK_OBJ_PIV_AUTH, // Public key for PIV authentication
|
||||||
PIV_PUBK_OBJ_CARD_AUTH, // Public Key for card authentication
|
PIV_PUBK_OBJ_CARD_AUTH, // Public key for card authentication
|
||||||
PIV_PUBK_OBJ_DS, // Public Key for digital signature
|
PIV_PUBK_OBJ_DS, // Public key for digital signature
|
||||||
PIV_PUBK_OBJ_KM, // Public Key for key management
|
PIV_PUBK_OBJ_KM, // Public key for key management
|
||||||
|
PIV_PUBK_OBJ_RETIRED1, // Public key for retired key 1
|
||||||
|
PIV_PUBK_OBJ_RETIRED2, // Public key for retired key 2
|
||||||
|
PIV_PUBK_OBJ_RETIRED3, // Public key for retired key 3
|
||||||
|
PIV_PUBK_OBJ_RETIRED4, // Public key for retired key 4
|
||||||
|
PIV_PUBK_OBJ_RETIRED5, // Public key for retired key 5
|
||||||
|
PIV_PUBK_OBJ_RETIRED6, // Public key for retired key 6
|
||||||
|
PIV_PUBK_OBJ_RETIRED7, // Public key for retired key 7
|
||||||
|
PIV_PUBK_OBJ_RETIRED8, // Public key for retired key 8
|
||||||
|
PIV_PUBK_OBJ_RETIRED9, // Public key for retired key 9
|
||||||
|
PIV_PUBK_OBJ_RETIRED10, // Public key for retired key 10
|
||||||
|
PIV_PUBK_OBJ_RETIRED11, // Public key for retired key 11
|
||||||
|
PIV_PUBK_OBJ_RETIRED12, // Public key for retired key 12
|
||||||
|
PIV_PUBK_OBJ_RETIRED13, // Public key for retired key 13
|
||||||
|
PIV_PUBK_OBJ_RETIRED14, // Public key for retired key 14
|
||||||
|
PIV_PUBK_OBJ_RETIRED15, // Public key for retired key 15
|
||||||
|
PIV_PUBK_OBJ_RETIRED16, // Public key for retired key 16
|
||||||
|
PIV_PUBK_OBJ_RETIRED17, // Public key for retired key 17
|
||||||
|
PIV_PUBK_OBJ_RETIRED18, // Public key for retired key 18
|
||||||
|
PIV_PUBK_OBJ_RETIRED19, // Public key for retired key 19
|
||||||
|
PIV_PUBK_OBJ_RETIRED20, // Public key for retired key 20
|
||||||
PIV_PUBK_OBJ_LAST
|
PIV_PUBK_OBJ_LAST
|
||||||
|
|
||||||
} piv_obj_id_t;
|
} piv_obj_id_t;
|
||||||
|
|||||||
+355
-114
@@ -24,34 +24,34 @@ static piv_obj_t piv_objects[] = {
|
|||||||
{PIV_DATA_OBJ_X509_CARD_AUTH, 1, 0, 0, "X.509 Certificate for Card Authentication", 0, 0, get_doa, 1},
|
{PIV_DATA_OBJ_X509_CARD_AUTH, 1, 0, 0, "X.509 Certificate for Card Authentication", 0, 0, get_doa, 1},
|
||||||
{PIV_DATA_OBJ_X509_DS, 1, 0, 0, "X.509 Certificate for Digital Signature", 0, 0, get_doa, 2},
|
{PIV_DATA_OBJ_X509_DS, 1, 0, 0, "X.509 Certificate for Digital Signature", 0, 0, get_doa, 2},
|
||||||
{PIV_DATA_OBJ_X509_KM, 1, 0, 0, "X.509 Certificate for Key Management", 0, 0, get_doa, 3},
|
{PIV_DATA_OBJ_X509_KM, 1, 0, 0, "X.509 Certificate for Key Management", 0, 0, get_doa, 3},
|
||||||
{PIV_DATA_OBJ_CCC, 1, 0, 0, "Card Capability Container", 0, 0, get_doa, 4},
|
{PIV_DATA_OBJ_X509_RETIRED1, 1, 0, 0, "X.509 Certificate for Retired Key 1", 0, 0, get_doa, 4},
|
||||||
{PIV_DATA_OBJ_CHUI, 1, 0, 0, "Card Holder Unique Identifier", 0, 0, get_doa, 5},
|
{PIV_DATA_OBJ_X509_RETIRED2, 1, 0, 0, "X.509 Certificate for Retired Key 2", 0, 0, get_doa, 5},
|
||||||
{PIV_DATA_OBJ_CHF, 1, 1, 0, "Card Holder Fingerprints", 0, 0, get_doa, 6},
|
{PIV_DATA_OBJ_X509_RETIRED3, 1, 0, 0, "X.509 Certificate for Retired Key 3", 0, 0, get_doa, 6},
|
||||||
{PIV_DATA_OBJ_SEC_OBJ, 1, 0, 0, "Security Object", 0, 0, get_doa, 7},
|
{PIV_DATA_OBJ_X509_RETIRED4, 1, 0, 0, "X.509 Certificate for Retired Key 4", 0, 0, get_doa, 7},
|
||||||
{PIV_DATA_OBJ_CHFI, 1, 1, 0, "Cardholder Facial Images", 0, 0, get_doa, 8},
|
{PIV_DATA_OBJ_X509_RETIRED5, 1, 0, 0, "X.509 Certificate for Retired Key 5", 0, 0, get_doa, 8},
|
||||||
{PIV_DATA_OBJ_PI, 1, 1, 0, "Printed Information", 0, 0, get_doa, 9},
|
{PIV_DATA_OBJ_X509_RETIRED6, 1, 0, 0, "X.509 Certificate for Retired Key 6", 0, 0, get_doa, 9},
|
||||||
{PIV_DATA_OBJ_DISCOVERY, 1, 0, 0, "Discovery Object", 0, 0, get_doa, 10},
|
{PIV_DATA_OBJ_X509_RETIRED7, 1, 0, 0, "X.509 Certificate for Retired Key 7", 0, 0, get_doa, 10},
|
||||||
{PIV_DATA_OBJ_HISTORY, 1, 0, 0, "Key History Object", 0, 0, get_doa, 11},
|
{PIV_DATA_OBJ_X509_RETIRED8, 1, 0, 0, "X.509 Certificate for Retired Key 8", 0, 0, get_doa, 11},
|
||||||
{PIV_DATA_OBJ_RETIRED_X509_1, 1, 0, 0, "Retired X.509 Certificate for Key Management 1", 0, 0, get_doa, 12},
|
{PIV_DATA_OBJ_X509_RETIRED9, 1, 0, 0, "X.509 Certificate for Retired Key 9", 0, 0, get_doa, 12},
|
||||||
{PIV_DATA_OBJ_RETIRED_X509_2, 1, 0, 0, "Retired X.509 Certificate for Key Management 2", 0, 0, get_doa, 13},
|
{PIV_DATA_OBJ_X509_RETIRED10, 1, 0, 0, "X.509 Certificate for Retired Key 10", 0, 0, get_doa, 13},
|
||||||
{PIV_DATA_OBJ_RETIRED_X509_3, 1, 0, 0, "Retired X.509 Certificate for Key Management 3", 0, 0, get_doa, 14},
|
{PIV_DATA_OBJ_X509_RETIRED11, 1, 0, 0, "X.509 Certificate for Retired Key 11", 0, 0, get_doa, 14},
|
||||||
{PIV_DATA_OBJ_RETIRED_X509_4, 1, 0, 0, "Retired X.509 Certificate for Key Management 4", 0, 0, get_doa, 15},
|
{PIV_DATA_OBJ_X509_RETIRED12, 1, 0, 0, "X.509 Certificate for Retired Key 12", 0, 0, get_doa, 15},
|
||||||
{PIV_DATA_OBJ_RETIRED_X509_5, 1, 0, 0, "Retired X.509 Certificate for Key Management 5", 0, 0, get_doa, 16},
|
{PIV_DATA_OBJ_X509_RETIRED13, 1, 0, 0, "X.509 Certificate for Retired Key 13", 0, 0, get_doa, 16},
|
||||||
{PIV_DATA_OBJ_RETIRED_X509_6, 1, 0, 0, "Retired X.509 Certificate for Key Management 6", 0, 0, get_doa, 17},
|
{PIV_DATA_OBJ_X509_RETIRED14, 1, 0, 0, "X.509 Certificate for Retired Key 14", 0, 0, get_doa, 17},
|
||||||
{PIV_DATA_OBJ_RETIRED_X509_7, 1, 0, 0, "Retired X.509 Certificate for Key Management 7", 0, 0, get_doa, 18},
|
{PIV_DATA_OBJ_X509_RETIRED15, 1, 0, 0, "X.509 Certificate for Retired Key 15", 0, 0, get_doa, 18},
|
||||||
{PIV_DATA_OBJ_RETIRED_X509_8, 1, 0, 0, "Retired X.509 Certificate for Key Management 8", 0, 0, get_doa, 19},
|
{PIV_DATA_OBJ_X509_RETIRED16, 1, 0, 0, "X.509 Certificate for Retired Key 16", 0, 0, get_doa, 19},
|
||||||
{PIV_DATA_OBJ_RETIRED_X509_9, 1, 0, 0, "Retired X.509 Certificate for Key Management 9", 0, 0, get_doa, 20},
|
{PIV_DATA_OBJ_X509_RETIRED17, 1, 0, 0, "X.509 Certificate for Retired Key 17", 0, 0, get_doa, 20},
|
||||||
{PIV_DATA_OBJ_RETIRED_X509_10, 1, 0, 0, "Retired X.509 Certificate for Key Management 10", 0, 0, get_doa, 21},
|
{PIV_DATA_OBJ_X509_RETIRED18, 1, 0, 0, "X.509 Certificate for Retired Key 18", 0, 0, get_doa, 21},
|
||||||
{PIV_DATA_OBJ_RETIRED_X509_11, 1, 0, 0, "Retired X.509 Certificate for Key Management 11", 0, 0, get_doa, 22},
|
{PIV_DATA_OBJ_X509_RETIRED19, 1, 0, 0, "X.509 Certificate for Retired Key 19", 0, 0, get_doa, 22},
|
||||||
{PIV_DATA_OBJ_RETIRED_X509_12, 1, 0, 0, "Retired X.509 Certificate for Key Management 12", 0, 0, get_doa, 23},
|
{PIV_DATA_OBJ_X509_RETIRED20, 1, 0, 0, "X.509 Certificate for Retired Key 20", 0, 0, get_doa, 23},
|
||||||
{PIV_DATA_OBJ_RETIRED_X509_13, 1, 0, 0, "Retired X.509 Certificate for Key Management 13", 0, 0, get_doa, 24},
|
{PIV_DATA_OBJ_CCC, 1, 0, 0, "Card Capability Container", 0, 0, get_doa, 24},
|
||||||
{PIV_DATA_OBJ_RETIRED_X509_14, 1, 0, 0, "Retired X.509 Certificate for Key Management 14", 0, 0, get_doa, 25},
|
{PIV_DATA_OBJ_CHUI, 1, 0, 0, "Card Holder Unique Identifier", 0, 0, get_doa, 25},
|
||||||
{PIV_DATA_OBJ_RETIRED_X509_15, 1, 0, 0, "Retired X.509 Certificate for Key Management 15", 0, 0, get_doa, 26},
|
{PIV_DATA_OBJ_CHF, 1, 1, 0, "Card Holder Fingerprints", 0, 0, get_doa, 26},
|
||||||
{PIV_DATA_OBJ_RETIRED_X509_16, 1, 0, 0, "Retired X.509 Certificate for Key Management 16", 0, 0, get_doa, 27},
|
{PIV_DATA_OBJ_SEC_OBJ, 1, 0, 0, "Security Object", 0, 0, get_doa, 27},
|
||||||
{PIV_DATA_OBJ_RETIRED_X509_17, 1, 0, 0, "Retired X.509 Certificate for Key Management 17", 0, 0, get_doa, 28},
|
{PIV_DATA_OBJ_CHFI, 1, 1, 0, "Cardholder Facial Images", 0, 0, get_doa, 28},
|
||||||
{PIV_DATA_OBJ_RETIRED_X509_18, 1, 0, 0, "Retired X.509 Certificate for Key Management 18", 0, 0, get_doa, 29},
|
{PIV_DATA_OBJ_PI, 1, 1, 0, "Printed Information", 0, 0, get_doa, 29},
|
||||||
{PIV_DATA_OBJ_RETIRED_X509_19, 1, 0, 0, "Retired X.509 Certificate for Key Management 19", 0, 0, get_doa, 30},
|
{PIV_DATA_OBJ_DISCOVERY, 1, 0, 0, "Discovery Object", 0, 0, get_doa, 30},
|
||||||
{PIV_DATA_OBJ_RETIRED_X509_20, 1, 0, 0, "Retired X.509 Certificate for Key Management 20", 0, 0, get_doa, 31},
|
{PIV_DATA_OBJ_HISTORY, 1, 0, 0, "Key History Object", 0, 0, get_doa, 31},
|
||||||
{PIV_DATA_OBJ_IRIS_IMAGE, 1, 1, 0, "Cardholder Iris Images", 0, 0, get_doa, 32},
|
{PIV_DATA_OBJ_IRIS_IMAGE, 1, 1, 0, "Cardholder Iris Images", 0, 0, get_doa, 32},
|
||||||
{PIV_DATA_OBJ_BITGT, 1, 0, 0, "Biometric Information Templates Group Template", 0, 0, get_doa, 33},
|
{PIV_DATA_OBJ_BITGT, 1, 0, 0, "Biometric Information Templates Group Template", 0, 0, get_doa, 33},
|
||||||
{PIV_DATA_OBJ_SM_SIGNER, 1, 0, 0, "Secure Messaging Certificate Signer", 0, 0, get_doa, 34},
|
{PIV_DATA_OBJ_SM_SIGNER, 1, 0, 0, "Secure Messaging Certificate Signer", 0, 0, get_doa, 34},
|
||||||
@@ -62,63 +62,142 @@ static piv_obj_t piv_objects[] = {
|
|||||||
{PIV_CERT_OBJ_X509_CARD_AUTH, 1, 0, 0, "X.509 Certificate for Card Authentication", 0, 0, get_coa, 1},
|
{PIV_CERT_OBJ_X509_CARD_AUTH, 1, 0, 0, "X.509 Certificate for Card Authentication", 0, 0, get_coa, 1},
|
||||||
{PIV_CERT_OBJ_X509_DS, 1, 0, 0, "X.509 Certificate for Digital Signature", 0, 0, get_coa, 2},
|
{PIV_CERT_OBJ_X509_DS, 1, 0, 0, "X.509 Certificate for Digital Signature", 0, 0, get_coa, 2},
|
||||||
{PIV_CERT_OBJ_X509_KM, 1, 0, 0, "X.509 Certificate for Key Management", 0, 0, get_coa, 3},
|
{PIV_CERT_OBJ_X509_KM, 1, 0, 0, "X.509 Certificate for Key Management", 0, 0, get_coa, 3},
|
||||||
{PIV_CERT_OBJ_LAST, 1, 0, 0, "", 0, 0, NULL, 4},
|
{PIV_CERT_OBJ_X509_RETIRED1, 1, 0, 0, "X.509 Certificate for Retired Key 1", 0, 0, get_coa, 4},
|
||||||
|
{PIV_CERT_OBJ_X509_RETIRED2, 1, 0, 0, "X.509 Certificate for Retired Key 2", 0, 0, get_coa, 5},
|
||||||
|
{PIV_CERT_OBJ_X509_RETIRED3, 1, 0, 0, "X.509 Certificate for Retired Key 3", 0, 0, get_coa, 6},
|
||||||
|
{PIV_CERT_OBJ_X509_RETIRED4, 1, 0, 0, "X.509 Certificate for Retired Key 4", 0, 0, get_coa, 7},
|
||||||
|
{PIV_CERT_OBJ_X509_RETIRED5, 1, 0, 0, "X.509 Certificate for Retired Key 5", 0, 0, get_coa, 8},
|
||||||
|
{PIV_CERT_OBJ_X509_RETIRED6, 1, 0, 0, "X.509 Certificate for Retired Key 6", 0, 0, get_coa, 9},
|
||||||
|
{PIV_CERT_OBJ_X509_RETIRED7, 1, 0, 0, "X.509 Certificate for Retired Key 7", 0, 0, get_coa, 10},
|
||||||
|
{PIV_CERT_OBJ_X509_RETIRED8, 1, 0, 0, "X.509 Certificate for Retired Key 8", 0, 0, get_coa, 11},
|
||||||
|
{PIV_CERT_OBJ_X509_RETIRED9, 1, 0, 0, "X.509 Certificate for Retired Key 9", 0, 0, get_coa, 12},
|
||||||
|
{PIV_CERT_OBJ_X509_RETIRED10, 1, 0, 0, "X.509 Certificate for Retired Key 10", 0, 0, get_coa, 13},
|
||||||
|
{PIV_CERT_OBJ_X509_RETIRED11, 1, 0, 0, "X.509 Certificate for Retired Key 11", 0, 0, get_coa, 14},
|
||||||
|
{PIV_CERT_OBJ_X509_RETIRED12, 1, 0, 0, "X.509 Certificate for Retired Key 12", 0, 0, get_coa, 15},
|
||||||
|
{PIV_CERT_OBJ_X509_RETIRED13, 1, 0, 0, "X.509 Certificate for Retired Key 13", 0, 0, get_coa, 16},
|
||||||
|
{PIV_CERT_OBJ_X509_RETIRED14, 1, 0, 0, "X.509 Certificate for Retired Key 14", 0, 0, get_coa, 17},
|
||||||
|
{PIV_CERT_OBJ_X509_RETIRED15, 1, 0, 0, "X.509 Certificate for Retired Key 15", 0, 0, get_coa, 18},
|
||||||
|
{PIV_CERT_OBJ_X509_RETIRED16, 1, 0, 0, "X.509 Certificate for Retired Key 16", 0, 0, get_coa, 19},
|
||||||
|
{PIV_CERT_OBJ_X509_RETIRED17, 1, 0, 0, "X.509 Certificate for Retired Key 17", 0, 0, get_coa, 20},
|
||||||
|
{PIV_CERT_OBJ_X509_RETIRED18, 1, 0, 0, "X.509 Certificate for Retired Key 18", 0, 0, get_coa, 21},
|
||||||
|
{PIV_CERT_OBJ_X509_RETIRED19, 1, 0, 0, "X.509 Certificate for Retired Key 19", 0, 0, get_coa, 22},
|
||||||
|
{PIV_CERT_OBJ_X509_RETIRED20, 1, 0, 0, "X.509 Certificate for Retired Key 20", 0, 0, get_coa, 23},
|
||||||
|
{PIV_CERT_OBJ_LAST, 1, 0, 0, "", 0, 0, NULL, 24},
|
||||||
|
|
||||||
{PIV_PVTK_OBJ_PIV_AUTH, 1, 1, 0, "Private key for PIV Authentication", 0, 0, get_proa, 0}, // 9a
|
{PIV_PVTK_OBJ_PIV_AUTH, 1, 1, 0, "Private key for PIV Authentication", 0, 0, get_proa, 0}, // 9a
|
||||||
{PIV_PVTK_OBJ_CARD_AUTH, 1, 0, 0, "Private key for Card Authentication", 0, 0, get_proa, 1}, // 9e
|
{PIV_PVTK_OBJ_CARD_AUTH, 1, 0, 0, "Private key for Card Authentication", 0, 0, get_proa, 1}, // 9e
|
||||||
{PIV_PVTK_OBJ_DS, 1, 1, 0, "Private key for Digital Signature", 0, 0, get_proa, 2}, // 9c
|
{PIV_PVTK_OBJ_DS, 1, 1, 0, "Private key for Digital Signature", 0, 0, get_proa, 2}, // 9c
|
||||||
{PIV_PVTK_OBJ_KM, 1, 1, 0, "Private key for Key Management", 0, 0, get_proa, 3}, // 9d
|
{PIV_PVTK_OBJ_KM, 1, 1, 0, "Private key for Key Management", 0, 0, get_proa, 3}, // 9d
|
||||||
{PIV_PVTK_OBJ_LAST, 1, 0, 0, "", 0, 0, NULL, 4},
|
{PIV_PVTK_OBJ_RETIRED1, 1, 1, 0, "Private key for Retired Key 1", 0, 0, get_proa, 4},
|
||||||
|
{PIV_PVTK_OBJ_RETIRED2, 1, 1, 0, "Private key for Retired Key 2", 0, 0, get_proa, 5},
|
||||||
|
{PIV_PVTK_OBJ_RETIRED3, 1, 1, 0, "Private key for Retired Key 3", 0, 0, get_proa, 6},
|
||||||
|
{PIV_PVTK_OBJ_RETIRED4, 1, 1, 0, "Private key for Retired Key 4", 0, 0, get_proa, 7},
|
||||||
|
{PIV_PVTK_OBJ_RETIRED5, 1, 1, 0, "Private key for Retired Key 5", 0, 0, get_proa, 8},
|
||||||
|
{PIV_PVTK_OBJ_RETIRED6, 1, 1, 0, "Private key for Retired Key 6", 0, 0, get_proa, 9},
|
||||||
|
{PIV_PVTK_OBJ_RETIRED7, 1, 1, 0, "Private key for Retired Key 7", 0, 0, get_proa, 10},
|
||||||
|
{PIV_PVTK_OBJ_RETIRED8, 1, 1, 0, "Private key for Retired Key 8", 0, 0, get_proa, 11},
|
||||||
|
{PIV_PVTK_OBJ_RETIRED9, 1, 1, 0, "Private key for Retired Key 9", 0, 0, get_proa, 12},
|
||||||
|
{PIV_PVTK_OBJ_RETIRED10, 1, 1, 0, "Private key forRretired Key 10", 0, 0, get_proa, 13},
|
||||||
|
{PIV_PVTK_OBJ_RETIRED11, 1, 1, 0, "Private key forRretired Key 11", 0, 0, get_proa, 14},
|
||||||
|
{PIV_PVTK_OBJ_RETIRED12, 1, 1, 0, "Private key forRretired Key 12", 0, 0, get_proa, 15},
|
||||||
|
{PIV_PVTK_OBJ_RETIRED13, 1, 1, 0, "Private key forRretired Key 13", 0, 0, get_proa, 16},
|
||||||
|
{PIV_PVTK_OBJ_RETIRED14, 1, 1, 0, "Private key forRretired Key 14", 0, 0, get_proa, 17},
|
||||||
|
{PIV_PVTK_OBJ_RETIRED15, 1, 1, 0, "Private key forRretired Key 15", 0, 0, get_proa, 18},
|
||||||
|
{PIV_PVTK_OBJ_RETIRED16, 1, 1, 0, "Private key forRretired Key 16", 0, 0, get_proa, 19},
|
||||||
|
{PIV_PVTK_OBJ_RETIRED17, 1, 1, 0, "Private key forRretired Key 17", 0, 0, get_proa, 20},
|
||||||
|
{PIV_PVTK_OBJ_RETIRED18, 1, 1, 0, "Private key forRretired Key 18", 0, 0, get_proa, 21},
|
||||||
|
{PIV_PVTK_OBJ_RETIRED19, 1, 1, 0, "Private key forRretired Key 19", 0, 0, get_proa, 22},
|
||||||
|
{PIV_PVTK_OBJ_RETIRED20, 1, 1, 0, "Private key forRretired Key 20", 0, 0, get_proa, 23},
|
||||||
|
{PIV_PVTK_OBJ_LAST, 1, 0, 0, "", 0, 0, NULL, 24},
|
||||||
|
|
||||||
{PIV_PUBK_OBJ_PIV_AUTH, 1, 0, 0, "Public key for PIV Authentication", 0, 0, get_puoa, 0},
|
{PIV_PUBK_OBJ_PIV_AUTH, 1, 0, 0, "Public key for PIV Authentication", 0, 0, get_puoa, 0},
|
||||||
{PIV_PUBK_OBJ_CARD_AUTH, 1, 0, 0, "Public key for Card Authentication", 0, 0, get_puoa, 1},
|
{PIV_PUBK_OBJ_CARD_AUTH, 1, 0, 0, "Public key for Card Authentication", 0, 0, get_puoa, 1},
|
||||||
{PIV_PUBK_OBJ_DS, 1, 0, 0, "Public key for Digital Signature", 0, 0, get_puoa, 2},
|
{PIV_PUBK_OBJ_DS, 1, 0, 0, "Public key for Digital Signature", 0, 0, get_puoa, 2},
|
||||||
{PIV_PUBK_OBJ_KM, 1, 0, 0, "Public key for Key Management", 0, 0, get_puoa, 3},
|
{PIV_PUBK_OBJ_KM, 1, 0, 0, "Public key for Key Management", 0, 0, get_puoa, 3},
|
||||||
{PIV_PUBK_OBJ_LAST, 1, 0, 0, "", 0, 0, NULL, 4}
|
{PIV_PUBK_OBJ_RETIRED1, 1, 0, 0, "Public key for Retired Key 1", 0, 0, get_puoa, 4},
|
||||||
|
{PIV_PUBK_OBJ_RETIRED2, 1, 0, 0, "Public key for Retired Key 2", 0, 0, get_puoa, 5},
|
||||||
|
{PIV_PUBK_OBJ_RETIRED3, 1, 0, 0, "Public key for Retired Key 3", 0, 0, get_puoa, 6},
|
||||||
|
{PIV_PUBK_OBJ_RETIRED4, 1, 0, 0, "Public key for Retired Key 4", 0, 0, get_puoa, 7},
|
||||||
|
{PIV_PUBK_OBJ_RETIRED5, 1, 0, 0, "Public key for Retired Key 5", 0, 0, get_puoa, 8},
|
||||||
|
{PIV_PUBK_OBJ_RETIRED6, 1, 0, 0, "Public key for Retired Key 6", 0, 0, get_puoa, 9},
|
||||||
|
{PIV_PUBK_OBJ_RETIRED7, 1, 0, 0, "Public key for Retired Key 7", 0, 0, get_puoa, 10},
|
||||||
|
{PIV_PUBK_OBJ_RETIRED8, 1, 0, 0, "Public key for Retired Key 8", 0, 0, get_puoa, 11},
|
||||||
|
{PIV_PUBK_OBJ_RETIRED9, 1, 0, 0, "Public key for Retired Key 9", 0, 0, get_puoa, 12},
|
||||||
|
{PIV_PUBK_OBJ_RETIRED10, 1, 0, 0, "Public key for Retired Key 10", 0, 0, get_puoa, 13},
|
||||||
|
{PIV_PUBK_OBJ_RETIRED11, 1, 0, 0, "Public key for Retired Key 11", 0, 0, get_puoa, 14},
|
||||||
|
{PIV_PUBK_OBJ_RETIRED12, 1, 0, 0, "Public key for Retired Key 12", 0, 0, get_puoa, 15},
|
||||||
|
{PIV_PUBK_OBJ_RETIRED13, 1, 0, 0, "Public key for Retired Key 13", 0, 0, get_puoa, 16},
|
||||||
|
{PIV_PUBK_OBJ_RETIRED14, 1, 0, 0, "Public key for Retired Key 14", 0, 0, get_puoa, 17},
|
||||||
|
{PIV_PUBK_OBJ_RETIRED15, 1, 0, 0, "Public key for Retired Key 15", 0, 0, get_puoa, 18},
|
||||||
|
{PIV_PUBK_OBJ_RETIRED16, 1, 0, 0, "Public key for Retired Key 16", 0, 0, get_puoa, 19},
|
||||||
|
{PIV_PUBK_OBJ_RETIRED17, 1, 0, 0, "Public key for Retired Key 17", 0, 0, get_puoa, 20},
|
||||||
|
{PIV_PUBK_OBJ_RETIRED18, 1, 0, 0, "Public key for Retired Key 18", 0, 0, get_puoa, 21},
|
||||||
|
{PIV_PUBK_OBJ_RETIRED19, 1, 0, 0, "Public key for Retired Key 19", 0, 0, get_puoa, 22},
|
||||||
|
{PIV_PUBK_OBJ_RETIRED20, 1, 0, 0, "Public key for Retired Key 20", 0, 0, get_puoa, 23},
|
||||||
|
{PIV_PUBK_OBJ_LAST, 1, 0, 0, "", 0, 0, NULL, 24}
|
||||||
};
|
};
|
||||||
|
|
||||||
static piv_data_obj_t data_objects[] = {
|
static piv_data_obj_t data_objects[] = {
|
||||||
{"2.16.840.1.101.3.7.2.1.1", 3, "\x5F\xC1\x05", "\x01\x01"},
|
{"2.16.840.1.101.3.7.2.1.1", 3, "\x5F\xC1\x05", "\x01\x01"}, // PIV Authentication
|
||||||
{"2.16.840.1.101.3.7.2.5.0", 3, "\x5F\xC1\x01", "\x05\x00"},
|
{"2.16.840.1.101.3.7.2.5.0", 3, "\x5F\xC1\x01", "\x05\x00"}, // Card Authentication
|
||||||
{"2.16.840.1.101.3.7.2.1.0", 3, "\x5F\xC1\x0A", "\x01\x00"},
|
{"2.16.840.1.101.3.7.2.1.0", 3, "\x5F\xC1\x0A", "\x01\x00"}, // Digital Signature
|
||||||
{"2.16.840.1.101.3.7.2.1.2", 3, "\x5F\xC1\x0B", "\x01\x02"},
|
{"2.16.840.1.101.3.7.2.1.2", 3, "\x5F\xC1\x0B", "\x01\x02"}, // Key Management
|
||||||
{"2.16.840.1.101.3.7.1.219.0", 3, "\x5F\xC1\x07", "\xDB\x00"},
|
{"2.16.840.1.101.3.7.2.16.1", 3, "\x5F\xC1\x0D", "\x10\x01"}, // Retired Key 1
|
||||||
{"2.16.840.1.101.3.7.2.48.0", 3, "\x5F\xC1\x02", "\x30\x00"},
|
{"2.16.840.1.101.3.7.2.16.2", 3, "\x5F\xC1\x0E", "\x10\x02"}, // Retired Key 2
|
||||||
{"2.16.840.1.101.3.7.2.96.16", 3, "\x5F\xC1\x03", "\x60\x10"},
|
{"2.16.840.1.101.3.7.2.16.3", 3, "\x5F\xC1\x0F", "\x10\x03"}, // Retired Key 3
|
||||||
{"2.16.840.1.101.3.7.2.144.0", 3, "\x5F\xC1\x06", "\x90\x00"},
|
{"2.16.840.1.101.3.7.2.16.4", 3, "\x5F\xC1\x10", "\x10\x04"}, // Retired Key 4
|
||||||
{"2.16.840.1.101.3.7.2.96.48", 3, "\x5F\xC1\x08", "\x60\x30"},
|
{"2.16.840.1.101.3.7.2.16.5", 3, "\x5F\xC1\x11", "\x10\x05"}, // Retired Key 5
|
||||||
{"2.16.840.1.101.3.7.2.48.1", 3, "\x5F\xC1\x09", "\x30\x01"},
|
{"2.16.840.1.101.3.7.2.16.6", 3, "\x5F\xC1\x12", "\x10\x06"}, // Retired Key 6
|
||||||
{"2.16.840.1.101.3.7.2.96.80", 1, "\x7E", "\x60\x50"},
|
{"2.16.840.1.101.3.7.2.16.7", 3, "\x5F\xC1\x13", "\x10\x07"}, // Retired Key 7
|
||||||
{"2.16.840.1.101.3.7.2.96.96", 3, "\x5F\xC1\x0C", "\x60\x60"},
|
{"2.16.840.1.101.3.7.2.16.8", 3, "\x5F\xC1\x14", "\x10\x08"}, // Retired Key 8
|
||||||
|
{"2.16.840.1.101.3.7.2.16.9", 3, "\x5F\xC1\x15", "\x10\x09"}, // Retired Key 9
|
||||||
/* 800-73-3, 21 new objects, 20 history certificates */
|
{"2.16.840.1.101.3.7.2.16.10", 3, "\x5F\xC1\x16", "\x10\x0A"}, // Retired Key 10
|
||||||
{"2.16.840.1.101.3.7.2.16.1", 3, "\x5F\xC1\x0D", "\x10\x01"},
|
{"2.16.840.1.101.3.7.2.16.11", 3, "\x5F\xC1\x17", "\x10\x0B"}, // Retired Key 11
|
||||||
{"2.16.840.1.101.3.7.2.16.2", 3, "\x5F\xC1\x0E", "\x10\x02"},
|
{"2.16.840.1.101.3.7.2.16.12", 3, "\x5F\xC1\x18", "\x10\x0C"}, // Retired Key 12
|
||||||
{"2.16.840.1.101.3.7.2.16.3", 3, "\x5F\xC1\x0F", "\x10\x03"},
|
{"2.16.840.1.101.3.7.2.16.13", 3, "\x5F\xC1\x19", "\x10\x0D"}, // Retired Key 13
|
||||||
{"2.16.840.1.101.3.7.2.16.4", 3, "\x5F\xC1\x10", "\x10\x04"},
|
{"2.16.840.1.101.3.7.2.16.14", 3, "\x5F\xC1\x1A", "\x10\x0E"}, // Retired Key 14
|
||||||
{"2.16.840.1.101.3.7.2.16.5", 3, "\x5F\xC1\x11", "\x10\x05"},
|
{"2.16.840.1.101.3.7.2.16.15", 3, "\x5F\xC1\x1B", "\x10\x0F"}, // Retired Key 15
|
||||||
{"2.16.840.1.101.3.7.2.16.7", 3, "\x5F\xC1\x13", "\x10\x07"},
|
{"2.16.840.1.101.3.7.2.16.16", 3, "\x5F\xC1\x1C", "\x10\x10"}, // Retired Key 16
|
||||||
{"2.16.840.1.101.3.7.2.16.8", 3, "\x5F\xC1\x14", "\x10\x08"},
|
{"2.16.840.1.101.3.7.2.16.17", 3, "\x5F\xC1\x1D", "\x10\x11"}, // Retired Key 17
|
||||||
{"2.16.840.1.101.3.7.2.16.9", 3, "\x5F\xC1\x15", "\x10\x09"},
|
{"2.16.840.1.101.3.7.2.16.18", 3, "\x5F\xC1\x1E", "\x10\x12"}, // Retired Key 18
|
||||||
{"2.16.840.1.101.3.7.2.16.10", 3, "\x5F\xC1\x16", "\x10\x0A"},
|
{"2.16.840.1.101.3.7.2.16.19", 3, "\x5F\xC1\x1F", "\x10\x13"}, // Retired Key 19
|
||||||
{"2.16.840.1.101.3.7.2.16.11", 3, "\x5F\xC1\x17", "\x10\x0B"},
|
{"2.16.840.1.101.3.7.2.16.20", 3, "\x5F\xC1\x20", "\x10\x14"}, // Retired Key 20
|
||||||
{"2.16.840.1.101.3.7.2.16.12", 3, "\x5F\xC1\x18", "\x10\x0C"},
|
{"2.16.840.1.101.3.7.1.219.0", 3, "\x5F\xC1\x07", "\xDB\x00"}, // CCC
|
||||||
{"2.16.840.1.101.3.7.2.16.13", 3, "\x5F\xC1\x19", "\x10\x0D"},
|
{"2.16.840.1.101.3.7.2.48.0", 3, "\x5F\xC1\x02", "\x30\x00"}, // CHUID
|
||||||
{"2.16.840.1.101.3.7.2.16.14", 3, "\x5F\xC1\x1A", "\x10\x0E"},
|
{"2.16.840.1.101.3.7.2.96.16", 3, "\x5F\xC1\x03", "\x60\x10"}, // CHFP
|
||||||
{"2.16.840.1.101.3.7.2.16.15", 3, "\x5F\xC1\x1B", "\x10\x0F"},
|
{"2.16.840.1.101.3.7.2.144.0", 3, "\x5F\xC1\x06", "\x90\x00"}, // Security Object
|
||||||
{"2.16.840.1.101.3.7.2.16.16", 3, "\x5F\xC1\x1C", "\x10\x10"},
|
{"2.16.840.1.101.3.7.2.96.48", 3, "\x5F\xC1\x08", "\x60\x30"}, // CHFI
|
||||||
{"2.16.840.1.101.3.7.2.16.17", 3, "\x5F\xC1\x1D", "\x10\x11"},
|
{"2.16.840.1.101.3.7.2.48.1", 3, "\x5F\xC1\x09", "\x30\x01"}, // Printed Information
|
||||||
{"2.16.840.1.101.3.7.2.16.18", 3, "\x5F\xC1\x1E", "\x10\x12"},
|
{"2.16.840.1.101.3.7.2.96.80", 1, "\x7E", "\x60\x50"}, // Discovery Object
|
||||||
{"2.16.840.1.101.3.7.2.16.19", 3, "\x5F\xC1\x1F", "\x10\x13"},
|
{"2.16.840.1.101.3.7.2.96.96", 3, "\x5F\xC1\x0C", "\x60\x60"}, // Key History Object
|
||||||
{"2.16.840.1.101.3.7.2.16.20", 3, "\x5F\xC1\x20", "\x10\x14"},
|
{"2.16.840.1.101.3.7.2.16.21", 3, "\x5F\xC1\x21", "\x10\x15"}, // CHII
|
||||||
{"2.16.840.1.101.3.7.2.16.21", 3, "\x5F\xC1\x21", "\x10\x15"},
|
{"2.16.840.1.101.3.7.2.16.22", 2, "\x7F\x61", "\x10\x16"}, // Biometric Information
|
||||||
{"2.16.840.1.101.3.7.2.16.22", 2, "\x7F\x61", "\x10\x16"},
|
{"2.16.840.1.101.3.7.2.16.23", 3, "\x5F\xC1\x22", "\x10\x17"}, // Secure Messaging Certificate Signer
|
||||||
{"2.16.840.1.101.3.7.2.16.23", 3, "\x5F\xC1\x22", "\x10\x17"},
|
{"2.16.840.1.101.3.7.2.16.24", 3, "\x5F\xC1\x23", "\x10\x18"}, // Pairing Code Reference Data Container
|
||||||
{"2.16.840.1.101.3.7.2.16.24", 3, "\x5F\xC1\x23", "\x10\x18"},
|
|
||||||
{"", 0, "", ""}
|
{"", 0, "", ""}
|
||||||
};
|
};
|
||||||
|
|
||||||
static piv_cert_obj_t cert_objects[] = {
|
static piv_cert_obj_t cert_objects[] = {
|
||||||
|
{NULL},
|
||||||
|
{NULL},
|
||||||
|
{NULL},
|
||||||
|
{NULL},
|
||||||
|
{NULL},
|
||||||
|
{NULL},
|
||||||
|
{NULL},
|
||||||
|
{NULL},
|
||||||
|
{NULL},
|
||||||
|
{NULL},
|
||||||
|
{NULL},
|
||||||
|
{NULL},
|
||||||
|
{NULL},
|
||||||
|
{NULL},
|
||||||
|
{NULL},
|
||||||
|
{NULL},
|
||||||
|
{NULL},
|
||||||
|
{NULL},
|
||||||
|
{NULL},
|
||||||
|
{NULL},
|
||||||
{NULL},
|
{NULL},
|
||||||
{NULL},
|
{NULL},
|
||||||
{NULL},
|
{NULL},
|
||||||
@@ -131,10 +210,50 @@ static piv_pvtk_obj_t pvtkey_objects[] = {
|
|||||||
{1, 1, 0, 0, 0},
|
{1, 1, 0, 0, 0},
|
||||||
{1, 1, 0, 0, 0},
|
{1, 1, 0, 0, 0},
|
||||||
{1, 1, 0, 0, 1},
|
{1, 1, 0, 0, 1},
|
||||||
|
{1, 1, 0, 0, 0},
|
||||||
|
{1, 1, 0, 0, 0},
|
||||||
|
{1, 1, 0, 0, 0},
|
||||||
|
{1, 1, 0, 0, 0},
|
||||||
|
{1, 1, 0, 0, 0},
|
||||||
|
{1, 1, 0, 0, 0},
|
||||||
|
{1, 1, 0, 0, 0},
|
||||||
|
{1, 1, 0, 0, 0},
|
||||||
|
{1, 1, 0, 0, 0},
|
||||||
|
{1, 1, 0, 0, 0},
|
||||||
|
{1, 1, 0, 0, 0},
|
||||||
|
{1, 1, 0, 0, 0},
|
||||||
|
{1, 1, 0, 0, 0},
|
||||||
|
{1, 1, 0, 0, 0},
|
||||||
|
{1, 1, 0, 0, 0},
|
||||||
|
{1, 1, 0, 0, 0},
|
||||||
|
{1, 1, 0, 0, 0},
|
||||||
|
{1, 1, 0, 0, 0},
|
||||||
|
{1, 1, 0, 0, 0},
|
||||||
|
{1, 1, 0, 0, 0},
|
||||||
{1, 1, 0, 0, 0}
|
{1, 1, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
static piv_pubk_obj_t pubkey_objects[] = {
|
static piv_pubk_obj_t pubkey_objects[] = {
|
||||||
|
{NULL, 1, 1, 0, 0},
|
||||||
|
{NULL, 1, 1, 0, 0},
|
||||||
|
{NULL, 1, 1, 0, 0},
|
||||||
|
{NULL, 1, 1, 0, 0},
|
||||||
|
{NULL, 1, 1, 0, 0},
|
||||||
|
{NULL, 1, 1, 0, 0},
|
||||||
|
{NULL, 1, 1, 0, 0},
|
||||||
|
{NULL, 1, 1, 0, 0},
|
||||||
|
{NULL, 1, 1, 0, 0},
|
||||||
|
{NULL, 1, 1, 0, 0},
|
||||||
|
{NULL, 1, 1, 0, 0},
|
||||||
|
{NULL, 1, 1, 0, 0},
|
||||||
|
{NULL, 1, 1, 0, 0},
|
||||||
|
{NULL, 1, 1, 0, 0},
|
||||||
|
{NULL, 1, 1, 0, 0},
|
||||||
|
{NULL, 1, 1, 0, 0},
|
||||||
|
{NULL, 1, 1, 0, 0},
|
||||||
|
{NULL, 1, 1, 0, 0},
|
||||||
|
{NULL, 1, 1, 0, 0},
|
||||||
|
{NULL, 1, 1, 0, 0},
|
||||||
{NULL, 1, 1, 0, 0},
|
{NULL, 1, 1, 0, 0},
|
||||||
{NULL, 1, 1, 0, 0},
|
{NULL, 1, 1, 0, 0},
|
||||||
{NULL, 1, 1, 0, 0},
|
{NULL, 1, 1, 0, 0},
|
||||||
@@ -221,8 +340,12 @@ static CK_ULONG get_modulus_bits(EVP_PKEY *key) {
|
|||||||
return do_get_rsa_modulus_length(key);
|
return do_get_rsa_modulus_length(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
static CK_ULONG get_public_exponent(EVP_PKEY *key) {
|
static CK_RV get_public_exponent(EVP_PKEY *key, CK_BYTE_PTR data, CK_ULONG_PTR len) {
|
||||||
return do_get_public_exponent(key);
|
return do_get_public_exponent(key, data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static CK_RV get_modulus(EVP_PKEY *key, CK_BYTE_PTR data, CK_ULONG_PTR len) {
|
||||||
|
return do_get_modulus(key, data, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static CK_RV get_public_key(EVP_PKEY *key, CK_BYTE_PTR data, CK_ULONG_PTR len) {
|
static CK_RV get_public_key(EVP_PKEY *key, CK_BYTE_PTR data, CK_ULONG_PTR len) {
|
||||||
@@ -285,7 +408,7 @@ CK_RV get_doa(CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_PTR template) {
|
|||||||
|
|
||||||
case CKA_OBJECT_ID: // TODO: how about just storing the OID in DER ?
|
case CKA_OBJECT_ID: // TODO: how about just storing the OID in DER ?
|
||||||
DBG("OID");
|
DBG("OID");
|
||||||
strcpy((char *)tmp, data_objects[piv_objects[obj].sub_id].oid);
|
memcpy((char *)tmp, data_objects[piv_objects[obj].sub_id].oid, sizeof(tmp));
|
||||||
asn1_encode_oid(tmp, tmp, &len);
|
asn1_encode_oid(tmp, tmp, &len);
|
||||||
data = tmp;
|
data = tmp;
|
||||||
break;
|
break;
|
||||||
@@ -374,15 +497,15 @@ CK_RV get_coa(CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_PTR template) {
|
|||||||
|
|
||||||
case CKA_ISSUER:
|
case CKA_ISSUER:
|
||||||
DBG("ISSUER TODO"); // Default empty
|
DBG("ISSUER TODO"); // Default empty
|
||||||
return CKR_FUNCTION_FAILED;
|
return CKR_ATTRIBUTE_TYPE_INVALID;
|
||||||
|
|
||||||
case CKA_SERIAL_NUMBER:
|
case CKA_SERIAL_NUMBER:
|
||||||
DBG("SERIAL NUMBER TODO"); // Default empty
|
DBG("SERIAL NUMBER TODO"); // Default empty
|
||||||
return CKR_FUNCTION_FAILED;
|
return CKR_ATTRIBUTE_TYPE_INVALID;
|
||||||
|
|
||||||
case CKA_SUBJECT:
|
case CKA_SUBJECT:
|
||||||
DBG("SUBJECT TODO"); // Required
|
DBG("SUBJECT TODO"); // Required
|
||||||
return CKR_FUNCTION_FAILED;
|
return CKR_ATTRIBUTE_TYPE_INVALID;
|
||||||
|
|
||||||
case CKA_ID:
|
case CKA_ID:
|
||||||
DBG("ID");
|
DBG("ID");
|
||||||
@@ -393,11 +516,11 @@ CK_RV get_coa(CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_PTR template) {
|
|||||||
|
|
||||||
case CKA_START_DATE:
|
case CKA_START_DATE:
|
||||||
DBG("START DATE TODO"); // Default empty
|
DBG("START DATE TODO"); // Default empty
|
||||||
return CKR_FUNCTION_FAILED;
|
return CKR_ATTRIBUTE_TYPE_INVALID;
|
||||||
|
|
||||||
case CKA_END_DATE:
|
case CKA_END_DATE:
|
||||||
DBG("END DATE TODO"); // Default empty
|
DBG("END DATE TODO"); // Default empty
|
||||||
return CKR_FUNCTION_FAILED;
|
return CKR_ATTRIBUTE_TYPE_INVALID;
|
||||||
|
|
||||||
case CKA_MODIFIABLE:
|
case CKA_MODIFIABLE:
|
||||||
DBG("MODIFIABLE");
|
DBG("MODIFIABLE");
|
||||||
@@ -477,7 +600,7 @@ CK_RV get_proa(CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_PTR template) {
|
|||||||
|
|
||||||
case CKA_SUBJECT:
|
case CKA_SUBJECT:
|
||||||
DBG("SUBJECT TODO"); // Default empty
|
DBG("SUBJECT TODO"); // Default empty
|
||||||
return CKR_FUNCTION_FAILED;
|
return CKR_ATTRIBUTE_TYPE_INVALID;
|
||||||
|
|
||||||
case CKA_ID:
|
case CKA_ID:
|
||||||
DBG("ID");
|
DBG("ID");
|
||||||
@@ -488,7 +611,7 @@ CK_RV get_proa(CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_PTR template) {
|
|||||||
|
|
||||||
case CKA_SENSITIVE:
|
case CKA_SENSITIVE:
|
||||||
DBG("SENSITIVE TODO"); // Default empty
|
DBG("SENSITIVE TODO"); // Default empty
|
||||||
return CKR_FUNCTION_FAILED;
|
return CKR_ATTRIBUTE_TYPE_INVALID;
|
||||||
|
|
||||||
case CKA_DECRYPT:
|
case CKA_DECRYPT:
|
||||||
DBG("DECRYPT"); // Default empy
|
DBG("DECRYPT"); // Default empy
|
||||||
@@ -513,7 +636,7 @@ CK_RV get_proa(CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_PTR template) {
|
|||||||
|
|
||||||
case CKA_SIGN_RECOVER:
|
case CKA_SIGN_RECOVER:
|
||||||
DBG("SIGN RECOVER TODO"); // Default empty
|
DBG("SIGN RECOVER TODO"); // Default empty
|
||||||
return CKR_FUNCTION_FAILED;
|
return CKR_ATTRIBUTE_TYPE_INVALID;
|
||||||
|
|
||||||
case CKA_DERIVE:
|
case CKA_DERIVE:
|
||||||
DBG("DERIVE"); // Default false
|
DBG("DERIVE"); // Default false
|
||||||
@@ -524,11 +647,11 @@ CK_RV get_proa(CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_PTR template) {
|
|||||||
|
|
||||||
case CKA_START_DATE:
|
case CKA_START_DATE:
|
||||||
DBG("START DATE TODO"); // Default empty
|
DBG("START DATE TODO"); // Default empty
|
||||||
return CKR_FUNCTION_FAILED;
|
return CKR_ATTRIBUTE_TYPE_INVALID;
|
||||||
|
|
||||||
case CKA_END_DATE:
|
case CKA_END_DATE:
|
||||||
DBG("END DATE TODO"); // Default empty
|
DBG("END DATE TODO"); // Default empty
|
||||||
return CKR_FUNCTION_FAILED;
|
return CKR_ATTRIBUTE_TYPE_INVALID;
|
||||||
|
|
||||||
case CKA_MODULUS:
|
case CKA_MODULUS:
|
||||||
DBG("MODULUS");
|
DBG("MODULUS");
|
||||||
@@ -608,10 +731,9 @@ CK_RV get_proa(CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_PTR template) {
|
|||||||
if (ul_tmp != CKK_RSA)
|
if (ul_tmp != CKK_RSA)
|
||||||
return CKR_ATTRIBUTE_VALUE_INVALID;
|
return CKR_ATTRIBUTE_VALUE_INVALID;
|
||||||
|
|
||||||
ul_tmp = get_public_exponent(pubkey_objects[piv_objects[obj].sub_id].data); // Getting the info from the pubk
|
if (get_public_exponent(pubkey_objects[piv_objects[obj].sub_id].data, b_tmp, &len) != CKR_OK)
|
||||||
if (ul_tmp == 0)
|
|
||||||
return CKR_FUNCTION_FAILED;
|
return CKR_FUNCTION_FAILED;
|
||||||
data = (CK_BYTE_PTR) &ul_tmp;
|
data = b_tmp;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* case CKA_PRIVATE_EXPONENT: */
|
/* case CKA_PRIVATE_EXPONENT: */
|
||||||
@@ -628,7 +750,7 @@ CK_RV get_proa(CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_PTR template) {
|
|||||||
/* case CKA_EXTRACTABLE: */
|
/* case CKA_EXTRACTABLE: */
|
||||||
case CKA_LOCAL:
|
case CKA_LOCAL:
|
||||||
DBG("LOCAL TODO"); // Required
|
DBG("LOCAL TODO"); // Required
|
||||||
return CKR_FUNCTION_FAILED;
|
return CKR_ATTRIBUTE_TYPE_INVALID;
|
||||||
|
|
||||||
/* case CKA_NEVER_EXTRACTABLE: */
|
/* case CKA_NEVER_EXTRACTABLE: */
|
||||||
/*case CKA_ALWAYS_SENSITIVE:*/
|
/*case CKA_ALWAYS_SENSITIVE:*/
|
||||||
@@ -719,7 +841,7 @@ CK_RV get_puoa(CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_PTR template) {
|
|||||||
|
|
||||||
case CKA_SUBJECT:
|
case CKA_SUBJECT:
|
||||||
DBG("SUBJECT TODO"); // Default empty
|
DBG("SUBJECT TODO"); // Default empty
|
||||||
return CKR_FUNCTION_FAILED;
|
return CKR_ATTRIBUTE_TYPE_INVALID;
|
||||||
|
|
||||||
case CKA_ID:
|
case CKA_ID:
|
||||||
DBG("ID");
|
DBG("ID");
|
||||||
@@ -758,11 +880,11 @@ CK_RV get_puoa(CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_PTR template) {
|
|||||||
|
|
||||||
case CKA_START_DATE:
|
case CKA_START_DATE:
|
||||||
DBG("START DATE TODO"); // Default empty
|
DBG("START DATE TODO"); // Default empty
|
||||||
return CKR_FUNCTION_FAILED;
|
return CKR_ATTRIBUTE_TYPE_INVALID;
|
||||||
|
|
||||||
case CKA_END_DATE:
|
case CKA_END_DATE:
|
||||||
DBG("END DATE TODO"); // Default empty
|
DBG("END DATE TODO"); // Default empty
|
||||||
return CKR_FUNCTION_FAILED;
|
return CKR_ATTRIBUTE_TYPE_INVALID;
|
||||||
|
|
||||||
case CKA_EC_POINT:
|
case CKA_EC_POINT:
|
||||||
DBG("EC_POINT");
|
DBG("EC_POINT");
|
||||||
@@ -809,7 +931,7 @@ CK_RV get_puoa(CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_PTR template) {
|
|||||||
if (ul_tmp != CKK_RSA)
|
if (ul_tmp != CKK_RSA)
|
||||||
return CKR_ATTRIBUTE_VALUE_INVALID;
|
return CKR_ATTRIBUTE_VALUE_INVALID;
|
||||||
|
|
||||||
if (get_public_key(pubkey_objects[piv_objects[obj].sub_id].data, b_tmp, &len) != CKR_OK)
|
if (get_modulus(pubkey_objects[piv_objects[obj].sub_id].data, b_tmp, &len) != CKR_OK)
|
||||||
return CKR_FUNCTION_FAILED;
|
return CKR_FUNCTION_FAILED;
|
||||||
data = b_tmp;
|
data = b_tmp;
|
||||||
break;
|
break;
|
||||||
@@ -842,15 +964,14 @@ CK_RV get_puoa(CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_PTR template) {
|
|||||||
if (ul_tmp != CKK_RSA)
|
if (ul_tmp != CKK_RSA)
|
||||||
return CKR_ATTRIBUTE_VALUE_INVALID;
|
return CKR_ATTRIBUTE_VALUE_INVALID;
|
||||||
|
|
||||||
ul_tmp = get_public_exponent(pubkey_objects[piv_objects[obj].sub_id].data); // Getting the info from the pubk
|
if (get_public_exponent(pubkey_objects[piv_objects[obj].sub_id].data, b_tmp, &len) != CKR_OK)
|
||||||
if (ul_tmp == 0)
|
|
||||||
return CKR_FUNCTION_FAILED;
|
return CKR_FUNCTION_FAILED;
|
||||||
data = (CK_BYTE_PTR) &ul_tmp;
|
data = b_tmp;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CKA_LOCAL:
|
case CKA_LOCAL:
|
||||||
DBG("LOCAL TODO"); // Required
|
DBG("LOCAL TODO"); // Required
|
||||||
return CKR_FUNCTION_FAILED;
|
return CKR_ATTRIBUTE_TYPE_INVALID;
|
||||||
|
|
||||||
case CKA_MODIFIABLE:
|
case CKA_MODIFIABLE:
|
||||||
DBG("MODIFIABLE");
|
DBG("MODIFIABLE");
|
||||||
@@ -883,7 +1004,6 @@ CK_RV get_puoa(CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_PTR template) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CK_ULONG piv_2_ykpiv(piv_obj_id_t id) {
|
CK_ULONG piv_2_ykpiv(piv_obj_id_t id) {
|
||||||
// TODO: add retired keys
|
|
||||||
switch(id) {
|
switch(id) {
|
||||||
case PIV_CERT_OBJ_X509_PIV_AUTH:
|
case PIV_CERT_OBJ_X509_PIV_AUTH:
|
||||||
return YKPIV_OBJ_AUTHENTICATION;
|
return YKPIV_OBJ_AUTHENTICATION;
|
||||||
@@ -897,6 +1017,66 @@ CK_ULONG piv_2_ykpiv(piv_obj_id_t id) {
|
|||||||
case PIV_CERT_OBJ_X509_KM:
|
case PIV_CERT_OBJ_X509_KM:
|
||||||
return YKPIV_OBJ_KEY_MANAGEMENT;
|
return YKPIV_OBJ_KEY_MANAGEMENT;
|
||||||
|
|
||||||
|
case PIV_CERT_OBJ_X509_RETIRED1:
|
||||||
|
return YKPIV_OBJ_RETIRED1;
|
||||||
|
|
||||||
|
case PIV_CERT_OBJ_X509_RETIRED2:
|
||||||
|
return YKPIV_OBJ_RETIRED2;
|
||||||
|
|
||||||
|
case PIV_CERT_OBJ_X509_RETIRED3:
|
||||||
|
return YKPIV_OBJ_RETIRED3;
|
||||||
|
|
||||||
|
case PIV_CERT_OBJ_X509_RETIRED4:
|
||||||
|
return YKPIV_OBJ_RETIRED4;
|
||||||
|
|
||||||
|
case PIV_CERT_OBJ_X509_RETIRED5:
|
||||||
|
return YKPIV_OBJ_RETIRED5;
|
||||||
|
|
||||||
|
case PIV_CERT_OBJ_X509_RETIRED6:
|
||||||
|
return YKPIV_OBJ_RETIRED6;
|
||||||
|
|
||||||
|
case PIV_CERT_OBJ_X509_RETIRED7:
|
||||||
|
return YKPIV_OBJ_RETIRED7;
|
||||||
|
|
||||||
|
case PIV_CERT_OBJ_X509_RETIRED8:
|
||||||
|
return YKPIV_OBJ_RETIRED8;
|
||||||
|
|
||||||
|
case PIV_CERT_OBJ_X509_RETIRED9:
|
||||||
|
return YKPIV_OBJ_RETIRED9;
|
||||||
|
|
||||||
|
case PIV_CERT_OBJ_X509_RETIRED10:
|
||||||
|
return YKPIV_OBJ_RETIRED10;
|
||||||
|
|
||||||
|
case PIV_CERT_OBJ_X509_RETIRED11:
|
||||||
|
return YKPIV_OBJ_RETIRED11;
|
||||||
|
|
||||||
|
case PIV_CERT_OBJ_X509_RETIRED12:
|
||||||
|
return YKPIV_OBJ_RETIRED12;
|
||||||
|
|
||||||
|
case PIV_CERT_OBJ_X509_RETIRED13:
|
||||||
|
return YKPIV_OBJ_RETIRED13;
|
||||||
|
|
||||||
|
case PIV_CERT_OBJ_X509_RETIRED14:
|
||||||
|
return YKPIV_OBJ_RETIRED14;
|
||||||
|
|
||||||
|
case PIV_CERT_OBJ_X509_RETIRED15:
|
||||||
|
return YKPIV_OBJ_RETIRED15;
|
||||||
|
|
||||||
|
case PIV_CERT_OBJ_X509_RETIRED16:
|
||||||
|
return YKPIV_OBJ_RETIRED16;
|
||||||
|
|
||||||
|
case PIV_CERT_OBJ_X509_RETIRED17:
|
||||||
|
return YKPIV_OBJ_RETIRED17;
|
||||||
|
|
||||||
|
case PIV_CERT_OBJ_X509_RETIRED18:
|
||||||
|
return YKPIV_OBJ_RETIRED18;
|
||||||
|
|
||||||
|
case PIV_CERT_OBJ_X509_RETIRED19:
|
||||||
|
return YKPIV_OBJ_RETIRED19;
|
||||||
|
|
||||||
|
case PIV_CERT_OBJ_X509_RETIRED20:
|
||||||
|
return YKPIV_OBJ_RETIRED20;
|
||||||
|
|
||||||
case PIV_PVTK_OBJ_PIV_AUTH:
|
case PIV_PVTK_OBJ_PIV_AUTH:
|
||||||
return YKPIV_KEY_AUTHENTICATION;
|
return YKPIV_KEY_AUTHENTICATION;
|
||||||
|
|
||||||
@@ -909,6 +1089,66 @@ CK_ULONG piv_2_ykpiv(piv_obj_id_t id) {
|
|||||||
case PIV_PVTK_OBJ_KM:
|
case PIV_PVTK_OBJ_KM:
|
||||||
return YKPIV_KEY_KEYMGM;
|
return YKPIV_KEY_KEYMGM;
|
||||||
|
|
||||||
|
case PIV_PVTK_OBJ_RETIRED1:
|
||||||
|
return YKPIV_KEY_RETIRED1;
|
||||||
|
|
||||||
|
case PIV_PVTK_OBJ_RETIRED2:
|
||||||
|
return YKPIV_KEY_RETIRED2;
|
||||||
|
|
||||||
|
case PIV_PVTK_OBJ_RETIRED3:
|
||||||
|
return YKPIV_KEY_RETIRED3;
|
||||||
|
|
||||||
|
case PIV_PVTK_OBJ_RETIRED4:
|
||||||
|
return YKPIV_KEY_RETIRED4;
|
||||||
|
|
||||||
|
case PIV_PVTK_OBJ_RETIRED5:
|
||||||
|
return YKPIV_KEY_RETIRED5;
|
||||||
|
|
||||||
|
case PIV_PVTK_OBJ_RETIRED6:
|
||||||
|
return YKPIV_KEY_RETIRED6;
|
||||||
|
|
||||||
|
case PIV_PVTK_OBJ_RETIRED7:
|
||||||
|
return YKPIV_KEY_RETIRED7;
|
||||||
|
|
||||||
|
case PIV_PVTK_OBJ_RETIRED8:
|
||||||
|
return YKPIV_KEY_RETIRED8;
|
||||||
|
|
||||||
|
case PIV_PVTK_OBJ_RETIRED9:
|
||||||
|
return YKPIV_KEY_RETIRED9;
|
||||||
|
|
||||||
|
case PIV_PVTK_OBJ_RETIRED10:
|
||||||
|
return YKPIV_KEY_RETIRED10;
|
||||||
|
|
||||||
|
case PIV_PVTK_OBJ_RETIRED11:
|
||||||
|
return YKPIV_KEY_RETIRED11;
|
||||||
|
|
||||||
|
case PIV_PVTK_OBJ_RETIRED12:
|
||||||
|
return YKPIV_KEY_RETIRED12;
|
||||||
|
|
||||||
|
case PIV_PVTK_OBJ_RETIRED13:
|
||||||
|
return YKPIV_KEY_RETIRED13;
|
||||||
|
|
||||||
|
case PIV_PVTK_OBJ_RETIRED14:
|
||||||
|
return YKPIV_KEY_RETIRED14;
|
||||||
|
|
||||||
|
case PIV_PVTK_OBJ_RETIRED15:
|
||||||
|
return YKPIV_KEY_RETIRED15;
|
||||||
|
|
||||||
|
case PIV_PVTK_OBJ_RETIRED16:
|
||||||
|
return YKPIV_KEY_RETIRED16;
|
||||||
|
|
||||||
|
case PIV_PVTK_OBJ_RETIRED17:
|
||||||
|
return YKPIV_KEY_RETIRED17;
|
||||||
|
|
||||||
|
case PIV_PVTK_OBJ_RETIRED18:
|
||||||
|
return YKPIV_KEY_RETIRED18;
|
||||||
|
|
||||||
|
case PIV_PVTK_OBJ_RETIRED19:
|
||||||
|
return YKPIV_KEY_RETIRED19;
|
||||||
|
|
||||||
|
case PIV_PVTK_OBJ_RETIRED20:
|
||||||
|
return YKPIV_KEY_RETIRED20;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return 0ul;
|
return 0ul;
|
||||||
}
|
}
|
||||||
@@ -1063,6 +1303,8 @@ CK_RV check_create_cert(CK_ATTRIBUTE_PTR templ, CK_ULONG n,
|
|||||||
case CKA_TOKEN:
|
case CKA_TOKEN:
|
||||||
case CKA_LABEL:
|
case CKA_LABEL:
|
||||||
case CKA_SUBJECT:
|
case CKA_SUBJECT:
|
||||||
|
case CKA_ISSUER:
|
||||||
|
case CKA_CERTIFICATE_TYPE:
|
||||||
// Ignore other attributes
|
// Ignore other attributes
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1150,18 +1392,23 @@ CK_RV check_create_ec_key(CK_ATTRIBUTE_PTR templ, CK_ULONG n, CK_BYTE_PTR id,
|
|||||||
has_params == CK_FALSE)
|
has_params == CK_FALSE)
|
||||||
return CKR_TEMPLATE_INCOMPLETE;
|
return CKR_TEMPLATE_INCOMPLETE;
|
||||||
|
|
||||||
if (*value_len != 32)
|
if (*value_len == 32 || *value_len == 31) {
|
||||||
|
if (ec_params_len != 10 || memcmp(ec_params, PRIME256V1, ec_params_len) != 0)
|
||||||
|
return CKR_ATTRIBUTE_VALUE_INVALID;
|
||||||
|
}
|
||||||
|
else /*if () TODO: P384*/
|
||||||
return CKR_ATTRIBUTE_VALUE_INVALID;
|
return CKR_ATTRIBUTE_VALUE_INVALID;
|
||||||
|
|
||||||
if (*value_len == 32 && (ec_params_len != 10 || memcmp(ec_params, PRIME256V1, ec_params_len)) != 0)
|
|
||||||
return CKR_TEMPLATE_INCONSISTENT;
|
|
||||||
|
|
||||||
return CKR_OK;
|
return CKR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
CK_RV check_create_rsa_key(CK_ATTRIBUTE_PTR templ, CK_ULONG n, CK_BYTE_PTR id,
|
CK_RV check_create_rsa_key(CK_ATTRIBUTE_PTR templ, CK_ULONG n, CK_BYTE_PTR id,
|
||||||
CK_BYTE_PTR *p, CK_BYTE_PTR *q, CK_BYTE_PTR *dp,
|
CK_BYTE_PTR *p, CK_ULONG_PTR p_len,
|
||||||
CK_BYTE_PTR *dq, CK_BYTE_PTR *qinv, CK_ULONG_PTR value_len, CK_ULONG_PTR vendor_defined) {
|
CK_BYTE_PTR *q, CK_ULONG_PTR q_len,
|
||||||
|
CK_BYTE_PTR *dp, CK_ULONG_PTR dp_len,
|
||||||
|
CK_BYTE_PTR *dq, CK_ULONG_PTR dq_len,
|
||||||
|
CK_BYTE_PTR *qinv, CK_ULONG_PTR qinv_len,
|
||||||
|
CK_ULONG_PTR vendor_defined) {
|
||||||
|
|
||||||
CK_ULONG i;
|
CK_ULONG i;
|
||||||
CK_BBOOL has_id = CK_FALSE;
|
CK_BBOOL has_id = CK_FALSE;
|
||||||
@@ -1171,11 +1418,6 @@ CK_RV check_create_rsa_key(CK_ATTRIBUTE_PTR templ, CK_ULONG n, CK_BYTE_PTR id,
|
|||||||
CK_BBOOL has_dp = CK_FALSE;
|
CK_BBOOL has_dp = CK_FALSE;
|
||||||
CK_BBOOL has_dq = CK_FALSE;
|
CK_BBOOL has_dq = CK_FALSE;
|
||||||
CK_BBOOL has_qinv = CK_FALSE;
|
CK_BBOOL has_qinv = CK_FALSE;
|
||||||
CK_ULONG p_len = 0;
|
|
||||||
CK_ULONG q_len = 0;
|
|
||||||
CK_ULONG dp_len = 0;
|
|
||||||
CK_ULONG dq_len = 0;
|
|
||||||
CK_ULONG qinv_len = 0;
|
|
||||||
|
|
||||||
*vendor_defined = 0;
|
*vendor_defined = 0;
|
||||||
|
|
||||||
@@ -1210,35 +1452,35 @@ CK_RV check_create_rsa_key(CK_ATTRIBUTE_PTR templ, CK_ULONG n, CK_BYTE_PTR id,
|
|||||||
case CKA_PRIME_1:
|
case CKA_PRIME_1:
|
||||||
has_p = CK_TRUE;
|
has_p = CK_TRUE;
|
||||||
*p = (CK_BYTE_PTR)templ[i].pValue;
|
*p = (CK_BYTE_PTR)templ[i].pValue;
|
||||||
p_len = templ[i].ulValueLen;
|
*p_len = templ[i].ulValueLen;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CKA_PRIME_2:
|
case CKA_PRIME_2:
|
||||||
has_q = CK_TRUE;
|
has_q = CK_TRUE;
|
||||||
*q = (CK_BYTE_PTR)templ[i].pValue;
|
*q = (CK_BYTE_PTR)templ[i].pValue;
|
||||||
q_len = templ[i].ulValueLen;
|
*q_len = templ[i].ulValueLen;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CKA_EXPONENT_1:
|
case CKA_EXPONENT_1:
|
||||||
has_dp = CK_TRUE;
|
has_dp = CK_TRUE;
|
||||||
*dp = (CK_BYTE_PTR)templ[i].pValue;
|
*dp = (CK_BYTE_PTR)templ[i].pValue;
|
||||||
dp_len = templ[i].ulValueLen;
|
*dp_len = templ[i].ulValueLen;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CKA_EXPONENT_2:
|
case CKA_EXPONENT_2:
|
||||||
has_dq = CK_TRUE;
|
has_dq = CK_TRUE;
|
||||||
*dq = (CK_BYTE_PTR)templ[i].pValue;
|
*dq = (CK_BYTE_PTR)templ[i].pValue;
|
||||||
dq_len = templ[i].ulValueLen;
|
*dq_len = templ[i].ulValueLen;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CKA_COEFFICIENT:
|
case CKA_COEFFICIENT:
|
||||||
has_qinv = CK_TRUE;
|
has_qinv = CK_TRUE;
|
||||||
*qinv = (CK_BYTE_PTR)templ[i].pValue;
|
*qinv = (CK_BYTE_PTR)templ[i].pValue;
|
||||||
qinv_len = templ[i].ulValueLen;
|
*qinv_len = templ[i].ulValueLen;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1269,13 +1511,12 @@ CK_RV check_create_rsa_key(CK_ATTRIBUTE_PTR templ, CK_ULONG n, CK_BYTE_PTR id,
|
|||||||
has_qinv == CK_FALSE)
|
has_qinv == CK_FALSE)
|
||||||
return CKR_TEMPLATE_INCOMPLETE;
|
return CKR_TEMPLATE_INCOMPLETE;
|
||||||
|
|
||||||
if (p_len != 64 && p_len != 128)
|
if (*p_len != 64 && *p_len != 128)
|
||||||
return CKR_ATTRIBUTE_VALUE_INVALID;
|
return CKR_ATTRIBUTE_VALUE_INVALID;
|
||||||
|
|
||||||
*value_len = p_len;
|
|
||||||
|
|
||||||
if (q_len != p_len || dp_len != p_len ||
|
if (*q_len != *p_len || *dp_len > *p_len ||
|
||||||
dq_len != p_len || qinv_len != p_len)
|
*dq_len > *p_len || *qinv_len > *p_len)
|
||||||
return CKR_ATTRIBUTE_VALUE_INVALID;
|
return CKR_ATTRIBUTE_VALUE_INVALID;
|
||||||
|
|
||||||
return CKR_OK;
|
return CKR_OK;
|
||||||
|
|||||||
+6
-2
@@ -18,8 +18,12 @@ CK_RV check_create_cert(CK_ATTRIBUTE_PTR templ, CK_ULONG n, CK_BYTE_PTR id,
|
|||||||
CK_RV check_create_ec_key(CK_ATTRIBUTE_PTR templ, CK_ULONG n, CK_BYTE_PTR id,
|
CK_RV check_create_ec_key(CK_ATTRIBUTE_PTR templ, CK_ULONG n, CK_BYTE_PTR id,
|
||||||
CK_BYTE_PTR *value, CK_ULONG_PTR value_len, CK_ULONG_PTR vendor_defined);
|
CK_BYTE_PTR *value, CK_ULONG_PTR value_len, CK_ULONG_PTR vendor_defined);
|
||||||
CK_RV check_create_rsa_key(CK_ATTRIBUTE_PTR templ, CK_ULONG n, CK_BYTE_PTR id,
|
CK_RV check_create_rsa_key(CK_ATTRIBUTE_PTR templ, CK_ULONG n, CK_BYTE_PTR id,
|
||||||
CK_BYTE_PTR *p, CK_BYTE_PTR *q, CK_BYTE_PTR *dp,
|
CK_BYTE_PTR *p, CK_ULONG_PTR p_len,
|
||||||
CK_BYTE_PTR *dq, CK_BYTE_PTR *qinv, CK_ULONG_PTR value_len, CK_ULONG_PTR vendor_defined);
|
CK_BYTE_PTR *q, CK_ULONG_PTR q_len,
|
||||||
|
CK_BYTE_PTR *dp, CK_ULONG_PTR dp_len,
|
||||||
|
CK_BYTE_PTR *dq, CK_ULONG_PTR dq_len,
|
||||||
|
CK_BYTE_PTR *qinv, CK_ULONG_PTR qinv_len,
|
||||||
|
CK_ULONG_PTR vendor_defined);
|
||||||
CK_RV check_delete_cert(CK_OBJECT_HANDLE hObject, CK_BYTE_PTR id);
|
CK_RV check_delete_cert(CK_OBJECT_HANDLE hObject, CK_BYTE_PTR id);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+30
-3
@@ -317,16 +317,43 @@ CK_ULONG do_get_rsa_modulus_length(EVP_PKEY *key) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CK_ULONG do_get_public_exponent(EVP_PKEY *key) {
|
CK_RV do_get_modulus(EVP_PKEY *key, CK_BYTE_PTR data, CK_ULONG_PTR len) {
|
||||||
|
RSA *rsa;
|
||||||
|
|
||||||
|
rsa = EVP_PKEY_get1_RSA(key);
|
||||||
|
if (rsa == NULL)
|
||||||
|
return CKR_FUNCTION_FAILED;
|
||||||
|
|
||||||
|
if ((CK_ULONG)BN_num_bytes(rsa->n) > *len) {
|
||||||
|
RSA_free(rsa);
|
||||||
|
rsa = NULL;
|
||||||
|
return CKR_BUFFER_TOO_SMALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*len = (CK_ULONG)BN_bn2bin(rsa->n, data);
|
||||||
|
|
||||||
|
RSA_free(rsa);
|
||||||
|
rsa = NULL;
|
||||||
|
|
||||||
|
return CKR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
CK_RV do_get_public_exponent(EVP_PKEY *key, CK_BYTE_PTR data, CK_ULONG_PTR len) {
|
||||||
|
|
||||||
CK_ULONG e = 0;
|
CK_ULONG e = 0;
|
||||||
RSA *rsa;
|
RSA *rsa;
|
||||||
|
|
||||||
rsa = EVP_PKEY_get1_RSA(key);
|
rsa = EVP_PKEY_get1_RSA(key);
|
||||||
if (rsa == NULL)
|
if (rsa == NULL)
|
||||||
return 0;
|
return CKR_FUNCTION_FAILED;
|
||||||
|
|
||||||
BN_bn2bin(rsa->e, (unsigned char *)&e);
|
if ((CK_ULONG)BN_num_bytes(rsa->e) > *len) {
|
||||||
|
RSA_free(rsa);
|
||||||
|
rsa = NULL;
|
||||||
|
return CKR_BUFFER_TOO_SMALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*len = (CK_ULONG)BN_bn2bin(rsa->e, data);
|
||||||
|
|
||||||
RSA_free(rsa);
|
RSA_free(rsa);
|
||||||
rsa = NULL;
|
rsa = NULL;
|
||||||
|
|||||||
@@ -20,8 +20,9 @@ CK_RV do_delete_cert(X509 **cert);
|
|||||||
CK_RV do_store_pubk(X509 *cert, EVP_PKEY **key);
|
CK_RV do_store_pubk(X509 *cert, EVP_PKEY **key);
|
||||||
CK_KEY_TYPE do_get_key_type(EVP_PKEY *key);
|
CK_KEY_TYPE do_get_key_type(EVP_PKEY *key);
|
||||||
CK_ULONG do_get_rsa_modulus_length(EVP_PKEY *key);
|
CK_ULONG do_get_rsa_modulus_length(EVP_PKEY *key);
|
||||||
CK_ULONG do_get_public_exponent(EVP_PKEY *key);
|
CK_RV do_get_public_exponent(EVP_PKEY *key, CK_BYTE_PTR data, CK_ULONG_PTR len);
|
||||||
CK_RV do_get_public_key(EVP_PKEY *key, CK_BYTE_PTR data, CK_ULONG_PTR len);
|
CK_RV do_get_public_key(EVP_PKEY *key, CK_BYTE_PTR data, CK_ULONG_PTR len);
|
||||||
|
CK_RV do_get_modulus(EVP_PKEY *key, CK_BYTE_PTR data, CK_ULONG_PTR len);
|
||||||
CK_RV do_encode_rsa_public_key(CK_BYTE_PTR data, CK_ULONG len, RSA **key);
|
CK_RV do_encode_rsa_public_key(CK_BYTE_PTR data, CK_ULONG len, RSA **key);
|
||||||
CK_RV do_get_curve_parameters(EVP_PKEY *key, CK_BYTE_PTR data, CK_ULONG_PTR len);
|
CK_RV do_get_curve_parameters(EVP_PKEY *key, CK_BYTE_PTR data, CK_ULONG_PTR len);
|
||||||
CK_RV do_delete_pubk(EVP_PKEY **key);
|
CK_RV do_delete_pubk(EVP_PKEY **key);
|
||||||
|
|||||||
@@ -239,6 +239,9 @@ extern "C" {
|
|||||||
|
|
||||||
#define __PASTE(x,y) x##y
|
#define __PASTE(x,y) x##y
|
||||||
|
|
||||||
|
#if defined _WIN32 || _WIN64
|
||||||
|
#pragma pack(push, cryptoki, 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* packing defines */
|
/* packing defines */
|
||||||
//#include "pkcs11p.h" // TODO: msc specific?
|
//#include "pkcs11p.h" // TODO: msc specific?
|
||||||
@@ -309,6 +312,11 @@ struct CK_FUNCTION_LIST {
|
|||||||
/* unpack */
|
/* unpack */
|
||||||
//#include "pkcs11u.h" // TODO: msc specific?
|
//#include "pkcs11u.h" // TODO: msc specific?
|
||||||
|
|
||||||
|
#if defined _WIN32 || _WIN64
|
||||||
|
#pragma pack(pop, cryptoki)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+9
-4
@@ -108,7 +108,9 @@ typedef CK_VOID_PTR CK_PTR CK_VOID_PTR_PTR;
|
|||||||
|
|
||||||
|
|
||||||
/* pack */
|
/* pack */
|
||||||
//#include "pkcs11p.h" // TODO: msc specific?
|
#if defined _WIN32 || _WIN64
|
||||||
|
#pragma pack(push, cryptoki, 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct CK_VERSION {
|
typedef struct CK_VERSION {
|
||||||
CK_BYTE major; /* integer portion of version number */
|
CK_BYTE major; /* integer portion of version number */
|
||||||
@@ -1182,14 +1184,17 @@ typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR;
|
|||||||
#define CKA_NETSCAPE_DB 0xD5A0DB00UL
|
#define CKA_NETSCAPE_DB 0xD5A0DB00UL
|
||||||
#define CKA_NETSCAPE_TRUST 0x80000001UL
|
#define CKA_NETSCAPE_TRUST 0x80000001UL
|
||||||
|
|
||||||
/* undo packing */
|
|
||||||
//#include "pkcs11u.h" // TODO: msc specific?
|
|
||||||
|
|
||||||
// YUBICO specific attributes
|
// YUBICO specific attributes
|
||||||
#define CKA_TOUCH_PIN_DEFAULT 0x00000000U
|
#define CKA_TOUCH_PIN_DEFAULT 0x00000000U
|
||||||
#define CKA_TOUCH_ALWAYS 0x00000001U
|
#define CKA_TOUCH_ALWAYS 0x00000001U
|
||||||
#define CKA_PIN_ONCE 0x00000002U
|
#define CKA_PIN_ONCE 0x00000002U
|
||||||
#define CKA_PIN_ALWAYS 0x00000004U
|
#define CKA_PIN_ALWAYS 0x00000004U
|
||||||
|
#define CKA_PIN_NEVER 0x00000008U
|
||||||
|
#define CKA_TOUCH_NEVER 0x00000016U
|
||||||
|
|
||||||
|
/* undo packing */
|
||||||
|
#if defined _WIN32 || _WIN64
|
||||||
|
#pragma pack(pop, cryptoki)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+592
-29
@@ -3,54 +3,617 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#define MANUFACTURER_ID "Yubico (www.yubico.com)"
|
#include <openssl/rsa.h>
|
||||||
#define YKCS11_DESCRIPTION "PKCS#11 PIV Library (SP-800-73)"
|
#include <openssl/ec.h>
|
||||||
#define CRYPTOKI_VERSION_MAJ 2
|
#include <openssl/bn.h>
|
||||||
#define CRYPTOKI_VERSION_MIN 40
|
#include <openssl/x509.h>
|
||||||
|
#include <openssl/rand.h>
|
||||||
|
|
||||||
|
void dump_hex(const unsigned char *buf, unsigned int len, FILE *output, int space) {
|
||||||
|
unsigned int i;
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
fprintf(output, "%02x%s", buf[i], space == 1 ? " " : "");
|
||||||
|
}
|
||||||
|
fprintf(output, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
static void lib_info() {
|
|
||||||
|
|
||||||
CK_INFO info;
|
|
||||||
CK_FUNCTION_LIST_PTR funcs;
|
CK_FUNCTION_LIST_PTR funcs;
|
||||||
|
|
||||||
if (C_GetFunctionList(&funcs) != CKR_OK) {
|
#define asrt(c, e, m) _asrt(__LINE__, c, e, m);
|
||||||
|
|
||||||
|
static void _asrt(int line, CK_ULONG check, CK_ULONG expected, CK_CHAR_PTR msg) {
|
||||||
|
|
||||||
|
if (check == expected)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fprintf(stderr, "<%s>:%d check failed with value %lu (0x%lx), expected %lu (0x%lx)\n",
|
||||||
|
msg, line, check, check, expected, expected);
|
||||||
|
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void get_functions(CK_FUNCTION_LIST_PTR_PTR funcs) {
|
||||||
|
|
||||||
|
if (C_GetFunctionList(funcs) != CKR_OK) {
|
||||||
fprintf(stderr, "Get function list failed\n");
|
fprintf(stderr, "Get function list failed\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (funcs->C_GetInfo(&info) != CKR_OK) {
|
|
||||||
fprintf(stderr, "GetInfo failed\n");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(info.manufacturerID, MANUFACTURER_ID) != 0) {
|
static void test_lib_info() {
|
||||||
fprintf(stderr, "unexpected manufacturer ID %s\n", info.manufacturerID);
|
|
||||||
exit(EXIT_FAILURE);
|
const CK_CHAR_PTR MANUFACTURER_ID = "Yubico (www.yubico.com)";
|
||||||
|
const CK_CHAR_PTR YKCS11_DESCRIPTION = "PKCS#11 PIV Library (SP-800-73)";
|
||||||
|
const CK_ULONG CRYPTOKI_VERSION_MAJ = 2;
|
||||||
|
const CK_ULONG CRYPTOKI_VERSION_MIN = 40;
|
||||||
|
|
||||||
|
|
||||||
|
CK_INFO info;
|
||||||
|
|
||||||
|
asrt(funcs->C_GetInfo(&info), CKR_OK, "GET_INFO");
|
||||||
|
|
||||||
|
asrt(strcmp(info.manufacturerID, MANUFACTURER_ID), 0, "MANUFACTURER");
|
||||||
|
|
||||||
|
asrt(info.cryptokiVersion.major, CRYPTOKI_VERSION_MAJ, "CK_MAJ");
|
||||||
|
asrt(info.cryptokiVersion.minor, CRYPTOKI_VERSION_MIN, "CK_MIN");
|
||||||
|
|
||||||
|
asrt(info.libraryVersion.major, YKCS11_VERSION_MAJOR, "LIB_MAJ");
|
||||||
|
asrt(info.libraryVersion.minor, ((YKCS11_VERSION_MINOR * 10) + YKCS11_VERSION_PATCH ), "LIB_MIN");
|
||||||
|
|
||||||
|
asrt(strcmp(info.libraryDescription, YKCS11_DESCRIPTION), 0, "LIB_DESC");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.cryptokiVersion.major != CRYPTOKI_VERSION_MAJ ||
|
#ifdef HW_TESTS
|
||||||
info.cryptokiVersion.minor != CRYPTOKI_VERSION_MIN ) {
|
static void test_initalize() {
|
||||||
fprintf(stderr, "unexpected Cryptoki version %d.%d\n", info.cryptokiVersion.major, info.cryptokiVersion.minor);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (info.libraryVersion.major != YKCS11_VERSION_MAJOR ||
|
asrt(funcs->C_Initialize(NULL), CKR_OK, "INITIALIZE");
|
||||||
info.libraryVersion.minor != ((YKCS11_VERSION_MINOR * 100) + YKCS11_VERSION_PATCH )) {
|
|
||||||
fprintf(stderr, "unexpected YKCS11 version %d.%d\n", info.libraryVersion.major, info.libraryVersion.minor);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(info.libraryDescription, YKCS11_DESCRIPTION) != 0) {
|
asrt(funcs->C_Finalize(NULL), CKR_OK, "FINALIZE");
|
||||||
fprintf(stderr, "unexpected description %s\n", info.libraryDescription);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_token_info() {
|
||||||
|
|
||||||
|
const CK_CHAR_PTR TOKEN_LABEL = "YubiKey PIV";
|
||||||
|
const CK_CHAR_PTR TOKEN_MODEL = "YubiKey "; // Skip last 3 characters (version dependent)
|
||||||
|
const CK_CHAR_PTR TOKEN_SERIAL = "1234";
|
||||||
|
const CK_FLAGS TOKEN_FLAGS = CKF_RNG | CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED | CKF_TOKEN_INITIALIZED;
|
||||||
|
const CK_VERSION HW = {0, 0};
|
||||||
|
const CK_CHAR_PTR TOKEN_TIME = " ";
|
||||||
|
CK_TOKEN_INFO info;
|
||||||
|
|
||||||
|
asrt(funcs->C_Initialize(NULL), CKR_OK, "INITIALIZE");
|
||||||
|
|
||||||
|
asrt(funcs->C_GetTokenInfo(0, &info), CKR_OK, "GetTokeninfo");
|
||||||
|
asrt(strncmp(info.label, TOKEN_LABEL, strlen(TOKEN_LABEL)), 0, "TOKEN_LABEL");
|
||||||
|
// Skip manufacturer id (not used)
|
||||||
|
asrt(strncmp(info.model, TOKEN_MODEL, strlen(TOKEN_MODEL)), 0, "TOKEN_MODEL");
|
||||||
|
asrt(strncmp(info.serialNumber, TOKEN_SERIAL, strlen(TOKEN_SERIAL)), 0, "SERIAL_NUMBER");
|
||||||
|
asrt(info.flags, TOKEN_FLAGS, "TOKEN_FLAGS");
|
||||||
|
asrt(info.ulMaxSessionCount, CK_UNAVAILABLE_INFORMATION, "MAX_SESSION_COUNT");
|
||||||
|
asrt(info.ulSessionCount, CK_UNAVAILABLE_INFORMATION, "SESSION_COUNT");
|
||||||
|
asrt(info.ulMaxRwSessionCount, CK_UNAVAILABLE_INFORMATION, "MAX_RW_SESSION_COUNT");
|
||||||
|
asrt(info.ulRwSessionCount, CK_UNAVAILABLE_INFORMATION, "RW_SESSION_COUNT");
|
||||||
|
asrt(info.ulMaxPinLen, 8, "MAX_PIN_LEN");
|
||||||
|
asrt(info.ulMinPinLen, 6, "MIN_PIN_LEN");
|
||||||
|
asrt(info.ulTotalPublicMemory, CK_UNAVAILABLE_INFORMATION, "TOTAL_PUB_MEM");
|
||||||
|
asrt(info.ulFreePublicMemory, CK_UNAVAILABLE_INFORMATION, "FREE_PUB_MEM");
|
||||||
|
asrt(info.ulTotalPrivateMemory, CK_UNAVAILABLE_INFORMATION, "TOTAL_PVT_MEM");
|
||||||
|
asrt(info.ulFreePrivateMemory, CK_UNAVAILABLE_INFORMATION, "FREE_PVT_MEM");
|
||||||
|
asrt(info.hardwareVersion.major, HW.major, "HW_MAJ");
|
||||||
|
asrt(info.hardwareVersion.minor, HW.minor, "HW_MIN");
|
||||||
|
|
||||||
|
if (info.firmwareVersion.major != 4 && info.firmwareVersion.major != 0)
|
||||||
|
asrt(info.firmwareVersion.major, 4, "FW_MAJ");
|
||||||
|
|
||||||
|
asrt(strcmp(info.utcTime, TOKEN_TIME), 0, "TOKEN_TIME");
|
||||||
|
|
||||||
|
asrt(funcs->C_Finalize(NULL), CKR_OK, "FINALIZE");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_mechanism_list_and_info() {
|
||||||
|
|
||||||
|
CK_MECHANISM_TYPE_PTR mechs;
|
||||||
|
CK_ULONG n_mechs;
|
||||||
|
CK_MECHANISM_INFO info;
|
||||||
|
CK_ULONG i;
|
||||||
|
|
||||||
|
static const CK_MECHANISM_TYPE token_mechanisms[] = {
|
||||||
|
CKM_RSA_PKCS_KEY_PAIR_GEN,
|
||||||
|
CKM_RSA_PKCS,
|
||||||
|
CKM_RSA_PKCS_PSS,
|
||||||
|
CKM_RSA_X_509,
|
||||||
|
CKM_SHA1_RSA_PKCS,
|
||||||
|
CKM_SHA256_RSA_PKCS,
|
||||||
|
CKM_SHA384_RSA_PKCS,
|
||||||
|
CKM_SHA512_RSA_PKCS,
|
||||||
|
CKM_SHA1_RSA_PKCS_PSS,
|
||||||
|
CKM_SHA256_RSA_PKCS_PSS,
|
||||||
|
CKM_SHA384_RSA_PKCS_PSS,
|
||||||
|
CKM_SHA512_RSA_PKCS_PSS,
|
||||||
|
CKM_EC_KEY_PAIR_GEN,
|
||||||
|
CKM_ECDSA,
|
||||||
|
CKM_ECDSA_SHA1,
|
||||||
|
CKM_ECDSA_SHA256,
|
||||||
|
CKM_SHA_1,
|
||||||
|
CKM_SHA256,
|
||||||
|
CKM_SHA384,
|
||||||
|
CKM_SHA512
|
||||||
|
};
|
||||||
|
|
||||||
|
static const CK_MECHANISM_INFO token_mechanism_infos[] = { // KEEP ALIGNED WITH token_mechanisms
|
||||||
|
{1024, 2048, CKF_HW | CKF_GENERATE_KEY_PAIR},
|
||||||
|
{1024, 2048, CKF_HW | CKF_DECRYPT | CKF_SIGN},
|
||||||
|
{1024, 2048, CKF_HW | CKF_SIGN},
|
||||||
|
{1024, 2048, CKF_HW | CKF_DECRYPT | CKF_SIGN},
|
||||||
|
{1024, 2048, CKF_HW | CKF_SIGN},
|
||||||
|
{1024, 2048, CKF_HW | CKF_SIGN},
|
||||||
|
{1024, 2048, CKF_HW | CKF_SIGN},
|
||||||
|
{1024, 2048, CKF_HW | CKF_SIGN},
|
||||||
|
{1024, 2048, CKF_HW | CKF_SIGN},
|
||||||
|
{1024, 2048, CKF_HW | CKF_SIGN},
|
||||||
|
{1024, 2048, CKF_HW | CKF_SIGN},
|
||||||
|
{1024, 2048, CKF_HW | CKF_SIGN},
|
||||||
|
{256, 384, CKF_HW | CKF_GENERATE_KEY_PAIR},
|
||||||
|
{256, 384, CKF_HW | CKF_SIGN},
|
||||||
|
{256, 384, CKF_HW | CKF_SIGN},
|
||||||
|
{256, 384, CKF_HW | CKF_SIGN},
|
||||||
|
{0, 0, CKF_DIGEST},
|
||||||
|
{0, 0, CKF_DIGEST},
|
||||||
|
{0, 0, CKF_DIGEST},
|
||||||
|
{0, 0, CKF_DIGEST}
|
||||||
|
};
|
||||||
|
|
||||||
|
asrt(funcs->C_Initialize(NULL), CKR_OK, "INITIALIZE");
|
||||||
|
|
||||||
|
asrt(funcs->C_GetMechanismList(0, NULL, &n_mechs), CKR_OK, "GetMechanismList");
|
||||||
|
|
||||||
|
mechs = malloc(n_mechs * sizeof(CK_MECHANISM_TYPE));
|
||||||
|
asrt(funcs->C_GetMechanismList(0, mechs, &n_mechs), CKR_OK, "GetMechanismList");
|
||||||
|
|
||||||
|
asrt(memcmp(token_mechanisms, mechs, sizeof(token_mechanisms)), 0, "CHECK MECHS");
|
||||||
|
|
||||||
|
for (i = 0; i < n_mechs; i++) {
|
||||||
|
asrt(funcs->C_GetMechanismInfo(0, mechs[i], &info), CKR_OK, "GET MECH INFO");
|
||||||
|
asrt(memcmp(token_mechanism_infos + i, &info, sizeof(CK_MECHANISM_INFO)), 0, "CHECK MECH INFO");
|
||||||
|
}
|
||||||
|
|
||||||
|
asrt(funcs->C_Finalize(NULL), CKR_OK, "FINALIZE");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_session() {
|
||||||
|
|
||||||
|
CK_SESSION_HANDLE session;
|
||||||
|
CK_SESSION_INFO info;
|
||||||
|
|
||||||
|
asrt(funcs->C_Initialize(NULL), CKR_OK, "INITIALIZE");
|
||||||
|
|
||||||
|
asrt(funcs->C_OpenSession(0, CKF_SERIAL_SESSION, NULL, NULL, &session), CKR_OK, "OpenSession1");
|
||||||
|
asrt(funcs->C_CloseSession(session), CKR_OK, "CloseSession");
|
||||||
|
|
||||||
|
asrt(funcs->C_OpenSession(0, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL, NULL, &session), CKR_OK, "OpenSession2");
|
||||||
|
asrt(funcs->C_GetSessionInfo(session, &info), CKR_OK, "GetSessionInfo");
|
||||||
|
asrt(info.state, CKS_RW_PUBLIC_SESSION, "CHECK STATE");
|
||||||
|
asrt(info.flags, CKF_SERIAL_SESSION | CKF_RW_SESSION, "CHECK FLAGS");
|
||||||
|
asrt(info.ulDeviceError, 0, "CHECK DEVICE ERROR");
|
||||||
|
asrt(funcs->C_CloseSession(session), CKR_OK, "CloseSession");
|
||||||
|
|
||||||
|
asrt(funcs->C_OpenSession(0, CKF_SERIAL_SESSION, NULL, NULL, &session), CKR_OK, "OpenSession3");
|
||||||
|
asrt(funcs->C_CloseAllSessions(0), CKR_OK, "CloseAllSessions");
|
||||||
|
|
||||||
|
asrt(funcs->C_Finalize(NULL), CKR_OK, "FINALIZE");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_login() {
|
||||||
|
|
||||||
|
CK_SESSION_HANDLE session;
|
||||||
|
CK_SESSION_INFO info;
|
||||||
|
|
||||||
|
asrt(funcs->C_Initialize(NULL), CKR_OK, "INITIALIZE");
|
||||||
|
|
||||||
|
asrt(funcs->C_OpenSession(0, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL, NULL, &session), CKR_OK, "OpenSession1");
|
||||||
|
|
||||||
|
asrt(funcs->C_Login(session, CKU_USER, "123456", 6), CKR_OK, "Login USER");
|
||||||
|
asrt(funcs->C_Logout(session), CKR_OK, "Logout USER");
|
||||||
|
|
||||||
|
asrt(funcs->C_Login(session, CKU_SO, "010203040506070801020304050607080102030405060708", 48), CKR_OK, "Login SO");
|
||||||
|
asrt(funcs->C_Logout(session), CKR_OK, "Logout SO");
|
||||||
|
|
||||||
|
asrt(funcs->C_CloseSession(session), CKR_OK, "CloseSession");
|
||||||
|
|
||||||
|
asrt(funcs->C_Finalize(NULL), CKR_OK, "FINALIZE");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Import a newly generated P256 pvt key and a certificate
|
||||||
|
// to every slot and use the key to sign some data
|
||||||
|
static void test_import_and_sign_all_10() {
|
||||||
|
|
||||||
|
EVP_PKEY *evp;
|
||||||
|
EC_KEY *eck;
|
||||||
|
const EC_POINT *ecp;
|
||||||
|
const BIGNUM *bn;
|
||||||
|
char pvt[32];
|
||||||
|
X509 *cert;
|
||||||
|
ASN1_TIME *tm;
|
||||||
|
CK_BYTE i, j;
|
||||||
|
CK_BYTE some_data[32];
|
||||||
|
|
||||||
|
CK_ULONG class_k = CKO_PRIVATE_KEY;
|
||||||
|
CK_ULONG class_c = CKO_CERTIFICATE;
|
||||||
|
CK_ULONG kt = CKK_ECDSA;
|
||||||
|
CK_BYTE id = 0;
|
||||||
|
CK_BYTE params[] = {0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07};
|
||||||
|
CK_BYTE sig[64];
|
||||||
|
CK_ULONG recv_len;
|
||||||
|
CK_BYTE value_c[3100];
|
||||||
|
CK_ULONG cert_len;
|
||||||
|
CK_BYTE der_encoded[80];
|
||||||
|
CK_BYTE_PTR der_ptr;
|
||||||
|
CK_BYTE_PTR r_ptr;
|
||||||
|
CK_BYTE_PTR s_ptr;
|
||||||
|
CK_ULONG r_len;
|
||||||
|
CK_ULONG s_len;
|
||||||
|
|
||||||
|
unsigned char *p;
|
||||||
|
|
||||||
|
CK_ATTRIBUTE privateKeyTemplate[] = {
|
||||||
|
{CKA_CLASS, &class_k, sizeof(class_k)},
|
||||||
|
{CKA_KEY_TYPE, &kt, sizeof(kt)},
|
||||||
|
{CKA_ID, &id, sizeof(id)},
|
||||||
|
{CKA_EC_PARAMS, ¶ms, sizeof(params)},
|
||||||
|
{CKA_VALUE, pvt, sizeof(pvt)}
|
||||||
|
};
|
||||||
|
|
||||||
|
CK_ATTRIBUTE publicKeyTemplate[] = {
|
||||||
|
{CKA_CLASS, &class_c, sizeof(class_c)},
|
||||||
|
{CKA_ID, &id, sizeof(id)},
|
||||||
|
{CKA_VALUE, value_c, sizeof(value_c)}
|
||||||
|
};
|
||||||
|
|
||||||
|
CK_OBJECT_HANDLE obj[24];
|
||||||
|
CK_SESSION_HANDLE session;
|
||||||
|
CK_MECHANISM mech = {CKM_ECDSA, NULL};
|
||||||
|
|
||||||
|
evp = EVP_PKEY_new();
|
||||||
|
|
||||||
|
if (evp == NULL)
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
eck = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
|
||||||
|
|
||||||
|
if (eck == NULL)
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
asrt(EC_KEY_generate_key(eck), 1, "GENERATE ECK");
|
||||||
|
|
||||||
|
bn = EC_KEY_get0_private_key(eck);
|
||||||
|
|
||||||
|
asrt(BN_bn2bin(bn, pvt), 32, "EXTRACT PVT");
|
||||||
|
|
||||||
|
if (EVP_PKEY_set1_EC_KEY(evp, eck) == 0)
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
cert = X509_new();
|
||||||
|
|
||||||
|
if (cert == NULL)
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
if (X509_set_pubkey(cert, evp) == 0)
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
tm = ASN1_TIME_new();
|
||||||
|
if (tm == NULL)
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
ASN1_TIME_set_string(tm, "000001010000Z");
|
||||||
|
X509_set_notBefore(cert, tm);
|
||||||
|
X509_set_notAfter(cert, tm);
|
||||||
|
|
||||||
|
cert->sig_alg->algorithm = OBJ_nid2obj(8);
|
||||||
|
cert->cert_info->signature->algorithm = OBJ_nid2obj(8);
|
||||||
|
|
||||||
|
ASN1_BIT_STRING_set_bit(cert->signature, 8, 1);
|
||||||
|
ASN1_BIT_STRING_set(cert->signature, "\x00", 1);
|
||||||
|
|
||||||
|
p = value_c;
|
||||||
|
if ((cert_len = (CK_ULONG) i2d_X509(cert, &p)) == 0 || cert_len > sizeof(value_c))
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
publicKeyTemplate[2].ulValueLen = cert_len;
|
||||||
|
|
||||||
|
asrt(funcs->C_Initialize(NULL), CKR_OK, "INITIALIZE");
|
||||||
|
asrt(funcs->C_OpenSession(0, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL, NULL, &session), CKR_OK, "OpenSession1");
|
||||||
|
asrt(funcs->C_Login(session, CKU_SO, "010203040506070801020304050607080102030405060708", 48), CKR_OK, "Login SO");
|
||||||
|
|
||||||
|
for (i = 0; i < 24; i++) {
|
||||||
|
id = i;
|
||||||
|
asrt(funcs->C_CreateObject(session, publicKeyTemplate, 3, obj + i), CKR_OK, "IMPORT CERT");
|
||||||
|
asrt(funcs->C_CreateObject(session, privateKeyTemplate, 5, obj + i), CKR_OK, "IMPORT KEY");
|
||||||
|
}
|
||||||
|
|
||||||
|
asrt(funcs->C_Logout(session), CKR_OK, "Logout SO");
|
||||||
|
|
||||||
|
for (i = 0; i < 24; i++) {
|
||||||
|
for (j = 0; j < 10; j++) {
|
||||||
|
|
||||||
|
if(RAND_pseudo_bytes(some_data, sizeof(some_data)) == -1)
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
asrt(funcs->C_Login(session, CKU_USER, "123456", 6), CKR_OK, "Login USER");
|
||||||
|
asrt(funcs->C_SignInit(session, &mech, obj[i]), CKR_OK, "SignInit");
|
||||||
|
|
||||||
|
recv_len = sizeof(sig);
|
||||||
|
asrt(funcs->C_Sign(session, some_data, sizeof(some_data), sig, &recv_len), CKR_OK, "Sign");
|
||||||
|
|
||||||
|
r_len = 32;
|
||||||
|
s_len = 32;
|
||||||
|
|
||||||
|
der_ptr = der_encoded;
|
||||||
|
*der_ptr++ = 0x30;
|
||||||
|
*der_ptr++ = 0xff; // placeholder, fix below
|
||||||
|
|
||||||
|
r_ptr = sig;
|
||||||
|
|
||||||
|
*der_ptr++ = 0x02;
|
||||||
|
*der_ptr++ = r_len;
|
||||||
|
if (*r_ptr >= 0x80) {
|
||||||
|
*(der_ptr - 1) = *(der_ptr - 1) + 1;
|
||||||
|
*der_ptr++ = 0x00;
|
||||||
|
}
|
||||||
|
else if (*r_ptr == 0x00 && *(r_ptr + 1) < 0x80) {
|
||||||
|
r_len--;
|
||||||
|
*(der_ptr - 1) = *(der_ptr - 1) - 1;
|
||||||
|
r_ptr++;
|
||||||
|
}
|
||||||
|
memcpy(der_ptr, r_ptr, r_len);
|
||||||
|
der_ptr+= r_len;
|
||||||
|
|
||||||
|
s_ptr = sig + 32;
|
||||||
|
|
||||||
|
*der_ptr++ = 0x02;
|
||||||
|
*der_ptr++ = s_len;
|
||||||
|
if (*s_ptr >= 0x80) {
|
||||||
|
*(der_ptr - 1) = *(der_ptr - 1) + 1;
|
||||||
|
*der_ptr++ = 0x00;
|
||||||
|
}
|
||||||
|
else if (*s_ptr == 0x00 && *(s_ptr + 1) < 0x80) {
|
||||||
|
s_len--;
|
||||||
|
*(der_ptr - 1) = *(der_ptr - 1) - 1;
|
||||||
|
s_ptr++;
|
||||||
|
}
|
||||||
|
memcpy(der_ptr, s_ptr, s_len);
|
||||||
|
der_ptr+= s_len;
|
||||||
|
|
||||||
|
der_encoded[1] = der_ptr - der_encoded - 2;
|
||||||
|
|
||||||
|
dump_hex(der_encoded, der_encoded[1] + 2, stderr, 1);
|
||||||
|
|
||||||
|
asrt(ECDSA_verify(0, some_data, sizeof(some_data), der_encoded, der_encoded[1] + 2, eck), 1, "ECDSA VERIFICATION");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
asrt(funcs->C_Logout(session), CKR_OK, "Logout USER");
|
||||||
|
|
||||||
|
asrt(funcs->C_CloseSession(session), CKR_OK, "CloseSession");
|
||||||
|
asrt(funcs->C_Finalize(NULL), CKR_OK, "FINALIZE");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Import a newly generated RSA1024 pvt key and a certificate
|
||||||
|
// to every slot and use the key to sign some data
|
||||||
|
static void test_import_and_sign_all_10_RSA() {
|
||||||
|
|
||||||
|
EVP_PKEY *evp;
|
||||||
|
RSA *rsak;
|
||||||
|
X509 *cert;
|
||||||
|
ASN1_TIME *tm;
|
||||||
|
CK_BYTE i, j;
|
||||||
|
CK_BYTE some_data[32];
|
||||||
|
CK_BYTE e[] = {0x01, 0x00, 0x01};
|
||||||
|
CK_BYTE p[64];
|
||||||
|
CK_BYTE q[64];
|
||||||
|
CK_BYTE dp[64];
|
||||||
|
CK_BYTE dq[64];
|
||||||
|
CK_BYTE qinv[64];
|
||||||
|
BIGNUM *e_bn;
|
||||||
|
CK_ULONG class_k = CKO_PRIVATE_KEY;
|
||||||
|
CK_ULONG class_c = CKO_CERTIFICATE;
|
||||||
|
CK_ULONG kt = CKK_RSA;
|
||||||
|
CK_BYTE id = 0;
|
||||||
|
CK_BYTE sig[64];
|
||||||
|
CK_ULONG recv_len;
|
||||||
|
CK_BYTE value_c[3100];
|
||||||
|
CK_ULONG cert_len;
|
||||||
|
CK_BYTE der_encoded[80];
|
||||||
|
CK_BYTE_PTR der_ptr;
|
||||||
|
CK_BYTE_PTR r_ptr;
|
||||||
|
CK_BYTE_PTR s_ptr;
|
||||||
|
CK_ULONG r_len;
|
||||||
|
CK_ULONG s_len;
|
||||||
|
|
||||||
|
unsigned char *px;
|
||||||
|
|
||||||
|
CK_ATTRIBUTE privateKeyTemplate[] = {
|
||||||
|
{CKA_CLASS, &class_k, sizeof(class_k)},
|
||||||
|
{CKA_KEY_TYPE, &kt, sizeof(kt)},
|
||||||
|
{CKA_ID, &id, sizeof(id)},
|
||||||
|
{CKA_PUBLIC_EXPONENT, e, sizeof(e)},
|
||||||
|
{CKA_PRIME_1, p, sizeof(p)},
|
||||||
|
{CKA_PRIME_2, q, sizeof(q)},
|
||||||
|
{CKA_EXPONENT_1, dp, sizeof(dp)},
|
||||||
|
{CKA_EXPONENT_2, dq, sizeof(dq)},
|
||||||
|
{CKA_COEFFICIENT, qinv, sizeof(qinv)}
|
||||||
|
};
|
||||||
|
|
||||||
|
CK_ATTRIBUTE publicKeyTemplate[] = {
|
||||||
|
{CKA_CLASS, &class_c, sizeof(class_c)},
|
||||||
|
{CKA_ID, &id, sizeof(id)},
|
||||||
|
{CKA_VALUE, value_c, sizeof(value_c)}
|
||||||
|
};
|
||||||
|
|
||||||
|
CK_OBJECT_HANDLE obj[24];
|
||||||
|
CK_SESSION_HANDLE session;
|
||||||
|
CK_MECHANISM mech = {CKM_RSA_PKCS, NULL};
|
||||||
|
|
||||||
|
evp = EVP_PKEY_new();
|
||||||
|
|
||||||
|
if (evp == NULL)
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
rsak = RSA_new();
|
||||||
|
|
||||||
|
if (rsak == NULL)
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
e_bn = BN_bin2bn(e, 3, NULL);
|
||||||
|
|
||||||
|
if (e_bn == NULL)
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
asrt(RSA_generate_key_ex(rsak, 1024, e_bn, NULL), 1, "GENERATE RSAK");
|
||||||
|
|
||||||
|
asrt(BN_bn2bin(rsak->p, p), 64, "GET P");
|
||||||
|
asrt(BN_bn2bin(rsak->q, q), 64, "GET Q");
|
||||||
|
asrt(BN_bn2bin(rsak->dmp1, dp), 64, "GET DP");
|
||||||
|
asrt(BN_bn2bin(rsak->dmq1, dp), 64, "GET DQ");
|
||||||
|
asrt(BN_bn2bin(rsak->iqmp, qinv), 64, "GET QINV");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (EVP_PKEY_set1_RSA(evp, rsak) == 0)
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
cert = X509_new();
|
||||||
|
|
||||||
|
if (cert == NULL)
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
if (X509_set_pubkey(cert, evp) == 0)
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
tm = ASN1_TIME_new();
|
||||||
|
if (tm == NULL)
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
ASN1_TIME_set_string(tm, "000001010000Z");
|
||||||
|
X509_set_notBefore(cert, tm);
|
||||||
|
X509_set_notAfter(cert, tm);
|
||||||
|
|
||||||
|
cert->sig_alg->algorithm = OBJ_nid2obj(8);
|
||||||
|
cert->cert_info->signature->algorithm = OBJ_nid2obj(8);
|
||||||
|
|
||||||
|
ASN1_BIT_STRING_set_bit(cert->signature, 8, 1);
|
||||||
|
ASN1_BIT_STRING_set(cert->signature, "\x00", 1);
|
||||||
|
|
||||||
|
px = value_c;
|
||||||
|
if ((cert_len = (CK_ULONG) i2d_X509(cert, &px)) == 0 || cert_len > sizeof(value_c))
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
publicKeyTemplate[2].ulValueLen = cert_len;
|
||||||
|
|
||||||
|
asrt(funcs->C_Initialize(NULL), CKR_OK, "INITIALIZE");
|
||||||
|
asrt(funcs->C_OpenSession(0, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL, NULL, &session), CKR_OK, "OpenSession1");
|
||||||
|
asrt(funcs->C_Login(session, CKU_SO, "010203040506070801020304050607080102030405060708", 48), CKR_OK, "Login SO");
|
||||||
|
|
||||||
|
for (i = 0; i < 24; i++) {
|
||||||
|
id = i;
|
||||||
|
asrt(funcs->C_CreateObject(session, publicKeyTemplate, 3, obj + i), CKR_OK, "IMPORT CERT");
|
||||||
|
asrt(funcs->C_CreateObject(session, privateKeyTemplate, 9, obj + i), CKR_OK, "IMPORT KEY");
|
||||||
|
}
|
||||||
|
|
||||||
|
asrt(funcs->C_Logout(session), CKR_OK, "Logout SO");
|
||||||
|
|
||||||
|
for (i = 0; i < 24; i++) {
|
||||||
|
for (j = 0; j < 10; j++) {
|
||||||
|
|
||||||
|
if(RAND_pseudo_bytes(some_data, sizeof(some_data)) == -1)
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
asrt(funcs->C_Login(session, CKU_USER, "123456", 6), CKR_OK, "Login USER");
|
||||||
|
asrt(funcs->C_SignInit(session, &mech, obj[i]), CKR_OK, "SignInit");
|
||||||
|
|
||||||
|
recv_len = sizeof(sig);
|
||||||
|
asrt(funcs->C_Sign(session, some_data, sizeof(some_data), sig, &recv_len), CKR_OK, "Sign");
|
||||||
|
|
||||||
|
/* r_len = 32; */
|
||||||
|
/* s_len = 32; */
|
||||||
|
|
||||||
|
/* der_ptr = der_encoded; */
|
||||||
|
/* *der_ptr++ = 0x30; */
|
||||||
|
/* *der_ptr++ = 0xff; // placeholder, fix below */
|
||||||
|
|
||||||
|
/* r_ptr = sig; */
|
||||||
|
|
||||||
|
/* *der_ptr++ = 0x02; */
|
||||||
|
/* *der_ptr++ = r_len; */
|
||||||
|
/* if (*r_ptr >= 0x80) { */
|
||||||
|
/* *(der_ptr - 1) = *(der_ptr - 1) + 1; */
|
||||||
|
/* *der_ptr++ = 0x00; */
|
||||||
|
/* } */
|
||||||
|
/* else if (*r_ptr == 0x00 && *(r_ptr + 1) < 0x80) { */
|
||||||
|
/* r_len--; */
|
||||||
|
/* *(der_ptr - 1) = *(der_ptr - 1) - 1; */
|
||||||
|
/* r_ptr++; */
|
||||||
|
/* } */
|
||||||
|
/* memcpy(der_ptr, r_ptr, r_len); */
|
||||||
|
/* der_ptr+= r_len; */
|
||||||
|
|
||||||
|
/* s_ptr = sig + 32; */
|
||||||
|
|
||||||
|
/* *der_ptr++ = 0x02; */
|
||||||
|
/* *der_ptr++ = s_len; */
|
||||||
|
/* if (*s_ptr >= 0x80) { */
|
||||||
|
/* *(der_ptr - 1) = *(der_ptr - 1) + 1; */
|
||||||
|
/* *der_ptr++ = 0x00; */
|
||||||
|
/* } */
|
||||||
|
/* else if (*s_ptr == 0x00 && *(s_ptr + 1) < 0x80) { */
|
||||||
|
/* s_len--; */
|
||||||
|
/* *(der_ptr - 1) = *(der_ptr - 1) - 1; */
|
||||||
|
/* s_ptr++; */
|
||||||
|
/* } */
|
||||||
|
/* memcpy(der_ptr, s_ptr, s_len); */
|
||||||
|
/* der_ptr+= s_len; */
|
||||||
|
|
||||||
|
/* der_encoded[1] = der_ptr - der_encoded - 2; */
|
||||||
|
|
||||||
|
/* dump_hex(der_encoded, der_encoded[1] + 2, stderr, 1); */
|
||||||
|
|
||||||
|
/* asrt(ECDSA_verify(0, some_data, sizeof(some_data), der_encoded, der_encoded[1] + 2, eck), 1, "ECDSA VERIFICATION"); */
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
asrt(funcs->C_Logout(session), CKR_OK, "Logout USER");
|
||||||
|
|
||||||
|
asrt(funcs->C_CloseSession(session), CKR_OK, "CloseSession");
|
||||||
|
asrt(funcs->C_Finalize(NULL), CKR_OK, "FINALIZE");
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
|
|
||||||
lib_info();
|
get_functions(&funcs);
|
||||||
|
|
||||||
|
test_lib_info();
|
||||||
|
|
||||||
|
#ifdef HW_TESTS
|
||||||
|
test_initalize();
|
||||||
|
test_token_info();
|
||||||
|
test_mechanism_list_and_info();
|
||||||
|
test_session();
|
||||||
|
test_login();
|
||||||
|
test_import_and_sign_all_10();
|
||||||
|
test_import_and_sign_all_10_RSA();
|
||||||
|
#else
|
||||||
|
fprintf(stderr, "HARDWARE TESTS DISABLED!, skipping...\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
|
||||||
|
|||||||
+79
-75
@@ -12,9 +12,24 @@ static CK_RV COMMON_token_login(ykpiv_state *state, CK_USER_TYPE user, CK_UTF8CH
|
|||||||
int tries = 0; // TODO: this is effectively disregarded, should we add a better value in ykpiv_verify?
|
int tries = 0; // TODO: this is effectively disregarded, should we add a better value in ykpiv_verify?
|
||||||
unsigned char key[24];
|
unsigned char key[24];
|
||||||
size_t key_len = sizeof(key);
|
size_t key_len = sizeof(key);
|
||||||
|
unsigned char *term_pin;
|
||||||
|
ykpiv_rc res;
|
||||||
|
|
||||||
if (user == CKU_USER) {
|
if (user == CKU_USER) {
|
||||||
if (ykpiv_verify(state, (char *)pin, &tries) != YKPIV_OK) {
|
// add null termination for the pin
|
||||||
|
term_pin = malloc(pin_len + 1);
|
||||||
|
if (term_pin == NULL) {
|
||||||
|
return CKR_HOST_MEMORY;
|
||||||
|
}
|
||||||
|
memcpy(term_pin, pin, pin_len);
|
||||||
|
term_pin[pin_len] = 0;
|
||||||
|
|
||||||
|
res = ykpiv_verify(state, (char *)term_pin, &tries);
|
||||||
|
|
||||||
|
OPENSSL_cleanse(term_pin, pin_len);
|
||||||
|
free(term_pin);
|
||||||
|
|
||||||
|
if (res != YKPIV_OK) {
|
||||||
DBG("Failed to login");
|
DBG("Failed to login");
|
||||||
return CKR_PIN_INCORRECT;
|
return CKR_PIN_INCORRECT;
|
||||||
}
|
}
|
||||||
@@ -58,7 +73,7 @@ static CK_RV COMMON_token_generate_key(ykpiv_state *state, CK_BBOOL rsa,
|
|||||||
switch(key_len) {
|
switch(key_len) {
|
||||||
case 2048:
|
case 2048:
|
||||||
if (rsa == CK_TRUE)
|
if (rsa == CK_TRUE)
|
||||||
in_data[4] = YKPIV_ALGO_RSA2048;
|
*in_ptr++ = YKPIV_ALGO_RSA2048;
|
||||||
else
|
else
|
||||||
return CKR_FUNCTION_FAILED;
|
return CKR_FUNCTION_FAILED;
|
||||||
|
|
||||||
@@ -143,7 +158,7 @@ static CK_RV COMMON_token_generate_key(ykpiv_state *state, CK_BBOOL rsa,
|
|||||||
|
|
||||||
static CK_RV COMMON_token_import_cert(ykpiv_state *state, CK_ULONG cert_id, CK_BYTE_PTR in) {
|
static CK_RV COMMON_token_import_cert(ykpiv_state *state, CK_ULONG cert_id, CK_BYTE_PTR in) {
|
||||||
|
|
||||||
unsigned char certdata[2100];
|
unsigned char certdata[3072];
|
||||||
unsigned char *certptr;
|
unsigned char *certptr;
|
||||||
CK_ULONG cert_len;
|
CK_ULONG cert_len;
|
||||||
|
|
||||||
@@ -153,7 +168,7 @@ static CK_RV COMMON_token_import_cert(ykpiv_state *state, CK_ULONG cert_id, CK_B
|
|||||||
if ((rv = do_check_cert(in, &cert_len)) != CKR_OK)
|
if ((rv = do_check_cert(in, &cert_len)) != CKR_OK)
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
if (cert_len > 2100)
|
if (cert_len > 3072)
|
||||||
return CKR_FUNCTION_FAILED;
|
return CKR_FUNCTION_FAILED;
|
||||||
|
|
||||||
certptr = certdata;
|
certptr = certdata;
|
||||||
@@ -176,85 +191,73 @@ static CK_RV COMMON_token_import_cert(ykpiv_state *state, CK_ULONG cert_id, CK_B
|
|||||||
return CKR_OK;
|
return CKR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
CK_RV COMMON_token_import_private_key(ykpiv_state *state, CK_BYTE key_id, CK_BYTE_PTR p, CK_BYTE_PTR q,
|
CK_RV COMMON_token_import_private_key(ykpiv_state *state, CK_BYTE key_id,
|
||||||
CK_BYTE_PTR dp, CK_BYTE_PTR dq, CK_BYTE_PTR qinv,
|
CK_BYTE_PTR p, CK_ULONG p_len,
|
||||||
CK_BYTE_PTR ec_data, CK_ULONG elem_len, CK_ULONG vendor_defined) {
|
CK_BYTE_PTR q, CK_ULONG q_len,
|
||||||
|
CK_BYTE_PTR dp, CK_ULONG dp_len,
|
||||||
|
CK_BYTE_PTR dq, CK_ULONG dq_len,
|
||||||
|
CK_BYTE_PTR qinv, CK_ULONG qinv_len,
|
||||||
|
CK_BYTE_PTR ec_data, CK_ULONG ec_data_len,
|
||||||
|
CK_ULONG vendor_defined) {
|
||||||
|
|
||||||
unsigned char key_data[1024];
|
CK_BYTE pin_policy;
|
||||||
unsigned char *in_ptr = key_data;
|
CK_BYTE touch_policy;
|
||||||
unsigned char templ[] = {0, YKPIV_INS_IMPORT_KEY, 0, key_id};
|
CK_BYTE algo;
|
||||||
unsigned char data[0xff];
|
ykpiv_rc rc;
|
||||||
unsigned long recv_len = sizeof(data);
|
|
||||||
int sw;
|
|
||||||
|
|
||||||
if (elem_len == 128) // TODO: add a flag to check algo type ?
|
if (p == NULL) {
|
||||||
templ[2] = YKPIV_ALGO_RSA2048;
|
if (ec_data_len == 32 || ec_data_len == 31)
|
||||||
else if (elem_len == 64)
|
algo = YKPIV_ALGO_ECCP256;
|
||||||
templ[2] = YKPIV_ALGO_RSA1024;
|
else
|
||||||
else if(elem_len == 32)
|
algo = YKPIV_ALGO_ECCP384;
|
||||||
templ[2] = YKPIV_ALGO_ECCP256;
|
|
||||||
|
|
||||||
if (templ[2] == YKPIV_ALGO_RSA1024 ||templ[2] == YKPIV_ALGO_RSA2048) {
|
|
||||||
*in_ptr++ = 0x01;
|
|
||||||
in_ptr += set_length(in_ptr, elem_len);
|
|
||||||
memcpy(in_ptr, p, (size_t)(elem_len));
|
|
||||||
in_ptr += elem_len;
|
|
||||||
|
|
||||||
*in_ptr++ = 0x02;
|
|
||||||
in_ptr += set_length(in_ptr, elem_len);
|
|
||||||
memcpy(in_ptr, q, (size_t)(elem_len));
|
|
||||||
in_ptr += elem_len;
|
|
||||||
|
|
||||||
*in_ptr++ = 0x03;
|
|
||||||
in_ptr += set_length(in_ptr, elem_len);
|
|
||||||
memcpy(in_ptr, dp, (size_t)(elem_len));
|
|
||||||
in_ptr += elem_len;
|
|
||||||
|
|
||||||
*in_ptr++ = 0x04;
|
|
||||||
in_ptr += set_length(in_ptr, elem_len);
|
|
||||||
memcpy(in_ptr, dq, (size_t)(elem_len));
|
|
||||||
in_ptr += elem_len;
|
|
||||||
|
|
||||||
*in_ptr++ = 0x05;
|
|
||||||
in_ptr += set_length(in_ptr, elem_len);
|
|
||||||
memcpy(in_ptr, qinv, (size_t)(elem_len));
|
|
||||||
in_ptr += elem_len;
|
|
||||||
}
|
}
|
||||||
else if (templ[2] == YKPIV_ALGO_ECCP256) {
|
else if (ec_data == NULL) {
|
||||||
*in_ptr++ = 0x06;
|
if (p_len == 64)
|
||||||
in_ptr += set_length(in_ptr, elem_len);
|
algo = YKPIV_ALGO_RSA1024;
|
||||||
memcpy(in_ptr, ec_data, (size_t)(elem_len));
|
else
|
||||||
in_ptr += elem_len;
|
algo = YKPIV_ALGO_RSA2048;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
// PIN policy and touch
|
|
||||||
if (vendor_defined != 0) {
|
|
||||||
if (vendor_defined & CKA_PIN_ONCE) {
|
|
||||||
*in_ptr++ = YKPIV_PINPOLICY_TAG;
|
|
||||||
*in_ptr++ = 0x01;
|
|
||||||
*in_ptr++ = YKPIV_PINPOLICY_ONCE;
|
|
||||||
}
|
|
||||||
else if (vendor_defined & CKA_PIN_ALWAYS) {
|
|
||||||
*in_ptr++ = YKPIV_PINPOLICY_TAG;
|
|
||||||
*in_ptr++ = 0x01;
|
|
||||||
*in_ptr++ = YKPIV_PINPOLICY_ALWAYS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vendor_defined & CKA_TOUCH_ALWAYS) {
|
|
||||||
*in_ptr++ = YKPIV_TOUCHPOLICY_TAG;
|
|
||||||
*in_ptr++ = 0x01;
|
|
||||||
*in_ptr++ = YKPIV_TOUCHPOLICY_ALWAYS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ykpiv_transfer_data(state, templ, key_data, in_ptr - key_data, data, &recv_len, &sw) != YKPIV_OK)
|
|
||||||
return CKR_FUNCTION_FAILED;
|
return CKR_FUNCTION_FAILED;
|
||||||
|
|
||||||
if (sw != 0x9000)
|
pin_policy = YKPIV_PINPOLICY_DEFAULT;
|
||||||
return CKR_DEVICE_ERROR;
|
touch_policy = YKPIV_TOUCHPOLICY_DEFAULT;
|
||||||
|
if (vendor_defined != 0) {
|
||||||
|
if (vendor_defined & CKA_PIN_ONCE) {
|
||||||
|
pin_policy = YKPIV_PINPOLICY_ONCE;
|
||||||
|
}
|
||||||
|
else if (vendor_defined & CKA_PIN_ALWAYS) {
|
||||||
|
pin_policy = YKPIV_PINPOLICY_ALWAYS;
|
||||||
|
}
|
||||||
|
else if (vendor_defined & CKA_PIN_NEVER) {
|
||||||
|
pin_policy = YKPIV_PINPOLICY_NEVER;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return CKR_ATTRIBUTE_VALUE_INVALID;
|
||||||
|
|
||||||
|
if (vendor_defined & CKA_TOUCH_ALWAYS) {
|
||||||
|
touch_policy = YKPIV_TOUCHPOLICY_ALWAYS;
|
||||||
|
}
|
||||||
|
else if (vendor_defined & CKA_TOUCH_NEVER) {
|
||||||
|
touch_policy = YKPIV_TOUCHPOLICY_NEVER;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return CKR_ATTRIBUTE_VALUE_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = ykpiv_import_private_key(state, key_id, algo,
|
||||||
|
p, p_len,
|
||||||
|
q, q_len,
|
||||||
|
dp, dp_len,
|
||||||
|
dq, dq_len,
|
||||||
|
qinv, qinv_len,
|
||||||
|
ec_data, ec_data_len,
|
||||||
|
pin_policy, touch_policy);
|
||||||
|
|
||||||
|
if (rc != YKPIV_OK)
|
||||||
|
return CKR_FUNCTION_FAILED;
|
||||||
|
|
||||||
return CKR_OK;
|
return CKR_OK;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CK_RV COMMON_token_delete_cert(ykpiv_state *state, CK_ULONG cert_id) {
|
CK_RV COMMON_token_delete_cert(ykpiv_state *state, CK_ULONG cert_id) {
|
||||||
@@ -287,6 +290,7 @@ token_vendor_t get_token_vendor(vendor_id_t vid) {
|
|||||||
v.token_import_cert = COMMON_token_import_cert;
|
v.token_import_cert = COMMON_token_import_cert;
|
||||||
v.token_import_private_key = COMMON_token_import_private_key;
|
v.token_import_private_key = COMMON_token_import_private_key;
|
||||||
v.token_delete_cert = COMMON_token_delete_cert;
|
v.token_delete_cert = COMMON_token_delete_cert;
|
||||||
|
v.token_change_pin = YUBICO_token_change_pin;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UNKNOWN:
|
case UNKNOWN:
|
||||||
|
|||||||
+11
-3
@@ -10,7 +10,7 @@ typedef CK_RV (*get_t_label_f)(CK_UTF8CHAR_PTR, CK_ULONG);
|
|||||||
typedef CK_RV (*get_t_manufacturer_f)(CK_UTF8CHAR_PTR, CK_ULONG);
|
typedef CK_RV (*get_t_manufacturer_f)(CK_UTF8CHAR_PTR, CK_ULONG);
|
||||||
typedef CK_RV (*get_t_model_f)(ykpiv_state *, CK_UTF8CHAR_PTR, CK_ULONG);
|
typedef CK_RV (*get_t_model_f)(ykpiv_state *, CK_UTF8CHAR_PTR, CK_ULONG);
|
||||||
typedef CK_RV (*get_t_flags_f)(CK_FLAGS_PTR);
|
typedef CK_RV (*get_t_flags_f)(CK_FLAGS_PTR);
|
||||||
typedef CK_RV (*get_t_version_f)(CK_UTF8CHAR_PTR, CK_ULONG, CK_VERSION_PTR);
|
typedef CK_RV (*get_t_version_f)(ykpiv_state *, CK_VERSION_PTR);
|
||||||
typedef CK_RV (*get_t_serial_f)(CK_CHAR_PTR, CK_ULONG);
|
typedef CK_RV (*get_t_serial_f)(CK_CHAR_PTR, CK_ULONG);
|
||||||
typedef CK_RV (*get_t_mechanisms_num_f)(CK_ULONG_PTR);
|
typedef CK_RV (*get_t_mechanisms_num_f)(CK_ULONG_PTR);
|
||||||
typedef CK_RV (*get_t_mechanism_list_f)(CK_MECHANISM_TYPE_PTR, CK_ULONG);
|
typedef CK_RV (*get_t_mechanism_list_f)(CK_MECHANISM_TYPE_PTR, CK_ULONG);
|
||||||
@@ -18,13 +18,20 @@ typedef CK_RV (*get_t_mechanism_info_f)(CK_MECHANISM_TYPE, CK_MECHANISM_INFO_PTR
|
|||||||
typedef CK_RV (*get_t_objects_num_f)(ykpiv_state *, CK_ULONG_PTR, CK_ULONG_PTR);
|
typedef CK_RV (*get_t_objects_num_f)(ykpiv_state *, CK_ULONG_PTR, CK_ULONG_PTR);
|
||||||
typedef CK_RV (*get_t_object_list_f)(ykpiv_state *, piv_obj_id_t *, CK_ULONG);
|
typedef CK_RV (*get_t_object_list_f)(ykpiv_state *, piv_obj_id_t *, CK_ULONG);
|
||||||
typedef CK_RV (*get_t_raw_certificate_f)(ykpiv_state *, piv_obj_id_t, CK_BYTE_PTR, CK_ULONG_PTR);
|
typedef CK_RV (*get_t_raw_certificate_f)(ykpiv_state *, piv_obj_id_t, CK_BYTE_PTR, CK_ULONG_PTR);
|
||||||
|
typedef CK_RV (*t_change_pin_f)(ykpiv_state *, CK_USER_TYPE, CK_UTF8CHAR_PTR, CK_ULONG, CK_UTF8CHAR_PTR, CK_ULONG);
|
||||||
|
|
||||||
// Common token functions below
|
// Common token functions below
|
||||||
typedef CK_RV (*t_login_f)(ykpiv_state *, CK_USER_TYPE, CK_UTF8CHAR_PTR, CK_ULONG);
|
typedef CK_RV (*t_login_f)(ykpiv_state *, CK_USER_TYPE, CK_UTF8CHAR_PTR, CK_ULONG);
|
||||||
typedef CK_RV (*t_generate_key_f)(ykpiv_state *, CK_BBOOL, CK_BYTE, CK_ULONG, CK_ULONG);
|
typedef CK_RV (*t_generate_key_f)(ykpiv_state *, CK_BBOOL, CK_BYTE, CK_ULONG, CK_ULONG);
|
||||||
typedef CK_RV (*t_import_cert_f)(ykpiv_state *, CK_ULONG, CK_BYTE_PTR);
|
typedef CK_RV (*t_import_cert_f)(ykpiv_state *, CK_ULONG, CK_BYTE_PTR);
|
||||||
typedef CK_RV (*t_import_private_key_f)(ykpiv_state *, CK_BYTE, CK_BYTE_PTR, CK_BYTE_PTR, CK_BYTE_PTR,
|
typedef CK_RV (*t_import_private_key_f)(ykpiv_state *, CK_BYTE,
|
||||||
CK_BYTE_PTR, CK_BYTE_PTR, CK_BYTE_PTR, CK_ULONG, CK_ULONG);
|
CK_BYTE_PTR, CK_ULONG,
|
||||||
|
CK_BYTE_PTR, CK_ULONG,
|
||||||
|
CK_BYTE_PTR, CK_ULONG,
|
||||||
|
CK_BYTE_PTR, CK_ULONG,
|
||||||
|
CK_BYTE_PTR, CK_ULONG,
|
||||||
|
CK_BYTE_PTR, CK_ULONG,
|
||||||
|
CK_ULONG);
|
||||||
typedef CK_RV (*t_delete_cert_f)(ykpiv_state *, CK_ULONG);
|
typedef CK_RV (*t_delete_cert_f)(ykpiv_state *, CK_ULONG);
|
||||||
|
|
||||||
// TODO: replace all the common calls with functions defined in .c that use libykpiv
|
// TODO: replace all the common calls with functions defined in .c that use libykpiv
|
||||||
@@ -47,6 +54,7 @@ typedef struct {
|
|||||||
t_import_cert_f token_import_cert;
|
t_import_cert_f token_import_cert;
|
||||||
t_import_private_key_f token_import_private_key;
|
t_import_private_key_f token_import_private_key;
|
||||||
t_delete_cert_f token_delete_cert;
|
t_delete_cert_f token_delete_cert;
|
||||||
|
t_change_pin_f token_change_pin;
|
||||||
} token_vendor_t;
|
} token_vendor_t;
|
||||||
|
|
||||||
token_vendor_t get_token_vendor(vendor_id_t vid);
|
token_vendor_t get_token_vendor(vendor_id_t vid);
|
||||||
|
|||||||
+25
-20
@@ -29,16 +29,16 @@ CK_RV parse_readers(ykpiv_state *state, const CK_BYTE_PTR readers, const CK_ULON
|
|||||||
|
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < len; i++)
|
||||||
if (readers[i] == '\0' && i != len - 1) {
|
if (readers[i] == '\0' && i != len - 1) {
|
||||||
slots[*n_slots].vid = get_vendor_id(p);
|
slots[*n_slots].vid = get_vendor_id((char *)p);
|
||||||
|
|
||||||
if (slots[*n_slots].vid == UNKNOWN) { // TODO: distinguish between tokenless and unsupported?
|
if (slots[*n_slots].vid == UNKNOWN) { // TODO: distinguish between tokenless and unsupported?
|
||||||
// Unknown slot, just save what info we have
|
// Unknown slot, just save what info we have
|
||||||
memset(&slots[*n_slots].info, 0, sizeof(CK_SLOT_INFO));
|
memset(&slots[*n_slots].info, 0, sizeof(CK_SLOT_INFO));
|
||||||
memset(slots[*n_slots].info.slotDescription, ' ', sizeof(slots[*n_slots].info.slotDescription));
|
memset(slots[*n_slots].info.slotDescription, ' ', sizeof(slots[*n_slots].info.slotDescription));
|
||||||
if (strlen(p) <= sizeof(slots[*n_slots].info.slotDescription))
|
if (strlen((char *)p) <= sizeof(slots[*n_slots].info.slotDescription))
|
||||||
strncpy(slots[*n_slots].info.slotDescription, p, strlen(p));
|
memcpy(slots[*n_slots].info.slotDescription, p, strlen((char *)p));
|
||||||
else
|
else
|
||||||
strncpy(slots[*n_slots].info.slotDescription, p, sizeof(slots[*n_slots].info.slotDescription));
|
memcpy(slots[*n_slots].info.slotDescription, p, sizeof(slots[*n_slots].info.slotDescription));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Supported slot
|
// Supported slot
|
||||||
@@ -49,7 +49,7 @@ CK_RV parse_readers(ykpiv_state *state, const CK_BYTE_PTR readers, const CK_ULON
|
|||||||
memset(slots[*n_slots].info.slotDescription, ' ', sizeof(slots[*n_slots].info.slotDescription));
|
memset(slots[*n_slots].info.slotDescription, ' ', sizeof(slots[*n_slots].info.slotDescription));
|
||||||
s = slots[*n_slots].info.slotDescription;
|
s = slots[*n_slots].info.slotDescription;
|
||||||
l = sizeof(slots[*n_slots].info.slotDescription);
|
l = sizeof(slots[*n_slots].info.slotDescription);
|
||||||
strncpy((char *)s, (char*)p, l);
|
memcpy((char *)s, (char*)p, l);
|
||||||
|
|
||||||
memset(slots[*n_slots].info.manufacturerID, ' ', sizeof(slots[*n_slots].info.manufacturerID));
|
memset(slots[*n_slots].info.manufacturerID, ' ', sizeof(slots[*n_slots].info.manufacturerID));
|
||||||
s = slots[*n_slots].info.manufacturerID;
|
s = slots[*n_slots].info.manufacturerID;
|
||||||
@@ -76,7 +76,7 @@ CK_RV parse_readers(ykpiv_state *state, const CK_BYTE_PTR readers, const CK_ULON
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
(*n_slots)++;
|
(*n_slots)++;
|
||||||
p += i + 1;
|
p = readers + i + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return CKR_OK;
|
return CKR_OK;
|
||||||
@@ -114,17 +114,23 @@ CK_RV create_token(ykpiv_state *state, CK_BYTE_PTR p, ykcs11_slot_t *slot) {
|
|||||||
|
|
||||||
if (ykpiv_connect(state, (char *)p) != YKPIV_OK)
|
if (ykpiv_connect(state, (char *)p) != YKPIV_OK)
|
||||||
return CKR_FUNCTION_FAILED;
|
return CKR_FUNCTION_FAILED;
|
||||||
|
|
||||||
memset(t_info->model, ' ', sizeof(t_info->model));
|
memset(t_info->model, ' ', sizeof(t_info->model));
|
||||||
if(token.get_token_model(state, t_info->model, sizeof(t_info->model)) != CKR_OK)
|
if(token.get_token_model(state, t_info->model, sizeof(t_info->model)) != CKR_OK) {
|
||||||
return CKR_FUNCTION_FAILED;
|
|
||||||
ykpiv_disconnect(state);
|
ykpiv_disconnect(state);
|
||||||
|
return CKR_FUNCTION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
memset(t_info->serialNumber, ' ', sizeof(t_info->serialNumber));
|
memset(t_info->serialNumber, ' ', sizeof(t_info->serialNumber));
|
||||||
if(token.get_token_serial(t_info->serialNumber, sizeof(t_info->serialNumber)) != CKR_OK)
|
if(token.get_token_serial(t_info->serialNumber, sizeof(t_info->serialNumber)) != CKR_OK) {
|
||||||
|
ykpiv_disconnect(state);
|
||||||
return CKR_FUNCTION_FAILED;
|
return CKR_FUNCTION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
if (token.get_token_flags(&t_info->flags) != CKR_OK)
|
if (token.get_token_flags(&t_info->flags) != CKR_OK) {
|
||||||
|
ykpiv_disconnect(state);
|
||||||
return CKR_FUNCTION_FAILED;
|
return CKR_FUNCTION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
t_info->ulMaxSessionCount = CK_UNAVAILABLE_INFORMATION;
|
t_info->ulMaxSessionCount = CK_UNAVAILABLE_INFORMATION;
|
||||||
|
|
||||||
@@ -146,20 +152,19 @@ CK_RV create_token(ykpiv_state *state, CK_BYTE_PTR p, ykcs11_slot_t *slot) {
|
|||||||
|
|
||||||
t_info->ulFreePrivateMemory = CK_UNAVAILABLE_INFORMATION;
|
t_info->ulFreePrivateMemory = CK_UNAVAILABLE_INFORMATION;
|
||||||
|
|
||||||
//ykpiv_get_version(piv_state, buf, sizeof(buf));
|
// Ignore hardware version, report firmware version
|
||||||
//if (token_vendor.get_token_version(buf, strlen(buf), &ver) != CKR_OK) // TODO: fix this
|
if (token.get_token_version(state, &t_info->firmwareVersion) != CKR_OK) {
|
||||||
// return CKR_FUNCTION_FAILED;
|
ykpiv_disconnect(state);
|
||||||
|
return CKR_FUNCTION_FAILED;
|
||||||
//t_info->hardwareVersion = ver; // version number of hardware // TODO: fix
|
}
|
||||||
|
|
||||||
//t_info->firmwareVersion = ver; // version number of firmware // TODO: fix
|
|
||||||
|
|
||||||
memset(t_info->utcTime, ' ', sizeof(t_info->utcTime)); // No clock present, clear
|
memset(t_info->utcTime, ' ', sizeof(t_info->utcTime)); // No clock present, clear
|
||||||
|
|
||||||
// TODO: also get token objects here? (and destroy on failure)
|
|
||||||
slot->token->objects = NULL;
|
slot->token->objects = NULL;
|
||||||
slot->token->n_objects = 0;
|
slot->token->n_objects = 0;
|
||||||
|
|
||||||
|
ykpiv_disconnect(state);
|
||||||
|
|
||||||
return CKR_OK;
|
return CKR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,8 +175,8 @@ void destroy_token(ykcs11_slot_t *slot) {
|
|||||||
|
|
||||||
CK_BBOOL is_valid_key_id(CK_BYTE id) {
|
CK_BBOOL is_valid_key_id(CK_BYTE id) {
|
||||||
|
|
||||||
// Valid ids are 0, 1, 2, 3
|
// Valid ids are [0, 23] aka [0x00, 0x17]
|
||||||
if (id > 3)
|
if (id > 23)
|
||||||
return CK_FALSE;
|
return CK_FALSE;
|
||||||
|
|
||||||
return CK_TRUE;
|
return CK_TRUE;
|
||||||
|
|||||||
+78
-22
@@ -51,7 +51,7 @@ CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
CK_BYTE readers[2048];
|
CK_BYTE readers[2048];
|
||||||
CK_ULONG len = sizeof(readers);
|
size_t len = sizeof(readers);
|
||||||
|
|
||||||
DIN;
|
DIN;
|
||||||
|
|
||||||
@@ -114,7 +114,7 @@ CK_DEFINE_FUNCTION(CK_RV, C_GetInfo)(
|
|||||||
CK_INFO_PTR pInfo
|
CK_INFO_PTR pInfo
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
CK_VERSION ver = {YKCS11_VERSION_MAJOR, (YKCS11_VERSION_MINOR * 100) + YKCS11_VERSION_PATCH};
|
CK_VERSION ver = {YKCS11_VERSION_MAJOR, (YKCS11_VERSION_MINOR * 10) + YKCS11_VERSION_PATCH};
|
||||||
|
|
||||||
DIN;
|
DIN;
|
||||||
|
|
||||||
@@ -421,7 +421,36 @@ CK_DEFINE_FUNCTION(CK_RV, C_SetPIN)(
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
DIN;
|
DIN;
|
||||||
DBG("TODO!!!");
|
CK_RV rv;
|
||||||
|
token_vendor_t token;
|
||||||
|
|
||||||
|
if (piv_state == NULL) {
|
||||||
|
DBG("libykpiv is not initialized or already finalized");
|
||||||
|
return CKR_CRYPTOKI_NOT_INITIALIZED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session.handle == CK_INVALID_HANDLE) {
|
||||||
|
DBG("User called SetPIN on closed session");
|
||||||
|
return CKR_SESSION_CLOSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hSession != YKCS11_SESSION_ID) {
|
||||||
|
DBG("Unknown session %lu", hSession);
|
||||||
|
return CKR_SESSION_HANDLE_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
CK_USER_TYPE user_type = CKU_USER;
|
||||||
|
if (session.info.state == CKS_RW_SO_FUNCTIONS) {
|
||||||
|
user_type = CKU_SO;
|
||||||
|
}
|
||||||
|
|
||||||
|
token = get_token_vendor(session.slot->token->vid);
|
||||||
|
rv = token.token_change_pin(piv_state, user_type, pOldPin, ulOldLen, pNewPin, ulNewLen);
|
||||||
|
if (rv != CKR_OK) {
|
||||||
|
DBG("Pin change failed %lx", rv);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
DOUT;
|
DOUT;
|
||||||
return CKR_OK;
|
return CKR_OK;
|
||||||
}
|
}
|
||||||
@@ -438,7 +467,7 @@ CK_DEFINE_FUNCTION(CK_RV, C_OpenSession)(
|
|||||||
CK_RV rv;
|
CK_RV rv;
|
||||||
piv_obj_id_t *cert_ids;
|
piv_obj_id_t *cert_ids;
|
||||||
CK_ULONG i;
|
CK_ULONG i;
|
||||||
CK_BYTE cert_data[2100]; // Max cert value for ykpiv
|
CK_BYTE cert_data[3072]; // Max cert value for ykpiv
|
||||||
CK_ULONG cert_len = sizeof(cert_data);
|
CK_ULONG cert_len = sizeof(cert_data);
|
||||||
|
|
||||||
DIN; // TODO: pApplication and Notify
|
DIN; // TODO: pApplication and Notify
|
||||||
@@ -479,7 +508,7 @@ CK_DEFINE_FUNCTION(CK_RV, C_OpenSession)(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((flags & CKF_SERIAL_SESSION) == 0) {
|
if ((flags & CKF_SERIAL_SESSION) == 0) {
|
||||||
DBG("Open session called without CKF_SERIAL_SESSION set"); // Reuired by spes
|
DBG("Open session called without CKF_SERIAL_SESSION set"); // Required by specs
|
||||||
return CKR_SESSION_PARALLEL_NOT_SUPPORTED;
|
return CKR_SESSION_PARALLEL_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -507,6 +536,7 @@ CK_DEFINE_FUNCTION(CK_RV, C_OpenSession)(
|
|||||||
session.info.state = CKS_RO_PUBLIC_SESSION; // Nobody has logged in, default RW session
|
session.info.state = CKS_RO_PUBLIC_SESSION; // Nobody has logged in, default RW session
|
||||||
}
|
}
|
||||||
|
|
||||||
|
session.info.slotID = slotID;
|
||||||
session.info.flags = flags;
|
session.info.flags = flags;
|
||||||
session.info.ulDeviceError = 0;
|
session.info.ulDeviceError = 0;
|
||||||
|
|
||||||
@@ -731,8 +761,8 @@ CK_DEFINE_FUNCTION(CK_RV, C_Login)(
|
|||||||
return CKR_SESSION_HANDLE_INVALID;
|
return CKR_SESSION_HANDLE_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((session.info.flags & CKF_RW_SESSION) == 0) { // TODO: make macros for these?
|
if (userType == CKU_SO && (session.info.flags & CKF_RW_SESSION) == 0) { // TODO: make macros for these?
|
||||||
DBG("Tried to log-in to a read-only session");
|
DBG("Tried to log-in SO user to a read-only session");
|
||||||
return CKR_SESSION_READ_ONLY_EXISTS;
|
return CKR_SESSION_READ_ONLY_EXISTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -858,6 +888,13 @@ CK_DEFINE_FUNCTION(CK_RV, C_CreateObject)(
|
|||||||
CK_BYTE_PTR dp;
|
CK_BYTE_PTR dp;
|
||||||
CK_BYTE_PTR dq;
|
CK_BYTE_PTR dq;
|
||||||
CK_BYTE_PTR qinv;
|
CK_BYTE_PTR qinv;
|
||||||
|
CK_ULONG p_len;
|
||||||
|
CK_ULONG q_len;
|
||||||
|
CK_ULONG dp_len;
|
||||||
|
CK_ULONG dq_len;
|
||||||
|
CK_ULONG qinv_len;
|
||||||
|
CK_BYTE_PTR ec_data;
|
||||||
|
CK_ULONG ec_data_len;
|
||||||
CK_ULONG vendor_defined;
|
CK_ULONG vendor_defined;
|
||||||
token_vendor_t token;
|
token_vendor_t token;
|
||||||
CK_BBOOL is_new;
|
CK_BBOOL is_new;
|
||||||
@@ -972,6 +1009,7 @@ CK_DEFINE_FUNCTION(CK_RV, C_CreateObject)(
|
|||||||
DBG("Unable to store certificate data");
|
DBG("Unable to store certificate data");
|
||||||
return CKR_FUNCTION_FAILED;
|
return CKR_FUNCTION_FAILED;
|
||||||
}
|
}
|
||||||
|
*phObject = cert_id;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -980,11 +1018,17 @@ CK_DEFINE_FUNCTION(CK_RV, C_CreateObject)(
|
|||||||
|
|
||||||
// Try to parse the key as EC
|
// Try to parse the key as EC
|
||||||
is_rsa = CK_FALSE;
|
is_rsa = CK_FALSE;
|
||||||
rv = check_create_ec_key(pTemplate, ulCount, &id, &value, &value_len, &vendor_defined);
|
rv = check_create_ec_key(pTemplate, ulCount, &id, &ec_data, &ec_data_len, &vendor_defined);
|
||||||
if (rv != CKR_OK) {
|
if (rv != CKR_OK) {
|
||||||
// Try to parse the key as RSA
|
// Try to parse the key as RSA
|
||||||
is_rsa = CK_TRUE;
|
is_rsa = CK_TRUE;
|
||||||
rv = check_create_rsa_key(pTemplate, ulCount, &id, &p, &q, &dp, &dq, &qinv, &value_len, &vendor_defined);
|
rv = check_create_rsa_key(pTemplate, ulCount, &id,
|
||||||
|
&p, &p_len,
|
||||||
|
&q, &q_len,
|
||||||
|
&dp, &dp_len,
|
||||||
|
&dq, &dq_len,
|
||||||
|
&qinv, &qinv_len,
|
||||||
|
&vendor_defined);
|
||||||
if (rv != CKR_OK) {
|
if (rv != CKR_OK) {
|
||||||
DBG("Private key template not valid");
|
DBG("Private key template not valid");
|
||||||
return rv;
|
return rv;
|
||||||
@@ -997,9 +1041,14 @@ CK_DEFINE_FUNCTION(CK_RV, C_CreateObject)(
|
|||||||
|
|
||||||
if (is_rsa == CK_TRUE) {
|
if (is_rsa == CK_TRUE) {
|
||||||
DBG("Key is RSA");
|
DBG("Key is RSA");
|
||||||
rv = token.token_import_private_key(piv_state, piv_2_ykpiv(object), p, q, dp, dq, qinv,
|
rv = token.token_import_private_key(piv_state, piv_2_ykpiv(object),
|
||||||
NULL,
|
p, p_len,
|
||||||
value_len, vendor_defined);
|
q, q_len,
|
||||||
|
dp, dp_len,
|
||||||
|
dq, dq_len,
|
||||||
|
qinv, qinv_len,
|
||||||
|
NULL, 0,
|
||||||
|
vendor_defined);
|
||||||
if (rv != CKR_OK) {
|
if (rv != CKR_OK) {
|
||||||
DBG("Unable to import RSA private key");
|
DBG("Unable to import RSA private key");
|
||||||
return rv;
|
return rv;
|
||||||
@@ -1007,14 +1056,22 @@ CK_DEFINE_FUNCTION(CK_RV, C_CreateObject)(
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DBG("Key is ECDSA");
|
DBG("Key is ECDSA");
|
||||||
rv = token.token_import_private_key(piv_state, piv_2_ykpiv(object), NULL, NULL, NULL, NULL, NULL,
|
rv = token.token_import_private_key(piv_state, piv_2_ykpiv(object),
|
||||||
value,
|
NULL, 0,
|
||||||
value_len, vendor_defined);
|
NULL, 0,
|
||||||
|
NULL, 0,
|
||||||
|
NULL, 0,
|
||||||
|
NULL, 0,
|
||||||
|
ec_data, ec_data_len,
|
||||||
|
vendor_defined);
|
||||||
if (rv != CKR_OK) {
|
if (rv != CKR_OK) {
|
||||||
DBG("Unable to import ECDSA private key");
|
DBG("Unable to import ECDSA private key");
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*phObject = PIV_PVTK_OBJ_PIV_AUTH + id;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -1627,8 +1684,7 @@ CK_DEFINE_FUNCTION(CK_RV, C_SignInit)(
|
|||||||
return CKR_OPERATION_ACTIVE;
|
return CKR_OPERATION_ACTIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pMechanism == NULL_PTR ||
|
if (pMechanism == NULL_PTR)
|
||||||
hKey == NULL_PTR)
|
|
||||||
return CKR_ARGUMENTS_BAD;
|
return CKR_ARGUMENTS_BAD;
|
||||||
|
|
||||||
DBG("Trying to sign some data with mechanism %lu and key %lu", pMechanism->mechanism, hKey);
|
DBG("Trying to sign some data with mechanism %lu and key %lu", pMechanism->mechanism, hKey);
|
||||||
@@ -1785,7 +1841,7 @@ CK_DEFINE_FUNCTION(CK_RV, C_Sign)(
|
|||||||
|
|
||||||
DBG("Sending %lu bytes to sign", ulDataLen);
|
DBG("Sending %lu bytes to sign", ulDataLen);
|
||||||
#if YKCS11_DBG == 1
|
#if YKCS11_DBG == 1
|
||||||
dump_hex(pData, ulDataLen, stderr, CK_TRUE);
|
dump_data(pData, ulDataLen, stderr, CK_TRUE, format_arg_hex);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (is_hashed_mechanism(op_info.mechanism.mechanism) == CK_TRUE) {
|
if (is_hashed_mechanism(op_info.mechanism.mechanism) == CK_TRUE) {
|
||||||
@@ -1827,7 +1883,7 @@ CK_DEFINE_FUNCTION(CK_RV, C_Sign)(
|
|||||||
DBG("Using key %lx", op_info.op.sign.key_id);
|
DBG("Using key %lx", op_info.op.sign.key_id);
|
||||||
DBG("After padding and transformation there are %lu bytes", op_info.buf_len);
|
DBG("After padding and transformation there are %lu bytes", op_info.buf_len);
|
||||||
#if YKCS11_DBG == 1
|
#if YKCS11_DBG == 1
|
||||||
dump_hex(op_info.buf, op_info.buf_len, stderr, CK_TRUE);
|
dump_data(op_info.buf, op_info.buf_len, stderr, CK_TRUE, format_arg_hex);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
*pulSignatureLen = sizeof(op_info.buf);
|
*pulSignatureLen = sizeof(op_info.buf);
|
||||||
@@ -1848,7 +1904,7 @@ CK_DEFINE_FUNCTION(CK_RV, C_Sign)(
|
|||||||
|
|
||||||
DBG("Got %lu bytes back", *pulSignatureLen);
|
DBG("Got %lu bytes back", *pulSignatureLen);
|
||||||
#if YKCS11_DBG == 1
|
#if YKCS11_DBG == 1
|
||||||
dump_hex(pSignature, *pulSignatureLen, stderr, CK_TRUE);
|
dump_data(pSignature, *pulSignatureLen, stderr, CK_TRUE, format_arg_hex);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!is_RSA_mechanism(op_info.mechanism.mechanism)) {
|
if (!is_RSA_mechanism(op_info.mechanism.mechanism)) {
|
||||||
@@ -1858,7 +1914,7 @@ CK_DEFINE_FUNCTION(CK_RV, C_Sign)(
|
|||||||
|
|
||||||
DBG("After removing DER encoding %lu", *pulSignatureLen);
|
DBG("After removing DER encoding %lu", *pulSignatureLen);
|
||||||
#if YKCS11_DBG == 1
|
#if YKCS11_DBG == 1
|
||||||
dump_hex(pSignature, *pulSignatureLen, stderr, CK_TRUE);
|
dump_data(pSignature, *pulSignatureLen, stderr, CK_TRUE, format_arg_hex);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2090,7 +2146,7 @@ CK_DEFINE_FUNCTION(CK_RV, C_GenerateKeyPair)(
|
|||||||
CK_ULONG pvtk_id;
|
CK_ULONG pvtk_id;
|
||||||
CK_ULONG pubk_id;
|
CK_ULONG pubk_id;
|
||||||
piv_obj_id_t *obj_ptr;
|
piv_obj_id_t *obj_ptr;
|
||||||
CK_BYTE cert_data[2100];
|
CK_BYTE cert_data[3072];
|
||||||
CK_ULONG cert_len;
|
CK_ULONG cert_len;
|
||||||
|
|
||||||
DIN;
|
DIN;
|
||||||
|
|||||||
+89
-50
@@ -66,9 +66,29 @@ static const CK_MECHANISM_INFO token_mechanism_infos[] = { // KEEP ALIGNED WITH
|
|||||||
|
|
||||||
static const piv_obj_id_t token_objects[] = { // TODO: is there a way to get this from the token?
|
static const piv_obj_id_t token_objects[] = { // TODO: is there a way to get this from the token?
|
||||||
PIV_DATA_OBJ_X509_PIV_AUTH, // PIV authentication
|
PIV_DATA_OBJ_X509_PIV_AUTH, // PIV authentication
|
||||||
PIV_DATA_OBJ_X509_CARD_AUTH, // Certificate for card authentication
|
PIV_DATA_OBJ_X509_CARD_AUTH, // card authentication
|
||||||
PIV_DATA_OBJ_X509_DS, // Certificate for digital signature
|
PIV_DATA_OBJ_X509_DS, // digital signature
|
||||||
PIV_DATA_OBJ_X509_KM, // Certificate for key management
|
PIV_DATA_OBJ_X509_KM, // key management
|
||||||
|
PIV_DATA_OBJ_X509_RETIRED1, // Retired key 1
|
||||||
|
PIV_DATA_OBJ_X509_RETIRED2, // Retired key 2
|
||||||
|
PIV_DATA_OBJ_X509_RETIRED3, // Retired key 3
|
||||||
|
PIV_DATA_OBJ_X509_RETIRED4, // Retired key 4
|
||||||
|
PIV_DATA_OBJ_X509_RETIRED5, // Retired key 5
|
||||||
|
PIV_DATA_OBJ_X509_RETIRED6, // Retired key 6
|
||||||
|
PIV_DATA_OBJ_X509_RETIRED7, // Retired key 7
|
||||||
|
PIV_DATA_OBJ_X509_RETIRED8, // Retired key 8
|
||||||
|
PIV_DATA_OBJ_X509_RETIRED9, // Retired key 9
|
||||||
|
PIV_DATA_OBJ_X509_RETIRED10, // Retired key 10
|
||||||
|
PIV_DATA_OBJ_X509_RETIRED11, // Retired key 11
|
||||||
|
PIV_DATA_OBJ_X509_RETIRED12, // Retired key 12
|
||||||
|
PIV_DATA_OBJ_X509_RETIRED13, // Retired key 13
|
||||||
|
PIV_DATA_OBJ_X509_RETIRED14, // Retired key 14
|
||||||
|
PIV_DATA_OBJ_X509_RETIRED15, // Retired key 15
|
||||||
|
PIV_DATA_OBJ_X509_RETIRED16, // Retired key 16
|
||||||
|
PIV_DATA_OBJ_X509_RETIRED17, // Retired key 17
|
||||||
|
PIV_DATA_OBJ_X509_RETIRED18, // Retired key 18
|
||||||
|
PIV_DATA_OBJ_X509_RETIRED19, // Retired key 19
|
||||||
|
PIV_DATA_OBJ_X509_RETIRED20, // Retired key 20
|
||||||
PIV_DATA_OBJ_CCC, // Card capability container
|
PIV_DATA_OBJ_CCC, // Card capability container
|
||||||
PIV_DATA_OBJ_CHUI, // Cardholder unique id
|
PIV_DATA_OBJ_CHUI, // Cardholder unique id
|
||||||
PIV_DATA_OBJ_CHF, // Cardholder fingerprints
|
PIV_DATA_OBJ_CHF, // Cardholder fingerprints
|
||||||
@@ -77,32 +97,13 @@ static const piv_obj_id_t token_objects[] = { // TODO: is there a way to get thi
|
|||||||
//PIV_DATA_OBJ_PI, // Cardholder printed information
|
//PIV_DATA_OBJ_PI, // Cardholder printed information
|
||||||
//PIV_DATA_OBJ_DISCOVERY, // Discovery object
|
//PIV_DATA_OBJ_DISCOVERY, // Discovery object
|
||||||
//PIV_DATA_OBJ_HISTORY, // History object
|
//PIV_DATA_OBJ_HISTORY, // History object
|
||||||
/* PIV_DATA_OBJ_RETIRED_X509_1, // Retired certificate for KM 1
|
|
||||||
PIV_DATA_OBJ_RETIRED_X509_2, // Retired certificate for KM 2
|
|
||||||
PIV_DATA_OBJ_RETIRED_X509_3, // Retired certificate for KM 3
|
|
||||||
PIV_DATA_OBJ_RETIRED_X509_4, // Retired certificate for KM 4
|
|
||||||
PIV_DATA_OBJ_RETIRED_X509_5, // Retired certificate for KM 5
|
|
||||||
PIV_DATA_OBJ_RETIRED_X509_6, // Retired certificate for KM 6
|
|
||||||
PIV_DATA_OBJ_RETIRED_X509_7, // Retired certificate for KM 7
|
|
||||||
PIV_DATA_OBJ_RETIRED_X509_8, // Retired certificate for KM 8
|
|
||||||
PIV_DATA_OBJ_RETIRED_X509_9, // Retired certificate for KM 9
|
|
||||||
PIV_DATA_OBJ_RETIRED_X509_10, // Retired certificate for KM 10
|
|
||||||
PIV_DATA_OBJ_RETIRED_X509_11, // Retired certificate for KM 11
|
|
||||||
PIV_DATA_OBJ_RETIRED_X509_12, // Retired certificate for KM 12
|
|
||||||
PIV_DATA_OBJ_RETIRED_X509_13, // Retired certificate for KM 13
|
|
||||||
PIV_DATA_OBJ_RETIRED_X509_14, // Retired certificate for KM 14
|
|
||||||
PIV_DATA_OBJ_RETIRED_X509_15, // Retired certificate for KM 15
|
|
||||||
PIV_DATA_OBJ_RETIRED_X509_16, // Retired certificate for KM 16
|
|
||||||
PIV_DATA_OBJ_RETIRED_X509_17, // Retired certificate for KM 17
|
|
||||||
PIV_DATA_OBJ_RETIRED_X509_18, // Retired certificate for KM 18
|
|
||||||
PIV_DATA_OBJ_RETIRED_X509_19, // Retired certificate for KM 19
|
|
||||||
PIV_DATA_OBJ_RETIRED_X509_20, // Retired certificate for KM 20*/
|
|
||||||
//PIV_DATA_OBJ_IRIS_IMAGE, // Cardholder iris images
|
//PIV_DATA_OBJ_IRIS_IMAGE, // Cardholder iris images
|
||||||
//PIV_DATA_OBJ_BITGT, // Biometric information templates group template
|
//PIV_DATA_OBJ_BITGT, // Biometric information templates group template
|
||||||
//PIV_DATA_OBJ_SM_SIGNER, // Secure messaging signer
|
//PIV_DATA_OBJ_SM_SIGNER, // Secure messaging signer
|
||||||
//PIV_DATA_OBJ_PC_REF_DATA, // Pairing code reference data
|
//PIV_DATA_OBJ_PC_REF_DATA, // Pairing code reference data
|
||||||
};
|
};
|
||||||
static const CK_ULONG token_objects_num = sizeof(token_objects) / sizeof(piv_obj_id_t);
|
static const CK_ULONG neo_token_objects_num = sizeof(token_objects) / sizeof(piv_obj_id_t) - 20;
|
||||||
|
static const CK_ULONG yk4_token_objects_num = sizeof(token_objects) / sizeof(piv_obj_id_t);
|
||||||
|
|
||||||
CK_RV YUBICO_get_token_label(CK_UTF8CHAR_PTR str, CK_ULONG len) {
|
CK_RV YUBICO_get_token_label(CK_UTF8CHAR_PTR str, CK_ULONG len) {
|
||||||
|
|
||||||
@@ -152,32 +153,18 @@ CK_RV YUBICO_get_token_flags(CK_FLAGS_PTR flags) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CK_RV YUBICO_get_token_version(CK_UTF8CHAR_PTR v_str, CK_ULONG len, CK_VERSION_PTR version) {
|
CK_RV YUBICO_get_token_version(ykpiv_state *state, CK_VERSION_PTR version) {
|
||||||
|
|
||||||
CK_VERSION v = {0, 0};
|
char buf[16];
|
||||||
unsigned int i = 0;
|
|
||||||
|
|
||||||
while (i < len && v_str[i] != '.') {
|
if (version == NULL)
|
||||||
v.major *= 10;
|
return CKR_ARGUMENTS_BAD;
|
||||||
v.major += v_str[i++] - '0';
|
|
||||||
}
|
|
||||||
|
|
||||||
i++;
|
if (ykpiv_get_version(state, buf, sizeof(buf)) != YKPIV_OK)
|
||||||
|
return CKR_FUNCTION_FAILED;
|
||||||
|
|
||||||
while (i < len && v_str[i] != '.') {
|
version->major = (buf[0] - '0');
|
||||||
v.minor *= 10;
|
version->minor = (buf[2] - '0') * 100 + (buf[4] - '0');
|
||||||
v.minor += v_str[i++] - '0';
|
|
||||||
}
|
|
||||||
|
|
||||||
i++;
|
|
||||||
|
|
||||||
while (i < len && v_str[i] != '.') {
|
|
||||||
v.minor *= 10;
|
|
||||||
v.minor += v_str[i++] - '0';
|
|
||||||
}
|
|
||||||
|
|
||||||
version->major = v.major;
|
|
||||||
version->minor = v.minor;
|
|
||||||
|
|
||||||
return CKR_OK;
|
return CKR_OK;
|
||||||
}
|
}
|
||||||
@@ -227,11 +214,14 @@ static CK_RV get_objects(ykpiv_state *state, CK_BBOOL num_only,
|
|||||||
piv_obj_id_t *obj, CK_ULONG_PTR len, CK_ULONG_PTR num_certs) {
|
piv_obj_id_t *obj, CK_ULONG_PTR len, CK_ULONG_PTR num_certs) {
|
||||||
CK_BYTE buf[2048];
|
CK_BYTE buf[2048];
|
||||||
CK_ULONG buf_len;
|
CK_ULONG buf_len;
|
||||||
|
CK_BYTE major;
|
||||||
|
CK_ULONG i;
|
||||||
|
|
||||||
piv_obj_id_t certs[4]; // TODO: this can be > 4 if there are retired keys
|
piv_obj_id_t certs[24];
|
||||||
piv_obj_id_t pvtkeys[4];
|
piv_obj_id_t pvtkeys[24];
|
||||||
piv_obj_id_t pubkeys[4];
|
piv_obj_id_t pubkeys[24];
|
||||||
CK_ULONG n_cert = 0;
|
CK_ULONG n_cert = 0;
|
||||||
|
CK_ULONG token_objects_num = neo_token_objects_num;
|
||||||
|
|
||||||
if (state == NULL || len == NULL_PTR)
|
if (state == NULL || len == NULL_PTR)
|
||||||
return CKR_ARGUMENTS_BAD;
|
return CKR_ARGUMENTS_BAD;
|
||||||
@@ -239,6 +229,11 @@ static CK_RV get_objects(ykpiv_state *state, CK_BBOOL num_only,
|
|||||||
if (num_only == CK_FALSE && obj == NULL)
|
if (num_only == CK_FALSE && obj == NULL)
|
||||||
return CKR_ARGUMENTS_BAD;
|
return CKR_ARGUMENTS_BAD;
|
||||||
|
|
||||||
|
if (ykpiv_get_version(state, (char *) buf, sizeof(buf)) != YKPIV_OK)
|
||||||
|
return CKR_FUNCTION_FAILED;
|
||||||
|
|
||||||
|
major = buf[0] - '0';
|
||||||
|
|
||||||
buf_len = sizeof(buf);
|
buf_len = sizeof(buf);
|
||||||
if (ykpiv_fetch_object(state, YKPIV_OBJ_AUTHENTICATION, buf, &buf_len) == YKPIV_OK) {
|
if (ykpiv_fetch_object(state, YKPIV_OBJ_AUTHENTICATION, buf, &buf_len) == YKPIV_OK) {
|
||||||
certs[n_cert] = PIV_CERT_OBJ_X509_PIV_AUTH;
|
certs[n_cert] = PIV_CERT_OBJ_X509_PIV_AUTH;
|
||||||
@@ -275,6 +270,20 @@ static CK_RV get_objects(ykpiv_state *state, CK_BBOOL num_only,
|
|||||||
DBG("Found KMK cert (9d)");
|
DBG("Found KMK cert (9d)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (major >= 4) {
|
||||||
|
for (i = 0; i < 20; i++) {
|
||||||
|
buf_len = sizeof(buf);
|
||||||
|
if (ykpiv_fetch_object(state, YKPIV_OBJ_RETIRED1 + i, buf, &buf_len) == YKPIV_OK) {
|
||||||
|
certs[n_cert] = PIV_CERT_OBJ_X509_RETIRED1 + i;
|
||||||
|
pvtkeys[n_cert] = PIV_PVTK_OBJ_RETIRED1 + i;
|
||||||
|
pubkeys[n_cert] = PIV_PUBK_OBJ_RETIRED1 + i;
|
||||||
|
n_cert++;
|
||||||
|
DBG("Found RETIRED cert (%lx)", 0x82 + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
token_objects_num = yk4_token_objects_num;
|
||||||
|
}
|
||||||
|
|
||||||
DBG("The total number of objects for this token is %lu", (n_cert * 3) + token_objects_num);
|
DBG("The total number of objects for this token is %lu", (n_cert * 3) + token_objects_num);
|
||||||
|
|
||||||
if (num_only == CK_TRUE) {
|
if (num_only == CK_TRUE) {
|
||||||
@@ -289,8 +298,16 @@ static CK_RV get_objects(ykpiv_state *state, CK_BBOOL num_only,
|
|||||||
if (*len < (n_cert * 3) + token_objects_num)
|
if (*len < (n_cert * 3) + token_objects_num)
|
||||||
return CKR_BUFFER_TOO_SMALL;
|
return CKR_BUFFER_TOO_SMALL;
|
||||||
|
|
||||||
// Copy mandatory data objects
|
// Copy data objects
|
||||||
|
if (major >= 4) {
|
||||||
|
// YK4: just copy all the objects
|
||||||
memcpy(obj, token_objects, token_objects_num * sizeof(piv_obj_id_t));
|
memcpy(obj, token_objects, token_objects_num * sizeof(piv_obj_id_t));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// NEO: remove retired keys
|
||||||
|
memcpy(obj, token_objects, 4 * sizeof(piv_obj_id_t));
|
||||||
|
memcpy(obj + 4, token_objects + 24, (neo_token_objects_num - 4) * sizeof(piv_obj_id_t));
|
||||||
|
}
|
||||||
|
|
||||||
// Copy certificates
|
// Copy certificates
|
||||||
if (n_cert > 0) {
|
if (n_cert > 0) {
|
||||||
@@ -317,3 +334,25 @@ CK_RV YUBICO_get_token_raw_certificate(ykpiv_state *state, piv_obj_id_t obj, CK_
|
|||||||
|
|
||||||
return CKR_OK;
|
return CKR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CK_RV YUBICO_token_change_pin(ykpiv_state *state, CK_USER_TYPE user_type, CK_UTF8CHAR_PTR pOldPin, CK_ULONG ulOldLen, CK_UTF8CHAR_PTR pNewPin, CK_ULONG ulNewLen) {
|
||||||
|
int tries;
|
||||||
|
ykpiv_rc res;
|
||||||
|
if (user_type != CKU_USER) {
|
||||||
|
DBG("TODO implement other users pin change");
|
||||||
|
return CKR_FUNCTION_FAILED;
|
||||||
|
}
|
||||||
|
res = ykpiv_change_pin(state, pOldPin, ulOldLen, pNewPin, ulNewLen, &tries);
|
||||||
|
switch (res) {
|
||||||
|
case YKPIV_OK:
|
||||||
|
return CKR_OK;
|
||||||
|
case YKPIV_SIZE_ERROR:
|
||||||
|
return CKR_PIN_LEN_RANGE;
|
||||||
|
case YKPIV_WRONG_PIN:
|
||||||
|
return CKR_PIN_INCORRECT;
|
||||||
|
case YKPIV_PIN_LOCKED:
|
||||||
|
return CKR_PIN_LOCKED;
|
||||||
|
default:
|
||||||
|
return CKR_FUNCTION_FAILED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,12 +10,14 @@ CK_RV YUBICO_get_token_manufacturer(CK_UTF8CHAR_PTR str, CK_ULONG len);
|
|||||||
CK_RV YUBICO_get_token_model(ykpiv_state *state, CK_UTF8CHAR_PTR str, CK_ULONG len);
|
CK_RV YUBICO_get_token_model(ykpiv_state *state, CK_UTF8CHAR_PTR str, CK_ULONG len);
|
||||||
CK_RV YUBICO_get_token_flags(CK_FLAGS_PTR flags);
|
CK_RV YUBICO_get_token_flags(CK_FLAGS_PTR flags);
|
||||||
CK_RV YUBICO_get_token_serial(CK_CHAR_PTR str, CK_ULONG len);
|
CK_RV YUBICO_get_token_serial(CK_CHAR_PTR str, CK_ULONG len);
|
||||||
CK_RV YUBICO_get_token_version(CK_UTF8CHAR_PTR v_str, CK_ULONG v_str_len, CK_VERSION_PTR version);
|
CK_RV YUBICO_get_token_version(ykpiv_state *state, CK_VERSION_PTR version);
|
||||||
CK_RV YUBICO_get_token_mechanisms_num(CK_ULONG_PTR num);
|
CK_RV YUBICO_get_token_mechanisms_num(CK_ULONG_PTR num);
|
||||||
CK_RV YUBICO_get_token_mechanism_list(CK_MECHANISM_TYPE_PTR mec, CK_ULONG num);
|
CK_RV YUBICO_get_token_mechanism_list(CK_MECHANISM_TYPE_PTR mec, CK_ULONG num);
|
||||||
CK_RV YUBICO_get_token_mechanism_info(CK_MECHANISM_TYPE mec, CK_MECHANISM_INFO_PTR info);
|
CK_RV YUBICO_get_token_mechanism_info(CK_MECHANISM_TYPE mec, CK_MECHANISM_INFO_PTR info);
|
||||||
CK_RV YUBICO_get_token_objects_num(ykpiv_state *state, CK_ULONG_PTR num, CK_ULONG_PTR num_certs);
|
CK_RV YUBICO_get_token_objects_num(ykpiv_state *state, CK_ULONG_PTR num, CK_ULONG_PTR num_certs);
|
||||||
CK_RV YUBICO_get_token_object_list(ykpiv_state *state, piv_obj_id_t *obj, CK_ULONG num);
|
CK_RV YUBICO_get_token_object_list(ykpiv_state *state, piv_obj_id_t *obj, CK_ULONG num);
|
||||||
CK_RV YUBICO_get_token_raw_certificate(ykpiv_state *state, piv_obj_id_t obj, CK_BYTE_PTR data, CK_ULONG_PTR len);
|
CK_RV YUBICO_get_token_raw_certificate(ykpiv_state *state, piv_obj_id_t obj, CK_BYTE_PTR data, CK_ULONG_PTR len);
|
||||||
|
CK_RV YUBICO_token_change_pin(ykpiv_state *state, CK_USER_TYPE user_type, CK_UTF8CHAR_PTR pOldPin, CK_ULONG ulOldLen,
|
||||||
|
CK_UTF8CHAR_PTR pNewPin, CK_ULONG ulNewLen);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user