blob: 815bd8b8baa7308231e530eba5d7b85390ff7ea8 [file] [log] [blame]
Jean-Paul Calderone8671c852011-03-02 19:26:20 -05001# Copyright (c) Jean-Paul Calderone
2# See LICENSE file for details.
Jean-Paul Calderone8b63d452008-03-21 18:31:12 -04003
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05004"""
Jonathan Ballet648875f2011-07-16 14:14:58 +09005Unit tests for :py:mod:`OpenSSL.crypto`.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05006"""
7
Alex Chanb00ede22017-01-30 07:24:40 +00008from warnings import simplefilter
Jean-Paul Calderone0b88b6a2009-07-05 12:44:41 -04009
Alex Gaynor4b9c96a2014-08-14 09:51:48 -070010import base64
Jean-Paul Calderone62ca8da2010-08-11 19:58:08 -040011from subprocess import PIPE, Popen
Rick Dean47262da2009-07-08 16:17:17 -050012from datetime import datetime, timedelta
Sándor Oroszi43c97762020-09-11 17:17:31 +020013import sys
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -050014
Alex Gaynor791212d2015-09-05 15:46:08 -040015import pytest
16
Alex Gaynor9939ba12017-06-25 16:28:24 -040017from cryptography import x509
Paul Kehrer72d968b2016-07-29 15:31:04 +080018from cryptography.hazmat.backends.openssl.backend import backend
19from cryptography.hazmat.primitives import serialization
20from cryptography.hazmat.primitives.asymmetric import rsa
21
Alex Gaynore466bc92017-07-06 23:43:47 -040022import flaky
23
Alex Gaynor01f90a12019-02-07 09:14:48 -050024from OpenSSL.crypto import TYPE_RSA, TYPE_DSA, Error, PKey
25from OpenSSL.crypto import X509, X509Name
Alex Gaynor31287502015-09-05 16:11:27 -040026from OpenSSL.crypto import (
Dan Sully44e767a2016-06-04 18:05:27 -070027 X509Store,
28 X509StoreFlags,
Dan Sully44e767a2016-06-04 18:05:27 -070029 X509StoreContext,
Alex Gaynor03737182020-07-23 20:40:46 -040030 X509StoreContextError,
Alex Gaynor31287502015-09-05 16:11:27 -040031)
Alex Gaynor01f90a12019-02-07 09:14:48 -050032from OpenSSL.crypto import X509Req
33from OpenSSL.crypto import X509Extension
Rick Dean5b7b6372009-04-01 11:34:06 -050034from OpenSSL.crypto import load_certificate, load_privatekey
Cory Benfield6492f7c2015-10-27 16:57:58 +090035from OpenSSL.crypto import load_publickey, dump_publickey
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -040036from OpenSSL.crypto import FILETYPE_PEM, FILETYPE_ASN1, FILETYPE_TEXT
Jean-Paul Calderone71919862009-04-01 13:01:19 -040037from OpenSSL.crypto import dump_certificate, load_certificate_request
38from OpenSSL.crypto import dump_certificate_request, dump_privatekey
Alex Gaynor01f90a12019-02-07 09:14:48 -050039from OpenSSL.crypto import PKCS7, load_pkcs7_data
40from OpenSSL.crypto import PKCS12, load_pkcs12
Dominic Chenf05b2122015-10-13 16:32:35 +000041from OpenSSL.crypto import CRL, Revoked, dump_crl, load_crl
Alex Gaynor01f90a12019-02-07 09:14:48 -050042from OpenSSL.crypto import NetscapeSPKI
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -040043from OpenSSL.crypto import (
Alex Gaynor03737182020-07-23 20:40:46 -040044 sign,
45 verify,
46 get_elliptic_curve,
47 get_elliptic_curves,
48)
Hynek Schlawackf0e66852015-10-16 20:18:38 +020049
Sándor Oroszi43c97762020-09-11 17:17:31 +020050from OpenSSL._util import ffi as _ffi, lib as _lib
51
52from .util import (
53 EqualityTestsMixin,
54 is_consistent_type,
55 WARNING_TYPE_EXPECTED,
56 NON_ASCII,
57)
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040058
Alex Gaynoraceb3e22015-09-05 12:00:22 -040059
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -040060def normalize_privatekey_pem(pem):
61 return dump_privatekey(FILETYPE_PEM, load_privatekey(FILETYPE_PEM, pem))
62
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040063
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -050064GOOD_CIPHER = "blowfish"
65BAD_CIPHER = "zippers"
66
Anthony Alba2ce737f2015-12-04 11:04:56 +080067GOOD_DIGEST = "SHA1"
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -050068BAD_DIGEST = "monkeys"
69
Paul Kehrera40898b2017-06-11 16:30:58 -100070old_root_cert_pem = b"""-----BEGIN CERTIFICATE-----
Rick Dean94e46fd2009-07-18 14:51:24 -050071MIIC7TCCAlagAwIBAgIIPQzE4MbeufQwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UE
72BhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdU
73ZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwIhgPMjAwOTAzMjUxMjM2
74NThaGA8yMDE3MDYxMTEyMzY1OFowWDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklM
75MRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdUZXN0aW5nMRgwFgYDVQQDEw9U
76ZXN0aW5nIFJvb3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPmaQumL
77urpE527uSEHdL1pqcDRmWzu+98Y6YHzT/J7KWEamyMCNZ6fRW1JCR782UQ8a07fy
782xXsKy4WdKaxyG8CcatwmXvpvRQ44dSANMihHELpANTdyVp6DCysED6wkQFurHlF
791dshEaJw8b/ypDhmbVIo6Ci1xvCJqivbLFnbAgMBAAGjgbswgbgwHQYDVR0OBBYE
80FINVdy1eIfFJDAkk51QJEo3IfgSuMIGIBgNVHSMEgYAwfoAUg1V3LV4h8UkMCSTn
81VAkSjch+BK6hXKRaMFgxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UE
82BxMHQ2hpY2FnbzEQMA4GA1UEChMHVGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBS
83b290IENBggg9DMTgxt659DAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GB
84AGGCDazMJGoWNBpc03u6+smc95dEead2KlZXBATOdFT1VesY3+nUOqZhEhTGlDMi
85hkgaZnzoIq/Uamidegk4hirsCT/R+6vsKAAxNTcBjUeZjlykCJWy5ojShGftXIKY
86w/njVbKMXrvc83qmTdGl3TAM0fxQIpqgcglFLveEBgzn
87-----END CERTIFICATE-----
Alex Gaynore7f51982016-09-11 11:48:14 -040088"""
Rick Dean94e46fd2009-07-18 14:51:24 -050089
Paul Kehrera40898b2017-06-11 16:30:58 -100090root_cert_pem = b"""-----BEGIN CERTIFICATE-----
Paul Kehrerbeaf9f52020-08-03 17:50:31 -050091MIIE7jCCA1agAwIBAgIIPQzE4MbeufQwDQYJKoZIhvcNAQELBQAwWDELMAkGA1UE
Paul Kehrera40898b2017-06-11 16:30:58 -100092BhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdU
Paul Kehrerbeaf9f52020-08-03 17:50:31 -050093ZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwHhcNMjAwODAyMTcxMTE5
94WhcNNDcxMjIwMTcxMTE5WjBYMQswCQYDVQQGEwJVUzELMAkGA1UECBMCSUwxEDAO
Paul Kehrera40898b2017-06-11 16:30:58 -100095BgNVBAcTB0NoaWNhZ28xEDAOBgNVBAoTB1Rlc3RpbmcxGDAWBgNVBAMTD1Rlc3Rp
Paul Kehrerbeaf9f52020-08-03 17:50:31 -050096bmcgUm9vdCBDQTCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBALpY5jb+
97S7AUbx9gzN06wkqUeb+eNLTjCOKofiMTn8Y0TqCA2ZyY3XMcNBMaIS7hdFTgmmqt
98fFntYobxLAl/twfbz9AnRaVDh2HyUvHvMBxKn1HSDLALLtqdF0pcXIjP04S7NKPQ
99Umgkv2H0KwcUpYlgjTFtXRiP+7wDSiQeP1YVSriEoE0TXK14F8np6ZKK0oQ+u16d
100Wn3MGQwFzS+Ipgoz0jbi5D2KzmK2dzHdxY8M2Dktkz/W3DUfUwaTohYed2DG39LP
101NUFOxekgXdIZ3vQbDfsEQt27TUzOztbo/BqK7YkRLzzOQFz+dKAxH6Hy6Bu9op7e
102DWS9TfD/+UmDxr3IeoLMpmUBKxmzTC4qpej+W1UuCE12dMo4LoadlkG+/l1oABqd
103Ucf45WgaFk3xpyEuGnDxjs6rqYPoEapIichxN2fgN+jkgH9ed44r0yOoVeG2pmwD
104YFCCxzkmiuzLADlfM1LUzqUNKVFcOakD3iujHEalnDIJsc/znYsqaRvCkQIDAQAB
105o4G7MIG4MB0GA1UdDgQWBBSDVXctXiHxSQwJJOdUCRKNyH4ErjCBiAYDVR0jBIGA
106MH6AFINVdy1eIfFJDAkk51QJEo3IfgSuoVykWjBYMQswCQYDVQQGEwJVUzELMAkG
107A1UECBMCSUwxEDAOBgNVBAcTB0NoaWNhZ28xEDAOBgNVBAoTB1Rlc3RpbmcxGDAW
108BgNVBAMTD1Rlc3RpbmcgUm9vdCBDQYIIPQzE4MbeufQwDAYDVR0TBAUwAwEB/zAN
109BgkqhkiG9w0BAQsFAAOCAYEAFIMFxLHaVDY/nsbYzI7+zxe4GJeUqRIj2g4XK/nF
1106lHLRFL2YP5yJ+Jm4JDkoZqKq/tcEQLIssQS++s6tBSdvFwdY6imfpEZgFPuodrZ
111KbYm4Xuouw09EQCEjPxBOQ1NEcPuwuDtvD6/BOfm3SRFRTq/gQwxKlZ7C/4l8b1+
112OQPIUryqdlFBpyE/M95GzaNdmkQx41PevEih2nqWnbTsXLeiSXLGoubMTxKEK4T+
113J7Ci2KTRJ3SYMgTNU6MNcl7b9Tpw9/KVG80IbpzNQ1LDh3ZtkOfqoou1lmBTeNPu
114g2C/oiW6lVAmZx1TL9gbUtkJ0Q2iW4D9TF+zuYi2qpbVU3RvoqK25x3AuIWf4JOL
1153cTNjJ/3zmGSORRJvcGyvVnL30R+vwpaxvyuqMjz3kBjkK2Z2pvElZMJiZhbGG7k
116MHZQ5A26v0/iQVno6FRv3cQb9EeAZtNHcIEgsNhPZ53XVnwZ58ByvATMLKNN8dWF
117Q+8Bbr7QFxeWvQfHYX2yaQZ/
Paul Kehrera40898b2017-06-11 16:30:58 -1000118-----END CERTIFICATE-----
119"""
120
Alex Gaynore7f51982016-09-11 11:48:14 -0400121root_key_pem = b"""-----BEGIN RSA PRIVATE KEY-----
Paul Kehrerbeaf9f52020-08-03 17:50:31 -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
Rick Dean94e46fd2009-07-18 14:51:24 -0500159-----END RSA PRIVATE KEY-----
Alex Gaynore7f51982016-09-11 11:48:14 -0400160"""
Rick Dean94e46fd2009-07-18 14:51:24 -0500161
Paul Kehrerbeaf9f52020-08-03 17:50:31 -0500162root_key_der = base64.b64decode(
163 """
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'
201"""
202)
203
204normalized_root_key_pem = normalize_privatekey_pem(root_key_pem)
205
Alex Gaynore7f51982016-09-11 11:48:14 -0400206intermediate_cert_pem = b"""-----BEGIN CERTIFICATE-----
Paul Kehrerbeaf9f52020-08-03 17:50:31 -0500207MIIEXDCCAsSgAwIBAgIRAMPzhm6//0Y/g2pmnHR2C4cwDQYJKoZIhvcNAQELBQAw
Stephen Holsapple0d9815f2014-08-27 19:36:53 -0700208WDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAw
Paul Kehrerbeaf9f52020-08-03 17:50:31 -0500209DgYDVQQKEwdUZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwHhcNMjAw
210ODAyMTcxMTIwWhcNNDcxMjIwMTcxMTIwWjBmMRUwEwYDVQQDEwxpbnRlcm1lZGlh
Stephen Holsapple0d9815f2014-08-27 19:36:53 -0700211dGUxDDAKBgNVBAoTA29yZzERMA8GA1UECxMIb3JnLXVuaXQxCzAJBgNVBAYTAlVT
Paul Kehrerbeaf9f52020-08-03 17:50:31 -0500212MQswCQYDVQQIEwJDQTESMBAGA1UEBxMJU2FuIERpZWdvMIIBojANBgkqhkiG9w0B
213AQEFAAOCAY8AMIIBigKCAYEAo3rOxOVrdLdRsR1o0+JG7MRpCtMoafA63TM/DczL
214Q4jURv5MzyTE7FFdXq4xNJRYgD16vUavZluQGj30+5Lkt07CuO/BK3itl8UW+dsH
215p95gzBvgnj5AVZGkNOQ0Y4CbXO087Ywep7tpBfZ5fzURLeH+OHQGseEFZ5e0w8Az
216AarWu+Ez5RGpkaZ61iiJa53mAgkrjw+o83UrpDT2nrXiyR6Fx4K4eb1rarodWqGv
217jSkdT5MA4i0gDhsIBnTarPB+0KM8M7od8DkLsTHBt4rYYCHgCX1bWavzGlqPEw9h
218ksK+LAbQKD9J2AxYDkL0PAeUuvWMhxEmN6hXePiw63sJzukRunAvut5A2+42JMkW
219guDyqIvAjlCYcIyBvUbphP3qSFqww/hpZ2wh5UZOc1mzYJKR9MgI8/UhRJEJ7NyY
220pF24EJbisjNE30ot8aM2/5cI5KevclcuPJWH8PjT/i1VnNpM4S8MqoPw6F+d75d/
221CtfI+LLfns4k3G9I+Qgxmpa5AgMBAAGjEzARMA8GA1UdEwEB/wQFMAMBAf8wDQYJ
222KoZIhvcNAQELBQADggGBAFVQ3Dmljrnbjys9ZIqcTs/B5ktKUAU2KNMO9TmoFymE
223YhHKbCb5u/CnWq3jtBW6jgkQHrhfY9leUlH87BkB2o16BcSKjHknHZ2MCdEvQvOM
224/nkkMDkOEoRn8mfCCxxgt8Kxf07wHDcnKoeJ3h9BXIl6nyJqJAcVWEJm1d75ayDG
2250Kr0z+LcqMtQqYI0csK/XDQkunlE95qti1HzxW+JeAf6nRkr7RNZLtGmUGAMfyBK
2269A0Db8QLR7O92YEmwoXtp+euN6uDdjw4A7KHjNXMdvqZoRfbZEA9c6XJTBj22h87
227gYUFRVpkNDrC/c9u6WgA943yMgFCwjrlTsmi+uoweT9U5r4TA+dVCDAv943aWCNm
228A+TiuIXlJAHl2PlH7Umu/oMQKDEt+0n4QcQLBZyK3CYU5kg+ms9vOvE19Lhp8HeS
229xqm6dwKpdm7/8EfGNW3s8Gm4KM26mb7dtSdHJFuR/BQ5y/cn4qIMyeGfHvsVew+2
230neyFR2Oc/nUlZMKfyHI+pA==
Stephen Holsapple0d9815f2014-08-27 19:36:53 -0700231-----END CERTIFICATE-----
Alex Gaynore7f51982016-09-11 11:48:14 -0400232"""
Stephen Holsapple0d9815f2014-08-27 19:36:53 -0700233
Alex Gaynore7f51982016-09-11 11:48:14 -0400234intermediate_key_pem = b"""-----BEGIN RSA PRIVATE KEY-----
Paul Kehrerbeaf9f52020-08-03 17:50:31 -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
Stephen Holsapple0d9815f2014-08-27 19:36:53 -0700272-----END RSA PRIVATE KEY-----
Alex Gaynore7f51982016-09-11 11:48:14 -0400273"""
Stephen Holsapple0d9815f2014-08-27 19:36:53 -0700274
Alex Gaynore7f51982016-09-11 11:48:14 -0400275server_cert_pem = b"""-----BEGIN CERTIFICATE-----
Paul Kehrerbeaf9f52020-08-03 17:50:31 -0500276MIIEKTCCApGgAwIBAgIJAJn/HpR21r/8MA0GCSqGSIb3DQEBCwUAMFgxCzAJBgNV
Paul Kehrera40898b2017-06-11 16:30:58 -1000277BAYTAlVTMQswCQYDVQQIDAJJTDEQMA4GA1UEBwwHQ2hpY2FnbzEQMA4GA1UECgwH
Paul Kehrerbeaf9f52020-08-03 17:50:31 -0500278VGVzdGluZzEYMBYGA1UEAwwPVGVzdGluZyBSb290IENBMB4XDTIwMDgwMjE3MTEy
279MFoXDTQ3MTIyMDE3MTEyMFowGDEWMBQGA1UEAwwNbG92ZWx5IHNlcnZlcjCCAaIw
280DQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAKU9txhKg6Nc0dVK9Vv4MYuYP6Hs
281oR483+wC53V8axkfy2TynrBSug8HapeSFW5jwdwcsjaDwEIAugZfRoz0N1vR/Q6T
282OFAYn2hRwlAgUXVk3NXpDNV/QRliGvxhLAVpvu1a4ExfVZoOQyPa8pogDgrUdB3e
283tYmmFHNa09Lv1nyMZWi6t7zH2weq6/Dxpm0BWf+THFcunv9TNfAqmDV5qbxvaUPh
284uvRpN+X2N3tejB8WKt+UmzAXUi3P3OgYimWXwq8Rmorc1rk5j+ksl6qYwZvi7rRV
285g1ZAH7bGhXC9eEU/1Z9q26OhAPdTyJD0pc+G9vMz6VijLRXcgHBUP09lSeqxnNxc
286pWoX6nRdGn6PkDhewHM05iqAE3ZHnc8kSBcRX85SoW5dGOhvvUTs4ePVNTo3vHdQ
287vftTDD+I3rbFnYTKUAzHTPSWGE7LVEiWJ94RKSADXgve0qq8o377UMnY7W3UygSY
288odyUZ29B5EfZ88EpIs/h5NomDv5VcQEoCWN1owIDAQABozYwNDAdBgNVHQ4EFgQU
289g1V3LV4h8UkMCSTnVAkSjch+BK4wEwYDVR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZI
290hvcNAQELBQADggGBACn0LsqO94tk8i+RbG5hryNduem9n8b8doYD97iaux6QLvY/
291A8DFduJtUevZ3OCsRYQSGa3V/ysMzN7/DIUkpRLevZmdw+1L6PGR7peR2xIQ+yEW
292bL88vLjezaYIzMKHJRmN8oP3DQtGJm6U2fMMiEHWqRtULIVpnFppzPI2z7+tDeyg
293PFD2YeiFWoq5lmXStrK+KYPJbhTn0gz4QlGBs7PLY2JMDRSVj6ctkvrpXbC3Rb3m
294qo2FY/y51ACg77Txc6NAmNE6tCknwaUjRQP2MuoYFm5/Z6O9/g49AEVIE101zHqV
295N6SkcTUaXAuQIyZaqwdndfOB4rrFyAkoxTM5OamIQl80hZKf4R5rM7D7Sz8kAWJi
296BPIcewN0XnI6lm+zPAVUAE8dZfgJmJR5ifZHYCuv96EX0RpYsddeik8UmjkZ2/ch
297vRzvRSNNxVC6Zoe6vKNUb89XMtJZqY80WxfWG3Z2Hwf9KvS+2KAH/6MiSMj0RI5F
298SCB2PMQm6DYXwM1EyA==
Rick Dean94e46fd2009-07-18 14:51:24 -0500299-----END CERTIFICATE-----
Alex Gaynore7f51982016-09-11 11:48:14 -0400300"""
Rick Dean94e46fd2009-07-18 14:51:24 -0500301
Alex Gaynor03737182020-07-23 20:40:46 -0400302server_key_pem = normalize_privatekey_pem(
303 b"""-----BEGIN RSA PRIVATE KEY-----
Paul Kehrerbeaf9f52020-08-03 17:50:31 -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
Rick Dean94e46fd2009-07-18 14:51:24 -0500341-----END RSA PRIVATE KEY-----
Alex Gaynor03737182020-07-23 20:40:46 -0400342"""
343)
Rick Dean94e46fd2009-07-18 14:51:24 -0500344
Alex Gaynore7f51982016-09-11 11:48:14 -0400345intermediate_server_cert_pem = b"""-----BEGIN CERTIFICATE-----
Paul Kehrerbeaf9f52020-08-03 17:50:31 -0500346MIIEXTCCAsWgAwIBAgIRAPQFY9jfskSihdiNSNdt6GswDQYJKoZIhvcNAQELBQAw
Stephen Holsapple0d9815f2014-08-27 19:36:53 -0700347ZjEVMBMGA1UEAxMMaW50ZXJtZWRpYXRlMQwwCgYDVQQKEwNvcmcxETAPBgNVBAsT
348CG9yZy11bml0MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVNh
Paul Kehrerbeaf9f52020-08-03 17:50:31 -0500349biBEaWVnbzAeFw0yMDA4MDIxNzExMjBaFw00NzEyMjAxNzExMjBaMG4xHTAbBgNV
Stephen Holsapple0d9815f2014-08-27 19:36:53 -0700350BAMTFGludGVybWVkaWF0ZS1zZXJ2aWNlMQwwCgYDVQQKEwNvcmcxETAPBgNVBAsT
351CG9yZy11bml0MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVNh
Paul Kehrerbeaf9f52020-08-03 17:50:31 -0500352biBEaWVnbzCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAL3UcTxwCsMZ
353qIE+7lolm8t6lT0IYZkE4L7u2qI64m9CvztudqqKYZcrprZobZxqPhqc8IO3CFR2
354nVzwZWxrHCcm6nAzJjVXUFrc4TLsVYYJL1QvKXxr97VIiySU7x6xWrQQsqDtlrb0
355jH59EYFbM2eMk2fBT2X4h6YMXlqyrDjZF6apClXtkdxGJGqR5PCTs4cvrYW7TpIm
356cuJq0S+MRBguZpriM+wOK7cXrqfRPFRzZtPXskpQPSAMDDAOGKl8OZfoVFYzG8KG
357omOa0hcHtgYX2GCDs1g1maY6Haw9bgs041BoApH9aQxehy5dfU39DcFoKSE3dCjR
358FaR6ryCA+f8L1F3xVaHsvX443CYF0/holfsptTjNd1T1z8WR5h1jtY0gJ/ERgcJZ
359UgDRE3lEkTLExS/nuGVfdwnlkxny9jbtYp2YcjYjUkChLtTgz4ommeIdBdDvSu8M
360wWHMtQNxECs5qA5J384cLh11Nd9exWUjiQ9yAZ0qTOzTkdH7VPHfxQIDAQABMA0G
361CSqGSIb3DQEBCwUAA4IBgQA2jC5hJ/+46RLBuaZiJhBawiY+HqybEAZWM/IBGZO4
362UKcRotovU+sb1jg+vpXwePSBPEtQoZce0jN0TKiCdlLM4/9lybAvc6qBLJ0d4VS5
363BU5QsCs9IKyvswAFVipQZi0szYwHk8T145SH/fPao8oznf5ae4a6rK9PyZqT7Ix1
364nnKGffbJs0dY+jlxmx/BPlbsGfTwPL6LexghjvbpbXWUdVLP3gAW6DPCtRd6lhWj
365JvgCkF2SnbQ7GgnPEYi8h09j0c6/sK6jLoNAatJyIlRGE1cdGYZVUlVW/xP6lYM0
366Mi1KKl0ZXOne4vPTtnTBBqrpjdLydH3WM1IxdwSRbmF15OD6BWzzKV4IYUJ21GDh
367YrVrcIeN49pUoKVTTn0Sql8f8mXxJhJ54wo9TKdIGZeuwTZrfWjcjWghXgghXGoP
368RI/I5fk/OMu0Oc06/+xdwCBHCSge0/vxK6fhTu7PxmJhQcZF0sDZyb6LXm2feVkG
3696FsxnsvstVNO3oJdpa8daLs=
Stephen Holsapple0d9815f2014-08-27 19:36:53 -0700370-----END CERTIFICATE-----
Alex Gaynore7f51982016-09-11 11:48:14 -0400371"""
Stephen Holsapple0d9815f2014-08-27 19:36:53 -0700372
Alex Gaynore7f51982016-09-11 11:48:14 -0400373intermediate_server_key_pem = b"""-----BEGIN RSA PRIVATE KEY-----
Paul Kehrerbeaf9f52020-08-03 17:50:31 -0500374MIIG5AIBAAKCAYEAvdRxPHAKwxmogT7uWiWby3qVPQhhmQTgvu7aojrib0K/O252
375qophlyumtmhtnGo+Gpzwg7cIVHadXPBlbGscJybqcDMmNVdQWtzhMuxVhgkvVC8p
376fGv3tUiLJJTvHrFatBCyoO2WtvSMfn0RgVszZ4yTZ8FPZfiHpgxeWrKsONkXpqkK
377Ve2R3EYkapHk8JOzhy+thbtOkiZy4mrRL4xEGC5mmuIz7A4rtxeup9E8VHNm09ey
378SlA9IAwMMA4YqXw5l+hUVjMbwoaiY5rSFwe2BhfYYIOzWDWZpjodrD1uCzTjUGgC
379kf1pDF6HLl19Tf0NwWgpITd0KNEVpHqvIID5/wvUXfFVoey9fjjcJgXT+GiV+ym1
380OM13VPXPxZHmHWO1jSAn8RGBwllSANETeUSRMsTFL+e4ZV93CeWTGfL2Nu1inZhy
381NiNSQKEu1ODPiiaZ4h0F0O9K7wzBYcy1A3EQKzmoDknfzhwuHXU1317FZSOJD3IB
382nSpM7NOR0ftU8d/FAgMBAAECggGAYNwla1FALIzLDieuNxE5jXne7GV6Zzm187as
383mFqzb1H/gbO7mQlDAn+jcS+Xvlf3mFy73HloJrDfWqzPE6MTmmag+N8gf9ctiS9r
384OTCd8uZ839ews2vj2PxLAz97Q437WiWq/7I7VN8zUNdAN2DxucRg8nAQs1c8390v
385x9ejSN580u0t+OpfoqWnrzkCOD8lO7V4NOR+EtTLifw3AKvxkuUaNa12ENyqMaJD
3863B1HS1AXB8DnmEOY7OE41sxaiSB44M7tsr31ldUCbEf/A5OZWeCfloP2c2g+Td8s
387+sl+AzoGa1HsFOqiqdDw8lKynfT1VukaaCtOr0pGeh6XW65aHRGI0B+mHIEM7yR0
388f2NjfvgejqNekWyJ+XeTcmrPPcSH72F9ansLRpUullAi+6OkPFIiwyKCP/S2sLwh
389cqe3NITfMweWDt7GqgOhz1yWaewXgdruWiFAYAh2JDBtgMWTUwWgkKyFCb4mrI6r
390zqiBpA8Mjm/H17h/dQqF3iRuaZOBAoHBAPDvVseeiGwZjDXuQD9acCBZU23xwevR
3916NVe/FLY1bybgsOBQCApQIWKH72eIHo12ULRMe/uZUo3su9JSCc8Gt8DsQpiZ2a+
392z8rS6uEw/UZGMWeLjcIVK5IeeD7OJ/BXEbwoxVvWLYYgWHpYwY9eqppsMlVqmIHY
393lfRAaepEkU/4euRl1VTFxkU0sYw7Tj+gbFQDydB0NSLIU/x10tlHblT+O5tgBLJh
394kL7II9tyoGaCUjNnACErmi1FA+lNsx1eAwKBwQDJsw+sIhujRHrajCV5dqq5cx3h
395ZQNfamoX6xfXYjNHjkeFnFpHB2w6ffe00q2Kt5+0AaSA295n1vPx6IKzKYMr8kpD
3960Kiv+mlKK5w7lZzdCeoJb8Co2t9viZXrN9lNetXiSZldrg5nlG8Gmi2RKn65vIfp
397ZFc8CExXpQWNMSLJlu2qM8Sjt4h8M880khuTggCeIDbw7YfyanlNhsNpOGv/r+Hd
3983i0BP0Qd1sZWkZ+hp/JJFdvyEh5vINgSABfNJJcCgcEA8LqioVcEBcZM8oG3jdVF
3993PyDQIHieUXFdpOuVvSyMf3LXJ3ivX+aKRNF/YZl+tWc24b7dzhh2hLm5PD6d8E1
400NAiTNsX1fJJAOe4dopz5IuL1b/jezcGrRBbPnCkNfLTyUmcGMmlAGRhubugJlb9H
401hH2AmRmlgW8u/NnzOZADBL1HxLb+vPHS1cj9cRi8aRRXyGX0miPSB4vTZpcu8cvO
402MHvIgMkiSDz1i7mbIiNYorOpgBR066+OH5cqfkwVH82TAoHAO3dZdYyQzXARMIIF
403QmxkJUz1UFCxz93V7btYSh4ftEcUeyX/z9U2aYBeGafLloxQv4eEcqFgTwkm3vmI
404Hz5r9/b1Qk0wjsGrbTyyUTbpCpozsBiMmrv9CCtuUe0jWh6PFKpSVzZL9OnkWfP2
40530fCGQymnX8B4ScpKuXyXxBPi1O+OmIM5Z/k04mK25sAGltHx1cEG8BMRoJxxROo
406ZUtHPBkk5H7ukeGPOaTq0PcaM1UKr9WMBTCmXGk4iwYP/mF9AoHBAOTlFVgGbbjk
407Cp/Wd7IrYCBKlnkIyBUMx5icLcsFmgXWx+Gx1HualD2aZ7kctYOfo+zLEyA6roni
408bSFLrxT4Od4uqwb51iZoJWxO+C3H1i9NoieU5JOnw5Osyl7OMXm3DkaS/N+ipP/b
4093bx1y8/WnGgqWWguXKt2lmgOItaEKrXYr6VZ1Z4upnLtkbxLANnqkQcL9287tXaW
410GPVXEteEXrtPj1f+9QYsMKuTWfaw6XfnBkBHxEZgWR+2hAN2z3c/Eg==
Stephen Holsapple0d9815f2014-08-27 19:36:53 -0700411-----END RSA PRIVATE KEY-----
Alex Gaynore7f51982016-09-11 11:48:14 -0400412"""
Stephen Holsapple0d9815f2014-08-27 19:36:53 -0700413
Alex Gaynore7f51982016-09-11 11:48:14 -0400414client_cert_pem = b"""-----BEGIN CERTIFICATE-----
Paul Kehrerbeaf9f52020-08-03 17:50:31 -0500415MIIEJzCCAo+gAwIBAgIJAKxpFI5lODkjMA0GCSqGSIb3DQEBCwUAMFgxCzAJBgNV
Paul Kehrera40898b2017-06-11 16:30:58 -1000416BAYTAlVTMQswCQYDVQQIDAJJTDEQMA4GA1UEBwwHQ2hpY2FnbzEQMA4GA1UECgwH
Paul Kehrerbeaf9f52020-08-03 17:50:31 -0500417VGVzdGluZzEYMBYGA1UEAwwPVGVzdGluZyBSb290IENBMB4XDTIwMDgwMjE3MTEy
418MVoXDTQ3MTIyMDE3MTEyMVowFjEUMBIGA1UEAwwLdWdseSBjbGllbnQwggGiMA0G
419CSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQDGChdOMY164FScJqfiJ5LEtjYOKEg4
420nmMAMGuHIT8wZZEfzaaHhBbypzKq2cPP1qtyHgvtUMM6KOFEj4y9AonqzzdlVxbM
421i6+AvYLWlPoB5r/G1GdslUvXbc7F02B/6sB/+iFXmcdjOjAQcLWxVgUL+1CoeoY1
422awNYmzQueK/T82a/6AYTdrx7XRX4wfxjYb1o3bnnRD/jGSakIylXeUGFsiSNkBs/
423dJMkUONxizAdAE2tW6NhPuE2O0UipzUhdgFnH6WPfJ0J1S7jZ3eQTUrLkFpWSp/Z
424hx/l/Ql9vO0wagHaT2wOiZdKVT8S6V6OPzJ7/H1evCoM6EuSPBC5DDP1nPetCK1v
425uC9kb7Dg6yFPt1CKrVFt0Y6W5Y5/GzisUtvYV/OGtX4DOwL9It68D04Qrvun1t/a
426Dh/c5gKqfqIGHUvUucFmOi6DrRpadfraLZMRGN2ysPjoVwhMgwwSmSWhziQIUfxK
427oyz1CUsyr5Gh5gdifbe1AOYwu6YdtlmhqCsCAwEAAaM2MDQwHQYDVR0OBBYEFINV
428dy1eIfFJDAkk51QJEo3IfgSuMBMGA1UdJQQMMAoGCCsGAQUFBwMCMA0GCSqGSIb3
429DQEBCwUAA4IBgQAhAEACc1j6EYoSfVJD8N/FlYfHRizdfVJyrmMnC8ID1vtfrU2z
430S2q+49ja2NyM4Sq+Cf+i+sFfzFG92LayZt9Mc1BnHZMdNzQL7Ynr2nDLxHsHzuYa
431N21/ucTpHEFGLmvQ/eWBMxQQ9TbiNXn+tnnqg46dRzN3vHJp+g5+ijtMcuh007z2
432niiO8F07wlb960XviejWejMC8hBLWlA7i3EjAkDO8RFQnG2Py5cQX9GgmWH1sDy3
433rIsWlU+e46ysSWK/bnudnAlzZMB9KJATVZu5+xmCumH2hLJv5vz+jnKcgU9MBZMO
434cKgNdFUbtRlU/gfTaohmLIuSquunCCrXLsLD8ygbKKXfSPGVo2XkvX3oxqUo6dmA
435LvU4N4sCQGiSzW+a13HBtk3TBZFsJSWUGSW/H7TVFiAonumJKRqRxMOkkB9JxX+V
4369LZBYuBLpOeK4wZ8BUSNlHKnGpDzl0DzdYrGlzWz0jXlLGZ8KMfXAn9h0mOZ+IyK
437eUlgMBYyAspCQzM=
Rick Dean94e46fd2009-07-18 14:51:24 -0500438-----END CERTIFICATE-----
Alex Gaynore7f51982016-09-11 11:48:14 -0400439"""
Rick Dean94e46fd2009-07-18 14:51:24 -0500440
Alex Gaynor03737182020-07-23 20:40:46 -0400441client_key_pem = normalize_privatekey_pem(
442 b"""-----BEGIN RSA PRIVATE KEY-----
Paul Kehrerbeaf9f52020-08-03 17:50:31 -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
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400480-----END RSA PRIVATE KEY-----
Alex Gaynor03737182020-07-23 20:40:46 -0400481"""
482)
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400483
Alex Gaynore7f51982016-09-11 11:48:14 -0400484cleartextCertificateRequestPEM = b"""-----BEGIN CERTIFICATE REQUEST-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400485MIIBnjCCAQcCAQAwXjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQH
486EwdDaGljYWdvMRcwFQYDVQQKEw5NeSBDb21wYW55IEx0ZDEXMBUGA1UEAxMORnJl
487ZGVyaWNrIERlYW4wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANp6Y17WzKSw
488BsUWkXdqg6tnXy8H8hA1msCMWpc+/2KJ4mbv5NyD6UD+/SqagQqulPbF/DFea9nA
489E0zhmHJELcM8gUTIlXv/cgDWnmK4xj8YkjVUiCdqKRAKeuzLG1pGmwwF5lGeJpXN
490xQn5ecR0UYSOWj6TTGXB9VyUMQzCClcBAgMBAAGgADANBgkqhkiG9w0BAQUFAAOB
491gQAAJGuF/R/GGbeC7FbFW+aJgr9ee0Xbl6nlhu7pTe67k+iiKT2dsl2ti68MVTnu
492Vrb3HUNqOkiwsJf6kCtq5oPn3QVYzTa76Dt2y3Rtzv6boRSlmlfrgS92GNma8JfR
493oICQk3nAudi6zl1Dix3BCv1pUp5KMtGn3MeDEi6QFGy2rA==
494-----END CERTIFICATE REQUEST-----
Alex Gaynore7f51982016-09-11 11:48:14 -0400495"""
Rick Dean5b7b6372009-04-01 11:34:06 -0500496
Alex Gaynore7f51982016-09-11 11:48:14 -0400497encryptedPrivateKeyPEM = b"""-----BEGIN RSA PRIVATE KEY-----
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400498Proc-Type: 4,ENCRYPTED
499DEK-Info: DES-EDE3-CBC,9573604A18579E9E
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400500
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400501SHOho56WxDkT0ht10UTeKc0F5u8cqIa01kzFAmETw0MAs8ezYtK15NPdCXUm3X/2
502a17G7LSF5bkxOgZ7vpXyMzun/owrj7CzvLxyncyEFZWvtvzaAhPhvTJtTIB3kf8B
5038+qRcpTGK7NgXEgYBW5bj1y4qZkD4zCL9o9NQzsKI3Ie8i0239jsDOWR38AxjXBH
504mGwAQ4Z6ZN5dnmM4fhMIWsmFf19sNyAML4gHenQCHhmXbjXeVq47aC2ProInJbrm
505+00TcisbAQ40V9aehVbcDKtS4ZbMVDwncAjpXpcncC54G76N6j7F7wL7L/FuXa3A
506fvSVy9n2VfF/pJ3kYSflLHH2G/DFxjF7dl0GxhKPxJjp3IJi9VtuvmN9R2jZWLQF
507tfC8dXgy/P9CfFQhlinqBTEwgH0oZ/d4k4NVFDSdEMaSdmBAjlHpc+Vfdty3HVnV
508rKXj//wslsFNm9kIwJGIgKUa/n2jsOiydrsk1mgH7SmNCb3YHgZhbbnq0qLat/HC
509gHDt3FHpNQ31QzzL3yrenFB2L9osIsnRsDTPFNi4RX4SpDgNroxOQmyzCCV6H+d4
510o1mcnNiZSdxLZxVKccq0AfRpHqpPAFnJcQHP6xyT9MZp6fBa0XkxDnt9kNU8H3Qw
5117SJWZ69VXjBUzMlQViLuaWMgTnL+ZVyFZf9hTF7U/ef4HMLMAVNdiaGG+G+AjCV/
512MbzjS007Oe4qqBnCWaFPSnJX6uLApeTbqAxAeyCql56ULW5x6vDMNC3dwjvS/CEh
51311n8RkgFIQA0AhuKSIg3CbuartRsJnWOLwgLTzsrKYL4yRog1RJrtw==
514-----END RSA PRIVATE KEY-----
Alex Gaynore7f51982016-09-11 11:48:14 -0400515"""
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400516
Alex Gaynore7f51982016-09-11 11:48:14 -0400517encryptedPrivateKeyPEMPassphrase = b"foobar"
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400518
Cory Benfield6492f7c2015-10-27 16:57:58 +0900519
Alex Gaynore7f51982016-09-11 11:48:14 -0400520cleartextPublicKeyPEM = b"""-----BEGIN PUBLIC KEY-----
Cory Benfield6492f7c2015-10-27 16:57:58 +0900521MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxszlc+b71LvlLS0ypt/l
522gT/JzSVJtnEqw9WUNGeiChywX2mmQLHEt7KP0JikqUFZOtPclNY823Q4pErMTSWC
52390qlUxI47vNJbXGRfmO2q6Zfw6SE+E9iUb74xezbOJLjBuUIkQzEKEFV+8taiRV+
524ceg1v01yCT2+OjhQW3cxG42zxyRFmqesbQAUWgS3uhPrUQqYQUEiTmVhh4FBUKZ5
525XIneGUpX1S7mXRxTLH6YzRoGFqRoc9A0BBNcoXHTWnxV215k4TeHMFYE5RG0KYAS
5268Xk5iKICEXwnZreIt3jyygqoOKsKZMK/Zl2VhMGhJR6HXRpQCyASzEG7bgtROLhL
527ywIDAQAB
528-----END PUBLIC KEY-----
Alex Gaynore7f51982016-09-11 11:48:14 -0400529"""
Cory Benfield6492f7c2015-10-27 16:57:58 +0900530
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400531# Some PKCS#7 stuff. Generated with the openssl command line:
532#
533# openssl crl2pkcs7 -inform pem -outform pem -certfile s.pem -nocrl
534#
535# with a certificate and key (but the key should be irrelevant) in s.pem
Alex Gaynore7f51982016-09-11 11:48:14 -0400536pkcs7Data = b"""\
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400537-----BEGIN PKCS7-----
538MIIDNwYJKoZIhvcNAQcCoIIDKDCCAyQCAQExADALBgkqhkiG9w0BBwGgggMKMIID
539BjCCAm+gAwIBAgIBATANBgkqhkiG9w0BAQQFADB7MQswCQYDVQQGEwJTRzERMA8G
540A1UEChMITTJDcnlwdG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtN
541MkNyeXB0byBDZXJ0aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNA
542cG9zdDEuY29tMB4XDTAwMDkxMDA5NTEzMFoXDTAyMDkxMDA5NTEzMFowUzELMAkG
543A1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIwEAYDVQQDEwlsb2NhbGhvc3Qx
544HTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tMFwwDQYJKoZIhvcNAQEBBQAD
545SwAwSAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh5kwI
546zOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEAAaOCAQQwggEAMAkGA1UdEwQCMAAw
547LAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0G
548A1UdDgQWBBTPhIKSvnsmYsBVNWjj0m3M2z0qVTCBpQYDVR0jBIGdMIGagBT7hyNp
54965w6kxXlxb8pUU/+7Sg4AaF/pH0wezELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0y
550Q3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UEAxMbTTJDcnlwdG8g
551Q2VydGlmaWNhdGUgTWFzdGVyMR0wGwYJKoZIhvcNAQkBFg5uZ3BzQHBvc3QxLmNv
552bYIBADANBgkqhkiG9w0BAQQFAAOBgQA7/CqT6PoHycTdhEStWNZde7M/2Yc6BoJu
553VwnW8YxGO8Sn6UJ4FeffZNcYZddSDKosw8LtPOeWoK3JINjAk5jiPQ2cww++7QGG
554/g5NDjxFZNDJP1dGiLAxPW6JXwov4v0FmdzfLOZ01jDcgQQZqEpYlgpuI5JEWUQ9
555Ho4EzbYCOaEAMQA=
556-----END PKCS7-----
Alex Gaynore7f51982016-09-11 11:48:14 -0400557"""
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400558
Alex Gaynor03737182020-07-23 20:40:46 -0400559pkcs7DataASN1 = base64.b64decode(
560 b"""
Alex Gaynor4b9c96a2014-08-14 09:51:48 -0700561MIIDNwYJKoZIhvcNAQcCoIIDKDCCAyQCAQExADALBgkqhkiG9w0BBwGgggMKMIID
562BjCCAm+gAwIBAgIBATANBgkqhkiG9w0BAQQFADB7MQswCQYDVQQGEwJTRzERMA8G
563A1UEChMITTJDcnlwdG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtN
564MkNyeXB0byBDZXJ0aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNA
565cG9zdDEuY29tMB4XDTAwMDkxMDA5NTEzMFoXDTAyMDkxMDA5NTEzMFowUzELMAkG
566A1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIwEAYDVQQDEwlsb2NhbGhvc3Qx
567HTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tMFwwDQYJKoZIhvcNAQEBBQAD
568SwAwSAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh5kwI
569zOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEAAaOCAQQwggEAMAkGA1UdEwQCMAAw
570LAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0G
571A1UdDgQWBBTPhIKSvnsmYsBVNWjj0m3M2z0qVTCBpQYDVR0jBIGdMIGagBT7hyNp
57265w6kxXlxb8pUU/+7Sg4AaF/pH0wezELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0y
573Q3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UEAxMbTTJDcnlwdG8g
574Q2VydGlmaWNhdGUgTWFzdGVyMR0wGwYJKoZIhvcNAQkBFg5uZ3BzQHBvc3QxLmNv
575bYIBADANBgkqhkiG9w0BAQQFAAOBgQA7/CqT6PoHycTdhEStWNZde7M/2Yc6BoJu
576VwnW8YxGO8Sn6UJ4FeffZNcYZddSDKosw8LtPOeWoK3JINjAk5jiPQ2cww++7QGG
577/g5NDjxFZNDJP1dGiLAxPW6JXwov4v0FmdzfLOZ01jDcgQQZqEpYlgpuI5JEWUQ9
578Ho4EzbYCOaEAMQA=
Alex Gaynor03737182020-07-23 20:40:46 -0400579"""
580)
Alex Gaynor4b9c96a2014-08-14 09:51:48 -0700581
Alex Gaynore7f51982016-09-11 11:48:14 -0400582crlData = b"""\
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -0500583-----BEGIN X509 CRL-----
584MIIBWzCBxTANBgkqhkiG9w0BAQQFADBYMQswCQYDVQQGEwJVUzELMAkGA1UECBMC
585SUwxEDAOBgNVBAcTB0NoaWNhZ28xEDAOBgNVBAoTB1Rlc3RpbmcxGDAWBgNVBAMT
586D1Rlc3RpbmcgUm9vdCBDQRcNMDkwNzI2MDQzNDU2WhcNMTIwOTI3MDI0MTUyWjA8
587MBUCAgOrGA8yMDA5MDcyNTIzMzQ1NlowIwICAQAYDzIwMDkwNzI1MjMzNDU2WjAM
588MAoGA1UdFQQDCgEEMA0GCSqGSIb3DQEBBAUAA4GBAEBt7xTs2htdD3d4ErrcGAw1
5894dKcVnIWTutoI7xxen26Wwvh8VCsT7i/UeP+rBl9rC/kfjWjzQk3/zleaarGTpBT
5900yp4HXRFFoRhhSE/hP+eteaPXRgrsNRLHe9ZDd69wmh7J1wMDb0m81RG7kqcbsid
591vrzEeLDRiiPl92dyyWmu
592-----END X509 CRL-----
Alex Gaynore7f51982016-09-11 11:48:14 -0400593"""
Jean-Paul Calderonee890db32010-08-22 16:55:15 -0400594
Alex Gaynore7f51982016-09-11 11:48:14 -0400595crlDataUnsupportedExtension = b"""\
Paul Kehrer5e3dd4c2016-03-11 09:58:28 -0400596-----BEGIN X509 CRL-----
597MIIGRzCCBS8CAQIwDQYJKoZIhvcNAQELBQAwJzELMAkGA1UEBhMCVVMxGDAWBgNV
598BAMMD2NyeXB0b2dyYXBoeS5pbxgPMjAxNTAxMDEwMDAwMDBaGA8yMDE2MDEwMTAw
599MDAwMFowggTOMBQCAQAYDzIwMTUwMTAxMDAwMDAwWjByAgEBGA8yMDE1MDEwMTAw
600MDAwMFowXDAYBgNVHRgEERgPMjAxNTAxMDEwMDAwMDBaMDQGA1UdHQQtMCukKTAn
601MQswCQYDVQQGEwJVUzEYMBYGA1UEAwwPY3J5cHRvZ3JhcGh5LmlvMAoGA1UdFQQD
602CgEAMHICAQIYDzIwMTUwMTAxMDAwMDAwWjBcMBgGA1UdGAQRGA8yMDE1MDEwMTAw
603MDAwMFowNAYDVR0dBC0wK6QpMCcxCzAJBgNVBAYTAlVTMRgwFgYDVQQDDA9jcnlw
604dG9ncmFwaHkuaW8wCgYDVR0VBAMKAQEwcgIBAxgPMjAxNTAxMDEwMDAwMDBaMFww
605GAYDVR0YBBEYDzIwMTUwMTAxMDAwMDAwWjA0BgNVHR0ELTArpCkwJzELMAkGA1UE
606BhMCVVMxGDAWBgNVBAMMD2NyeXB0b2dyYXBoeS5pbzAKBgNVHRUEAwoBAjByAgEE
607GA8yMDE1MDEwMTAwMDAwMFowXDAYBgNVHRgEERgPMjAxNTAxMDEwMDAwMDBaMDQG
608A1UdHQQtMCukKTAnMQswCQYDVQQGEwJVUzEYMBYGA1UEAwwPY3J5cHRvZ3JhcGh5
609LmlvMAoGA1UdFQQDCgEDMHICAQUYDzIwMTUwMTAxMDAwMDAwWjBcMBgGA1UdGAQR
610GA8yMDE1MDEwMTAwMDAwMFowNAYDVR0dBC0wK6QpMCcxCzAJBgNVBAYTAlVTMRgw
611FgYDVQQDDA9jcnlwdG9ncmFwaHkuaW8wCgYDVR0VBAMKAQQwcgIBBhgPMjAxNTAx
612MDEwMDAwMDBaMFwwGAYDVR0YBBEYDzIwMTUwMTAxMDAwMDAwWjA0BgNVHR0ELTAr
613pCkwJzELMAkGA1UEBhMCVVMxGDAWBgNVBAMMD2NyeXB0b2dyYXBoeS5pbzAKBgNV
614HRUEAwoBBTByAgEHGA8yMDE1MDEwMTAwMDAwMFowXDAYBgNVHRgEERgPMjAxNTAx
615MDEwMDAwMDBaMDQGA1UdHQQtMCukKTAnMQswCQYDVQQGEwJVUzEYMBYGA1UEAwwP
616Y3J5cHRvZ3JhcGh5LmlvMAoGA1UdFQQDCgEGMHICAQgYDzIwMTUwMTAxMDAwMDAw
617WjBcMBgGA1UdGAQRGA8yMDE1MDEwMTAwMDAwMFowNAYDVR0dBC0wK6QpMCcxCzAJ
618BgNVBAYTAlVTMRgwFgYDVQQDDA9jcnlwdG9ncmFwaHkuaW8wCgYDVR0VBAMKAQgw
619cgIBCRgPMjAxNTAxMDEwMDAwMDBaMFwwGAYDVR0YBBEYDzIwMTUwMTAxMDAwMDAw
620WjA0BgNVHR0ELTArpCkwJzELMAkGA1UEBhMCVVMxGDAWBgNVBAMMD2NyeXB0b2dy
621YXBoeS5pbzAKBgNVHRUEAwoBCTByAgEKGA8yMDE1MDEwMTAwMDAwMFowXDAYBgNV
622HRgEERgPMjAxNTAxMDEwMDAwMDBaMDQGA1UdHQQtMCukKTAnMQswCQYDVQQGEwJV
623UzEYMBYGA1UEAwwPY3J5cHRvZ3JhcGh5LmlvMAoGA1UdFQQDCgEKMC4CAQsYDzIw
624MTUwMTAxMDAwMDAwWjAYMAoGA1UdFQQDCgEBMAoGAyoDBAQDCgEAMA0GCSqGSIb3
625DQEBCwUAA4IBAQBTaloHlPaCZzYee8LxkWej5meiqxQVNWFoVdjesroa+f1FRrH+
626drRU60Nq97KCKf7f9GNN/J3ZIlQmYhmuDqh12f+XLpotoj1ZRfBz2hjFCkJlv+2c
627oWWGNHgA70ndFoVtcmX088SYpX8E3ARATivS4q2h9WlwV6rO93mhg3HGIe3JpcK4
6287BcW6Poi/ut/zsDOkVbI00SqaujRpdmdCTht82MH3ztjyDkI9KYaD/YEweKSrWOz
629SdEILd164bfBeLuplVI+xpmTEMVNpXBlSXl7+xIw9Vk7p7Q1Pa3k/SvhOldYCm6y
630C1xAg/AAq6w78yzYt18j5Mj0s6eeHi1YpHKw
631-----END X509 CRL-----
Alex Gaynore7f51982016-09-11 11:48:14 -0400632"""
Paul Kehrer5e3dd4c2016-03-11 09:58:28 -0400633
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400634
635# A broken RSA private key which can be used to test the error path through
636# PKey.check.
Alex Gaynore7f51982016-09-11 11:48:14 -0400637inconsistentPrivateKeyPEM = b"""-----BEGIN RSA PRIVATE KEY-----
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400638MIIBPAIBAAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh
6395kwIzOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEaAQJBAIqm/bz4NA1H++Vx5Ewx
640OcKp3w19QSaZAwlGRtsUxrP7436QjnREM3Bm8ygU11BjkPVmtrKm6AayQfCHqJoT
641zIECIQDW0BoMoL0HOYM/mrTLhaykYAVqgIeJsPjvkEhTFXWBuQIhAM3deFAvWNu4
642nklUQ37XsCT2c9tmNt1LAT+slG2JOTTRAiAuXDtC/m3NYVwyHfFm+zKHRzHkClk2
643HjubeEgjpj32AQIhAJqMGTaZVOwevTXvvHwNeH+vRWsAYU/gbx+OQB+7VOcBAiEA
644oolb6NMg/R3enNPvS1O4UU1H8wpaF77L4yiSWlE0p4w=
645-----END RSA PRIVATE KEY-----
Alex Gaynore7f51982016-09-11 11:48:14 -0400646"""
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400647
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -0400648# certificate with NULL bytes in subjectAltName and common name
649
Alex Gaynore7f51982016-09-11 11:48:14 -0400650nulbyteSubjectAltNamePEM = b"""-----BEGIN CERTIFICATE-----
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -0400651MIIE2DCCA8CgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBxTELMAkGA1UEBhMCVVMx
652DzANBgNVBAgMBk9yZWdvbjESMBAGA1UEBwwJQmVhdmVydG9uMSMwIQYDVQQKDBpQ
653eXRob24gU29mdHdhcmUgRm91bmRhdGlvbjEgMB4GA1UECwwXUHl0aG9uIENvcmUg
654RGV2ZWxvcG1lbnQxJDAiBgNVBAMMG251bGwucHl0aG9uLm9yZwBleGFtcGxlLm9y
655ZzEkMCIGCSqGSIb3DQEJARYVcHl0aG9uLWRldkBweXRob24ub3JnMB4XDTEzMDgw
656NzEzMTE1MloXDTEzMDgwNzEzMTI1MlowgcUxCzAJBgNVBAYTAlVTMQ8wDQYDVQQI
657DAZPcmVnb24xEjAQBgNVBAcMCUJlYXZlcnRvbjEjMCEGA1UECgwaUHl0aG9uIFNv
658ZnR3YXJlIEZvdW5kYXRpb24xIDAeBgNVBAsMF1B5dGhvbiBDb3JlIERldmVsb3Bt
659ZW50MSQwIgYDVQQDDBtudWxsLnB5dGhvbi5vcmcAZXhhbXBsZS5vcmcxJDAiBgkq
660hkiG9w0BCQEWFXB5dGhvbi1kZXZAcHl0aG9uLm9yZzCCASIwDQYJKoZIhvcNAQEB
661BQADggEPADCCAQoCggEBALXq7cn7Rn1vO3aA3TrzA5QLp6bb7B3f/yN0CJ2XFj+j
662pHs+Gw6WWSUDpybiiKnPec33BFawq3kyblnBMjBU61ioy5HwQqVkJ8vUVjGIUq3P
663vX/wBmQfzCe4o4uM89gpHyUL9UYGG8oCRa17dgqcv7u5rg0Wq2B1rgY+nHwx3JIv
664KRrgSwyRkGzpN8WQ1yrXlxWjgI9de0mPVDDUlywcWze1q2kwaEPTM3hLAmD1PESA
665oY/n8A/RXoeeRs9i/Pm/DGUS8ZPINXk/yOzsR/XvvkTVroIeLZqfmFpnZeF0cHzL
66608LODkVJJ9zjLdT7SA4vnne4FEbAxDbKAq5qkYzaL4UCAwEAAaOB0DCBzTAMBgNV
667HRMBAf8EAjAAMB0GA1UdDgQWBBSIWlXAUv9hzVKjNQ/qWpwkOCL3XDALBgNVHQ8E
668BAMCBeAwgZAGA1UdEQSBiDCBhYIeYWx0bnVsbC5weXRob24ub3JnAGV4YW1wbGUu
669Y29tgSBudWxsQHB5dGhvbi5vcmcAdXNlckBleGFtcGxlLm9yZ4YpaHR0cDovL251
670bGwucHl0aG9uLm9yZwBodHRwOi8vZXhhbXBsZS5vcmeHBMAAAgGHECABDbgAAAAA
671AAAAAAAAAAEwDQYJKoZIhvcNAQEFBQADggEBAKxPRe99SaghcI6IWT7UNkJw9aO9
672i9eo0Fj2MUqxpKbdb9noRDy2CnHWf7EIYZ1gznXPdwzSN4YCjV5d+Q9xtBaowT0j
673HPERs1ZuytCNNJTmhyqZ8q6uzMLoht4IqH/FBfpvgaeC5tBTnTT0rD5A/olXeimk
674kX4LxlEx5RAvpGB2zZVRGr6LobD9rVK91xuHYNIxxxfEGE8tCCWjp0+3ksri9SXx
675VHWBnbM9YaL32u3hxm8sYB/Yb8WSBavJCWJJqRStVRHM1koZlJmXNx2BX4vPo6iW
676RFEIPQsFZRLrtnCAiEhyT8bC2s/Njlu6ly9gtJZWSV46Q3ZjBL4q9sHKqZQ=
Alex Gaynore7f51982016-09-11 11:48:14 -0400677-----END CERTIFICATE-----"""
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -0400678
Alex Gaynore7f51982016-09-11 11:48:14 -0400679large_key_pem = b"""-----BEGIN RSA PRIVATE KEY-----
Colleen Murphye09399b2016-03-01 17:40:49 -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
730vYeU7Ab/
Alex Gaynore7f51982016-09-11 11:48:14 -0400731-----END RSA PRIVATE KEY-----"""
Colleen Murphye09399b2016-03-01 17:40:49 -0800732
Paul Kehrer72d968b2016-07-29 15:31:04 +0800733ec_private_key_pem = b"""-----BEGIN PRIVATE KEY-----
734MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgYirTZSx+5O8Y6tlG
735cka6W6btJiocdrdolfcukSoTEk+hRANCAAQkvPNu7Pa1GcsWU4v7ptNfqCJVq8Cx
736zo0MUVPQgwJ3aJtNM1QMOQUayCrRwfklg+D/rFSUwEUqtZh7fJDiFqz3
737-----END PRIVATE KEY-----
738"""
739
Paul Kehrer59d26252017-07-20 10:45:54 +0200740ec_root_key_pem = b"""-----BEGIN EC PRIVATE KEY-----
741MIGlAgEBBDEAz/HOBFPYLB0jLWeTpJn4Yc4m/C4mdWymVHBjOmnwiPHKT326iYN/
742ZhmSs+RM94RsoAcGBSuBBAAioWQDYgAEwE5vDdla/nLpWAPAQ0yFGqwLuw4BcN2r
743U+sKab5EAEHzLeceRa8ffncYdCXNoVsBcdob1y66CFZMEWLetPTmGapyWkBAs6/L
7448kUlkU9OsE+7IVo4QQJkgV5gM+Dim1XE
745-----END EC PRIVATE KEY-----
746"""
747
748ec_root_cert_pem = b"""-----BEGIN CERTIFICATE-----
749MIICLTCCAbKgAwIBAgIMWW/hwTl6ufz6/WkCMAoGCCqGSM49BAMDMFgxGDAWBgNV
750BAMTD1Rlc3RpbmcgUm9vdCBDQTEQMA4GA1UEChMHVGVzdGluZzEQMA4GA1UEBxMH
751Q2hpY2FnbzELMAkGA1UECBMCSUwxCzAJBgNVBAYTAlVTMCAXDTE3MDcxOTIyNDgz
752M1oYDzk5OTkxMjMxMjM1OTU5WjBYMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0Ex
753EDAOBgNVBAoTB1Rlc3RpbmcxEDAOBgNVBAcTB0NoaWNhZ28xCzAJBgNVBAgTAklM
754MQswCQYDVQQGEwJVUzB2MBAGByqGSM49AgEGBSuBBAAiA2IABMBObw3ZWv5y6VgD
755wENMhRqsC7sOAXDdq1PrCmm+RABB8y3nHkWvH353GHQlzaFbAXHaG9cuughWTBFi
7563rT05hmqclpAQLOvy/JFJZFPTrBPuyFaOEECZIFeYDPg4ptVxKNDMEEwDwYDVR0T
757AQH/BAUwAwEB/zAPBgNVHQ8BAf8EBQMDBwQAMB0GA1UdDgQWBBSoTrF0H2m8RDzB
758MnY2KReEPfz7ZjAKBggqhkjOPQQDAwNpADBmAjEA3+G1oVCxGjYX4iUN93QYcNHe
759e3fJQJwX9+KsHRut6qNZDUbvRbtO1YIAwB4UJZjwAjEAtXCPURS5A4McZHnSwgTi
760Td8GMrwKz0557OxxtKN6uVVy4ACFMqEw0zN/KJI1vxc9
761-----END CERTIFICATE-----"""
762
Mrmaxmeier8cd3b172020-03-11 22:03:59 +0100763rsa_p_not_prime_pem = """
764-----BEGIN RSA PRIVATE KEY-----
765MBsCAQACAS0CAQcCAQACAQ8CAQMCAQACAQACAQA=
766-----END RSA PRIVATE KEY-----
767"""
768
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400769
Alex Chanc6077062016-11-18 13:53:39 +0000770@pytest.fixture
771def x509_data():
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400772 """
Alex Chanc6077062016-11-18 13:53:39 +0000773 Create a new private key and start a certificate request (for a test
774 to finish in one way or another).
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400775 """
Alex Chanc6077062016-11-18 13:53:39 +0000776 # Basic setup stuff to generate a certificate
777 pkey = PKey()
Alex Gaynor6e9f9762018-05-12 07:44:37 -0400778 pkey.generate_key(TYPE_RSA, 512)
Alex Chanc6077062016-11-18 13:53:39 +0000779 req = X509Req()
780 req.set_pubkey(pkey)
781 # Authority good you have.
782 req.get_subject().commonName = "Yoda root CA"
783 x509 = X509()
784 subject = x509.get_subject()
785 subject.commonName = req.get_subject().commonName
786 x509.set_issuer(subject)
787 x509.set_pubkey(pkey)
788 now = datetime.now()
789 expire = datetime.now() + timedelta(days=100)
790 x509.set_notBefore(now.strftime("%Y%m%d%H%M%SZ").encode())
791 x509.set_notAfter(expire.strftime("%Y%m%d%H%M%SZ").encode())
792 yield pkey, x509
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400793
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400794
Alex Chanc6077062016-11-18 13:53:39 +0000795class TestX509Ext(object):
796 """
797 Tests for `OpenSSL.crypto.X509Extension`.
798 """
Jean-Paul Calderoneef9a3dc2013-03-02 16:33:32 -0800799
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -0400800 def test_str(self):
801 """
Alex Chanc6077062016-11-18 13:53:39 +0000802 The string representation of `X509Extension` instances as
803 returned by `str` includes stuff.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -0400804 """
805 # This isn't necessarily the best string representation. Perhaps it
806 # will be changed/improved in the future.
Alex Chanc6077062016-11-18 13:53:39 +0000807 assert (
Alex Gaynor03737182020-07-23 20:40:46 -0400808 str(X509Extension(b"basicConstraints", True, b"CA:false"))
809 == "CA:FALSE"
Alex Chanc6077062016-11-18 13:53:39 +0000810 )
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -0400811
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400812 def test_type(self):
813 """
Alex Gaynor01f90a12019-02-07 09:14:48 -0500814 `X509Extension` can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400815 """
Alex Chanc6077062016-11-18 13:53:39 +0000816 assert is_consistent_type(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400817 X509Extension,
Alex Gaynor03737182020-07-23 20:40:46 -0400818 "X509Extension",
819 b"basicConstraints",
820 True,
821 b"CA:true",
822 )
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400823
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500824 def test_construction(self):
825 """
Alex Chanc6077062016-11-18 13:53:39 +0000826 `X509Extension` accepts an extension type name, a critical flag,
Alex Gaynor01f90a12019-02-07 09:14:48 -0500827 and an extension value and returns an `X509Extension` instance.
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500828 """
Alex Gaynor03737182020-07-23 20:40:46 -0400829 basic = X509Extension(b"basicConstraints", True, b"CA:true")
Alex Gaynor01f90a12019-02-07 09:14:48 -0500830 assert isinstance(basic, X509Extension)
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500831
Alex Gaynor03737182020-07-23 20:40:46 -0400832 comment = X509Extension(b"nsComment", False, b"pyOpenSSL unit test")
Alex Gaynor01f90a12019-02-07 09:14:48 -0500833 assert isinstance(comment, X509Extension)
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500834
Alex Gaynor03737182020-07-23 20:40:46 -0400835 @pytest.mark.parametrize(
836 "type_name, critical, value",
837 [
838 (b"thisIsMadeUp", False, b"hi"),
839 (b"basicConstraints", False, b"blah blah"),
840 # Exercise a weird one (an extension which uses the r2i method).
841 # This exercises the codepath that requires a non-NULL ctx to be
842 # passed to X509V3_EXT_nconf. It can't work now because we provide
843 # no configuration database. It might be made to work in the
844 # future.
845 (
846 b"proxyCertInfo",
847 True,
848 b"language:id-ppl-anyLanguage,pathlen:1,policy:text:AB",
849 ),
850 ],
851 )
Alex Chanc6077062016-11-18 13:53:39 +0000852 def test_invalid_extension(self, type_name, critical, value):
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500853 """
Alex Chanc6077062016-11-18 13:53:39 +0000854 `X509Extension` raises something if it is passed a bad
855 extension name or value.
856 """
857 with pytest.raises(Error):
858 X509Extension(type_name, critical, value)
859
Alex Gaynor03737182020-07-23 20:40:46 -0400860 @pytest.mark.parametrize("critical_flag", [True, False])
Alex Chanc6077062016-11-18 13:53:39 +0000861 def test_get_critical(self, critical_flag):
862 """
863 `X509ExtensionType.get_critical` returns the value of the
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500864 extension's critical flag.
865 """
Alex Gaynor03737182020-07-23 20:40:46 -0400866 ext = X509Extension(b"basicConstraints", critical_flag, b"CA:true")
Alex Chanc6077062016-11-18 13:53:39 +0000867 assert ext.get_critical() == critical_flag
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500868
Alex Gaynor03737182020-07-23 20:40:46 -0400869 @pytest.mark.parametrize(
870 "short_name, value",
871 [(b"basicConstraints", b"CA:true"), (b"nsComment", b"foo bar")],
872 )
Alex Chanc6077062016-11-18 13:53:39 +0000873 def test_get_short_name(self, short_name, value):
Jean-Paul Calderonef8c5fab2008-12-31 15:53:48 -0500874 """
Alex Chanc6077062016-11-18 13:53:39 +0000875 `X509ExtensionType.get_short_name` returns a string giving the
Alex Gaynor31287502015-09-05 16:11:27 -0400876 short type name of the extension.
Jean-Paul Calderonef8c5fab2008-12-31 15:53:48 -0500877 """
Alex Chanc6077062016-11-18 13:53:39 +0000878 ext = X509Extension(short_name, True, value)
879 assert ext.get_short_name() == short_name
Jean-Paul Calderonef8c5fab2008-12-31 15:53:48 -0500880
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400881 def test_get_data(self):
882 """
Alex Chanc6077062016-11-18 13:53:39 +0000883 `X509Extension.get_data` returns a string giving the data of
Alex Gaynor31287502015-09-05 16:11:27 -0400884 the extension.
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400885 """
Alex Gaynor03737182020-07-23 20:40:46 -0400886 ext = X509Extension(b"basicConstraints", True, b"CA:true")
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400887 # Expect to get back the DER encoded form of CA:true.
Alex Gaynor03737182020-07-23 20:40:46 -0400888 assert ext.get_data() == b"0\x03\x01\x01\xff"
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400889
Alex Chanc6077062016-11-18 13:53:39 +0000890 def test_unused_subject(self, x509_data):
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400891 """
Alex Chanc6077062016-11-18 13:53:39 +0000892 The `subject` parameter to `X509Extension` may be provided for an
893 extension which does not use it and is ignored in this case.
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400894 """
Alex Chanc6077062016-11-18 13:53:39 +0000895 pkey, x509 = x509_data
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400896 ext1 = X509Extension(
Alex Gaynor03737182020-07-23 20:40:46 -0400897 b"basicConstraints", False, b"CA:TRUE", subject=x509
898 )
Alex Chanc6077062016-11-18 13:53:39 +0000899 x509.add_extensions([ext1])
Alex Gaynor03737182020-07-23 20:40:46 -0400900 x509.sign(pkey, "sha1")
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400901 # This is a little lame. Can we think of a better way?
Alex Chanc6077062016-11-18 13:53:39 +0000902 text = dump_certificate(FILETYPE_TEXT, x509)
Alex Gaynor03737182020-07-23 20:40:46 -0400903 assert b"X509v3 Basic Constraints:" in text
904 assert b"CA:TRUE" in text
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400905
Alex Chanc6077062016-11-18 13:53:39 +0000906 def test_subject(self, x509_data):
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400907 """
Alex Chanc6077062016-11-18 13:53:39 +0000908 If an extension requires a subject, the `subject` parameter to
909 `X509Extension` provides its value.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400910 """
Alex Chanc6077062016-11-18 13:53:39 +0000911 pkey, x509 = x509_data
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400912 ext3 = X509Extension(
Alex Gaynor03737182020-07-23 20:40:46 -0400913 b"subjectKeyIdentifier", False, b"hash", subject=x509
914 )
Alex Chanc6077062016-11-18 13:53:39 +0000915 x509.add_extensions([ext3])
Alex Gaynor03737182020-07-23 20:40:46 -0400916 x509.sign(pkey, "sha1")
Alex Chanc6077062016-11-18 13:53:39 +0000917 text = dump_certificate(FILETYPE_TEXT, x509)
Alex Gaynor03737182020-07-23 20:40:46 -0400918 assert b"X509v3 Subject Key Identifier:" in text
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400919
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400920 def test_missing_subject(self):
921 """
Alex Chanc6077062016-11-18 13:53:39 +0000922 If an extension requires a subject and the `subject` parameter
Alex Gaynor31287502015-09-05 16:11:27 -0400923 is given no value, something happens.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400924 """
Alex Chanc6077062016-11-18 13:53:39 +0000925 with pytest.raises(Error):
Alex Gaynor03737182020-07-23 20:40:46 -0400926 X509Extension(b"subjectKeyIdentifier", False, b"hash")
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400927
Alex Gaynor03737182020-07-23 20:40:46 -0400928 @pytest.mark.parametrize("bad_obj", [True, object(), "hello", []])
Alex Chanc6077062016-11-18 13:53:39 +0000929 def test_invalid_subject(self, bad_obj):
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400930 """
Alex Chanc6077062016-11-18 13:53:39 +0000931 If the `subject` parameter is given a value which is not an
932 `X509` instance, `TypeError` is raised.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400933 """
Alex Chanc6077062016-11-18 13:53:39 +0000934 with pytest.raises(TypeError):
935 X509Extension(
Alex Gaynor03737182020-07-23 20:40:46 -0400936 "basicConstraints", False, "CA:TRUE", subject=bad_obj
937 )
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400938
Alex Chanc6077062016-11-18 13:53:39 +0000939 def test_unused_issuer(self, x509_data):
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400940 """
Alex Chanc6077062016-11-18 13:53:39 +0000941 The `issuer` parameter to `X509Extension` may be provided for an
942 extension which does not use it and is ignored in this case.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400943 """
Alex Chanc6077062016-11-18 13:53:39 +0000944 pkey, x509 = x509_data
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400945 ext1 = X509Extension(
Alex Gaynor03737182020-07-23 20:40:46 -0400946 b"basicConstraints", False, b"CA:TRUE", issuer=x509
947 )
Alex Chanc6077062016-11-18 13:53:39 +0000948 x509.add_extensions([ext1])
Alex Gaynor03737182020-07-23 20:40:46 -0400949 x509.sign(pkey, "sha1")
Alex Chanc6077062016-11-18 13:53:39 +0000950 text = dump_certificate(FILETYPE_TEXT, x509)
Alex Gaynor03737182020-07-23 20:40:46 -0400951 assert b"X509v3 Basic Constraints:" in text
952 assert b"CA:TRUE" in text
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400953
Alex Chanc6077062016-11-18 13:53:39 +0000954 def test_issuer(self, x509_data):
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400955 """
Alex Chanc6077062016-11-18 13:53:39 +0000956 If an extension requires an issuer, the `issuer` parameter to
957 `X509Extension` provides its value.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400958 """
Alex Chanc6077062016-11-18 13:53:39 +0000959 pkey, x509 = x509_data
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400960 ext2 = X509Extension(
Alex Gaynor03737182020-07-23 20:40:46 -0400961 b"authorityKeyIdentifier", False, b"issuer:always", issuer=x509
962 )
Alex Chanc6077062016-11-18 13:53:39 +0000963 x509.add_extensions([ext2])
Alex Gaynor03737182020-07-23 20:40:46 -0400964 x509.sign(pkey, "sha1")
Alex Chanc6077062016-11-18 13:53:39 +0000965 text = dump_certificate(FILETYPE_TEXT, x509)
Alex Gaynor03737182020-07-23 20:40:46 -0400966 assert b"X509v3 Authority Key Identifier:" in text
967 assert b"DirName:/CN=Yoda root CA" in text
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400968
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400969 def test_missing_issuer(self):
970 """
Alex Chanc6077062016-11-18 13:53:39 +0000971 If an extension requires an issue and the `issuer` parameter is
972 given no value, something happens.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400973 """
Alex Chanc6077062016-11-18 13:53:39 +0000974 with pytest.raises(Error):
975 X509Extension(
Alex Gaynor03737182020-07-23 20:40:46 -0400976 b"authorityKeyIdentifier", False, b"keyid:always,issuer:always"
977 )
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400978
Alex Gaynor03737182020-07-23 20:40:46 -0400979 @pytest.mark.parametrize("bad_obj", [True, object(), "hello", []])
Alex Chanc6077062016-11-18 13:53:39 +0000980 def test_invalid_issuer(self, bad_obj):
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400981 """
Alex Chanc6077062016-11-18 13:53:39 +0000982 If the `issuer` parameter is given a value which is not an
983 `X509` instance, `TypeError` is raised.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400984 """
Alex Chanc6077062016-11-18 13:53:39 +0000985 with pytest.raises(TypeError):
986 X509Extension(
Alex Gaynor03737182020-07-23 20:40:46 -0400987 "basicConstraints",
988 False,
989 "keyid:always,issuer:always",
990 issuer=bad_obj,
991 )
Rick Dean47262da2009-07-08 16:17:17 -0500992
993
Paul Kehrer72d968b2016-07-29 15:31:04 +0800994class TestPKey(object):
995 """
Hynek Schlawack3bcf3152017-02-18 08:25:34 +0100996 Tests for `OpenSSL.crypto.PKey`.
Paul Kehrer72d968b2016-07-29 15:31:04 +0800997 """
998
999 def test_convert_from_cryptography_private_key(self):
1000 """
1001 PKey.from_cryptography_key creates a proper private PKey.
1002 """
1003 key = serialization.load_pem_private_key(
1004 intermediate_key_pem, None, backend
1005 )
1006 pkey = PKey.from_cryptography_key(key)
1007
1008 assert isinstance(pkey, PKey)
1009 assert pkey.bits() == key.key_size
1010 assert pkey._only_public is False
1011 assert pkey._initialized is True
1012
1013 def test_convert_from_cryptography_public_key(self):
1014 """
1015 PKey.from_cryptography_key creates a proper public PKey.
1016 """
1017 key = serialization.load_pem_public_key(cleartextPublicKeyPEM, backend)
1018 pkey = PKey.from_cryptography_key(key)
1019
1020 assert isinstance(pkey, PKey)
1021 assert pkey.bits() == key.key_size
1022 assert pkey._only_public is True
1023 assert pkey._initialized is True
1024
1025 def test_convert_from_cryptography_unsupported_type(self):
1026 """
1027 PKey.from_cryptography_key raises TypeError with an unsupported type.
1028 """
1029 key = serialization.load_pem_private_key(
1030 ec_private_key_pem, None, backend
1031 )
1032 with pytest.raises(TypeError):
1033 PKey.from_cryptography_key(key)
1034
1035 def test_convert_public_pkey_to_cryptography_key(self):
1036 """
1037 PKey.to_cryptography_key creates a proper cryptography public key.
1038 """
1039 pkey = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
1040 key = pkey.to_cryptography_key()
1041
1042 assert isinstance(key, rsa.RSAPublicKey)
1043 assert pkey.bits() == key.key_size
1044
1045 def test_convert_private_pkey_to_cryptography_key(self):
1046 """
1047 PKey.to_cryptography_key creates a proper cryptography private key.
1048 """
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05001049 pkey = load_privatekey(FILETYPE_PEM, root_key_pem)
Paul Kehrer72d968b2016-07-29 15:31:04 +08001050 key = pkey.to_cryptography_key()
1051
1052 assert isinstance(key, rsa.RSAPrivateKey)
1053 assert pkey.bits() == key.key_size
1054
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001055 def test_type(self):
1056 """
Alex Gaynor01f90a12019-02-07 09:14:48 -05001057 `PKey` can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001058 """
Alex Gaynor03737182020-07-23 20:40:46 -04001059 assert is_consistent_type(PKey, "PKey")
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001060
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001061 def test_construction(self):
1062 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001063 `PKey` takes no arguments and returns a new `PKey` instance.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001064 """
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001065 key = PKey()
Alex Chan9e2a9932017-01-25 14:29:19 +00001066 assert isinstance(key, PKey)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001067
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001068 def test_pregeneration(self):
1069 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001070 `PKey.bits` and `PKey.type` return `0` before the key is generated.
1071 `PKey.check` raises `TypeError` before the key is generated.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001072 """
1073 key = PKey()
Alex Chan9e2a9932017-01-25 14:29:19 +00001074 assert key.type() == 0
1075 assert key.bits() == 0
1076 with pytest.raises(TypeError):
1077 key.check()
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001078
Alex Chan9e2a9932017-01-25 14:29:19 +00001079 def test_failed_generation(self):
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001080 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001081 `PKey.generate_key` takes two arguments, the first giving the key type
1082 as one of `TYPE_RSA` or `TYPE_DSA` and the second giving the number of
1083 bits to generate. If an invalid type is specified or generation fails,
1084 `Error` is raised. If an invalid number of bits is specified,
1085 `ValueError` or `Error` is raised.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001086 """
1087 key = PKey()
Alex Chan9e2a9932017-01-25 14:29:19 +00001088 with pytest.raises(TypeError):
1089 key.generate_key("foo", "bar")
1090 with pytest.raises(Error):
1091 key.generate_key(-1, 0)
Jean-Paul Calderoneab82db72008-03-06 00:09:31 -05001092
Alex Chan9e2a9932017-01-25 14:29:19 +00001093 with pytest.raises(ValueError):
1094 key.generate_key(TYPE_RSA, -1)
1095 with pytest.raises(ValueError):
1096 key.generate_key(TYPE_RSA, 0)
Jean-Paul Calderoned71fe982008-03-06 00:31:50 -05001097
Alex Gaynor5bb2bd12016-07-03 10:48:32 -04001098 with pytest.raises(TypeError):
1099 key.generate_key(TYPE_RSA, object())
1100
Jean-Paul Calderoned71fe982008-03-06 00:31:50 -05001101 # XXX RSA generation for small values of bits is fairly buggy in a wide
1102 # range of OpenSSL versions. I need to figure out what the safe lower
1103 # bound for a reasonable number of OpenSSL versions is and explicitly
1104 # check for that in the wrapper. The failure behavior is typically an
1105 # infinite loop inside OpenSSL.
1106
Alex Chan9e2a9932017-01-25 14:29:19 +00001107 # with pytest.raises(Error):
1108 # key.generate_key(TYPE_RSA, 2)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001109
1110 # XXX DSA generation seems happy with any number of bits. The DSS
1111 # says bits must be between 512 and 1024 inclusive. OpenSSL's DSA
1112 # generator doesn't seem to care about the upper limit at all. For
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001113 # the lower limit, it uses 512 if anything smaller is specified.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001114 # So, it doesn't seem possible to make generate_key fail for
1115 # TYPE_DSA with a bits argument which is at least an int.
1116
Alex Chan9e2a9932017-01-25 14:29:19 +00001117 # with pytest.raises(Error):
1118 # key.generate_key(TYPE_DSA, -7)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001119
Alex Chan9e2a9932017-01-25 14:29:19 +00001120 def test_rsa_generation(self):
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001121 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001122 `PKey.generate_key` generates an RSA key when passed `TYPE_RSA` as a
1123 type and a reasonable number of bits.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001124 """
Alex Gaynor6e9f9762018-05-12 07:44:37 -04001125 bits = 512
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001126 key = PKey()
1127 key.generate_key(TYPE_RSA, bits)
Alex Chan9e2a9932017-01-25 14:29:19 +00001128 assert key.type() == TYPE_RSA
1129 assert key.bits() == bits
1130 assert key.check()
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001131
Alex Chan9e2a9932017-01-25 14:29:19 +00001132 def test_dsa_generation(self):
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001133 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001134 `PKey.generate_key` generates a DSA key when passed `TYPE_DSA` as a
1135 type and a reasonable number of bits.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001136 """
1137 # 512 is a magic number. The DSS (Digital Signature Standard)
1138 # allows a minimum of 512 bits for DSA. DSA_generate_parameters
1139 # will silently promote any value below 512 to 512.
1140 bits = 512
1141 key = PKey()
1142 key.generate_key(TYPE_DSA, bits)
Alex Chan9e2a9932017-01-25 14:29:19 +00001143 assert key.type() == TYPE_DSA
1144 assert key.bits() == bits
1145 with pytest.raises(TypeError):
1146 key.check()
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001147
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001148 def test_regeneration(self):
1149 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001150 `PKey.generate_key` can be called multiple times on the same key to
1151 generate new keys.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001152 """
1153 key = PKey()
1154 for type, bits in [(TYPE_RSA, 512), (TYPE_DSA, 576)]:
Alex Gaynor7f636492015-09-04 13:26:52 -04001155 key.generate_key(type, bits)
Alex Chan9e2a9932017-01-25 14:29:19 +00001156 assert key.type() == type
1157 assert key.bits() == bits
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001158
Alex Chan9e2a9932017-01-25 14:29:19 +00001159 def test_inconsistent_key(self):
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -04001160 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001161 `PKey.check` returns `Error` if the key is not consistent.
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -04001162 """
1163 key = load_privatekey(FILETYPE_PEM, inconsistentPrivateKeyPEM)
Alex Chan9e2a9932017-01-25 14:29:19 +00001164 with pytest.raises(Error):
1165 key.check()
Jean-Paul Calderonee81020e2011-06-12 21:48:57 -04001166
Jean-Paul Calderone02d01972011-10-31 10:39:29 -04001167 def test_check_public_key(self):
1168 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001169 `PKey.check` raises `TypeError` if only the public part of the key
1170 is available.
Jean-Paul Calderone02d01972011-10-31 10:39:29 -04001171 """
1172 # A trick to get a public-only key
1173 key = PKey()
1174 key.generate_key(TYPE_RSA, 512)
1175 cert = X509()
1176 cert.set_pubkey(key)
1177 pub = cert.get_pubkey()
Alex Chan9e2a9932017-01-25 14:29:19 +00001178 with pytest.raises(TypeError):
1179 pub.check()
Jean-Paul Calderone02d01972011-10-31 10:39:29 -04001180
Mrmaxmeier8cd3b172020-03-11 22:03:59 +01001181 def test_check_pr_897(self):
1182 """
1183 `PKey.check` raises `OpenSSL.crypto.Error` if provided with broken key
1184 """
1185 pkey = load_privatekey(FILETYPE_PEM, rsa_p_not_prime_pem)
1186 with pytest.raises(Error):
1187 pkey.check()
1188
Jean-Paul Calderone02d01972011-10-31 10:39:29 -04001189
Alex Chan9e2a9932017-01-25 14:29:19 +00001190def x509_name(**attrs):
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001191 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001192 Return a new X509Name with the given attributes.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001193 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001194 # XXX There's no other way to get a new X509Name yet.
1195 name = X509().get_subject()
1196 attrs = list(attrs.items())
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001197
Alex Chan9e2a9932017-01-25 14:29:19 +00001198 # Make the order stable - order matters!
1199 def key(attr):
1200 return attr[1]
Alex Gaynor03737182020-07-23 20:40:46 -04001201
Alex Chan9e2a9932017-01-25 14:29:19 +00001202 attrs.sort(key=key)
1203 for k, v in attrs:
1204 setattr(name, k, v)
1205 return name
Alex Gaynor85b49702015-09-05 16:30:59 -04001206
Alex Chan9e2a9932017-01-25 14:29:19 +00001207
1208class TestX509Name(object):
1209 """
1210 Unit tests for `OpenSSL.crypto.X509Name`.
1211 """
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001212
Rick Deane15b1472009-07-09 15:53:42 -05001213 def test_type(self):
1214 """
Alex Gaynor01f90a12019-02-07 09:14:48 -05001215 The type of X509Name objects is `X509Name`.
Rick Deane15b1472009-07-09 15:53:42 -05001216 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001217 name = x509_name()
Alex Gaynor01f90a12019-02-07 09:14:48 -05001218 assert isinstance(name, X509Name)
Rick Deane15b1472009-07-09 15:53:42 -05001219
Alex Chan9e2a9932017-01-25 14:29:19 +00001220 def test_only_string_attributes(self):
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -04001221 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001222 Attempting to set a non-`str` attribute name on an `X509Name` instance
1223 causes `TypeError` to be raised.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -04001224 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001225 name = x509_name()
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -04001226 # Beyond these cases, you may also think that unicode should be
Alex Gaynor31287502015-09-05 16:11:27 -04001227 # rejected. Sorry, you're wrong. unicode is automatically converted
1228 # to str outside of the control of X509Name, so there's no way to
1229 # reject it.
Jean-Paul Calderoneff363be2013-03-03 10:21:23 -08001230
Alex Gaynor31287502015-09-05 16:11:27 -04001231 # Also, this used to test str subclasses, but that test is less
1232 # relevant now that the implementation is in Python instead of C. Also
1233 # PyPy automatically converts str subclasses to str when they are
1234 # passed to setattr, so we can't test it on PyPy. Apparently CPython
1235 # does this sometimes as well.
Alex Chan9e2a9932017-01-25 14:29:19 +00001236 with pytest.raises(TypeError):
1237 setattr(name, None, "hello")
1238 with pytest.raises(TypeError):
1239 setattr(name, 30, "hello")
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -04001240
Alex Chan9e2a9932017-01-25 14:29:19 +00001241 def test_set_invalid_attribute(self):
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -04001242 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001243 Attempting to set any attribute name on an `X509Name` instance for
1244 which no corresponding NID is defined causes `AttributeError` to be
1245 raised.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -04001246 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001247 name = x509_name()
1248 with pytest.raises(AttributeError):
1249 setattr(name, "no such thing", None)
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -04001250
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001251 def test_attributes(self):
1252 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001253 `X509Name` instances have attributes for each standard (?)
1254 X509Name field.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001255 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001256 name = x509_name()
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001257 name.commonName = "foo"
Alex Gaynor37726112016-07-04 09:51:32 -04001258 assert name.commonName == "foo"
1259 assert name.CN == "foo"
1260
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001261 name.CN = "baz"
Alex Gaynor37726112016-07-04 09:51:32 -04001262 assert name.commonName == "baz"
1263 assert name.CN == "baz"
1264
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001265 name.commonName = "bar"
Alex Gaynor37726112016-07-04 09:51:32 -04001266 assert name.commonName == "bar"
1267 assert name.CN == "bar"
1268
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001269 name.CN = "quux"
Alex Gaynor37726112016-07-04 09:51:32 -04001270 assert name.commonName == "quux"
1271 assert name.CN == "quux"
1272
1273 assert name.OU is None
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001274
Alex Gaynor7778e792016-07-03 23:38:48 -04001275 with pytest.raises(AttributeError):
1276 name.foobar
1277
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001278 def test_copy(self):
1279 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001280 `X509Name` creates a new `X509Name` instance with all the same
1281 attributes as an existing `X509Name` instance when called with one.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001282 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001283 name = x509_name(commonName="foo", emailAddress="bar@example.com")
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001284
1285 copy = X509Name(name)
Alex Chan9e2a9932017-01-25 14:29:19 +00001286 assert copy.commonName == "foo"
1287 assert copy.emailAddress == "bar@example.com"
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001288
1289 # Mutate the copy and ensure the original is unmodified.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001290 copy.commonName = "baz"
Alex Chan9e2a9932017-01-25 14:29:19 +00001291 assert name.commonName == "foo"
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001292
1293 # Mutate the original and ensure the copy is unmodified.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001294 name.emailAddress = "quux@example.com"
Alex Chan9e2a9932017-01-25 14:29:19 +00001295 assert copy.emailAddress == "bar@example.com"
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001296
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001297 def test_repr(self):
1298 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001299 `repr` passed an `X509Name` instance should return a string containing
1300 a description of the type and the NIDs which have been set on it.
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001301 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001302 name = x509_name(commonName="foo", emailAddress="bar")
1303 assert repr(name) == "<X509Name object '/emailAddress=bar/CN=foo'>"
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001304
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001305 def test_comparison(self):
1306 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001307 `X509Name` instances should compare based on their NIDs.
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001308 """
Alex Gaynor03737182020-07-23 20:40:46 -04001309
Alex Chan9e2a9932017-01-25 14:29:19 +00001310 def _equality(a, b, assert_true, assert_false):
1311 assert_true(a == b)
1312 assert_false(a != b)
1313 assert_true(b == a)
1314 assert_false(b != a)
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001315
Alex Chan9e2a9932017-01-25 14:29:19 +00001316 def assert_true(x):
1317 assert x
1318
1319 def assert_false(x):
1320 assert not x
1321
1322 def assert_equal(a, b):
1323 _equality(a, b, assert_true, assert_false)
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001324
1325 # Instances compare equal to themselves.
Alex Chan9e2a9932017-01-25 14:29:19 +00001326 name = x509_name()
1327 assert_equal(name, name)
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001328
1329 # Empty instances should compare equal to each other.
Alex Chan9e2a9932017-01-25 14:29:19 +00001330 assert_equal(x509_name(), x509_name())
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001331
1332 # Instances with equal NIDs should compare equal to each other.
Alex Gaynor03737182020-07-23 20:40:46 -04001333 assert_equal(x509_name(commonName="foo"), x509_name(commonName="foo"))
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001334
1335 # Instance with equal NIDs set using different aliases should compare
1336 # equal to each other.
Alex Gaynor03737182020-07-23 20:40:46 -04001337 assert_equal(x509_name(commonName="foo"), x509_name(CN="foo"))
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001338
1339 # Instances with more than one NID with the same values should compare
1340 # equal to each other.
Alex Gaynor03737182020-07-23 20:40:46 -04001341 assert_equal(
1342 x509_name(CN="foo", organizationalUnitName="bar"),
1343 x509_name(commonName="foo", OU="bar"),
1344 )
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001345
Alex Chan9e2a9932017-01-25 14:29:19 +00001346 def assert_not_equal(a, b):
1347 _equality(a, b, assert_false, assert_true)
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001348
1349 # Instances with different values for the same NID should not compare
1350 # equal to each other.
Alex Gaynor03737182020-07-23 20:40:46 -04001351 assert_not_equal(x509_name(CN="foo"), x509_name(CN="bar"))
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001352
1353 # Instances with different NIDs should not compare equal to each other.
Alex Gaynor03737182020-07-23 20:40:46 -04001354 assert_not_equal(x509_name(CN="foo"), x509_name(OU="foo"))
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001355
Alex Chan9e2a9932017-01-25 14:29:19 +00001356 assert_not_equal(x509_name(), object())
Alex Gaynor7778e792016-07-03 23:38:48 -04001357
Alex Chan9e2a9932017-01-25 14:29:19 +00001358 def _inequality(a, b, assert_true, assert_false):
1359 assert_true(a < b)
1360 assert_true(a <= b)
1361 assert_true(b > a)
1362 assert_true(b >= a)
1363 assert_false(a > b)
1364 assert_false(a >= b)
1365 assert_false(b < a)
1366 assert_false(b <= a)
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001367
Alex Chan9e2a9932017-01-25 14:29:19 +00001368 def assert_less_than(a, b):
1369 _inequality(a, b, assert_true, assert_false)
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001370
1371 # An X509Name with a NID with a value which sorts less than the value
1372 # of the same NID on another X509Name compares less than the other
1373 # X509Name.
Alex Gaynor03737182020-07-23 20:40:46 -04001374 assert_less_than(x509_name(CN="abc"), x509_name(CN="def"))
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001375
Alex Chan9e2a9932017-01-25 14:29:19 +00001376 def assert_greater_than(a, b):
1377 _inequality(a, b, assert_false, assert_true)
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001378
1379 # An X509Name with a NID with a value which sorts greater than the
1380 # value of the same NID on another X509Name compares greater than the
1381 # other X509Name.
Alex Gaynor03737182020-07-23 20:40:46 -04001382 assert_greater_than(x509_name(CN="def"), x509_name(CN="abc"))
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001383
Jean-Paul Calderone110cd092008-03-24 17:27:42 -04001384 def test_hash(self):
1385 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001386 `X509Name.hash` returns an integer hash based on the value of the name.
Jean-Paul Calderone110cd092008-03-24 17:27:42 -04001387 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001388 a = x509_name(CN="foo")
1389 b = x509_name(CN="foo")
1390 assert a.hash() == b.hash()
Jean-Paul Calderone110cd092008-03-24 17:27:42 -04001391 a.CN = "bar"
Alex Chan9e2a9932017-01-25 14:29:19 +00001392 assert a.hash() != b.hash()
Jean-Paul Calderone110cd092008-03-24 17:27:42 -04001393
Jean-Paul Calderonee957a002008-03-25 15:16:51 -04001394 def test_der(self):
1395 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001396 `X509Name.der` returns the DER encoded form of the name.
Jean-Paul Calderonee957a002008-03-25 15:16:51 -04001397 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001398 a = x509_name(CN="foo", C="US")
Alex Gaynor03737182020-07-23 20:40:46 -04001399 assert (
1400 a.der() == b"0\x1b1\x0b0\t\x06\x03U\x04\x06\x13\x02US"
1401 b"1\x0c0\n\x06\x03U\x04\x03\x0c\x03foo"
1402 )
Jean-Paul Calderonee957a002008-03-25 15:16:51 -04001403
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001404 def test_get_components(self):
1405 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001406 `X509Name.get_components` returns a `list` of two-tuples of `str`
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001407 giving the NIDs and associated values which make up the name.
1408 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001409 a = x509_name()
1410 assert a.get_components() == []
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001411 a.CN = "foo"
Alex Chan9e2a9932017-01-25 14:29:19 +00001412 assert a.get_components() == [(b"CN", b"foo")]
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001413 a.organizationalUnitName = "bar"
Alex Chan9e2a9932017-01-25 14:29:19 +00001414 assert a.get_components() == [(b"CN", b"foo"), (b"OU", b"bar")]
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001415
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001416 def test_load_nul_byte_attribute(self):
1417 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001418 An `X509Name` from an `X509` instance loaded from a file can have a
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001419 NUL byte in the value of one of its attributes.
1420 """
1421 cert = load_certificate(FILETYPE_PEM, nulbyteSubjectAltNamePEM)
1422 subject = cert.get_subject()
Alex Chan9e2a9932017-01-25 14:29:19 +00001423 assert "null.python.org\x00example.org" == subject.commonName
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001424
Romuald Brunet4183beb2019-01-21 19:38:33 +01001425 def test_load_nul_byte_components(self):
1426 """
1427 An `X509Name` from an `X509` instance loaded from a file can have a
1428 NUL byte in the value of its components
1429 """
1430 cert = load_certificate(FILETYPE_PEM, nulbyteSubjectAltNamePEM)
1431 subject = cert.get_subject()
1432 components = subject.get_components()
Alex Gaynor03737182020-07-23 20:40:46 -04001433 ccn = [value for name, value in components if name == b"CN"]
1434 assert ccn[0] == b"null.python.org\x00example.org"
Romuald Brunet4183beb2019-01-21 19:38:33 +01001435
Alex Chan9e2a9932017-01-25 14:29:19 +00001436 def test_set_attribute_failure(self):
Jean-Paul Calderone5300d6a2013-12-29 16:36:50 -05001437 """
1438 If the value of an attribute cannot be set for some reason then
Alex Chan9e2a9932017-01-25 14:29:19 +00001439 `Error` is raised.
Jean-Paul Calderone5300d6a2013-12-29 16:36:50 -05001440 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001441 name = x509_name()
Jean-Paul Calderone5300d6a2013-12-29 16:36:50 -05001442 # This value is too long
Alex Chan9e2a9932017-01-25 14:29:19 +00001443 with pytest.raises(Error):
1444 setattr(name, "O", b"x" * 512)
Jean-Paul Calderone5300d6a2013-12-29 16:36:50 -05001445
1446
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001447class _PKeyInteractionTestsMixin:
1448 """
1449 Tests which involve another thing and a PKey.
1450 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001451
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001452 def signable(self):
1453 """
Alex Chanfb078d82017-04-20 11:16:15 +01001454 Return something with a `set_pubkey`, `set_pubkey`, and `sign` method.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001455 """
1456 raise NotImplementedError()
1457
Alex Chanb00ede22017-01-30 07:24:40 +00001458 def test_sign_with_ungenerated(self):
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001459 """
Alex Chanb00ede22017-01-30 07:24:40 +00001460 `X509Req.sign` raises `ValueError` when passed a `PKey` with no parts.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001461 """
1462 request = self.signable()
1463 key = PKey()
Alex Chanb00ede22017-01-30 07:24:40 +00001464 with pytest.raises(ValueError):
1465 request.sign(key, GOOD_DIGEST)
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001466
Alex Chanb00ede22017-01-30 07:24:40 +00001467 def test_sign_with_public_key(self):
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001468 """
Alex Chanb00ede22017-01-30 07:24:40 +00001469 `X509Req.sign` raises `ValueError` when passed a `PKey` with no private
1470 part as the signing key.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001471 """
1472 request = self.signable()
1473 key = PKey()
1474 key.generate_key(TYPE_RSA, 512)
1475 request.set_pubkey(key)
1476 pub = request.get_pubkey()
Alex Chanb00ede22017-01-30 07:24:40 +00001477 with pytest.raises(ValueError):
1478 request.sign(pub, GOOD_DIGEST)
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001479
Alex Chanb00ede22017-01-30 07:24:40 +00001480 def test_sign_with_unknown_digest(self):
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001481 """
Alex Chanb00ede22017-01-30 07:24:40 +00001482 `X509Req.sign` raises `ValueError` when passed a digest name which is
1483 not known.
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001484 """
1485 request = self.signable()
1486 key = PKey()
1487 key.generate_key(TYPE_RSA, 512)
Alex Chanb00ede22017-01-30 07:24:40 +00001488 with pytest.raises(ValueError):
1489 request.sign(key, BAD_DIGEST)
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001490
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001491 def test_sign(self):
1492 """
Alex Chanb00ede22017-01-30 07:24:40 +00001493 `X509Req.sign` succeeds when passed a private key object and a
1494 valid digest function. `X509Req.verify` can be used to check
Alex Gaynor31287502015-09-05 16:11:27 -04001495 the signature.
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001496 """
1497 request = self.signable()
1498 key = PKey()
1499 key.generate_key(TYPE_RSA, 512)
1500 request.set_pubkey(key)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001501 request.sign(key, GOOD_DIGEST)
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001502 # If the type has a verify method, cover that too.
Alex Gaynor03737182020-07-23 20:40:46 -04001503 if getattr(request, "verify", None) is not None:
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001504 pub = request.get_pubkey()
Alex Chanb00ede22017-01-30 07:24:40 +00001505 assert request.verify(pub)
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001506 # Make another key that won't verify.
1507 key = PKey()
1508 key.generate_key(TYPE_RSA, 512)
Alex Chanb00ede22017-01-30 07:24:40 +00001509 with pytest.raises(Error):
1510 request.verify(key)
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001511
1512
Alex Chanb00ede22017-01-30 07:24:40 +00001513class TestX509Req(_PKeyInteractionTestsMixin):
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001514 """
Alex Chanb00ede22017-01-30 07:24:40 +00001515 Tests for `OpenSSL.crypto.X509Req`.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001516 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001517
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001518 def signable(self):
1519 """
Alex Chanb00ede22017-01-30 07:24:40 +00001520 Create and return a new `X509Req`.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001521 """
1522 return X509Req()
1523
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001524 def test_type(self):
1525 """
Alex Gaynor01f90a12019-02-07 09:14:48 -05001526 `X509Req` can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001527 """
Alex Gaynor03737182020-07-23 20:40:46 -04001528 assert is_consistent_type(X509Req, "X509Req")
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001529
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001530 def test_construction(self):
1531 """
Alex Gaynor01f90a12019-02-07 09:14:48 -05001532 `X509Req` takes no arguments and returns an `X509Req` instance.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001533 """
1534 request = X509Req()
Alex Gaynor01f90a12019-02-07 09:14:48 -05001535 assert isinstance(request, X509Req)
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001536
Jean-Paul Calderone8dd19b82008-12-28 20:41:16 -05001537 def test_version(self):
1538 """
Alex Chanb00ede22017-01-30 07:24:40 +00001539 `X509Req.set_version` sets the X.509 version of the certificate
1540 request. `X509Req.get_version` returns the X.509 version of the
1541 certificate request. The initial value of the version is 0.
Jean-Paul Calderone8dd19b82008-12-28 20:41:16 -05001542 """
1543 request = X509Req()
Alex Chanb00ede22017-01-30 07:24:40 +00001544 assert request.get_version() == 0
Jean-Paul Calderone8dd19b82008-12-28 20:41:16 -05001545 request.set_version(1)
Alex Chanb00ede22017-01-30 07:24:40 +00001546 assert request.get_version() == 1
Jean-Paul Calderone8dd19b82008-12-28 20:41:16 -05001547 request.set_version(3)
Alex Chanb00ede22017-01-30 07:24:40 +00001548 assert request.get_version() == 3
Jean-Paul Calderone8dd19b82008-12-28 20:41:16 -05001549
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001550 def test_version_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001551 """
Alex Chanb00ede22017-01-30 07:24:40 +00001552 `X509Req.set_version` raises `TypeError` if called with a non-`int`
1553 argument.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001554 """
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001555 request = X509Req()
Alex Chanb00ede22017-01-30 07:24:40 +00001556 with pytest.raises(TypeError):
1557 request.set_version("foo")
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001558
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001559 def test_get_subject(self):
1560 """
Alex Chanb00ede22017-01-30 07:24:40 +00001561 `X509Req.get_subject` returns an `X509Name` for the subject of the
1562 request and which is valid even after the request object is
1563 otherwise dead.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001564 """
1565 request = X509Req()
1566 subject = request.get_subject()
Alex Gaynor01f90a12019-02-07 09:14:48 -05001567 assert isinstance(subject, X509Name)
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001568 subject.commonName = "foo"
Alex Chanb00ede22017-01-30 07:24:40 +00001569 assert request.get_subject().commonName == "foo"
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001570 del request
1571 subject.commonName = "bar"
Alex Chanb00ede22017-01-30 07:24:40 +00001572 assert subject.commonName == "bar"
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001573
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001574 def test_add_extensions(self):
1575 """
Alex Chanb00ede22017-01-30 07:24:40 +00001576 `X509Req.add_extensions` accepts a `list` of `X509Extension` instances
1577 and adds them to the X509 request.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001578 """
1579 request = X509Req()
Alex Gaynor03737182020-07-23 20:40:46 -04001580 request.add_extensions(
1581 [X509Extension(b"basicConstraints", True, b"CA:false")]
1582 )
Stephen Holsappleca545b72014-01-28 21:43:25 -08001583 exts = request.get_extensions()
Alex Chanb00ede22017-01-30 07:24:40 +00001584 assert len(exts) == 1
Alex Gaynor03737182020-07-23 20:40:46 -04001585 assert exts[0].get_short_name() == b"basicConstraints"
Alex Chanb00ede22017-01-30 07:24:40 +00001586 assert exts[0].get_critical() == 1
Alex Gaynor03737182020-07-23 20:40:46 -04001587 assert exts[0].get_data() == b"0\x00"
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001588
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001589 def test_get_extensions(self):
1590 """
Alex Chanb00ede22017-01-30 07:24:40 +00001591 `X509Req.get_extensions` returns a `list` of extensions added to this
1592 X509 request.
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001593 """
1594 request = X509Req()
1595 exts = request.get_extensions()
Alex Chanb00ede22017-01-30 07:24:40 +00001596 assert exts == []
Alex Gaynor03737182020-07-23 20:40:46 -04001597 request.add_extensions(
1598 [
1599 X509Extension(b"basicConstraints", True, b"CA:true"),
1600 X509Extension(b"keyUsage", False, b"digitalSignature"),
1601 ]
1602 )
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001603 exts = request.get_extensions()
Alex Chanb00ede22017-01-30 07:24:40 +00001604 assert len(exts) == 2
Alex Gaynor03737182020-07-23 20:40:46 -04001605 assert exts[0].get_short_name() == b"basicConstraints"
Alex Chanb00ede22017-01-30 07:24:40 +00001606 assert exts[0].get_critical() == 1
Alex Gaynor03737182020-07-23 20:40:46 -04001607 assert exts[0].get_data() == b"0\x03\x01\x01\xff"
1608 assert exts[1].get_short_name() == b"keyUsage"
Alex Chanb00ede22017-01-30 07:24:40 +00001609 assert exts[1].get_critical() == 0
Alex Gaynor03737182020-07-23 20:40:46 -04001610 assert exts[1].get_data() == b"\x03\x02\x07\x80"
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001611
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001612 def test_add_extensions_wrong_args(self):
1613 """
Alex Chanb00ede22017-01-30 07:24:40 +00001614 `X509Req.add_extensions` raises `TypeError` if called with a
1615 non-`list`. Or it raises `ValueError` if called with a `list`
1616 containing objects other than `X509Extension` instances.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001617 """
1618 request = X509Req()
Alex Chanb00ede22017-01-30 07:24:40 +00001619 with pytest.raises(TypeError):
1620 request.add_extensions(object())
1621 with pytest.raises(ValueError):
1622 request.add_extensions([object()])
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001623
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001624 def test_verify_wrong_args(self):
1625 """
Alex Chanb00ede22017-01-30 07:24:40 +00001626 `X509Req.verify` raises `TypeError` if passed anything other than a
1627 `PKey` instance as its single argument.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001628 """
1629 request = X509Req()
Alex Chanb00ede22017-01-30 07:24:40 +00001630 with pytest.raises(TypeError):
1631 request.verify(object())
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001632
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001633 def test_verify_uninitialized_key(self):
1634 """
Alex Chanb00ede22017-01-30 07:24:40 +00001635 `X509Req.verify` raises `OpenSSL.crypto.Error` if called with a
1636 `OpenSSL.crypto.PKey` which contains no key data.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001637 """
1638 request = X509Req()
1639 pkey = PKey()
Alex Chanb00ede22017-01-30 07:24:40 +00001640 with pytest.raises(Error):
1641 request.verify(pkey)
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001642
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001643 def test_verify_wrong_key(self):
1644 """
Alex Chanb00ede22017-01-30 07:24:40 +00001645 `X509Req.verify` raises `OpenSSL.crypto.Error` if called with a
1646 `OpenSSL.crypto.PKey` which does not represent the public part of the
Alex Gaynor31287502015-09-05 16:11:27 -04001647 key which signed the request.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001648 """
1649 request = X509Req()
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05001650 pkey = load_privatekey(FILETYPE_PEM, root_key_pem)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001651 request.sign(pkey, GOOD_DIGEST)
Alex Chanb00ede22017-01-30 07:24:40 +00001652 another_pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
1653 with pytest.raises(Error):
1654 request.verify(another_pkey)
1655
1656 def test_verify_success(self):
1657 """
1658 `X509Req.verify` returns `True` if called with a `OpenSSL.crypto.PKey`
1659 which represents the public part of the key which signed the request.
1660 """
1661 request = X509Req()
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05001662 pkey = load_privatekey(FILETYPE_PEM, root_key_pem)
Alex Chanb00ede22017-01-30 07:24:40 +00001663 request.sign(pkey, GOOD_DIGEST)
1664 assert request.verify(pkey)
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001665
Paul Kehrer41c10242017-06-29 18:24:17 -05001666 def test_convert_from_cryptography(self):
1667 crypto_req = x509.load_pem_x509_csr(
1668 cleartextCertificateRequestPEM, backend
1669 )
1670 req = X509Req.from_cryptography(crypto_req)
1671 assert isinstance(req, X509Req)
1672
1673 def test_convert_from_cryptography_unsupported_type(self):
1674 with pytest.raises(TypeError):
1675 X509Req.from_cryptography(object())
1676
1677 def test_convert_to_cryptography_key(self):
1678 req = load_certificate_request(
1679 FILETYPE_PEM, cleartextCertificateRequestPEM
1680 )
1681 crypto_req = req.to_cryptography()
1682 assert isinstance(crypto_req, x509.CertificateSigningRequest)
1683
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001684
Alex Chanb00ede22017-01-30 07:24:40 +00001685class TestX509(_PKeyInteractionTestsMixin):
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001686 """
Alex Chanb00ede22017-01-30 07:24:40 +00001687 Tests for `OpenSSL.crypto.X509`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001688 """
Alex Gaynor03737182020-07-23 20:40:46 -04001689
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05001690 pemData = root_cert_pem + root_key_pem
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001691
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001692 def signable(self):
1693 """
Alex Chanb00ede22017-01-30 07:24:40 +00001694 Create and return a new `X509`.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001695 """
1696 return X509()
1697
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001698 def test_type(self):
1699 """
Alex Gaynor01f90a12019-02-07 09:14:48 -05001700 `X509` can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001701 """
Alex Gaynor03737182020-07-23 20:40:46 -04001702 assert is_consistent_type(X509, "X509")
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001703
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001704 def test_construction(self):
1705 """
Alex Gaynor01f90a12019-02-07 09:14:48 -05001706 `X509` takes no arguments and returns an instance of `X509`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001707 """
1708 certificate = X509()
Alex Gaynor01f90a12019-02-07 09:14:48 -05001709 assert isinstance(certificate, X509)
Alex Gaynor03737182020-07-23 20:40:46 -04001710 assert type(certificate).__name__ == "X509"
Alex Chanb00ede22017-01-30 07:24:40 +00001711 assert type(certificate) == X509
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001712
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001713 def test_set_version_wrong_args(self):
1714 """
Alex Chanb00ede22017-01-30 07:24:40 +00001715 `X509.set_version` raises `TypeError` if invoked with an argument
1716 not of type `int`.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001717 """
1718 cert = X509()
Alex Chanb00ede22017-01-30 07:24:40 +00001719 with pytest.raises(TypeError):
1720 cert.set_version(None)
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001721
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001722 def test_version(self):
1723 """
Alex Chanb00ede22017-01-30 07:24:40 +00001724 `X509.set_version` sets the certificate version number.
1725 `X509.get_version` retrieves it.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001726 """
1727 cert = X509()
1728 cert.set_version(1234)
Alex Chanb00ede22017-01-30 07:24:40 +00001729 assert cert.get_version() == 1234
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001730
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001731 def test_serial_number(self):
1732 """
Alex Chanb00ede22017-01-30 07:24:40 +00001733 The serial number of an `X509` can be retrieved and
1734 modified with `X509.get_serial_number` and
1735 `X509.set_serial_number`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001736 """
1737 certificate = X509()
Alex Chanb00ede22017-01-30 07:24:40 +00001738 with pytest.raises(TypeError):
1739 certificate.set_serial_number("1")
1740 assert certificate.get_serial_number() == 0
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001741 certificate.set_serial_number(1)
Alex Chanb00ede22017-01-30 07:24:40 +00001742 assert certificate.get_serial_number() == 1
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001743 certificate.set_serial_number(2 ** 32 + 1)
Alex Chanb00ede22017-01-30 07:24:40 +00001744 assert certificate.get_serial_number() == 2 ** 32 + 1
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001745 certificate.set_serial_number(2 ** 64 + 1)
Alex Chanb00ede22017-01-30 07:24:40 +00001746 assert certificate.get_serial_number() == 2 ** 64 + 1
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001747 certificate.set_serial_number(2 ** 128 + 1)
Alex Chanb00ede22017-01-30 07:24:40 +00001748 assert certificate.get_serial_number() == 2 ** 128 + 1
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001749
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001750 def _setBoundTest(self, which):
1751 """
Alex Chanb00ede22017-01-30 07:24:40 +00001752 `X509.set_notBefore` takes a string in the format of an
Alex Gaynor31287502015-09-05 16:11:27 -04001753 ASN1 GENERALIZEDTIME and sets the beginning of the certificate's
1754 validity period to it.
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001755 """
1756 certificate = X509()
Alex Gaynor03737182020-07-23 20:40:46 -04001757 set = getattr(certificate, "set_not" + which)
1758 get = getattr(certificate, "get_not" + which)
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001759
Jean-Paul Calderonee0615b52008-03-09 21:44:46 -04001760 # Starts with no value.
Alex Chanb00ede22017-01-30 07:24:40 +00001761 assert get() is None
Jean-Paul Calderonee0615b52008-03-09 21:44:46 -04001762
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001763 # GMT (Or is it UTC?) -exarkun
Alex Gaynore7f51982016-09-11 11:48:14 -04001764 when = b"20040203040506Z"
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001765 set(when)
Alex Chanb00ede22017-01-30 07:24:40 +00001766 assert get() == when
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001767
1768 # A plus two hours and thirty minutes offset
Alex Gaynore7f51982016-09-11 11:48:14 -04001769 when = b"20040203040506+0530"
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001770 set(when)
Alex Chanb00ede22017-01-30 07:24:40 +00001771 assert get() == when
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001772
1773 # A minus one hour fifteen minutes offset
Alex Gaynore7f51982016-09-11 11:48:14 -04001774 when = b"20040203040506-0115"
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001775 set(when)
Alex Chanb00ede22017-01-30 07:24:40 +00001776 assert get() == when
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001777
1778 # An invalid string results in a ValueError
Alex Chanb00ede22017-01-30 07:24:40 +00001779 with pytest.raises(ValueError):
1780 set(b"foo bar")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001781
Jean-Paul Calderone31ca2002010-01-30 15:14:43 -05001782 # The wrong number of arguments results in a TypeError.
Alex Chanb00ede22017-01-30 07:24:40 +00001783 with pytest.raises(TypeError):
1784 set()
Alex Gaynor85b49702015-09-05 16:30:59 -04001785 with pytest.raises(TypeError):
1786 set(b"20040203040506Z", b"20040203040506Z")
Alex Chanb00ede22017-01-30 07:24:40 +00001787 with pytest.raises(TypeError):
1788 get(b"foo bar")
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001789
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001790 # XXX ASN1_TIME (not GENERALIZEDTIME)
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001791
1792 def test_set_notBefore(self):
1793 """
Alex Chanb00ede22017-01-30 07:24:40 +00001794 `X509.set_notBefore` takes a string in the format of an
Alex Gaynor31287502015-09-05 16:11:27 -04001795 ASN1 GENERALIZEDTIME and sets the beginning of the certificate's
1796 validity period to it.
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001797 """
1798 self._setBoundTest("Before")
1799
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001800 def test_set_notAfter(self):
1801 """
Alex Chanb00ede22017-01-30 07:24:40 +00001802 `X509.set_notAfter` takes a string in the format of an ASN1
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001803 GENERALIZEDTIME and sets the end of the certificate's validity period
1804 to it.
1805 """
1806 self._setBoundTest("After")
Jean-Paul Calderone76576d52008-03-24 16:04:46 -04001807
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001808 def test_get_notBefore(self):
1809 """
Alex Chanb00ede22017-01-30 07:24:40 +00001810 `X509.get_notBefore` returns a string in the format of an
Alex Gaynor31287502015-09-05 16:11:27 -04001811 ASN1 GENERALIZEDTIME even for certificates which store it as UTCTIME
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001812 internally.
1813 """
Paul Kehrera40898b2017-06-11 16:30:58 -10001814 cert = load_certificate(FILETYPE_PEM, old_root_cert_pem)
Alex Chanb00ede22017-01-30 07:24:40 +00001815 assert cert.get_notBefore() == b"20090325123658Z"
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001816
Rick Dean38a05c82009-07-18 01:41:30 -05001817 def test_get_notAfter(self):
1818 """
Alex Chanb00ede22017-01-30 07:24:40 +00001819 `X509.get_notAfter` returns a string in the format of an
Alex Gaynor31287502015-09-05 16:11:27 -04001820 ASN1 GENERALIZEDTIME even for certificates which store it as UTCTIME
Rick Dean38a05c82009-07-18 01:41:30 -05001821 internally.
1822 """
Paul Kehrera40898b2017-06-11 16:30:58 -10001823 cert = load_certificate(FILETYPE_PEM, old_root_cert_pem)
Alex Chanb00ede22017-01-30 07:24:40 +00001824 assert cert.get_notAfter() == b"20170611123658Z"
Rick Dean38a05c82009-07-18 01:41:30 -05001825
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001826 def test_gmtime_adj_notBefore_wrong_args(self):
1827 """
Alex Chanb00ede22017-01-30 07:24:40 +00001828 `X509.gmtime_adj_notBefore` raises `TypeError` if called with a
1829 non-`int` argument.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001830 """
1831 cert = X509()
Alex Chanb00ede22017-01-30 07:24:40 +00001832 with pytest.raises(TypeError):
1833 cert.gmtime_adj_notBefore(None)
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001834
Alex Gaynor7f5610c2017-07-07 00:09:34 -04001835 @flaky.flaky
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001836 def test_gmtime_adj_notBefore(self):
1837 """
Alex Chanb00ede22017-01-30 07:24:40 +00001838 `X509.gmtime_adj_notBefore` changes the not-before timestamp to be the
1839 current time plus the number of seconds passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001840 """
1841 cert = load_certificate(FILETYPE_PEM, self.pemData)
Alex Gaynor03737182020-07-23 20:40:46 -04001842 not_before_min = datetime.utcnow().replace(microsecond=0) + timedelta(
1843 seconds=100
Alex Gaynor85b49702015-09-05 16:30:59 -04001844 )
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001845 cert.gmtime_adj_notBefore(100)
Alex Gaynor85b49702015-09-05 16:30:59 -04001846 not_before = datetime.strptime(
1847 cert.get_notBefore().decode(), "%Y%m%d%H%M%SZ"
1848 )
Alex Gaynor7f5610c2017-07-07 00:09:34 -04001849 not_before_max = datetime.utcnow() + timedelta(seconds=100)
Alex Chanb00ede22017-01-30 07:24:40 +00001850 assert not_before_min <= not_before <= not_before_max
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001851
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001852 def test_gmtime_adj_notAfter_wrong_args(self):
1853 """
Alex Chanb00ede22017-01-30 07:24:40 +00001854 `X509.gmtime_adj_notAfter` raises `TypeError` if called with a
1855 non-`int` argument.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001856 """
1857 cert = X509()
Alex Chanb00ede22017-01-30 07:24:40 +00001858 with pytest.raises(TypeError):
1859 cert.gmtime_adj_notAfter(None)
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001860
Alex Gaynor642de6f2017-07-24 00:57:38 -04001861 @flaky.flaky
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001862 def test_gmtime_adj_notAfter(self):
1863 """
Alex Chanb00ede22017-01-30 07:24:40 +00001864 `X509.gmtime_adj_notAfter` changes the not-after timestamp
Alex Gaynor31287502015-09-05 16:11:27 -04001865 to be the current time plus the number of seconds passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001866 """
1867 cert = load_certificate(FILETYPE_PEM, self.pemData)
Alex Gaynor03737182020-07-23 20:40:46 -04001868 not_after_min = datetime.utcnow().replace(microsecond=0) + timedelta(
1869 seconds=100
Alex Gaynor85b49702015-09-05 16:30:59 -04001870 )
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001871 cert.gmtime_adj_notAfter(100)
Alex Gaynor85b49702015-09-05 16:30:59 -04001872 not_after = datetime.strptime(
1873 cert.get_notAfter().decode(), "%Y%m%d%H%M%SZ"
1874 )
Maximilian Hilsbed25c92015-07-25 12:58:07 +02001875 not_after_max = datetime.utcnow() + timedelta(seconds=100)
Alex Chanb00ede22017-01-30 07:24:40 +00001876 assert not_after_min <= not_after <= not_after_max
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001877
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001878 def test_has_expired(self):
1879 """
Alex Chanb00ede22017-01-30 07:24:40 +00001880 `X509.has_expired` returns `True` if the certificate's not-after time
1881 is in the past.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001882 """
1883 cert = X509()
1884 cert.gmtime_adj_notAfter(-1)
Alex Chanb00ede22017-01-30 07:24:40 +00001885 assert cert.has_expired()
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001886
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001887 def test_has_not_expired(self):
1888 """
Alex Chanb00ede22017-01-30 07:24:40 +00001889 `X509.has_expired` returns `False` if the certificate's not-after time
1890 is in the future.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001891 """
1892 cert = X509()
1893 cert.gmtime_adj_notAfter(2)
Alex Chanb00ede22017-01-30 07:24:40 +00001894 assert not cert.has_expired()
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001895
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001896 def test_root_has_not_expired(self):
1897 """
Alex Chanb00ede22017-01-30 07:24:40 +00001898 `X509.has_expired` returns `False` if the certificate's not-after time
1899 is in the future.
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001900 """
1901 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Alex Chanb00ede22017-01-30 07:24:40 +00001902 assert not cert.has_expired()
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001903
Rick Dean38a05c82009-07-18 01:41:30 -05001904 def test_digest(self):
1905 """
Alex Chanb00ede22017-01-30 07:24:40 +00001906 `X509.digest` returns a string giving ":"-separated hex-encoded
Alex Gaynor31287502015-09-05 16:11:27 -04001907 words of the digest of the certificate.
Rick Dean38a05c82009-07-18 01:41:30 -05001908 """
Paul Kehrera40898b2017-06-11 16:30:58 -10001909 cert = load_certificate(FILETYPE_PEM, old_root_cert_pem)
Alex Chanb00ede22017-01-30 07:24:40 +00001910 assert (
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001911 # This is MD5 instead of GOOD_DIGEST because the digest algorithm
1912 # actually matters to the assertion (ie, another arbitrary, good
1913 # digest will not product the same digest).
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001914 # Digest verified with the command:
1915 # openssl x509 -in root_cert.pem -noout -fingerprint -md5
Alex Gaynor03737182020-07-23 20:40:46 -04001916 cert.digest("MD5")
1917 == b"19:B3:05:26:2B:F8:F2:FF:0B:8F:21:07:A8:28:B8:75"
1918 )
Rick Dean38a05c82009-07-18 01:41:30 -05001919
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001920 def _extcert(self, pkey, extensions):
1921 cert = X509()
David Benjamin6b799472020-06-24 17:14:16 -04001922 # Certificates with extensions must be X.509v3, which is encoded with a
1923 # version of two.
1924 cert.set_version(2)
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001925 cert.set_pubkey(pkey)
1926 cert.get_subject().commonName = "Unit Tests"
1927 cert.get_issuer().commonName = "Unit Tests"
Alex Gaynore7f51982016-09-11 11:48:14 -04001928 when = datetime.now().strftime("%Y%m%d%H%M%SZ").encode("ascii")
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001929 cert.set_notBefore(when)
1930 cert.set_notAfter(when)
1931
1932 cert.add_extensions(extensions)
Alex Gaynor03737182020-07-23 20:40:46 -04001933 cert.sign(pkey, "sha1")
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001934 return load_certificate(
Alex Gaynor03737182020-07-23 20:40:46 -04001935 FILETYPE_PEM, dump_certificate(FILETYPE_PEM, cert)
1936 )
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001937
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001938 def test_extension_count(self):
1939 """
Alex Chanb00ede22017-01-30 07:24:40 +00001940 `X509.get_extension_count` returns the number of extensions
Alex Gaynor31287502015-09-05 16:11:27 -04001941 that are present in the certificate.
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001942 """
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001943 pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
Alex Gaynor03737182020-07-23 20:40:46 -04001944 ca = X509Extension(b"basicConstraints", True, b"CA:FALSE")
1945 key = X509Extension(b"keyUsage", True, b"digitalSignature")
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001946 subjectAltName = X509Extension(
Alex Gaynor03737182020-07-23 20:40:46 -04001947 b"subjectAltName", True, b"DNS:example.com"
1948 )
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001949
1950 # Try a certificate with no extensions at all.
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001951 c = self._extcert(pkey, [])
Alex Chanb00ede22017-01-30 07:24:40 +00001952 assert c.get_extension_count() == 0
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001953
1954 # And a certificate with one
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001955 c = self._extcert(pkey, [ca])
Alex Chanb00ede22017-01-30 07:24:40 +00001956 assert c.get_extension_count() == 1
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001957
1958 # And a certificate with several
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001959 c = self._extcert(pkey, [ca, key, subjectAltName])
Alex Chanb00ede22017-01-30 07:24:40 +00001960 assert c.get_extension_count() == 3
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001961
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001962 def test_get_extension(self):
1963 """
Alex Chanb00ede22017-01-30 07:24:40 +00001964 `X509.get_extension` takes an integer and returns an
1965 `X509Extension` corresponding to the extension at that index.
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001966 """
1967 pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
Alex Gaynor03737182020-07-23 20:40:46 -04001968 ca = X509Extension(b"basicConstraints", True, b"CA:FALSE")
1969 key = X509Extension(b"keyUsage", True, b"digitalSignature")
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001970 subjectAltName = X509Extension(
Alex Gaynor03737182020-07-23 20:40:46 -04001971 b"subjectAltName", False, b"DNS:example.com"
1972 )
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001973
1974 cert = self._extcert(pkey, [ca, key, subjectAltName])
1975
1976 ext = cert.get_extension(0)
Alex Chanb00ede22017-01-30 07:24:40 +00001977 assert isinstance(ext, X509Extension)
1978 assert ext.get_critical()
Alex Gaynor03737182020-07-23 20:40:46 -04001979 assert ext.get_short_name() == b"basicConstraints"
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001980
1981 ext = cert.get_extension(1)
Alex Chanb00ede22017-01-30 07:24:40 +00001982 assert isinstance(ext, X509Extension)
1983 assert ext.get_critical()
Alex Gaynor03737182020-07-23 20:40:46 -04001984 assert ext.get_short_name() == b"keyUsage"
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001985
1986 ext = cert.get_extension(2)
Alex Chanb00ede22017-01-30 07:24:40 +00001987 assert isinstance(ext, X509Extension)
1988 assert not ext.get_critical()
Alex Gaynor03737182020-07-23 20:40:46 -04001989 assert ext.get_short_name() == b"subjectAltName"
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001990
Alex Chanb00ede22017-01-30 07:24:40 +00001991 with pytest.raises(IndexError):
1992 cert.get_extension(-1)
1993 with pytest.raises(IndexError):
1994 cert.get_extension(4)
1995 with pytest.raises(TypeError):
1996 cert.get_extension("hello")
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001997
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001998 def test_nullbyte_subjectAltName(self):
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001999 """
Jean-Paul Calderone9af07b02013-08-23 16:07:31 -04002000 The fields of a `subjectAltName` extension on an X509 may contain NUL
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04002001 bytes and this value is reflected in the string representation of the
2002 extension object.
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04002003 """
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04002004 cert = load_certificate(FILETYPE_PEM, nulbyteSubjectAltNamePEM)
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04002005
2006 ext = cert.get_extension(3)
Alex Gaynor03737182020-07-23 20:40:46 -04002007 assert ext.get_short_name() == b"subjectAltName"
Alex Chanb00ede22017-01-30 07:24:40 +00002008 assert (
Alex Gaynore7f51982016-09-11 11:48:14 -04002009 b"DNS:altnull.python.org\x00example.com, "
2010 b"email:null@python.org\x00user@example.org, "
2011 b"URI:http://null.python.org\x00http://example.org, "
Alex Gaynor03737182020-07-23 20:40:46 -04002012 b"IP Address:192.0.2.1, IP Address:2001:DB8:0:0:0:0:0:1\n"
2013 == str(ext).encode("ascii")
2014 )
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04002015
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002016 def test_invalid_digest_algorithm(self):
2017 """
Alex Chanb00ede22017-01-30 07:24:40 +00002018 `X509.digest` raises `ValueError` if called with an unrecognized hash
2019 algorithm.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002020 """
2021 cert = X509()
Alex Chanb00ede22017-01-30 07:24:40 +00002022 with pytest.raises(ValueError):
2023 cert.digest(BAD_DIGEST)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002024
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002025 def test_get_subject(self):
2026 """
Alex Chanb00ede22017-01-30 07:24:40 +00002027 `X509.get_subject` returns an `X509Name` instance.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002028 """
2029 cert = load_certificate(FILETYPE_PEM, self.pemData)
2030 subj = cert.get_subject()
Alex Chanb00ede22017-01-30 07:24:40 +00002031 assert isinstance(subj, X509Name)
Alex Gaynor03737182020-07-23 20:40:46 -04002032 assert subj.get_components() == [
2033 (b"C", b"US"),
2034 (b"ST", b"IL"),
2035 (b"L", b"Chicago"),
2036 (b"O", b"Testing"),
2037 (b"CN", b"Testing Root CA"),
2038 ]
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002039
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002040 def test_set_subject_wrong_args(self):
2041 """
Alex Chanb00ede22017-01-30 07:24:40 +00002042 `X509.set_subject` raises a `TypeError` if called with an argument not
2043 of type `X509Name`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002044 """
2045 cert = X509()
Alex Gaynor85b49702015-09-05 16:30:59 -04002046 with pytest.raises(TypeError):
Alex Chanb00ede22017-01-30 07:24:40 +00002047 cert.set_subject(None)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002048
2049 def test_set_subject(self):
2050 """
Alex Chanb00ede22017-01-30 07:24:40 +00002051 `X509.set_subject` changes the subject of the certificate to the one
2052 passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002053 """
2054 cert = X509()
2055 name = cert.get_subject()
Alex Gaynor03737182020-07-23 20:40:46 -04002056 name.C = "AU"
2057 name.OU = "Unit Tests"
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002058 cert.set_subject(name)
Alex Gaynor03737182020-07-23 20:40:46 -04002059 assert cert.get_subject().get_components() == [
2060 (b"C", b"AU"),
2061 (b"OU", b"Unit Tests"),
2062 ]
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002063
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002064 def test_get_issuer(self):
2065 """
Alex Chanb00ede22017-01-30 07:24:40 +00002066 `X509.get_issuer` returns an `X509Name` instance.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002067 """
2068 cert = load_certificate(FILETYPE_PEM, self.pemData)
2069 subj = cert.get_issuer()
Alex Chanb00ede22017-01-30 07:24:40 +00002070 assert isinstance(subj, X509Name)
Jean-Paul Calderone30a4cb32010-08-11 23:54:12 -04002071 comp = subj.get_components()
Alex Gaynor03737182020-07-23 20:40:46 -04002072 assert comp == [
2073 (b"C", b"US"),
2074 (b"ST", b"IL"),
2075 (b"L", b"Chicago"),
2076 (b"O", b"Testing"),
2077 (b"CN", b"Testing Root CA"),
2078 ]
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002079
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002080 def test_set_issuer_wrong_args(self):
2081 """
Alex Chanb00ede22017-01-30 07:24:40 +00002082 `X509.set_issuer` raises a `TypeError` if called with an argument not
2083 of type `X509Name`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002084 """
2085 cert = X509()
Alex Chanb00ede22017-01-30 07:24:40 +00002086 with pytest.raises(TypeError):
2087 cert.set_issuer(None)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002088
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002089 def test_set_issuer(self):
2090 """
Alex Chanb00ede22017-01-30 07:24:40 +00002091 `X509.set_issuer` changes the issuer of the certificate to the
Alex Gaynor31287502015-09-05 16:11:27 -04002092 one passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002093 """
2094 cert = X509()
2095 name = cert.get_issuer()
Alex Gaynor03737182020-07-23 20:40:46 -04002096 name.C = "AU"
2097 name.OU = "Unit Tests"
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002098 cert.set_issuer(name)
Alex Gaynor03737182020-07-23 20:40:46 -04002099 assert cert.get_issuer().get_components() == [
2100 (b"C", b"AU"),
2101 (b"OU", b"Unit Tests"),
2102 ]
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002103
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002104 def test_get_pubkey_uninitialized(self):
2105 """
Alex Chanb00ede22017-01-30 07:24:40 +00002106 When called on a certificate with no public key, `X509.get_pubkey`
2107 raises `OpenSSL.crypto.Error`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002108 """
2109 cert = X509()
Alex Chanb00ede22017-01-30 07:24:40 +00002110 with pytest.raises(Error):
2111 cert.get_pubkey()
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002112
Alex Gaynor7778e792016-07-03 23:38:48 -04002113 def test_set_pubkey_wrong_type(self):
2114 """
Alex Chanb00ede22017-01-30 07:24:40 +00002115 `X509.set_pubkey` raises `TypeError` when given an object of the
2116 wrong type.
Alex Gaynor7778e792016-07-03 23:38:48 -04002117 """
2118 cert = X509()
2119 with pytest.raises(TypeError):
2120 cert.set_pubkey(object())
2121
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04002122 def test_subject_name_hash(self):
2123 """
Alex Chanb00ede22017-01-30 07:24:40 +00002124 `X509.subject_name_hash` returns the hash of the certificate's
Alex Gaynor31287502015-09-05 16:11:27 -04002125 subject name.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04002126 """
2127 cert = load_certificate(FILETYPE_PEM, self.pemData)
Alex Gaynor4cb05202019-02-02 11:06:41 -05002128 # SHA1
2129 assert cert.subject_name_hash() == 3278919224
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04002130
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04002131 def test_get_signature_algorithm(self):
2132 """
Alex Chanb00ede22017-01-30 07:24:40 +00002133 `X509.get_signature_algorithm` returns a string which means
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04002134 the algorithm used to sign the certificate.
2135 """
2136 cert = load_certificate(FILETYPE_PEM, self.pemData)
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05002137 assert b"sha256WithRSAEncryption" == cert.get_signature_algorithm()
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04002138
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04002139 def test_get_undefined_signature_algorithm(self):
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04002140 """
Alex Chanb00ede22017-01-30 07:24:40 +00002141 `X509.get_signature_algorithm` raises `ValueError` if the signature
2142 algorithm is undefined or unknown.
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04002143 """
2144 # This certificate has been modified to indicate a bogus OID in the
2145 # signature algorithm field so that OpenSSL does not recognize it.
Alex Gaynore7f51982016-09-11 11:48:14 -04002146 certPEM = b"""\
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04002147-----BEGIN CERTIFICATE-----
2148MIIC/zCCAmigAwIBAgIBATAGBgJ8BQUAMHsxCzAJBgNVBAYTAlNHMREwDwYDVQQK
2149EwhNMkNyeXB0bzEUMBIGA1UECxMLTTJDcnlwdG8gQ0ExJDAiBgNVBAMTG00yQ3J5
2150cHRvIENlcnRpZmljYXRlIE1hc3RlcjEdMBsGCSqGSIb3DQEJARYObmdwc0Bwb3N0
2151MS5jb20wHhcNMDAwOTEwMDk1MTMwWhcNMDIwOTEwMDk1MTMwWjBTMQswCQYDVQQG
2152EwJTRzERMA8GA1UEChMITTJDcnlwdG8xEjAQBgNVBAMTCWxvY2FsaG9zdDEdMBsG
2153CSqGSIb3DQEJARYObmdwc0Bwb3N0MS5jb20wXDANBgkqhkiG9w0BAQEFAANLADBI
2154AkEArL57d26W9fNXvOhNlZzlPOACmvwOZ5AdNgLzJ1/MfsQQJ7hHVeHmTAjM664V
2155+fXvwUGJLziCeBo1ysWLRnl8CQIDAQABo4IBBDCCAQAwCQYDVR0TBAIwADAsBglg
2156hkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0O
2157BBYEFM+EgpK+eyZiwFU1aOPSbczbPSpVMIGlBgNVHSMEgZ0wgZqAFPuHI2nrnDqT
2158FeXFvylRT/7tKDgBoX+kfTB7MQswCQYDVQQGEwJTRzERMA8GA1UEChMITTJDcnlw
2159dG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtNMkNyeXB0byBDZXJ0
2160aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tggEA
2161MA0GCSqGSIb3DQEBBAUAA4GBADv8KpPo+gfJxN2ERK1Y1l17sz/ZhzoGgm5XCdbx
2162jEY7xKfpQngV599k1xhl11IMqizDwu0855agrckg2MCTmOI9DZzDD77tAYb+Dk0O
2163PEVk0Mk/V0aIsDE9bolfCi/i/QWZ3N8s5nTWMNyBBBmoSliWCm4jkkRZRD0ejgTN
2164tgI5
2165-----END CERTIFICATE-----
Alex Gaynore7f51982016-09-11 11:48:14 -04002166"""
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04002167 cert = load_certificate(FILETYPE_PEM, certPEM)
Alex Chanb00ede22017-01-30 07:24:40 +00002168 with pytest.raises(ValueError):
2169 cert.get_signature_algorithm()
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04002170
Alex Gaynor37726112016-07-04 09:51:32 -04002171 def test_sign_bad_pubkey_type(self):
2172 """
Alex Chanb00ede22017-01-30 07:24:40 +00002173 `X509.sign` raises `TypeError` when called with the wrong type.
Alex Gaynor37726112016-07-04 09:51:32 -04002174 """
2175 cert = X509()
2176 with pytest.raises(TypeError):
2177 cert.sign(object(), b"sha256")
2178
Alex Gaynor9939ba12017-06-25 16:28:24 -04002179 def test_convert_from_cryptography(self):
2180 crypto_cert = x509.load_pem_x509_certificate(
2181 intermediate_cert_pem, backend
2182 )
2183 cert = X509.from_cryptography(crypto_cert)
2184
2185 assert isinstance(cert, X509)
2186 assert cert.get_version() == crypto_cert.version.value
2187
2188 def test_convert_from_cryptography_unsupported_type(self):
2189 with pytest.raises(TypeError):
2190 X509.from_cryptography(object())
2191
2192 def test_convert_to_cryptography_key(self):
2193 cert = load_certificate(FILETYPE_PEM, intermediate_cert_pem)
2194 crypto_cert = cert.to_cryptography()
2195
2196 assert isinstance(crypto_cert, x509.Certificate)
2197 assert crypto_cert.version.value == cert.get_version()
2198
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04002199
Alex Chan9e2a9932017-01-25 14:29:19 +00002200class TestX509Store(object):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002201 """
Alex Chan9e2a9932017-01-25 14:29:19 +00002202 Test for `OpenSSL.crypto.X509Store`.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002203 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002204
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002205 def test_type(self):
2206 """
Alex Chan9e2a9932017-01-25 14:29:19 +00002207 `X509Store` is a type object.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002208 """
Alex Gaynor03737182020-07-23 20:40:46 -04002209 assert is_consistent_type(X509Store, "X509Store")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002210
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002211 def test_add_cert(self):
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08002212 """
Alex Chan9e2a9932017-01-25 14:29:19 +00002213 `X509Store.add_cert` adds a `X509` instance to the certificate store.
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08002214 """
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05002215 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002216 store = X509Store()
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08002217 store.add_cert(cert)
2218
Alex Gaynor03737182020-07-23 20:40:46 -04002219 @pytest.mark.parametrize("cert", [None, 1.0, "cert", object()])
Alex Chanfb078d82017-04-20 11:16:15 +01002220 def test_add_cert_wrong_args(self, cert):
2221 """
2222 `X509Store.add_cert` raises `TypeError` if passed a non-X509 object
2223 as its first argument.
2224 """
2225 store = X509Store()
2226 with pytest.raises(TypeError):
2227 store.add_cert(cert)
2228
Paul Kehrer0e6c5532018-08-23 10:52:15 -05002229 def test_add_cert_accepts_duplicate(self):
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08002230 """
Paul Kehrer0e6c5532018-08-23 10:52:15 -05002231 `X509Store.add_cert` doesn't raise `OpenSSL.crypto.Error` if an attempt
2232 is made to add the same certificate to the store more than once.
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08002233 """
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05002234 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08002235 store = X509Store()
2236 store.add_cert(cert)
Paul Kehrer0e6c5532018-08-23 10:52:15 -05002237 store.add_cert(cert)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002238
Sándor Oroszi43c97762020-09-11 17:17:31 +02002239 @pytest.mark.parametrize(
2240 "cafile, capath, call_cafile, call_capath",
2241 [
2242 (
2243 "/cafile" + NON_ASCII,
2244 None,
2245 b"/cafile" + NON_ASCII.encode(sys.getfilesystemencoding()),
2246 _ffi.NULL,
2247 ),
2248 (
2249 b"/cafile" + NON_ASCII.encode("utf-8"),
2250 None,
2251 b"/cafile" + NON_ASCII.encode("utf-8"),
2252 _ffi.NULL,
2253 ),
2254 (
2255 None,
2256 "/capath" + NON_ASCII,
2257 _ffi.NULL,
2258 b"/capath" + NON_ASCII.encode(sys.getfilesystemencoding()),
2259 ),
2260 (
2261 None,
2262 b"/capath" + NON_ASCII.encode("utf-8"),
2263 _ffi.NULL,
2264 b"/capath" + NON_ASCII.encode("utf-8"),
2265 ),
2266 ],
2267 )
2268 def test_load_locations_parameters(
2269 self, cafile, capath, call_cafile, call_capath, monkeypatch
2270 ):
2271 class LibMock(object):
2272 def load_locations(self, store, cafile, capath):
2273 self.cafile = cafile
2274 self.capath = capath
2275 return 1
2276
2277 lib_mock = LibMock()
2278 monkeypatch.setattr(
2279 _lib, "X509_STORE_load_locations", lib_mock.load_locations
2280 )
2281
2282 store = X509Store()
2283 store.load_locations(cafile=cafile, capath=capath)
2284
2285 assert call_cafile == lib_mock.cafile
2286 assert call_capath == lib_mock.capath
2287
2288 def test_load_locations_fails_when_all_args_are_none(self):
2289 store = X509Store()
2290 with pytest.raises(Error):
2291 store.load_locations(None, None)
2292
2293 def test_load_locations_raises_error_on_failure(self, tmpdir):
2294 invalid_ca_file = tmpdir.join("invalid.pem")
2295 invalid_ca_file.write("This is not a certificate")
2296
2297 store = X509Store()
2298 with pytest.raises(Error):
2299 store.load_locations(cafile=str(invalid_ca_file))
2300
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002301
Alex Chanb00ede22017-01-30 07:24:40 +00002302class TestPKCS12(object):
Rick Dean623ee362009-07-17 12:22:16 -05002303 """
Alex Chanb00ede22017-01-30 07:24:40 +00002304 Test for `OpenSSL.crypto.PKCS12` and `OpenSSL.crypto.load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05002305 """
Alex Gaynor03737182020-07-23 20:40:46 -04002306
Jean-Paul Calderonec3a41f72009-07-25 12:36:02 -04002307 def test_type(self):
2308 """
Alex Gaynor01f90a12019-02-07 09:14:48 -05002309 `PKCS12` is a type object.
Jean-Paul Calderonec3a41f72009-07-25 12:36:02 -04002310 """
Alex Gaynor03737182020-07-23 20:40:46 -04002311 assert is_consistent_type(PKCS12, "PKCS12")
Jean-Paul Calderonec3a41f72009-07-25 12:36:02 -04002312
Rick Deanf94096c2009-07-18 14:23:06 -05002313 def test_empty_construction(self):
Rick Dean38a05c82009-07-18 01:41:30 -05002314 """
Alex Chanb00ede22017-01-30 07:24:40 +00002315 `PKCS12` returns a new instance of `PKCS12` with no certificate,
2316 private key, CA certificates, or friendly name.
Rick Dean38a05c82009-07-18 01:41:30 -05002317 """
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002318 p12 = PKCS12()
Alex Chanb00ede22017-01-30 07:24:40 +00002319 assert None is p12.get_certificate()
2320 assert None is p12.get_privatekey()
2321 assert None is p12.get_ca_certificates()
2322 assert None is p12.get_friendlyname()
Rick Dean623ee362009-07-17 12:22:16 -05002323
2324 def test_type_errors(self):
Rick Dean38a05c82009-07-18 01:41:30 -05002325 """
Alex Chanb00ede22017-01-30 07:24:40 +00002326 The `PKCS12` setter functions (`set_certificate`, `set_privatekey`,
2327 `set_ca_certificates`, and `set_friendlyname`) raise `TypeError`
2328 when passed objects of types other than those expected.
Rick Dean38a05c82009-07-18 01:41:30 -05002329 """
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002330 p12 = PKCS12()
Alex Chanb00ede22017-01-30 07:24:40 +00002331 for bad_arg in [3, PKey(), X509]:
2332 with pytest.raises(TypeError):
2333 p12.set_certificate(bad_arg)
Alex Gaynor03737182020-07-23 20:40:46 -04002334 for bad_arg in [3, "legbone", X509()]:
Alex Chanb00ede22017-01-30 07:24:40 +00002335 with pytest.raises(TypeError):
2336 p12.set_privatekey(bad_arg)
2337 for bad_arg in [3, X509(), (3, 4), (PKey(),)]:
2338 with pytest.raises(TypeError):
2339 p12.set_ca_certificates(bad_arg)
Alex Gaynor03737182020-07-23 20:40:46 -04002340 for bad_arg in [6, ("foo", "bar")]:
Alex Chanb00ede22017-01-30 07:24:40 +00002341 with pytest.raises(TypeError):
2342 p12.set_friendlyname(bad_arg)
Rick Dean623ee362009-07-17 12:22:16 -05002343
2344 def test_key_only(self):
2345 """
Alex Chanb00ede22017-01-30 07:24:40 +00002346 A `PKCS12` with only a private key can be exported using
2347 `PKCS12.export` and loaded again using `load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05002348 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002349 passwd = b"blah"
Rick Dean623ee362009-07-17 12:22:16 -05002350 p12 = PKCS12()
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05002351 pkey = load_privatekey(FILETYPE_PEM, root_key_pem)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002352 p12.set_privatekey(pkey)
Alex Chanb00ede22017-01-30 07:24:40 +00002353 assert None is p12.get_certificate()
2354 assert pkey == p12.get_privatekey()
Rick Dean321a0512009-08-13 17:21:29 -05002355 try:
2356 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
2357 except Error:
2358 # Some versions of OpenSSL will throw an exception
2359 # for this nearly useless PKCS12 we tried to generate:
2360 # [('PKCS12 routines', 'PKCS12_create', 'invalid null argument')]
2361 return
Rick Dean623ee362009-07-17 12:22:16 -05002362 p12 = load_pkcs12(dumped_p12, passwd)
Alex Chanb00ede22017-01-30 07:24:40 +00002363 assert None is p12.get_ca_certificates()
2364 assert None is p12.get_certificate()
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002365
2366 # OpenSSL fails to bring the key back to us. So sad. Perhaps in the
2367 # future this will be improved.
Alex Chanb00ede22017-01-30 07:24:40 +00002368 assert isinstance(p12.get_privatekey(), (PKey, type(None)))
Rick Dean623ee362009-07-17 12:22:16 -05002369
2370 def test_cert_only(self):
2371 """
Alex Chanb00ede22017-01-30 07:24:40 +00002372 A `PKCS12` with only a certificate can be exported using
2373 `PKCS12.export` and loaded again using `load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05002374 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002375 passwd = b"blah"
Rick Dean623ee362009-07-17 12:22:16 -05002376 p12 = PKCS12()
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05002377 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002378 p12.set_certificate(cert)
Alex Chanb00ede22017-01-30 07:24:40 +00002379 assert cert == p12.get_certificate()
2380 assert None is p12.get_privatekey()
Rick Dean321a0512009-08-13 17:21:29 -05002381 try:
2382 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
2383 except Error:
2384 # Some versions of OpenSSL will throw an exception
2385 # for this nearly useless PKCS12 we tried to generate:
2386 # [('PKCS12 routines', 'PKCS12_create', 'invalid null argument')]
2387 return
Rick Dean623ee362009-07-17 12:22:16 -05002388 p12 = load_pkcs12(dumped_p12, passwd)
Alex Chanb00ede22017-01-30 07:24:40 +00002389 assert None is p12.get_privatekey()
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002390
2391 # OpenSSL fails to bring the cert back to us. Groany mcgroan.
Alex Chanb00ede22017-01-30 07:24:40 +00002392 assert isinstance(p12.get_certificate(), (X509, type(None)))
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002393
2394 # Oh ho. It puts the certificate into the ca certificates list, in
2395 # fact. Totally bogus, I would think. Nevertheless, let's exploit
2396 # that to check to see if it reconstructed the certificate we expected
2397 # it to. At some point, hopefully this will change so that
2398 # p12.get_certificate() is actually what returns the loaded
2399 # certificate.
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05002400 assert root_cert_pem == dump_certificate(
Alex Gaynor03737182020-07-23 20:40:46 -04002401 FILETYPE_PEM, p12.get_ca_certificates()[0]
2402 )
Rick Dean623ee362009-07-17 12:22:16 -05002403
Alex Gaynor03737182020-07-23 20:40:46 -04002404 def gen_pkcs12(
2405 self, cert_pem=None, key_pem=None, ca_pem=None, friendly_name=None
2406 ):
Rick Dean623ee362009-07-17 12:22:16 -05002407 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002408 Generate a PKCS12 object with components from PEM. Verify that the set
2409 functions return None.
Rick Dean623ee362009-07-17 12:22:16 -05002410 """
Rick Deanf94096c2009-07-18 14:23:06 -05002411 p12 = PKCS12()
2412 if cert_pem:
2413 ret = p12.set_certificate(load_certificate(FILETYPE_PEM, cert_pem))
Alex Chanb00ede22017-01-30 07:24:40 +00002414 assert ret is None
Rick Deanf94096c2009-07-18 14:23:06 -05002415 if key_pem:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002416 ret = p12.set_privatekey(load_privatekey(FILETYPE_PEM, key_pem))
Alex Chanb00ede22017-01-30 07:24:40 +00002417 assert ret is None
Rick Deanf94096c2009-07-18 14:23:06 -05002418 if ca_pem:
Alex Gaynor85b49702015-09-05 16:30:59 -04002419 ret = p12.set_ca_certificates(
2420 (load_certificate(FILETYPE_PEM, ca_pem),)
2421 )
Alex Chanb00ede22017-01-30 07:24:40 +00002422 assert ret is None
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002423 if friendly_name:
2424 ret = p12.set_friendlyname(friendly_name)
Alex Chanb00ede22017-01-30 07:24:40 +00002425 assert ret is None
Rick Deanf94096c2009-07-18 14:23:06 -05002426 return p12
2427
Alex Gaynor03737182020-07-23 20:40:46 -04002428 def check_recovery(
2429 self, p12_str, key=None, cert=None, ca=None, passwd=b"", extra=()
2430 ):
Rick Deanf94096c2009-07-18 14:23:06 -05002431 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002432 Use openssl program to confirm three components are recoverable from a
2433 PKCS12 string.
Rick Deanf94096c2009-07-18 14:23:06 -05002434 """
2435 if key:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002436 recovered_key = _runopenssl(
Alex Gaynor03737182020-07-23 20:40:46 -04002437 p12_str,
2438 b"pkcs12",
2439 b"-nocerts",
2440 b"-nodes",
2441 b"-passin",
2442 b"pass:" + passwd,
2443 *extra
2444 )
2445 assert recovered_key[-len(key) :] == key
Rick Deanf94096c2009-07-18 14:23:06 -05002446 if cert:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002447 recovered_cert = _runopenssl(
Alex Gaynor03737182020-07-23 20:40:46 -04002448 p12_str,
2449 b"pkcs12",
2450 b"-clcerts",
2451 b"-nodes",
2452 b"-passin",
2453 b"pass:" + passwd,
2454 b"-nokeys",
2455 *extra
2456 )
2457 assert recovered_cert[-len(cert) :] == cert
Rick Deanf94096c2009-07-18 14:23:06 -05002458 if ca:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002459 recovered_cert = _runopenssl(
Alex Gaynor03737182020-07-23 20:40:46 -04002460 p12_str,
2461 b"pkcs12",
2462 b"-cacerts",
2463 b"-nodes",
2464 b"-passin",
2465 b"pass:" + passwd,
2466 b"-nokeys",
2467 *extra
2468 )
2469 assert recovered_cert[-len(ca) :] == ca
Rick Deanf94096c2009-07-18 14:23:06 -05002470
Stephen Holsapple38482622014-04-05 20:29:34 -07002471 def verify_pkcs12_container(self, p12):
2472 """
2473 Verify that the PKCS#12 container contains the correct client
2474 certificate and private key.
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002475
2476 :param p12: The PKCS12 instance to verify.
Alex Chanb00ede22017-01-30 07:24:40 +00002477 :type p12: `PKCS12`
Stephen Holsapple38482622014-04-05 20:29:34 -07002478 """
2479 cert_pem = dump_certificate(FILETYPE_PEM, p12.get_certificate())
2480 key_pem = dump_privatekey(FILETYPE_PEM, p12.get_privatekey())
Alex Gaynor03737182020-07-23 20:40:46 -04002481 assert (client_cert_pem, client_key_pem, None) == (
2482 cert_pem,
2483 key_pem,
2484 p12.get_ca_certificates(),
2485 )
Stephen Holsapple38482622014-04-05 20:29:34 -07002486
Rick Deanf94096c2009-07-18 14:23:06 -05002487 def test_load_pkcs12(self):
2488 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002489 A PKCS12 string generated using the openssl command line can be loaded
Alex Chanb00ede22017-01-30 07:24:40 +00002490 with `load_pkcs12` and its components extracted and examined.
Rick Deanf94096c2009-07-18 14:23:06 -05002491 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002492 passwd = b"whatever"
Rick Dean623ee362009-07-17 12:22:16 -05002493 pem = client_key_pem + client_cert_pem
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002494 p12_str = _runopenssl(
Alex Gaynor85b49702015-09-05 16:30:59 -04002495 pem,
2496 b"pkcs12",
2497 b"-export",
2498 b"-clcerts",
2499 b"-passout",
Alex Gaynor03737182020-07-23 20:40:46 -04002500 b"pass:" + passwd,
Alex Gaynor85b49702015-09-05 16:30:59 -04002501 )
Stephen Holsapple38482622014-04-05 20:29:34 -07002502 p12 = load_pkcs12(p12_str, passphrase=passwd)
2503 self.verify_pkcs12_container(p12)
2504
Abraham Martinc5484ba2015-03-25 15:33:05 +00002505 def test_load_pkcs12_text_passphrase(self):
2506 """
2507 A PKCS12 string generated using the openssl command line can be loaded
Alex Chanb00ede22017-01-30 07:24:40 +00002508 with `load_pkcs12` and its components extracted and examined.
Abraham Martinc5484ba2015-03-25 15:33:05 +00002509 Using text as passphrase instead of bytes. DeprecationWarning expected.
2510 """
2511 pem = client_key_pem + client_cert_pem
2512 passwd = b"whatever"
Alex Gaynor03737182020-07-23 20:40:46 -04002513 p12_str = _runopenssl(
2514 pem,
2515 b"pkcs12",
2516 b"-export",
2517 b"-clcerts",
2518 b"-passout",
2519 b"pass:" + passwd,
2520 )
Alex Chanb00ede22017-01-30 07:24:40 +00002521 with pytest.warns(DeprecationWarning) as w:
Abraham Martinc5484ba2015-03-25 15:33:05 +00002522 simplefilter("always")
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002523 p12 = load_pkcs12(p12_str, passphrase=b"whatever".decode("ascii"))
Alex Gaynor03737182020-07-23 20:40:46 -04002524 msg = "{0} for passphrase is no longer accepted, use bytes".format(
2525 WARNING_TYPE_EXPECTED
2526 )
2527 assert msg == str(w[-1].message)
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002528
Abraham Martinc5484ba2015-03-25 15:33:05 +00002529 self.verify_pkcs12_container(p12)
2530
Stephen Holsapple38482622014-04-05 20:29:34 -07002531 def test_load_pkcs12_no_passphrase(self):
2532 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002533 A PKCS12 string generated using openssl command line can be loaded with
Alex Chanb00ede22017-01-30 07:24:40 +00002534 `load_pkcs12` without a passphrase and its components extracted
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002535 and examined.
Stephen Holsapple38482622014-04-05 20:29:34 -07002536 """
2537 pem = client_key_pem + client_cert_pem
2538 p12_str = _runopenssl(
Alex Gaynor03737182020-07-23 20:40:46 -04002539 pem, b"pkcs12", b"-export", b"-clcerts", b"-passout", b"pass:"
2540 )
Stephen Holsapple38482622014-04-05 20:29:34 -07002541 p12 = load_pkcs12(p12_str)
2542 self.verify_pkcs12_container(p12)
2543
Stephen Holsapple38482622014-04-05 20:29:34 -07002544 def _dump_and_load(self, dump_passphrase, load_passphrase):
2545 """
2546 A helper method to dump and load a PKCS12 object.
2547 """
2548 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem)
2549 dumped_p12 = p12.export(passphrase=dump_passphrase, iter=2, maciter=3)
2550 return load_pkcs12(dumped_p12, passphrase=load_passphrase)
2551
Stephen Holsapple38482622014-04-05 20:29:34 -07002552 def test_load_pkcs12_null_passphrase_load_empty(self):
2553 """
2554 A PKCS12 string can be dumped with a null passphrase, loaded with an
Alex Chanb00ede22017-01-30 07:24:40 +00002555 empty passphrase with `load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002556 extracted and examined.
2557 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002558 self.verify_pkcs12_container(
Alex Gaynor03737182020-07-23 20:40:46 -04002559 self._dump_and_load(dump_passphrase=None, load_passphrase=b"")
2560 )
Stephen Holsapple38482622014-04-05 20:29:34 -07002561
Stephen Holsapple38482622014-04-05 20:29:34 -07002562 def test_load_pkcs12_null_passphrase_load_null(self):
2563 """
2564 A PKCS12 string can be dumped with a null passphrase, loaded with a
Alex Chanb00ede22017-01-30 07:24:40 +00002565 null passphrase with `load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002566 extracted and examined.
2567 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002568 self.verify_pkcs12_container(
Alex Gaynor03737182020-07-23 20:40:46 -04002569 self._dump_and_load(dump_passphrase=None, load_passphrase=None)
2570 )
Stephen Holsapple38482622014-04-05 20:29:34 -07002571
Stephen Holsapple38482622014-04-05 20:29:34 -07002572 def test_load_pkcs12_empty_passphrase_load_empty(self):
2573 """
2574 A PKCS12 string can be dumped with an empty passphrase, loaded with an
Alex Chanb00ede22017-01-30 07:24:40 +00002575 empty passphrase with `load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002576 extracted and examined.
2577 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002578 self.verify_pkcs12_container(
Alex Gaynor03737182020-07-23 20:40:46 -04002579 self._dump_and_load(dump_passphrase=b"", load_passphrase=b"")
2580 )
Stephen Holsapple38482622014-04-05 20:29:34 -07002581
Stephen Holsapple38482622014-04-05 20:29:34 -07002582 def test_load_pkcs12_empty_passphrase_load_null(self):
2583 """
2584 A PKCS12 string can be dumped with an empty passphrase, loaded with a
Alex Chanb00ede22017-01-30 07:24:40 +00002585 null passphrase with `load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002586 extracted and examined.
2587 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002588 self.verify_pkcs12_container(
Alex Gaynor03737182020-07-23 20:40:46 -04002589 self._dump_and_load(dump_passphrase=b"", load_passphrase=None)
2590 )
Rick Deanf94096c2009-07-18 14:23:06 -05002591
Rick Deanee568302009-07-24 09:56:29 -05002592 def test_load_pkcs12_garbage(self):
2593 """
Alex Chanb00ede22017-01-30 07:24:40 +00002594 `load_pkcs12` raises `OpenSSL.crypto.Error` when passed
Alex Gaynor85b49702015-09-05 16:30:59 -04002595 a string which is not a PKCS12 dump.
Rick Deanee568302009-07-24 09:56:29 -05002596 """
Paul Kehrerc45a6ea2020-08-03 15:54:20 -05002597 passwd = b"whatever"
Alex Chanb00ede22017-01-30 07:24:40 +00002598 with pytest.raises(Error) as err:
Alex Gaynor03737182020-07-23 20:40:46 -04002599 load_pkcs12(b"fruit loops", passwd)
2600 assert err.value.args[0][0][0] == "asn1 encoding routines"
Alex Chanb00ede22017-01-30 07:24:40 +00002601 assert len(err.value.args[0][0]) == 3
Rick Deanee568302009-07-24 09:56:29 -05002602
Rick Deanf94096c2009-07-18 14:23:06 -05002603 def test_replace(self):
2604 """
Alex Chanb00ede22017-01-30 07:24:40 +00002605 `PKCS12.set_certificate` replaces the certificate in a PKCS12
2606 cluster. `PKCS12.set_privatekey` replaces the private key.
2607 `PKCS12.set_ca_certificates` replaces the CA certificates.
Rick Deanf94096c2009-07-18 14:23:06 -05002608 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002609 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
2610 p12.set_certificate(load_certificate(FILETYPE_PEM, server_cert_pem))
2611 p12.set_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002612 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Rick Deanf94096c2009-07-18 14:23:06 -05002613 client_cert = load_certificate(FILETYPE_PEM, client_cert_pem)
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002614 p12.set_ca_certificates([root_cert]) # not a tuple
Alex Chanb00ede22017-01-30 07:24:40 +00002615 assert 1 == len(p12.get_ca_certificates())
2616 assert root_cert == p12.get_ca_certificates()[0]
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002617 p12.set_ca_certificates([client_cert, root_cert])
Alex Chanb00ede22017-01-30 07:24:40 +00002618 assert 2 == len(p12.get_ca_certificates())
2619 assert client_cert == p12.get_ca_certificates()[0]
2620 assert root_cert == p12.get_ca_certificates()[1]
Rick Deanf94096c2009-07-18 14:23:06 -05002621
Rick Deanf94096c2009-07-18 14:23:06 -05002622 def test_friendly_name(self):
2623 """
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002624 The *friendlyName* of a PKCS12 can be set and retrieved via
Alex Chanb00ede22017-01-30 07:24:40 +00002625 `PKCS12.get_friendlyname` and `PKCS12_set_friendlyname`, and a
2626 `PKCS12` with a friendly name set can be dumped with `PKCS12.export`.
Rick Deanf94096c2009-07-18 14:23:06 -05002627 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002628 passwd = b'Dogmeat[]{}!@#$%^&*()~`?/.,<>-_+=";:'
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002629 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Alex Gaynor03737182020-07-23 20:40:46 -04002630 for friendly_name in [b"Serverlicious", None, b"###"]:
Rick Dean42d69e12009-07-20 11:36:08 -05002631 p12.set_friendlyname(friendly_name)
Alex Chanb00ede22017-01-30 07:24:40 +00002632 assert p12.get_friendlyname() == friendly_name
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002633 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
Rick Dean42d69e12009-07-20 11:36:08 -05002634 reloaded_p12 = load_pkcs12(dumped_p12, passwd)
Alex Chanb00ede22017-01-30 07:24:40 +00002635 assert p12.get_friendlyname() == reloaded_p12.get_friendlyname()
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002636 # We would use the openssl program to confirm the friendly
2637 # name, but it is not possible. The pkcs12 command
2638 # does not store the friendly name in the cert's
Rick Dean42d69e12009-07-20 11:36:08 -05002639 # alias, which we could then extract.
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002640 self.check_recovery(
Alex Gaynor03737182020-07-23 20:40:46 -04002641 dumped_p12,
2642 key=server_key_pem,
2643 cert=server_cert_pem,
2644 ca=root_cert_pem,
2645 passwd=passwd,
2646 )
Rick Deanf94096c2009-07-18 14:23:06 -05002647
Rick Deanf94096c2009-07-18 14:23:06 -05002648 def test_various_empty_passphrases(self):
2649 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002650 Test that missing, None, and '' passphrases are identical for PKCS12
2651 export.
Rick Deanf94096c2009-07-18 14:23:06 -05002652 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002653 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002654 passwd = b""
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002655 dumped_p12_empty = p12.export(iter=2, maciter=0, passphrase=passwd)
2656 dumped_p12_none = p12.export(iter=3, maciter=2, passphrase=None)
2657 dumped_p12_nopw = p12.export(iter=9, maciter=4)
2658 for dumped_p12 in [dumped_p12_empty, dumped_p12_none, dumped_p12_nopw]:
2659 self.check_recovery(
Alex Gaynor03737182020-07-23 20:40:46 -04002660 dumped_p12,
2661 key=client_key_pem,
2662 cert=client_cert_pem,
2663 ca=root_cert_pem,
2664 passwd=passwd,
2665 )
Rick Deanf94096c2009-07-18 14:23:06 -05002666
Rick Deanf94096c2009-07-18 14:23:06 -05002667 def test_removing_ca_cert(self):
2668 """
Alex Chanb00ede22017-01-30 07:24:40 +00002669 Passing `None` to `PKCS12.set_ca_certificates` removes all CA
2670 certificates.
Rick Deanf94096c2009-07-18 14:23:06 -05002671 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002672 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2673 p12.set_ca_certificates(None)
Alex Chanb00ede22017-01-30 07:24:40 +00002674 assert None is p12.get_ca_certificates()
Rick Deanf94096c2009-07-18 14:23:06 -05002675
Rick Deanf94096c2009-07-18 14:23:06 -05002676 def test_export_without_mac(self):
2677 """
Alex Chanb00ede22017-01-30 07:24:40 +00002678 Exporting a PKCS12 with a `maciter` of `-1` excludes the MAC entirely.
Rick Deanf94096c2009-07-18 14:23:06 -05002679 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002680 passwd = b"Lake Michigan"
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002681 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Rick Dean623ee362009-07-17 12:22:16 -05002682 dumped_p12 = p12.export(maciter=-1, passphrase=passwd, iter=2)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002683 self.check_recovery(
Alex Gaynor03737182020-07-23 20:40:46 -04002684 dumped_p12,
2685 key=server_key_pem,
2686 cert=server_cert_pem,
2687 passwd=passwd,
2688 extra=(b"-nomacver",),
2689 )
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002690
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002691 def test_load_without_mac(self):
2692 """
2693 Loading a PKCS12 without a MAC does something other than crash.
2694 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002695 passwd = b"Lake Michigan"
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002696 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2697 dumped_p12 = p12.export(maciter=-1, passphrase=passwd, iter=2)
Rick Dean321a0512009-08-13 17:21:29 -05002698 try:
2699 recovered_p12 = load_pkcs12(dumped_p12, passwd)
2700 # The person who generated this PCKS12 should be flogged,
2701 # or better yet we should have a means to determine
2702 # whether a PCKS12 had a MAC that was verified.
2703 # Anyway, libopenssl chooses to allow it, so the
2704 # pyopenssl binding does as well.
Alex Chanb00ede22017-01-30 07:24:40 +00002705 assert isinstance(recovered_p12, PKCS12)
Rick Dean321a0512009-08-13 17:21:29 -05002706 except Error:
2707 # Failing here with an exception is preferred as some openssl
2708 # versions do.
2709 pass
Rick Dean623ee362009-07-17 12:22:16 -05002710
Rick Dean25bcc1f2009-07-20 11:53:13 -05002711 def test_zero_len_list_for_ca(self):
2712 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002713 A PKCS12 with an empty CA certificates list can be exported.
Rick Dean25bcc1f2009-07-20 11:53:13 -05002714 """
Alex Gaynor03737182020-07-23 20:40:46 -04002715 passwd = b"Hobie 18"
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002716 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem)
Alex Gaynor85b49702015-09-05 16:30:59 -04002717 p12.set_ca_certificates([])
Alex Chanb00ede22017-01-30 07:24:40 +00002718 assert () == p12.get_ca_certificates()
Alex Gaynor85b49702015-09-05 16:30:59 -04002719 dumped_p12 = p12.export(passphrase=passwd, iter=3)
2720 self.check_recovery(
Alex Gaynor03737182020-07-23 20:40:46 -04002721 dumped_p12, key=server_key_pem, cert=server_cert_pem, passwd=passwd
2722 )
Rick Dean25bcc1f2009-07-20 11:53:13 -05002723
Rick Deanf94096c2009-07-18 14:23:06 -05002724 def test_export_without_args(self):
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04002725 """
Alex Chanb00ede22017-01-30 07:24:40 +00002726 All the arguments to `PKCS12.export` are optional.
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04002727 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002728 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Rick Deanf94096c2009-07-18 14:23:06 -05002729 dumped_p12 = p12.export() # no args
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002730 self.check_recovery(
Alex Gaynor03737182020-07-23 20:40:46 -04002731 dumped_p12, key=server_key_pem, cert=server_cert_pem, passwd=b""
2732 )
Rick Deanf94096c2009-07-18 14:23:06 -05002733
Abraham Martinc5484ba2015-03-25 15:33:05 +00002734 def test_export_without_bytes(self):
2735 """
Alex Chanb00ede22017-01-30 07:24:40 +00002736 Test `PKCS12.export` with text not bytes as passphrase
Abraham Martinc5484ba2015-03-25 15:33:05 +00002737 """
2738 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2739
Alex Chanb00ede22017-01-30 07:24:40 +00002740 with pytest.warns(DeprecationWarning) as w:
Abraham Martinc5484ba2015-03-25 15:33:05 +00002741 simplefilter("always")
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002742 dumped_p12 = p12.export(passphrase=b"randomtext".decode("ascii"))
Alex Gaynor03737182020-07-23 20:40:46 -04002743 msg = "{0} for passphrase is no longer accepted, use bytes".format(
2744 WARNING_TYPE_EXPECTED
2745 )
2746 assert msg == str(w[-1].message)
Abraham Martinc5484ba2015-03-25 15:33:05 +00002747 self.check_recovery(
Alex Gaynor791212d2015-09-05 15:46:08 -04002748 dumped_p12,
2749 key=server_key_pem,
2750 cert=server_cert_pem,
Alex Gaynor03737182020-07-23 20:40:46 -04002751 passwd=b"randomtext",
Alex Gaynor791212d2015-09-05 15:46:08 -04002752 )
Abraham Martinc5484ba2015-03-25 15:33:05 +00002753
Rick Deanf94096c2009-07-18 14:23:06 -05002754 def test_key_cert_mismatch(self):
2755 """
Alex Chanb00ede22017-01-30 07:24:40 +00002756 `PKCS12.export` raises an exception when a key and certificate
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002757 mismatch.
Rick Deanf94096c2009-07-18 14:23:06 -05002758 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002759 p12 = self.gen_pkcs12(server_cert_pem, client_key_pem, root_cert_pem)
Alex Chanb00ede22017-01-30 07:24:40 +00002760 with pytest.raises(Error):
2761 p12.export()
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002762
2763
Rick Dean4c9ad612009-07-17 15:05:22 -05002764def _runopenssl(pem, *args):
2765 """
2766 Run the command line openssl tool with the given arguments and write
Rick Dean55d1ce62009-08-13 17:40:24 -05002767 the given PEM to its stdin. Not safe for quotes.
Rick Dean4c9ad612009-07-17 15:05:22 -05002768 """
Alex Gaynor6cbc69a2017-07-25 09:07:04 -04002769 proc = Popen([b"openssl"] + list(args), stdin=PIPE, stdout=PIPE)
Jean-Paul Calderone62ca8da2010-08-11 19:58:08 -04002770 proc.stdin.write(pem)
2771 proc.stdin.close()
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002772 output = proc.stdout.read()
2773 proc.stdout.close()
2774 proc.wait()
2775 return output
Rick Dean4c9ad612009-07-17 15:05:22 -05002776
2777
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002778class TestLoadPublicKey(object):
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002779 """
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002780 Tests for :func:`load_publickey`.
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002781 """
Alex Gaynor03737182020-07-23 20:40:46 -04002782
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002783 def test_loading_works(self):
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002784 """
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002785 load_publickey loads public keys and sets correct attributes.
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002786 """
2787 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002788
2789 assert True is key._only_public
2790 assert 2048 == key.bits()
2791 assert TYPE_RSA == key.type()
2792
2793 def test_invalid_type(self):
2794 """
2795 load_publickey doesn't support FILETYPE_TEXT.
2796 """
2797 with pytest.raises(ValueError):
2798 load_publickey(FILETYPE_TEXT, cleartextPublicKeyPEM)
2799
2800 def test_invalid_key_format(self):
2801 """
2802 load_publickey explodes on incorrect keys.
2803 """
2804 with pytest.raises(Error):
2805 load_publickey(FILETYPE_ASN1, cleartextPublicKeyPEM)
2806
2807 def test_tolerates_unicode_strings(self):
2808 """
2809 load_publickey works with text strings, not just bytes.
2810 """
Alex Gaynor03737182020-07-23 20:40:46 -04002811 serialized = cleartextPublicKeyPEM.decode("ascii")
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002812 key = load_publickey(FILETYPE_PEM, serialized)
2813 dumped_pem = dump_publickey(FILETYPE_PEM, key)
2814
2815 assert dumped_pem == cleartextPublicKeyPEM
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002816
2817
Alex Chanb00ede22017-01-30 07:24:40 +00002818class TestFunction(object):
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002819 """
Alex Chanb00ede22017-01-30 07:24:40 +00002820 Tests for free-functions in the `OpenSSL.crypto` module.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002821 """
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002822
2823 def test_load_privatekey_invalid_format(self):
2824 """
Alex Chanb00ede22017-01-30 07:24:40 +00002825 `load_privatekey` raises `ValueError` if passed an unknown filetype.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002826 """
Alex Chanb00ede22017-01-30 07:24:40 +00002827 with pytest.raises(ValueError):
2828 load_privatekey(100, root_key_pem)
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002829
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002830 def test_load_privatekey_invalid_passphrase_type(self):
2831 """
Alex Chanb00ede22017-01-30 07:24:40 +00002832 `load_privatekey` raises `TypeError` if passed a passphrase that is
2833 neither a `str` nor a callable.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002834 """
Alex Chanb00ede22017-01-30 07:24:40 +00002835 with pytest.raises(TypeError):
2836 load_privatekey(
Alex Gaynor03737182020-07-23 20:40:46 -04002837 FILETYPE_PEM, encryptedPrivateKeyPEMPassphrase, object()
2838 )
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002839
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002840 def test_load_privatekey_wrongPassphrase(self):
2841 """
Alex Chanb00ede22017-01-30 07:24:40 +00002842 `load_privatekey` raises `OpenSSL.crypto.Error` when it is passed an
2843 encrypted PEM and an incorrect passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002844 """
Alex Chanb00ede22017-01-30 07:24:40 +00002845 with pytest.raises(Error) as err:
2846 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, b"quack")
2847 assert err.value.args[0] != []
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002848
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002849 def test_load_privatekey_passphraseWrongType(self):
2850 """
Alex Chanb00ede22017-01-30 07:24:40 +00002851 `load_privatekey` raises `ValueError` when it is passeda passphrase
2852 with a private key encoded in a format, that doesn't support
2853 encryption.
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002854 """
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05002855 key = load_privatekey(FILETYPE_PEM, root_key_pem)
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002856 blob = dump_privatekey(FILETYPE_ASN1, key)
Alex Chanb00ede22017-01-30 07:24:40 +00002857 with pytest.raises(ValueError):
2858 load_privatekey(FILETYPE_ASN1, blob, "secret")
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002859
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002860 def test_load_privatekey_passphrase(self):
2861 """
Alex Chanb00ede22017-01-30 07:24:40 +00002862 `load_privatekey` can create a `PKey` object from an encrypted PEM
2863 string if given the passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002864 """
2865 key = load_privatekey(
Alex Gaynor03737182020-07-23 20:40:46 -04002866 FILETYPE_PEM,
2867 encryptedPrivateKeyPEM,
2868 encryptedPrivateKeyPEMPassphrase,
2869 )
Alex Gaynor01f90a12019-02-07 09:14:48 -05002870 assert isinstance(key, PKey)
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002871
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002872 def test_load_privatekey_passphrase_exception(self):
2873 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002874 If the passphrase callback raises an exception, that exception is
Alex Chanb00ede22017-01-30 07:24:40 +00002875 raised by `load_privatekey`.
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002876 """
Alex Gaynor03737182020-07-23 20:40:46 -04002877
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002878 def cb(ignored):
2879 raise ArithmeticError
2880
Alex Gaynor791212d2015-09-05 15:46:08 -04002881 with pytest.raises(ArithmeticError):
2882 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002883
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002884 def test_load_privatekey_wrongPassphraseCallback(self):
2885 """
Alex Chanb00ede22017-01-30 07:24:40 +00002886 `load_privatekey` raises `OpenSSL.crypto.Error` when it
Jean-Paul Calderoned440a082011-09-14 11:02:05 -04002887 is passed an encrypted PEM and a passphrase callback which returns an
2888 incorrect passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002889 """
2890 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002891
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002892 def cb(*a):
2893 called.append(None)
Alex Gaynore7f51982016-09-11 11:48:14 -04002894 return b"quack"
Alex Gaynor03737182020-07-23 20:40:46 -04002895
Alex Chanb00ede22017-01-30 07:24:40 +00002896 with pytest.raises(Error) as err:
2897 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
2898 assert called
2899 assert err.value.args[0] != []
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002900
2901 def test_load_privatekey_passphraseCallback(self):
2902 """
Alex Chanb00ede22017-01-30 07:24:40 +00002903 `load_privatekey` can create a `PKey` object from an encrypted PEM
2904 string if given a passphrase callback which returns the correct
2905 password.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002906 """
2907 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002908
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002909 def cb(writing):
2910 called.append(writing)
2911 return encryptedPrivateKeyPEMPassphrase
Alex Gaynor03737182020-07-23 20:40:46 -04002912
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002913 key = load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
Alex Gaynor01f90a12019-02-07 09:14:48 -05002914 assert isinstance(key, PKey)
Alex Chanb00ede22017-01-30 07:24:40 +00002915 assert called == [False]
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002916
Jean-Paul Calderone105cb952011-09-14 10:16:46 -04002917 def test_load_privatekey_passphrase_wrong_return_type(self):
2918 """
Alex Chanb00ede22017-01-30 07:24:40 +00002919 `load_privatekey` raises `ValueError` if the passphrase callback
2920 returns something other than a byte string.
Jean-Paul Calderone105cb952011-09-14 10:16:46 -04002921 """
Alex Chanb00ede22017-01-30 07:24:40 +00002922 with pytest.raises(ValueError):
2923 load_privatekey(
Alex Gaynor03737182020-07-23 20:40:46 -04002924 FILETYPE_PEM, encryptedPrivateKeyPEM, lambda *args: 3
2925 )
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002926
Alex Chanfb078d82017-04-20 11:16:15 +01002927 def test_dump_privatekey_wrong_args(self):
2928 """
2929 `dump_privatekey` raises `TypeError` if called with a `cipher`
2930 argument but no `passphrase` argument.
2931 """
2932 key = PKey()
2933 key.generate_key(TYPE_RSA, 512)
2934 with pytest.raises(TypeError):
2935 dump_privatekey(FILETYPE_PEM, key, cipher=GOOD_CIPHER)
2936
Paul Kehrercded9932017-06-29 18:43:42 -05002937 def test_dump_privatekey_not_rsa_key(self):
2938 """
2939 `dump_privatekey` raises `TypeError` if called with a key that is
2940 not RSA.
2941 """
2942 key = PKey()
2943 key.generate_key(TYPE_DSA, 512)
2944 with pytest.raises(TypeError):
2945 dump_privatekey(FILETYPE_TEXT, key)
2946
2947 def test_dump_privatekey_invalid_pkey(self):
2948 with pytest.raises(TypeError):
2949 dump_privatekey(FILETYPE_TEXT, object())
2950
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002951 def test_dump_privatekey_unknown_cipher(self):
2952 """
Alex Chanb00ede22017-01-30 07:24:40 +00002953 `dump_privatekey` raises `ValueError` if called with an unrecognized
2954 cipher name.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002955 """
2956 key = PKey()
2957 key.generate_key(TYPE_RSA, 512)
Alex Chanb00ede22017-01-30 07:24:40 +00002958 with pytest.raises(ValueError):
2959 dump_privatekey(FILETYPE_PEM, key, BAD_CIPHER, "passphrase")
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002960
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002961 def test_dump_privatekey_invalid_passphrase_type(self):
2962 """
Alex Chanb00ede22017-01-30 07:24:40 +00002963 `dump_privatekey` raises `TypeError` if called with a passphrase which
2964 is neither a `str` nor a callable.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002965 """
2966 key = PKey()
2967 key.generate_key(TYPE_RSA, 512)
Alex Chanb00ede22017-01-30 07:24:40 +00002968 with pytest.raises(TypeError):
2969 dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, object())
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002970
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002971 def test_dump_privatekey_invalid_filetype(self):
2972 """
Alex Chanb00ede22017-01-30 07:24:40 +00002973 `dump_privatekey` raises `ValueError` if called with an unrecognized
2974 filetype.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002975 """
2976 key = PKey()
2977 key.generate_key(TYPE_RSA, 512)
Alex Chanb00ede22017-01-30 07:24:40 +00002978 with pytest.raises(ValueError):
2979 dump_privatekey(100, key)
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002980
Alex Chanb00ede22017-01-30 07:24:40 +00002981 def test_load_privatekey_passphrase_callback_length(self):
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002982 """
Alex Chanb00ede22017-01-30 07:24:40 +00002983 `crypto.load_privatekey` should raise an error when the passphrase
2984 provided by the callback is too long, not silently truncate it.
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002985 """
Alex Gaynor03737182020-07-23 20:40:46 -04002986
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002987 def cb(ignored):
2988 return "a" * 1025
2989
Alex Gaynor791212d2015-09-05 15:46:08 -04002990 with pytest.raises(ValueError):
2991 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002992
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002993 def test_dump_privatekey_passphrase(self):
2994 """
Alex Chanb00ede22017-01-30 07:24:40 +00002995 `dump_privatekey` writes an encrypted PEM when given a passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002996 """
Alex Gaynore7f51982016-09-11 11:48:14 -04002997 passphrase = b"foo"
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05002998 key = load_privatekey(FILETYPE_PEM, root_key_pem)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002999 pem = dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, passphrase)
Alex Gaynor12576002019-11-18 00:18:50 -05003000 assert isinstance(pem, bytes)
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04003001 loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
Alex Gaynor01f90a12019-02-07 09:14:48 -05003002 assert isinstance(loadedKey, PKey)
Alex Chanb00ede22017-01-30 07:24:40 +00003003 assert loadedKey.type() == key.type()
3004 assert loadedKey.bits() == key.bits()
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04003005
Alex Chanb00ede22017-01-30 07:24:40 +00003006 def test_dump_privatekey_passphrase_wrong_type(self):
Ziga Seilnacht376cf972009-12-22 16:04:10 +01003007 """
Alex Chanb00ede22017-01-30 07:24:40 +00003008 `dump_privatekey` raises `ValueError` when it is passed a passphrase
3009 with a private key encoded in a format, that doesn't support
3010 encryption.
Ziga Seilnacht376cf972009-12-22 16:04:10 +01003011 """
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003012 key = load_privatekey(FILETYPE_PEM, root_key_pem)
Alex Gaynor791212d2015-09-05 15:46:08 -04003013 with pytest.raises(ValueError):
3014 dump_privatekey(FILETYPE_ASN1, key, GOOD_CIPHER, "secret")
Ziga Seilnacht376cf972009-12-22 16:04:10 +01003015
Rick Dean5b7b6372009-04-01 11:34:06 -05003016 def test_dump_certificate(self):
3017 """
Alex Chanb00ede22017-01-30 07:24:40 +00003018 `dump_certificate` writes PEM, DER, and text.
Rick Dean5b7b6372009-04-01 11:34:06 -05003019 """
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003020 pemData = root_cert_pem + root_key_pem
Rick Dean5b7b6372009-04-01 11:34:06 -05003021 cert = load_certificate(FILETYPE_PEM, pemData)
3022 dumped_pem = dump_certificate(FILETYPE_PEM, cert)
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003023 assert dumped_pem == root_cert_pem
Rick Dean5b7b6372009-04-01 11:34:06 -05003024 dumped_der = dump_certificate(FILETYPE_ASN1, cert)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003025 good_der = _runopenssl(dumped_pem, b"x509", b"-outform", b"DER")
Alex Chanb00ede22017-01-30 07:24:40 +00003026 assert dumped_der == good_der
Rick Dean5b7b6372009-04-01 11:34:06 -05003027 cert2 = load_certificate(FILETYPE_ASN1, dumped_der)
3028 dumped_pem2 = dump_certificate(FILETYPE_PEM, cert2)
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003029 assert dumped_pem2 == root_cert_pem
Rick Dean5b7b6372009-04-01 11:34:06 -05003030 dumped_text = dump_certificate(FILETYPE_TEXT, cert)
Paul Kehrerc45a6ea2020-08-03 15:54:20 -05003031 assert len(dumped_text) > 500
Rick Dean5b7b6372009-04-01 11:34:06 -05003032
Alex Gaynor37726112016-07-04 09:51:32 -04003033 def test_dump_certificate_bad_type(self):
3034 """
Alex Chanb00ede22017-01-30 07:24:40 +00003035 `dump_certificate` raises a `ValueError` if it's called with
Alex Gaynor37726112016-07-04 09:51:32 -04003036 a bad type.
3037 """
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003038 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Alex Gaynor37726112016-07-04 09:51:32 -04003039 with pytest.raises(ValueError):
3040 dump_certificate(object(), cert)
3041
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08003042 def test_dump_privatekey_pem(self):
Rick Dean5b7b6372009-04-01 11:34:06 -05003043 """
Alex Chanb00ede22017-01-30 07:24:40 +00003044 `dump_privatekey` writes a PEM
Rick Dean5b7b6372009-04-01 11:34:06 -05003045 """
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003046 key = load_privatekey(FILETYPE_PEM, root_key_pem)
Alex Chanb00ede22017-01-30 07:24:40 +00003047 assert key.check()
Rick Dean5b7b6372009-04-01 11:34:06 -05003048 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003049 assert dumped_pem == normalized_root_key_pem
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08003050
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08003051 def test_dump_privatekey_asn1(self):
3052 """
Alex Chanb00ede22017-01-30 07:24:40 +00003053 `dump_privatekey` writes a DER
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08003054 """
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003055 key = load_privatekey(FILETYPE_PEM, root_key_pem)
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08003056
Rick Dean5b7b6372009-04-01 11:34:06 -05003057 dumped_der = dump_privatekey(FILETYPE_ASN1, key)
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003058 assert dumped_der == root_key_der
3059
3060 def test_load_privatekey_asn1(self):
3061 """
3062 `dump_privatekey` writes a DER
3063 """
3064 key = load_privatekey(FILETYPE_ASN1, root_key_der)
3065 assert key.bits() == 3072
3066 assert key.type() == TYPE_RSA
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08003067
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08003068 def test_dump_privatekey_text(self):
3069 """
Alex Chanb00ede22017-01-30 07:24:40 +00003070 `dump_privatekey` writes a text
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08003071 """
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003072 key = load_privatekey(FILETYPE_PEM, root_key_pem)
Rick Dean5b7b6372009-04-01 11:34:06 -05003073 dumped_text = dump_privatekey(FILETYPE_TEXT, key)
Paul Kehrerc45a6ea2020-08-03 15:54:20 -05003074 assert len(dumped_text) > 500
Rick Dean5b7b6372009-04-01 11:34:06 -05003075
Cory Benfield6492f7c2015-10-27 16:57:58 +09003076 def test_dump_publickey_pem(self):
3077 """
Cory Benfield11c10192015-10-27 17:23:03 +09003078 dump_publickey writes a PEM.
Cory Benfield6492f7c2015-10-27 16:57:58 +09003079 """
3080 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
3081 dumped_pem = dump_publickey(FILETYPE_PEM, key)
Cory Benfieldd86f1d82015-10-27 17:25:17 +09003082 assert dumped_pem == cleartextPublicKeyPEM
Cory Benfield6492f7c2015-10-27 16:57:58 +09003083
3084 def test_dump_publickey_asn1(self):
3085 """
Cory Benfield11c10192015-10-27 17:23:03 +09003086 dump_publickey writes a DER.
Cory Benfield6492f7c2015-10-27 16:57:58 +09003087 """
3088 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
3089 dumped_der = dump_publickey(FILETYPE_ASN1, key)
3090 key2 = load_publickey(FILETYPE_ASN1, dumped_der)
3091 dumped_pem2 = dump_publickey(FILETYPE_PEM, key2)
Cory Benfieldd86f1d82015-10-27 17:25:17 +09003092 assert dumped_pem2 == cleartextPublicKeyPEM
Cory Benfield6492f7c2015-10-27 16:57:58 +09003093
Cory Benfielde02c7d82015-10-27 17:34:49 +09003094 def test_dump_publickey_invalid_type(self):
3095 """
3096 dump_publickey doesn't support FILETYPE_TEXT.
3097 """
3098 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
3099
3100 with pytest.raises(ValueError):
3101 dump_publickey(FILETYPE_TEXT, key)
3102
Rick Dean5b7b6372009-04-01 11:34:06 -05003103 def test_dump_certificate_request(self):
3104 """
Alex Chanb00ede22017-01-30 07:24:40 +00003105 `dump_certificate_request` writes a PEM, DER, and text.
Rick Dean5b7b6372009-04-01 11:34:06 -05003106 """
Alex Gaynor31287502015-09-05 16:11:27 -04003107 req = load_certificate_request(
Alex Gaynor03737182020-07-23 20:40:46 -04003108 FILETYPE_PEM, cleartextCertificateRequestPEM
3109 )
Rick Dean5b7b6372009-04-01 11:34:06 -05003110 dumped_pem = dump_certificate_request(FILETYPE_PEM, req)
Alex Chanb00ede22017-01-30 07:24:40 +00003111 assert dumped_pem == cleartextCertificateRequestPEM
Rick Dean5b7b6372009-04-01 11:34:06 -05003112 dumped_der = dump_certificate_request(FILETYPE_ASN1, req)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003113 good_der = _runopenssl(dumped_pem, b"req", b"-outform", b"DER")
Alex Chanb00ede22017-01-30 07:24:40 +00003114 assert dumped_der == good_der
Rick Dean5b7b6372009-04-01 11:34:06 -05003115 req2 = load_certificate_request(FILETYPE_ASN1, dumped_der)
3116 dumped_pem2 = dump_certificate_request(FILETYPE_PEM, req2)
Alex Chanb00ede22017-01-30 07:24:40 +00003117 assert dumped_pem2 == cleartextCertificateRequestPEM
Rick Dean5b7b6372009-04-01 11:34:06 -05003118 dumped_text = dump_certificate_request(FILETYPE_TEXT, req)
Paul Kehrerc45a6ea2020-08-03 15:54:20 -05003119 assert len(dumped_text) > 500
Alex Chanb00ede22017-01-30 07:24:40 +00003120 with pytest.raises(ValueError):
3121 dump_certificate_request(100, req)
Rick Dean5b7b6372009-04-01 11:34:06 -05003122
Alex Chanb00ede22017-01-30 07:24:40 +00003123 def test_dump_privatekey_passphrase_callback(self):
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04003124 """
Alex Chanb00ede22017-01-30 07:24:40 +00003125 `dump_privatekey` writes an encrypted PEM when given a callback
Alex Gaynor791212d2015-09-05 15:46:08 -04003126 which returns the correct passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04003127 """
Alex Gaynore7f51982016-09-11 11:48:14 -04003128 passphrase = b"foo"
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04003129 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003130
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04003131 def cb(writing):
3132 called.append(writing)
3133 return passphrase
Alex Gaynor03737182020-07-23 20:40:46 -04003134
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003135 key = load_privatekey(FILETYPE_PEM, root_key_pem)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003136 pem = dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
Alex Gaynor12576002019-11-18 00:18:50 -05003137 assert isinstance(pem, bytes)
Alex Chanb00ede22017-01-30 07:24:40 +00003138 assert called == [True]
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04003139 loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
Alex Gaynor01f90a12019-02-07 09:14:48 -05003140 assert isinstance(loadedKey, PKey)
Alex Chanb00ede22017-01-30 07:24:40 +00003141 assert loadedKey.type() == key.type()
3142 assert loadedKey.bits() == key.bits()
Rick Dean5b7b6372009-04-01 11:34:06 -05003143
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01003144 def test_dump_privatekey_passphrase_exception(self):
3145 """
Alex Chanb00ede22017-01-30 07:24:40 +00003146 `dump_privatekey` should not overwrite the exception raised
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01003147 by the passphrase callback.
3148 """
Alex Gaynor03737182020-07-23 20:40:46 -04003149
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01003150 def cb(ignored):
3151 raise ArithmeticError
3152
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003153 key = load_privatekey(FILETYPE_PEM, root_key_pem)
Alex Gaynor85b49702015-09-05 16:30:59 -04003154 with pytest.raises(ArithmeticError):
3155 dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01003156
Ziga Seilnacht781295a2009-12-22 14:58:01 +01003157 def test_dump_privatekey_passphraseCallbackLength(self):
3158 """
Alex Chanb00ede22017-01-30 07:24:40 +00003159 `crypto.dump_privatekey` should raise an error when the passphrase
3160 provided by the callback is too long, not silently truncate it.
Ziga Seilnacht781295a2009-12-22 14:58:01 +01003161 """
Alex Gaynor03737182020-07-23 20:40:46 -04003162
Ziga Seilnacht781295a2009-12-22 14:58:01 +01003163 def cb(ignored):
3164 return "a" * 1025
3165
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003166 key = load_privatekey(FILETYPE_PEM, root_key_pem)
Alex Gaynor85b49702015-09-05 16:30:59 -04003167 with pytest.raises(ValueError):
3168 dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
Ziga Seilnacht781295a2009-12-22 14:58:01 +01003169
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07003170 def test_load_pkcs7_data_pem(self):
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003171 """
Alex Chanb00ede22017-01-30 07:24:40 +00003172 `load_pkcs7_data` accepts a PKCS#7 string and returns an instance of
3173 `PKCS`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003174 """
3175 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
Alex Chanb00ede22017-01-30 07:24:40 +00003176 assert isinstance(pkcs7, PKCS7)
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003177
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07003178 def test_load_pkcs7_data_asn1(self):
Alex Gaynor9875a912014-08-14 13:35:05 -07003179 """
Alex Chanb00ede22017-01-30 07:24:40 +00003180 `load_pkcs7_data` accepts a bytes containing ASN1 data representing
3181 PKCS#7 and returns an instance of `PKCS7`.
Alex Gaynor9875a912014-08-14 13:35:05 -07003182 """
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07003183 pkcs7 = load_pkcs7_data(FILETYPE_ASN1, pkcs7DataASN1)
Alex Chanb00ede22017-01-30 07:24:40 +00003184 assert isinstance(pkcs7, PKCS7)
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07003185
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08003186 def test_load_pkcs7_data_invalid(self):
3187 """
Alex Chanb00ede22017-01-30 07:24:40 +00003188 If the data passed to `load_pkcs7_data` is invalid, `Error` is raised.
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08003189 """
Alex Chanb00ede22017-01-30 07:24:40 +00003190 with pytest.raises(Error):
3191 load_pkcs7_data(FILETYPE_PEM, b"foo")
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08003192
Alex Gaynor09a386e2016-07-03 09:32:44 -04003193 def test_load_pkcs7_type_invalid(self):
3194 """
Alex Chanb00ede22017-01-30 07:24:40 +00003195 If the type passed to `load_pkcs7_data`, `ValueError` is raised.
Alex Gaynor09a386e2016-07-03 09:32:44 -04003196 """
3197 with pytest.raises(ValueError):
3198 load_pkcs7_data(object(), b"foo")
3199
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08003200
Alex Chan9e2a9932017-01-25 14:29:19 +00003201class TestLoadCertificate(object):
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05003202 """
Alex Chan9e2a9932017-01-25 14:29:19 +00003203 Tests for `load_certificate_request`.
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05003204 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003205
Alex Chan9e2a9932017-01-25 14:29:19 +00003206 def test_bad_file_type(self):
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05003207 """
Alex Chan9e2a9932017-01-25 14:29:19 +00003208 If the file type passed to `load_certificate_request` is neither
3209 `FILETYPE_PEM` nor `FILETYPE_ASN1` then `ValueError` is raised.
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05003210 """
Alex Gaynor7778e792016-07-03 23:38:48 -04003211 with pytest.raises(ValueError):
3212 load_certificate_request(object(), b"")
3213 with pytest.raises(ValueError):
3214 load_certificate(object(), b"")
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05003215
Alex Gaynor37726112016-07-04 09:51:32 -04003216 def test_bad_certificate(self):
3217 """
Alex Chan9e2a9932017-01-25 14:29:19 +00003218 If the bytes passed to `load_certificate` are not a valid certificate,
3219 an exception is raised.
Alex Gaynor37726112016-07-04 09:51:32 -04003220 """
3221 with pytest.raises(Error):
3222 load_certificate(FILETYPE_ASN1, b"lol")
3223
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05003224
Alex Chanb00ede22017-01-30 07:24:40 +00003225class TestPKCS7(object):
Jean-Paul Calderone68649052009-07-17 21:14:27 -04003226 """
Alex Chanb00ede22017-01-30 07:24:40 +00003227 Tests for `PKCS7`.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04003228 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003229
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003230 def test_type_is_signed(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003231 """
Alex Chanb00ede22017-01-30 07:24:40 +00003232 `PKCS7.type_is_signed` returns `True` if the PKCS7 object is of
3233 the type *signed*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003234 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003235 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
Alex Chanb00ede22017-01-30 07:24:40 +00003236 assert pkcs7.type_is_signed()
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003237
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003238 def test_type_is_enveloped(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003239 """
Alex Chanb00ede22017-01-30 07:24:40 +00003240 `PKCS7.type_is_enveloped` returns `False` if the PKCS7 object is not
3241 of the type *enveloped*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003242 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003243 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
Alex Chanb00ede22017-01-30 07:24:40 +00003244 assert not pkcs7.type_is_enveloped()
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003245
Alex Chanb00ede22017-01-30 07:24:40 +00003246 def test_type_is_signed_and_enveloped(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003247 """
Alex Chanb00ede22017-01-30 07:24:40 +00003248 `PKCS7.type_is_signedAndEnveloped` returns `False`
Alex Gaynor791212d2015-09-05 15:46:08 -04003249 if the PKCS7 object is not of the type *signed and enveloped*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003250 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003251 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
Alex Chanb00ede22017-01-30 07:24:40 +00003252 assert not pkcs7.type_is_signedAndEnveloped()
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003253
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04003254 def test_type_is_data(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003255 """
Alex Chanb00ede22017-01-30 07:24:40 +00003256 `PKCS7.type_is_data` returns `False` if the PKCS7 object is not of
3257 the type data.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003258 """
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04003259 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
Alex Chanb00ede22017-01-30 07:24:40 +00003260 assert not pkcs7.type_is_data()
Jean-Paul Calderone97b28ca2010-07-30 10:56:07 -04003261
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04003262 def test_get_type_name(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003263 """
Alex Chanb00ede22017-01-30 07:24:40 +00003264 `PKCS7.get_type_name` returns a `str` giving the
Alex Gaynor791212d2015-09-05 15:46:08 -04003265 type name.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003266 """
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04003267 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
Alex Gaynor03737182020-07-23 20:40:46 -04003268 assert pkcs7.get_type_name() == b"pkcs7-signedData"
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04003269
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04003270 def test_attribute(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003271 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003272 If an attribute other than one of the methods tested here is accessed
Alex Chanb00ede22017-01-30 07:24:40 +00003273 on an instance of `PKCS7`, `AttributeError` is raised.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003274 """
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04003275 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
Alex Chanb00ede22017-01-30 07:24:40 +00003276 with pytest.raises(AttributeError):
3277 pkcs7.foo
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04003278
3279
Alex Chanb00ede22017-01-30 07:24:40 +00003280class TestNetscapeSPKI(_PKeyInteractionTestsMixin):
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003281 """
Alex Chanb00ede22017-01-30 07:24:40 +00003282 Tests for `OpenSSL.crypto.NetscapeSPKI`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003283 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003284
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04003285 def signable(self):
3286 """
Alex Chanb00ede22017-01-30 07:24:40 +00003287 Return a new `NetscapeSPKI` for use with signing tests.
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04003288 """
3289 return NetscapeSPKI()
3290
Jean-Paul Calderone68649052009-07-17 21:14:27 -04003291 def test_type(self):
3292 """
Alex Gaynor01f90a12019-02-07 09:14:48 -05003293 `NetscapeSPKI` can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04003294 """
Alex Gaynor03737182020-07-23 20:40:46 -04003295 assert is_consistent_type(NetscapeSPKI, "NetscapeSPKI")
Jean-Paul Calderone68649052009-07-17 21:14:27 -04003296
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003297 def test_construction(self):
3298 """
Alex Gaynor01f90a12019-02-07 09:14:48 -05003299 `NetscapeSPKI` returns an instance of `NetscapeSPKI`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003300 """
3301 nspki = NetscapeSPKI()
Alex Gaynor01f90a12019-02-07 09:14:48 -05003302 assert isinstance(nspki, NetscapeSPKI)
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003303
Jean-Paul Calderone969efaa2010-08-03 18:19:19 -04003304 def test_invalid_attribute(self):
3305 """
Alex Chanb00ede22017-01-30 07:24:40 +00003306 Accessing a non-existent attribute of a `NetscapeSPKI` instance
3307 causes an `AttributeError` to be raised.
Jean-Paul Calderone969efaa2010-08-03 18:19:19 -04003308 """
3309 nspki = NetscapeSPKI()
Alex Chanb00ede22017-01-30 07:24:40 +00003310 with pytest.raises(AttributeError):
3311 nspki.foo
Jean-Paul Calderone969efaa2010-08-03 18:19:19 -04003312
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04003313 def test_b64_encode(self):
3314 """
Alex Chanb00ede22017-01-30 07:24:40 +00003315 `NetscapeSPKI.b64_encode` encodes the certificate to a base64 blob.
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04003316 """
3317 nspki = NetscapeSPKI()
3318 blob = nspki.b64_encode()
Alex Gaynor12576002019-11-18 00:18:50 -05003319 assert isinstance(blob, bytes)
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04003320
3321
Paul Kehrer2c605ba2016-03-11 11:17:26 -04003322class TestRevoked(object):
3323 """
Alex Chandeec9342016-12-19 22:00:38 +00003324 Tests for `OpenSSL.crypto.Revoked`.
Paul Kehrer2c605ba2016-03-11 11:17:26 -04003325 """
Alex Gaynor03737182020-07-23 20:40:46 -04003326
Paul Kehrer2c605ba2016-03-11 11:17:26 -04003327 def test_ignores_unsupported_revoked_cert_extension_get_reason(self):
3328 """
3329 The get_reason method on the Revoked class checks to see if the
3330 extension is NID_crl_reason and should skip it otherwise. This test
3331 loads a CRL with extensions it should ignore.
3332 """
3333 crl = load_crl(FILETYPE_PEM, crlDataUnsupportedExtension)
3334 revoked = crl.get_revoked()
3335 reason = revoked[1].get_reason()
Alex Gaynor03737182020-07-23 20:40:46 -04003336 assert reason == b"Unspecified"
Paul Kehrer2c605ba2016-03-11 11:17:26 -04003337
3338 def test_ignores_unsupported_revoked_cert_extension_set_new_reason(self):
3339 crl = load_crl(FILETYPE_PEM, crlDataUnsupportedExtension)
3340 revoked = crl.get_revoked()
3341 revoked[1].set_reason(None)
3342 reason = revoked[1].get_reason()
3343 assert reason is None
3344
Rick Dean536ba022009-07-24 23:57:27 -05003345 def test_construction(self):
3346 """
Alex Chandeec9342016-12-19 22:00:38 +00003347 Confirm we can create `OpenSSL.crypto.Revoked`. Check that it is
3348 empty.
Rick Dean536ba022009-07-24 23:57:27 -05003349 """
3350 revoked = Revoked()
Alex Chandeec9342016-12-19 22:00:38 +00003351 assert isinstance(revoked, Revoked)
3352 assert type(revoked) == Revoked
Alex Gaynor03737182020-07-23 20:40:46 -04003353 assert revoked.get_serial() == b"00"
Alex Chandeec9342016-12-19 22:00:38 +00003354 assert revoked.get_rev_date() is None
3355 assert revoked.get_reason() is None
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003356
Rick Dean536ba022009-07-24 23:57:27 -05003357 def test_serial(self):
3358 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003359 Confirm we can set and get serial numbers from
Alex Chandeec9342016-12-19 22:00:38 +00003360 `OpenSSL.crypto.Revoked`. Confirm errors are handled with grace.
Rick Dean536ba022009-07-24 23:57:27 -05003361 """
3362 revoked = Revoked()
Alex Gaynor03737182020-07-23 20:40:46 -04003363 ret = revoked.set_serial(b"10b")
Alex Chandeec9342016-12-19 22:00:38 +00003364 assert ret is None
Rick Dean536ba022009-07-24 23:57:27 -05003365 ser = revoked.get_serial()
Alex Gaynor03737182020-07-23 20:40:46 -04003366 assert ser == b"010B"
Rick Dean536ba022009-07-24 23:57:27 -05003367
Alex Gaynor03737182020-07-23 20:40:46 -04003368 revoked.set_serial(b"31ppp") # a type error would be nice
Rick Dean536ba022009-07-24 23:57:27 -05003369 ser = revoked.get_serial()
Alex Gaynor03737182020-07-23 20:40:46 -04003370 assert ser == b"31"
Rick Dean536ba022009-07-24 23:57:27 -05003371
Alex Chandeec9342016-12-19 22:00:38 +00003372 with pytest.raises(ValueError):
Alex Gaynor03737182020-07-23 20:40:46 -04003373 revoked.set_serial(b"pqrst")
Alex Chandeec9342016-12-19 22:00:38 +00003374 with pytest.raises(TypeError):
3375 revoked.set_serial(100)
Rick Dean536ba022009-07-24 23:57:27 -05003376
Rick Dean536ba022009-07-24 23:57:27 -05003377 def test_date(self):
3378 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003379 Confirm we can set and get revocation dates from
Alex Chandeec9342016-12-19 22:00:38 +00003380 `OpenSSL.crypto.Revoked`. Confirm errors are handled with grace.
Rick Dean536ba022009-07-24 23:57:27 -05003381 """
3382 revoked = Revoked()
3383 date = revoked.get_rev_date()
Alex Chandeec9342016-12-19 22:00:38 +00003384 assert date is None
Rick Dean536ba022009-07-24 23:57:27 -05003385
Alex Gaynore7f51982016-09-11 11:48:14 -04003386 now = datetime.now().strftime("%Y%m%d%H%M%SZ").encode("ascii")
Rick Dean536ba022009-07-24 23:57:27 -05003387 ret = revoked.set_rev_date(now)
Alex Chandeec9342016-12-19 22:00:38 +00003388 assert ret is None
Rick Dean536ba022009-07-24 23:57:27 -05003389 date = revoked.get_rev_date()
Alex Chandeec9342016-12-19 22:00:38 +00003390 assert date == now
Rick Dean536ba022009-07-24 23:57:27 -05003391
Rick Dean6385faf2009-07-26 00:07:47 -05003392 def test_reason(self):
3393 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003394 Confirm we can set and get revocation reasons from
Alex Chandeec9342016-12-19 22:00:38 +00003395 `OpenSSL.crypto.Revoked`. The "get" need to work as "set".
3396 Likewise, each reason of all_reasons() must work.
Rick Dean6385faf2009-07-26 00:07:47 -05003397 """
3398 revoked = Revoked()
3399 for r in revoked.all_reasons():
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003400 for x in range(2):
Rick Dean6385faf2009-07-26 00:07:47 -05003401 ret = revoked.set_reason(r)
Alex Chandeec9342016-12-19 22:00:38 +00003402 assert ret is None
Rick Dean6385faf2009-07-26 00:07:47 -05003403 reason = revoked.get_reason()
Alex Gaynor03737182020-07-23 20:40:46 -04003404 assert reason.lower().replace(b" ", b"") == r.lower().replace(
3405 b" ", b""
3406 )
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003407 r = reason # again with the resp of get
Rick Dean6385faf2009-07-26 00:07:47 -05003408
3409 revoked.set_reason(None)
Alex Chandeec9342016-12-19 22:00:38 +00003410 assert revoked.get_reason() is None
Rick Dean6385faf2009-07-26 00:07:47 -05003411
Alex Gaynor03737182020-07-23 20:40:46 -04003412 @pytest.mark.parametrize("reason", [object(), 1.0, u"foo"])
Alex Chanfb078d82017-04-20 11:16:15 +01003413 def test_set_reason_wrong_args(self, reason):
3414 """
3415 `Revoked.set_reason` raises `TypeError` if called with an argument
3416 which is neither `None` nor a byte string.
3417 """
3418 revoked = Revoked()
3419 with pytest.raises(TypeError):
3420 revoked.set_reason(reason)
3421
Alex Chandeec9342016-12-19 22:00:38 +00003422 def test_set_reason_invalid_reason(self):
Rick Dean6385faf2009-07-26 00:07:47 -05003423 """
Alex Chandeec9342016-12-19 22:00:38 +00003424 Calling `OpenSSL.crypto.Revoked.set_reason` with an argument which
3425 isn't a valid reason results in `ValueError` being raised.
Rick Dean6385faf2009-07-26 00:07:47 -05003426 """
3427 revoked = Revoked()
Alex Chandeec9342016-12-19 22:00:38 +00003428 with pytest.raises(ValueError):
Alex Gaynor03737182020-07-23 20:40:46 -04003429 revoked.set_reason(b"blue")
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003430
3431
Alex Chan7be83a52017-01-24 15:19:29 +00003432class TestCRL(object):
Rick Dean536ba022009-07-24 23:57:27 -05003433 """
Alex Chan7be83a52017-01-24 15:19:29 +00003434 Tests for `OpenSSL.crypto.CRL`.
Rick Dean536ba022009-07-24 23:57:27 -05003435 """
Alex Gaynor03737182020-07-23 20:40:46 -04003436
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003437 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3438 pkey = load_privatekey(FILETYPE_PEM, root_key_pem)
Rick Dean536ba022009-07-24 23:57:27 -05003439
Dan Sully44e767a2016-06-04 18:05:27 -07003440 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3441 root_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3442 intermediate_cert = load_certificate(FILETYPE_PEM, intermediate_cert_pem)
3443 intermediate_key = load_privatekey(FILETYPE_PEM, intermediate_key_pem)
3444 intermediate_server_cert = load_certificate(
Alex Gaynor03737182020-07-23 20:40:46 -04003445 FILETYPE_PEM, intermediate_server_cert_pem
3446 )
Dan Sully44e767a2016-06-04 18:05:27 -07003447 intermediate_server_key = load_privatekey(
Alex Gaynor03737182020-07-23 20:40:46 -04003448 FILETYPE_PEM, intermediate_server_key_pem
3449 )
Dan Sully44e767a2016-06-04 18:05:27 -07003450
Rick Dean536ba022009-07-24 23:57:27 -05003451 def test_construction(self):
3452 """
Alex Chan7be83a52017-01-24 15:19:29 +00003453 Confirm we can create `OpenSSL.crypto.CRL`. Check
Rick Dean536ba022009-07-24 23:57:27 -05003454 that it is empty
3455 """
3456 crl = CRL()
Alex Chan7be83a52017-01-24 15:19:29 +00003457 assert isinstance(crl, CRL)
3458 assert crl.get_revoked() is None
Jean-Paul Calderone2efd03e2010-01-30 13:59:55 -05003459
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003460 def _get_crl(self):
Rick Dean536ba022009-07-24 23:57:27 -05003461 """
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003462 Get a new ``CRL`` with a revocation.
Rick Dean536ba022009-07-24 23:57:27 -05003463 """
3464 crl = CRL()
3465 revoked = Revoked()
Alex Gaynore7f51982016-09-11 11:48:14 -04003466 now = datetime.now().strftime("%Y%m%d%H%M%SZ").encode("ascii")
Rick Dean536ba022009-07-24 23:57:27 -05003467 revoked.set_rev_date(now)
Alex Gaynor03737182020-07-23 20:40:46 -04003468 revoked.set_serial(b"3ab")
3469 revoked.set_reason(b"sUpErSeDEd")
Rick Dean536ba022009-07-24 23:57:27 -05003470 crl.add_revoked(revoked)
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003471 return crl
Rick Dean536ba022009-07-24 23:57:27 -05003472
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003473 def test_export_pem(self):
3474 """
3475 If not passed a format, ``CRL.export`` returns a "PEM" format string
3476 representing a serial number, a revoked reason, and certificate issuer
3477 information.
3478 """
Rick Dean536ba022009-07-24 23:57:27 -05003479 # PEM format
Paul Kehrer7d5a3bf2019-01-21 12:24:02 -06003480 dumped_crl = self._get_crl().export(
Alex Gaynor173e4ba2017-06-30 08:01:12 -07003481 self.cert, self.pkey, days=20, digest=b"sha256"
3482 )
Paul Kehrer7d5a3bf2019-01-21 12:24:02 -06003483 crl = x509.load_pem_x509_crl(dumped_crl, backend)
3484 revoked = crl.get_revoked_certificate_by_serial_number(0x03AB)
3485 assert revoked is not None
Alex Gaynor03737182020-07-23 20:40:46 -04003486 assert crl.issuer == x509.Name(
3487 [
3488 x509.NameAttribute(x509.NameOID.COUNTRY_NAME, u"US"),
3489 x509.NameAttribute(x509.NameOID.STATE_OR_PROVINCE_NAME, u"IL"),
3490 x509.NameAttribute(x509.NameOID.LOCALITY_NAME, u"Chicago"),
3491 x509.NameAttribute(x509.NameOID.ORGANIZATION_NAME, u"Testing"),
3492 x509.NameAttribute(
3493 x509.NameOID.COMMON_NAME, u"Testing Root CA"
3494 ),
3495 ]
3496 )
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003497
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003498 def test_export_der(self):
3499 """
3500 If passed ``FILETYPE_ASN1`` for the format, ``CRL.export`` returns a
3501 "DER" format string representing a serial number, a revoked reason, and
3502 certificate issuer information.
3503 """
3504 crl = self._get_crl()
Rick Dean536ba022009-07-24 23:57:27 -05003505
3506 # DER format
Paul Kehrer7d5a3bf2019-01-21 12:24:02 -06003507 dumped_crl = self._get_crl().export(
Alex Gaynor173e4ba2017-06-30 08:01:12 -07003508 self.cert, self.pkey, FILETYPE_ASN1, digest=b"md5"
3509 )
Paul Kehrer7d5a3bf2019-01-21 12:24:02 -06003510 crl = x509.load_der_x509_crl(dumped_crl, backend)
3511 revoked = crl.get_revoked_certificate_by_serial_number(0x03AB)
3512 assert revoked is not None
Alex Gaynor03737182020-07-23 20:40:46 -04003513 assert crl.issuer == x509.Name(
3514 [
3515 x509.NameAttribute(x509.NameOID.COUNTRY_NAME, u"US"),
3516 x509.NameAttribute(x509.NameOID.STATE_OR_PROVINCE_NAME, u"IL"),
3517 x509.NameAttribute(x509.NameOID.LOCALITY_NAME, u"Chicago"),
3518 x509.NameAttribute(x509.NameOID.ORGANIZATION_NAME, u"Testing"),
3519 x509.NameAttribute(
3520 x509.NameOID.COMMON_NAME, u"Testing Root CA"
3521 ),
3522 ]
3523 )
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003524
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003525 def test_export_text(self):
3526 """
3527 If passed ``FILETYPE_TEXT`` for the format, ``CRL.export`` returns a
3528 text format string like the one produced by the openssl command line
3529 tool.
3530 """
3531 crl = self._get_crl()
3532
Rick Dean536ba022009-07-24 23:57:27 -05003533 # text format
Alex Gaynor173e4ba2017-06-30 08:01:12 -07003534 dumped_text = crl.export(
3535 self.cert, self.pkey, type=FILETYPE_TEXT, digest=b"md5"
3536 )
Paul Kehrerc45a6ea2020-08-03 15:54:20 -05003537 assert len(dumped_text) > 500
Rick Dean536ba022009-07-24 23:57:27 -05003538
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003539 def test_export_custom_digest(self):
3540 """
3541 If passed the name of a digest function, ``CRL.export`` uses a
3542 signature algorithm based on that digest function.
3543 """
3544 crl = self._get_crl()
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003545 dumped_crl = crl.export(self.cert, self.pkey, digest=b"sha1")
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003546 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
Alex Gaynor03737182020-07-23 20:40:46 -04003547 text.index(b"Signature Algorithm: sha1")
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003548
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003549 def test_export_md5_digest(self):
3550 """
3551 If passed md5 as the digest function, ``CRL.export`` uses md5 and does
3552 not emit a deprecation warning.
3553 """
3554 crl = self._get_crl()
Alex Chan7be83a52017-01-24 15:19:29 +00003555 with pytest.warns(None) as catcher:
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003556 simplefilter("always")
Alex Chan7be83a52017-01-24 15:19:29 +00003557 assert 0 == len(catcher)
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003558 dumped_crl = crl.export(self.cert, self.pkey, digest=b"md5")
3559 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
Alex Gaynor03737182020-07-23 20:40:46 -04003560 text.index(b"Signature Algorithm: md5")
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003561
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003562 def test_export_default_digest(self):
3563 """
Alex Gaynor173e4ba2017-06-30 08:01:12 -07003564 If not passed the name of a digest function, ``CRL.export`` raises a
3565 ``TypeError``.
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003566 """
3567 crl = self._get_crl()
Alex Gaynor173e4ba2017-06-30 08:01:12 -07003568 with pytest.raises(TypeError):
3569 crl.export(self.cert, self.pkey)
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003570
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003571 def test_export_invalid(self):
3572 """
Alex Chan7be83a52017-01-24 15:19:29 +00003573 If `CRL.export` is used with an uninitialized `X509` instance,
3574 `OpenSSL.crypto.Error` is raised.
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003575 """
3576 crl = CRL()
Alex Chan7be83a52017-01-24 15:19:29 +00003577 with pytest.raises(Error):
Alex Gaynor173e4ba2017-06-30 08:01:12 -07003578 crl.export(X509(), PKey(), digest=b"sha256")
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003579
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003580 def test_add_revoked_keyword(self):
3581 """
Alex Chan7be83a52017-01-24 15:19:29 +00003582 `OpenSSL.CRL.add_revoked` accepts its single argument as the
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04003583 ``revoked`` keyword argument.
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003584 """
3585 crl = CRL()
3586 revoked = Revoked()
Paul Kehrerb11bffc2016-03-10 18:30:29 -04003587 revoked.set_serial(b"01")
Paul Kehrer2fe23b02016-03-09 22:02:15 -04003588 revoked.set_rev_date(b"20160310020145Z")
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003589 crl.add_revoked(revoked=revoked)
Alex Chan7be83a52017-01-24 15:19:29 +00003590 assert isinstance(crl.get_revoked()[0], Revoked)
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003591
Jean-Paul Calderone883ca4b2010-01-30 13:55:13 -05003592 def test_export_wrong_args(self):
3593 """
Alex Chan7be83a52017-01-24 15:19:29 +00003594 Calling `OpenSSL.CRL.export` with arguments other than the certificate,
Jean-Paul Calderonef1515862010-01-30 13:57:03 -05003595 private key, integer file type, and integer number of days it
Alex Chan7be83a52017-01-24 15:19:29 +00003596 expects, results in a `TypeError` being raised.
Jean-Paul Calderone883ca4b2010-01-30 13:55:13 -05003597 """
3598 crl = CRL()
Alex Gaynor85b49702015-09-05 16:30:59 -04003599 with pytest.raises(TypeError):
3600 crl.export(None, self.pkey, FILETYPE_PEM, 10)
3601 with pytest.raises(TypeError):
3602 crl.export(self.cert, None, FILETYPE_PEM, 10)
3603 with pytest.raises(TypeError):
3604 crl.export(self.cert, self.pkey, None, 10)
Alex Chan7be83a52017-01-24 15:19:29 +00003605 with pytest.raises(TypeError):
3606 crl.export(self.cert, FILETYPE_PEM, None)
Jean-Paul Calderonef1515862010-01-30 13:57:03 -05003607
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003608 def test_export_unknown_filetype(self):
3609 """
Alex Chan7be83a52017-01-24 15:19:29 +00003610 Calling `OpenSSL.CRL.export` with a file type other than
3611 `FILETYPE_PEM`, `FILETYPE_ASN1`, or
3612 `FILETYPE_TEXT` results in a `ValueError` being raised.
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003613 """
3614 crl = CRL()
Alex Gaynor85b49702015-09-05 16:30:59 -04003615 with pytest.raises(ValueError):
Alex Gaynor173e4ba2017-06-30 08:01:12 -07003616 crl.export(self.cert, self.pkey, 100, 10, digest=b"sha256")
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003617
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003618 def test_export_unknown_digest(self):
Bulat Gaifullin5f9eea42014-09-23 19:35:15 +04003619 """
Alex Chan7be83a52017-01-24 15:19:29 +00003620 Calling `OpenSSL.CRL.export` with an unsupported digest results
3621 in a `ValueError` being raised.
Bulat Gaifullin5f9eea42014-09-23 19:35:15 +04003622 """
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003623 crl = CRL()
Alex Chan7be83a52017-01-24 15:19:29 +00003624 with pytest.raises(ValueError):
3625 crl.export(
Alex Gaynor03737182020-07-23 20:40:46 -04003626 self.cert, self.pkey, FILETYPE_PEM, 10, b"strange-digest"
3627 )
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003628
Rick Dean536ba022009-07-24 23:57:27 -05003629 def test_get_revoked(self):
3630 """
Alex Chan7be83a52017-01-24 15:19:29 +00003631 Use python to create a simple CRL with two revocations. Get back the
3632 `Revoked` using `OpenSSL.CRL.get_revoked` and verify them.
Rick Dean536ba022009-07-24 23:57:27 -05003633 """
3634 crl = CRL()
3635
3636 revoked = Revoked()
Alex Gaynore7f51982016-09-11 11:48:14 -04003637 now = datetime.now().strftime("%Y%m%d%H%M%SZ").encode("ascii")
Rick Dean536ba022009-07-24 23:57:27 -05003638 revoked.set_rev_date(now)
Alex Gaynor03737182020-07-23 20:40:46 -04003639 revoked.set_serial(b"3ab")
Rick Dean536ba022009-07-24 23:57:27 -05003640 crl.add_revoked(revoked)
Alex Gaynor03737182020-07-23 20:40:46 -04003641 revoked.set_serial(b"100")
3642 revoked.set_reason(b"sUpErSeDEd")
Rick Dean536ba022009-07-24 23:57:27 -05003643 crl.add_revoked(revoked)
3644
3645 revs = crl.get_revoked()
Alex Chan7be83a52017-01-24 15:19:29 +00003646 assert len(revs) == 2
3647 assert type(revs[0]) == Revoked
3648 assert type(revs[1]) == Revoked
Alex Gaynor03737182020-07-23 20:40:46 -04003649 assert revs[0].get_serial() == b"03AB"
3650 assert revs[1].get_serial() == b"0100"
Alex Chan7be83a52017-01-24 15:19:29 +00003651 assert revs[0].get_rev_date() == now
3652 assert revs[1].get_rev_date() == now
Jean-Paul Calderoneecef6fa2010-01-30 13:47:18 -05003653
Rick Dean536ba022009-07-24 23:57:27 -05003654 def test_load_crl(self):
3655 """
Alex Chan7be83a52017-01-24 15:19:29 +00003656 Load a known CRL and inspect its revocations. Both EM and DER formats
3657 are loaded.
Rick Dean536ba022009-07-24 23:57:27 -05003658 """
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003659 crl = load_crl(FILETYPE_PEM, crlData)
Rick Dean536ba022009-07-24 23:57:27 -05003660 revs = crl.get_revoked()
Alex Chan7be83a52017-01-24 15:19:29 +00003661 assert len(revs) == 2
Alex Gaynor03737182020-07-23 20:40:46 -04003662 assert revs[0].get_serial() == b"03AB"
Alex Chan7be83a52017-01-24 15:19:29 +00003663 assert revs[0].get_reason() is None
Alex Gaynor03737182020-07-23 20:40:46 -04003664 assert revs[1].get_serial() == b"0100"
3665 assert revs[1].get_reason() == b"Superseded"
Rick Dean536ba022009-07-24 23:57:27 -05003666
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003667 der = _runopenssl(crlData, b"crl", b"-outform", b"DER")
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003668 crl = load_crl(FILETYPE_ASN1, der)
Rick Dean536ba022009-07-24 23:57:27 -05003669 revs = crl.get_revoked()
Alex Chan7be83a52017-01-24 15:19:29 +00003670 assert len(revs) == 2
Alex Gaynor03737182020-07-23 20:40:46 -04003671 assert revs[0].get_serial() == b"03AB"
Alex Chan7be83a52017-01-24 15:19:29 +00003672 assert revs[0].get_reason() is None
Alex Gaynor03737182020-07-23 20:40:46 -04003673 assert revs[1].get_serial() == b"0100"
3674 assert revs[1].get_reason() == b"Superseded"
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003675
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003676 def test_load_crl_bad_filetype(self):
3677 """
Alex Chan7be83a52017-01-24 15:19:29 +00003678 Calling `OpenSSL.crypto.load_crl` with an unknown file type raises a
3679 `ValueError`.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003680 """
Alex Chan7be83a52017-01-24 15:19:29 +00003681 with pytest.raises(ValueError):
3682 load_crl(100, crlData)
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003683
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003684 def test_load_crl_bad_data(self):
3685 """
Alex Chan7be83a52017-01-24 15:19:29 +00003686 Calling `OpenSSL.crypto.load_crl` with file data which can't be loaded
3687 raises a `OpenSSL.crypto.Error`.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003688 """
Alex Chan7be83a52017-01-24 15:19:29 +00003689 with pytest.raises(Error):
3690 load_crl(FILETYPE_PEM, b"hello, world")
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003691
Dan Sully44e767a2016-06-04 18:05:27 -07003692 def test_get_issuer(self):
3693 """
Alex Chan7be83a52017-01-24 15:19:29 +00003694 Load a known CRL and assert its issuer's common name is what we expect
3695 from the encoded crlData string.
Dan Sully44e767a2016-06-04 18:05:27 -07003696 """
3697 crl = load_crl(FILETYPE_PEM, crlData)
Alex Chan7be83a52017-01-24 15:19:29 +00003698 assert isinstance(crl.get_issuer(), X509Name)
Alex Gaynor03737182020-07-23 20:40:46 -04003699 assert crl.get_issuer().CN == "Testing Root CA"
Dan Sully44e767a2016-06-04 18:05:27 -07003700
Dominic Chenf05b2122015-10-13 16:32:35 +00003701 def test_dump_crl(self):
3702 """
3703 The dumped CRL matches the original input.
3704 """
3705 crl = load_crl(FILETYPE_PEM, crlData)
3706 buf = dump_crl(FILETYPE_PEM, crl)
3707 assert buf == crlData
3708
Dan Sully44e767a2016-06-04 18:05:27 -07003709 def _make_test_crl(self, issuer_cert, issuer_key, certs=()):
3710 """
3711 Create a CRL.
3712
3713 :param list[X509] certs: A list of certificates to revoke.
3714 :rtype: CRL
3715 """
3716 crl = CRL()
3717 for cert in certs:
3718 revoked = Revoked()
3719 # FIXME: This string splicing is an unfortunate implementation
3720 # detail that has been reported in
3721 # https://github.com/pyca/pyopenssl/issues/258
Alex Gaynor03737182020-07-23 20:40:46 -04003722 serial = hex(cert.get_serial_number())[2:].encode("utf-8")
Dan Sully44e767a2016-06-04 18:05:27 -07003723 revoked.set_serial(serial)
Alex Gaynor03737182020-07-23 20:40:46 -04003724 revoked.set_reason(b"unspecified")
3725 revoked.set_rev_date(b"20140601000000Z")
Dan Sully44e767a2016-06-04 18:05:27 -07003726 crl.add_revoked(revoked)
3727 crl.set_version(1)
Alex Gaynor03737182020-07-23 20:40:46 -04003728 crl.set_lastUpdate(b"20140601000000Z")
3729 crl.set_nextUpdate(b"20180601000000Z")
3730 crl.sign(issuer_cert, issuer_key, digest=b"sha512")
Dan Sully44e767a2016-06-04 18:05:27 -07003731 return crl
3732
3733 def test_verify_with_revoked(self):
3734 """
Alex Chan7be83a52017-01-24 15:19:29 +00003735 `verify_certificate` raises error when an intermediate certificate is
3736 revoked.
Dan Sully44e767a2016-06-04 18:05:27 -07003737 """
3738 store = X509Store()
3739 store.add_cert(self.root_cert)
3740 store.add_cert(self.intermediate_cert)
3741 root_crl = self._make_test_crl(
Alex Gaynor03737182020-07-23 20:40:46 -04003742 self.root_cert, self.root_key, certs=[self.intermediate_cert]
3743 )
Dan Sully44e767a2016-06-04 18:05:27 -07003744 intermediate_crl = self._make_test_crl(
Alex Gaynor03737182020-07-23 20:40:46 -04003745 self.intermediate_cert, self.intermediate_key, certs=[]
3746 )
Dan Sully44e767a2016-06-04 18:05:27 -07003747 store.add_crl(root_crl)
3748 store.add_crl(intermediate_crl)
3749 store.set_flags(
Alex Gaynor03737182020-07-23 20:40:46 -04003750 X509StoreFlags.CRL_CHECK | X509StoreFlags.CRL_CHECK_ALL
3751 )
Dan Sully44e767a2016-06-04 18:05:27 -07003752 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Alex Chan7be83a52017-01-24 15:19:29 +00003753 with pytest.raises(X509StoreContextError) as err:
3754 store_ctx.verify_certificate()
Alex Gaynor03737182020-07-23 20:40:46 -04003755 assert err.value.args[0][2] == "certificate revoked"
Dan Sully44e767a2016-06-04 18:05:27 -07003756
3757 def test_verify_with_missing_crl(self):
3758 """
Alex Chan7be83a52017-01-24 15:19:29 +00003759 `verify_certificate` raises error when an intermediate certificate's
3760 CRL is missing.
Dan Sully44e767a2016-06-04 18:05:27 -07003761 """
3762 store = X509Store()
3763 store.add_cert(self.root_cert)
3764 store.add_cert(self.intermediate_cert)
3765 root_crl = self._make_test_crl(
Alex Gaynor03737182020-07-23 20:40:46 -04003766 self.root_cert, self.root_key, certs=[self.intermediate_cert]
3767 )
Dan Sully44e767a2016-06-04 18:05:27 -07003768 store.add_crl(root_crl)
3769 store.set_flags(
Alex Gaynor03737182020-07-23 20:40:46 -04003770 X509StoreFlags.CRL_CHECK | X509StoreFlags.CRL_CHECK_ALL
3771 )
Dan Sully44e767a2016-06-04 18:05:27 -07003772 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Alex Chan7be83a52017-01-24 15:19:29 +00003773 with pytest.raises(X509StoreContextError) as err:
3774 store_ctx.verify_certificate()
Alex Gaynor03737182020-07-23 20:40:46 -04003775 assert err.value.args[0][2] == "unable to get certificate CRL"
3776 assert err.value.certificate.get_subject().CN == "intermediate-service"
Dan Sully44e767a2016-06-04 18:05:27 -07003777
Paul Kehrer41c10242017-06-29 18:24:17 -05003778 def test_convert_from_cryptography(self):
3779 crypto_crl = x509.load_pem_x509_crl(crlData, backend)
3780 crl = CRL.from_cryptography(crypto_crl)
3781 assert isinstance(crl, CRL)
3782
3783 def test_convert_from_cryptography_unsupported_type(self):
3784 with pytest.raises(TypeError):
3785 CRL.from_cryptography(object())
3786
3787 def test_convert_to_cryptography_key(self):
3788 crl = load_crl(FILETYPE_PEM, crlData)
3789 crypto_crl = crl.to_cryptography()
3790 assert isinstance(crypto_crl, x509.CertificateRevocationList)
3791
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003792
Alex Chan7be83a52017-01-24 15:19:29 +00003793class TestX509StoreContext(object):
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003794 """
Alex Chan7be83a52017-01-24 15:19:29 +00003795 Tests for `OpenSSL.crypto.X509StoreContext`.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003796 """
Alex Gaynor03737182020-07-23 20:40:46 -04003797
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003798 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3799 intermediate_cert = load_certificate(FILETYPE_PEM, intermediate_cert_pem)
Alex Gaynor31287502015-09-05 16:11:27 -04003800 intermediate_server_cert = load_certificate(
Alex Gaynor03737182020-07-23 20:40:46 -04003801 FILETYPE_PEM, intermediate_server_cert_pem
3802 )
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003803
3804 def test_valid(self):
3805 """
Alex Chan7be83a52017-01-24 15:19:29 +00003806 `verify_certificate` returns ``None`` when called with a certificate
3807 and valid chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003808 """
3809 store = X509Store()
3810 store.add_cert(self.root_cert)
3811 store.add_cert(self.intermediate_cert)
3812 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Alex Chan7be83a52017-01-24 15:19:29 +00003813 assert store_ctx.verify_certificate() is None
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003814
3815 def test_reuse(self):
3816 """
Alex Chan7be83a52017-01-24 15:19:29 +00003817 `verify_certificate` can be called multiple times with the same
Jean-Paul Calderone06e01b92015-01-18 15:43:13 -05003818 ``X509StoreContext`` instance to produce the same result.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003819 """
3820 store = X509Store()
3821 store.add_cert(self.root_cert)
3822 store.add_cert(self.intermediate_cert)
3823 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Alex Chan7be83a52017-01-24 15:19:29 +00003824 assert store_ctx.verify_certificate() is None
3825 assert store_ctx.verify_certificate() is None
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003826
Sándor Oroszi83ef2302020-10-12 15:42:23 +02003827 @pytest.mark.parametrize(
3828 "root_cert, chain, verified_cert",
3829 [
3830 pytest.param(
3831 root_cert,
3832 [intermediate_cert],
3833 intermediate_server_cert,
3834 id="intermediate in chain",
3835 ),
3836 pytest.param(
3837 root_cert,
3838 [],
3839 intermediate_cert,
3840 id="empty chain",
3841 ),
3842 pytest.param(
3843 root_cert,
3844 [root_cert, intermediate_server_cert, intermediate_cert],
3845 intermediate_server_cert,
3846 id="extra certs in chain",
3847 ),
3848 ],
3849 )
3850 def test_verify_success_with_chain(self, root_cert, chain, verified_cert):
3851 store = X509Store()
3852 store.add_cert(root_cert)
3853 store_ctx = X509StoreContext(store, verified_cert, chain=chain)
3854 assert store_ctx.verify_certificate() is None
3855
3856 def test_valid_untrusted_chain_reuse(self):
3857 """
3858 `verify_certificate` using an untrusted chain can be called multiple
3859 times with the same ``X509StoreContext`` instance to produce the same
3860 result.
3861 """
3862 store = X509Store()
3863 store.add_cert(self.root_cert)
3864 chain = [self.intermediate_cert]
3865
3866 store_ctx = X509StoreContext(
3867 store, self.intermediate_server_cert, chain=chain
3868 )
3869 assert store_ctx.verify_certificate() is None
3870 assert store_ctx.verify_certificate() is None
3871
3872 def test_chain_reference(self):
3873 """
3874 ``X509StoreContext`` properly keeps references to the untrusted chain
3875 certificates.
3876 """
3877 store = X509Store()
3878 store.add_cert(self.root_cert)
3879 chain = [load_certificate(FILETYPE_PEM, intermediate_cert_pem)]
3880
3881 store_ctx = X509StoreContext(
3882 store, self.intermediate_server_cert, chain=chain
3883 )
3884
3885 del chain
3886 assert store_ctx.verify_certificate() is None
3887
3888 @pytest.mark.parametrize(
3889 "root_cert, chain, verified_cert",
3890 [
3891 pytest.param(
3892 root_cert,
3893 [],
3894 intermediate_server_cert,
3895 id="intermediate missing",
3896 ),
3897 pytest.param(
3898 None,
3899 [intermediate_cert],
3900 intermediate_server_cert,
3901 id="no trusted root",
3902 ),
3903 pytest.param(
3904 None,
3905 [root_cert, intermediate_cert],
3906 intermediate_server_cert,
3907 id="untrusted root, full chain is available",
3908 ),
3909 pytest.param(
3910 intermediate_cert,
3911 [root_cert, intermediate_cert],
3912 intermediate_server_cert,
3913 id="untrusted root, intermediate is trusted and in chain",
3914 ),
3915 ],
3916 )
3917 def test_verify_fail_with_chain(self, root_cert, chain, verified_cert):
3918 store = X509Store()
3919 if root_cert:
3920 store.add_cert(root_cert)
3921
3922 store_ctx = X509StoreContext(store, verified_cert, chain=chain)
3923
3924 with pytest.raises(X509StoreContextError):
3925 store_ctx.verify_certificate()
3926
3927 @pytest.mark.parametrize(
3928 "chain, expected_error",
3929 [
3930 pytest.param(
3931 [intermediate_cert, "This is not a certificate"],
3932 TypeError,
3933 id="non-certificate in chain",
3934 ),
3935 pytest.param(
3936 42,
3937 TypeError,
3938 id="non-list chain",
3939 ),
3940 ],
3941 )
3942 def test_untrusted_chain_wrong_args(self, chain, expected_error):
3943 """
3944 Creating ``X509StoreContext`` with wrong chain raises an exception.
3945 """
3946 store = X509Store()
3947 store.add_cert(self.root_cert)
3948
3949 with pytest.raises(expected_error):
3950 X509StoreContext(store, self.intermediate_server_cert, chain=chain)
3951
3952 def test_failure_building_untrusted_chain_raises(self, monkeypatch):
3953 """
3954 Creating ``X509StoreContext`` raises ``OpenSSL.crypto.Error`` when
3955 the underlying lib fails to add the certificate to the stack.
3956 """
3957 monkeypatch.setattr(_lib, "sk_X509_push", lambda _stack, _x509: -1)
3958
3959 store = X509Store()
3960 store.add_cert(self.root_cert)
3961 chain = [self.intermediate_cert]
3962
3963 with pytest.raises(Error):
3964 X509StoreContext(store, self.intermediate_server_cert, chain=chain)
3965
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003966 def test_trusted_self_signed(self):
3967 """
Alex Chan7be83a52017-01-24 15:19:29 +00003968 `verify_certificate` returns ``None`` when called with a self-signed
3969 certificate and itself in the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003970 """
3971 store = X509Store()
3972 store.add_cert(self.root_cert)
3973 store_ctx = X509StoreContext(store, self.root_cert)
Alex Chan7be83a52017-01-24 15:19:29 +00003974 assert store_ctx.verify_certificate() is None
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003975
3976 def test_untrusted_self_signed(self):
3977 """
Alex Chan7be83a52017-01-24 15:19:29 +00003978 `verify_certificate` raises error when a self-signed certificate is
3979 verified without itself in the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003980 """
3981 store = X509Store()
3982 store_ctx = X509StoreContext(store, self.root_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003983 with pytest.raises(X509StoreContextError) as exc:
3984 store_ctx.verify_certificate()
3985
Alex Gaynor03737182020-07-23 20:40:46 -04003986 assert exc.value.args[0][2] == "self signed certificate"
3987 assert exc.value.certificate.get_subject().CN == "Testing Root CA"
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003988
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003989 def test_invalid_chain_no_root(self):
3990 """
Alex Chan7be83a52017-01-24 15:19:29 +00003991 `verify_certificate` raises error when a root certificate is missing
3992 from the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003993 """
3994 store = X509Store()
3995 store.add_cert(self.intermediate_cert)
3996 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003997
3998 with pytest.raises(X509StoreContextError) as exc:
3999 store_ctx.verify_certificate()
4000
Alex Gaynor03737182020-07-23 20:40:46 -04004001 assert exc.value.args[0][2] == "unable to get issuer certificate"
4002 assert exc.value.certificate.get_subject().CN == "intermediate"
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05004003
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07004004 def test_invalid_chain_no_intermediate(self):
4005 """
Alex Chan7be83a52017-01-24 15:19:29 +00004006 `verify_certificate` raises error when an intermediate certificate is
4007 missing from the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07004008 """
4009 store = X509Store()
4010 store.add_cert(self.root_cert)
4011 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05004012
Alex Gaynor85b49702015-09-05 16:30:59 -04004013 with pytest.raises(X509StoreContextError) as exc:
4014 store_ctx.verify_certificate()
4015
Alex Gaynor03737182020-07-23 20:40:46 -04004016 assert exc.value.args[0][2] == "unable to get local issuer certificate"
4017 assert exc.value.certificate.get_subject().CN == "intermediate-service"
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07004018
Stephen Holsapple46a09252015-02-12 14:45:43 -08004019 def test_modification_pre_verify(self):
4020 """
Alex Chan7be83a52017-01-24 15:19:29 +00004021 `verify_certificate` can use a store context modified after
Stephen Holsapple46a09252015-02-12 14:45:43 -08004022 instantiation.
4023 """
4024 store_bad = X509Store()
4025 store_bad.add_cert(self.intermediate_cert)
4026 store_good = X509Store()
4027 store_good.add_cert(self.root_cert)
4028 store_good.add_cert(self.intermediate_cert)
4029 store_ctx = X509StoreContext(store_bad, self.intermediate_server_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04004030
4031 with pytest.raises(X509StoreContextError) as exc:
4032 store_ctx.verify_certificate()
4033
Alex Gaynor03737182020-07-23 20:40:46 -04004034 assert exc.value.args[0][2] == "unable to get issuer certificate"
4035 assert exc.value.certificate.get_subject().CN == "intermediate"
Alex Gaynor85b49702015-09-05 16:30:59 -04004036
Stephen Holsapple46a09252015-02-12 14:45:43 -08004037 store_ctx.set_store(store_good)
Alex Chan7be83a52017-01-24 15:19:29 +00004038 assert store_ctx.verify_certificate() is None
Stephen Holsapple46a09252015-02-12 14:45:43 -08004039
Thomas Sileoe15e60a2016-11-22 18:13:30 +01004040 def test_verify_with_time(self):
4041 """
4042 `verify_certificate` raises error when the verification time is
4043 set at notAfter.
4044 """
4045 store = X509Store()
4046 store.add_cert(self.root_cert)
4047 store.add_cert(self.intermediate_cert)
4048
4049 expire_time = self.intermediate_server_cert.get_notAfter()
4050 expire_datetime = datetime.strptime(
Alex Gaynor03737182020-07-23 20:40:46 -04004051 expire_time.decode("utf-8"), "%Y%m%d%H%M%SZ"
Thomas Sileoe15e60a2016-11-22 18:13:30 +01004052 )
4053 store.set_time(expire_datetime)
4054
4055 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
4056 with pytest.raises(X509StoreContextError) as exc:
4057 store_ctx.verify_certificate()
4058
Alex Gaynor03737182020-07-23 20:40:46 -04004059 assert exc.value.args[0][2] == "certificate has expired"
Thomas Sileoe15e60a2016-11-22 18:13:30 +01004060
Shane Harvey33c54992020-08-05 16:48:51 -07004061 def test_get_verified_chain(self):
4062 """
4063 `get_verified_chain` returns the verified chain.
4064 """
4065 store = X509Store()
4066 store.add_cert(self.root_cert)
4067 store.add_cert(self.intermediate_cert)
4068 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
4069 chain = store_ctx.get_verified_chain()
4070 assert len(chain) == 3
4071 intermediate_subject = self.intermediate_server_cert.get_subject()
4072 assert chain[0].get_subject() == intermediate_subject
4073 assert chain[1].get_subject() == self.intermediate_cert.get_subject()
4074 assert chain[2].get_subject() == self.root_cert.get_subject()
4075 # Test reuse
4076 chain = store_ctx.get_verified_chain()
4077 assert len(chain) == 3
4078 assert chain[0].get_subject() == intermediate_subject
4079 assert chain[1].get_subject() == self.intermediate_cert.get_subject()
4080 assert chain[2].get_subject() == self.root_cert.get_subject()
4081
4082 def test_get_verified_chain_invalid_chain_no_root(self):
4083 """
4084 `get_verified_chain` raises error when cert verification fails.
4085 """
4086 store = X509Store()
4087 store.add_cert(self.intermediate_cert)
4088 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
4089
4090 with pytest.raises(X509StoreContextError) as exc:
4091 store_ctx.get_verified_chain()
4092
4093 assert exc.value.args[0][2] == "unable to get issuer certificate"
4094 assert exc.value.certificate.get_subject().CN == "intermediate"
4095
Sándor Oroszi43c97762020-09-11 17:17:31 +02004096 @pytest.fixture
4097 def root_ca_file(self, tmpdir):
4098 return self._create_ca_file(tmpdir, "root_ca_hash_dir", self.root_cert)
4099
4100 @pytest.fixture
4101 def intermediate_ca_file(self, tmpdir):
4102 return self._create_ca_file(
4103 tmpdir, "intermediate_ca_hash_dir", self.intermediate_cert
4104 )
4105
4106 @staticmethod
4107 def _create_ca_file(base_path, hash_directory, cacert):
4108 ca_hash = "{:08x}.0".format(cacert.subject_name_hash())
4109 cafile = base_path.join(hash_directory, ca_hash)
4110 cafile.write_binary(
4111 dump_certificate(FILETYPE_PEM, cacert), ensure=True
4112 )
4113 return cafile
4114
4115 def test_verify_with_ca_file_location(self, root_ca_file):
4116 store = X509Store()
4117 store.load_locations(str(root_ca_file))
4118
4119 store_ctx = X509StoreContext(store, self.intermediate_cert)
4120 store_ctx.verify_certificate()
4121
4122 def test_verify_with_ca_path_location(self, root_ca_file):
4123 store = X509Store()
4124 store.load_locations(None, str(root_ca_file.dirname))
4125
4126 store_ctx = X509StoreContext(store, self.intermediate_cert)
4127 store_ctx.verify_certificate()
4128
4129 def test_verify_with_cafile_and_capath(
4130 self, root_ca_file, intermediate_ca_file
4131 ):
4132 store = X509Store()
4133 store.load_locations(
4134 cafile=str(root_ca_file), capath=str(intermediate_ca_file.dirname)
4135 )
4136
4137 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
4138 store_ctx.verify_certificate()
4139
4140 def test_verify_with_multiple_ca_files(
4141 self, root_ca_file, intermediate_ca_file
4142 ):
4143 store = X509Store()
4144 store.load_locations(str(root_ca_file))
4145 store.load_locations(str(intermediate_ca_file))
4146
4147 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
4148 store_ctx.verify_certificate()
4149
4150 def test_verify_failure_with_empty_ca_directory(self, tmpdir):
4151 store = X509Store()
4152 store.load_locations(None, str(tmpdir))
4153
4154 store_ctx = X509StoreContext(store, self.intermediate_cert)
4155 with pytest.raises(X509StoreContextError) as exc:
4156 store_ctx.verify_certificate()
4157
4158 assert exc.value.args[0][2] == "unable to get local issuer certificate"
4159
Stephen Holsapple46a09252015-02-12 14:45:43 -08004160
Alex Chan7be83a52017-01-24 15:19:29 +00004161class TestSignVerify(object):
James Yonan7c2e5d32010-02-27 05:45:50 -07004162 """
Alex Chan7be83a52017-01-24 15:19:29 +00004163 Tests for `OpenSSL.crypto.sign` and `OpenSSL.crypto.verify`.
James Yonan7c2e5d32010-02-27 05:45:50 -07004164 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04004165
James Yonan7c2e5d32010-02-27 05:45:50 -07004166 def test_sign_verify(self):
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04004167 """
Alex Chan7be83a52017-01-24 15:19:29 +00004168 `sign` generates a cryptographic signature which `verify` can check.
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04004169 """
Alex Gaynore7f51982016-09-11 11:48:14 -04004170 content = (
4171 b"It was a bright cold day in April, and the clocks were striking "
4172 b"thirteen. Winston Smith, his chin nuzzled into his breast in an "
4173 b"effort to escape the vile wind, slipped quickly through the "
4174 b"glass doors of Victory Mansions, though not quickly enough to "
Alex Gaynor03737182020-07-23 20:40:46 -04004175 b"prevent a swirl of gritty dust from entering along with him."
4176 )
Jean-Paul Calderoneb98ce212010-06-22 09:46:27 -04004177
4178 # sign the content with this private key
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04004179 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
Jean-Paul Calderoneb98ce212010-06-22 09:46:27 -04004180 # verify the content with this cert
4181 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
4182 # certificate unrelated to priv_key, used to trigger an error
4183 bad_cert = load_certificate(FILETYPE_PEM, server_cert_pem)
James Yonan7c2e5d32010-02-27 05:45:50 -07004184
Alex Gaynor03737182020-07-23 20:40:46 -04004185 for digest in ["md5", "sha1"]:
James Yonan7c2e5d32010-02-27 05:45:50 -07004186 sig = sign(priv_key, content, digest)
4187
Alex Gaynoraceb3e22015-09-05 12:00:22 -04004188 # Verify the signature of content, will throw an exception if
4189 # error.
James Yonan7c2e5d32010-02-27 05:45:50 -07004190 verify(good_cert, sig, content, digest)
4191
4192 # This should fail because the certificate doesn't match the
4193 # private key that was used to sign the content.
Alex Chan7be83a52017-01-24 15:19:29 +00004194 with pytest.raises(Error):
4195 verify(bad_cert, sig, content, digest)
James Yonan7c2e5d32010-02-27 05:45:50 -07004196
4197 # This should fail because we've "tainted" the content after
4198 # signing it.
Alex Chan7be83a52017-01-24 15:19:29 +00004199 with pytest.raises(Error):
4200 verify(good_cert, sig, content + b"tainted", digest)
James Yonan7c2e5d32010-02-27 05:45:50 -07004201
4202 # test that unknown digest types fail
Alex Chan7be83a52017-01-24 15:19:29 +00004203 with pytest.raises(ValueError):
4204 sign(priv_key, content, "strange-digest")
4205 with pytest.raises(ValueError):
4206 verify(good_cert, sig, content, "strange-digest")
James Yonan7c2e5d32010-02-27 05:45:50 -07004207
Abraham Martinc5484ba2015-03-25 15:33:05 +00004208 def test_sign_verify_with_text(self):
4209 """
Alex Chan7be83a52017-01-24 15:19:29 +00004210 `sign` generates a cryptographic signature which
4211 `verify` can check. Deprecation warnings raised because using
Alex Gaynor791212d2015-09-05 15:46:08 -04004212 text instead of bytes as content
Abraham Martinc5484ba2015-03-25 15:33:05 +00004213 """
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04004214 content = (
Jean-Paul Calderone362c1f52015-03-29 08:01:39 -04004215 b"It was a bright cold day in April, and the clocks were striking "
4216 b"thirteen. Winston Smith, his chin nuzzled into his breast in an "
4217 b"effort to escape the vile wind, slipped quickly through the "
4218 b"glass doors of Victory Mansions, though not quickly enough to "
4219 b"prevent a swirl of gritty dust from entering along with him."
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04004220 ).decode("ascii")
Abraham Martinc5484ba2015-03-25 15:33:05 +00004221
4222 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
4223 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Alex Gaynor03737182020-07-23 20:40:46 -04004224 for digest in ["md5", "sha1"]:
Alex Chan7be83a52017-01-24 15:19:29 +00004225 with pytest.warns(DeprecationWarning) as w:
Abraham Martinc5484ba2015-03-25 15:33:05 +00004226 simplefilter("always")
4227 sig = sign(priv_key, content, digest)
Alex Gaynor03737182020-07-23 20:40:46 -04004228 assert "{0} for data is no longer accepted, use bytes".format(
4229 WARNING_TYPE_EXPECTED
4230 ) == str(w[-1].message)
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04004231
Alex Chan7be83a52017-01-24 15:19:29 +00004232 with pytest.warns(DeprecationWarning) as w:
Abraham Martinc5484ba2015-03-25 15:33:05 +00004233 simplefilter("always")
4234 verify(cert, sig, content, digest)
Alex Gaynor03737182020-07-23 20:40:46 -04004235 assert "{0} for data is no longer accepted, use bytes".format(
4236 WARNING_TYPE_EXPECTED
4237 ) == str(w[-1].message)
Abraham Martinc5484ba2015-03-25 15:33:05 +00004238
Paul Kehrer59d26252017-07-20 10:45:54 +02004239 def test_sign_verify_ecdsa(self):
4240 """
4241 `sign` generates a cryptographic signature which `verify` can check.
4242 ECDSA Signatures in the X9.62 format may have variable length,
4243 different from the length of the private key.
4244 """
4245 content = (
4246 b"It was a bright cold day in April, and the clocks were striking "
4247 b"thirteen. Winston Smith, his chin nuzzled into his breast in an "
4248 b"effort to escape the vile wind, slipped quickly through the "
4249 b"glass doors of Victory Mansions, though not quickly enough to "
4250 b"prevent a swirl of gritty dust from entering along with him."
Paul Kehrerc45a6ea2020-08-03 15:54:20 -05004251 )
Paul Kehrer59d26252017-07-20 10:45:54 +02004252 priv_key = load_privatekey(FILETYPE_PEM, ec_root_key_pem)
4253 cert = load_certificate(FILETYPE_PEM, ec_root_cert_pem)
4254 sig = sign(priv_key, content, "sha1")
4255 verify(cert, sig, content, "sha1")
4256
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05004257 def test_sign_nulls(self):
4258 """
Alex Chan7be83a52017-01-24 15:19:29 +00004259 `sign` produces a signature for a string with embedded nulls.
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05004260 """
Alex Gaynore7f51982016-09-11 11:48:14 -04004261 content = b"Watch out! \0 Did you see it?"
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05004262 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
4263 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
4264 sig = sign(priv_key, content, "sha1")
4265 verify(good_cert, sig, content, "sha1")
4266
Colleen Murphye09399b2016-03-01 17:40:49 -08004267 def test_sign_with_large_key(self):
4268 """
Alex Chan7be83a52017-01-24 15:19:29 +00004269 `sign` produces a signature for a string when using a long key.
Colleen Murphye09399b2016-03-01 17:40:49 -08004270 """
Alex Gaynore7f51982016-09-11 11:48:14 -04004271 content = (
4272 b"It was a bright cold day in April, and the clocks were striking "
4273 b"thirteen. Winston Smith, his chin nuzzled into his breast in an "
4274 b"effort to escape the vile wind, slipped quickly through the "
4275 b"glass doors of Victory Mansions, though not quickly enough to "
Alex Gaynor03737182020-07-23 20:40:46 -04004276 b"prevent a swirl of gritty dust from entering along with him."
4277 )
Colleen Murphye09399b2016-03-01 17:40:49 -08004278
4279 priv_key = load_privatekey(FILETYPE_PEM, large_key_pem)
4280 sign(priv_key, content, "sha1")
4281
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05004282
Alex Chan63ef9bc2016-12-19 12:02:06 +00004283class TestEllipticCurve(object):
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004284 """
Alex Chan63ef9bc2016-12-19 12:02:06 +00004285 Tests for `_EllipticCurve`, `get_elliptic_curve`, and
4286 `get_elliptic_curves`.
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004287 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04004288
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004289 def test_set(self):
4290 """
Alex Chan63ef9bc2016-12-19 12:02:06 +00004291 `get_elliptic_curves` returns a `set`.
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004292 """
Alex Chan63ef9bc2016-12-19 12:02:06 +00004293 assert isinstance(get_elliptic_curves(), set)
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004294
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004295 def test_a_curve(self):
4296 """
Alex Chan63ef9bc2016-12-19 12:02:06 +00004297 `get_elliptic_curve` can be used to retrieve a particular supported
4298 curve.
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004299 """
4300 curves = get_elliptic_curves()
Alex Chan63ef9bc2016-12-19 12:02:06 +00004301 curve = next(iter(curves))
4302 assert curve.name == get_elliptic_curve(curve.name).name
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004303
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004304 def test_not_a_curve(self):
4305 """
Alex Chan63ef9bc2016-12-19 12:02:06 +00004306 `get_elliptic_curve` raises `ValueError` if called with a name which
4307 does not identify a supported curve.
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004308 """
Alex Chan63ef9bc2016-12-19 12:02:06 +00004309 with pytest.raises(ValueError):
4310 get_elliptic_curve(u"this curve was just invented")
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004311
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004312 def test_repr(self):
4313 """
4314 The string representation of a curve object includes simply states the
4315 object is a curve and what its name is.
4316 """
4317 curves = get_elliptic_curves()
Alex Chan63ef9bc2016-12-19 12:02:06 +00004318 curve = next(iter(curves))
4319 assert "<Curve %r>" % (curve.name,) == repr(curve)
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004320
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004321 def test_to_EC_KEY(self):
4322 """
4323 The curve object can export a version of itself as an EC_KEY* via the
Alex Chan63ef9bc2016-12-19 12:02:06 +00004324 private `_EllipticCurve._to_EC_KEY`.
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004325 """
4326 curves = get_elliptic_curves()
Alex Chan63ef9bc2016-12-19 12:02:06 +00004327 curve = next(iter(curves))
4328 # It's not easy to assert anything about this object. However, see
4329 # leakcheck/crypto.py for a test that demonstrates it at least does
4330 # not leak memory.
4331 curve._to_EC_KEY()
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004332
4333
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04004334class EllipticCurveFactory(object):
4335 """
4336 A helper to get the names of two curves.
4337 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04004338
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04004339 def __init__(self):
4340 curves = iter(get_elliptic_curves())
Alex Chan63ef9bc2016-12-19 12:02:06 +00004341 self.curve_name = next(curves).name
4342 self.another_curve_name = next(curves).name
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04004343
4344
Alex Chan63ef9bc2016-12-19 12:02:06 +00004345class TestEllipticCurveEquality(EqualityTestsMixin):
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04004346 """
Paul Kehrer7d5a3bf2019-01-21 12:24:02 -06004347 Tests `_EllipticCurve`'s implementation of ``==`` and ``!=``.
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04004348 """
Alex Gaynor03737182020-07-23 20:40:46 -04004349
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04004350 curve_factory = EllipticCurveFactory()
4351
4352 if curve_factory.curve_name is None:
4353 skip = "There are no curves available there can be no curve objects."
4354
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04004355 def anInstance(self):
4356 """
4357 Get the curve object for an arbitrary curve supported by the system.
4358 """
4359 return get_elliptic_curve(self.curve_factory.curve_name)
4360
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04004361 def anotherInstance(self):
4362 """
4363 Get the curve object for an arbitrary curve supported by the system -
4364 but not the one returned by C{anInstance}.
4365 """
4366 return get_elliptic_curve(self.curve_factory.another_curve_name)
4367
4368
Alex Chan63ef9bc2016-12-19 12:02:06 +00004369class TestEllipticCurveHash(object):
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04004370 """
Alex Chan63ef9bc2016-12-19 12:02:06 +00004371 Tests for `_EllipticCurve`'s implementation of hashing (thus use as
4372 an item in a `dict` or `set`).
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04004373 """
Alex Gaynor03737182020-07-23 20:40:46 -04004374
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04004375 curve_factory = EllipticCurveFactory()
4376
4377 if curve_factory.curve_name is None:
4378 skip = "There are no curves available there can be no curve objects."
4379
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04004380 def test_contains(self):
4381 """
Alex Chan63ef9bc2016-12-19 12:02:06 +00004382 The ``in`` operator reports that a `set` containing a curve does
4383 contain that curve.
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04004384 """
4385 curve = get_elliptic_curve(self.curve_factory.curve_name)
4386 curves = set([curve])
Alex Chan63ef9bc2016-12-19 12:02:06 +00004387 assert curve in curves
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04004388
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04004389 def test_does_not_contain(self):
4390 """
Alex Chan63ef9bc2016-12-19 12:02:06 +00004391 The ``in`` operator reports that a `set` not containing a curve
4392 does not contain that curve.
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04004393 """
4394 curve = get_elliptic_curve(self.curve_factory.curve_name)
Alex Gaynor03737182020-07-23 20:40:46 -04004395 curves = set(
4396 [get_elliptic_curve(self.curve_factory.another_curve_name)]
4397 )
Alex Chan63ef9bc2016-12-19 12:02:06 +00004398 assert curve not in curves