diff options
author | Alex Gaynor <alex.gaynor@gmail.com> | 2015-05-14 23:16:53 -0400 |
---|---|---|
committer | Alex Gaynor <alex.gaynor@gmail.com> | 2015-05-14 23:16:53 -0400 |
commit | 388f92ab5cfd5c60fcd8712e5889c4ded300959b (patch) | |
tree | 4ed919a89157fbf80ef9fbfd7abe56bc58dddd91 /tests | |
parent | 4e1dd2e0e35ce3880380af2c6fa278de87b0df2f (diff) | |
parent | f9531ada2f09accdb42156bca7917af5266220c6 (diff) | |
download | cryptography-388f92ab5cfd5c60fcd8712e5889c4ded300959b.tar.gz cryptography-388f92ab5cfd5c60fcd8712e5889c4ded300959b.tar.bz2 cryptography-388f92ab5cfd5c60fcd8712e5889c4ded300959b.zip |
Merge branch 'master' into macstadium-travis
Diffstat (limited to 'tests')
-rw-r--r-- | tests/hazmat/primitives/test_ec.py | 15 | ||||
-rw-r--r-- | tests/test_utils.py | 294 | ||||
-rw-r--r-- | tests/test_x509_ext.py | 1411 | ||||
-rw-r--r-- | tests/utils.py | 105 |
4 files changed, 1800 insertions, 25 deletions
diff --git a/tests/hazmat/primitives/test_ec.py b/tests/hazmat/primitives/test_ec.py index 3273fe63..82b5b3a1 100644 --- a/tests/hazmat/primitives/test_ec.py +++ b/tests/hazmat/primitives/test_ec.py @@ -305,10 +305,17 @@ class TestECDSAVectors(object): @pytest.mark.parametrize( "vector", - load_vectors_from_file( - os.path.join( - "asymmetric", "ECDSA", "FIPS_186-3", "SigGen.txt"), - load_fips_ecdsa_signing_vectors + itertools.chain( + load_vectors_from_file( + os.path.join( + "asymmetric", "ECDSA", "FIPS_186-3", "SigGen.txt"), + load_fips_ecdsa_signing_vectors + ), + load_vectors_from_file( + os.path.join( + "asymmetric", "ECDSA", "SECP256K1", "SigGen.txt"), + load_fips_ecdsa_signing_vectors + ), ) ) def test_signatures(self, backend, vector): diff --git a/tests/test_utils.py b/tests/test_utils.py index bc5f2e14..61efb10c 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -21,7 +21,8 @@ from .utils import ( check_backend_support, load_cryptrec_vectors, load_fips_dsa_key_pair_vectors, load_fips_dsa_sig_vectors, load_fips_ecdsa_key_pair_vectors, load_fips_ecdsa_signing_vectors, - load_hash_vectors, load_kasvs_dh_vectors, load_nist_vectors, + load_hash_vectors, load_kasvs_dh_vectors, + load_kasvs_ecdh_vectors, load_nist_vectors, load_pkcs1_vectors, load_rsa_nist_vectors, load_vectors_from_file, raises_unsupported_algorithm, select_backends, skip_if_empty ) @@ -3044,6 +3045,297 @@ d518475576730ed528779366568e46b7dd4ed787cb72d0733c93 assert expected == load_kasvs_dh_vectors(vector_data) +def test_load_kasvs_ecdh_vectors(): + vector_data = textwrap.dedent(""" + # Parameter set(s) supported: EA EB EC ED EE + # CAVSid: CAVSid (in hex: 434156536964) + # IUTid: In hex: a1b2c3d4e5 + [EA] + + [Curve selected: P-192] + [SHA(s) supported (Used for hashing Z): SHA1] + [EB] + + [Curve selected: P-224] + [SHA(s) supported (Used for hashing Z): SHA224] + [EC] + + [Curve selected: P-256] + [SHA(s) supported (Used for hashing Z): SHA256] + [ED] + + [Curve selected: P-384] + [SHA(s) supported (Used for hashing Z): SHA384] + [EE] + + [Curve selected: P-521] + [SHA(s) supported (Used for hashing Z): SHA512] + # Generated on Thu Mar 17 19:46:10 2011 + + + + [EA - SHA1] + + + COUNT = 0 + dsCAVS = f70c297a683d6b7ef82b5af7349606c4447c8b4fc6fa5e80 + QsCAVSx = f7b5061fb557e516c50abf541d97dbfd76ca7172b22cf590 + QsCAVSy = 135e15e21f9e85c76205fd148a92ac19f9e6243ddab322d1 + dsIUT = a5b4bbad57f101ca48021cb7440cd681a9d40cd51b99d917 + QsIUTx = 79a77fcb18a32cdb59ed5d87740f29e8565d649dbf01ce86 + QsIUTy = f7187efaa0b1573f1fb00905d46810b880bf738b4c720bb7 + Z = 26382468d721761e14a87dc3bee67340095c6455962d1ba3 + CAVSHashZZ = af52ba700d3bbba7ce2916d6b729422c26c32364 + Result = P (0 - Correct) + + + + COUNT = 2 + dsCAVS = 5f909dcb0ccce58c82fada748c47297579e6a981b5518a96 + QsCAVSx = 537f1ecfda0e366de393a9bc8188fcc280311bffefe21ecf + QsCAVSy = a1fa1f98498d65f2754caff4e5303a4066a5ff89fde95381 + dsIUT = 3357aa7f47f3e09421602cc12cdce4434c68e330d44de05e + QsIUTx = 6a33d43d9c72173eabc7a771a5687748c4774c62762e96ec + QsIUTy = 8033f238b3abc69470aad4be8dbe4f60a2fd50207626c56a + Z = 3153034f6617326f19c35be8c99a0585431adf09d2f8e0fd + CAVSHashZZ = f8414e30c2d382e28d2a57a2447fdc203baa416b + Result = F (8 - Z changed ) + + + + COUNT = 8 + dsCAVS = 8fcfaf0524cc868fad20e50410a2205319f1327308d98dc8 + QsCAVSx = 9b0243d80a9e328738080fb4d46bc450243d0efb7ead0c92 + QsCAVSy = ad5bebad7f03849693071537f60ef858cad214123beee7c7 + dsIUT = bba95dac90289cb68ca2b006f9757219b70579c299ad7a7d + QsIUTx = 7733dc0cb365cd6312724196b9b4eb491fd4d2e31b9afdb1 + QsIUTy = 92ffa3722acc5b94d772258ba2d471b06c0f53f56fcd8662 + Z = 0f3c6e4a29a08296ae730f56a1ebf819ea2edfa6f0434e40 + CAVSHashZZ = c124545eed4b83a799e7e90371d806b5684a1bd2 + Result = P (13 - Z value should have leading 0 nibble ) + + + [EB - SHA224] + + + COUNT = 0 + dsCAVS = e53a88af7cf8ce6bf13c8b9ad191494e37a6acc1368c71f4306e39e5 + QsCAVSx = 3a24217c4b957fea922eec9d9ac52d5cb4b3fcd95efde1e4fa0dd6e2 + QsCAVSy = 775b94025a808eb6f4af14ea4b57dca576c35373c6dc198b15b981df + dsIUT = 09f51e302c6a0fe6ff48f34c208c6af91e70f65f88102e6fcab9af4a + QsIUTx = c5d5706ccd7424c74fd616e699865af96e56f39adea6aa059e5092b5 + QsIUTy = f0729077bb602404d56d2f7e2ba5bb2f383df4a5425567881ff0165d + Z = b1259ceedfb663d9515089cf727e7024fb3d86cbcec611b4ba0b4ab6 + CAVSHashZZ = 8b21fd05a4b50e401908cd8f26757f5c57f22b69f170aa7381f8596d + Result = P (0 - Correct) + + + + [EC - SHA256] + + + COUNT = 0 + dsCAVS = 305dfb4a8850cc59280891147baf457bfe5e2bae984571634a77dc8d3472fa9b + QsCAVSx = 202cb5a224e6c2a84e624094486edf04116c8d68ec1f4a0e0ed9ee090e1a900b + QsCAVSy = cacf3a5789bb33954be600425d62d9eae5371f90f88167258814213e4a4f4b1a + dsIUT = 72cc52808f294b64b6f7233c3d2f5d96cc1d29287320e39e1c151deef0bc14eb + QsIUTx = 49a768c9a4ca56e374f685dd76a461b1016c59dcded2c8d8cbd9f23ca453831f + QsIUTy = b1e3bb9b5f12a3b5ae788535d4554bd8c46e0e6130075e4e437d3854cf8f1c34 + Z = c0147c3c2691b450b5edc08b51aea224d9f4359ff67aab6da3146f396dbceaea + CAVSHashZZ = ea9ffd54511979ab8c4b387784972cbd05fc5fd4ff78e048b0026557b56a5\ +1dd + Result = F (2 - CAVS's Static public key Y fails PKV 5.6.2.5) + + + + [ED - SHA384] + + + COUNT = 0 + dsCAVS = 0e5c98ff2d2a3aab14ad0067b60dbe64e4f541ab5bed11c5a0c55ae1e60b51ff5\ +faaf377837977d80cbfdc33c2ff542b + QsCAVSx = d1bf2ac21637d66d6398aac01dcd56ac6f065fb45d1f6f16747bab9e9b01b463\ +0b59b20927aea147355bf41838acb482 + QsCAVSy = 4c9e23f1c5a41647d094086bf4ed31708651f21d996c47780688ac10f77deee2\ +e43b5241b6caecd2fd5444bc50472e0e + dsIUT = f865418473e5bf7d2e1bbcd9bd5a9270c003a9dd35e778133ca59fcab4bb64fe24\ +d6800e7047bdd033abc8bfa8db35b5 + QsIUTx = 32b72ab9b558249dcbc6cbade234f58e4f7aa5d3f6420ea99a5f997e8c2a91fb7\ +fd83779d0d2169428683771c745fd1a + QsIUTy = c749e02a3719bb56bf1dfc4ba3820309c01ab6e84cb29db7cdd80f127233f5295\ +687f8178f3a8704c1063b84c2ee472f + Z = a781430e6078a179df3f9ee27cd8fdc6188f161b6c4ccc4053ef6c6ca6fc222946883a\ +53c06db08f0a020023ced055aa + CAVSHashZZ = ccb70d0adbabe4d8956519db0d536605cbb366aed58fc55718f56ae3648fa\ +5c9ee7bae56cc463587cb74e2f9c6ace1cb + Result = P (0 - Correct) + + + + [EE - SHA512] + + + COUNT = 0 + dsCAVS = 0000002fef62381162942889a6094a6bb9ac1f4ddf66d9cda9f618232d31b90c5\ +0d7da78a47ed91d40cae946898571db972dc294b109815f38feee9eaac0d5f7c3250728 + QsCAVSx = 0000004b05ffa025113390797f2736174aa1c784f4dd34e764ee40d40e4d2442\ +677ebea3498086c9473e5c92789cbdb02bb327bbd61d58690f6a83d9ca73bccbde37dec4 + QsCAVSy = 0000004da67cffc98070b82af61feba78787efefb13bd810d80ff92304788e49\ +a4e5b634b3565474a8ecb1615d7b1b77a7a27875adb73a8a5d8f3f84e5e8b744cda250b0 + dsIUT = 00000311a5e520e238141527671a38cb6f776d96a9f82ef70dffa11dc0895f4060\ +f1abbb9ad6fd259e4a7beaf5f7266ea1bb45bcbfebfda2705e5c551e710fb1d745f57e + QsIUTx = 0000010ba3778cb2cc965834c0a9593adc6a222692656d657fb0d15293edf0ab3\ +3762384a96a16fddea7540b7ccbcca46ec4ac9bcf95fdb5aa18e158aab4d91981bd733e + QsIUTy = 0000018522df93ddd636e5bc94daecdc600fa241686ec18634fd30b7cbdfdc9ff\ +ba1166ac08df34a31896f6fad191414929261ebd7187afb72919f8a0c926be37f99c1e5 + Z = 01a5e4b31be4b1346e53906b6767b1fe94ec1a8a5abc28fb6f01518c056959af3bc933\ +5dddab178b52318cc5512559931b8dc18de0ce810c2c7f15769d7ce70e719c + CAVSHashZZ = d2d6538feb65d609f377b81a027dc800eed07b69c0e9eedb243369202ed47\ +f47021022a6c9b45ed791d09d9540eb81ea065fc1959eca365001ee39928c343d75 + Result = F (7 - IUT's Static private key d changed-prikey validity) + + + + """).splitlines() + + expected = [ + {'errno': 0, + 'fail': False, + 'COUNT': 0, + 'CAVS': { + 'd': int("f70c297a683d6b7ef82b5af7349606c4447c8b4fc6fa5e80", 16), + 'x': int("f7b5061fb557e516c50abf541d97dbfd76ca7172b22cf590", 16), + 'y': int("135e15e21f9e85c76205fd148a92ac19f9e6243ddab322d1", 16)}, + 'IUT': { + 'd': int("a5b4bbad57f101ca48021cb7440cd681a9d40cd51b99d917", 16), + 'x': int("79a77fcb18a32cdb59ed5d87740f29e8565d649dbf01ce86", 16), + 'y': int("f7187efaa0b1573f1fb00905d46810b880bf738b4c720bb7", 16)}, + 'Z': int("26382468d721761e14a87dc3bee67340095c6455962d1ba3", 16), + 'curve': 'secp192r1'}, + + {'errno': 8, + 'fail': True, + 'COUNT': 2, + 'CAVS': { + 'd': int("5f909dcb0ccce58c82fada748c47297579e6a981b5518a96", 16), + 'x': int("537f1ecfda0e366de393a9bc8188fcc280311bffefe21ecf", 16), + 'y': int("a1fa1f98498d65f2754caff4e5303a4066a5ff89fde95381", 16)}, + 'IUT': { + 'd': int("3357aa7f47f3e09421602cc12cdce4434c68e330d44de05e", 16), + 'x': int("6a33d43d9c72173eabc7a771a5687748c4774c62762e96ec", 16), + 'y': int("8033f238b3abc69470aad4be8dbe4f60a2fd50207626c56a", 16)}, + 'Z': int("3153034f6617326f19c35be8c99a0585431adf09d2f8e0fd", 16), + 'curve': 'secp192r1'}, + + {'errno': 13, + 'fail': False, + 'COUNT': 8, + 'CAVS': { + 'd': int("8fcfaf0524cc868fad20e50410a2205319f1327308d98dc8", 16), + 'x': int("9b0243d80a9e328738080fb4d46bc450243d0efb7ead0c92", 16), + 'y': int("ad5bebad7f03849693071537f60ef858cad214123beee7c7", 16)}, + 'IUT': { + 'd': int("bba95dac90289cb68ca2b006f9757219b70579c299ad7a7d", 16), + 'x': int("7733dc0cb365cd6312724196b9b4eb491fd4d2e31b9afdb1", 16), + 'y': int("92ffa3722acc5b94d772258ba2d471b06c0f53f56fcd8662", 16)}, + 'Z': int("0f3c6e4a29a08296ae730f56a1ebf819ea2edfa6f0434e40", 16), + 'curve': 'secp192r1'}, + + {'errno': 0, + 'fail': False, + 'COUNT': 0, + 'CAVS': { + 'd': int("e53a88af7cf8ce6bf13c8b9ad191494e37a6acc1368c71f4" + "306e39e5", 16), + 'x': int("3a24217c4b957fea922eec9d9ac52d5cb4b3fcd95efde1e4" + "fa0dd6e2", 16), + 'y': int("775b94025a808eb6f4af14ea4b57dca576c35373c6dc198b" + "15b981df", 16)}, + 'IUT': { + 'd': int("09f51e302c6a0fe6ff48f34c208c6af91e70f65f88102e6f" + "cab9af4a", 16), + 'x': int("c5d5706ccd7424c74fd616e699865af96e56f39adea6aa05" + "9e5092b5", 16), + 'y': int("f0729077bb602404d56d2f7e2ba5bb2f383df4a542556788" + "1ff0165d", 16)}, + 'Z': int("b1259ceedfb663d9515089cf727e7024fb3d86cbcec611b4" + "ba0b4ab6", 16), + 'curve': 'secp224r1'}, + + {'errno': 2, + 'fail': True, + 'COUNT': 0, + 'CAVS': { + 'd': int("305dfb4a8850cc59280891147baf457bfe5e2bae98457163" + "4a77dc8d3472fa9b", 16), + 'x': int("202cb5a224e6c2a84e624094486edf04116c8d68ec1f4a0e" + "0ed9ee090e1a900b", 16), + 'y': int("cacf3a5789bb33954be600425d62d9eae5371f90f8816725" + "8814213e4a4f4b1a", 16)}, + 'IUT': { + 'd': int("72cc52808f294b64b6f7233c3d2f5d96cc1d29287320e39e" + "1c151deef0bc14eb", 16), + 'x': int("49a768c9a4ca56e374f685dd76a461b1016c59dcded2c8d8" + "cbd9f23ca453831f", 16), + 'y': int("b1e3bb9b5f12a3b5ae788535d4554bd8c46e0e6130075e4e" + "437d3854cf8f1c34", 16)}, + 'Z': int("c0147c3c2691b450b5edc08b51aea224d9f4359ff67aab6d" + "a3146f396dbceaea", 16), + 'curve': 'secp256r1'}, + + {'errno': 0, + 'fail': False, + 'COUNT': 0, + 'CAVS': { + 'd': int("0e5c98ff2d2a3aab14ad0067b60dbe64e4f541ab5bed11c5" + "a0c55ae1e60b51ff5faaf377837977d80cbfdc33c2ff542b", 16), + 'x': int("d1bf2ac21637d66d6398aac01dcd56ac6f065fb45d1f6f16" + "747bab9e9b01b4630b59b20927aea147355bf41838acb482", 16), + 'y': int("4c9e23f1c5a41647d094086bf4ed31708651f21d996c4778" + "0688ac10f77deee2e43b5241b6caecd2fd5444bc50472e0e", 16)}, + 'IUT': { + 'd': int("f865418473e5bf7d2e1bbcd9bd5a9270c003a9dd35e77813" + "3ca59fcab4bb64fe24d6800e7047bdd033abc8bfa8db35b5", 16), + 'x': int("32b72ab9b558249dcbc6cbade234f58e4f7aa5d3f6420ea9" + "9a5f997e8c2a91fb7fd83779d0d2169428683771c745fd1a", 16), + 'y': int("c749e02a3719bb56bf1dfc4ba3820309c01ab6e84cb29db7" + "cdd80f127233f5295687f8178f3a8704c1063b84c2ee472f", 16)}, + 'Z': int("a781430e6078a179df3f9ee27cd8fdc6188f161b6c4ccc40" + "53ef6c6ca6fc222946883a53c06db08f0a020023ced055aa", 16), + 'curve': 'secp384r1'}, + + {'errno': 7, + 'fail': True, + 'COUNT': 0, + 'CAVS': { + 'd': int("0000002fef62381162942889a6094a6bb9ac1f4ddf66d9cd" + "a9f618232d31b90c50d7da78a47ed91d40cae946898571db" + "972dc294b109815f38feee9eaac0d5f7c3250728", 16), + 'x': int("0000004b05ffa025113390797f2736174aa1c784f4dd34e7" + "64ee40d40e4d2442677ebea3498086c9473e5c92789cbdb0" + "2bb327bbd61d58690f6a83d9ca73bccbde37dec4", 16), + 'y': int("0000004da67cffc98070b82af61feba78787efefb13bd810" + "d80ff92304788e49a4e5b634b3565474a8ecb1615d7b1b77" + "a7a27875adb73a8a5d8f3f84e5e8b744cda250b0", 16)}, + 'IUT': { + 'd': int("00000311a5e520e238141527671a38cb6f776d96a9f82ef7" + "0dffa11dc0895f4060f1abbb9ad6fd259e4a7beaf5f7266e" + "a1bb45bcbfebfda2705e5c551e710fb1d745f57e", 16), + 'x': int("0000010ba3778cb2cc965834c0a9593adc6a222692656d65" + "7fb0d15293edf0ab33762384a96a16fddea7540b7ccbcca4" + "6ec4ac9bcf95fdb5aa18e158aab4d91981bd733e", 16), + 'y': int("0000018522df93ddd636e5bc94daecdc600fa241686ec186" + "34fd30b7cbdfdc9ffba1166ac08df34a31896f6fad191414" + "929261ebd7187afb72919f8a0c926be37f99c1e5", 16)}, + 'Z': int("01a5e4b31be4b1346e53906b6767b1fe94ec1a8a5abc28fb" + "6f01518c056959af3bc9335dddab178b52318cc551255993" + "1b8dc18de0ce810c2c7f15769d7ce70e719c", 16), + 'curve': 'secp521r1'} + ] + + assert expected == load_kasvs_ecdh_vectors(vector_data) + + def test_vector_version(): assert cryptography.__version__ == cryptography_vectors.__version__ diff --git a/tests/test_x509_ext.py b/tests/test_x509_ext.py index d38fe573..72f2f9e4 100644 --- a/tests/test_x509_ext.py +++ b/tests/test_x509_ext.py @@ -39,6 +39,296 @@ class TestExtension(object): ) +class TestNoticeReference(object): + def test_notice_numbers_not_all_int(self): + with pytest.raises(TypeError): + x509.NoticeReference("org", [1, 2, "three"]) + + def test_notice_numbers_none(self): + with pytest.raises(TypeError): + x509.NoticeReference("org", None) + + def test_repr(self): + nr = x509.NoticeReference(u"org", [1, 3, 4]) + + if six.PY3: + assert repr(nr) == ( + "<NoticeReference(organization='org', notice_numbers=[1, 3, 4" + "])>" + ) + else: + assert repr(nr) == ( + "<NoticeReference(organization=u'org', notice_numbers=[1, 3, " + "4])>" + ) + + def test_eq(self): + nr = x509.NoticeReference("org", [1, 2]) + nr2 = x509.NoticeReference("org", [1, 2]) + assert nr == nr2 + + def test_ne(self): + nr = x509.NoticeReference("org", [1, 2]) + nr2 = x509.NoticeReference("org", [1]) + nr3 = x509.NoticeReference(None, [1, 2]) + assert nr != nr2 + assert nr != nr3 + assert nr != object() + + +class TestUserNotice(object): + def test_notice_reference_invalid(self): + with pytest.raises(TypeError): + x509.UserNotice("invalid", None) + + def test_notice_reference_none(self): + un = x509.UserNotice(None, "text") + assert un.notice_reference is None + assert un.explicit_text == "text" + + def test_repr(self): + un = x509.UserNotice(x509.NoticeReference(u"org", [1]), u"text") + if six.PY3: + assert repr(un) == ( + "<UserNotice(notice_reference=<NoticeReference(organization='" + "org', notice_numbers=[1])>, explicit_text='text')>" + ) + else: + assert repr(un) == ( + "<UserNotice(notice_reference=<NoticeReference(organization=u" + "'org', notice_numbers=[1])>, explicit_text=u'text')>" + ) + + def test_eq(self): + nr = x509.NoticeReference("org", [1, 2]) + nr2 = x509.NoticeReference("org", [1, 2]) + un = x509.UserNotice(nr, "text") + un2 = x509.UserNotice(nr2, "text") + assert un == un2 + + def test_ne(self): + nr = x509.NoticeReference("org", [1, 2]) + nr2 = x509.NoticeReference("org", [1]) + un = x509.UserNotice(nr, "text") + un2 = x509.UserNotice(nr2, "text") + un3 = x509.UserNotice(nr, "text3") + assert un != un2 + assert un != un3 + assert un != object() + + +class TestPolicyInformation(object): + def test_invalid_policy_identifier(self): + with pytest.raises(TypeError): + x509.PolicyInformation("notanoid", None) + + def test_none_policy_qualifiers(self): + pi = x509.PolicyInformation(x509.ObjectIdentifier("1.2.3"), None) + assert pi.policy_identifier == x509.ObjectIdentifier("1.2.3") + assert pi.policy_qualifiers is None + + def test_policy_qualifiers(self): + pq = [u"string"] + pi = x509.PolicyInformation(x509.ObjectIdentifier("1.2.3"), pq) + assert pi.policy_identifier == x509.ObjectIdentifier("1.2.3") + assert pi.policy_qualifiers == pq + + def test_invalid_policy_identifiers(self): + with pytest.raises(TypeError): + x509.PolicyInformation(x509.ObjectIdentifier("1.2.3"), [1, 2]) + + def test_repr(self): + pq = [u"string", x509.UserNotice(None, u"hi")] + pi = x509.PolicyInformation(x509.ObjectIdentifier("1.2.3"), pq) + if six.PY3: + assert repr(pi) == ( + "<PolicyInformation(policy_identifier=<ObjectIdentifier(oid=1." + "2.3, name=Unknown OID)>, policy_qualifiers=['string', <UserNo" + "tice(notice_reference=None, explicit_text='hi')>])>" + ) + else: + assert repr(pi) == ( + "<PolicyInformation(policy_identifier=<ObjectIdentifier(oid=1." + "2.3, name=Unknown OID)>, policy_qualifiers=[u'string', <UserN" + "otice(notice_reference=None, explicit_text=u'hi')>])>" + ) + + def test_eq(self): + pi = x509.PolicyInformation( + x509.ObjectIdentifier("1.2.3"), + [u"string", x509.UserNotice(None, u"hi")] + ) + pi2 = x509.PolicyInformation( + x509.ObjectIdentifier("1.2.3"), + [u"string", x509.UserNotice(None, u"hi")] + ) + assert pi == pi2 + + def test_ne(self): + pi = x509.PolicyInformation( + x509.ObjectIdentifier("1.2.3"), [u"string"] + ) + pi2 = x509.PolicyInformation( + x509.ObjectIdentifier("1.2.3"), [u"string2"] + ) + pi3 = x509.PolicyInformation( + x509.ObjectIdentifier("1.2.3.4"), [u"string"] + ) + assert pi != pi2 + assert pi != pi3 + assert pi != object() + + +class TestCertificatePolicies(object): + def test_invalid_policies(self): + pq = [u"string"] + pi = x509.PolicyInformation(x509.ObjectIdentifier("1.2.3"), pq) + with pytest.raises(TypeError): + x509.CertificatePolicies([1, pi]) + + def test_iter_len(self): + pq = [u"string"] + pi = x509.PolicyInformation(x509.ObjectIdentifier("1.2.3"), pq) + cp = x509.CertificatePolicies([pi]) + assert len(cp) == 1 + for policyinfo in cp: + assert policyinfo == pi + + def test_repr(self): + pq = [u"string"] + pi = x509.PolicyInformation(x509.ObjectIdentifier("1.2.3"), pq) + cp = x509.CertificatePolicies([pi]) + if six.PY3: + assert repr(cp) == ( + "<CertificatePolicies([<PolicyInformation(policy_identifier=<O" + "bjectIdentifier(oid=1.2.3, name=Unknown OID)>, policy_qualifi" + "ers=['string'])>])>" + ) + else: + assert repr(cp) == ( + "<CertificatePolicies([<PolicyInformation(policy_identifier=<O" + "bjectIdentifier(oid=1.2.3, name=Unknown OID)>, policy_qualifi" + "ers=[u'string'])>])>" + ) + + def test_eq(self): + pi = x509.PolicyInformation( + x509.ObjectIdentifier("1.2.3"), [u"string"] + ) + cp = x509.CertificatePolicies([pi]) + pi2 = x509.PolicyInformation( + x509.ObjectIdentifier("1.2.3"), [u"string"] + ) + cp2 = x509.CertificatePolicies([pi2]) + assert cp == cp2 + + def test_ne(self): + pi = x509.PolicyInformation( + x509.ObjectIdentifier("1.2.3"), [u"string"] + ) + cp = x509.CertificatePolicies([pi]) + pi2 = x509.PolicyInformation( + x509.ObjectIdentifier("1.2.3"), [u"string2"] + ) + cp2 = x509.CertificatePolicies([pi2]) + assert cp != cp2 + assert cp != object() + + +@pytest.mark.requires_backend_interface(interface=RSABackend) +@pytest.mark.requires_backend_interface(interface=X509Backend) +class TestCertificatePoliciesExtension(object): + def test_cps_uri_policy_qualifier(self, backend): + cert = _load_cert( + os.path.join("x509", "custom", "cp_cps_uri.pem"), + x509.load_pem_x509_certificate, + backend + ) + + cp = cert.extensions.get_extension_for_oid( + x509.OID_CERTIFICATE_POLICIES + ).value + + assert cp == x509.CertificatePolicies([ + x509.PolicyInformation( + x509.ObjectIdentifier("2.16.840.1.12345.1.2.3.4.1"), + [u"http://other.com/cps"] + ) + ]) + + def test_user_notice_with_notice_reference(self, backend): + cert = _load_cert( + os.path.join( + "x509", "custom", "cp_user_notice_with_notice_reference.pem" + ), + x509.load_pem_x509_certificate, + backend + ) + + cp = cert.extensions.get_extension_for_oid( + x509.OID_CERTIFICATE_POLICIES + ).value + + assert cp == x509.CertificatePolicies([ + x509.PolicyInformation( + x509.ObjectIdentifier("2.16.840.1.12345.1.2.3.4.1"), + [ + u"http://example.com/cps", + u"http://other.com/cps", + x509.UserNotice( + x509.NoticeReference(u"my org", [1, 2, 3, 4]), + u"thing" + ) + ] + ) + ]) + + def test_user_notice_with_explicit_text(self, backend): + cert = _load_cert( + os.path.join( + "x509", "custom", "cp_user_notice_with_explicit_text.pem" + ), + x509.load_pem_x509_certificate, + backend + ) + + cp = cert.extensions.get_extension_for_oid( + x509.OID_CERTIFICATE_POLICIES + ).value + + assert cp == x509.CertificatePolicies([ + x509.PolicyInformation( + x509.ObjectIdentifier("2.16.840.1.12345.1.2.3.4.1"), + [x509.UserNotice(None, u"thing")] + ) + ]) + + def test_user_notice_no_explicit_text(self, backend): + cert = _load_cert( + os.path.join( + "x509", "custom", "cp_user_notice_no_explicit_text.pem" + ), + x509.load_pem_x509_certificate, + backend + ) + + cp = cert.extensions.get_extension_for_oid( + x509.OID_CERTIFICATE_POLICIES + ).value + + assert cp == x509.CertificatePolicies([ + x509.PolicyInformation( + x509.ObjectIdentifier("2.16.840.1.12345.1.2.3.4.1"), + [ + x509.UserNotice( + x509.NoticeReference(u"my org", [1, 2, 3, 4]), + None + ) + ] + ) + ]) + + class TestKeyUsage(object): def test_key_agreement_false_encipher_decipher_true(self): with pytest.raises(ValueError): @@ -173,6 +463,57 @@ class TestKeyUsage(object): "only=False)>" ) + def test_eq(self): + ku = x509.KeyUsage( + digital_signature=False, + content_commitment=False, + key_encipherment=False, + data_encipherment=False, + key_agreement=True, + key_cert_sign=False, + crl_sign=False, + encipher_only=False, + decipher_only=True + ) + ku2 = x509.KeyUsage( + digital_signature=False, + content_commitment=False, + key_encipherment=False, + data_encipherment=False, + key_agreement=True, + key_cert_sign=False, + crl_sign=False, + encipher_only=False, + decipher_only=True + ) + assert ku == ku2 + + def test_ne(self): + ku = x509.KeyUsage( + digital_signature=False, + content_commitment=False, + key_encipherment=False, + data_encipherment=False, + key_agreement=True, + key_cert_sign=False, + crl_sign=False, + encipher_only=False, + decipher_only=True + ) + ku2 = x509.KeyUsage( + digital_signature=False, + content_commitment=False, + key_encipherment=False, + data_encipherment=False, + key_agreement=False, + key_cert_sign=False, + crl_sign=False, + encipher_only=False, + decipher_only=False + ) + assert ku != ku2 + assert ku != object() + class TestSubjectKeyIdentifier(object): def test_properties(self): @@ -221,29 +562,33 @@ class TestSubjectKeyIdentifier(object): class TestAuthorityKeyIdentifier(object): - def test_authority_cert_issuer_not_name(self): + def test_authority_cert_issuer_not_generalname(self): with pytest.raises(TypeError): - x509.AuthorityKeyIdentifier(b"identifier", "notname", 3) + x509.AuthorityKeyIdentifier(b"identifier", ["notname"], 3) def test_authority_cert_serial_number_not_integer(self): - name = x509.Name([ - x509.NameAttribute(x509.ObjectIdentifier('oid'), 'value1'), - x509.NameAttribute(x509.ObjectIdentifier('oid2'), 'value2'), - ]) + dirname = x509.DirectoryName( + x509.Name([ + x509.NameAttribute(x509.ObjectIdentifier('oid'), 'value1'), + x509.NameAttribute(x509.ObjectIdentifier('oid2'), 'value2'), + ]) + ) with pytest.raises(TypeError): - x509.AuthorityKeyIdentifier(b"identifier", name, "notanint") + x509.AuthorityKeyIdentifier(b"identifier", [dirname], "notanint") def test_authority_issuer_none_serial_not_none(self): with pytest.raises(ValueError): x509.AuthorityKeyIdentifier(b"identifier", None, 3) def test_authority_issuer_not_none_serial_none(self): - name = x509.Name([ - x509.NameAttribute(x509.ObjectIdentifier('oid'), 'value1'), - x509.NameAttribute(x509.ObjectIdentifier('oid2'), 'value2'), - ]) + dirname = x509.DirectoryName( + x509.Name([ + x509.NameAttribute(x509.ObjectIdentifier('oid'), 'value1'), + x509.NameAttribute(x509.ObjectIdentifier('oid2'), 'value2'), + ]) + ) with pytest.raises(ValueError): - x509.AuthorityKeyIdentifier(b"identifier", name, None) + x509.AuthorityKeyIdentifier(b"identifier", [dirname], None) def test_authority_cert_serial_and_issuer_none(self): aki = x509.AuthorityKeyIdentifier(b"id", None, None) @@ -252,24 +597,55 @@ class TestAuthorityKeyIdentifier(object): assert aki.authority_cert_serial_number is None def test_repr(self): - name = x509.Name([x509.NameAttribute(x509.OID_COMMON_NAME, 'myCN')]) - aki = x509.AuthorityKeyIdentifier(b"digest", name, 1234) + dirname = x509.DirectoryName( + x509.Name([x509.NameAttribute(x509.OID_COMMON_NAME, 'myCN')]) + ) + aki = x509.AuthorityKeyIdentifier(b"digest", [dirname], 1234) if six.PY3: assert repr(aki) == ( "<AuthorityKeyIdentifier(key_identifier=b'digest', authority_" - "cert_issuer=<Name([<NameAttribute(oid=<ObjectIdentifier(oid=" - "2.5.4.3, name=commonName)>, value='myCN')>])>, authority_cer" - "t_serial_number=1234)>" + "cert_issuer=[<DirectoryName(value=<Name([<NameAttribute(oid=" + "<ObjectIdentifier(oid=2.5.4.3, name=commonName)>, value='myC" + "N')>])>)>], authority_cert_serial_number=1234)>" ) else: assert repr(aki) == ( "<AuthorityKeyIdentifier(key_identifier='digest', authority_ce" - "rt_issuer=<Name([<NameAttribute(oid=<ObjectIdentifier(oid=2.5" - ".4.3, name=commonName)>, value='myCN')>])>, authority_cert_se" - "rial_number=1234)>" + "rt_issuer=[<DirectoryName(value=<Name([<NameAttribute(oid=<Ob" + "jectIdentifier(oid=2.5.4.3, name=commonName)>, value='myCN')>" + "])>)>], authority_cert_serial_number=1234)>" ) + def test_eq(self): + dirname = x509.DirectoryName( + x509.Name([x509.NameAttribute(x509.OID_COMMON_NAME, 'myCN')]) + ) + aki = x509.AuthorityKeyIdentifier(b"digest", [dirname], 1234) + dirname2 = x509.DirectoryName( + x509.Name([x509.NameAttribute(x509.OID_COMMON_NAME, 'myCN')]) + ) + aki2 = x509.AuthorityKeyIdentifier(b"digest", [dirname2], 1234) + assert aki == aki2 + + def test_ne(self): + dirname = x509.DirectoryName( + x509.Name([x509.NameAttribute(x509.OID_COMMON_NAME, 'myCN')]) + ) + dirname5 = x509.DirectoryName( + x509.Name([x509.NameAttribute(x509.OID_COMMON_NAME, 'aCN')]) + ) + aki = x509.AuthorityKeyIdentifier(b"digest", [dirname], 1234) + aki2 = x509.AuthorityKeyIdentifier(b"diges", [dirname], 1234) + aki3 = x509.AuthorityKeyIdentifier(b"digest", None, None) + aki4 = x509.AuthorityKeyIdentifier(b"digest", [dirname], 12345) + aki5 = x509.AuthorityKeyIdentifier(b"digest", [dirname5], 12345) + assert aki != aki2 + assert aki != aki3 + assert aki != aki4 + assert aki != aki5 + assert aki != object() + class TestBasicConstraints(object): def test_ca_not_boolean(self): @@ -297,6 +673,19 @@ class TestBasicConstraints(object): "<BasicConstraints(ca=True, path_length=None)>" ) + def test_eq(self): + na = x509.BasicConstraints(ca=True, path_length=None) + na2 = x509.BasicConstraints(ca=True, path_length=None) + assert na == na2 + + def test_ne(self): + na = x509.BasicConstraints(ca=True, path_length=None) + na2 = x509.BasicConstraints(ca=True, path_length=1) + na3 = x509.BasicConstraints(ca=False, path_length=None) + assert na != na2 + assert na != na3 + assert na != object() + class TestExtendedKeyUsage(object): def test_not_all_oids(self): @@ -325,6 +714,21 @@ class TestExtendedKeyUsage(object): "tAuth)>])>" ) + def test_eq(self): + eku = x509.ExtendedKeyUsage([ + x509.ObjectIdentifier("1.3.6"), x509.ObjectIdentifier("1.3.7") + ]) + eku2 = x509.ExtendedKeyUsage([ + x509.ObjectIdentifier("1.3.6"), x509.ObjectIdentifier("1.3.7") + ]) + assert eku == eku2 + + def test_ne(self): + eku = x509.ExtendedKeyUsage([x509.ObjectIdentifier("1.3.6")]) + eku2 = x509.ExtendedKeyUsage([x509.ObjectIdentifier("1.3.6.1")]) + assert eku != eku2 + assert eku != object() + @pytest.mark.requires_backend_interface(interface=RSABackend) @pytest.mark.requires_backend_interface(interface=X509Backend) @@ -737,6 +1141,25 @@ class TestSubjectAlternativeName(object): "<SubjectAlternativeName([<DNSName(value=cryptography.io)>])>" ) + def test_eq(self): + san = x509.SubjectAlternativeName( + [x509.DNSName(u"cryptography.io")] + ) + san2 = x509.SubjectAlternativeName( + [x509.DNSName(u"cryptography.io")] + ) + assert san == san2 + + def test_ne(self): + san = x509.SubjectAlternativeName( + [x509.DNSName(u"cryptography.io")] + ) + san2 = x509.SubjectAlternativeName( + [x509.RFC822Name(u"admin@cryptography.io")] + ) + assert san != san2 + assert san != object() + @pytest.mark.requires_backend_interface(interface=RSABackend) @pytest.mark.requires_backend_interface(interface=X509Backend) @@ -856,3 +1279,951 @@ class TestRSASubjectAlternativeNameExtension(object): x509.NameAttribute(x509.OID_STATE_OR_PROVINCE_NAME, 'Texas'), ]) ] == dirname + + def test_rfc822name(self, backend): + cert = _load_cert( + os.path.join( + "x509", "custom", "san_rfc822_idna.pem" + ), + x509.load_pem_x509_certificate, + backend + ) + ext = cert.extensions.get_extension_for_oid( + x509.OID_SUBJECT_ALTERNATIVE_NAME + ) + assert ext is not None + assert ext.critical is False + + san = ext.value + + rfc822name = san.get_values_for_type(x509.RFC822Name) + assert [u"email@em\xe5\xefl.com"] == rfc822name + + def test_unicode_rfc822_name_dns_name_uri(self, backend): + cert = _load_cert( + os.path.join( + "x509", "custom", "san_idna_names.pem" + ), + x509.load_pem_x509_certificate, + backend + ) + ext = cert.extensions.get_extension_for_oid( + x509.OID_SUBJECT_ALTERNATIVE_NAME + ) + assert ext is not None + rfc822_name = ext.value.get_values_for_type(x509.RFC822Name) + dns_name = ext.value.get_values_for_type(x509.DNSName) + uri = ext.value.get_values_for_type(x509.UniformResourceIdentifier) + assert rfc822_name == [u"email@\u043f\u044b\u043a\u0430.cryptography"] + assert dns_name == [u"\u043f\u044b\u043a\u0430.cryptography"] + assert uri == [u"https://www.\u043f\u044b\u043a\u0430.cryptography"] + + def test_rfc822name_dnsname_ipaddress_directoryname_uri(self, backend): + cert = _load_cert( + os.path.join( + "x509", "custom", "san_email_dns_ip_dirname_uri.pem" + ), + x509.load_pem_x509_certificate, + backend + ) + ext = cert.extensions.get_extension_for_oid( + x509.OID_SUBJECT_ALTERNATIVE_NAME + ) + assert ext is not None + assert ext.critical is False + + san = ext.value + + rfc822_name = san.get_values_for_type(x509.RFC822Name) + uri = san.get_values_for_type(x509.UniformResourceIdentifier) + dns = san.get_values_for_type(x509.DNSName) + ip = san.get_values_for_type(x509.IPAddress) + dirname = san.get_values_for_type(x509.DirectoryName) + assert [u"user@cryptography.io"] == rfc822_name + assert [u"https://cryptography.io"] == uri + assert [u"cryptography.io"] == dns + assert [ + x509.Name([ + x509.NameAttribute(x509.OID_COMMON_NAME, 'dirCN'), + x509.NameAttribute( + x509.OID_ORGANIZATION_NAME, 'Cryptographic Authority' + ), + ]) + ] == dirname + assert [ + ipaddress.ip_address(u"127.0.0.1"), + ipaddress.ip_address(u"ff::") + ] == ip + + def test_invalid_rfc822name(self, backend): + cert = _load_cert( + os.path.join( + "x509", "custom", "san_rfc822_names.pem" + ), + x509.load_pem_x509_certificate, + backend + ) + with pytest.raises(ValueError) as exc: + cert.extensions + + assert 'Invalid rfc822name value' in str(exc.value) + + +@pytest.mark.requires_backend_interface(interface=RSABackend) +@pytest.mark.requires_backend_interface(interface=X509Backend) +class TestExtendedKeyUsageExtension(object): + def test_eku(self, backend): + cert = _load_cert( + os.path.join( + "x509", "custom", "extended_key_usage.pem" + ), + x509.load_pem_x509_certificate, + backend + ) + ext = cert.extensions.get_extension_for_oid( + x509.OID_EXTENDED_KEY_USAGE + ) + assert ext is not None + assert ext.critical is False + + assert [ + x509.ObjectIdentifier("1.3.6.1.5.5.7.3.1"), + x509.ObjectIdentifier("1.3.6.1.5.5.7.3.2"), + x509.ObjectIdentifier("1.3.6.1.5.5.7.3.3"), + x509.ObjectIdentifier("1.3.6.1.5.5.7.3.4"), + x509.ObjectIdentifier("1.3.6.1.5.5.7.3.9"), + x509.ObjectIdentifier("1.3.6.1.5.5.7.3.8"), + x509.ObjectIdentifier("2.5.29.37.0"), + x509.ObjectIdentifier("2.16.840.1.113730.4.1"), + ] == list(ext.value) + + +class TestAccessDescription(object): + def test_invalid_access_method(self): + with pytest.raises(ValueError): + x509.AccessDescription("notanoid", x509.DNSName(u"test")) + + def test_invalid_access_location(self): + with pytest.raises(TypeError): + x509.AccessDescription(x509.OID_CA_ISSUERS, "invalid") + + def test_repr(self): + ad = x509.AccessDescription( + x509.OID_OCSP, + x509.UniformResourceIdentifier(u"http://ocsp.domain.com") + ) + assert repr(ad) == ( + "<AccessDescription(access_method=<ObjectIdentifier(oid=1.3.6.1.5." + "5.7.48.1, name=OCSP)>, access_location=<UniformResourceIdentifier" + "(value=http://ocsp.domain.com)>)>" + ) + + def test_eq(self): + ad = x509.AccessDescription( + x509.OID_OCSP, + x509.UniformResourceIdentifier(u"http://ocsp.domain.com") + ) + ad2 = x509.AccessDescription( + x509.OID_OCSP, + x509.UniformResourceIdentifier(u"http://ocsp.domain.com") + ) + assert ad == ad2 + + def test_ne(self): + ad = x509.AccessDescription( + x509.OID_OCSP, + x509.UniformResourceIdentifier(u"http://ocsp.domain.com") + ) + ad2 = x509.AccessDescription( + x509.OID_CA_ISSUERS, + x509.UniformResourceIdentifier(u"http://ocsp.domain.com") + ) + ad3 = x509.AccessDescription( + x509.OID_OCSP, + x509.UniformResourceIdentifier(u"http://notthesame") + ) + assert ad != ad2 + assert ad != ad3 + assert ad != object() + + +class TestAuthorityInformationAccess(object): + def test_invalid_descriptions(self): + with pytest.raises(TypeError): + x509.AuthorityInformationAccess(["notanAccessDescription"]) + + def test_iter_len(self): + aia = x509.AuthorityInformationAccess([ + x509.AccessDescription( + x509.OID_OCSP, + x509.UniformResourceIdentifier(u"http://ocsp.domain.com") + ), + x509.AccessDescription( + x509.OID_CA_ISSUERS, + x509.UniformResourceIdentifier(u"http://domain.com/ca.crt") + ) + ]) + assert len(aia) == 2 + assert list(aia) == [ + x509.AccessDescription( + x509.OID_OCSP, + x509.UniformResourceIdentifier(u"http://ocsp.domain.com") + ), + x509.AccessDescription( + x509.OID_CA_ISSUERS, + x509.UniformResourceIdentifier(u"http://domain.com/ca.crt") + ) + ] + + def test_repr(self): + aia = x509.AuthorityInformationAccess([ + x509.AccessDescription( + x509.OID_OCSP, + x509.UniformResourceIdentifier(u"http://ocsp.domain.com") + ), + x509.AccessDescription( + x509.OID_CA_ISSUERS, + x509.UniformResourceIdentifier(u"http://domain.com/ca.crt") + ) + ]) + assert repr(aia) == ( + "<AuthorityInformationAccess([<AccessDescription(access_method=<Ob" + "jectIdentifier(oid=1.3.6.1.5.5.7.48.1, name=OCSP)>, access_locati" + "on=<UniformResourceIdentifier(value=http://ocsp.domain.com)>)>, <" + "AccessDescription(access_method=<ObjectIdentifier(oid=1.3.6.1.5.5" + ".7.48.2, name=caIssuers)>, access_location=<UniformResourceIdenti" + "fier(value=http://domain.com/ca.crt)>)>])>" + ) + + def test_eq(self): + aia = x509.AuthorityInformationAccess([ + x509.AccessDescription( + x509.OID_OCSP, + x509.UniformResourceIdentifier(u"http://ocsp.domain.com") + ), + x509.AccessDescription( + x509.OID_CA_ISSUERS, + x509.UniformResourceIdentifier(u"http://domain.com/ca.crt") + ) + ]) + aia2 = x509.AuthorityInformationAccess([ + x509.AccessDescription( + x509.OID_OCSP, + x509.UniformResourceIdentifier(u"http://ocsp.domain.com") + ), + x509.AccessDescription( + x509.OID_CA_ISSUERS, + x509.UniformResourceIdentifier(u"http://domain.com/ca.crt") + ) + ]) + assert aia == aia2 + + def test_ne(self): + aia = x509.AuthorityInformationAccess([ + x509.AccessDescription( + x509.OID_OCSP, + x509.UniformResourceIdentifier(u"http://ocsp.domain.com") + ), + x509.AccessDescription( + x509.OID_CA_ISSUERS, + x509.UniformResourceIdentifier(u"http://domain.com/ca.crt") + ) + ]) + aia2 = x509.AuthorityInformationAccess([ + x509.AccessDescription( + x509.OID_OCSP, + x509.UniformResourceIdentifier(u"http://ocsp.domain.com") + ), + ]) + + assert aia != aia2 + assert aia != object() + + +@pytest.mark.requires_backend_interface(interface=RSABackend) +@pytest.mark.requires_backend_interface(interface=X509Backend) +class TestAuthorityInformationAccessExtension(object): + def test_aia_ocsp_ca_issuers(self, backend): + cert = _load_cert( + os.path.join("x509", "cryptography.io.pem"), + x509.load_pem_x509_certificate, + backend + ) + ext = cert.extensions.get_extension_for_oid( + x509.OID_AUTHORITY_INFORMATION_ACCESS + ) + assert ext is not None + assert ext.critical is False + + assert ext.value == x509.AuthorityInformationAccess([ + x509.AccessDescription( + x509.OID_OCSP, + x509.UniformResourceIdentifier(u"http://gv.symcd.com") + ), + x509.AccessDescription( + x509.OID_CA_ISSUERS, + x509.UniformResourceIdentifier(u"http://gv.symcb.com/gv.crt") + ), + ]) + + def test_aia_multiple_ocsp_ca_issuers(self, backend): + cert = _load_cert( + os.path.join("x509", "custom", "aia_ocsp_ca_issuers.pem"), + x509.load_pem_x509_certificate, + backend + ) + ext = cert.extensions.get_extension_for_oid( + x509.OID_AUTHORITY_INFORMATION_ACCESS + ) + assert ext is not None + assert ext.critical is False + + assert ext.value == x509.AuthorityInformationAccess([ + x509.AccessDescription( + x509.OID_OCSP, + x509.UniformResourceIdentifier(u"http://ocsp.domain.com") + ), + x509.AccessDescription( + x509.OID_OCSP, + x509.UniformResourceIdentifier(u"http://ocsp2.domain.com") + ), + x509.AccessDescription( + x509.OID_CA_ISSUERS, + x509.DirectoryName(x509.Name([ + x509.NameAttribute(x509.OID_COMMON_NAME, "myCN"), + x509.NameAttribute(x509.OID_ORGANIZATION_NAME, "some Org"), + ])) + ), + ]) + + def test_aia_ocsp_only(self, backend): + cert = _load_cert( + os.path.join("x509", "custom", "aia_ocsp.pem"), + x509.load_pem_x509_certificate, + backend + ) + ext = cert.extensions.get_extension_for_oid( + x509.OID_AUTHORITY_INFORMATION_ACCESS + ) + assert ext is not None + assert ext.critical is False + + assert ext.value == x509.AuthorityInformationAccess([ + x509.AccessDescription( + x509.OID_OCSP, + x509.UniformResourceIdentifier(u"http://ocsp.domain.com") + ), + ]) + + def test_aia_ca_issuers_only(self, backend): + cert = _load_cert( + os.path.join("x509", "custom", "aia_ca_issuers.pem"), + x509.load_pem_x509_certificate, + backend + ) + ext = cert.extensions.get_extension_for_oid( + x509.OID_AUTHORITY_INFORMATION_ACCESS + ) + assert ext is not None + assert ext.critical is False + + assert ext.value == x509.AuthorityInformationAccess([ + x509.AccessDescription( + x509.OID_CA_ISSUERS, + x509.DirectoryName(x509.Name([ + x509.NameAttribute(x509.OID_COMMON_NAME, "myCN"), + x509.NameAttribute(x509.OID_ORGANIZATION_NAME, "some Org"), + ])) + ), + ]) + + +@pytest.mark.requires_backend_interface(interface=RSABackend) +@pytest.mark.requires_backend_interface(interface=X509Backend) +class TestAuthorityKeyIdentifierExtension(object): + def test_aki_keyid(self, backend): + cert = _load_cert( + os.path.join( + "x509", "cryptography.io.pem" + ), + x509.load_pem_x509_certificate, + backend + ) + ext = cert.extensions.get_extension_for_oid( + x509.OID_AUTHORITY_KEY_IDENTIFIER + ) + assert ext is not None + assert ext.critical is False + + assert ext.value.key_identifier == ( + b"\xc3\x9c\xf3\xfc\xd3F\x084\xbb\xceF\x7f\xa0|[\xf3\xe2\x08\xcbY" + ) + assert ext.value.authority_cert_issuer is None + assert ext.value.authority_cert_serial_number is None + + def test_aki_all_fields(self, backend): + cert = _load_cert( + os.path.join( + "x509", "custom", "authority_key_identifier.pem" + ), + x509.load_pem_x509_certificate, + backend + ) + ext = cert.extensions.get_extension_for_oid( + x509.OID_AUTHORITY_KEY_IDENTIFIER + ) + assert ext is not None + assert ext.critical is False + + assert ext.value.key_identifier == ( + b"9E>\xca=b\x1d\xea\x86I\xf6Z\xab@\xb7\xa4p\x98\xf1\xec" + ) + assert ext.value.authority_cert_issuer == [ + x509.DirectoryName( + x509.Name([ + x509.NameAttribute( + x509.OID_ORGANIZATION_NAME, u"PyCA" + ), + x509.NameAttribute( + x509.OID_COMMON_NAME, u"cryptography.io" + ) + ]) + ) + ] + assert ext.value.authority_cert_serial_number == 3 + + def test_aki_no_keyid(self, backend): + cert = _load_cert( + os.path.join( + "x509", "custom", "authority_key_identifier_no_keyid.pem" + ), + x509.load_pem_x509_certificate, + backend + ) + ext = cert.extensions.get_extension_for_oid( + x509.OID_AUTHORITY_KEY_IDENTIFIER + ) + assert ext is not None + assert ext.critical is False + + assert ext.value.key_identifier is None + assert ext.value.authority_cert_issuer == [ + x509.DirectoryName( + x509.Name([ + x509.NameAttribute( + x509.OID_ORGANIZATION_NAME, u"PyCA" + ), + x509.NameAttribute( + x509.OID_COMMON_NAME, u"cryptography.io" + ) + ]) + ) + ] + assert ext.value.authority_cert_serial_number == 3 + + +class TestDistributionPoint(object): + def test_distribution_point_full_name_not_general_names(self): + with pytest.raises(TypeError): + x509.DistributionPoint(["notgn"], None, None, None) + + def test_distribution_point_relative_name_not_name(self): + with pytest.raises(TypeError): + x509.DistributionPoint(None, "notname", None, None) + + def test_distribution_point_full_and_relative_not_none(self): + with pytest.raises(ValueError): + x509.DistributionPoint("data", "notname", None, None) + + def test_crl_issuer_not_general_names(self): + with pytest.raises(TypeError): + x509.DistributionPoint(None, None, None, ["notgn"]) + + def test_reason_not_reasonflags(self): + with pytest.raises(TypeError): + x509.DistributionPoint( + [x509.UniformResourceIdentifier(u"http://crypt.og/crl")], + None, + frozenset(["notreasonflags"]), + None + ) + + def test_reason_not_frozenset(self): + with pytest.raises(TypeError): + x509.DistributionPoint( + [x509.UniformResourceIdentifier(u"http://crypt.og/crl")], + None, + [x509.ReasonFlags.ca_compromise], + None + ) + + def test_disallowed_reasons(self): + with pytest.raises(ValueError): + x509.DistributionPoint( + [x509.UniformResourceIdentifier(u"http://crypt.og/crl")], + None, + frozenset([x509.ReasonFlags.unspecified]), + None + ) + + with pytest.raises(ValueError): + x509.DistributionPoint( + [x509.UniformResourceIdentifier(u"http://crypt.og/crl")], + None, + frozenset([x509.ReasonFlags.remove_from_crl]), + None + ) + + def test_reason_only(self): + with pytest.raises(ValueError): + x509.DistributionPoint( + None, + None, + frozenset([x509.ReasonFlags.aa_compromise]), + None + ) + + def test_eq(self): + dp = x509.DistributionPoint( + [x509.UniformResourceIdentifier(u"http://crypt.og/crl")], + None, + frozenset([x509.ReasonFlags.superseded]), + [ + x509.DirectoryName( + x509.Name([ + x509.NameAttribute( + x509.OID_COMMON_NAME, "Important CA" + ) + ]) + ) + ], + ) + dp2 = x509.DistributionPoint( + [x509.UniformResourceIdentifier(u"http://crypt.og/crl")], + None, + frozenset([x509.ReasonFlags.superseded]), + [ + x509.DirectoryName( + x509.Name([ + x509.NameAttribute( + x509.OID_COMMON_NAME, "Important CA" + ) + ]) + ) + ], + ) + assert dp == dp2 + + def test_ne(self): + dp = x509.DistributionPoint( + [x509.UniformResourceIdentifier(u"http://crypt.og/crl")], + None, + frozenset([x509.ReasonFlags.superseded]), + [ + x509.DirectoryName( + x509.Name([ + x509.NameAttribute( + x509.OID_COMMON_NAME, "Important CA" + ) + ]) + ) + ], + ) + dp2 = x509.DistributionPoint( + [x509.UniformResourceIdentifier(u"http://crypt.og/crl")], + None, + None, + None + ) + assert dp != dp2 + assert dp != object() + + def test_repr(self): + dp = x509.DistributionPoint( + None, + x509.Name([ + x509.NameAttribute(x509.OID_COMMON_NAME, "myCN") + ]), + frozenset([x509.ReasonFlags.ca_compromise]), + [ + x509.DirectoryName( + x509.Name([ + x509.NameAttribute( + x509.OID_COMMON_NAME, "Important CA" + ) + ]) + ) + ], + ) + if six.PY3: + assert repr(dp) == ( + "<DistributionPoint(full_name=None, relative_name=<Name([<Name" + "Attribute(oid=<ObjectIdentifier(oid=2.5.4.3, name=commonName)" + ">, value='myCN')>])>, reasons=frozenset({<ReasonFlags.ca_comp" + "romise: 'cACompromise'>}), crl_issuer=[<DirectoryName(value=<" + "Name([<NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.3, name=" + "commonName)>, value='Important CA')>])>)>])>" + ) + else: + assert repr(dp) == ( + "<DistributionPoint(full_name=None, relative_name=<Name([<Name" + "Attribute(oid=<ObjectIdentifier(oid=2.5.4.3, name=commonName)" + ">, value='myCN')>])>, reasons=frozenset([<ReasonFlags.ca_comp" + "romise: 'cACompromise'>]), crl_issuer=[<DirectoryName(value=<" + "Name([<NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.3, name=" + "commonName)>, value='Important CA')>])>)>])>" + ) + + +class TestCRLDistributionPoints(object): + def test_invalid_distribution_points(self): + with pytest.raises(TypeError): + x509.CRLDistributionPoints(["notadistributionpoint"]) + + def test_iter_len(self): + cdp = x509.CRLDistributionPoints([ + x509.DistributionPoint( + [x509.UniformResourceIdentifier(u"http://domain")], + None, + None, + None + ), + x509.DistributionPoint( + [x509.UniformResourceIdentifier(u"ftp://domain")], + None, + frozenset([ + x509.ReasonFlags.key_compromise, + x509.ReasonFlags.ca_compromise, + ]), + None + ), + ]) + assert len(cdp) == 2 + assert list(cdp) == [ + x509.DistributionPoint( + [x509.UniformResourceIdentifier(u"http://domain")], + None, + None, + None + ), + x509.DistributionPoint( + [x509.UniformResourceIdentifier(u"ftp://domain")], + None, + frozenset([ + x509.ReasonFlags.key_compromise, + x509.ReasonFlags.ca_compromise, + ]), + None + ), + ] + + def test_repr(self): + cdp = x509.CRLDistributionPoints([ + x509.DistributionPoint( + [x509.UniformResourceIdentifier(u"ftp://domain")], + None, + frozenset([x509.ReasonFlags.key_compromise]), + None + ), + ]) + if six.PY3: + assert repr(cdp) == ( + "<CRLDistributionPoints([<DistributionPoint(full_name=[<Unifo" + "rmResourceIdentifier(value=ftp://domain)>], relative_name=No" + "ne, reasons=frozenset({<ReasonFlags.key_compromise: 'keyComp" + "romise'>}), crl_issuer=None)>])>" + ) + else: + assert repr(cdp) == ( + "<CRLDistributionPoints([<DistributionPoint(full_name=[<Unifo" + "rmResourceIdentifier(value=ftp://domain)>], relative_name=No" + "ne, reasons=frozenset([<ReasonFlags.key_compromise: 'keyComp" + "romise'>]), crl_issuer=None)>])>" + ) + + def test_eq(self): + cdp = x509.CRLDistributionPoints([ + x509.DistributionPoint( + [x509.UniformResourceIdentifier(u"ftp://domain")], + None, + frozenset([ + x509.ReasonFlags.key_compromise, + x509.ReasonFlags.ca_compromise, + ]), + [x509.UniformResourceIdentifier(u"uri://thing")], + ), + ]) + cdp2 = x509.CRLDistributionPoints([ + x509.DistributionPoint( + [x509.UniformResourceIdentifier(u"ftp://domain")], + None, + frozenset([ + x509.ReasonFlags.key_compromise, + x509.ReasonFlags.ca_compromise, + ]), + [x509.UniformResourceIdentifier(u"uri://thing")], + ), + ]) + assert cdp == cdp2 + + def test_ne(self): + cdp = x509.CRLDistributionPoints([ + x509.DistributionPoint( + [x509.UniformResourceIdentifier(u"ftp://domain")], + None, + frozenset([ + x509.ReasonFlags.key_compromise, + x509.ReasonFlags.ca_compromise, + ]), + [x509.UniformResourceIdentifier(u"uri://thing")], + ), + ]) + cdp2 = x509.CRLDistributionPoints([ + x509.DistributionPoint( + [x509.UniformResourceIdentifier(u"ftp://domain2")], + None, + frozenset([ + x509.ReasonFlags.key_compromise, + x509.ReasonFlags.ca_compromise, + ]), + [x509.UniformResourceIdentifier(u"uri://thing")], + ), + ]) + cdp3 = x509.CRLDistributionPoints([ + x509.DistributionPoint( + [x509.UniformResourceIdentifier(u"ftp://domain")], + None, + frozenset([x509.ReasonFlags.key_compromise]), + [x509.UniformResourceIdentifier(u"uri://thing")], + ), + ]) + cdp4 = x509.CRLDistributionPoints([ + x509.DistributionPoint( + [x509.UniformResourceIdentifier(u"ftp://domain")], + None, + frozenset([ + x509.ReasonFlags.key_compromise, + x509.ReasonFlags.ca_compromise, + ]), + [x509.UniformResourceIdentifier(u"uri://thing2")], + ), + ]) + assert cdp != cdp2 + assert cdp != cdp3 + assert cdp != cdp4 + assert cdp != object() + + +@pytest.mark.requires_backend_interface(interface=RSABackend) +@pytest.mark.requires_backend_interface(interface=X509Backend) +class TestCRLDistributionPointsExtension(object): + def test_fullname_and_crl_issuer(self, backend): + cert = _load_cert( + os.path.join( + "x509", "PKITS_data", "certs", "ValidcRLIssuerTest28EE.crt" + ), + x509.load_der_x509_certificate, + backend + ) + + cdps = cert.extensions.get_extension_for_oid( + x509.OID_CRL_DISTRIBUTION_POINTS + ).value + + assert cdps == x509.CRLDistributionPoints([ + x509.DistributionPoint( + full_name=[x509.DirectoryName( + x509.Name([ + x509.NameAttribute(x509.OID_COUNTRY_NAME, "US"), + x509.NameAttribute( + x509.OID_ORGANIZATION_NAME, + "Test Certificates 2011" + ), + x509.NameAttribute( + x509.OID_ORGANIZATIONAL_UNIT_NAME, + "indirectCRL CA3 cRLIssuer" + ), + x509.NameAttribute( + x509.OID_COMMON_NAME, + "indirect CRL for indirectCRL CA3" + ), + ]) + )], + relative_name=None, + reasons=None, + crl_issuer=[x509.DirectoryName( + x509.Name([ + x509.NameAttribute(x509.OID_COUNTRY_NAME, "US"), + x509.NameAttribute( + x509.OID_ORGANIZATION_NAME, + "Test Certificates 2011" + ), + x509.NameAttribute( + x509.OID_ORGANIZATIONAL_UNIT_NAME, + "indirectCRL CA3 cRLIssuer" + ), + ]) + )], + ) + ]) + + def test_relativename_and_crl_issuer(self, backend): + cert = _load_cert( + os.path.join( + "x509", "PKITS_data", "certs", "ValidcRLIssuerTest29EE.crt" + ), + x509.load_der_x509_certificate, + backend + ) + + cdps = cert.extensions.get_extension_for_oid( + x509.OID_CRL_DISTRIBUTION_POINTS + ).value + + assert cdps == x509.CRLDistributionPoints([ + x509.DistributionPoint( + full_name=None, + relative_name=x509.Name([ + x509.NameAttribute( + x509.OID_COMMON_NAME, + "indirect CRL for indirectCRL CA3" + ), + ]), + reasons=None, + crl_issuer=[x509.DirectoryName( + x509.Name([ + x509.NameAttribute(x509.OID_COUNTRY_NAME, "US"), + x509.NameAttribute( + x509.OID_ORGANIZATION_NAME, + "Test Certificates 2011" + ), + x509.NameAttribute( + x509.OID_ORGANIZATIONAL_UNIT_NAME, + "indirectCRL CA3 cRLIssuer" + ), + ]) + )], + ) + ]) + + def test_fullname_crl_issuer_reasons(self, backend): + cert = _load_cert( + os.path.join( + "x509", "custom", "cdp_fullname_reasons_crl_issuer.pem" + ), + x509.load_pem_x509_certificate, + backend + ) + + cdps = cert.extensions.get_extension_for_oid( + x509.OID_CRL_DISTRIBUTION_POINTS + ).value + + assert cdps == x509.CRLDistributionPoints([ + x509.DistributionPoint( + full_name=[x509.UniformResourceIdentifier( + u"http://myhost.com/myca.crl" + )], + relative_name=None, + reasons=frozenset([ + x509.ReasonFlags.key_compromise, + x509.ReasonFlags.ca_compromise + ]), + crl_issuer=[x509.DirectoryName( + x509.Name([ + x509.NameAttribute(x509.OID_COUNTRY_NAME, "US"), + x509.NameAttribute( + x509.OID_ORGANIZATION_NAME, "PyCA" + ), + x509.NameAttribute( + x509.OID_COMMON_NAME, "cryptography CA" + ), + ]) + )], + ) + ]) + + def test_all_reasons(self, backend): + cert = _load_cert( + os.path.join( + "x509", "custom", "cdp_all_reasons.pem" + ), + x509.load_pem_x509_certificate, + backend + ) + + cdps = cert.extensions.get_extension_for_oid( + x509.OID_CRL_DISTRIBUTION_POINTS + ).value + + assert cdps == x509.CRLDistributionPoints([ + x509.DistributionPoint( + full_name=[x509.UniformResourceIdentifier( + u"http://domain.com/some.crl" + )], + relative_name=None, + reasons=frozenset([ + x509.ReasonFlags.key_compromise, + x509.ReasonFlags.ca_compromise, + x509.ReasonFlags.affiliation_changed, + x509.ReasonFlags.superseded, + x509.ReasonFlags.privilege_withdrawn, + x509.ReasonFlags.cessation_of_operation, + x509.ReasonFlags.aa_compromise, + x509.ReasonFlags.certificate_hold, + ]), + crl_issuer=None + ) + ]) + + def test_single_reason(self, backend): + cert = _load_cert( + os.path.join( + "x509", "custom", "cdp_reason_aa_compromise.pem" + ), + x509.load_pem_x509_certificate, + backend + ) + + cdps = cert.extensions.get_extension_for_oid( + x509.OID_CRL_DISTRIBUTION_POINTS + ).value + + assert cdps == x509.CRLDistributionPoints([ + x509.DistributionPoint( + full_name=[x509.UniformResourceIdentifier( + u"http://domain.com/some.crl" + )], + relative_name=None, + reasons=frozenset([x509.ReasonFlags.aa_compromise]), + crl_issuer=None + ) + ]) + + def test_crl_issuer_only(self, backend): + cert = _load_cert( + os.path.join( + "x509", "custom", "cdp_crl_issuer.pem" + ), + x509.load_pem_x509_certificate, + backend + ) + + cdps = cert.extensions.get_extension_for_oid( + x509.OID_CRL_DISTRIBUTION_POINTS + ).value + + assert cdps == x509.CRLDistributionPoints([ + x509.DistributionPoint( + full_name=None, + relative_name=None, + reasons=None, + crl_issuer=[x509.DirectoryName( + x509.Name([ + x509.NameAttribute( + x509.OID_COMMON_NAME, "cryptography CA" + ), + ]) + )], + ) + ]) diff --git a/tests/utils.py b/tests/utils.py index 65c99fbf..ab922c94 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", @@ -656,3 +657,107 @@ def load_kasvs_dh_vectors(vector_data): } return vectors + + +def load_kasvs_ecdh_vectors(vector_data): + """ + Loads data out of the KASVS key exchange vector data + """ + + curve_name_map = { + "P-192": "secp192r1", + "P-224": "secp224r1", + "P-256": "secp256r1", + "P-384": "secp384r1", + "P-521": "secp521r1", + } + + result_rx = re.compile(r"([FP]) \(([0-9]+) -") + + tags = [] + sets = dict() + vectors = [] + + # find info in header + for line in vector_data: + line = line.strip() + + if line.startswith("#"): + parm = line.split("Parameter set(s) supported:") + if len(parm) == 2: + names = parm[1].strip().split() + for n in names: + tags.append("[%s]" % n) + break + + # Sets Metadata + tag = None + curve = None + for line in vector_data: + line = line.strip() + + if not line or line.startswith("#"): + continue + + if line in tags: + tag = line + curve = None + elif line.startswith("[Curve selected:"): + curve = curve_name_map[line.split(':')[1].strip()[:-1]] + + if tag is not None and curve is not None: + sets[tag.strip("[]")] = curve + tag = None + if len(tags) == len(sets): + break + + # Data + data = { + "CAVS": dict(), + "IUT": dict(), + } + tag = None + for line in vector_data: + line = line.strip() + + if not line or line.startswith("#"): + continue + + if line.startswith("["): + tag = line.split()[0][1:] + elif line.startswith("COUNT = "): + data["COUNT"] = int(line.split("=")[1], 16) + elif line.startswith("dsCAVS = "): + data["CAVS"]["d"] = int(line.split("=")[1], 16) + elif line.startswith("QsCAVSx = "): + data["CAVS"]["x"] = int(line.split("=")[1], 16) + elif line.startswith("QsCAVSy = "): + data["CAVS"]["y"] = int(line.split("=")[1], 16) + elif line.startswith("dsIUT = "): + data["IUT"]["d"] = int(line.split("=")[1], 16) + elif line.startswith("QsIUTx = "): + data["IUT"]["x"] = int(line.split("=")[1], 16) + elif line.startswith("QsIUTy = "): + data["IUT"]["y"] = int(line.split("=")[1], 16) + elif line.startswith("Z = "): + data["Z"] = int(line.split("=")[1], 16) + elif line.startswith("Result = "): + result_str = line.split("=")[1].strip() + match = result_rx.match(result_str) + + if match.group(1) == "F": + data["fail"] = True + else: + data["fail"] = False + data["errno"] = int(match.group(2)) + + data["curve"] = sets[tag] + + vectors.append(data) + + data = { + "CAVS": dict(), + "IUT": dict(), + } + + return vectors |