blob: 265d31ee39cfa4517b5b1466a86f5fbb18239ae3 [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 -0500304MIIG5AIBAAKCAYEApT23GEqDo1zR1Ur1W/gxi5g/oeyhHjzf7ALndXxrGR/LZPKe
305sFK6Dwdql5IVbmPB3ByyNoPAQgC6Bl9GjPQ3W9H9DpM4UBifaFHCUCBRdWTc1ekM
3061X9BGWIa/GEsBWm+7VrgTF9Vmg5DI9rymiAOCtR0Hd61iaYUc1rT0u/WfIxlaLq3
307vMfbB6rr8PGmbQFZ/5McVy6e/1M18CqYNXmpvG9pQ+G69Gk35fY3e16MHxYq35Sb
308MBdSLc/c6BiKZZfCrxGaitzWuTmP6SyXqpjBm+LutFWDVkAftsaFcL14RT/Vn2rb
309o6EA91PIkPSlz4b28zPpWKMtFdyAcFQ/T2VJ6rGc3FylahfqdF0afo+QOF7AczTm
310KoATdkedzyRIFxFfzlKhbl0Y6G+9ROzh49U1Oje8d1C9+1MMP4jetsWdhMpQDMdM
3119JYYTstUSJYn3hEpIANeC97SqryjfvtQydjtbdTKBJih3JRnb0HkR9nzwSkiz+Hk
3122iYO/lVxASgJY3WjAgMBAAECggGAJST2X5OAe9yFnri25vGn0YVr6G5U2YM9osQU
313W6iYOpGXGx4e5evyvyYfo+rGvoXWMjCRLwf2099t8bjBFzZeq1lM1VXqtraSPtUC
314JRjettDxg3Rb2jI85APVpR4C00SuEpT3DrPvfi3ukcTJ/DNwdKbFY2GI1WRr/HJS
315Y3xebqjwstYmL12Nsu+NEiCAFMjU/kqHeGGWhDakTVSF2p96tE0nEIdRi1eLpTnv
316xt++B87n3FJ/gBP9+SZcth+uHKA8Wr42CqJR3z8b/blICYCd2LABFdZjL4aHfce9
317Xe7UyVoySYC6N0YSbLLfsVu/w/qsYitcTvWCyekX4eT2U9Sdje46LGN4MFJSYy8K
318Qw4hzz6JhUrAiwxPb2MLkq6q7AvdFwVAFl7xuH9J13yuN9x+w4NL9h3hzr4iC7nk
319xVrmme279h1hfuCR1+1Bb0fLvdl5VevT9SZYCg5BCL7JxHGofcBZ3ZE9R9Q7QYVv
320rCKHFZ5tIOkVJk2mcR5NvK6r7ethAoHBAM7BFvBPHgJ5xtny7M9xvaMQD9PZ3zzb
321PUD83lh+DlmLyzKLw2/OblyJgO8ECWUDNR1QkL5khq5Z2t1Kj77Hak7mUUlICbIc
322LKZLiAosuKBo/ps6emRRhIf9NNYR2G1k9GWyk3KicD/htllPl10j64vgBg2M/LQJ
3232Oh95oWMck7RRdWHCwfBjND3YsYoN0hY9GXgr+ByDRQgAacvnpHlFCRmSPqiAJGh
324kPKIRfjLgVFbL1cIj7oHpcModgZr7Dgc/wKBwQDMmVhsmiefTscZSCoCIqXVsJJ0
325edDmIvAl3cFozf9/+5JADjnp/9zcdANNN/oMfynOPx+0R2CygxooZaRKbnHPcVlu
326SCxwaloagNSFVt8lZ2PwybutfdMN8YbU431ypNLJjInI3Z66eHBRDZZZviu5AtoL
3275WYAvFzN502P1IVrJBo0lht7ftQMwM4NAhRaaFrUCrycREwUl0u9PxswmDhignWs
328+fyJ93D5aVC1wHjUN9WYTEOM66goZTuSDD8mE10CgcAbl3UiOMy+c9XvvBWSUZGH
329M1uJYCgEjRWNmLFridcMaDWD11cLkrbzrn4AZ7+BNX5fHSNT5UJ7/g3RPmQUh7RO
330Nzpd1zlEBbKHtsi+4tz4u0pPGOzAeoh/RXFJqDQD1VcwQzaeM8NbIxocrRx8F5EV
331p53nLQuEU1QZIsQiym1uy0rQhicYr+HE+V67Jx7JjuV+uw99mnrYVrUhxJ8axUF8
3324hGXMQt2Y+NeGoWMAEyPuOWGbeQQZXjfpISrsrdhfa0CgcEAxqbdRBUpA3Tpu5Jl
333t00M1z5p9M2SFuE1ao61i5z3xrvsdGVbtefH+gRqcD85eYi+fpKrpc7oBGtmqnKF
3344f76YgAcZQeOnlekxLbxocWHRDnuv4wfvYO9uHwZ/fojg3ylbSwXXABSbZsi8o/O
335u7P5n9k0/Pfu4igBs6oxlMU0BaM4DnbwmCe8m+VYKykpud440kjaeJ+XfyanU0hC
336jhw+Iueoehr/KLYn6wJmaxJGP0c3DHh/3gOxcgdYn6VkawPBAoHBAMJ7jfxZJfBO
337i0gDsD9Kz3EkGI8HbBpgC2Cd9DGQR9qTZy1/l/ObM2jwNumJjoHsN8fkha1d6/3n
33801hA4LwLB/SLQHx+7k1749sH7m1FaczWa9eUxNkwFiVTBYIyvbekNfJogLX9pVow
339vEuNe+J8vxLt3gQJ1DUz+2Air8v//OIqQ+akDnPkwiqHDqynNNWO+jq708aUunVT
340TTvknsoT3qT8H/N1FwbCZ14eKV+bXHcv1lVrLdW/DnjDZRpMFa3LSg==
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 -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
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
Huw Jonescdd66962020-10-13 05:14:19 +0100519cleartextPrivateKeyPEM = """-----BEGIN PRIVATE KEY-----
520MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMcRMugJ4kvkOEuT
521AvMFr9+3A6+HAB6nKYcXXZz93ube8rJpBZQEfWn73H10dQiQR/a+rhxYEeLy8dPc
522UkFcGR9miVkukJ59zex7iySJY76bdBD8gyx1LTKrkCstP2XHKEYqgbj+tm7VzJnY
523sQLqoaa5NeyWJnUC3MJympkAS7p3AgMBAAECgYAoBAcNqd75jnjaiETRgVUnTWzK
524PgMCJmwsob/JrSa/lhWHU6Exbe2f/mcGOQDFpesxaIcrX3DJBDkkc2d9h/vsfo5v
525JLk/rbHoItWxwuY5n5raAPeQPToKpTDxDrL6Ejhgcxd19wNht7/XSrYZ+dq3iU6G
526mOEvU2hrnfIW3kwVYQJBAP62G6R0gucNfaKGtHzfR3TN9G/DnCItchF+TxGTtpdh
527Cz32MG+7pirT/0xunekmUIp15QHdRy496sVxWTCooLkCQQDIEwXTAwhLNRGFEs5S
528jSkxNfTVeNiOzlG8jPBJJDAdlLt1gUqjZWnk9yU+itMSGi/6eeuH2n04FFk+SV/T
5297ryvAkB0y0ZDk5VOozX/p2rtc2iNm77A3N4kIdiTQuq4sZXhNgN0pwWwxke8jbcb
5308gEAnqwBwWt//locTxHu9TmjgT8pAkEAlbF16B0atXptM02QxT8MlN8z4gxaqu4/
531RX2FwpOq1FcVsqMbvwj/o+ouGY8wwRiK0TMrQCf/DFhdNTcc1aqHzQJBAKWtq4LI
532uVZjCAuyrqEnt7R1bOiLrar+/ezJPY2z+f2rb1TGr31ztPeFvO3edLw+QdhzwJGp
533QKImYzqMe+zkIOQ=
534-----END PRIVATE KEY-----
535"""
Cory Benfield6492f7c2015-10-27 16:57:58 +0900536
Alex Gaynore7f51982016-09-11 11:48:14 -0400537cleartextPublicKeyPEM = b"""-----BEGIN PUBLIC KEY-----
Cory Benfield6492f7c2015-10-27 16:57:58 +0900538MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxszlc+b71LvlLS0ypt/l
539gT/JzSVJtnEqw9WUNGeiChywX2mmQLHEt7KP0JikqUFZOtPclNY823Q4pErMTSWC
54090qlUxI47vNJbXGRfmO2q6Zfw6SE+E9iUb74xezbOJLjBuUIkQzEKEFV+8taiRV+
541ceg1v01yCT2+OjhQW3cxG42zxyRFmqesbQAUWgS3uhPrUQqYQUEiTmVhh4FBUKZ5
542XIneGUpX1S7mXRxTLH6YzRoGFqRoc9A0BBNcoXHTWnxV215k4TeHMFYE5RG0KYAS
5438Xk5iKICEXwnZreIt3jyygqoOKsKZMK/Zl2VhMGhJR6HXRpQCyASzEG7bgtROLhL
544ywIDAQAB
545-----END PUBLIC KEY-----
Alex Gaynore7f51982016-09-11 11:48:14 -0400546"""
Cory Benfield6492f7c2015-10-27 16:57:58 +0900547
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400548# Some PKCS#7 stuff. Generated with the openssl command line:
549#
550# openssl crl2pkcs7 -inform pem -outform pem -certfile s.pem -nocrl
551#
552# with a certificate and key (but the key should be irrelevant) in s.pem
Alex Gaynore7f51982016-09-11 11:48:14 -0400553pkcs7Data = b"""\
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400554-----BEGIN PKCS7-----
555MIIDNwYJKoZIhvcNAQcCoIIDKDCCAyQCAQExADALBgkqhkiG9w0BBwGgggMKMIID
556BjCCAm+gAwIBAgIBATANBgkqhkiG9w0BAQQFADB7MQswCQYDVQQGEwJTRzERMA8G
557A1UEChMITTJDcnlwdG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtN
558MkNyeXB0byBDZXJ0aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNA
559cG9zdDEuY29tMB4XDTAwMDkxMDA5NTEzMFoXDTAyMDkxMDA5NTEzMFowUzELMAkG
560A1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIwEAYDVQQDEwlsb2NhbGhvc3Qx
561HTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tMFwwDQYJKoZIhvcNAQEBBQAD
562SwAwSAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh5kwI
563zOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEAAaOCAQQwggEAMAkGA1UdEwQCMAAw
564LAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0G
565A1UdDgQWBBTPhIKSvnsmYsBVNWjj0m3M2z0qVTCBpQYDVR0jBIGdMIGagBT7hyNp
56665w6kxXlxb8pUU/+7Sg4AaF/pH0wezELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0y
567Q3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UEAxMbTTJDcnlwdG8g
568Q2VydGlmaWNhdGUgTWFzdGVyMR0wGwYJKoZIhvcNAQkBFg5uZ3BzQHBvc3QxLmNv
569bYIBADANBgkqhkiG9w0BAQQFAAOBgQA7/CqT6PoHycTdhEStWNZde7M/2Yc6BoJu
570VwnW8YxGO8Sn6UJ4FeffZNcYZddSDKosw8LtPOeWoK3JINjAk5jiPQ2cww++7QGG
571/g5NDjxFZNDJP1dGiLAxPW6JXwov4v0FmdzfLOZ01jDcgQQZqEpYlgpuI5JEWUQ9
572Ho4EzbYCOaEAMQA=
573-----END PKCS7-----
Alex Gaynore7f51982016-09-11 11:48:14 -0400574"""
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400575
Alex Gaynor03737182020-07-23 20:40:46 -0400576pkcs7DataASN1 = base64.b64decode(
577 b"""
Alex Gaynor4b9c96a2014-08-14 09:51:48 -0700578MIIDNwYJKoZIhvcNAQcCoIIDKDCCAyQCAQExADALBgkqhkiG9w0BBwGgggMKMIID
579BjCCAm+gAwIBAgIBATANBgkqhkiG9w0BAQQFADB7MQswCQYDVQQGEwJTRzERMA8G
580A1UEChMITTJDcnlwdG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtN
581MkNyeXB0byBDZXJ0aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNA
582cG9zdDEuY29tMB4XDTAwMDkxMDA5NTEzMFoXDTAyMDkxMDA5NTEzMFowUzELMAkG
583A1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIwEAYDVQQDEwlsb2NhbGhvc3Qx
584HTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tMFwwDQYJKoZIhvcNAQEBBQAD
585SwAwSAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh5kwI
586zOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEAAaOCAQQwggEAMAkGA1UdEwQCMAAw
587LAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0G
588A1UdDgQWBBTPhIKSvnsmYsBVNWjj0m3M2z0qVTCBpQYDVR0jBIGdMIGagBT7hyNp
58965w6kxXlxb8pUU/+7Sg4AaF/pH0wezELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0y
590Q3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UEAxMbTTJDcnlwdG8g
591Q2VydGlmaWNhdGUgTWFzdGVyMR0wGwYJKoZIhvcNAQkBFg5uZ3BzQHBvc3QxLmNv
592bYIBADANBgkqhkiG9w0BAQQFAAOBgQA7/CqT6PoHycTdhEStWNZde7M/2Yc6BoJu
593VwnW8YxGO8Sn6UJ4FeffZNcYZddSDKosw8LtPOeWoK3JINjAk5jiPQ2cww++7QGG
594/g5NDjxFZNDJP1dGiLAxPW6JXwov4v0FmdzfLOZ01jDcgQQZqEpYlgpuI5JEWUQ9
595Ho4EzbYCOaEAMQA=
Alex Gaynor03737182020-07-23 20:40:46 -0400596"""
597)
Alex Gaynor4b9c96a2014-08-14 09:51:48 -0700598
Alex Gaynore7f51982016-09-11 11:48:14 -0400599crlData = b"""\
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -0500600-----BEGIN X509 CRL-----
601MIIBWzCBxTANBgkqhkiG9w0BAQQFADBYMQswCQYDVQQGEwJVUzELMAkGA1UECBMC
602SUwxEDAOBgNVBAcTB0NoaWNhZ28xEDAOBgNVBAoTB1Rlc3RpbmcxGDAWBgNVBAMT
603D1Rlc3RpbmcgUm9vdCBDQRcNMDkwNzI2MDQzNDU2WhcNMTIwOTI3MDI0MTUyWjA8
604MBUCAgOrGA8yMDA5MDcyNTIzMzQ1NlowIwICAQAYDzIwMDkwNzI1MjMzNDU2WjAM
605MAoGA1UdFQQDCgEEMA0GCSqGSIb3DQEBBAUAA4GBAEBt7xTs2htdD3d4ErrcGAw1
6064dKcVnIWTutoI7xxen26Wwvh8VCsT7i/UeP+rBl9rC/kfjWjzQk3/zleaarGTpBT
6070yp4HXRFFoRhhSE/hP+eteaPXRgrsNRLHe9ZDd69wmh7J1wMDb0m81RG7kqcbsid
608vrzEeLDRiiPl92dyyWmu
609-----END X509 CRL-----
Alex Gaynore7f51982016-09-11 11:48:14 -0400610"""
Jean-Paul Calderonee890db32010-08-22 16:55:15 -0400611
Alex Gaynore7f51982016-09-11 11:48:14 -0400612crlDataUnsupportedExtension = b"""\
Paul Kehrer5e3dd4c2016-03-11 09:58:28 -0400613-----BEGIN X509 CRL-----
614MIIGRzCCBS8CAQIwDQYJKoZIhvcNAQELBQAwJzELMAkGA1UEBhMCVVMxGDAWBgNV
615BAMMD2NyeXB0b2dyYXBoeS5pbxgPMjAxNTAxMDEwMDAwMDBaGA8yMDE2MDEwMTAw
616MDAwMFowggTOMBQCAQAYDzIwMTUwMTAxMDAwMDAwWjByAgEBGA8yMDE1MDEwMTAw
617MDAwMFowXDAYBgNVHRgEERgPMjAxNTAxMDEwMDAwMDBaMDQGA1UdHQQtMCukKTAn
618MQswCQYDVQQGEwJVUzEYMBYGA1UEAwwPY3J5cHRvZ3JhcGh5LmlvMAoGA1UdFQQD
619CgEAMHICAQIYDzIwMTUwMTAxMDAwMDAwWjBcMBgGA1UdGAQRGA8yMDE1MDEwMTAw
620MDAwMFowNAYDVR0dBC0wK6QpMCcxCzAJBgNVBAYTAlVTMRgwFgYDVQQDDA9jcnlw
621dG9ncmFwaHkuaW8wCgYDVR0VBAMKAQEwcgIBAxgPMjAxNTAxMDEwMDAwMDBaMFww
622GAYDVR0YBBEYDzIwMTUwMTAxMDAwMDAwWjA0BgNVHR0ELTArpCkwJzELMAkGA1UE
623BhMCVVMxGDAWBgNVBAMMD2NyeXB0b2dyYXBoeS5pbzAKBgNVHRUEAwoBAjByAgEE
624GA8yMDE1MDEwMTAwMDAwMFowXDAYBgNVHRgEERgPMjAxNTAxMDEwMDAwMDBaMDQG
625A1UdHQQtMCukKTAnMQswCQYDVQQGEwJVUzEYMBYGA1UEAwwPY3J5cHRvZ3JhcGh5
626LmlvMAoGA1UdFQQDCgEDMHICAQUYDzIwMTUwMTAxMDAwMDAwWjBcMBgGA1UdGAQR
627GA8yMDE1MDEwMTAwMDAwMFowNAYDVR0dBC0wK6QpMCcxCzAJBgNVBAYTAlVTMRgw
628FgYDVQQDDA9jcnlwdG9ncmFwaHkuaW8wCgYDVR0VBAMKAQQwcgIBBhgPMjAxNTAx
629MDEwMDAwMDBaMFwwGAYDVR0YBBEYDzIwMTUwMTAxMDAwMDAwWjA0BgNVHR0ELTAr
630pCkwJzELMAkGA1UEBhMCVVMxGDAWBgNVBAMMD2NyeXB0b2dyYXBoeS5pbzAKBgNV
631HRUEAwoBBTByAgEHGA8yMDE1MDEwMTAwMDAwMFowXDAYBgNVHRgEERgPMjAxNTAx
632MDEwMDAwMDBaMDQGA1UdHQQtMCukKTAnMQswCQYDVQQGEwJVUzEYMBYGA1UEAwwP
633Y3J5cHRvZ3JhcGh5LmlvMAoGA1UdFQQDCgEGMHICAQgYDzIwMTUwMTAxMDAwMDAw
634WjBcMBgGA1UdGAQRGA8yMDE1MDEwMTAwMDAwMFowNAYDVR0dBC0wK6QpMCcxCzAJ
635BgNVBAYTAlVTMRgwFgYDVQQDDA9jcnlwdG9ncmFwaHkuaW8wCgYDVR0VBAMKAQgw
636cgIBCRgPMjAxNTAxMDEwMDAwMDBaMFwwGAYDVR0YBBEYDzIwMTUwMTAxMDAwMDAw
637WjA0BgNVHR0ELTArpCkwJzELMAkGA1UEBhMCVVMxGDAWBgNVBAMMD2NyeXB0b2dy
638YXBoeS5pbzAKBgNVHRUEAwoBCTByAgEKGA8yMDE1MDEwMTAwMDAwMFowXDAYBgNV
639HRgEERgPMjAxNTAxMDEwMDAwMDBaMDQGA1UdHQQtMCukKTAnMQswCQYDVQQGEwJV
640UzEYMBYGA1UEAwwPY3J5cHRvZ3JhcGh5LmlvMAoGA1UdFQQDCgEKMC4CAQsYDzIw
641MTUwMTAxMDAwMDAwWjAYMAoGA1UdFQQDCgEBMAoGAyoDBAQDCgEAMA0GCSqGSIb3
642DQEBCwUAA4IBAQBTaloHlPaCZzYee8LxkWej5meiqxQVNWFoVdjesroa+f1FRrH+
643drRU60Nq97KCKf7f9GNN/J3ZIlQmYhmuDqh12f+XLpotoj1ZRfBz2hjFCkJlv+2c
644oWWGNHgA70ndFoVtcmX088SYpX8E3ARATivS4q2h9WlwV6rO93mhg3HGIe3JpcK4
6457BcW6Poi/ut/zsDOkVbI00SqaujRpdmdCTht82MH3ztjyDkI9KYaD/YEweKSrWOz
646SdEILd164bfBeLuplVI+xpmTEMVNpXBlSXl7+xIw9Vk7p7Q1Pa3k/SvhOldYCm6y
647C1xAg/AAq6w78yzYt18j5Mj0s6eeHi1YpHKw
648-----END X509 CRL-----
Alex Gaynore7f51982016-09-11 11:48:14 -0400649"""
Paul Kehrer5e3dd4c2016-03-11 09:58:28 -0400650
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400651
652# A broken RSA private key which can be used to test the error path through
653# PKey.check.
Alex Gaynore7f51982016-09-11 11:48:14 -0400654inconsistentPrivateKeyPEM = b"""-----BEGIN RSA PRIVATE KEY-----
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400655MIIBPAIBAAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh
6565kwIzOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEaAQJBAIqm/bz4NA1H++Vx5Ewx
657OcKp3w19QSaZAwlGRtsUxrP7436QjnREM3Bm8ygU11BjkPVmtrKm6AayQfCHqJoT
658zIECIQDW0BoMoL0HOYM/mrTLhaykYAVqgIeJsPjvkEhTFXWBuQIhAM3deFAvWNu4
659nklUQ37XsCT2c9tmNt1LAT+slG2JOTTRAiAuXDtC/m3NYVwyHfFm+zKHRzHkClk2
660HjubeEgjpj32AQIhAJqMGTaZVOwevTXvvHwNeH+vRWsAYU/gbx+OQB+7VOcBAiEA
661oolb6NMg/R3enNPvS1O4UU1H8wpaF77L4yiSWlE0p4w=
662-----END RSA PRIVATE KEY-----
Alex Gaynore7f51982016-09-11 11:48:14 -0400663"""
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400664
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -0400665# certificate with NULL bytes in subjectAltName and common name
666
Alex Gaynore7f51982016-09-11 11:48:14 -0400667nulbyteSubjectAltNamePEM = b"""-----BEGIN CERTIFICATE-----
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -0400668MIIE2DCCA8CgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBxTELMAkGA1UEBhMCVVMx
669DzANBgNVBAgMBk9yZWdvbjESMBAGA1UEBwwJQmVhdmVydG9uMSMwIQYDVQQKDBpQ
670eXRob24gU29mdHdhcmUgRm91bmRhdGlvbjEgMB4GA1UECwwXUHl0aG9uIENvcmUg
671RGV2ZWxvcG1lbnQxJDAiBgNVBAMMG251bGwucHl0aG9uLm9yZwBleGFtcGxlLm9y
672ZzEkMCIGCSqGSIb3DQEJARYVcHl0aG9uLWRldkBweXRob24ub3JnMB4XDTEzMDgw
673NzEzMTE1MloXDTEzMDgwNzEzMTI1MlowgcUxCzAJBgNVBAYTAlVTMQ8wDQYDVQQI
674DAZPcmVnb24xEjAQBgNVBAcMCUJlYXZlcnRvbjEjMCEGA1UECgwaUHl0aG9uIFNv
675ZnR3YXJlIEZvdW5kYXRpb24xIDAeBgNVBAsMF1B5dGhvbiBDb3JlIERldmVsb3Bt
676ZW50MSQwIgYDVQQDDBtudWxsLnB5dGhvbi5vcmcAZXhhbXBsZS5vcmcxJDAiBgkq
677hkiG9w0BCQEWFXB5dGhvbi1kZXZAcHl0aG9uLm9yZzCCASIwDQYJKoZIhvcNAQEB
678BQADggEPADCCAQoCggEBALXq7cn7Rn1vO3aA3TrzA5QLp6bb7B3f/yN0CJ2XFj+j
679pHs+Gw6WWSUDpybiiKnPec33BFawq3kyblnBMjBU61ioy5HwQqVkJ8vUVjGIUq3P
680vX/wBmQfzCe4o4uM89gpHyUL9UYGG8oCRa17dgqcv7u5rg0Wq2B1rgY+nHwx3JIv
681KRrgSwyRkGzpN8WQ1yrXlxWjgI9de0mPVDDUlywcWze1q2kwaEPTM3hLAmD1PESA
682oY/n8A/RXoeeRs9i/Pm/DGUS8ZPINXk/yOzsR/XvvkTVroIeLZqfmFpnZeF0cHzL
68308LODkVJJ9zjLdT7SA4vnne4FEbAxDbKAq5qkYzaL4UCAwEAAaOB0DCBzTAMBgNV
684HRMBAf8EAjAAMB0GA1UdDgQWBBSIWlXAUv9hzVKjNQ/qWpwkOCL3XDALBgNVHQ8E
685BAMCBeAwgZAGA1UdEQSBiDCBhYIeYWx0bnVsbC5weXRob24ub3JnAGV4YW1wbGUu
686Y29tgSBudWxsQHB5dGhvbi5vcmcAdXNlckBleGFtcGxlLm9yZ4YpaHR0cDovL251
687bGwucHl0aG9uLm9yZwBodHRwOi8vZXhhbXBsZS5vcmeHBMAAAgGHECABDbgAAAAA
688AAAAAAAAAAEwDQYJKoZIhvcNAQEFBQADggEBAKxPRe99SaghcI6IWT7UNkJw9aO9
689i9eo0Fj2MUqxpKbdb9noRDy2CnHWf7EIYZ1gznXPdwzSN4YCjV5d+Q9xtBaowT0j
690HPERs1ZuytCNNJTmhyqZ8q6uzMLoht4IqH/FBfpvgaeC5tBTnTT0rD5A/olXeimk
691kX4LxlEx5RAvpGB2zZVRGr6LobD9rVK91xuHYNIxxxfEGE8tCCWjp0+3ksri9SXx
692VHWBnbM9YaL32u3hxm8sYB/Yb8WSBavJCWJJqRStVRHM1koZlJmXNx2BX4vPo6iW
693RFEIPQsFZRLrtnCAiEhyT8bC2s/Njlu6ly9gtJZWSV46Q3ZjBL4q9sHKqZQ=
Alex Gaynore7f51982016-09-11 11:48:14 -0400694-----END CERTIFICATE-----"""
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -0400695
Alex Gaynore7f51982016-09-11 11:48:14 -0400696large_key_pem = b"""-----BEGIN RSA PRIVATE KEY-----
Colleen Murphye09399b2016-03-01 17:40:49 -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
747vYeU7Ab/
Alex Gaynore7f51982016-09-11 11:48:14 -0400748-----END RSA PRIVATE KEY-----"""
Colleen Murphye09399b2016-03-01 17:40:49 -0800749
Paul Kehrer72d968b2016-07-29 15:31:04 +0800750ec_private_key_pem = b"""-----BEGIN PRIVATE KEY-----
751MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgYirTZSx+5O8Y6tlG
752cka6W6btJiocdrdolfcukSoTEk+hRANCAAQkvPNu7Pa1GcsWU4v7ptNfqCJVq8Cx
753zo0MUVPQgwJ3aJtNM1QMOQUayCrRwfklg+D/rFSUwEUqtZh7fJDiFqz3
754-----END PRIVATE KEY-----
755"""
756
Paul Kehrer59d26252017-07-20 10:45:54 +0200757ec_root_key_pem = b"""-----BEGIN EC PRIVATE KEY-----
758MIGlAgEBBDEAz/HOBFPYLB0jLWeTpJn4Yc4m/C4mdWymVHBjOmnwiPHKT326iYN/
759ZhmSs+RM94RsoAcGBSuBBAAioWQDYgAEwE5vDdla/nLpWAPAQ0yFGqwLuw4BcN2r
760U+sKab5EAEHzLeceRa8ffncYdCXNoVsBcdob1y66CFZMEWLetPTmGapyWkBAs6/L
7618kUlkU9OsE+7IVo4QQJkgV5gM+Dim1XE
762-----END EC PRIVATE KEY-----
763"""
764
765ec_root_cert_pem = b"""-----BEGIN CERTIFICATE-----
766MIICLTCCAbKgAwIBAgIMWW/hwTl6ufz6/WkCMAoGCCqGSM49BAMDMFgxGDAWBgNV
767BAMTD1Rlc3RpbmcgUm9vdCBDQTEQMA4GA1UEChMHVGVzdGluZzEQMA4GA1UEBxMH
768Q2hpY2FnbzELMAkGA1UECBMCSUwxCzAJBgNVBAYTAlVTMCAXDTE3MDcxOTIyNDgz
769M1oYDzk5OTkxMjMxMjM1OTU5WjBYMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0Ex
770EDAOBgNVBAoTB1Rlc3RpbmcxEDAOBgNVBAcTB0NoaWNhZ28xCzAJBgNVBAgTAklM
771MQswCQYDVQQGEwJVUzB2MBAGByqGSM49AgEGBSuBBAAiA2IABMBObw3ZWv5y6VgD
772wENMhRqsC7sOAXDdq1PrCmm+RABB8y3nHkWvH353GHQlzaFbAXHaG9cuughWTBFi
7733rT05hmqclpAQLOvy/JFJZFPTrBPuyFaOEECZIFeYDPg4ptVxKNDMEEwDwYDVR0T
774AQH/BAUwAwEB/zAPBgNVHQ8BAf8EBQMDBwQAMB0GA1UdDgQWBBSoTrF0H2m8RDzB
775MnY2KReEPfz7ZjAKBggqhkjOPQQDAwNpADBmAjEA3+G1oVCxGjYX4iUN93QYcNHe
776e3fJQJwX9+KsHRut6qNZDUbvRbtO1YIAwB4UJZjwAjEAtXCPURS5A4McZHnSwgTi
777Td8GMrwKz0557OxxtKN6uVVy4ACFMqEw0zN/KJI1vxc9
778-----END CERTIFICATE-----"""
779
Mrmaxmeier8cd3b172020-03-11 22:03:59 +0100780rsa_p_not_prime_pem = """
781-----BEGIN RSA PRIVATE KEY-----
782MBsCAQACAS0CAQcCAQACAQ8CAQMCAQACAQACAQA=
783-----END RSA PRIVATE KEY-----
784"""
785
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400786
Alex Chanc6077062016-11-18 13:53:39 +0000787@pytest.fixture
788def x509_data():
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400789 """
Alex Chanc6077062016-11-18 13:53:39 +0000790 Create a new private key and start a certificate request (for a test
791 to finish in one way or another).
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400792 """
Alex Chanc6077062016-11-18 13:53:39 +0000793 # Basic setup stuff to generate a certificate
794 pkey = PKey()
Alex Gaynor6e9f9762018-05-12 07:44:37 -0400795 pkey.generate_key(TYPE_RSA, 512)
Alex Chanc6077062016-11-18 13:53:39 +0000796 req = X509Req()
797 req.set_pubkey(pkey)
798 # Authority good you have.
799 req.get_subject().commonName = "Yoda root CA"
800 x509 = X509()
801 subject = x509.get_subject()
802 subject.commonName = req.get_subject().commonName
803 x509.set_issuer(subject)
804 x509.set_pubkey(pkey)
805 now = datetime.now()
806 expire = datetime.now() + timedelta(days=100)
807 x509.set_notBefore(now.strftime("%Y%m%d%H%M%SZ").encode())
808 x509.set_notAfter(expire.strftime("%Y%m%d%H%M%SZ").encode())
809 yield pkey, x509
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400810
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400811
Alex Chanc6077062016-11-18 13:53:39 +0000812class TestX509Ext(object):
813 """
814 Tests for `OpenSSL.crypto.X509Extension`.
815 """
Jean-Paul Calderoneef9a3dc2013-03-02 16:33:32 -0800816
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -0400817 def test_str(self):
818 """
Alex Chanc6077062016-11-18 13:53:39 +0000819 The string representation of `X509Extension` instances as
820 returned by `str` includes stuff.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -0400821 """
822 # This isn't necessarily the best string representation. Perhaps it
823 # will be changed/improved in the future.
Alex Chanc6077062016-11-18 13:53:39 +0000824 assert (
Alex Gaynor03737182020-07-23 20:40:46 -0400825 str(X509Extension(b"basicConstraints", True, b"CA:false"))
826 == "CA:FALSE"
Alex Chanc6077062016-11-18 13:53:39 +0000827 )
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -0400828
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400829 def test_type(self):
830 """
Alex Gaynor01f90a12019-02-07 09:14:48 -0500831 `X509Extension` can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400832 """
Alex Chanc6077062016-11-18 13:53:39 +0000833 assert is_consistent_type(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400834 X509Extension,
Alex Gaynor03737182020-07-23 20:40:46 -0400835 "X509Extension",
836 b"basicConstraints",
837 True,
838 b"CA:true",
839 )
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400840
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500841 def test_construction(self):
842 """
Alex Chanc6077062016-11-18 13:53:39 +0000843 `X509Extension` accepts an extension type name, a critical flag,
Alex Gaynor01f90a12019-02-07 09:14:48 -0500844 and an extension value and returns an `X509Extension` instance.
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500845 """
Alex Gaynor03737182020-07-23 20:40:46 -0400846 basic = X509Extension(b"basicConstraints", True, b"CA:true")
Alex Gaynor01f90a12019-02-07 09:14:48 -0500847 assert isinstance(basic, X509Extension)
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500848
Alex Gaynor03737182020-07-23 20:40:46 -0400849 comment = X509Extension(b"nsComment", False, b"pyOpenSSL unit test")
Alex Gaynor01f90a12019-02-07 09:14:48 -0500850 assert isinstance(comment, X509Extension)
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500851
Alex Gaynor03737182020-07-23 20:40:46 -0400852 @pytest.mark.parametrize(
853 "type_name, critical, value",
854 [
855 (b"thisIsMadeUp", False, b"hi"),
856 (b"basicConstraints", False, b"blah blah"),
857 # Exercise a weird one (an extension which uses the r2i method).
858 # This exercises the codepath that requires a non-NULL ctx to be
859 # passed to X509V3_EXT_nconf. It can't work now because we provide
860 # no configuration database. It might be made to work in the
861 # future.
862 (
863 b"proxyCertInfo",
864 True,
865 b"language:id-ppl-anyLanguage,pathlen:1,policy:text:AB",
866 ),
867 ],
868 )
Alex Chanc6077062016-11-18 13:53:39 +0000869 def test_invalid_extension(self, type_name, critical, value):
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500870 """
Alex Chanc6077062016-11-18 13:53:39 +0000871 `X509Extension` raises something if it is passed a bad
872 extension name or value.
873 """
874 with pytest.raises(Error):
875 X509Extension(type_name, critical, value)
876
Alex Gaynor03737182020-07-23 20:40:46 -0400877 @pytest.mark.parametrize("critical_flag", [True, False])
Alex Chanc6077062016-11-18 13:53:39 +0000878 def test_get_critical(self, critical_flag):
879 """
880 `X509ExtensionType.get_critical` returns the value of the
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500881 extension's critical flag.
882 """
Alex Gaynor03737182020-07-23 20:40:46 -0400883 ext = X509Extension(b"basicConstraints", critical_flag, b"CA:true")
Alex Chanc6077062016-11-18 13:53:39 +0000884 assert ext.get_critical() == critical_flag
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500885
Alex Gaynor03737182020-07-23 20:40:46 -0400886 @pytest.mark.parametrize(
887 "short_name, value",
888 [(b"basicConstraints", b"CA:true"), (b"nsComment", b"foo bar")],
889 )
Alex Chanc6077062016-11-18 13:53:39 +0000890 def test_get_short_name(self, short_name, value):
Jean-Paul Calderonef8c5fab2008-12-31 15:53:48 -0500891 """
Alex Chanc6077062016-11-18 13:53:39 +0000892 `X509ExtensionType.get_short_name` returns a string giving the
Alex Gaynor31287502015-09-05 16:11:27 -0400893 short type name of the extension.
Jean-Paul Calderonef8c5fab2008-12-31 15:53:48 -0500894 """
Alex Chanc6077062016-11-18 13:53:39 +0000895 ext = X509Extension(short_name, True, value)
896 assert ext.get_short_name() == short_name
Jean-Paul Calderonef8c5fab2008-12-31 15:53:48 -0500897
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400898 def test_get_data(self):
899 """
Alex Chanc6077062016-11-18 13:53:39 +0000900 `X509Extension.get_data` returns a string giving the data of
Alex Gaynor31287502015-09-05 16:11:27 -0400901 the extension.
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400902 """
Alex Gaynor03737182020-07-23 20:40:46 -0400903 ext = X509Extension(b"basicConstraints", True, b"CA:true")
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400904 # Expect to get back the DER encoded form of CA:true.
Alex Gaynor03737182020-07-23 20:40:46 -0400905 assert ext.get_data() == b"0\x03\x01\x01\xff"
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400906
Alex Chanc6077062016-11-18 13:53:39 +0000907 def test_unused_subject(self, x509_data):
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400908 """
Alex Chanc6077062016-11-18 13:53:39 +0000909 The `subject` parameter to `X509Extension` may be provided for an
910 extension which does not use it and is ignored in this case.
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400911 """
Alex Chanc6077062016-11-18 13:53:39 +0000912 pkey, x509 = x509_data
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400913 ext1 = X509Extension(
Alex Gaynor03737182020-07-23 20:40:46 -0400914 b"basicConstraints", False, b"CA:TRUE", subject=x509
915 )
Alex Chanc6077062016-11-18 13:53:39 +0000916 x509.add_extensions([ext1])
Alex Gaynor03737182020-07-23 20:40:46 -0400917 x509.sign(pkey, "sha1")
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400918 # This is a little lame. Can we think of a better way?
Alex Chanc6077062016-11-18 13:53:39 +0000919 text = dump_certificate(FILETYPE_TEXT, x509)
Alex Gaynor03737182020-07-23 20:40:46 -0400920 assert b"X509v3 Basic Constraints:" in text
921 assert b"CA:TRUE" in text
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400922
Alex Chanc6077062016-11-18 13:53:39 +0000923 def test_subject(self, x509_data):
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400924 """
Alex Chanc6077062016-11-18 13:53:39 +0000925 If an extension requires a subject, the `subject` parameter to
926 `X509Extension` provides its value.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400927 """
Alex Chanc6077062016-11-18 13:53:39 +0000928 pkey, x509 = x509_data
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400929 ext3 = X509Extension(
Alex Gaynor03737182020-07-23 20:40:46 -0400930 b"subjectKeyIdentifier", False, b"hash", subject=x509
931 )
Alex Chanc6077062016-11-18 13:53:39 +0000932 x509.add_extensions([ext3])
Alex Gaynor03737182020-07-23 20:40:46 -0400933 x509.sign(pkey, "sha1")
Alex Chanc6077062016-11-18 13:53:39 +0000934 text = dump_certificate(FILETYPE_TEXT, x509)
Alex Gaynor03737182020-07-23 20:40:46 -0400935 assert b"X509v3 Subject Key Identifier:" in text
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400936
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400937 def test_missing_subject(self):
938 """
Alex Chanc6077062016-11-18 13:53:39 +0000939 If an extension requires a subject and the `subject` parameter
Alex Gaynor31287502015-09-05 16:11:27 -0400940 is given no value, something happens.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400941 """
Alex Chanc6077062016-11-18 13:53:39 +0000942 with pytest.raises(Error):
Alex Gaynor03737182020-07-23 20:40:46 -0400943 X509Extension(b"subjectKeyIdentifier", False, b"hash")
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400944
Alex Gaynor03737182020-07-23 20:40:46 -0400945 @pytest.mark.parametrize("bad_obj", [True, object(), "hello", []])
Alex Chanc6077062016-11-18 13:53:39 +0000946 def test_invalid_subject(self, bad_obj):
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400947 """
Alex Chanc6077062016-11-18 13:53:39 +0000948 If the `subject` parameter is given a value which is not an
949 `X509` instance, `TypeError` is raised.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400950 """
Alex Chanc6077062016-11-18 13:53:39 +0000951 with pytest.raises(TypeError):
952 X509Extension(
Alex Gaynor03737182020-07-23 20:40:46 -0400953 "basicConstraints", False, "CA:TRUE", subject=bad_obj
954 )
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400955
Alex Chanc6077062016-11-18 13:53:39 +0000956 def test_unused_issuer(self, x509_data):
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400957 """
Alex Chanc6077062016-11-18 13:53:39 +0000958 The `issuer` parameter to `X509Extension` may be provided for an
959 extension which does not use it and is ignored in this case.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400960 """
Alex Chanc6077062016-11-18 13:53:39 +0000961 pkey, x509 = x509_data
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400962 ext1 = X509Extension(
Alex Gaynor03737182020-07-23 20:40:46 -0400963 b"basicConstraints", False, b"CA:TRUE", issuer=x509
964 )
Alex Chanc6077062016-11-18 13:53:39 +0000965 x509.add_extensions([ext1])
Alex Gaynor03737182020-07-23 20:40:46 -0400966 x509.sign(pkey, "sha1")
Alex Chanc6077062016-11-18 13:53:39 +0000967 text = dump_certificate(FILETYPE_TEXT, x509)
Alex Gaynor03737182020-07-23 20:40:46 -0400968 assert b"X509v3 Basic Constraints:" in text
969 assert b"CA:TRUE" in text
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400970
Alex Chanc6077062016-11-18 13:53:39 +0000971 def test_issuer(self, x509_data):
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400972 """
Alex Chanc6077062016-11-18 13:53:39 +0000973 If an extension requires an issuer, the `issuer` parameter to
974 `X509Extension` provides its value.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400975 """
Alex Chanc6077062016-11-18 13:53:39 +0000976 pkey, x509 = x509_data
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400977 ext2 = X509Extension(
Alex Gaynor03737182020-07-23 20:40:46 -0400978 b"authorityKeyIdentifier", False, b"issuer:always", issuer=x509
979 )
Alex Chanc6077062016-11-18 13:53:39 +0000980 x509.add_extensions([ext2])
Alex Gaynor03737182020-07-23 20:40:46 -0400981 x509.sign(pkey, "sha1")
Alex Chanc6077062016-11-18 13:53:39 +0000982 text = dump_certificate(FILETYPE_TEXT, x509)
Alex Gaynor03737182020-07-23 20:40:46 -0400983 assert b"X509v3 Authority Key Identifier:" in text
984 assert b"DirName:/CN=Yoda root CA" in text
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400985
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400986 def test_missing_issuer(self):
987 """
Alex Chanc6077062016-11-18 13:53:39 +0000988 If an extension requires an issue and the `issuer` parameter is
989 given no value, something happens.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400990 """
Alex Chanc6077062016-11-18 13:53:39 +0000991 with pytest.raises(Error):
992 X509Extension(
Alex Gaynor03737182020-07-23 20:40:46 -0400993 b"authorityKeyIdentifier", False, b"keyid:always,issuer:always"
994 )
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400995
Alex Gaynor03737182020-07-23 20:40:46 -0400996 @pytest.mark.parametrize("bad_obj", [True, object(), "hello", []])
Alex Chanc6077062016-11-18 13:53:39 +0000997 def test_invalid_issuer(self, bad_obj):
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400998 """
Alex Chanc6077062016-11-18 13:53:39 +0000999 If the `issuer` parameter is given a value which is not an
1000 `X509` instance, `TypeError` is raised.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -04001001 """
Alex Chanc6077062016-11-18 13:53:39 +00001002 with pytest.raises(TypeError):
1003 X509Extension(
Alex Gaynor03737182020-07-23 20:40:46 -04001004 "basicConstraints",
1005 False,
1006 "keyid:always,issuer:always",
1007 issuer=bad_obj,
1008 )
Rick Dean47262da2009-07-08 16:17:17 -05001009
1010
Paul Kehrer72d968b2016-07-29 15:31:04 +08001011class TestPKey(object):
1012 """
Hynek Schlawack3bcf3152017-02-18 08:25:34 +01001013 Tests for `OpenSSL.crypto.PKey`.
Paul Kehrer72d968b2016-07-29 15:31:04 +08001014 """
1015
1016 def test_convert_from_cryptography_private_key(self):
1017 """
1018 PKey.from_cryptography_key creates a proper private PKey.
1019 """
1020 key = serialization.load_pem_private_key(
1021 intermediate_key_pem, None, backend
1022 )
1023 pkey = PKey.from_cryptography_key(key)
1024
1025 assert isinstance(pkey, PKey)
1026 assert pkey.bits() == key.key_size
1027 assert pkey._only_public is False
1028 assert pkey._initialized is True
1029
1030 def test_convert_from_cryptography_public_key(self):
1031 """
1032 PKey.from_cryptography_key creates a proper public PKey.
1033 """
1034 key = serialization.load_pem_public_key(cleartextPublicKeyPEM, backend)
1035 pkey = PKey.from_cryptography_key(key)
1036
1037 assert isinstance(pkey, PKey)
1038 assert pkey.bits() == key.key_size
1039 assert pkey._only_public is True
1040 assert pkey._initialized is True
1041
1042 def test_convert_from_cryptography_unsupported_type(self):
1043 """
1044 PKey.from_cryptography_key raises TypeError with an unsupported type.
1045 """
1046 key = serialization.load_pem_private_key(
1047 ec_private_key_pem, None, backend
1048 )
1049 with pytest.raises(TypeError):
1050 PKey.from_cryptography_key(key)
1051
1052 def test_convert_public_pkey_to_cryptography_key(self):
1053 """
1054 PKey.to_cryptography_key creates a proper cryptography public key.
1055 """
1056 pkey = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
1057 key = pkey.to_cryptography_key()
1058
1059 assert isinstance(key, rsa.RSAPublicKey)
1060 assert pkey.bits() == key.key_size
1061
1062 def test_convert_private_pkey_to_cryptography_key(self):
1063 """
1064 PKey.to_cryptography_key creates a proper cryptography private key.
1065 """
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05001066 pkey = load_privatekey(FILETYPE_PEM, root_key_pem)
Paul Kehrer72d968b2016-07-29 15:31:04 +08001067 key = pkey.to_cryptography_key()
1068
1069 assert isinstance(key, rsa.RSAPrivateKey)
1070 assert pkey.bits() == key.key_size
1071
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001072 def test_type(self):
1073 """
Alex Gaynor01f90a12019-02-07 09:14:48 -05001074 `PKey` can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001075 """
Alex Gaynor03737182020-07-23 20:40:46 -04001076 assert is_consistent_type(PKey, "PKey")
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001077
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001078 def test_construction(self):
1079 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001080 `PKey` takes no arguments and returns a new `PKey` instance.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001081 """
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001082 key = PKey()
Alex Chan9e2a9932017-01-25 14:29:19 +00001083 assert isinstance(key, PKey)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001084
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001085 def test_pregeneration(self):
1086 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001087 `PKey.bits` and `PKey.type` return `0` before the key is generated.
1088 `PKey.check` raises `TypeError` before the key is generated.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001089 """
1090 key = PKey()
Alex Chan9e2a9932017-01-25 14:29:19 +00001091 assert key.type() == 0
1092 assert key.bits() == 0
1093 with pytest.raises(TypeError):
1094 key.check()
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001095
Alex Chan9e2a9932017-01-25 14:29:19 +00001096 def test_failed_generation(self):
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001097 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001098 `PKey.generate_key` takes two arguments, the first giving the key type
1099 as one of `TYPE_RSA` or `TYPE_DSA` and the second giving the number of
1100 bits to generate. If an invalid type is specified or generation fails,
1101 `Error` is raised. If an invalid number of bits is specified,
1102 `ValueError` or `Error` is raised.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001103 """
1104 key = PKey()
Alex Chan9e2a9932017-01-25 14:29:19 +00001105 with pytest.raises(TypeError):
1106 key.generate_key("foo", "bar")
1107 with pytest.raises(Error):
1108 key.generate_key(-1, 0)
Jean-Paul Calderoneab82db72008-03-06 00:09:31 -05001109
Alex Chan9e2a9932017-01-25 14:29:19 +00001110 with pytest.raises(ValueError):
1111 key.generate_key(TYPE_RSA, -1)
1112 with pytest.raises(ValueError):
1113 key.generate_key(TYPE_RSA, 0)
Jean-Paul Calderoned71fe982008-03-06 00:31:50 -05001114
Alex Gaynor5bb2bd12016-07-03 10:48:32 -04001115 with pytest.raises(TypeError):
1116 key.generate_key(TYPE_RSA, object())
1117
Jean-Paul Calderoned71fe982008-03-06 00:31:50 -05001118 # XXX RSA generation for small values of bits is fairly buggy in a wide
1119 # range of OpenSSL versions. I need to figure out what the safe lower
1120 # bound for a reasonable number of OpenSSL versions is and explicitly
1121 # check for that in the wrapper. The failure behavior is typically an
1122 # infinite loop inside OpenSSL.
1123
Alex Chan9e2a9932017-01-25 14:29:19 +00001124 # with pytest.raises(Error):
1125 # key.generate_key(TYPE_RSA, 2)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001126
1127 # XXX DSA generation seems happy with any number of bits. The DSS
1128 # says bits must be between 512 and 1024 inclusive. OpenSSL's DSA
1129 # generator doesn't seem to care about the upper limit at all. For
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001130 # the lower limit, it uses 512 if anything smaller is specified.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001131 # So, it doesn't seem possible to make generate_key fail for
1132 # TYPE_DSA with a bits argument which is at least an int.
1133
Alex Chan9e2a9932017-01-25 14:29:19 +00001134 # with pytest.raises(Error):
1135 # key.generate_key(TYPE_DSA, -7)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001136
Alex Chan9e2a9932017-01-25 14:29:19 +00001137 def test_rsa_generation(self):
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001138 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001139 `PKey.generate_key` generates an RSA key when passed `TYPE_RSA` as a
1140 type and a reasonable number of bits.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001141 """
Alex Gaynor6e9f9762018-05-12 07:44:37 -04001142 bits = 512
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001143 key = PKey()
1144 key.generate_key(TYPE_RSA, bits)
Alex Chan9e2a9932017-01-25 14:29:19 +00001145 assert key.type() == TYPE_RSA
1146 assert key.bits() == bits
1147 assert key.check()
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001148
Alex Chan9e2a9932017-01-25 14:29:19 +00001149 def test_dsa_generation(self):
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001150 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001151 `PKey.generate_key` generates a DSA key when passed `TYPE_DSA` as a
1152 type and a reasonable number of bits.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001153 """
1154 # 512 is a magic number. The DSS (Digital Signature Standard)
1155 # allows a minimum of 512 bits for DSA. DSA_generate_parameters
1156 # will silently promote any value below 512 to 512.
1157 bits = 512
1158 key = PKey()
1159 key.generate_key(TYPE_DSA, bits)
Alex Chan9e2a9932017-01-25 14:29:19 +00001160 assert key.type() == TYPE_DSA
1161 assert key.bits() == bits
1162 with pytest.raises(TypeError):
1163 key.check()
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001164
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001165 def test_regeneration(self):
1166 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001167 `PKey.generate_key` can be called multiple times on the same key to
1168 generate new keys.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05001169 """
1170 key = PKey()
1171 for type, bits in [(TYPE_RSA, 512), (TYPE_DSA, 576)]:
Alex Gaynor7f636492015-09-04 13:26:52 -04001172 key.generate_key(type, bits)
Alex Chan9e2a9932017-01-25 14:29:19 +00001173 assert key.type() == type
1174 assert key.bits() == bits
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001175
Alex Chan9e2a9932017-01-25 14:29:19 +00001176 def test_inconsistent_key(self):
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -04001177 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001178 `PKey.check` returns `Error` if the key is not consistent.
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -04001179 """
1180 key = load_privatekey(FILETYPE_PEM, inconsistentPrivateKeyPEM)
Alex Chan9e2a9932017-01-25 14:29:19 +00001181 with pytest.raises(Error):
1182 key.check()
Jean-Paul Calderonee81020e2011-06-12 21:48:57 -04001183
Jean-Paul Calderone02d01972011-10-31 10:39:29 -04001184 def test_check_public_key(self):
1185 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001186 `PKey.check` raises `TypeError` if only the public part of the key
1187 is available.
Jean-Paul Calderone02d01972011-10-31 10:39:29 -04001188 """
1189 # A trick to get a public-only key
1190 key = PKey()
1191 key.generate_key(TYPE_RSA, 512)
1192 cert = X509()
1193 cert.set_pubkey(key)
1194 pub = cert.get_pubkey()
Alex Chan9e2a9932017-01-25 14:29:19 +00001195 with pytest.raises(TypeError):
1196 pub.check()
Jean-Paul Calderone02d01972011-10-31 10:39:29 -04001197
Mrmaxmeier8cd3b172020-03-11 22:03:59 +01001198 def test_check_pr_897(self):
1199 """
1200 `PKey.check` raises `OpenSSL.crypto.Error` if provided with broken key
1201 """
1202 pkey = load_privatekey(FILETYPE_PEM, rsa_p_not_prime_pem)
1203 with pytest.raises(Error):
1204 pkey.check()
1205
Jean-Paul Calderone02d01972011-10-31 10:39:29 -04001206
Alex Chan9e2a9932017-01-25 14:29:19 +00001207def x509_name(**attrs):
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001208 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001209 Return a new X509Name with the given attributes.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001210 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001211 # XXX There's no other way to get a new X509Name yet.
1212 name = X509().get_subject()
1213 attrs = list(attrs.items())
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001214
Alex Chan9e2a9932017-01-25 14:29:19 +00001215 # Make the order stable - order matters!
1216 def key(attr):
1217 return attr[1]
Alex Gaynor03737182020-07-23 20:40:46 -04001218
Alex Chan9e2a9932017-01-25 14:29:19 +00001219 attrs.sort(key=key)
1220 for k, v in attrs:
1221 setattr(name, k, v)
1222 return name
Alex Gaynor85b49702015-09-05 16:30:59 -04001223
Alex Chan9e2a9932017-01-25 14:29:19 +00001224
1225class TestX509Name(object):
1226 """
1227 Unit tests for `OpenSSL.crypto.X509Name`.
1228 """
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001229
Rick Deane15b1472009-07-09 15:53:42 -05001230 def test_type(self):
1231 """
Alex Gaynor01f90a12019-02-07 09:14:48 -05001232 The type of X509Name objects is `X509Name`.
Rick Deane15b1472009-07-09 15:53:42 -05001233 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001234 name = x509_name()
Alex Gaynor01f90a12019-02-07 09:14:48 -05001235 assert isinstance(name, X509Name)
Rick Deane15b1472009-07-09 15:53:42 -05001236
Alex Chan9e2a9932017-01-25 14:29:19 +00001237 def test_only_string_attributes(self):
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -04001238 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001239 Attempting to set a non-`str` attribute name on an `X509Name` instance
1240 causes `TypeError` to be raised.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -04001241 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001242 name = x509_name()
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -04001243 # Beyond these cases, you may also think that unicode should be
Alex Gaynor31287502015-09-05 16:11:27 -04001244 # rejected. Sorry, you're wrong. unicode is automatically converted
1245 # to str outside of the control of X509Name, so there's no way to
1246 # reject it.
Jean-Paul Calderoneff363be2013-03-03 10:21:23 -08001247
Alex Gaynor31287502015-09-05 16:11:27 -04001248 # Also, this used to test str subclasses, but that test is less
1249 # relevant now that the implementation is in Python instead of C. Also
1250 # PyPy automatically converts str subclasses to str when they are
1251 # passed to setattr, so we can't test it on PyPy. Apparently CPython
1252 # does this sometimes as well.
Alex Chan9e2a9932017-01-25 14:29:19 +00001253 with pytest.raises(TypeError):
1254 setattr(name, None, "hello")
1255 with pytest.raises(TypeError):
1256 setattr(name, 30, "hello")
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -04001257
Alex Chan9e2a9932017-01-25 14:29:19 +00001258 def test_set_invalid_attribute(self):
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -04001259 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001260 Attempting to set any attribute name on an `X509Name` instance for
1261 which no corresponding NID is defined causes `AttributeError` to be
1262 raised.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -04001263 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001264 name = x509_name()
1265 with pytest.raises(AttributeError):
1266 setattr(name, "no such thing", None)
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -04001267
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001268 def test_attributes(self):
1269 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001270 `X509Name` instances have attributes for each standard (?)
1271 X509Name field.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001272 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001273 name = x509_name()
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001274 name.commonName = "foo"
Alex Gaynor37726112016-07-04 09:51:32 -04001275 assert name.commonName == "foo"
1276 assert name.CN == "foo"
1277
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001278 name.CN = "baz"
Alex Gaynor37726112016-07-04 09:51:32 -04001279 assert name.commonName == "baz"
1280 assert name.CN == "baz"
1281
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001282 name.commonName = "bar"
Alex Gaynor37726112016-07-04 09:51:32 -04001283 assert name.commonName == "bar"
1284 assert name.CN == "bar"
1285
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001286 name.CN = "quux"
Alex Gaynor37726112016-07-04 09:51:32 -04001287 assert name.commonName == "quux"
1288 assert name.CN == "quux"
1289
1290 assert name.OU is None
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001291
Alex Gaynor7778e792016-07-03 23:38:48 -04001292 with pytest.raises(AttributeError):
1293 name.foobar
1294
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001295 def test_copy(self):
1296 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001297 `X509Name` creates a new `X509Name` instance with all the same
1298 attributes as an existing `X509Name` instance when called with one.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001299 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001300 name = x509_name(commonName="foo", emailAddress="bar@example.com")
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001301
1302 copy = X509Name(name)
Alex Chan9e2a9932017-01-25 14:29:19 +00001303 assert copy.commonName == "foo"
1304 assert copy.emailAddress == "bar@example.com"
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001305
1306 # Mutate the copy and ensure the original is unmodified.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001307 copy.commonName = "baz"
Alex Chan9e2a9932017-01-25 14:29:19 +00001308 assert name.commonName == "foo"
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001309
1310 # Mutate the original and ensure the copy is unmodified.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001311 name.emailAddress = "quux@example.com"
Alex Chan9e2a9932017-01-25 14:29:19 +00001312 assert copy.emailAddress == "bar@example.com"
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001313
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001314 def test_repr(self):
1315 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001316 `repr` passed an `X509Name` instance should return a string containing
1317 a description of the type and the NIDs which have been set on it.
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001318 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001319 name = x509_name(commonName="foo", emailAddress="bar")
1320 assert repr(name) == "<X509Name object '/emailAddress=bar/CN=foo'>"
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001321
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001322 def test_comparison(self):
1323 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001324 `X509Name` instances should compare based on their NIDs.
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001325 """
Alex Gaynor03737182020-07-23 20:40:46 -04001326
Alex Chan9e2a9932017-01-25 14:29:19 +00001327 def _equality(a, b, assert_true, assert_false):
1328 assert_true(a == b)
1329 assert_false(a != b)
1330 assert_true(b == a)
1331 assert_false(b != a)
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001332
Alex Chan9e2a9932017-01-25 14:29:19 +00001333 def assert_true(x):
1334 assert x
1335
1336 def assert_false(x):
1337 assert not x
1338
1339 def assert_equal(a, b):
1340 _equality(a, b, assert_true, assert_false)
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001341
1342 # Instances compare equal to themselves.
Alex Chan9e2a9932017-01-25 14:29:19 +00001343 name = x509_name()
1344 assert_equal(name, name)
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001345
1346 # Empty instances should compare equal to each other.
Alex Chan9e2a9932017-01-25 14:29:19 +00001347 assert_equal(x509_name(), x509_name())
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001348
1349 # Instances with equal NIDs should compare equal to each other.
Alex Gaynor03737182020-07-23 20:40:46 -04001350 assert_equal(x509_name(commonName="foo"), x509_name(commonName="foo"))
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001351
1352 # Instance with equal NIDs set using different aliases should compare
1353 # equal to each other.
Alex Gaynor03737182020-07-23 20:40:46 -04001354 assert_equal(x509_name(commonName="foo"), x509_name(CN="foo"))
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001355
1356 # Instances with more than one NID with the same values should compare
1357 # equal to each other.
Alex Gaynor03737182020-07-23 20:40:46 -04001358 assert_equal(
1359 x509_name(CN="foo", organizationalUnitName="bar"),
1360 x509_name(commonName="foo", OU="bar"),
1361 )
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001362
Alex Chan9e2a9932017-01-25 14:29:19 +00001363 def assert_not_equal(a, b):
1364 _equality(a, b, assert_false, assert_true)
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001365
1366 # Instances with different values for the same NID should not compare
1367 # equal to each other.
Alex Gaynor03737182020-07-23 20:40:46 -04001368 assert_not_equal(x509_name(CN="foo"), x509_name(CN="bar"))
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001369
1370 # Instances with different NIDs should not compare equal to each other.
Alex Gaynor03737182020-07-23 20:40:46 -04001371 assert_not_equal(x509_name(CN="foo"), x509_name(OU="foo"))
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001372
Alex Chan9e2a9932017-01-25 14:29:19 +00001373 assert_not_equal(x509_name(), object())
Alex Gaynor7778e792016-07-03 23:38:48 -04001374
Alex Chan9e2a9932017-01-25 14:29:19 +00001375 def _inequality(a, b, assert_true, assert_false):
1376 assert_true(a < b)
1377 assert_true(a <= b)
1378 assert_true(b > a)
1379 assert_true(b >= a)
1380 assert_false(a > b)
1381 assert_false(a >= b)
1382 assert_false(b < a)
1383 assert_false(b <= a)
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001384
Alex Chan9e2a9932017-01-25 14:29:19 +00001385 def assert_less_than(a, b):
1386 _inequality(a, b, assert_true, assert_false)
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001387
1388 # An X509Name with a NID with a value which sorts less than the value
1389 # of the same NID on another X509Name compares less than the other
1390 # X509Name.
Alex Gaynor03737182020-07-23 20:40:46 -04001391 assert_less_than(x509_name(CN="abc"), x509_name(CN="def"))
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001392
Alex Chan9e2a9932017-01-25 14:29:19 +00001393 def assert_greater_than(a, b):
1394 _inequality(a, b, assert_false, assert_true)
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001395
1396 # An X509Name with a NID with a value which sorts greater than the
1397 # value of the same NID on another X509Name compares greater than the
1398 # other X509Name.
Alex Gaynor03737182020-07-23 20:40:46 -04001399 assert_greater_than(x509_name(CN="def"), x509_name(CN="abc"))
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001400
Jean-Paul Calderone110cd092008-03-24 17:27:42 -04001401 def test_hash(self):
1402 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001403 `X509Name.hash` returns an integer hash based on the value of the name.
Jean-Paul Calderone110cd092008-03-24 17:27:42 -04001404 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001405 a = x509_name(CN="foo")
1406 b = x509_name(CN="foo")
1407 assert a.hash() == b.hash()
Jean-Paul Calderone110cd092008-03-24 17:27:42 -04001408 a.CN = "bar"
Alex Chan9e2a9932017-01-25 14:29:19 +00001409 assert a.hash() != b.hash()
Jean-Paul Calderone110cd092008-03-24 17:27:42 -04001410
Jean-Paul Calderonee957a002008-03-25 15:16:51 -04001411 def test_der(self):
1412 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001413 `X509Name.der` returns the DER encoded form of the name.
Jean-Paul Calderonee957a002008-03-25 15:16:51 -04001414 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001415 a = x509_name(CN="foo", C="US")
Alex Gaynor03737182020-07-23 20:40:46 -04001416 assert (
1417 a.der() == b"0\x1b1\x0b0\t\x06\x03U\x04\x06\x13\x02US"
1418 b"1\x0c0\n\x06\x03U\x04\x03\x0c\x03foo"
1419 )
Jean-Paul Calderonee957a002008-03-25 15:16:51 -04001420
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001421 def test_get_components(self):
1422 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001423 `X509Name.get_components` returns a `list` of two-tuples of `str`
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001424 giving the NIDs and associated values which make up the name.
1425 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001426 a = x509_name()
1427 assert a.get_components() == []
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001428 a.CN = "foo"
Alex Chan9e2a9932017-01-25 14:29:19 +00001429 assert a.get_components() == [(b"CN", b"foo")]
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001430 a.organizationalUnitName = "bar"
Alex Chan9e2a9932017-01-25 14:29:19 +00001431 assert a.get_components() == [(b"CN", b"foo"), (b"OU", b"bar")]
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001432
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001433 def test_load_nul_byte_attribute(self):
1434 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001435 An `X509Name` from an `X509` instance loaded from a file can have a
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001436 NUL byte in the value of one of its attributes.
1437 """
1438 cert = load_certificate(FILETYPE_PEM, nulbyteSubjectAltNamePEM)
1439 subject = cert.get_subject()
Alex Chan9e2a9932017-01-25 14:29:19 +00001440 assert "null.python.org\x00example.org" == subject.commonName
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001441
Romuald Brunet4183beb2019-01-21 19:38:33 +01001442 def test_load_nul_byte_components(self):
1443 """
1444 An `X509Name` from an `X509` instance loaded from a file can have a
1445 NUL byte in the value of its components
1446 """
1447 cert = load_certificate(FILETYPE_PEM, nulbyteSubjectAltNamePEM)
1448 subject = cert.get_subject()
1449 components = subject.get_components()
Alex Gaynor03737182020-07-23 20:40:46 -04001450 ccn = [value for name, value in components if name == b"CN"]
1451 assert ccn[0] == b"null.python.org\x00example.org"
Romuald Brunet4183beb2019-01-21 19:38:33 +01001452
Alex Chan9e2a9932017-01-25 14:29:19 +00001453 def test_set_attribute_failure(self):
Jean-Paul Calderone5300d6a2013-12-29 16:36:50 -05001454 """
1455 If the value of an attribute cannot be set for some reason then
Alex Chan9e2a9932017-01-25 14:29:19 +00001456 `Error` is raised.
Jean-Paul Calderone5300d6a2013-12-29 16:36:50 -05001457 """
Alex Chan9e2a9932017-01-25 14:29:19 +00001458 name = x509_name()
Jean-Paul Calderone5300d6a2013-12-29 16:36:50 -05001459 # This value is too long
Alex Chan9e2a9932017-01-25 14:29:19 +00001460 with pytest.raises(Error):
1461 setattr(name, "O", b"x" * 512)
Jean-Paul Calderone5300d6a2013-12-29 16:36:50 -05001462
1463
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001464class _PKeyInteractionTestsMixin:
1465 """
1466 Tests which involve another thing and a PKey.
1467 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001468
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001469 def signable(self):
1470 """
Alex Chanfb078d82017-04-20 11:16:15 +01001471 Return something with a `set_pubkey`, `set_pubkey`, and `sign` method.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001472 """
1473 raise NotImplementedError()
1474
Alex Chanb00ede22017-01-30 07:24:40 +00001475 def test_sign_with_ungenerated(self):
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001476 """
Alex Chanb00ede22017-01-30 07:24:40 +00001477 `X509Req.sign` raises `ValueError` when passed a `PKey` with no parts.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001478 """
1479 request = self.signable()
1480 key = PKey()
Alex Chanb00ede22017-01-30 07:24:40 +00001481 with pytest.raises(ValueError):
1482 request.sign(key, GOOD_DIGEST)
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001483
Alex Chanb00ede22017-01-30 07:24:40 +00001484 def test_sign_with_public_key(self):
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001485 """
Alex Chanb00ede22017-01-30 07:24:40 +00001486 `X509Req.sign` raises `ValueError` when passed a `PKey` with no private
1487 part as the signing key.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001488 """
1489 request = self.signable()
1490 key = PKey()
1491 key.generate_key(TYPE_RSA, 512)
1492 request.set_pubkey(key)
1493 pub = request.get_pubkey()
Alex Chanb00ede22017-01-30 07:24:40 +00001494 with pytest.raises(ValueError):
1495 request.sign(pub, GOOD_DIGEST)
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001496
Alex Chanb00ede22017-01-30 07:24:40 +00001497 def test_sign_with_unknown_digest(self):
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001498 """
Alex Chanb00ede22017-01-30 07:24:40 +00001499 `X509Req.sign` raises `ValueError` when passed a digest name which is
1500 not known.
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001501 """
1502 request = self.signable()
1503 key = PKey()
1504 key.generate_key(TYPE_RSA, 512)
Alex Chanb00ede22017-01-30 07:24:40 +00001505 with pytest.raises(ValueError):
1506 request.sign(key, BAD_DIGEST)
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001507
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001508 def test_sign(self):
1509 """
Alex Chanb00ede22017-01-30 07:24:40 +00001510 `X509Req.sign` succeeds when passed a private key object and a
1511 valid digest function. `X509Req.verify` can be used to check
Alex Gaynor31287502015-09-05 16:11:27 -04001512 the signature.
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001513 """
1514 request = self.signable()
1515 key = PKey()
1516 key.generate_key(TYPE_RSA, 512)
1517 request.set_pubkey(key)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001518 request.sign(key, GOOD_DIGEST)
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001519 # If the type has a verify method, cover that too.
Alex Gaynor03737182020-07-23 20:40:46 -04001520 if getattr(request, "verify", None) is not None:
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001521 pub = request.get_pubkey()
Alex Chanb00ede22017-01-30 07:24:40 +00001522 assert request.verify(pub)
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001523 # Make another key that won't verify.
1524 key = PKey()
1525 key.generate_key(TYPE_RSA, 512)
Alex Chanb00ede22017-01-30 07:24:40 +00001526 with pytest.raises(Error):
1527 request.verify(key)
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001528
1529
Alex Chanb00ede22017-01-30 07:24:40 +00001530class TestX509Req(_PKeyInteractionTestsMixin):
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001531 """
Alex Chanb00ede22017-01-30 07:24:40 +00001532 Tests for `OpenSSL.crypto.X509Req`.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001533 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001534
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001535 def signable(self):
1536 """
Alex Chanb00ede22017-01-30 07:24:40 +00001537 Create and return a new `X509Req`.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001538 """
1539 return X509Req()
1540
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001541 def test_type(self):
1542 """
Alex Gaynor01f90a12019-02-07 09:14:48 -05001543 `X509Req` can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001544 """
Alex Gaynor03737182020-07-23 20:40:46 -04001545 assert is_consistent_type(X509Req, "X509Req")
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001546
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001547 def test_construction(self):
1548 """
Alex Gaynor01f90a12019-02-07 09:14:48 -05001549 `X509Req` takes no arguments and returns an `X509Req` instance.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001550 """
1551 request = X509Req()
Alex Gaynor01f90a12019-02-07 09:14:48 -05001552 assert isinstance(request, X509Req)
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001553
Jean-Paul Calderone8dd19b82008-12-28 20:41:16 -05001554 def test_version(self):
1555 """
Alex Chanb00ede22017-01-30 07:24:40 +00001556 `X509Req.set_version` sets the X.509 version of the certificate
1557 request. `X509Req.get_version` returns the X.509 version of the
1558 certificate request. The initial value of the version is 0.
Jean-Paul Calderone8dd19b82008-12-28 20:41:16 -05001559 """
1560 request = X509Req()
Alex Chanb00ede22017-01-30 07:24:40 +00001561 assert request.get_version() == 0
Jean-Paul Calderone8dd19b82008-12-28 20:41:16 -05001562 request.set_version(1)
Alex Chanb00ede22017-01-30 07:24:40 +00001563 assert request.get_version() == 1
Jean-Paul Calderone8dd19b82008-12-28 20:41:16 -05001564 request.set_version(3)
Alex Chanb00ede22017-01-30 07:24:40 +00001565 assert request.get_version() == 3
Jean-Paul Calderone8dd19b82008-12-28 20:41:16 -05001566
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001567 def test_version_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001568 """
Alex Chanb00ede22017-01-30 07:24:40 +00001569 `X509Req.set_version` raises `TypeError` if called with a non-`int`
1570 argument.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001571 """
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001572 request = X509Req()
Alex Chanb00ede22017-01-30 07:24:40 +00001573 with pytest.raises(TypeError):
1574 request.set_version("foo")
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001575
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001576 def test_get_subject(self):
1577 """
Alex Chanb00ede22017-01-30 07:24:40 +00001578 `X509Req.get_subject` returns an `X509Name` for the subject of the
1579 request and which is valid even after the request object is
1580 otherwise dead.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001581 """
1582 request = X509Req()
1583 subject = request.get_subject()
Alex Gaynor01f90a12019-02-07 09:14:48 -05001584 assert isinstance(subject, X509Name)
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001585 subject.commonName = "foo"
Alex Chanb00ede22017-01-30 07:24:40 +00001586 assert request.get_subject().commonName == "foo"
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001587 del request
1588 subject.commonName = "bar"
Alex Chanb00ede22017-01-30 07:24:40 +00001589 assert subject.commonName == "bar"
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001590
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001591 def test_add_extensions(self):
1592 """
Alex Chanb00ede22017-01-30 07:24:40 +00001593 `X509Req.add_extensions` accepts a `list` of `X509Extension` instances
1594 and adds them to the X509 request.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001595 """
1596 request = X509Req()
Alex Gaynor03737182020-07-23 20:40:46 -04001597 request.add_extensions(
1598 [X509Extension(b"basicConstraints", True, b"CA:false")]
1599 )
Stephen Holsappleca545b72014-01-28 21:43:25 -08001600 exts = request.get_extensions()
Alex Chanb00ede22017-01-30 07:24:40 +00001601 assert len(exts) == 1
Alex Gaynor03737182020-07-23 20:40:46 -04001602 assert exts[0].get_short_name() == b"basicConstraints"
Alex Chanb00ede22017-01-30 07:24:40 +00001603 assert exts[0].get_critical() == 1
Alex Gaynor03737182020-07-23 20:40:46 -04001604 assert exts[0].get_data() == b"0\x00"
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001605
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001606 def test_get_extensions(self):
1607 """
Alex Chanb00ede22017-01-30 07:24:40 +00001608 `X509Req.get_extensions` returns a `list` of extensions added to this
1609 X509 request.
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001610 """
1611 request = X509Req()
1612 exts = request.get_extensions()
Alex Chanb00ede22017-01-30 07:24:40 +00001613 assert exts == []
Alex Gaynor03737182020-07-23 20:40:46 -04001614 request.add_extensions(
1615 [
1616 X509Extension(b"basicConstraints", True, b"CA:true"),
1617 X509Extension(b"keyUsage", False, b"digitalSignature"),
1618 ]
1619 )
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001620 exts = request.get_extensions()
Alex Chanb00ede22017-01-30 07:24:40 +00001621 assert len(exts) == 2
Alex Gaynor03737182020-07-23 20:40:46 -04001622 assert exts[0].get_short_name() == b"basicConstraints"
Alex Chanb00ede22017-01-30 07:24:40 +00001623 assert exts[0].get_critical() == 1
Alex Gaynor03737182020-07-23 20:40:46 -04001624 assert exts[0].get_data() == b"0\x03\x01\x01\xff"
1625 assert exts[1].get_short_name() == b"keyUsage"
Alex Chanb00ede22017-01-30 07:24:40 +00001626 assert exts[1].get_critical() == 0
Alex Gaynor03737182020-07-23 20:40:46 -04001627 assert exts[1].get_data() == b"\x03\x02\x07\x80"
Paul Kehrer09b5d702020-11-27 15:22:30 -06001628 # Requesting it a second time should return the same list
1629 exts = request.get_extensions()
1630 assert len(exts) == 2
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001631
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001632 def test_add_extensions_wrong_args(self):
1633 """
Alex Chanb00ede22017-01-30 07:24:40 +00001634 `X509Req.add_extensions` raises `TypeError` if called with a
1635 non-`list`. Or it raises `ValueError` if called with a `list`
1636 containing objects other than `X509Extension` instances.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001637 """
1638 request = X509Req()
Alex Chanb00ede22017-01-30 07:24:40 +00001639 with pytest.raises(TypeError):
1640 request.add_extensions(object())
1641 with pytest.raises(ValueError):
1642 request.add_extensions([object()])
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001643
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001644 def test_verify_wrong_args(self):
1645 """
Alex Chanb00ede22017-01-30 07:24:40 +00001646 `X509Req.verify` raises `TypeError` if passed anything other than a
1647 `PKey` instance as its single argument.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001648 """
1649 request = X509Req()
Alex Chanb00ede22017-01-30 07:24:40 +00001650 with pytest.raises(TypeError):
1651 request.verify(object())
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001652
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001653 def test_verify_uninitialized_key(self):
1654 """
Alex Chanb00ede22017-01-30 07:24:40 +00001655 `X509Req.verify` raises `OpenSSL.crypto.Error` if called with a
1656 `OpenSSL.crypto.PKey` which contains no key data.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001657 """
1658 request = X509Req()
1659 pkey = PKey()
Alex Chanb00ede22017-01-30 07:24:40 +00001660 with pytest.raises(Error):
1661 request.verify(pkey)
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001662
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001663 def test_verify_wrong_key(self):
1664 """
Alex Chanb00ede22017-01-30 07:24:40 +00001665 `X509Req.verify` raises `OpenSSL.crypto.Error` if called with a
1666 `OpenSSL.crypto.PKey` which does not represent the public part of the
Alex Gaynor31287502015-09-05 16:11:27 -04001667 key which signed the request.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001668 """
1669 request = X509Req()
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05001670 pkey = load_privatekey(FILETYPE_PEM, root_key_pem)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001671 request.sign(pkey, GOOD_DIGEST)
Alex Chanb00ede22017-01-30 07:24:40 +00001672 another_pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
1673 with pytest.raises(Error):
1674 request.verify(another_pkey)
1675
1676 def test_verify_success(self):
1677 """
1678 `X509Req.verify` returns `True` if called with a `OpenSSL.crypto.PKey`
1679 which represents the public part of the key which signed the request.
1680 """
1681 request = X509Req()
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05001682 pkey = load_privatekey(FILETYPE_PEM, root_key_pem)
Alex Chanb00ede22017-01-30 07:24:40 +00001683 request.sign(pkey, GOOD_DIGEST)
1684 assert request.verify(pkey)
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001685
Paul Kehrer41c10242017-06-29 18:24:17 -05001686 def test_convert_from_cryptography(self):
1687 crypto_req = x509.load_pem_x509_csr(
1688 cleartextCertificateRequestPEM, backend
1689 )
1690 req = X509Req.from_cryptography(crypto_req)
1691 assert isinstance(req, X509Req)
1692
1693 def test_convert_from_cryptography_unsupported_type(self):
1694 with pytest.raises(TypeError):
1695 X509Req.from_cryptography(object())
1696
1697 def test_convert_to_cryptography_key(self):
1698 req = load_certificate_request(
1699 FILETYPE_PEM, cleartextCertificateRequestPEM
1700 )
1701 crypto_req = req.to_cryptography()
1702 assert isinstance(crypto_req, x509.CertificateSigningRequest)
1703
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001704
Alex Chanb00ede22017-01-30 07:24:40 +00001705class TestX509(_PKeyInteractionTestsMixin):
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001706 """
Alex Chanb00ede22017-01-30 07:24:40 +00001707 Tests for `OpenSSL.crypto.X509`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001708 """
Alex Gaynor03737182020-07-23 20:40:46 -04001709
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05001710 pemData = root_cert_pem + root_key_pem
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001711
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001712 def signable(self):
1713 """
Alex Chanb00ede22017-01-30 07:24:40 +00001714 Create and return a new `X509`.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001715 """
1716 return X509()
1717
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001718 def test_type(self):
1719 """
Alex Gaynor01f90a12019-02-07 09:14:48 -05001720 `X509` can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001721 """
Alex Gaynor03737182020-07-23 20:40:46 -04001722 assert is_consistent_type(X509, "X509")
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001723
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001724 def test_construction(self):
1725 """
Alex Gaynor01f90a12019-02-07 09:14:48 -05001726 `X509` takes no arguments and returns an instance of `X509`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001727 """
1728 certificate = X509()
Alex Gaynor01f90a12019-02-07 09:14:48 -05001729 assert isinstance(certificate, X509)
Alex Gaynor03737182020-07-23 20:40:46 -04001730 assert type(certificate).__name__ == "X509"
Alex Chanb00ede22017-01-30 07:24:40 +00001731 assert type(certificate) == X509
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001732
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001733 def test_set_version_wrong_args(self):
1734 """
Alex Chanb00ede22017-01-30 07:24:40 +00001735 `X509.set_version` raises `TypeError` if invoked with an argument
1736 not of type `int`.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001737 """
1738 cert = X509()
Alex Chanb00ede22017-01-30 07:24:40 +00001739 with pytest.raises(TypeError):
1740 cert.set_version(None)
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001741
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001742 def test_version(self):
1743 """
Alex Chanb00ede22017-01-30 07:24:40 +00001744 `X509.set_version` sets the certificate version number.
1745 `X509.get_version` retrieves it.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001746 """
1747 cert = X509()
1748 cert.set_version(1234)
Alex Chanb00ede22017-01-30 07:24:40 +00001749 assert cert.get_version() == 1234
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001750
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001751 def test_serial_number(self):
1752 """
Alex Chanb00ede22017-01-30 07:24:40 +00001753 The serial number of an `X509` can be retrieved and
1754 modified with `X509.get_serial_number` and
1755 `X509.set_serial_number`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001756 """
1757 certificate = X509()
Alex Chanb00ede22017-01-30 07:24:40 +00001758 with pytest.raises(TypeError):
1759 certificate.set_serial_number("1")
1760 assert certificate.get_serial_number() == 0
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001761 certificate.set_serial_number(1)
Alex Chanb00ede22017-01-30 07:24:40 +00001762 assert certificate.get_serial_number() == 1
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001763 certificate.set_serial_number(2 ** 32 + 1)
Alex Chanb00ede22017-01-30 07:24:40 +00001764 assert certificate.get_serial_number() == 2 ** 32 + 1
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001765 certificate.set_serial_number(2 ** 64 + 1)
Alex Chanb00ede22017-01-30 07:24:40 +00001766 assert certificate.get_serial_number() == 2 ** 64 + 1
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001767 certificate.set_serial_number(2 ** 128 + 1)
Alex Chanb00ede22017-01-30 07:24:40 +00001768 assert certificate.get_serial_number() == 2 ** 128 + 1
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001769
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001770 def _setBoundTest(self, which):
1771 """
Alex Chanb00ede22017-01-30 07:24:40 +00001772 `X509.set_notBefore` takes a string in the format of an
Alex Gaynor31287502015-09-05 16:11:27 -04001773 ASN1 GENERALIZEDTIME and sets the beginning of the certificate's
1774 validity period to it.
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001775 """
1776 certificate = X509()
Alex Gaynor03737182020-07-23 20:40:46 -04001777 set = getattr(certificate, "set_not" + which)
1778 get = getattr(certificate, "get_not" + which)
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001779
Jean-Paul Calderonee0615b52008-03-09 21:44:46 -04001780 # Starts with no value.
Alex Chanb00ede22017-01-30 07:24:40 +00001781 assert get() is None
Jean-Paul Calderonee0615b52008-03-09 21:44:46 -04001782
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001783 # GMT (Or is it UTC?) -exarkun
Alex Gaynore7f51982016-09-11 11:48:14 -04001784 when = b"20040203040506Z"
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001785 set(when)
Alex Chanb00ede22017-01-30 07:24:40 +00001786 assert get() == when
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001787
1788 # A plus two hours and thirty minutes offset
Alex Gaynore7f51982016-09-11 11:48:14 -04001789 when = b"20040203040506+0530"
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001790 set(when)
Alex Chanb00ede22017-01-30 07:24:40 +00001791 assert get() == when
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001792
1793 # A minus one hour fifteen minutes offset
Alex Gaynore7f51982016-09-11 11:48:14 -04001794 when = b"20040203040506-0115"
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001795 set(when)
Alex Chanb00ede22017-01-30 07:24:40 +00001796 assert get() == when
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001797
1798 # An invalid string results in a ValueError
Alex Chanb00ede22017-01-30 07:24:40 +00001799 with pytest.raises(ValueError):
1800 set(b"foo bar")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001801
Jean-Paul Calderone31ca2002010-01-30 15:14:43 -05001802 # The wrong number of arguments results in a TypeError.
Alex Chanb00ede22017-01-30 07:24:40 +00001803 with pytest.raises(TypeError):
1804 set()
Alex Gaynor85b49702015-09-05 16:30:59 -04001805 with pytest.raises(TypeError):
1806 set(b"20040203040506Z", b"20040203040506Z")
Alex Chanb00ede22017-01-30 07:24:40 +00001807 with pytest.raises(TypeError):
1808 get(b"foo bar")
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001809
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001810 # XXX ASN1_TIME (not GENERALIZEDTIME)
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001811
1812 def test_set_notBefore(self):
1813 """
Alex Chanb00ede22017-01-30 07:24:40 +00001814 `X509.set_notBefore` takes a string in the format of an
Alex Gaynor31287502015-09-05 16:11:27 -04001815 ASN1 GENERALIZEDTIME and sets the beginning of the certificate's
1816 validity period to it.
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001817 """
1818 self._setBoundTest("Before")
1819
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001820 def test_set_notAfter(self):
1821 """
Alex Chanb00ede22017-01-30 07:24:40 +00001822 `X509.set_notAfter` takes a string in the format of an ASN1
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001823 GENERALIZEDTIME and sets the end of the certificate's validity period
1824 to it.
1825 """
1826 self._setBoundTest("After")
Jean-Paul Calderone76576d52008-03-24 16:04:46 -04001827
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001828 def test_get_notBefore(self):
1829 """
Alex Chanb00ede22017-01-30 07:24:40 +00001830 `X509.get_notBefore` returns a string in the format of an
Alex Gaynor31287502015-09-05 16:11:27 -04001831 ASN1 GENERALIZEDTIME even for certificates which store it as UTCTIME
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001832 internally.
1833 """
Paul Kehrera40898b2017-06-11 16:30:58 -10001834 cert = load_certificate(FILETYPE_PEM, old_root_cert_pem)
Alex Chanb00ede22017-01-30 07:24:40 +00001835 assert cert.get_notBefore() == b"20090325123658Z"
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001836
Rick Dean38a05c82009-07-18 01:41:30 -05001837 def test_get_notAfter(self):
1838 """
Alex Chanb00ede22017-01-30 07:24:40 +00001839 `X509.get_notAfter` returns a string in the format of an
Alex Gaynor31287502015-09-05 16:11:27 -04001840 ASN1 GENERALIZEDTIME even for certificates which store it as UTCTIME
Rick Dean38a05c82009-07-18 01:41:30 -05001841 internally.
1842 """
Paul Kehrera40898b2017-06-11 16:30:58 -10001843 cert = load_certificate(FILETYPE_PEM, old_root_cert_pem)
Alex Chanb00ede22017-01-30 07:24:40 +00001844 assert cert.get_notAfter() == b"20170611123658Z"
Rick Dean38a05c82009-07-18 01:41:30 -05001845
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001846 def test_gmtime_adj_notBefore_wrong_args(self):
1847 """
Alex Chanb00ede22017-01-30 07:24:40 +00001848 `X509.gmtime_adj_notBefore` raises `TypeError` if called with a
1849 non-`int` argument.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001850 """
1851 cert = X509()
Alex Chanb00ede22017-01-30 07:24:40 +00001852 with pytest.raises(TypeError):
1853 cert.gmtime_adj_notBefore(None)
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001854
Alex Gaynor7f5610c2017-07-07 00:09:34 -04001855 @flaky.flaky
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001856 def test_gmtime_adj_notBefore(self):
1857 """
Alex Chanb00ede22017-01-30 07:24:40 +00001858 `X509.gmtime_adj_notBefore` changes the not-before timestamp to be the
1859 current time plus the number of seconds passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001860 """
1861 cert = load_certificate(FILETYPE_PEM, self.pemData)
Alex Gaynor03737182020-07-23 20:40:46 -04001862 not_before_min = datetime.utcnow().replace(microsecond=0) + timedelta(
1863 seconds=100
Alex Gaynor85b49702015-09-05 16:30:59 -04001864 )
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001865 cert.gmtime_adj_notBefore(100)
Alex Gaynor85b49702015-09-05 16:30:59 -04001866 not_before = datetime.strptime(
1867 cert.get_notBefore().decode(), "%Y%m%d%H%M%SZ"
1868 )
Alex Gaynor7f5610c2017-07-07 00:09:34 -04001869 not_before_max = datetime.utcnow() + timedelta(seconds=100)
Alex Chanb00ede22017-01-30 07:24:40 +00001870 assert not_before_min <= not_before <= not_before_max
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001871
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001872 def test_gmtime_adj_notAfter_wrong_args(self):
1873 """
Alex Chanb00ede22017-01-30 07:24:40 +00001874 `X509.gmtime_adj_notAfter` raises `TypeError` if called with a
1875 non-`int` argument.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001876 """
1877 cert = X509()
Alex Chanb00ede22017-01-30 07:24:40 +00001878 with pytest.raises(TypeError):
1879 cert.gmtime_adj_notAfter(None)
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001880
Alex Gaynor642de6f2017-07-24 00:57:38 -04001881 @flaky.flaky
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001882 def test_gmtime_adj_notAfter(self):
1883 """
Alex Chanb00ede22017-01-30 07:24:40 +00001884 `X509.gmtime_adj_notAfter` changes the not-after timestamp
Alex Gaynor31287502015-09-05 16:11:27 -04001885 to be the current time plus the number of seconds passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001886 """
1887 cert = load_certificate(FILETYPE_PEM, self.pemData)
Alex Gaynor03737182020-07-23 20:40:46 -04001888 not_after_min = datetime.utcnow().replace(microsecond=0) + timedelta(
1889 seconds=100
Alex Gaynor85b49702015-09-05 16:30:59 -04001890 )
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001891 cert.gmtime_adj_notAfter(100)
Alex Gaynor85b49702015-09-05 16:30:59 -04001892 not_after = datetime.strptime(
1893 cert.get_notAfter().decode(), "%Y%m%d%H%M%SZ"
1894 )
Maximilian Hilsbed25c92015-07-25 12:58:07 +02001895 not_after_max = datetime.utcnow() + timedelta(seconds=100)
Alex Chanb00ede22017-01-30 07:24:40 +00001896 assert not_after_min <= not_after <= not_after_max
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001897
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001898 def test_has_expired(self):
1899 """
Alex Chanb00ede22017-01-30 07:24:40 +00001900 `X509.has_expired` returns `True` if the certificate's not-after time
1901 is in the past.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001902 """
1903 cert = X509()
1904 cert.gmtime_adj_notAfter(-1)
Alex Chanb00ede22017-01-30 07:24:40 +00001905 assert cert.has_expired()
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001906
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001907 def test_has_not_expired(self):
1908 """
Alex Chanb00ede22017-01-30 07:24:40 +00001909 `X509.has_expired` returns `False` if the certificate's not-after time
1910 is in the future.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001911 """
1912 cert = X509()
1913 cert.gmtime_adj_notAfter(2)
Alex Chanb00ede22017-01-30 07:24:40 +00001914 assert not cert.has_expired()
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001915
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001916 def test_root_has_not_expired(self):
1917 """
Alex Chanb00ede22017-01-30 07:24:40 +00001918 `X509.has_expired` returns `False` if the certificate's not-after time
1919 is in the future.
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001920 """
1921 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Alex Chanb00ede22017-01-30 07:24:40 +00001922 assert not cert.has_expired()
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001923
Rick Dean38a05c82009-07-18 01:41:30 -05001924 def test_digest(self):
1925 """
Alex Chanb00ede22017-01-30 07:24:40 +00001926 `X509.digest` returns a string giving ":"-separated hex-encoded
Alex Gaynor31287502015-09-05 16:11:27 -04001927 words of the digest of the certificate.
Rick Dean38a05c82009-07-18 01:41:30 -05001928 """
Paul Kehrera40898b2017-06-11 16:30:58 -10001929 cert = load_certificate(FILETYPE_PEM, old_root_cert_pem)
Alex Chanb00ede22017-01-30 07:24:40 +00001930 assert (
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001931 # This is MD5 instead of GOOD_DIGEST because the digest algorithm
1932 # actually matters to the assertion (ie, another arbitrary, good
1933 # digest will not product the same digest).
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001934 # Digest verified with the command:
1935 # openssl x509 -in root_cert.pem -noout -fingerprint -md5
Alex Gaynor03737182020-07-23 20:40:46 -04001936 cert.digest("MD5")
1937 == b"19:B3:05:26:2B:F8:F2:FF:0B:8F:21:07:A8:28:B8:75"
1938 )
Rick Dean38a05c82009-07-18 01:41:30 -05001939
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001940 def _extcert(self, pkey, extensions):
1941 cert = X509()
David Benjamin6b799472020-06-24 17:14:16 -04001942 # Certificates with extensions must be X.509v3, which is encoded with a
1943 # version of two.
1944 cert.set_version(2)
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001945 cert.set_pubkey(pkey)
1946 cert.get_subject().commonName = "Unit Tests"
1947 cert.get_issuer().commonName = "Unit Tests"
Alex Gaynore7f51982016-09-11 11:48:14 -04001948 when = datetime.now().strftime("%Y%m%d%H%M%SZ").encode("ascii")
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001949 cert.set_notBefore(when)
1950 cert.set_notAfter(when)
1951
1952 cert.add_extensions(extensions)
Alex Gaynor03737182020-07-23 20:40:46 -04001953 cert.sign(pkey, "sha1")
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001954 return load_certificate(
Alex Gaynor03737182020-07-23 20:40:46 -04001955 FILETYPE_PEM, dump_certificate(FILETYPE_PEM, cert)
1956 )
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001957
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001958 def test_extension_count(self):
1959 """
Alex Chanb00ede22017-01-30 07:24:40 +00001960 `X509.get_extension_count` returns the number of extensions
Alex Gaynor31287502015-09-05 16:11:27 -04001961 that are present in the certificate.
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001962 """
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001963 pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
Alex Gaynor03737182020-07-23 20:40:46 -04001964 ca = X509Extension(b"basicConstraints", True, b"CA:FALSE")
1965 key = X509Extension(b"keyUsage", True, b"digitalSignature")
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001966 subjectAltName = X509Extension(
Alex Gaynor03737182020-07-23 20:40:46 -04001967 b"subjectAltName", True, b"DNS:example.com"
1968 )
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001969
1970 # Try a certificate with no extensions at all.
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001971 c = self._extcert(pkey, [])
Alex Chanb00ede22017-01-30 07:24:40 +00001972 assert c.get_extension_count() == 0
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001973
1974 # And a certificate with one
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001975 c = self._extcert(pkey, [ca])
Alex Chanb00ede22017-01-30 07:24:40 +00001976 assert c.get_extension_count() == 1
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001977
1978 # And a certificate with several
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001979 c = self._extcert(pkey, [ca, key, subjectAltName])
Alex Chanb00ede22017-01-30 07:24:40 +00001980 assert c.get_extension_count() == 3
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001981
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001982 def test_get_extension(self):
1983 """
Alex Chanb00ede22017-01-30 07:24:40 +00001984 `X509.get_extension` takes an integer and returns an
1985 `X509Extension` corresponding to the extension at that index.
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001986 """
1987 pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
Alex Gaynor03737182020-07-23 20:40:46 -04001988 ca = X509Extension(b"basicConstraints", True, b"CA:FALSE")
1989 key = X509Extension(b"keyUsage", True, b"digitalSignature")
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001990 subjectAltName = X509Extension(
Alex Gaynor03737182020-07-23 20:40:46 -04001991 b"subjectAltName", False, b"DNS:example.com"
1992 )
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001993
1994 cert = self._extcert(pkey, [ca, key, subjectAltName])
1995
1996 ext = cert.get_extension(0)
Alex Chanb00ede22017-01-30 07:24:40 +00001997 assert isinstance(ext, X509Extension)
1998 assert ext.get_critical()
Alex Gaynor03737182020-07-23 20:40:46 -04001999 assert ext.get_short_name() == b"basicConstraints"
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04002000
2001 ext = cert.get_extension(1)
Alex Chanb00ede22017-01-30 07:24:40 +00002002 assert isinstance(ext, X509Extension)
2003 assert ext.get_critical()
Alex Gaynor03737182020-07-23 20:40:46 -04002004 assert ext.get_short_name() == b"keyUsage"
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04002005
2006 ext = cert.get_extension(2)
Alex Chanb00ede22017-01-30 07:24:40 +00002007 assert isinstance(ext, X509Extension)
2008 assert not ext.get_critical()
Alex Gaynor03737182020-07-23 20:40:46 -04002009 assert ext.get_short_name() == b"subjectAltName"
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04002010
Alex Chanb00ede22017-01-30 07:24:40 +00002011 with pytest.raises(IndexError):
2012 cert.get_extension(-1)
2013 with pytest.raises(IndexError):
2014 cert.get_extension(4)
2015 with pytest.raises(TypeError):
2016 cert.get_extension("hello")
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04002017
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04002018 def test_nullbyte_subjectAltName(self):
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04002019 """
Jean-Paul Calderone9af07b02013-08-23 16:07:31 -04002020 The fields of a `subjectAltName` extension on an X509 may contain NUL
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04002021 bytes and this value is reflected in the string representation of the
2022 extension object.
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04002023 """
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04002024 cert = load_certificate(FILETYPE_PEM, nulbyteSubjectAltNamePEM)
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04002025
2026 ext = cert.get_extension(3)
Alex Gaynor03737182020-07-23 20:40:46 -04002027 assert ext.get_short_name() == b"subjectAltName"
Alex Chanb00ede22017-01-30 07:24:40 +00002028 assert (
Alex Gaynore7f51982016-09-11 11:48:14 -04002029 b"DNS:altnull.python.org\x00example.com, "
2030 b"email:null@python.org\x00user@example.org, "
2031 b"URI:http://null.python.org\x00http://example.org, "
Alex Gaynor03737182020-07-23 20:40:46 -04002032 b"IP Address:192.0.2.1, IP Address:2001:DB8:0:0:0:0:0:1\n"
2033 == str(ext).encode("ascii")
2034 )
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04002035
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002036 def test_invalid_digest_algorithm(self):
2037 """
Alex Chanb00ede22017-01-30 07:24:40 +00002038 `X509.digest` raises `ValueError` if called with an unrecognized hash
2039 algorithm.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002040 """
2041 cert = X509()
Alex Chanb00ede22017-01-30 07:24:40 +00002042 with pytest.raises(ValueError):
2043 cert.digest(BAD_DIGEST)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002044
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002045 def test_get_subject(self):
2046 """
Alex Chanb00ede22017-01-30 07:24:40 +00002047 `X509.get_subject` returns an `X509Name` instance.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002048 """
2049 cert = load_certificate(FILETYPE_PEM, self.pemData)
2050 subj = cert.get_subject()
Alex Chanb00ede22017-01-30 07:24:40 +00002051 assert isinstance(subj, X509Name)
Alex Gaynor03737182020-07-23 20:40:46 -04002052 assert subj.get_components() == [
2053 (b"C", b"US"),
2054 (b"ST", b"IL"),
2055 (b"L", b"Chicago"),
2056 (b"O", b"Testing"),
2057 (b"CN", b"Testing Root CA"),
2058 ]
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002059
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002060 def test_set_subject_wrong_args(self):
2061 """
Alex Chanb00ede22017-01-30 07:24:40 +00002062 `X509.set_subject` raises a `TypeError` if called with an argument not
2063 of type `X509Name`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002064 """
2065 cert = X509()
Alex Gaynor85b49702015-09-05 16:30:59 -04002066 with pytest.raises(TypeError):
Alex Chanb00ede22017-01-30 07:24:40 +00002067 cert.set_subject(None)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002068
2069 def test_set_subject(self):
2070 """
Alex Chanb00ede22017-01-30 07:24:40 +00002071 `X509.set_subject` changes the subject of the certificate to the one
2072 passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002073 """
2074 cert = X509()
2075 name = cert.get_subject()
Alex Gaynor03737182020-07-23 20:40:46 -04002076 name.C = "AU"
2077 name.OU = "Unit Tests"
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002078 cert.set_subject(name)
Alex Gaynor03737182020-07-23 20:40:46 -04002079 assert cert.get_subject().get_components() == [
2080 (b"C", b"AU"),
2081 (b"OU", b"Unit Tests"),
2082 ]
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002083
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002084 def test_get_issuer(self):
2085 """
Alex Chanb00ede22017-01-30 07:24:40 +00002086 `X509.get_issuer` returns an `X509Name` instance.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002087 """
2088 cert = load_certificate(FILETYPE_PEM, self.pemData)
2089 subj = cert.get_issuer()
Alex Chanb00ede22017-01-30 07:24:40 +00002090 assert isinstance(subj, X509Name)
Jean-Paul Calderone30a4cb32010-08-11 23:54:12 -04002091 comp = subj.get_components()
Alex Gaynor03737182020-07-23 20:40:46 -04002092 assert comp == [
2093 (b"C", b"US"),
2094 (b"ST", b"IL"),
2095 (b"L", b"Chicago"),
2096 (b"O", b"Testing"),
2097 (b"CN", b"Testing Root CA"),
2098 ]
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002099
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002100 def test_set_issuer_wrong_args(self):
2101 """
Alex Chanb00ede22017-01-30 07:24:40 +00002102 `X509.set_issuer` raises a `TypeError` if called with an argument not
2103 of type `X509Name`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002104 """
2105 cert = X509()
Alex Chanb00ede22017-01-30 07:24:40 +00002106 with pytest.raises(TypeError):
2107 cert.set_issuer(None)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002108
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002109 def test_set_issuer(self):
2110 """
Alex Chanb00ede22017-01-30 07:24:40 +00002111 `X509.set_issuer` changes the issuer of the certificate to the
Alex Gaynor31287502015-09-05 16:11:27 -04002112 one passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002113 """
2114 cert = X509()
2115 name = cert.get_issuer()
Alex Gaynor03737182020-07-23 20:40:46 -04002116 name.C = "AU"
2117 name.OU = "Unit Tests"
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002118 cert.set_issuer(name)
Alex Gaynor03737182020-07-23 20:40:46 -04002119 assert cert.get_issuer().get_components() == [
2120 (b"C", b"AU"),
2121 (b"OU", b"Unit Tests"),
2122 ]
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002123
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002124 def test_get_pubkey_uninitialized(self):
2125 """
Alex Chanb00ede22017-01-30 07:24:40 +00002126 When called on a certificate with no public key, `X509.get_pubkey`
2127 raises `OpenSSL.crypto.Error`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002128 """
2129 cert = X509()
Alex Chanb00ede22017-01-30 07:24:40 +00002130 with pytest.raises(Error):
2131 cert.get_pubkey()
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002132
Alex Gaynor7778e792016-07-03 23:38:48 -04002133 def test_set_pubkey_wrong_type(self):
2134 """
Alex Chanb00ede22017-01-30 07:24:40 +00002135 `X509.set_pubkey` raises `TypeError` when given an object of the
2136 wrong type.
Alex Gaynor7778e792016-07-03 23:38:48 -04002137 """
2138 cert = X509()
2139 with pytest.raises(TypeError):
2140 cert.set_pubkey(object())
2141
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04002142 def test_subject_name_hash(self):
2143 """
Alex Chanb00ede22017-01-30 07:24:40 +00002144 `X509.subject_name_hash` returns the hash of the certificate's
Alex Gaynor31287502015-09-05 16:11:27 -04002145 subject name.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04002146 """
2147 cert = load_certificate(FILETYPE_PEM, self.pemData)
Alex Gaynor4cb05202019-02-02 11:06:41 -05002148 # SHA1
2149 assert cert.subject_name_hash() == 3278919224
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04002150
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04002151 def test_get_signature_algorithm(self):
2152 """
Alex Chanb00ede22017-01-30 07:24:40 +00002153 `X509.get_signature_algorithm` returns a string which means
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04002154 the algorithm used to sign the certificate.
2155 """
2156 cert = load_certificate(FILETYPE_PEM, self.pemData)
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05002157 assert b"sha256WithRSAEncryption" == cert.get_signature_algorithm()
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04002158
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04002159 def test_get_undefined_signature_algorithm(self):
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04002160 """
Alex Chanb00ede22017-01-30 07:24:40 +00002161 `X509.get_signature_algorithm` raises `ValueError` if the signature
2162 algorithm is undefined or unknown.
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04002163 """
2164 # This certificate has been modified to indicate a bogus OID in the
2165 # signature algorithm field so that OpenSSL does not recognize it.
Alex Gaynore7f51982016-09-11 11:48:14 -04002166 certPEM = b"""\
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04002167-----BEGIN CERTIFICATE-----
2168MIIC/zCCAmigAwIBAgIBATAGBgJ8BQUAMHsxCzAJBgNVBAYTAlNHMREwDwYDVQQK
2169EwhNMkNyeXB0bzEUMBIGA1UECxMLTTJDcnlwdG8gQ0ExJDAiBgNVBAMTG00yQ3J5
2170cHRvIENlcnRpZmljYXRlIE1hc3RlcjEdMBsGCSqGSIb3DQEJARYObmdwc0Bwb3N0
2171MS5jb20wHhcNMDAwOTEwMDk1MTMwWhcNMDIwOTEwMDk1MTMwWjBTMQswCQYDVQQG
2172EwJTRzERMA8GA1UEChMITTJDcnlwdG8xEjAQBgNVBAMTCWxvY2FsaG9zdDEdMBsG
2173CSqGSIb3DQEJARYObmdwc0Bwb3N0MS5jb20wXDANBgkqhkiG9w0BAQEFAANLADBI
2174AkEArL57d26W9fNXvOhNlZzlPOACmvwOZ5AdNgLzJ1/MfsQQJ7hHVeHmTAjM664V
2175+fXvwUGJLziCeBo1ysWLRnl8CQIDAQABo4IBBDCCAQAwCQYDVR0TBAIwADAsBglg
2176hkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0O
2177BBYEFM+EgpK+eyZiwFU1aOPSbczbPSpVMIGlBgNVHSMEgZ0wgZqAFPuHI2nrnDqT
2178FeXFvylRT/7tKDgBoX+kfTB7MQswCQYDVQQGEwJTRzERMA8GA1UEChMITTJDcnlw
2179dG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtNMkNyeXB0byBDZXJ0
2180aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tggEA
2181MA0GCSqGSIb3DQEBBAUAA4GBADv8KpPo+gfJxN2ERK1Y1l17sz/ZhzoGgm5XCdbx
2182jEY7xKfpQngV599k1xhl11IMqizDwu0855agrckg2MCTmOI9DZzDD77tAYb+Dk0O
2183PEVk0Mk/V0aIsDE9bolfCi/i/QWZ3N8s5nTWMNyBBBmoSliWCm4jkkRZRD0ejgTN
2184tgI5
2185-----END CERTIFICATE-----
Alex Gaynore7f51982016-09-11 11:48:14 -04002186"""
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04002187 cert = load_certificate(FILETYPE_PEM, certPEM)
Alex Chanb00ede22017-01-30 07:24:40 +00002188 with pytest.raises(ValueError):
2189 cert.get_signature_algorithm()
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04002190
Alex Gaynor37726112016-07-04 09:51:32 -04002191 def test_sign_bad_pubkey_type(self):
2192 """
Alex Chanb00ede22017-01-30 07:24:40 +00002193 `X509.sign` raises `TypeError` when called with the wrong type.
Alex Gaynor37726112016-07-04 09:51:32 -04002194 """
2195 cert = X509()
2196 with pytest.raises(TypeError):
2197 cert.sign(object(), b"sha256")
2198
Alex Gaynor9939ba12017-06-25 16:28:24 -04002199 def test_convert_from_cryptography(self):
2200 crypto_cert = x509.load_pem_x509_certificate(
2201 intermediate_cert_pem, backend
2202 )
2203 cert = X509.from_cryptography(crypto_cert)
2204
2205 assert isinstance(cert, X509)
2206 assert cert.get_version() == crypto_cert.version.value
2207
2208 def test_convert_from_cryptography_unsupported_type(self):
2209 with pytest.raises(TypeError):
2210 X509.from_cryptography(object())
2211
2212 def test_convert_to_cryptography_key(self):
2213 cert = load_certificate(FILETYPE_PEM, intermediate_cert_pem)
2214 crypto_cert = cert.to_cryptography()
2215
2216 assert isinstance(crypto_cert, x509.Certificate)
2217 assert crypto_cert.version.value == cert.get_version()
2218
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04002219
Alex Chan9e2a9932017-01-25 14:29:19 +00002220class TestX509Store(object):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002221 """
Alex Chan9e2a9932017-01-25 14:29:19 +00002222 Test for `OpenSSL.crypto.X509Store`.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002223 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002224
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002225 def test_type(self):
2226 """
Alex Chan9e2a9932017-01-25 14:29:19 +00002227 `X509Store` is a type object.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002228 """
Alex Gaynor03737182020-07-23 20:40:46 -04002229 assert is_consistent_type(X509Store, "X509Store")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002230
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002231 def test_add_cert(self):
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08002232 """
Alex Chan9e2a9932017-01-25 14:29:19 +00002233 `X509Store.add_cert` adds a `X509` instance to the certificate store.
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08002234 """
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05002235 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002236 store = X509Store()
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08002237 store.add_cert(cert)
2238
Alex Gaynor03737182020-07-23 20:40:46 -04002239 @pytest.mark.parametrize("cert", [None, 1.0, "cert", object()])
Alex Chanfb078d82017-04-20 11:16:15 +01002240 def test_add_cert_wrong_args(self, cert):
2241 """
2242 `X509Store.add_cert` raises `TypeError` if passed a non-X509 object
2243 as its first argument.
2244 """
2245 store = X509Store()
2246 with pytest.raises(TypeError):
2247 store.add_cert(cert)
2248
Paul Kehrer0e6c5532018-08-23 10:52:15 -05002249 def test_add_cert_accepts_duplicate(self):
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08002250 """
Paul Kehrer0e6c5532018-08-23 10:52:15 -05002251 `X509Store.add_cert` doesn't raise `OpenSSL.crypto.Error` if an attempt
2252 is made to add the same certificate to the store more than once.
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08002253 """
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05002254 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08002255 store = X509Store()
2256 store.add_cert(cert)
Paul Kehrer0e6c5532018-08-23 10:52:15 -05002257 store.add_cert(cert)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002258
Sándor Oroszi43c97762020-09-11 17:17:31 +02002259 @pytest.mark.parametrize(
2260 "cafile, capath, call_cafile, call_capath",
2261 [
2262 (
2263 "/cafile" + NON_ASCII,
2264 None,
2265 b"/cafile" + NON_ASCII.encode(sys.getfilesystemencoding()),
2266 _ffi.NULL,
2267 ),
2268 (
2269 b"/cafile" + NON_ASCII.encode("utf-8"),
2270 None,
2271 b"/cafile" + NON_ASCII.encode("utf-8"),
2272 _ffi.NULL,
2273 ),
2274 (
2275 None,
2276 "/capath" + NON_ASCII,
2277 _ffi.NULL,
2278 b"/capath" + NON_ASCII.encode(sys.getfilesystemencoding()),
2279 ),
2280 (
2281 None,
2282 b"/capath" + NON_ASCII.encode("utf-8"),
2283 _ffi.NULL,
2284 b"/capath" + NON_ASCII.encode("utf-8"),
2285 ),
2286 ],
2287 )
2288 def test_load_locations_parameters(
2289 self, cafile, capath, call_cafile, call_capath, monkeypatch
2290 ):
2291 class LibMock(object):
2292 def load_locations(self, store, cafile, capath):
2293 self.cafile = cafile
2294 self.capath = capath
2295 return 1
2296
2297 lib_mock = LibMock()
2298 monkeypatch.setattr(
2299 _lib, "X509_STORE_load_locations", lib_mock.load_locations
2300 )
2301
2302 store = X509Store()
2303 store.load_locations(cafile=cafile, capath=capath)
2304
2305 assert call_cafile == lib_mock.cafile
2306 assert call_capath == lib_mock.capath
2307
2308 def test_load_locations_fails_when_all_args_are_none(self):
2309 store = X509Store()
2310 with pytest.raises(Error):
2311 store.load_locations(None, None)
2312
2313 def test_load_locations_raises_error_on_failure(self, tmpdir):
2314 invalid_ca_file = tmpdir.join("invalid.pem")
2315 invalid_ca_file.write("This is not a certificate")
2316
2317 store = X509Store()
2318 with pytest.raises(Error):
2319 store.load_locations(cafile=str(invalid_ca_file))
2320
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002321
Alex Chanb00ede22017-01-30 07:24:40 +00002322class TestPKCS12(object):
Rick Dean623ee362009-07-17 12:22:16 -05002323 """
Alex Chanb00ede22017-01-30 07:24:40 +00002324 Test for `OpenSSL.crypto.PKCS12` and `OpenSSL.crypto.load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05002325 """
Alex Gaynor03737182020-07-23 20:40:46 -04002326
Jean-Paul Calderonec3a41f72009-07-25 12:36:02 -04002327 def test_type(self):
2328 """
Alex Gaynor01f90a12019-02-07 09:14:48 -05002329 `PKCS12` is a type object.
Jean-Paul Calderonec3a41f72009-07-25 12:36:02 -04002330 """
Alex Gaynor03737182020-07-23 20:40:46 -04002331 assert is_consistent_type(PKCS12, "PKCS12")
Jean-Paul Calderonec3a41f72009-07-25 12:36:02 -04002332
Rick Deanf94096c2009-07-18 14:23:06 -05002333 def test_empty_construction(self):
Rick Dean38a05c82009-07-18 01:41:30 -05002334 """
Alex Chanb00ede22017-01-30 07:24:40 +00002335 `PKCS12` returns a new instance of `PKCS12` with no certificate,
2336 private key, CA certificates, or friendly name.
Rick Dean38a05c82009-07-18 01:41:30 -05002337 """
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002338 p12 = PKCS12()
Alex Chanb00ede22017-01-30 07:24:40 +00002339 assert None is p12.get_certificate()
2340 assert None is p12.get_privatekey()
2341 assert None is p12.get_ca_certificates()
2342 assert None is p12.get_friendlyname()
Rick Dean623ee362009-07-17 12:22:16 -05002343
2344 def test_type_errors(self):
Rick Dean38a05c82009-07-18 01:41:30 -05002345 """
Alex Chanb00ede22017-01-30 07:24:40 +00002346 The `PKCS12` setter functions (`set_certificate`, `set_privatekey`,
2347 `set_ca_certificates`, and `set_friendlyname`) raise `TypeError`
2348 when passed objects of types other than those expected.
Rick Dean38a05c82009-07-18 01:41:30 -05002349 """
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002350 p12 = PKCS12()
Alex Chanb00ede22017-01-30 07:24:40 +00002351 for bad_arg in [3, PKey(), X509]:
2352 with pytest.raises(TypeError):
2353 p12.set_certificate(bad_arg)
Alex Gaynor03737182020-07-23 20:40:46 -04002354 for bad_arg in [3, "legbone", X509()]:
Alex Chanb00ede22017-01-30 07:24:40 +00002355 with pytest.raises(TypeError):
2356 p12.set_privatekey(bad_arg)
2357 for bad_arg in [3, X509(), (3, 4), (PKey(),)]:
2358 with pytest.raises(TypeError):
2359 p12.set_ca_certificates(bad_arg)
Alex Gaynor03737182020-07-23 20:40:46 -04002360 for bad_arg in [6, ("foo", "bar")]:
Alex Chanb00ede22017-01-30 07:24:40 +00002361 with pytest.raises(TypeError):
2362 p12.set_friendlyname(bad_arg)
Rick Dean623ee362009-07-17 12:22:16 -05002363
2364 def test_key_only(self):
2365 """
Alex Chanb00ede22017-01-30 07:24:40 +00002366 A `PKCS12` with only a private key can be exported using
2367 `PKCS12.export` and loaded again using `load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05002368 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002369 passwd = b"blah"
Rick Dean623ee362009-07-17 12:22:16 -05002370 p12 = PKCS12()
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05002371 pkey = load_privatekey(FILETYPE_PEM, root_key_pem)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002372 p12.set_privatekey(pkey)
Alex Chanb00ede22017-01-30 07:24:40 +00002373 assert None is p12.get_certificate()
2374 assert pkey == p12.get_privatekey()
Rick Dean321a0512009-08-13 17:21:29 -05002375 try:
2376 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
2377 except Error:
2378 # Some versions of OpenSSL will throw an exception
2379 # for this nearly useless PKCS12 we tried to generate:
2380 # [('PKCS12 routines', 'PKCS12_create', 'invalid null argument')]
2381 return
Rick Dean623ee362009-07-17 12:22:16 -05002382 p12 = load_pkcs12(dumped_p12, passwd)
Alex Chanb00ede22017-01-30 07:24:40 +00002383 assert None is p12.get_ca_certificates()
2384 assert None is p12.get_certificate()
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002385
2386 # OpenSSL fails to bring the key back to us. So sad. Perhaps in the
2387 # future this will be improved.
Alex Chanb00ede22017-01-30 07:24:40 +00002388 assert isinstance(p12.get_privatekey(), (PKey, type(None)))
Rick Dean623ee362009-07-17 12:22:16 -05002389
2390 def test_cert_only(self):
2391 """
Alex Chanb00ede22017-01-30 07:24:40 +00002392 A `PKCS12` with only a certificate can be exported using
2393 `PKCS12.export` and loaded again using `load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05002394 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002395 passwd = b"blah"
Rick Dean623ee362009-07-17 12:22:16 -05002396 p12 = PKCS12()
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05002397 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002398 p12.set_certificate(cert)
Alex Chanb00ede22017-01-30 07:24:40 +00002399 assert cert == p12.get_certificate()
2400 assert None is p12.get_privatekey()
Rick Dean321a0512009-08-13 17:21:29 -05002401 try:
2402 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
2403 except Error:
2404 # Some versions of OpenSSL will throw an exception
2405 # for this nearly useless PKCS12 we tried to generate:
2406 # [('PKCS12 routines', 'PKCS12_create', 'invalid null argument')]
2407 return
Rick Dean623ee362009-07-17 12:22:16 -05002408 p12 = load_pkcs12(dumped_p12, passwd)
Alex Chanb00ede22017-01-30 07:24:40 +00002409 assert None is p12.get_privatekey()
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002410
2411 # OpenSSL fails to bring the cert back to us. Groany mcgroan.
Alex Chanb00ede22017-01-30 07:24:40 +00002412 assert isinstance(p12.get_certificate(), (X509, type(None)))
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002413
2414 # Oh ho. It puts the certificate into the ca certificates list, in
2415 # fact. Totally bogus, I would think. Nevertheless, let's exploit
2416 # that to check to see if it reconstructed the certificate we expected
2417 # it to. At some point, hopefully this will change so that
2418 # p12.get_certificate() is actually what returns the loaded
2419 # certificate.
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05002420 assert root_cert_pem == dump_certificate(
Alex Gaynor03737182020-07-23 20:40:46 -04002421 FILETYPE_PEM, p12.get_ca_certificates()[0]
2422 )
Rick Dean623ee362009-07-17 12:22:16 -05002423
Alex Gaynor03737182020-07-23 20:40:46 -04002424 def gen_pkcs12(
2425 self, cert_pem=None, key_pem=None, ca_pem=None, friendly_name=None
2426 ):
Rick Dean623ee362009-07-17 12:22:16 -05002427 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002428 Generate a PKCS12 object with components from PEM. Verify that the set
2429 functions return None.
Rick Dean623ee362009-07-17 12:22:16 -05002430 """
Rick Deanf94096c2009-07-18 14:23:06 -05002431 p12 = PKCS12()
2432 if cert_pem:
2433 ret = p12.set_certificate(load_certificate(FILETYPE_PEM, cert_pem))
Alex Chanb00ede22017-01-30 07:24:40 +00002434 assert ret is None
Rick Deanf94096c2009-07-18 14:23:06 -05002435 if key_pem:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002436 ret = p12.set_privatekey(load_privatekey(FILETYPE_PEM, key_pem))
Alex Chanb00ede22017-01-30 07:24:40 +00002437 assert ret is None
Rick Deanf94096c2009-07-18 14:23:06 -05002438 if ca_pem:
Alex Gaynor85b49702015-09-05 16:30:59 -04002439 ret = p12.set_ca_certificates(
2440 (load_certificate(FILETYPE_PEM, ca_pem),)
2441 )
Alex Chanb00ede22017-01-30 07:24:40 +00002442 assert ret is None
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002443 if friendly_name:
2444 ret = p12.set_friendlyname(friendly_name)
Alex Chanb00ede22017-01-30 07:24:40 +00002445 assert ret is None
Rick Deanf94096c2009-07-18 14:23:06 -05002446 return p12
2447
Alex Gaynor03737182020-07-23 20:40:46 -04002448 def check_recovery(
2449 self, p12_str, key=None, cert=None, ca=None, passwd=b"", extra=()
2450 ):
Rick Deanf94096c2009-07-18 14:23:06 -05002451 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002452 Use openssl program to confirm three components are recoverable from a
2453 PKCS12 string.
Rick Deanf94096c2009-07-18 14:23:06 -05002454 """
2455 if key:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002456 recovered_key = _runopenssl(
Alex Gaynor03737182020-07-23 20:40:46 -04002457 p12_str,
2458 b"pkcs12",
2459 b"-nocerts",
2460 b"-nodes",
2461 b"-passin",
2462 b"pass:" + passwd,
2463 *extra
2464 )
2465 assert recovered_key[-len(key) :] == key
Rick Deanf94096c2009-07-18 14:23:06 -05002466 if cert:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002467 recovered_cert = _runopenssl(
Alex Gaynor03737182020-07-23 20:40:46 -04002468 p12_str,
2469 b"pkcs12",
2470 b"-clcerts",
2471 b"-nodes",
2472 b"-passin",
2473 b"pass:" + passwd,
2474 b"-nokeys",
2475 *extra
2476 )
2477 assert recovered_cert[-len(cert) :] == cert
Rick Deanf94096c2009-07-18 14:23:06 -05002478 if ca:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002479 recovered_cert = _runopenssl(
Alex Gaynor03737182020-07-23 20:40:46 -04002480 p12_str,
2481 b"pkcs12",
2482 b"-cacerts",
2483 b"-nodes",
2484 b"-passin",
2485 b"pass:" + passwd,
2486 b"-nokeys",
2487 *extra
2488 )
2489 assert recovered_cert[-len(ca) :] == ca
Rick Deanf94096c2009-07-18 14:23:06 -05002490
Stephen Holsapple38482622014-04-05 20:29:34 -07002491 def verify_pkcs12_container(self, p12):
2492 """
2493 Verify that the PKCS#12 container contains the correct client
2494 certificate and private key.
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002495
2496 :param p12: The PKCS12 instance to verify.
Alex Chanb00ede22017-01-30 07:24:40 +00002497 :type p12: `PKCS12`
Stephen Holsapple38482622014-04-05 20:29:34 -07002498 """
2499 cert_pem = dump_certificate(FILETYPE_PEM, p12.get_certificate())
2500 key_pem = dump_privatekey(FILETYPE_PEM, p12.get_privatekey())
Alex Gaynor03737182020-07-23 20:40:46 -04002501 assert (client_cert_pem, client_key_pem, None) == (
2502 cert_pem,
2503 key_pem,
2504 p12.get_ca_certificates(),
2505 )
Stephen Holsapple38482622014-04-05 20:29:34 -07002506
Rick Deanf94096c2009-07-18 14:23:06 -05002507 def test_load_pkcs12(self):
2508 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002509 A PKCS12 string generated using the openssl command line can be loaded
Alex Chanb00ede22017-01-30 07:24:40 +00002510 with `load_pkcs12` and its components extracted and examined.
Rick Deanf94096c2009-07-18 14:23:06 -05002511 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002512 passwd = b"whatever"
Rick Dean623ee362009-07-17 12:22:16 -05002513 pem = client_key_pem + client_cert_pem
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002514 p12_str = _runopenssl(
Alex Gaynor85b49702015-09-05 16:30:59 -04002515 pem,
2516 b"pkcs12",
2517 b"-export",
2518 b"-clcerts",
2519 b"-passout",
Alex Gaynor03737182020-07-23 20:40:46 -04002520 b"pass:" + passwd,
Alex Gaynor85b49702015-09-05 16:30:59 -04002521 )
Stephen Holsapple38482622014-04-05 20:29:34 -07002522 p12 = load_pkcs12(p12_str, passphrase=passwd)
2523 self.verify_pkcs12_container(p12)
2524
Abraham Martinc5484ba2015-03-25 15:33:05 +00002525 def test_load_pkcs12_text_passphrase(self):
2526 """
2527 A PKCS12 string generated using the openssl command line can be loaded
Alex Chanb00ede22017-01-30 07:24:40 +00002528 with `load_pkcs12` and its components extracted and examined.
Abraham Martinc5484ba2015-03-25 15:33:05 +00002529 Using text as passphrase instead of bytes. DeprecationWarning expected.
2530 """
2531 pem = client_key_pem + client_cert_pem
2532 passwd = b"whatever"
Alex Gaynor03737182020-07-23 20:40:46 -04002533 p12_str = _runopenssl(
2534 pem,
2535 b"pkcs12",
2536 b"-export",
2537 b"-clcerts",
2538 b"-passout",
2539 b"pass:" + passwd,
2540 )
Alex Chanb00ede22017-01-30 07:24:40 +00002541 with pytest.warns(DeprecationWarning) as w:
Abraham Martinc5484ba2015-03-25 15:33:05 +00002542 simplefilter("always")
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002543 p12 = load_pkcs12(p12_str, passphrase=b"whatever".decode("ascii"))
Alex Gaynor03737182020-07-23 20:40:46 -04002544 msg = "{0} for passphrase is no longer accepted, use bytes".format(
2545 WARNING_TYPE_EXPECTED
2546 )
2547 assert msg == str(w[-1].message)
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002548
Abraham Martinc5484ba2015-03-25 15:33:05 +00002549 self.verify_pkcs12_container(p12)
2550
Stephen Holsapple38482622014-04-05 20:29:34 -07002551 def test_load_pkcs12_no_passphrase(self):
2552 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002553 A PKCS12 string generated using openssl command line can be loaded with
Alex Chanb00ede22017-01-30 07:24:40 +00002554 `load_pkcs12` without a passphrase and its components extracted
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002555 and examined.
Stephen Holsapple38482622014-04-05 20:29:34 -07002556 """
2557 pem = client_key_pem + client_cert_pem
2558 p12_str = _runopenssl(
Alex Gaynor03737182020-07-23 20:40:46 -04002559 pem, b"pkcs12", b"-export", b"-clcerts", b"-passout", b"pass:"
2560 )
Stephen Holsapple38482622014-04-05 20:29:34 -07002561 p12 = load_pkcs12(p12_str)
2562 self.verify_pkcs12_container(p12)
2563
Stephen Holsapple38482622014-04-05 20:29:34 -07002564 def _dump_and_load(self, dump_passphrase, load_passphrase):
2565 """
2566 A helper method to dump and load a PKCS12 object.
2567 """
2568 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem)
2569 dumped_p12 = p12.export(passphrase=dump_passphrase, iter=2, maciter=3)
2570 return load_pkcs12(dumped_p12, passphrase=load_passphrase)
2571
Stephen Holsapple38482622014-04-05 20:29:34 -07002572 def test_load_pkcs12_null_passphrase_load_empty(self):
2573 """
2574 A PKCS12 string can be dumped with a null 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=None, load_passphrase=b"")
2580 )
Stephen Holsapple38482622014-04-05 20:29:34 -07002581
Stephen Holsapple38482622014-04-05 20:29:34 -07002582 def test_load_pkcs12_null_passphrase_load_null(self):
2583 """
2584 A PKCS12 string can be dumped with a null 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=None, load_passphrase=None)
2590 )
Stephen Holsapple38482622014-04-05 20:29:34 -07002591
Stephen Holsapple38482622014-04-05 20:29:34 -07002592 def test_load_pkcs12_empty_passphrase_load_empty(self):
2593 """
2594 A PKCS12 string can be dumped with an empty passphrase, loaded with an
Alex Chanb00ede22017-01-30 07:24:40 +00002595 empty passphrase with `load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002596 extracted and examined.
2597 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002598 self.verify_pkcs12_container(
Alex Gaynor03737182020-07-23 20:40:46 -04002599 self._dump_and_load(dump_passphrase=b"", load_passphrase=b"")
2600 )
Stephen Holsapple38482622014-04-05 20:29:34 -07002601
Stephen Holsapple38482622014-04-05 20:29:34 -07002602 def test_load_pkcs12_empty_passphrase_load_null(self):
2603 """
2604 A PKCS12 string can be dumped with an empty passphrase, loaded with a
Alex Chanb00ede22017-01-30 07:24:40 +00002605 null passphrase with `load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002606 extracted and examined.
2607 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002608 self.verify_pkcs12_container(
Alex Gaynor03737182020-07-23 20:40:46 -04002609 self._dump_and_load(dump_passphrase=b"", load_passphrase=None)
2610 )
Rick Deanf94096c2009-07-18 14:23:06 -05002611
Rick Deanee568302009-07-24 09:56:29 -05002612 def test_load_pkcs12_garbage(self):
2613 """
Alex Chanb00ede22017-01-30 07:24:40 +00002614 `load_pkcs12` raises `OpenSSL.crypto.Error` when passed
Alex Gaynor85b49702015-09-05 16:30:59 -04002615 a string which is not a PKCS12 dump.
Rick Deanee568302009-07-24 09:56:29 -05002616 """
Paul Kehrerc45a6ea2020-08-03 15:54:20 -05002617 passwd = b"whatever"
Alex Chanb00ede22017-01-30 07:24:40 +00002618 with pytest.raises(Error) as err:
Alex Gaynor03737182020-07-23 20:40:46 -04002619 load_pkcs12(b"fruit loops", passwd)
2620 assert err.value.args[0][0][0] == "asn1 encoding routines"
Alex Chanb00ede22017-01-30 07:24:40 +00002621 assert len(err.value.args[0][0]) == 3
Rick Deanee568302009-07-24 09:56:29 -05002622
Rick Deanf94096c2009-07-18 14:23:06 -05002623 def test_replace(self):
2624 """
Alex Chanb00ede22017-01-30 07:24:40 +00002625 `PKCS12.set_certificate` replaces the certificate in a PKCS12
2626 cluster. `PKCS12.set_privatekey` replaces the private key.
2627 `PKCS12.set_ca_certificates` replaces the CA certificates.
Rick Deanf94096c2009-07-18 14:23:06 -05002628 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002629 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
2630 p12.set_certificate(load_certificate(FILETYPE_PEM, server_cert_pem))
2631 p12.set_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002632 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Rick Deanf94096c2009-07-18 14:23:06 -05002633 client_cert = load_certificate(FILETYPE_PEM, client_cert_pem)
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002634 p12.set_ca_certificates([root_cert]) # not a tuple
Alex Chanb00ede22017-01-30 07:24:40 +00002635 assert 1 == len(p12.get_ca_certificates())
2636 assert root_cert == p12.get_ca_certificates()[0]
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002637 p12.set_ca_certificates([client_cert, root_cert])
Alex Chanb00ede22017-01-30 07:24:40 +00002638 assert 2 == len(p12.get_ca_certificates())
2639 assert client_cert == p12.get_ca_certificates()[0]
2640 assert root_cert == p12.get_ca_certificates()[1]
Rick Deanf94096c2009-07-18 14:23:06 -05002641
Rick Deanf94096c2009-07-18 14:23:06 -05002642 def test_friendly_name(self):
2643 """
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002644 The *friendlyName* of a PKCS12 can be set and retrieved via
Alex Chanb00ede22017-01-30 07:24:40 +00002645 `PKCS12.get_friendlyname` and `PKCS12_set_friendlyname`, and a
2646 `PKCS12` with a friendly name set can be dumped with `PKCS12.export`.
Rick Deanf94096c2009-07-18 14:23:06 -05002647 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002648 passwd = b'Dogmeat[]{}!@#$%^&*()~`?/.,<>-_+=";:'
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002649 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Alex Gaynor03737182020-07-23 20:40:46 -04002650 for friendly_name in [b"Serverlicious", None, b"###"]:
Rick Dean42d69e12009-07-20 11:36:08 -05002651 p12.set_friendlyname(friendly_name)
Alex Chanb00ede22017-01-30 07:24:40 +00002652 assert p12.get_friendlyname() == friendly_name
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002653 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
Rick Dean42d69e12009-07-20 11:36:08 -05002654 reloaded_p12 = load_pkcs12(dumped_p12, passwd)
Alex Chanb00ede22017-01-30 07:24:40 +00002655 assert p12.get_friendlyname() == reloaded_p12.get_friendlyname()
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002656 # We would use the openssl program to confirm the friendly
2657 # name, but it is not possible. The pkcs12 command
2658 # does not store the friendly name in the cert's
Rick Dean42d69e12009-07-20 11:36:08 -05002659 # alias, which we could then extract.
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002660 self.check_recovery(
Alex Gaynor03737182020-07-23 20:40:46 -04002661 dumped_p12,
2662 key=server_key_pem,
2663 cert=server_cert_pem,
2664 ca=root_cert_pem,
2665 passwd=passwd,
2666 )
Rick Deanf94096c2009-07-18 14:23:06 -05002667
Rick Deanf94096c2009-07-18 14:23:06 -05002668 def test_various_empty_passphrases(self):
2669 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002670 Test that missing, None, and '' passphrases are identical for PKCS12
2671 export.
Rick Deanf94096c2009-07-18 14:23:06 -05002672 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002673 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002674 passwd = b""
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002675 dumped_p12_empty = p12.export(iter=2, maciter=0, passphrase=passwd)
2676 dumped_p12_none = p12.export(iter=3, maciter=2, passphrase=None)
2677 dumped_p12_nopw = p12.export(iter=9, maciter=4)
2678 for dumped_p12 in [dumped_p12_empty, dumped_p12_none, dumped_p12_nopw]:
2679 self.check_recovery(
Alex Gaynor03737182020-07-23 20:40:46 -04002680 dumped_p12,
2681 key=client_key_pem,
2682 cert=client_cert_pem,
2683 ca=root_cert_pem,
2684 passwd=passwd,
2685 )
Rick Deanf94096c2009-07-18 14:23:06 -05002686
Rick Deanf94096c2009-07-18 14:23:06 -05002687 def test_removing_ca_cert(self):
2688 """
Alex Chanb00ede22017-01-30 07:24:40 +00002689 Passing `None` to `PKCS12.set_ca_certificates` removes all CA
2690 certificates.
Rick Deanf94096c2009-07-18 14:23:06 -05002691 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002692 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2693 p12.set_ca_certificates(None)
Alex Chanb00ede22017-01-30 07:24:40 +00002694 assert None is p12.get_ca_certificates()
Rick Deanf94096c2009-07-18 14:23:06 -05002695
Rick Deanf94096c2009-07-18 14:23:06 -05002696 def test_export_without_mac(self):
2697 """
Alex Chanb00ede22017-01-30 07:24:40 +00002698 Exporting a PKCS12 with a `maciter` of `-1` excludes the MAC entirely.
Rick Deanf94096c2009-07-18 14:23:06 -05002699 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002700 passwd = b"Lake Michigan"
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002701 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Rick Dean623ee362009-07-17 12:22:16 -05002702 dumped_p12 = p12.export(maciter=-1, passphrase=passwd, iter=2)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002703 self.check_recovery(
Alex Gaynor03737182020-07-23 20:40:46 -04002704 dumped_p12,
2705 key=server_key_pem,
2706 cert=server_cert_pem,
2707 passwd=passwd,
2708 extra=(b"-nomacver",),
2709 )
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002710
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002711 def test_load_without_mac(self):
2712 """
2713 Loading a PKCS12 without a MAC does something other than crash.
2714 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002715 passwd = b"Lake Michigan"
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002716 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2717 dumped_p12 = p12.export(maciter=-1, passphrase=passwd, iter=2)
Rick Dean321a0512009-08-13 17:21:29 -05002718 try:
2719 recovered_p12 = load_pkcs12(dumped_p12, passwd)
2720 # The person who generated this PCKS12 should be flogged,
2721 # or better yet we should have a means to determine
2722 # whether a PCKS12 had a MAC that was verified.
2723 # Anyway, libopenssl chooses to allow it, so the
2724 # pyopenssl binding does as well.
Alex Chanb00ede22017-01-30 07:24:40 +00002725 assert isinstance(recovered_p12, PKCS12)
Rick Dean321a0512009-08-13 17:21:29 -05002726 except Error:
2727 # Failing here with an exception is preferred as some openssl
2728 # versions do.
2729 pass
Rick Dean623ee362009-07-17 12:22:16 -05002730
Rick Dean25bcc1f2009-07-20 11:53:13 -05002731 def test_zero_len_list_for_ca(self):
2732 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002733 A PKCS12 with an empty CA certificates list can be exported.
Rick Dean25bcc1f2009-07-20 11:53:13 -05002734 """
Alex Gaynor03737182020-07-23 20:40:46 -04002735 passwd = b"Hobie 18"
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002736 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem)
Alex Gaynor85b49702015-09-05 16:30:59 -04002737 p12.set_ca_certificates([])
Alex Chanb00ede22017-01-30 07:24:40 +00002738 assert () == p12.get_ca_certificates()
Alex Gaynor85b49702015-09-05 16:30:59 -04002739 dumped_p12 = p12.export(passphrase=passwd, iter=3)
2740 self.check_recovery(
Alex Gaynor03737182020-07-23 20:40:46 -04002741 dumped_p12, key=server_key_pem, cert=server_cert_pem, passwd=passwd
2742 )
Rick Dean25bcc1f2009-07-20 11:53:13 -05002743
Rick Deanf94096c2009-07-18 14:23:06 -05002744 def test_export_without_args(self):
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04002745 """
Alex Chanb00ede22017-01-30 07:24:40 +00002746 All the arguments to `PKCS12.export` are optional.
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04002747 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002748 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Rick Deanf94096c2009-07-18 14:23:06 -05002749 dumped_p12 = p12.export() # no args
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002750 self.check_recovery(
Alex Gaynor03737182020-07-23 20:40:46 -04002751 dumped_p12, key=server_key_pem, cert=server_cert_pem, passwd=b""
2752 )
Rick Deanf94096c2009-07-18 14:23:06 -05002753
Abraham Martinc5484ba2015-03-25 15:33:05 +00002754 def test_export_without_bytes(self):
2755 """
Alex Chanb00ede22017-01-30 07:24:40 +00002756 Test `PKCS12.export` with text not bytes as passphrase
Abraham Martinc5484ba2015-03-25 15:33:05 +00002757 """
2758 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2759
Alex Chanb00ede22017-01-30 07:24:40 +00002760 with pytest.warns(DeprecationWarning) as w:
Abraham Martinc5484ba2015-03-25 15:33:05 +00002761 simplefilter("always")
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002762 dumped_p12 = p12.export(passphrase=b"randomtext".decode("ascii"))
Alex Gaynor03737182020-07-23 20:40:46 -04002763 msg = "{0} for passphrase is no longer accepted, use bytes".format(
2764 WARNING_TYPE_EXPECTED
2765 )
2766 assert msg == str(w[-1].message)
Abraham Martinc5484ba2015-03-25 15:33:05 +00002767 self.check_recovery(
Alex Gaynor791212d2015-09-05 15:46:08 -04002768 dumped_p12,
2769 key=server_key_pem,
2770 cert=server_cert_pem,
Alex Gaynor03737182020-07-23 20:40:46 -04002771 passwd=b"randomtext",
Alex Gaynor791212d2015-09-05 15:46:08 -04002772 )
Abraham Martinc5484ba2015-03-25 15:33:05 +00002773
Rick Deanf94096c2009-07-18 14:23:06 -05002774 def test_key_cert_mismatch(self):
2775 """
Alex Chanb00ede22017-01-30 07:24:40 +00002776 `PKCS12.export` raises an exception when a key and certificate
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002777 mismatch.
Rick Deanf94096c2009-07-18 14:23:06 -05002778 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002779 p12 = self.gen_pkcs12(server_cert_pem, client_key_pem, root_cert_pem)
Alex Chanb00ede22017-01-30 07:24:40 +00002780 with pytest.raises(Error):
2781 p12.export()
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002782
2783
Rick Dean4c9ad612009-07-17 15:05:22 -05002784def _runopenssl(pem, *args):
2785 """
2786 Run the command line openssl tool with the given arguments and write
Rick Dean55d1ce62009-08-13 17:40:24 -05002787 the given PEM to its stdin. Not safe for quotes.
Rick Dean4c9ad612009-07-17 15:05:22 -05002788 """
Alex Gaynor6cbc69a2017-07-25 09:07:04 -04002789 proc = Popen([b"openssl"] + list(args), stdin=PIPE, stdout=PIPE)
Jean-Paul Calderone62ca8da2010-08-11 19:58:08 -04002790 proc.stdin.write(pem)
2791 proc.stdin.close()
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002792 output = proc.stdout.read()
2793 proc.stdout.close()
2794 proc.wait()
2795 return output
Rick Dean4c9ad612009-07-17 15:05:22 -05002796
2797
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002798class TestLoadPublicKey(object):
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002799 """
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002800 Tests for :func:`load_publickey`.
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002801 """
Alex Gaynor03737182020-07-23 20:40:46 -04002802
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002803 def test_loading_works(self):
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002804 """
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002805 load_publickey loads public keys and sets correct attributes.
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002806 """
2807 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002808
2809 assert True is key._only_public
2810 assert 2048 == key.bits()
2811 assert TYPE_RSA == key.type()
2812
2813 def test_invalid_type(self):
2814 """
2815 load_publickey doesn't support FILETYPE_TEXT.
2816 """
2817 with pytest.raises(ValueError):
2818 load_publickey(FILETYPE_TEXT, cleartextPublicKeyPEM)
2819
2820 def test_invalid_key_format(self):
2821 """
2822 load_publickey explodes on incorrect keys.
2823 """
2824 with pytest.raises(Error):
2825 load_publickey(FILETYPE_ASN1, cleartextPublicKeyPEM)
2826
2827 def test_tolerates_unicode_strings(self):
2828 """
2829 load_publickey works with text strings, not just bytes.
2830 """
Alex Gaynor03737182020-07-23 20:40:46 -04002831 serialized = cleartextPublicKeyPEM.decode("ascii")
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002832 key = load_publickey(FILETYPE_PEM, serialized)
2833 dumped_pem = dump_publickey(FILETYPE_PEM, key)
2834
2835 assert dumped_pem == cleartextPublicKeyPEM
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002836
2837
Alex Chanb00ede22017-01-30 07:24:40 +00002838class TestFunction(object):
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002839 """
Alex Chanb00ede22017-01-30 07:24:40 +00002840 Tests for free-functions in the `OpenSSL.crypto` module.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002841 """
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002842
2843 def test_load_privatekey_invalid_format(self):
2844 """
Alex Chanb00ede22017-01-30 07:24:40 +00002845 `load_privatekey` raises `ValueError` if passed an unknown filetype.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002846 """
Alex Chanb00ede22017-01-30 07:24:40 +00002847 with pytest.raises(ValueError):
2848 load_privatekey(100, root_key_pem)
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002849
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002850 def test_load_privatekey_invalid_passphrase_type(self):
2851 """
Alex Chanb00ede22017-01-30 07:24:40 +00002852 `load_privatekey` raises `TypeError` if passed a passphrase that is
2853 neither a `str` nor a callable.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002854 """
Alex Chanb00ede22017-01-30 07:24:40 +00002855 with pytest.raises(TypeError):
2856 load_privatekey(
Alex Gaynor03737182020-07-23 20:40:46 -04002857 FILETYPE_PEM, encryptedPrivateKeyPEMPassphrase, object()
2858 )
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002859
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002860 def test_load_privatekey_wrongPassphrase(self):
2861 """
Alex Chanb00ede22017-01-30 07:24:40 +00002862 `load_privatekey` raises `OpenSSL.crypto.Error` when it is passed an
2863 encrypted PEM and an incorrect passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002864 """
Alex Chanb00ede22017-01-30 07:24:40 +00002865 with pytest.raises(Error) as err:
2866 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, b"quack")
2867 assert err.value.args[0] != []
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002868
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002869 def test_load_privatekey_passphraseWrongType(self):
2870 """
Alex Chanb00ede22017-01-30 07:24:40 +00002871 `load_privatekey` raises `ValueError` when it is passeda passphrase
2872 with a private key encoded in a format, that doesn't support
2873 encryption.
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002874 """
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05002875 key = load_privatekey(FILETYPE_PEM, root_key_pem)
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002876 blob = dump_privatekey(FILETYPE_ASN1, key)
Alex Chanb00ede22017-01-30 07:24:40 +00002877 with pytest.raises(ValueError):
2878 load_privatekey(FILETYPE_ASN1, blob, "secret")
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002879
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002880 def test_load_privatekey_passphrase(self):
2881 """
Alex Chanb00ede22017-01-30 07:24:40 +00002882 `load_privatekey` can create a `PKey` object from an encrypted PEM
2883 string if given the passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002884 """
2885 key = load_privatekey(
Alex Gaynor03737182020-07-23 20:40:46 -04002886 FILETYPE_PEM,
2887 encryptedPrivateKeyPEM,
2888 encryptedPrivateKeyPEMPassphrase,
2889 )
Alex Gaynor01f90a12019-02-07 09:14:48 -05002890 assert isinstance(key, PKey)
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002891
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002892 def test_load_privatekey_passphrase_exception(self):
2893 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002894 If the passphrase callback raises an exception, that exception is
Alex Chanb00ede22017-01-30 07:24:40 +00002895 raised by `load_privatekey`.
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002896 """
Alex Gaynor03737182020-07-23 20:40:46 -04002897
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002898 def cb(ignored):
2899 raise ArithmeticError
2900
Alex Gaynor791212d2015-09-05 15:46:08 -04002901 with pytest.raises(ArithmeticError):
2902 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002903
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002904 def test_load_privatekey_wrongPassphraseCallback(self):
2905 """
Alex Chanb00ede22017-01-30 07:24:40 +00002906 `load_privatekey` raises `OpenSSL.crypto.Error` when it
Jean-Paul Calderoned440a082011-09-14 11:02:05 -04002907 is passed an encrypted PEM and a passphrase callback which returns an
2908 incorrect passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002909 """
2910 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002911
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002912 def cb(*a):
2913 called.append(None)
Alex Gaynore7f51982016-09-11 11:48:14 -04002914 return b"quack"
Alex Gaynor03737182020-07-23 20:40:46 -04002915
Alex Chanb00ede22017-01-30 07:24:40 +00002916 with pytest.raises(Error) as err:
2917 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
2918 assert called
2919 assert err.value.args[0] != []
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002920
2921 def test_load_privatekey_passphraseCallback(self):
2922 """
Alex Chanb00ede22017-01-30 07:24:40 +00002923 `load_privatekey` can create a `PKey` object from an encrypted PEM
2924 string if given a passphrase callback which returns the correct
2925 password.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002926 """
2927 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002928
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002929 def cb(writing):
2930 called.append(writing)
2931 return encryptedPrivateKeyPEMPassphrase
Alex Gaynor03737182020-07-23 20:40:46 -04002932
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002933 key = load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
Alex Gaynor01f90a12019-02-07 09:14:48 -05002934 assert isinstance(key, PKey)
Alex Chanb00ede22017-01-30 07:24:40 +00002935 assert called == [False]
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002936
Jean-Paul Calderone105cb952011-09-14 10:16:46 -04002937 def test_load_privatekey_passphrase_wrong_return_type(self):
2938 """
Alex Chanb00ede22017-01-30 07:24:40 +00002939 `load_privatekey` raises `ValueError` if the passphrase callback
2940 returns something other than a byte string.
Jean-Paul Calderone105cb952011-09-14 10:16:46 -04002941 """
Alex Chanb00ede22017-01-30 07:24:40 +00002942 with pytest.raises(ValueError):
2943 load_privatekey(
Alex Gaynor03737182020-07-23 20:40:46 -04002944 FILETYPE_PEM, encryptedPrivateKeyPEM, lambda *args: 3
2945 )
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002946
Alex Chanfb078d82017-04-20 11:16:15 +01002947 def test_dump_privatekey_wrong_args(self):
2948 """
2949 `dump_privatekey` raises `TypeError` if called with a `cipher`
2950 argument but no `passphrase` argument.
2951 """
2952 key = PKey()
2953 key.generate_key(TYPE_RSA, 512)
2954 with pytest.raises(TypeError):
2955 dump_privatekey(FILETYPE_PEM, key, cipher=GOOD_CIPHER)
2956
Paul Kehrercded9932017-06-29 18:43:42 -05002957 def test_dump_privatekey_not_rsa_key(self):
2958 """
2959 `dump_privatekey` raises `TypeError` if called with a key that is
2960 not RSA.
2961 """
2962 key = PKey()
2963 key.generate_key(TYPE_DSA, 512)
2964 with pytest.raises(TypeError):
2965 dump_privatekey(FILETYPE_TEXT, key)
2966
2967 def test_dump_privatekey_invalid_pkey(self):
2968 with pytest.raises(TypeError):
2969 dump_privatekey(FILETYPE_TEXT, object())
2970
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002971 def test_dump_privatekey_unknown_cipher(self):
2972 """
Alex Chanb00ede22017-01-30 07:24:40 +00002973 `dump_privatekey` raises `ValueError` if called with an unrecognized
2974 cipher name.
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(FILETYPE_PEM, key, BAD_CIPHER, "passphrase")
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002980
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002981 def test_dump_privatekey_invalid_passphrase_type(self):
2982 """
Alex Chanb00ede22017-01-30 07:24:40 +00002983 `dump_privatekey` raises `TypeError` if called with a passphrase which
2984 is neither a `str` nor a callable.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002985 """
2986 key = PKey()
2987 key.generate_key(TYPE_RSA, 512)
Alex Chanb00ede22017-01-30 07:24:40 +00002988 with pytest.raises(TypeError):
2989 dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, object())
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002990
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002991 def test_dump_privatekey_invalid_filetype(self):
2992 """
Alex Chanb00ede22017-01-30 07:24:40 +00002993 `dump_privatekey` raises `ValueError` if called with an unrecognized
2994 filetype.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002995 """
2996 key = PKey()
2997 key.generate_key(TYPE_RSA, 512)
Alex Chanb00ede22017-01-30 07:24:40 +00002998 with pytest.raises(ValueError):
2999 dump_privatekey(100, key)
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04003000
Alex Chanb00ede22017-01-30 07:24:40 +00003001 def test_load_privatekey_passphrase_callback_length(self):
Ziga Seilnacht781295a2009-12-22 14:58:01 +01003002 """
Alex Chanb00ede22017-01-30 07:24:40 +00003003 `crypto.load_privatekey` should raise an error when the passphrase
3004 provided by the callback is too long, not silently truncate it.
Ziga Seilnacht781295a2009-12-22 14:58:01 +01003005 """
Alex Gaynor03737182020-07-23 20:40:46 -04003006
Ziga Seilnacht781295a2009-12-22 14:58:01 +01003007 def cb(ignored):
3008 return "a" * 1025
3009
Alex Gaynor791212d2015-09-05 15:46:08 -04003010 with pytest.raises(ValueError):
3011 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
Ziga Seilnacht781295a2009-12-22 14:58:01 +01003012
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04003013 def test_dump_privatekey_passphrase(self):
3014 """
Alex Chanb00ede22017-01-30 07:24:40 +00003015 `dump_privatekey` writes an encrypted PEM when given a passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04003016 """
Alex Gaynore7f51982016-09-11 11:48:14 -04003017 passphrase = b"foo"
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003018 key = load_privatekey(FILETYPE_PEM, root_key_pem)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003019 pem = dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, passphrase)
Alex Gaynor12576002019-11-18 00:18:50 -05003020 assert isinstance(pem, bytes)
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04003021 loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
Alex Gaynor01f90a12019-02-07 09:14:48 -05003022 assert isinstance(loadedKey, PKey)
Alex Chanb00ede22017-01-30 07:24:40 +00003023 assert loadedKey.type() == key.type()
3024 assert loadedKey.bits() == key.bits()
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04003025
Alex Chanb00ede22017-01-30 07:24:40 +00003026 def test_dump_privatekey_passphrase_wrong_type(self):
Ziga Seilnacht376cf972009-12-22 16:04:10 +01003027 """
Alex Chanb00ede22017-01-30 07:24:40 +00003028 `dump_privatekey` raises `ValueError` when it is passed a passphrase
3029 with a private key encoded in a format, that doesn't support
3030 encryption.
Ziga Seilnacht376cf972009-12-22 16:04:10 +01003031 """
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003032 key = load_privatekey(FILETYPE_PEM, root_key_pem)
Alex Gaynor791212d2015-09-05 15:46:08 -04003033 with pytest.raises(ValueError):
3034 dump_privatekey(FILETYPE_ASN1, key, GOOD_CIPHER, "secret")
Ziga Seilnacht376cf972009-12-22 16:04:10 +01003035
Rick Dean5b7b6372009-04-01 11:34:06 -05003036 def test_dump_certificate(self):
3037 """
Alex Chanb00ede22017-01-30 07:24:40 +00003038 `dump_certificate` writes PEM, DER, and text.
Rick Dean5b7b6372009-04-01 11:34:06 -05003039 """
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003040 pemData = root_cert_pem + root_key_pem
Rick Dean5b7b6372009-04-01 11:34:06 -05003041 cert = load_certificate(FILETYPE_PEM, pemData)
3042 dumped_pem = dump_certificate(FILETYPE_PEM, cert)
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003043 assert dumped_pem == root_cert_pem
Rick Dean5b7b6372009-04-01 11:34:06 -05003044 dumped_der = dump_certificate(FILETYPE_ASN1, cert)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003045 good_der = _runopenssl(dumped_pem, b"x509", b"-outform", b"DER")
Alex Chanb00ede22017-01-30 07:24:40 +00003046 assert dumped_der == good_der
Rick Dean5b7b6372009-04-01 11:34:06 -05003047 cert2 = load_certificate(FILETYPE_ASN1, dumped_der)
3048 dumped_pem2 = dump_certificate(FILETYPE_PEM, cert2)
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003049 assert dumped_pem2 == root_cert_pem
Rick Dean5b7b6372009-04-01 11:34:06 -05003050 dumped_text = dump_certificate(FILETYPE_TEXT, cert)
Paul Kehrerc45a6ea2020-08-03 15:54:20 -05003051 assert len(dumped_text) > 500
Rick Dean5b7b6372009-04-01 11:34:06 -05003052
Alex Gaynor37726112016-07-04 09:51:32 -04003053 def test_dump_certificate_bad_type(self):
3054 """
Alex Chanb00ede22017-01-30 07:24:40 +00003055 `dump_certificate` raises a `ValueError` if it's called with
Alex Gaynor37726112016-07-04 09:51:32 -04003056 a bad type.
3057 """
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003058 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Alex Gaynor37726112016-07-04 09:51:32 -04003059 with pytest.raises(ValueError):
3060 dump_certificate(object(), cert)
3061
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08003062 def test_dump_privatekey_pem(self):
Rick Dean5b7b6372009-04-01 11:34:06 -05003063 """
Alex Chanb00ede22017-01-30 07:24:40 +00003064 `dump_privatekey` writes a PEM
Rick Dean5b7b6372009-04-01 11:34:06 -05003065 """
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003066 key = load_privatekey(FILETYPE_PEM, root_key_pem)
Alex Chanb00ede22017-01-30 07:24:40 +00003067 assert key.check()
Rick Dean5b7b6372009-04-01 11:34:06 -05003068 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003069 assert dumped_pem == normalized_root_key_pem
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08003070
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08003071 def test_dump_privatekey_asn1(self):
3072 """
Alex Chanb00ede22017-01-30 07:24:40 +00003073 `dump_privatekey` writes a DER
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08003074 """
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003075 key = load_privatekey(FILETYPE_PEM, root_key_pem)
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08003076
Rick Dean5b7b6372009-04-01 11:34:06 -05003077 dumped_der = dump_privatekey(FILETYPE_ASN1, key)
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003078 assert dumped_der == root_key_der
3079
3080 def test_load_privatekey_asn1(self):
3081 """
3082 `dump_privatekey` writes a DER
3083 """
3084 key = load_privatekey(FILETYPE_ASN1, root_key_der)
3085 assert key.bits() == 3072
3086 assert key.type() == TYPE_RSA
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08003087
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08003088 def test_dump_privatekey_text(self):
3089 """
Alex Chanb00ede22017-01-30 07:24:40 +00003090 `dump_privatekey` writes a text
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08003091 """
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003092 key = load_privatekey(FILETYPE_PEM, root_key_pem)
Rick Dean5b7b6372009-04-01 11:34:06 -05003093 dumped_text = dump_privatekey(FILETYPE_TEXT, key)
Paul Kehrerc45a6ea2020-08-03 15:54:20 -05003094 assert len(dumped_text) > 500
Rick Dean5b7b6372009-04-01 11:34:06 -05003095
Cory Benfield6492f7c2015-10-27 16:57:58 +09003096 def test_dump_publickey_pem(self):
3097 """
Cory Benfield11c10192015-10-27 17:23:03 +09003098 dump_publickey writes a PEM.
Cory Benfield6492f7c2015-10-27 16:57:58 +09003099 """
3100 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
3101 dumped_pem = dump_publickey(FILETYPE_PEM, key)
Cory Benfieldd86f1d82015-10-27 17:25:17 +09003102 assert dumped_pem == cleartextPublicKeyPEM
Cory Benfield6492f7c2015-10-27 16:57:58 +09003103
3104 def test_dump_publickey_asn1(self):
3105 """
Cory Benfield11c10192015-10-27 17:23:03 +09003106 dump_publickey writes a DER.
Cory Benfield6492f7c2015-10-27 16:57:58 +09003107 """
3108 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
3109 dumped_der = dump_publickey(FILETYPE_ASN1, key)
3110 key2 = load_publickey(FILETYPE_ASN1, dumped_der)
3111 dumped_pem2 = dump_publickey(FILETYPE_PEM, key2)
Cory Benfieldd86f1d82015-10-27 17:25:17 +09003112 assert dumped_pem2 == cleartextPublicKeyPEM
Cory Benfield6492f7c2015-10-27 16:57:58 +09003113
Cory Benfielde02c7d82015-10-27 17:34:49 +09003114 def test_dump_publickey_invalid_type(self):
3115 """
3116 dump_publickey doesn't support FILETYPE_TEXT.
3117 """
3118 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
3119
3120 with pytest.raises(ValueError):
3121 dump_publickey(FILETYPE_TEXT, key)
3122
Rick Dean5b7b6372009-04-01 11:34:06 -05003123 def test_dump_certificate_request(self):
3124 """
Alex Chanb00ede22017-01-30 07:24:40 +00003125 `dump_certificate_request` writes a PEM, DER, and text.
Rick Dean5b7b6372009-04-01 11:34:06 -05003126 """
Alex Gaynor31287502015-09-05 16:11:27 -04003127 req = load_certificate_request(
Alex Gaynor03737182020-07-23 20:40:46 -04003128 FILETYPE_PEM, cleartextCertificateRequestPEM
3129 )
Rick Dean5b7b6372009-04-01 11:34:06 -05003130 dumped_pem = dump_certificate_request(FILETYPE_PEM, req)
Alex Chanb00ede22017-01-30 07:24:40 +00003131 assert dumped_pem == cleartextCertificateRequestPEM
Rick Dean5b7b6372009-04-01 11:34:06 -05003132 dumped_der = dump_certificate_request(FILETYPE_ASN1, req)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003133 good_der = _runopenssl(dumped_pem, b"req", b"-outform", b"DER")
Alex Chanb00ede22017-01-30 07:24:40 +00003134 assert dumped_der == good_der
Rick Dean5b7b6372009-04-01 11:34:06 -05003135 req2 = load_certificate_request(FILETYPE_ASN1, dumped_der)
3136 dumped_pem2 = dump_certificate_request(FILETYPE_PEM, req2)
Alex Chanb00ede22017-01-30 07:24:40 +00003137 assert dumped_pem2 == cleartextCertificateRequestPEM
Rick Dean5b7b6372009-04-01 11:34:06 -05003138 dumped_text = dump_certificate_request(FILETYPE_TEXT, req)
Paul Kehrerc45a6ea2020-08-03 15:54:20 -05003139 assert len(dumped_text) > 500
Alex Chanb00ede22017-01-30 07:24:40 +00003140 with pytest.raises(ValueError):
3141 dump_certificate_request(100, req)
Rick Dean5b7b6372009-04-01 11:34:06 -05003142
Alex Chanb00ede22017-01-30 07:24:40 +00003143 def test_dump_privatekey_passphrase_callback(self):
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04003144 """
Alex Chanb00ede22017-01-30 07:24:40 +00003145 `dump_privatekey` writes an encrypted PEM when given a callback
Alex Gaynor791212d2015-09-05 15:46:08 -04003146 which returns the correct passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04003147 """
Alex Gaynore7f51982016-09-11 11:48:14 -04003148 passphrase = b"foo"
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04003149 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003150
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04003151 def cb(writing):
3152 called.append(writing)
3153 return passphrase
Alex Gaynor03737182020-07-23 20:40:46 -04003154
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003155 key = load_privatekey(FILETYPE_PEM, root_key_pem)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003156 pem = dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
Alex Gaynor12576002019-11-18 00:18:50 -05003157 assert isinstance(pem, bytes)
Alex Chanb00ede22017-01-30 07:24:40 +00003158 assert called == [True]
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04003159 loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
Alex Gaynor01f90a12019-02-07 09:14:48 -05003160 assert isinstance(loadedKey, PKey)
Alex Chanb00ede22017-01-30 07:24:40 +00003161 assert loadedKey.type() == key.type()
3162 assert loadedKey.bits() == key.bits()
Rick Dean5b7b6372009-04-01 11:34:06 -05003163
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01003164 def test_dump_privatekey_passphrase_exception(self):
3165 """
Alex Chanb00ede22017-01-30 07:24:40 +00003166 `dump_privatekey` should not overwrite the exception raised
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01003167 by the passphrase callback.
3168 """
Alex Gaynor03737182020-07-23 20:40:46 -04003169
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01003170 def cb(ignored):
3171 raise ArithmeticError
3172
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003173 key = load_privatekey(FILETYPE_PEM, root_key_pem)
Alex Gaynor85b49702015-09-05 16:30:59 -04003174 with pytest.raises(ArithmeticError):
3175 dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01003176
Ziga Seilnacht781295a2009-12-22 14:58:01 +01003177 def test_dump_privatekey_passphraseCallbackLength(self):
3178 """
Alex Chanb00ede22017-01-30 07:24:40 +00003179 `crypto.dump_privatekey` should raise an error when the passphrase
3180 provided by the callback is too long, not silently truncate it.
Ziga Seilnacht781295a2009-12-22 14:58:01 +01003181 """
Alex Gaynor03737182020-07-23 20:40:46 -04003182
Ziga Seilnacht781295a2009-12-22 14:58:01 +01003183 def cb(ignored):
3184 return "a" * 1025
3185
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003186 key = load_privatekey(FILETYPE_PEM, root_key_pem)
Alex Gaynor85b49702015-09-05 16:30:59 -04003187 with pytest.raises(ValueError):
3188 dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
Ziga Seilnacht781295a2009-12-22 14:58:01 +01003189
Huw Jonescdd66962020-10-13 05:14:19 +01003190 def test_dump_privatekey_truncated(self):
3191 """
3192 `crypto.dump_privatekey` should not truncate a passphrase that contains
3193 a null byte.
3194 """
3195 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
3196 passphrase = b"foo\x00bar"
3197 truncated_passphrase = passphrase.split(b"\x00", 1)[0]
3198
3199 # By dumping with the full passphrase load should raise an error if we
3200 # try to load using the truncated passphrase. If dump truncated the
3201 # passphrase, then we WILL load the privatekey and the test fails
3202 encrypted_key_pem = dump_privatekey(
3203 FILETYPE_PEM, key, "AES-256-CBC", passphrase
3204 )
3205 with pytest.raises(Error):
3206 load_privatekey(
3207 FILETYPE_PEM, encrypted_key_pem, truncated_passphrase
3208 )
3209
3210 def test_load_privatekey_truncated(self):
3211 """
3212 `crypto.load_privatekey` should not truncate a passphrase that contains
3213 a null byte.
3214 """
3215 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
3216 passphrase = b"foo\x00bar"
3217 truncated_passphrase = passphrase.split(b"\x00", 1)[0]
3218
3219 # By dumping using the truncated passphrase load should raise an error
3220 # if we try to load using the full passphrase. If load truncated the
3221 # passphrase, then we WILL load the privatekey and the test fails
3222 encrypted_key_pem = dump_privatekey(
3223 FILETYPE_PEM, key, "AES-256-CBC", truncated_passphrase
3224 )
3225 with pytest.raises(Error):
3226 load_privatekey(FILETYPE_PEM, encrypted_key_pem, passphrase)
3227
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07003228 def test_load_pkcs7_data_pem(self):
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003229 """
Alex Chanb00ede22017-01-30 07:24:40 +00003230 `load_pkcs7_data` accepts a PKCS#7 string and returns an instance of
3231 `PKCS`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003232 """
3233 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
Alex Chanb00ede22017-01-30 07:24:40 +00003234 assert isinstance(pkcs7, PKCS7)
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003235
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07003236 def test_load_pkcs7_data_asn1(self):
Alex Gaynor9875a912014-08-14 13:35:05 -07003237 """
Alex Chanb00ede22017-01-30 07:24:40 +00003238 `load_pkcs7_data` accepts a bytes containing ASN1 data representing
3239 PKCS#7 and returns an instance of `PKCS7`.
Alex Gaynor9875a912014-08-14 13:35:05 -07003240 """
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07003241 pkcs7 = load_pkcs7_data(FILETYPE_ASN1, pkcs7DataASN1)
Alex Chanb00ede22017-01-30 07:24:40 +00003242 assert isinstance(pkcs7, PKCS7)
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07003243
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08003244 def test_load_pkcs7_data_invalid(self):
3245 """
Alex Chanb00ede22017-01-30 07:24:40 +00003246 If the data passed to `load_pkcs7_data` is invalid, `Error` is raised.
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08003247 """
Alex Chanb00ede22017-01-30 07:24:40 +00003248 with pytest.raises(Error):
3249 load_pkcs7_data(FILETYPE_PEM, b"foo")
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08003250
Alex Gaynor09a386e2016-07-03 09:32:44 -04003251 def test_load_pkcs7_type_invalid(self):
3252 """
Alex Chanb00ede22017-01-30 07:24:40 +00003253 If the type passed to `load_pkcs7_data`, `ValueError` is raised.
Alex Gaynor09a386e2016-07-03 09:32:44 -04003254 """
3255 with pytest.raises(ValueError):
3256 load_pkcs7_data(object(), b"foo")
3257
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08003258
Alex Chan9e2a9932017-01-25 14:29:19 +00003259class TestLoadCertificate(object):
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05003260 """
Alex Chan9e2a9932017-01-25 14:29:19 +00003261 Tests for `load_certificate_request`.
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05003262 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003263
Alex Chan9e2a9932017-01-25 14:29:19 +00003264 def test_bad_file_type(self):
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05003265 """
Alex Chan9e2a9932017-01-25 14:29:19 +00003266 If the file type passed to `load_certificate_request` is neither
3267 `FILETYPE_PEM` nor `FILETYPE_ASN1` then `ValueError` is raised.
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05003268 """
Alex Gaynor7778e792016-07-03 23:38:48 -04003269 with pytest.raises(ValueError):
3270 load_certificate_request(object(), b"")
3271 with pytest.raises(ValueError):
3272 load_certificate(object(), b"")
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05003273
Alex Gaynor37726112016-07-04 09:51:32 -04003274 def test_bad_certificate(self):
3275 """
Alex Chan9e2a9932017-01-25 14:29:19 +00003276 If the bytes passed to `load_certificate` are not a valid certificate,
3277 an exception is raised.
Alex Gaynor37726112016-07-04 09:51:32 -04003278 """
3279 with pytest.raises(Error):
3280 load_certificate(FILETYPE_ASN1, b"lol")
3281
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05003282
Alex Chanb00ede22017-01-30 07:24:40 +00003283class TestPKCS7(object):
Jean-Paul Calderone68649052009-07-17 21:14:27 -04003284 """
Alex Chanb00ede22017-01-30 07:24:40 +00003285 Tests for `PKCS7`.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04003286 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003287
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003288 def test_type_is_signed(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003289 """
Alex Chanb00ede22017-01-30 07:24:40 +00003290 `PKCS7.type_is_signed` returns `True` if the PKCS7 object is of
3291 the type *signed*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003292 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003293 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
Alex Chanb00ede22017-01-30 07:24:40 +00003294 assert pkcs7.type_is_signed()
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003295
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003296 def test_type_is_enveloped(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003297 """
Alex Chanb00ede22017-01-30 07:24:40 +00003298 `PKCS7.type_is_enveloped` returns `False` if the PKCS7 object is not
3299 of the type *enveloped*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003300 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003301 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
Alex Chanb00ede22017-01-30 07:24:40 +00003302 assert not pkcs7.type_is_enveloped()
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003303
Alex Chanb00ede22017-01-30 07:24:40 +00003304 def test_type_is_signed_and_enveloped(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003305 """
Alex Chanb00ede22017-01-30 07:24:40 +00003306 `PKCS7.type_is_signedAndEnveloped` returns `False`
Alex Gaynor791212d2015-09-05 15:46:08 -04003307 if the PKCS7 object is not of the type *signed and enveloped*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003308 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003309 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
Alex Chanb00ede22017-01-30 07:24:40 +00003310 assert not pkcs7.type_is_signedAndEnveloped()
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003311
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04003312 def test_type_is_data(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003313 """
Alex Chanb00ede22017-01-30 07:24:40 +00003314 `PKCS7.type_is_data` returns `False` if the PKCS7 object is not of
3315 the type data.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003316 """
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04003317 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
Alex Chanb00ede22017-01-30 07:24:40 +00003318 assert not pkcs7.type_is_data()
Jean-Paul Calderone97b28ca2010-07-30 10:56:07 -04003319
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04003320 def test_get_type_name(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003321 """
Alex Chanb00ede22017-01-30 07:24:40 +00003322 `PKCS7.get_type_name` returns a `str` giving the
Alex Gaynor791212d2015-09-05 15:46:08 -04003323 type name.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003324 """
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04003325 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
Alex Gaynor03737182020-07-23 20:40:46 -04003326 assert pkcs7.get_type_name() == b"pkcs7-signedData"
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04003327
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04003328 def test_attribute(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003329 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003330 If an attribute other than one of the methods tested here is accessed
Alex Chanb00ede22017-01-30 07:24:40 +00003331 on an instance of `PKCS7`, `AttributeError` is raised.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003332 """
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04003333 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
Alex Chanb00ede22017-01-30 07:24:40 +00003334 with pytest.raises(AttributeError):
3335 pkcs7.foo
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04003336
3337
Alex Chanb00ede22017-01-30 07:24:40 +00003338class TestNetscapeSPKI(_PKeyInteractionTestsMixin):
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003339 """
Alex Chanb00ede22017-01-30 07:24:40 +00003340 Tests for `OpenSSL.crypto.NetscapeSPKI`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003341 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003342
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04003343 def signable(self):
3344 """
Alex Chanb00ede22017-01-30 07:24:40 +00003345 Return a new `NetscapeSPKI` for use with signing tests.
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04003346 """
3347 return NetscapeSPKI()
3348
Jean-Paul Calderone68649052009-07-17 21:14:27 -04003349 def test_type(self):
3350 """
Alex Gaynor01f90a12019-02-07 09:14:48 -05003351 `NetscapeSPKI` can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04003352 """
Alex Gaynor03737182020-07-23 20:40:46 -04003353 assert is_consistent_type(NetscapeSPKI, "NetscapeSPKI")
Jean-Paul Calderone68649052009-07-17 21:14:27 -04003354
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003355 def test_construction(self):
3356 """
Alex Gaynor01f90a12019-02-07 09:14:48 -05003357 `NetscapeSPKI` returns an instance of `NetscapeSPKI`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003358 """
3359 nspki = NetscapeSPKI()
Alex Gaynor01f90a12019-02-07 09:14:48 -05003360 assert isinstance(nspki, NetscapeSPKI)
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003361
Jean-Paul Calderone969efaa2010-08-03 18:19:19 -04003362 def test_invalid_attribute(self):
3363 """
Alex Chanb00ede22017-01-30 07:24:40 +00003364 Accessing a non-existent attribute of a `NetscapeSPKI` instance
3365 causes an `AttributeError` to be raised.
Jean-Paul Calderone969efaa2010-08-03 18:19:19 -04003366 """
3367 nspki = NetscapeSPKI()
Alex Chanb00ede22017-01-30 07:24:40 +00003368 with pytest.raises(AttributeError):
3369 nspki.foo
Jean-Paul Calderone969efaa2010-08-03 18:19:19 -04003370
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04003371 def test_b64_encode(self):
3372 """
Alex Chanb00ede22017-01-30 07:24:40 +00003373 `NetscapeSPKI.b64_encode` encodes the certificate to a base64 blob.
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04003374 """
3375 nspki = NetscapeSPKI()
3376 blob = nspki.b64_encode()
Alex Gaynor12576002019-11-18 00:18:50 -05003377 assert isinstance(blob, bytes)
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04003378
3379
Paul Kehrer2c605ba2016-03-11 11:17:26 -04003380class TestRevoked(object):
3381 """
Alex Chandeec9342016-12-19 22:00:38 +00003382 Tests for `OpenSSL.crypto.Revoked`.
Paul Kehrer2c605ba2016-03-11 11:17:26 -04003383 """
Alex Gaynor03737182020-07-23 20:40:46 -04003384
Paul Kehrer2c605ba2016-03-11 11:17:26 -04003385 def test_ignores_unsupported_revoked_cert_extension_get_reason(self):
3386 """
3387 The get_reason method on the Revoked class checks to see if the
3388 extension is NID_crl_reason and should skip it otherwise. This test
3389 loads a CRL with extensions it should ignore.
3390 """
3391 crl = load_crl(FILETYPE_PEM, crlDataUnsupportedExtension)
3392 revoked = crl.get_revoked()
3393 reason = revoked[1].get_reason()
Alex Gaynor03737182020-07-23 20:40:46 -04003394 assert reason == b"Unspecified"
Paul Kehrer2c605ba2016-03-11 11:17:26 -04003395
3396 def test_ignores_unsupported_revoked_cert_extension_set_new_reason(self):
3397 crl = load_crl(FILETYPE_PEM, crlDataUnsupportedExtension)
3398 revoked = crl.get_revoked()
3399 revoked[1].set_reason(None)
3400 reason = revoked[1].get_reason()
3401 assert reason is None
3402
Rick Dean536ba022009-07-24 23:57:27 -05003403 def test_construction(self):
3404 """
Alex Chandeec9342016-12-19 22:00:38 +00003405 Confirm we can create `OpenSSL.crypto.Revoked`. Check that it is
3406 empty.
Rick Dean536ba022009-07-24 23:57:27 -05003407 """
3408 revoked = Revoked()
Alex Chandeec9342016-12-19 22:00:38 +00003409 assert isinstance(revoked, Revoked)
3410 assert type(revoked) == Revoked
Alex Gaynor03737182020-07-23 20:40:46 -04003411 assert revoked.get_serial() == b"00"
Alex Chandeec9342016-12-19 22:00:38 +00003412 assert revoked.get_rev_date() is None
3413 assert revoked.get_reason() is None
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003414
Rick Dean536ba022009-07-24 23:57:27 -05003415 def test_serial(self):
3416 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003417 Confirm we can set and get serial numbers from
Alex Chandeec9342016-12-19 22:00:38 +00003418 `OpenSSL.crypto.Revoked`. Confirm errors are handled with grace.
Rick Dean536ba022009-07-24 23:57:27 -05003419 """
3420 revoked = Revoked()
Alex Gaynor03737182020-07-23 20:40:46 -04003421 ret = revoked.set_serial(b"10b")
Alex Chandeec9342016-12-19 22:00:38 +00003422 assert ret is None
Rick Dean536ba022009-07-24 23:57:27 -05003423 ser = revoked.get_serial()
Alex Gaynor03737182020-07-23 20:40:46 -04003424 assert ser == b"010B"
Rick Dean536ba022009-07-24 23:57:27 -05003425
Alex Gaynor03737182020-07-23 20:40:46 -04003426 revoked.set_serial(b"31ppp") # a type error would be nice
Rick Dean536ba022009-07-24 23:57:27 -05003427 ser = revoked.get_serial()
Alex Gaynor03737182020-07-23 20:40:46 -04003428 assert ser == b"31"
Rick Dean536ba022009-07-24 23:57:27 -05003429
Alex Chandeec9342016-12-19 22:00:38 +00003430 with pytest.raises(ValueError):
Alex Gaynor03737182020-07-23 20:40:46 -04003431 revoked.set_serial(b"pqrst")
Alex Chandeec9342016-12-19 22:00:38 +00003432 with pytest.raises(TypeError):
3433 revoked.set_serial(100)
Rick Dean536ba022009-07-24 23:57:27 -05003434
Rick Dean536ba022009-07-24 23:57:27 -05003435 def test_date(self):
3436 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003437 Confirm we can set and get revocation dates from
Alex Chandeec9342016-12-19 22:00:38 +00003438 `OpenSSL.crypto.Revoked`. Confirm errors are handled with grace.
Rick Dean536ba022009-07-24 23:57:27 -05003439 """
3440 revoked = Revoked()
3441 date = revoked.get_rev_date()
Alex Chandeec9342016-12-19 22:00:38 +00003442 assert date is None
Rick Dean536ba022009-07-24 23:57:27 -05003443
Alex Gaynore7f51982016-09-11 11:48:14 -04003444 now = datetime.now().strftime("%Y%m%d%H%M%SZ").encode("ascii")
Rick Dean536ba022009-07-24 23:57:27 -05003445 ret = revoked.set_rev_date(now)
Alex Chandeec9342016-12-19 22:00:38 +00003446 assert ret is None
Rick Dean536ba022009-07-24 23:57:27 -05003447 date = revoked.get_rev_date()
Alex Chandeec9342016-12-19 22:00:38 +00003448 assert date == now
Rick Dean536ba022009-07-24 23:57:27 -05003449
Rick Dean6385faf2009-07-26 00:07:47 -05003450 def test_reason(self):
3451 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003452 Confirm we can set and get revocation reasons from
Alex Chandeec9342016-12-19 22:00:38 +00003453 `OpenSSL.crypto.Revoked`. The "get" need to work as "set".
3454 Likewise, each reason of all_reasons() must work.
Rick Dean6385faf2009-07-26 00:07:47 -05003455 """
3456 revoked = Revoked()
3457 for r in revoked.all_reasons():
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003458 for x in range(2):
Rick Dean6385faf2009-07-26 00:07:47 -05003459 ret = revoked.set_reason(r)
Alex Chandeec9342016-12-19 22:00:38 +00003460 assert ret is None
Rick Dean6385faf2009-07-26 00:07:47 -05003461 reason = revoked.get_reason()
Alex Gaynor03737182020-07-23 20:40:46 -04003462 assert reason.lower().replace(b" ", b"") == r.lower().replace(
3463 b" ", b""
3464 )
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003465 r = reason # again with the resp of get
Rick Dean6385faf2009-07-26 00:07:47 -05003466
3467 revoked.set_reason(None)
Alex Chandeec9342016-12-19 22:00:38 +00003468 assert revoked.get_reason() is None
Rick Dean6385faf2009-07-26 00:07:47 -05003469
Alex Gaynor03737182020-07-23 20:40:46 -04003470 @pytest.mark.parametrize("reason", [object(), 1.0, u"foo"])
Alex Chanfb078d82017-04-20 11:16:15 +01003471 def test_set_reason_wrong_args(self, reason):
3472 """
3473 `Revoked.set_reason` raises `TypeError` if called with an argument
3474 which is neither `None` nor a byte string.
3475 """
3476 revoked = Revoked()
3477 with pytest.raises(TypeError):
3478 revoked.set_reason(reason)
3479
Alex Chandeec9342016-12-19 22:00:38 +00003480 def test_set_reason_invalid_reason(self):
Rick Dean6385faf2009-07-26 00:07:47 -05003481 """
Alex Chandeec9342016-12-19 22:00:38 +00003482 Calling `OpenSSL.crypto.Revoked.set_reason` with an argument which
3483 isn't a valid reason results in `ValueError` being raised.
Rick Dean6385faf2009-07-26 00:07:47 -05003484 """
3485 revoked = Revoked()
Alex Chandeec9342016-12-19 22:00:38 +00003486 with pytest.raises(ValueError):
Alex Gaynor03737182020-07-23 20:40:46 -04003487 revoked.set_reason(b"blue")
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003488
3489
Alex Chan7be83a52017-01-24 15:19:29 +00003490class TestCRL(object):
Rick Dean536ba022009-07-24 23:57:27 -05003491 """
Alex Chan7be83a52017-01-24 15:19:29 +00003492 Tests for `OpenSSL.crypto.CRL`.
Rick Dean536ba022009-07-24 23:57:27 -05003493 """
Alex Gaynor03737182020-07-23 20:40:46 -04003494
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003495 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3496 pkey = load_privatekey(FILETYPE_PEM, root_key_pem)
Rick Dean536ba022009-07-24 23:57:27 -05003497
Dan Sully44e767a2016-06-04 18:05:27 -07003498 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3499 root_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3500 intermediate_cert = load_certificate(FILETYPE_PEM, intermediate_cert_pem)
3501 intermediate_key = load_privatekey(FILETYPE_PEM, intermediate_key_pem)
3502 intermediate_server_cert = load_certificate(
Alex Gaynor03737182020-07-23 20:40:46 -04003503 FILETYPE_PEM, intermediate_server_cert_pem
3504 )
Dan Sully44e767a2016-06-04 18:05:27 -07003505 intermediate_server_key = load_privatekey(
Alex Gaynor03737182020-07-23 20:40:46 -04003506 FILETYPE_PEM, intermediate_server_key_pem
3507 )
Dan Sully44e767a2016-06-04 18:05:27 -07003508
Rick Dean536ba022009-07-24 23:57:27 -05003509 def test_construction(self):
3510 """
Alex Chan7be83a52017-01-24 15:19:29 +00003511 Confirm we can create `OpenSSL.crypto.CRL`. Check
Rick Dean536ba022009-07-24 23:57:27 -05003512 that it is empty
3513 """
3514 crl = CRL()
Alex Chan7be83a52017-01-24 15:19:29 +00003515 assert isinstance(crl, CRL)
3516 assert crl.get_revoked() is None
Jean-Paul Calderone2efd03e2010-01-30 13:59:55 -05003517
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003518 def _get_crl(self):
Rick Dean536ba022009-07-24 23:57:27 -05003519 """
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003520 Get a new ``CRL`` with a revocation.
Rick Dean536ba022009-07-24 23:57:27 -05003521 """
3522 crl = CRL()
3523 revoked = Revoked()
Alex Gaynore7f51982016-09-11 11:48:14 -04003524 now = datetime.now().strftime("%Y%m%d%H%M%SZ").encode("ascii")
Rick Dean536ba022009-07-24 23:57:27 -05003525 revoked.set_rev_date(now)
Alex Gaynor03737182020-07-23 20:40:46 -04003526 revoked.set_serial(b"3ab")
3527 revoked.set_reason(b"sUpErSeDEd")
Rick Dean536ba022009-07-24 23:57:27 -05003528 crl.add_revoked(revoked)
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003529 return crl
Rick Dean536ba022009-07-24 23:57:27 -05003530
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003531 def test_export_pem(self):
3532 """
3533 If not passed a format, ``CRL.export`` returns a "PEM" format string
3534 representing a serial number, a revoked reason, and certificate issuer
3535 information.
3536 """
Rick Dean536ba022009-07-24 23:57:27 -05003537 # PEM format
Paul Kehrer7d5a3bf2019-01-21 12:24:02 -06003538 dumped_crl = self._get_crl().export(
Alex Gaynor173e4ba2017-06-30 08:01:12 -07003539 self.cert, self.pkey, days=20, digest=b"sha256"
3540 )
Paul Kehrer7d5a3bf2019-01-21 12:24:02 -06003541 crl = x509.load_pem_x509_crl(dumped_crl, backend)
3542 revoked = crl.get_revoked_certificate_by_serial_number(0x03AB)
3543 assert revoked is not None
Alex Gaynor03737182020-07-23 20:40:46 -04003544 assert crl.issuer == x509.Name(
3545 [
3546 x509.NameAttribute(x509.NameOID.COUNTRY_NAME, u"US"),
3547 x509.NameAttribute(x509.NameOID.STATE_OR_PROVINCE_NAME, u"IL"),
3548 x509.NameAttribute(x509.NameOID.LOCALITY_NAME, u"Chicago"),
3549 x509.NameAttribute(x509.NameOID.ORGANIZATION_NAME, u"Testing"),
3550 x509.NameAttribute(
3551 x509.NameOID.COMMON_NAME, u"Testing Root CA"
3552 ),
3553 ]
3554 )
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003555
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003556 def test_export_der(self):
3557 """
3558 If passed ``FILETYPE_ASN1`` for the format, ``CRL.export`` returns a
3559 "DER" format string representing a serial number, a revoked reason, and
3560 certificate issuer information.
3561 """
3562 crl = self._get_crl()
Rick Dean536ba022009-07-24 23:57:27 -05003563
3564 # DER format
Paul Kehrer7d5a3bf2019-01-21 12:24:02 -06003565 dumped_crl = self._get_crl().export(
Alex Gaynor173e4ba2017-06-30 08:01:12 -07003566 self.cert, self.pkey, FILETYPE_ASN1, digest=b"md5"
3567 )
Paul Kehrer7d5a3bf2019-01-21 12:24:02 -06003568 crl = x509.load_der_x509_crl(dumped_crl, backend)
3569 revoked = crl.get_revoked_certificate_by_serial_number(0x03AB)
3570 assert revoked is not None
Alex Gaynor03737182020-07-23 20:40:46 -04003571 assert crl.issuer == x509.Name(
3572 [
3573 x509.NameAttribute(x509.NameOID.COUNTRY_NAME, u"US"),
3574 x509.NameAttribute(x509.NameOID.STATE_OR_PROVINCE_NAME, u"IL"),
3575 x509.NameAttribute(x509.NameOID.LOCALITY_NAME, u"Chicago"),
3576 x509.NameAttribute(x509.NameOID.ORGANIZATION_NAME, u"Testing"),
3577 x509.NameAttribute(
3578 x509.NameOID.COMMON_NAME, u"Testing Root CA"
3579 ),
3580 ]
3581 )
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003582
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003583 def test_export_text(self):
3584 """
3585 If passed ``FILETYPE_TEXT`` for the format, ``CRL.export`` returns a
3586 text format string like the one produced by the openssl command line
3587 tool.
3588 """
3589 crl = self._get_crl()
3590
Rick Dean536ba022009-07-24 23:57:27 -05003591 # text format
Alex Gaynor173e4ba2017-06-30 08:01:12 -07003592 dumped_text = crl.export(
3593 self.cert, self.pkey, type=FILETYPE_TEXT, digest=b"md5"
3594 )
Paul Kehrerc45a6ea2020-08-03 15:54:20 -05003595 assert len(dumped_text) > 500
Rick Dean536ba022009-07-24 23:57:27 -05003596
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003597 def test_export_custom_digest(self):
3598 """
3599 If passed the name of a digest function, ``CRL.export`` uses a
3600 signature algorithm based on that digest function.
3601 """
3602 crl = self._get_crl()
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003603 dumped_crl = crl.export(self.cert, self.pkey, digest=b"sha1")
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003604 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
Alex Gaynor03737182020-07-23 20:40:46 -04003605 text.index(b"Signature Algorithm: sha1")
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003606
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003607 def test_export_md5_digest(self):
3608 """
3609 If passed md5 as the digest function, ``CRL.export`` uses md5 and does
3610 not emit a deprecation warning.
3611 """
3612 crl = self._get_crl()
Alex Chan7be83a52017-01-24 15:19:29 +00003613 with pytest.warns(None) as catcher:
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003614 simplefilter("always")
Alex Chan7be83a52017-01-24 15:19:29 +00003615 assert 0 == len(catcher)
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003616 dumped_crl = crl.export(self.cert, self.pkey, digest=b"md5")
3617 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
Alex Gaynor03737182020-07-23 20:40:46 -04003618 text.index(b"Signature Algorithm: md5")
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003619
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003620 def test_export_default_digest(self):
3621 """
Alex Gaynor173e4ba2017-06-30 08:01:12 -07003622 If not passed the name of a digest function, ``CRL.export`` raises a
3623 ``TypeError``.
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003624 """
3625 crl = self._get_crl()
Alex Gaynor173e4ba2017-06-30 08:01:12 -07003626 with pytest.raises(TypeError):
3627 crl.export(self.cert, self.pkey)
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003628
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003629 def test_export_invalid(self):
3630 """
Alex Chan7be83a52017-01-24 15:19:29 +00003631 If `CRL.export` is used with an uninitialized `X509` instance,
3632 `OpenSSL.crypto.Error` is raised.
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003633 """
3634 crl = CRL()
Alex Chan7be83a52017-01-24 15:19:29 +00003635 with pytest.raises(Error):
Alex Gaynor173e4ba2017-06-30 08:01:12 -07003636 crl.export(X509(), PKey(), digest=b"sha256")
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003637
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003638 def test_add_revoked_keyword(self):
3639 """
Alex Chan7be83a52017-01-24 15:19:29 +00003640 `OpenSSL.CRL.add_revoked` accepts its single argument as the
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04003641 ``revoked`` keyword argument.
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003642 """
3643 crl = CRL()
3644 revoked = Revoked()
Paul Kehrerb11bffc2016-03-10 18:30:29 -04003645 revoked.set_serial(b"01")
Paul Kehrer2fe23b02016-03-09 22:02:15 -04003646 revoked.set_rev_date(b"20160310020145Z")
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003647 crl.add_revoked(revoked=revoked)
Alex Chan7be83a52017-01-24 15:19:29 +00003648 assert isinstance(crl.get_revoked()[0], Revoked)
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003649
Jean-Paul Calderone883ca4b2010-01-30 13:55:13 -05003650 def test_export_wrong_args(self):
3651 """
Alex Chan7be83a52017-01-24 15:19:29 +00003652 Calling `OpenSSL.CRL.export` with arguments other than the certificate,
Jean-Paul Calderonef1515862010-01-30 13:57:03 -05003653 private key, integer file type, and integer number of days it
Alex Chan7be83a52017-01-24 15:19:29 +00003654 expects, results in a `TypeError` being raised.
Jean-Paul Calderone883ca4b2010-01-30 13:55:13 -05003655 """
3656 crl = CRL()
Alex Gaynor85b49702015-09-05 16:30:59 -04003657 with pytest.raises(TypeError):
3658 crl.export(None, self.pkey, FILETYPE_PEM, 10)
3659 with pytest.raises(TypeError):
3660 crl.export(self.cert, None, FILETYPE_PEM, 10)
3661 with pytest.raises(TypeError):
3662 crl.export(self.cert, self.pkey, None, 10)
Alex Chan7be83a52017-01-24 15:19:29 +00003663 with pytest.raises(TypeError):
3664 crl.export(self.cert, FILETYPE_PEM, None)
Jean-Paul Calderonef1515862010-01-30 13:57:03 -05003665
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003666 def test_export_unknown_filetype(self):
3667 """
Alex Chan7be83a52017-01-24 15:19:29 +00003668 Calling `OpenSSL.CRL.export` with a file type other than
3669 `FILETYPE_PEM`, `FILETYPE_ASN1`, or
3670 `FILETYPE_TEXT` results in a `ValueError` being raised.
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003671 """
3672 crl = CRL()
Alex Gaynor85b49702015-09-05 16:30:59 -04003673 with pytest.raises(ValueError):
Alex Gaynor173e4ba2017-06-30 08:01:12 -07003674 crl.export(self.cert, self.pkey, 100, 10, digest=b"sha256")
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003675
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003676 def test_export_unknown_digest(self):
Bulat Gaifullin5f9eea42014-09-23 19:35:15 +04003677 """
Alex Chan7be83a52017-01-24 15:19:29 +00003678 Calling `OpenSSL.CRL.export` with an unsupported digest results
3679 in a `ValueError` being raised.
Bulat Gaifullin5f9eea42014-09-23 19:35:15 +04003680 """
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003681 crl = CRL()
Alex Chan7be83a52017-01-24 15:19:29 +00003682 with pytest.raises(ValueError):
3683 crl.export(
Alex Gaynor03737182020-07-23 20:40:46 -04003684 self.cert, self.pkey, FILETYPE_PEM, 10, b"strange-digest"
3685 )
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003686
Rick Dean536ba022009-07-24 23:57:27 -05003687 def test_get_revoked(self):
3688 """
Alex Chan7be83a52017-01-24 15:19:29 +00003689 Use python to create a simple CRL with two revocations. Get back the
3690 `Revoked` using `OpenSSL.CRL.get_revoked` and verify them.
Rick Dean536ba022009-07-24 23:57:27 -05003691 """
3692 crl = CRL()
3693
3694 revoked = Revoked()
Alex Gaynore7f51982016-09-11 11:48:14 -04003695 now = datetime.now().strftime("%Y%m%d%H%M%SZ").encode("ascii")
Rick Dean536ba022009-07-24 23:57:27 -05003696 revoked.set_rev_date(now)
Alex Gaynor03737182020-07-23 20:40:46 -04003697 revoked.set_serial(b"3ab")
Rick Dean536ba022009-07-24 23:57:27 -05003698 crl.add_revoked(revoked)
Alex Gaynor03737182020-07-23 20:40:46 -04003699 revoked.set_serial(b"100")
3700 revoked.set_reason(b"sUpErSeDEd")
Rick Dean536ba022009-07-24 23:57:27 -05003701 crl.add_revoked(revoked)
3702
3703 revs = crl.get_revoked()
Alex Chan7be83a52017-01-24 15:19:29 +00003704 assert len(revs) == 2
3705 assert type(revs[0]) == Revoked
3706 assert type(revs[1]) == Revoked
Alex Gaynor03737182020-07-23 20:40:46 -04003707 assert revs[0].get_serial() == b"03AB"
3708 assert revs[1].get_serial() == b"0100"
Alex Chan7be83a52017-01-24 15:19:29 +00003709 assert revs[0].get_rev_date() == now
3710 assert revs[1].get_rev_date() == now
Jean-Paul Calderoneecef6fa2010-01-30 13:47:18 -05003711
Rick Dean536ba022009-07-24 23:57:27 -05003712 def test_load_crl(self):
3713 """
Alex Chan7be83a52017-01-24 15:19:29 +00003714 Load a known CRL and inspect its revocations. Both EM and DER formats
3715 are loaded.
Rick Dean536ba022009-07-24 23:57:27 -05003716 """
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003717 crl = load_crl(FILETYPE_PEM, crlData)
Rick Dean536ba022009-07-24 23:57:27 -05003718 revs = crl.get_revoked()
Alex Chan7be83a52017-01-24 15:19:29 +00003719 assert len(revs) == 2
Alex Gaynor03737182020-07-23 20:40:46 -04003720 assert revs[0].get_serial() == b"03AB"
Alex Chan7be83a52017-01-24 15:19:29 +00003721 assert revs[0].get_reason() is None
Alex Gaynor03737182020-07-23 20:40:46 -04003722 assert revs[1].get_serial() == b"0100"
3723 assert revs[1].get_reason() == b"Superseded"
Rick Dean536ba022009-07-24 23:57:27 -05003724
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003725 der = _runopenssl(crlData, b"crl", b"-outform", b"DER")
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003726 crl = load_crl(FILETYPE_ASN1, der)
Rick Dean536ba022009-07-24 23:57:27 -05003727 revs = crl.get_revoked()
Alex Chan7be83a52017-01-24 15:19:29 +00003728 assert len(revs) == 2
Alex Gaynor03737182020-07-23 20:40:46 -04003729 assert revs[0].get_serial() == b"03AB"
Alex Chan7be83a52017-01-24 15:19:29 +00003730 assert revs[0].get_reason() is None
Alex Gaynor03737182020-07-23 20:40:46 -04003731 assert revs[1].get_serial() == b"0100"
3732 assert revs[1].get_reason() == b"Superseded"
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003733
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003734 def test_load_crl_bad_filetype(self):
3735 """
Alex Chan7be83a52017-01-24 15:19:29 +00003736 Calling `OpenSSL.crypto.load_crl` with an unknown file type raises a
3737 `ValueError`.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003738 """
Alex Chan7be83a52017-01-24 15:19:29 +00003739 with pytest.raises(ValueError):
3740 load_crl(100, crlData)
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003741
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003742 def test_load_crl_bad_data(self):
3743 """
Alex Chan7be83a52017-01-24 15:19:29 +00003744 Calling `OpenSSL.crypto.load_crl` with file data which can't be loaded
3745 raises a `OpenSSL.crypto.Error`.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003746 """
Alex Chan7be83a52017-01-24 15:19:29 +00003747 with pytest.raises(Error):
3748 load_crl(FILETYPE_PEM, b"hello, world")
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003749
Dan Sully44e767a2016-06-04 18:05:27 -07003750 def test_get_issuer(self):
3751 """
Alex Chan7be83a52017-01-24 15:19:29 +00003752 Load a known CRL and assert its issuer's common name is what we expect
3753 from the encoded crlData string.
Dan Sully44e767a2016-06-04 18:05:27 -07003754 """
3755 crl = load_crl(FILETYPE_PEM, crlData)
Alex Chan7be83a52017-01-24 15:19:29 +00003756 assert isinstance(crl.get_issuer(), X509Name)
Alex Gaynor03737182020-07-23 20:40:46 -04003757 assert crl.get_issuer().CN == "Testing Root CA"
Dan Sully44e767a2016-06-04 18:05:27 -07003758
Dominic Chenf05b2122015-10-13 16:32:35 +00003759 def test_dump_crl(self):
3760 """
3761 The dumped CRL matches the original input.
3762 """
3763 crl = load_crl(FILETYPE_PEM, crlData)
3764 buf = dump_crl(FILETYPE_PEM, crl)
3765 assert buf == crlData
3766
Dan Sully44e767a2016-06-04 18:05:27 -07003767 def _make_test_crl(self, issuer_cert, issuer_key, certs=()):
3768 """
3769 Create a CRL.
3770
3771 :param list[X509] certs: A list of certificates to revoke.
3772 :rtype: CRL
3773 """
3774 crl = CRL()
3775 for cert in certs:
3776 revoked = Revoked()
3777 # FIXME: This string splicing is an unfortunate implementation
3778 # detail that has been reported in
3779 # https://github.com/pyca/pyopenssl/issues/258
Alex Gaynor03737182020-07-23 20:40:46 -04003780 serial = hex(cert.get_serial_number())[2:].encode("utf-8")
Dan Sully44e767a2016-06-04 18:05:27 -07003781 revoked.set_serial(serial)
Alex Gaynor03737182020-07-23 20:40:46 -04003782 revoked.set_reason(b"unspecified")
3783 revoked.set_rev_date(b"20140601000000Z")
Dan Sully44e767a2016-06-04 18:05:27 -07003784 crl.add_revoked(revoked)
3785 crl.set_version(1)
Alex Gaynor03737182020-07-23 20:40:46 -04003786 crl.set_lastUpdate(b"20140601000000Z")
3787 crl.set_nextUpdate(b"20180601000000Z")
3788 crl.sign(issuer_cert, issuer_key, digest=b"sha512")
Dan Sully44e767a2016-06-04 18:05:27 -07003789 return crl
3790
3791 def test_verify_with_revoked(self):
3792 """
Alex Chan7be83a52017-01-24 15:19:29 +00003793 `verify_certificate` raises error when an intermediate certificate is
3794 revoked.
Dan Sully44e767a2016-06-04 18:05:27 -07003795 """
3796 store = X509Store()
3797 store.add_cert(self.root_cert)
3798 store.add_cert(self.intermediate_cert)
3799 root_crl = self._make_test_crl(
Alex Gaynor03737182020-07-23 20:40:46 -04003800 self.root_cert, self.root_key, certs=[self.intermediate_cert]
3801 )
Dan Sully44e767a2016-06-04 18:05:27 -07003802 intermediate_crl = self._make_test_crl(
Alex Gaynor03737182020-07-23 20:40:46 -04003803 self.intermediate_cert, self.intermediate_key, certs=[]
3804 )
Dan Sully44e767a2016-06-04 18:05:27 -07003805 store.add_crl(root_crl)
3806 store.add_crl(intermediate_crl)
3807 store.set_flags(
Alex Gaynor03737182020-07-23 20:40:46 -04003808 X509StoreFlags.CRL_CHECK | X509StoreFlags.CRL_CHECK_ALL
3809 )
Dan Sully44e767a2016-06-04 18:05:27 -07003810 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Alex Chan7be83a52017-01-24 15:19:29 +00003811 with pytest.raises(X509StoreContextError) as err:
3812 store_ctx.verify_certificate()
Alex Gaynor03737182020-07-23 20:40:46 -04003813 assert err.value.args[0][2] == "certificate revoked"
Dan Sully44e767a2016-06-04 18:05:27 -07003814
3815 def test_verify_with_missing_crl(self):
3816 """
Alex Chan7be83a52017-01-24 15:19:29 +00003817 `verify_certificate` raises error when an intermediate certificate's
3818 CRL is missing.
Dan Sully44e767a2016-06-04 18:05:27 -07003819 """
3820 store = X509Store()
3821 store.add_cert(self.root_cert)
3822 store.add_cert(self.intermediate_cert)
3823 root_crl = self._make_test_crl(
Alex Gaynor03737182020-07-23 20:40:46 -04003824 self.root_cert, self.root_key, certs=[self.intermediate_cert]
3825 )
Dan Sully44e767a2016-06-04 18:05:27 -07003826 store.add_crl(root_crl)
3827 store.set_flags(
Alex Gaynor03737182020-07-23 20:40:46 -04003828 X509StoreFlags.CRL_CHECK | X509StoreFlags.CRL_CHECK_ALL
3829 )
Dan Sully44e767a2016-06-04 18:05:27 -07003830 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Alex Chan7be83a52017-01-24 15:19:29 +00003831 with pytest.raises(X509StoreContextError) as err:
3832 store_ctx.verify_certificate()
Alex Gaynor03737182020-07-23 20:40:46 -04003833 assert err.value.args[0][2] == "unable to get certificate CRL"
3834 assert err.value.certificate.get_subject().CN == "intermediate-service"
Dan Sully44e767a2016-06-04 18:05:27 -07003835
Paul Kehrer41c10242017-06-29 18:24:17 -05003836 def test_convert_from_cryptography(self):
3837 crypto_crl = x509.load_pem_x509_crl(crlData, backend)
3838 crl = CRL.from_cryptography(crypto_crl)
3839 assert isinstance(crl, CRL)
3840
3841 def test_convert_from_cryptography_unsupported_type(self):
3842 with pytest.raises(TypeError):
3843 CRL.from_cryptography(object())
3844
3845 def test_convert_to_cryptography_key(self):
3846 crl = load_crl(FILETYPE_PEM, crlData)
3847 crypto_crl = crl.to_cryptography()
3848 assert isinstance(crypto_crl, x509.CertificateRevocationList)
3849
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003850
Alex Chan7be83a52017-01-24 15:19:29 +00003851class TestX509StoreContext(object):
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003852 """
Alex Chan7be83a52017-01-24 15:19:29 +00003853 Tests for `OpenSSL.crypto.X509StoreContext`.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003854 """
Alex Gaynor03737182020-07-23 20:40:46 -04003855
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003856 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3857 intermediate_cert = load_certificate(FILETYPE_PEM, intermediate_cert_pem)
Alex Gaynor31287502015-09-05 16:11:27 -04003858 intermediate_server_cert = load_certificate(
Alex Gaynor03737182020-07-23 20:40:46 -04003859 FILETYPE_PEM, intermediate_server_cert_pem
3860 )
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003861
3862 def test_valid(self):
3863 """
Alex Chan7be83a52017-01-24 15:19:29 +00003864 `verify_certificate` returns ``None`` when called with a certificate
3865 and valid chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003866 """
3867 store = X509Store()
3868 store.add_cert(self.root_cert)
3869 store.add_cert(self.intermediate_cert)
3870 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Alex Chan7be83a52017-01-24 15:19:29 +00003871 assert store_ctx.verify_certificate() is None
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003872
3873 def test_reuse(self):
3874 """
Alex Chan7be83a52017-01-24 15:19:29 +00003875 `verify_certificate` can be called multiple times with the same
Jean-Paul Calderone06e01b92015-01-18 15:43:13 -05003876 ``X509StoreContext`` instance to produce the same result.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003877 """
3878 store = X509Store()
3879 store.add_cert(self.root_cert)
3880 store.add_cert(self.intermediate_cert)
3881 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Alex Chan7be83a52017-01-24 15:19:29 +00003882 assert store_ctx.verify_certificate() is None
3883 assert store_ctx.verify_certificate() is None
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003884
Sándor Oroszi83ef2302020-10-12 15:42:23 +02003885 @pytest.mark.parametrize(
3886 "root_cert, chain, verified_cert",
3887 [
3888 pytest.param(
3889 root_cert,
3890 [intermediate_cert],
3891 intermediate_server_cert,
3892 id="intermediate in chain",
3893 ),
3894 pytest.param(
3895 root_cert,
3896 [],
3897 intermediate_cert,
3898 id="empty chain",
3899 ),
3900 pytest.param(
3901 root_cert,
3902 [root_cert, intermediate_server_cert, intermediate_cert],
3903 intermediate_server_cert,
3904 id="extra certs in chain",
3905 ),
3906 ],
3907 )
3908 def test_verify_success_with_chain(self, root_cert, chain, verified_cert):
3909 store = X509Store()
3910 store.add_cert(root_cert)
3911 store_ctx = X509StoreContext(store, verified_cert, chain=chain)
3912 assert store_ctx.verify_certificate() is None
3913
3914 def test_valid_untrusted_chain_reuse(self):
3915 """
3916 `verify_certificate` using an untrusted chain can be called multiple
3917 times with the same ``X509StoreContext`` instance to produce the same
3918 result.
3919 """
3920 store = X509Store()
3921 store.add_cert(self.root_cert)
3922 chain = [self.intermediate_cert]
3923
3924 store_ctx = X509StoreContext(
3925 store, self.intermediate_server_cert, chain=chain
3926 )
3927 assert store_ctx.verify_certificate() is None
3928 assert store_ctx.verify_certificate() is None
3929
3930 def test_chain_reference(self):
3931 """
3932 ``X509StoreContext`` properly keeps references to the untrusted chain
3933 certificates.
3934 """
3935 store = X509Store()
3936 store.add_cert(self.root_cert)
3937 chain = [load_certificate(FILETYPE_PEM, intermediate_cert_pem)]
3938
3939 store_ctx = X509StoreContext(
3940 store, self.intermediate_server_cert, chain=chain
3941 )
3942
3943 del chain
3944 assert store_ctx.verify_certificate() is None
3945
3946 @pytest.mark.parametrize(
3947 "root_cert, chain, verified_cert",
3948 [
3949 pytest.param(
3950 root_cert,
3951 [],
3952 intermediate_server_cert,
3953 id="intermediate missing",
3954 ),
3955 pytest.param(
3956 None,
3957 [intermediate_cert],
3958 intermediate_server_cert,
3959 id="no trusted root",
3960 ),
3961 pytest.param(
3962 None,
3963 [root_cert, intermediate_cert],
3964 intermediate_server_cert,
3965 id="untrusted root, full chain is available",
3966 ),
3967 pytest.param(
3968 intermediate_cert,
3969 [root_cert, intermediate_cert],
3970 intermediate_server_cert,
3971 id="untrusted root, intermediate is trusted and in chain",
3972 ),
3973 ],
3974 )
3975 def test_verify_fail_with_chain(self, root_cert, chain, verified_cert):
3976 store = X509Store()
3977 if root_cert:
3978 store.add_cert(root_cert)
3979
3980 store_ctx = X509StoreContext(store, verified_cert, chain=chain)
3981
3982 with pytest.raises(X509StoreContextError):
3983 store_ctx.verify_certificate()
3984
3985 @pytest.mark.parametrize(
3986 "chain, expected_error",
3987 [
3988 pytest.param(
3989 [intermediate_cert, "This is not a certificate"],
3990 TypeError,
3991 id="non-certificate in chain",
3992 ),
3993 pytest.param(
3994 42,
3995 TypeError,
3996 id="non-list chain",
3997 ),
3998 ],
3999 )
4000 def test_untrusted_chain_wrong_args(self, chain, expected_error):
4001 """
4002 Creating ``X509StoreContext`` with wrong chain raises an exception.
4003 """
4004 store = X509Store()
4005 store.add_cert(self.root_cert)
4006
4007 with pytest.raises(expected_error):
4008 X509StoreContext(store, self.intermediate_server_cert, chain=chain)
4009
4010 def test_failure_building_untrusted_chain_raises(self, monkeypatch):
4011 """
4012 Creating ``X509StoreContext`` raises ``OpenSSL.crypto.Error`` when
4013 the underlying lib fails to add the certificate to the stack.
4014 """
4015 monkeypatch.setattr(_lib, "sk_X509_push", lambda _stack, _x509: -1)
4016
4017 store = X509Store()
4018 store.add_cert(self.root_cert)
4019 chain = [self.intermediate_cert]
4020
4021 with pytest.raises(Error):
4022 X509StoreContext(store, self.intermediate_server_cert, chain=chain)
4023
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07004024 def test_trusted_self_signed(self):
4025 """
Alex Chan7be83a52017-01-24 15:19:29 +00004026 `verify_certificate` returns ``None`` when called with a self-signed
4027 certificate and itself in the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07004028 """
4029 store = X509Store()
4030 store.add_cert(self.root_cert)
4031 store_ctx = X509StoreContext(store, self.root_cert)
Alex Chan7be83a52017-01-24 15:19:29 +00004032 assert store_ctx.verify_certificate() is None
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07004033
4034 def test_untrusted_self_signed(self):
4035 """
Alex Chan7be83a52017-01-24 15:19:29 +00004036 `verify_certificate` raises error when a self-signed certificate is
4037 verified without itself in the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07004038 """
4039 store = X509Store()
4040 store_ctx = X509StoreContext(store, self.root_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04004041 with pytest.raises(X509StoreContextError) as exc:
4042 store_ctx.verify_certificate()
4043
Alex Gaynor03737182020-07-23 20:40:46 -04004044 assert exc.value.args[0][2] == "self signed certificate"
4045 assert exc.value.certificate.get_subject().CN == "Testing Root CA"
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05004046
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07004047 def test_invalid_chain_no_root(self):
4048 """
Alex Chan7be83a52017-01-24 15:19:29 +00004049 `verify_certificate` raises error when a root certificate is missing
4050 from the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07004051 """
4052 store = X509Store()
4053 store.add_cert(self.intermediate_cert)
4054 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04004055
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] == "unable to get issuer certificate"
4060 assert exc.value.certificate.get_subject().CN == "intermediate"
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05004061
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07004062 def test_invalid_chain_no_intermediate(self):
4063 """
Alex Chan7be83a52017-01-24 15:19:29 +00004064 `verify_certificate` raises error when an intermediate certificate is
4065 missing from the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07004066 """
4067 store = X509Store()
4068 store.add_cert(self.root_cert)
4069 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05004070
Alex Gaynor85b49702015-09-05 16:30:59 -04004071 with pytest.raises(X509StoreContextError) as exc:
4072 store_ctx.verify_certificate()
4073
Alex Gaynor03737182020-07-23 20:40:46 -04004074 assert exc.value.args[0][2] == "unable to get local issuer certificate"
4075 assert exc.value.certificate.get_subject().CN == "intermediate-service"
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07004076
Stephen Holsapple46a09252015-02-12 14:45:43 -08004077 def test_modification_pre_verify(self):
4078 """
Alex Chan7be83a52017-01-24 15:19:29 +00004079 `verify_certificate` can use a store context modified after
Stephen Holsapple46a09252015-02-12 14:45:43 -08004080 instantiation.
4081 """
4082 store_bad = X509Store()
4083 store_bad.add_cert(self.intermediate_cert)
4084 store_good = X509Store()
4085 store_good.add_cert(self.root_cert)
4086 store_good.add_cert(self.intermediate_cert)
4087 store_ctx = X509StoreContext(store_bad, self.intermediate_server_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04004088
4089 with pytest.raises(X509StoreContextError) as exc:
4090 store_ctx.verify_certificate()
4091
Alex Gaynor03737182020-07-23 20:40:46 -04004092 assert exc.value.args[0][2] == "unable to get issuer certificate"
4093 assert exc.value.certificate.get_subject().CN == "intermediate"
Alex Gaynor85b49702015-09-05 16:30:59 -04004094
Stephen Holsapple46a09252015-02-12 14:45:43 -08004095 store_ctx.set_store(store_good)
Alex Chan7be83a52017-01-24 15:19:29 +00004096 assert store_ctx.verify_certificate() is None
Stephen Holsapple46a09252015-02-12 14:45:43 -08004097
Thomas Sileoe15e60a2016-11-22 18:13:30 +01004098 def test_verify_with_time(self):
4099 """
4100 `verify_certificate` raises error when the verification time is
4101 set at notAfter.
4102 """
4103 store = X509Store()
4104 store.add_cert(self.root_cert)
4105 store.add_cert(self.intermediate_cert)
4106
4107 expire_time = self.intermediate_server_cert.get_notAfter()
4108 expire_datetime = datetime.strptime(
Alex Gaynor03737182020-07-23 20:40:46 -04004109 expire_time.decode("utf-8"), "%Y%m%d%H%M%SZ"
Thomas Sileoe15e60a2016-11-22 18:13:30 +01004110 )
4111 store.set_time(expire_datetime)
4112
4113 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
4114 with pytest.raises(X509StoreContextError) as exc:
4115 store_ctx.verify_certificate()
4116
Alex Gaynor03737182020-07-23 20:40:46 -04004117 assert exc.value.args[0][2] == "certificate has expired"
Thomas Sileoe15e60a2016-11-22 18:13:30 +01004118
Shane Harvey33c54992020-08-05 16:48:51 -07004119 def test_get_verified_chain(self):
4120 """
4121 `get_verified_chain` returns the verified chain.
4122 """
4123 store = X509Store()
4124 store.add_cert(self.root_cert)
4125 store.add_cert(self.intermediate_cert)
4126 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
4127 chain = store_ctx.get_verified_chain()
4128 assert len(chain) == 3
4129 intermediate_subject = self.intermediate_server_cert.get_subject()
4130 assert chain[0].get_subject() == intermediate_subject
4131 assert chain[1].get_subject() == self.intermediate_cert.get_subject()
4132 assert chain[2].get_subject() == self.root_cert.get_subject()
4133 # Test reuse
4134 chain = store_ctx.get_verified_chain()
4135 assert len(chain) == 3
4136 assert chain[0].get_subject() == intermediate_subject
4137 assert chain[1].get_subject() == self.intermediate_cert.get_subject()
4138 assert chain[2].get_subject() == self.root_cert.get_subject()
4139
4140 def test_get_verified_chain_invalid_chain_no_root(self):
4141 """
4142 `get_verified_chain` raises error when cert verification fails.
4143 """
4144 store = X509Store()
4145 store.add_cert(self.intermediate_cert)
4146 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
4147
4148 with pytest.raises(X509StoreContextError) as exc:
4149 store_ctx.get_verified_chain()
4150
4151 assert exc.value.args[0][2] == "unable to get issuer certificate"
4152 assert exc.value.certificate.get_subject().CN == "intermediate"
4153
Sándor Oroszi43c97762020-09-11 17:17:31 +02004154 @pytest.fixture
4155 def root_ca_file(self, tmpdir):
4156 return self._create_ca_file(tmpdir, "root_ca_hash_dir", self.root_cert)
4157
4158 @pytest.fixture
4159 def intermediate_ca_file(self, tmpdir):
4160 return self._create_ca_file(
4161 tmpdir, "intermediate_ca_hash_dir", self.intermediate_cert
4162 )
4163
4164 @staticmethod
4165 def _create_ca_file(base_path, hash_directory, cacert):
4166 ca_hash = "{:08x}.0".format(cacert.subject_name_hash())
4167 cafile = base_path.join(hash_directory, ca_hash)
4168 cafile.write_binary(
4169 dump_certificate(FILETYPE_PEM, cacert), ensure=True
4170 )
4171 return cafile
4172
4173 def test_verify_with_ca_file_location(self, root_ca_file):
4174 store = X509Store()
4175 store.load_locations(str(root_ca_file))
4176
4177 store_ctx = X509StoreContext(store, self.intermediate_cert)
4178 store_ctx.verify_certificate()
4179
4180 def test_verify_with_ca_path_location(self, root_ca_file):
4181 store = X509Store()
4182 store.load_locations(None, str(root_ca_file.dirname))
4183
4184 store_ctx = X509StoreContext(store, self.intermediate_cert)
4185 store_ctx.verify_certificate()
4186
4187 def test_verify_with_cafile_and_capath(
4188 self, root_ca_file, intermediate_ca_file
4189 ):
4190 store = X509Store()
4191 store.load_locations(
4192 cafile=str(root_ca_file), capath=str(intermediate_ca_file.dirname)
4193 )
4194
4195 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
4196 store_ctx.verify_certificate()
4197
4198 def test_verify_with_multiple_ca_files(
4199 self, root_ca_file, intermediate_ca_file
4200 ):
4201 store = X509Store()
4202 store.load_locations(str(root_ca_file))
4203 store.load_locations(str(intermediate_ca_file))
4204
4205 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
4206 store_ctx.verify_certificate()
4207
4208 def test_verify_failure_with_empty_ca_directory(self, tmpdir):
4209 store = X509Store()
4210 store.load_locations(None, str(tmpdir))
4211
4212 store_ctx = X509StoreContext(store, self.intermediate_cert)
4213 with pytest.raises(X509StoreContextError) as exc:
4214 store_ctx.verify_certificate()
4215
4216 assert exc.value.args[0][2] == "unable to get local issuer certificate"
4217
Stephen Holsapple46a09252015-02-12 14:45:43 -08004218
Alex Chan7be83a52017-01-24 15:19:29 +00004219class TestSignVerify(object):
James Yonan7c2e5d32010-02-27 05:45:50 -07004220 """
Alex Chan7be83a52017-01-24 15:19:29 +00004221 Tests for `OpenSSL.crypto.sign` and `OpenSSL.crypto.verify`.
James Yonan7c2e5d32010-02-27 05:45:50 -07004222 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04004223
James Yonan7c2e5d32010-02-27 05:45:50 -07004224 def test_sign_verify(self):
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04004225 """
Alex Chan7be83a52017-01-24 15:19:29 +00004226 `sign` generates a cryptographic signature which `verify` can check.
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04004227 """
Alex Gaynore7f51982016-09-11 11:48:14 -04004228 content = (
4229 b"It was a bright cold day in April, and the clocks were striking "
4230 b"thirteen. Winston Smith, his chin nuzzled into his breast in an "
4231 b"effort to escape the vile wind, slipped quickly through the "
4232 b"glass doors of Victory Mansions, though not quickly enough to "
Alex Gaynor03737182020-07-23 20:40:46 -04004233 b"prevent a swirl of gritty dust from entering along with him."
4234 )
Jean-Paul Calderoneb98ce212010-06-22 09:46:27 -04004235
4236 # sign the content with this private key
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04004237 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
Jean-Paul Calderoneb98ce212010-06-22 09:46:27 -04004238 # verify the content with this cert
4239 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
4240 # certificate unrelated to priv_key, used to trigger an error
4241 bad_cert = load_certificate(FILETYPE_PEM, server_cert_pem)
James Yonan7c2e5d32010-02-27 05:45:50 -07004242
Alex Gaynor03737182020-07-23 20:40:46 -04004243 for digest in ["md5", "sha1"]:
James Yonan7c2e5d32010-02-27 05:45:50 -07004244 sig = sign(priv_key, content, digest)
4245
Alex Gaynoraceb3e22015-09-05 12:00:22 -04004246 # Verify the signature of content, will throw an exception if
4247 # error.
James Yonan7c2e5d32010-02-27 05:45:50 -07004248 verify(good_cert, sig, content, digest)
4249
4250 # This should fail because the certificate doesn't match the
4251 # private key that was used to sign the content.
Alex Chan7be83a52017-01-24 15:19:29 +00004252 with pytest.raises(Error):
4253 verify(bad_cert, sig, content, digest)
James Yonan7c2e5d32010-02-27 05:45:50 -07004254
4255 # This should fail because we've "tainted" the content after
4256 # signing it.
Alex Chan7be83a52017-01-24 15:19:29 +00004257 with pytest.raises(Error):
4258 verify(good_cert, sig, content + b"tainted", digest)
James Yonan7c2e5d32010-02-27 05:45:50 -07004259
4260 # test that unknown digest types fail
Alex Chan7be83a52017-01-24 15:19:29 +00004261 with pytest.raises(ValueError):
4262 sign(priv_key, content, "strange-digest")
4263 with pytest.raises(ValueError):
4264 verify(good_cert, sig, content, "strange-digest")
James Yonan7c2e5d32010-02-27 05:45:50 -07004265
Abraham Martinc5484ba2015-03-25 15:33:05 +00004266 def test_sign_verify_with_text(self):
4267 """
Alex Chan7be83a52017-01-24 15:19:29 +00004268 `sign` generates a cryptographic signature which
4269 `verify` can check. Deprecation warnings raised because using
Alex Gaynor791212d2015-09-05 15:46:08 -04004270 text instead of bytes as content
Abraham Martinc5484ba2015-03-25 15:33:05 +00004271 """
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04004272 content = (
Jean-Paul Calderone362c1f52015-03-29 08:01:39 -04004273 b"It was a bright cold day in April, and the clocks were striking "
4274 b"thirteen. Winston Smith, his chin nuzzled into his breast in an "
4275 b"effort to escape the vile wind, slipped quickly through the "
4276 b"glass doors of Victory Mansions, though not quickly enough to "
4277 b"prevent a swirl of gritty dust from entering along with him."
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04004278 ).decode("ascii")
Abraham Martinc5484ba2015-03-25 15:33:05 +00004279
4280 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
4281 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Alex Gaynor03737182020-07-23 20:40:46 -04004282 for digest in ["md5", "sha1"]:
Alex Chan7be83a52017-01-24 15:19:29 +00004283 with pytest.warns(DeprecationWarning) as w:
Abraham Martinc5484ba2015-03-25 15:33:05 +00004284 simplefilter("always")
4285 sig = sign(priv_key, content, digest)
Alex Gaynor03737182020-07-23 20:40:46 -04004286 assert "{0} for data is no longer accepted, use bytes".format(
4287 WARNING_TYPE_EXPECTED
4288 ) == str(w[-1].message)
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04004289
Alex Chan7be83a52017-01-24 15:19:29 +00004290 with pytest.warns(DeprecationWarning) as w:
Abraham Martinc5484ba2015-03-25 15:33:05 +00004291 simplefilter("always")
4292 verify(cert, sig, content, digest)
Alex Gaynor03737182020-07-23 20:40:46 -04004293 assert "{0} for data is no longer accepted, use bytes".format(
4294 WARNING_TYPE_EXPECTED
4295 ) == str(w[-1].message)
Abraham Martinc5484ba2015-03-25 15:33:05 +00004296
Paul Kehrer59d26252017-07-20 10:45:54 +02004297 def test_sign_verify_ecdsa(self):
4298 """
4299 `sign` generates a cryptographic signature which `verify` can check.
4300 ECDSA Signatures in the X9.62 format may have variable length,
4301 different from the length of the private key.
4302 """
4303 content = (
4304 b"It was a bright cold day in April, and the clocks were striking "
4305 b"thirteen. Winston Smith, his chin nuzzled into his breast in an "
4306 b"effort to escape the vile wind, slipped quickly through the "
4307 b"glass doors of Victory Mansions, though not quickly enough to "
4308 b"prevent a swirl of gritty dust from entering along with him."
Paul Kehrerc45a6ea2020-08-03 15:54:20 -05004309 )
Paul Kehrer59d26252017-07-20 10:45:54 +02004310 priv_key = load_privatekey(FILETYPE_PEM, ec_root_key_pem)
4311 cert = load_certificate(FILETYPE_PEM, ec_root_cert_pem)
4312 sig = sign(priv_key, content, "sha1")
4313 verify(cert, sig, content, "sha1")
4314
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05004315 def test_sign_nulls(self):
4316 """
Alex Chan7be83a52017-01-24 15:19:29 +00004317 `sign` produces a signature for a string with embedded nulls.
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05004318 """
Alex Gaynore7f51982016-09-11 11:48:14 -04004319 content = b"Watch out! \0 Did you see it?"
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05004320 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
4321 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
4322 sig = sign(priv_key, content, "sha1")
4323 verify(good_cert, sig, content, "sha1")
4324
Colleen Murphye09399b2016-03-01 17:40:49 -08004325 def test_sign_with_large_key(self):
4326 """
Alex Chan7be83a52017-01-24 15:19:29 +00004327 `sign` produces a signature for a string when using a long key.
Colleen Murphye09399b2016-03-01 17:40:49 -08004328 """
Alex Gaynore7f51982016-09-11 11:48:14 -04004329 content = (
4330 b"It was a bright cold day in April, and the clocks were striking "
4331 b"thirteen. Winston Smith, his chin nuzzled into his breast in an "
4332 b"effort to escape the vile wind, slipped quickly through the "
4333 b"glass doors of Victory Mansions, though not quickly enough to "
Alex Gaynor03737182020-07-23 20:40:46 -04004334 b"prevent a swirl of gritty dust from entering along with him."
4335 )
Colleen Murphye09399b2016-03-01 17:40:49 -08004336
4337 priv_key = load_privatekey(FILETYPE_PEM, large_key_pem)
4338 sign(priv_key, content, "sha1")
4339
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05004340
Alex Chan63ef9bc2016-12-19 12:02:06 +00004341class TestEllipticCurve(object):
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004342 """
Alex Chan63ef9bc2016-12-19 12:02:06 +00004343 Tests for `_EllipticCurve`, `get_elliptic_curve`, and
4344 `get_elliptic_curves`.
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004345 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04004346
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004347 def test_set(self):
4348 """
Alex Chan63ef9bc2016-12-19 12:02:06 +00004349 `get_elliptic_curves` returns a `set`.
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004350 """
Alex Chan63ef9bc2016-12-19 12:02:06 +00004351 assert isinstance(get_elliptic_curves(), set)
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004352
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004353 def test_a_curve(self):
4354 """
Alex Chan63ef9bc2016-12-19 12:02:06 +00004355 `get_elliptic_curve` can be used to retrieve a particular supported
4356 curve.
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004357 """
4358 curves = get_elliptic_curves()
Alex Chan63ef9bc2016-12-19 12:02:06 +00004359 curve = next(iter(curves))
4360 assert curve.name == get_elliptic_curve(curve.name).name
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004361
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004362 def test_not_a_curve(self):
4363 """
Alex Chan63ef9bc2016-12-19 12:02:06 +00004364 `get_elliptic_curve` raises `ValueError` if called with a name which
4365 does not identify a supported curve.
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004366 """
Alex Chan63ef9bc2016-12-19 12:02:06 +00004367 with pytest.raises(ValueError):
4368 get_elliptic_curve(u"this curve was just invented")
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004369
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004370 def test_repr(self):
4371 """
4372 The string representation of a curve object includes simply states the
4373 object is a curve and what its name is.
4374 """
4375 curves = get_elliptic_curves()
Alex Chan63ef9bc2016-12-19 12:02:06 +00004376 curve = next(iter(curves))
4377 assert "<Curve %r>" % (curve.name,) == repr(curve)
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004378
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004379 def test_to_EC_KEY(self):
4380 """
4381 The curve object can export a version of itself as an EC_KEY* via the
Alex Chan63ef9bc2016-12-19 12:02:06 +00004382 private `_EllipticCurve._to_EC_KEY`.
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004383 """
4384 curves = get_elliptic_curves()
Alex Chan63ef9bc2016-12-19 12:02:06 +00004385 curve = next(iter(curves))
4386 # It's not easy to assert anything about this object. However, see
4387 # leakcheck/crypto.py for a test that demonstrates it at least does
4388 # not leak memory.
4389 curve._to_EC_KEY()
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004390
4391
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04004392class EllipticCurveFactory(object):
4393 """
4394 A helper to get the names of two curves.
4395 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04004396
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04004397 def __init__(self):
4398 curves = iter(get_elliptic_curves())
Alex Chan63ef9bc2016-12-19 12:02:06 +00004399 self.curve_name = next(curves).name
4400 self.another_curve_name = next(curves).name
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04004401
4402
Alex Chan63ef9bc2016-12-19 12:02:06 +00004403class TestEllipticCurveEquality(EqualityTestsMixin):
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04004404 """
Paul Kehrer7d5a3bf2019-01-21 12:24:02 -06004405 Tests `_EllipticCurve`'s implementation of ``==`` and ``!=``.
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04004406 """
Alex Gaynor03737182020-07-23 20:40:46 -04004407
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04004408 curve_factory = EllipticCurveFactory()
4409
4410 if curve_factory.curve_name is None:
4411 skip = "There are no curves available there can be no curve objects."
4412
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04004413 def anInstance(self):
4414 """
4415 Get the curve object for an arbitrary curve supported by the system.
4416 """
4417 return get_elliptic_curve(self.curve_factory.curve_name)
4418
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04004419 def anotherInstance(self):
4420 """
4421 Get the curve object for an arbitrary curve supported by the system -
4422 but not the one returned by C{anInstance}.
4423 """
4424 return get_elliptic_curve(self.curve_factory.another_curve_name)
4425
4426
Alex Chan63ef9bc2016-12-19 12:02:06 +00004427class TestEllipticCurveHash(object):
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04004428 """
Alex Chan63ef9bc2016-12-19 12:02:06 +00004429 Tests for `_EllipticCurve`'s implementation of hashing (thus use as
4430 an item in a `dict` or `set`).
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04004431 """
Alex Gaynor03737182020-07-23 20:40:46 -04004432
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04004433 curve_factory = EllipticCurveFactory()
4434
4435 if curve_factory.curve_name is None:
4436 skip = "There are no curves available there can be no curve objects."
4437
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04004438 def test_contains(self):
4439 """
Alex Chan63ef9bc2016-12-19 12:02:06 +00004440 The ``in`` operator reports that a `set` containing a curve does
4441 contain that curve.
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04004442 """
4443 curve = get_elliptic_curve(self.curve_factory.curve_name)
4444 curves = set([curve])
Alex Chan63ef9bc2016-12-19 12:02:06 +00004445 assert curve in curves
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04004446
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04004447 def test_does_not_contain(self):
4448 """
Alex Chan63ef9bc2016-12-19 12:02:06 +00004449 The ``in`` operator reports that a `set` not containing a curve
4450 does not contain that curve.
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04004451 """
4452 curve = get_elliptic_curve(self.curve_factory.curve_name)
Alex Gaynor03737182020-07-23 20:40:46 -04004453 curves = set(
4454 [get_elliptic_curve(self.curve_factory.another_curve_name)]
4455 )
Alex Chan63ef9bc2016-12-19 12:02:06 +00004456 assert curve not in curves