Updated DB_Helper by adding firebase methods.
This commit is contained in:
parent
485cc3bbba
commit
c82121d036
1810 changed files with 537281 additions and 1 deletions
54
venv/Lib/site-packages/Crypto/SelfTest/PublicKey/__init__.py
Normal file
54
venv/Lib/site-packages/Crypto/SelfTest/PublicKey/__init__.py
Normal file
|
@ -0,0 +1,54 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# SelfTest/PublicKey/__init__.py: Self-test for public key crypto
|
||||
#
|
||||
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
|
||||
#
|
||||
# ===================================================================
|
||||
# The contents of this file are dedicated to the public domain. To
|
||||
# the extent that dedication to the public domain is not available,
|
||||
# everyone is granted a worldwide, perpetual, royalty-free,
|
||||
# non-exclusive license to exercise all rights associated with the
|
||||
# contents of this file for any purpose whatsoever.
|
||||
# No rights are reserved.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
# ===================================================================
|
||||
|
||||
"""Self-test for public-key crypto"""
|
||||
|
||||
__revision__ = "$Id$"
|
||||
|
||||
import os
|
||||
|
||||
def get_tests(config={}):
|
||||
tests = []
|
||||
from Crypto.SelfTest.PublicKey import test_DSA; tests += test_DSA.get_tests(config=config)
|
||||
from Crypto.SelfTest.PublicKey import test_RSA; tests += test_RSA.get_tests(config=config)
|
||||
from Crypto.SelfTest.PublicKey import test_ECC; tests += test_ECC.get_tests(config=config)
|
||||
|
||||
from Crypto.SelfTest.PublicKey import test_import_DSA
|
||||
tests +=test_import_DSA.get_tests(config=config)
|
||||
|
||||
from Crypto.SelfTest.PublicKey import test_import_RSA
|
||||
tests += test_import_RSA.get_tests(config=config)
|
||||
|
||||
from Crypto.SelfTest.PublicKey import test_import_ECC
|
||||
tests += test_import_ECC.get_tests(config=config)
|
||||
|
||||
from Crypto.SelfTest.PublicKey import test_ElGamal; tests += test_ElGamal.get_tests(config=config)
|
||||
return tests
|
||||
|
||||
if __name__ == '__main__':
|
||||
import unittest
|
||||
suite = lambda: unittest.TestSuite(get_tests())
|
||||
unittest.main(defaultTest='suite')
|
||||
|
||||
# vim:set ts=4 sw=4 sts=4 expandtab:
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
240
venv/Lib/site-packages/Crypto/SelfTest/PublicKey/test_DSA.py
Normal file
240
venv/Lib/site-packages/Crypto/SelfTest/PublicKey/test_DSA.py
Normal file
|
@ -0,0 +1,240 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# SelfTest/PublicKey/test_DSA.py: Self-test for the DSA primitive
|
||||
#
|
||||
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
|
||||
#
|
||||
# ===================================================================
|
||||
# The contents of this file are dedicated to the public domain. To
|
||||
# the extent that dedication to the public domain is not available,
|
||||
# everyone is granted a worldwide, perpetual, royalty-free,
|
||||
# non-exclusive license to exercise all rights associated with the
|
||||
# contents of this file for any purpose whatsoever.
|
||||
# No rights are reserved.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
# ===================================================================
|
||||
|
||||
"""Self-test suite for Crypto.PublicKey.DSA"""
|
||||
|
||||
import os
|
||||
from Crypto.Util.py3compat import *
|
||||
|
||||
import unittest
|
||||
from Crypto.SelfTest.st_common import list_test_cases, a2b_hex, b2a_hex
|
||||
|
||||
def _sws(s):
|
||||
"""Remove whitespace from a text or byte string"""
|
||||
if isinstance(s,str):
|
||||
return "".join(s.split())
|
||||
else:
|
||||
return b("").join(s.split())
|
||||
|
||||
class DSATest(unittest.TestCase):
|
||||
# Test vector from "Appendix 5. Example of the DSA" of
|
||||
# "Digital Signature Standard (DSS)",
|
||||
# U.S. Department of Commerce/National Institute of Standards and Technology
|
||||
# FIPS 186-2 (+Change Notice), 2000 January 27.
|
||||
# http://csrc.nist.gov/publications/fips/fips186-2/fips186-2-change1.pdf
|
||||
|
||||
y = _sws("""19131871 d75b1612 a819f29d 78d1b0d7 346f7aa7 7bb62a85
|
||||
9bfd6c56 75da9d21 2d3a36ef 1672ef66 0b8c7c25 5cc0ec74
|
||||
858fba33 f44c0669 9630a76b 030ee333""")
|
||||
|
||||
g = _sws("""626d0278 39ea0a13 413163a5 5b4cb500 299d5522 956cefcb
|
||||
3bff10f3 99ce2c2e 71cb9de5 fa24babf 58e5b795 21925c9c
|
||||
c42e9f6f 464b088c c572af53 e6d78802""")
|
||||
|
||||
p = _sws("""8df2a494 492276aa 3d25759b b06869cb eac0d83a fb8d0cf7
|
||||
cbb8324f 0d7882e5 d0762fc5 b7210eaf c2e9adac 32ab7aac
|
||||
49693dfb f83724c2 ec0736ee 31c80291""")
|
||||
|
||||
q = _sws("""c773218c 737ec8ee 993b4f2d ed30f48e dace915f""")
|
||||
|
||||
x = _sws("""2070b322 3dba372f de1c0ffc 7b2e3b49 8b260614""")
|
||||
|
||||
k = _sws("""358dad57 1462710f 50e254cf 1a376b2b deaadfbf""")
|
||||
k_inverse = _sws("""0d516729 8202e49b 4116ac10 4fc3f415 ae52f917""")
|
||||
m = b2a_hex(b("abc"))
|
||||
m_hash = _sws("""a9993e36 4706816a ba3e2571 7850c26c 9cd0d89d""")
|
||||
r = _sws("""8bac1ab6 6410435c b7181f95 b16ab97c 92b341c0""")
|
||||
s = _sws("""41e2345f 1f56df24 58f426d1 55b4ba2d b6dcd8c8""")
|
||||
|
||||
def setUp(self):
|
||||
global DSA, Random, bytes_to_long, size
|
||||
from Crypto.PublicKey import DSA
|
||||
from Crypto import Random
|
||||
from Crypto.Util.number import bytes_to_long, inverse, size
|
||||
|
||||
self.dsa = DSA
|
||||
|
||||
def test_generate_1arg(self):
|
||||
"""DSA (default implementation) generated key (1 argument)"""
|
||||
dsaObj = self.dsa.generate(1024)
|
||||
self._check_private_key(dsaObj)
|
||||
pub = dsaObj.publickey()
|
||||
self._check_public_key(pub)
|
||||
|
||||
def test_generate_2arg(self):
|
||||
"""DSA (default implementation) generated key (2 arguments)"""
|
||||
dsaObj = self.dsa.generate(1024, Random.new().read)
|
||||
self._check_private_key(dsaObj)
|
||||
pub = dsaObj.publickey()
|
||||
self._check_public_key(pub)
|
||||
|
||||
def test_construct_4tuple(self):
|
||||
"""DSA (default implementation) constructed key (4-tuple)"""
|
||||
(y, g, p, q) = [bytes_to_long(a2b_hex(param)) for param in (self.y, self.g, self.p, self.q)]
|
||||
dsaObj = self.dsa.construct((y, g, p, q))
|
||||
self._test_verification(dsaObj)
|
||||
|
||||
def test_construct_5tuple(self):
|
||||
"""DSA (default implementation) constructed key (5-tuple)"""
|
||||
(y, g, p, q, x) = [bytes_to_long(a2b_hex(param)) for param in (self.y, self.g, self.p, self.q, self.x)]
|
||||
dsaObj = self.dsa.construct((y, g, p, q, x))
|
||||
self._test_signing(dsaObj)
|
||||
self._test_verification(dsaObj)
|
||||
|
||||
def test_construct_bad_key4(self):
|
||||
(y, g, p, q) = [bytes_to_long(a2b_hex(param)) for param in (self.y, self.g, self.p, self.q)]
|
||||
tup = (y, g, p+1, q)
|
||||
self.assertRaises(ValueError, self.dsa.construct, tup)
|
||||
|
||||
tup = (y, g, p, q+1)
|
||||
self.assertRaises(ValueError, self.dsa.construct, tup)
|
||||
|
||||
tup = (y, 1, p, q)
|
||||
self.assertRaises(ValueError, self.dsa.construct, tup)
|
||||
|
||||
def test_construct_bad_key5(self):
|
||||
(y, g, p, q, x) = [bytes_to_long(a2b_hex(param)) for param in (self.y, self.g, self.p, self.q, self.x)]
|
||||
tup = (y, g, p, q, x+1)
|
||||
self.assertRaises(ValueError, self.dsa.construct, tup)
|
||||
|
||||
tup = (y, g, p, q, q+10)
|
||||
self.assertRaises(ValueError, self.dsa.construct, tup)
|
||||
|
||||
def _check_private_key(self, dsaObj):
|
||||
# Check capabilities
|
||||
self.assertEqual(1, dsaObj.has_private())
|
||||
self.assertEqual(1, dsaObj.can_sign())
|
||||
self.assertEqual(0, dsaObj.can_encrypt())
|
||||
|
||||
# Sanity check key data
|
||||
self.assertEqual(1, dsaObj.p > dsaObj.q) # p > q
|
||||
self.assertEqual(160, size(dsaObj.q)) # size(q) == 160 bits
|
||||
self.assertEqual(0, (dsaObj.p - 1) % dsaObj.q) # q is a divisor of p-1
|
||||
self.assertEqual(dsaObj.y, pow(dsaObj.g, dsaObj.x, dsaObj.p)) # y == g**x mod p
|
||||
self.assertEqual(1, 0 < dsaObj.x < dsaObj.q) # 0 < x < q
|
||||
|
||||
def _check_public_key(self, dsaObj):
|
||||
k = bytes_to_long(a2b_hex(self.k))
|
||||
m_hash = bytes_to_long(a2b_hex(self.m_hash))
|
||||
|
||||
# Check capabilities
|
||||
self.assertEqual(0, dsaObj.has_private())
|
||||
self.assertEqual(1, dsaObj.can_sign())
|
||||
self.assertEqual(0, dsaObj.can_encrypt())
|
||||
|
||||
# Check that private parameters are all missing
|
||||
self.assertEqual(0, hasattr(dsaObj, 'x'))
|
||||
|
||||
# Sanity check key data
|
||||
self.assertEqual(1, dsaObj.p > dsaObj.q) # p > q
|
||||
self.assertEqual(160, size(dsaObj.q)) # size(q) == 160 bits
|
||||
self.assertEqual(0, (dsaObj.p - 1) % dsaObj.q) # q is a divisor of p-1
|
||||
|
||||
# Public-only key objects should raise an error when .sign() is called
|
||||
self.assertRaises(TypeError, dsaObj._sign, m_hash, k)
|
||||
|
||||
# Check __eq__ and __ne__
|
||||
self.assertEqual(dsaObj.publickey() == dsaObj.publickey(),True) # assert_
|
||||
self.assertEqual(dsaObj.publickey() != dsaObj.publickey(),False) # failIf
|
||||
|
||||
def _test_signing(self, dsaObj):
|
||||
k = bytes_to_long(a2b_hex(self.k))
|
||||
m_hash = bytes_to_long(a2b_hex(self.m_hash))
|
||||
r = bytes_to_long(a2b_hex(self.r))
|
||||
s = bytes_to_long(a2b_hex(self.s))
|
||||
(r_out, s_out) = dsaObj._sign(m_hash, k)
|
||||
self.assertEqual((r, s), (r_out, s_out))
|
||||
|
||||
def _test_verification(self, dsaObj):
|
||||
m_hash = bytes_to_long(a2b_hex(self.m_hash))
|
||||
r = bytes_to_long(a2b_hex(self.r))
|
||||
s = bytes_to_long(a2b_hex(self.s))
|
||||
self.assertTrue(dsaObj._verify(m_hash, (r, s)))
|
||||
self.assertFalse(dsaObj._verify(m_hash + 1, (r, s)))
|
||||
|
||||
|
||||
class DSADomainTest(unittest.TestCase):
|
||||
|
||||
def test_domain1(self):
|
||||
"""Verify we can generate new keys in a given domain"""
|
||||
dsa_key_1 = DSA.generate(1024)
|
||||
domain_params = dsa_key_1.domain()
|
||||
|
||||
dsa_key_2 = DSA.generate(1024, domain=domain_params)
|
||||
self.assertEqual(dsa_key_1.p, dsa_key_2.p)
|
||||
self.assertEqual(dsa_key_1.q, dsa_key_2.q)
|
||||
self.assertEqual(dsa_key_1.g, dsa_key_2.g)
|
||||
|
||||
self.assertEqual(dsa_key_1.domain(), dsa_key_2.domain())
|
||||
|
||||
def _get_weak_domain(self):
|
||||
|
||||
from Crypto.Math.Numbers import Integer
|
||||
from Crypto.Math import Primality
|
||||
|
||||
p = Integer(4)
|
||||
while p.size_in_bits() != 1024 or Primality.test_probable_prime(p) != Primality.PROBABLY_PRIME:
|
||||
q1 = Integer.random(exact_bits=80)
|
||||
q2 = Integer.random(exact_bits=80)
|
||||
q = q1 * q2
|
||||
z = Integer.random(exact_bits=1024-160)
|
||||
p = z * q + 1
|
||||
|
||||
h = Integer(2)
|
||||
g = 1
|
||||
while g == 1:
|
||||
g = pow(h, z, p)
|
||||
h += 1
|
||||
|
||||
return (p, q, g)
|
||||
|
||||
|
||||
def test_generate_error_weak_domain(self):
|
||||
"""Verify that domain parameters with composite q are rejected"""
|
||||
|
||||
domain_params = self._get_weak_domain()
|
||||
self.assertRaises(ValueError, DSA.generate, 1024, domain=domain_params)
|
||||
|
||||
|
||||
def test_construct_error_weak_domain(self):
|
||||
"""Verify that domain parameters with composite q are rejected"""
|
||||
|
||||
from Crypto.Math.Numbers import Integer
|
||||
|
||||
p, q, g = self._get_weak_domain()
|
||||
y = pow(g, 89, p)
|
||||
self.assertRaises(ValueError, DSA.construct, (y, g, p, q))
|
||||
|
||||
|
||||
def get_tests(config={}):
|
||||
tests = []
|
||||
tests += list_test_cases(DSATest)
|
||||
tests += list_test_cases(DSADomainTest)
|
||||
return tests
|
||||
|
||||
if __name__ == '__main__':
|
||||
suite = lambda: unittest.TestSuite(get_tests())
|
||||
unittest.main(defaultTest='suite')
|
||||
|
||||
# vim:set ts=4 sw=4 sts=4 expandtab:
|
284
venv/Lib/site-packages/Crypto/SelfTest/PublicKey/test_ECC.py
Normal file
284
venv/Lib/site-packages/Crypto/SelfTest/PublicKey/test_ECC.py
Normal file
|
@ -0,0 +1,284 @@
|
|||
# ===================================================================
|
||||
#
|
||||
# Copyright (c) 2015, Legrandin <helderijs@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
# ===================================================================
|
||||
|
||||
import unittest
|
||||
import time
|
||||
from Crypto.SelfTest.st_common import list_test_cases
|
||||
from Crypto.SelfTest.loader import load_tests
|
||||
|
||||
from Crypto.PublicKey import ECC
|
||||
from Crypto.PublicKey.ECC import EccPoint, _curve, EccKey
|
||||
|
||||
class TestEccPoint_NIST(unittest.TestCase):
|
||||
"""Tests defined in section 4.3 of https://www.nsa.gov/ia/_files/nist-routines.pdf"""
|
||||
|
||||
pointS = EccPoint(
|
||||
0xde2444bebc8d36e682edd27e0f271508617519b3221a8fa0b77cab3989da97c9,
|
||||
0xc093ae7ff36e5380fc01a5aad1e66659702de80f53cec576b6350b243042a256)
|
||||
|
||||
pointT = EccPoint(
|
||||
0x55a8b00f8da1d44e62f6b3b25316212e39540dc861c89575bb8cf92e35e0986b,
|
||||
0x5421c3209c2d6c704835d82ac4c3dd90f61a8a52598b9e7ab656e9d8c8b24316)
|
||||
|
||||
def test_set(self):
|
||||
pointW = EccPoint(0, 0)
|
||||
pointW.set(self.pointS)
|
||||
self.assertEqual(pointW, self.pointS)
|
||||
|
||||
def test_copy(self):
|
||||
pointW = self.pointS.copy()
|
||||
self.assertEqual(pointW, self.pointS)
|
||||
pointW.set(self.pointT)
|
||||
self.assertEqual(pointW, self.pointT)
|
||||
self.assertNotEqual(self.pointS, self.pointT)
|
||||
|
||||
def test_addition(self):
|
||||
pointRx = 0x72b13dd4354b6b81745195e98cc5ba6970349191ac476bd4553cf35a545a067e
|
||||
pointRy = 0x8d585cbb2e1327d75241a8a122d7620dc33b13315aa5c9d46d013011744ac264
|
||||
|
||||
pointR = self.pointS + self.pointT
|
||||
self.assertEqual(pointR.x, pointRx)
|
||||
self.assertEqual(pointR.y, pointRy)
|
||||
|
||||
pai = EccPoint.point_at_infinity()
|
||||
|
||||
# S + 0
|
||||
pointR = self.pointS + pai
|
||||
self.assertEqual(pointR, self.pointS)
|
||||
|
||||
# 0 + S
|
||||
pointR = pai + self.pointS
|
||||
self.assertEqual(pointR, self.pointS)
|
||||
|
||||
# 0 + 0
|
||||
pointR = pai + pai
|
||||
self.assertEqual(pointR, pai)
|
||||
|
||||
def test_inplace_addition(self):
|
||||
pointRx = 0x72b13dd4354b6b81745195e98cc5ba6970349191ac476bd4553cf35a545a067e
|
||||
pointRy = 0x8d585cbb2e1327d75241a8a122d7620dc33b13315aa5c9d46d013011744ac264
|
||||
|
||||
pointR = self.pointS.copy()
|
||||
pointR += self.pointT
|
||||
self.assertEqual(pointR.x, pointRx)
|
||||
self.assertEqual(pointR.y, pointRy)
|
||||
|
||||
pai = EccPoint.point_at_infinity()
|
||||
|
||||
# S + 0
|
||||
pointR = self.pointS.copy()
|
||||
pointR += pai
|
||||
self.assertEqual(pointR, self.pointS)
|
||||
|
||||
# 0 + S
|
||||
pointR = pai.copy()
|
||||
pointR += self.pointS
|
||||
self.assertEqual(pointR, self.pointS)
|
||||
|
||||
# 0 + 0
|
||||
pointR = pai.copy()
|
||||
pointR += pai
|
||||
self.assertEqual(pointR, pai)
|
||||
|
||||
def test_doubling(self):
|
||||
pointRx = 0x7669e6901606ee3ba1a8eef1e0024c33df6c22f3b17481b82a860ffcdb6127b0
|
||||
pointRy = 0xfa878162187a54f6c39f6ee0072f33de389ef3eecd03023de10ca2c1db61d0c7
|
||||
|
||||
pointR = self.pointS.copy()
|
||||
pointR.double()
|
||||
self.assertEqual(pointR.x, pointRx)
|
||||
self.assertEqual(pointR.y, pointRy)
|
||||
|
||||
# 2*0
|
||||
pai = self.pointS.point_at_infinity()
|
||||
pointR = pai.copy()
|
||||
pointR.double()
|
||||
self.assertEqual(pointR, pai)
|
||||
|
||||
# S + S
|
||||
pointR = self.pointS.copy()
|
||||
pointR += pointR
|
||||
self.assertEqual(pointR.x, pointRx)
|
||||
self.assertEqual(pointR.y, pointRy)
|
||||
|
||||
def test_scalar_multiply(self):
|
||||
d = 0xc51e4753afdec1e6b6c6a5b992f43f8dd0c7a8933072708b6522468b2ffb06fd
|
||||
pointRx = 0x51d08d5f2d4278882946d88d83c97d11e62becc3cfc18bedacc89ba34eeca03f
|
||||
pointRy = 0x75ee68eb8bf626aa5b673ab51f6e744e06f8fcf8a6c0cf3035beca956a7b41d5
|
||||
|
||||
pointR = self.pointS * d
|
||||
self.assertEqual(pointR.x, pointRx)
|
||||
self.assertEqual(pointR.y, pointRy)
|
||||
|
||||
# 0*S
|
||||
pai = self.pointS.point_at_infinity()
|
||||
pointR = self.pointS * 0
|
||||
self.assertEqual(pointR, pai)
|
||||
|
||||
# -1*S
|
||||
self.assertRaises(ValueError, lambda: self.pointS * -1)
|
||||
|
||||
def test_joing_scalar_multiply(self):
|
||||
d = 0xc51e4753afdec1e6b6c6a5b992f43f8dd0c7a8933072708b6522468b2ffb06fd
|
||||
e = 0xd37f628ece72a462f0145cbefe3f0b355ee8332d37acdd83a358016aea029db7
|
||||
pointRx = 0xd867b4679221009234939221b8046245efcf58413daacbeff857b8588341f6b8
|
||||
pointRy = 0xf2504055c03cede12d22720dad69c745106b6607ec7e50dd35d54bd80f615275
|
||||
|
||||
pointR = self.pointS * d + self.pointT * e
|
||||
self.assertEqual(pointR.x, pointRx)
|
||||
self.assertEqual(pointR.y, pointRy)
|
||||
|
||||
|
||||
class TestEccPoint_PAI(unittest.TestCase):
|
||||
"""Test vectors from http://point-at-infinity.org/ecc/nisttv"""
|
||||
|
||||
pointG = EccPoint(_curve.Gx, _curve.Gy)
|
||||
|
||||
|
||||
tv_pai = load_tests(("Crypto", "SelfTest", "PublicKey", "test_vectors", "ECC"),
|
||||
"point-at-infinity.org-P256.txt",
|
||||
"P-256 tests from point-at-infinity.org",
|
||||
{ "k" : lambda k: int(k),
|
||||
"x" : lambda x: int(x, 16),
|
||||
"y" : lambda y: int(y, 16)} )
|
||||
assert(tv_pai)
|
||||
for tv in tv_pai:
|
||||
def new_test(self, scalar=tv.k, x=tv.x, y=tv.y):
|
||||
result = self.pointG * scalar
|
||||
self.assertEqual(result.x, x)
|
||||
self.assertEqual(result.y, y)
|
||||
setattr(TestEccPoint_PAI, "test_%d" % tv.count, new_test)
|
||||
|
||||
|
||||
class TestEccKey(unittest.TestCase):
|
||||
|
||||
def test_private_key(self):
|
||||
|
||||
key = EccKey(curve="P-256", d=1)
|
||||
self.assertEqual(key.d, 1)
|
||||
self.assertTrue(key.has_private())
|
||||
self.assertEqual(key.pointQ.x, _curve.Gx)
|
||||
self.assertEqual(key.pointQ.y, _curve.Gy)
|
||||
|
||||
point = EccPoint(_curve.Gx, _curve.Gy)
|
||||
key = EccKey(curve="P-256", d=1, point=point)
|
||||
self.assertEqual(key.d, 1)
|
||||
self.assertTrue(key.has_private())
|
||||
self.assertEqual(key.pointQ, point)
|
||||
|
||||
# Other names
|
||||
key = EccKey(curve="secp256r1", d=1)
|
||||
key = EccKey(curve="prime256v1", d=1)
|
||||
|
||||
def test_public_key(self):
|
||||
|
||||
point = EccPoint(_curve.Gx, _curve.Gy)
|
||||
key = EccKey(curve="P-256", point=point)
|
||||
self.assertFalse(key.has_private())
|
||||
self.assertEqual(key.pointQ, point)
|
||||
|
||||
def test_public_key_derived(self):
|
||||
|
||||
priv_key = EccKey(curve="P-256", d=3)
|
||||
pub_key = priv_key.public_key()
|
||||
self.assertFalse(pub_key.has_private())
|
||||
self.assertEqual(priv_key.pointQ, pub_key.pointQ)
|
||||
|
||||
def test_invalid_curve(self):
|
||||
self.assertRaises(ValueError, lambda: EccKey(curve="P-257", d=1))
|
||||
|
||||
def test_invalid_d(self):
|
||||
self.assertRaises(ValueError, lambda: EccKey(curve="P-256", d=0))
|
||||
self.assertRaises(ValueError, lambda: EccKey(curve="P-256", d=_curve.order))
|
||||
|
||||
def test_equality(self):
|
||||
|
||||
private_key = ECC.construct(d=3, curve="P-256")
|
||||
private_key2 = ECC.construct(d=3, curve="P-256")
|
||||
private_key3 = ECC.construct(d=4, curve="P-256")
|
||||
|
||||
public_key = private_key.public_key()
|
||||
public_key2 = private_key2.public_key()
|
||||
public_key3 = private_key3.public_key()
|
||||
|
||||
self.assertEqual(private_key, private_key2)
|
||||
self.assertNotEqual(private_key, private_key3)
|
||||
|
||||
self.assertEqual(public_key, public_key2)
|
||||
self.assertNotEqual(public_key, public_key3)
|
||||
|
||||
self.assertNotEqual(public_key, private_key)
|
||||
|
||||
|
||||
class TestEccModule(unittest.TestCase):
|
||||
|
||||
def test_generate(self):
|
||||
|
||||
key = ECC.generate(curve="P-256")
|
||||
self.assertTrue(key.has_private())
|
||||
self.assertEqual(key.pointQ, EccPoint(_curve.Gx, _curve.Gy) * key.d)
|
||||
|
||||
# Other names
|
||||
ECC.generate(curve="secp256r1")
|
||||
ECC.generate(curve="prime256v1")
|
||||
|
||||
def test_construct(self):
|
||||
|
||||
key = ECC.construct(curve="P-256", d=1)
|
||||
self.assertTrue(key.has_private())
|
||||
self.assertEqual(key.pointQ, _curve.G)
|
||||
|
||||
key = ECC.construct(curve="P-256", point_x=_curve.Gx, point_y=_curve.Gy)
|
||||
self.assertFalse(key.has_private())
|
||||
self.assertEqual(key.pointQ, _curve.G)
|
||||
|
||||
# Other names
|
||||
ECC.construct(curve="secp256r1", d=1)
|
||||
ECC.construct(curve="prime256v1", d=1)
|
||||
|
||||
def test_negative_construct(self):
|
||||
coord = dict(point_x=10, point_y=4)
|
||||
coordG = dict(point_x=_curve.Gx, point_y=_curve.Gy)
|
||||
|
||||
self.assertRaises(ValueError, ECC.construct, curve="P-256", **coord)
|
||||
self.assertRaises(ValueError, ECC.construct, curve="P-256", d=2, **coordG)
|
||||
|
||||
|
||||
def get_tests(config={}):
|
||||
tests = []
|
||||
tests += list_test_cases(TestEccPoint_NIST)
|
||||
tests += list_test_cases(TestEccPoint_PAI)
|
||||
tests += list_test_cases(TestEccKey)
|
||||
tests += list_test_cases(TestEccModule)
|
||||
return tests
|
||||
|
||||
if __name__ == '__main__':
|
||||
suite = lambda: unittest.TestSuite(get_tests())
|
||||
unittest.main(defaultTest='suite')
|
217
venv/Lib/site-packages/Crypto/SelfTest/PublicKey/test_ElGamal.py
Normal file
217
venv/Lib/site-packages/Crypto/SelfTest/PublicKey/test_ElGamal.py
Normal file
|
@ -0,0 +1,217 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# SelfTest/PublicKey/test_ElGamal.py: Self-test for the ElGamal primitive
|
||||
#
|
||||
# ===================================================================
|
||||
# The contents of this file are dedicated to the public domain. To
|
||||
# the extent that dedication to the public domain is not available,
|
||||
# everyone is granted a worldwide, perpetual, royalty-free,
|
||||
# non-exclusive license to exercise all rights associated with the
|
||||
# contents of this file for any purpose whatsoever.
|
||||
# No rights are reserved.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
# ===================================================================
|
||||
|
||||
"""Self-test suite for Crypto.PublicKey.ElGamal"""
|
||||
|
||||
__revision__ = "$Id$"
|
||||
|
||||
import unittest
|
||||
from Crypto.SelfTest.st_common import list_test_cases, a2b_hex, b2a_hex
|
||||
from Crypto import Random
|
||||
from Crypto.PublicKey import ElGamal
|
||||
from Crypto.Util.number import bytes_to_long
|
||||
from Crypto.Util.py3compat import *
|
||||
|
||||
class ElGamalTest(unittest.TestCase):
|
||||
|
||||
#
|
||||
# Test vectors
|
||||
#
|
||||
# There seem to be no real ElGamal test vectors available in the
|
||||
# public domain. The following test vectors have been generated
|
||||
# with libgcrypt 1.5.0.
|
||||
#
|
||||
# Encryption
|
||||
tve=[
|
||||
{
|
||||
# 256 bits
|
||||
'p' :'BA4CAEAAED8CBE952AFD2126C63EB3B345D65C2A0A73D2A3AD4138B6D09BD933',
|
||||
'g' :'05',
|
||||
'y' :'60D063600ECED7C7C55146020E7A31C4476E9793BEAED420FEC9E77604CAE4EF',
|
||||
'x' :'1D391BA2EE3C37FE1BA175A69B2C73A11238AD77675932',
|
||||
'k' :'F5893C5BAB4131264066F57AB3D8AD89E391A0B68A68A1',
|
||||
'pt' :'48656C6C6F207468657265',
|
||||
'ct1':'32BFD5F487966CEA9E9356715788C491EC515E4ED48B58F0F00971E93AAA5EC7',
|
||||
'ct2':'7BE8FBFF317C93E82FCEF9BD515284BA506603FEA25D01C0CB874A31F315EE68'
|
||||
},
|
||||
|
||||
{
|
||||
# 512 bits
|
||||
'p' :'F1B18AE9F7B4E08FDA9A04832F4E919D89462FD31BF12F92791A93519F75076D6CE3942689CDFF2F344CAFF0F82D01864F69F3AECF566C774CBACF728B81A227',
|
||||
'g' :'07',
|
||||
'y' :'688628C676E4F05D630E1BE39D0066178CA7AA83836B645DE5ADD359B4825A12B02EF4252E4E6FA9BEC1DB0BE90F6D7C8629CABB6E531F472B2664868156E20C',
|
||||
'x' :'14E60B1BDFD33436C0DA8A22FDC14A2CCDBBED0627CE68',
|
||||
'k' :'38DBF14E1F319BDA9BAB33EEEADCAF6B2EA5250577ACE7',
|
||||
'pt' :'48656C6C6F207468657265',
|
||||
'ct1':'290F8530C2CC312EC46178724F196F308AD4C523CEABB001FACB0506BFED676083FE0F27AC688B5C749AB3CB8A80CD6F7094DBA421FB19442F5A413E06A9772B',
|
||||
'ct2':'1D69AAAD1DC50493FB1B8E8721D621D683F3BF1321BE21BC4A43E11B40C9D4D9C80DE3AAC2AB60D31782B16B61112E68220889D53C4C3136EE6F6CE61F8A23A0'
|
||||
}
|
||||
]
|
||||
|
||||
# Signature
|
||||
tvs=[
|
||||
{
|
||||
# 256 bits
|
||||
'p' :'D2F3C41EA66530838A704A48FFAC9334F4701ECE3A97CEE4C69DD01AE7129DD7',
|
||||
'g' :'05',
|
||||
'y' :'C3F9417DC0DAFEA6A05C1D2333B7A95E63B3F4F28CC962254B3256984D1012E7',
|
||||
'x' :'165E4A39BE44D5A2D8B1332D416BC559616F536BC735BB',
|
||||
'k' :'C7F0C794A7EAD726E25A47FF8928013680E73C51DD3D7D99BFDA8F492585928F',
|
||||
'h' :'48656C6C6F207468657265',
|
||||
'sig1':'35CA98133779E2073EF31165AFCDEB764DD54E96ADE851715495F9C635E1E7C2',
|
||||
'sig2':'0135B88B1151279FE5D8078D4FC685EE81177EE9802AB123A73925FC1CB059A7',
|
||||
},
|
||||
{
|
||||
# 512 bits
|
||||
'p' :'E24CF3A4B8A6AF749DCA6D714282FE4AABEEE44A53BB6ED15FBE32B5D3C3EF9CC4124A2ECA331F3C1C1B667ACA3766825217E7B5F9856648D95F05330C6A19CF',
|
||||
'g' :'0B',
|
||||
'y' :'2AD3A1049CA5D4ED207B2431C79A8719BB4073D4A94E450EA6CEE8A760EB07ADB67C0D52C275EE85D7B52789061EE45F2F37D9B2AE522A51C28329766BFE68AC',
|
||||
'x' :'16CBB4F46D9ECCF24FF9F7E63CAA3BD8936341555062AB',
|
||||
'k' :'8A3D89A4E429FD2476D7D717251FB79BF900FFE77444E6BB8299DC3F84D0DD57ABAB50732AE158EA52F5B9E7D8813E81FD9F79470AE22F8F1CF9AEC820A78C69',
|
||||
'h' :'48656C6C6F207468657265',
|
||||
'sig1':'BE001AABAFFF976EC9016198FBFEA14CBEF96B000CCC0063D3324016F9E91FE80D8F9325812ED24DDB2B4D4CF4430B169880B3CE88313B53255BD4EC0378586F',
|
||||
'sig2':'5E266F3F837BA204E3BBB6DBECC0611429D96F8C7CE8F4EFDF9D4CB681C2A954468A357BF4242CEC7418B51DFC081BCD21299EF5B5A0DDEF3A139A1817503DDE',
|
||||
}
|
||||
]
|
||||
|
||||
def test_generate_180(self):
|
||||
self._test_random_key(180)
|
||||
|
||||
def test_encryption(self):
|
||||
for tv in self.tve:
|
||||
d = self.convert_tv(tv, True)
|
||||
key = ElGamal.construct(d['key'])
|
||||
ct = key._encrypt(d['pt'], d['k'])
|
||||
self.assertEqual(ct[0], d['ct1'])
|
||||
self.assertEqual(ct[1], d['ct2'])
|
||||
|
||||
def test_decryption(self):
|
||||
for tv in self.tve:
|
||||
d = self.convert_tv(tv, True)
|
||||
key = ElGamal.construct(d['key'])
|
||||
pt = key._decrypt((d['ct1'], d['ct2']))
|
||||
self.assertEqual(pt, d['pt'])
|
||||
|
||||
def test_signing(self):
|
||||
for tv in self.tvs:
|
||||
d = self.convert_tv(tv, True)
|
||||
key = ElGamal.construct(d['key'])
|
||||
sig1, sig2 = key._sign(d['h'], d['k'])
|
||||
self.assertEqual(sig1, d['sig1'])
|
||||
self.assertEqual(sig2, d['sig2'])
|
||||
|
||||
def test_verification(self):
|
||||
for tv in self.tvs:
|
||||
d = self.convert_tv(tv, True)
|
||||
key = ElGamal.construct(d['key'])
|
||||
# Positive test
|
||||
res = key._verify( d['h'], (d['sig1'],d['sig2']) )
|
||||
self.assertTrue(res)
|
||||
# Negative test
|
||||
res = key._verify( d['h'], (d['sig1']+1,d['sig2']) )
|
||||
self.assertFalse(res)
|
||||
|
||||
def test_bad_key3(self):
|
||||
tup = tup0 = list(self.convert_tv(self.tvs[0], 1)['key'])[:3]
|
||||
tup[0] += 1 # p += 1 (not prime)
|
||||
self.assertRaises(ValueError, ElGamal.construct, tup)
|
||||
|
||||
tup = tup0
|
||||
tup[1] = 1 # g = 1
|
||||
self.assertRaises(ValueError, ElGamal.construct, tup)
|
||||
|
||||
tup = tup0
|
||||
tup[2] = tup[0]*2 # y = 2*p
|
||||
self.assertRaises(ValueError, ElGamal.construct, tup)
|
||||
|
||||
def test_bad_key4(self):
|
||||
tup = tup0 = list(self.convert_tv(self.tvs[0], 1)['key'])
|
||||
tup[3] += 1 # x += 1
|
||||
self.assertRaises(ValueError, ElGamal.construct, tup)
|
||||
|
||||
def convert_tv(self, tv, as_longs=0):
|
||||
"""Convert a test vector from textual form (hexadecimal ascii
|
||||
to either integers or byte strings."""
|
||||
key_comps = 'p','g','y','x'
|
||||
tv2 = {}
|
||||
for c in list(tv.keys()):
|
||||
tv2[c] = a2b_hex(tv[c])
|
||||
if as_longs or c in key_comps or c in ('sig1','sig2'):
|
||||
tv2[c] = bytes_to_long(tv2[c])
|
||||
tv2['key']=[]
|
||||
for c in key_comps:
|
||||
tv2['key'] += [tv2[c]]
|
||||
del tv2[c]
|
||||
return tv2
|
||||
|
||||
def _test_random_key(self, bits):
|
||||
elgObj = ElGamal.generate(bits, Random.new().read)
|
||||
self._check_private_key(elgObj)
|
||||
self._exercise_primitive(elgObj)
|
||||
pub = elgObj.publickey()
|
||||
self._check_public_key(pub)
|
||||
self._exercise_public_primitive(elgObj)
|
||||
|
||||
def _check_private_key(self, elgObj):
|
||||
|
||||
# Check capabilities
|
||||
self.assertTrue(elgObj.has_private())
|
||||
|
||||
# Sanity check key data
|
||||
self.assertTrue(1<elgObj.g<(elgObj.p-1))
|
||||
self.assertEqual(pow(elgObj.g, elgObj.p-1, elgObj.p), 1)
|
||||
self.assertTrue(1<elgObj.x<(elgObj.p-1))
|
||||
self.assertEqual(pow(elgObj.g, elgObj.x, elgObj.p), elgObj.y)
|
||||
|
||||
def _check_public_key(self, elgObj):
|
||||
|
||||
# Check capabilities
|
||||
self.assertFalse(elgObj.has_private())
|
||||
|
||||
# Sanity check key data
|
||||
self.assertTrue(1<elgObj.g<(elgObj.p-1))
|
||||
self.assertEqual(pow(elgObj.g, elgObj.p-1, elgObj.p), 1)
|
||||
|
||||
def _exercise_primitive(self, elgObj):
|
||||
# Test encryption/decryption
|
||||
plaintext = 127218
|
||||
ciphertext = elgObj._encrypt(plaintext, 123456789)
|
||||
plaintextP = elgObj._decrypt(ciphertext)
|
||||
self.assertEqual(plaintext, plaintextP)
|
||||
|
||||
# Test signature/verification
|
||||
signature = elgObj._sign(plaintext, 987654321)
|
||||
elgObj._verify(plaintext, signature)
|
||||
|
||||
def _exercise_public_primitive(self, elgObj):
|
||||
plaintext = 92987276
|
||||
ciphertext = elgObj._encrypt(plaintext, 123456789)
|
||||
|
||||
def get_tests(config={}):
|
||||
tests = []
|
||||
tests += list_test_cases(ElGamalTest)
|
||||
return tests
|
||||
|
||||
if __name__ == '__main__':
|
||||
suite = lambda: unittest.TestSuite(get_tests())
|
||||
unittest.main(defaultTest='suite')
|
||||
|
315
venv/Lib/site-packages/Crypto/SelfTest/PublicKey/test_RSA.py
Normal file
315
venv/Lib/site-packages/Crypto/SelfTest/PublicKey/test_RSA.py
Normal file
|
@ -0,0 +1,315 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# SelfTest/PublicKey/test_RSA.py: Self-test for the RSA primitive
|
||||
#
|
||||
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
|
||||
#
|
||||
# ===================================================================
|
||||
# The contents of this file are dedicated to the public domain. To
|
||||
# the extent that dedication to the public domain is not available,
|
||||
# everyone is granted a worldwide, perpetual, royalty-free,
|
||||
# non-exclusive license to exercise all rights associated with the
|
||||
# contents of this file for any purpose whatsoever.
|
||||
# No rights are reserved.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
# ===================================================================
|
||||
|
||||
"""Self-test suite for Crypto.PublicKey.RSA"""
|
||||
|
||||
__revision__ = "$Id$"
|
||||
|
||||
import os
|
||||
import pickle
|
||||
from pickle import PicklingError
|
||||
from Crypto.Util.py3compat import *
|
||||
|
||||
import unittest
|
||||
from Crypto.SelfTest.st_common import list_test_cases, a2b_hex, b2a_hex
|
||||
|
||||
class RSATest(unittest.TestCase):
|
||||
# Test vectors from "RSA-OAEP and RSA-PSS test vectors (.zip file)"
|
||||
# ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip
|
||||
# See RSADSI's PKCS#1 page at
|
||||
# http://www.rsa.com/rsalabs/node.asp?id=2125
|
||||
|
||||
# from oaep-int.txt
|
||||
|
||||
# TODO: PyCrypto treats the message as starting *after* the leading "00"
|
||||
# TODO: That behaviour should probably be changed in the future.
|
||||
plaintext = """
|
||||
eb 7a 19 ac e9 e3 00 63 50 e3 29 50 4b 45 e2
|
||||
ca 82 31 0b 26 dc d8 7d 5c 68 f1 ee a8 f5 52 67
|
||||
c3 1b 2e 8b b4 25 1f 84 d7 e0 b2 c0 46 26 f5 af
|
||||
f9 3e dc fb 25 c9 c2 b3 ff 8a e1 0e 83 9a 2d db
|
||||
4c dc fe 4f f4 77 28 b4 a1 b7 c1 36 2b aa d2 9a
|
||||
b4 8d 28 69 d5 02 41 21 43 58 11 59 1b e3 92 f9
|
||||
82 fb 3e 87 d0 95 ae b4 04 48 db 97 2f 3a c1 4f
|
||||
7b c2 75 19 52 81 ce 32 d2 f1 b7 6d 4d 35 3e 2d
|
||||
"""
|
||||
|
||||
ciphertext = """
|
||||
12 53 e0 4d c0 a5 39 7b b4 4a 7a b8 7e 9b f2 a0
|
||||
39 a3 3d 1e 99 6f c8 2a 94 cc d3 00 74 c9 5d f7
|
||||
63 72 20 17 06 9e 52 68 da 5d 1c 0b 4f 87 2c f6
|
||||
53 c1 1d f8 23 14 a6 79 68 df ea e2 8d ef 04 bb
|
||||
6d 84 b1 c3 1d 65 4a 19 70 e5 78 3b d6 eb 96 a0
|
||||
24 c2 ca 2f 4a 90 fe 9f 2e f5 c9 c1 40 e5 bb 48
|
||||
da 95 36 ad 87 00 c8 4f c9 13 0a de a7 4e 55 8d
|
||||
51 a7 4d df 85 d8 b5 0d e9 68 38 d6 06 3e 09 55
|
||||
"""
|
||||
|
||||
modulus = """
|
||||
bb f8 2f 09 06 82 ce 9c 23 38 ac 2b 9d a8 71 f7
|
||||
36 8d 07 ee d4 10 43 a4 40 d6 b6 f0 74 54 f5 1f
|
||||
b8 df ba af 03 5c 02 ab 61 ea 48 ce eb 6f cd 48
|
||||
76 ed 52 0d 60 e1 ec 46 19 71 9d 8a 5b 8b 80 7f
|
||||
af b8 e0 a3 df c7 37 72 3e e6 b4 b7 d9 3a 25 84
|
||||
ee 6a 64 9d 06 09 53 74 88 34 b2 45 45 98 39 4e
|
||||
e0 aa b1 2d 7b 61 a5 1f 52 7a 9a 41 f6 c1 68 7f
|
||||
e2 53 72 98 ca 2a 8f 59 46 f8 e5 fd 09 1d bd cb
|
||||
"""
|
||||
|
||||
e = 0x11 # public exponent
|
||||
|
||||
prime_factor = """
|
||||
c9 7f b1 f0 27 f4 53 f6 34 12 33 ea aa d1 d9 35
|
||||
3f 6c 42 d0 88 66 b1 d0 5a 0f 20 35 02 8b 9d 86
|
||||
98 40 b4 16 66 b4 2e 92 ea 0d a3 b4 32 04 b5 cf
|
||||
ce 33 52 52 4d 04 16 a5 a4 41 e7 00 af 46 15 03
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
global RSA, Random, bytes_to_long
|
||||
from Crypto.PublicKey import RSA
|
||||
from Crypto import Random
|
||||
from Crypto.Util.number import bytes_to_long, inverse
|
||||
self.n = bytes_to_long(a2b_hex(self.modulus))
|
||||
self.p = bytes_to_long(a2b_hex(self.prime_factor))
|
||||
|
||||
# Compute q, d, and u from n, e, and p
|
||||
self.q = self.n // self.p
|
||||
self.d = inverse(self.e, (self.p-1)*(self.q-1))
|
||||
self.u = inverse(self.p, self.q) # u = e**-1 (mod q)
|
||||
|
||||
self.rsa = RSA
|
||||
|
||||
def test_generate_1arg(self):
|
||||
"""RSA (default implementation) generated key (1 argument)"""
|
||||
rsaObj = self.rsa.generate(1024)
|
||||
self._check_private_key(rsaObj)
|
||||
self._exercise_primitive(rsaObj)
|
||||
pub = rsaObj.publickey()
|
||||
self._check_public_key(pub)
|
||||
self._exercise_public_primitive(rsaObj)
|
||||
|
||||
def test_generate_2arg(self):
|
||||
"""RSA (default implementation) generated key (2 arguments)"""
|
||||
rsaObj = self.rsa.generate(1024, Random.new().read)
|
||||
self._check_private_key(rsaObj)
|
||||
self._exercise_primitive(rsaObj)
|
||||
pub = rsaObj.publickey()
|
||||
self._check_public_key(pub)
|
||||
self._exercise_public_primitive(rsaObj)
|
||||
|
||||
def test_generate_3args(self):
|
||||
rsaObj = self.rsa.generate(1024, Random.new().read,e=65537)
|
||||
self._check_private_key(rsaObj)
|
||||
self._exercise_primitive(rsaObj)
|
||||
pub = rsaObj.publickey()
|
||||
self._check_public_key(pub)
|
||||
self._exercise_public_primitive(rsaObj)
|
||||
self.assertEqual(65537,rsaObj.e)
|
||||
|
||||
def test_construct_2tuple(self):
|
||||
"""RSA (default implementation) constructed key (2-tuple)"""
|
||||
pub = self.rsa.construct((self.n, self.e))
|
||||
self._check_public_key(pub)
|
||||
self._check_encryption(pub)
|
||||
|
||||
def test_construct_3tuple(self):
|
||||
"""RSA (default implementation) constructed key (3-tuple)"""
|
||||
rsaObj = self.rsa.construct((self.n, self.e, self.d))
|
||||
self._check_encryption(rsaObj)
|
||||
self._check_decryption(rsaObj)
|
||||
|
||||
def test_construct_4tuple(self):
|
||||
"""RSA (default implementation) constructed key (4-tuple)"""
|
||||
rsaObj = self.rsa.construct((self.n, self.e, self.d, self.p))
|
||||
self._check_encryption(rsaObj)
|
||||
self._check_decryption(rsaObj)
|
||||
|
||||
def test_construct_5tuple(self):
|
||||
"""RSA (default implementation) constructed key (5-tuple)"""
|
||||
rsaObj = self.rsa.construct((self.n, self.e, self.d, self.p, self.q))
|
||||
self._check_private_key(rsaObj)
|
||||
self._check_encryption(rsaObj)
|
||||
self._check_decryption(rsaObj)
|
||||
|
||||
def test_construct_6tuple(self):
|
||||
"""RSA (default implementation) constructed key (6-tuple)"""
|
||||
rsaObj = self.rsa.construct((self.n, self.e, self.d, self.p, self.q, self.u))
|
||||
self._check_private_key(rsaObj)
|
||||
self._check_encryption(rsaObj)
|
||||
self._check_decryption(rsaObj)
|
||||
|
||||
def test_construct_bad_key2(self):
|
||||
tup = (self.n, 1)
|
||||
self.assertRaises(ValueError, self.rsa.construct, tup)
|
||||
|
||||
# An even modulus is wrong
|
||||
tup = (self.n+1, self.e)
|
||||
self.assertRaises(ValueError, self.rsa.construct, tup)
|
||||
|
||||
def test_construct_bad_key3(self):
|
||||
tup = (self.n, self.e, self.d+1)
|
||||
self.assertRaises(ValueError, self.rsa.construct, tup)
|
||||
|
||||
def test_construct_bad_key5(self):
|
||||
tup = (self.n, self.e, self.d, self.p, self.p)
|
||||
self.assertRaises(ValueError, self.rsa.construct, tup)
|
||||
|
||||
tup = (self.p*self.p, self.e, self.p, self.p)
|
||||
self.assertRaises(ValueError, self.rsa.construct, tup)
|
||||
|
||||
tup = (self.p*self.p, 3, self.p, self.q)
|
||||
self.assertRaises(ValueError, self.rsa.construct, tup)
|
||||
|
||||
def test_construct_bad_key6(self):
|
||||
tup = (self.n, self.e, self.d, self.p, self.q, 10)
|
||||
self.assertRaises(ValueError, self.rsa.construct, tup)
|
||||
|
||||
from Crypto.Util.number import inverse
|
||||
tup = (self.n, self.e, self.d, self.p, self.q, inverse(self.q, self.p))
|
||||
self.assertRaises(ValueError, self.rsa.construct, tup)
|
||||
|
||||
def test_factoring(self):
|
||||
rsaObj = self.rsa.construct([self.n, self.e, self.d])
|
||||
self.assertTrue(rsaObj.p==self.p or rsaObj.p==self.q)
|
||||
self.assertTrue(rsaObj.q==self.p or rsaObj.q==self.q)
|
||||
self.assertTrue(rsaObj.q*rsaObj.p == self.n)
|
||||
|
||||
self.assertRaises(ValueError, self.rsa.construct, [self.n, self.e, self.n-1])
|
||||
|
||||
def test_repr(self):
|
||||
rsaObj = self.rsa.construct((self.n, self.e, self.d, self.p, self.q))
|
||||
repr(rsaObj)
|
||||
|
||||
def test_serialization(self):
|
||||
"""RSA keys are unpickable"""
|
||||
|
||||
rsa_key = self.rsa.generate(1024)
|
||||
self.assertRaises(PicklingError, pickle.dumps, rsa_key)
|
||||
|
||||
def test_raw_rsa_boundary(self):
|
||||
# The argument of every RSA raw operation (encrypt/decrypt) must be positive
|
||||
# and no larger than the modulus
|
||||
rsa_obj = self.rsa.generate(1024)
|
||||
|
||||
self.assertRaises(ValueError, rsa_obj._decrypt, rsa_obj.n)
|
||||
self.assertRaises(ValueError, rsa_obj._encrypt, rsa_obj.n)
|
||||
|
||||
self.assertRaises(ValueError, rsa_obj._decrypt, 0)
|
||||
self.assertRaises(ValueError, rsa_obj._encrypt, 0)
|
||||
|
||||
def test_size(self):
|
||||
pub = self.rsa.construct((self.n, self.e))
|
||||
self.assertEqual(pub.size_in_bits(), 1024)
|
||||
self.assertEqual(pub.size_in_bytes(), 128)
|
||||
|
||||
def _check_private_key(self, rsaObj):
|
||||
from Crypto.Math.Numbers import Integer
|
||||
|
||||
# Check capabilities
|
||||
self.assertEqual(1, rsaObj.has_private())
|
||||
|
||||
# Sanity check key data
|
||||
self.assertEqual(rsaObj.n, rsaObj.p * rsaObj.q) # n = pq
|
||||
lcm = int(Integer(rsaObj.p-1).lcm(rsaObj.q-1))
|
||||
self.assertEqual(1, rsaObj.d * rsaObj.e % lcm) # ed = 1 (mod LCM(p-1, q-1))
|
||||
self.assertEqual(1, rsaObj.p * rsaObj.u % rsaObj.q) # pu = 1 (mod q)
|
||||
self.assertEqual(1, rsaObj.p > 1) # p > 1
|
||||
self.assertEqual(1, rsaObj.q > 1) # q > 1
|
||||
self.assertEqual(1, rsaObj.e > 1) # e > 1
|
||||
self.assertEqual(1, rsaObj.d > 1) # d > 1
|
||||
|
||||
def _check_public_key(self, rsaObj):
|
||||
ciphertext = a2b_hex(self.ciphertext)
|
||||
|
||||
# Check capabilities
|
||||
self.assertEqual(0, rsaObj.has_private())
|
||||
|
||||
# Check rsaObj.[ne] -> rsaObj.[ne] mapping
|
||||
self.assertEqual(rsaObj.n, rsaObj.n)
|
||||
self.assertEqual(rsaObj.e, rsaObj.e)
|
||||
|
||||
# Check that private parameters are all missing
|
||||
self.assertEqual(0, hasattr(rsaObj, 'd'))
|
||||
self.assertEqual(0, hasattr(rsaObj, 'p'))
|
||||
self.assertEqual(0, hasattr(rsaObj, 'q'))
|
||||
self.assertEqual(0, hasattr(rsaObj, 'u'))
|
||||
|
||||
# Sanity check key data
|
||||
self.assertEqual(1, rsaObj.e > 1) # e > 1
|
||||
|
||||
# Public keys should not be able to sign or decrypt
|
||||
self.assertRaises(TypeError, rsaObj._decrypt,
|
||||
bytes_to_long(ciphertext))
|
||||
|
||||
# Check __eq__ and __ne__
|
||||
self.assertEqual(rsaObj.publickey() == rsaObj.publickey(),True) # assert_
|
||||
self.assertEqual(rsaObj.publickey() != rsaObj.publickey(),False) # failIf
|
||||
|
||||
def _exercise_primitive(self, rsaObj):
|
||||
# Since we're using a randomly-generated key, we can't check the test
|
||||
# vector, but we can make sure encryption and decryption are inverse
|
||||
# operations.
|
||||
ciphertext = bytes_to_long(a2b_hex(self.ciphertext))
|
||||
|
||||
# Test decryption
|
||||
plaintext = rsaObj._decrypt(ciphertext)
|
||||
|
||||
# Test encryption (2 arguments)
|
||||
new_ciphertext2 = rsaObj._encrypt(plaintext)
|
||||
self.assertEqual(ciphertext, new_ciphertext2)
|
||||
|
||||
def _exercise_public_primitive(self, rsaObj):
|
||||
plaintext = a2b_hex(self.plaintext)
|
||||
|
||||
# Test encryption (2 arguments)
|
||||
new_ciphertext2 = rsaObj._encrypt(bytes_to_long(plaintext))
|
||||
|
||||
def _check_encryption(self, rsaObj):
|
||||
plaintext = a2b_hex(self.plaintext)
|
||||
ciphertext = a2b_hex(self.ciphertext)
|
||||
|
||||
# Test encryption
|
||||
new_ciphertext2 = rsaObj._encrypt(bytes_to_long(plaintext))
|
||||
self.assertEqual(bytes_to_long(ciphertext), new_ciphertext2)
|
||||
|
||||
def _check_decryption(self, rsaObj):
|
||||
plaintext = bytes_to_long(a2b_hex(self.plaintext))
|
||||
ciphertext = bytes_to_long(a2b_hex(self.ciphertext))
|
||||
|
||||
# Test plain decryption
|
||||
new_plaintext = rsaObj._decrypt(ciphertext)
|
||||
self.assertEqual(plaintext, new_plaintext)
|
||||
|
||||
|
||||
def get_tests(config={}):
|
||||
tests = []
|
||||
tests += list_test_cases(RSATest)
|
||||
return tests
|
||||
|
||||
if __name__ == '__main__':
|
||||
suite = lambda: unittest.TestSuite(get_tests())
|
||||
unittest.main(defaultTest='suite')
|
||||
|
||||
# vim:set ts=4 sw=4 sts=4 expandtab:
|
|
@ -0,0 +1,545 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# SelfTest/PublicKey/test_import_DSA.py: Self-test for importing DSA keys
|
||||
#
|
||||
# ===================================================================
|
||||
# The contents of this file are dedicated to the public domain. To
|
||||
# the extent that dedication to the public domain is not available,
|
||||
# everyone is granted a worldwide, perpetual, royalty-free,
|
||||
# non-exclusive license to exercise all rights associated with the
|
||||
# contents of this file for any purpose whatsoever.
|
||||
# No rights are reserved.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
# ===================================================================
|
||||
|
||||
import unittest
|
||||
import re
|
||||
|
||||
from Crypto.PublicKey import DSA
|
||||
from Crypto.SelfTest.st_common import *
|
||||
from Crypto.Util.py3compat import *
|
||||
|
||||
from binascii import unhexlify
|
||||
|
||||
class ImportKeyTests(unittest.TestCase):
|
||||
|
||||
y = 92137165128186062214622779787483327510946462589285775188003362705875131352591574106484271700740858696583623951844732128165434284507709057439633739849986759064015013893156866539696757799934634945787496920169462601722830899660681779448742875054459716726855443681559131362852474817534616736104831095601710736729
|
||||
p = 162452170958135306109773853318304545923250830605675936228618290525164105310663722368377131295055868997377338797580997938253236213714988311430600065853662861806894003694743806769284131194035848116051021923956699231855223389086646903420682639786976554552864568460372266462812137447840653688476258666833303658691
|
||||
q = 988791743931120302950649732173330531512663554851
|
||||
g = 85583152299197514738065570254868711517748965097380456700369348466136657764813442044039878840094809620913085570225318356734366886985903212775602770761953571967834823306046501307810937486758039063386311593890777319935391363872375452381836756832784184928202587843258855704771836753434368484556809100537243908232
|
||||
x = 540873410045082450874416847965843801027716145253
|
||||
|
||||
def setUp(self):
|
||||
|
||||
# It is easier to write test vectors in text form,
|
||||
# and convert them to byte strigs dynamically here
|
||||
for mname, mvalue in list(ImportKeyTests.__dict__.items()):
|
||||
if mname[:4] in ('der_', 'pem_', 'ssh_'):
|
||||
if mname[:4] == 'der_':
|
||||
mvalue = unhexlify(tobytes(mvalue))
|
||||
mvalue = tobytes(mvalue)
|
||||
setattr(self, mname, mvalue)
|
||||
|
||||
# 1. SubjectPublicKeyInfo
|
||||
der_public=\
|
||||
'308201b73082012b06072a8648ce3804013082011e02818100e756ee1717f4b6'+\
|
||||
'794c7c214724a19763742c45572b4b3f8ff3b44f3be9f44ce039a2757695ec91'+\
|
||||
'5697da74ef914fcd1b05660e2419c761d639f45d2d79b802dbd23e7ab8b81b47'+\
|
||||
'9a380e1f30932584ba2a0b955032342ebc83cb5ca906e7b0d7cd6fe656cecb4c'+\
|
||||
'8b5a77123a8c6750a481e3b06057aff6aa6eba620b832d60c3021500ad32f48c'+\
|
||||
'd3ae0c45a198a61fa4b5e20320763b2302818079dfdc3d614fe635fceb7eaeae'+\
|
||||
'3718dc2efefb45282993ac6749dc83c223d8c1887296316b3b0b54466cf444f3'+\
|
||||
'4b82e3554d0b90a778faaf1306f025dae6a3e36c7f93dd5bac4052b92370040a'+\
|
||||
'ca70b8d5820599711900efbc961812c355dd9beffe0981da85c5548074b41c56'+\
|
||||
'ae43fd300d89262e4efd89943f99a651b03888038185000281810083352a69a1'+\
|
||||
'32f34843d2a0eb995bff4e2f083a73f0049d2c91ea2f0ce43d144abda48199e4'+\
|
||||
'b003c570a8af83303d45105f606c5c48d925a40ed9c2630c2fa4cdbf838539de'+\
|
||||
'b9a29f919085f2046369f627ca84b2cb1e2c7940564b670f963ab1164d4e2ca2'+\
|
||||
'bf6ffd39f12f548928bf4d2d1b5e6980b4f1be4c92a91986fba559'
|
||||
|
||||
def testImportKey1(self):
|
||||
key_obj = DSA.importKey(self.der_public)
|
||||
self.assertFalse(key_obj.has_private())
|
||||
self.assertEqual(self.y, key_obj.y)
|
||||
self.assertEqual(self.p, key_obj.p)
|
||||
self.assertEqual(self.q, key_obj.q)
|
||||
self.assertEqual(self.g, key_obj.g)
|
||||
|
||||
def testExportKey1(self):
|
||||
tup = (self.y, self.g, self.p, self.q)
|
||||
key = DSA.construct(tup)
|
||||
encoded = key.exportKey('DER')
|
||||
self.assertEqual(self.der_public, encoded)
|
||||
|
||||
# 2.
|
||||
pem_public="""\
|
||||
-----BEGIN DSA PUBLIC KEY-----
|
||||
MIIBtzCCASsGByqGSM44BAEwggEeAoGBAOdW7hcX9LZ5THwhRyShl2N0LEVXK0s/
|
||||
j/O0Tzvp9EzgOaJ1dpXskVaX2nTvkU/NGwVmDiQZx2HWOfRdLXm4AtvSPnq4uBtH
|
||||
mjgOHzCTJYS6KguVUDI0LryDy1ypBuew181v5lbOy0yLWncSOoxnUKSB47BgV6/2
|
||||
qm66YguDLWDDAhUArTL0jNOuDEWhmKYfpLXiAyB2OyMCgYB539w9YU/mNfzrfq6u
|
||||
NxjcLv77RSgpk6xnSdyDwiPYwYhyljFrOwtURmz0RPNLguNVTQuQp3j6rxMG8CXa
|
||||
5qPjbH+T3VusQFK5I3AECspwuNWCBZlxGQDvvJYYEsNV3Zvv/gmB2oXFVIB0tBxW
|
||||
rkP9MA2JJi5O/YmUP5mmUbA4iAOBhQACgYEAgzUqaaEy80hD0qDrmVv/Ti8IOnPw
|
||||
BJ0skeovDOQ9FEq9pIGZ5LADxXCor4MwPUUQX2BsXEjZJaQO2cJjDC+kzb+DhTne
|
||||
uaKfkZCF8gRjafYnyoSyyx4seUBWS2cPljqxFk1OLKK/b/058S9UiSi/TS0bXmmA
|
||||
tPG+TJKpGYb7pVk=
|
||||
-----END DSA PUBLIC KEY-----"""
|
||||
|
||||
def testImportKey2(self):
|
||||
for pem in (self.pem_public, tostr(self.pem_public)):
|
||||
key_obj = DSA.importKey(pem)
|
||||
self.assertFalse(key_obj.has_private())
|
||||
self.assertEqual(self.y, key_obj.y)
|
||||
self.assertEqual(self.p, key_obj.p)
|
||||
self.assertEqual(self.q, key_obj.q)
|
||||
self.assertEqual(self.g, key_obj.g)
|
||||
|
||||
def testExportKey2(self):
|
||||
tup = (self.y, self.g, self.p, self.q)
|
||||
key = DSA.construct(tup)
|
||||
encoded = key.exportKey('PEM')
|
||||
self.assertEqual(self.pem_public, encoded)
|
||||
|
||||
# 3. OpenSSL/OpenSSH format
|
||||
der_private=\
|
||||
'308201bb02010002818100e756ee1717f4b6794c7c214724a19763742c45572b'+\
|
||||
'4b3f8ff3b44f3be9f44ce039a2757695ec915697da74ef914fcd1b05660e2419'+\
|
||||
'c761d639f45d2d79b802dbd23e7ab8b81b479a380e1f30932584ba2a0b955032'+\
|
||||
'342ebc83cb5ca906e7b0d7cd6fe656cecb4c8b5a77123a8c6750a481e3b06057'+\
|
||||
'aff6aa6eba620b832d60c3021500ad32f48cd3ae0c45a198a61fa4b5e2032076'+\
|
||||
'3b2302818079dfdc3d614fe635fceb7eaeae3718dc2efefb45282993ac6749dc'+\
|
||||
'83c223d8c1887296316b3b0b54466cf444f34b82e3554d0b90a778faaf1306f0'+\
|
||||
'25dae6a3e36c7f93dd5bac4052b92370040aca70b8d5820599711900efbc9618'+\
|
||||
'12c355dd9beffe0981da85c5548074b41c56ae43fd300d89262e4efd89943f99'+\
|
||||
'a651b038880281810083352a69a132f34843d2a0eb995bff4e2f083a73f0049d'+\
|
||||
'2c91ea2f0ce43d144abda48199e4b003c570a8af83303d45105f606c5c48d925'+\
|
||||
'a40ed9c2630c2fa4cdbf838539deb9a29f919085f2046369f627ca84b2cb1e2c'+\
|
||||
'7940564b670f963ab1164d4e2ca2bf6ffd39f12f548928bf4d2d1b5e6980b4f1'+\
|
||||
'be4c92a91986fba55902145ebd9a3f0b82069d98420986b314215025756065'
|
||||
|
||||
def testImportKey3(self):
|
||||
key_obj = DSA.importKey(self.der_private)
|
||||
self.assertTrue(key_obj.has_private())
|
||||
self.assertEqual(self.y, key_obj.y)
|
||||
self.assertEqual(self.p, key_obj.p)
|
||||
self.assertEqual(self.q, key_obj.q)
|
||||
self.assertEqual(self.g, key_obj.g)
|
||||
self.assertEqual(self.x, key_obj.x)
|
||||
|
||||
def testExportKey3(self):
|
||||
tup = (self.y, self.g, self.p, self.q, self.x)
|
||||
key = DSA.construct(tup)
|
||||
encoded = key.exportKey('DER', pkcs8=False)
|
||||
self.assertEqual(self.der_private, encoded)
|
||||
|
||||
# 4.
|
||||
pem_private="""\
|
||||
-----BEGIN DSA PRIVATE KEY-----
|
||||
MIIBuwIBAAKBgQDnVu4XF/S2eUx8IUckoZdjdCxFVytLP4/ztE876fRM4DmidXaV
|
||||
7JFWl9p075FPzRsFZg4kGcdh1jn0XS15uALb0j56uLgbR5o4Dh8wkyWEuioLlVAy
|
||||
NC68g8tcqQbnsNfNb+ZWzstMi1p3EjqMZ1CkgeOwYFev9qpuumILgy1gwwIVAK0y
|
||||
9IzTrgxFoZimH6S14gMgdjsjAoGAed/cPWFP5jX8636urjcY3C7++0UoKZOsZ0nc
|
||||
g8Ij2MGIcpYxazsLVEZs9ETzS4LjVU0LkKd4+q8TBvAl2uaj42x/k91brEBSuSNw
|
||||
BArKcLjVggWZcRkA77yWGBLDVd2b7/4JgdqFxVSAdLQcVq5D/TANiSYuTv2JlD+Z
|
||||
plGwOIgCgYEAgzUqaaEy80hD0qDrmVv/Ti8IOnPwBJ0skeovDOQ9FEq9pIGZ5LAD
|
||||
xXCor4MwPUUQX2BsXEjZJaQO2cJjDC+kzb+DhTneuaKfkZCF8gRjafYnyoSyyx4s
|
||||
eUBWS2cPljqxFk1OLKK/b/058S9UiSi/TS0bXmmAtPG+TJKpGYb7pVkCFF69mj8L
|
||||
ggadmEIJhrMUIVAldWBl
|
||||
-----END DSA PRIVATE KEY-----"""
|
||||
|
||||
def testImportKey4(self):
|
||||
for pem in (self.pem_private, tostr(self.pem_private)):
|
||||
key_obj = DSA.importKey(pem)
|
||||
self.assertTrue(key_obj.has_private())
|
||||
self.assertEqual(self.y, key_obj.y)
|
||||
self.assertEqual(self.p, key_obj.p)
|
||||
self.assertEqual(self.q, key_obj.q)
|
||||
self.assertEqual(self.g, key_obj.g)
|
||||
self.assertEqual(self.x, key_obj.x)
|
||||
|
||||
def testExportKey4(self):
|
||||
tup = (self.y, self.g, self.p, self.q, self.x)
|
||||
key = DSA.construct(tup)
|
||||
encoded = key.exportKey('PEM', pkcs8=False)
|
||||
self.assertEqual(self.pem_private, encoded)
|
||||
|
||||
# 5. PKCS8 (unencrypted)
|
||||
der_pkcs8=\
|
||||
'3082014a0201003082012b06072a8648ce3804013082011e02818100e756ee17'+\
|
||||
'17f4b6794c7c214724a19763742c45572b4b3f8ff3b44f3be9f44ce039a27576'+\
|
||||
'95ec915697da74ef914fcd1b05660e2419c761d639f45d2d79b802dbd23e7ab8'+\
|
||||
'b81b479a380e1f30932584ba2a0b955032342ebc83cb5ca906e7b0d7cd6fe656'+\
|
||||
'cecb4c8b5a77123a8c6750a481e3b06057aff6aa6eba620b832d60c3021500ad'+\
|
||||
'32f48cd3ae0c45a198a61fa4b5e20320763b2302818079dfdc3d614fe635fceb'+\
|
||||
'7eaeae3718dc2efefb45282993ac6749dc83c223d8c1887296316b3b0b54466c'+\
|
||||
'f444f34b82e3554d0b90a778faaf1306f025dae6a3e36c7f93dd5bac4052b923'+\
|
||||
'70040aca70b8d5820599711900efbc961812c355dd9beffe0981da85c5548074'+\
|
||||
'b41c56ae43fd300d89262e4efd89943f99a651b03888041602145ebd9a3f0b82'+\
|
||||
'069d98420986b314215025756065'
|
||||
|
||||
def testImportKey5(self):
|
||||
key_obj = DSA.importKey(self.der_pkcs8)
|
||||
self.assertTrue(key_obj.has_private())
|
||||
self.assertEqual(self.y, key_obj.y)
|
||||
self.assertEqual(self.p, key_obj.p)
|
||||
self.assertEqual(self.q, key_obj.q)
|
||||
self.assertEqual(self.g, key_obj.g)
|
||||
self.assertEqual(self.x, key_obj.x)
|
||||
|
||||
def testExportKey5(self):
|
||||
tup = (self.y, self.g, self.p, self.q, self.x)
|
||||
key = DSA.construct(tup)
|
||||
encoded = key.exportKey('DER')
|
||||
self.assertEqual(self.der_pkcs8, encoded)
|
||||
encoded = key.exportKey('DER', pkcs8=True)
|
||||
self.assertEqual(self.der_pkcs8, encoded)
|
||||
|
||||
# 6.
|
||||
pem_pkcs8="""\
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIBSgIBADCCASsGByqGSM44BAEwggEeAoGBAOdW7hcX9LZ5THwhRyShl2N0LEVX
|
||||
K0s/j/O0Tzvp9EzgOaJ1dpXskVaX2nTvkU/NGwVmDiQZx2HWOfRdLXm4AtvSPnq4
|
||||
uBtHmjgOHzCTJYS6KguVUDI0LryDy1ypBuew181v5lbOy0yLWncSOoxnUKSB47Bg
|
||||
V6/2qm66YguDLWDDAhUArTL0jNOuDEWhmKYfpLXiAyB2OyMCgYB539w9YU/mNfzr
|
||||
fq6uNxjcLv77RSgpk6xnSdyDwiPYwYhyljFrOwtURmz0RPNLguNVTQuQp3j6rxMG
|
||||
8CXa5qPjbH+T3VusQFK5I3AECspwuNWCBZlxGQDvvJYYEsNV3Zvv/gmB2oXFVIB0
|
||||
tBxWrkP9MA2JJi5O/YmUP5mmUbA4iAQWAhRevZo/C4IGnZhCCYazFCFQJXVgZQ==
|
||||
-----END PRIVATE KEY-----"""
|
||||
|
||||
def testImportKey6(self):
|
||||
for pem in (self.pem_pkcs8, tostr(self.pem_pkcs8)):
|
||||
key_obj = DSA.importKey(pem)
|
||||
self.assertTrue(key_obj.has_private())
|
||||
self.assertEqual(self.y, key_obj.y)
|
||||
self.assertEqual(self.p, key_obj.p)
|
||||
self.assertEqual(self.q, key_obj.q)
|
||||
self.assertEqual(self.g, key_obj.g)
|
||||
self.assertEqual(self.x, key_obj.x)
|
||||
|
||||
def testExportKey6(self):
|
||||
tup = (self.y, self.g, self.p, self.q, self.x)
|
||||
key = DSA.construct(tup)
|
||||
encoded = key.exportKey('PEM')
|
||||
self.assertEqual(self.pem_pkcs8, encoded)
|
||||
encoded = key.exportKey('PEM', pkcs8=True)
|
||||
self.assertEqual(self.pem_pkcs8, encoded)
|
||||
|
||||
# 7. OpenSSH/RFC4253
|
||||
ssh_pub="""ssh-dss AAAAB3NzaC1kc3MAAACBAOdW7hcX9LZ5THwhRyShl2N0LEVXK0s/j/O0Tzvp9EzgOaJ1dpXskVaX2nTvkU/NGwVmDiQZx2HWOfRdLXm4AtvSPnq4uBtHmjgOHzCTJYS6KguVUDI0LryDy1ypBuew181v5lbOy0yLWncSOoxnUKSB47BgV6/2qm66YguDLWDDAAAAFQCtMvSM064MRaGYph+kteIDIHY7IwAAAIB539w9YU/mNfzrfq6uNxjcLv77RSgpk6xnSdyDwiPYwYhyljFrOwtURmz0RPNLguNVTQuQp3j6rxMG8CXa5qPjbH+T3VusQFK5I3AECspwuNWCBZlxGQDvvJYYEsNV3Zvv/gmB2oXFVIB0tBxWrkP9MA2JJi5O/YmUP5mmUbA4iAAAAIEAgzUqaaEy80hD0qDrmVv/Ti8IOnPwBJ0skeovDOQ9FEq9pIGZ5LADxXCor4MwPUUQX2BsXEjZJaQO2cJjDC+kzb+DhTneuaKfkZCF8gRjafYnyoSyyx4seUBWS2cPljqxFk1OLKK/b/058S9UiSi/TS0bXmmAtPG+TJKpGYb7pVk="""
|
||||
|
||||
def testImportKey7(self):
|
||||
for ssh in (self.ssh_pub, tostr(self.ssh_pub)):
|
||||
key_obj = DSA.importKey(ssh)
|
||||
self.assertFalse(key_obj.has_private())
|
||||
self.assertEqual(self.y, key_obj.y)
|
||||
self.assertEqual(self.p, key_obj.p)
|
||||
self.assertEqual(self.q, key_obj.q)
|
||||
self.assertEqual(self.g, key_obj.g)
|
||||
|
||||
def testExportKey7(self):
|
||||
tup = (self.y, self.g, self.p, self.q)
|
||||
key = DSA.construct(tup)
|
||||
encoded = key.exportKey('OpenSSH')
|
||||
self.assertEqual(self.ssh_pub, encoded)
|
||||
|
||||
# 8. Encrypted OpenSSL/OpenSSH
|
||||
pem_private_encrypted="""\
|
||||
-----BEGIN DSA PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: AES-128-CBC,70B6908939D65E9F2EB999E8729788CE
|
||||
|
||||
4V6GHRDpCrdZ8MBjbyp5AlGUrjvr2Pn2e2zVxy5RBt4FBj9/pa0ae0nnyUPMLSUU
|
||||
kKyOR0topRYTVRLElm4qVrb5uNZ3hRwfbklr+pSrB7O9eHz9V5sfOQxyODS07JxK
|
||||
k1OdOs70/ouMXLF9EWfAZOmWUccZKHNblUwg1p1UrZIz5jXw4dUE/zqhvXh6d+iC
|
||||
ADsICaBCjCrRQJKDp50h3+ndQjkYBKVH+pj8TiQ79U7lAvdp3+iMghQN6YXs9mdI
|
||||
gFpWw/f97oWM4GHZFqHJ+VSMNFjBiFhAvYV587d7Lk4dhD8sCfbxj42PnfRgUItc
|
||||
nnPqHxmhMQozBWzYM4mQuo3XbF2WlsNFbOzFVyGhw1Bx1s91qvXBVWJh2ozrW0s6
|
||||
HYDV7ZkcTml/4kjA/d+mve6LZ8kuuR1qCiZx6rkffhh1gDN/1Xz3HVvIy/dQ+h9s
|
||||
5zp7PwUoWbhqp3WCOr156P6gR8qo7OlT6wMh33FSXK/mxikHK136fV2shwTKQVII
|
||||
rJBvXpj8nACUmi7scKuTWGeUoXa+dwTZVVe+b+L2U1ZM7+h/neTJiXn7u99PFUwu
|
||||
xVJtxaV37m3aXxtCsPnbBg==
|
||||
-----END DSA PRIVATE KEY-----"""
|
||||
|
||||
def testImportKey8(self):
|
||||
for pem in (self.pem_private_encrypted, tostr(self.pem_private_encrypted)):
|
||||
key_obj = DSA.importKey(pem, "PWDTEST")
|
||||
self.assertTrue(key_obj.has_private())
|
||||
self.assertEqual(self.y, key_obj.y)
|
||||
self.assertEqual(self.p, key_obj.p)
|
||||
self.assertEqual(self.q, key_obj.q)
|
||||
self.assertEqual(self.g, key_obj.g)
|
||||
self.assertEqual(self.x, key_obj.x)
|
||||
|
||||
def testExportKey8(self):
|
||||
tup = (self.y, self.g, self.p, self.q, self.x)
|
||||
key = DSA.construct(tup)
|
||||
encoded = key.exportKey('PEM', pkcs8=False, passphrase="PWDTEST")
|
||||
key = DSA.importKey(encoded, "PWDTEST")
|
||||
self.assertEqual(self.y, key.y)
|
||||
self.assertEqual(self.p, key.p)
|
||||
self.assertEqual(self.q, key.q)
|
||||
self.assertEqual(self.g, key.g)
|
||||
self.assertEqual(self.x, key.x)
|
||||
|
||||
# 9. Encrypted PKCS8
|
||||
# pbeWithMD5AndDES-CBC
|
||||
pem_pkcs8_encrypted="""\
|
||||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MIIBcTAbBgkqhkiG9w0BBQMwDgQI0GC3BJ/jSw8CAggABIIBUHc1cXZpExIE9tC7
|
||||
7ryiW+5ihtF2Ekurq3e408GYSAu5smJjN2bvQXmzRFBz8W38K8eMf1sbWroZ4+zn
|
||||
kZSbb9nSm5kAa8lR2+oF2k+WRswMR/PTC3f/D9STO2X0QxdrzKgIHEcSGSHp5jTx
|
||||
aVvbkCDHo9vhBTl6S3ogZ48As/MEro76+9igUwJ1jNhIQZPJ7e20QH5qDpQFFJN4
|
||||
CKl2ENSEuwGiqBszItFy4dqH0g63ZGZV/xt9wSO9Rd7SK/EbA/dklOxBa5Y/VItM
|
||||
gnIhs9XDMoGYyn6F023EicNJm6g/bVQk81BTTma4tm+12TKGdYm+QkeZvCOMZylr
|
||||
Wv67cKwO3cAXt5C3QXMDgYR64XvuaT5h7C0igMp2afSXJlnbHEbFxQVJlv83T4FM
|
||||
eZ4k+NQDbEL8GiHmFxzDWQAuPPZKJWEEEV2p/To+WOh+kSDHQw==
|
||||
-----END ENCRYPTED PRIVATE KEY-----"""
|
||||
|
||||
def testImportKey9(self):
|
||||
for pem in (self.pem_pkcs8_encrypted, tostr(self.pem_pkcs8_encrypted)):
|
||||
key_obj = DSA.importKey(pem, "PWDTEST")
|
||||
self.assertTrue(key_obj.has_private())
|
||||
self.assertEqual(self.y, key_obj.y)
|
||||
self.assertEqual(self.p, key_obj.p)
|
||||
self.assertEqual(self.q, key_obj.q)
|
||||
self.assertEqual(self.g, key_obj.g)
|
||||
self.assertEqual(self.x, key_obj.x)
|
||||
|
||||
# 10. Encrypted PKCS8
|
||||
# pkcs5PBES2 /
|
||||
# pkcs5PBKDF2 (rounds=1000, salt=D725BF1B6B8239F4) /
|
||||
# des-EDE3-CBC (iv=27A1C66C42AFEECE)
|
||||
#
|
||||
der_pkcs8_encrypted=\
|
||||
'30820196304006092a864886f70d01050d3033301b06092a864886f70d01050c'+\
|
||||
'300e0408d725bf1b6b8239f4020203e8301406082a864886f70d0307040827a1'+\
|
||||
'c66c42afeece048201505cacfde7bf8edabb3e0d387950dc872662ea7e9b1ed4'+\
|
||||
'400d2e7e6186284b64668d8d0328c33a9d9397e6f03df7cb68268b0a06b4e22f'+\
|
||||
'7d132821449ecf998a8b696dbc6dd2b19e66d7eb2edfeb4153c1771d49702395'+\
|
||||
'4f36072868b5fcccf93413a5ac4b2eb47d4b3f681c6bd67ae363ed776f45ae47'+\
|
||||
'174a00098a7c930a50f820b227ddf50f9742d8e950d02586ff2dac0e3c372248'+\
|
||||
'e5f9b6a7a02f4004f20c87913e0f7b52bccc209b95d478256a890b31d4c9adec'+\
|
||||
'21a4d157a179a93a3dad06f94f3ce486b46dfa7fc15fd852dd7680bbb2f17478'+\
|
||||
'7e71bd8dbaf81eca7518d76c1d26256e95424864ba45ca5d47d7c5a421be02fa'+\
|
||||
'b94ab01e18593f66cf9094eb5c94b9ecf3aa08b854a195cf87612fbe5e96c426'+\
|
||||
'2b0d573e52dc71ba3f5e468c601e816c49b7d32c698b22175e89aaef0c443770'+\
|
||||
'5ef2f88a116d99d8e2869a4fd09a771b84b49e4ccb79aadcb1c9'
|
||||
|
||||
def testImportKey10(self):
|
||||
key_obj = DSA.importKey(self.der_pkcs8_encrypted, "PWDTEST")
|
||||
self.assertTrue(key_obj.has_private())
|
||||
self.assertEqual(self.y, key_obj.y)
|
||||
self.assertEqual(self.p, key_obj.p)
|
||||
self.assertEqual(self.q, key_obj.q)
|
||||
self.assertEqual(self.g, key_obj.g)
|
||||
self.assertEqual(self.x, key_obj.x)
|
||||
|
||||
def testExportKey10(self):
|
||||
tup = (self.y, self.g, self.p, self.q, self.x)
|
||||
key = DSA.construct(tup)
|
||||
randfunc = BytesIO(unhexlify(b("27A1C66C42AFEECE") + b("D725BF1B6B8239F4"))).read
|
||||
encoded = key.exportKey('DER', pkcs8=True, passphrase="PWDTEST", randfunc=randfunc)
|
||||
self.assertEqual(self.der_pkcs8_encrypted, encoded)
|
||||
|
||||
# ----
|
||||
|
||||
def testImportError1(self):
|
||||
self.assertRaises(ValueError, DSA.importKey, self.der_pkcs8_encrypted, "wrongpwd")
|
||||
|
||||
def testExportError2(self):
|
||||
tup = (self.y, self.g, self.p, self.q, self.x)
|
||||
key = DSA.construct(tup)
|
||||
self.assertRaises(ValueError, key.exportKey, 'DER', pkcs8=False, passphrase="PWDTEST")
|
||||
|
||||
def test_import_key(self):
|
||||
"""Verify importKey is an alias to import_key"""
|
||||
|
||||
key_obj = DSA.import_key(self.der_public)
|
||||
self.assertFalse(key_obj.has_private())
|
||||
self.assertEqual(self.y, key_obj.y)
|
||||
self.assertEqual(self.p, key_obj.p)
|
||||
self.assertEqual(self.q, key_obj.q)
|
||||
self.assertEqual(self.g, key_obj.g)
|
||||
|
||||
|
||||
class ImportKeyFromX509Cert(unittest.TestCase):
|
||||
|
||||
def test_x509v1(self):
|
||||
|
||||
# Sample V1 certificate with a 1024 bit DSA key
|
||||
x509_v1_cert = """
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDUjCCArsCAQIwDQYJKoZIhvcNAQEFBQAwfjENMAsGA1UEChMEQWNtZTELMAkG
|
||||
A1UECxMCUkQxHDAaBgkqhkiG9w0BCQEWDXNwYW1AYWNtZS5vcmcxEzARBgNVBAcT
|
||||
Ck1ldHJvcG9saXMxETAPBgNVBAgTCE5ldyBZb3JrMQswCQYDVQQGEwJVUzENMAsG
|
||||
A1UEAxMEdGVzdDAeFw0xNDA3MTEyMDM4NDNaFw0xNzA0MDYyMDM4NDNaME0xCzAJ
|
||||
BgNVBAYTAlVTMREwDwYDVQQIEwhOZXcgWW9yazENMAsGA1UEChMEQWNtZTELMAkG
|
||||
A1UECxMCUkQxDzANBgNVBAMTBnBvbGFuZDCCAbYwggErBgcqhkjOOAQBMIIBHgKB
|
||||
gQDOrN4Ox4+t3T6wKeHfhzArhcrNEFMQ4Ss+4PIKyimDy9Bn64WPkL1B/9dvYIga
|
||||
23GLu6tVJmXo6EdJnVOHEMhr99EeOwuDWWeP7Awq7RSlKEejokr4BEzMTW/tExSD
|
||||
cO6/GI7xzh0eTH+VTTPDfyrJMYCkh0rJAfCP+5xrmPNetwIVALtXYOV1yoRrzJ2Q
|
||||
M5uEjidH6GiZAoGAfUqA1SAm5g5U68SILMVX9l5rq0OpB0waBMpJQ31/R/yXNDqo
|
||||
c3gGWZTOJFU4IzwNpGhrGNADUByz/lc1SAOAdEJIr0JVrhbGewQjB4pWqoLGbBKz
|
||||
RoavTNDc/zD7SYa12evWDHADwvlXoeQg+lWop1zS8OqaDC7aLGKpWN3/m8kDgYQA
|
||||
AoGAKoirPAfcp1rbbl4y2FFAIktfW8f4+T7d2iKSg73aiVfujhNOt1Zz1lfC0NI2
|
||||
eonLWO3tAM4XGKf1TLjb5UXngGn40okPsaA81YE6ZIKm20ywjlOY3QkAEdMaLVY3
|
||||
9PJvM8RGB9m7pLKxyHfGMfF40MVN4222zKeGp7xhM0CNiCUwDQYJKoZIhvcNAQEF
|
||||
BQADgYEAfbNZfpYa2KlALEM1FZnwvQDvJHntHz8LdeJ4WM7CXDlKi67wY2HKM30w
|
||||
s2xej75imkVOFd1kF2d0A8sjfriXLVIt1Hwq9ANZomhu4Edx0xpH8tqdh/bDtnM2
|
||||
TmduZNY9OWkb07h0CtWD6Zt8fhRllVsSSrlWd/2or7FXNC5weFQ=
|
||||
-----END CERTIFICATE-----
|
||||
""".strip()
|
||||
|
||||
# DSA public key as dumped by openssl
|
||||
y_str = """
|
||||
2a:88:ab:3c:07:dc:a7:5a:db:6e:5e:32:d8:51:40:
|
||||
22:4b:5f:5b:c7:f8:f9:3e:dd:da:22:92:83:bd:da:
|
||||
89:57:ee:8e:13:4e:b7:56:73:d6:57:c2:d0:d2:36:
|
||||
7a:89:cb:58:ed:ed:00:ce:17:18:a7:f5:4c:b8:db:
|
||||
e5:45:e7:80:69:f8:d2:89:0f:b1:a0:3c:d5:81:3a:
|
||||
64:82:a6:db:4c:b0:8e:53:98:dd:09:00:11:d3:1a:
|
||||
2d:56:37:f4:f2:6f:33:c4:46:07:d9:bb:a4:b2:b1:
|
||||
c8:77:c6:31:f1:78:d0:c5:4d:e3:6d:b6:cc:a7:86:
|
||||
a7:bc:61:33:40:8d:88:25
|
||||
"""
|
||||
p_str = """
|
||||
00:ce:ac:de:0e:c7:8f:ad:dd:3e:b0:29:e1:df:87:
|
||||
30:2b:85:ca:cd:10:53:10:e1:2b:3e:e0:f2:0a:ca:
|
||||
29:83:cb:d0:67:eb:85:8f:90:bd:41:ff:d7:6f:60:
|
||||
88:1a:db:71:8b:bb:ab:55:26:65:e8:e8:47:49:9d:
|
||||
53:87:10:c8:6b:f7:d1:1e:3b:0b:83:59:67:8f:ec:
|
||||
0c:2a:ed:14:a5:28:47:a3:a2:4a:f8:04:4c:cc:4d:
|
||||
6f:ed:13:14:83:70:ee:bf:18:8e:f1:ce:1d:1e:4c:
|
||||
7f:95:4d:33:c3:7f:2a:c9:31:80:a4:87:4a:c9:01:
|
||||
f0:8f:fb:9c:6b:98:f3:5e:b7
|
||||
"""
|
||||
q_str = """
|
||||
00:bb:57:60:e5:75:ca:84:6b:cc:9d:90:33:9b:84:
|
||||
8e:27:47:e8:68:99
|
||||
"""
|
||||
g_str = """
|
||||
7d:4a:80:d5:20:26:e6:0e:54:eb:c4:88:2c:c5:57:
|
||||
f6:5e:6b:ab:43:a9:07:4c:1a:04:ca:49:43:7d:7f:
|
||||
47:fc:97:34:3a:a8:73:78:06:59:94:ce:24:55:38:
|
||||
23:3c:0d:a4:68:6b:18:d0:03:50:1c:b3:fe:57:35:
|
||||
48:03:80:74:42:48:af:42:55:ae:16:c6:7b:04:23:
|
||||
07:8a:56:aa:82:c6:6c:12:b3:46:86:af:4c:d0:dc:
|
||||
ff:30:fb:49:86:b5:d9:eb:d6:0c:70:03:c2:f9:57:
|
||||
a1:e4:20:fa:55:a8:a7:5c:d2:f0:ea:9a:0c:2e:da:
|
||||
2c:62:a9:58:dd:ff:9b:c9
|
||||
"""
|
||||
|
||||
key = DSA.importKey(x509_v1_cert)
|
||||
for comp_name in ('y', 'p', 'q', 'g'):
|
||||
comp_str = locals()[comp_name + "_str"]
|
||||
comp = int(re.sub("[^0-9a-f]", "", comp_str), 16)
|
||||
self.assertEqual(getattr(key, comp_name), comp)
|
||||
self.assertFalse(key.has_private())
|
||||
|
||||
def test_x509v3(self):
|
||||
|
||||
# Sample V3 certificate with a 1024 bit DSA key
|
||||
x509_v3_cert = """
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFhjCCA26gAwIBAgIBAzANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQGEwJVUzEL
|
||||
MAkGA1UECAwCTUQxEjAQBgNVBAcMCUJhbHRpbW9yZTEQMA4GA1UEAwwHVGVzdCBD
|
||||
QTEfMB0GCSqGSIb3DQEJARYQdGVzdEBleGFtcGxlLmNvbTAeFw0xNDA3MTMyMDUz
|
||||
MjBaFw0xNzA0MDgyMDUzMjBaMEAxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJNRDES
|
||||
MBAGA1UEBwwJQmFsdGltb3JlMRAwDgYDVQQDDAdhdXN0cmlhMIIBtjCCASsGByqG
|
||||
SM44BAEwggEeAoGBALfd8gyEpVPA0ZI69Kp3nyJcu5N0ZZ3K1K9hleQLNqKEcZOh
|
||||
7a/C2J1TPdmHTLJ0rAwBZ1nWxnARSgRphziGDFspKCYQwYcSMz8KoFgvXbXpuchy
|
||||
oFACiQ2LqZnc5MakuLQtLcQciSYGYj3zmZdYMoa904F1aDWr+DxQI6DVC3/bAhUA
|
||||
hqXMCJ6fQK3G2O9S3/CC/yVZXCsCgYBRXROl3R2khX7l10LQjDEgo3B1IzjXU/jP
|
||||
McMBl6XO+nBJXxr/scbq8Ajiv7LTnGpSjgryHtvfj887kfvo8QbSS3kp3vq5uSqI
|
||||
ui7E7r3jguWaLj616AG1HWOctXJUjqsiabZwsp2h09gHTzmHEXBOmiARu8xFxKAH
|
||||
xsuo7onAbwOBhAACgYBylWjWSnKHE8mHx1A5m/0GQx6xnhWIe3+MJAnEhRGxA2J4
|
||||
SCsfWU0OwglIQToh1z5uUU9oDi9cYgNPBevOFRnDhc2yaJY6VAYnI+D+6J5IU6Yd
|
||||
0iaG/iSc4sV4bFr0axcPpse3SN0XaQxiKeSFBfFnoMqL+dd9Gb3QPZSllBcVD6OB
|
||||
1TCB0jAdBgNVHQ4EFgQUx5wN0Puotv388M9Tp/fsPbZpzAUwHwYDVR0jBBgwFoAU
|
||||
a0hkif3RMaraiWtsOOZZlLu9wJwwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwSgYD
|
||||
VR0RBEMwQYILZXhhbXBsZS5jb22CD3d3dy5leGFtcGxlLmNvbYIQbWFpbC5leGFt
|
||||
cGxlLmNvbYIPZnRwLmV4YW1wbGUuY29tMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NM
|
||||
IEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTANBgkqhkiG9w0BAQsFAAOCAgEAyWf1TiJI
|
||||
aNEIA9o/PG8/JiGASTS2/HBVTJbkq03k6NkJVk/GxC1DPziTUJ+CdWlHWcAi1EOW
|
||||
Ach3QxNDRrVfCOfCMDgElIO1094/reJgdFYG00LRi8QkRJuxANV7YS4tLudhyHJC
|
||||
kR2lhdMNmEuzWK+s2y+5cLrdm7qdvdENQCcV67uvGPx4sc+EaE7x13SczKjWBtbo
|
||||
QCs6JTOW+EkPRl4Zo27K4OIZ43/J+GxvwU9QUVH3wPVdbbLNw+QeTFBYMTEcxyc4
|
||||
kv50HPBFaithziXBFyvdIs19FjkFzu0Uz/e0zb1+vMzQlJMD94HVOrMnIj5Sb2cL
|
||||
KKdYXS4uhxFJmdV091Xur5JkYYwEzuaGav7J3zOzYutrIGTgDluLCvA+VQkRcTsy
|
||||
jZ065SkY/v+38QHp+cmm8WRluupJTs8wYzVp6Fu0iFaaK7ztFmaZmHpiPIfDFjva
|
||||
aCIgzzT5NweJd/b71A2SyzHXJ14zBXsr1PMylMp2TpHIidhuuNuQL6I0HaollB4M
|
||||
Z3FsVBMhVDw4Z76qnFPr8mZE2tar33hSlJI/3pS/bBiukuBk8U7VB0X8OqaUnP3C
|
||||
7b2Z4G8GtqDVcKGMzkvMjT4n9rKd/Le+qHSsQOGO9W/0LB7UDAZSwUsfAPnoBgdS
|
||||
5t9tIomLCOstByXi+gGZue1TcdCa3Ph4kO0=
|
||||
-----END CERTIFICATE-----
|
||||
""".strip()
|
||||
|
||||
# DSA public key as dumped by openssl
|
||||
y_str = """
|
||||
72:95:68:d6:4a:72:87:13:c9:87:c7:50:39:9b:fd:
|
||||
06:43:1e:b1:9e:15:88:7b:7f:8c:24:09:c4:85:11:
|
||||
b1:03:62:78:48:2b:1f:59:4d:0e:c2:09:48:41:3a:
|
||||
21:d7:3e:6e:51:4f:68:0e:2f:5c:62:03:4f:05:eb:
|
||||
ce:15:19:c3:85:cd:b2:68:96:3a:54:06:27:23:e0:
|
||||
fe:e8:9e:48:53:a6:1d:d2:26:86:fe:24:9c:e2:c5:
|
||||
78:6c:5a:f4:6b:17:0f:a6:c7:b7:48:dd:17:69:0c:
|
||||
62:29:e4:85:05:f1:67:a0:ca:8b:f9:d7:7d:19:bd:
|
||||
d0:3d:94:a5:94:17:15:0f
|
||||
"""
|
||||
p_str = """
|
||||
00:b7:dd:f2:0c:84:a5:53:c0:d1:92:3a:f4:aa:77:
|
||||
9f:22:5c:bb:93:74:65:9d:ca:d4:af:61:95:e4:0b:
|
||||
36:a2:84:71:93:a1:ed:af:c2:d8:9d:53:3d:d9:87:
|
||||
4c:b2:74:ac:0c:01:67:59:d6:c6:70:11:4a:04:69:
|
||||
87:38:86:0c:5b:29:28:26:10:c1:87:12:33:3f:0a:
|
||||
a0:58:2f:5d:b5:e9:b9:c8:72:a0:50:02:89:0d:8b:
|
||||
a9:99:dc:e4:c6:a4:b8:b4:2d:2d:c4:1c:89:26:06:
|
||||
62:3d:f3:99:97:58:32:86:bd:d3:81:75:68:35:ab:
|
||||
f8:3c:50:23:a0:d5:0b:7f:db
|
||||
"""
|
||||
q_str = """
|
||||
00:86:a5:cc:08:9e:9f:40:ad:c6:d8:ef:52:df:f0:
|
||||
82:ff:25:59:5c:2b
|
||||
"""
|
||||
g_str = """
|
||||
51:5d:13:a5:dd:1d:a4:85:7e:e5:d7:42:d0:8c:31:
|
||||
20:a3:70:75:23:38:d7:53:f8:cf:31:c3:01:97:a5:
|
||||
ce:fa:70:49:5f:1a:ff:b1:c6:ea:f0:08:e2:bf:b2:
|
||||
d3:9c:6a:52:8e:0a:f2:1e:db:df:8f:cf:3b:91:fb:
|
||||
e8:f1:06:d2:4b:79:29:de:fa:b9:b9:2a:88:ba:2e:
|
||||
c4:ee:bd:e3:82:e5:9a:2e:3e:b5:e8:01:b5:1d:63:
|
||||
9c:b5:72:54:8e:ab:22:69:b6:70:b2:9d:a1:d3:d8:
|
||||
07:4f:39:87:11:70:4e:9a:20:11:bb:cc:45:c4:a0:
|
||||
07:c6:cb:a8:ee:89:c0:6f
|
||||
"""
|
||||
|
||||
key = DSA.importKey(x509_v3_cert)
|
||||
for comp_name in ('y', 'p', 'q', 'g'):
|
||||
comp_str = locals()[comp_name + "_str"]
|
||||
comp = int(re.sub("[^0-9a-f]", "", comp_str), 16)
|
||||
self.assertEqual(getattr(key, comp_name), comp)
|
||||
self.assertFalse(key.has_private())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
def get_tests(config={}):
|
||||
tests = []
|
||||
tests += list_test_cases(ImportKeyTests)
|
||||
tests += list_test_cases(ImportKeyFromX509Cert)
|
||||
return tests
|
||||
|
||||
if __name__ == '__main__':
|
||||
suite = lambda: unittest.TestSuite(get_tests())
|
||||
unittest.main(defaultTest='suite')
|
||||
|
|
@ -0,0 +1,392 @@
|
|||
# ===================================================================
|
||||
#
|
||||
# Copyright (c) 2015, Legrandin <helderijs@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
# ===================================================================
|
||||
|
||||
import unittest
|
||||
from Crypto.SelfTest.st_common import list_test_cases
|
||||
from Crypto.Util._file_system import pycryptodome_filename
|
||||
from Crypto.Util.py3compat import b, unhexlify, bord, tostr
|
||||
from Crypto.Util.number import bytes_to_long
|
||||
from Crypto.Hash import SHAKE128
|
||||
|
||||
from Crypto.PublicKey import ECC
|
||||
|
||||
def load_file(filename, mode="rb"):
|
||||
fd = open(pycryptodome_filename([
|
||||
"Crypto",
|
||||
"SelfTest",
|
||||
"PublicKey",
|
||||
"test_vectors",
|
||||
"ECC",
|
||||
], filename), mode)
|
||||
return fd.read()
|
||||
|
||||
|
||||
def compact(lines):
|
||||
ext = b("").join(lines)
|
||||
return unhexlify(tostr(ext).replace(" ", "").replace(":", ""))
|
||||
|
||||
|
||||
def create_ref_keys():
|
||||
key_lines = load_file("ecc_p256.txt").splitlines()
|
||||
private_key_d = bytes_to_long(compact(key_lines[2:5]))
|
||||
public_key_xy = compact(key_lines[6:11])
|
||||
assert bord(public_key_xy[0]) == 4 # Uncompressed
|
||||
public_key_x = bytes_to_long(public_key_xy[1:33])
|
||||
public_key_y = bytes_to_long(public_key_xy[33:])
|
||||
|
||||
return (ECC.construct(curve="P-256", d=private_key_d),
|
||||
ECC.construct(curve="P-256", point_x=public_key_x, point_y=public_key_y))
|
||||
|
||||
|
||||
# Create reference key pair
|
||||
ref_private, ref_public = create_ref_keys()
|
||||
|
||||
|
||||
def get_fixed_prng():
|
||||
return SHAKE128.new().update(b("SEED")).read
|
||||
|
||||
|
||||
class TestImport(unittest.TestCase):
|
||||
|
||||
def test_import_public_der(self):
|
||||
key_file = load_file("ecc_p256_public.der")
|
||||
|
||||
key = ECC._import_subjectPublicKeyInfo(key_file)
|
||||
self.assertEqual(ref_public, key)
|
||||
|
||||
key = ECC._import_der(key_file, None)
|
||||
self.assertEqual(ref_public, key)
|
||||
|
||||
key = ECC.import_key(key_file)
|
||||
self.assertEqual(ref_public, key)
|
||||
|
||||
def test_import_private_der(self):
|
||||
key_file = load_file("ecc_p256_private.der")
|
||||
|
||||
key = ECC._import_private_der(key_file, None)
|
||||
self.assertEqual(ref_private, key)
|
||||
|
||||
key = ECC._import_der(key_file, None)
|
||||
self.assertEqual(ref_private, key)
|
||||
|
||||
key = ECC.import_key(key_file)
|
||||
self.assertEqual(ref_private, key)
|
||||
|
||||
def test_import_private_pkcs8_clear(self):
|
||||
key_file = load_file("ecc_p256_private_p8_clear.der")
|
||||
|
||||
key = ECC._import_der(key_file, None)
|
||||
self.assertEqual(ref_private, key)
|
||||
|
||||
key = ECC.import_key(key_file)
|
||||
self.assertEqual(ref_private, key)
|
||||
|
||||
def test_import_private_pkcs8_in_pem_clear(self):
|
||||
key_file = load_file("ecc_p256_private_p8_clear.pem")
|
||||
|
||||
key = ECC.import_key(key_file)
|
||||
self.assertEqual(ref_private, key)
|
||||
|
||||
def test_import_private_pkcs8_encrypted_1(self):
|
||||
key_file = load_file("ecc_p256_private_p8.der")
|
||||
|
||||
key = ECC._import_der(key_file, "secret")
|
||||
self.assertEqual(ref_private, key)
|
||||
|
||||
key = ECC.import_key(key_file, "secret")
|
||||
self.assertEqual(ref_private, key)
|
||||
|
||||
def test_import_private_pkcs8_encrypted_2(self):
|
||||
key_file = load_file("ecc_p256_private_p8.pem")
|
||||
|
||||
key = ECC.import_key(key_file, "secret")
|
||||
self.assertEqual(ref_private, key)
|
||||
|
||||
def test_import_x509_der(self):
|
||||
key_file = load_file("ecc_p256_x509.der")
|
||||
|
||||
key = ECC._import_der(key_file, None)
|
||||
self.assertEqual(ref_public, key)
|
||||
|
||||
key = ECC.import_key(key_file)
|
||||
self.assertEqual(ref_public, key)
|
||||
|
||||
def test_import_public_pem(self):
|
||||
key_file = load_file("ecc_p256_public.pem")
|
||||
|
||||
key = ECC.import_key(key_file)
|
||||
self.assertEqual(ref_public, key)
|
||||
|
||||
def test_import_private_pem(self):
|
||||
key_file = load_file("ecc_p256_private.pem")
|
||||
|
||||
key = ECC.import_key(key_file)
|
||||
self.assertEqual(ref_private, key)
|
||||
|
||||
def test_import_private_pem_encrypted(self):
|
||||
for algo in "des3", : # TODO: , "aes128", "aes192", "aes256_gcm":
|
||||
key_file = load_file("ecc_p256_private_enc_%s.pem" % algo)
|
||||
|
||||
key = ECC.import_key(key_file, "secret")
|
||||
self.assertEqual(ref_private, key)
|
||||
|
||||
key = ECC.import_key(tostr(key_file), b("secret"))
|
||||
self.assertEqual(ref_private, key)
|
||||
|
||||
def test_import_x509_pem(self):
|
||||
key_file = load_file("ecc_p256_x509.pem")
|
||||
|
||||
key = ECC.import_key(key_file)
|
||||
self.assertEqual(ref_public, key)
|
||||
|
||||
def test_import_openssh(self):
|
||||
key_file = load_file("ecc_p256_public_openssh.txt")
|
||||
|
||||
key = ECC._import_openssh(key_file)
|
||||
self.assertEqual(ref_public, key)
|
||||
|
||||
key = ECC.import_key(key_file)
|
||||
self.assertEqual(ref_public, key)
|
||||
|
||||
|
||||
class TestExport(unittest.TestCase):
|
||||
|
||||
def test_export_public_der(self):
|
||||
key_file = load_file("ecc_p256_public.der")
|
||||
|
||||
encoded = ref_public._export_subjectPublicKeyInfo()
|
||||
self.assertEqual(key_file, encoded)
|
||||
|
||||
# ---
|
||||
|
||||
encoded = ref_public.export_key(format="DER")
|
||||
self.assertEqual(key_file, encoded)
|
||||
|
||||
def test_export_private_der(self):
|
||||
key_file = load_file("ecc_p256_private.der")
|
||||
|
||||
encoded = ref_private._export_private_der()
|
||||
self.assertEqual(key_file, encoded)
|
||||
|
||||
# ---
|
||||
|
||||
encoded = ref_private.export_key(format="DER", use_pkcs8=False)
|
||||
self.assertEqual(key_file, encoded)
|
||||
|
||||
def test_export_private_pkcs8_clear(self):
|
||||
key_file = load_file("ecc_p256_private_p8_clear.der")
|
||||
|
||||
encoded = ref_private._export_pkcs8()
|
||||
self.assertEqual(key_file, encoded)
|
||||
|
||||
# ---
|
||||
|
||||
encoded = ref_private.export_key(format="DER")
|
||||
self.assertEqual(key_file, encoded)
|
||||
|
||||
def test_export_private_pkcs8_encrypted(self):
|
||||
encoded = ref_private._export_pkcs8(passphrase="secret",
|
||||
protection="PBKDF2WithHMAC-SHA1AndAES128-CBC")
|
||||
|
||||
# This should prove that the output is password-protected
|
||||
self.assertRaises(ValueError, ECC._import_pkcs8, encoded, None)
|
||||
|
||||
decoded = ECC._import_pkcs8(encoded, "secret")
|
||||
self.assertEqual(ref_private, decoded)
|
||||
|
||||
# ---
|
||||
|
||||
encoded = ref_private.export_key(format="DER",
|
||||
passphrase="secret",
|
||||
protection="PBKDF2WithHMAC-SHA1AndAES128-CBC")
|
||||
decoded = ECC.import_key(encoded, "secret")
|
||||
self.assertEqual(ref_private, decoded)
|
||||
|
||||
def test_export_public_pem(self):
|
||||
key_file = load_file("ecc_p256_public.pem", "rt").strip()
|
||||
|
||||
encoded = ref_private._export_public_pem()
|
||||
self.assertEqual(key_file, encoded)
|
||||
|
||||
# ---
|
||||
|
||||
encoded = ref_public.export_key(format="PEM")
|
||||
self.assertEqual(key_file, encoded)
|
||||
|
||||
def test_export_private_pem_clear(self):
|
||||
key_file = load_file("ecc_p256_private.pem", "rt").strip()
|
||||
|
||||
encoded = ref_private._export_private_pem(None)
|
||||
self.assertEqual(key_file, encoded)
|
||||
|
||||
# ---
|
||||
|
||||
encoded = ref_private.export_key(format="PEM", use_pkcs8=False)
|
||||
self.assertEqual(key_file, encoded)
|
||||
|
||||
def test_export_private_pem_encrypted(self):
|
||||
encoded = ref_private._export_private_pem(passphrase=b("secret"))
|
||||
|
||||
# This should prove that the output is password-protected
|
||||
self.assertRaises(ValueError, ECC.import_key, encoded)
|
||||
|
||||
assert "EC PRIVATE KEY" in encoded
|
||||
|
||||
decoded = ECC.import_key(encoded, "secret")
|
||||
self.assertEqual(ref_private, decoded)
|
||||
|
||||
# ---
|
||||
|
||||
encoded = ref_private.export_key(format="PEM",
|
||||
passphrase="secret",
|
||||
use_pkcs8=False)
|
||||
decoded = ECC.import_key(encoded, "secret")
|
||||
self.assertEqual(ref_private, decoded)
|
||||
|
||||
def test_export_private_pkcs8_and_pem_1(self):
|
||||
# PKCS8 inside PEM with both unencrypted
|
||||
key_file = load_file("ecc_p256_private_p8_clear.pem", "rt").strip()
|
||||
|
||||
encoded = ref_private._export_private_clear_pkcs8_in_clear_pem()
|
||||
self.assertEqual(key_file, encoded)
|
||||
|
||||
# ---
|
||||
|
||||
encoded = ref_private.export_key(format="PEM")
|
||||
self.assertEqual(key_file, encoded)
|
||||
|
||||
def test_export_private_pkcs8_and_pem_2(self):
|
||||
# PKCS8 inside PEM with PKCS8 encryption
|
||||
encoded = ref_private._export_private_encrypted_pkcs8_in_clear_pem("secret",
|
||||
protection="PBKDF2WithHMAC-SHA1AndAES128-CBC")
|
||||
|
||||
# This should prove that the output is password-protected
|
||||
self.assertRaises(ValueError, ECC.import_key, encoded)
|
||||
|
||||
assert "ENCRYPTED PRIVATE KEY" in encoded
|
||||
|
||||
decoded = ECC.import_key(encoded, "secret")
|
||||
self.assertEqual(ref_private, decoded)
|
||||
|
||||
# ---
|
||||
|
||||
encoded = ref_private.export_key(format="PEM",
|
||||
passphrase="secret",
|
||||
protection="PBKDF2WithHMAC-SHA1AndAES128-CBC")
|
||||
decoded = ECC.import_key(encoded, "secret")
|
||||
self.assertEqual(ref_private, decoded)
|
||||
|
||||
def test_export_openssh(self):
|
||||
key_file = load_file("ecc_p256_public_openssh.txt", "rt")
|
||||
|
||||
encoded = ref_public._export_openssh()
|
||||
self.assertEqual(key_file, encoded)
|
||||
|
||||
# ---
|
||||
|
||||
encoded = ref_public.export_key(format="OpenSSH")
|
||||
self.assertEqual(key_file, encoded)
|
||||
|
||||
def test_prng(self):
|
||||
# Test that password-protected containers use the provided PRNG
|
||||
encoded1 = ref_private.export_key(format="PEM",
|
||||
passphrase="secret",
|
||||
protection="PBKDF2WithHMAC-SHA1AndAES128-CBC",
|
||||
randfunc=get_fixed_prng())
|
||||
encoded2 = ref_private.export_key(format="PEM",
|
||||
passphrase="secret",
|
||||
protection="PBKDF2WithHMAC-SHA1AndAES128-CBC",
|
||||
randfunc=get_fixed_prng())
|
||||
self.assertEqual(encoded1, encoded2)
|
||||
|
||||
# ---
|
||||
|
||||
encoded1 = ref_private.export_key(format="PEM",
|
||||
use_pkcs8=False,
|
||||
passphrase="secret",
|
||||
randfunc=get_fixed_prng())
|
||||
encoded2 = ref_private.export_key(format="PEM",
|
||||
use_pkcs8=False,
|
||||
passphrase="secret",
|
||||
randfunc=get_fixed_prng())
|
||||
self.assertEqual(encoded1, encoded2)
|
||||
|
||||
def test_byte_or_string_passphrase(self):
|
||||
encoded1 = ref_private.export_key(format="PEM",
|
||||
use_pkcs8=False,
|
||||
passphrase="secret",
|
||||
randfunc=get_fixed_prng())
|
||||
encoded2 = ref_private.export_key(format="PEM",
|
||||
use_pkcs8=False,
|
||||
passphrase=b("secret"),
|
||||
randfunc=get_fixed_prng())
|
||||
self.assertEqual(encoded1, encoded2)
|
||||
|
||||
def test_error_params1(self):
|
||||
# Unknown format
|
||||
self.assertRaises(ValueError, ref_private.export_key, format="XXX")
|
||||
|
||||
# Missing 'protection' parameter when PKCS#8 is used
|
||||
ref_private.export_key(format="PEM", passphrase="secret",
|
||||
use_pkcs8=False)
|
||||
self.assertRaises(ValueError, ref_private.export_key, format="PEM",
|
||||
passphrase="secret")
|
||||
|
||||
# DER format but no PKCS#8
|
||||
self.assertRaises(ValueError, ref_private.export_key, format="DER",
|
||||
passphrase="secret",
|
||||
use_pkcs8=False,
|
||||
protection="PBKDF2WithHMAC-SHA1AndAES128-CBC")
|
||||
|
||||
# Incorrect parameters for public keys
|
||||
self.assertRaises(ValueError, ref_public.export_key, format="DER",
|
||||
use_pkcs8=False)
|
||||
|
||||
# Empty password
|
||||
self.assertRaises(ValueError, ref_private.export_key, format="PEM",
|
||||
passphrase="", use_pkcs8=False)
|
||||
self.assertRaises(ValueError, ref_private.export_key, format="PEM",
|
||||
passphrase="",
|
||||
protection="PBKDF2WithHMAC-SHA1AndAES128-CBC")
|
||||
|
||||
# No private keys with OpenSSH
|
||||
self.assertRaises(ValueError, ref_private.export_key, format="OpenSSH",
|
||||
passphrase="secret")
|
||||
|
||||
|
||||
def get_tests(config={}):
|
||||
tests = []
|
||||
tests += list_test_cases(TestImport)
|
||||
tests += list_test_cases(TestExport)
|
||||
return tests
|
||||
|
||||
if __name__ == '__main__':
|
||||
suite = lambda: unittest.TestSuite(get_tests())
|
||||
unittest.main(defaultTest='suite')
|
|
@ -0,0 +1,501 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# SelfTest/PublicKey/test_importKey.py: Self-test for importing RSA keys
|
||||
#
|
||||
# ===================================================================
|
||||
# The contents of this file are dedicated to the public domain. To
|
||||
# the extent that dedication to the public domain is not available,
|
||||
# everyone is granted a worldwide, perpetual, royalty-free,
|
||||
# non-exclusive license to exercise all rights associated with the
|
||||
# contents of this file for any purpose whatsoever.
|
||||
# No rights are reserved.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
# ===================================================================
|
||||
|
||||
import unittest
|
||||
import re
|
||||
|
||||
from Crypto.PublicKey import RSA
|
||||
from Crypto.SelfTest.st_common import *
|
||||
from Crypto.Util.py3compat import *
|
||||
from Crypto.Util.number import inverse
|
||||
from Crypto.Util import asn1
|
||||
|
||||
def der2pem(der, text='PUBLIC'):
|
||||
import binascii
|
||||
chunks = [ binascii.b2a_base64(der[i:i+48]) for i in range(0, len(der), 48) ]
|
||||
pem = b('-----BEGIN %s KEY-----\n' % text)
|
||||
pem += b('').join(chunks)
|
||||
pem += b('-----END %s KEY-----' % text)
|
||||
return pem
|
||||
|
||||
class ImportKeyTests(unittest.TestCase):
|
||||
# 512-bit RSA key generated with openssl
|
||||
rsaKeyPEM = '''-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIBOwIBAAJBAL8eJ5AKoIsjURpcEoGubZMxLD7+kT+TLr7UkvEtFrRhDDKMtuII
|
||||
q19FrL4pUIMymPMSLBn3hJLe30Dw48GQM4UCAwEAAQJACUSDEp8RTe32ftq8IwG8
|
||||
Wojl5mAd1wFiIOrZ/Uv8b963WJOJiuQcVN29vxU5+My9GPZ7RA3hrDBEAoHUDPrI
|
||||
OQIhAPIPLz4dphiD9imAkivY31Rc5AfHJiQRA7XixTcjEkojAiEAyh/pJHks/Mlr
|
||||
+rdPNEpotBjfV4M4BkgGAA/ipcmaAjcCIQCHvhwwKVBLzzTscT2HeUdEeBMoiXXK
|
||||
JACAr3sJQJGxIQIgarRp+m1WSKV1MciwMaTOnbU7wxFs9DP1pva76lYBzgUCIQC9
|
||||
n0CnZCJ6IZYqSt0H5N7+Q+2Ro64nuwV/OSQfM6sBwQ==
|
||||
-----END RSA PRIVATE KEY-----'''
|
||||
|
||||
# As above, but this is actually an unencrypted PKCS#8 key
|
||||
rsaKeyPEM8 = '''-----BEGIN PRIVATE KEY-----
|
||||
MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAvx4nkAqgiyNRGlwS
|
||||
ga5tkzEsPv6RP5MuvtSS8S0WtGEMMoy24girX0WsvilQgzKY8xIsGfeEkt7fQPDj
|
||||
wZAzhQIDAQABAkAJRIMSnxFN7fZ+2rwjAbxaiOXmYB3XAWIg6tn9S/xv3rdYk4mK
|
||||
5BxU3b2/FTn4zL0Y9ntEDeGsMEQCgdQM+sg5AiEA8g8vPh2mGIP2KYCSK9jfVFzk
|
||||
B8cmJBEDteLFNyMSSiMCIQDKH+kkeSz8yWv6t080Smi0GN9XgzgGSAYAD+KlyZoC
|
||||
NwIhAIe+HDApUEvPNOxxPYd5R0R4EyiJdcokAICvewlAkbEhAiBqtGn6bVZIpXUx
|
||||
yLAxpM6dtTvDEWz0M/Wm9rvqVgHOBQIhAL2fQKdkInohlipK3Qfk3v5D7ZGjrie7
|
||||
BX85JB8zqwHB
|
||||
-----END PRIVATE KEY-----'''
|
||||
|
||||
# The same RSA private key as in rsaKeyPEM, but now encrypted
|
||||
rsaKeyEncryptedPEM=(
|
||||
|
||||
# PEM encryption
|
||||
# With DES and passphrase 'test'
|
||||
('test', '''-----BEGIN RSA PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: DES-CBC,AF8F9A40BD2FA2FC
|
||||
|
||||
Ckl9ex1kaVEWhYC2QBmfaF+YPiR4NFkRXA7nj3dcnuFEzBnY5XULupqQpQI3qbfA
|
||||
u8GYS7+b3toWWiHZivHbAAUBPDIZG9hKDyB9Sq2VMARGsX1yW1zhNvZLIiVJzUHs
|
||||
C6NxQ1IJWOXzTew/xM2I26kPwHIvadq+/VaT8gLQdjdH0jOiVNaevjWnLgrn1mLP
|
||||
BCNRMdcexozWtAFNNqSzfW58MJL2OdMi21ED184EFytIc1BlB+FZiGZduwKGuaKy
|
||||
9bMbdb/1PSvsSzPsqW7KSSrTw6MgJAFJg6lzIYvR5F4poTVBxwBX3+EyEmShiaNY
|
||||
IRX3TgQI0IjrVuLmvlZKbGWP18FXj7I7k9tSsNOOzllTTdq3ny5vgM3A+ynfAaxp
|
||||
dysKznQ6P+IoqML1WxAID4aGRMWka+uArOJ148Rbj9s=
|
||||
-----END RSA PRIVATE KEY-----'''),
|
||||
|
||||
# PKCS8 encryption
|
||||
('winter', '''-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MIIBpjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIeZIsbW3O+JcCAggA
|
||||
MBQGCCqGSIb3DQMHBAgSM2p0D8FilgSCAWBhFyP2tiGKVpGj3mO8qIBzinU60ApR
|
||||
3unvP+N6j7LVgnV2lFGaXbJ6a1PbQXe+2D6DUyBLo8EMXrKKVLqOMGkFMHc0UaV6
|
||||
R6MmrsRDrbOqdpTuVRW+NVd5J9kQQh4xnfU/QrcPPt7vpJvSf4GzG0n666Ki50OV
|
||||
M/feuVlIiyGXY6UWdVDpcOV72cq02eNUs/1JWdh2uEBvA9fCL0c07RnMrdT+CbJQ
|
||||
NjJ7f8ULtp7xvR9O3Al/yJ4Wv3i4VxF1f3MCXzhlUD4I0ONlr0kJWgeQ80q/cWhw
|
||||
ntvgJwnCn2XR1h6LA8Wp+0ghDTsL2NhJpWd78zClGhyU4r3hqu1XDjoXa7YCXCix
|
||||
jCV15+ViDJzlNCwg+W6lRg18sSLkCT7alviIE0U5tHc6UPbbHwT5QqAxAABaP+nZ
|
||||
CGqJGyiwBzrKebjgSm/KRd4C91XqcsysyH2kKPfT51MLAoD4xelOURBP
|
||||
-----END ENCRYPTED PRIVATE KEY-----'''
|
||||
),
|
||||
)
|
||||
|
||||
rsaPublicKeyPEM = '''-----BEGIN RSA PUBLIC KEY-----
|
||||
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAL8eJ5AKoIsjURpcEoGubZMxLD7+kT+T
|
||||
Lr7UkvEtFrRhDDKMtuIIq19FrL4pUIMymPMSLBn3hJLe30Dw48GQM4UCAwEAAQ==
|
||||
-----END RSA PUBLIC KEY-----'''
|
||||
|
||||
# Obtained using 'ssh-keygen -i -m PKCS8 -f rsaPublicKeyPEM'
|
||||
rsaPublicKeyOpenSSH = b('''ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAQQC/HieQCqCLI1EaXBKBrm2TMSw+/pE/ky6+1JLxLRa0YQwyjLbiCKtfRay+KVCDMpjzEiwZ94SS3t9A8OPBkDOF comment\n''')
|
||||
|
||||
# The private key, in PKCS#1 format encoded with DER
|
||||
rsaKeyDER = a2b_hex(
|
||||
'''3082013b020100024100bf1e27900aa08b23511a5c1281ae6d93312c3efe
|
||||
913f932ebed492f12d16b4610c328cb6e208ab5f45acbe2950833298f312
|
||||
2c19f78492dedf40f0e3c190338502030100010240094483129f114dedf6
|
||||
7edabc2301bc5a88e5e6601dd7016220ead9fd4bfc6fdeb75893898ae41c
|
||||
54ddbdbf1539f8ccbd18f67b440de1ac30440281d40cfac839022100f20f
|
||||
2f3e1da61883f62980922bd8df545ce407c726241103b5e2c53723124a23
|
||||
022100ca1fe924792cfcc96bfab74f344a68b418df578338064806000fe2
|
||||
a5c99a023702210087be1c3029504bcf34ec713d877947447813288975ca
|
||||
240080af7b094091b12102206ab469fa6d5648a57531c8b031a4ce9db53b
|
||||
c3116cf433f5a6f6bbea5601ce05022100bd9f40a764227a21962a4add07
|
||||
e4defe43ed91a3ae27bb057f39241f33ab01c1
|
||||
'''.replace(" ",""))
|
||||
|
||||
# The private key, in unencrypted PKCS#8 format encoded with DER
|
||||
rsaKeyDER8 = a2b_hex(
|
||||
'''30820155020100300d06092a864886f70d01010105000482013f3082013
|
||||
b020100024100bf1e27900aa08b23511a5c1281ae6d93312c3efe913f932
|
||||
ebed492f12d16b4610c328cb6e208ab5f45acbe2950833298f3122c19f78
|
||||
492dedf40f0e3c190338502030100010240094483129f114dedf67edabc2
|
||||
301bc5a88e5e6601dd7016220ead9fd4bfc6fdeb75893898ae41c54ddbdb
|
||||
f1539f8ccbd18f67b440de1ac30440281d40cfac839022100f20f2f3e1da
|
||||
61883f62980922bd8df545ce407c726241103b5e2c53723124a23022100c
|
||||
a1fe924792cfcc96bfab74f344a68b418df578338064806000fe2a5c99a0
|
||||
23702210087be1c3029504bcf34ec713d877947447813288975ca240080a
|
||||
f7b094091b12102206ab469fa6d5648a57531c8b031a4ce9db53bc3116cf
|
||||
433f5a6f6bbea5601ce05022100bd9f40a764227a21962a4add07e4defe4
|
||||
3ed91a3ae27bb057f39241f33ab01c1
|
||||
'''.replace(" ",""))
|
||||
|
||||
rsaPublicKeyDER = a2b_hex(
|
||||
'''305c300d06092a864886f70d0101010500034b003048024100bf1e27900a
|
||||
a08b23511a5c1281ae6d93312c3efe913f932ebed492f12d16b4610c328c
|
||||
b6e208ab5f45acbe2950833298f3122c19f78492dedf40f0e3c190338502
|
||||
03010001
|
||||
'''.replace(" ",""))
|
||||
|
||||
n = int('BF 1E 27 90 0A A0 8B 23 51 1A 5C 12 81 AE 6D 93 31 2C 3E FE 91 3F 93 2E BE D4 92 F1 2D 16 B4 61 0C 32 8C B6 E2 08 AB 5F 45 AC BE 29 50 83 32 98 F3 12 2C 19 F7 84 92 DE DF 40 F0 E3 C1 90 33 85'.replace(" ",""),16)
|
||||
e = 65537
|
||||
d = int('09 44 83 12 9F 11 4D ED F6 7E DA BC 23 01 BC 5A 88 E5 E6 60 1D D7 01 62 20 EA D9 FD 4B FC 6F DE B7 58 93 89 8A E4 1C 54 DD BD BF 15 39 F8 CC BD 18 F6 7B 44 0D E1 AC 30 44 02 81 D4 0C FA C8 39'.replace(" ",""),16)
|
||||
p = int('00 F2 0F 2F 3E 1D A6 18 83 F6 29 80 92 2B D8 DF 54 5C E4 07 C7 26 24 11 03 B5 E2 C5 37 23 12 4A 23'.replace(" ",""),16)
|
||||
q = int('00 CA 1F E9 24 79 2C FC C9 6B FA B7 4F 34 4A 68 B4 18 DF 57 83 38 06 48 06 00 0F E2 A5 C9 9A 02 37'.replace(" ",""),16)
|
||||
|
||||
# This is q^{-1} mod p). fastmath and slowmath use pInv (p^{-1}
|
||||
# mod q) instead!
|
||||
qInv = int('00 BD 9F 40 A7 64 22 7A 21 96 2A 4A DD 07 E4 DE FE 43 ED 91 A3 AE 27 BB 05 7F 39 24 1F 33 AB 01 C1'.replace(" ",""),16)
|
||||
pInv = inverse(p,q)
|
||||
|
||||
def testImportKey1(self):
|
||||
"""Verify import of RSAPrivateKey DER SEQUENCE"""
|
||||
key = RSA.importKey(self.rsaKeyDER)
|
||||
self.assertTrue(key.has_private())
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
self.assertEqual(key.d, self.d)
|
||||
self.assertEqual(key.p, self.p)
|
||||
self.assertEqual(key.q, self.q)
|
||||
|
||||
def testImportKey2(self):
|
||||
"""Verify import of SubjectPublicKeyInfo DER SEQUENCE"""
|
||||
key = RSA.importKey(self.rsaPublicKeyDER)
|
||||
self.assertFalse(key.has_private())
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
|
||||
def testImportKey3unicode(self):
|
||||
"""Verify import of RSAPrivateKey DER SEQUENCE, encoded with PEM as unicode"""
|
||||
key = RSA.importKey(self.rsaKeyPEM)
|
||||
self.assertEqual(key.has_private(),True) # assert_
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
self.assertEqual(key.d, self.d)
|
||||
self.assertEqual(key.p, self.p)
|
||||
self.assertEqual(key.q, self.q)
|
||||
|
||||
def testImportKey3bytes(self):
|
||||
"""Verify import of RSAPrivateKey DER SEQUENCE, encoded with PEM as byte string"""
|
||||
key = RSA.importKey(b(self.rsaKeyPEM))
|
||||
self.assertEqual(key.has_private(),True) # assert_
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
self.assertEqual(key.d, self.d)
|
||||
self.assertEqual(key.p, self.p)
|
||||
self.assertEqual(key.q, self.q)
|
||||
|
||||
def testImportKey4unicode(self):
|
||||
"""Verify import of RSAPrivateKey DER SEQUENCE, encoded with PEM as unicode"""
|
||||
key = RSA.importKey(self.rsaPublicKeyPEM)
|
||||
self.assertEqual(key.has_private(),False) # failIf
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
|
||||
def testImportKey4bytes(self):
|
||||
"""Verify import of SubjectPublicKeyInfo DER SEQUENCE, encoded with PEM as byte string"""
|
||||
key = RSA.importKey(b(self.rsaPublicKeyPEM))
|
||||
self.assertEqual(key.has_private(),False) # failIf
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
|
||||
def testImportKey5(self):
|
||||
"""Verifies that the imported key is still a valid RSA pair"""
|
||||
key = RSA.importKey(self.rsaKeyPEM)
|
||||
idem = key._encrypt(key._decrypt(89))
|
||||
self.assertEqual(idem, 89)
|
||||
|
||||
def testImportKey6(self):
|
||||
"""Verifies that the imported key is still a valid RSA pair"""
|
||||
key = RSA.importKey(self.rsaKeyDER)
|
||||
idem = key._encrypt(key._decrypt(65))
|
||||
self.assertEqual(idem, 65)
|
||||
|
||||
def testImportKey7(self):
|
||||
"""Verify import of OpenSSH public key"""
|
||||
key = RSA.importKey(self.rsaPublicKeyOpenSSH)
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
|
||||
def testImportKey8(self):
|
||||
"""Verify import of encrypted PrivateKeyInfo DER SEQUENCE"""
|
||||
for t in self.rsaKeyEncryptedPEM:
|
||||
key = RSA.importKey(t[1], t[0])
|
||||
self.assertTrue(key.has_private())
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
self.assertEqual(key.d, self.d)
|
||||
self.assertEqual(key.p, self.p)
|
||||
self.assertEqual(key.q, self.q)
|
||||
|
||||
def testImportKey9(self):
|
||||
"""Verify import of unencrypted PrivateKeyInfo DER SEQUENCE"""
|
||||
key = RSA.importKey(self.rsaKeyDER8)
|
||||
self.assertTrue(key.has_private())
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
self.assertEqual(key.d, self.d)
|
||||
self.assertEqual(key.p, self.p)
|
||||
self.assertEqual(key.q, self.q)
|
||||
|
||||
def testImportKey10(self):
|
||||
"""Verify import of unencrypted PrivateKeyInfo DER SEQUENCE, encoded with PEM"""
|
||||
key = RSA.importKey(self.rsaKeyPEM8)
|
||||
self.assertTrue(key.has_private())
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
self.assertEqual(key.d, self.d)
|
||||
self.assertEqual(key.p, self.p)
|
||||
self.assertEqual(key.q, self.q)
|
||||
|
||||
def testImportKey11(self):
|
||||
"""Verify import of RSAPublicKey DER SEQUENCE"""
|
||||
der = asn1.DerSequence([17, 3]).encode()
|
||||
key = RSA.importKey(der)
|
||||
self.assertEqual(key.n, 17)
|
||||
self.assertEqual(key.e, 3)
|
||||
|
||||
def testImportKey12(self):
|
||||
"""Verify import of RSAPublicKey DER SEQUENCE, encoded with PEM"""
|
||||
der = asn1.DerSequence([17, 3]).encode()
|
||||
pem = der2pem(der)
|
||||
key = RSA.importKey(pem)
|
||||
self.assertEqual(key.n, 17)
|
||||
self.assertEqual(key.e, 3)
|
||||
|
||||
def test_import_key_windows_cr_lf(self):
|
||||
pem_cr_lf = "\r\n".join(self.rsaKeyPEM.splitlines())
|
||||
key = RSA.importKey(pem_cr_lf)
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
self.assertEqual(key.d, self.d)
|
||||
self.assertEqual(key.p, self.p)
|
||||
self.assertEqual(key.q, self.q)
|
||||
|
||||
###
|
||||
def testExportKey1(self):
|
||||
key = RSA.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
|
||||
derKey = key.exportKey("DER")
|
||||
self.assertEqual(derKey, self.rsaKeyDER)
|
||||
|
||||
def testExportKey2(self):
|
||||
key = RSA.construct([self.n, self.e])
|
||||
derKey = key.exportKey("DER")
|
||||
self.assertEqual(derKey, self.rsaPublicKeyDER)
|
||||
|
||||
def testExportKey3(self):
|
||||
key = RSA.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
|
||||
pemKey = key.exportKey("PEM")
|
||||
self.assertEqual(pemKey, b(self.rsaKeyPEM))
|
||||
|
||||
def testExportKey4(self):
|
||||
key = RSA.construct([self.n, self.e])
|
||||
pemKey = key.exportKey("PEM")
|
||||
self.assertEqual(pemKey, b(self.rsaPublicKeyPEM))
|
||||
|
||||
def testExportKey5(self):
|
||||
key = RSA.construct([self.n, self.e])
|
||||
openssh_1 = key.exportKey("OpenSSH").split()
|
||||
openssh_2 = self.rsaPublicKeyOpenSSH.split()
|
||||
self.assertEqual(openssh_1[0], openssh_2[0])
|
||||
self.assertEqual(openssh_1[1], openssh_2[1])
|
||||
|
||||
def testExportKey7(self):
|
||||
key = RSA.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
|
||||
derKey = key.exportKey("DER", pkcs=8)
|
||||
self.assertEqual(derKey, self.rsaKeyDER8)
|
||||
|
||||
def testExportKey8(self):
|
||||
key = RSA.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
|
||||
pemKey = key.exportKey("PEM", pkcs=8)
|
||||
self.assertEqual(pemKey, b(self.rsaKeyPEM8))
|
||||
|
||||
def testExportKey9(self):
|
||||
key = RSA.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
|
||||
self.assertRaises(ValueError, key.exportKey, "invalid-format")
|
||||
|
||||
def testExportKey10(self):
|
||||
# Export and re-import the encrypted key. It must match.
|
||||
# PEM envelope, PKCS#1, old PEM encryption
|
||||
key = RSA.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
|
||||
outkey = key.exportKey('PEM', 'test')
|
||||
self.assertTrue(tostr(outkey).find('4,ENCRYPTED')!=-1)
|
||||
self.assertTrue(tostr(outkey).find('BEGIN RSA PRIVATE KEY')!=-1)
|
||||
inkey = RSA.importKey(outkey, 'test')
|
||||
self.assertEqual(key.n, inkey.n)
|
||||
self.assertEqual(key.e, inkey.e)
|
||||
self.assertEqual(key.d, inkey.d)
|
||||
|
||||
def testExportKey11(self):
|
||||
# Export and re-import the encrypted key. It must match.
|
||||
# PEM envelope, PKCS#1, old PEM encryption
|
||||
key = RSA.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
|
||||
outkey = key.exportKey('PEM', 'test', pkcs=1)
|
||||
self.assertTrue(tostr(outkey).find('4,ENCRYPTED')!=-1)
|
||||
self.assertTrue(tostr(outkey).find('BEGIN RSA PRIVATE KEY')!=-1)
|
||||
inkey = RSA.importKey(outkey, 'test')
|
||||
self.assertEqual(key.n, inkey.n)
|
||||
self.assertEqual(key.e, inkey.e)
|
||||
self.assertEqual(key.d, inkey.d)
|
||||
|
||||
def testExportKey12(self):
|
||||
# Export and re-import the encrypted key. It must match.
|
||||
# PEM envelope, PKCS#8, old PEM encryption
|
||||
key = RSA.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
|
||||
outkey = key.exportKey('PEM', 'test', pkcs=8)
|
||||
self.assertTrue(tostr(outkey).find('4,ENCRYPTED')!=-1)
|
||||
self.assertTrue(tostr(outkey).find('BEGIN PRIVATE KEY')!=-1)
|
||||
inkey = RSA.importKey(outkey, 'test')
|
||||
self.assertEqual(key.n, inkey.n)
|
||||
self.assertEqual(key.e, inkey.e)
|
||||
self.assertEqual(key.d, inkey.d)
|
||||
|
||||
def testExportKey13(self):
|
||||
# Export and re-import the encrypted key. It must match.
|
||||
# PEM envelope, PKCS#8, PKCS#8 encryption
|
||||
key = RSA.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
|
||||
outkey = key.exportKey('PEM', 'test', pkcs=8,
|
||||
protection='PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC')
|
||||
self.assertTrue(tostr(outkey).find('4,ENCRYPTED')==-1)
|
||||
self.assertTrue(tostr(outkey).find('BEGIN ENCRYPTED PRIVATE KEY')!=-1)
|
||||
inkey = RSA.importKey(outkey, 'test')
|
||||
self.assertEqual(key.n, inkey.n)
|
||||
self.assertEqual(key.e, inkey.e)
|
||||
self.assertEqual(key.d, inkey.d)
|
||||
|
||||
def testExportKey14(self):
|
||||
# Export and re-import the encrypted key. It must match.
|
||||
# DER envelope, PKCS#8, PKCS#8 encryption
|
||||
key = RSA.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
|
||||
outkey = key.exportKey('DER', 'test', pkcs=8)
|
||||
inkey = RSA.importKey(outkey, 'test')
|
||||
self.assertEqual(key.n, inkey.n)
|
||||
self.assertEqual(key.e, inkey.e)
|
||||
self.assertEqual(key.d, inkey.d)
|
||||
|
||||
def testExportKey15(self):
|
||||
# Verify that that error an condition is detected when trying to
|
||||
# use a password with DER encoding and PKCS#1.
|
||||
key = RSA.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
|
||||
self.assertRaises(ValueError, key.exportKey, 'DER', 'test', 1)
|
||||
|
||||
def test_import_key(self):
|
||||
"""Verify that import_key is an alias to importKey"""
|
||||
key = RSA.import_key(self.rsaPublicKeyDER)
|
||||
self.assertFalse(key.has_private())
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
|
||||
|
||||
class ImportKeyFromX509Cert(unittest.TestCase):
|
||||
|
||||
def test_x509v1(self):
|
||||
|
||||
# Sample V1 certificate with a 1024 bit RSA key
|
||||
x509_v1_cert = """
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICOjCCAaMCAQEwDQYJKoZIhvcNAQEEBQAwfjENMAsGA1UEChMEQWNtZTELMAkG
|
||||
A1UECxMCUkQxHDAaBgkqhkiG9w0BCQEWDXNwYW1AYWNtZS5vcmcxEzARBgNVBAcT
|
||||
Ck1ldHJvcG9saXMxETAPBgNVBAgTCE5ldyBZb3JrMQswCQYDVQQGEwJVUzENMAsG
|
||||
A1UEAxMEdGVzdDAeFw0xNDA3MTExOTU3MjRaFw0xNzA0MDYxOTU3MjRaME0xCzAJ
|
||||
BgNVBAYTAlVTMREwDwYDVQQIEwhOZXcgWW9yazENMAsGA1UEChMEQWNtZTELMAkG
|
||||
A1UECxMCUkQxDzANBgNVBAMTBmxhdHZpYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
|
||||
gYkCgYEAyG+kytdRj3TFbRmHDYp3TXugVQ81chew0qeOxZWOz80IjtWpgdOaCvKW
|
||||
NCuc8wUR9BWrEQW+39SaRMLiQfQtyFSQZijc3nsEBu/Lo4uWZ0W/FHDRVSvkJA/V
|
||||
Ex5NL5ikI+wbUeCV5KajGNDalZ8F1pk32+CBs8h1xNx5DyxuEHUCAwEAATANBgkq
|
||||
hkiG9w0BAQQFAAOBgQCVQF9Y//Q4Psy+umEM38pIlbZ2hxC5xNz/MbVPwuCkNcGn
|
||||
KYNpQJP+JyVTsPpO8RLZsAQDzRueMI3S7fbbwTzAflN0z19wvblvu93xkaBytVok
|
||||
9VBAH28olVhy9b1MMeg2WOt5sUEQaFNPnwwsyiY9+HsRpvpRnPSQF+kyYVsshQ==
|
||||
-----END CERTIFICATE-----
|
||||
""".strip()
|
||||
|
||||
# RSA public key as dumped by openssl
|
||||
exponent = 65537
|
||||
modulus_str = """
|
||||
00:c8:6f:a4:ca:d7:51:8f:74:c5:6d:19:87:0d:8a:
|
||||
77:4d:7b:a0:55:0f:35:72:17:b0:d2:a7:8e:c5:95:
|
||||
8e:cf:cd:08:8e:d5:a9:81:d3:9a:0a:f2:96:34:2b:
|
||||
9c:f3:05:11:f4:15:ab:11:05:be:df:d4:9a:44:c2:
|
||||
e2:41:f4:2d:c8:54:90:66:28:dc:de:7b:04:06:ef:
|
||||
cb:a3:8b:96:67:45:bf:14:70:d1:55:2b:e4:24:0f:
|
||||
d5:13:1e:4d:2f:98:a4:23:ec:1b:51:e0:95:e4:a6:
|
||||
a3:18:d0:da:95:9f:05:d6:99:37:db:e0:81:b3:c8:
|
||||
75:c4:dc:79:0f:2c:6e:10:75
|
||||
"""
|
||||
modulus = int(re.sub("[^0-9a-f]","", modulus_str), 16)
|
||||
|
||||
key = RSA.importKey(x509_v1_cert)
|
||||
self.assertEqual(key.e, exponent)
|
||||
self.assertEqual(key.n, modulus)
|
||||
self.assertFalse(key.has_private())
|
||||
|
||||
def test_x509v3(self):
|
||||
|
||||
# Sample V3 certificate with a 1024 bit RSA key
|
||||
x509_v3_cert = """
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEcjCCAlqgAwIBAgIBATANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQGEwJVUzEL
|
||||
MAkGA1UECAwCTUQxEjAQBgNVBAcMCUJhbHRpbW9yZTEQMA4GA1UEAwwHVGVzdCBD
|
||||
QTEfMB0GCSqGSIb3DQEJARYQdGVzdEBleGFtcGxlLmNvbTAeFw0xNDA3MTIwOTM1
|
||||
MTJaFw0xNzA0MDcwOTM1MTJaMEQxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJNRDES
|
||||
MBAGA1UEBwwJQmFsdGltb3JlMRQwEgYDVQQDDAtUZXN0IFNlcnZlcjCBnzANBgkq
|
||||
hkiG9w0BAQEFAAOBjQAwgYkCgYEA/S7GJV2OcFdyNMQ4K75KrYFtMEn3VnEFdPHa
|
||||
jyS37XlMxSh0oS4GeTGVUCJInl5Cpsv8WQdh03FfeOdvzp5IZ46OcjeOPiWnmjgl
|
||||
2G5j7e2bDH7RSchGV+OD6Fb1Agvuu2/9iy8fdf3rPQ/7eAddzKUrzwacVbnW+tg2
|
||||
QtSXKRcCAwEAAaOB1TCB0jAdBgNVHQ4EFgQU/WwCX7FfWMIPDFfJ+I8a2COG+l8w
|
||||
HwYDVR0jBBgwFoAUa0hkif3RMaraiWtsOOZZlLu9wJwwCQYDVR0TBAIwADALBgNV
|
||||
HQ8EBAMCBeAwSgYDVR0RBEMwQYILZXhhbXBsZS5jb22CD3d3dy5leGFtcGxlLmNv
|
||||
bYIQbWFpbC5leGFtcGxlLmNvbYIPZnRwLmV4YW1wbGUuY29tMCwGCWCGSAGG+EIB
|
||||
DQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTANBgkqhkiG9w0BAQsF
|
||||
AAOCAgEAvO6xfdsGbnoK4My3eJthodTAjMjPwFVY133LH04QLcCv54TxKhtUg1fi
|
||||
PgdjVe1HpTytPBfXy2bSZbXAN0abZCtw1rYrnn7o1g2pN8iypVq3zVn0iMTzQzxs
|
||||
zEPO3bpR/UhNSf90PmCsS5rqZpAAnXSaAy1ClwHWk/0eG2pYkhE1m1ABVMN2lsAW
|
||||
e9WxGk6IFqaI9O37NYQwmEypMs4DC+ECJEvbPFiqi3n0gbXCZJJ6omDA5xJldaYK
|
||||
Oa7KR3s/qjBsu9UAiWpLBuFoSTHIF2aeRKRFmUdmzwo43eVPep65pY6eQ4AdL2RF
|
||||
rqEuINbGlzI5oQyYhu71IwB+iPZXaZZPlwjLgOsuad/p2hOgDb5WxUi8FnDPursQ
|
||||
ujfpIpmrOP/zpvvQWnwePI3lI+5n41kTBSbefXEdv6rXpHk3QRzB90uPxnXPdxSC
|
||||
16ASA8bQT5an/1AgoE3k9CrcD2K0EmgaX0YI0HUhkyzbkg34EhpWJ6vvRUbRiNRo
|
||||
9cIbt/ya9Y9u0Ja8GLXv6dwX0l0IdJMkL8KifXUFAVCujp1FBrr/gdmwQn8itANy
|
||||
+qbnWSxmOvtaY0zcaFAcONuHva0h51/WqXOMO1eb8PhR4HIIYU8p1oBwQp7dSni8
|
||||
THDi1F+GG5PsymMDj5cWK42f+QzjVw5PrVmFqqrrEoMlx8DWh5Y=
|
||||
-----END CERTIFICATE-----
|
||||
""".strip()
|
||||
|
||||
# RSA public key as dumped by openssl
|
||||
exponent = 65537
|
||||
modulus_str = """
|
||||
00:fd:2e:c6:25:5d:8e:70:57:72:34:c4:38:2b:be:
|
||||
4a:ad:81:6d:30:49:f7:56:71:05:74:f1:da:8f:24:
|
||||
b7:ed:79:4c:c5:28:74:a1:2e:06:79:31:95:50:22:
|
||||
48:9e:5e:42:a6:cb:fc:59:07:61:d3:71:5f:78:e7:
|
||||
6f:ce:9e:48:67:8e:8e:72:37:8e:3e:25:a7:9a:38:
|
||||
25:d8:6e:63:ed:ed:9b:0c:7e:d1:49:c8:46:57:e3:
|
||||
83:e8:56:f5:02:0b:ee:bb:6f:fd:8b:2f:1f:75:fd:
|
||||
eb:3d:0f:fb:78:07:5d:cc:a5:2b:cf:06:9c:55:b9:
|
||||
d6:fa:d8:36:42:d4:97:29:17
|
||||
"""
|
||||
modulus = int(re.sub("[^0-9a-f]","", modulus_str), 16)
|
||||
|
||||
key = RSA.importKey(x509_v3_cert)
|
||||
self.assertEqual(key.e, exponent)
|
||||
self.assertEqual(key.n, modulus)
|
||||
self.assertFalse(key.has_private())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
def get_tests(config={}):
|
||||
tests = []
|
||||
tests += list_test_cases(ImportKeyTests)
|
||||
tests += list_test_cases(ImportKeyFromX509Cert)
|
||||
return tests
|
||||
|
||||
if __name__ == '__main__':
|
||||
suite = lambda: unittest.TestSuite(get_tests())
|
||||
unittest.main(defaultTest='suite')
|
||||
|
||||
# vim:set ts=4 sw=4 sts=4 expandtab:
|
|
@ -0,0 +1,18 @@
|
|||
Private-Key: (256 bit)
|
||||
priv:
|
||||
5c:4e:43:20:ef:26:0f:91:ed:9f:c5:97:ae:e9:8c:
|
||||
82:36:b6:0e:0c:ed:69:2c:c7:a0:57:d5:e4:57:98:
|
||||
a0:52
|
||||
pub:
|
||||
04:a4:0a:d5:9a:20:50:eb:e9:24:79:bd:5f:b1:6b:
|
||||
b2:e4:5b:64:65:eb:3c:b2:b1:ef:fe:42:3f:ab:e6:
|
||||
cb:74:24:db:82:19:ef:0b:ab:80:ac:f2:6f:d7:05:
|
||||
95:b6:1f:e4:76:0d:33:ee:d8:0d:d0:3d:2f:d0:df:
|
||||
b2:7b:8c:e7:5c
|
||||
ASN1 OID: prime256v1
|
||||
NIST CURVE: P-256
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIFxOQyDvJg+R7Z/Fl67pjII2tg4M7Wksx6BX1eRXmKBSoAoGCCqGSM49
|
||||
AwEHoUQDQgAEpArVmiBQ6+kkeb1fsWuy5FtkZes8srHv/kI/q+bLdCTbghnvC6uA
|
||||
rPJv1wWVth/kdg0z7tgN0D0v0N+ye4znXA==
|
||||
-----END EC PRIVATE KEY-----
|
Binary file not shown.
|
@ -0,0 +1,5 @@
|
|||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIFxOQyDvJg+R7Z/Fl67pjII2tg4M7Wksx6BX1eRXmKBSoAoGCCqGSM49
|
||||
AwEHoUQDQgAEpArVmiBQ6+kkeb1fsWuy5FtkZes8srHv/kI/q+bLdCTbghnvC6uA
|
||||
rPJv1wWVth/kdg0z7tgN0D0v0N+ye4znXA==
|
||||
-----END EC PRIVATE KEY-----
|
|
@ -0,0 +1,8 @@
|
|||
-----BEGIN EC PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: AES-128-CBC,288614CF0887BAE11B8B660C3CA24139
|
||||
|
||||
7Jy/LNIYkloV8x1LVRjy59phEtKrli8ySiFDf6nIBtAmt/WLoZijmCMJ7VTXVXNq
|
||||
lyruBM2t4At/0EFI3CSQKxFvsnHDwHL9WYEDPC+gQ/Xy8j2JU0IAM+BuasjHAgXw
|
||||
tq0sJUnRh+xNiI2FotEBC8S194M+lp3RkBZwoBlk3w0=
|
||||
-----END EC PRIVATE KEY-----
|
|
@ -0,0 +1,8 @@
|
|||
-----BEGIN EC PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: AES-192-CBC,82AE4C810C9CF67736F256DEDFD6908E
|
||||
|
||||
gWOVzIDfiMQuIvOQ2m5BWQRWYL7DMb2Mbz4GO8ovBHMNOkMAdi0GhanI+dpQyjtw
|
||||
V9zYBjbqtpMGzACusVYFxvkE9VOb1tj+QphG09Nv4/oUNXBdx1RDxrvntaB/Uskj
|
||||
0zIDV/7D9esLIPTiBtwy62ZAc5Pxk88IG/Z2nGvJZMg=
|
||||
-----END EC PRIVATE KEY-----
|
|
@ -0,0 +1,8 @@
|
|||
-----BEGIN EC PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: id-aes256-GCM,4071BCFFB5B7CE18CEBFE901
|
||||
|
||||
oh6vdMD9bkUvRwtaBkYz6MMWCtjE2GvIKx+diG8XxzakcFzVIqXlDXfEcVIs6Vis
|
||||
LFofIdBHElQxRUTnCCkb21pmly6v0ZLDugwMWNz6ichaie1gXqi+JwjPe2Ju5aro
|
||||
UNeOPqFlVkCeEvHxE3eR1vqlDBLar9VwtA==
|
||||
-----END EC PRIVATE KEY-----
|
|
@ -0,0 +1,8 @@
|
|||
-----BEGIN EC PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: DES-EDE3-CBC,7E383189A0521324
|
||||
|
||||
GT+hvDACAQAq8mD20yQFuQo5Gfg3gPJbZSErmgtdMa5xRLzPEWFnP1yOfZFIgVhn
|
||||
HKLNhgrfbNRh3Ij/DcC6gQ+/35Ts9r+4KLMP6qXuEEfQGTCRu0JQbbMCheN7iNM1
|
||||
8ji47sMaVPJPLrBbD6bPcUl8Tfv0+Xiikvxia5NjqAE=
|
||||
-----END EC PRIVATE KEY-----
|
Binary file not shown.
|
@ -0,0 +1,6 @@
|
|||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MIGwMBsGCSqGSIb3DQEFAzAOBAjtAa3UT6r2WAICCAAEgZA1MjDX/jkmLeNTlbCK
|
||||
oDJPqo9OzHoZInlg4diuvId3uAPxyYnMuwTJvCSklOPXQLkgpYsYRF3YgNBuGAld
|
||||
VQvWcbfwX1eQSqOx6FBCWJgXpWLhlI9qViRDYNQfyam8Xszq7tOdsOdJhSuA+YCt
|
||||
5mBj57E8tUNLLR6P3lAUIM8WJBlxOWyR0EqdM5vcxYIzzTM=
|
||||
-----END ENCRYPTED PRIVATE KEY-----
|
Binary file not shown.
|
@ -0,0 +1,5 @@
|
|||
-----BEGIN PRIVATE KEY-----
|
||||
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgXE5DIO8mD5Htn8WX
|
||||
rumMgja2DgztaSzHoFfV5FeYoFKhRANCAASkCtWaIFDr6SR5vV+xa7LkW2Rl6zyy
|
||||
se/+Qj+r5st0JNuCGe8Lq4Cs8m/XBZW2H+R2DTPu2A3QPS/Q37J7jOdc
|
||||
-----END PRIVATE KEY-----
|
Binary file not shown.
|
@ -0,0 +1,4 @@
|
|||
-----BEGIN PUBLIC KEY-----
|
||||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEpArVmiBQ6+kkeb1fsWuy5FtkZes8
|
||||
srHv/kI/q+bLdCTbghnvC6uArPJv1wWVth/kdg0z7tgN0D0v0N+ye4znXA==
|
||||
-----END PUBLIC KEY-----
|
|
@ -0,0 +1 @@
|
|||
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKQK1ZogUOvpJHm9X7FrsuRbZGXrPLKx7/5CP6vmy3Qk24IZ7wurgKzyb9cFlbYf5HYNM+7YDdA9L9DfsnuM51w=
|
Binary file not shown.
|
@ -0,0 +1,11 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBjTCCATOgAwIBAgIJAJtI7kH/tXlvMAoGCCqGSM49BAMCMCMxCzAJBgNVBAYT
|
||||
AkdCMRQwEgYDVQQDDAtleGFtcGxlLmNvbTAeFw0xNjAxMzAwNjMyNTBaFw0xNzAx
|
||||
MjkwNjMyNTBaMCMxCzAJBgNVBAYTAkdCMRQwEgYDVQQDDAtleGFtcGxlLmNvbTBZ
|
||||
MBMGByqGSM49AgEGCCqGSM49AwEHA0IABKQK1ZogUOvpJHm9X7FrsuRbZGXrPLKx
|
||||
7/5CP6vmy3Qk24IZ7wurgKzyb9cFlbYf5HYNM+7YDdA9L9DfsnuM51yjUDBOMB0G
|
||||
A1UdDgQWBBSv2v+sOg8Z+VTAJk5ob4nDRS1+jjAfBgNVHSMEGDAWgBSv2v+sOg8Z
|
||||
+VTAJk5ob4nDRS1+jjAMBgNVHRMEBTADAQH/MAoGCCqGSM49BAMCA0gAMEUCID3r
|
||||
ARj3nfwBK4uE3BmlGKjaH5JR3e9iEac7BT93W6hOAiEAuNZxsvUpadoB4SqurLVg
|
||||
lrdvw9wpYr8JTq7q2KUIQes=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,33 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
set -x
|
||||
|
||||
openssl version | tee openssl_version.txt
|
||||
|
||||
# Private key
|
||||
openssl ecparam -name prime256v1 -genkey -noout -conv_form uncompressed -out ecc_p256_private.pem
|
||||
openssl ec -in ecc_p256_private.pem -outform DER -out ecc_p256_private.der
|
||||
openssl pkcs8 -in ecc_p256_private.der -inform DER -out ecc_p256_private_p8_clear.der -outform DER -nocrypt -topk8
|
||||
openssl pkcs8 -in ecc_p256_private.der -inform DER -out ecc_p256_private_p8_clear.pem -outform PEM -nocrypt -topk8
|
||||
openssl ec -in ecc_p256_private.pem -text -out ecc_p256.txt
|
||||
|
||||
# Encrypted private key
|
||||
openssl pkcs8 -in ecc_p256_private.der -inform DER -passout 'pass:secret' -out ecc_p256_private_p8.der -outform DER -topk8
|
||||
openssl pkcs8 -in ecc_p256_private.der -inform DER -passout 'pass:secret' -out ecc_p256_private_p8.pem -outform PEM -topk8
|
||||
openssl ec -in ecc_p256_private.pem -des3 -out ecc_p256_private_enc_des3.pem -passout 'pass:secret' -outform PEM
|
||||
openssl ec -in ecc_p256_private.pem -aes128 -out ecc_p256_private_enc_aes128.pem -passout 'pass:secret' -outform PEM
|
||||
openssl ec -in ecc_p256_private.pem -aes192 -out ecc_p256_private_enc_aes192.pem -passout 'pass:secret' -outform PEM
|
||||
openssl ec -in ecc_p256_private.pem -aes-256-gcm -out ecc_p256_private_enc_aes256_gcm.pem -passout 'pass:secret' -outform PEM
|
||||
|
||||
# Public key
|
||||
openssl ec -in ecc_p256_private.pem -pubout -out ecc_p256_public.pem
|
||||
openssl ec -pubin -in ecc_p256_public.pem -outform DER -out ecc_p256_public.der
|
||||
|
||||
# X.509 cert
|
||||
openssl req -new -key ecc_p256_private.pem -days 365 -x509 -out ecc_p256_x509.pem -subj '/C=GB/CN=example.com'
|
||||
openssl x509 -in ecc_p256_x509.pem -out ecc_p256_x509.der -outform DER
|
||||
|
||||
# OpenSSH
|
||||
chmod 600 ecc_p256_private.pem
|
||||
ssh-keygen -f ecc_p256_private.pem -y > ecc_p256_public_openssh.txt
|
|
@ -0,0 +1 @@
|
|||
OpenSSL 1.0.2e-fips 3 Dec 2015
|
|
@ -0,0 +1,212 @@
|
|||
#
|
||||
# Test vectors for NIST P-256 curve found in http://point-at-infinity.org/ecc/nisttv
|
||||
# on 1 Jan 2016.
|
||||
#
|
||||
|
||||
k = 1
|
||||
x = 6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296
|
||||
y = 4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5
|
||||
|
||||
k = 2
|
||||
x = 7CF27B188D034F7E8A52380304B51AC3C08969E277F21B35A60B48FC47669978
|
||||
y = 07775510DB8ED040293D9AC69F7430DBBA7DADE63CE982299E04B79D227873D1
|
||||
|
||||
k = 3
|
||||
x = 5ECBE4D1A6330A44C8F7EF951D4BF165E6C6B721EFADA985FB41661BC6E7FD6C
|
||||
y = 8734640C4998FF7E374B06CE1A64A2ECD82AB036384FB83D9A79B127A27D5032
|
||||
|
||||
k = 4
|
||||
x = E2534A3532D08FBBA02DDE659EE62BD0031FE2DB785596EF509302446B030852
|
||||
y = E0F1575A4C633CC719DFEE5FDA862D764EFC96C3F30EE0055C42C23F184ED8C6
|
||||
|
||||
k = 5
|
||||
x = 51590B7A515140D2D784C85608668FDFEF8C82FD1F5BE52421554A0DC3D033ED
|
||||
y = E0C17DA8904A727D8AE1BF36BF8A79260D012F00D4D80888D1D0BB44FDA16DA4
|
||||
|
||||
k = 6
|
||||
x = B01A172A76A4602C92D3242CB897DDE3024C740DEBB215B4C6B0AAE93C2291A9
|
||||
y = E85C10743237DAD56FEC0E2DFBA703791C00F7701C7E16BDFD7C48538FC77FE2
|
||||
|
||||
k = 7
|
||||
x = 8E533B6FA0BF7B4625BB30667C01FB607EF9F8B8A80FEF5B300628703187B2A3
|
||||
y = 73EB1DBDE03318366D069F83A6F5900053C73633CB041B21C55E1A86C1F400B4
|
||||
|
||||
k = 8
|
||||
x = 62D9779DBEE9B0534042742D3AB54CADC1D238980FCE97DBB4DD9DC1DB6FB393
|
||||
y = AD5ACCBD91E9D8244FF15D771167CEE0A2ED51F6BBE76A78DA540A6A0F09957E
|
||||
|
||||
k = 9
|
||||
x = EA68D7B6FEDF0B71878938D51D71F8729E0ACB8C2C6DF8B3D79E8A4B90949EE0
|
||||
y = 2A2744C972C9FCE787014A964A8EA0C84D714FEAA4DE823FE85A224A4DD048FA
|
||||
|
||||
k = 10
|
||||
x = CEF66D6B2A3A993E591214D1EA223FB545CA6C471C48306E4C36069404C5723F
|
||||
y = 878662A229AAAE906E123CDD9D3B4C10590DED29FE751EEECA34BBAA44AF0773
|
||||
|
||||
k = 11
|
||||
x = 3ED113B7883B4C590638379DB0C21CDA16742ED0255048BF433391D374BC21D1
|
||||
y = 9099209ACCC4C8A224C843AFA4F4C68A090D04DA5E9889DAE2F8EEFCE82A3740
|
||||
|
||||
k = 12
|
||||
x = 741DD5BDA817D95E4626537320E5D55179983028B2F82C99D500C5EE8624E3C4
|
||||
y = 0770B46A9C385FDC567383554887B1548EEB912C35BA5CA71995FF22CD4481D3
|
||||
|
||||
k = 13
|
||||
x = 177C837AE0AC495A61805DF2D85EE2FC792E284B65EAD58A98E15D9D46072C01
|
||||
y = 63BB58CD4EBEA558A24091ADB40F4E7226EE14C3A1FB4DF39C43BBE2EFC7BFD8
|
||||
|
||||
k = 14
|
||||
x = 54E77A001C3862B97A76647F4336DF3CF126ACBE7A069C5E5709277324D2920B
|
||||
y = F599F1BB29F4317542121F8C05A2E7C37171EA77735090081BA7C82F60D0B375
|
||||
|
||||
k = 15
|
||||
x = F0454DC6971ABAE7ADFB378999888265AE03AF92DE3A0EF163668C63E59B9D5F
|
||||
y = B5B93EE3592E2D1F4E6594E51F9643E62A3B21CE75B5FA3F47E59CDE0D034F36
|
||||
|
||||
k = 16
|
||||
x = 76A94D138A6B41858B821C629836315FCD28392EFF6CA038A5EB4787E1277C6E
|
||||
y = A985FE61341F260E6CB0A1B5E11E87208599A0040FC78BAA0E9DDD724B8C5110
|
||||
|
||||
k = 17
|
||||
x = 47776904C0F1CC3A9C0984B66F75301A5FA68678F0D64AF8BA1ABCE34738A73E
|
||||
y = AA005EE6B5B957286231856577648E8381B2804428D5733F32F787FF71F1FCDC
|
||||
|
||||
k = 18
|
||||
x = 1057E0AB5780F470DEFC9378D1C7C87437BB4C6F9EA55C63D936266DBD781FDA
|
||||
y = F6F1645A15CBE5DC9FA9B7DFD96EE5A7DCC11B5C5EF4F1F78D83B3393C6A45A2
|
||||
|
||||
k = 19
|
||||
x = CB6D2861102C0C25CE39B7C17108C507782C452257884895C1FC7B74AB03ED83
|
||||
y = 58D7614B24D9EF515C35E7100D6D6CE4A496716E30FA3E03E39150752BCECDAA
|
||||
|
||||
k = 20
|
||||
x = 83A01A9378395BAB9BCD6A0AD03CC56D56E6B19250465A94A234DC4C6B28DA9A
|
||||
y = 76E49B6DE2F73234AE6A5EB9D612B75C9F2202BB6923F54FF8240AAA86F640B8
|
||||
|
||||
k = 112233445566778899
|
||||
x = 339150844EC15234807FE862A86BE77977DBFB3AE3D96F4C22795513AEAAB82F
|
||||
y = B1C14DDFDC8EC1B2583F51E85A5EB3A155840F2034730E9B5ADA38B674336A21
|
||||
|
||||
k = 112233445566778899112233445566778899
|
||||
x = 1B7E046A076CC25E6D7FA5003F6729F665CC3241B5ADAB12B498CD32F2803264
|
||||
y = BFEA79BE2B666B073DB69A2A241ADAB0738FE9D2DD28B5604EB8C8CF097C457B
|
||||
|
||||
k = 29852220098221261079183923314599206100666902414330245206392788703677545185283
|
||||
x = 9EACE8F4B071E677C5350B02F2BB2B384AAE89D58AA72CA97A170572E0FB222F
|
||||
y = 1BBDAEC2430B09B93F7CB08678636CE12EAAFD58390699B5FD2F6E1188FC2A78
|
||||
|
||||
k = 57896042899961394862005778464643882389978449576758748073725983489954366354431
|
||||
x = 878F22CC6DB6048D2B767268F22FFAD8E56AB8E2DC615F7BD89F1E350500DD8D
|
||||
y = 714A5D7BB901C9C5853400D12341A892EF45D87FC553786756C4F0C9391D763E
|
||||
|
||||
k = 1766845392945710151501889105729049882997660004824848915955419660366636031
|
||||
x = 659A379625AB122F2512B8DADA02C6348D53B54452DFF67AC7ACE4E8856295CA
|
||||
y = 49D81AB97B648464D0B4A288BD7818FAB41A16426E943527C4FED8736C53D0F6
|
||||
|
||||
k = 28948025760307534517734791687894775804466072615242963443097661355606862201087
|
||||
x = CBCEAAA8A4DD44BBCE58E8DB7740A5510EC2CB7EA8DA8D8F036B3FB04CDA4DE4
|
||||
y = 4BD7AA301A80D7F59FD983FEDBE59BB7B2863FE46494935E3745B360E32332FA
|
||||
|
||||
k = 113078210460870548944811695960290644973229224625838436424477095834645696384
|
||||
x = F0C4A0576154FF3A33A3460D42EAED806E854DFA37125221D37935124BA462A4
|
||||
y = 5B392FA964434D29EEC6C9DBC261CF116796864AA2FAADB984A2DF38D1AEF7A3
|
||||
|
||||
k = 12078056106883488161242983286051341125085761470677906721917479268909056
|
||||
x = 5E6C8524B6369530B12C62D31EC53E0288173BD662BDF680B53A41ECBCAD00CC
|
||||
y = 447FE742C2BFEF4D0DB14B5B83A2682309B5618E0064A94804E9282179FE089F
|
||||
|
||||
k = 57782969857385448082319957860328652998540760998293976083718804450708503920639
|
||||
x = 03792E541BC209076A3D7920A915021ECD396A6EB5C3960024BE5575F3223484
|
||||
y = FC774AE092403101563B712F68170312304F20C80B40C06282063DB25F268DE4
|
||||
|
||||
k = 57896017119460046759583662757090100341435943767777707906455551163257755533312
|
||||
x = 2379FF85AB693CDF901D6CE6F2473F39C04A2FE3DCD842CE7AAB0E002095BCF8
|
||||
y = F8B476530A634589D5129E46F322B02FBC610A703D80875EE70D7CE1877436A1
|
||||
|
||||
k = 452312848374287284681282171017647412726433684238464212999305864837160993279
|
||||
x = C1E4072C529BF2F44DA769EFC934472848003B3AF2C0F5AA8F8DDBD53E12ED7C
|
||||
y = 39A6EE77812BB37E8079CD01ED649D3830FCA46F718C1D3993E4A591824ABCDB
|
||||
|
||||
k = 904571339174065134293634407946054000774746055866917729876676367558469746684
|
||||
x = 34DFBC09404C21E250A9B40FA8772897AC63A094877DB65862B61BD1507B34F3
|
||||
y = CF6F8A876C6F99CEAEC87148F18C7E1E0DA6E165FFC8ED82ABB65955215F77D3
|
||||
|
||||
k = 115792089210356248762697446949407573529996955224135760342422259061068512044349
|
||||
x = 83A01A9378395BAB9BCD6A0AD03CC56D56E6B19250465A94A234DC4C6B28DA9A
|
||||
y = 891B64911D08CDCC5195A14629ED48A360DDFD4596DC0AB007DBF5557909BF47
|
||||
|
||||
k = 115792089210356248762697446949407573529996955224135760342422259061068512044350
|
||||
x = CB6D2861102C0C25CE39B7C17108C507782C452257884895C1FC7B74AB03ED83
|
||||
y = A7289EB3DB2610AFA3CA18EFF292931B5B698E92CF05C1FC1C6EAF8AD4313255
|
||||
|
||||
k = 115792089210356248762697446949407573529996955224135760342422259061068512044351
|
||||
x = 1057E0AB5780F470DEFC9378D1C7C87437BB4C6F9EA55C63D936266DBD781FDA
|
||||
y = 090E9BA4EA341A246056482026911A58233EE4A4A10B0E08727C4CC6C395BA5D
|
||||
|
||||
k = 115792089210356248762697446949407573529996955224135760342422259061068512044352
|
||||
x = 47776904C0F1CC3A9C0984B66F75301A5FA68678F0D64AF8BA1ABCE34738A73E
|
||||
y = 55FFA1184A46A8D89DCE7A9A889B717C7E4D7FBCD72A8CC0CD0878008E0E0323
|
||||
|
||||
k = 115792089210356248762697446949407573529996955224135760342422259061068512044353
|
||||
x = 76A94D138A6B41858B821C629836315FCD28392EFF6CA038A5EB4787E1277C6E
|
||||
y = 567A019DCBE0D9F2934F5E4A1EE178DF7A665FFCF0387455F162228DB473AEEF
|
||||
|
||||
k = 115792089210356248762697446949407573529996955224135760342422259061068512044354
|
||||
x = F0454DC6971ABAE7ADFB378999888265AE03AF92DE3A0EF163668C63E59B9D5F
|
||||
y = 4A46C11BA6D1D2E1B19A6B1AE069BC19D5C4DE328A4A05C0B81A6321F2FCB0C9
|
||||
|
||||
k = 115792089210356248762697446949407573529996955224135760342422259061068512044355
|
||||
x = 54E77A001C3862B97A76647F4336DF3CF126ACBE7A069C5E5709277324D2920B
|
||||
y = 0A660E43D60BCE8BBDEDE073FA5D183C8E8E15898CAF6FF7E45837D09F2F4C8A
|
||||
|
||||
k = 115792089210356248762697446949407573529996955224135760342422259061068512044356
|
||||
x = 177C837AE0AC495A61805DF2D85EE2FC792E284B65EAD58A98E15D9D46072C01
|
||||
y = 9C44A731B1415AA85DBF6E524BF0B18DD911EB3D5E04B20C63BC441D10384027
|
||||
|
||||
k = 115792089210356248762697446949407573529996955224135760342422259061068512044357
|
||||
x = 741DD5BDA817D95E4626537320E5D55179983028B2F82C99D500C5EE8624E3C4
|
||||
y = F88F4B9463C7A024A98C7CAAB7784EAB71146ED4CA45A358E66A00DD32BB7E2C
|
||||
|
||||
k = 115792089210356248762697446949407573529996955224135760342422259061068512044358
|
||||
x = 3ED113B7883B4C590638379DB0C21CDA16742ED0255048BF433391D374BC21D1
|
||||
y = 6F66DF64333B375EDB37BC505B0B3975F6F2FB26A16776251D07110317D5C8BF
|
||||
|
||||
k = 115792089210356248762697446949407573529996955224135760342422259061068512044359
|
||||
x = CEF66D6B2A3A993E591214D1EA223FB545CA6C471C48306E4C36069404C5723F
|
||||
y = 78799D5CD655517091EDC32262C4B3EFA6F212D7018AE11135CB4455BB50F88C
|
||||
|
||||
k = 115792089210356248762697446949407573529996955224135760342422259061068512044360
|
||||
x = EA68D7B6FEDF0B71878938D51D71F8729E0ACB8C2C6DF8B3D79E8A4B90949EE0
|
||||
y = D5D8BB358D36031978FEB569B5715F37B28EB0165B217DC017A5DDB5B22FB705
|
||||
|
||||
k = 115792089210356248762697446949407573529996955224135760342422259061068512044361
|
||||
x = 62D9779DBEE9B0534042742D3AB54CADC1D238980FCE97DBB4DD9DC1DB6FB393
|
||||
y = 52A533416E1627DCB00EA288EE98311F5D12AE0A4418958725ABF595F0F66A81
|
||||
|
||||
k = 115792089210356248762697446949407573529996955224135760342422259061068512044362
|
||||
x = 8E533B6FA0BF7B4625BB30667C01FB607EF9F8B8A80FEF5B300628703187B2A3
|
||||
y = 8C14E2411FCCE7CA92F9607C590A6FFFAC38C9CD34FBE4DE3AA1E5793E0BFF4B
|
||||
|
||||
k = 115792089210356248762697446949407573529996955224135760342422259061068512044363
|
||||
x = B01A172A76A4602C92D3242CB897DDE3024C740DEBB215B4C6B0AAE93C2291A9
|
||||
y = 17A3EF8ACDC8252B9013F1D20458FC86E3FF0890E381E9420283B7AC7038801D
|
||||
|
||||
k = 115792089210356248762697446949407573529996955224135760342422259061068512044364
|
||||
x = 51590B7A515140D2D784C85608668FDFEF8C82FD1F5BE52421554A0DC3D033ED
|
||||
y = 1F3E82566FB58D83751E40C9407586D9F2FED1002B27F7772E2F44BB025E925B
|
||||
|
||||
k = 115792089210356248762697446949407573529996955224135760342422259061068512044365
|
||||
x = E2534A3532D08FBBA02DDE659EE62BD0031FE2DB785596EF509302446B030852
|
||||
y = 1F0EA8A4B39CC339E62011A02579D289B103693D0CF11FFAA3BD3DC0E7B12739
|
||||
|
||||
k = 115792089210356248762697446949407573529996955224135760342422259061068512044366
|
||||
x = 5ECBE4D1A6330A44C8F7EF951D4BF165E6C6B721EFADA985FB41661BC6E7FD6C
|
||||
y = 78CB9BF2B6670082C8B4F931E59B5D1327D54FCAC7B047C265864ED85D82AFCD
|
||||
|
||||
k = 115792089210356248762697446949407573529996955224135760342422259061068512044367
|
||||
x = 7CF27B188D034F7E8A52380304B51AC3C08969E277F21B35A60B48FC47669978
|
||||
y = F888AAEE24712FC0D6C26539608BCF244582521AC3167DD661FB4862DD878C2E
|
||||
|
||||
k = 115792089210356248762697446949407573529996955224135760342422259061068512044368
|
||||
x = 6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296
|
||||
y = B01CBD1C01E58065711814B583F061E9D431CCA994CEA1313449BF97C840AE0A
|
Loading…
Add table
Add a link
Reference in a new issue