- sc_pkcs15_decipher now takes a flags argument, so we know when to
strip off any pkcs#1 padding. git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@585 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
parent
f618b754a2
commit
7f6453d715
@ -75,6 +75,7 @@ extern "C" {
|
|||||||
#define SC_ERROR_NOT_SUPPORTED -1408
|
#define SC_ERROR_NOT_SUPPORTED -1408
|
||||||
#define SC_ERROR_PASSPHRASE_REQUIRED -1409
|
#define SC_ERROR_PASSPHRASE_REQUIRED -1409
|
||||||
#define SC_ERROR_EXTRACTABLE_KEY -1410
|
#define SC_ERROR_EXTRACTABLE_KEY -1410
|
||||||
|
#define SC_ERROR_DECRYPT_FAILED -1411
|
||||||
|
|
||||||
/* Relating to PKCS #15 init stuff */
|
/* Relating to PKCS #15 init stuff */
|
||||||
#define SC_ERROR_PKCS15INIT -1500
|
#define SC_ERROR_PKCS15INIT -1500
|
||||||
|
@ -27,15 +27,37 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
static int pkcs1_strip_padding(u8 *data, size_t len)
|
||||||
|
{
|
||||||
|
unsigned int n = 0;
|
||||||
|
|
||||||
|
if (data[0] != 0x00 && data[1] != 0x02)
|
||||||
|
return SC_ERROR_DECRYPT_FAILED;
|
||||||
|
/* Skip over padding bytes */
|
||||||
|
for (n = 2; n < len && data[n]; n++)
|
||||||
|
;
|
||||||
|
/* Must be at least 8 pad bytes */
|
||||||
|
if (n >= len || n < 10)
|
||||||
|
return SC_ERROR_DECRYPT_FAILED;
|
||||||
|
n++;
|
||||||
|
|
||||||
|
/* Now move decrypted contents to head of buffer */
|
||||||
|
memmove(data, data + n, len - n);
|
||||||
|
return len - n;
|
||||||
|
}
|
||||||
|
|
||||||
int sc_pkcs15_decipher(struct sc_pkcs15_card *p15card,
|
int sc_pkcs15_decipher(struct sc_pkcs15_card *p15card,
|
||||||
const struct sc_pkcs15_object *obj,
|
const struct sc_pkcs15_object *obj,
|
||||||
|
unsigned long flags,
|
||||||
const u8 * in, size_t inlen, u8 *out, size_t outlen)
|
const u8 * in, size_t inlen, u8 *out, size_t outlen)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
struct sc_algorithm_info *alg_info;
|
||||||
struct sc_security_env senv;
|
struct sc_security_env senv;
|
||||||
struct sc_context *ctx = p15card->card->ctx;
|
struct sc_context *ctx = p15card->card->ctx;
|
||||||
struct sc_path path, file_id;
|
struct sc_path path, file_id;
|
||||||
const struct sc_pkcs15_prkey_info *prkey = (const struct sc_pkcs15_prkey_info *) obj->data;
|
const struct sc_pkcs15_prkey_info *prkey = (const struct sc_pkcs15_prkey_info *) obj->data;
|
||||||
|
unsigned long pad_flags = 0;
|
||||||
|
|
||||||
/* If the key is extractable, the caller should extract the
|
/* If the key is extractable, the caller should extract the
|
||||||
* key and do the crypto himself */
|
* key and do the crypto himself */
|
||||||
@ -53,9 +75,32 @@ int sc_pkcs15_decipher(struct sc_pkcs15_card *p15card,
|
|||||||
file_id.len = 2;
|
file_id.len = 2;
|
||||||
path.len -= 2;
|
path.len -= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
alg_info = _sc_card_find_rsa_alg(p15card->card, prkey->modulus_length);
|
||||||
|
if (alg_info == NULL) {
|
||||||
|
error(ctx, "Card does not support RSA with key length %d\n", prkey->modulus_length);
|
||||||
|
return SC_ERROR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
senv.algorithm = SC_ALGORITHM_RSA;
|
senv.algorithm = SC_ALGORITHM_RSA;
|
||||||
senv.algorithm_flags = 0;
|
senv.algorithm_flags = 0;
|
||||||
|
|
||||||
|
if (flags & SC_ALGORITHM_RSA_PAD_PKCS1) {
|
||||||
|
if (!(alg_info->flags & SC_ALGORITHM_RSA_PAD_PKCS1))
|
||||||
|
pad_flags |= SC_ALGORITHM_RSA_PAD_PKCS1;
|
||||||
|
else
|
||||||
|
senv.algorithm_flags |= SC_ALGORITHM_RSA_PAD_PKCS1;
|
||||||
|
} else if ((flags & SC_ALGORITHM_RSA_PAD_ANSI) ||
|
||||||
|
(flags & SC_ALGORITHM_RSA_PAD_ISO9796)) {
|
||||||
|
error(ctx, "Only PKCS #1 padding method supported\n");
|
||||||
|
return SC_ERROR_NOT_SUPPORTED;
|
||||||
|
} else {
|
||||||
|
if (!(alg_info->flags & SC_ALGORITHM_RSA_RAW)) {
|
||||||
|
error(ctx, "Card requires RSA padding\n");
|
||||||
|
return SC_ERROR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
senv.algorithm_flags |= SC_ALGORITHM_RSA_RAW;
|
||||||
|
}
|
||||||
|
|
||||||
senv.file_ref = file_id;
|
senv.file_ref = file_id;
|
||||||
senv.operation = SC_SEC_OPERATION_DECIPHER;
|
senv.operation = SC_SEC_OPERATION_DECIPHER;
|
||||||
senv.key_ref_len = 1;
|
senv.key_ref_len = 1;
|
||||||
@ -75,6 +120,13 @@ int sc_pkcs15_decipher(struct sc_pkcs15_card *p15card,
|
|||||||
SC_TEST_RET(ctx, r, "sc_set_security_env() failed");
|
SC_TEST_RET(ctx, r, "sc_set_security_env() failed");
|
||||||
r = sc_decipher(p15card->card, in, inlen, out, outlen);
|
r = sc_decipher(p15card->card, in, inlen, out, outlen);
|
||||||
SC_TEST_RET(ctx, r, "sc_decipher() failed");
|
SC_TEST_RET(ctx, r, "sc_decipher() failed");
|
||||||
|
|
||||||
|
/* Strip any padding */
|
||||||
|
if (pad_flags & SC_ALGORITHM_RSA_PAD_PKCS1) {
|
||||||
|
r = pkcs1_strip_padding(out, r);
|
||||||
|
SC_TEST_RET(ctx, r, "Invalid PKCS#1 padding");
|
||||||
|
}
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,6 +353,7 @@ void sc_pkcs15_print_card(const struct sc_pkcs15_card *card);
|
|||||||
|
|
||||||
int sc_pkcs15_decipher(struct sc_pkcs15_card *p15card,
|
int sc_pkcs15_decipher(struct sc_pkcs15_card *p15card,
|
||||||
const struct sc_pkcs15_object *prkey_obj,
|
const struct sc_pkcs15_object *prkey_obj,
|
||||||
|
unsigned long flags,
|
||||||
const u8 *in, size_t inlen, u8 *out, size_t outlen);
|
const u8 *in, size_t inlen, u8 *out, size_t outlen);
|
||||||
|
|
||||||
int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card,
|
int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card,
|
||||||
|
@ -1184,6 +1184,7 @@ pkcs15_prkey_unwrap(struct sc_pkcs11_session *ses, void *obj,
|
|||||||
p15card = (struct sc_pkcs15_card*) ses->slot->card->fw_data;
|
p15card = (struct sc_pkcs15_card*) ses->slot->card->fw_data;
|
||||||
prkey = (struct pkcs15_prkey_object *) obj;
|
prkey = (struct pkcs15_prkey_object *) obj;
|
||||||
rv = sc_pkcs15_decipher(p15card, prkey->prkey_object,
|
rv = sc_pkcs15_decipher(p15card, prkey->prkey_object,
|
||||||
|
SC_ALGORITHM_RSA_PAD_PKCS1,
|
||||||
pData, ulDataLen,
|
pData, ulDataLen,
|
||||||
unwrapped_key, sizeof(unwrapped_key));
|
unwrapped_key, sizeof(unwrapped_key));
|
||||||
debug(context, "Key unwrap complete. Result %d.\n", rv);
|
debug(context, "Key unwrap complete. Result %d.\n", rv);
|
||||||
|
@ -371,7 +371,9 @@ int decipher(struct sc_pkcs15_object *obj)
|
|||||||
r = SC_ERROR_NOT_SUPPORTED;
|
r = SC_ERROR_NOT_SUPPORTED;
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
r = sc_pkcs15_decipher(p15card, obj, buf, c, out, len);
|
r = sc_pkcs15_decipher(p15card, obj,
|
||||||
|
opt_crypt_flags & SC_ALGORITHM_RSA_PAD_PKCS1,
|
||||||
|
buf, c, out, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
|
Loading…
Reference in New Issue
Block a user