[pkg-opensc-commit] [opensc] 71/295: Improve handling of OpenPGP card PIN change and unblock commands

Eric Dorland eric at moszumanska.debian.org
Sat Jun 24 21:11:17 UTC 2017


This is an automated email from the git hooks/post-receive script.

eric pushed a commit to branch master
in repository opensc.

commit dc476a9f3313a0aab4ea09220a8763765fe639f2
Author: Maciej S. Szmigiero <mail at maciej.szmigiero.name>
Date:   Sun Aug 14 01:46:55 2016 +0200

    Improve handling of OpenPGP card PIN change and unblock commands
    
    "CHANGE REFERENCE DATA" (PIN change) and "RESET RETRY COUNTER"
    (PIN unblock) commands in OpenPGP card have various limitations.
    These also depend on whether the card is version 1.x or 2.x.
    
    Provide helpful debug messages for user in case he is trying to do
    a PIN command in a way that isn't supported by the card.
    
    Also, take into account that version 2.x cards don't support references to
    PW1-mode 2 (82) in these commands - change them to PW1 (81).
    
    Signed-off-by: Maciej S. Szmigiero <mail at maciej.szmigiero.name>
---
 src/libopensc/card-openpgp.c | 48 ++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 46 insertions(+), 2 deletions(-)

diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c
index 916b38c..35e7c50 100644
--- a/src/libopensc/card-openpgp.c
+++ b/src/libopensc/card-openpgp.c
@@ -1518,6 +1518,8 @@ pgp_put_data(sc_card_t *card, unsigned int tag, const u8 *buf, size_t buf_len)
 static int
 pgp_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left)
 {
+	struct pgp_priv_data *priv = DRVDATA(card);
+
 	LOG_FUNC_CALLED(card->ctx);
 
 	if (data->pin_type != SC_AC_CHV)
@@ -1531,8 +1533,17 @@ pgp_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left)
 	 * So, if we receive Ref=1, Ref=2, we must convert to 81, 82...
 	 * In OpenPGP v1, the PINs are named CHV1, CHV2, CHV3.
 	 * In v2, they are named PW1, PW3 (PW1 operates in 2 modes).
-	 * However, the PIN references (P2 in APDU) are the same in both versions:
-	 * 81 (CHV1 or PW1), 82 (CHV2 or PW1-mode 2), 83 (CHV3 or PW3).
+	 *
+	 * The PIN references (P2 in APDU) for "VERIFY" are the same in both versions:
+	 * 81 (CHV1 or PW1), 82 (CHV2 or PW1-mode 2), 83 (CHV3 or PW3),
+	 * On the other hand from version 2.0 "CHANGE REFERENCE DATA" and
+	 * "RESET RETRY COUNTER" don't support PW1-mode 2 (82) and need this
+	 * value changed to PW1 (81).
+	 * Both of these commands also differ between card versions in that
+	 * v1 cards can use only implicit old PIN or CHV3 test for both commands
+	 * whereas v2 can use both implicit (for PW3) and explicit
+	 * (for special "Resetting Code") PIN test for "RESET RETRY COUNTER"
+	 * and only explicit test for "CHANGE REFERENCE DATA".
 	 *
 	 * Note that if this function is called from sc_pkcs15_verify_pin() in pkcs15-pin.c,
 	 * the Ref is already 81, 82, 83.
@@ -1540,6 +1551,39 @@ pgp_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left)
 
 	/* convert the PIN Reference if needed */
 	data->pin_reference |= 0x80;
+
+	/* check version-dependent constraints */
+	if (data->cmd == SC_PIN_CMD_CHANGE || data->cmd == SC_PIN_CMD_UNBLOCK) {
+		if (priv->bcd_version >= OPENPGP_CARD_2_0) {
+			if (data->pin_reference == 0x82)
+				data->pin_reference = 0x81;
+
+			if (data->cmd == SC_PIN_CMD_CHANGE) {
+				if (data->pin1.len == 0 &&
+				    !(data->flags & SC_PIN_CMD_USE_PINPAD))
+					LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS,
+						     "v2 cards don't support implicit old PIN for PIN change.");
+
+				data->flags &= ~SC_PIN_CMD_IMPLICIT_CHANGE;
+			}
+		} else {
+			if (data->pin1.len != 0) {
+				sc_log(card->ctx,
+				       "v1 cards don't support explicit old or CHV3 PIN, PIN ignored.");
+				sc_log(card->ctx,
+				       "please make sure that you have verified the relevant PIN first.");
+				data->pin1.len = 0;
+			}
+
+			data->flags |= SC_PIN_CMD_IMPLICIT_CHANGE;
+		}
+	}
+
+	if (data->cmd == SC_PIN_CMD_UNBLOCK && data->pin2.len == 0 &&
+	    !(data->flags & SC_PIN_CMD_USE_PINPAD))
+		LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS,
+			     "new PIN must be provided for unblock operation.");
+
 	/* ensure pin_reference is 81, 82, 83 */
 	if (!(data->pin_reference == 0x81 || data->pin_reference == 0x82 || data->pin_reference == 0x83)) {
 		LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS,

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-opensc/opensc.git



More information about the pkg-opensc-commit mailing list