aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/development/custom-vectors/secp256k1.rst32
-rw-r--r--docs/development/custom-vectors/secp256k1/generate_secp256k1.py89
-rw-r--r--docs/development/custom-vectors/secp256k1/verify_secp256k1.py59
-rw-r--r--docs/development/test-vectors.rst14
-rw-r--r--docs/x509.rst8
-rw-r--r--tests/utils.py1
-rw-r--r--vectors/cryptography_vectors/x509/custom/authority_key_identifier.pem19
-rw-r--r--vectors/cryptography_vectors/x509/custom/authority_key_identifier_no_keyid.pem19
8 files changed, 236 insertions, 5 deletions
diff --git a/docs/development/custom-vectors/secp256k1.rst b/docs/development/custom-vectors/secp256k1.rst
new file mode 100644
index 00000000..b19bf4e4
--- /dev/null
+++ b/docs/development/custom-vectors/secp256k1.rst
@@ -0,0 +1,32 @@
+SECP256K1 vector creation
+=========================
+
+This page documents the code that was used to generate the SECP256K1 elliptic
+curve test vectors as well as code used to verify them against another
+implementation.
+
+
+Creation
+--------
+
+The vectors are generated using a `pure Python ecdsa`_ implementation. The test
+messages and combinations of algorithms are derived from the NIST vector data.
+
+.. literalinclude:: /development/custom-vectors/secp256k1/generate_secp256k1.py
+
+Download link: :download:`generate_secp256k1.py
+</development/custom-vectors/secp256k1/generate_secp256k1.py>`
+
+
+Verification
+------------
+
+``cryptography`` was modified to support the SECP256K1 curve. Then
+the following python script was run to generate the vector files.
+
+.. literalinclude:: /development/custom-vectors/secp256k1/verify_secp256k1.py
+
+Download link: :download:`verify_secp256k1.py
+</development/custom-vectors/secp256k1/verify_secp256k1.py>`
+
+.. _`pure Python ecdsa`: https://pypi.python.org/pypi/ecdsa
diff --git a/docs/development/custom-vectors/secp256k1/generate_secp256k1.py b/docs/development/custom-vectors/secp256k1/generate_secp256k1.py
new file mode 100644
index 00000000..502a3ff6
--- /dev/null
+++ b/docs/development/custom-vectors/secp256k1/generate_secp256k1.py
@@ -0,0 +1,89 @@
+from __future__ import absolute_import, print_function
+
+import hashlib
+import os
+from binascii import hexlify
+from collections import defaultdict
+
+from ecdsa import SECP256k1, SigningKey
+from ecdsa.util import sigdecode_der, sigencode_der
+
+from cryptography_vectors import open_vector_file
+
+from tests.utils import (
+ load_fips_ecdsa_signing_vectors, load_vectors_from_file
+)
+
+HASHLIB_HASH_TYPES = {
+ "SHA-1": hashlib.sha1,
+ "SHA-224": hashlib.sha224,
+ "SHA-256": hashlib.sha256,
+ "SHA-384": hashlib.sha384,
+ "SHA-512": hashlib.sha512,
+}
+
+
+class TruncatedHash(object):
+ def __init__(self, hasher):
+ self.hasher = hasher
+
+ def __call__(self, data):
+ self.hasher.update(data)
+ return self
+
+ def digest(self):
+ return self.hasher.digest()[:256 // 8]
+
+
+def build_vectors(fips_vectors):
+ vectors = defaultdict(list)
+ for vector in fips_vectors:
+ vectors[vector['digest_algorithm']].append(vector['message'])
+
+ for digest_algorithm, messages in vectors.items():
+ if digest_algorithm not in HASHLIB_HASH_TYPES:
+ continue
+
+ yield ""
+ yield "[K-256,{0}]".format(digest_algorithm)
+ yield ""
+
+ for message in messages:
+ # Make a hash context
+ hash_func = TruncatedHash(HASHLIB_HASH_TYPES[digest_algorithm]())
+
+ # Sign the message using warner/ecdsa
+ secret_key = SigningKey.generate(curve=SECP256k1)
+ public_key = secret_key.get_verifying_key()
+ signature = secret_key.sign(message, hashfunc=hash_func,
+ sigencode=sigencode_der)
+
+ r, s = sigdecode_der(signature, None)
+
+ yield "Msg = {0}".format(hexlify(message))
+ yield "d = {0:x}".format(secret_key.privkey.secret_multiplier)
+ yield "Qx = {0:x}".format(public_key.pubkey.point.x())
+ yield "Qy = {0:x}".format(public_key.pubkey.point.y())
+ yield "R = {0:x}".format(r)
+ yield "S = {0:x}".format(s)
+ yield ""
+
+
+def write_file(lines, dest):
+ for line in lines:
+ print(line)
+ print(line, file=dest)
+
+source_path = os.path.join("asymmetric", "ECDSA", "FIPS_186-3", "SigGen.txt")
+dest_path = os.path.join("asymmetric", "ECDSA", "SECP256K1", "SigGen.txt")
+
+fips_vectors = load_vectors_from_file(
+ source_path,
+ load_fips_ecdsa_signing_vectors
+)
+
+with open_vector_file(dest_path, "w") as dest_file:
+ write_file(
+ build_vectors(fips_vectors),
+ dest_file
+ )
diff --git a/docs/development/custom-vectors/secp256k1/verify_secp256k1.py b/docs/development/custom-vectors/secp256k1/verify_secp256k1.py
new file mode 100644
index 00000000..3d2c25b9
--- /dev/null
+++ b/docs/development/custom-vectors/secp256k1/verify_secp256k1.py
@@ -0,0 +1,59 @@
+from __future__ import absolute_import, print_function
+
+import os
+
+from cryptography.hazmat.backends import default_backend
+from cryptography.hazmat.primitives import hashes
+from cryptography.hazmat.primitives.asymmetric import ec
+from cryptography.hazmat.primitives.asymmetric.utils import (
+ encode_rfc6979_signature
+)
+
+from tests.utils import (
+ load_fips_ecdsa_signing_vectors, load_vectors_from_file
+)
+
+CRYPTOGRAPHY_HASH_TYPES = {
+ "SHA-1": hashes.SHA1,
+ "SHA-224": hashes.SHA224,
+ "SHA-256": hashes.SHA256,
+ "SHA-384": hashes.SHA384,
+ "SHA-512": hashes.SHA512,
+}
+
+
+def verify_one_vector(vector):
+ digest_algorithm = vector['digest_algorithm']
+ message = vector['message']
+ x = vector['x']
+ y = vector['y']
+ signature = encode_rfc6979_signature(vector['r'], vector['s'])
+
+ numbers = ec.EllipticCurvePublicNumbers(
+ x, y,
+ ec.SECP256K1()
+ )
+
+ key = numbers.public_key(default_backend())
+
+ verifier = key.verifier(
+ signature,
+ ec.ECDSA(CRYPTOGRAPHY_HASH_TYPES[digest_algorithm]())
+ )
+ verifier.update(message)
+ return verifier.verify()
+
+
+def verify_vectors(vectors):
+ for vector in vectors:
+ assert verify_one_vector(vector)
+
+
+vector_path = os.path.join("asymmetric", "ECDSA", "SECP256K1", "SigGen.txt")
+
+secp256k1_vectors = load_vectors_from_file(
+ vector_path,
+ load_fips_ecdsa_signing_vectors
+)
+
+verify_vectors(secp256k1_vectors)
diff --git a/docs/development/test-vectors.rst b/docs/development/test-vectors.rst
index f6eecfec..77ec6259 100644
--- a/docs/development/test-vectors.rst
+++ b/docs/development/test-vectors.rst
@@ -37,9 +37,14 @@ Asymmetric ciphers
Ruby test suite.
-Custom Asymmetric Vectors
+Custom asymmetric vectors
~~~~~~~~~~~~~~~~~~~~~~~~~
+.. toctree::
+ :maxdepth: 1
+
+ custom-vectors/secp256k1
+
* ``asymmetric/PEM_Serialization/ec_private_key.pem`` and
``asymmetric/DER_Serialization/ec_private_key.der`` - Contains an Elliptic
Curve key generated by OpenSSL from the curve ``secp256r1``.
@@ -78,6 +83,7 @@ Custom Asymmetric Vectors
``asymmetric/public/PKCS1/rsa.pub.der`` are PKCS1 conversions of the public
key from ``asymmetric/PKCS8/unenc-rsa-pkcs8.pem`` using PEM and DER encoding.
+
Key exchange
~~~~~~~~~~~~
@@ -160,6 +166,12 @@ Custom X.509 Vectors
containing an inhibit any policy extension with the value 5.
* ``inhibit_any_policy_negative.pem`` - An RSA 2048 bit self-signed certificate
containing an inhibit any policy extension with the value -1.
+* ``authority_key_identifier.pem`` - An RSA 2048 bit self-signed certificate
+ containing an authority key identifier extension with key identifier,
+ authority certificate issuer, and authority certificate serial number fields.
+* ``authority_key_identifier_no_keyid.pem`` - An RSA 2048 bit self-signed
+ certificate containing an authority key identifier extension with authority
+ certificate issuer and authority certificate serial number fields.
Custom X.509 Request Vectors
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/docs/x509.rst b/docs/x509.rst
index 7cfc74e8..f9c9af2f 100644
--- a/docs/x509.rst
+++ b/docs/x509.rst
@@ -682,10 +682,10 @@ X.509 Extensions
certificate. This attribute only has meaning if ``ca`` is true.
If ``ca`` is true then a path length of None means there's no
restriction on the number of subordinate CAs in the certificate chain.
- If it is zero or greater then that number defines the maximum length.
- For example, a ``path_length`` of 1 means the certificate can sign a
- subordinate CA, but the subordinate CA is not allowed to create
- subordinates with ``ca`` set to true.
+ If it is zero or greater then it defines the maximum length for a
+ subordinate CA's certificate chain. For example, a ``path_length`` of 1
+ means the certificate can sign a subordinate CA, but the subordinate CA
+ is not allowed to create subordinates with ``ca`` set to true.
.. class:: ExtendedKeyUsage
diff --git a/tests/utils.py b/tests/utils.py
index 65c99fbf..c48a1f99 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -498,6 +498,7 @@ _ECDSA_CURVE_NAMES = {
"K-163": "sect163k1",
"K-233": "sect233k1",
+ "K-256": "secp256k1",
"K-283": "sect283k1",
"K-409": "sect409k1",
"K-571": "sect571k1",
diff --git a/vectors/cryptography_vectors/x509/custom/authority_key_identifier.pem b/vectors/cryptography_vectors/x509/custom/authority_key_identifier.pem
new file mode 100644
index 00000000..cbe9169f
--- /dev/null
+++ b/vectors/cryptography_vectors/x509/custom/authority_key_identifier.pem
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDIjCCAgqgAwIBAgIBAzANBgkqhkiG9w0BAQUFADApMQ0wCwYDVQQKDARQeUNB
+MRgwFgYDVQQDDA9jcnlwdG9ncmFwaHkuaW8wHhcNMTUwNTAzMDk0OTU2WhcNMTYw
+NTAyMDk0OTU2WjApMQ0wCwYDVQQKDARQeUNBMRgwFgYDVQQDDA9jcnlwdG9ncmFw
+aHkuaW8wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDCadi1UZioxdnP
+ajqlRZHeKsSxvXXhgrWvlt91P3gV0dBThRFhJsLOhjNLz6PO6KeRbjz9GhTA2hdk
+xtIpXrjvTv9dEJ1/k0xebsHWgFC43aTlgekw0U4cMwMe5NGeeg1tfzbJwldIN+cK
+vabc08ADlkmM6DMnUArkzA2yii0DErRFMSIGrkDr6E9puord3h6Mh8Jfnc3TDAq8
+Qo1DI2XM7oFSWNfecQ9KbIC5wzzT+7Shoyz7QmCk/XhRzt8Xcfc3yAXIwazvLf8b
+YP1auaSG11a5E+w6onj91h8UHKKOXu+rdq5YYPZ+qUYpxA7ZJ/VAGadMulYbXaO8
+Syi39HTpAgMBAAGjVTBTMFEGA1UdIwRKMEiAFDlFPso9Yh3qhkn2WqtAt6RwmPHs
+oS2kKzApMQ0wCwYDVQQKDARQeUNBMRgwFgYDVQQDDA9jcnlwdG9ncmFwaHkuaW+C
+AQMwDQYJKoZIhvcNAQEFBQADggEBAFbZYy6aZJUK/f7nJx2Rs/ht6hMbM32/RoXZ
+JGbYapNVqVu/vymcfc/se3FHS5OVmPsnRlo/FIKDn/r5DGl73Sn/FvDJiLJZFucT
+msyYuHZ+ZRYWzWmN2fcB3cfxj0s3qps6f5OoCOqoINOSe4HRGlw4X9keZSD+3xAt
+vHNwQdlPC7zWbPdrzLT+FqR0e/O81vFJJS6drHJWqPcR3NQVtZw+UF7A/HKwbfeL
+Nu2zj6165hzOi9HUxa2/mPr/eLUUV1sTzXp2+TFjt3rVCjW1XnpMLdwNBHzjpyAB
+dTOX3iw0+BPy3s2jtnCW1PLpc74kvSTaBwhg74sq39EXfIKax00=
+-----END CERTIFICATE-----
diff --git a/vectors/cryptography_vectors/x509/custom/authority_key_identifier_no_keyid.pem b/vectors/cryptography_vectors/x509/custom/authority_key_identifier_no_keyid.pem
new file mode 100644
index 00000000..fffcc653
--- /dev/null
+++ b/vectors/cryptography_vectors/x509/custom/authority_key_identifier_no_keyid.pem
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDDDCCAfSgAwIBAgIBAzANBgkqhkiG9w0BAQUFADApMQ0wCwYDVQQKDARQeUNB
+MRgwFgYDVQQDDA9jcnlwdG9ncmFwaHkuaW8wHhcNMTUwNTAzMTAxNTU2WhcNMTYw
+NTAyMTAxNTU2WjApMQ0wCwYDVQQKDARQeUNBMRgwFgYDVQQDDA9jcnlwdG9ncmFw
+aHkuaW8wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDCadi1UZioxdnP
+ajqlRZHeKsSxvXXhgrWvlt91P3gV0dBThRFhJsLOhjNLz6PO6KeRbjz9GhTA2hdk
+xtIpXrjvTv9dEJ1/k0xebsHWgFC43aTlgekw0U4cMwMe5NGeeg1tfzbJwldIN+cK
+vabc08ADlkmM6DMnUArkzA2yii0DErRFMSIGrkDr6E9puord3h6Mh8Jfnc3TDAq8
+Qo1DI2XM7oFSWNfecQ9KbIC5wzzT+7Shoyz7QmCk/XhRzt8Xcfc3yAXIwazvLf8b
+YP1auaSG11a5E+w6onj91h8UHKKOXu+rdq5YYPZ+qUYpxA7ZJ/VAGadMulYbXaO8
+Syi39HTpAgMBAAGjPzA9MDsGA1UdIwQ0MDKhLaQrMCkxDTALBgNVBAoMBFB5Q0Ex
+GDAWBgNVBAMMD2NyeXB0b2dyYXBoeS5pb4IBAzANBgkqhkiG9w0BAQUFAAOCAQEA
+AViX0VIVQW2xyf0lfLiuFhrpdgX9i49StZvs+n/qH5yvWxfqRJAyVT1pk2Xs0Goj
+ul7vYMfIGU0nIr8eLMlAH9j6lkllAd/oO1BDONZ1kH6PMdkOdvgz5gmhMQx6MFr6
+zMzzQ+JOAnXKFFUEycOiRJyh3VXiTY1M1IG1kWY+LoqB72S7y9c25yFoHqUNi2Xf
+rbuaR7gNS/4z7XvLJkbNbVS2+y69gQGL+8vk5AG7MiZ1mzUQ44r/zy6HNDBb55kK
+H+YTYavijRApH5hccJBXyoIM0x9ZtKdcrV0h+J2KOFGEyHp3FXViFEB2IZUpJNA/
+aduVbH8gZy5Y+cHzenwzBg==
+-----END CERTIFICATE-----