Merge branch 'devel/p384' into ykcs11

Conflicts:
	NEWS
	configure.ac
	lib/ykpiv.c
	lib/ykpiv.h
	tool/util.c
	tool/util.h
This commit is contained in:
Klas Lindfors
2015-09-07 14:32:37 +02:00
9 changed files with 452 additions and 294 deletions
+4 -1
View File
@@ -1,6 +1,9 @@
yubico-piv-tool NEWS -- History of user-visible changes. -*- outline -*- yubico-piv-tool NEWS -- History of user-visible changes. -*- outline -*-
* Version 1.0.2 (unreleased) * Version 1.1.0 (unreleased)
** Support for YubiKey 4 stuff
ECCP384, touch, retired keys etc
* Version 1.0.1 (released 2015-07-10) * Version 1.0.1 (released 2015-07-10)
+4 -4
View File
@@ -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.0.2]) AC_INIT([yubico-piv-tool], [1.1.0])
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], 1) AC_SUBST([LT_CURRENT], 2)
AC_SUBST([LT_REVISION], 7) AC_SUBST([LT_REVISION], 0)
AC_SUBST([LT_AGE], 0) AC_SUBST([LT_AGE], 1)
AM_INIT_AUTOMAKE([-Wall -Werror foreign]) AM_INIT_AUTOMAKE([-Wall -Werror foreign])
AM_SILENT_RULES([yes]) AM_SILENT_RULES([yes])
+35 -51
View File
@@ -452,6 +452,10 @@ ykpiv_rc ykpiv_authenticate(ykpiv_state *state, unsigned const char *key) {
} }
ykpiv_rc ykpiv_set_mgmkey(ykpiv_state *state, const unsigned char *new_key) { ykpiv_rc ykpiv_set_mgmkey(ykpiv_state *state, const unsigned char *new_key) {
return ykpiv_set_mgmkey2(state, new_key, 0);
}
ykpiv_rc ykpiv_set_mgmkey2(ykpiv_state *state, const unsigned char *new_key, const unsigned char touch) {
APDU apdu; APDU apdu;
unsigned char data[0xff]; unsigned char data[0xff];
unsigned long recv_len = sizeof(data); unsigned long recv_len = sizeof(data);
@@ -478,7 +482,13 @@ ykpiv_rc ykpiv_set_mgmkey(ykpiv_state *state, const unsigned char *new_key) {
memset(apdu.raw, 0, sizeof(apdu)); memset(apdu.raw, 0, sizeof(apdu));
apdu.st.ins = YKPIV_INS_SET_MGMKEY; apdu.st.ins = YKPIV_INS_SET_MGMKEY;
apdu.st.p1 = 0xff; apdu.st.p1 = 0xff;
apdu.st.p2 = 0xff; if(touch == 0) {
apdu.st.p2 = 0xff;
} else if(touch == 1) {
apdu.st.p2 = 0xfe;
} else {
return YKPIV_GENERIC_ERROR;
}
apdu.st.lc = DES_KEY_SZ * 3 + 3; apdu.st.lc = DES_KEY_SZ * 3 + 3;
apdu.st.data[0] = YKPIV_ALGO_3DES; apdu.st.data[0] = YKPIV_ALGO_3DES;
apdu.st.data[1] = YKPIV_KEY_CARDMGM; apdu.st.data[1] = YKPIV_KEY_CARDMGM;
@@ -524,7 +534,7 @@ ykpiv_rc ykpiv_hex_decode(const char *hex_in, size_t in_len,
} }
static ykpiv_rc _general_authenticate(ykpiv_state *state, static ykpiv_rc _general_authenticate(ykpiv_state *state,
const unsigned char *raw_in, size_t in_len, const unsigned char *sign_in, size_t in_len,
unsigned char *out, size_t *out_len, unsigned char *out, size_t *out_len,
unsigned char algorithm, unsigned char key, bool decipher, bool padding) { unsigned char algorithm, unsigned char key, bool decipher, bool padding) {
unsigned char indata[1024]; unsigned char indata[1024];
@@ -532,63 +542,37 @@ static ykpiv_rc _general_authenticate(ykpiv_state *state,
unsigned char data[1024]; unsigned char data[1024];
unsigned char templ[] = {0, YKPIV_INS_AUTHENTICATE, algorithm, key}; unsigned char templ[] = {0, YKPIV_INS_AUTHENTICATE, algorithm, key};
unsigned long recv_len = sizeof(data); unsigned long recv_len = sizeof(data);
unsigned char sign_in[256]; size_t key_len = 0;
size_t pad_len = 0;
int sw; int sw;
size_t bytes; size_t bytes;
size_t len = 0; size_t len = 0;
ykpiv_rc res; ykpiv_rc res;
switch(algorithm) { switch(algorithm) {
case YKPIV_ALGO_RSA1024: case YKPIV_ALGO_RSA1024:
pad_len = 128; key_len = 128;
case YKPIV_ALGO_RSA2048:
case YKPIV_ALGO_RSA2048: if(key_len == 0) {
if(pad_len == 0) { key_len = 256;
pad_len = 256;
}
if(!decipher) {
// Signature
if (padding) {
// Padding required
if(in_len + RSA_PKCS1_PADDING_SIZE > pad_len) {
return YKPIV_SIZE_ERROR;
}
// Add padding and copy data
RSA_padding_add_PKCS1_type_1(sign_in, pad_len, raw_in, in_len);
in_len = pad_len;
} }
else { if(in_len != key_len) {
// No padding required return YKPIV_SIZE_ERROR;
if (in_len != pad_len)
return YKPIV_SIZE_ERROR;
// Just copy data
memcpy(sign_in, raw_in, in_len);
} }
} break;
else { case YKPIV_ALGO_ECCP256:
// Decryption key_len = 32;
if(in_len != pad_len) { case YKPIV_ALGO_ECCP384:
return YKPIV_SIZE_ERROR; if(key_len == 0) {
key_len = 48;
} }
if(!decipher && in_len > key_len) {
// Just copy data return YKPIV_SIZE_ERROR;
memcpy(sign_in, raw_in, in_len); } else if(decipher && in_len != (key_len * 2) + 1) {
} return YKPIV_SIZE_ERROR;
break; }
break;
case YKPIV_ALGO_ECCP256: default:
if(!decipher && in_len > 32) { return YKPIV_ALGORITHM_ERROR;
return YKPIV_SIZE_ERROR;
} else if(decipher && in_len != 65) {
return YKPIV_SIZE_ERROR;
}
memcpy(sign_in, raw_in, in_len);
break;
default:
return YKPIV_ALGORITHM_ERROR;
} }
if(in_len < 0x80) { if(in_len < 0x80) {
@@ -603,7 +587,7 @@ static ykpiv_rc _general_authenticate(ykpiv_state *state,
dataptr += set_length(dataptr, in_len + bytes + 3); dataptr += set_length(dataptr, in_len + bytes + 3);
*dataptr++ = 0x82; *dataptr++ = 0x82;
*dataptr++ = 0x00; *dataptr++ = 0x00;
*dataptr++ = algorithm == YKPIV_ALGO_ECCP256 && decipher ? 0x85 : 0x81; *dataptr++ = YKPIV_IS_EC(algorithm) && decipher ? 0x85 : 0x81;
dataptr += set_length(dataptr, in_len); dataptr += set_length(dataptr, in_len);
memcpy(dataptr, sign_in, (size_t)in_len); memcpy(dataptr, sign_in, (size_t)in_len);
dataptr += in_len; dataptr += in_len;
+36
View File
@@ -88,6 +88,8 @@ extern "C"
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_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,
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);
@@ -95,6 +97,7 @@ extern "C"
#define YKPIV_ALGO_RSA1024 0x06 #define YKPIV_ALGO_RSA1024 0x06
#define YKPIV_ALGO_RSA2048 0x07 #define YKPIV_ALGO_RSA2048 0x07
#define YKPIV_ALGO_ECCP256 0x11 #define YKPIV_ALGO_ECCP256 0x11
#define YKPIV_ALGO_ECCP384 0x14
#define YKPIV_KEY_AUTHENTICATION 0x9a #define YKPIV_KEY_AUTHENTICATION 0x9a
#define YKPIV_KEY_CARDMGM 0x9b #define YKPIV_KEY_CARDMGM 0x9b
@@ -116,6 +119,27 @@ extern "C"
#define YKPIV_OBJ_KEY_HISTORY 0x5fc10c #define YKPIV_OBJ_KEY_HISTORY 0x5fc10c
#define YKPIV_OBJ_IRIS 0x5fc121 #define YKPIV_OBJ_IRIS 0x5fc121
#define YKPIV_OBJ_RETIRED1 0x5fc10d
#define YKPIV_OBJ_RETIRED2 0x5fc10e
#define YKPIV_OBJ_RETIRED3 0x5fc10f
#define YKPIV_OBJ_RETIRED4 0x5fc110
#define YKPIV_OBJ_RETIRED5 0x5fc111
#define YKPIV_OBJ_RETIRED6 0x5fc112
#define YKPIV_OBJ_RETIRED7 0x5fc113
#define YKPIV_OBJ_RETIRED8 0x5fc114
#define YKPIV_OBJ_RETIRED9 0x5fc115
#define YKPIV_OBJ_RETIRED10 0x5fc116
#define YKPIV_OBJ_RETIRED11 0x5fc117
#define YKPIV_OBJ_RETIRED12 0x5fc118
#define YKPIV_OBJ_RETIRED13 0x5fc119
#define YKPIV_OBJ_RETIRED14 0x5fc11a
#define YKPIV_OBJ_RETIRED15 0x5fc11b
#define YKPIV_OBJ_RETIRED16 0x5fc11c
#define YKPIV_OBJ_RETIRED17 0x5fc11d
#define YKPIV_OBJ_RETIRED18 0x5fc11e
#define YKPIV_OBJ_RETIRED19 0x5fc11f
#define YKPIV_OBJ_RETIRED20 0x5fc120
#define YKPIV_INS_VERIFY 0x20 #define YKPIV_INS_VERIFY 0x20
#define YKPIV_INS_CHANGE_REFERENCE 0x24 #define YKPIV_INS_CHANGE_REFERENCE 0x24
#define YKPIV_INS_RESET_RETRY 0x2c #define YKPIV_INS_RESET_RETRY 0x2c
@@ -131,6 +155,18 @@ extern "C"
#define YKPIV_INS_RESET 0xfb #define YKPIV_INS_RESET 0xfb
#define YKPIV_INS_SET_PIN_RETRIES 0xfa #define YKPIV_INS_SET_PIN_RETRIES 0xfa
#define YKPIV_PINPOLICY_TAG 0xaa
#define YKPIV_PINPOLICY_NEVER 1
#define YKPIV_PINPOLICY_ONCE 2
#define YKPIV_PINPOLICY_ALWAYS 3
#define YKPIV_TOUCHPOLICY_TAG 0xab
#define YKPIV_TOUCHPOLICY_NEVER 1
#define YKPIV_TOUCHPOLICY_ALWAYS 2
#define YKPIV_IS_EC(a) ((a == YKPIV_ALGO_ECCP256 || a == YKPIV_ALGO_ECCP384))
#define YKPIV_IS_RSA(a) ((a == YKPIV_ALGO_RSA1024 || a == YKPIV_ALGO_RSA2048))
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
+6
View File
@@ -56,3 +56,9 @@ global:
ykpiv_connect2; ykpiv_connect2;
ykpiv_sign_data2; ykpiv_sign_data2;
} YKPIV_0.1.0; } YKPIV_0.1.0;
YKPIV_1.1.0
{
global:
ykpiv_set_mgmkey2;
} YKPIV_0.1.0;
+7 -4
View File
@@ -36,14 +36,15 @@ option "action" a "Action to take" values="version","generate","set-mgm-key",
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"
option "slot" s "What key slot to operate on" values="9a","9c","9d","9e" enum optional option "slot" s "What key slot to operate on" values="9a","9c","9d","9e","82","83","84","85","86","87","88","89","8a","8b","8c","8d","8e","8f","90","91","92","93","94","95" enum optional
text " text "
9a is for PIV Authentication 9a is for PIV Authentication
9c is for Digital Signature (PIN always checked) 9c is for Digital Signature (PIN always checked)
9d is for Key Management 9d is for Key Management
9e is for Card Authentication (PIN never checked)\n" 9e is for Card Authentication (PIN never checked)
option "algorithm" A "What algorithm to use" values="RSA1024","RSA2048","ECCP256" enum optional default="RSA2048" 82-95 is for Retired Key Management\n"
option "hash" H "Hash to use for signatures" values="SHA1","SHA256","SHA512" enum optional default="SHA256" option "algorithm" A "What algorithm to use" values="RSA1024","RSA2048","ECCP256","ECCP384" enum optional default="RSA2048"
option "hash" H "Hash to use for signatures" values="SHA1","SHA256","SHA384","SHA512" enum optional default="SHA256"
option "new-key" n "New authentication key to use" string optional option "new-key" n "New authentication key to use" string optional
option "pin-retries" - "Number of retries before the pin code is blocked" int optional dependon="puk-retries" option "pin-retries" - "Number of retries before the pin code is blocked" int optional dependon="puk-retries"
option "puk-retries" - "Number of retries before the puk code is blocked" int optional dependon="pin-retries" option "puk-retries" - "Number of retries before the puk code is blocked" int optional dependon="pin-retries"
@@ -57,4 +58,6 @@ text "
/CN=host.example.com/OU=test/O=example.com/\n" /CN=host.example.com/OU=test/O=example.com/\n"
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 "touch-policy" - "Set touch policy for action generate, import-key or set-mgm-key" values="never","always" enum optional
option "sign" - "Sign data" flag off hidden option "sign" - "Sign data" flag off hidden
+193
View File
@@ -82,6 +82,8 @@ unsigned char get_algorithm(EVP_PKEY *key) {
int curve = EC_GROUP_get_curve_name(group); int curve = EC_GROUP_get_curve_name(group);
if(curve == NID_X9_62_prime256v1) { if(curve == NID_X9_62_prime256v1) {
return YKPIV_ALGO_ECCP256; return YKPIV_ALGO_ECCP256;
} else if(curve == NID_secp384r1) {
return YKPIV_ALGO_ECCP384;
} else { } else {
fprintf(stderr, "Unknown EC curve %d\n", curve); fprintf(stderr, "Unknown EC curve %d\n", curve);
return 0; return 0;
@@ -200,6 +202,66 @@ int get_object_id(enum enum_slot slot) {
case slot_arg_9e: case slot_arg_9e:
object = YKPIV_OBJ_CARD_AUTH; object = YKPIV_OBJ_CARD_AUTH;
break; break;
case slot_arg_82:
object = YKPIV_OBJ_RETIRED1;
break;
case slot_arg_83:
object = YKPIV_OBJ_RETIRED2;
break;
case slot_arg_84:
object = YKPIV_OBJ_RETIRED3;
break;
case slot_arg_85:
object = YKPIV_OBJ_RETIRED4;
break;
case slot_arg_86:
object = YKPIV_OBJ_RETIRED5;
break;
case slot_arg_87:
object = YKPIV_OBJ_RETIRED6;
break;
case slot_arg_88:
object = YKPIV_OBJ_RETIRED7;
break;
case slot_arg_89:
object = YKPIV_OBJ_RETIRED8;
break;
case slot_arg_8a:
object = YKPIV_OBJ_RETIRED9;
break;
case slot_arg_8b:
object = YKPIV_OBJ_RETIRED10;
break;
case slot_arg_8c:
object = YKPIV_OBJ_RETIRED11;
break;
case slot_arg_8d:
object = YKPIV_OBJ_RETIRED12;
break;
case slot_arg_8e:
object = YKPIV_OBJ_RETIRED13;
break;
case slot_arg_8f:
object = YKPIV_OBJ_RETIRED14;
break;
case slot_arg_90:
object = YKPIV_OBJ_RETIRED15;
break;
case slot_arg_91:
object = YKPIV_OBJ_RETIRED16;
break;
case slot_arg_92:
object = YKPIV_OBJ_RETIRED17;
break;
case slot_arg_93:
object = YKPIV_OBJ_RETIRED18;
break;
case slot_arg_94:
object = YKPIV_OBJ_RETIRED19;
break;
case slot_arg_95:
object = YKPIV_OBJ_RETIRED20;
break;
case slot__NULL: case slot__NULL:
default: default:
object = 0; object = 0;
@@ -284,3 +346,134 @@ bool read_pw(const char *name, char *pwbuf, size_t pwbuflen, int verify) {
} }
return true; return true;
} }
static unsigned const char sha1oid[] = {
0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x05, 0x00,
0x04, 0x14
};
static unsigned const char sha256oid[] = {
0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04,
0x02, 0x01, 0x05, 0x00, 0x04, 0x20
};
static unsigned const char sha384oid[] = {
0x30, 0x41, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04,
0x02, 0x02, 0x05, 0x00, 0x04, 0x30
};
static unsigned const char sha512oid[] = {
0x30, 0x51, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04,
0x02, 0x03, 0x05, 0x00, 0x04, 0x40
};
const EVP_MD *get_hash(enum enum_hash hash, const unsigned char **oid, size_t *oid_len) {
switch(hash) {
case hash_arg_SHA1:
if(oid) {
*oid = sha1oid;
*oid_len = sizeof(sha1oid);
}
return EVP_sha1();
case hash_arg_SHA256:
if(oid) {
*oid = sha256oid;
*oid_len = sizeof(sha256oid);
}
return EVP_sha256();
case hash_arg_SHA384:
if(oid) {
*oid = sha384oid;
*oid_len = sizeof(sha384oid);
}
return EVP_sha384();
case hash_arg_SHA512:
if(oid) {
*oid = sha512oid;
*oid_len = sizeof(sha512oid);
}
return EVP_sha512();
case hash__NULL:
default:
return NULL;
}
}
int get_hashnid(enum enum_hash hash, unsigned char algorithm) {
switch(algorithm) {
case YKPIV_ALGO_RSA1024:
case YKPIV_ALGO_RSA2048:
switch(hash) {
case hash_arg_SHA1:
return NID_sha1WithRSAEncryption;
case hash_arg_SHA256:
return NID_sha256WithRSAEncryption;
case hash_arg_SHA384:
return NID_sha384WithRSAEncryption;
case hash_arg_SHA512:
return NID_sha512WithRSAEncryption;
case hash__NULL:
default:
return 0;
}
case YKPIV_ALGO_ECCP256:
case YKPIV_ALGO_ECCP384:
switch(hash) {
case hash_arg_SHA1:
return NID_ecdsa_with_SHA1;
case hash_arg_SHA256:
return NID_ecdsa_with_SHA256;
case hash_arg_SHA384:
return NID_ecdsa_with_SHA384;
case hash_arg_SHA512:
return NID_ecdsa_with_SHA512;
case hash__NULL:
default:
return 0;
}
default:
return 0;
}
}
unsigned char get_piv_algorithm(enum enum_algorithm algorithm) {
switch(algorithm) {
case algorithm_arg_RSA2048:
return YKPIV_ALGO_RSA2048;
case algorithm_arg_RSA1024:
return YKPIV_ALGO_RSA1024;
case algorithm_arg_ECCP256:
return YKPIV_ALGO_ECCP256;
case algorithm_arg_ECCP384:
return YKPIV_ALGO_ECCP384;
case algorithm__NULL:
default:
return 0;
}
}
unsigned char get_pin_policy(enum enum_pin_policy policy) {
switch(policy) {
case pin_policy_arg_never:
return YKPIV_PINPOLICY_NEVER;
case pin_policy_arg_once:
return YKPIV_PINPOLICY_ONCE;
case pin_policy_arg_always:
return YKPIV_PINPOLICY_ALWAYS;
case pin_policy__NULL:
default:
return 0;
}
}
unsigned char get_touch_policy(enum enum_touch_policy policy) {
switch(policy) {
case touch_policy_arg_never:
return YKPIV_TOUCHPOLICY_NEVER;
case touch_policy_arg_always:
return YKPIV_TOUCHPOLICY_ALWAYS;
case touch_policy__NULL:
default:
return 0;
}
}
+5
View File
@@ -50,5 +50,10 @@ bool set_component_with_len(unsigned char**, const BIGNUM*, int);
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);
const EVP_MD *get_hash(enum enum_hash, const unsigned char**, size_t*);
int get_hashnid(enum enum_hash, unsigned char);
unsigned char get_piv_algorithm(enum enum_algorithm);
unsigned char get_pin_policy(enum enum_pin_policy);
unsigned char get_touch_policy(enum enum_touch_policy);
#endif #endif
+162 -234
View File
@@ -63,20 +63,7 @@ unsigned const char chuid_tmpl[] = {
}; };
#define CHUID_GUID_OFFS 29 #define CHUID_GUID_OFFS 29
unsigned const char sha1oid[] = { #define MAX_OID_LEN 19
0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x05, 0x00,
0x04, 0x14
};
unsigned const char sha256oid[] = {
0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04,
0x02, 0x01, 0x05, 0x00, 0x04, 0x20
};
unsigned const char sha512oid[] = {
0x30, 0x51, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04,
0x02, 0x03, 0x05, 0x00, 0x04, 0x40
};
#define KEY_LEN 24 #define KEY_LEN 24
@@ -100,8 +87,10 @@ static void print_version(ykpiv_state *state, const char *output_file_name) {
static bool generate_key(ykpiv_state *state, const char *slot, static bool generate_key(ykpiv_state *state, const char *slot,
enum enum_algorithm algorithm, const char *output_file_name, enum enum_algorithm algorithm, const char *output_file_name,
enum enum_key_format key_format) { enum enum_key_format key_format, enum enum_pin_policy pin_policy,
unsigned char in_data[5]; enum enum_touch_policy touch_policy) {
unsigned char in_data[11];
unsigned char *in_ptr = in_data;
unsigned char data[1024]; unsigned char data[1024];
unsigned char templ[] = {0, YKPIV_INS_GENERATE_ASYMMERTRIC, 0, 0}; unsigned char templ[] = {0, YKPIV_INS_GENERATE_ASYMMERTRIC, 0, 0};
unsigned long recv_len = sizeof(data); unsigned long recv_len = sizeof(data);
@@ -124,31 +113,46 @@ static bool generate_key(ykpiv_state *state, const char *slot,
return false; return false;
} }
in_data[0] = 0xac; *in_ptr++ = 0xac;
in_data[1] = 3; *in_ptr++ = 3;
in_data[2] = 0x80; *in_ptr++ = 0x80;
in_data[3] = 1; *in_ptr++ = 1;
switch(algorithm) { *in_ptr++ = get_piv_algorithm(algorithm);
case algorithm_arg_RSA2048: if(in_data[4] == 0) {
in_data[4] = YKPIV_ALGO_RSA2048; fprintf(stderr, "Unexepcted algorithm.\n");
break; goto generate_out;
case algorithm_arg_RSA1024:
in_data[4] = YKPIV_ALGO_RSA1024;
break;
case algorithm_arg_ECCP256:
in_data[4] = YKPIV_ALGO_ECCP256;
break;
case algorithm__NULL:
default:
fprintf(stderr, "Unexepcted algorithm.\n");
goto generate_out;
} }
if(ykpiv_transfer_data(state, templ, in_data, sizeof(in_data), data, if(pin_policy != pin_policy__NULL) {
in_data[1] += 3;
*in_ptr++ = YKPIV_PINPOLICY_TAG;
*in_ptr++ = 1;
*in_ptr++ = get_pin_policy(pin_policy);
}
if(touch_policy != touch_policy__NULL) {
in_data[1] += 3;
*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) { &recv_len, &sw) != YKPIV_OK) {
fprintf(stderr, "Failed to communicate.\n"); fprintf(stderr, "Failed to communicate.\n");
goto generate_out; goto generate_out;
} else if(sw != 0x9000) { } else if(sw != 0x9000) {
fprintf(stderr, "Failed to generate new key.\n"); fprintf(stderr, "Failed to generate new key (");
if(sw == 0x6b00) {
fprintf(stderr, "slot not supported?)\n");
} else if(sw == 0x6a80) {
if(pin_policy != pin_policy__NULL) {
fprintf(stderr, "pin policy not supported?)\n");
} else if(touch_policy != touch_policy__NULL) {
fprintf(stderr, "touch policy not supported?)\n");
} else {
fprintf(stderr, "algorithm not supported?)\n");
}
} else {
fprintf(stderr, "error %x)\n", sw);
}
goto generate_out; goto generate_out;
} }
@@ -187,24 +191,34 @@ static bool generate_key(ykpiv_state *state, const char *slot,
rsa->n = bignum_n; rsa->n = bignum_n;
rsa->e = bignum_e; rsa->e = bignum_e;
EVP_PKEY_set1_RSA(public_key, rsa); EVP_PKEY_set1_RSA(public_key, rsa);
} else if(algorithm == algorithm_arg_ECCP256) { } else if(algorithm == algorithm_arg_ECCP256 || algorithm == algorithm_arg_ECCP384) {
EC_GROUP *group; EC_GROUP *group;
unsigned char *data_ptr = data + 3; unsigned char *data_ptr = data + 3;
int nid;
size_t len;
if(algorithm == algorithm_arg_ECCP256) {
nid = NID_X9_62_prime256v1;
len = 65;
} else {
nid = NID_secp384r1;
len = 97;
}
eckey = EC_KEY_new(); eckey = EC_KEY_new();
group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1); group = EC_GROUP_new_by_curve_name(nid);
EC_GROUP_set_asn1_flag(group, NID_X9_62_prime256v1); EC_GROUP_set_asn1_flag(group, nid);
EC_KEY_set_group(eckey, group); EC_KEY_set_group(eckey, group);
point = EC_POINT_new(group); point = EC_POINT_new(group);
if(*data_ptr++ != 0x86) { if(*data_ptr++ != 0x86) {
fprintf(stderr, "Failed to parse public key structure.\n"); fprintf(stderr, "Failed to parse public key structure.\n");
goto generate_out; goto generate_out;
} }
if(*data_ptr++ != 65) { /* the curve point should always be 65 bytes */ if(*data_ptr++ != len) { /* the curve point should always be 65 bytes */
fprintf(stderr, "Unexpected length.\n"); fprintf(stderr, "Unexpected length.\n");
goto generate_out; goto generate_out;
} }
if(!EC_POINT_oct2point(group, point, data_ptr, 65, NULL)) { if(!EC_POINT_oct2point(group, point, data_ptr, len, NULL)) {
fprintf(stderr, "Failed to load public point.\n"); fprintf(stderr, "Failed to load public point.\n");
goto generate_out; goto generate_out;
} }
@@ -283,7 +297,8 @@ static bool set_pin_retries(ykpiv_state *state, int pin_retries, int puk_retries
} }
static bool import_key(ykpiv_state *state, enum enum_key_format key_format, static bool import_key(ykpiv_state *state, enum enum_key_format key_format,
const char *input_file_name, const char *slot, char *password) { const char *input_file_name, const char *slot, char *password,
enum enum_pin_policy pin_policy, enum enum_touch_policy touch_policy) {
int key = 0; int key = 0;
FILE *input_file = NULL; FILE *input_file = NULL;
EVP_PKEY *private_key = NULL; EVP_PKEY *private_key = NULL;
@@ -336,7 +351,7 @@ static bool import_key(ykpiv_state *state, enum enum_key_format key_format,
unsigned char *in_ptr = in_data; unsigned char *in_ptr = in_data;
unsigned char templ[] = {0, YKPIV_INS_IMPORT_KEY, algorithm, key}; unsigned char templ[] = {0, YKPIV_INS_IMPORT_KEY, algorithm, key};
int sw; int sw;
if(algorithm == YKPIV_ALGO_RSA1024 || algorithm == YKPIV_ALGO_RSA2048) { 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 *e_ptr = e;
@@ -380,20 +395,45 @@ static bool import_key(ykpiv_state *state, enum enum_key_format key_format,
fprintf(stderr, "Failed setting iqmp component.\n"); fprintf(stderr, "Failed setting iqmp component.\n");
goto import_out; goto import_out;
} }
} else if(algorithm == YKPIV_ALGO_ECCP256) { } 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;
if(algorithm == YKPIV_ALGO_ECCP384) {
element_len = 48;
}
*in_ptr++ = 0x06; *in_ptr++ = 0x06;
if(set_component_with_len(&in_ptr, s, 32) == 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;
} }
} }
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, if(ykpiv_transfer_data(state, templ, in_data, in_ptr - in_data, data,
&recv_len, &sw) != YKPIV_OK) { &recv_len, &sw) != YKPIV_OK) {
return false; 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) { } else if(sw != 0x9000) {
fprintf(stderr, "Failed import command with code %x.\n", sw); fprintf(stderr, "Failed import command with code %x.\n", sw);
} else { } else {
@@ -559,7 +599,7 @@ static bool request_certificate(ykpiv_state *state, enum enum_key_format key_for
EVP_PKEY *public_key = NULL; EVP_PKEY *public_key = NULL;
const EVP_MD *md; const EVP_MD *md;
bool ret = false; bool ret = false;
unsigned char digest[EVP_MAX_MD_SIZE + sizeof(sha512oid)]; // maximum.. unsigned char digest[EVP_MAX_MD_SIZE + MAX_OID_LEN];
unsigned int digest_len; unsigned int digest_len;
unsigned int md_len; unsigned int md_len;
unsigned char algorithm; unsigned char algorithm;
@@ -597,25 +637,9 @@ static bool request_certificate(ykpiv_state *state, enum enum_key_format key_for
goto request_out; goto request_out;
} }
switch(hash) { md = get_hash(hash, &oid, &oid_len);
case hash_arg_SHA1: if(md == NULL) {
md = EVP_sha1(); goto request_out;
oid = sha1oid;
oid_len = sizeof(sha1oid);
break;
case hash_arg_SHA256:
md = EVP_sha256();
oid = sha256oid;
oid_len = sizeof(sha256oid);
break;
case hash_arg_SHA512:
md = EVP_sha512();
oid = sha512oid;
oid_len = sizeof(sha512oid);
break;
case hash__NULL:
default:
goto request_out;
} }
md_len = (unsigned int)EVP_MD_size(md); md_len = (unsigned int)EVP_MD_size(md);
@@ -651,48 +675,19 @@ static bool request_certificate(ykpiv_state *state, enum enum_key_format key_for
goto request_out; goto request_out;
} }
switch(algorithm) { nid = get_hashnid(hash, algorithm);
case YKPIV_ALGO_RSA1024: if(nid == 0) {
case YKPIV_ALGO_RSA2048: fprintf(stderr, "Unsupported algorithm %x or hash %x\n", algorithm, hash);
signinput = digest; goto request_out;
len = oid_len + digest_len;
switch(hash) {
case hash_arg_SHA1:
nid = NID_sha1WithRSAEncryption;
break;
case hash_arg_SHA256:
nid = NID_sha256WithRSAEncryption;
break;
case hash_arg_SHA512:
nid = NID_sha512WithRSAEncryption;
break;
case hash__NULL:
default:
goto request_out;
}
break;
case YKPIV_ALGO_ECCP256:
signinput = digest + oid_len;
len = digest_len;
switch(hash) {
case hash_arg_SHA1:
nid = NID_ecdsa_with_SHA1;
break;
case hash_arg_SHA256:
nid = NID_ecdsa_with_SHA256;
break;
case hash_arg_SHA512:
nid = NID_ecdsa_with_SHA512;
break;
case hash__NULL:
default:
goto request_out;
}
break;
default:
fprintf(stderr, "Unsupported algorithm %x.\n", algorithm);
goto request_out;
} }
if(YKPIV_IS_RSA(algorithm)) {
signinput = digest;
len = oid_len + digest_len;
} else {
signinput = digest + oid_len;
len = digest_len;
}
req->sig_alg->algorithm = OBJ_nid2obj(nid); req->sig_alg->algorithm = OBJ_nid2obj(nid);
{ {
unsigned char signature[1024]; unsigned char signature[1024];
@@ -743,7 +738,7 @@ static bool selfsign_certificate(ykpiv_state *state, enum enum_key_format key_fo
X509 *x509 = NULL; X509 *x509 = NULL;
X509_NAME *name = NULL; X509_NAME *name = NULL;
const EVP_MD *md; const EVP_MD *md;
unsigned char digest[EVP_MAX_MD_SIZE + sizeof(sha512oid)]; unsigned char digest[EVP_MAX_MD_SIZE + MAX_OID_LEN];
unsigned int digest_len; unsigned int digest_len;
unsigned char algorithm; unsigned char algorithm;
int key = 0; int key = 0;
@@ -781,27 +776,10 @@ static bool selfsign_certificate(ykpiv_state *state, enum enum_key_format key_fo
goto selfsign_out; goto selfsign_out;
} }
switch(hash) { md = get_hash(hash, &oid, &oid_len);
case hash_arg_SHA1: if(md == NULL) {
md = EVP_sha1(); goto selfsign_out;
oid = sha1oid;
oid_len = sizeof(sha1oid);
break;
case hash_arg_SHA256:
md = EVP_sha256();
oid = sha256oid;
oid_len = sizeof(sha256oid);
break;
case hash_arg_SHA512:
md = EVP_sha512();
oid = sha512oid;
oid_len = sizeof(sha512oid);
break;
case hash__NULL:
default:
goto selfsign_out;
} }
md_len = (unsigned int)EVP_MD_size(md); md_len = (unsigned int)EVP_MD_size(md);
digest_len = sizeof(digest) - md_len; digest_len = sizeof(digest) - md_len;
@@ -843,48 +821,18 @@ static bool selfsign_certificate(ykpiv_state *state, enum enum_key_format key_fo
fprintf(stderr, "Failed setting certificate issuer.\n"); fprintf(stderr, "Failed setting certificate issuer.\n");
goto selfsign_out; goto selfsign_out;
} }
switch(algorithm) { nid = get_hashnid(hash, algorithm);
case YKPIV_ALGO_RSA1024: if(nid == 0) {
case YKPIV_ALGO_RSA2048: goto selfsign_out;
signinput = digest;
len = oid_len + md_len;
switch(hash) {
case hash_arg_SHA1:
nid = NID_sha1WithRSAEncryption;
break;
case hash_arg_SHA256:
nid = NID_sha256WithRSAEncryption;
break;
case hash_arg_SHA512:
nid = NID_sha512WithRSAEncryption;
break;
case hash__NULL:
default:
goto selfsign_out;
}
break;
case YKPIV_ALGO_ECCP256:
signinput = digest + oid_len;
len = md_len;
switch(hash) {
case hash_arg_SHA1:
nid = NID_ecdsa_with_SHA1;
break;
case hash_arg_SHA256:
nid = NID_ecdsa_with_SHA256;
break;
case hash_arg_SHA512:
nid = NID_ecdsa_with_SHA512;
break;
case hash__NULL:
default:
goto selfsign_out;
}
break;
default:
fprintf(stderr, "Unsupported algorithm %x.\n", algorithm);
goto selfsign_out;
} }
if(YKPIV_IS_RSA(algorithm)) {
signinput = digest;
len = oid_len + md_len;
} else {
signinput = digest + oid_len;
len = md_len;
}
x509->sig_alg->algorithm = OBJ_nid2obj(nid); x509->sig_alg->algorithm = OBJ_nid2obj(nid);
x509->cert_info->signature->algorithm = x509->sig_alg->algorithm; x509->cert_info->signature->algorithm = x509->sig_alg->algorithm;
memcpy(digest, oid, oid_len); memcpy(digest, oid, oid_len);
@@ -1138,37 +1086,17 @@ static bool sign_file(ykpiv_state *state, const char *input, const char *output,
return false; return false;
} }
switch(algorithm) { algo = get_piv_algorithm(algorithm);
case algorithm_arg_RSA2048: if(algo == 0) {
algo = YKPIV_ALGO_RSA2048; goto out;
break;
case algorithm_arg_RSA1024:
algo = YKPIV_ALGO_RSA1024;
break;
case algorithm_arg_ECCP256:
algo = YKPIV_ALGO_ECCP256;
break;
case algorithm__NULL:
default:
goto out;
} }
{ {
EVP_MD_CTX *mdctx; EVP_MD_CTX *mdctx;
switch(hash) { md = get_hash(hash, NULL, NULL);
case hash_arg_SHA1: if(md == NULL) {
md = EVP_sha1(); goto out;
break;
case hash_arg_SHA256:
md = EVP_sha256();
break;
case hash_arg_SHA512:
md = EVP_sha512();
break;
case hash__NULL:
default:
goto out;
} }
mdctx = EVP_MD_CTX_create(); mdctx = EVP_MD_CTX_create();
@@ -1187,7 +1115,7 @@ static bool sign_file(ykpiv_state *state, const char *input, const char *output,
EVP_MD_CTX_destroy(mdctx); EVP_MD_CTX_destroy(mdctx);
} }
if(algo == YKPIV_ALGO_RSA1024 || algo == YKPIV_ALGO_RSA2048) { if(YKPIV_IS_RSA(algo)) {
prepare_rsa_signature(hashed, hash_len, hashed, &hash_len, EVP_MD_type(md)); prepare_rsa_signature(hashed, hash_len, hashed, &hash_len, EVP_MD_type(md));
} }
@@ -1268,6 +1196,9 @@ static void print_cert_info(ykpiv_state *state, enum enum_slot slot, const EVP_M
case YKPIV_ALGO_ECCP256: case YKPIV_ALGO_ECCP256:
fprintf(output, "ECCP256\n"); fprintf(output, "ECCP256\n");
break; break;
case YKPIV_ALGO_ECCP384:
fprintf(output, "ECCP384\n");
break;
default: default:
fprintf(output, "Unknown\n"); fprintf(output, "Unknown\n");
} }
@@ -1328,19 +1259,9 @@ static bool status(ykpiv_state *state, enum enum_hash hash,
return false; return false;
} }
switch(hash) { md = get_hash(hash, NULL, NULL);
case hash_arg_SHA1: if(md == NULL) {
md = EVP_sha1(); return false;
break;
case hash_arg_SHA256:
md = EVP_sha256();
break;
case hash_arg_SHA512:
md = EVP_sha512();
break;
case hash__NULL:
default:
return false;
} }
fprintf(output_file, "CHUID:\t"); fprintf(output_file, "CHUID:\t");
@@ -1404,19 +1325,9 @@ static bool test_signature(ykpiv_state *state, enum enum_slot slot,
goto test_out; goto test_out;
} }
switch(hash) { md = get_hash(hash, NULL, NULL);
case hash_arg_SHA1: if(md == NULL) {
md = EVP_sha1(); return false;
break;
case hash_arg_SHA256:
md = EVP_sha256();
break;
case hash_arg_SHA512:
md = EVP_sha512();
break;
case hash__NULL:
default:
return false;
} }
{ {
@@ -1456,7 +1367,7 @@ static bool test_signature(ykpiv_state *state, enum enum_slot slot,
goto test_out; goto test_out;
} }
sscanf(cmdline_parser_slot_values[slot], "%2x", &key); sscanf(cmdline_parser_slot_values[slot], "%2x", &key);
if(algorithm == YKPIV_ALGO_RSA1024 || algorithm == YKPIV_ALGO_RSA2048) { if(YKPIV_IS_RSA(algorithm)) {
prepare_rsa_signature(data, data_len, encoded, &enc_len, EVP_MD_type(md)); prepare_rsa_signature(data, data_len, encoded, &enc_len, EVP_MD_type(md));
ptr = encoded; ptr = encoded;
} else { } else {
@@ -1490,6 +1401,7 @@ static bool test_signature(ykpiv_state *state, enum enum_slot slot,
break; break;
case YKPIV_ALGO_ECCP256: case YKPIV_ALGO_ECCP256:
case YKPIV_ALGO_ECCP384:
{ {
EC_KEY *ec = EVP_PKEY_get1_EC_KEY(pubkey); EC_KEY *ec = EVP_PKEY_get1_EC_KEY(pubkey);
if(ECDSA_verify(0, data, (int)data_len, signature, (int)sig_len, ec) == 1) { if(ECDSA_verify(0, data, (int)data_len, signature, (int)sig_len, ec) == 1) {
@@ -1561,7 +1473,7 @@ static bool test_decipher(ykpiv_state *state, enum enum_slot slot,
goto decipher_out; goto decipher_out;
} }
sscanf(cmdline_parser_slot_values[slot], "%2x", &key); sscanf(cmdline_parser_slot_values[slot], "%2x", &key);
if(algorithm == YKPIV_ALGO_RSA1024 || algorithm == YKPIV_ALGO_RSA2048) { if(YKPIV_IS_RSA(algorithm)) {
unsigned char secret[32]; unsigned char secret[32];
unsigned char secret2[32]; unsigned char secret2[32];
unsigned char data[256]; unsigned char data[256];
@@ -1602,20 +1514,30 @@ static bool test_decipher(ykpiv_state *state, enum enum_slot slot,
} else { } else {
fprintf(stderr, "Failed unwrapping PKCS1 envelope.\n"); fprintf(stderr, "Failed unwrapping PKCS1 envelope.\n");
} }
} else { } else if(YKPIV_IS_EC(algorithm)) {
unsigned char secret[32]; unsigned char secret[48];
unsigned char secret2[32]; unsigned char secret2[48];
unsigned char public_key[65]; unsigned char public_key[97];
unsigned char *ptr = public_key; unsigned char *ptr = public_key;
size_t len = sizeof(secret); size_t len = sizeof(secret);
EC_KEY *ec = EVP_PKEY_get1_EC_KEY(pubkey); EC_KEY *ec = EVP_PKEY_get1_EC_KEY(pubkey);
int nid;
size_t key_len;
tmpkey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); if(algorithm == YKPIV_ALGO_ECCP256) {
nid = NID_X9_62_prime256v1;
key_len = 32;
} else {
nid = NID_secp384r1;
key_len = 48;
}
tmpkey = EC_KEY_new_by_curve_name(nid);
EC_KEY_generate_key(tmpkey); EC_KEY_generate_key(tmpkey);
ECDH_compute_key(secret, len, EC_KEY_get0_public_key(ec), tmpkey, NULL); ECDH_compute_key(secret, len, EC_KEY_get0_public_key(ec), tmpkey, NULL);
i2o_ECPublicKey(tmpkey, &ptr); i2o_ECPublicKey(tmpkey, &ptr);
if(ykpiv_decipher_data(state, public_key, sizeof(public_key), secret2, &len, algorithm, key) != YKPIV_OK) { if(ykpiv_decipher_data(state, public_key, (key_len * 2) + 1, secret2, &len, algorithm, key) != YKPIV_OK) {
fprintf(stderr, "Failed ECDH exchange!\n"); fprintf(stderr, "Failed ECDH exchange!\n");
goto decipher_out; goto decipher_out;
} }
@@ -1625,7 +1547,7 @@ static bool test_decipher(ykpiv_state *state, enum enum_slot slot,
fprintf(stderr, "ECDH card generated: "); fprintf(stderr, "ECDH card generated: ");
dump_hex(secret2, len, stderr, true); dump_hex(secret2, len, stderr, true);
} }
if(memcmp(secret, secret2, 32) == 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");
ret = true; ret = true;
} else { } else {
@@ -1786,7 +1708,8 @@ int main(int argc, char *argv[]) {
print_version(state, args_info.output_arg); print_version(state, args_info.output_arg);
break; break;
case action_arg_generate: case action_arg_generate:
if(generate_key(state, args_info.slot_orig, args_info.algorithm_arg, args_info.output_arg, args_info.key_format_arg) == false) { if(generate_key(state, args_info.slot_orig, args_info.algorithm_arg, args_info.output_arg, args_info.key_format_arg,
args_info.pin_policy_arg, args_info.touch_policy_arg) == false) {
ret = EXIT_FAILURE; ret = EXIT_FAILURE;
} else { } else {
fprintf(stderr, "Successfully generated a new private key.\n"); fprintf(stderr, "Successfully generated a new private key.\n");
@@ -1807,8 +1730,12 @@ int main(int argc, char *argv[]) {
if(ykpiv_hex_decode(new_mgm_key, strlen(new_mgm_key), new_key, &new_key_len) != YKPIV_OK) { if(ykpiv_hex_decode(new_mgm_key, strlen(new_mgm_key), new_key, &new_key_len) != YKPIV_OK) {
fprintf(stderr, "Failed decoding new key!\n"); fprintf(stderr, "Failed decoding new key!\n");
ret = EXIT_FAILURE; ret = EXIT_FAILURE;
} else if(ykpiv_set_mgmkey(state, new_key) != YKPIV_OK) { } else if(ykpiv_set_mgmkey2(state, new_key, args_info.touch_policy_arg == touch_policy_arg_always ? 1 : 0) != YKPIV_OK) {
fprintf(stderr, "Failed setting the new key!\n"); fprintf(stderr, "Failed setting the new key!");
if(args_info.touch_policy_arg != touch_policy__NULL) {
fprintf(stderr, " Maybe touch policy is not supported on this key?");
}
fprintf(stderr, "\n");
ret = EXIT_FAILURE; ret = EXIT_FAILURE;
} else { } else {
fprintf(stderr, "Successfully set new management key.\n"); fprintf(stderr, "Successfully set new management key.\n");
@@ -1835,7 +1762,8 @@ 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) == false) { if(import_key(state, args_info.key_format_arg, args_info.input_arg, args_info.slot_orig, args_info.password_arg,
args_info.pin_policy_arg, args_info.touch_policy_arg) == false) {
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");