add test for digital signature after keygen
authorNIIBE Yutaka <gniibe@fsij.org>
Thu, 28 Jun 2012 02:06:36 +0000 (11:06 +0900)
committerNIIBE Yutaka <gniibe@fsij.org>
Thu, 28 Jun 2012 02:07:11 +0000 (11:07 +0900)
ChangeLog
test/features/201_keygen.feature [deleted file]
test/features/201_setup_passphrase.feature [new file with mode: 0644]
test/features/202_keygen.feature [new file with mode: 0644]
test/features/203_compute_signature.feature [new file with mode: 0644]
test/features/steps.py
test/gnuk.py
test/rsa_keys.py

index 20086fe..52511a2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,8 +1,11 @@
 2012-06-28  Niibe Yutaka  <gniibe@fsij.org>
 
        * test/gnuk.py (gnuk_token): New method: increment_seq.
-       (icc_send_cmd): Handle timeout.
-       (cmd_genkey): New.
+       (gnuk_token.icc_send_cmd): Handle timeout.
+       (gnuk_token.cmd_genkey): New.
+       (gnuk_token.cmd_get_public_key): New.
+
+       * test/rsa_keys.py (verify_signature): New.
 
 2012-06-27  Niibe Yutaka  <gniibe@fsij.org>
 
diff --git a/test/features/201_keygen.feature b/test/features/201_keygen.feature
deleted file mode 100644 (file)
index 472ccde..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-@keygen
-Feature: key generation
-  In order to use a token
-  A token should have keys
-
-  Scenario: generate OPENPGP.1 key (sign)
-     When generating a key of OPENPGP.1
-     And put the first data to c7
-     And put the second data to ce
-     Then it should get success
-
-  Scenario: generate OPENPGP.2 key (decrypt)
-     When generating a key of OPENPGP.2
-     And put the first data to c8
-     And put the second data to cf
-     Then it should get success
-
-  Scenario: generate OPENPGP.3 key (authentication)
-     When generating a key of OPENPGP.3
-     And put the first data to c9
-     And put the second data to d0
-     Then it should get success
diff --git a/test/features/201_setup_passphrase.feature b/test/features/201_setup_passphrase.feature
new file mode 100644 (file)
index 0000000..554c169
--- /dev/null
@@ -0,0 +1,32 @@
+@keygen
+Feature: setup pass phrase
+  In order to conform OpenPGP card 2.0 specification
+  A token should support pass phrase: PW1, PW3 and reset code
+
+  Scenario: setup PW1 (admin-full mode)
+     Given cmd_change_reference_data with 1 and "123456user pass phrase"
+     Then it should get success
+
+  Scenario: verify PW1 (1)
+     Given cmd_verify with 1 and "user pass phrase"
+     Then it should get success
+
+  Scenario: verify PW1 (2)
+     Given cmd_verify with 2 and "user pass phrase"
+     Then it should get success
+
+  Scenario: setup reset code (in admin-full mode)
+     Given cmd_put_data with d3 and "example reset code 000"
+     Then it should get success
+
+  Scenario: reset pass phrase by reset code (in admin-full mode)
+     Given cmd_reset_retry_counter with 0 and "example reset code 000new user pass phrase"
+     Then it should get success
+
+  Scenario: verify PW1 (1) again
+     Given cmd_verify with 1 and "new user pass phrase"
+     Then it should get success
+
+  Scenario: verify PW1 (2) again
+     Given cmd_verify with 2 and "new user pass phrase"
+     Then it should get success
diff --git a/test/features/202_keygen.feature b/test/features/202_keygen.feature
new file mode 100644 (file)
index 0000000..53e6628
--- /dev/null
@@ -0,0 +1,30 @@
+@keygen
+Feature: key generation
+  In order to use a token
+  A token should have keys
+
+  Scenario: generate OPENPGP.1 key (sign)
+     When generating a key of OPENPGP.1
+     And put the first data to c7
+     And put the second data to ce
+     Then it should get success
+
+  Scenario: generate OPENPGP.2 key (decrypt)
+     When generating a key of OPENPGP.2
+     And put the first data to c8
+     And put the second data to cf
+     Then it should get success
+
+  Scenario: generate OPENPGP.3 key (authentication)
+     When generating a key of OPENPGP.3
+     And put the first data to c9
+     And put the second data to d0
+     Then it should get success
+
+  Scenario: verify PW1 (1) after genkey
+     Given cmd_verify with 1 and "new user pass phrase"
+     Then it should get success
+
+  Scenario: verify PW1 (2) after genkey
+     Given cmd_verify with 2 and "new user pass phrase"
+     Then it should get success
diff --git a/test/features/203_compute_signature.feature b/test/features/203_compute_signature.feature
new file mode 100644 (file)
index 0000000..d7bc959
--- /dev/null
@@ -0,0 +1,36 @@
+@keygen
+Feature: compute digital signature
+  In order to use a token
+  A token should compute digital signature properly
+
+  Scenario: compute digital signature by OPENPGP.1 key (1)
+     Given a message "This is a test message."
+     And a public key from token for OPENPGP.1
+     And let a token compute digital signature
+     And verify signature
+     Then it should get success
+
+  Scenario: compute digital signature by OPENPGP.1 key (2)
+     Given a message "This is another test message.\nMultiple lines.\n"
+     And a public key from token for OPENPGP.1
+     And let a token compute digital signature
+     And verify signature
+     Then it should get success
+
+  Scenario: compute digital signature by OPENPGP.3 key (1)
+     Given a message "This is a test message."
+     And a public key from token for OPENPGP.3
+     And let a token authenticate
+     And verify signature
+     Then it should get success
+
+  Scenario: compute digital signature by OPENPGP.3 key (2)
+     Given a message "This is another test message.\nMultiple lines.\n"
+     And a public key from token for OPENPGP.3
+     And let a token authenticate
+     And verify signature
+     Then it should get success
+
+  Scenario: data object ds counter
+     When requesting ds counter: 93
+     Then you should get: \x00\x00\x02
index 030577e..dff6339 100644 (file)
@@ -69,6 +69,15 @@ def set_msg(content_str_repr):
     msg = ast.literal_eval(content_str_repr)
     scc.digestinfo = rsa_keys.compute_digestinfo(msg)
 
+@Given("a public key from token for OPENPGP.(.*)")
+def get_public_key(openpgp_keyno_str):
+    openpgp_keyno = int(openpgp_keyno_str)
+    scc.pubkey_info = ftc.token.cmd_get_public_key(openpgp_keyno)
+
+@Given("verify signature")
+def verify_signature():
+    scc.result = rsa_keys.verify_signature(scc.pubkey_info, scc.digestinfo, scc.sig)
+
 @Given("let a token compute digital signature")
 def compute_signature():
     scc.sig = int(hexlify(ftc.token.cmd_pso(0x9e, 0x9a, scc.digestinfo)),16)
index d6564dd..a334678 100644 (file)
@@ -344,6 +344,22 @@ class gnuk_token(object):
         pk = self.cmd_get_response(sw[1])
         return (pk[9:9+256], pk[9+256+2:9+256+2+3])
 
+    def cmd_get_public_key(self, keyno):
+        if keyno == 1:
+            data = '\xb6\x00'
+        elif keyno == 2:
+            data = '\xb8\x00'
+        else:
+            data = '\xa4\x00'
+        cmd_data = iso7816_compose(0x47, 0x81, 0, data)
+        sw = self.icc_send_cmd(cmd_data)
+        if len(sw) != 2:
+            raise ValueError(sw)
+        elif sw[0] != 0x61:
+            raise ValueError("%02x%02x" % (sw[0], sw[1]))
+        pk = self.cmd_get_response(sw[1])
+        return (pk[9:9+256], pk[9+256+2:9+256+2+3])
+
 
 def compare(data_original, data_in_device):
     i = 0 
index a130377..2193026 100644 (file)
@@ -137,3 +137,10 @@ def encrypt(keyno, plaintext):
     n = key[keyno][7]
     m = pkcs1_pad_for_crypt(plaintext)
     return '\x00' + integer_to_bytes(pow(m, e, n))
+
+def verify_signature(pubkey_info, digestinfo, sig):
+    n = int(hexlify(pubkey_info[0]), 16)
+    e = int(hexlify(pubkey_info[1]), 16)
+    di_pkcs1 = pow(sig,e,n)
+    m = pkcs1_pad_for_sign(digestinfo)
+    return di_pkcs1 == m