Пример #1
0
def get_keypair(hostname):
    """Generate a dummy keypair for the given hostname.

    This method generates a dummy DSA keypair for the given hostname.
    It returns a tuple (pub, priv) where "pub" is a dict of values for
    the public key, and "priv" is a DSA128Key object containing the
    private key.  Multiple calls to this method for the same hostname
    are guaranteed to produce the same key.

    To make this work we take advantage of the fact that DSA key generation
    is just "generate x by some random method, where 0 < x < q".  Replace
    "some random method" with "sha1 hash of hostname" and we're all set.
    """
    # Use pre-agreed parameters for p, q and g.
    q = DUMMY_Q
    p = DUMMY_P
    g = DUMMY_G
    # Generate private key x by "some random method".
    x = long(hashlib.sha1(hostname).hexdigest(), 16)
    assert x != 0, "SHA1(hostname) is zero - what are the odds?!"
    # Calculate public key y as usual.
    y = pow(g, x, p)
    data = {
        "algorithm": "DS",
        "p": _hex(p),
        "q": _hex(q),
        "g": _hex(g),
        "y": _hex(y),
        "x": _hex(x),
    }
    privkey = jwt.DS128Key(data)
    del data["x"]
    return data, privkey
    def test_dsa_verification(self):
        # This is a dummy DSA key I generated via PyCrypto.
        # M2Crypto doesn't seem to let me get at the values of x and y.
        # I've line wrapped it for readability.
        def _hex(value):
            return hex(long(value.replace(" ", "").replace("\n", "").strip()))

        data = {
            "p":
            _hex("""6703904104057623261995085583676902361410672713749348
                      7374515589871295072792250899011720632358392764362903244
                      12395020783955234715731001076129344181463063193L"""),
            "q":
            hex(1006478751418673383937866166434285354892250535133L),
            "g":
            _hex("""1801778249650423365253284139284406405780267098493217
                      0320675876307450879812560049234773036938891018778074993
                      01874343843218156663689824126183823813389886834L"""),
            "y":
            _hex("""4148629652526876030475847300836791685289385792662680
                      5886292874741635965095055693693232436255359496594291250
                      77637642734034732001089176915352691113947372211L"""),
            "x":
            hex(487025797851506801093339352420308364866214860934L),
        }
        key = jwt.DS128Key(data)
        data.pop("x")
        pubkey = jwt.DS128Key(data)
        # This key should be able to sign and verify things to itself.
        self.assertTrue(pubkey.verify("hello", key.sign("hello")))
        self.assertFalse(pubkey.verify("HELLO", key.sign("hello")))
        self.assertRaises(Exception, pubkey.sign, "hello")
        # And it should gracefully handle a variety of stupid input:
        #   - signature too long
        self.assertFalse(pubkey.verify("HELLO", "X" * 100))
        #   - "r" value too large
        self.assertFalse(pubkey.verify("HELLO", ("\xFF" * 20) + "\x01" * 20))
        #   - "s" value too large
        self.assertFalse(pubkey.verify("HELLO", "\x01" + ("\xFF" * 20)))
 def _make_keypair(self):
     data = DS128_KEY_DATA.copy()
     key = jwt.DS128Key(data)
     data.pop("x")
     pubkey = FALLBACK_DS128Key(data)
     return key, pubkey