- 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:
okir 2002-04-23 08:17:06 +00:00
parent f618b754a2
commit 7f6453d715
5 changed files with 58 additions and 1 deletions

View File

@ -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

View File

@ -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;
} }

View File

@ -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,

View File

@ -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);

View File

@ -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) {