diff --git a/applets/openpgp/openpgp.c b/applets/openpgp/openpgp.c index acbd9ffc..13d11ee3 100644 --- a/applets/openpgp/openpgp.c +++ b/applets/openpgp/openpgp.c @@ -78,10 +78,10 @@ static const uint8_t extended_length_info[] = {0x02, 0x02, HI(APDU_BUFFER_SIZE), 0x02, 0x02, HI(APDU_BUFFER_SIZE), LO(APDU_BUFFER_SIZE)}; static const uint8_t extended_capabilities[] = { - 0x34, // Support key import, pw1 status change, and algorithm attributes changes + 0x74, // Support get challenge, key import, pw1 status change, and algorithm attributes changes 0x00, // No SM algorithm - 0x00, - 0x00, // No challenge support + HI(APDU_BUFFER_SIZE), + LO(APDU_BUFFER_SIZE), // Challenge size HI(MAX_CERT_LENGTH), LO(MAX_CERT_LENGTH), // Cert length HI(MAX_DO_LENGTH), @@ -1201,6 +1201,14 @@ static int openpgp_activate(const CAPDU *capdu, RAPDU *rapdu) { return openpgp_install(1); } +static int openpgp_get_challenge(const CAPDU *capdu, RAPDU *rapdu) { + if (P1 != 0x00 || P2 != 0x00) EXCEPT(SW_WRONG_P1P2); + if (LE > APDU_BUFFER_SIZE) EXCEPT(SW_WRONG_LENGTH); + random_buffer(RDATA, LE); + LL = LE; + return 0; +} + int openpgp_process_apdu(const CAPDU *capdu, RAPDU *rapdu) { LL = 0; SW = SW_NO_ERROR; @@ -1287,6 +1295,9 @@ int openpgp_process_apdu(const CAPDU *capdu, RAPDU *rapdu) { ret = openpgp_sign_or_auth(capdu, rapdu, false); stop_blinking(); break; + case OPENPGP_INS_GET_CHALLENGE: + ret = openpgp_get_challenge(capdu, rapdu); + break; case OPENPGP_INS_TERMINATE: ret = openpgp_terminate(capdu, rapdu); break; diff --git a/include/openpgp.h b/include/openpgp.h index ef3fcfd8..3f21792b 100644 --- a/include/openpgp.h +++ b/include/openpgp.h @@ -18,6 +18,7 @@ #define OPENPGP_INS_GENERATE_ASYMMETRIC_KEY_PAIR 0x47 #define OPENPGP_INS_TERMINATE 0xE6 #define OPENPGP_INS_ACTIVATE 0x44 +#define OPENPGP_INS_GET_CHALLENGE 0x84 #define TAG_AID 0x4F #define TAG_LOGIN 0x5E diff --git a/test-via-pcsc/openpgp_test.go b/test-via-pcsc/openpgp_test.go index 48533b93..09778dce 100644 --- a/test-via-pcsc/openpgp_test.go +++ b/test-via-pcsc/openpgp_test.go @@ -107,6 +107,13 @@ func TestOpenPGPApplet(t *testing.T) { So(res, ShouldResemble, []byte{2, 2, 0x05, 0x3C, 2, 2, 0x05, 0x3C}) // 1340 bytes }) + Convey("Get challenge", func(ctx C) { + res, code, err := app.Send([]byte{0x00, 0x84, 0x00, 0x00, 0x00, 0x05, 0x3C}) + So(err, ShouldBeNil) + So(code, ShouldEqual, 0x9000) + So(len(res), ShouldEqual, 0x53C) // 1340 bytes + }) + Convey("Admin PIN retry times", func(ctx C) { _, code, err := app.Send([]byte{0x00, 0x20, 0x00, 0x83}) So(err, ShouldBeNil)