[Cryptech-Commits] [sw/pkcs11] 03/04: Generalize and extend tests of externally-supplied RSA keys.

git at cryptech.is git at cryptech.is
Thu Jun 16 23:07:48 UTC 2016


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

sra at hactrn.net pushed a commit to branch master
in repository sw/pkcs11.

commit 5bc5ebe683cac561dedcac5d1ec3f6856fa77a52
Author: Rob Austein <sra at hactrn.net>
AuthorDate: Thu Jun 16 16:31:34 2016 -0400

    Generalize and extend tests of externally-supplied RSA keys.
    
    Disable 3416-bit RSA key generation tests while we sort out whether
    simply padding the modulus out to the next 32-bit boundary is
    sufficient to support these with ModExpS6/ModExpA7.
---
 unit_tests.py | 235 +++++++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 169 insertions(+), 66 deletions(-)

diff --git a/unit_tests.py b/unit_tests.py
index 4b02a35..efda5e9 100644
--- a/unit_tests.py
+++ b/unit_tests.py
@@ -11,10 +11,17 @@ import sys
 from py11 import *
 from py11.mutex import MutexDB
 
+try:
+    from Crypto.Util.number import inverse
+    from Crypto.PublicKey   import RSA
+    pycrypto_loaded = True
+except ImportError:
+    pycrypto_loaded = False
+
 
 def log(msg):
     if not args.quiet:
-        sys.stderr.write(msg)
+        sys.stderr.write("{}\n".format(msg))
 
 def main():
     from sys import argv
@@ -72,11 +79,11 @@ def setUpModule():
         cmd = [args.server]
         if geteuid() != 0:
             cmd.insert(0, "sudo")
-        log("Starting RPC server: {}\n".format(" ".join(cmd)))
+        log("Starting RPC server: {}".format(" ".join(cmd)))
         rpc = Popen(cmd, env = dict(environ, CRYPTECH_KEYSTORE = server_keystore))
 
     # Order of PINs here is significant, see p11util for details.
-    log("Setting PINs (SLOW!)\n")
+    log("Setting PINs (SLOW!)")
     if args.wheel_pin is None:
         flags = "-sup"
         pins  = (args.initial_pin, args.so_pin, args.user_pin)
@@ -85,10 +92,10 @@ def setUpModule():
         pins  = (args.initial_pin, args.wheel_pin, args.so_pin, args.user_pin)
     Popen((args.p11util, flags), stdin = PIPE).communicate("".join(pin + "\n" for pin in pins))
 
-    log("Loading PKCS #11 library {}\n".format(args.libpkcs11))
+    log("Loading PKCS #11 library {}".format(args.libpkcs11))
     p11 = PKCS11(args.libpkcs11)
 
-    log("Setup complete\n")
+    log("Setup complete")
 
 
 def tearDownModule():
@@ -122,13 +129,22 @@ class TimedTestCase(unittest.TestCase):
 
     def setUp(self):
         super(TimedTestCase, self).setUp()
+        self.addCleanup(self._print_timing)
         self.startTime = datetime.datetime.now()
 
     def tearDown(self):
         self.endTime = datetime.datetime.now()
-        log("runtime {} seconds ... ".format(self.endTime - self.startTime))
         super(TimedTestCase, self).tearDown()
 
+    def _print_timing(self):
+        try:
+            elapsed = self.endTime - self.startTime
+        except AttributeError:
+            pass
+        else:
+            log("Runtime {}".format(elapsed))
+
+
 class TestInit(TimedTestCase):
     """
     Test all the flavors of C_Initialize().
@@ -444,13 +460,12 @@ class TestKeys(TimedTestCase):
         p11.C_VerifyInit(self.session, CKM_ECDSA_SHA256, o)
         p11.C_Verify(self.session, hamster, sig)
 
-    def extract_rsa_public_key(self, handle):
-        from Crypto.PublicKey import RSA
+    def _extract_rsa_public_key(self, handle):
         a = p11.C_GetAttributeValue(self.session, handle, CKA_MODULUS, CKA_PUBLIC_EXPONENT)
         return RSA.construct((a[CKA_MODULUS], a[CKA_PUBLIC_EXPONENT]))
 
     def assertRawRSASignatureMatches(self, handle, plain, sig):
-        pubkey = self.extract_rsa_public_key(handle)
+        pubkey = self._extract_rsa_public_key(handle)
         result = pubkey.encrypt(sig, 0)[0]
         prefix = "\x00\x01" if False else "\x01" # XXX
         expect = prefix + "\xff" * (len(result) - len(plain) - len(prefix) - 1) + "\x00" + plain
@@ -472,6 +487,8 @@ class TestKeys(TimedTestCase):
 
     def test_gen_sign_verify_tralala_rsa_3416(self):
         "Generate/sign/verify with RSA-3416 (no hashing, message to be signed not a hash at all)"
+        if not args.all_tests:
+            self.skipTest("Key length not a multiple of 32, so expected to fail (very slowly)")
         tralala = "tralala-en-hopsasa"
         public_key, private_key = p11.C_GenerateKeyPair(
             self.session, CKM_RSA_PKCS_KEY_PAIR_GEN, CKA_MODULUS_BITS = 3416,
@@ -484,65 +501,14 @@ class TestKeys(TimedTestCase):
         p11.C_VerifyInit(self.session, CKM_RSA_PKCS, public_key)
         p11.C_Verify(self.session, tralala, sig)
 
-    def test_load_sign_verify_rsa_3416(self):
-        "Load/sign/verify with RSA-3416 and externally-supplied key (no hashing, message to be signed not a hash at all)"
-        from Crypto.Util.number import long_to_bytes, inverse
-        from Crypto.PublicKey   import RSA
-        from textwrap           import dedent
-        k = RSA.importKey(dedent('''\
-            -----BEGIN PRIVATE KEY-----
-            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
-            BvUE7g/dCNw3ISPEAgVJZUHJ
-            -----END PRIVATE KEY-----
-        '''))
-        public_key = p11.C_CreateObject(
-            self.session, CKA_TOKEN = True, CKA_CLASS = CKO_PUBLIC_KEY, CKA_KEY_TYPE = CKK_RSA, CKA_ID = "RSA-3416",
-            CKA_VERIFY          = True,
+    def _load_rsa_keypair(self, pem, cka_id = None):
+        k = RSA.importKey(pem)
+        public = dict(
+            CKA_TOKEN = True, CKA_CLASS = CKO_PUBLIC_KEY, CKA_KEY_TYPE = CKK_RSA, CKA_VERIFY = True,
             CKA_MODULUS         = k.n,
             CKA_PUBLIC_EXPONENT = k.e)
-        private_key = p11.C_CreateObject(
-            self.session, CKA_TOKEN = True, CKA_CLASS = CKO_PRIVATE_KEY, CKA_KEY_TYPE = CKK_RSA, CKA_ID = "RSA-3416",
-            CKA_SIGN            = True,
+        private = dict(
+            CKA_TOKEN = True, CKA_CLASS = CKO_PRIVATE_KEY, CKA_KEY_TYPE = CKK_RSA, CKA_SIGN = True,
             CKA_MODULUS         = k.n,
             CKA_PUBLIC_EXPONENT = k.e,
             CKA_PRIVATE_EXPONENT= k.d,
@@ -551,7 +517,39 @@ class TestKeys(TimedTestCase):
             CKA_COEFFICIENT     = inverse(k.q, k.p),
             CKA_EXPONENT_1      = k.d % (k.p - 1),
             CKA_EXPONENT_2      = k.d % (k.q - 1))
+        if cka_id is not None:
+            public[CKA_ID] = private[CKA_ID] = cka_id
+        public_key  = p11.C_CreateObject(self.session, public)
+        private_key = p11.C_CreateObject(self.session, private)
         self.assertIsKeypair(public_key, private_key)
+        return public_key, private_key
+
+    @unittest.skipUnless(pycrypto_loaded, "requires PyCrypto")
+    def test_load_sign_verify_rsa_1024(self):
+        "Load/sign/verify with RSA-1024-SHA-512 and externally-supplied key"
+        public_key, private_key = self._load_rsa_keypair(rsa_1024_pem, "RSA-1024")
+        hamster = "Your mother was a hamster"
+        p11.C_SignInit(self.session, CKM_SHA512_RSA_PKCS, private_key)
+        sig = p11.C_Sign(self.session, hamster)
+        self.assertIsInstance(sig, str)
+        p11.C_VerifyInit(self.session, CKM_SHA512_RSA_PKCS, public_key)
+        p11.C_Verify(self.session, hamster, sig)
+
+    @unittest.skipUnless(pycrypto_loaded, "requires PyCrypto")
+    def test_load_sign_verify_rsa_2048(self):
+        "Load/sign/verify with RSA-2048-SHA-512 and externally-supplied key"
+        public_key, private_key = self._load_rsa_keypair(rsa_2048_pem, "RSA-2048")
+        hamster = "Your mother was a hamster"
+        p11.C_SignInit(self.session, CKM_SHA512_RSA_PKCS, private_key)
+        sig = p11.C_Sign(self.session, hamster)
+        self.assertIsInstance(sig, str)
+        p11.C_VerifyInit(self.session, CKM_SHA512_RSA_PKCS, public_key)
+        p11.C_Verify(self.session, hamster, sig)
+
+    @unittest.skipUnless(pycrypto_loaded, "requires PyCrypto")
+    def test_load_sign_verify_rsa_3416(self):
+        "Load/sign/verify with RSA-3416-SHA-512 and externally-supplied key"
+        public_key, private_key = self._load_rsa_keypair(rsa_3416_pem, "RSA-3416")
         hamster = "Your mother was a hamster"
         p11.C_SignInit(self.session, CKM_SHA512_RSA_PKCS, private_key)
         sig = p11.C_Sign(self.session, hamster)
@@ -561,6 +559,8 @@ class TestKeys(TimedTestCase):
 
     def test_gen_sign_verify_rsa_3416(self):
         "Generate/sign/verify with RSA-3416-SHA-512"
+        if not args.all_tests:
+            self.skipTest("Key length not a multiple of 32, so expected to fail (very slowly)")
         public_key, private_key = p11.C_GenerateKeyPair(
             self.session, CKM_RSA_PKCS_KEY_PAIR_GEN, CKA_MODULUS_BITS = 3416,
             CKA_ID = "RSA-3416", CKA_SIGN = True, CKA_VERIFY = True, CKA_TOKEN = True)
@@ -592,5 +592,108 @@ class TestKeys(TimedTestCase):
         p11.C_VerifyInit(self.session, CKM_SHA512_RSA_PKCS, public_key)
         p11.C_Verify(self.session, hamster, sig)
 
+
+# Keys for preload tests, here rather than inline because they're
+# bulky.  These are in PKCS #8 format, see PyCrypto or the "pkey" and
+# "genpkey" commands to OpenSSL's command line tool.
+
+rsa_1024_pem = '''\
+-----BEGIN PRIVATE KEY-----
+MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAIwSaEpCTVJvbd4Z
+B1P8H9EgFlZqats7PeBIOlC2Q1zla7wBmNJkX5Jkez8tF3l22Sn99c6c6PuhyhzB
+dZtifQbZniKCJEzyby5MXZeSr20rPdrqiB9FX13mmtLN7ii4nLyAYFAQ4R8ZvdH2
+dRIWtxwhS7d4AyrWYhJkemIvSApfAgMBAAECgYAmL1Zy+AQwNuRSqawPvynFTuQI
+Bta+kTXbEJWlLyrKBlkKVb0djfNn6zCWFmrR2A53nh4Gh0wUXRTGJg8znvPKJPcp
+45znc7aGQFmDivvl5m/UkbqET6SB6JyCOCKzYa1Rtn3YFMkf/3MgzrWIhFv+UNH/
+I5lSjzJcCrN4mgI+AQJBALcTNa0mOWRXX+6jssbf65Cx6wmHsrrptXiP9gKfwdkx
+697EzyvPDL8xwL20O+xBFehj866O/f8nOPP47imOPoECQQDD3gU8wD8MeWLqYcXI
+AdERIuuk1VnL36QOzn9NoPF01DLJcrcbN24i5/9tcza3Kdec8fexJTh/PMBvR8Zr
+w5jfAkAnFgrXtNl7+suYf4qjuxroAZRUrIwUK+F6pAG5/bG9VVMudIZmrAXkrBKi
+beB9SEgNHYnhMtY3q4AVVohChwQBAkAR1I5Jf3691fcJOylUEcZEdxdYhAuOoac/
+qdCw8mvIpOCSshy1H5CpINGB1zEt72MvaF+SAr9n5dHmz3Pir4WlAkB/ZccJ5QBH
+uBP0/flXdmhG5lC3MTMiiE7Rls/3L2t6S4xVDnQ81RYf7Car53WN7qSVSZnhDGsn
+BJpghq2nYUH1
+-----END PRIVATE KEY-----
+'''
+
+rsa_2048_pem = '''\
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCzvgb90hKxeDJy
+zeWz/F4JGZ3Acl1i3url3VPXHyoldyhuNC+8jf4iM7TGBYGLH+sYkBXWu9GD0erl
+KBMJMTBO8OdXulSAJh8r1Z8qNPSVNguvNgGQlRDGc7tZJ6gWFlzM2g5flED24bN9
+6Ir9O1cZi7xMc0Nzkn9Rms5IwPW8OB4IZZlbFC6Ih9vUSp06Tm3rQ/eQJkhLFbzM
+ejc9OH1LSpYtji44ohmy/jPJsmSlzwK5JSchZqbxl/msVw1t/nZS3loqKUMvzn9F
+iARLiaIrUKNCmSmL8HqEt2qKt0ESHG0vX07h5W5iHIJOuKhqcX3li8nFcwsOV3AB
+RsCRgeppAgMBAAECggEANEeTVQRjN4dUdRv6Me23lEIFJlKdYwKfpBhKKIoCAj+0
+XMmFEPzj7CLJ88bqNQMlqFFQaNLcT9Eg12Jelw/dkzhysYuaxGNSMbfCwc4BTd0Y
+bO/yaJFS/cXvujDUrQf4GgVapOZENwrS4E5hDuLRpLaGIF5uQhFcQuoaEgM99m6H
+TzOIhtu3DjdbfSsmkGVQ7xUVFcvaCrMVoq06dvUH4HpYTKeeqgcVv++XjIe83Nzv
++oN5U2oFOzrYpGGHN6jrekmmbEaxy8UHOySC6Y+UyRrPEy9q1ZgkkC9VCrM7E28/
+4PETw8MI7uNoosuFXofctKjtRvC5Sn9zW3dyv9NkAQKBgQDSkdDy4+xN2kA7gdry
+4eLKUzKRNSbnoPrCu2TENUR8oTjbJ52LQEbGa9HIKaM33701hJsc34C6adJgoY9c
+PoBcJgxOI7N40A/rI3c8krKS5X/ViBY3TzJsP3LaBKDdfioaTDVTjhYD6v2eu7Lt
+4eIqa8sVA4PhLSVGRW53ZSYjwQKBgQDahY6cR8WgPseQJTkCbKyfKCSuz6nioZpC
+stkpKhJepzE6AKZTLLWvNIPNT/khl40aby5seLNkY3Tb9cYBX2iShGv4cguPMiAl
+hb7Uljz19i6YaX74gkTjsYpv44ddLSZp+/FTOl0C0I8WocQpb8B2d4BgvfxgHrHb
+KCHnyihQqQKBgQC7PKPixt7hnzdMcrxhCpDiPbaSPgQZJSC1NXJ1sbPzalynKwPA
+xefpGgiRBs02qsGRLBfNRcQuflhuSlqyuHTk+4Qnm0FEJSZyfLfS6dLWIjJYikjO
+56I7dPPIfyMXsM75UVh9srNKypK4qciCFEBKXk1XoyeKe91QLf77NbsDQQKBgDnY
+CLwNs56Lf8AEWmbt5XPr6GntxoabSH5HYXyoClzL3RgBfAWgXCeYuxrqBISD3XIV
+5DAKc1IrkY94K4XJf6DpNLt7VNv+5MuJ783ORyzEkej+ZAHcWef74y1jCT386aI8
+ctEZLe3Ez1uqToa5cjTpxS3WnKvE9EeTBAabWLihAoGBAKft+PG+j+QhZeHSGxRz
+mY6AQHH4z7IU94fmXiT2kTsG8/svhPNfsmVt7UCSJbCaYsrcuR2NonVV8wn/U793
+LcnLAV+WObeduMTBCasJw8IniFwFhhfkxOtmlevExE1I3ENwkRlJ7NdROky4pnd5
+LGmN2EOOlFijEGxBfw+Wb1rQ
+-----END PRIVATE KEY-----
+'''
+
+rsa_3416_pem = '''\
+-----BEGIN PRIVATE KEY-----
+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
+BvUE7g/dCNw3ISPEAgVJZUHJ
+-----END PRIVATE KEY-----
+'''
+
+
 if __name__ == "__main__":
     main()



More information about the Commits mailing list