From 7ce5ea4dc2080a1a76f1a92884608c1ebcff0e84 Mon Sep 17 00:00:00 2001 From: Alessio Di Mauro Date: Mon, 3 Aug 2015 16:21:09 +0200 Subject: [PATCH] Added sign_data2 to libykpiv to disable padding. --- lib/ykpiv.c | 26 ++++++++++++++++++++------ lib/ykpiv.h | 6 +++++- lib/ykpiv.map | 1 + ykcs11/mechanisms.c | 8 ++++++-- ykcs11/mechanisms.h | 4 ++-- ykcs11/openssl_utils.c | 2 +- ykcs11/ykcs11.c | 30 +++++++++++++----------------- 7 files changed, 48 insertions(+), 29 deletions(-) diff --git a/lib/ykpiv.c b/lib/ykpiv.c index e8182ad..8cd9a70 100644 --- a/lib/ykpiv.c +++ b/lib/ykpiv.c @@ -520,7 +520,7 @@ ykpiv_rc ykpiv_hex_decode(const char *hex_in, size_t in_len, static ykpiv_rc _general_authenticate(ykpiv_state *state, const unsigned char *raw_in, size_t in_len, unsigned char *out, size_t *out_len, - unsigned char algorithm, unsigned char key, bool decipher) { + unsigned char algorithm, unsigned char key, bool decipher, bool padding) { unsigned char indata[1024]; unsigned char *dataptr = indata; unsigned char data[1024]; @@ -538,14 +538,18 @@ static ykpiv_rc _general_authenticate(ykpiv_state *state, pad_len = 128; case YKPIV_ALGO_RSA2048: if(pad_len == 0) { - pad_len = 256; + pad_len = 256; } if(!decipher) { if(in_len + RSA_PKCS1_PADDING_SIZE > pad_len) { return YKPIV_SIZE_ERROR; } - RSA_padding_add_PKCS1_type_1(sign_in, pad_len, raw_in, in_len); - in_len = pad_len; + if (padding) { + RSA_padding_add_PKCS1_type_1(sign_in, pad_len, raw_in, in_len); + in_len = pad_len; + } + else if (in_len != pad_len) + return YKPIV_SIZE_ERROR; } else { if(in_len != pad_len) { return YKPIV_SIZE_ERROR; @@ -629,7 +633,17 @@ ykpiv_rc ykpiv_sign_data(ykpiv_state *state, unsigned char algorithm, unsigned char key) { return _general_authenticate(state, raw_in, in_len, sign_out, out_len, - algorithm, key, false); + algorithm, key, false, true); +} + +ykpiv_rc ykpiv_sign_data2(ykpiv_state *state, + const unsigned char *raw_in, size_t in_len, + unsigned char *sign_out, size_t *out_len, + unsigned char algorithm, unsigned char key, + int padding) { + + return _general_authenticate(state, raw_in, in_len, sign_out, out_len, + algorithm, key, false, padding); } @@ -637,7 +651,7 @@ ykpiv_rc ykpiv_decipher_data(ykpiv_state *state, const unsigned char *in, size_t in_len, unsigned char *out, size_t *out_len, unsigned char algorithm, unsigned char key) { return _general_authenticate(state, in, in_len, out, out_len, - algorithm, key, true); + algorithm, key, true, true); } ykpiv_rc ykpiv_get_version(ykpiv_state *state, char *version, size_t len) { diff --git a/lib/ykpiv.h b/lib/ykpiv.h index 0ccbfbb..baa7d98 100644 --- a/lib/ykpiv.h +++ b/lib/ykpiv.h @@ -64,7 +64,8 @@ extern "C" ykpiv_rc ykpiv_init(ykpiv_state **state, int verbose); ykpiv_rc ykpiv_done(ykpiv_state *state); ykpiv_rc ykpiv_connect(ykpiv_state *state, const char *wanted); - ykpiv_rc ykpiv_connect2(ykpiv_state *state, const char *wanted, unsigned char **readers, unsigned long *len); + ykpiv_rc ykpiv_connect2(ykpiv_state *state, const char *wanted, + unsigned char **readers, unsigned long *len); // Allow to return a reader string ykpiv_rc ykpiv_disconnect(ykpiv_state *state); ykpiv_rc ykpiv_transfer_data(ykpiv_state *state, const unsigned char *templ, const unsigned char *in_data, long in_len, @@ -76,6 +77,9 @@ extern "C" ykpiv_rc ykpiv_sign_data(ykpiv_state *state, const unsigned char *sign_in, size_t in_len, unsigned char *sign_out, size_t *out_len, unsigned char algorithm, unsigned char key); + ykpiv_rc ykpiv_sign_data2(ykpiv_state *state, const unsigned char *sign_in, + size_t in_len, unsigned char *sign_out, size_t *out_len, + unsigned char algorithm, unsigned char key, int padding); // Allow not to add padding ykpiv_rc ykpiv_decipher_data(ykpiv_state *state, const unsigned char *enc_in, size_t in_len, unsigned char *enc_out, size_t *out_len, unsigned char algorithm, unsigned char key); diff --git a/lib/ykpiv.map b/lib/ykpiv.map index 09c7847..a6ddb40 100644 --- a/lib/ykpiv.map +++ b/lib/ykpiv.map @@ -53,4 +53,5 @@ YKPIV_0.2.0 global: ykpiv_decipher_data; ykpiv_connect2; + ykpiv_sign_data2; } YKPIV_0.1.0; diff --git a/ykcs11/mechanisms.c b/ykcs11/mechanisms.c index 7eb0c69..0d3e30e 100644 --- a/ykcs11/mechanisms.c +++ b/ykcs11/mechanisms.c @@ -85,14 +85,18 @@ CK_BBOOL is_RSA_mechanism(CK_MECHANISM_TYPE m) { return CK_FALSE; } -CK_RV do_sign_padding(CK_MECHANISM_PTR m, CK_BYTE_PTR in, CK_ULONG in_len, - CK_BYTE_PTR out, CK_ULONG out_len, CK_ULONG key_len) { +CK_RV apply_sign_mechanism(CK_MECHANISM_PTR m, CK_BYTE_PTR in, CK_ULONG in_len, + CK_BYTE_PTR out, CK_ULONG out_len, CK_ULONG key_len) { switch (m->mechanism) { case CKM_RSA_PKCS: return do_pkcs_t1(in, in_len, out, out_len, key_len); case CKM_RSA_PKCS_PSS: + return CKR_FUNCTION_FAILED; + case CKM_RSA_X_509: + return CKR_OK; + case CKM_SHA1_RSA_PKCS: case CKM_SHA256_RSA_PKCS: case CKM_SHA384_RSA_PKCS: diff --git a/ykcs11/mechanisms.h b/ykcs11/mechanisms.h index 8a38121..cb4130d 100644 --- a/ykcs11/mechanisms.h +++ b/ykcs11/mechanisms.h @@ -7,7 +7,7 @@ CK_RV check_sign_mechanism(const ykcs11_session_t *s, CK_MECHANISM_PTR m); CK_BBOOL is_RSA_mechanism(CK_MECHANISM_TYPE m); -CK_RV do_sign_padding(CK_MECHANISM_PTR m, CK_BYTE_PTR in, CK_ULONG in_len, - CK_BYTE_PTR out, CK_ULONG out_len, CK_ULONG key_len); +CK_RV apply_sign_mechanism(CK_MECHANISM_PTR m, CK_BYTE_PTR in, CK_ULONG in_len, + CK_BYTE_PTR out, CK_ULONG out_len, CK_ULONG key_len); #endif diff --git a/ykcs11/openssl_utils.c b/ykcs11/openssl_utils.c index cb98f28..afdfcf1 100644 --- a/ykcs11/openssl_utils.c +++ b/ykcs11/openssl_utils.c @@ -130,7 +130,7 @@ CK_RV free_key(EVP_PKEY *key) { CK_RV do_pkcs_t1(CK_BYTE_PTR in, CK_ULONG in_len, CK_BYTE_PTR out, CK_ULONG out_len, CK_ULONG key_len) { fprintf(stderr, "Apply padding to %lu bytes and get %lu\n", in_len, key_len); - // TODO: rand must be seeded first + // TODO: rand must be seeded first (should be automatic) if (out_len < key_len) CKR_BUFFER_TOO_SMALL; diff --git a/ykcs11/ykcs11.c b/ykcs11/ykcs11.c index df38bbf..781bdaf 100644 --- a/ykcs11/ykcs11.c +++ b/ykcs11/ykcs11.c @@ -814,7 +814,8 @@ CK_DEFINE_FUNCTION(CK_RV, C_GetAttributeValue)( ) { DIN; - CK_RV rv; + CK_ULONG i; + CK_RV rv, rv_final; if (piv_state == NULL) { DBG(("libykpiv is not initialized or already finalized")); @@ -835,24 +836,20 @@ CK_DEFINE_FUNCTION(CK_RV, C_GetAttributeValue)( if (find_obj.active != CK_TRUE) return CKR_OPERATION_NOT_INITIALIZED; - if (pTemplate[0].pValue == NULL_PTR) { - DBG(("Just get size")); - rv = get_attribute(&session, hObject, pTemplate); + rv_final = CKR_OK; + for (i = 0; i < ulCount; i++) { + rv = get_attribute(&session, hObject, pTemplate + i); + + // TODO: this function has some complex cases for return vlaue. Make sure to check them. if (rv != CKR_OK) { - DBG(("Unable to get size for attribute %lu of object %lu", pTemplate->type, hObject)); + DBG(("Unable to get attribute %lu of object %lu", (pTemplate + i)->type, hObject)); + rv_final = rv; } - DOUT; - return CKR_OK; } - DBG(("Trying to get %lu attribute(s) for object %lu", ulCount, hObject)); - DBG(("Type: 0x%lx Value: %lu Len: %lu", pTemplate[0].type, *((CK_ULONG_PTR)pTemplate[0].pValue), pTemplate[0].ulValueLen)); - // TODO: here for i in ulCount (get all the attributes) - - return get_attribute(&session, hObject, pTemplate); DOUT; - return CKR_OK; + return rv_final; } CK_DEFINE_FUNCTION(CK_RV, C_SetAttributeValue)( @@ -1339,10 +1336,10 @@ CK_DEFINE_FUNCTION(CK_RV, C_Sign)( DBG(("Sending %lu bytes to sign", ulDataLen)); dump_hex(pData, ulDataLen, stderr, CK_TRUE); -/* if (do_sign_padding(&sign_info.mechanism, pData, ulDataLen, buf, buf_len, 2048 / 8) != CKR_OK) { + if (apply_sign_mechanism(&sign_info.mechanism, pData, ulDataLen, buf, buf_len, 2048 / 8) != CKR_OK) { DBG(("Unable to apply padding scheme")); return CKR_FUNCTION_FAILED; - }*/ + } memcpy(buf, pData, ulDataLen); // ykpiv does padding already //dump_hex(buf, 256, stderr, CK_TRUE); //*pulSignatureLen = 256; @@ -1353,8 +1350,7 @@ CK_DEFINE_FUNCTION(CK_RV, C_Sign)( } DBG(("Got %lu bytes back", *pulSignatureLen)); dump_hex(pSignature, *pulSignatureLen, stderr, CK_TRUE); -/* memcpy(pSignature, sig_buf, sig_len_out); - *pulSignatureLen = sig_len_out;*/ + DOUT; return CKR_OK; }