diff --git a/lib/ykpiv.c b/lib/ykpiv.c index 614846e..468d9ef 100644 --- a/lib/ykpiv.c +++ b/lib/ykpiv.c @@ -461,7 +461,7 @@ ykpiv_rc ykpiv_parse_key(ykpiv_state *state, } ykpiv_rc ykpiv_sign_data(ykpiv_state *state, - const unsigned char *sign_in, int in_len, + const unsigned char *raw_in, int in_len, unsigned char *sign_out, size_t *out_len, unsigned char algorithm, unsigned char key) { @@ -470,13 +470,34 @@ ykpiv_rc ykpiv_sign_data(ykpiv_state *state, unsigned char data[1024]; unsigned char templ[] = {0, YKPIV_INS_AUTHENTICATE, algorithm, key}; unsigned long recv_len = sizeof(data); + unsigned char sign_in[256]; + size_t pad_len = 0; int sw; int bytes; size_t len = 0; ykpiv_rc res; - if(in_len > 1000) { - return YKPIV_SIZE_ERROR; + switch(algorithm) { + case YKPIV_ALGO_RSA1024: + pad_len = 128; + case YKPIV_ALGO_RSA2048: + if(pad_len == 0) { + pad_len = 256; + } + if(in_len > pad_len) { + return YKPIV_SIZE_ERROR; + } + RSA_padding_add_PKCS1_type_1(sign_in, pad_len, raw_in, in_len); + in_len = pad_len; + break; + case YKPIV_ALGO_ECCP256: + if(in_len > 32) { + return YKPIV_SIZE_ERROR; + } + memcpy(sign_in, raw_in, in_len); + break; + default: + return YKPIV_ALGORITHM_ERROR; } if(in_len < 0x80) { diff --git a/lib/ykpiv.h b/lib/ykpiv.h index b093051..6022a1a 100644 --- a/lib/ykpiv.h +++ b/lib/ykpiv.h @@ -55,6 +55,7 @@ extern "C" YKPIV_PARSE_ERROR = -9, YKPIV_WRONG_PIN = -10, YKPIV_INVALID_OBJECT = -11, + YKPIV_ALGORITHM_ERROR = -12, } ykpiv_rc; const char *ykpiv_strerror(ykpiv_rc err); diff --git a/tool/yubico-piv-tool.c b/tool/yubico-piv-tool.c index aafa811..bf9b0ef 100644 --- a/tool/yubico-piv-tool.c +++ b/tool/yubico-piv-tool.c @@ -523,7 +523,7 @@ static bool request_certificate(ykpiv_state *state, enum enum_key_format key_for unsigned int digest_len = DIGEST_LEN; unsigned char algorithm; int key = 0; - unsigned char signinput[256]; + unsigned char *signinput; int len = 0; sscanf(slot, "%x", &key); @@ -582,18 +582,15 @@ static bool request_certificate(ykpiv_state *state, enum enum_key_format key_for switch(algorithm) { case YKPIV_ALGO_RSA1024: - len = 128; case YKPIV_ALGO_RSA2048: - if(len == 0) { - len = 256; - } - RSA_padding_add_PKCS1_type_1(signinput, len, digest, sizeof(digest)); + signinput = digest; + len = sizeof(digest); req->sig_alg->algorithm = OBJ_nid2obj(NID_sha256WithRSAEncryption); break; case YKPIV_ALGO_ECCP256: - req->sig_alg->algorithm = OBJ_nid2obj(NID_ecdsa_with_SHA256); + signinput = digest + sizeof(sha256oid); len = DIGEST_LEN; - memcpy(signinput, digest + sizeof(sha256oid), DIGEST_LEN); + req->sig_alg->algorithm = OBJ_nid2obj(NID_ecdsa_with_SHA256); break; default: fprintf(stderr, "Unsupported algorithm %x.\n", algorithm); @@ -648,7 +645,7 @@ static bool selfsign_certificate(ykpiv_state *state, enum enum_key_format key_fo unsigned int digest_len = DIGEST_LEN; unsigned char algorithm; int key = 0; - unsigned char signinput[256]; + unsigned char *signinput; int len = 0; sscanf(slot, "%x", &key); @@ -718,18 +715,15 @@ static bool selfsign_certificate(ykpiv_state *state, enum enum_key_format key_fo } switch(algorithm) { case YKPIV_ALGO_RSA1024: - len = 128; case YKPIV_ALGO_RSA2048: - if(len == 0) { - len = 256; - } - RSA_padding_add_PKCS1_type_1(signinput, len, digest, sizeof(digest)); + signinput = digest; + len = sizeof(digest); x509->sig_alg->algorithm = OBJ_nid2obj(NID_sha256WithRSAEncryption); break; case YKPIV_ALGO_ECCP256: - x509->sig_alg->algorithm = OBJ_nid2obj(NID_ecdsa_with_SHA256); + signinput = digest + sizeof(sha256oid); len = DIGEST_LEN; - memcpy(signinput, digest + sizeof(sha256oid), DIGEST_LEN); + x509->sig_alg->algorithm = OBJ_nid2obj(NID_ecdsa_with_SHA256); break; default: fprintf(stderr, "Unsupported algorithm %x.\n", algorithm);